diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 94e5eb707a3..f4255baeb03 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -144,6 +144,24 @@ jobs: scripts/perf/run-quadrant-matrix.sh \ | tee "scripts/perf/results/quadrant-matrix-${{ github.run_id }}.md" + # spec-5.50 D1: CR read-path profile (SELECT-heavy / long-snapshot / + # parallel-scan). Build-invariant counter deltas + cross-backend + # redundancy (= construct_delta / distinct_cr_keys, NOT distinct_blocks); + # absolute wall is cassert-inflated trend only (perf.yml is all-cassert, + # §15.1). warn-only (perf is never a hard gate, 规则 20.A). Perf tier, + # NOT fast-gate / nightly correctness shard (spec-5.50 Q9 / L91). + - name: CR read-path profile (warn-only, Linux) + if: runner.os == 'Linux' + continue-on-error: true + run: | + mkdir -p scripts/perf/results + INSTALL_PREFIX=$HOME/linkdb-install \ + scripts/perf/run-cr-profile.sh --axis all \ + --rows "${CR_PROFILE_ROWS:-3000}" \ + --readers "${CR_PROFILE_READERS:-4}" \ + --out "scripts/perf/results/cr-profile-${{ github.run_id }}.csv" \ + | tee "scripts/perf/results/cr-profile-${{ github.run_id }}.log" + - name: Collect perf artifacts if: always() run: | diff --git a/install/bin/clusterdb b/install/bin/clusterdb new file mode 100755 index 00000000000..70a5970e8e4 Binary files /dev/null and b/install/bin/clusterdb differ diff --git a/install/bin/createdb b/install/bin/createdb new file mode 100755 index 00000000000..54cfb95d62f Binary files /dev/null and b/install/bin/createdb differ diff --git a/install/bin/createuser b/install/bin/createuser new file mode 100755 index 00000000000..00fc3731763 Binary files /dev/null and b/install/bin/createuser differ diff --git a/install/bin/dropdb b/install/bin/dropdb new file mode 100755 index 00000000000..722772a1c9d Binary files /dev/null and b/install/bin/dropdb differ diff --git a/install/bin/dropuser b/install/bin/dropuser new file mode 100755 index 00000000000..8f05c95c418 Binary files /dev/null and b/install/bin/dropuser differ diff --git a/install/bin/ecpg b/install/bin/ecpg new file mode 100755 index 00000000000..1fe725097d1 Binary files /dev/null and b/install/bin/ecpg differ diff --git a/install/bin/initdb b/install/bin/initdb new file mode 100755 index 00000000000..a33a0265b3f Binary files /dev/null and b/install/bin/initdb differ diff --git a/install/bin/pg_amcheck b/install/bin/pg_amcheck new file mode 100755 index 00000000000..efa4d9a575d Binary files /dev/null and b/install/bin/pg_amcheck differ diff --git a/install/bin/pg_archivecleanup b/install/bin/pg_archivecleanup new file mode 100755 index 00000000000..7a55a31299e Binary files /dev/null and b/install/bin/pg_archivecleanup differ diff --git a/install/bin/pg_basebackup b/install/bin/pg_basebackup new file mode 100755 index 00000000000..78604b41e6e Binary files /dev/null and b/install/bin/pg_basebackup differ diff --git a/install/bin/pg_checksums b/install/bin/pg_checksums new file mode 100755 index 00000000000..f4b78581f24 Binary files /dev/null and b/install/bin/pg_checksums differ diff --git a/install/bin/pg_config b/install/bin/pg_config new file mode 100755 index 00000000000..51acc76a729 Binary files /dev/null and b/install/bin/pg_config differ diff --git a/install/bin/pg_controldata b/install/bin/pg_controldata new file mode 100755 index 00000000000..579ba53c224 Binary files /dev/null and b/install/bin/pg_controldata differ diff --git a/install/bin/pg_ctl b/install/bin/pg_ctl new file mode 100755 index 00000000000..7f0c0a5405c Binary files /dev/null and b/install/bin/pg_ctl differ diff --git a/install/bin/pg_dump b/install/bin/pg_dump new file mode 100755 index 00000000000..9e35364eb7b Binary files /dev/null and b/install/bin/pg_dump differ diff --git a/install/bin/pg_dumpall b/install/bin/pg_dumpall new file mode 100755 index 00000000000..9eb7dba525c Binary files /dev/null and b/install/bin/pg_dumpall differ diff --git a/install/bin/pg_isready b/install/bin/pg_isready new file mode 100755 index 00000000000..2eadb07b9a0 Binary files /dev/null and b/install/bin/pg_isready differ diff --git a/install/bin/pg_receivewal b/install/bin/pg_receivewal new file mode 100755 index 00000000000..8ef98157824 Binary files /dev/null and b/install/bin/pg_receivewal differ diff --git a/install/bin/pg_recvlogical b/install/bin/pg_recvlogical new file mode 100755 index 00000000000..9a663fd5704 Binary files /dev/null and b/install/bin/pg_recvlogical differ diff --git a/install/bin/pg_resetwal b/install/bin/pg_resetwal new file mode 100755 index 00000000000..27c91efc784 Binary files /dev/null and b/install/bin/pg_resetwal differ diff --git a/install/bin/pg_restore b/install/bin/pg_restore new file mode 100755 index 00000000000..7f9d10fac6b Binary files /dev/null and b/install/bin/pg_restore differ diff --git a/install/bin/pg_rewind b/install/bin/pg_rewind new file mode 100755 index 00000000000..611d46e2d82 Binary files /dev/null and b/install/bin/pg_rewind differ diff --git a/install/bin/pg_test_fsync b/install/bin/pg_test_fsync new file mode 100755 index 00000000000..6fb8e58aa88 Binary files /dev/null and b/install/bin/pg_test_fsync differ diff --git a/install/bin/pg_test_timing b/install/bin/pg_test_timing new file mode 100755 index 00000000000..a0e1fea265a Binary files /dev/null and b/install/bin/pg_test_timing differ diff --git a/install/bin/pg_upgrade b/install/bin/pg_upgrade new file mode 100755 index 00000000000..5ca7643ab82 Binary files /dev/null and b/install/bin/pg_upgrade differ diff --git a/install/bin/pg_verifybackup b/install/bin/pg_verifybackup new file mode 100755 index 00000000000..fb047a5417d Binary files /dev/null and b/install/bin/pg_verifybackup differ diff --git a/install/bin/pg_waldump b/install/bin/pg_waldump new file mode 100755 index 00000000000..735ae60a2fc Binary files /dev/null and b/install/bin/pg_waldump differ diff --git a/install/bin/pgbench b/install/bin/pgbench new file mode 100755 index 00000000000..cbb5a9bd7da Binary files /dev/null and b/install/bin/pgbench differ diff --git a/install/bin/pgrac-acceptance b/install/bin/pgrac-acceptance new file mode 100755 index 00000000000..f2461cad323 --- /dev/null +++ b/install/bin/pgrac-acceptance @@ -0,0 +1,304 @@ +#!/bin/bash +#------------------------------------------------------------------------- +# +# pgrac-acceptance -- DBA self-verification smoke check for pgrac +# Stage 1+/2.1 deliverables on a running cluster. +# Sync'd to 030_acceptance.pl thresholds (Hardening +# v1.0.1 D-H8 / codex review P1-2). +# +# Runs ~10 read-only psql queries against an already-started pgrac +# instance and prints a coloured PASS/FAIL table. Intended for DBA +# self-service confirmation that an installed pgrac binary is wired +# up correctly: catalog views are reachable, injection-point registry +# is populated, pgstat counters are visible, --pgrac-version flag +# works. Does not modify any state. +# +# Exit code: 0 if every check passes, 1 if any check fails. +# +# Author: SqlRush +# Portions Copyright (c) 2026, pgrac contributors +# +# Spec: specs/spec-0.30-stage0-acceptance.md (Deliverable 5) +# +# NOTES +# Deliberately depends only on bash + psql + awk (no perl, no jq); +# must run on any machine that has the pgrac client tools installed. +# +# This is a smoke check, not a full regression net. The exhaustive +# cross-spec acceptance test lives in +# src/test/cluster_tap/t/030_acceptance.pl (TAP, 59+ assertions); +# pgrac-acceptance trims that down to the ~10 user-visible signals +# a DBA can interpret without source-tree access. +# +#------------------------------------------------------------------------- +set -uo pipefail + +PROGNAME="pgrac-acceptance" + +# ---- defaults --------------------------------------------------------- +PORT="" +DBNAME="postgres" +HOSTOPT="" +USEROPT="" +NO_COLOR="${NO_COLOR:-}" + +# ---- helpers ---------------------------------------------------------- + +die() { + echo "$PROGNAME: $*" 1>&2 + exit 2 +} + +usage() { + cat <. +EOF +} + +# ANSI colours (suppressed when NO_COLOR is set or stdout is not a tty). +if [ -n "$NO_COLOR" ] || [ ! -t 1 ]; then + C_GREEN="" + C_RED="" + C_BOLD="" + C_RESET="" +else + C_GREEN=$'\033[32m' + C_RED=$'\033[31m' + C_BOLD=$'\033[1m' + C_RESET=$'\033[0m' +fi + +PASS_COUNT=0 +FAIL_COUNT=0 + +# Run a SQL query and capture stdout; suppress psql notices/banners. +psql_query() { + local sql="$1" + psql -X -A -t -q $HOSTOPT $USEROPT \ + ${PORT:+-p "$PORT"} -d "$DBNAME" \ + -c "$sql" 2>/dev/null +} + +# Record a check result. $1 is "PASS" or "FAIL"; $2 is the description. +record() { + local outcome="$1" + local desc="$2" + if [ "$outcome" = "PASS" ]; then + echo "${C_GREEN}[PASS]${C_RESET} $desc" + PASS_COUNT=$((PASS_COUNT + 1)) + else + echo "${C_RED}[FAIL]${C_RESET} $desc" + FAIL_COUNT=$((FAIL_COUNT + 1)) + fi +} + +# Check that a SQL query returns a value matching an expected pattern. +# Args: description, sql, expected-regex +check_sql() { + local desc="$1" + local sql="$2" + local expect="$3" + local got + got=$(psql_query "$sql") + if [[ "$got" =~ $expect ]]; then + record PASS "$desc (got: $got)" + else + record FAIL "$desc (expected /$expect/, got: $got)" + fi +} + +# Check that a SQL query returns at least N rows-of-count. +# Args: description, sql, minimum-int +check_sql_min() { + local desc="$1" + local sql="$2" + local min="$3" + local got + got=$(psql_query "$sql") + if [[ "$got" =~ ^[0-9]+$ ]] && [ "$got" -ge "$min" ]; then + record PASS "$desc ($got >= $min)" + else + record FAIL "$desc (expected >= $min, got: $got)" + fi +} + +# ---- argument parsing ------------------------------------------------- + +while [ $# -gt 0 ]; do + case "$1" in + -p) + shift + [ $# -gt 0 ] || die "option -p requires an argument" + PORT="$1" + ;; + -p*) + PORT="${1#-p}" + ;; + --port) + shift + [ $# -gt 0 ] || die "option --port requires an argument" + PORT="$1" + ;; + --port=*) + PORT="${1#*=}" + ;; + -d) + shift + [ $# -gt 0 ] || die "option -d requires an argument" + DBNAME="$1" + ;; + --db=*) + DBNAME="${1#*=}" + ;; + -h) + shift + [ $# -gt 0 ] || die "option -h requires an argument" + HOSTOPT="-h $1" + ;; + --host=*) + HOSTOPT="-h ${1#*=}" + ;; + -U) + shift + [ $# -gt 0 ] || die "option -U requires an argument" + USEROPT="-U $1" + ;; + --username=*) + USEROPT="-U ${1#*=}" + ;; + -V|--version) + POSTGRES_BIN=$(command -v postgres || true) + if [ -n "$POSTGRES_BIN" ] && [ -x "$POSTGRES_BIN" ]; then + "$POSTGRES_BIN" --pgrac-version 2>/dev/null \ + || echo "$PROGNAME (pgrac, version unavailable from postgres)" + else + echo "$PROGNAME (pgrac, postgres binary not in PATH)" + fi + exit 0 + ;; + -\?|--help) + usage + exit 0 + ;; + *) + die "unrecognised option \"$1\" (try --help)" + ;; + esac + shift +done + +# ---- preflight -------------------------------------------------------- + +command -v psql >/dev/null 2>&1 || die "psql not found in PATH" + +POSTGRES_BIN=$(command -v postgres || true) +[ -n "$POSTGRES_BIN" ] || die "postgres binary not in PATH" + +# ---- header ----------------------------------------------------------- + +echo "==================================================" +echo " pgrac Stage 1+/2.1 acceptance smoke check" +echo "==================================================" + +# ---- check 1: postgres binary present and executable ------------------ +if [ -x "$POSTGRES_BIN" ]; then + record PASS "postgres binary present and executable ($POSTGRES_BIN)" +else + record FAIL "postgres binary present and executable (not executable)" +fi + +# ---- check 2: --pgrac-version flag works ------------------------------ +PGRAC_VER=$("$POSTGRES_BIN" --pgrac-version 2>/dev/null || true) +if [[ "$PGRAC_VER" =~ ^pgrac\ v[0-9] ]]; then + record PASS "postgres --pgrac-version returns \"$PGRAC_VER\"" +else + record FAIL "postgres --pgrac-version (got: ${PGRAC_VER:-})" +fi + +# Bail out early if we cannot reach a running cluster: the remaining +# checks all require a SQL connection. Probe with SELECT 1. +if ! psql_query "SELECT 1" >/dev/null; then + echo + echo "${C_BOLD}${C_RED}ERROR:${C_RESET} cannot connect to postmaster (port=${PORT:-default}, db=$DBNAME)." + echo "Start the cluster first: pgrac-start -D PGDATA" + exit 2 +fi + +# ---- check 3: cluster.node_id GUC accessible -------------------------- +check_sql "cluster.node_id GUC accessible" \ + "SHOW cluster.node_id" \ + "^-?[0-9]+$" + +# ---- check 4: pg_cluster_nodes view returns >= 1 row ------------------ +check_sql_min "pg_cluster_nodes returns >= 1 row" \ + "SELECT count(*) FROM pg_cluster_nodes" \ + 1 + +# ---- check 5: pg_stat_cluster_wait_events returns 60 rows ------------- +# Stage 1+/2.1 current count. 030_acceptance.pl is the SSOT for this +# threshold; keep this script in sync (Hardening v1.0.1 D-H8 / codex +# review P1-2 -- sync from Stage 0 = 51 to current). +check_sql "pg_stat_cluster_wait_events returns 60 rows" \ + "SELECT count(*) FROM pg_stat_cluster_wait_events" \ + "^60$" + +# ---- check 6: pg_stat_cluster_nodes returns >= 1 row ------------------ +check_sql_min "pg_stat_cluster_nodes returns >= 1 row" \ + "SELECT count(*) FROM pg_stat_cluster_nodes" \ + 1 + +# ---- check 7: pg_stat_cluster_injections has 83 registered points ---- +# Stage 1+/2.1 current count. 030_acceptance.pl is the SSOT for this +# threshold; keep this script in sync (Hardening v1.0.1 D-H8 / codex +# review P1-2 -- sync from Stage 0 = 28 to current). +check_sql "pg_stat_cluster_injections has 83 registered injection points" \ + "SELECT count(*) FROM pg_stat_cluster_injections" \ + "^83$" + +# ---- check 8: cluster.inject.armed_count counter visible ------------- +check_sql_min "pg_stat_cluster_counters has cluster.inject.armed_count" \ + "SELECT count(*) FROM pg_stat_cluster_counters WHERE name = 'cluster.inject.armed_count'" \ + 1 + +# ---- check 9: pg_cluster_state returns 16 categories ----------------- +# Stage 1+/2.1 current count. 030_acceptance.pl §O2 is the SSOT for +# the exact category set; keep this script in sync (Hardening v1.0.1 +# D-H8 / codex review P1-2 -- sync from Stage 0 = 11 to current). +check_sql "pg_cluster_state returns 16 categories" \ + "SELECT count(DISTINCT category) FROM pg_cluster_state" \ + "^16$" + +# ---- check 10: cluster_phase is 'init' (postmaster booted ok) -------- +check_sql "phase.cluster_phase = 'init'" \ + "SELECT value FROM pg_cluster_state WHERE category = 'phase' AND key = 'cluster_phase'" \ + "^init$" + +# ---- summary ---------------------------------------------------------- + +TOTAL=$((PASS_COUNT + FAIL_COUNT)) +echo +if [ "$FAIL_COUNT" -eq 0 ]; then + echo "${C_BOLD}${C_GREEN}${PASS_COUNT}/${TOTAL} checks passed. Stage 1+/2.1 acceptance: GREEN.${C_RESET}" + exit 0 +else + echo "${C_BOLD}${C_RED}${FAIL_COUNT}/${TOTAL} checks FAILED. Stage 1+/2.1 acceptance: RED.${C_RESET}" + exit 1 +fi diff --git a/install/bin/pgrac-init b/install/bin/pgrac-init new file mode 100755 index 00000000000..2b2e1e0d924 --- /dev/null +++ b/install/bin/pgrac-init @@ -0,0 +1,368 @@ +#!/bin/bash +#------------------------------------------------------------------------- +# +# pgrac-init -- initialise a new pgrac data directory +# +# Stage 0.20 stub: a thin wrapper around initdb that additionally +# (a) sets cluster.node_id in postgresql.conf, and (b) writes a +# minimal pgrac.conf with a [node.] section. Stage 2+ will +# extend this script (or replace it) with multi-node bootstrap +# orchestration. +# +# Author: SqlRush +# Portions Copyright (c) 2026, pgrac contributors +# +# Spec: specs/spec-0.20-init-tools.md +# Design: docs/cluster-conf-design.md (pgrac.conf format) +# +#------------------------------------------------------------------------- +set -euo pipefail + +PROGNAME="pgrac-init" +PGRAC_VERSION="0.1.0-stage0.20" + +# ---- defaults --------------------------------------------------------- +PGDATA_OPT="" +NODE_ID="0" +CLUSTER_NAME="pgrac" +INITDB_OPTS="" +FORCE="no" +WAL_THREADS_DIR="" + +# ---- helpers ---------------------------------------------------------- + +die() { + echo "$PROGNAME: $*" 1>&2 + exit 1 +} + +usage() { + cat < + (initdb -X) and cluster.wal_threads_dir is set + in postgresql.conf (spec-4.1; requires an + absolute path) + --force rewrite postgresql.conf cluster.node_id and + pgrac.conf even if PGDATA is already initialised + (initdb itself still refuses to clobber data) + -o, --initdb-options=OPTS pass OPTS to initdb verbatim + (use --initdb-options="--encoding=UTF8 --locale=C") + -V, --version output version information, then exit + -?, --help show this help, then exit + +Report bugs to . +EOF +} + +version() { + echo "$PROGNAME (pgrac) $PGRAC_VERSION" +} + +# Locate a PG bin tool. Search order: explicit env override, the +# directory of this script (matches a normal install), then PATH. +locate_pg_tool() { + local tool="$1" + local env_var="$2" + local override="${!env_var:-}" + if [ -n "$override" ]; then + if [ -x "$override" ]; then + echo "$override" + return 0 + fi + die "$env_var=$override is not executable" + fi + local sibling + sibling="$(dirname "$(realpath "$0")")/$tool" + if [ -x "$sibling" ]; then + echo "$sibling" + return 0 + fi + if command -v "$tool" >/dev/null 2>&1; then + command -v "$tool" + return 0 + fi + die "$tool not found (set $env_var or adjust PATH)" +} + +# Append a key=value to postgresql.conf, replacing an existing line +# that already has the same key (commented or not). Idempotent if the +# value already matches; refuses to overwrite a different value unless +# --force. +set_postgresql_conf_value() { + local conf="$1" key="$2" value="$3" + local key_re="${key//./\\.}" + # Only UNcommented lines count as an existing setting. The shipped + # postgresql.conf.sample carries commented documentation anchors + # (e.g. "#cluster.node_id = -1"); treating those as a live value + # made every fresh bootstrap demand --force (spec-4.1 review fix). + # A commented anchor is left in place and the live value appended: + # last-wins postgresql.conf semantics make the appended line rule. + local pattern="^[[:space:]]*${key_re}[[:space:]]*=" + local current + if grep -Eq "$pattern" "$conf"; then + current=$(grep -E "$pattern" "$conf" | tail -1 \ + | sed -E "s/^[[:space:]]*${key_re}[[:space:]]*=[[:space:]]*//; s/[[:space:]]*#.*$//; s/[[:space:]]*$//") + if [ "$current" = "$value" ]; then + return 0 + fi + if [ "$FORCE" != "yes" ]; then + die "$conf already sets $key=$current (use --force to overwrite to $value)" + fi + # Replace the existing line in-place. + local tmp + tmp=$(mktemp) + awk -v key="$key" -v val="$value" -v pat="$pattern" ' + $0 ~ pat && !done { print key " = " val; done = 1; next } + { print } + ' "$conf" >"$tmp" + mv "$tmp" "$conf" + echo "$PROGNAME: updated $key = $value in $conf" + return 0 + fi + { + echo "" + echo "# Added by $PROGNAME (Stage 0.20)." + echo "$key = $value" + } >>"$conf" + echo "$PROGNAME: appended $key = $value to $conf" +} + +# Write pgrac.conf with the [cluster] header and one [node.N] section. +# Refuses to overwrite an existing file unless --force. +write_pgrac_conf() { + local conf="$1" node_id="$2" cluster_name="$3" + local hostname_short + hostname_short=$(hostname -s 2>/dev/null || hostname || echo "localhost") + if [ -e "$conf" ] && [ "$FORCE" != "yes" ]; then + die "$conf already exists (use --force to overwrite)" + fi + cat >"$conf" </dev/null || true) + if [ -z "$pg_config_bin" ]; then + return 0 + fi + if "$pg_config_bin" --configure 2>/dev/null | grep -q -- '--enable-cluster'; then + return 0 + fi + cat 1>&2 <<'EOF' +WARNING: this build does not include --enable-cluster. +WARNING: cluster.node_id will be flagged as 'unrecognized configuration +WARNING: parameter' when the server starts. Rebuild with +WARNING: ./configure --enable-cluster +WARNING: to use pgrac cluster features. +EOF +} + +# ---- argument parsing ------------------------------------------------- + +while [ $# -gt 0 ]; do + case "$1" in + -D) + shift + [ $# -gt 0 ] || die "option -D requires an argument" + PGDATA_OPT="$1" + ;; + -D*) + PGDATA_OPT="${1#-D}" + ;; + --pgdata) + shift + [ $# -gt 0 ] || die "option --pgdata requires an argument" + PGDATA_OPT="$1" + ;; + --pgdata=*) + PGDATA_OPT="${1#*=}" + ;; + --node-id) + shift + [ $# -gt 0 ] || die "option --node-id requires an argument" + NODE_ID="$1" + ;; + --node-id=*) + NODE_ID="${1#*=}" + ;; + --cluster-name) + shift + [ $# -gt 0 ] || die "option --cluster-name requires an argument" + CLUSTER_NAME="$1" + ;; + --cluster-name=*) + CLUSTER_NAME="${1#*=}" + ;; + --wal-threads-dir) + shift + [ $# -gt 0 ] || die "option --wal-threads-dir requires an argument" + WAL_THREADS_DIR="$1" + ;; + --wal-threads-dir=*) + WAL_THREADS_DIR="${1#*=}" + ;; + --force) + FORCE="yes" + ;; + -o) + shift + [ $# -gt 0 ] || die "option -o requires an argument" + INITDB_OPTS="$1" + ;; + -o*) + INITDB_OPTS="${1#-o}" + ;; + --initdb-options) + shift + [ $# -gt 0 ] || die "option --initdb-options requires an argument" + INITDB_OPTS="$1" + ;; + --initdb-options=*) + INITDB_OPTS="${1#*=}" + ;; + -V|--version) + version + exit 0 + ;; + -\?|--help) + usage + exit 0 + ;; + --) + shift + break + ;; + -*) + echo "$PROGNAME: invalid option \"$1\"" 1>&2 + echo "Try \"$PROGNAME --help\" for more information." 1>&2 + exit 1 + ;; + *) + if [ -n "$PGDATA_OPT" ]; then + die "too many positional arguments" + fi + PGDATA_OPT="$1" + ;; + esac + shift +done + +# Resolve PGDATA: CLI flag > environment > error. +TARGET_PGDATA="${PGDATA_OPT:-${PGDATA:-}}" +[ -n "$TARGET_PGDATA" ] || die "no data directory specified (use -D or set PGDATA)" + +# Validate node id. +case "$NODE_ID" in + ''|*[!0-9]*) die "--node-id must be a non-negative integer (got \"$NODE_ID\")" ;; +esac +if [ "$NODE_ID" -lt 0 ] || [ "$NODE_ID" -gt 127 ]; then + die "--node-id must be in [0, 127] (got $NODE_ID)" +fi + +INITDB=$(locate_pg_tool initdb INITDB) + +warn_if_disable_cluster_build + +# ---- Step 0: per-thread WAL layout (spec-4.1) ------------------------- +# +# thread_id = node_id + 1 (0 is the permanent legacy sentinel and never +# becomes a directory name). The thread directory is created here and +# handed to initdb -X, which relocates pg_wal via the standard symlink +# mechanism; the server validates the routing at startup +# (cluster_wal_thread_init, FATAL 53RA0/53RA1 on mismatch). + +WAL_THREAD_XOPT="" +if [ -n "$WAL_THREADS_DIR" ]; then + case "$WAL_THREADS_DIR" in + /*) ;; + *) die "--wal-threads-dir must be an absolute path (got \"$WAL_THREADS_DIR\")" ;; + esac + # Refuse an already-initialised PGDATA BEFORE touching the shared + # WAL root: a failing command must not leave an empty thread_N + # directory behind on shared storage. + if [ -f "$TARGET_PGDATA/PG_VERSION" ]; then + die "--wal-threads-dir cannot relocate an already-initialised PGDATA (move pg_wal manually, see the pgrac manual)" + fi + THREAD_ID=$((NODE_ID + 1)) + THREAD_DIR="$WAL_THREADS_DIR/thread_$THREAD_ID" + mkdir -p "$THREAD_DIR" || die "could not create \"$THREAD_DIR\"" + if [ -n "$(ls -A "$THREAD_DIR" 2>/dev/null)" ]; then + die "WAL thread directory \"$THREAD_DIR\" is not empty (another node's stream?)" + fi + WAL_THREAD_XOPT="-X $THREAD_DIR" + echo "$PROGNAME: WAL thread $THREAD_ID stream at \"$THREAD_DIR\"" +fi + +# ---- Step 1: initdb (if PGDATA empty / missing) ----------------------- + +if [ -d "$TARGET_PGDATA" ] && [ -n "$(ls -A "$TARGET_PGDATA" 2>/dev/null)" ]; then + if [ -f "$TARGET_PGDATA/PG_VERSION" ]; then + echo "$PROGNAME: PGDATA \"$TARGET_PGDATA\" already initialised, skipping initdb" + else + die "PGDATA \"$TARGET_PGDATA\" exists but is not a PG data directory" + fi +else + echo "$PROGNAME: running initdb -D \"$TARGET_PGDATA\"" + # shellcheck disable=SC2086 # INITDB_OPTS / WAL_THREAD_XOPT intentionally word-split + "$INITDB" -D "$TARGET_PGDATA" $WAL_THREAD_XOPT $INITDB_OPTS +fi + +PG_CONF="$TARGET_PGDATA/postgresql.conf" +PGRAC_CONF="$TARGET_PGDATA/pgrac.conf" + +[ -f "$PG_CONF" ] || die "$PG_CONF missing -- initdb did not produce expected layout" + +# ---- Step 2: cluster.node_id in postgresql.conf ----------------------- + +set_postgresql_conf_value "$PG_CONF" "cluster.node_id" "$NODE_ID" + +if [ -n "$WAL_THREADS_DIR" ]; then + set_postgresql_conf_value "$PG_CONF" "cluster.wal_threads_dir" "'$WAL_THREADS_DIR'" +fi + +# ---- Step 3: write pgrac.conf ----------------------------------------- + +if [ -f "$PGRAC_CONF" ] && [ "$FORCE" != "yes" ]; then + echo "$PROGNAME: $PGRAC_CONF already exists, leaving in place (use --force to overwrite)" +else + write_pgrac_conf "$PGRAC_CONF" "$NODE_ID" "$CLUSTER_NAME" +fi + +# ---- Step 4: success message ------------------------------------------ + +cat <] section +# matches. All preflight failures are reported with hints pointing +# at pgrac-init. +# +# Author: SqlRush +# Portions Copyright (c) 2026, pgrac contributors +# +# Spec: specs/spec-0.20-init-tools.md +# +#------------------------------------------------------------------------- +set -euo pipefail + +PROGNAME="pgrac-start" +PGRAC_VERSION="0.1.0-stage0.20" + +# ---- defaults --------------------------------------------------------- +PGDATA_OPT="" +PG_CTL_PASSTHROUGH=() + +# ---- helpers ---------------------------------------------------------- + +die() { + echo "$PROGNAME: $*" 1>&2 + exit 1 +} + +usage() { + cat <] (if present) matches cluster.node_id + +Use pgrac-init -D PGDATA to bootstrap a new data directory. +Report bugs to . +EOF +} + +version() { + echo "$PROGNAME (pgrac) $PGRAC_VERSION" +} + +locate_pg_tool() { + local tool="$1" + local env_var="$2" + local override="${!env_var:-}" + if [ -n "$override" ]; then + if [ -x "$override" ]; then + echo "$override" + return 0 + fi + die "$env_var=$override is not executable" + fi + local sibling + sibling="$(dirname "$(realpath "$0")")/$tool" + if [ -x "$sibling" ]; then + echo "$sibling" + return 0 + fi + if command -v "$tool" >/dev/null 2>&1; then + command -v "$tool" + return 0 + fi + die "$tool not found (set $env_var or adjust PATH)" +} + +# Read cluster.node_id from postgresql.conf. Returns the value (or +# empty string if not set / commented out). +read_cluster_node_id() { + local conf="$1" + local pattern='^[[:space:]]*cluster\.node_id[[:space:]]*=' + grep -E "$pattern" "$conf" 2>/dev/null | tail -1 \ + | sed -E 's/^[[:space:]]*cluster\.node_id[[:space:]]*=[[:space:]]*//; s/[[:space:]]*#.*$//; s/[[:space:]]*$//' +} + +# Read the first [node.N] section header in pgrac.conf and return N. +# Empty if no [node.*] section is present. +read_pgrac_conf_node_id() { + local conf="$1" + grep -E '^[[:space:]]*\[node\.[0-9]+\]' "$conf" 2>/dev/null | head -1 \ + | sed -E 's/^[[:space:]]*\[node\.([0-9]+)\].*$/\1/' +} + +# ---- argument parsing ------------------------------------------------- + +while [ $# -gt 0 ]; do + case "$1" in + -D) + shift + [ $# -gt 0 ] || die "option -D requires an argument" + PGDATA_OPT="$1" + ;; + -D*) + PGDATA_OPT="${1#-D}" + ;; + --pgdata) + shift + [ $# -gt 0 ] || die "option --pgdata requires an argument" + PGDATA_OPT="$1" + ;; + --pgdata=*) + PGDATA_OPT="${1#*=}" + ;; + -l|--log) + shift + [ $# -gt 0 ] || die "option -l requires an argument" + PG_CTL_PASSTHROUGH+=("-l" "$1") + ;; + -l*) + PG_CTL_PASSTHROUGH+=("-l" "${1#-l}") + ;; + --log=*) + PG_CTL_PASSTHROUGH+=("-l" "${1#*=}") + ;; + -w|--wait) + PG_CTL_PASSTHROUGH+=("-w") + ;; + -W|--no-wait) + PG_CTL_PASSTHROUGH+=("-W") + ;; + -t|--timeout) + shift + [ $# -gt 0 ] || die "option -t requires an argument" + PG_CTL_PASSTHROUGH+=("-t" "$1") + ;; + --timeout=*) + PG_CTL_PASSTHROUGH+=("-t" "${1#*=}") + ;; + -o) + shift + [ $# -gt 0 ] || die "option -o requires an argument" + PG_CTL_PASSTHROUGH+=("-o" "$1") + ;; + -o*) + PG_CTL_PASSTHROUGH+=("-o" "${1#-o}") + ;; + --options=*) + PG_CTL_PASSTHROUGH+=("-o" "${1#*=}") + ;; + -V|--version) + version + exit 0 + ;; + -\?|--help) + usage + exit 0 + ;; + --) + shift + break + ;; + -*) + echo "$PROGNAME: invalid option \"$1\"" 1>&2 + echo "Try \"$PROGNAME --help\" for more information." 1>&2 + exit 1 + ;; + *) + die "unexpected positional argument \"$1\"" + ;; + esac + shift +done + +# Anything after `--` is also passed through to pg_ctl unchanged. +while [ $# -gt 0 ]; do + PG_CTL_PASSTHROUGH+=("$1") + shift +done + +# Resolve PGDATA. +TARGET_PGDATA="${PGDATA_OPT:-${PGDATA:-}}" +[ -n "$TARGET_PGDATA" ] || die "no data directory specified (use -D or set PGDATA)" + +# ---- preflight checks ------------------------------------------------- + +[ -d "$TARGET_PGDATA" ] \ + || die "PGDATA \"$TARGET_PGDATA\" does not exist (run \"pgrac-init -D '$TARGET_PGDATA'\" first)" + +[ -f "$TARGET_PGDATA/PG_VERSION" ] \ + || die "PGDATA \"$TARGET_PGDATA\" is not a PG data directory (PG_VERSION missing)" + +PG_CONF="$TARGET_PGDATA/postgresql.conf" +PGRAC_CONF="$TARGET_PGDATA/pgrac.conf" + +[ -f "$PG_CONF" ] || die "$PG_CONF missing" + +CLUSTER_NODE_ID=$(read_cluster_node_id "$PG_CONF") +if [ -z "$CLUSTER_NODE_ID" ]; then + cat 1>&2 <&2 + echo "$PROGNAME: WARNING: postmaster will FATAL on startup unless cluster.node_id" \ + "appears as a [node.N] in pgrac.conf. Run pgrac-init --force to fix." 1>&2 + fi +fi + +# ---- exec pg_ctl ------------------------------------------------------ + +PG_CTL=$(locate_pg_tool pg_ctl PG_CTL) + +echo "$PROGNAME: starting cluster (cluster.node_id=$CLUSTER_NODE_ID, PGDATA=\"$TARGET_PGDATA\")" +exec "$PG_CTL" -D "$TARGET_PGDATA" start "${PG_CTL_PASSTHROUGH[@]}" diff --git a/install/bin/postgres b/install/bin/postgres new file mode 100755 index 00000000000..62f5d0fe4b4 Binary files /dev/null and b/install/bin/postgres differ diff --git a/install/bin/psql b/install/bin/psql new file mode 100755 index 00000000000..08ae48a35ca Binary files /dev/null and b/install/bin/psql differ diff --git a/install/bin/reindexdb b/install/bin/reindexdb new file mode 100755 index 00000000000..60cdadf17b0 Binary files /dev/null and b/install/bin/reindexdb differ diff --git a/install/bin/vacuumdb b/install/bin/vacuumdb new file mode 100755 index 00000000000..0c81a5ea7e3 Binary files /dev/null and b/install/bin/vacuumdb differ diff --git a/install/include/ecpg_config.h b/install/include/ecpg_config.h new file mode 100644 index 00000000000..afe8fa7fb54 --- /dev/null +++ b/install/include/ecpg_config.h @@ -0,0 +1,19 @@ +/* src/interfaces/ecpg/include/ecpg_config.h. Generated from ecpg_config.h.in by configure. */ +/* Define to 1 to build client libraries as thread-safe code. + * (--enable-thread-safety) */ +#define ENABLE_THREAD_SAFETY 1 + +/* Define to 1 if the system has the type `int64'. */ +/* #undef HAVE_INT64 */ + +/* Define to 1 if `long int' works and is 64 bits. */ +#define HAVE_LONG_INT_64 1 + +/* Define to 1 if the system has the type `long long int'. */ +#define HAVE_LONG_LONG_INT 1 + +/* Define to 1 if `long long int' works and is 64 bits. */ +/* #undef HAVE_LONG_LONG_INT_64 */ + +/* Define to 1 to use to define type bool. */ +#define PG_USE_STDBOOL 1 diff --git a/install/include/ecpg_informix.h b/install/include/ecpg_informix.h new file mode 100644 index 00000000000..5d918c37972 --- /dev/null +++ b/install/include/ecpg_informix.h @@ -0,0 +1,90 @@ +/* + * This file contains stuff needed to be as compatible to Informix as possible. + * src/interfaces/ecpg/include/ecpg_informix.h + */ +#ifndef _ECPG_INFORMIX_H +#define _ECPG_INFORMIX_H + +#include +#include +#include +#include +#include + +#define SQLNOTFOUND 100 + +#define ECPG_INFORMIX_NUM_OVERFLOW -1200 +#define ECPG_INFORMIX_NUM_UNDERFLOW -1201 +#define ECPG_INFORMIX_DIVIDE_ZERO -1202 +#define ECPG_INFORMIX_BAD_YEAR -1204 +#define ECPG_INFORMIX_BAD_MONTH -1205 +#define ECPG_INFORMIX_BAD_DAY -1206 +#define ECPG_INFORMIX_ENOSHORTDATE -1209 +#define ECPG_INFORMIX_DATE_CONVERT -1210 +#define ECPG_INFORMIX_OUT_OF_MEMORY -1211 +#define ECPG_INFORMIX_ENOTDMY -1212 +#define ECPG_INFORMIX_BAD_NUMERIC -1213 +#define ECPG_INFORMIX_BAD_EXPONENT -1216 +#define ECPG_INFORMIX_BAD_DATE -1218 +#define ECPG_INFORMIX_EXTRA_CHARS -1264 + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern int rdatestr(date d, char *str); +extern void rtoday(date * d); +extern int rjulmdy(date d, short *mdy); +extern int rdefmtdate(date * d, const char *fmt, const char *str); +extern int rfmtdate(date d, const char *fmt, char *str); +extern int rmdyjul(short *mdy, date * d); +extern int rstrdate(const char *str, date * d); +extern int rdayofweek(date d); + +extern int rfmtlong(long lng_val, const char *fmt, char *outbuf); +extern int rgetmsg(int msgnum, char *s, int maxsize); +extern int risnull(int t, const char *ptr); +extern int rsetnull(int t, char *ptr); +extern int rtypalign(int offset, int type); +extern int rtypmsize(int type, int len); +extern int rtypwidth(int sqltype, int sqllen); +extern void rupshift(char *str); + +extern int byleng(char *str, int len); +extern void ldchar(char *src, int len, char *dest); + +extern void ECPG_informix_set_var(int number, void *pointer, int lineno); +extern void *ECPG_informix_get_var(int number); +extern void ECPG_informix_reset_sqlca(void); + +/* Informix defines these in decimal.h */ +int decadd(decimal *arg1, decimal *arg2, decimal *sum); +int deccmp(decimal *arg1, decimal *arg2); +void deccopy(decimal *src, decimal *target); +int deccvasc(const char *cp, int len, decimal *np); +int deccvdbl(double dbl, decimal *np); +int deccvint(int in, decimal *np); +int deccvlong(long lng, decimal *np); +int decdiv(decimal *n1, decimal *n2, decimal *result); +int decmul(decimal *n1, decimal *n2, decimal *result); +int decsub(decimal *n1, decimal *n2, decimal *result); +int dectoasc(decimal *np, char *cp, int len, int right); +int dectodbl(decimal *np, double *dblp); +int dectoint(decimal *np, int *ip); +int dectolong(decimal *np, long *lngp); + +/* Informix defines these in datetime.h */ +extern void dtcurrent(timestamp * ts); +extern int dtcvasc(char *str, timestamp * ts); +extern int dtsub(timestamp * ts1, timestamp * ts2, interval * iv); +extern int dttoasc(timestamp * ts, char *output); +extern int dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr); +extern int intoasc(interval * i, char *str); +extern int dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue); + +#ifdef __cplusplus +} +#endif + +#endif /* ndef _ECPG_INFORMIX_H */ diff --git a/install/include/ecpgerrno.h b/install/include/ecpgerrno.h new file mode 100644 index 00000000000..c4bc526463d --- /dev/null +++ b/install/include/ecpgerrno.h @@ -0,0 +1,79 @@ +/* src/interfaces/ecpg/include/ecpgerrno.h */ + +#ifndef _ECPG_ERRNO_H +#define _ECPG_ERRNO_H + +#include + +/* This is a list of all error codes the embedded SQL program can return */ +#define ECPG_NO_ERROR 0 +#define ECPG_NOT_FOUND 100 + +/* system error codes returned by ecpglib get the correct number, + * but are made negative + */ +#define ECPG_OUT_OF_MEMORY -ENOMEM + +/* first we have a set of ecpg messages, they start at 200 */ +#define ECPG_UNSUPPORTED -200 +#define ECPG_TOO_MANY_ARGUMENTS -201 +#define ECPG_TOO_FEW_ARGUMENTS -202 +#define ECPG_TOO_MANY_MATCHES -203 +#define ECPG_INT_FORMAT -204 +#define ECPG_UINT_FORMAT -205 +#define ECPG_FLOAT_FORMAT -206 +#define ECPG_NUMERIC_FORMAT -207 +#define ECPG_INTERVAL_FORMAT -208 +#define ECPG_DATE_FORMAT -209 +#define ECPG_TIMESTAMP_FORMAT -210 +#define ECPG_CONVERT_BOOL -211 +#define ECPG_EMPTY -212 +#define ECPG_MISSING_INDICATOR -213 +#define ECPG_NO_ARRAY -214 +#define ECPG_DATA_NOT_ARRAY -215 +#define ECPG_ARRAY_INSERT -216 + +#define ECPG_NO_CONN -220 +#define ECPG_NOT_CONN -221 + +#define ECPG_INVALID_STMT -230 + +/* dynamic SQL related */ +#define ECPG_UNKNOWN_DESCRIPTOR -240 +#define ECPG_INVALID_DESCRIPTOR_INDEX -241 +#define ECPG_UNKNOWN_DESCRIPTOR_ITEM -242 +#define ECPG_VAR_NOT_NUMERIC -243 +#define ECPG_VAR_NOT_CHAR -244 + +/* finally the backend error messages, they start at 400 */ +#define ECPG_PGSQL -400 +#define ECPG_TRANS -401 +#define ECPG_CONNECT -402 +#define ECPG_DUPLICATE_KEY -403 +#define ECPG_SUBSELECT_NOT_ONE -404 + +/* for compatibility we define some different error codes for the same error + * if adding a new one make sure to not double define it */ +#define ECPG_INFORMIX_DUPLICATE_KEY -239 +#define ECPG_INFORMIX_SUBSELECT_NOT_ONE -284 + +/* backend WARNINGs, starting at 600 */ +#define ECPG_WARNING_UNRECOGNIZED -600 + /* WARNING: (transaction aborted): queries ignored until END */ + + /* + * WARNING: current transaction is aborted, queries ignored until end of + * transaction block + */ +#define ECPG_WARNING_QUERY_IGNORED -601 + /* WARNING: PerformPortalClose: portal "*" not found */ +#define ECPG_WARNING_UNKNOWN_PORTAL -602 + /* WARNING: BEGIN: already a transaction in progress */ +#define ECPG_WARNING_IN_TRANSACTION -603 + /* WARNING: AbortTransaction and not in in-progress state */ + /* WARNING: COMMIT: no transaction in progress */ +#define ECPG_WARNING_NO_TRANSACTION -604 + /* WARNING: BlankPortalAssignName: portal * already exists */ +#define ECPG_WARNING_PORTAL_EXISTS -605 + +#endif /* !_ECPG_ERRNO_H */ diff --git a/install/include/ecpglib.h b/install/include/ecpglib.h new file mode 100644 index 00000000000..21a21344830 --- /dev/null +++ b/install/include/ecpglib.h @@ -0,0 +1,109 @@ +/* + * Client-visible declarations for ecpglib + * + * src/interfaces/ecpg/include/ecpglib.h + */ + +#ifndef _ECPGLIB_H +#define _ECPGLIB_H + +#include + +#include "ecpg_config.h" +#include "ecpgtype.h" +#include "libpq-fe.h" +#include "sqlca.h" + +/* + * This is a small extract from c.h since we don't want to leak all postgres + * definitions into ecpg programs; but we need to know what bool is. + */ +#ifndef __cplusplus + +#ifdef PG_USE_STDBOOL +#include +#else + +/* + * We assume bool has been defined if true and false are. This avoids + * duplicate-typedef errors if this file is included after c.h. + */ +#if !(defined(true) && defined(false)) +typedef unsigned char bool; +#endif + +#ifndef true +#define true ((bool) 1) +#endif + +#ifndef false +#define false ((bool) 0) +#endif + +#endif /* not PG_USE_STDBOOL */ +#endif /* not C++ */ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +void ECPGdebug(int n, FILE *dbgs); +bool ECPGstatus(int lineno, const char *connection_name); +bool ECPGsetcommit(int lineno, const char *mode, const char *connection_name); +bool ECPGsetconn(int lineno, const char *connection_name); +bool ECPGconnect(int lineno, int c, const char *name, const char *user, + const char *passwd, const char *connection_name, int autocommit); +bool ECPGdo(const int lineno, const int compat, const int force_indicator, + const char *connection_name, const bool questionmarks, + const int st, const char *query,...); +bool ECPGtrans(int lineno, const char *connection_name, const char *transaction); +bool ECPGdisconnect(int lineno, const char *connection_name); +bool ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, + const char *name, const char *variable); +bool ECPGdeallocate(int lineno, int c, const char *connection_name, const char *name); +bool ECPGdeallocate_all(int lineno, int compat, const char *connection_name); +char *ECPGprepared_statement(const char *connection_name, const char *name, int lineno); +PGconn *ECPGget_PGconn(const char *connection_name); +PGTransactionStatusType ECPGtransactionStatus(const char *connection_name); + + /* print an error message */ +void sqlprint(void); + +/* define this for simplicity as well as compatibility */ + +#define SQLCODE sqlca.sqlcode +#define SQLSTATE sqlca.sqlstate + +/* dynamic SQL */ + +bool ECPGdo_descriptor(int line, const char *connection, + const char *descriptor, const char *query); +bool ECPGdeallocate_desc(int line, const char *name); +bool ECPGallocate_desc(int line, const char *name); +bool ECPGget_desc_header(int lineno, const char *desc_name, int *count); +bool ECPGget_desc(int lineno, const char *desc_name, int index,...); +bool ECPGset_desc_header(int lineno, const char *desc_name, int count); +bool ECPGset_desc(int lineno, const char *desc_name, int index,...); + +void ECPGset_noind_null(enum ECPGttype type, void *ptr); +bool ECPGis_noind_null(enum ECPGttype type, const void *ptr); +bool ECPGdescribe(int line, int compat, bool input, + const char *connection_name, const char *stmt_name,...); + +void ECPGset_var(int number, void *pointer, int lineno); +void *ECPGget_var(int number); + +/* dynamic result allocation */ +void ECPGfree_auto_mem(void); + +#ifdef ENABLE_THREAD_SAFETY +void ecpg_pthreads_init(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _ECPGLIB_H */ diff --git a/install/include/ecpgtype.h b/install/include/ecpgtype.h new file mode 100644 index 00000000000..3a575081e4f --- /dev/null +++ b/install/include/ecpgtype.h @@ -0,0 +1,109 @@ +/* + * This file implements a data structure that is built and maintained by the + * preprocessor. + * + * All types that can be handled for host variable declarations has to + * be handled eventually. + * + * src/interfaces/ecpg/include/ecpgtype.h + */ + +/* + * Here are all the types that we are to handle. Note that it is the type + * that is registered and that has nothing whatsoever to do with the storage + * class. + * + * Simple types + * integers: char, short, int, long (signed and unsigned) + * floats: float, double + * + * Complex types: + * VARCHAR, VARCHAR2 - Strings with length (maxlen is given in the declaration) + * Arrays of simple types and of VARCHAR, VARCHAR2 (size given in declaration) + * Records build of simple types, arrays and other structs. + * + * Complicating things: + * typedefs and struct names! + * + * Conclusion: + * This is a typically recursive definition. A structure of typed list elements + * would probably work fine: + */ + +#ifndef _ECPGTYPE_H +#define _ECPGTYPE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum ECPGttype +{ + ECPGt_char = 1, ECPGt_unsigned_char, ECPGt_short, ECPGt_unsigned_short, + ECPGt_int, ECPGt_unsigned_int, ECPGt_long, ECPGt_unsigned_long, + ECPGt_long_long, ECPGt_unsigned_long_long, + ECPGt_bool, + ECPGt_float, ECPGt_double, + ECPGt_varchar, ECPGt_varchar2, + ECPGt_numeric, /* this is a decimal that stores its digits in + * a malloced array */ + ECPGt_decimal, /* this is a decimal that stores its digits in + * a fixed array */ + ECPGt_date, + ECPGt_timestamp, + ECPGt_interval, + ECPGt_array, + ECPGt_struct, + ECPGt_union, + ECPGt_descriptor, /* sql descriptor, no C variable */ + ECPGt_char_variable, + ECPGt_const, /* a constant is needed sometimes */ + ECPGt_EOIT, /* End of insert types. */ + ECPGt_EORT, /* End of result types. */ + ECPGt_NO_INDICATOR, /* no indicator */ + ECPGt_string, /* trimmed (char *) type */ + ECPGt_sqlda, /* C struct descriptor */ + ECPGt_bytea +}; + + /* descriptor items */ +enum ECPGdtype +{ + ECPGd_count = 1, + ECPGd_data, + ECPGd_di_code, + ECPGd_di_precision, + ECPGd_indicator, + ECPGd_key_member, + ECPGd_length, + ECPGd_name, + ECPGd_nullable, + ECPGd_octet, + ECPGd_precision, + ECPGd_ret_length, + ECPGd_ret_octet, + ECPGd_scale, + ECPGd_type, + ECPGd_EODT, /* End of descriptor types. */ + ECPGd_cardinality +}; + +#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string) || ((type) == ECPGt_bytea)) + +/* we also have to handle different statement types */ +enum ECPG_statement_type +{ + ECPGst_normal, + ECPGst_execute, + ECPGst_exec_immediate, + ECPGst_prepnormal, + ECPGst_prepare, + ECPGst_exec_with_exprlist +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _ECPGTYPE_H */ diff --git a/install/include/libpq-events.h b/install/include/libpq-events.h new file mode 100644 index 00000000000..b9d51376342 --- /dev/null +++ b/install/include/libpq-events.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------- + * + * libpq-events.h + * This file contains definitions that are useful to applications + * that invoke the libpq "events" API, but are not interesting to + * ordinary users of libpq. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/libpq-events.h + * + *------------------------------------------------------------------------- + */ + +#ifndef LIBPQ_EVENTS_H +#define LIBPQ_EVENTS_H + +#include "libpq-fe.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Callback Event Ids */ +typedef enum +{ + PGEVT_REGISTER, + PGEVT_CONNRESET, + PGEVT_CONNDESTROY, + PGEVT_RESULTCREATE, + PGEVT_RESULTCOPY, + PGEVT_RESULTDESTROY +} PGEventId; + +typedef struct +{ + PGconn *conn; +} PGEventRegister; + +typedef struct +{ + PGconn *conn; +} PGEventConnReset; + +typedef struct +{ + PGconn *conn; +} PGEventConnDestroy; + +typedef struct +{ + PGconn *conn; + PGresult *result; +} PGEventResultCreate; + +typedef struct +{ + const PGresult *src; + PGresult *dest; +} PGEventResultCopy; + +typedef struct +{ + PGresult *result; +} PGEventResultDestroy; + +typedef int (*PGEventProc) (PGEventId evtId, void *evtInfo, void *passThrough); + +/* Registers an event proc with the given PGconn. */ +extern int PQregisterEventProc(PGconn *conn, PGEventProc proc, + const char *name, void *passThrough); + +/* Sets the PGconn instance data for the provided proc to data. */ +extern int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data); + +/* Gets the PGconn instance data for the provided proc. */ +extern void *PQinstanceData(const PGconn *conn, PGEventProc proc); + +/* Sets the PGresult instance data for the provided proc to data. */ +extern int PQresultSetInstanceData(PGresult *result, PGEventProc proc, void *data); + +/* Gets the PGresult instance data for the provided proc. */ +extern void *PQresultInstanceData(const PGresult *result, PGEventProc proc); + +/* Fires RESULTCREATE events for an application-created PGresult. */ +extern int PQfireResultCreateEvents(PGconn *conn, PGresult *res); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBPQ_EVENTS_H */ diff --git a/install/include/libpq-fe.h b/install/include/libpq-fe.h new file mode 100644 index 00000000000..7476dbe0e90 --- /dev/null +++ b/install/include/libpq-fe.h @@ -0,0 +1,675 @@ +/*------------------------------------------------------------------------- + * + * libpq-fe.h + * This file contains definitions for structures and + * externs for functions used by frontend postgres applications. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/libpq-fe.h + * + *------------------------------------------------------------------------- + */ + +#ifndef LIBPQ_FE_H +#define LIBPQ_FE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/* + * postgres_ext.h defines the backend's externally visible types, + * such as Oid. + */ +#include "postgres_ext.h" + +/* + * These symbols may be used in compile-time #ifdef tests for the availability + * of newer libpq features. + */ +/* Indicates presence of PQenterPipelineMode and friends */ +#define LIBPQ_HAS_PIPELINING 1 +/* Indicates presence of PQsetTraceFlags; also new PQtrace output format */ +#define LIBPQ_HAS_TRACE_FLAGS 1 +/* Indicates that PQsslAttribute(NULL, "library") is useful */ +#define LIBPQ_HAS_SSL_LIBRARY_DETECTION 1 + +/* + * Option flags for PQcopyResult + */ +#define PG_COPYRES_ATTRS 0x01 +#define PG_COPYRES_TUPLES 0x02 /* Implies PG_COPYRES_ATTRS */ +#define PG_COPYRES_EVENTS 0x04 +#define PG_COPYRES_NOTICEHOOKS 0x08 + +/* Application-visible enum types */ + +/* + * Although it is okay to add to these lists, values which become unused + * should never be removed, nor should constants be redefined - that would + * break compatibility with existing code. + */ + +typedef enum +{ + CONNECTION_OK, + CONNECTION_BAD, + /* Non-blocking mode only below here */ + + /* + * The existence of these should never be relied upon - they should only + * be used for user feedback or similar purposes. + */ + CONNECTION_STARTED, /* Waiting for connection to be made. */ + CONNECTION_MADE, /* Connection OK; waiting to send. */ + CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the + * postmaster. */ + CONNECTION_AUTH_OK, /* Received authentication; waiting for + * backend startup. */ + CONNECTION_SETENV, /* This state is no longer used. */ + CONNECTION_SSL_STARTUP, /* Negotiating SSL. */ + CONNECTION_NEEDED, /* Internal state: connect() needed */ + CONNECTION_CHECK_WRITABLE, /* Checking if session is read-write. */ + CONNECTION_CONSUME, /* Consuming any extra messages. */ + CONNECTION_GSS_STARTUP, /* Negotiating GSSAPI. */ + CONNECTION_CHECK_TARGET, /* Checking target server properties. */ + CONNECTION_CHECK_STANDBY /* Checking if server is in standby mode. */ +} ConnStatusType; + +typedef enum +{ + PGRES_POLLING_FAILED = 0, + PGRES_POLLING_READING, /* These two indicate that one may */ + PGRES_POLLING_WRITING, /* use select before polling again. */ + PGRES_POLLING_OK, + PGRES_POLLING_ACTIVE /* unused; keep for awhile for backwards + * compatibility */ +} PostgresPollingStatusType; + +typedef enum +{ + PGRES_EMPTY_QUERY = 0, /* empty query string was executed */ + PGRES_COMMAND_OK, /* a query command that doesn't return + * anything was executed properly by the + * backend */ + PGRES_TUPLES_OK, /* a query command that returns tuples was + * executed properly by the backend, PGresult + * contains the result tuples */ + PGRES_COPY_OUT, /* Copy Out data transfer in progress */ + PGRES_COPY_IN, /* Copy In data transfer in progress */ + PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the + * backend */ + PGRES_NONFATAL_ERROR, /* notice or warning message */ + PGRES_FATAL_ERROR, /* query failed */ + PGRES_COPY_BOTH, /* Copy In/Out data transfer in progress */ + PGRES_SINGLE_TUPLE, /* single tuple from larger resultset */ + PGRES_PIPELINE_SYNC, /* pipeline synchronization point */ + PGRES_PIPELINE_ABORTED /* Command didn't run because of an abort + * earlier in a pipeline */ +} ExecStatusType; + +typedef enum +{ + PQTRANS_IDLE, /* connection idle */ + PQTRANS_ACTIVE, /* command in progress */ + PQTRANS_INTRANS, /* idle, within transaction block */ + PQTRANS_INERROR, /* idle, within failed transaction */ + PQTRANS_UNKNOWN /* cannot determine status */ +} PGTransactionStatusType; + +typedef enum +{ + PQERRORS_TERSE, /* single-line error messages */ + PQERRORS_DEFAULT, /* recommended style */ + PQERRORS_VERBOSE, /* all the facts, ma'am */ + PQERRORS_SQLSTATE /* only error severity and SQLSTATE code */ +} PGVerbosity; + +typedef enum +{ + PQSHOW_CONTEXT_NEVER, /* never show CONTEXT field */ + PQSHOW_CONTEXT_ERRORS, /* show CONTEXT for errors only (default) */ + PQSHOW_CONTEXT_ALWAYS /* always show CONTEXT field */ +} PGContextVisibility; + +/* + * PGPing - The ordering of this enum should not be altered because the + * values are exposed externally via pg_isready. + */ + +typedef enum +{ + PQPING_OK, /* server is accepting connections */ + PQPING_REJECT, /* server is alive but rejecting connections */ + PQPING_NO_RESPONSE, /* could not establish connection */ + PQPING_NO_ATTEMPT /* connection not attempted (bad params) */ +} PGPing; + +/* + * PGpipelineStatus - Current status of pipeline mode + */ +typedef enum +{ + PQ_PIPELINE_OFF, + PQ_PIPELINE_ON, + PQ_PIPELINE_ABORTED +} PGpipelineStatus; + +/* PGconn encapsulates a connection to the backend. + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_conn PGconn; + +/* PGresult encapsulates the result of a query (or more precisely, of a single + * SQL command --- a query string given to PQsendQuery can contain multiple + * commands and thus return multiple PGresult objects). + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_result PGresult; + +/* PGcancel encapsulates the information needed to cancel a running + * query on an existing connection. + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_cancel PGcancel; + +/* PGnotify represents the occurrence of a NOTIFY message. + * Ideally this would be an opaque typedef, but it's so simple that it's + * unlikely to change. + * NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's, + * whereas in earlier versions it was always your own backend's PID. + */ +typedef struct pgNotify +{ + char *relname; /* notification condition name */ + int be_pid; /* process ID of notifying server process */ + char *extra; /* notification parameter */ + /* Fields below here are private to libpq; apps should not use 'em */ + struct pgNotify *next; /* list link */ +} PGnotify; + +/* Function types for notice-handling callbacks */ +typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res); +typedef void (*PQnoticeProcessor) (void *arg, const char *message); + +/* Print options for PQprint() */ +typedef char pqbool; + +typedef struct _PQprintOpt +{ + 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; /* insert to HTML */ + char *caption; /* HTML
*/ + char **fieldName; /* null terminated array of replacement field + * names */ +} PQprintOpt; + +/* ---------------- + * Structure for the conninfo parameter definitions returned by PQconndefaults + * or PQconninfoParse. + * + * All fields except "val" point at static strings which must not be altered. + * "val" is either NULL or a malloc'd current-value string. PQconninfoFree() + * will release both the val strings and the PQconninfoOption array itself. + * ---------------- + */ +typedef struct _PQconninfoOption +{ + 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; + +/* ---------------- + * PQArgBlock -- structure for PQfn() arguments + * ---------------- + */ +typedef struct +{ + int len; + int isint; + union + { + int *ptr; /* can't use void (dec compiler barfs) */ + int integer; + } u; +} PQArgBlock; + +/* ---------------- + * PGresAttDesc -- Data about a single attribute (column) of a query result + * ---------------- + */ +typedef struct pgresAttDesc +{ + char *name; /* column name */ + Oid tableid; /* source table, if known */ + int columnid; /* source column, if known */ + int format; /* format code for value (text/binary) */ + Oid typid; /* type id */ + int typlen; /* type size */ + int atttypmod; /* type-specific modifier info */ +} PGresAttDesc; + +/* ---------------- + * Exported functions of libpq + * ---------------- + */ + +/* === in fe-connect.c === */ + +/* make a new client connection to the backend */ +/* Asynchronous (non-blocking) */ +extern PGconn *PQconnectStart(const char *conninfo); +extern PGconn *PQconnectStartParams(const char *const *keywords, + const char *const *values, int expand_dbname); +extern PostgresPollingStatusType PQconnectPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern PGconn *PQconnectdb(const char *conninfo); +extern PGconn *PQconnectdbParams(const char *const *keywords, + const char *const *values, int expand_dbname); +extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, + const char *pgoptions, const char *pgtty, + const char *dbName, + const char *login, const char *pwd); + +#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \ + PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL) + +/* close the current connection and free the PGconn data structure */ +extern void PQfinish(PGconn *conn); + +/* get info about connection options known to PQconnectdb */ +extern PQconninfoOption *PQconndefaults(void); + +/* parse connection options in same way as PQconnectdb */ +extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); + +/* return the connection options used by a live connection */ +extern PQconninfoOption *PQconninfo(PGconn *conn); + +/* free the data structure returned by PQconndefaults() or PQconninfoParse() */ +extern void PQconninfoFree(PQconninfoOption *connOptions); + +/* + * close the current connection and reestablish a new one with the same + * parameters + */ +/* Asynchronous (non-blocking) */ +extern int PQresetStart(PGconn *conn); +extern PostgresPollingStatusType PQresetPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern void PQreset(PGconn *conn); + +/* request a cancel structure */ +extern PGcancel *PQgetCancel(PGconn *conn); + +/* free a cancel structure */ +extern void PQfreeCancel(PGcancel *cancel); + +/* issue a cancel request */ +extern int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + +/* backwards compatible version of PQcancel; not thread-safe */ +extern int PQrequestCancel(PGconn *conn); + +/* Accessor functions for PGconn objects */ +extern char *PQdb(const PGconn *conn); +extern char *PQuser(const PGconn *conn); +extern char *PQpass(const PGconn *conn); +extern char *PQhost(const PGconn *conn); +extern char *PQhostaddr(const PGconn *conn); +extern char *PQport(const PGconn *conn); +extern char *PQtty(const PGconn *conn); +extern char *PQoptions(const PGconn *conn); +extern ConnStatusType PQstatus(const PGconn *conn); +extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn); +extern const char *PQparameterStatus(const PGconn *conn, + const char *paramName); +extern int PQprotocolVersion(const PGconn *conn); +extern int PQserverVersion(const PGconn *conn); +extern char *PQerrorMessage(const PGconn *conn); +extern int PQsocket(const PGconn *conn); +extern int PQbackendPID(const PGconn *conn); +extern PGpipelineStatus PQpipelineStatus(const PGconn *conn); +extern int PQconnectionNeedsPassword(const PGconn *conn); +extern int PQconnectionUsedPassword(const PGconn *conn); +extern int PQconnectionUsedGSSAPI(const PGconn *conn); +extern int PQclientEncoding(const PGconn *conn); +extern int PQsetClientEncoding(PGconn *conn, const char *encoding); + +/* SSL information functions */ +extern int PQsslInUse(PGconn *conn); +extern void *PQsslStruct(PGconn *conn, const char *struct_name); +extern const char *PQsslAttribute(PGconn *conn, const char *attribute_name); +extern const char *const *PQsslAttributeNames(PGconn *conn); + +/* Get the OpenSSL structure associated with a connection. Returns NULL for + * unencrypted connections or if any other TLS library is in use. */ +extern void *PQgetssl(PGconn *conn); + +/* Tell libpq whether it needs to initialize OpenSSL */ +extern void PQinitSSL(int do_init); + +/* More detailed way to tell libpq whether it needs to initialize OpenSSL */ +extern void PQinitOpenSSL(int do_ssl, int do_crypto); + +/* Return true if GSSAPI encryption is in use */ +extern int PQgssEncInUse(PGconn *conn); + +/* Returns GSSAPI context if GSSAPI is in use */ +extern void *PQgetgssctx(PGconn *conn); + +/* Set verbosity for PQerrorMessage and PQresultErrorMessage */ +extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); + +/* Set CONTEXT visibility for PQerrorMessage and PQresultErrorMessage */ +extern PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, + PGContextVisibility show_context); + +/* Override default notice handling routines */ +extern PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, + PQnoticeReceiver proc, + void *arg); +extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, + PQnoticeProcessor proc, + void *arg); + +/* + * Used to set callback that prevents concurrent access to + * non-thread safe functions that libpq needs. + * The default implementation uses a libpq internal mutex. + * Only required for multithreaded apps that use kerberos + * both within their app and for postgresql connections. + */ +typedef void (*pgthreadlock_t) (int acquire); + +extern pgthreadlock_t PQregisterThreadLock(pgthreadlock_t newhandler); + +/* === in fe-trace.c === */ +extern void PQtrace(PGconn *conn, FILE *debug_port); +extern void PQuntrace(PGconn *conn); + +/* flags controlling trace output: */ +/* omit timestamps from each line */ +#define PQTRACE_SUPPRESS_TIMESTAMPS (1<<0) +/* redact portions of some messages, for testing frameworks */ +#define PQTRACE_REGRESS_MODE (1<<1) +extern void PQsetTraceFlags(PGconn *conn, int flags); + +/* === in fe-exec.c === */ + +/* Simple synchronous query */ +extern PGresult *PQexec(PGconn *conn, const char *query); +extern PGresult *PQexecParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern PGresult *PQprepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern PGresult *PQexecPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + +/* Interface for multiple-result or asynchronous queries */ +#define PQ_QUERY_PARAM_MAX_LIMIT 65535 + +extern int PQsendQuery(PGconn *conn, const char *query); +extern int PQsendQueryParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern int PQsendPrepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern int PQsendQueryPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern int PQsetSingleRowMode(PGconn *conn); +extern PGresult *PQgetResult(PGconn *conn); + +/* Routines for managing an asynchronous query */ +extern int PQisBusy(PGconn *conn); +extern int PQconsumeInput(PGconn *conn); + +/* Routines for pipeline mode management */ +extern int PQenterPipelineMode(PGconn *conn); +extern int PQexitPipelineMode(PGconn *conn); +extern int PQpipelineSync(PGconn *conn); +extern int PQsendFlushRequest(PGconn *conn); + +/* LISTEN/NOTIFY support */ +extern PGnotify *PQnotifies(PGconn *conn); + +/* Routines for copy in/out */ +extern int PQputCopyData(PGconn *conn, const char *buffer, int nbytes); +extern int PQputCopyEnd(PGconn *conn, const char *errormsg); +extern int PQgetCopyData(PGconn *conn, char **buffer, int async); + +/* Deprecated routines for copy in/out */ +extern int PQgetline(PGconn *conn, char *buffer, int length); +extern int PQputline(PGconn *conn, const char *string); +extern int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize); +extern int PQputnbytes(PGconn *conn, const char *buffer, int nbytes); +extern int PQendcopy(PGconn *conn); + +/* Set blocking/nonblocking connection to the backend */ +extern int PQsetnonblocking(PGconn *conn, int arg); +extern int PQisnonblocking(const PGconn *conn); +extern int PQisthreadsafe(void); +extern PGPing PQping(const char *conninfo); +extern PGPing PQpingParams(const char *const *keywords, + const char *const *values, int expand_dbname); + +/* Force the write buffer to be written (or at least try) */ +extern int PQflush(PGconn *conn); + +/* + * "Fast path" interface --- not really recommended for application + * use + */ +extern PGresult *PQfn(PGconn *conn, + int fnid, + int *result_buf, + int *result_len, + int result_is_int, + const PQArgBlock *args, + int nargs); + +/* Accessor functions for PGresult objects */ +extern ExecStatusType PQresultStatus(const PGresult *res); +extern char *PQresStatus(ExecStatusType status); +extern char *PQresultErrorMessage(const PGresult *res); +extern char *PQresultVerboseErrorMessage(const PGresult *res, + PGVerbosity verbosity, + PGContextVisibility show_context); +extern char *PQresultErrorField(const PGresult *res, int fieldcode); +extern int PQntuples(const PGresult *res); +extern int PQnfields(const PGresult *res); +extern int PQbinaryTuples(const PGresult *res); +extern char *PQfname(const PGresult *res, int field_num); +extern int PQfnumber(const PGresult *res, const char *field_name); +extern Oid PQftable(const PGresult *res, int field_num); +extern int PQftablecol(const PGresult *res, int field_num); +extern int PQfformat(const PGresult *res, int field_num); +extern Oid PQftype(const PGresult *res, int field_num); +extern int PQfsize(const PGresult *res, int field_num); +extern int PQfmod(const PGresult *res, int field_num); +extern char *PQcmdStatus(PGresult *res); +extern char *PQoidStatus(const PGresult *res); /* old and ugly */ +extern Oid PQoidValue(const PGresult *res); /* new and improved */ +extern char *PQcmdTuples(PGresult *res); +extern char *PQgetvalue(const PGresult *res, int tup_num, int field_num); +extern int PQgetlength(const PGresult *res, int tup_num, int field_num); +extern int PQgetisnull(const PGresult *res, int tup_num, int field_num); +extern int PQnparams(const PGresult *res); +extern Oid PQparamtype(const PGresult *res, int param_num); + +/* Describe prepared statements and portals */ +extern PGresult *PQdescribePrepared(PGconn *conn, const char *stmt); +extern PGresult *PQdescribePortal(PGconn *conn, const char *portal); +extern int PQsendDescribePrepared(PGconn *conn, const char *stmt); +extern int PQsendDescribePortal(PGconn *conn, const char *portal); + +/* Delete a PGresult */ +extern void PQclear(PGresult *res); + +/* For freeing other alloc'd results, such as PGnotify structs */ +extern void PQfreemem(void *ptr); + +/* Exists for backward compatibility. bjm 2003-03-24 */ +#define PQfreeNotify(ptr) PQfreemem(ptr) + +/* Error when no password was given. */ +/* Note: depending on this is deprecated; use PQconnectionNeedsPassword(). */ +#define PQnoPasswordSupplied "fe_sendauth: no password supplied\n" + +/* Create and manipulate PGresults */ +extern PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); +extern PGresult *PQcopyResult(const PGresult *src, int flags); +extern int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs); +extern void *PQresultAlloc(PGresult *res, size_t nBytes); +extern size_t PQresultMemorySize(const PGresult *res); +extern int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); + +/* Quoting strings before inclusion in queries. */ +extern size_t PQescapeStringConn(PGconn *conn, + char *to, const char *from, size_t length, + int *error); +extern char *PQescapeLiteral(PGconn *conn, const char *str, size_t len); +extern char *PQescapeIdentifier(PGconn *conn, const char *str, size_t len); +extern unsigned char *PQescapeByteaConn(PGconn *conn, + const unsigned char *from, size_t from_length, + size_t *to_length); +extern unsigned char *PQunescapeBytea(const unsigned char *strtext, + size_t *retbuflen); + +/* These forms are deprecated! */ +extern size_t PQescapeString(char *to, const char *from, size_t length); +extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, + size_t *to_length); + + + +/* === in fe-print.c === */ + +extern void PQprint(FILE *fout, /* output stream */ + const PGresult *res, + const PQprintOpt *po); /* option structure */ + +/* + * really old printing routines + */ +extern void PQdisplayTuples(const PGresult *res, + FILE *fp, /* where to send the output */ + int fillAlign, /* pad the fields with spaces */ + const char *fieldSep, /* field separator */ + int printHeader, /* display headers? */ + int quiet); + +extern void PQprintTuples(const PGresult *res, + FILE *fout, /* output stream */ + int PrintAttNames, /* print attribute names */ + int TerseOutput, /* delimiter bars */ + int colWidth); /* width of column, if 0, use + * variable width */ + + +/* === in fe-lobj.c === */ + +/* Large-object access routines */ +extern int lo_open(PGconn *conn, Oid lobjId, int mode); +extern int lo_close(PGconn *conn, int fd); +extern int lo_read(PGconn *conn, int fd, char *buf, size_t len); +extern int lo_write(PGconn *conn, int fd, const char *buf, size_t len); +extern int lo_lseek(PGconn *conn, int fd, int offset, int whence); +extern pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); +extern Oid lo_creat(PGconn *conn, int mode); +extern Oid lo_create(PGconn *conn, Oid lobjId); +extern int lo_tell(PGconn *conn, int fd); +extern pg_int64 lo_tell64(PGconn *conn, int fd); +extern int lo_truncate(PGconn *conn, int fd, size_t len); +extern int lo_truncate64(PGconn *conn, int fd, pg_int64 len); +extern int lo_unlink(PGconn *conn, Oid lobjId); +extern Oid lo_import(PGconn *conn, const char *filename); +extern Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); +extern int lo_export(PGconn *conn, Oid lobjId, const char *filename); + +/* === in fe-misc.c === */ + +/* Get the version of the libpq library in use */ +extern int PQlibVersion(void); + +/* Determine length of multibyte encoded char at *s */ +extern int PQmblen(const char *s, int encoding); + +/* Same, but not more than the distance to the end of string s */ +extern int PQmblenBounded(const char *s, int encoding); + +/* Determine display length of multibyte encoded char at *s */ +extern int PQdsplen(const char *s, int encoding); + +/* Get encoding id from environment variable PGCLIENTENCODING */ +extern int PQenv2encoding(void); + +/* === in fe-auth.c === */ + +extern char *PQencryptPassword(const char *passwd, const char *user); +extern char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm); + +/* === in encnames.c === */ + +extern int pg_char_to_encoding(const char *name); +extern const char *pg_encoding_to_char(int encoding); +extern int pg_valid_server_encoding_id(int encoding); + +/* === in fe-secure-openssl.c === */ + +/* Support for overriding sslpassword handling with a callback */ +typedef int (*PQsslKeyPassHook_OpenSSL_type) (char *buf, int size, PGconn *conn); +extern PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void); +extern void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook); +extern int PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBPQ_FE_H */ diff --git a/install/include/libpq/libpq-fs.h b/install/include/libpq/libpq-fs.h new file mode 100644 index 00000000000..f89e0f9e3fb --- /dev/null +++ b/install/include/libpq/libpq-fs.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * libpq-fs.h + * definitions for using Inversion file system routines (ie, large objects) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/libpq-fs.h + * + *------------------------------------------------------------------------- + */ +#ifndef LIBPQ_FS_H +#define LIBPQ_FS_H + +/* + * Read/write mode flags for inversion (large object) calls + */ + +#define INV_WRITE 0x00020000 +#define INV_READ 0x00040000 + +#endif /* LIBPQ_FS_H */ diff --git a/install/include/pg_config.h b/install/include/pg_config.h new file mode 100644 index 00000000000..9af8a0586f7 --- /dev/null +++ b/install/include/pg_config.h @@ -0,0 +1,830 @@ +/* src/include/pg_config.h. Generated from pg_config.h.in by configure. */ +/* src/include/pg_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* The normal alignment of `double', in bytes. */ +#define ALIGNOF_DOUBLE 8 + +/* The normal alignment of `int', in bytes. */ +#define ALIGNOF_INT 4 + +/* The normal alignment of `long', in bytes. */ +#define ALIGNOF_LONG 8 + +/* The normal alignment of `long long int', in bytes. */ +/* #undef ALIGNOF_LONG_LONG_INT */ + +/* The normal alignment of `PG_INT128_TYPE', in bytes. */ +#define ALIGNOF_PG_INT128_TYPE 16 + +/* The normal alignment of `short', in bytes. */ +#define ALIGNOF_SHORT 2 + +/* Size of a disk block --- this also limits the size of a tuple. You can set + it bigger if you need bigger tuples (although TOAST should reduce the need + to have large tuples, since fields can be spread across multiple tuples). + BLCKSZ must be a power of 2. The maximum possible value of BLCKSZ is + currently 2^15 (32768). This is determined by the 15-bit widths of the + lp_off and lp_len fields in ItemIdData (see include/storage/itemid.h). + Changing BLCKSZ requires an initdb. */ +#define BLCKSZ 8192 + +/* Saved arguments from configure */ +#define CONFIGURE_ARGS " '--prefix=/private/tmp/pgrac-worktrees/linkdb-spec-5.50-cr-profile/install' '--with-openssl' '--with-icu' '--with-lz4' '--with-zstd' '--enable-cluster' '--enable-injection-points' '--enable-tap-tests' '--enable-cassert' 'PKG_CONFIG_PATH=/opt/homebrew/opt/icu4c@78/lib/pkgconfig:/opt/homebrew/opt/openssl@3/lib/pkgconfig:/opt/homebrew/opt/lz4/lib/pkgconfig:/opt/homebrew/opt/zstd/lib/pkgconfig' 'LDFLAGS=-L/opt/homebrew/opt/openssl@3/lib' 'CPPFLAGS=-I/opt/homebrew/opt/openssl@3/include'" + +/* Define to the default TCP port number on which the server listens and to + which clients will try to connect. This can be overridden at run-time, but + it's convenient if your clients have the right default compiled in. + (--with-pgport=PORTNUM) */ +#define DEF_PGPORT 5432 + +/* Define to the default TCP port number as a string constant. */ +#define DEF_PGPORT_STR "5432" + +/* Define to the file name extension of dynamically-loadable modules. */ +#define DLSUFFIX ".dylib" + +/* Define to build with GSSAPI support. (--with-gssapi) */ +/* #undef ENABLE_GSS */ + +/* Define to 1 if you want National Language Support. (--enable-nls) */ +/* #undef ENABLE_NLS */ + +/* Define to 1 to build client libraries as thread-safe code. + (--enable-thread-safety) */ +#define ENABLE_THREAD_SAFETY 1 + +/* Define to 1 if you have the `append_history' function. */ +/* #undef HAVE_APPEND_HISTORY */ + +/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ +#define HAVE_ASN1_STRING_GET0_DATA 1 + +/* Define to 1 if you want to use atomics if available. */ +#define HAVE_ATOMICS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ATOMIC_H */ + +/* Define to 1 if you have the `backtrace_symbols' function. */ +#define HAVE_BACKTRACE_SYMBOLS 1 + +/* Define to 1 if you have the `BIO_meth_new' function. */ +#define HAVE_BIO_METH_NEW 1 + +/* Define to 1 if your compiler handles computed gotos. */ +#define HAVE_COMPUTED_GOTO 1 + +/* Define to 1 if you have the `copyfile' function. */ +#define HAVE_COPYFILE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_COPYFILE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRTDEFS_H */ + +/* Define to 1 if you have the `CRYPTO_lock' function. */ +/* #undef HAVE_CRYPTO_LOCK */ + +/* Define to 1 if you have the declaration of `fdatasync', and to 0 if you + don't. */ +#define HAVE_DECL_FDATASYNC 0 + +/* Define to 1 if you have the declaration of `F_FULLFSYNC', and to 0 if you + don't. */ +#define HAVE_DECL_F_FULLFSYNC 1 + +/* Define to 1 if you have the declaration of + `LLVMCreateGDBRegistrationListener', and to 0 if you don't. */ +/* #undef HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER */ + +/* Define to 1 if you have the declaration of + `LLVMCreatePerfJITEventListener', and to 0 if you don't. */ +/* #undef HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER */ + +/* Define to 1 if you have the declaration of `LLVMGetHostCPUFeatures', and to + 0 if you don't. */ +/* #undef HAVE_DECL_LLVMGETHOSTCPUFEATURES */ + +/* Define to 1 if you have the declaration of `LLVMGetHostCPUName', and to 0 + if you don't. */ +/* #undef HAVE_DECL_LLVMGETHOSTCPUNAME */ + +/* Define to 1 if you have the declaration of `LLVMOrcGetSymbolAddressIn', and + to 0 if you don't. */ +/* #undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN */ + +/* Define to 1 if you have the declaration of `memset_s', and to 0 if you + don't. */ +#define HAVE_DECL_MEMSET_S 1 + +/* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you + don't. */ +#define HAVE_DECL_POSIX_FADVISE 0 + +/* Define to 1 if you have the declaration of `preadv', and to 0 if you don't. + */ +#define HAVE_DECL_PREADV 1 + +/* Define to 1 if you have the declaration of `pwritev', and to 0 if you + don't. */ +#define HAVE_DECL_PWRITEV 1 + +/* Define to 1 if you have the declaration of `strchrnul', and to 0 if you + don't. */ +#define HAVE_DECL_STRCHRNUL 1 + +/* Define to 1 if you have the declaration of `strlcat', and to 0 if you + don't. */ +#define HAVE_DECL_STRLCAT 1 + +/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you + don't. */ +#define HAVE_DECL_STRLCPY 1 + +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +#define HAVE_DECL_STRNLEN 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDITLINE_HISTORY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDITLINE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_EXECINFO_H 1 + +/* Define to 1 if you have the `explicit_bzero' function. */ +/* #undef HAVE_EXPLICIT_BZERO */ + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#define HAVE_FSEEKO 1 + +/* Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int). */ +#define HAVE_GCC__ATOMIC_INT32_CAS 1 + +/* Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, + int64). */ +#define HAVE_GCC__ATOMIC_INT64_CAS 1 + +/* Define to 1 if you have __sync_lock_test_and_set(char *) and friends. */ +#define HAVE_GCC__SYNC_CHAR_TAS 1 + +/* Define to 1 if you have __sync_val_compare_and_swap(int *, int, int). */ +#define HAVE_GCC__SYNC_INT32_CAS 1 + +/* Define to 1 if you have __sync_lock_test_and_set(int *) and friends. */ +#define HAVE_GCC__SYNC_INT32_TAS 1 + +/* Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64). + */ +#define HAVE_GCC__SYNC_INT64_CAS 1 + +/* Define to 1 if you have the `getifaddrs' function. */ +#define HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the `getopt' function. */ +#define HAVE_GETOPT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the `getopt_long' function. */ +#define HAVE_GETOPT_LONG 1 + +/* Define to 1 if you have the `getpeereid' function. */ +#define HAVE_GETPEEREID 1 + +/* Define to 1 if you have the `getpeerucred' function. */ +/* #undef HAVE_GETPEERUCRED */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_EXT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_EXT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_HISTORY_H */ + +/* Define to 1 if you have the `history_truncate_file' function. */ +#define HAVE_HISTORY_TRUNCATE_FILE 1 + +/* Define to 1 if you have the `HMAC_CTX_free' function. */ +#define HAVE_HMAC_CTX_FREE 1 + +/* Define to 1 if you have the `HMAC_CTX_new' function. */ +#define HAVE_HMAC_CTX_NEW 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the `inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if the system has the type `int64'. */ +/* #undef HAVE_INT64 */ + +/* Define to 1 if the system has the type `int8'. */ +/* #undef HAVE_INT8 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the global variable 'int opterr'. */ +#define HAVE_INT_OPTERR 1 + +/* Define to 1 if you have the global variable 'int optreset'. */ +#define HAVE_INT_OPTRESET 1 + +/* Define to 1 if you have the global variable 'int timezone'. */ +#define HAVE_INT_TIMEZONE 1 + +/* Define to 1 if __builtin_constant_p(x) implies "i"(x) acceptance. */ +/* #undef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P */ + +/* Define to 1 if you have the `kqueue' function. */ +#define HAVE_KQUEUE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LANGINFO_H 1 + +/* Define to 1 if you have the `ldap_initialize' function. */ +/* #undef HAVE_LDAP_INITIALIZE */ + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#define HAVE_LIBCRYPTO 1 + +/* Define to 1 if you have the `ldap' library (-lldap). */ +/* #undef HAVE_LIBLDAP */ + +/* Define to 1 if you have the `lz4' library (-llz4). */ +#define HAVE_LIBLZ4 1 + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the `pam' library (-lpam). */ +/* #undef HAVE_LIBPAM */ + +/* Define if you have a function readline library */ +#define HAVE_LIBREADLINE 1 + +/* Define to 1 if you have the `selinux' library (-lselinux). */ +/* #undef HAVE_LIBSELINUX */ + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#define HAVE_LIBSSL 1 + +/* Define to 1 if you have the `wldap32' library (-lwldap32). */ +/* #undef HAVE_LIBWLDAP32 */ + +/* Define to 1 if you have the `xml2' library (-lxml2). */ +/* #undef HAVE_LIBXML2 */ + +/* Define to 1 if you have the `xslt' library (-lxslt). */ +/* #undef HAVE_LIBXSLT */ + +/* Define to 1 if you have the `z' library (-lz). */ +#define HAVE_LIBZ 1 + +/* Define to 1 if you have the `zstd' library (-lzstd). */ +#define HAVE_LIBZSTD 1 + +/* Define to 1 if the system has the type `locale_t'. */ +#define HAVE_LOCALE_T 1 + +/* Define to 1 if `long int' works and is 64 bits. */ +#define HAVE_LONG_INT_64 1 + +/* Define to 1 if `long long int' works and is 64 bits. */ +/* #undef HAVE_LONG_LONG_INT_64 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MBARRIER_H */ + +/* Define to 1 if you have the `mbstowcs_l' function. */ +#define HAVE_MBSTOWCS_L 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mkdtemp' function. */ +#define HAVE_MKDTEMP 1 + +/* Define to 1 if you have the `OPENSSL_init_ssl' function. */ +#define HAVE_OPENSSL_INIT_SSL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OSSP_UUID_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PAM_PAM_APPL_H */ + +/* Define to 1 if you have the `posix_fadvise' function. */ +/* #undef HAVE_POSIX_FADVISE */ + +/* Define to 1 if you have the `posix_fallocate' function. */ +/* #undef HAVE_POSIX_FALLOCATE */ + +/* Define to 1 if you have the `ppoll' function. */ +/* #undef HAVE_PPOLL */ + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the `pthread_barrier_wait' function. */ +/* #undef HAVE_PTHREAD_BARRIER_WAIT */ + +/* Define to 1 if you have the `pthread_is_threaded_np' function. */ +#define HAVE_PTHREAD_IS_THREADED_NP 1 + +/* Have PTHREAD_PRIO_INHERIT. */ +#define HAVE_PTHREAD_PRIO_INHERIT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_READLINE_HISTORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_READLINE_READLINE_H 1 + +/* Define to 1 if you have the `rl_completion_matches' function. */ +#define HAVE_RL_COMPLETION_MATCHES 1 + +/* Define to 1 if you have the global variable 'rl_completion_suppress_quote'. + */ +/* #undef HAVE_RL_COMPLETION_SUPPRESS_QUOTE */ + +/* Define to 1 if you have the `rl_filename_completion_function' function. */ +#define HAVE_RL_FILENAME_COMPLETION_FUNCTION 1 + +/* Define to 1 if you have the global variable 'rl_filename_quote_characters'. + */ +/* #undef HAVE_RL_FILENAME_QUOTE_CHARACTERS */ + +/* Define to 1 if you have the global variable 'rl_filename_quoting_function'. + */ +/* #undef HAVE_RL_FILENAME_QUOTING_FUNCTION */ + +/* Define to 1 if you have the `rl_reset_screen_size' function. */ +/* #undef HAVE_RL_RESET_SCREEN_SIZE */ + +/* Define to 1 if you have the `rl_variable_bind' function. */ +#define HAVE_RL_VARIABLE_BIND 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SECURITY_PAM_APPL_H */ + +/* Define to 1 if you have the `setproctitle' function. */ +/* #undef HAVE_SETPROCTITLE */ + +/* Define to 1 if you have the `setproctitle_fast' function. */ +/* #undef HAVE_SETPROCTITLE_FAST */ + +/* Define to 1 if the system has the type `socklen_t'. */ +#define HAVE_SOCKLEN_T 1 + +/* Define to 1 if you have spinlocks. */ +#define HAVE_SPINLOCKS 1 + +/* Define to 1 if you have the `SSL_CTX_set_cert_cb' function. */ +#define HAVE_SSL_CTX_SET_CERT_CB 1 + +/* Define to 1 if you have the `SSL_CTX_set_num_tickets' function. */ +#define HAVE_SSL_CTX_SET_NUM_TICKETS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +#define HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the `strnlen' function. */ +#define HAVE_STRNLEN 1 + +/* Define to 1 if you have the `strsignal' function. */ +#define HAVE_STRSIGNAL 1 + +/* Define to 1 if the system has the type `struct option'. */ +#define HAVE_STRUCT_OPTION 1 + +/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ +#define HAVE_STRUCT_SOCKADDR_SA_LEN 1 + +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +#define HAVE_STRUCT_TM_TM_ZONE 1 + +/* Define to 1 if you have the `syncfs' function. */ +/* #undef HAVE_SYNCFS */ + +/* Define to 1 if you have the `sync_file_range' function. */ +/* #undef HAVE_SYNC_FILE_RANGE */ + +/* Define to 1 if you have the syslog interface. */ +#define HAVE_SYSLOG 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_EPOLL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_EVENT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PERSONALITY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PROCCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SIGNALFD_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UCRED_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if your compiler understands `typeof' or something similar. */ +#define HAVE_TYPEOF 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UCRED_H */ + +/* Define to 1 if the system has the type `uint64'. */ +/* #undef HAVE_UINT64 */ + +/* Define to 1 if the system has the type `uint8'. */ +/* #undef HAVE_UINT8 */ + +/* Define to 1 if the system has the type `union semun'. */ +#define HAVE_UNION_SEMUN 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `uselocale' function. */ +#define HAVE_USELOCALE 1 + +/* Define to 1 if you have BSD UUID support. */ +/* #undef HAVE_UUID_BSD */ + +/* Define to 1 if you have E2FS UUID support. */ +/* #undef HAVE_UUID_E2FS */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UUID_H */ + +/* Define to 1 if you have OSSP UUID support. */ +/* #undef HAVE_UUID_OSSP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UUID_UUID_H */ + +/* Define to 1 if your compiler knows the visibility("hidden") attribute. */ +#define HAVE_VISIBILITY_ATTRIBUTE 1 + +/* Define to 1 if you have the `wcstombs_l' function. */ +#define HAVE_WCSTOMBS_L 1 + +/* Define to 1 if you have the `X509_get_signature_info' function. */ +#define HAVE_X509_GET_SIGNATURE_INFO 1 + +/* Define to 1 if you have the `X509_get_signature_nid' function. */ +#define HAVE_X509_GET_SIGNATURE_NID 1 + +/* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ +/* #undef HAVE_X86_64_POPCNTQ */ + +/* Define to 1 if your compiler understands __builtin_bswap16. */ +#define HAVE__BUILTIN_BSWAP16 1 + +/* Define to 1 if your compiler understands __builtin_bswap32. */ +#define HAVE__BUILTIN_BSWAP32 1 + +/* Define to 1 if your compiler understands __builtin_bswap64. */ +#define HAVE__BUILTIN_BSWAP64 1 + +/* Define to 1 if your compiler understands __builtin_clz. */ +#define HAVE__BUILTIN_CLZ 1 + +/* Define to 1 if your compiler understands __builtin_constant_p. */ +#define HAVE__BUILTIN_CONSTANT_P 1 + +/* Define to 1 if your compiler understands __builtin_ctz. */ +#define HAVE__BUILTIN_CTZ 1 + +/* Define to 1 if your compiler understands __builtin_frame_address. */ +#define HAVE__BUILTIN_FRAME_ADDRESS 1 + +/* Define to 1 if your compiler understands __builtin_$op_overflow. */ +#define HAVE__BUILTIN_OP_OVERFLOW 1 + +/* Define to 1 if your compiler understands __builtin_popcount. */ +#define HAVE__BUILTIN_POPCOUNT 1 + +/* Define to 1 if your compiler understands __builtin_types_compatible_p. */ +#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1 + +/* Define to 1 if your compiler understands __builtin_unreachable. */ +#define HAVE__BUILTIN_UNREACHABLE 1 + +/* Define to 1 if you have the `_configthreadlocale' function. */ +/* #undef HAVE__CONFIGTHREADLOCALE */ + +/* Define to 1 if you have __cpuid. */ +/* #undef HAVE__CPUID */ + +/* Define to 1 if you have __get_cpuid. */ +/* #undef HAVE__GET_CPUID */ + +/* Define to 1 if your compiler understands _Static_assert. */ +#define HAVE__STATIC_ASSERT 1 + +/* Define to the appropriate printf length modifier for 64-bit ints. */ +#define INT64_MODIFIER "l" + +/* Define to 1 if `locale_t' requires . */ +/* #undef LOCALE_T_IN_XLOCALE */ + +/* Define as the maximum alignment requirement of any C data type. */ +#define MAXIMUM_ALIGNOF 8 + +/* Define bytes to use libc memset(). */ +#define MEMSET_LOOP_LIMIT 1024 + +/* Define to the OpenSSL API version in use. This avoids deprecation warnings + from newer OpenSSL versions. */ +#define OPENSSL_API_COMPAT 0x10001000L + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "pgsql-bugs@lists.postgresql.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "PostgreSQL" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "PostgreSQL 16.13" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "postgresql" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "https://www.postgresql.org/" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "16.13" + +/* Define to the name of a signed 128-bit integer type. */ +#define PG_INT128_TYPE __int128 + +/* Define to the name of a signed 64-bit integer type. */ +#define PG_INT64_TYPE long int + +/* Define to the name of the default PostgreSQL service principal in Kerberos + (GSSAPI). (--with-krb-srvnam=NAME) */ +#define PG_KRB_SRVNAM "postgres" + +/* PostgreSQL major version as a string */ +#define PG_MAJORVERSION "16" + +/* PostgreSQL major version number */ +#define PG_MAJORVERSION_NUM 16 + +/* PostgreSQL minor version number */ +#define PG_MINORVERSION_NUM 13 + +/* Define to best printf format archetype, usually gnu_printf if available. */ +#define PG_PRINTF_ATTRIBUTE __syslog__ + +/* Define to 1 to use to define type bool. */ +#define PG_USE_STDBOOL 1 + +/* PostgreSQL version as a string */ +#define PG_VERSION "16.13" + +/* PostgreSQL version as a number */ +#define PG_VERSION_NUM 160013 + +/* A string containing the version number, platform, and C compiler */ +#define PG_VERSION_STR "PostgreSQL 16.13 on aarch64-apple-darwin25.4.0, compiled by Apple clang version 21.0.0 (clang-2100.0.123.102), 64-bit" + +/* Define to 1 to allow profiling output to be saved separately for each + process. */ +/* #undef PROFILE_PID_DIR */ + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* RELSEG_SIZE is the maximum number of blocks allowed in one disk file. Thus, + the maximum size of a single file is RELSEG_SIZE * BLCKSZ; relations bigger + than that are divided into multiple files. RELSEG_SIZE * BLCKSZ must be + less than your OS' limit on file size. This is often 2 GB or 4GB in a + 32-bit operating system, unless you have large file support enabled. By + default, we make the limit 1 GB to avoid any possible integer-overflow + problems within the OS. A limit smaller than necessary only means we divide + a large relation into more chunks than necessary, so it seems best to err + in the direction of a small limit. A power-of-2 value is recommended to + save a few cycles in md.c, but is not absolutely required. Changing + RELSEG_SIZE requires an initdb. */ +#define RELSEG_SIZE 131072 + +/* The size of `bool', as computed by sizeof. */ +#define SIZEOF_BOOL 1 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* The size of `off_t', as computed by sizeof. */ +#define SIZEOF_OFF_T 8 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 8 + +/* The size of `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 8 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if strerror_r() returns int. */ +#define STRERROR_R_INT 1 + +/* Define to 1 to use ARMv8 CRC Extension. */ +#define USE_ARMV8_CRC32C 1 + +/* Define to 1 to use ARMv8 CRC Extension with a runtime check. */ +/* #undef USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK */ + +/* Define to 1 to build with assertion checks. (--enable-cassert) */ +#define USE_ASSERT_CHECKING 1 + +/* PGRAC: Define to 1 to build test-only injection helpers. (--enable-injection-points) */ +#define ENABLE_INJECTION 1 + +/* Define to 1 to build with Bonjour support. (--with-bonjour) */ +/* #undef USE_BONJOUR */ + +/* PGRAC: Define to 1 to build pgrac cluster subsystem. (--enable-cluster) */ +#define USE_PGRAC_CLUSTER 1 + +/* Define to 1 to build with BSD Authentication support. (--with-bsd-auth) */ +/* #undef USE_BSD_AUTH */ + +/* Define to build with ICU support. (--with-icu) */ +#define USE_ICU 1 + +/* Define to 1 to build with LDAP support. (--with-ldap) */ +/* #undef USE_LDAP */ + +/* Define to 1 to build with XML support. (--with-libxml) */ +/* #undef USE_LIBXML */ + +/* Define to 1 to use XSLT support when building contrib/xml2. + (--with-libxslt) */ +/* #undef USE_LIBXSLT */ + +/* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ +/* #undef USE_LLVM */ + +/* Define to 1 to build with LZ4 support. (--with-lz4) */ +#define USE_LZ4 1 + +/* Define to select named POSIX semaphores. */ +/* #undef USE_NAMED_POSIX_SEMAPHORES */ + +/* Define to 1 to build with OpenSSL support. (--with-ssl=openssl) */ +#define USE_OPENSSL 1 + +/* Define to 1 to build with PAM support. (--with-pam) */ +/* #undef USE_PAM */ + +/* Define to 1 to use software CRC-32C implementation (slicing-by-8). */ +/* #undef USE_SLICING_BY_8_CRC32C */ + +/* Define to 1 use Intel SSE 4.2 CRC instructions. */ +/* #undef USE_SSE42_CRC32C */ + +/* Define to 1 to use Intel SSE 4.2 CRC instructions with a runtime check. */ +/* #undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK */ + +/* Define to build with systemd support. (--with-systemd) */ +/* #undef USE_SYSTEMD */ + +/* Define to select SysV-style semaphores. */ +#define USE_SYSV_SEMAPHORES 1 + +/* Define to select SysV-style shared memory. */ +#define USE_SYSV_SHARED_MEMORY 1 + +/* Define to select unnamed POSIX semaphores. */ +/* #undef USE_UNNAMED_POSIX_SEMAPHORES */ + +/* Define to select Win32-style semaphores. */ +/* #undef USE_WIN32_SEMAPHORES */ + +/* Define to select Win32-style shared memory. */ +/* #undef USE_WIN32_SHARED_MEMORY */ + +/* Define to 1 to build with ZSTD support. (--with-zstd) */ +#define USE_ZSTD 1 + +/* Define to 1 if `wcstombs_l' requires . */ +#define WCSTOMBS_L_IN_XLOCALE 1 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Size of a WAL file block. This need have no particular relation to BLCKSZ. + XLOG_BLCKSZ must be a power of 2, and if your system supports O_DIRECT I/O, + XLOG_BLCKSZ must be a multiple of the alignment requirement for direct-I/O + buffers, else direct I/O may fail. Changing XLOG_BLCKSZ requires an initdb. + */ +#define XLOG_BLCKSZ 8192 + + + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* #undef _LARGEFILE_SOURCE */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to keyword to use for C99 restrict support, or to nothing if not + supported */ +#define pg_restrict __restrict + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#define restrict __restrict +/* Work around a bug in Sun C++: it does not support _Restrict or + __restrict__, even though the corresponding Sun C compiler ends up with + "#define restrict _Restrict" or "#define restrict __restrict__" in the + previous line. Perhaps some future version of Sun C++ will work with + restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ +#if defined __SUNPRO_CC && !defined __RESTRICT +# define _Restrict +# define __restrict__ +#endif + +/* Define to how the compiler spells `typeof'. */ +/* #undef typeof */ diff --git a/install/include/pg_config_ext.h b/install/include/pg_config_ext.h new file mode 100644 index 00000000000..b4c07dd8572 --- /dev/null +++ b/install/include/pg_config_ext.h @@ -0,0 +1,8 @@ +/* src/include/pg_config_ext.h. Generated from pg_config_ext.h.in by configure. */ +/* + * src/include/pg_config_ext.h.in. This is generated manually, not by + * autoheader, since we want to limit which symbols get defined here. + */ + +/* Define to the name of a signed 64-bit integer type. */ +#define PG_INT64_TYPE long int diff --git a/install/include/pg_config_manual.h b/install/include/pg_config_manual.h new file mode 100644 index 00000000000..a1a93ad706e --- /dev/null +++ b/install/include/pg_config_manual.h @@ -0,0 +1,372 @@ +/*------------------------------------------------------------------------ + * PostgreSQL manual configuration settings + * + * This file contains various configuration symbols and limits. In + * all cases, changing them is only useful in very rare situations or + * for developers. If you edit any of these, be sure to do a *full* + * rebuild (and an initdb if noted). + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/pg_config_manual.h + *------------------------------------------------------------------------ + */ + +/* + * This is the default value for wal_segment_size to be used when initdb is run + * without the --wal-segsize option. It must be a valid segment size. + */ +#define DEFAULT_XLOG_SEG_SIZE (16*1024*1024) + +/* + * Maximum length for identifiers (e.g. table names, column names, + * function names). Names actually are limited to one fewer byte than this, + * because the length must include a trailing zero byte. + * + * Changing this requires an initdb. + */ +#define NAMEDATALEN 64 + +/* + * Maximum number of arguments to a function. + * + * The minimum value is 8 (GIN indexes use 8-argument support functions). + * The maximum possible value is around 600 (limited by index tuple size in + * pg_proc's index; BLCKSZ larger than 8K would allow more). Values larger + * than needed will waste memory and processing time, but do not directly + * cost disk space. + * + * Changing this does not require an initdb, but it does require a full + * backend recompile (including any user-defined C functions). + */ +#define FUNC_MAX_ARGS 100 + +/* + * When creating a product derived from PostgreSQL with changes that cause + * incompatibilities for loadable modules, it is recommended to change this + * string so that dfmgr.c can refuse to load incompatible modules with a clean + * error message. Typical examples that cause incompatibilities are any + * changes to node tags or node structures. (Note that dfmgr.c already + * detects common sources of incompatibilities due to major version + * differences and due to some changed compile-time constants. This setting + * is for catching anything that cannot be detected in a straightforward way.) + * + * There is no prescribed format for the string. The suggestion is to include + * product or company name, and optionally any internally-relevant ABI + * version. Example: "ACME Postgres/1.2". Note that the string will appear + * in a user-facing error message if an ABI mismatch is detected. + */ +#define FMGR_ABI_EXTRA "PostgreSQL" + +/* + * Maximum number of columns in an index. There is little point in making + * this anything but a multiple of 32, because the main cost is associated + * with index tuple header size (see access/itup.h). + * + * Changing this requires an initdb. + */ +#define INDEX_MAX_KEYS 32 + +/* + * Maximum number of columns in a partition key + */ +#define PARTITION_MAX_KEYS 32 + +/* + * Decide whether built-in 8-byte types, including float8, int8, and + * timestamp, are passed by value. This is on by default if sizeof(Datum) >= + * 8 (that is, on 64-bit platforms). If sizeof(Datum) < 8 (32-bit platforms), + * this must be off. We keep this here as an option so that it is easy to + * test the pass-by-reference code paths on 64-bit platforms. + * + * Changing this requires an initdb. + */ +#if SIZEOF_VOID_P >= 8 +#define USE_FLOAT8_BYVAL 1 +#endif + +/* + * When we don't have native spinlocks, we use semaphores to simulate them. + * Decreasing this value reduces consumption of OS resources; increasing it + * may improve performance, but supplying a real spinlock implementation is + * probably far better. + */ +#define NUM_SPINLOCK_SEMAPHORES 128 + +/* + * When we have neither spinlocks nor atomic operations support we're + * implementing atomic operations on top of spinlock on top of semaphores. To + * be safe against atomic operations while holding a spinlock separate + * semaphores have to be used. + */ +#define NUM_ATOMICS_SEMAPHORES 64 + +/* + * MAXPGPATH: standard size of a pathname buffer in PostgreSQL (hence, + * maximum usable pathname length is one less). + * + * We'd use a standard system header symbol for this, if there weren't + * so many to choose from: MAXPATHLEN, MAX_PATH, PATH_MAX are all + * defined by different "standards", and often have different values + * on the same platform! So we just punt and use a reasonably + * generous setting here. + */ +#define MAXPGPATH 1024 + +/* + * You can try changing this if you have a machine with bytes of + * another size, but no guarantee... + */ +#define BITS_PER_BYTE 8 + +/* + * Preferred alignment for disk I/O buffers. On some CPUs, copies between + * user space and kernel space are significantly faster if the user buffer + * is aligned on a larger-than-MAXALIGN boundary. Ideally this should be + * a platform-dependent value, but for now we just hard-wire it. + */ +#define ALIGNOF_BUFFER 32 + +/* + * If EXEC_BACKEND is defined, the postmaster uses an alternative method for + * starting subprocesses: Instead of simply using fork(), as is standard on + * Unix platforms, it uses fork()+exec() or something equivalent on Windows, + * as well as lots of extra code to bring the required global state to those + * new processes. This must be enabled on Windows (because there is no + * fork()). On other platforms, it's only useful for verifying those + * otherwise Windows-specific code paths. + */ +#if defined(WIN32) && !defined(__CYGWIN__) +#define EXEC_BACKEND +#endif + +/* + * USE_POSIX_FADVISE controls whether Postgres will attempt to use the + * posix_fadvise() kernel call. Usually the automatic configure tests are + * sufficient, but some older Linux distributions had broken versions of + * posix_fadvise(). If necessary you can remove the #define here. + */ +#if HAVE_DECL_POSIX_FADVISE && defined(HAVE_POSIX_FADVISE) +#define USE_POSIX_FADVISE +#endif + +/* + * USE_PREFETCH code should be compiled only if we have a way to implement + * prefetching. (This is decoupled from USE_POSIX_FADVISE because there + * might in future be support for alternative low-level prefetch APIs. + * If you change this, you probably need to adjust the error message in + * check_effective_io_concurrency.) + */ +#ifdef USE_POSIX_FADVISE +#define USE_PREFETCH +#endif + +/* + * Default and maximum values for backend_flush_after, bgwriter_flush_after + * and checkpoint_flush_after; measured in blocks. Currently, these are + * enabled by default if sync_file_range() exists, ie, only on Linux. Perhaps + * we could also enable by default if we have mmap and msync(MS_ASYNC)? + */ +#ifdef HAVE_SYNC_FILE_RANGE +#define DEFAULT_BACKEND_FLUSH_AFTER 0 /* never enabled by default */ +#define DEFAULT_BGWRITER_FLUSH_AFTER 64 +#define DEFAULT_CHECKPOINT_FLUSH_AFTER 32 +#else +#define DEFAULT_BACKEND_FLUSH_AFTER 0 +#define DEFAULT_BGWRITER_FLUSH_AFTER 0 +#define DEFAULT_CHECKPOINT_FLUSH_AFTER 0 +#endif +/* upper limit for all three variables */ +#define WRITEBACK_MAX_PENDING_FLUSHES 256 + +/* + * USE_SSL code should be compiled only when compiling with an SSL + * implementation. + */ +#ifdef USE_OPENSSL +#define USE_SSL +#endif + +/* + * This is the default directory in which AF_UNIX socket files are + * placed. Caution: changing this risks breaking your existing client + * applications, which are likely to continue to look in the old + * directory. But if you just hate the idea of sockets in /tmp, + * here's where to twiddle it. You can also override this at runtime + * with the postmaster's -k switch. + * + * If set to an empty string, then AF_UNIX sockets are not used by default: A + * server will not create an AF_UNIX socket unless the run-time configuration + * is changed, a client will connect via TCP/IP by default and will only use + * an AF_UNIX socket if one is explicitly specified. + * + * This is done by default on Windows because there is no good standard + * location for AF_UNIX sockets and many installations on Windows don't + * support them yet. + */ +#ifndef WIN32 +#define DEFAULT_PGSOCKET_DIR "/tmp" +#else +#define DEFAULT_PGSOCKET_DIR "" +#endif + +/* + * This is the default event source for Windows event log. + */ +#define DEFAULT_EVENT_SOURCE "PostgreSQL" + +/* + * Assumed cache line size. This doesn't affect correctness, but can be used + * for low-level optimizations. Currently, this is used to pad some data + * structures in xlog.c, to ensure that highly-contended fields are on + * different cache lines. Too small a value can hurt performance due to false + * sharing, while the only downside of too large a value is a few bytes of + * wasted memory. The default is 128, which should be large enough for all + * supported platforms. + */ +#define PG_CACHE_LINE_SIZE 128 + +/* + * Assumed alignment requirement for direct I/O. 4K corresponds to common + * sector and memory page size. + */ +#define PG_IO_ALIGN_SIZE 4096 + +/* + *------------------------------------------------------------------------ + * The following symbols are for enabling debugging code, not for + * controlling user-visible features or resource limits. + *------------------------------------------------------------------------ + */ + +/* + * Include Valgrind "client requests", mostly in the memory allocator, so + * Valgrind understands PostgreSQL memory contexts. This permits detecting + * memory errors that Valgrind would not detect on a vanilla build. It also + * enables detection of buffer accesses that take place without holding a + * buffer pin (or without holding a buffer lock in the case of index access + * methods that superimpose their own custom client requests on top of the + * generic bufmgr.c requests). + * + * "make installcheck" is significantly slower under Valgrind. The client + * requests fall in hot code paths, so USE_VALGRIND slows execution by a few + * percentage points even when not run under Valgrind. + * + * Do not try to test the server under Valgrind without having built the + * server with USE_VALGRIND; else you will get false positives from sinval + * messaging (see comments in AddCatcacheInvalidationMessage). It's also + * important to use the suppression file src/tools/valgrind.supp to + * exclude other known false positives. + * + * You should normally use MEMORY_CONTEXT_CHECKING with USE_VALGRIND; + * instrumentation of repalloc() is inferior without it. + */ +/* #define USE_VALGRIND */ + +/* + * Define this to cause pfree()'d memory to be cleared immediately, to + * facilitate catching bugs that refer to already-freed values. + * Right now, this gets defined automatically if --enable-cassert. + */ +#ifdef USE_ASSERT_CHECKING +#define CLOBBER_FREED_MEMORY +#endif + +/* + * Define this to check memory allocation errors (scribbling on more + * bytes than were allocated). Right now, this gets defined + * automatically if --enable-cassert or USE_VALGRIND. + */ +#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND) +#define MEMORY_CONTEXT_CHECKING +#endif + +/* + * Define this to cause palloc()'d memory to be filled with random data, to + * facilitate catching code that depends on the contents of uninitialized + * memory. Caution: this is horrendously expensive. + */ +/* #define RANDOMIZE_ALLOCATED_MEMORY */ + +/* + * For cache-invalidation debugging, define DISCARD_CACHES_ENABLED to enable + * use of the debug_discard_caches GUC to aggressively flush syscache/relcache + * entries whenever it's possible to deliver invalidations. See + * AcceptInvalidationMessages() in src/backend/utils/cache/inval.c for + * details. + * + * USE_ASSERT_CHECKING builds default to enabling this. It's possible to use + * DISCARD_CACHES_ENABLED without a cassert build and the implied + * CLOBBER_FREED_MEMORY and MEMORY_CONTEXT_CHECKING options, but it's unlikely + * to be as effective at identifying problems. + */ +/* #define DISCARD_CACHES_ENABLED */ + +#if defined(USE_ASSERT_CHECKING) && !defined(DISCARD_CACHES_ENABLED) +#define DISCARD_CACHES_ENABLED +#endif + +/* + * Backwards compatibility for the older compile-time-only clobber-cache + * macros. + */ +#if !defined(DISCARD_CACHES_ENABLED) && (defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY)) +#define DISCARD_CACHES_ENABLED +#endif + +/* + * Recover memory used for relcache entries when invalidated. See + * RelationBuildDesc() in src/backend/utils/cache/relcache.c. + * + * This is active automatically for clobber-cache builds when clobbering is + * active, but can be overridden here by explicitly defining + * RECOVER_RELATION_BUILD_MEMORY. Define to 1 to always free relation cache + * memory even when clobber is off, or to 0 to never free relation cache + * memory even when clobbering is on. + */ + /* #define RECOVER_RELATION_BUILD_MEMORY 0 */ /* Force disable */ + /* #define RECOVER_RELATION_BUILD_MEMORY 1 */ /* Force enable */ + +/* + * Define this to force all parse and plan trees to be passed through + * copyObject(), to facilitate catching errors and omissions in + * copyObject(). + */ +/* #define COPY_PARSE_PLAN_TREES */ + +/* + * Define this to force all parse and plan trees to be passed through + * outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in + * those modules. + */ +/* #define WRITE_READ_PARSE_PLAN_TREES */ + +/* + * Define this to force all raw parse trees for DML statements to be scanned + * by raw_expression_tree_walker(), to facilitate catching errors and + * omissions in that function. + */ +/* #define RAW_EXPRESSION_COVERAGE_TEST */ + +/* + * Enable debugging print statements for lock-related operations. + */ +/* #define LOCK_DEBUG */ + +/* + * Enable debugging print statements for WAL-related operations; see + * also the wal_debug GUC var. + */ +/* #define WAL_DEBUG */ + +/* + * Enable tracing of resource consumption during sort operations; + * see also the trace_sort GUC var. For 8.1 this is enabled by default. + */ +#define TRACE_SORT 1 + +/* + * Enable tracing of syncscan operations (see also the trace_syncscan GUC var). + */ +/* #define TRACE_SYNCSCAN */ diff --git a/install/include/pg_config_os.h b/install/include/pg_config_os.h new file mode 100644 index 00000000000..15fb69d6dbb --- /dev/null +++ b/install/include/pg_config_os.h @@ -0,0 +1,8 @@ +/* src/include/port/darwin.h */ + +#define __darwin__ 1 + +#if HAVE_DECL_F_FULLFSYNC /* not present before macOS 10.3 */ +#define HAVE_FSYNC_WRITETHROUGH + +#endif diff --git a/install/include/pgtypes.h b/install/include/pgtypes.h new file mode 100644 index 00000000000..dbf759b45f5 --- /dev/null +++ b/install/include/pgtypes.h @@ -0,0 +1,17 @@ +/* src/interfaces/ecpg/include/pgtypes.h */ + +#ifndef PGTYPES_H +#define PGTYPES_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern void PGTYPESchar_free(char *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* PGTYPES_H */ diff --git a/install/include/pgtypes_date.h b/install/include/pgtypes_date.h new file mode 100644 index 00000000000..5490cf8217d --- /dev/null +++ b/install/include/pgtypes_date.h @@ -0,0 +1,32 @@ +/* src/interfaces/ecpg/include/pgtypes_date.h */ + +#ifndef PGTYPES_DATETIME +#define PGTYPES_DATETIME + +#include +#include + +typedef long date; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern date * PGTYPESdate_new(void); +extern void PGTYPESdate_free(date * d); +extern date PGTYPESdate_from_asc(char *str, char **endptr); +extern char *PGTYPESdate_to_asc(date dDate); +extern date PGTYPESdate_from_timestamp(timestamp dt); +extern void PGTYPESdate_julmdy(date jd, int *mdy); +extern void PGTYPESdate_mdyjul(int *mdy, date * jdate); +extern int PGTYPESdate_dayofweek(date dDate); +extern void PGTYPESdate_today(date * d); +extern int PGTYPESdate_defmt_asc(date * d, const char *fmt, const char *str); +extern int PGTYPESdate_fmt_asc(date dDate, const char *fmtstring, char *outbuf); + +#ifdef __cplusplus +} +#endif + +#endif /* PGTYPES_DATETIME */ diff --git a/install/include/pgtypes_error.h b/install/include/pgtypes_error.h new file mode 100644 index 00000000000..9fc22a26aaf --- /dev/null +++ b/install/include/pgtypes_error.h @@ -0,0 +1,18 @@ +/* src/interfaces/ecpg/include/pgtypes_error.h */ + +#define PGTYPES_NUM_OVERFLOW 301 +#define PGTYPES_NUM_BAD_NUMERIC 302 +#define PGTYPES_NUM_DIVIDE_ZERO 303 +#define PGTYPES_NUM_UNDERFLOW 304 + +#define PGTYPES_DATE_BAD_DATE 310 +#define PGTYPES_DATE_ERR_EARGS 311 +#define PGTYPES_DATE_ERR_ENOSHORTDATE 312 +#define PGTYPES_DATE_ERR_ENOTDMY 313 +#define PGTYPES_DATE_BAD_DAY 314 +#define PGTYPES_DATE_BAD_MONTH 315 + +#define PGTYPES_TS_BAD_TIMESTAMP 320 +#define PGTYPES_TS_ERR_EINFTIME 321 + +#define PGTYPES_INTVL_BAD_INTERVAL 330 diff --git a/install/include/pgtypes_interval.h b/install/include/pgtypes_interval.h new file mode 100644 index 00000000000..2809b356f73 --- /dev/null +++ b/install/include/pgtypes_interval.h @@ -0,0 +1,48 @@ +/* src/interfaces/ecpg/include/pgtypes_interval.h */ + +#ifndef PGTYPES_INTERVAL +#define PGTYPES_INTERVAL + +#include +#include + +#ifndef C_H + +#ifdef HAVE_LONG_INT_64 +#ifndef HAVE_INT64 +typedef long int int64; +#endif +#elif defined(HAVE_LONG_LONG_INT_64) +#ifndef HAVE_INT64 +typedef long long int int64; +#endif +#else +/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ +#error must have a working 64-bit integer datatype +#endif + +#define HAVE_INT64_TIMESTAMP +#endif /* C_H */ + +typedef struct +{ + int64 time; /* all time units other than months and years */ + long month; /* months and years, after time for alignment */ +} interval; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern interval * PGTYPESinterval_new(void); +extern void PGTYPESinterval_free(interval * intvl); +extern interval * PGTYPESinterval_from_asc(char *str, char **endptr); +extern char *PGTYPESinterval_to_asc(interval * span); +extern int PGTYPESinterval_copy(interval * intvlsrc, interval * intvldest); + +#ifdef __cplusplus +} +#endif + +#endif /* PGTYPES_INTERVAL */ diff --git a/install/include/pgtypes_numeric.h b/install/include/pgtypes_numeric.h new file mode 100644 index 00000000000..61506f44ca8 --- /dev/null +++ b/install/include/pgtypes_numeric.h @@ -0,0 +1,69 @@ +#ifndef PGTYPES_NUMERIC +#define PGTYPES_NUMERIC + +#include + +#define NUMERIC_POS 0x0000 +#define NUMERIC_NEG 0x4000 +#define NUMERIC_NAN 0xC000 +#define NUMERIC_NULL 0xF000 +#define NUMERIC_MAX_PRECISION 1000 +#define NUMERIC_MAX_DISPLAY_SCALE NUMERIC_MAX_PRECISION +#define NUMERIC_MIN_DISPLAY_SCALE 0 +#define NUMERIC_MIN_SIG_DIGITS 16 + +#define DECSIZE 30 + +typedef unsigned char NumericDigit; +typedef struct +{ + int ndigits; /* number of digits in digits[] - can be 0! */ + int weight; /* weight of first digit */ + int rscale; /* result scale */ + int dscale; /* display scale */ + int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */ + NumericDigit *buf; /* start of alloc'd space for digits[] */ + NumericDigit *digits; /* decimal digits */ +} numeric; + +typedef struct +{ + int ndigits; /* number of digits in digits[] - can be 0! */ + int weight; /* weight of first digit */ + int rscale; /* result scale */ + int dscale; /* display scale */ + int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */ + NumericDigit digits[DECSIZE]; /* decimal digits */ +} decimal; + +#ifdef __cplusplus +extern "C" +{ +#endif + +numeric *PGTYPESnumeric_new(void); +decimal *PGTYPESdecimal_new(void); +void PGTYPESnumeric_free(numeric *var); +void PGTYPESdecimal_free(decimal *var); +numeric *PGTYPESnumeric_from_asc(char *str, char **endptr); +char *PGTYPESnumeric_to_asc(numeric *num, int dscale); +int PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result); +int PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result); +int PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result); +int PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result); +int PGTYPESnumeric_cmp(numeric *var1, numeric *var2); +int PGTYPESnumeric_from_int(signed int int_val, numeric *var); +int PGTYPESnumeric_from_long(signed long int long_val, numeric *var); +int PGTYPESnumeric_copy(numeric *src, numeric *dst); +int PGTYPESnumeric_from_double(double d, numeric *dst); +int PGTYPESnumeric_to_double(numeric *nv, double *dp); +int PGTYPESnumeric_to_int(numeric *nv, int *ip); +int PGTYPESnumeric_to_long(numeric *nv, long *lp); +int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst); +int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst); + +#ifdef __cplusplus +} +#endif + +#endif /* PGTYPES_NUMERIC */ diff --git a/install/include/pgtypes_timestamp.h b/install/include/pgtypes_timestamp.h new file mode 100644 index 00000000000..412ecc2d411 --- /dev/null +++ b/install/include/pgtypes_timestamp.h @@ -0,0 +1,31 @@ +/* src/interfaces/ecpg/include/pgtypes_timestamp.h */ + +#ifndef PGTYPES_TIMESTAMP +#define PGTYPES_TIMESTAMP + +#include +/* pgtypes_interval.h includes ecpg_config.h */ +#include + +typedef int64 timestamp; +typedef int64 TimestampTz; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr); +extern char *PGTYPEStimestamp_to_asc(timestamp tstamp); +extern int PGTYPEStimestamp_sub(timestamp * ts1, timestamp * ts2, interval * iv); +extern int PGTYPEStimestamp_fmt_asc(timestamp * ts, char *output, int str_len, const char *fmtstr); +extern void PGTYPEStimestamp_current(timestamp * ts); +extern int PGTYPEStimestamp_defmt_asc(const char *str, const char *fmt, timestamp * d); +extern int PGTYPEStimestamp_add_interval(timestamp * tin, interval * span, timestamp * tout); +extern int PGTYPEStimestamp_sub_interval(timestamp * tin, interval * span, timestamp * tout); + +#ifdef __cplusplus +} +#endif + +#endif /* PGTYPES_TIMESTAMP */ diff --git a/install/include/postgres_ext.h b/install/include/postgres_ext.h new file mode 100644 index 00000000000..240ad4e93bf --- /dev/null +++ b/install/include/postgres_ext.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * postgres_ext.h + * + * This file contains declarations of things that are visible everywhere + * in PostgreSQL *and* are visible to clients of frontend interface libraries. + * For example, the Oid type is part of the API of libpq and other libraries. + * + * Declarations which are specific to a particular interface should + * go in the header file for that interface (such as libpq-fe.h). This + * file is only for fundamental Postgres declarations. + * + * User-written C functions don't count as "external to Postgres." + * Those function much as local modifications to the backend itself, and + * use header files that are otherwise internal to Postgres to interface + * with the backend. + * + * src/include/postgres_ext.h + * + *------------------------------------------------------------------------- + */ + +#ifndef POSTGRES_EXT_H +#define POSTGRES_EXT_H + +#include "pg_config_ext.h" + +/* + * Object ID is a fundamental type in Postgres. + */ +typedef unsigned int Oid; + +#ifdef __cplusplus +#define InvalidOid (Oid(0)) +#else +#define InvalidOid ((Oid) 0) +#endif + +#define OID_MAX UINT_MAX +/* you will need to include to use the above #define */ + +#define atooid(x) ((Oid) strtoul((x), NULL, 10)) +/* the above needs */ + + +/* Define a signed 64-bit integer type for use in client API declarations. */ +typedef PG_INT64_TYPE pg_int64; + +/* + * Identifiers of error message fields. Kept here to keep common + * between frontend and backend, and also to export them to libpq + * applications. + */ +#define PG_DIAG_SEVERITY 'S' +#define PG_DIAG_SEVERITY_NONLOCALIZED 'V' +#define PG_DIAG_SQLSTATE 'C' +#define PG_DIAG_MESSAGE_PRIMARY 'M' +#define PG_DIAG_MESSAGE_DETAIL 'D' +#define PG_DIAG_MESSAGE_HINT 'H' +#define PG_DIAG_STATEMENT_POSITION 'P' +#define PG_DIAG_INTERNAL_POSITION 'p' +#define PG_DIAG_INTERNAL_QUERY 'q' +#define PG_DIAG_CONTEXT 'W' +#define PG_DIAG_SCHEMA_NAME 's' +#define PG_DIAG_TABLE_NAME 't' +#define PG_DIAG_COLUMN_NAME 'c' +#define PG_DIAG_DATATYPE_NAME 'd' +#define PG_DIAG_CONSTRAINT_NAME 'n' +#define PG_DIAG_SOURCE_FILE 'F' +#define PG_DIAG_SOURCE_LINE 'L' +#define PG_DIAG_SOURCE_FUNCTION 'R' + +#endif /* POSTGRES_EXT_H */ diff --git a/install/include/postgresql/informix/esql/datetime.h b/install/include/postgresql/informix/esql/datetime.h new file mode 100644 index 00000000000..44b24227e55 --- /dev/null +++ b/install/include/postgresql/informix/esql/datetime.h @@ -0,0 +1,14 @@ +/* src/interfaces/ecpg/include/datetime.h */ + +#ifndef _ECPG_DATETIME_H +#define _ECPG_DATETIME_H + +#include + +/* source created by ecpg which defines these symbols */ +#ifndef _ECPGLIB_H +typedef timestamp dtime_t; +typedef interval intrvl_t; +#endif /* ndef _ECPGLIB_H */ + +#endif /* ndef _ECPG_DATETIME_H */ diff --git a/install/include/postgresql/informix/esql/decimal.h b/install/include/postgresql/informix/esql/decimal.h new file mode 100644 index 00000000000..6ac29625304 --- /dev/null +++ b/install/include/postgresql/informix/esql/decimal.h @@ -0,0 +1,13 @@ +/* src/interfaces/ecpg/include/decimal.h */ + +#ifndef _ECPG_DECIMAL_H +#define _ECPG_DECIMAL_H + +#include + +/* source created by ecpg which defines this */ +#ifndef _ECPGLIB_H +typedef decimal dec_t; +#endif /* ndef _ECPGLIB_H */ + +#endif /* ndef _ECPG_DECIMAL_H */ diff --git a/install/include/postgresql/informix/esql/sqltypes.h b/install/include/postgresql/informix/esql/sqltypes.h new file mode 100644 index 00000000000..e7cbfa47956 --- /dev/null +++ b/install/include/postgresql/informix/esql/sqltypes.h @@ -0,0 +1,57 @@ +#ifndef ECPG_SQLTYPES_H +#define ECPG_SQLTYPES_H + +#include + +#define CCHARTYPE ECPGt_char +#define CSHORTTYPE ECPGt_short +#define CINTTYPE ECPGt_int +#define CLONGTYPE ECPGt_long +#define CFLOATTYPE ECPGt_float +#define CDOUBLETYPE ECPGt_double +#define CDECIMALTYPE ECPGt_decimal +#define CFIXCHARTYPE 108 +#define CSTRINGTYPE ECPGt_char +#define CDATETYPE ECPGt_date +#define CMONEYTYPE 111 +#define CDTIMETYPE ECPGt_timestamp +#define CLOCATORTYPE 113 +#define CVCHARTYPE ECPGt_varchar +#define CINVTYPE 115 +#define CFILETYPE 116 +#define CINT8TYPE ECPGt_long_long +#define CCOLLTYPE 118 +#define CLVCHARTYPE 119 +#define CFIXBINTYPE 120 +#define CVARBINTYPE 121 +#define CBOOLTYPE ECPGt_bool +#define CROWTYPE 123 +#define CLVCHARPTRTYPE 124 +#define CTYPEMAX 25 + +/* + * Values used in sqlda->sqlvar[i]->sqltype + */ +#define SQLCHAR ECPGt_char +#define SQLSMINT ECPGt_short +#define SQLINT ECPGt_int +#define SQLFLOAT ECPGt_double +#define SQLSMFLOAT ECPGt_float +#define SQLDECIMAL ECPGt_decimal +#define SQLSERIAL ECPGt_int +#define SQLDATE ECPGt_date +#define SQLDTIME ECPGt_timestamp +#define SQLTEXT ECPGt_char +#define SQLVCHAR ECPGt_char +#define SQLINTERVAL ECPGt_interval +#define SQLNCHAR ECPGt_char +#define SQLNVCHAR ECPGt_char +#ifdef HAVE_LONG_LONG_INT_64 +#define SQLINT8 ECPGt_long_long +#define SQLSERIAL8 ECPGt_long_long +#else +#define SQLINT8 ECPGt_long +#define SQLSERIAL8 ECPGt_long +#endif + +#endif /* ndef ECPG_SQLTYPES_H */ diff --git a/install/include/postgresql/internal/c.h b/install/include/postgresql/internal/c.h new file mode 100644 index 00000000000..a7258cce1fc --- /dev/null +++ b/install/include/postgresql/internal/c.h @@ -0,0 +1,1377 @@ +/*------------------------------------------------------------------------- + * + * c.h + * Fundamental C definitions. This is included by every .c file in + * PostgreSQL (via either postgres.h or postgres_fe.h, as appropriate). + * + * Note that the definitions here are not intended to be exposed to clients + * of the frontend interface libraries --- so we don't worry much about + * polluting the namespace with lots of stuff... + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/c.h + * + *------------------------------------------------------------------------- + */ +/* + *---------------------------------------------------------------- + * TABLE OF CONTENTS + * + * When adding stuff to this file, please try to put stuff + * into the relevant section, or add new sections as appropriate. + * + * section description + * ------- ------------------------------------------------ + * 0) pg_config.h and standard system headers + * 1) compiler characteristics + * 2) bool, true, false + * 3) standard system types + * 4) IsValid macros for system types + * 5) lengthof, alignment + * 6) assertions + * 7) widely useful macros + * 8) random stuff + * 9) system-specific hacks + * + * NOTE: since this file is included by both frontend and backend modules, + * it's usually wrong to put an "extern" declaration here, unless it's + * ifdef'd so that it's seen in only one case or the other. + * typedefs and macros are the kind of thing that might go here. + * + *---------------------------------------------------------------- + */ +#ifndef C_H +#define C_H + +#include "postgres_ext.h" + +/* Must undef pg_config_ext.h symbols before including pg_config.h */ +#undef PG_INT64_TYPE + +#include "pg_config.h" +#include "pg_config_manual.h" /* must be after pg_config.h */ +#include "pg_config_os.h" /* must be before any system header files */ + +/* System header files that should be available everywhere in Postgres */ +#include +#include +#include +#include +#include +#ifdef HAVE_STRINGS_H +#include +#endif +#include +#include +#include +#if defined(WIN32) || defined(__CYGWIN__) +#include /* ensure O_BINARY is available */ +#endif +#include +#ifdef ENABLE_NLS +#include +#endif + + +/* ---------------------------------------------------------------- + * Section 1: compiler characteristics + * + * type prefixes (const, signed, volatile, inline) are handled in pg_config.h. + * ---------------------------------------------------------------- + */ + +/* + * Disable "inline" if PG_FORCE_DISABLE_INLINE is defined. + * This is used to work around compiler bugs and might also be useful for + * investigatory purposes. + */ +#ifdef PG_FORCE_DISABLE_INLINE +#undef inline +#define inline +#endif + +/* + * Attribute macros + * + * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html + * Clang: https://clang.llvm.org/docs/AttributeReference.html + * Sunpro: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html + * XLC: https://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.2/com.ibm.xlc131.aix.doc/language_ref/function_attributes.html + * XLC: https://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.2/com.ibm.xlc131.aix.doc/language_ref/type_attrib.html + */ + +/* + * For compilers which don't support __has_attribute, we just define + * __has_attribute(x) to 0 so that we can define macros for various + * __attribute__s more easily below. + */ +#ifndef __has_attribute +#define __has_attribute(attribute) 0 +#endif + +/* only GCC supports the unused attribute */ +#ifdef __GNUC__ +#define pg_attribute_unused() __attribute__((unused)) +#else +#define pg_attribute_unused() +#endif + +/* + * pg_nodiscard means the compiler should warn if the result of a function + * call is ignored. The name "nodiscard" is chosen in alignment with + * (possibly future) C and C++ standards. For maximum compatibility, use it + * as a function declaration specifier, so it goes before the return type. + */ +#ifdef __GNUC__ +#define pg_nodiscard __attribute__((warn_unused_result)) +#else +#define pg_nodiscard +#endif + +/* + * Place this macro before functions that should be allowed to make misaligned + * accesses. Think twice before using it on non-x86-specific code! + * Testing can be done with "-fsanitize=alignment -fsanitize-trap=alignment" + * on clang, or "-fsanitize=alignment -fno-sanitize-recover=alignment" on gcc. + */ +#if __clang_major__ >= 7 || __GNUC__ >= 8 +#define pg_attribute_no_sanitize_alignment() __attribute__((no_sanitize("alignment"))) +#else +#define pg_attribute_no_sanitize_alignment() +#endif + +/* + * pg_attribute_nonnull means the compiler should warn if the function is + * called with the listed arguments set to NULL. If no arguments are + * listed, the compiler should warn if any pointer arguments are set to NULL. + */ +#if __has_attribute (nonnull) +#define pg_attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) +#else +#define pg_attribute_nonnull(...) +#endif + +/* + * Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only + * used in assert-enabled builds, to avoid compiler warnings about unused + * variables in assert-disabled builds. + */ +#ifdef USE_ASSERT_CHECKING +#define PG_USED_FOR_ASSERTS_ONLY +#else +#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused() +#endif + +/* GCC and XLC support format attributes */ +#if defined(__GNUC__) || defined(__IBMC__) +#define pg_attribute_format_arg(a) __attribute__((format_arg(a))) +#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a))) +#else +#define pg_attribute_format_arg(a) +#define pg_attribute_printf(f,a) +#endif + +/* GCC, Sunpro and XLC support aligned, packed and noreturn */ +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__) +#define pg_attribute_aligned(a) __attribute__((aligned(a))) +#define pg_attribute_noreturn() __attribute__((noreturn)) +#define pg_attribute_packed() __attribute__((packed)) +#define HAVE_PG_ATTRIBUTE_NORETURN 1 +#elif defined(_MSC_VER) +/* + * MSVC supports aligned. noreturn is also possible but in MSVC it is + * declared before the definition while pg_attribute_noreturn() macro + * is currently used after the definition. + * + * Packing is also possible but only by wrapping the entire struct definition + * which doesn't fit into our current macro declarations. + */ +#define pg_attribute_aligned(a) __declspec(align(a)) +#define pg_attribute_noreturn() +#else +/* + * NB: aligned and packed are not given default definitions because they + * affect code functionality; they *must* be implemented by the compiler + * if they are to be used. + */ +#define pg_attribute_noreturn() +#endif + +/* + * Use "pg_attribute_always_inline" in place of "inline" for functions that + * we wish to force inlining of, even when the compiler's heuristics would + * choose not to. But, if possible, don't force inlining in unoptimized + * debug builds. + */ +#if (defined(__GNUC__) && __GNUC__ > 3 && defined(__OPTIMIZE__)) || defined(__SUNPRO_C) || defined(__IBMC__) +/* GCC > 3, Sunpro and XLC support always_inline via __attribute__ */ +#define pg_attribute_always_inline __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +/* MSVC has a special keyword for this */ +#define pg_attribute_always_inline __forceinline +#else +/* Otherwise, the best we can do is to say "inline" */ +#define pg_attribute_always_inline inline +#endif + +/* + * Forcing a function not to be inlined can be useful if it's the slow path of + * a performance-critical function, or should be visible in profiles to allow + * for proper cost attribution. Note that unlike the pg_attribute_XXX macros + * above, this should be placed before the function's return type and name. + */ +/* GCC, Sunpro and XLC support noinline via __attribute__ */ +#if (defined(__GNUC__) && __GNUC__ > 2) || defined(__SUNPRO_C) || defined(__IBMC__) +#define pg_noinline __attribute__((noinline)) +/* msvc via declspec */ +#elif defined(_MSC_VER) +#define pg_noinline __declspec(noinline) +#else +#define pg_noinline +#endif + +/* + * For now, just define pg_attribute_cold and pg_attribute_hot to be empty + * macros on minGW 8.1. There appears to be a compiler bug that results in + * compilation failure. At this time, we still have at least one buildfarm + * animal running that compiler, so this should make that green again. It's + * likely this compiler is not popular enough to warrant keeping this code + * around forever, so let's just remove it once the last buildfarm animal + * upgrades. + */ +#if defined(__MINGW64__) && __GNUC__ == 8 && __GNUC_MINOR__ == 1 + +#define pg_attribute_cold +#define pg_attribute_hot + +#else +/* + * Marking certain functions as "hot" or "cold" can be useful to assist the + * compiler in arranging the assembly code in a more efficient way. + */ +#if __has_attribute (cold) +#define pg_attribute_cold __attribute__((cold)) +#else +#define pg_attribute_cold +#endif + +#if __has_attribute (hot) +#define pg_attribute_hot __attribute__((hot)) +#else +#define pg_attribute_hot +#endif + +#endif /* defined(__MINGW64__) && __GNUC__ == 8 && + * __GNUC_MINOR__ == 1 */ +/* + * Mark a point as unreachable in a portable fashion. This should preferably + * be something that the compiler understands, to aid code generation. + * In assert-enabled builds, we prefer abort() for debugging reasons. + */ +#if defined(HAVE__BUILTIN_UNREACHABLE) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __builtin_unreachable() +#elif defined(_MSC_VER) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __assume(0) +#else +#define pg_unreachable() abort() +#endif + +/* + * Hints to the compiler about the likelihood of a branch. Both likely() and + * unlikely() return the boolean value of the contained expression. + * + * These should only be used sparingly, in very hot code paths. It's very easy + * to mis-estimate likelihoods. + */ +#if __GNUC__ >= 3 +#define likely(x) __builtin_expect((x) != 0, 1) +#define unlikely(x) __builtin_expect((x) != 0, 0) +#else +#define likely(x) ((x) != 0) +#define unlikely(x) ((x) != 0) +#endif + +/* + * CppAsString + * Convert the argument to a string, using the C preprocessor. + * CppAsString2 + * Convert the argument to a string, after one round of macro expansion. + * CppConcat + * Concatenate two arguments together, using the C preprocessor. + * + * Note: There used to be support here for pre-ANSI C compilers that didn't + * support # and ##. Nowadays, these macros are just for clarity and/or + * backward compatibility with existing PostgreSQL code. + */ +#define CppAsString(identifier) #identifier +#define CppAsString2(x) CppAsString(x) +#define CppConcat(x, y) x##y + +/* + * VA_ARGS_NARGS + * Returns the number of macro arguments it is passed. + * + * An empty argument still counts as an argument, so effectively, this is + * "one more than the number of commas in the argument list". + * + * This works for up to 63 arguments. Internally, VA_ARGS_NARGS_() is passed + * 64+N arguments, and the C99 standard only requires macros to allow up to + * 127 arguments, so we can't portably go higher. The implementation is + * pretty trivial: VA_ARGS_NARGS_() returns its 64th argument, and we set up + * the call so that that is the appropriate one of the list of constants. + * This idea is due to Laurent Deniau. + * + * MSVC has an implementation of __VA_ARGS__ that doesn't conform to the + * standard unless you use the /Zc:preprocessor compiler flag, but that + * isn't available before Visual Studio 2019. For now, use a different + * definition that also works on older compilers. + */ +#ifdef _MSC_VER +#define EXPAND(args) args +#define VA_ARGS_NARGS(...) \ + VA_ARGS_NARGS_ EXPAND((__VA_ARGS__, \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) +#else + +#define VA_ARGS_NARGS(...) \ + VA_ARGS_NARGS_(__VA_ARGS__, \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#endif + +#define VA_ARGS_NARGS_( \ + _01,_02,_03,_04,_05,_06,_07,_08,_09,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63, N, ...) \ + (N) + +/* + * Generic function pointer. This can be used in the rare cases where it's + * necessary to cast a function pointer to a seemingly incompatible function + * pointer type while avoiding gcc's -Wcast-function-type warnings. + */ +typedef void (*pg_funcptr_t) (void); + +/* + * We require C99, hence the compiler should understand flexible array + * members. However, for documentation purposes we still consider it to be + * project style to write "field[FLEXIBLE_ARRAY_MEMBER]" not just "field[]". + * When computing the size of such an object, use "offsetof(struct s, f)" + * for portability. Don't use "offsetof(struct s, f[0])", as this doesn't + * work with MSVC and with C++ compilers. + */ +#define FLEXIBLE_ARRAY_MEMBER /* empty */ + +/* + * Does the compiler support #pragma GCC system_header? We optionally use it + * to avoid warnings that we can't fix (e.g. in the perl headers). + * See https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html + * + * Headers for which we do not want to show compiler warnings can, + * conditionally, use #pragma GCC system_header to avoid warnings. Obviously + * this should only be used for external headers over which we do not have + * control. + * + * Support for the pragma is tested here, instead of during configure, as gcc + * also warns about the pragma being used in a .c file. It's surprisingly hard + * to get autoconf to use .h as the file-ending. Looks like gcc has + * implemented the pragma since the 2000, so this test should suffice. + * + * + * Alternatively, we could add the include paths for problematic headers with + * -isystem, but that is a larger hammer and is harder to search for. + * + * A more granular alternative would be to use #pragma GCC diagnostic + * push/ignored/pop, but gcc warns about unknown warnings being ignored, so + * every to-be-ignored-temporarily compiler warning would require its own + * pg_config.h symbol and #ifdef. + */ +#ifdef __GNUC__ +#define HAVE_PRAGMA_GCC_SYSTEM_HEADER 1 +#endif + + +/* ---------------------------------------------------------------- + * Section 2: bool, true, false + * ---------------------------------------------------------------- + */ + +/* + * bool + * Boolean value, either true or false. + * + * We use stdbool.h if bool has size 1 after including it. That's useful for + * better compiler and debugger output and for compatibility with third-party + * libraries. But PostgreSQL currently cannot deal with bool of other sizes; + * there are static assertions around the code to prevent that. + * + * For C++ compilers, we assume the compiler has a compatible built-in + * definition of bool. + * + * See also the version of this code in src/interfaces/ecpg/include/ecpglib.h. + */ + +#ifndef __cplusplus + +#ifdef PG_USE_STDBOOL +#include +#else + +#ifndef bool +typedef unsigned char bool; +#endif + +#ifndef true +#define true ((bool) 1) +#endif + +#ifndef false +#define false ((bool) 0) +#endif + +#endif /* not PG_USE_STDBOOL */ +#endif /* not C++ */ + + +/* ---------------------------------------------------------------- + * Section 3: standard system types + * ---------------------------------------------------------------- + */ + +/* + * Pointer + * Variable holding address of any memory resident object. + * + * XXX Pointer arithmetic is done with this, so it can't be void * + * under "true" ANSI compilers. + */ +typedef char *Pointer; + +/* + * intN + * Signed integer, EXACTLY N BITS IN SIZE, + * used for numerical computations and the + * frontend/backend protocol. + */ +#ifndef HAVE_INT8 +typedef signed char int8; /* == 8 bits */ +typedef signed short int16; /* == 16 bits */ +typedef signed int int32; /* == 32 bits */ +#endif /* not HAVE_INT8 */ + +/* + * uintN + * Unsigned integer, EXACTLY N BITS IN SIZE, + * used for numerical computations and the + * frontend/backend protocol. + */ +#ifndef HAVE_UINT8 +typedef unsigned char uint8; /* == 8 bits */ +typedef unsigned short uint16; /* == 16 bits */ +typedef unsigned int uint32; /* == 32 bits */ +#endif /* not HAVE_UINT8 */ + +/* + * bitsN + * Unit of bitwise operation, AT LEAST N BITS IN SIZE. + */ +typedef uint8 bits8; /* >= 8 bits */ +typedef uint16 bits16; /* >= 16 bits */ +typedef uint32 bits32; /* >= 32 bits */ + +/* + * 64-bit integers + */ +#ifdef HAVE_LONG_INT_64 +/* Plain "long int" fits, use it */ + +#ifndef HAVE_INT64 +typedef long int int64; +#endif +#ifndef HAVE_UINT64 +typedef unsigned long int uint64; +#endif +#define INT64CONST(x) (x##L) +#define UINT64CONST(x) (x##UL) +#elif defined(HAVE_LONG_LONG_INT_64) +/* We have working support for "long long int", use that */ + +#ifndef HAVE_INT64 +typedef long long int int64; +#endif +#ifndef HAVE_UINT64 +typedef unsigned long long int uint64; +#endif +#define INT64CONST(x) (x##LL) +#define UINT64CONST(x) (x##ULL) +#else +/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ +#error must have a working 64-bit integer datatype +#endif + +/* snprintf format strings to use for 64-bit integers */ +#define INT64_FORMAT "%" INT64_MODIFIER "d" +#define UINT64_FORMAT "%" INT64_MODIFIER "u" + +/* + * 128-bit signed and unsigned integers + * There currently is only limited support for such types. + * E.g. 128bit literals and snprintf are not supported; but math is. + * Also, because we exclude such types when choosing MAXIMUM_ALIGNOF, + * it must be possible to coerce the compiler to allocate them on no + * more than MAXALIGN boundaries. + */ +#if defined(PG_INT128_TYPE) +#if defined(pg_attribute_aligned) || ALIGNOF_PG_INT128_TYPE <= MAXIMUM_ALIGNOF +#define HAVE_INT128 1 + +typedef PG_INT128_TYPE int128 +#if defined(pg_attribute_aligned) + pg_attribute_aligned(MAXIMUM_ALIGNOF) +#endif + ; + +typedef unsigned PG_INT128_TYPE uint128 +#if defined(pg_attribute_aligned) + pg_attribute_aligned(MAXIMUM_ALIGNOF) +#endif + ; + +#endif +#endif + +/* + * stdint.h limits aren't guaranteed to have compatible types with our fixed + * width types. So just define our own. + */ +#define PG_INT8_MIN (-0x7F-1) +#define PG_INT8_MAX (0x7F) +#define PG_UINT8_MAX (0xFF) +#define PG_INT16_MIN (-0x7FFF-1) +#define PG_INT16_MAX (0x7FFF) +#define PG_UINT16_MAX (0xFFFF) +#define PG_INT32_MIN (-0x7FFFFFFF-1) +#define PG_INT32_MAX (0x7FFFFFFF) +#define PG_UINT32_MAX (0xFFFFFFFFU) +#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1) +#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF) +#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF) + +/* + * We now always use int64 timestamps, but keep this symbol defined for the + * benefit of external code that might test it. + */ +#define HAVE_INT64_TIMESTAMP + +/* + * Size + * Size of any memory resident object, as returned by sizeof. + */ +typedef size_t Size; + +/* + * Index + * Index into any memory resident array. + * + * Note: + * Indices are non negative. + */ +typedef unsigned int Index; + +/* + * Offset + * Offset into any memory resident array. + * + * Note: + * This differs from an Index in that an Index is always + * non negative, whereas Offset may be negative. + */ +typedef signed int Offset; + +/* + * Common Postgres datatype names (as used in the catalogs) + */ +typedef float float4; +typedef double float8; + +#ifdef USE_FLOAT8_BYVAL +#define FLOAT8PASSBYVAL true +#else +#define FLOAT8PASSBYVAL false +#endif + +/* + * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, + * CommandId + */ + +/* typedef Oid is in postgres_ext.h */ + +/* + * regproc is the type name used in the include/catalog headers, but + * RegProcedure is the preferred name in C code. + */ +typedef Oid regproc; +typedef regproc RegProcedure; + +typedef uint32 TransactionId; + +typedef uint32 LocalTransactionId; + +typedef uint32 SubTransactionId; + +#define InvalidSubTransactionId ((SubTransactionId) 0) +#define TopSubTransactionId ((SubTransactionId) 1) + +/* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */ +typedef TransactionId MultiXactId; + +typedef uint32 MultiXactOffset; + +typedef uint32 CommandId; + +#define FirstCommandId ((CommandId) 0) +#define InvalidCommandId (~(CommandId)0) + + +/* ---------------- + * Variable-length datatypes all share the 'struct varlena' header. + * + * NOTE: for TOASTable types, this is an oversimplification, since the value + * may be compressed or moved out-of-line. However datatype-specific routines + * are mostly content to deal with de-TOASTed values only, and of course + * client-side routines should never see a TOASTed value. But even in a + * de-TOASTed value, beware of touching vl_len_ directly, as its + * representation is no longer convenient. It's recommended that code always + * use macros VARDATA_ANY, VARSIZE_ANY, VARSIZE_ANY_EXHDR, VARDATA, VARSIZE, + * and SET_VARSIZE instead of relying on direct mentions of the struct fields. + * See postgres.h for details of the TOASTed form. + * ---------------- + */ +struct varlena +{ + char vl_len_[4]; /* Do not touch this field directly! */ + char vl_dat[FLEXIBLE_ARRAY_MEMBER]; /* Data content is here */ +}; + +#define VARHDRSZ ((int32) sizeof(int32)) + +/* + * These widely-used datatypes are just a varlena header and the data bytes. + * There is no terminating null or anything like that --- the data length is + * always VARSIZE_ANY_EXHDR(ptr). + */ +typedef struct varlena bytea; +typedef struct varlena text; +typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */ +typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */ + +/* + * Specialized array types. These are physically laid out just the same + * as regular arrays (so that the regular array subscripting code works + * with them). They exist as distinct types mostly for historical reasons: + * they have nonstandard I/O behavior which we don't want to change for fear + * of breaking applications that look at the system catalogs. There is also + * an implementation issue for oidvector: it's part of the primary key for + * pg_proc, and we can't use the normal btree array support routines for that + * without circularity. + */ +typedef struct +{ + int32 vl_len_; /* these fields must match ArrayType! */ + int ndim; /* always 1 for int2vector */ + int32 dataoffset; /* always 0 for int2vector */ + Oid elemtype; + int dim1; + int lbound1; + int16 values[FLEXIBLE_ARRAY_MEMBER]; +} int2vector; + +typedef struct +{ + int32 vl_len_; /* these fields must match ArrayType! */ + int ndim; /* always 1 for oidvector */ + int32 dataoffset; /* always 0 for oidvector */ + Oid elemtype; + int dim1; + int lbound1; + Oid values[FLEXIBLE_ARRAY_MEMBER]; +} oidvector; + +/* + * Representation of a Name: effectively just a C string, but null-padded to + * exactly NAMEDATALEN bytes. The use of a struct is historical. + */ +typedef struct nameData +{ + char data[NAMEDATALEN]; +} NameData; +typedef NameData *Name; + +#define NameStr(name) ((name).data) + + +/* ---------------------------------------------------------------- + * Section 4: IsValid macros for system types + * ---------------------------------------------------------------- + */ +/* + * BoolIsValid + * True iff bool is valid. + */ +#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true) + +/* + * PointerIsValid + * True iff pointer is valid. + */ +#define PointerIsValid(pointer) ((const void*)(pointer) != NULL) + +/* + * PointerIsAligned + * True iff pointer is properly aligned to point to the given type. + */ +#define PointerIsAligned(pointer, type) \ + (((uintptr_t)(pointer) % (sizeof (type))) == 0) + +#define OffsetToPointer(base, offset) \ + ((void *)((char *) base + offset)) + +#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) + +#define RegProcedureIsValid(p) OidIsValid(p) + + +/* ---------------------------------------------------------------- + * Section 5: lengthof, alignment + * ---------------------------------------------------------------- + */ +/* + * lengthof + * Number of elements in an array. + */ +#define lengthof(array) (sizeof (array) / sizeof ((array)[0])) + +/* ---------------- + * Alignment macros: align a length or address appropriately for a given type. + * The fooALIGN() macros round up to a multiple of the required alignment, + * while the fooALIGN_DOWN() macros round down. The latter are more useful + * for problems like "how many X-sized structures will fit in a page?". + * + * NOTE: TYPEALIGN[_DOWN] will not work if ALIGNVAL is not a power of 2. + * That case seems extremely unlikely to be needed in practice, however. + * + * NOTE: MAXIMUM_ALIGNOF, and hence MAXALIGN(), intentionally exclude any + * larger-than-8-byte types the compiler might have. + * ---------------- + */ + +#define TYPEALIGN(ALIGNVAL,LEN) \ + (((uintptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uintptr_t) ((ALIGNVAL) - 1))) + +#define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) +#define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) +#define LONGALIGN(LEN) TYPEALIGN(ALIGNOF_LONG, (LEN)) +#define DOUBLEALIGN(LEN) TYPEALIGN(ALIGNOF_DOUBLE, (LEN)) +#define MAXALIGN(LEN) TYPEALIGN(MAXIMUM_ALIGNOF, (LEN)) +/* MAXALIGN covers only built-in types, not buffers */ +#define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) +#define CACHELINEALIGN(LEN) TYPEALIGN(PG_CACHE_LINE_SIZE, (LEN)) + +#define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ + (((uintptr_t) (LEN)) & ~((uintptr_t) ((ALIGNVAL) - 1))) + +#define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) +#define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) +#define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN)) +#define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN)) +#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN)) +#define BUFFERALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_BUFFER, (LEN)) + +/* + * The above macros will not work with types wider than uintptr_t, like with + * uint64 on 32-bit platforms. That's not problem for the usual use where a + * pointer or a length is aligned, but for the odd case that you need to + * align something (potentially) wider, use TYPEALIGN64. + */ +#define TYPEALIGN64(ALIGNVAL,LEN) \ + (((uint64) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64) ((ALIGNVAL) - 1))) + +/* we don't currently need wider versions of the other ALIGN macros */ +#define MAXALIGN64(LEN) TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN)) + + +/* ---------------------------------------------------------------- + * Section 6: assertions + * ---------------------------------------------------------------- + */ + +/* + * USE_ASSERT_CHECKING, if defined, turns on all the assertions. + * - plai 9/5/90 + * + * It should _NOT_ be defined in releases or in benchmark copies + */ + +/* + * Assert() can be used in both frontend and backend code. In frontend code it + * just calls the standard assert, if it's available. If use of assertions is + * not configured, it does nothing. + */ +#ifndef USE_ASSERT_CHECKING + +#define Assert(condition) ((void)true) +#define AssertMacro(condition) ((void)true) + +#elif defined(FRONTEND) + +#include +#define Assert(p) assert(p) +#define AssertMacro(p) ((void) assert(p)) + +#else /* USE_ASSERT_CHECKING && !FRONTEND */ + +/* + * Assert + * Generates a fatal exception if the given condition is false. + */ +#define Assert(condition) \ + do { \ + if (!(condition)) \ + ExceptionalCondition(#condition, __FILE__, __LINE__); \ + } while (0) + +/* + * AssertMacro is the same as Assert but it's suitable for use in + * expression-like macros, for example: + * + * #define foo(x) (AssertMacro(x != 0), bar(x)) + */ +#define AssertMacro(condition) \ + ((void) ((condition) || \ + (ExceptionalCondition(#condition, __FILE__, __LINE__), 0))) + +#endif /* USE_ASSERT_CHECKING && !FRONTEND */ + +/* + * Check that `ptr' is `bndr' aligned. + */ +#define AssertPointerAlignment(ptr, bndr) \ + Assert(TYPEALIGN(bndr, (uintptr_t)(ptr)) == (uintptr_t)(ptr)) + +/* + * ExceptionalCondition is compiled into the backend whether or not + * USE_ASSERT_CHECKING is defined, so as to support use of extensions + * that are built with that #define with a backend that isn't. Hence, + * we should declare it as long as !FRONTEND. + */ +#ifndef FRONTEND +extern void ExceptionalCondition(const char *conditionName, + const char *fileName, int lineNumber) pg_attribute_noreturn(); +#endif + +/* + * Macros to support compile-time assertion checks. + * + * If the "condition" (a compile-time-constant expression) evaluates to false, + * throw a compile error using the "errmessage" (a string literal). + * + * C11 has _Static_assert(), and most C99 compilers already support that. For + * portability, we wrap it into StaticAssertDecl(). _Static_assert() is a + * "declaration", and so it must be placed where for example a variable + * declaration would be valid. As long as we compile with + * -Wno-declaration-after-statement, that also means it cannot be placed after + * statements in a function. Macros StaticAssertStmt() and StaticAssertExpr() + * make it safe to use as a statement or in an expression, respectively. + * + * For compilers without _Static_assert(), we fall back on a kluge that + * assumes the compiler will complain about a negative width for a struct + * bit-field. This will not include a helpful error message, but it beats not + * getting an error at all. + */ +#ifndef __cplusplus +#ifdef HAVE__STATIC_ASSERT +#define StaticAssertDecl(condition, errmessage) \ + _Static_assert(condition, errmessage) +#define StaticAssertStmt(condition, errmessage) \ + do { _Static_assert(condition, errmessage); } while(0) +#define StaticAssertExpr(condition, errmessage) \ + ((void) ({ StaticAssertStmt(condition, errmessage); true; })) +#else /* !HAVE__STATIC_ASSERT */ +#define StaticAssertDecl(condition, errmessage) \ + extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) +#define StaticAssertStmt(condition, errmessage) \ + ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) +#define StaticAssertExpr(condition, errmessage) \ + StaticAssertStmt(condition, errmessage) +#endif /* HAVE__STATIC_ASSERT */ +#else /* C++ */ +#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410 +#define StaticAssertDecl(condition, errmessage) \ + static_assert(condition, errmessage) +#define StaticAssertStmt(condition, errmessage) \ + static_assert(condition, errmessage) +#define StaticAssertExpr(condition, errmessage) \ + ({ static_assert(condition, errmessage); }) +#else /* !__cpp_static_assert */ +#define StaticAssertDecl(condition, errmessage) \ + extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) +#define StaticAssertStmt(condition, errmessage) \ + do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0) +#define StaticAssertExpr(condition, errmessage) \ + ((void) ({ StaticAssertStmt(condition, errmessage); })) +#endif /* __cpp_static_assert */ +#endif /* C++ */ + + +/* + * Compile-time checks that a variable (or expression) has the specified type. + * + * AssertVariableIsOfType() can be used as a statement. + * AssertVariableIsOfTypeMacro() is intended for use in macros, eg + * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) + * + * If we don't have __builtin_types_compatible_p, we can still assert that + * the types have the same size. This is far from ideal (especially on 32-bit + * platforms) but it provides at least some coverage. + */ +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + (StaticAssertExpr(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ + + +/* ---------------------------------------------------------------- + * Section 7: widely useful macros + * ---------------------------------------------------------------- + */ +/* + * Max + * Return the maximum of two numbers. + */ +#define Max(x, y) ((x) > (y) ? (x) : (y)) + +/* + * Min + * Return the minimum of two numbers. + */ +#define Min(x, y) ((x) < (y) ? (x) : (y)) + + +/* Get a bit mask of the bits set in non-long aligned addresses */ +#define LONG_ALIGN_MASK (sizeof(long) - 1) + +/* + * MemSet + * Exactly the same as standard library function memset(), but considerably + * faster for zeroing small word-aligned structures (such as parsetree nodes). + * This has to be a macro because the main point is to avoid function-call + * overhead. However, we have also found that the loop is faster than + * native libc memset() on some platforms, even those with assembler + * memset() functions. More research needs to be done, perhaps with + * MEMSET_LOOP_LIMIT tests in configure. + */ +#define MemSet(start, val, len) \ + do \ + { \ + /* must be void* because we don't know if it is integer aligned yet */ \ + void *_vstart = (void *) (start); \ + int _val = (val); \ + Size _len = (len); \ +\ + if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ + (_len & LONG_ALIGN_MASK) == 0 && \ + _val == 0 && \ + _len <= MEMSET_LOOP_LIMIT && \ + /* \ + * If MEMSET_LOOP_LIMIT == 0, optimizer should find \ + * the whole "if" false at compile time. \ + */ \ + MEMSET_LOOP_LIMIT != 0) \ + { \ + long *_start = (long *) _vstart; \ + long *_stop = (long *) ((char *) _start + _len); \ + while (_start < _stop) \ + *_start++ = 0; \ + } \ + else \ + memset(_vstart, _val, _len); \ + } while (0) + +/* + * MemSetAligned is the same as MemSet except it omits the test to see if + * "start" is word-aligned. This is okay to use if the caller knows a-priori + * that the pointer is suitably aligned (typically, because he just got it + * from palloc(), which always delivers a max-aligned pointer). + */ +#define MemSetAligned(start, val, len) \ + do \ + { \ + long *_start = (long *) (start); \ + int _val = (val); \ + Size _len = (len); \ +\ + if ((_len & LONG_ALIGN_MASK) == 0 && \ + _val == 0 && \ + _len <= MEMSET_LOOP_LIMIT && \ + MEMSET_LOOP_LIMIT != 0) \ + { \ + long *_stop = (long *) ((char *) _start + _len); \ + while (_start < _stop) \ + *_start++ = 0; \ + } \ + else \ + memset(_start, _val, _len); \ + } while (0) + + +/* + * MemSetTest/MemSetLoop are a variant version that allow all the tests in + * MemSet to be done at compile time in cases where "val" and "len" are + * constants *and* we know the "start" pointer must be word-aligned. + * If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use + * MemSetAligned. Beware of multiple evaluations of the arguments when using + * this approach. + */ +#define MemSetTest(val, len) \ + ( ((len) & LONG_ALIGN_MASK) == 0 && \ + (len) <= MEMSET_LOOP_LIMIT && \ + MEMSET_LOOP_LIMIT != 0 && \ + (val) == 0 ) + +#define MemSetLoop(start, val, len) \ + do \ + { \ + long * _start = (long *) (start); \ + long * _stop = (long *) ((char *) _start + (Size) (len)); \ + \ + while (_start < _stop) \ + *_start++ = 0; \ + } while (0) + +/* + * Macros for range-checking float values before converting to integer. + * We must be careful here that the boundary values are expressed exactly + * in the float domain. PG_INTnn_MIN is an exact power of 2, so it will + * be represented exactly; but PG_INTnn_MAX isn't, and might get rounded + * off, so avoid using that. + * The input must be rounded to an integer beforehand, typically with rint(), + * else we might draw the wrong conclusion about close-to-the-limit values. + * These macros will do the right thing for Inf, but not necessarily for NaN, + * so check isnan(num) first if that's a possibility. + */ +#define FLOAT4_FITS_IN_INT16(num) \ + ((num) >= (float4) PG_INT16_MIN && (num) < -((float4) PG_INT16_MIN)) +#define FLOAT4_FITS_IN_INT32(num) \ + ((num) >= (float4) PG_INT32_MIN && (num) < -((float4) PG_INT32_MIN)) +#define FLOAT4_FITS_IN_INT64(num) \ + ((num) >= (float4) PG_INT64_MIN && (num) < -((float4) PG_INT64_MIN)) +#define FLOAT8_FITS_IN_INT16(num) \ + ((num) >= (float8) PG_INT16_MIN && (num) < -((float8) PG_INT16_MIN)) +#define FLOAT8_FITS_IN_INT32(num) \ + ((num) >= (float8) PG_INT32_MIN && (num) < -((float8) PG_INT32_MIN)) +#define FLOAT8_FITS_IN_INT64(num) \ + ((num) >= (float8) PG_INT64_MIN && (num) < -((float8) PG_INT64_MIN)) + + +/* ---------------------------------------------------------------- + * Section 8: random stuff + * ---------------------------------------------------------------- + */ + +/* + * Invert the sign of a qsort-style comparison result, ie, exchange negative + * and positive integer values, being careful not to get the wrong answer + * for INT_MIN. The argument should be an integral variable. + */ +#define INVERT_COMPARE_RESULT(var) \ + ((var) = ((var) < 0) ? 1 : -(var)) + +/* + * Use this, not "char buf[BLCKSZ]", to declare a field or local variable + * holding a page buffer, if that page might be accessed as a page. Otherwise + * the variable might be under-aligned, causing problems on alignment-picky + * hardware. We include both "double" and "int64" in the union to ensure that + * the compiler knows the value must be MAXALIGN'ed (cf. configure's + * computation of MAXIMUM_ALIGNOF). + */ +typedef union PGAlignedBlock +{ + char data[BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGAlignedBlock; + +/* + * Use this to declare a field or local variable holding a page buffer, if that + * page might be accessed as a page or passed to an SMgr I/O function. If + * allocating using the MemoryContext API, the aligned allocation functions + * should be used with PG_IO_ALIGN_SIZE. This alignment may be more efficient + * for I/O in general, but may be strictly required on some platforms when + * using direct I/O. + */ +typedef union PGIOAlignedBlock +{ +#ifdef pg_attribute_aligned + pg_attribute_aligned(PG_IO_ALIGN_SIZE) +#endif + char data[BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGIOAlignedBlock; + +/* Same, but for an XLOG_BLCKSZ-sized buffer */ +typedef union PGAlignedXLogBlock +{ +#ifdef pg_attribute_aligned + pg_attribute_aligned(PG_IO_ALIGN_SIZE) +#endif + char data[XLOG_BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGAlignedXLogBlock; + +/* msb for char */ +#define HIGHBIT (0x80) +#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT) + +/* + * Support macros for escaping strings. escape_backslash should be true + * if generating a non-standard-conforming string. Prefixing a string + * with ESCAPE_STRING_SYNTAX guarantees it is non-standard-conforming. + * Beware of multiple evaluation of the "ch" argument! + */ +#define SQL_STR_DOUBLE(ch, escape_backslash) \ + ((ch) == '\'' || ((ch) == '\\' && (escape_backslash))) + +#define ESCAPE_STRING_SYNTAX 'E' + + +#define STATUS_OK (0) +#define STATUS_ERROR (-1) +#define STATUS_EOF (-2) + +/* + * gettext support + */ + +#ifndef ENABLE_NLS +/* stuff we'd otherwise get from */ +#define gettext(x) (x) +#define dgettext(d,x) (x) +#define ngettext(s,p,n) ((n) == 1 ? (s) : (p)) +#define dngettext(d,s,p,n) ((n) == 1 ? (s) : (p)) +#endif + +#define _(x) gettext(x) + +/* + * Use this to mark string constants as needing translation at some later + * time, rather than immediately. This is useful for cases where you need + * access to the original string and translated string, and for cases where + * immediate translation is not possible, like when initializing global + * variables. + * + * https://www.gnu.org/software/gettext/manual/html_node/Special-cases.html + */ +#define gettext_noop(x) (x) + +/* + * To better support parallel installations of major PostgreSQL + * versions as well as parallel installations of major library soname + * versions, we mangle the gettext domain name by appending those + * version numbers. The coding rule ought to be that wherever the + * domain name is mentioned as a literal, it must be wrapped into + * PG_TEXTDOMAIN(). The macros below do not work on non-literals; but + * that is somewhat intentional because it avoids having to worry + * about multiple states of premangling and postmangling as the values + * are being passed around. + * + * Make sure this matches the installation rules in nls-global.mk. + */ +#ifdef SO_MAJOR_VERSION +#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION) +#else +#define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) +#endif + +/* + * Macro that allows to cast constness and volatile away from an expression, but doesn't + * allow changing the underlying type. Enforcement of the latter + * currently only works for gcc like compilers. + * + * Please note IT IS NOT SAFE to cast constness away if the result will ever + * be modified (it would be undefined behaviour). Doing so anyway can cause + * compiler misoptimizations or runtime crashes (modifying readonly memory). + * It is only safe to use when the result will not be modified, but API + * design or language restrictions prevent you from declaring that + * (e.g. because a function returns both const and non-const variables). + * + * Note that this only works in function scope, not for global variables (it'd + * be nice, but not trivial, to improve that). + */ +#if defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P) +#define unconstify(underlying_type, expr) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), const underlying_type), \ + "wrong cast"), \ + (underlying_type) (expr)) +#define unvolatize(underlying_type, expr) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), volatile underlying_type), \ + "wrong cast"), \ + (underlying_type) (expr)) +#else +#define unconstify(underlying_type, expr) \ + ((underlying_type) (expr)) +#define unvolatize(underlying_type, expr) \ + ((underlying_type) (expr)) +#endif + +/* ---------------------------------------------------------------- + * Section 9: system-specific hacks + * + * This should be limited to things that absolutely have to be + * included in every source file. The port-specific header file + * is usually a better place for this sort of thing. + * ---------------------------------------------------------------- + */ + +/* + * NOTE: this is also used for opening text files. + * WIN32 treats Control-Z as EOF in files opened in text mode. + * Therefore, we open files in binary mode on Win32 so we can read + * literal control-Z. The other affect is that we see CRLF, but + * that is OK because we can already handle those cleanly. + */ +#if defined(WIN32) || defined(__CYGWIN__) +#define PG_BINARY O_BINARY +#define PG_BINARY_A "ab" +#define PG_BINARY_R "rb" +#define PG_BINARY_W "wb" +#else +#define PG_BINARY 0 +#define PG_BINARY_A "a" +#define PG_BINARY_R "r" +#define PG_BINARY_W "w" +#endif + +/* + * Provide prototypes for routines not present in a particular machine's + * standard C library. + */ + +#if !HAVE_DECL_FDATASYNC +extern int fdatasync(int fildes); +#endif + +/* + * Thin wrappers that convert strings to exactly 64-bit integers, matching our + * definition of int64. (For the naming, compare that POSIX has + * strtoimax()/strtoumax() which return intmax_t/uintmax_t.) + */ +#ifdef HAVE_LONG_INT_64 +#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base)) +#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base)) +#else +#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base)) +#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base)) +#endif + +/* + * Similarly, wrappers around labs()/llabs() matching our int64. + */ +#ifdef HAVE_LONG_INT_64 +#define i64abs(i) labs(i) +#else +#define i64abs(i) llabs(i) +#endif + +/* + * Use "extern PGDLLIMPORT ..." to declare variables that are defined + * in the core backend and need to be accessible by loadable modules. + * No special marking is required on most ports. + */ +#ifndef PGDLLIMPORT +#define PGDLLIMPORT +#endif + +/* + * Use "extern PGDLLEXPORT ..." to declare functions that are defined in + * loadable modules and need to be callable by the core backend or other + * loadable modules. + * If the compiler knows __attribute__((visibility("*"))), we use that, + * unless we already have a platform-specific definition. Otherwise, + * no special marking is required. + */ +#ifndef PGDLLEXPORT +#ifdef HAVE_VISIBILITY_ATTRIBUTE +#define PGDLLEXPORT __attribute__((visibility("default"))) +#else +#define PGDLLEXPORT +#endif +#endif + +/* + * The following is used as the arg list for signal handlers. Any ports + * that take something other than an int argument should override this in + * their pg_config_os.h file. Note that variable names are required + * because it is used in both the prototypes as well as the definitions. + * Note also the long name. We expect that this won't collide with + * other names causing compiler warnings. + */ + +#ifndef SIGNAL_ARGS +#define SIGNAL_ARGS int postgres_signal_arg +#endif + +/* + * When there is no sigsetjmp, its functionality is provided by plain + * setjmp. We now support the case only on Windows. However, it seems + * that MinGW-64 has some longstanding issues in its setjmp support, + * so on that toolchain we cheat and use gcc's builtins. + */ +#ifdef WIN32 +#ifdef __MINGW64__ +typedef intptr_t sigjmp_buf[5]; +#define sigsetjmp(x,y) __builtin_setjmp(x) +#define siglongjmp __builtin_longjmp +#else /* !__MINGW64__ */ +#define sigjmp_buf jmp_buf +#define sigsetjmp(x,y) setjmp(x) +#define siglongjmp longjmp +#endif /* __MINGW64__ */ +#endif /* WIN32 */ + +/* /port compatibility functions */ +#include "port.h" + +#endif /* C_H */ diff --git a/install/include/postgresql/internal/fe-auth-sasl.h b/install/include/postgresql/internal/fe-auth-sasl.h new file mode 100644 index 00000000000..ddf6ea3f3f4 --- /dev/null +++ b/install/include/postgresql/internal/fe-auth-sasl.h @@ -0,0 +1,131 @@ +/*------------------------------------------------------------------------- + * + * fe-auth-sasl.h + * Defines the SASL mechanism interface for libpq. + * + * Each SASL mechanism defines a frontend and a backend callback structure. + * This is not part of the public API for applications. + * + * See src/include/libpq/sasl.h for the backend counterpart. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/fe-auth-sasl.h + * + *------------------------------------------------------------------------- + */ + +#ifndef FE_AUTH_SASL_H +#define FE_AUTH_SASL_H + +#include "libpq-fe.h" + +/* + * Frontend SASL mechanism callbacks. + * + * To implement a frontend mechanism, declare a pg_be_sasl_mech struct with + * appropriate callback implementations, then hook it into conn->sasl during + * pg_SASL_init()'s mechanism negotiation. + */ +typedef struct pg_fe_sasl_mech +{ + /*------- + * init() + * + * Initializes mechanism-specific state for a connection. This + * callback must return a pointer to its allocated state, which will + * be passed as-is as the first argument to the other callbacks. + * the free() callback is called to release any state resources. + * + * If state allocation fails, the implementation should return NULL to + * fail the authentication exchange. + * + * Input parameters: + * + * conn: The connection to the server + * + * password: The user's supplied password for the current connection + * + * mech: The mechanism name in use, for implementations that may + * advertise more than one name (such as *-PLUS variants). + *------- + */ + void *(*init) (PGconn *conn, const char *password, const char *mech); + + /*-------- + * exchange() + * + * Produces a client response to a server challenge. As a special case + * for client-first SASL mechanisms, exchange() is called with a NULL + * server response once at the start of the authentication exchange to + * generate an initial response. + * + * Input parameters: + * + * state: The opaque mechanism state returned by init() + * + * input: The challenge data sent by the server, or NULL when + * generating a client-first initial response (that is, when + * the server expects the client to send a message to start + * the exchange). This is guaranteed to be null-terminated + * for safety, but SASL allows embedded nulls in challenges, + * so mechanisms must be careful to check inputlen. + * + * inputlen: The length of the challenge data sent by the server, or -1 + * during client-first initial response generation. + * + * Output parameters, to be set by the callback function: + * + * output: A malloc'd buffer containing the client's response to + * the server (can be empty), or NULL if the exchange should + * be aborted. (*success should be set to false in the + * latter case.) + * + * outputlen: The length (0 or higher) of the client response buffer, + * ignored if output is NULL. + * + * done: Set to true if the SASL exchange should not continue, + * because the exchange is either complete or failed + * + * success: Set to true if the SASL exchange completed successfully. + * Ignored if *done is false. + *-------- + */ + void (*exchange) (void *state, char *input, int inputlen, + char **output, int *outputlen, + bool *done, bool *success); + + /*-------- + * channel_bound() + * + * Returns true if the connection has an established channel binding. A + * mechanism implementation must ensure that a SASL exchange has actually + * been completed, in addition to checking that channel binding is in use. + * + * Mechanisms that do not implement channel binding may simply return + * false. + * + * Input parameters: + * + * state: The opaque mechanism state returned by init() + *-------- + */ + bool (*channel_bound) (void *state); + + /*-------- + * free() + * + * Frees the state allocated by init(). This is called when the connection + * is dropped, not when the exchange is completed. + * + * Input parameters: + * + * state: The opaque mechanism state returned by init() + *-------- + */ + void (*free) (void *state); + +} pg_fe_sasl_mech; + +#endif /* FE_AUTH_SASL_H */ diff --git a/install/include/postgresql/internal/libpq-int.h b/install/include/postgresql/internal/libpq-int.h new file mode 100644 index 00000000000..66880f39aa4 --- /dev/null +++ b/install/include/postgresql/internal/libpq-int.h @@ -0,0 +1,950 @@ +/*------------------------------------------------------------------------- + * + * libpq-int.h + * This file contains internal definitions meant to be used only by + * the frontend libpq library, not by applications that call it. + * + * An application can include this file if it wants to bypass the + * official API defined by libpq-fe.h, but code that does so is much + * more likely to break across PostgreSQL releases than code that uses + * only the official API. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/libpq-int.h + * + *------------------------------------------------------------------------- + */ + +#ifndef LIBPQ_INT_H +#define LIBPQ_INT_H + +/* We assume libpq-fe.h has already been included. */ +#include "libpq-events.h" + +#include +#include +#include +/* MinGW has sys/time.h, but MSVC doesn't */ +#ifndef _MSC_VER +#include +#endif + +#ifdef ENABLE_THREAD_SAFETY +#ifdef WIN32 +#include "pthread-win32.h" +#else +#include +#endif +#include +#endif + +/* include stuff common to fe and be */ +#include "libpq/pqcomm.h" +/* include stuff found in fe only */ +#include "fe-auth-sasl.h" +#include "pqexpbuffer.h" + +#ifdef ENABLE_GSS +#if defined(HAVE_GSSAPI_H) +#include +#else +#include +#endif +#endif + +#ifdef ENABLE_SSPI +#define SECURITY_WIN32 +#if defined(WIN32) && !defined(_MSC_VER) +#include +#endif +#include +#undef SECURITY_WIN32 + +#ifndef ENABLE_GSS +/* + * Define a fake structure compatible with GSSAPI on Unix. + */ +typedef struct +{ + void *value; + int length; +} gss_buffer_desc; +#endif +#endif /* ENABLE_SSPI */ + +#ifdef USE_OPENSSL +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#define USE_SSL_ENGINE +#endif +#endif /* USE_OPENSSL */ + +#include "common/pg_prng.h" + +/* + * POSTGRES backend dependent Constants. + */ +#define CMDSTATUS_LEN 64 /* should match COMPLETION_TAG_BUFSIZE */ + +/* + * PGresult and the subsidiary types PGresAttDesc, PGresAttValue + * represent the result of a query (or more precisely, of a single SQL + * command --- a query string given to PQexec can contain multiple commands). + * Note we assume that a single command can return at most one tuple group, + * hence there is no need for multiple descriptor sets. + */ + +/* Subsidiary-storage management structure for PGresult. + * See space management routines in fe-exec.c for details. + * Note that space[k] refers to the k'th byte starting from the physical + * head of the block --- it's a union, not a struct! + */ +typedef union pgresult_data PGresult_data; + +union pgresult_data +{ + PGresult_data *next; /* link to next block, or NULL */ + char space[1]; /* dummy for accessing block as bytes */ +}; + +/* Data about a single parameter of a prepared statement */ +typedef struct pgresParamDesc +{ + Oid typid; /* type id */ +} PGresParamDesc; + +/* + * Data for a single attribute of a single tuple + * + * We use char* for Attribute values. + * + * The value pointer always points to a null-terminated area; we add a + * null (zero) byte after whatever the backend sends us. This is only + * particularly useful for text values ... with a binary value, the + * value might have embedded nulls, so the application can't use C string + * operators on it. But we add a null anyway for consistency. + * Note that the value itself does not contain a length word. + * + * A NULL attribute is a special case in two ways: its len field is NULL_LEN + * and its value field points to null_field in the owning PGresult. All the + * NULL attributes in a query result point to the same place (there's no need + * to store a null string separately for each one). + */ + +#define NULL_LEN (-1) /* pg_result len for NULL value */ + +typedef struct pgresAttValue +{ + int len; /* length in bytes of the value */ + char *value; /* actual value, plus terminating zero byte */ +} PGresAttValue; + +/* Typedef for message-field list entries */ +typedef struct pgMessageField +{ + struct pgMessageField *next; /* list link */ + char code; /* field code */ + char contents[FLEXIBLE_ARRAY_MEMBER]; /* value, nul-terminated */ +} PGMessageField; + +/* Fields needed for notice handling */ +typedef struct +{ + PQnoticeReceiver noticeRec; /* notice message receiver */ + void *noticeRecArg; + PQnoticeProcessor noticeProc; /* notice message processor */ + void *noticeProcArg; +} PGNoticeHooks; + +typedef struct PGEvent +{ + PGEventProc proc; /* the function to call on events */ + char *name; /* used only for error messages */ + void *passThrough; /* pointer supplied at registration time */ + void *data; /* optional state (instance) data */ + bool resultInitialized; /* T if RESULTCREATE/COPY succeeded */ +} PGEvent; + +struct pg_result +{ + int ntups; + int numAttributes; + PGresAttDesc *attDescs; + PGresAttValue **tuples; /* each PGresult tuple is an array of + * PGresAttValue's */ + int tupArrSize; /* allocated size of tuples array */ + int numParameters; + PGresParamDesc *paramDescs; + ExecStatusType resultStatus; + char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the query */ + int binary; /* binary tuple values if binary == 1, + * otherwise text */ + + /* + * These fields are copied from the originating PGconn, so that operations + * on the PGresult don't have to reference the PGconn. + */ + PGNoticeHooks noticeHooks; + PGEvent *events; + int nEvents; + int client_encoding; /* encoding id */ + + /* + * Error information (all NULL if not an error result). errMsg is the + * "overall" error message returned by PQresultErrorMessage. If we have + * per-field info then it is stored in a linked list. + */ + char *errMsg; /* error message, or NULL if no error */ + PGMessageField *errFields; /* message broken into fields */ + char *errQuery; /* text of triggering query, if available */ + + /* All NULL attributes in the query result point to this null string */ + char null_field[1]; + + /* + * Space management information. Note that attDescs and error stuff, if + * not null, point into allocated blocks. But tuples points to a + * separately malloc'd block, so that we can realloc it. + */ + PGresult_data *curBlock; /* most recently allocated block */ + int curOffset; /* start offset of free space in block */ + int spaceLeft; /* number of free bytes remaining in block */ + + size_t memorySize; /* total space allocated for this PGresult */ +}; + +/* PGAsyncStatusType defines the state of the query-execution state machine */ +typedef enum +{ + PGASYNC_IDLE, /* nothing's happening, dude */ + PGASYNC_BUSY, /* query in progress */ + PGASYNC_READY, /* query done, waiting for client to fetch + * result */ + PGASYNC_READY_MORE, /* query done, waiting for client to fetch + * result, more results expected from this + * query */ + PGASYNC_COPY_IN, /* Copy In data transfer in progress */ + PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */ + PGASYNC_COPY_BOTH, /* Copy In/Out data transfer in progress */ + PGASYNC_PIPELINE_IDLE, /* "Idle" between commands in pipeline mode */ +} PGAsyncStatusType; + +/* Target server type (decoded value of target_session_attrs) */ +typedef enum +{ + SERVER_TYPE_ANY = 0, /* Any server (default) */ + SERVER_TYPE_READ_WRITE, /* Read-write server */ + SERVER_TYPE_READ_ONLY, /* Read-only server */ + SERVER_TYPE_PRIMARY, /* Primary server */ + SERVER_TYPE_STANDBY, /* Standby server */ + SERVER_TYPE_PREFER_STANDBY, /* Prefer standby server */ + SERVER_TYPE_PREFER_STANDBY_PASS2 /* second pass - behaves same as ANY */ +} PGTargetServerType; + +/* Target server type (decoded value of load_balance_hosts) */ +typedef enum +{ + LOAD_BALANCE_DISABLE = 0, /* Use the existing host order (default) */ + LOAD_BALANCE_RANDOM, /* Randomly shuffle the hosts */ +} PGLoadBalanceType; + +/* Boolean value plus a not-known state, for GUCs we might have to fetch */ +typedef enum +{ + PG_BOOL_UNKNOWN = 0, /* Currently unknown */ + PG_BOOL_YES, /* Yes (true) */ + PG_BOOL_NO /* No (false) */ +} PGTernaryBool; + +/* Typedef for the EnvironmentOptions[] array */ +typedef struct PQEnvironmentOption +{ + const char *envName, /* name of an environment variable */ + *pgName; /* name of corresponding SET variable */ +} PQEnvironmentOption; + +/* Typedef for parameter-status list entries */ +typedef struct pgParameterStatus +{ + struct pgParameterStatus *next; /* list link */ + char *name; /* parameter name */ + char *value; /* parameter value */ + /* Note: name and value are stored in same malloc block as struct is */ +} pgParameterStatus; + +/* large-object-access data ... allocated only if large-object code is used. */ +typedef struct pgLobjfuncs +{ + Oid fn_lo_open; /* OID of backend function lo_open */ + Oid fn_lo_close; /* OID of backend function lo_close */ + Oid fn_lo_creat; /* OID of backend function lo_creat */ + Oid fn_lo_create; /* OID of backend function lo_create */ + Oid fn_lo_unlink; /* OID of backend function lo_unlink */ + Oid fn_lo_lseek; /* OID of backend function lo_lseek */ + Oid fn_lo_lseek64; /* OID of backend function lo_lseek64 */ + Oid fn_lo_tell; /* OID of backend function lo_tell */ + Oid fn_lo_tell64; /* OID of backend function lo_tell64 */ + Oid fn_lo_truncate; /* OID of backend function lo_truncate */ + Oid fn_lo_truncate64; /* OID of function lo_truncate64 */ + Oid fn_lo_read; /* OID of backend function LOread */ + Oid fn_lo_write; /* OID of backend function LOwrite */ +} PGlobjfuncs; + +/* PGdataValue represents a data field value being passed to a row processor. + * It could be either text or binary data; text data is not zero-terminated. + * A SQL NULL is represented by len < 0; then value is still valid but there + * are no data bytes there. + */ +typedef struct pgDataValue +{ + int len; /* data length in bytes, or <0 if NULL */ + const char *value; /* data value, without zero-termination */ +} PGdataValue; + +/* Host address type enum for struct pg_conn_host */ +typedef enum pg_conn_host_type +{ + CHT_HOST_NAME, + CHT_HOST_ADDRESS, + CHT_UNIX_SOCKET +} pg_conn_host_type; + +/* + * PGQueryClass tracks which query protocol is in use for each command queue + * entry, or special operation in execution + */ +typedef enum +{ + PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */ + PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */ + PGQUERY_PREPARE, /* Parse only (PQprepare) */ + PGQUERY_DESCRIBE, /* Describe Statement or Portal */ + PGQUERY_SYNC, /* Sync (at end of a pipeline) */ + PGQUERY_CLOSE +} PGQueryClass; + +/* + * An entry in the pending command queue. + */ +typedef struct PGcmdQueueEntry +{ + PGQueryClass queryclass; /* Query type */ + char *query; /* SQL command, or NULL if none/unknown/OOM */ + struct PGcmdQueueEntry *next; /* list link */ +} PGcmdQueueEntry; + +/* + * pg_conn_host stores all information about each of possibly several hosts + * mentioned in the connection string. Most fields are derived by splitting + * the relevant connection parameter (e.g., pghost) at commas. + */ +typedef struct pg_conn_host +{ + pg_conn_host_type type; /* type of host address */ + char *host; /* host name or socket path */ + char *hostaddr; /* host numeric IP address */ + char *port; /* port number (if NULL or empty, use + * DEF_PGPORT[_STR]) */ + char *password; /* password for this host, read from the + * password file; NULL if not sought or not + * found in password file. */ +} pg_conn_host; + +/* + * PGconn stores all the state data associated with a single connection + * to a backend. + */ +struct pg_conn +{ + /* Saved values of connection options */ + char *pghost; /* the machine on which the server is running, + * or a path to a UNIX-domain socket, or a + * comma-separated list of machines and/or + * paths; if NULL, use DEFAULT_PGSOCKET_DIR */ + char *pghostaddr; /* the numeric IP address of the machine on + * which the server is running, or a + * comma-separated list of same. Takes + * precedence over pghost. */ + char *pgport; /* the server's communication port number, or + * a comma-separated list of ports */ + char *connect_timeout; /* connection timeout (numeric string) */ + char *pgtcp_user_timeout; /* tcp user timeout (numeric string) */ + char *client_encoding_initial; /* encoding to use */ + char *pgoptions; /* options to start the backend with */ + char *appname; /* application name */ + char *fbappname; /* fallback application name */ + char *dbName; /* database name */ + char *replication; /* connect as the replication standby? */ + char *pguser; /* Postgres username and password, if any */ + char *pgpass; + char *pgpassfile; /* path to a file containing password(s) */ + char *channel_binding; /* channel binding mode + * (require,prefer,disable) */ + char *keepalives; /* use TCP keepalives? */ + char *keepalives_idle; /* time between TCP keepalives */ + char *keepalives_interval; /* time between TCP keepalive + * retransmits */ + char *keepalives_count; /* maximum number of TCP keepalive + * retransmits */ + char *sslmode; /* SSL mode (require,prefer,allow,disable) */ + char *sslcompression; /* SSL compression (0 or 1) */ + char *sslkey; /* client key filename */ + char *sslcert; /* client certificate filename */ + char *sslpassword; /* client key file password */ + char *sslcertmode; /* client cert mode (require,allow,disable) */ + char *sslrootcert; /* root certificate filename */ + char *sslcrl; /* certificate revocation list filename */ + char *sslcrldir; /* certificate revocation list directory name */ + char *sslsni; /* use SSL SNI extension (0 or 1) */ + char *requirepeer; /* required peer credentials for local sockets */ + char *gssencmode; /* GSS mode (require,prefer,disable) */ + char *krbsrvname; /* Kerberos service name */ + char *gsslib; /* What GSS library to use ("gssapi" or + * "sspi") */ + char *gssdelegation; /* Try to delegate GSS credentials? (0 or 1) */ + char *ssl_min_protocol_version; /* minimum TLS protocol version */ + char *ssl_max_protocol_version; /* maximum TLS protocol version */ + char *target_session_attrs; /* desired session properties */ + char *require_auth; /* name of the expected auth method */ + char *load_balance_hosts; /* load balance over hosts */ + + /* Optional file to write trace info to */ + FILE *Pfdebug; + int traceFlags; + + /* Callback procedures for notice message processing */ + PGNoticeHooks noticeHooks; + + /* Event procs registered via PQregisterEventProc */ + PGEvent *events; /* expandable array of event data */ + int nEvents; /* number of active events */ + int eventArraySize; /* allocated array size */ + + /* Status indicators */ + ConnStatusType status; + PGAsyncStatusType asyncStatus; + PGTransactionStatusType xactStatus; /* never changes to ACTIVE */ + char last_sqlstate[6]; /* last reported SQLSTATE */ + bool options_valid; /* true if OK to attempt connection */ + bool nonblocking; /* whether this connection is using nonblock + * sending semantics */ + PGpipelineStatus pipelineStatus; /* status of pipeline mode */ + bool singleRowMode; /* return current query result row-by-row? */ + char copy_is_binary; /* 1 = copy binary, 0 = copy text */ + int copy_already_done; /* # bytes already returned in COPY OUT */ + PGnotify *notifyHead; /* oldest unreported Notify msg */ + PGnotify *notifyTail; /* newest unreported Notify msg */ + + /* Support for multiple hosts in connection string */ + int nconnhost; /* # of hosts named in conn string */ + int whichhost; /* host we're currently trying/connected to */ + pg_conn_host *connhost; /* details about each named host */ + char *connip; /* IP address for current network connection */ + + /* + * The pending command queue as a singly-linked list. Head is the command + * currently in execution, tail is where new commands are added. + */ + PGcmdQueueEntry *cmd_queue_head; + PGcmdQueueEntry *cmd_queue_tail; + + /* + * To save malloc traffic, we don't free entries right away; instead we + * save them in this list for possible reuse. + */ + PGcmdQueueEntry *cmd_queue_recycle; + + /* Connection data */ + pgsocket sock; /* FD for socket, PGINVALID_SOCKET if + * unconnected */ + SockAddr laddr; /* Local address */ + SockAddr raddr; /* Remote address */ + ProtocolVersion pversion; /* FE/BE protocol version in use */ + int sversion; /* server version, e.g. 70401 for 7.4.1 */ + bool auth_req_received; /* true if any type of auth req received */ + bool password_needed; /* true if server demanded a password */ + bool gssapi_used; /* true if authenticated via gssapi */ + bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */ + bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */ + bool write_failed; /* have we had a write failure on sock? */ + char *write_err_msg; /* write error message, or NULL if OOM */ + + bool auth_required; /* require an authentication challenge from + * the server? */ + uint32 allowed_auth_methods; /* bitmask of acceptable AuthRequest + * codes */ + bool client_finished_auth; /* have we finished our half of the + * authentication exchange? */ + + + /* Transient state needed while establishing connection */ + PGTargetServerType target_server_type; /* desired session properties */ + PGLoadBalanceType load_balance_type; /* desired load balancing + * algorithm */ + bool try_next_addr; /* time to advance to next address/host? */ + bool try_next_host; /* time to advance to next connhost[]? */ + int naddr; /* number of addresses returned by getaddrinfo */ + int whichaddr; /* the address currently being tried */ + AddrInfo *addr; /* the array of addresses for the currently + * tried host */ + bool send_appname; /* okay to send application_name? */ + + /* Miscellaneous stuff */ + int be_pid; /* PID of backend --- needed for cancels */ + int be_key; /* key of backend --- needed for cancels */ + pgParameterStatus *pstatus; /* ParameterStatus data */ + int client_encoding; /* encoding id */ + bool std_strings; /* standard_conforming_strings */ + PGTernaryBool default_transaction_read_only; /* default_transaction_read_only */ + PGTernaryBool in_hot_standby; /* in_hot_standby */ + PGVerbosity verbosity; /* error/notice message verbosity */ + PGContextVisibility show_context; /* whether to show CONTEXT field */ + PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */ + pg_prng_state prng_state; /* prng state for load balancing connections */ + + + /* + * Buffer for data received from backend and not yet processed. + * + * NB: We rely on a maximum inBufSize/outBufSize of INT_MAX (and therefore + * an INT_MAX upper bound on the size of any and all packet contents) to + * avoid overflow; for example in reportErrorPosition(). Changing the type + * would require not only an adjustment to the overflow protection in + * pqCheck{In,Out}BufferSpace(), but also a careful audit of all libpq + * code that uses ints during size calculations. + */ + char *inBuffer; /* currently allocated buffer */ + int inBufSize; /* allocated size of buffer */ + int inStart; /* offset to first unconsumed data in buffer */ + int inCursor; /* next byte to tentatively consume */ + int inEnd; /* offset to first position after avail data */ + + /* Buffer for data not yet sent to backend */ + char *outBuffer; /* currently allocated buffer */ + int outBufSize; /* allocated size of buffer */ + int outCount; /* number of chars waiting in buffer */ + + /* State for constructing messages in outBuffer */ + int outMsgStart; /* offset to msg start (length word); if -1, + * msg has no length word */ + int outMsgEnd; /* offset to msg end (so far) */ + + /* Row processor interface workspace */ + PGdataValue *rowBuf; /* array for passing values to rowProcessor */ + int rowBufLen; /* number of entries allocated in rowBuf */ + + /* + * Status for asynchronous result construction. If result isn't NULL, it + * is a result being constructed or ready to return. If result is NULL + * and error_result is true, then we need to return a PGRES_FATAL_ERROR + * result, but haven't yet constructed it; text for the error has been + * appended to conn->errorMessage. (Delaying construction simplifies + * dealing with out-of-memory cases.) If next_result isn't NULL, it is a + * PGresult that will replace "result" after we return that one. + */ + PGresult *result; /* result being constructed */ + bool error_result; /* do we need to make an ERROR result? */ + PGresult *next_result; /* next result (used in single-row mode) */ + + /* Assorted state for SASL, SSL, GSS, etc */ + const pg_fe_sasl_mech *sasl; + void *sasl_state; + int scram_sha_256_iterations; + + /* SSL structures */ + bool ssl_in_use; + bool ssl_cert_requested; /* Did the server ask us for a cert? */ + bool ssl_cert_sent; /* Did we send one in reply? */ + +#ifdef USE_SSL + bool allow_ssl_try; /* Allowed to try SSL negotiation */ + bool wait_ssl_try; /* Delay SSL negotiation until after + * attempting normal connection */ +#ifdef USE_OPENSSL + SSL *ssl; /* SSL status, if have SSL connection */ + X509 *peer; /* X509 cert of server */ +#ifdef USE_SSL_ENGINE + ENGINE *engine; /* SSL engine, if any */ +#else + void *engine; /* dummy field to keep struct the same if + * OpenSSL version changes */ +#endif + bool crypto_loaded; /* Track if libcrypto locking callbacks have + * been done for this connection. This can be + * removed once support for OpenSSL 1.0.2 is + * removed as this locking is handled + * internally in OpenSSL >= 1.1.0. */ +#endif /* USE_OPENSSL */ +#endif /* USE_SSL */ + +#ifdef ENABLE_GSS + gss_ctx_id_t gctx; /* GSS context */ + gss_name_t gtarg_nam; /* GSS target name */ + + /* The following are encryption-only */ + bool try_gss; /* GSS attempting permitted */ + bool gssenc; /* GSS encryption is usable */ + gss_cred_id_t gcred; /* GSS credential temp storage. */ + + /* GSS encryption I/O state --- see fe-secure-gssapi.c */ + char *gss_SendBuffer; /* Encrypted data waiting to be sent */ + int gss_SendLength; /* End of data available in gss_SendBuffer */ + int gss_SendNext; /* Next index to send a byte from + * gss_SendBuffer */ + int gss_SendConsumed; /* Number of source bytes encrypted but + * not yet reported as sent */ + char *gss_RecvBuffer; /* Received, encrypted data */ + int gss_RecvLength; /* End of data available in gss_RecvBuffer */ + char *gss_ResultBuffer; /* Decryption of data in gss_RecvBuffer */ + int gss_ResultLength; /* End of data available in + * gss_ResultBuffer */ + int gss_ResultNext; /* Next index to read a byte from + * gss_ResultBuffer */ + uint32 gss_MaxPktSize; /* Maximum size we can encrypt and fit the + * results into our output buffer */ +#endif + +#ifdef ENABLE_SSPI + CredHandle *sspicred; /* SSPI credentials handle */ + CtxtHandle *sspictx; /* SSPI context */ + char *sspitarget; /* SSPI target name */ + int usesspi; /* Indicate if SSPI is in use on the + * connection */ +#endif + + /* + * Buffer for current error message. This is cleared at the start of any + * connection attempt or query cycle; after that, all code should append + * messages to it, never overwrite. + * + * In some situations we might report an error more than once in a query + * cycle. If so, errorMessage accumulates text from all the errors, and + * errorReported tracks how much we've already reported, so that the + * individual error PGresult objects don't contain duplicative text. + */ + PQExpBufferData errorMessage; /* expansible string */ + int errorReported; /* # bytes of string already reported */ + + /* Buffer for receiving various parts of messages */ + PQExpBufferData workBuffer; /* expansible string */ +}; + +/* PGcancel stores all data necessary to cancel a connection. A copy of this + * data is required to safely cancel a connection running on a different + * thread. + */ +struct pg_cancel +{ + SockAddr raddr; /* Remote address */ + int be_pid; /* PID of backend --- needed for cancels */ + int be_key; /* key of backend --- needed for cancels */ + int pgtcp_user_timeout; /* tcp user timeout */ + int keepalives; /* use TCP keepalives? */ + int keepalives_idle; /* time between TCP keepalives */ + int keepalives_interval; /* time between TCP keepalive + * retransmits */ + int keepalives_count; /* maximum number of TCP keepalive + * retransmits */ +}; + + +/* String descriptions of the ExecStatusTypes. + * direct use of this array is deprecated; call PQresStatus() instead. + */ +extern char *const pgresStatus[]; + + +#ifdef USE_SSL + +#ifndef WIN32 +#define USER_CERT_FILE ".postgresql/postgresql.crt" +#define USER_KEY_FILE ".postgresql/postgresql.key" +#define ROOT_CERT_FILE ".postgresql/root.crt" +#define ROOT_CRL_FILE ".postgresql/root.crl" +#else +/* On Windows, the "home" directory is already PostgreSQL-specific */ +#define USER_CERT_FILE "postgresql.crt" +#define USER_KEY_FILE "postgresql.key" +#define ROOT_CERT_FILE "root.crt" +#define ROOT_CRL_FILE "root.crl" +#endif + +#endif /* USE_SSL */ + +/* ---------------- + * Internal functions of libpq + * Functions declared here need to be visible across files of libpq, + * but are not intended to be called by applications. We use the + * convention "pqXXX" for internal functions, vs. the "PQxxx" names + * used for application-visible routines. + * ---------------- + */ + +/* === in fe-connect.c === */ + +extern void pqDropConnection(PGconn *conn, bool flushInput); +extern int pqPacketSend(PGconn *conn, char pack_type, + const void *buf, size_t buf_len); +extern bool pqGetHomeDirectory(char *buf, int bufsize); + +#ifdef ENABLE_THREAD_SAFETY +extern pgthreadlock_t pg_g_threadlock; + +#define pglock_thread() pg_g_threadlock(true) +#define pgunlock_thread() pg_g_threadlock(false) +#else +#define pglock_thread() ((void) 0) +#define pgunlock_thread() ((void) 0) +#endif + +/* === in fe-exec.c === */ + +extern void pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset); +extern void *pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary); +extern char *pqResultStrdup(PGresult *res, const char *str); +extern void pqClearAsyncResult(PGconn *conn); +extern void pqSaveErrorResult(PGconn *conn); +extern PGresult *pqPrepareAsyncResult(PGconn *conn); +extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3); +extern void pqSaveMessageField(PGresult *res, char code, + const char *value); +extern void pqSaveParameterStatus(PGconn *conn, const char *name, + const char *value); +extern int pqRowProcessor(PGconn *conn, const char **errmsgp); +extern void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, + bool gotSync); +extern int PQsendQueryContinue(PGconn *conn, const char *query); + +/* === in fe-protocol3.c === */ + +extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen, + const PQEnvironmentOption *options); +extern void pqParseInput3(PGconn *conn); +extern int pqGetErrorNotice3(PGconn *conn, bool isError); +extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, + PGVerbosity verbosity, PGContextVisibility show_context); +extern int pqGetNegotiateProtocolVersion3(PGconn *conn); +extern int pqGetCopyData3(PGconn *conn, char **buffer, int async); +extern int pqGetline3(PGconn *conn, char *s, int maxlen); +extern int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize); +extern int pqEndcopy3(PGconn *conn); +extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid, + int *result_buf, int *actual_result_len, + int result_is_int, + const PQArgBlock *args, int nargs); + +/* === in fe-misc.c === */ + + /* + * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for + * Get, EOF merely means the buffer is exhausted, not that there is + * necessarily any error. + */ +extern int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn); +extern int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn); +extern int pqGetc(char *result, PGconn *conn); +extern int pqPutc(char c, PGconn *conn); +extern int pqGets(PQExpBuffer buf, PGconn *conn); +extern int pqGets_append(PQExpBuffer buf, PGconn *conn); +extern int pqPuts(const char *s, PGconn *conn); +extern int pqGetnchar(char *s, size_t len, PGconn *conn); +extern int pqSkipnchar(size_t len, PGconn *conn); +extern int pqPutnchar(const char *s, size_t len, PGconn *conn); +extern int pqGetInt(int *result, size_t bytes, PGconn *conn); +extern int pqPutInt(int value, size_t bytes, PGconn *conn); +extern int pqPutMsgStart(char msg_type, PGconn *conn); +extern int pqPutMsgEnd(PGconn *conn); +extern int pqReadData(PGconn *conn); +extern int pqFlush(PGconn *conn); +extern int pqWait(int forRead, int forWrite, PGconn *conn); +extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, + time_t finish_time); +extern int pqReadReady(PGconn *conn); +extern int pqWriteReady(PGconn *conn); + +/* === in fe-secure.c === */ + +extern int pqsecure_initialize(PGconn *, bool, bool); +extern PostgresPollingStatusType pqsecure_open_client(PGconn *); +extern void pqsecure_close(PGconn *); +extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); +extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); +extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len); +extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len); + +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) +extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending); +extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, + bool got_epipe); +#endif + +/* === SSL === */ + +/* + * The SSL implementation provides these functions. + */ + +/* + * Implementation of PQinitSSL(). + */ +extern void pgtls_init_library(bool do_ssl, int do_crypto); + +/* + * Initialize SSL library. + * + * The conn parameter is only used to be able to pass back an error + * message - no connection-local setup is made here. do_ssl controls + * if SSL is initialized, and do_crypto does the same for the crypto + * part. + * + * Returns 0 if OK, -1 on failure (adding a message to conn->errorMessage). + */ +extern int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto); + +/* + * Begin or continue negotiating a secure session. + */ +extern PostgresPollingStatusType pgtls_open_client(PGconn *conn); + +/* + * Close SSL connection. + */ +extern void pgtls_close(PGconn *conn); + +/* + * Read data from a secure connection. + * + * On failure, this function is responsible for appending a suitable message + * to conn->errorMessage. The caller must still inspect errno, but only + * to determine whether to continue/retry after error. + */ +extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len); + +/* + * Is there unread data waiting in the SSL read buffer? + */ +extern bool pgtls_read_pending(PGconn *conn); + +/* + * Write data to a secure connection. + * + * On failure, this function is responsible for appending a suitable message + * to conn->errorMessage. The caller must still inspect errno, but only + * to determine whether to continue/retry after error. + */ +extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len); + +/* + * Get the hash of the server certificate, for SCRAM channel binding type + * tls-server-end-point. + * + * NULL is sent back to the caller in the event of an error, with an + * error message for the caller to consume. + * + * This is not supported with old versions of OpenSSL that don't have + * the X509_get_signature_nid() function. + */ +#if defined(USE_OPENSSL) && (defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO)) +#define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH +extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len); +#endif + +/* + * Verify that the server certificate matches the host name we connected to. + * + * The certificate's Common Name and Subject Alternative Names are considered. + * + * Returns 1 if the name matches, and 0 if it does not. On error, returns + * -1, and sets the libpq error message. + * + */ +extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, + int *names_examined, + char **first_name); + +/* === GSSAPI === */ + +#ifdef ENABLE_GSS + +/* + * Establish a GSSAPI-encrypted connection. + */ +extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn); + +/* + * Read and write functions for GSSAPI-encrypted connections, with internal + * buffering to handle nonblocking sockets. + */ +extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len); +extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len); +#endif + +/* === in fe-trace.c === */ + +extern void pqTraceOutputMessage(PGconn *conn, const char *message, + bool toServer); +extern void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message); + +/* === miscellaneous macros === */ + +/* + * Reset the conn's error-reporting state. + */ +#define pqClearConnErrorState(conn) \ + (resetPQExpBuffer(&(conn)->errorMessage), \ + (conn)->errorReported = 0) + +/* + * Check whether we have a PGresult pending to be returned --- either a + * constructed one in conn->result, or a "virtual" error result that we + * don't intend to materialize until the end of the query cycle. + */ +#define pgHavePendingResult(conn) \ + ((conn)->result != NULL || (conn)->error_result) + +/* + * this is so that we can check if a connection is non-blocking internally + * without the overhead of a function call + */ +#define pqIsnonblocking(conn) ((conn)->nonblocking) + +/* + * Connection's outbuffer threshold, for pipeline mode. + */ +#define OUTBUFFER_THRESHOLD 65536 + +#ifdef ENABLE_NLS +extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1); +extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2); +#else +#define libpq_gettext(x) (x) +#define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p)) +#endif +/* + * libpq code should use the above, not _(), since that would use the + * surrounding programs's message catalog. + */ +#undef _ + +extern void libpq_append_error(PQExpBuffer errorMessage, const char *fmt,...) pg_attribute_printf(2, 3); +extern void libpq_append_conn_error(PGconn *conn, const char *fmt,...) pg_attribute_printf(2, 3); + +/* + * These macros are needed to let error-handling code be portable between + * Unix and Windows. (ugh) + */ +#ifdef WIN32 +#define SOCK_ERRNO (WSAGetLastError()) +#define SOCK_STRERROR winsock_strerror +#define SOCK_ERRNO_SET(e) WSASetLastError(e) +#else +#define SOCK_ERRNO errno +#define SOCK_STRERROR strerror_r +#define SOCK_ERRNO_SET(e) (errno = (e)) +#endif + +#endif /* LIBPQ_INT_H */ diff --git a/install/include/postgresql/internal/libpq/pqcomm.h b/install/include/postgresql/internal/libpq/pqcomm.h new file mode 100644 index 00000000000..c85090259d9 --- /dev/null +++ b/install/include/postgresql/internal/libpq/pqcomm.h @@ -0,0 +1,163 @@ +/*------------------------------------------------------------------------- + * + * pqcomm.h + * Definitions common to frontends and backends. + * + * NOTE: for historical reasons, this does not correspond to pqcomm.c. + * pqcomm.c's routines are declared in libpq.h. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/pqcomm.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQCOMM_H +#define PQCOMM_H + +#include +#include +#include +#include + +typedef struct +{ + struct sockaddr_storage addr; + socklen_t salen; +} SockAddr; + +typedef struct +{ + int family; + SockAddr addr; +} AddrInfo; + +/* Configure the UNIX socket location for the well known port. */ + +#define UNIXSOCK_PATH(path, port, sockdir) \ + (AssertMacro(sockdir), \ + AssertMacro(*(sockdir) != '\0'), \ + snprintf(path, sizeof(path), "%s/.s.PGSQL.%d", \ + (sockdir), (port))) + +/* + * The maximum workable length of a socket path is what will fit into + * struct sockaddr_un. This is usually only 100 or so bytes :-(. + * + * For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(), + * then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes. + * (Because the standard API for getaddrinfo doesn't allow it to complain in + * a useful way when the socket pathname is too long, we have to test for + * this explicitly, instead of just letting the subroutine return an error.) + */ +#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path) + +/* + * A host that looks either like an absolute path or starts with @ is + * interpreted as a Unix-domain socket address. + */ +static inline bool +is_unixsock_path(const char *path) +{ + return is_absolute_path(path) || path[0] == '@'; +} + +/* + * These manipulate the frontend/backend protocol version number. + * + * The major number should be incremented for incompatible changes. The minor + * number should be incremented for compatible changes (eg. additional + * functionality). + * + * If a backend supports version m.n of the protocol it must actually support + * versions m.[0..n]. Backend support for version m-1 can be dropped after a + * `reasonable' length of time. + * + * A frontend isn't required to support anything other than the current + * version. + */ + +#define PG_PROTOCOL_MAJOR(v) ((v) >> 16) +#define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff) +#define PG_PROTOCOL(m,n) (((m) << 16) | (n)) + +/* + * The earliest and latest frontend/backend protocol version supported. + * (Only protocol version 3 is currently supported) + */ + +#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(3,0) +#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,0) + +typedef uint32 ProtocolVersion; /* FE/BE protocol version number */ + +typedef ProtocolVersion MsgType; + + +/* + * Packet lengths are 4 bytes in network byte order. + * + * The initial length is omitted from the packet layouts appearing below. + */ + +typedef uint32 PacketLen; + +extern PGDLLIMPORT bool Db_user_namespace; + +/* + * In protocol 3.0 and later, the startup packet length is not fixed, but + * we set an arbitrary limit on it anyway. This is just to prevent simple + * denial-of-service attacks via sending enough data to run the server + * out of memory. + */ +#define MAX_STARTUP_PACKET_LENGTH 10000 + + +/* These are the authentication request codes sent by the backend. */ + +#define AUTH_REQ_OK 0 /* User is authenticated */ +#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ +#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ +#define AUTH_REQ_PASSWORD 3 /* Password */ +#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ +#define AUTH_REQ_MD5 5 /* md5 password */ +/* 6 is available. It was used for SCM creds, not supported any more. */ +#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */ +#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */ +#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */ +#define AUTH_REQ_SASL 10 /* Begin SASL authentication */ +#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */ +#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */ +#define AUTH_REQ_MAX AUTH_REQ_SASL_FIN /* maximum AUTH_REQ_* value */ + +typedef uint32 AuthRequest; + + +/* + * A client can also send a cancel-current-operation request to the postmaster. + * This is uglier than sending it directly to the client's backend, but it + * avoids depending on out-of-band communication facilities. + * + * The cancel request code must not match any protocol version number + * we're ever likely to use. This random choice should do. + */ +#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678) + +typedef struct CancelRequestPacket +{ + /* Note that each field is stored in network byte order! */ + MsgType cancelRequestCode; /* code to identify a cancel request */ + uint32 backendPID; /* PID of client's backend */ + uint32 cancelAuthCode; /* secret key to authorize cancel */ +} CancelRequestPacket; + + +/* + * A client can also start by sending a SSL or GSSAPI negotiation request to + * get a secure channel. + */ +#define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679) +#define NEGOTIATE_GSS_CODE PG_PROTOCOL(1234,5680) + +#endif /* PQCOMM_H */ diff --git a/install/include/postgresql/internal/port.h b/install/include/postgresql/internal/port.h new file mode 100644 index 00000000000..2b2ea07ce5e --- /dev/null +++ b/install/include/postgresql/internal/port.h @@ -0,0 +1,550 @@ +/*------------------------------------------------------------------------- + * + * port.h + * Header for src/port/ compatibility functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PORT_H +#define PG_PORT_H + +#include + +/* + * Windows has enough specialized port stuff that we push most of it off + * into another file. + * Note: Some CYGWIN includes might #define WIN32. + */ +#if defined(WIN32) && !defined(__CYGWIN__) +#include "port/win32_port.h" +#endif + +/* socket has a different definition on WIN32 */ +#ifndef WIN32 +typedef int pgsocket; + +#define PGINVALID_SOCKET (-1) +#else +typedef SOCKET pgsocket; + +#define PGINVALID_SOCKET INVALID_SOCKET +#endif + +/* if platform lacks socklen_t, we assume this will work */ +#ifndef HAVE_SOCKLEN_T +typedef unsigned int socklen_t; +#endif + +/* non-blocking */ +extern bool pg_set_noblock(pgsocket sock); +extern bool pg_set_block(pgsocket sock); + +/* Portable path handling for Unix/Win32 (in path.c) */ + +extern bool has_drive_prefix(const char *path); +extern char *first_dir_separator(const char *filename); +extern char *last_dir_separator(const char *filename); +extern char *first_path_var_separator(const char *pathlist); +extern void join_path_components(char *ret_path, + const char *head, const char *tail); +extern void canonicalize_path(char *path); +extern void canonicalize_path_enc(char *path, int encoding); +extern void make_native_path(char *filename); +extern void cleanup_path(char *path); +extern bool path_contains_parent_reference(const char *path); +extern bool path_is_relative_and_below_cwd(const char *path); +extern bool path_is_prefix_of_path(const char *path1, const char *path2); +extern char *make_absolute_path(const char *path); +extern const char *get_progname(const char *argv0); +extern void get_share_path(const char *my_exec_path, char *ret_path); +extern void get_etc_path(const char *my_exec_path, char *ret_path); +extern void get_include_path(const char *my_exec_path, char *ret_path); +extern void get_pkginclude_path(const char *my_exec_path, char *ret_path); +extern void get_includeserver_path(const char *my_exec_path, char *ret_path); +extern void get_lib_path(const char *my_exec_path, char *ret_path); +extern void get_pkglib_path(const char *my_exec_path, char *ret_path); +extern void get_locale_path(const char *my_exec_path, char *ret_path); +extern void get_doc_path(const char *my_exec_path, char *ret_path); +extern void get_html_path(const char *my_exec_path, char *ret_path); +extern void get_man_path(const char *my_exec_path, char *ret_path); +extern bool get_home_path(char *ret_path); +extern void get_parent_directory(char *path); + +/* common/pgfnames.c */ +extern char **pgfnames(const char *path); +extern void pgfnames_cleanup(char **filenames); + +#define IS_NONWINDOWS_DIR_SEP(ch) ((ch) == '/') +#define is_nonwindows_absolute_path(filename) \ +( \ + IS_NONWINDOWS_DIR_SEP((filename)[0]) \ +) + +#define IS_WINDOWS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') +/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */ +#define is_windows_absolute_path(filename) \ +( \ + IS_WINDOWS_DIR_SEP((filename)[0]) || \ + (isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \ + IS_WINDOWS_DIR_SEP((filename)[2])) \ +) + +/* + * is_absolute_path and IS_DIR_SEP + * + * By using macros here we avoid needing to include path.c in libpq. + */ +#ifndef WIN32 +#define IS_DIR_SEP(ch) IS_NONWINDOWS_DIR_SEP(ch) +#define is_absolute_path(filename) is_nonwindows_absolute_path(filename) +#else +#define IS_DIR_SEP(ch) IS_WINDOWS_DIR_SEP(ch) +#define is_absolute_path(filename) is_windows_absolute_path(filename) +#endif + +/* + * This macro provides a centralized list of all errnos that identify + * hard failure of a previously-established network connection. + * The macro is intended to be used in a switch statement, in the form + * "case ALL_CONNECTION_FAILURE_ERRNOS:". + * + * Note: this groups EPIPE and ECONNRESET, which we take to indicate a + * probable server crash, with other errors that indicate loss of network + * connectivity without proving much about the server's state. Places that + * are actually reporting errors typically single out EPIPE and ECONNRESET, + * while allowing the network failures to be reported generically. + */ +#define ALL_CONNECTION_FAILURE_ERRNOS \ + EPIPE: \ + case ECONNRESET: \ + case ECONNABORTED: \ + case EHOSTDOWN: \ + case EHOSTUNREACH: \ + case ENETDOWN: \ + case ENETRESET: \ + case ENETUNREACH: \ + case ETIMEDOUT + +/* Portable locale initialization (in exec.c) */ +extern void set_pglocale_pgservice(const char *argv0, const char *app); + +/* Portable way to find and execute binaries (in exec.c) */ +extern int validate_exec(const char *path); +extern int find_my_exec(const char *argv0, char *retpath); +extern int find_other_exec(const char *argv0, const char *target, + const char *versionstr, char *retpath); +extern char *pipe_read_line(char *cmd, char *line, int maxsize); + +/* Doesn't belong here, but this is used with find_other_exec(), so... */ +#define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n" + +#ifdef EXEC_BACKEND +/* Disable ASLR before exec, for developer builds only (in exec.c) */ +extern int pg_disable_aslr(void); +#endif + + +#if defined(WIN32) || defined(__CYGWIN__) +#define EXE ".exe" +#else +#define EXE "" +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +#define DEVNULL "nul" +#else +#define DEVNULL "/dev/null" +#endif + +/* Portable delay handling */ +extern void pg_usleep(long microsec); + +/* Portable SQL-like case-independent comparisons and conversions */ +extern int pg_strcasecmp(const char *s1, const char *s2); +extern int pg_strncasecmp(const char *s1, const char *s2, size_t n); +extern unsigned char pg_toupper(unsigned char ch); +extern unsigned char pg_tolower(unsigned char ch); +extern unsigned char pg_ascii_toupper(unsigned char ch); +extern unsigned char pg_ascii_tolower(unsigned char ch); + +/* + * Beginning in v12, we always replace snprintf() and friends with our own + * implementation. This symbol is no longer consulted by the core code, + * but keep it defined anyway in case any extensions are looking at it. + */ +#define USE_REPL_SNPRINTF 1 + +/* + * Versions of libintl >= 0.13 try to replace printf() and friends with + * macros to their own versions that understand the %$ format. We do the + * same, so disable their macros, if they exist. + */ +#ifdef vsnprintf +#undef vsnprintf +#endif +#ifdef snprintf +#undef snprintf +#endif +#ifdef vsprintf +#undef vsprintf +#endif +#ifdef sprintf +#undef sprintf +#endif +#ifdef vfprintf +#undef vfprintf +#endif +#ifdef fprintf +#undef fprintf +#endif +#ifdef vprintf +#undef vprintf +#endif +#ifdef printf +#undef printf +#endif + +extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) pg_attribute_printf(3, 0); +extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); +extern int pg_vsprintf(char *str, const char *fmt, va_list args) pg_attribute_printf(2, 0); +extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3); +extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args) pg_attribute_printf(2, 0); +extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3); +extern int pg_vprintf(const char *fmt, va_list args) pg_attribute_printf(1, 0); +extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2); + +#ifndef WIN32 +/* + * We add a pg_ prefix as a warning that the Windows implementations have the + * non-standard side-effect of changing the current file position. + */ +#define pg_pread pread +#define pg_pwrite pwrite +#endif + +/* + * We use __VA_ARGS__ for printf to prevent replacing references to + * the "printf" format archetype in format() attribute declarations. + * That unfortunately means that taking a function pointer to printf + * will not do what we'd wish. (If you need to do that, you must name + * pg_printf explicitly.) For printf's sibling functions, use + * parameterless macros so that function pointers will work unsurprisingly. + */ +#define vsnprintf pg_vsnprintf +#define snprintf pg_snprintf +#define vsprintf pg_vsprintf +#define sprintf pg_sprintf +#define vfprintf pg_vfprintf +#define fprintf pg_fprintf +#define vprintf pg_vprintf +#define printf(...) pg_printf(__VA_ARGS__) + +/* This is also provided by snprintf.c */ +extern int pg_strfromd(char *str, size_t count, int precision, double value); + +/* Replace strerror() with our own, somewhat more robust wrapper */ +extern char *pg_strerror(int errnum); +#define strerror pg_strerror + +/* Likewise for strerror_r(); note we prefer the GNU API for that */ +extern char *pg_strerror_r(int errnum, char *buf, size_t buflen); +#define strerror_r pg_strerror_r +#define PG_STRERROR_R_BUFLEN 256 /* Recommended buffer size for strerror_r */ + +/* Wrap strsignal(), or provide our own version if necessary */ +extern const char *pg_strsignal(int signum); + +extern int pclose_check(FILE *stream); + +/* Global variable holding time zone information. */ +#if defined(WIN32) || defined(__CYGWIN__) +#define TIMEZONE_GLOBAL _timezone +#define TZNAME_GLOBAL _tzname +#else +#define TIMEZONE_GLOBAL timezone +#define TZNAME_GLOBAL tzname +#endif + +#if defined(WIN32) || defined(__CYGWIN__) +/* + * Win32 doesn't have reliable rename/unlink during concurrent access. + */ +extern int pgrename(const char *from, const char *to); +extern int pgunlink(const char *path); + +/* Include this first so later includes don't see these defines */ +#ifdef _MSC_VER +#include +#endif + +#define rename(from, to) pgrename(from, to) +#define unlink(path) pgunlink(path) +#endif /* defined(WIN32) || defined(__CYGWIN__) */ + +/* + * Win32 also doesn't have symlinks, but we can emulate them with + * junction points on newer Win32 versions. + * + * Cygwin has its own symlinks which work on Win95/98/ME where + * junction points don't, so use those instead. We have no way of + * knowing what type of system Cygwin binaries will be run on. + * Note: Some CYGWIN includes might #define WIN32. + */ +#if defined(WIN32) && !defined(__CYGWIN__) +extern int pgsymlink(const char *oldpath, const char *newpath); +extern int pgreadlink(const char *path, char *buf, size_t size); + +#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) +#define readlink(path, buf, size) pgreadlink(path, buf, size) +#endif + +extern bool rmtree(const char *path, bool rmtopdir); + +#if defined(WIN32) && !defined(__CYGWIN__) + +/* + * We want the 64-bit variant of lseek(). + * + * For Visual Studio, this must be after to avoid messing up its + * lseek() and _lseeki64() function declarations. + * + * For MinGW there is already a macro, so we have to undefine it (depending on + * _FILE_OFFSET_BITS, it may point at its own lseek64, but we don't want to + * count on that being set). + */ +#undef lseek +#define lseek(a,b,c) _lseeki64((a),(b),(c)) + +/* + * We want the 64-bit variant of chsize(). It sets errno and also returns it, + * so convert non-zero result to -1 to match POSIX. + * + * Prevent MinGW from declaring functions, and undefine its macro before we + * define our own. + */ +#ifndef _MSC_VER +#define FTRUNCATE_DEFINED +#include +#undef ftruncate +#endif +#define ftruncate(a,b) (_chsize_s((a),(b)) == 0 ? 0 : -1) + +/* + * open() and fopen() replacements to allow deletion of open files and + * passing of other special options. + */ +extern HANDLE pgwin32_open_handle(const char *, int, bool); +extern int pgwin32_open(const char *, int,...); +extern FILE *pgwin32_fopen(const char *, const char *); +#define open(a,b,c) pgwin32_open(a,b,c) +#define fopen(a,b) pgwin32_fopen(a,b) + +/* + * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want + * to use our popen wrapper, rather than plain _popen, so override that. For + * consistency, use our version of pclose, too. + */ +#ifdef popen +#undef popen +#endif +#ifdef pclose +#undef pclose +#endif + +/* + * system() and popen() replacements to enclose the command in an extra + * pair of quotes. + */ +extern int pgwin32_system(const char *command); +extern FILE *pgwin32_popen(const char *command, const char *type); + +#define system(a) pgwin32_system(a) +#define popen(a,b) pgwin32_popen(a,b) +#define pclose(a) _pclose(a) + +#else /* !WIN32 */ + +/* + * Win32 requires a special close for sockets and pipes, while on Unix + * close() does them all. + */ +#define closesocket close +#endif /* WIN32 */ + +/* + * On Windows, setvbuf() does not support _IOLBF mode, and interprets that + * as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0) + * crashes outright if "parameter validation" is enabled. Therefore, in + * places where we'd like to select line-buffered mode, we fall back to + * unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF + * directly in order to implement this behavior. + */ +#ifndef WIN32 +#define PG_IOLBF _IOLBF +#else +#define PG_IOLBF _IONBF +#endif + +/* + * Default "extern" declarations or macro substitutes for library routines. + * When necessary, these routines are provided by files in src/port/. + */ + +/* Type to use with fseeko/ftello */ +#ifndef WIN32 /* WIN32 is handled in port/win32_port.h */ +#define pgoff_t off_t +#endif + +#ifndef HAVE_GETPEEREID +/* On Windows, Perl might have incompatible definitions of uid_t and gid_t. */ +#ifndef PLPERL_HAVE_UID_GID +extern int getpeereid(int sock, uid_t *uid, gid_t *gid); +#endif +#endif + +/* + * Glibc doesn't use the builtin for clang due to a *gcc* bug in a version + * newer than the gcc compatibility clang claims to have. This would cause a + * *lot* of superfluous function calls, therefore revert when using clang. In + * C++ there's issues with libc++ (not libstdc++), so disable as well. + */ +#if defined(__clang__) && !defined(__cplusplus) +/* needs to be separate to not confuse other compilers */ +#if __has_builtin(__builtin_isinf) +/* need to include before, to avoid getting overwritten */ +#include +#undef isinf +#define isinf __builtin_isinf +#endif /* __has_builtin(isinf) */ +#endif /* __clang__ && !__cplusplus */ + +#ifndef HAVE_EXPLICIT_BZERO +extern void explicit_bzero(void *buf, size_t len); +#endif + +#ifdef HAVE_BUGGY_STRTOF +extern float pg_strtof(const char *nptr, char **endptr); +#define strtof(a,b) (pg_strtof((a),(b))) +#endif + +#ifdef WIN32 +/* src/port/win32link.c */ +extern int link(const char *src, const char *dst); +#endif + +#ifndef HAVE_MKDTEMP +extern char *mkdtemp(char *path); +#endif + +#ifndef HAVE_INET_ATON +#include +#include +extern int inet_aton(const char *cp, struct in_addr *addr); +#endif + +#if !HAVE_DECL_STRLCAT +extern size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#if !HAVE_DECL_STRLCPY +extern size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#if !HAVE_DECL_STRNLEN +extern size_t strnlen(const char *str, size_t maxlen); +#endif + +/* thread.c */ +#ifndef WIN32 +extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen); +extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen); +#endif + +extern void pg_qsort(void *base, size_t nel, size_t elsize, + int (*cmp) (const void *, const void *)); +extern int pg_qsort_strcmp(const void *a, const void *b); + +#define qsort(a,b,c,d) pg_qsort(a,b,c,d) + +typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg); + +extern void qsort_arg(void *base, size_t nel, size_t elsize, + qsort_arg_comparator cmp, void *arg); + +extern void qsort_interruptible(void *base, size_t nel, size_t elsize, + qsort_arg_comparator cmp, void *arg); + +extern void *bsearch_arg(const void *key, const void *base0, + size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg); + +/* port/chklocale.c */ +extern int pg_get_encoding_from_locale(const char *ctype, bool write_message); + +#if defined(WIN32) && !defined(FRONTEND) +extern int pg_codepage_to_encoding(UINT cp); +#endif + +/* port/inet_net_ntop.c */ +extern char *pg_inet_net_ntop(int af, const void *src, int bits, + char *dst, size_t size); + +/* port/pg_strong_random.c */ +extern void pg_strong_random_init(void); +extern bool pg_strong_random(void *buf, size_t len); + +/* + * pg_backend_random used to be a wrapper for pg_strong_random before + * Postgres 12 for the backend code. + */ +#define pg_backend_random pg_strong_random + +/* port/pgcheckdir.c */ +extern int pg_check_dir(const char *dir); + +/* port/pgmkdirp.c */ +extern int pg_mkdir_p(char *path, int omode); + +/* port/pqsignal.c (see also interfaces/libpq/legacy-pqsignal.c) */ +#ifdef FRONTEND +#define pqsignal pqsignal_fe +#endif +typedef void (*pqsigfunc) (SIGNAL_ARGS); +extern pqsigfunc pqsignal(int signo, pqsigfunc func); + +/* port/quotes.c */ +extern char *escape_single_quotes_ascii(const char *src); + +/* common/wait_error.c */ +extern char *wait_result_to_str(int exitstatus); +extern bool wait_result_is_signal(int exit_status, int signum); +extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found); +extern int wait_result_to_exit_code(int exit_status); + +/* + * Interfaces that we assume all Unix system have. We retain individual macros + * for better documentation. + * + * For symlink-related functions, there is often no need to test these macros, + * because we provided basic support on Windows that can work with absolute + * paths to directories. Code that wants to test for complete symlink support + * (including relative paths and non-directories) should be conditional on + * HAVE_READLINK or HAVE_SYMLINK. + */ +#ifndef WIN32 +#define HAVE_GETRLIMIT 1 +#define HAVE_POLL 1 +#define HAVE_POLL_H 1 +#define HAVE_READLINK 1 +#define HAVE_SETSID 1 +#define HAVE_SHM_OPEN 1 +#define HAVE_SYMLINK 1 +#endif + +#endif /* PG_PORT_H */ diff --git a/install/include/postgresql/internal/postgres_fe.h b/install/include/postgresql/internal/postgres_fe.h new file mode 100644 index 00000000000..5bc71dd0b37 --- /dev/null +++ b/install/include/postgresql/internal/postgres_fe.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * postgres_fe.h + * Primary include file for PostgreSQL client-side .c files + * + * This should be the first file included by PostgreSQL client libraries and + * application programs --- but not by backend modules, which should include + * postgres.h. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1995, Regents of the University of California + * + * src/include/postgres_fe.h + * + *------------------------------------------------------------------------- + */ +#ifndef POSTGRES_FE_H +#define POSTGRES_FE_H + +#ifndef FRONTEND +#define FRONTEND 1 +#endif + +#include "c.h" + +#include "common/fe_memutils.h" + +#endif /* POSTGRES_FE_H */ diff --git a/install/include/postgresql/internal/pqexpbuffer.h b/install/include/postgresql/internal/pqexpbuffer.h new file mode 100644 index 00000000000..020e94e3571 --- /dev/null +++ b/install/include/postgresql/internal/pqexpbuffer.h @@ -0,0 +1,192 @@ +/*------------------------------------------------------------------------- + * + * pqexpbuffer.h + * Declarations/definitions for "PQExpBuffer" functions. + * + * PQExpBuffer provides an indefinitely-extensible string data type. + * It can be used to buffer either ordinary C strings (null-terminated text) + * or arbitrary binary data. All storage is allocated with malloc(). + * + * This module is essentially the same as the backend's StringInfo data type, + * but it is intended for use in frontend libpq and client applications. + * Thus, it does not rely on palloc() nor elog(). + * + * It does rely on vsnprintf(); if configure finds that libc doesn't provide + * a usable vsnprintf(), then a copy of our own implementation of it will + * be linked into libpq. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/pqexpbuffer.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQEXPBUFFER_H +#define PQEXPBUFFER_H + +/*------------------------- + * PQExpBufferData holds information about an extensible string. + * data is the current buffer for the string (allocated with malloc). + * len is the current string length. There is guaranteed to be + * a terminating '\0' at data[len], although this is not very + * useful when the string holds binary data rather than text. + * maxlen is the allocated size in bytes of 'data', i.e. the maximum + * string size (including the terminating '\0' char) that we can + * currently store in 'data' without having to reallocate + * more space. We must always have maxlen > len. + * + * An exception occurs if we failed to allocate enough memory for the string + * buffer. In that case data points to a statically allocated empty string, + * and len = maxlen = 0. + *------------------------- + */ +typedef struct PQExpBufferData +{ + char *data; + size_t len; + size_t maxlen; +} PQExpBufferData; + +typedef PQExpBufferData *PQExpBuffer; + +/*------------------------ + * Test for a broken (out of memory) PQExpBuffer. + * When a buffer is "broken", all operations except resetting or deleting it + * are no-ops. + *------------------------ + */ +#define PQExpBufferBroken(str) \ + ((str) == NULL || (str)->maxlen == 0) + +/*------------------------ + * Same, but for use when using a static or local PQExpBufferData struct. + * For that, a null-pointer test is useless and may draw compiler warnings. + *------------------------ + */ +#define PQExpBufferDataBroken(buf) \ + ((buf).maxlen == 0) + +/*------------------------ + * Initial size of the data buffer in a PQExpBuffer. + * NB: this must be large enough to hold error messages that might + * be returned by PQrequestCancel(). + *------------------------ + */ +#define INITIAL_EXPBUFFER_SIZE 256 + +/*------------------------ + * There are two ways to create a PQExpBuffer object initially: + * + * PQExpBuffer stringptr = createPQExpBuffer(); + * Both the PQExpBufferData and the data buffer are malloc'd. + * + * PQExpBufferData string; + * initPQExpBuffer(&string); + * The data buffer is malloc'd but the PQExpBufferData is presupplied. + * This is appropriate if the PQExpBufferData is a field of another + * struct. + *------------------------- + */ + +/*------------------------ + * createPQExpBuffer + * Create an empty 'PQExpBufferData' & return a pointer to it. + */ +extern PQExpBuffer createPQExpBuffer(void); + +/*------------------------ + * initPQExpBuffer + * Initialize a PQExpBufferData struct (with previously undefined contents) + * to describe an empty string. + */ +extern void initPQExpBuffer(PQExpBuffer str); + +/*------------------------ + * To destroy a PQExpBuffer, use either: + * + * destroyPQExpBuffer(str); + * free()s both the data buffer and the PQExpBufferData. + * This is the inverse of createPQExpBuffer(). + * + * termPQExpBuffer(str) + * free()s the data buffer but not the PQExpBufferData itself. + * This is the inverse of initPQExpBuffer(). + * + * NOTE: some routines build up a string using PQExpBuffer, and then + * release the PQExpBufferData but return the data string itself to their + * caller. At that point the data string looks like a plain malloc'd + * string. + */ +extern void destroyPQExpBuffer(PQExpBuffer str); +extern void termPQExpBuffer(PQExpBuffer str); + +/*------------------------ + * resetPQExpBuffer + * Reset a PQExpBuffer to empty + * + * Note: if possible, a "broken" PQExpBuffer is returned to normal. + */ +extern void resetPQExpBuffer(PQExpBuffer str); + +/*------------------------ + * enlargePQExpBuffer + * Make sure there is enough space for 'needed' more bytes in the buffer + * ('needed' does not include the terminating null). + * + * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case + * the buffer is left in "broken" state.) + */ +extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed); + +/*------------------------ + * printfPQExpBuffer + * Format text data under the control of fmt (an sprintf-like format string) + * and insert it into str. More space is allocated to str if necessary. + * This is a convenience routine that does the same thing as + * resetPQExpBuffer() followed by appendPQExpBuffer(). + */ +extern void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); + +/*------------------------ + * appendPQExpBuffer + * Format text data under the control of fmt (an sprintf-like format string) + * and append it to whatever is already in str. More space is allocated + * to str if necessary. This is sort of like a combination of sprintf and + * strcat. + */ +extern void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); + +/*------------------------ + * appendPQExpBufferVA + * Attempt to format data and append it to str. Returns true if done + * (either successful or hard failure), false if need to retry. + * + * Caution: callers must be sure to preserve their entry-time errno + * when looping, in case the fmt contains "%m". + */ +extern bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) pg_attribute_printf(2, 0); + +/*------------------------ + * appendPQExpBufferStr + * Append the given string to a PQExpBuffer, allocating more space + * if necessary. + */ +extern void appendPQExpBufferStr(PQExpBuffer str, const char *data); + +/*------------------------ + * appendPQExpBufferChar + * Append a single byte to str. + * Like appendPQExpBuffer(str, "%c", ch) but much faster. + */ +extern void appendPQExpBufferChar(PQExpBuffer str, char ch); + +/*------------------------ + * appendBinaryPQExpBuffer + * Append arbitrary binary data to a PQExpBuffer, allocating more space + * if necessary. + */ +extern void appendBinaryPQExpBuffer(PQExpBuffer str, + const char *data, size_t datalen); + +#endif /* PQEXPBUFFER_H */ diff --git a/install/include/postgresql/server/access/amapi.h b/install/include/postgresql/server/access/amapi.h new file mode 100644 index 00000000000..2d70c5678c3 --- /dev/null +++ b/install/include/postgresql/server/access/amapi.h @@ -0,0 +1,296 @@ +/*------------------------------------------------------------------------- + * + * amapi.h + * API for Postgres index access methods. + * + * Copyright (c) 2015-2023, PostgreSQL Global Development Group + * + * src/include/access/amapi.h + * + *------------------------------------------------------------------------- + */ +#ifndef AMAPI_H +#define AMAPI_H + +#include "access/genam.h" + +/* + * We don't wish to include planner header files here, since most of an index + * AM's implementation isn't concerned with those data structures. To allow + * declaring amcostestimate_function here, use forward struct references. + */ +struct PlannerInfo; +struct IndexPath; + +/* Likewise, this file shouldn't depend on execnodes.h. */ +struct IndexInfo; + + +/* + * Properties for amproperty API. This list covers properties known to the + * core code, but an index AM can define its own properties, by matching the + * string property name. + */ +typedef enum IndexAMProperty +{ + AMPROP_UNKNOWN = 0, /* anything not known to core code */ + AMPROP_ASC, /* column properties */ + AMPROP_DESC, + AMPROP_NULLS_FIRST, + AMPROP_NULLS_LAST, + AMPROP_ORDERABLE, + AMPROP_DISTANCE_ORDERABLE, + AMPROP_RETURNABLE, + AMPROP_SEARCH_ARRAY, + AMPROP_SEARCH_NULLS, + AMPROP_CLUSTERABLE, /* index properties */ + AMPROP_INDEX_SCAN, + AMPROP_BITMAP_SCAN, + AMPROP_BACKWARD_SCAN, + AMPROP_CAN_ORDER, /* AM properties */ + AMPROP_CAN_UNIQUE, + AMPROP_CAN_MULTI_COL, + AMPROP_CAN_EXCLUDE, + AMPROP_CAN_INCLUDE +} IndexAMProperty; + +/* + * We use lists of this struct type to keep track of both operators and + * support functions while building or adding to an opclass or opfamily. + * amadjustmembers functions receive lists of these structs, and are allowed + * to alter their "ref" fields. + * + * The "ref" fields define how the pg_amop or pg_amproc entry should depend + * on the associated objects (that is, which dependency type to use, and + * which opclass or opfamily it should depend on). + * + * If ref_is_hard is true, the entry will have a NORMAL dependency on the + * operator or support func, and an INTERNAL dependency on the opclass or + * opfamily. This forces the opclass or opfamily to be dropped if the + * operator or support func is dropped, and requires the CASCADE option + * to do so. Nor will ALTER OPERATOR FAMILY DROP be allowed. This is + * the right behavior for objects that are essential to an opclass. + * + * If ref_is_hard is false, the entry will have an AUTO dependency on the + * operator or support func, and also an AUTO dependency on the opclass or + * opfamily. This allows ALTER OPERATOR FAMILY DROP, and causes that to + * happen automatically if the operator or support func is dropped. This + * is the right behavior for inessential ("loose") objects. + * + * We also make dependencies on lefttype/righttype, of the same strength as + * the dependency on the operator or support func, unless these dependencies + * are redundant with the dependency on the operator or support func. + */ +typedef struct OpFamilyMember +{ + bool is_func; /* is this an operator, or support func? */ + Oid object; /* operator or support func's OID */ + int number; /* strategy or support func number */ + Oid lefttype; /* lefttype */ + Oid righttype; /* righttype */ + Oid sortfamily; /* ordering operator's sort opfamily, or 0 */ + bool ref_is_hard; /* hard or soft dependency? */ + bool ref_is_family; /* is dependency on opclass or opfamily? */ + Oid refobjid; /* OID of opclass or opfamily */ +} OpFamilyMember; + + +/* + * Callback function signatures --- see indexam.sgml for more info. + */ + +/* build new index */ +typedef IndexBuildResult *(*ambuild_function) (Relation heapRelation, + Relation indexRelation, + struct IndexInfo *indexInfo); + +/* build empty index */ +typedef void (*ambuildempty_function) (Relation indexRelation); + +/* insert this tuple */ +typedef bool (*aminsert_function) (Relation indexRelation, + Datum *values, + bool *isnull, + ItemPointer heap_tid, + Relation heapRelation, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); + +/* bulk delete */ +typedef IndexBulkDeleteResult *(*ambulkdelete_function) (IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); + +/* post-VACUUM cleanup */ +typedef IndexBulkDeleteResult *(*amvacuumcleanup_function) (IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); + +/* can indexscan return IndexTuples? */ +typedef bool (*amcanreturn_function) (Relation indexRelation, int attno); + +/* estimate cost of an indexscan */ +typedef void (*amcostestimate_function) (struct PlannerInfo *root, + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); + +/* parse index reloptions */ +typedef bytea *(*amoptions_function) (Datum reloptions, + bool validate); + +/* report AM, index, or index column property */ +typedef bool (*amproperty_function) (Oid index_oid, int attno, + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); + +/* name of phase as used in progress reporting */ +typedef char *(*ambuildphasename_function) (int64 phasenum); + +/* validate definition of an opclass for this AM */ +typedef bool (*amvalidate_function) (Oid opclassoid); + +/* validate operators and support functions to be added to an opclass/family */ +typedef void (*amadjustmembers_function) (Oid opfamilyoid, + Oid opclassoid, + List *operators, + List *functions); + +/* prepare for index scan */ +typedef IndexScanDesc (*ambeginscan_function) (Relation indexRelation, + int nkeys, + int norderbys); + +/* (re)start index scan */ +typedef void (*amrescan_function) (IndexScanDesc scan, + ScanKey keys, + int nkeys, + ScanKey orderbys, + int norderbys); + +/* next valid tuple */ +typedef bool (*amgettuple_function) (IndexScanDesc scan, + ScanDirection direction); + +/* fetch all valid tuples */ +typedef int64 (*amgetbitmap_function) (IndexScanDesc scan, + TIDBitmap *tbm); + +/* end index scan */ +typedef void (*amendscan_function) (IndexScanDesc scan); + +/* mark current scan position */ +typedef void (*ammarkpos_function) (IndexScanDesc scan); + +/* restore marked scan position */ +typedef void (*amrestrpos_function) (IndexScanDesc scan); + +/* + * Callback function signatures - for parallel index scans. + */ + +/* estimate size of parallel scan descriptor */ +typedef Size (*amestimateparallelscan_function) (void); + +/* prepare for parallel index scan */ +typedef void (*aminitparallelscan_function) (void *target); + +/* (re)start parallel index scan */ +typedef void (*amparallelrescan_function) (IndexScanDesc scan); + +/* + * API struct for an index AM. Note this must be stored in a single palloc'd + * chunk of memory. + */ +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; + /* does AM store tuple information only at block granularity? */ + bool amsummarizing; + /* OR of parallel vacuum flags. See vacuum.h for flags. */ + uint8 amparallelvacuumoptions; + /* type of data stored in index, or InvalidOid if variable */ + Oid amkeytype; + + /* + * If you add new properties to either the above or the below lists, then + * they should also (usually) be exposed via the property API (see + * IndexAMProperty at the top of the file, and utils/adt/amutils.c). + */ + + /* 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; + + +/* Functions in access/index/amapi.c */ +extern IndexAmRoutine *GetIndexAmRoutine(Oid amhandler); +extern IndexAmRoutine *GetIndexAmRoutineByAmId(Oid amoid, bool noerror); + +#endif /* AMAPI_H */ diff --git a/install/include/postgresql/server/access/amvalidate.h b/install/include/postgresql/server/access/amvalidate.h new file mode 100644 index 00000000000..63d0e49e710 --- /dev/null +++ b/install/include/postgresql/server/access/amvalidate.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------- + * + * amvalidate.h + * Support routines for index access methods' amvalidate and + * amadjustmembers functions. + * + * Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/access/amvalidate.h + * + *------------------------------------------------------------------------- + */ +#ifndef AMVALIDATE_H +#define AMVALIDATE_H + +#include "utils/catcache.h" + + +/* Struct returned (in a list) by identify_opfamily_groups() */ +typedef struct OpFamilyOpFuncGroup +{ + Oid lefttype; /* amoplefttype/amproclefttype */ + Oid righttype; /* amoprighttype/amprocrighttype */ + uint64 operatorset; /* bitmask of operators with these types */ + uint64 functionset; /* bitmask of support funcs with these types */ +} OpFamilyOpFuncGroup; + + +/* Functions in access/index/amvalidate.c */ +extern List *identify_opfamily_groups(CatCList *oprlist, CatCList *proclist); +extern bool check_amproc_signature(Oid funcid, Oid restype, bool exact, + int minargs, int maxargs,...); +extern bool check_amoptsproc_signature(Oid funcid); +extern bool check_amop_signature(Oid opno, Oid restype, + Oid lefttype, Oid righttype); +extern Oid opclass_for_family_datatype(Oid amoid, Oid opfamilyoid, + Oid datatypeoid); +extern bool opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid); + +#endif /* AMVALIDATE_H */ diff --git a/install/include/postgresql/server/access/attmap.h b/install/include/postgresql/server/access/attmap.h new file mode 100644 index 00000000000..9156a1202bf --- /dev/null +++ b/install/include/postgresql/server/access/attmap.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * attmap.h + * Definitions for PostgreSQL attribute mappings + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/attmap.h + * + *------------------------------------------------------------------------- + */ +#ifndef ATTMAP_H +#define ATTMAP_H + +#include "access/attnum.h" +#include "access/tupdesc.h" + +/* + * Attribute mapping structure + * + * This maps attribute numbers between a pair of relations, designated + * 'input' and 'output' (most typically inheritance parent and child + * relations), whose common columns may have different attribute numbers. + * Such difference may arise due to the columns being ordered differently + * in the two relations or the two relations having dropped columns at + * different positions. + * + * 'maplen' is set to the number of attributes of the 'output' relation, + * taking into account any of its dropped attributes, with the corresponding + * elements of the 'attnums' array set to 0. + */ +typedef struct AttrMap +{ + AttrNumber *attnums; + int maplen; +} AttrMap; + +extern AttrMap *make_attrmap(int maplen); +extern void free_attrmap(AttrMap *map); + +/* Conversion routines to build mappings */ +extern AttrMap *build_attrmap_by_name(TupleDesc indesc, + TupleDesc outdesc, + bool missing_ok); +extern AttrMap *build_attrmap_by_name_if_req(TupleDesc indesc, + TupleDesc outdesc, + bool missing_ok); +extern AttrMap *build_attrmap_by_position(TupleDesc indesc, + TupleDesc outdesc, + const char *msg); + +#endif /* ATTMAP_H */ diff --git a/install/include/postgresql/server/access/attnum.h b/install/include/postgresql/server/access/attnum.h new file mode 100644 index 00000000000..4c4329526f1 --- /dev/null +++ b/install/include/postgresql/server/access/attnum.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * attnum.h + * POSTGRES attribute number definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/attnum.h + * + *------------------------------------------------------------------------- + */ +#ifndef ATTNUM_H +#define ATTNUM_H + + +/* + * user defined attribute numbers start at 1. -ay 2/95 + */ +typedef int16 AttrNumber; + +#define InvalidAttrNumber 0 +#define MaxAttrNumber 32767 + +/* ---------------- + * support macros + * ---------------- + */ +/* + * AttributeNumberIsValid + * True iff the attribute number is valid. + */ +#define AttributeNumberIsValid(attributeNumber) \ + ((bool) ((attributeNumber) != InvalidAttrNumber)) + +/* + * AttrNumberIsForUserDefinedAttr + * True iff the attribute number corresponds to a user defined attribute. + */ +#define AttrNumberIsForUserDefinedAttr(attributeNumber) \ + ((bool) ((attributeNumber) > 0)) + +/* + * AttrNumberGetAttrOffset + * Returns the attribute offset for an attribute number. + * + * Note: + * Assumes the attribute number is for a user defined attribute. + */ +#define AttrNumberGetAttrOffset(attNum) \ +( \ + AssertMacro(AttrNumberIsForUserDefinedAttr(attNum)), \ + ((attNum) - 1) \ +) + +/* + * AttrOffsetGetAttrNumber + * Returns the attribute number for an attribute offset. + */ +#define AttrOffsetGetAttrNumber(attributeOffset) \ + ((AttrNumber) (1 + (attributeOffset))) + +#endif /* ATTNUM_H */ diff --git a/install/include/postgresql/server/access/brin.h b/install/include/postgresql/server/access/brin.h new file mode 100644 index 00000000000..ed66f1b3d51 --- /dev/null +++ b/install/include/postgresql/server/access/brin.h @@ -0,0 +1,55 @@ +/* + * AM-callable functions for BRIN indexes + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/brin.h + */ +#ifndef BRIN_H +#define BRIN_H + +#include "nodes/execnodes.h" +#include "utils/relcache.h" + + +/* + * Storage type for BRIN's reloptions + */ +typedef struct BrinOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + BlockNumber pagesPerRange; + bool autosummarize; +} BrinOptions; + + +/* + * BrinStatsData represents stats data for planner use + */ +typedef struct BrinStatsData +{ + BlockNumber pagesPerRange; + BlockNumber revmapNumPages; +} BrinStatsData; + + +#define BRIN_DEFAULT_PAGES_PER_RANGE 128 +#define BrinGetPagesPerRange(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == BRIN_AM_OID), \ + (relation)->rd_options ? \ + ((BrinOptions *) (relation)->rd_options)->pagesPerRange : \ + BRIN_DEFAULT_PAGES_PER_RANGE) +#define BrinGetAutoSummarize(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == BRIN_AM_OID), \ + (relation)->rd_options ? \ + ((BrinOptions *) (relation)->rd_options)->autosummarize : \ + false) + + +extern void brinGetStats(Relation index, BrinStatsData *stats); + +#endif /* BRIN_H */ diff --git a/install/include/postgresql/server/access/brin_internal.h b/install/include/postgresql/server/access/brin_internal.h new file mode 100644 index 00000000000..97ddc925b27 --- /dev/null +++ b/install/include/postgresql/server/access/brin_internal.h @@ -0,0 +1,115 @@ +/* + * brin_internal.h + * internal declarations for BRIN indexes + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/brin_internal.h + */ +#ifndef BRIN_INTERNAL_H +#define BRIN_INTERNAL_H + +#include "access/amapi.h" +#include "storage/bufpage.h" +#include "utils/typcache.h" + + +/* + * A BrinDesc is a struct designed to enable decoding a BRIN tuple from the + * on-disk format to an in-memory tuple and vice-versa. + */ + +/* struct returned by "OpcInfo" amproc */ +typedef struct BrinOpcInfo +{ + /* Number of columns stored in an index column of this opclass */ + uint16 oi_nstored; + + /* Regular processing of NULLs in BrinValues? */ + bool oi_regular_nulls; + + /* Opaque pointer for the opclass' private use */ + void *oi_opaque; + + /* Type cache entries of the stored columns */ + TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; +} BrinOpcInfo; + +/* the size of a BrinOpcInfo for the given number of columns */ +#define SizeofBrinOpcInfo(ncols) \ + (offsetof(BrinOpcInfo, oi_typcache) + sizeof(TypeCacheEntry *) * ncols) + +typedef struct BrinDesc +{ + /* Containing memory context */ + MemoryContext bd_context; + + /* the index relation itself */ + Relation bd_index; + + /* tuple descriptor of the index relation */ + TupleDesc bd_tupdesc; + + /* cached copy for on-disk tuples; generated at first use */ + TupleDesc bd_disktdesc; + + /* total number of Datum entries that are stored on-disk for all columns */ + int bd_totalstored; + + /* per-column info; bd_tupdesc->natts entries long */ + BrinOpcInfo *bd_info[FLEXIBLE_ARRAY_MEMBER]; +} BrinDesc; + +/* + * Globally-known function support numbers for BRIN indexes. Individual + * opclasses can define more function support numbers, which must fall into + * BRIN_FIRST_OPTIONAL_PROCNUM .. BRIN_LAST_OPTIONAL_PROCNUM. + */ +#define BRIN_PROCNUM_OPCINFO 1 +#define BRIN_PROCNUM_ADDVALUE 2 +#define BRIN_PROCNUM_CONSISTENT 3 +#define BRIN_PROCNUM_UNION 4 +#define BRIN_MANDATORY_NPROCS 4 +#define BRIN_PROCNUM_OPTIONS 5 /* optional */ +/* procedure numbers up to 10 are reserved for BRIN future expansion */ +#define BRIN_FIRST_OPTIONAL_PROCNUM 11 +#define BRIN_LAST_OPTIONAL_PROCNUM 15 + +#undef BRIN_DEBUG + +#ifdef BRIN_DEBUG +#define BRIN_elog(args) elog args +#else +#define BRIN_elog(args) ((void) 0) +#endif + +/* brin.c */ +extern BrinDesc *brin_build_desc(Relation rel); +extern void brin_free_desc(BrinDesc *bdesc); +extern IndexBuildResult *brinbuild(Relation heap, Relation index, + struct IndexInfo *indexInfo); +extern void brinbuildempty(Relation index); +extern bool brininsert(Relation idxRel, Datum *values, bool *nulls, + ItemPointer heaptid, Relation heapRel, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); +extern IndexScanDesc brinbeginscan(Relation r, int nkeys, int norderbys); +extern int64 bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm); +extern void brinrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys); +extern void brinendscan(IndexScanDesc scan); +extern IndexBulkDeleteResult *brinbulkdelete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *brinvacuumcleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); +extern bytea *brinoptions(Datum reloptions, bool validate); + +/* brin_validate.c */ +extern bool brinvalidate(Oid opclassoid); + +#endif /* BRIN_INTERNAL_H */ diff --git a/install/include/postgresql/server/access/brin_page.h b/install/include/postgresql/server/access/brin_page.h new file mode 100644 index 00000000000..3670ca60102 --- /dev/null +++ b/install/include/postgresql/server/access/brin_page.h @@ -0,0 +1,96 @@ +/* + * brin_page.h + * Prototypes and definitions for BRIN page layouts + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/brin_page.h + * + * NOTES + * + * These structs should really be private to specific BRIN files, but it's + * useful to have them here so that they can be used by pageinspect and similar + * tools. + */ +#ifndef BRIN_PAGE_H +#define BRIN_PAGE_H + +#include "storage/block.h" +#include "storage/itemptr.h" + +/* + * Special area of BRIN pages. + * + * We define it in this odd way so that it always occupies the last + * MAXALIGN-sized element of each page. + */ +typedef struct BrinSpecialSpace +{ + uint16 vector[MAXALIGN(1) / sizeof(uint16)]; +} BrinSpecialSpace; + +/* + * Make the page type be the last half-word in the page, for consumption by + * pg_filedump and similar utilities. We don't really care much about the + * position of the "flags" half-word, but it's simpler to apply a consistent + * rule to both. + * + * See comments above GinPageOpaqueData. + */ +#define BrinPageType(page) \ + (((BrinSpecialSpace *) \ + PageGetSpecialPointer(page))->vector[MAXALIGN(1) / sizeof(uint16) - 1]) + +#define BrinPageFlags(page) \ + (((BrinSpecialSpace *) \ + PageGetSpecialPointer(page))->vector[MAXALIGN(1) / sizeof(uint16) - 2]) + +/* special space on all BRIN pages stores a "type" identifier */ +#define BRIN_PAGETYPE_META 0xF091 +#define BRIN_PAGETYPE_REVMAP 0xF092 +#define BRIN_PAGETYPE_REGULAR 0xF093 + +#define BRIN_IS_META_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_META) +#define BRIN_IS_REVMAP_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_REVMAP) +#define BRIN_IS_REGULAR_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_REGULAR) + +/* flags for BrinSpecialSpace */ +#define BRIN_EVACUATE_PAGE (1 << 0) + + +/* Metapage definitions */ +typedef struct BrinMetaPageData +{ + uint32 brinMagic; + uint32 brinVersion; + BlockNumber pagesPerRange; + BlockNumber lastRevmapPage; +} BrinMetaPageData; + +#define BRIN_CURRENT_VERSION 1 +#define BRIN_META_MAGIC 0xA8109CFA + +#define BRIN_METAPAGE_BLKNO 0 + +/* Definitions for revmap pages */ +typedef struct RevmapContents +{ + /* + * This array will fill all available space on the page. It should be + * declared [FLEXIBLE_ARRAY_MEMBER], but for some reason you can't do that + * in an otherwise-empty struct. + */ + ItemPointerData rm_tids[1]; +} RevmapContents; + +#define REVMAP_CONTENT_SIZE \ + (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - \ + offsetof(RevmapContents, rm_tids) - \ + MAXALIGN(sizeof(BrinSpecialSpace))) +/* max num of items in the array */ +#define REVMAP_PAGE_MAXITEMS \ + (REVMAP_CONTENT_SIZE / sizeof(ItemPointerData)) + +#endif /* BRIN_PAGE_H */ diff --git a/install/include/postgresql/server/access/brin_pageops.h b/install/include/postgresql/server/access/brin_pageops.h new file mode 100644 index 00000000000..041cc3241ac --- /dev/null +++ b/install/include/postgresql/server/access/brin_pageops.h @@ -0,0 +1,38 @@ +/* + * brin_pageops.h + * Prototypes for operating on BRIN pages. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/brin_pageops.h + */ +#ifndef BRIN_PAGEOPS_H +#define BRIN_PAGEOPS_H + +#include "access/brin_revmap.h" + +extern bool brin_doupdate(Relation idxrel, BlockNumber pagesPerRange, + BrinRevmap *revmap, BlockNumber heapBlk, + Buffer oldbuf, OffsetNumber oldoff, + const BrinTuple *origtup, Size origsz, + const BrinTuple *newtup, Size newsz, + bool samepage); +extern bool brin_can_do_samepage_update(Buffer buffer, Size origsz, + Size newsz); +extern OffsetNumber brin_doinsert(Relation idxrel, BlockNumber pagesPerRange, + BrinRevmap *revmap, Buffer *buffer, BlockNumber heapBlk, + BrinTuple *tup, Size itemsz); + +extern void brin_page_init(Page page, uint16 type); +extern void brin_metapage_init(Page page, BlockNumber pagesPerRange, + uint16 version); + +extern bool brin_start_evacuating_page(Relation idxRel, Buffer buf); +extern void brin_evacuate_page(Relation idxRel, BlockNumber pagesPerRange, + BrinRevmap *revmap, Buffer buf); + +extern void brin_page_cleanup(Relation idxrel, Buffer buf); + +#endif /* BRIN_PAGEOPS_H */ diff --git a/install/include/postgresql/server/access/brin_revmap.h b/install/include/postgresql/server/access/brin_revmap.h new file mode 100644 index 00000000000..75323630e07 --- /dev/null +++ b/install/include/postgresql/server/access/brin_revmap.h @@ -0,0 +1,41 @@ +/* + * brin_revmap.h + * Prototypes for BRIN reverse range maps + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/brin_revmap.h + */ + +#ifndef BRIN_REVMAP_H +#define BRIN_REVMAP_H + +#include "access/brin_tuple.h" +#include "storage/block.h" +#include "storage/buf.h" +#include "storage/itemptr.h" +#include "storage/off.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + +/* struct definition lives in brin_revmap.c */ +typedef struct BrinRevmap BrinRevmap; + +extern BrinRevmap *brinRevmapInitialize(Relation idxrel, + BlockNumber *pagesPerRange, Snapshot snapshot); +extern void brinRevmapTerminate(BrinRevmap *revmap); + +extern void brinRevmapExtend(BrinRevmap *revmap, + BlockNumber heapBlk); +extern Buffer brinLockRevmapPageForUpdate(BrinRevmap *revmap, + BlockNumber heapBlk); +extern void brinSetHeapBlockItemptr(Buffer buf, BlockNumber pagesPerRange, + BlockNumber heapBlk, ItemPointerData tid); +extern BrinTuple *brinGetTupleForHeapBlock(BrinRevmap *revmap, + BlockNumber heapBlk, Buffer *buf, OffsetNumber *off, + Size *size, int mode, Snapshot snapshot); +extern bool brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk); + +#endif /* BRIN_REVMAP_H */ diff --git a/install/include/postgresql/server/access/brin_tuple.h b/install/include/postgresql/server/access/brin_tuple.h new file mode 100644 index 00000000000..6f33ba6b256 --- /dev/null +++ b/install/include/postgresql/server/access/brin_tuple.h @@ -0,0 +1,112 @@ +/* + * brin_tuple.h + * Declarations for dealing with BRIN-specific tuples. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/brin_tuple.h + */ +#ifndef BRIN_TUPLE_H +#define BRIN_TUPLE_H + +#include "access/brin_internal.h" +#include "access/tupdesc.h" + +/* + * The BRIN opclasses may register serialization callback, in case the on-disk + * and in-memory representations differ (e.g. for performance reasons). + */ +typedef void (*brin_serialize_callback_type) (BrinDesc *bdesc, Datum src, Datum *dst); + +/* + * A BRIN index stores one index tuple per page range. Each index tuple + * has one BrinValues struct for each indexed column; in turn, each BrinValues + * has (besides the null flags) an array of Datum whose size is determined by + * the opclass. + */ +typedef struct BrinValues +{ + AttrNumber bv_attno; /* index attribute number */ + bool bv_hasnulls; /* are there any nulls in the page range? */ + bool bv_allnulls; /* are all values nulls in the page range? */ + Datum *bv_values; /* current accumulated values */ + Datum bv_mem_value; /* expanded accumulated values */ + MemoryContext bv_context; + brin_serialize_callback_type bv_serialize; +} BrinValues; + +/* + * This struct is used to represent an in-memory index tuple. The values can + * only be meaningfully decoded with an appropriate BrinDesc. + */ +typedef struct BrinMemTuple +{ + bool bt_placeholder; /* this is a placeholder tuple */ + bool bt_empty_range; /* range represents no tuples */ + BlockNumber bt_blkno; /* heap blkno that the tuple is for */ + MemoryContext bt_context; /* memcxt holding the bt_columns values */ + /* output arrays for brin_deform_tuple: */ + Datum *bt_values; /* values array */ + bool *bt_allnulls; /* allnulls array */ + bool *bt_hasnulls; /* hasnulls array */ + /* not an output array, but must be last */ + BrinValues bt_columns[FLEXIBLE_ARRAY_MEMBER]; +} BrinMemTuple; + +/* + * An on-disk BRIN tuple. This is possibly followed by a nulls bitmask, with + * room for 2 null bits (two bits for each indexed column); an opclass-defined + * number of Datum values for each column follow. + */ +typedef struct BrinTuple +{ + /* heap block number that the tuple is for */ + BlockNumber bt_blkno; + + /* --------------- + * bt_info is laid out in the following fashion: + * + * 7th (high) bit: has nulls + * 6th bit: is placeholder tuple + * 5th bit: range is empty + * 4-0 bit: offset of data + * --------------- + */ + uint8 bt_info; +} BrinTuple; + +#define SizeOfBrinTuple (offsetof(BrinTuple, bt_info) + sizeof(uint8)) + +/* + * bt_info manipulation macros + */ +#define BRIN_OFFSET_MASK 0x1F +#define BRIN_EMPTY_RANGE_MASK 0x20 +#define BRIN_PLACEHOLDER_MASK 0x40 +#define BRIN_NULLS_MASK 0x80 + +#define BrinTupleDataOffset(tup) ((Size) (((BrinTuple *) (tup))->bt_info & BRIN_OFFSET_MASK)) +#define BrinTupleHasNulls(tup) (((((BrinTuple *) (tup))->bt_info & BRIN_NULLS_MASK)) != 0) +#define BrinTupleIsPlaceholder(tup) (((((BrinTuple *) (tup))->bt_info & BRIN_PLACEHOLDER_MASK)) != 0) +#define BrinTupleIsEmptyRange(tup) (((((BrinTuple *) (tup))->bt_info & BRIN_EMPTY_RANGE_MASK)) != 0) + + +extern BrinTuple *brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, + BrinMemTuple *tuple, Size *size); +extern BrinTuple *brin_form_placeholder_tuple(BrinDesc *brdesc, + BlockNumber blkno, Size *size); +extern void brin_free_tuple(BrinTuple *tuple); +extern BrinTuple *brin_copy_tuple(BrinTuple *tuple, Size len, + BrinTuple *dest, Size *destsz); +extern bool brin_tuples_equal(const BrinTuple *a, Size alen, + const BrinTuple *b, Size blen); + +extern BrinMemTuple *brin_new_memtuple(BrinDesc *brdesc); +extern BrinMemTuple *brin_memtuple_initialize(BrinMemTuple *dtuple, + BrinDesc *brdesc); +extern BrinMemTuple *brin_deform_tuple(BrinDesc *brdesc, + BrinTuple *tuple, BrinMemTuple *dMemtuple); + +#endif /* BRIN_TUPLE_H */ diff --git a/install/include/postgresql/server/access/brin_xlog.h b/install/include/postgresql/server/access/brin_xlog.h new file mode 100644 index 00000000000..ae263a371f4 --- /dev/null +++ b/install/include/postgresql/server/access/brin_xlog.h @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------------- + * + * brin_xlog.h + * POSTGRES BRIN access XLOG definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/brin_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef BRIN_XLOG_H +#define BRIN_XLOG_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/bufpage.h" +#include "storage/itemptr.h" +#include "storage/relfilelocator.h" +#include "utils/relcache.h" + + +/* + * WAL record definitions for BRIN's WAL operations + * + * XLOG allows to store some information in high 4 bits of log + * record xl_info field. + */ +#define XLOG_BRIN_CREATE_INDEX 0x00 +#define XLOG_BRIN_INSERT 0x10 +#define XLOG_BRIN_UPDATE 0x20 +#define XLOG_BRIN_SAMEPAGE_UPDATE 0x30 +#define XLOG_BRIN_REVMAP_EXTEND 0x40 +#define XLOG_BRIN_DESUMMARIZE 0x50 + +#define XLOG_BRIN_OPMASK 0x70 +/* + * When we insert the first item on a new page, we restore the entire page in + * redo. + */ +#define XLOG_BRIN_INIT_PAGE 0x80 + +/* + * This is what we need to know about a BRIN index create. + * + * Backup block 0: metapage + */ +typedef struct xl_brin_createidx +{ + BlockNumber pagesPerRange; + uint16 version; +} xl_brin_createidx; +#define SizeOfBrinCreateIdx (offsetof(xl_brin_createidx, version) + sizeof(uint16)) + +/* + * This is what we need to know about a BRIN tuple insert + * + * Backup block 0: main page, block data is the new BrinTuple. + * Backup block 1: revmap page + */ +typedef struct xl_brin_insert +{ + BlockNumber heapBlk; + + /* extra information needed to update the revmap */ + BlockNumber pagesPerRange; + + /* offset number in the main page to insert the tuple to. */ + OffsetNumber offnum; +} xl_brin_insert; + +#define SizeOfBrinInsert (offsetof(xl_brin_insert, offnum) + sizeof(OffsetNumber)) + +/* + * A cross-page update is the same as an insert, but also stores information + * about the old tuple. + * + * Like in xl_brin_insert: + * Backup block 0: new page, block data includes the new BrinTuple. + * Backup block 1: revmap page + * + * And in addition: + * Backup block 2: old page + */ +typedef struct xl_brin_update +{ + /* offset number of old tuple on old page */ + OffsetNumber oldOffnum; + + xl_brin_insert insert; +} xl_brin_update; + +#define SizeOfBrinUpdate (offsetof(xl_brin_update, insert) + SizeOfBrinInsert) + +/* + * This is what we need to know about a BRIN tuple samepage update + * + * Backup block 0: updated page, with new BrinTuple as block data + */ +typedef struct xl_brin_samepage_update +{ + OffsetNumber offnum; +} xl_brin_samepage_update; + +#define SizeOfBrinSamepageUpdate (sizeof(OffsetNumber)) + +/* + * This is what we need to know about a revmap extension + * + * Backup block 0: metapage + * Backup block 1: new revmap page + */ +typedef struct xl_brin_revmap_extend +{ + /* + * XXX: This is actually redundant - the block number is stored as part of + * backup block 1. + */ + BlockNumber targetBlk; +} xl_brin_revmap_extend; + +#define SizeOfBrinRevmapExtend (offsetof(xl_brin_revmap_extend, targetBlk) + \ + sizeof(BlockNumber)) + +/* + * This is what we need to know about a range de-summarization + * + * Backup block 0: revmap page + * Backup block 1: regular page + */ +typedef struct xl_brin_desummarize +{ + BlockNumber pagesPerRange; + /* page number location to set to invalid */ + BlockNumber heapBlk; + /* offset of item to delete in regular index page */ + OffsetNumber regOffset; +} xl_brin_desummarize; + +#define SizeOfBrinDesummarize (offsetof(xl_brin_desummarize, regOffset) + \ + sizeof(OffsetNumber)) + + +extern void brin_redo(XLogReaderState *record); +extern void brin_desc(StringInfo buf, XLogReaderState *record); +extern const char *brin_identify(uint8 info); +extern void brin_mask(char *pagedata, BlockNumber blkno); + +#endif /* BRIN_XLOG_H */ diff --git a/install/include/postgresql/server/access/bufmask.h b/install/include/postgresql/server/access/bufmask.h new file mode 100644 index 00000000000..cf29ba49c66 --- /dev/null +++ b/install/include/postgresql/server/access/bufmask.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * bufmask.h + * Definitions for buffer masking routines, used to mask certain bits + * in a page which can be different when the WAL is generated + * and when the WAL is applied. This is really the job of each + * individual rmgr, but we make things easier by providing some + * common routines to handle cases which occur in multiple rmgrs. + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/access/bufmask.h + * + *------------------------------------------------------------------------- + */ + +#ifndef BUFMASK_H +#define BUFMASK_H + +#include "storage/block.h" +#include "storage/bufmgr.h" + +/* Marker used to mask pages consistently */ +#define MASK_MARKER 0 + +extern void mask_page_lsn_and_checksum(Page page); +extern void mask_page_hint_bits(Page page); +extern void mask_unused_space(Page page); +extern void mask_lp_flags(Page page); +extern void mask_page_content(Page page); + +#endif diff --git a/install/include/postgresql/server/access/clog.h b/install/include/postgresql/server/access/clog.h new file mode 100644 index 00000000000..d99444f073f --- /dev/null +++ b/install/include/postgresql/server/access/clog.h @@ -0,0 +1,63 @@ +/* + * clog.h + * + * PostgreSQL transaction-commit-log manager + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/clog.h + */ +#ifndef CLOG_H +#define CLOG_H + +#include "access/xlogreader.h" +#include "storage/sync.h" +#include "lib/stringinfo.h" + +/* + * Possible transaction statuses --- note that all-zeroes is the initial + * state. + * + * A "subcommitted" transaction is a committed subtransaction whose parent + * hasn't committed or aborted yet. + */ +typedef int XidStatus; + +#define TRANSACTION_STATUS_IN_PROGRESS 0x00 +#define TRANSACTION_STATUS_COMMITTED 0x01 +#define TRANSACTION_STATUS_ABORTED 0x02 +#define TRANSACTION_STATUS_SUB_COMMITTED 0x03 + +typedef struct xl_clog_truncate +{ + int pageno; + TransactionId oldestXact; + Oid oldestXactDb; +} xl_clog_truncate; + +extern void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, + TransactionId *subxids, XidStatus status, XLogRecPtr lsn); +extern XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn); + +extern Size CLOGShmemBuffers(void); +extern Size CLOGShmemSize(void); +extern void CLOGShmemInit(void); +extern void BootStrapCLOG(void); +extern void StartupCLOG(void); +extern void TrimCLOG(void); +extern void CheckPointCLOG(void); +extern void ExtendCLOG(TransactionId newestXact); +extern void TruncateCLOG(TransactionId oldestXact, Oid oldestxid_datoid); + +extern int clogsyncfiletag(const FileTag *ftag, char *path); + +/* XLOG stuff */ +#define CLOG_ZEROPAGE 0x00 +#define CLOG_TRUNCATE 0x10 + +extern void clog_redo(XLogReaderState *record); +extern void clog_desc(StringInfo buf, XLogReaderState *record); +extern const char *clog_identify(uint8 info); + +#endif /* CLOG_H */ diff --git a/install/include/postgresql/server/access/commit_ts.h b/install/include/postgresql/server/access/commit_ts.h new file mode 100644 index 00000000000..5087cdce51e --- /dev/null +++ b/install/include/postgresql/server/access/commit_ts.h @@ -0,0 +1,74 @@ +/* + * commit_ts.h + * + * PostgreSQL commit timestamp manager + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/commit_ts.h + */ +#ifndef COMMIT_TS_H +#define COMMIT_TS_H + +#include "access/xlog.h" +#include "datatype/timestamp.h" +#include "replication/origin.h" +#include "storage/sync.h" + + +extern PGDLLIMPORT bool track_commit_timestamp; + +extern void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, + TransactionId *subxids, TimestampTz timestamp, + RepOriginId nodeid); +extern bool TransactionIdGetCommitTsData(TransactionId xid, + TimestampTz *ts, RepOriginId *nodeid); +extern TransactionId GetLatestCommitTsData(TimestampTz *ts, + RepOriginId *nodeid); + +extern Size CommitTsShmemBuffers(void); +extern Size CommitTsShmemSize(void); +extern void CommitTsShmemInit(void); +extern void BootStrapCommitTs(void); +extern void StartupCommitTs(void); +extern void CommitTsParameterChange(bool newvalue, bool oldvalue); +extern void CompleteCommitTsInitialization(void); +extern void CheckPointCommitTs(void); +extern void ExtendCommitTs(TransactionId newestXact); +extern void TruncateCommitTs(TransactionId oldestXact); +extern void SetCommitTsLimit(TransactionId oldestXact, + TransactionId newestXact); +extern void AdvanceOldestCommitTsXid(TransactionId oldestXact); + +extern int committssyncfiletag(const FileTag *ftag, char *path); + +/* XLOG stuff */ +#define COMMIT_TS_ZEROPAGE 0x00 +#define COMMIT_TS_TRUNCATE 0x10 + +typedef struct xl_commit_ts_set +{ + TimestampTz timestamp; + RepOriginId nodeid; + TransactionId mainxid; + /* subxact Xids follow */ +} xl_commit_ts_set; + +#define SizeOfCommitTsSet (offsetof(xl_commit_ts_set, mainxid) + \ + sizeof(TransactionId)) + +typedef struct xl_commit_ts_truncate +{ + int pageno; + TransactionId oldestXid; +} xl_commit_ts_truncate; + +#define SizeOfCommitTsTruncate (offsetof(xl_commit_ts_truncate, oldestXid) + \ + sizeof(TransactionId)) + +extern void commit_ts_redo(XLogReaderState *record); +extern void commit_ts_desc(StringInfo buf, XLogReaderState *record); +extern const char *commit_ts_identify(uint8 info); + +#endif /* COMMIT_TS_H */ diff --git a/install/include/postgresql/server/access/detoast.h b/install/include/postgresql/server/access/detoast.h new file mode 100644 index 00000000000..908e1fc6919 --- /dev/null +++ b/install/include/postgresql/server/access/detoast.h @@ -0,0 +1,82 @@ +/*------------------------------------------------------------------------- + * + * detoast.h + * Access to compressed and external varlena values. + * + * Copyright (c) 2000-2023, PostgreSQL Global Development Group + * + * src/include/access/detoast.h + * + *------------------------------------------------------------------------- + */ +#ifndef DETOAST_H +#define DETOAST_H + +/* + * Macro to fetch the possibly-unaligned contents of an EXTERNAL datum + * into a local "struct varatt_external" toast pointer. This should be + * just a memcpy, but some versions of gcc seem to produce broken code + * that assumes the datum contents are aligned. Introducing an explicit + * intermediate "varattrib_1b_e *" variable seems to fix it. + */ +#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \ +do { \ + varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \ + Assert(VARATT_IS_EXTERNAL(attre)); \ + Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \ + memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \ +} while (0) + +/* Size of an EXTERNAL datum that contains a standard TOAST pointer */ +#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external)) + +/* Size of an EXTERNAL datum that contains an indirection pointer */ +#define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect)) + +/* ---------- + * detoast_external_attr() - + * + * Fetches an external stored attribute from the toast + * relation. Does NOT decompress it, if stored external + * in compressed format. + * ---------- + */ +extern struct varlena *detoast_external_attr(struct varlena *attr); + +/* ---------- + * detoast_attr() - + * + * Fully detoasts one attribute, fetching and/or decompressing + * it as needed. + * ---------- + */ +extern struct varlena *detoast_attr(struct varlena *attr); + +/* ---------- + * detoast_attr_slice() - + * + * Fetches only the specified portion of an attribute. + * (Handles all cases for attribute storage) + * ---------- + */ +extern struct varlena *detoast_attr_slice(struct varlena *attr, + int32 sliceoffset, + int32 slicelength); + +/* ---------- + * toast_raw_datum_size - + * + * Return the raw (detoasted) size of a varlena datum + * ---------- + */ +extern Size toast_raw_datum_size(Datum value); + +/* ---------- + * toast_datum_size - + * + * Return the storage size of a varlena datum + * ---------- + */ +extern Size toast_datum_size(Datum value); + +#endif /* DETOAST_H */ diff --git a/install/include/postgresql/server/access/genam.h b/install/include/postgresql/server/access/genam.h new file mode 100644 index 00000000000..7188d42894e --- /dev/null +++ b/install/include/postgresql/server/access/genam.h @@ -0,0 +1,243 @@ +/*------------------------------------------------------------------------- + * + * genam.h + * POSTGRES generalized index access method definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/genam.h + * + *------------------------------------------------------------------------- + */ +#ifndef GENAM_H +#define GENAM_H + +#include "access/sdir.h" +#include "access/skey.h" +#include "nodes/tidbitmap.h" +#include "storage/lockdefs.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + +/* We don't want this file to depend on execnodes.h. */ +struct IndexInfo; + +/* + * Struct for statistics returned by ambuild + */ +typedef struct IndexBuildResult +{ + double heap_tuples; /* # of tuples seen in parent table */ + double index_tuples; /* # of tuples inserted into index */ +} IndexBuildResult; + +/* + * Struct for input arguments passed to ambulkdelete and amvacuumcleanup + * + * num_heap_tuples is accurate only when estimated_count is false; + * otherwise it's just an estimate (currently, the estimate is the + * prior value of the relation's pg_class.reltuples field, so it could + * even be -1). It will always just be an estimate during ambulkdelete. + */ +typedef struct IndexVacuumInfo +{ + Relation index; /* the index being vacuumed */ + Relation heaprel; /* the heap relation the index belongs to */ + bool analyze_only; /* ANALYZE (without any actual vacuum) */ + bool report_progress; /* emit progress.h status reports */ + bool estimated_count; /* num_heap_tuples is an estimate */ + int message_level; /* ereport level for progress messages */ + double num_heap_tuples; /* tuples remaining in heap */ + BufferAccessStrategy strategy; /* access strategy for reads */ +} IndexVacuumInfo; + +/* + * Struct for statistics returned by ambulkdelete and amvacuumcleanup + * + * This struct is normally allocated by the first ambulkdelete call and then + * passed along through subsequent ones until amvacuumcleanup; however, + * amvacuumcleanup must be prepared to allocate it in the case where no + * ambulkdelete calls were made (because no tuples needed deletion). + * Note that an index AM could choose to return a larger struct + * of which this is just the first field; this provides a way for ambulkdelete + * to communicate additional private data to amvacuumcleanup. + * + * Note: pages_newly_deleted is the number of pages in the index that were + * deleted by the current vacuum operation. pages_deleted and pages_free + * refer to free space within the index file. + * + * Note: Some index AMs may compute num_index_tuples by reference to + * num_heap_tuples, in which case they should copy the estimated_count field + * from IndexVacuumInfo. + */ +typedef struct IndexBulkDeleteResult +{ + BlockNumber num_pages; /* pages remaining in index */ + bool estimated_count; /* num_index_tuples is an estimate */ + double num_index_tuples; /* tuples remaining */ + double tuples_removed; /* # removed during vacuum operation */ + BlockNumber pages_newly_deleted; /* # pages marked deleted by us */ + BlockNumber pages_deleted; /* # pages marked deleted (could be by us) */ + BlockNumber pages_free; /* # pages available for reuse */ +} IndexBulkDeleteResult; + +/* Typedef for callback function to determine if a tuple is bulk-deletable */ +typedef bool (*IndexBulkDeleteCallback) (ItemPointer itemptr, void *state); + +/* struct definitions appear in relscan.h */ +typedef struct IndexScanDescData *IndexScanDesc; +typedef struct SysScanDescData *SysScanDesc; + +typedef struct ParallelIndexScanDescData *ParallelIndexScanDesc; + +/* + * Enumeration specifying the type of uniqueness check to perform in + * index_insert(). + * + * UNIQUE_CHECK_YES is the traditional Postgres immediate check, possibly + * blocking to see if a conflicting transaction commits. + * + * For deferrable unique constraints, UNIQUE_CHECK_PARTIAL is specified at + * insertion time. The index AM should test if the tuple is unique, but + * should not throw error, block, or prevent the insertion if the tuple + * appears not to be unique. We'll recheck later when it is time for the + * constraint to be enforced. The AM must return true if the tuple is + * known unique, false if it is possibly non-unique. In the "true" case + * it is safe to omit the later recheck. + * + * When it is time to recheck the deferred constraint, a pseudo-insertion + * call is made with UNIQUE_CHECK_EXISTING. The tuple is already in the + * index in this case, so it should not be inserted again. Rather, just + * check for conflicting live tuples (possibly blocking). + */ +typedef enum IndexUniqueCheck +{ + UNIQUE_CHECK_NO, /* Don't do any uniqueness checking */ + UNIQUE_CHECK_YES, /* Enforce uniqueness at insertion time */ + UNIQUE_CHECK_PARTIAL, /* Test uniqueness, but no error */ + UNIQUE_CHECK_EXISTING /* Check if existing tuple is unique */ +} IndexUniqueCheck; + + +/* Nullable "ORDER BY col op const" distance */ +typedef struct IndexOrderByDistance +{ + double value; + bool isnull; +} IndexOrderByDistance; + +/* + * generalized index_ interface routines (in indexam.c) + */ + +/* + * IndexScanIsValid + * True iff the index scan is valid. + */ +#define IndexScanIsValid(scan) PointerIsValid(scan) + +extern Relation index_open(Oid relationId, LOCKMODE lockmode); +extern Relation try_index_open(Oid relationId, LOCKMODE lockmode); +extern void index_close(Relation relation, LOCKMODE lockmode); + +extern bool index_insert(Relation indexRelation, + Datum *values, bool *isnull, + ItemPointer heap_t_ctid, + Relation heapRelation, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); + +extern IndexScanDesc index_beginscan(Relation heapRelation, + Relation indexRelation, + Snapshot snapshot, + int nkeys, int norderbys); +extern IndexScanDesc index_beginscan_bitmap(Relation indexRelation, + Snapshot snapshot, + int nkeys); +extern void index_rescan(IndexScanDesc scan, + ScanKey keys, int nkeys, + ScanKey orderbys, int norderbys); +extern void index_endscan(IndexScanDesc scan); +extern void index_markpos(IndexScanDesc scan); +extern void index_restrpos(IndexScanDesc scan); +extern Size index_parallelscan_estimate(Relation indexRelation, Snapshot snapshot); +extern void index_parallelscan_initialize(Relation heapRelation, + Relation indexRelation, Snapshot snapshot, + ParallelIndexScanDesc target); +extern void index_parallelrescan(IndexScanDesc scan); +extern IndexScanDesc index_beginscan_parallel(Relation heaprel, + Relation indexrel, int nkeys, int norderbys, + ParallelIndexScanDesc pscan); +extern ItemPointer index_getnext_tid(IndexScanDesc scan, + ScanDirection direction); +struct TupleTableSlot; +extern bool index_fetch_heap(IndexScanDesc scan, struct TupleTableSlot *slot); +extern bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, + struct TupleTableSlot *slot); +extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap); + +extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info, + IndexBulkDeleteResult *istat, + IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *istat); +extern bool index_can_return(Relation indexRelation, int attno); +extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum, + uint16 procnum); +extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum, + uint16 procnum); +extern void index_store_float8_orderby_distances(IndexScanDesc scan, + Oid *orderByTypes, + IndexOrderByDistance *distances, + bool recheckOrderBy); +extern bytea *index_opclass_options(Relation indrel, AttrNumber attnum, + Datum attoptions, bool validate); + + +/* + * index access method support routines (in genam.c) + */ +extern IndexScanDesc RelationGetIndexScan(Relation indexRelation, + int nkeys, int norderbys); +extern void IndexScanEnd(IndexScanDesc scan); +extern char *BuildIndexValueDescription(Relation indexRelation, + Datum *values, bool *isnull); +extern TransactionId index_compute_xid_horizon_for_tuples(Relation irel, + Relation hrel, + Buffer ibuf, + OffsetNumber *itemnos, + int nitems); + +/* + * heap-or-index access to system catalogs (in genam.c) + */ +extern SysScanDesc systable_beginscan(Relation heapRelation, + Oid indexId, + bool indexOK, + Snapshot snapshot, + int nkeys, ScanKey key); +extern HeapTuple systable_getnext(SysScanDesc sysscan); +extern bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup); +extern void systable_endscan(SysScanDesc sysscan); +extern SysScanDesc systable_beginscan_ordered(Relation heapRelation, + Relation indexRelation, + Snapshot snapshot, + int nkeys, ScanKey key); +extern HeapTuple systable_getnext_ordered(SysScanDesc sysscan, + ScanDirection direction); +extern void systable_endscan_ordered(SysScanDesc sysscan); +extern void systable_inplace_update_begin(Relation relation, + Oid indexId, + bool indexOK, + Snapshot snapshot, + int nkeys, const ScanKeyData *key, + HeapTuple *oldtupcopy, + void **state); +extern void systable_inplace_update_finish(void *state, HeapTuple tuple); +extern void systable_inplace_update_cancel(void *state); + +#endif /* GENAM_H */ diff --git a/install/include/postgresql/server/access/generic_xlog.h b/install/include/postgresql/server/access/generic_xlog.h new file mode 100644 index 00000000000..1c6bdced950 --- /dev/null +++ b/install/include/postgresql/server/access/generic_xlog.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + * + * generic_xlog.h + * Generic xlog API definition. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/generic_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef GENERIC_XLOG_H +#define GENERIC_XLOG_H + +#include "access/xlog.h" +#include "access/xlog_internal.h" +#include "access/xloginsert.h" +#include "storage/bufpage.h" +#include "utils/rel.h" + +#define MAX_GENERIC_XLOG_PAGES XLR_NORMAL_MAX_BLOCK_ID + +/* Flag bits for GenericXLogRegisterBuffer */ +#define GENERIC_XLOG_FULL_IMAGE 0x0001 /* write full-page image */ + +/* state of generic xlog record construction */ +struct GenericXLogState; +typedef struct GenericXLogState GenericXLogState; + +/* API for construction of generic xlog records */ +extern GenericXLogState *GenericXLogStart(Relation relation); +extern GenericXLogState *GenericXLogStartLogged(bool is_logged); +extern Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, + int flags); +extern XLogRecPtr GenericXLogFinish(GenericXLogState *state); +extern void GenericXLogAbort(GenericXLogState *state); + +/* functions defined for rmgr */ +extern void generic_redo(XLogReaderState *record); +extern const char *generic_identify(uint8 info); +extern void generic_desc(StringInfo buf, XLogReaderState *record); +extern void generic_mask(char *page, BlockNumber blkno); + +#endif /* GENERIC_XLOG_H */ diff --git a/install/include/postgresql/server/access/gin.h b/install/include/postgresql/server/access/gin.h new file mode 100644 index 00000000000..f1655065289 --- /dev/null +++ b/install/include/postgresql/server/access/gin.h @@ -0,0 +1,91 @@ +/*-------------------------------------------------------------------------- + * gin.h + * Public header file for Generalized Inverted Index access method. + * + * Copyright (c) 2006-2023, PostgreSQL Global Development Group + * + * src/include/access/gin.h + *-------------------------------------------------------------------------- + */ +#ifndef GIN_H +#define GIN_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/block.h" +#include "utils/relcache.h" + + +/* + * amproc indexes for inverted indexes. + */ +#define GIN_COMPARE_PROC 1 +#define GIN_EXTRACTVALUE_PROC 2 +#define GIN_EXTRACTQUERY_PROC 3 +#define GIN_CONSISTENT_PROC 4 +#define GIN_COMPARE_PARTIAL_PROC 5 +#define GIN_TRICONSISTENT_PROC 6 +#define GIN_OPTIONS_PROC 7 +#define GINNProcs 7 + +/* + * searchMode settings for extractQueryFn. + */ +#define GIN_SEARCH_MODE_DEFAULT 0 +#define GIN_SEARCH_MODE_INCLUDE_EMPTY 1 +#define GIN_SEARCH_MODE_ALL 2 +#define GIN_SEARCH_MODE_EVERYTHING 3 /* for internal use only */ + +/* + * GinStatsData represents stats data for planner use + */ +typedef struct GinStatsData +{ + BlockNumber nPendingPages; + BlockNumber nTotalPages; + BlockNumber nEntryPages; + BlockNumber nDataPages; + int64 nEntries; + int32 ginVersion; +} GinStatsData; + +/* + * A ternary value used by tri-consistent functions. + * + * This must be of the same size as a bool because some code will cast a + * pointer to a bool to a pointer to a GinTernaryValue. + */ +typedef char GinTernaryValue; + +StaticAssertDecl(sizeof(GinTernaryValue) == sizeof(bool), + "sizes of GinTernaryValue and bool are not equal"); + +#define GIN_FALSE 0 /* item is not present / does not match */ +#define GIN_TRUE 1 /* item is present / matches */ +#define GIN_MAYBE 2 /* don't know if item is present / don't know + * if matches */ + +static inline GinTernaryValue +DatumGetGinTernaryValue(Datum X) +{ + return (GinTernaryValue) X; +} + +static inline Datum +GinTernaryValueGetDatum(GinTernaryValue X) +{ + return (Datum) X; +} + +#define PG_RETURN_GIN_TERNARY_VALUE(x) return GinTernaryValueGetDatum(x) + +/* GUC parameters */ +extern PGDLLIMPORT int GinFuzzySearchLimit; +extern PGDLLIMPORT int gin_pending_list_limit; + +/* ginutil.c */ +extern void ginGetStats(Relation index, GinStatsData *stats); +extern void ginUpdateStats(Relation index, const GinStatsData *stats, + bool is_build); + +#endif /* GIN_H */ diff --git a/install/include/postgresql/server/access/gin_private.h b/install/include/postgresql/server/access/gin_private.h new file mode 100644 index 00000000000..6da64928b66 --- /dev/null +++ b/install/include/postgresql/server/access/gin_private.h @@ -0,0 +1,502 @@ +/*-------------------------------------------------------------------------- + * gin_private.h + * header file for postgres inverted index access method implementation. + * + * Copyright (c) 2006-2023, PostgreSQL Global Development Group + * + * src/include/access/gin_private.h + *-------------------------------------------------------------------------- + */ +#ifndef GIN_PRIVATE_H +#define GIN_PRIVATE_H + +#include "access/amapi.h" +#include "access/gin.h" +#include "access/ginblock.h" +#include "access/itup.h" +#include "catalog/pg_am_d.h" +#include "fmgr.h" +#include "lib/rbtree.h" +#include "storage/bufmgr.h" + +/* + * Storage type for GIN's reloptions + */ +typedef struct GinOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + bool useFastUpdate; /* use fast updates? */ + int pendingListCleanupSize; /* maximum size of pending list */ +} GinOptions; + +#define GIN_DEFAULT_USE_FASTUPDATE true +#define GinGetUseFastUpdate(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == GIN_AM_OID), \ + (relation)->rd_options ? \ + ((GinOptions *) (relation)->rd_options)->useFastUpdate : GIN_DEFAULT_USE_FASTUPDATE) +#define GinGetPendingListCleanupSize(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == GIN_AM_OID), \ + (relation)->rd_options && \ + ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize != -1 ? \ + ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize : \ + gin_pending_list_limit) + + +/* Macros for buffer lock/unlock operations */ +#define GIN_UNLOCK BUFFER_LOCK_UNLOCK +#define GIN_SHARE BUFFER_LOCK_SHARE +#define GIN_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE + + +/* + * GinState: working data structure describing the index being worked on + */ +typedef struct GinState +{ + Relation index; + bool oneCol; /* true if single-column index */ + + /* + * origTupdesc is the nominal tuple descriptor of the index, ie, the i'th + * attribute shows the key type (not the input data type!) of the i'th + * index column. In a single-column index this describes the actual leaf + * index tuples. In a multi-column index, the actual leaf tuples contain + * a smallint column number followed by a key datum of the appropriate + * type for that column. We set up tupdesc[i] to describe the actual + * rowtype of the index tuples for the i'th column, ie, (int2, keytype). + * Note that in any case, leaf tuples contain more data than is known to + * the TupleDesc; see access/gin/README for details. + */ + TupleDesc origTupdesc; + TupleDesc tupdesc[INDEX_MAX_KEYS]; + + /* + * Per-index-column opclass support functions + */ + FmgrInfo compareFn[INDEX_MAX_KEYS]; + FmgrInfo extractValueFn[INDEX_MAX_KEYS]; + FmgrInfo extractQueryFn[INDEX_MAX_KEYS]; + FmgrInfo consistentFn[INDEX_MAX_KEYS]; + FmgrInfo triConsistentFn[INDEX_MAX_KEYS]; + FmgrInfo comparePartialFn[INDEX_MAX_KEYS]; /* optional method */ + /* canPartialMatch[i] is true if comparePartialFn[i] is valid */ + bool canPartialMatch[INDEX_MAX_KEYS]; + /* Collations to pass to the support functions */ + Oid supportCollation[INDEX_MAX_KEYS]; +} GinState; + + +/* ginutil.c */ +extern bytea *ginoptions(Datum reloptions, bool validate); +extern void initGinState(GinState *state, Relation index); +extern Buffer GinNewBuffer(Relation index); +extern void GinInitBuffer(Buffer b, uint32 f); +extern void GinInitPage(Page page, uint32 f, Size pageSize); +extern void GinInitMetabuffer(Buffer b); +extern int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, + Datum a, GinNullCategory categorya, + Datum b, GinNullCategory categoryb); +extern int ginCompareAttEntries(GinState *ginstate, + OffsetNumber attnuma, Datum a, GinNullCategory categorya, + OffsetNumber attnumb, Datum b, GinNullCategory categoryb); +extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attnum, + Datum value, bool isNull, + int32 *nentries, GinNullCategory **categories); + +extern OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple); +extern Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple, + GinNullCategory *category); + +/* gininsert.c */ +extern IndexBuildResult *ginbuild(Relation heap, Relation index, + struct IndexInfo *indexInfo); +extern void ginbuildempty(Relation index); +extern bool gininsert(Relation index, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); +extern void ginEntryInsert(GinState *ginstate, + OffsetNumber attnum, Datum key, GinNullCategory category, + ItemPointerData *items, uint32 nitem, + GinStatsData *buildStats); + +/* ginbtree.c */ + +typedef struct GinBtreeStack +{ + BlockNumber blkno; + Buffer buffer; + OffsetNumber off; + ItemPointerData iptr; + /* predictNumber contains predicted number of pages on current level */ + uint32 predictNumber; + struct GinBtreeStack *parent; +} GinBtreeStack; + +typedef struct GinBtreeData *GinBtree; + +/* Return codes for GinBtreeData.beginPlaceToPage method */ +typedef enum +{ + GPTP_NO_WORK, + GPTP_INSERT, + GPTP_SPLIT +} GinPlaceToPageRC; + +typedef struct GinBtreeData +{ + /* search methods */ + BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *); + BlockNumber (*getLeftMostChild) (GinBtree, Page); + bool (*isMoveRight) (GinBtree, Page); + bool (*findItem) (GinBtree, GinBtreeStack *); + + /* insert methods */ + OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber); + GinPlaceToPageRC (*beginPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void **, Page *, Page *); + void (*execPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void *); + void *(*prepareDownlink) (GinBtree, Buffer); + void (*fillRoot) (GinBtree, Page, BlockNumber, Page, BlockNumber, Page); + + bool isData; + + Relation index; + BlockNumber rootBlkno; + GinState *ginstate; /* not valid in a data scan */ + bool fullScan; + bool isBuild; + + /* Search key for Entry tree */ + OffsetNumber entryAttnum; + Datum entryKey; + GinNullCategory entryCategory; + + /* Search key for data tree (posting tree) */ + ItemPointerData itemptr; +} GinBtreeData; + +/* This represents a tuple to be inserted to entry tree. */ +typedef struct +{ + IndexTuple entry; /* tuple to insert */ + bool isDelete; /* delete old tuple at same offset? */ +} GinBtreeEntryInsertData; + +/* + * This represents an itempointer, or many itempointers, to be inserted to + * a data (posting tree) leaf page + */ +typedef struct +{ + ItemPointerData *items; + uint32 nitem; + uint32 curitem; +} GinBtreeDataLeafInsertData; + +/* + * For internal data (posting tree) pages, the insertion payload is a + * PostingItem + */ + +extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode, + bool rootConflictCheck, Snapshot snapshot); +extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode); +extern void freeGinBtreeStack(GinBtreeStack *stack); +extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack, + void *insertdata, GinStatsData *buildStats); + +/* ginentrypage.c */ +extern IndexTuple GinFormTuple(GinState *ginstate, + OffsetNumber attnum, Datum key, GinNullCategory category, + Pointer data, Size dataSize, int nipd, bool errorTooBig); +extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum, + Datum key, GinNullCategory category, + GinState *ginstate); +extern void ginEntryFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage); +extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum, + IndexTuple itup, int *nitems); + +/* gindatapage.c */ +extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast); +extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm); +extern BlockNumber createPostingTree(Relation index, + ItemPointerData *items, uint32 nitems, + GinStatsData *buildStats, Buffer entrybuffer); +extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset); +extern void GinPageDeletePostingItem(Page page, OffsetNumber offset); +extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, + ItemPointerData *items, uint32 nitem, + GinStatsData *buildStats); +extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno, Snapshot snapshot); +extern void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage); + +/* + * This is declared in ginvacuum.c, but is passed between ginVacuumItemPointers + * and ginVacuumPostingTreeLeaf and as an opaque struct, so we need a forward + * declaration for it. + */ +typedef struct GinVacuumState GinVacuumState; + +extern void ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, + GinVacuumState *gvs); + +/* ginscan.c */ + +/* + * GinScanKeyData describes a single GIN index qualifier expression. + * + * From each qual expression, we extract one or more specific index search + * conditions, which are represented by GinScanEntryData. It's quite + * possible for identical search conditions to be requested by more than + * one qual expression, in which case we merge such conditions to have just + * one unique GinScanEntry --- this is particularly important for efficiency + * when dealing with full-index-scan entries. So there can be multiple + * GinScanKeyData.scanEntry pointers to the same GinScanEntryData. + * + * In each GinScanKeyData, nentries is the true number of entries, while + * nuserentries is the number that extractQueryFn returned (which is what + * we report to consistentFn). The "user" entries must come first. + */ +typedef struct GinScanKeyData *GinScanKey; + +typedef struct GinScanEntryData *GinScanEntry; + +typedef struct GinScanKeyData +{ + /* Real number of entries in scanEntry[] (always > 0) */ + uint32 nentries; + /* Number of entries that extractQueryFn and consistentFn know about */ + uint32 nuserentries; + + /* array of GinScanEntry pointers, one per extracted search condition */ + GinScanEntry *scanEntry; + + /* + * At least one of the entries in requiredEntries must be present for a + * tuple to match the overall qual. + * + * additionalEntries contains entries that are needed by the consistent + * function to decide if an item matches, but are not sufficient to + * satisfy the qual without entries from requiredEntries. + */ + GinScanEntry *requiredEntries; + int nrequired; + GinScanEntry *additionalEntries; + int nadditional; + + /* array of check flags, reported to consistentFn */ + GinTernaryValue *entryRes; + bool (*boolConsistentFn) (GinScanKey key); + GinTernaryValue (*triConsistentFn) (GinScanKey key); + FmgrInfo *consistentFmgrInfo; + FmgrInfo *triConsistentFmgrInfo; + Oid collation; + + /* other data needed for calling consistentFn */ + Datum query; + /* NB: these three arrays have only nuserentries elements! */ + Datum *queryValues; + GinNullCategory *queryCategories; + Pointer *extra_data; + StrategyNumber strategy; + int32 searchMode; + OffsetNumber attnum; + + /* + * An excludeOnly scan key is not able to enumerate all matching tuples. + * That is, to be semantically correct on its own, it would need to have a + * GIN_CAT_EMPTY_QUERY scanEntry, but it doesn't. Such a key can still be + * used to filter tuples returned by other scan keys, so we will get the + * right answers as long as there's at least one non-excludeOnly scan key + * for each index attribute considered by the search. For efficiency + * reasons we don't want to have unnecessary GIN_CAT_EMPTY_QUERY entries, + * so we will convert an excludeOnly scan key to non-excludeOnly (by + * adding a GIN_CAT_EMPTY_QUERY scanEntry) only if there are no other + * non-excludeOnly scan keys. + */ + bool excludeOnly; + + /* + * Match status data. curItem is the TID most recently tested (could be a + * lossy-page pointer). curItemMatches is true if it passes the + * consistentFn test; if so, recheckCurItem is the recheck flag. + * isFinished means that all the input entry streams are finished, so this + * key cannot succeed for any later TIDs. + */ + ItemPointerData curItem; + bool curItemMatches; + bool recheckCurItem; + bool isFinished; +} GinScanKeyData; + +typedef struct GinScanEntryData +{ + /* query key and other information from extractQueryFn */ + Datum queryKey; + GinNullCategory queryCategory; + bool isPartialMatch; + Pointer extra_data; + StrategyNumber strategy; + int32 searchMode; + OffsetNumber attnum; + + /* Current page in posting tree */ + Buffer buffer; + + /* current ItemPointer to heap */ + ItemPointerData curItem; + + /* for a partial-match or full-scan query, we accumulate all TIDs here */ + TIDBitmap *matchBitmap; + TBMIterator *matchIterator; + TBMIterateResult *matchResult; + + /* used for Posting list and one page in Posting tree */ + ItemPointerData *list; + int nlist; + OffsetNumber offset; + + bool isFinished; + bool reduceResult; + uint32 predictNumberResult; + GinBtreeData btree; +} GinScanEntryData; + +typedef struct GinScanOpaqueData +{ + MemoryContext tempCtx; + GinState ginstate; + + GinScanKey keys; /* one per scan qualifier expr */ + uint32 nkeys; + + GinScanEntry *entries; /* one per index search condition */ + uint32 totalentries; + uint32 allocentries; /* allocated length of entries[] */ + + MemoryContext keyCtx; /* used to hold key and entry data */ + + bool isVoidRes; /* true if query is unsatisfiable */ +} GinScanOpaqueData; + +typedef GinScanOpaqueData *GinScanOpaque; + +extern IndexScanDesc ginbeginscan(Relation rel, int nkeys, int norderbys); +extern void ginendscan(IndexScanDesc scan); +extern void ginrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys); +extern void ginNewScanKey(IndexScanDesc scan); +extern void ginFreeScanKeys(GinScanOpaque so); + +/* ginget.c */ +extern int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm); + +/* ginlogic.c */ +extern void ginInitConsistentFunction(GinState *ginstate, GinScanKey key); + +/* ginvacuum.c */ +extern IndexBulkDeleteResult *ginbulkdelete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *ginvacuumcleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); +extern ItemPointer ginVacuumItemPointers(GinVacuumState *gvs, + ItemPointerData *items, int nitem, int *nremaining); + +/* ginvalidate.c */ +extern bool ginvalidate(Oid opclassoid); +extern void ginadjustmembers(Oid opfamilyoid, + Oid opclassoid, + List *operators, + List *functions); + +/* ginbulk.c */ +typedef struct GinEntryAccumulator +{ + RBTNode rbtnode; + Datum key; + GinNullCategory category; + OffsetNumber attnum; + bool shouldSort; + ItemPointerData *list; + uint32 maxcount; /* allocated size of list[] */ + uint32 count; /* current number of list[] entries */ +} GinEntryAccumulator; + +typedef struct +{ + GinState *ginstate; + Size allocatedMemory; + GinEntryAccumulator *entryallocator; + uint32 eas_used; + RBTree *tree; + RBTreeIterator tree_walk; +} BuildAccumulator; + +extern void ginInitBA(BuildAccumulator *accum); +extern void ginInsertBAEntries(BuildAccumulator *accum, + ItemPointer heapptr, OffsetNumber attnum, + Datum *entries, GinNullCategory *categories, + int32 nentries); +extern void ginBeginBAScan(BuildAccumulator *accum); +extern ItemPointerData *ginGetBAEntry(BuildAccumulator *accum, + OffsetNumber *attnum, Datum *key, GinNullCategory *category, + uint32 *n); + +/* ginfast.c */ + +typedef struct GinTupleCollector +{ + IndexTuple *tuples; + uint32 ntuples; + uint32 lentuples; + uint32 sumsize; +} GinTupleCollector; + +extern void ginHeapTupleFastInsert(GinState *ginstate, + GinTupleCollector *collector); +extern void ginHeapTupleFastCollect(GinState *ginstate, + GinTupleCollector *collector, + OffsetNumber attnum, Datum value, bool isNull, + ItemPointer ht_ctid); +extern void ginInsertCleanup(GinState *ginstate, bool full_clean, + bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats); + +/* ginpostinglist.c */ + +extern GinPostingList *ginCompressPostingList(const ItemPointer ipd, int nipd, + int maxsize, int *nwritten); +extern int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int len, TIDBitmap *tbm); + +extern ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len, + int *ndecoded_out); +extern ItemPointer ginPostingListDecode(GinPostingList *plist, int *ndecoded_out); +extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na, + ItemPointerData *b, uint32 nb, + int *nmerged); + +/* + * Merging the results of several gin scans compares item pointers a lot, + * so we want this to be inlined. + */ +static inline int +ginCompareItemPointers(ItemPointer a, ItemPointer b) +{ + uint64 ia = (uint64) GinItemPointerGetBlockNumber(a) << 32 | GinItemPointerGetOffsetNumber(a); + uint64 ib = (uint64) GinItemPointerGetBlockNumber(b) << 32 | GinItemPointerGetOffsetNumber(b); + + if (ia == ib) + return 0; + else if (ia > ib) + return 1; + else + return -1; +} + +extern int ginTraverseLock(Buffer buffer, bool searchMode); + +#endif /* GIN_PRIVATE_H */ diff --git a/install/include/postgresql/server/access/ginblock.h b/install/include/postgresql/server/access/ginblock.h new file mode 100644 index 00000000000..c59790ec5a9 --- /dev/null +++ b/install/include/postgresql/server/access/ginblock.h @@ -0,0 +1,346 @@ +/*-------------------------------------------------------------------------- + * ginblock.h + * details of structures stored in GIN index blocks + * + * Copyright (c) 2006-2023, PostgreSQL Global Development Group + * + * src/include/access/ginblock.h + *-------------------------------------------------------------------------- + */ +#ifndef GINBLOCK_H +#define GINBLOCK_H + +#include "access/transam.h" +#include "storage/block.h" +#include "storage/bufpage.h" +#include "storage/itemptr.h" +#include "storage/off.h" + +/* + * Page opaque data in an inverted index page. + * + * Note: GIN does not include a page ID word as do the other index types. + * This is OK because the opaque data is only 8 bytes and so can be reliably + * distinguished by size. Revisit this if the size ever increases. + * Further note: as of 9.2, SP-GiST also uses 8-byte special space, as does + * BRIN as of 9.5. This is still OK, as long as GIN isn't using all of the + * high-order bits in its flags word, because that way the flags word cannot + * match the page IDs used by SP-GiST and BRIN. + */ +typedef struct GinPageOpaqueData +{ + BlockNumber rightlink; /* next page if any */ + OffsetNumber maxoff; /* number of PostingItems on GIN_DATA & + * ~GIN_LEAF page. On GIN_LIST page, number of + * heap tuples. */ + uint16 flags; /* see bit definitions below */ +} GinPageOpaqueData; + +typedef GinPageOpaqueData *GinPageOpaque; + +#define GIN_DATA (1 << 0) +#define GIN_LEAF (1 << 1) +#define GIN_DELETED (1 << 2) +#define GIN_META (1 << 3) +#define GIN_LIST (1 << 4) +#define GIN_LIST_FULLROW (1 << 5) /* makes sense only on GIN_LIST page */ +#define GIN_INCOMPLETE_SPLIT (1 << 6) /* page was split, but parent not + * updated */ +#define GIN_COMPRESSED (1 << 7) + +/* Page numbers of fixed-location pages */ +#define GIN_METAPAGE_BLKNO (0) +#define GIN_ROOT_BLKNO (1) + +typedef struct GinMetaPageData +{ + /* + * Pointers to head and tail of pending list, which consists of GIN_LIST + * pages. These store fast-inserted entries that haven't yet been moved + * into the regular GIN structure. + */ + BlockNumber head; + BlockNumber tail; + + /* + * Free space in bytes in the pending list's tail page. + */ + uint32 tailFreeSize; + + /* + * We store both number of pages and number of heap tuples that are in the + * pending list. + */ + BlockNumber nPendingPages; + int64 nPendingHeapTuples; + + /* + * Statistics for planner use (accurate as of last VACUUM) + */ + BlockNumber nTotalPages; + BlockNumber nEntryPages; + BlockNumber nDataPages; + int64 nEntries; + + /* + * GIN version number (ideally this should have been at the front, but too + * late now. Don't move it!) + * + * Currently 2 (for indexes initialized in 9.4 or later) + * + * Version 1 (indexes initialized in version 9.1, 9.2 or 9.3), is + * compatible, but may contain uncompressed posting tree (leaf) pages and + * posting lists. They will be converted to compressed format when + * modified. + * + * Version 0 (indexes initialized in 9.0 or before) is compatible but may + * be missing null entries, including both null keys and placeholders. + * Reject full-index-scan attempts on such indexes. + */ + int32 ginVersion; +} GinMetaPageData; + +#define GIN_CURRENT_VERSION 2 + +#define GinPageGetMeta(p) \ + ((GinMetaPageData *) PageGetContents(p)) + +/* + * Macros for accessing a GIN index page's opaque data + */ +#define GinPageGetOpaque(page) ( (GinPageOpaque) PageGetSpecialPointer(page) ) + +#define GinPageIsLeaf(page) ( (GinPageGetOpaque(page)->flags & GIN_LEAF) != 0 ) +#define GinPageSetLeaf(page) ( GinPageGetOpaque(page)->flags |= GIN_LEAF ) +#define GinPageSetNonLeaf(page) ( GinPageGetOpaque(page)->flags &= ~GIN_LEAF ) +#define GinPageIsData(page) ( (GinPageGetOpaque(page)->flags & GIN_DATA) != 0 ) +#define GinPageSetData(page) ( GinPageGetOpaque(page)->flags |= GIN_DATA ) +#define GinPageIsList(page) ( (GinPageGetOpaque(page)->flags & GIN_LIST) != 0 ) +#define GinPageSetList(page) ( GinPageGetOpaque(page)->flags |= GIN_LIST ) +#define GinPageHasFullRow(page) ( (GinPageGetOpaque(page)->flags & GIN_LIST_FULLROW) != 0 ) +#define GinPageSetFullRow(page) ( GinPageGetOpaque(page)->flags |= GIN_LIST_FULLROW ) +#define GinPageIsCompressed(page) ( (GinPageGetOpaque(page)->flags & GIN_COMPRESSED) != 0 ) +#define GinPageSetCompressed(page) ( GinPageGetOpaque(page)->flags |= GIN_COMPRESSED ) + +#define GinPageIsDeleted(page) ( (GinPageGetOpaque(page)->flags & GIN_DELETED) != 0 ) +#define GinPageSetDeleted(page) ( GinPageGetOpaque(page)->flags |= GIN_DELETED) +#define GinPageSetNonDeleted(page) ( GinPageGetOpaque(page)->flags &= ~GIN_DELETED) +#define GinPageIsIncompleteSplit(page) ( (GinPageGetOpaque(page)->flags & GIN_INCOMPLETE_SPLIT) != 0 ) + +#define GinPageRightMost(page) ( GinPageGetOpaque(page)->rightlink == InvalidBlockNumber) + +/* + * We should reclaim deleted page only once every transaction started before + * its deletion is over. + */ +#define GinPageGetDeleteXid(page) ( ((PageHeader) (page))->pd_prune_xid ) +#define GinPageSetDeleteXid(page, xid) ( ((PageHeader) (page))->pd_prune_xid = xid) +extern bool GinPageIsRecyclable(Page page); + +/* + * We use our own ItemPointerGet(BlockNumber|OffsetNumber) + * to avoid Asserts, since sometimes the ip_posid isn't "valid" + */ +#define GinItemPointerGetBlockNumber(pointer) \ + (ItemPointerGetBlockNumberNoCheck(pointer)) + +#define GinItemPointerGetOffsetNumber(pointer) \ + (ItemPointerGetOffsetNumberNoCheck(pointer)) + +#define GinItemPointerSetBlockNumber(pointer, blkno) \ + (ItemPointerSetBlockNumber((pointer), (blkno))) + +#define GinItemPointerSetOffsetNumber(pointer, offnum) \ + (ItemPointerSetOffsetNumber((pointer), (offnum))) + + +/* + * Special-case item pointer values needed by the GIN search logic. + * MIN: sorts less than any valid item pointer + * MAX: sorts greater than any valid item pointer + * LOSSY PAGE: indicates a whole heap page, sorts after normal item + * pointers for that page + * Note that these are all distinguishable from an "invalid" item pointer + * (which is InvalidBlockNumber/0) as well as from all normal item + * pointers (which have item numbers in the range 1..MaxHeapTuplesPerPage). + */ +#define ItemPointerSetMin(p) \ + ItemPointerSet((p), (BlockNumber)0, (OffsetNumber)0) +#define ItemPointerIsMin(p) \ + (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)0 && \ + GinItemPointerGetBlockNumber(p) == (BlockNumber)0) +#define ItemPointerSetMax(p) \ + ItemPointerSet((p), InvalidBlockNumber, (OffsetNumber)0xffff) +#define ItemPointerSetLossyPage(p, b) \ + ItemPointerSet((p), (b), (OffsetNumber)0xffff) +#define ItemPointerIsLossyPage(p) \ + (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)0xffff && \ + GinItemPointerGetBlockNumber(p) != InvalidBlockNumber) + +/* + * Posting item in a non-leaf posting-tree page + */ +typedef struct +{ + /* We use BlockIdData not BlockNumber to avoid padding space wastage */ + BlockIdData child_blkno; + ItemPointerData key; +} PostingItem; + +#define PostingItemGetBlockNumber(pointer) \ + BlockIdGetBlockNumber(&(pointer)->child_blkno) + +#define PostingItemSetBlockNumber(pointer, blockNumber) \ + BlockIdSet(&((pointer)->child_blkno), (blockNumber)) + +/* + * Category codes to distinguish placeholder nulls from ordinary NULL keys. + * + * The first two code values were chosen to be compatible with the usual usage + * of bool isNull flags. However, casting between bool and GinNullCategory is + * risky because of the possibility of different bit patterns and type sizes, + * so it is no longer done. + * + * GIN_CAT_EMPTY_QUERY is never stored in the index; and notice that it is + * chosen to sort before not after regular key values. + */ +typedef signed char GinNullCategory; + +#define GIN_CAT_NORM_KEY 0 /* normal, non-null key value */ +#define GIN_CAT_NULL_KEY 1 /* null key value */ +#define GIN_CAT_EMPTY_ITEM 2 /* placeholder for zero-key item */ +#define GIN_CAT_NULL_ITEM 3 /* placeholder for null item */ +#define GIN_CAT_EMPTY_QUERY (-1) /* placeholder for full-scan query */ + +/* + * Access macros for null category byte in entry tuples + */ +#define GinCategoryOffset(itup,ginstate) \ + (IndexInfoFindDataOffset((itup)->t_info) + \ + ((ginstate)->oneCol ? 0 : sizeof(int16))) +#define GinGetNullCategory(itup,ginstate) \ + (*((GinNullCategory *) ((char*)(itup) + GinCategoryOffset(itup,ginstate)))) +#define GinSetNullCategory(itup,ginstate,c) \ + (*((GinNullCategory *) ((char*)(itup) + GinCategoryOffset(itup,ginstate))) = (c)) + +/* + * Access macros for leaf-page entry tuples (see discussion in README) + */ +#define GinGetNPosting(itup) GinItemPointerGetOffsetNumber(&(itup)->t_tid) +#define GinSetNPosting(itup,n) ItemPointerSetOffsetNumber(&(itup)->t_tid,n) +#define GIN_TREE_POSTING ((OffsetNumber)0xffff) +#define GinIsPostingTree(itup) (GinGetNPosting(itup) == GIN_TREE_POSTING) +#define GinSetPostingTree(itup, blkno) ( GinSetNPosting((itup),GIN_TREE_POSTING), ItemPointerSetBlockNumber(&(itup)->t_tid, blkno) ) +#define GinGetPostingTree(itup) GinItemPointerGetBlockNumber(&(itup)->t_tid) + +#define GIN_ITUP_COMPRESSED (1U << 31) +#define GinGetPostingOffset(itup) (GinItemPointerGetBlockNumber(&(itup)->t_tid) & (~GIN_ITUP_COMPRESSED)) +#define GinSetPostingOffset(itup,n) ItemPointerSetBlockNumber(&(itup)->t_tid,(n)|GIN_ITUP_COMPRESSED) +#define GinGetPosting(itup) ((Pointer) ((char*)(itup) + GinGetPostingOffset(itup))) +#define GinItupIsCompressed(itup) ((GinItemPointerGetBlockNumber(&(itup)->t_tid) & GIN_ITUP_COMPRESSED) != 0) + +/* + * Maximum size of an item on entry tree page. Make sure that we fit at least + * three items on each page. (On regular B-tree indexes, we must fit at least + * three items: two data items and the "high key". In GIN entry tree, we don't + * currently store the high key explicitly, we just use the rightmost item on + * the page, so it would actually be enough to fit two items.) + */ +#define GinMaxItemSize \ + Min(INDEX_SIZE_MASK, \ + MAXALIGN_DOWN(((BLCKSZ - \ + MAXALIGN(SizeOfPageHeaderData + 3 * sizeof(ItemIdData)) - \ + MAXALIGN(sizeof(GinPageOpaqueData))) / 3))) + +/* + * Access macros for non-leaf entry tuples + */ +#define GinGetDownlink(itup) GinItemPointerGetBlockNumber(&(itup)->t_tid) +#define GinSetDownlink(itup,blkno) ItemPointerSet(&(itup)->t_tid, blkno, InvalidOffsetNumber) + + +/* + * Data (posting tree) pages + * + * Posting tree pages don't store regular tuples. Non-leaf pages contain + * PostingItems, which are pairs of ItemPointers and child block numbers. + * Leaf pages contain GinPostingLists and an uncompressed array of item + * pointers. + * + * In a leaf page, the compressed posting lists are stored after the regular + * page header, one after each other. Although we don't store regular tuples, + * pd_lower is used to indicate the end of the posting lists. After that, free + * space follows. This layout is compatible with the "standard" heap and + * index page layout described in bufpage.h, so that we can e.g set buffer_std + * when writing WAL records. + * + * In the special space is the GinPageOpaque struct. + */ +#define GinDataLeafPageGetPostingList(page) \ + (GinPostingList *) ((PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData)))) +#define GinDataLeafPageGetPostingListSize(page) \ + (((PageHeader) page)->pd_lower - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(ItemPointerData))) + +#define GinDataLeafPageIsEmpty(page) \ + (GinPageIsCompressed(page) ? (GinDataLeafPageGetPostingListSize(page) == 0) : (GinPageGetOpaque(page)->maxoff < FirstOffsetNumber)) + +#define GinDataLeafPageGetFreeSpace(page) PageGetExactFreeSpace(page) + +#define GinDataPageGetRightBound(page) ((ItemPointer) PageGetContents(page)) +/* + * Pointer to the data portion of a posting tree page. For internal pages, + * that's the beginning of the array of PostingItems. For compressed leaf + * pages, the first compressed posting list. For uncompressed (pre-9.4) leaf + * pages, it's the beginning of the ItemPointer array. + */ +#define GinDataPageGetData(page) \ + (PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData))) +/* non-leaf pages contain PostingItems */ +#define GinDataPageGetPostingItem(page, i) \ + ((PostingItem *) (GinDataPageGetData(page) + ((i)-1) * sizeof(PostingItem))) + +/* + * Note: there is no GinDataPageGetDataSize macro, because before version + * 9.4, we didn't set pd_lower on data pages. There can be pages in the index + * that were binary-upgraded from earlier versions and still have an invalid + * pd_lower, so we cannot trust it in general. Compressed posting tree leaf + * pages are new in 9.4, however, so we can trust them; see + * GinDataLeafPageGetPostingListSize. + */ +#define GinDataPageSetDataSize(page, size) \ + { \ + Assert(size <= GinDataPageMaxDataSize); \ + ((PageHeader) page)->pd_lower = (size) + MAXALIGN(SizeOfPageHeaderData) + MAXALIGN(sizeof(ItemPointerData)); \ + } + +#define GinNonLeafDataPageGetFreeSpace(page) \ + (GinDataPageMaxDataSize - \ + GinPageGetOpaque(page)->maxoff * sizeof(PostingItem)) + +#define GinDataPageMaxDataSize \ + (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \ + - MAXALIGN(sizeof(ItemPointerData)) \ + - MAXALIGN(sizeof(GinPageOpaqueData))) + +/* + * List pages + */ +#define GinListPageSize \ + ( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GinPageOpaqueData)) ) + +/* + * A compressed posting list. + * + * Note: This requires 2-byte alignment. + */ +typedef struct +{ + ItemPointerData first; /* first item in this posting list (unpacked) */ + uint16 nbytes; /* number of bytes that follow */ + unsigned char bytes[FLEXIBLE_ARRAY_MEMBER]; /* varbyte encoded items */ +} GinPostingList; + +#define SizeOfGinPostingList(plist) (offsetof(GinPostingList, bytes) + SHORTALIGN((plist)->nbytes) ) +#define GinNextPostingListSegment(cur) ((GinPostingList *) (((char *) (cur)) + SizeOfGinPostingList((cur)))) + +#endif /* GINBLOCK_H */ diff --git a/install/include/postgresql/server/access/ginxlog.h b/install/include/postgresql/server/access/ginxlog.h new file mode 100644 index 00000000000..37095e5f17c --- /dev/null +++ b/install/include/postgresql/server/access/ginxlog.h @@ -0,0 +1,216 @@ +/*-------------------------------------------------------------------------- + * ginxlog.h + * header file for postgres inverted index xlog implementation. + * + * Copyright (c) 2006-2023, PostgreSQL Global Development Group + * + * src/include/access/ginxlog.h + *-------------------------------------------------------------------------- + */ +#ifndef GINXLOG_H +#define GINXLOG_H + +#include "access/ginblock.h" +#include "access/itup.h" +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/off.h" + +#define XLOG_GIN_CREATE_PTREE 0x10 + +typedef struct ginxlogCreatePostingTree +{ + uint32 size; + /* A compressed posting list follows */ +} ginxlogCreatePostingTree; + +/* + * The format of the insertion record varies depending on the page type. + * ginxlogInsert is the common part between all variants. + * + * Backup Blk 0: target page + * Backup Blk 1: left child, if this insertion finishes an incomplete split + */ + +#define XLOG_GIN_INSERT 0x20 + +typedef struct +{ + uint16 flags; /* GIN_INSERT_ISLEAF and/or GIN_INSERT_ISDATA */ + + /* + * FOLLOWS: + * + * 1. if not leaf page, block numbers of the left and right child pages + * whose split this insertion finishes, as BlockIdData[2] (beware of + * adding fields in this struct that would make them not 16-bit aligned) + * + * 2. a ginxlogInsertEntry or ginxlogRecompressDataLeaf struct, depending + * on tree type. + * + * NB: the below structs are only 16-bit aligned when appended to a + * ginxlogInsert struct! Beware of adding fields to them that require + * stricter alignment. + */ +} ginxlogInsert; + +typedef struct +{ + OffsetNumber offset; + bool isDelete; + IndexTupleData tuple; /* variable length */ +} ginxlogInsertEntry; + + +typedef struct +{ + uint16 nactions; + + /* Variable number of 'actions' follow */ +} ginxlogRecompressDataLeaf; + +/* + * Note: this struct is currently not used in code, and only acts as + * documentation. The WAL record format is as specified here, but the code + * uses straight access through a Pointer and memcpy to read/write these. + */ +typedef struct +{ + uint8 segno; /* segment this action applies to */ + char type; /* action type (see below) */ + + /* + * Action-specific data follows. For INSERT and REPLACE actions that is a + * GinPostingList struct. For ADDITEMS, a uint16 for the number of items + * added, followed by the items themselves as ItemPointers. DELETE actions + * have no further data. + */ +} ginxlogSegmentAction; + +/* Action types */ +#define GIN_SEGMENT_UNMODIFIED 0 /* no action (not used in WAL records) */ +#define GIN_SEGMENT_DELETE 1 /* a whole segment is removed */ +#define GIN_SEGMENT_INSERT 2 /* a whole segment is added */ +#define GIN_SEGMENT_REPLACE 3 /* a segment is replaced */ +#define GIN_SEGMENT_ADDITEMS 4 /* items are added to existing segment */ + +typedef struct +{ + OffsetNumber offset; + PostingItem newitem; +} ginxlogInsertDataInternal; + +/* + * Backup Blk 0: new left page (= original page, if not root split) + * Backup Blk 1: new right page + * Backup Blk 2: original page / new root page, if root split + * Backup Blk 3: left child, if this insertion completes an earlier split + */ +#define XLOG_GIN_SPLIT 0x30 + +typedef struct ginxlogSplit +{ + RelFileLocator locator; + BlockNumber rrlink; /* right link, or root's blocknumber if root + * split */ + BlockNumber leftChildBlkno; /* valid on a non-leaf split */ + BlockNumber rightChildBlkno; + uint16 flags; /* see below */ +} ginxlogSplit; + +/* + * Flags used in ginxlogInsert and ginxlogSplit records + */ +#define GIN_INSERT_ISDATA 0x01 /* for both insert and split records */ +#define GIN_INSERT_ISLEAF 0x02 /* ditto */ +#define GIN_SPLIT_ROOT 0x04 /* only for split records */ + +/* + * Vacuum simply WAL-logs the whole page, when anything is modified. This + * is functionally identical to XLOG_FPI records, but is kept separate for + * debugging purposes. (When inspecting the WAL stream, it's easier to see + * what's going on when GIN vacuum records are marked as such, not as heap + * records.) This is currently only used for entry tree leaf pages. + */ +#define XLOG_GIN_VACUUM_PAGE 0x40 + +/* + * Vacuuming posting tree leaf page is WAL-logged like recompression caused + * by insertion. + */ +#define XLOG_GIN_VACUUM_DATA_LEAF_PAGE 0x90 + +typedef struct ginxlogVacuumDataLeafPage +{ + ginxlogRecompressDataLeaf data; +} ginxlogVacuumDataLeafPage; + +/* + * Backup Blk 0: deleted page + * Backup Blk 1: parent + * Backup Blk 2: left sibling + */ +#define XLOG_GIN_DELETE_PAGE 0x50 + +typedef struct ginxlogDeletePage +{ + OffsetNumber parentOffset; + BlockNumber rightLink; + TransactionId deleteXid; /* last Xid which could see this page in scan */ +} ginxlogDeletePage; + +#define XLOG_GIN_UPDATE_META_PAGE 0x60 + +/* + * Backup Blk 0: metapage + * Backup Blk 1: tail page + */ +typedef struct ginxlogUpdateMeta +{ + RelFileLocator locator; + GinMetaPageData metadata; + BlockNumber prevTail; + BlockNumber newRightlink; + int32 ntuples; /* if ntuples > 0 then metadata.tail was + * updated with that many tuples; else new sub + * list was inserted */ + /* array of inserted tuples follows */ +} ginxlogUpdateMeta; + +#define XLOG_GIN_INSERT_LISTPAGE 0x70 + +typedef struct ginxlogInsertListPage +{ + BlockNumber rightlink; + int32 ntuples; + /* array of inserted tuples follows */ +} ginxlogInsertListPage; + +/* + * Backup Blk 0: metapage + * Backup Blk 1 to (ndeleted + 1): deleted pages + */ + +#define XLOG_GIN_DELETE_LISTPAGE 0x80 + +/* + * The WAL record for deleting list pages must contain a block reference to + * all the deleted pages, so the number of pages that can be deleted in one + * record is limited by XLR_MAX_BLOCK_ID. (block_id 0 is used for the + * metapage.) + */ +#define GIN_NDELETE_AT_ONCE Min(16, XLR_MAX_BLOCK_ID - 1) +typedef struct ginxlogDeleteListPages +{ + GinMetaPageData metadata; + int32 ndeleted; +} ginxlogDeleteListPages; + +extern void gin_redo(XLogReaderState *record); +extern void gin_desc(StringInfo buf, XLogReaderState *record); +extern const char *gin_identify(uint8 info); +extern void gin_xlog_startup(void); +extern void gin_xlog_cleanup(void); +extern void gin_mask(char *pagedata, BlockNumber blkno); + +#endif /* GINXLOG_H */ diff --git a/install/include/postgresql/server/access/gist.h b/install/include/postgresql/server/access/gist.h new file mode 100644 index 00000000000..0235716c06f --- /dev/null +++ b/install/include/postgresql/server/access/gist.h @@ -0,0 +1,248 @@ +/*------------------------------------------------------------------------- + * + * gist.h + * The public API for GiST indexes. This API is exposed to + * individuals implementing GiST indexes, so backward-incompatible + * changes should be made with care. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/gist.h + * + *------------------------------------------------------------------------- + */ +#ifndef GIST_H +#define GIST_H + +#include "access/itup.h" +#include "access/transam.h" +#include "access/xlog.h" +#include "access/xlogdefs.h" +#include "storage/block.h" +#include "storage/bufpage.h" +#include "utils/relcache.h" + +/* + * amproc indexes for GiST indexes. + */ +#define GIST_CONSISTENT_PROC 1 +#define GIST_UNION_PROC 2 +#define GIST_COMPRESS_PROC 3 +#define GIST_DECOMPRESS_PROC 4 +#define GIST_PENALTY_PROC 5 +#define GIST_PICKSPLIT_PROC 6 +#define GIST_EQUAL_PROC 7 +#define GIST_DISTANCE_PROC 8 +#define GIST_FETCH_PROC 9 +#define GIST_OPTIONS_PROC 10 +#define GIST_SORTSUPPORT_PROC 11 +#define GISTNProcs 11 + +/* + * Page opaque data in a GiST index page. + */ +#define F_LEAF (1 << 0) /* leaf page */ +#define F_DELETED (1 << 1) /* the page has been deleted */ +#define F_TUPLES_DELETED (1 << 2) /* some tuples on the page were + * deleted */ +#define F_FOLLOW_RIGHT (1 << 3) /* page to the right has no downlink */ +#define F_HAS_GARBAGE (1 << 4) /* some tuples on the page are dead, + * but not deleted yet */ + +/* + * NSN (node sequence number) is a special-purpose LSN which is stored on each + * index page in GISTPageOpaqueData and updated only during page splits. By + * recording the parent's LSN in GISTSearchItem.parentlsn, it is possible to + * detect concurrent child page splits by checking if parentlsn < child's NSN, + * and handle them properly. The child page's LSN is insufficient for this + * purpose since it is updated for every page change. + */ +typedef XLogRecPtr GistNSN; + +/* + * A fake LSN / NSN value used during index builds. Must be smaller than any + * real or fake (unlogged) LSN generated after the index build completes so + * that all splits are considered complete. + */ +#define GistBuildLSN ((XLogRecPtr) 1) + +/* + * For on-disk compatibility with pre-9.3 servers, NSN is stored as two + * 32-bit fields on disk, same as LSNs. + */ +typedef PageXLogRecPtr PageGistNSN; + +typedef struct GISTPageOpaqueData +{ + PageGistNSN nsn; /* this value must change on page split */ + BlockNumber rightlink; /* next page if any */ + uint16 flags; /* see bit definitions above */ + uint16 gist_page_id; /* for identification of GiST indexes */ +} GISTPageOpaqueData; + +typedef GISTPageOpaqueData *GISTPageOpaque; + +/* + * Maximum possible sizes for GiST index tuple and index key. Calculation is + * based on assumption that GiST page should fit at least 4 tuples. In theory, + * GiST index can be functional when page can fit 3 tuples. But that seems + * rather inefficient, so we use a bit conservative estimate. + * + * The maximum size of index key is true for unicolumn index. Therefore, this + * estimation should be used to figure out which maximum size of GiST index key + * makes sense at all. For multicolumn indexes, user might be able to tune + * key size using opclass parameters. + */ +#define GISTMaxIndexTupleSize \ + MAXALIGN_DOWN((BLCKSZ - SizeOfPageHeaderData - sizeof(GISTPageOpaqueData)) / \ + 4 - sizeof(ItemIdData)) + +#define GISTMaxIndexKeySize \ + (GISTMaxIndexTupleSize - MAXALIGN(sizeof(IndexTupleData))) + +/* + * The page ID is for the convenience of pg_filedump and similar utilities, + * which otherwise would have a hard time telling pages of different index + * types apart. It should be the last 2 bytes on the page. This is more or + * less "free" due to alignment considerations. + */ +#define GIST_PAGE_ID 0xFF81 + +/* + * This is the Split Vector to be returned by the PickSplit method. + * PickSplit should fill the indexes of tuples to go to the left side into + * spl_left[], and those to go to the right into spl_right[] (note the method + * is responsible for palloc'ing both of these arrays!). The tuple counts + * go into spl_nleft/spl_nright, and spl_ldatum/spl_rdatum must be set to + * the union keys for each side. + * + * If spl_ldatum_exists and spl_rdatum_exists are true, then we are performing + * a "secondary split" using a non-first index column. In this case some + * decisions have already been made about a page split, and the set of tuples + * being passed to PickSplit is just the tuples about which we are undecided. + * spl_ldatum/spl_rdatum then contain the union keys for the tuples already + * chosen to go left or right. Ideally the PickSplit method should take those + * keys into account while deciding what to do with the remaining tuples, ie + * it should try to "build out" from those unions so as to minimally expand + * them. If it does so, it should union the given tuples' keys into the + * existing spl_ldatum/spl_rdatum values rather than just setting those values + * from scratch, and then set spl_ldatum_exists/spl_rdatum_exists to false to + * show it has done this. + * + * If the PickSplit method fails to clear spl_ldatum_exists/spl_rdatum_exists, + * the core GiST code will make its own decision about how to merge the + * secondary-split results with the previously-chosen tuples, and will then + * recompute the union keys from scratch. This is a workable though often not + * optimal approach. + */ +typedef struct GIST_SPLITVEC +{ + OffsetNumber *spl_left; /* array of entries that go left */ + int spl_nleft; /* size of this array */ + Datum spl_ldatum; /* Union of keys in spl_left */ + bool spl_ldatum_exists; /* true, if spl_ldatum already exists. */ + + OffsetNumber *spl_right; /* array of entries that go right */ + int spl_nright; /* size of the array */ + Datum spl_rdatum; /* Union of keys in spl_right */ + bool spl_rdatum_exists; /* true, if spl_rdatum already exists. */ +} GIST_SPLITVEC; + +/* + * An entry on a GiST node. Contains the key, as well as its own + * location (rel,page,offset) which can supply the matching pointer. + * leafkey is a flag to tell us if the entry is in a leaf node. + */ +typedef struct GISTENTRY +{ + Datum key; + Relation rel; + Page page; + OffsetNumber offset; + bool leafkey; +} GISTENTRY; + +#define GistPageGetOpaque(page) ( (GISTPageOpaque) PageGetSpecialPointer(page) ) + +#define GistPageIsLeaf(page) ( GistPageGetOpaque(page)->flags & F_LEAF) +#define GIST_LEAF(entry) (GistPageIsLeaf((entry)->page)) + +#define GistPageIsDeleted(page) ( GistPageGetOpaque(page)->flags & F_DELETED) + +#define GistTuplesDeleted(page) ( GistPageGetOpaque(page)->flags & F_TUPLES_DELETED) +#define GistMarkTuplesDeleted(page) ( GistPageGetOpaque(page)->flags |= F_TUPLES_DELETED) +#define GistClearTuplesDeleted(page) ( GistPageGetOpaque(page)->flags &= ~F_TUPLES_DELETED) + +#define GistPageHasGarbage(page) ( GistPageGetOpaque(page)->flags & F_HAS_GARBAGE) +#define GistMarkPageHasGarbage(page) ( GistPageGetOpaque(page)->flags |= F_HAS_GARBAGE) +#define GistClearPageHasGarbage(page) ( GistPageGetOpaque(page)->flags &= ~F_HAS_GARBAGE) + +#define GistFollowRight(page) ( GistPageGetOpaque(page)->flags & F_FOLLOW_RIGHT) +#define GistMarkFollowRight(page) ( GistPageGetOpaque(page)->flags |= F_FOLLOW_RIGHT) +#define GistClearFollowRight(page) ( GistPageGetOpaque(page)->flags &= ~F_FOLLOW_RIGHT) + +#define GistPageGetNSN(page) ( PageXLogRecPtrGet(GistPageGetOpaque(page)->nsn)) +#define GistPageSetNSN(page, val) ( PageXLogRecPtrSet(GistPageGetOpaque(page)->nsn, val)) + + +/* + * On a deleted page, we store this struct. A deleted page doesn't contain any + * tuples, so we don't use the normal page layout with line pointers. Instead, + * this struct is stored right after the standard page header. pd_lower points + * to the end of this struct. If we add fields to this struct in the future, we + * can distinguish the old and new formats by pd_lower. + */ +typedef struct GISTDeletedPageContents +{ + /* last xid which could see the page in a scan */ + FullTransactionId deleteXid; +} GISTDeletedPageContents; + +static inline void +GistPageSetDeleted(Page page, FullTransactionId deletexid) +{ + Assert(PageIsEmpty(page)); + + GistPageGetOpaque(page)->flags |= F_DELETED; + ((PageHeader) page)->pd_lower = MAXALIGN(SizeOfPageHeaderData) + sizeof(GISTDeletedPageContents); + + ((GISTDeletedPageContents *) PageGetContents(page))->deleteXid = deletexid; +} + +static inline FullTransactionId +GistPageGetDeleteXid(Page page) +{ + Assert(GistPageIsDeleted(page)); + + /* Is the deleteXid field present? */ + if (((PageHeader) page)->pd_lower >= MAXALIGN(SizeOfPageHeaderData) + + offsetof(GISTDeletedPageContents, deleteXid) + sizeof(FullTransactionId)) + { + return ((GISTDeletedPageContents *) PageGetContents(page))->deleteXid; + } + else + return FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId); +} + +/* + * Vector of GISTENTRY structs; user-defined methods union and picksplit + * take it as one of their arguments + */ +typedef struct +{ + int32 n; /* number of elements */ + GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]; +} GistEntryVector; + +#define GEVHDRSZ (offsetof(GistEntryVector, vector)) + +/* + * macro to initialize a GISTENTRY + */ +#define gistentryinit(e, k, r, pg, o, l) \ + do { (e).key = (k); (e).rel = (r); (e).page = (pg); \ + (e).offset = (o); (e).leafkey = (l); } while (0) + +#endif /* GIST_H */ diff --git a/install/include/postgresql/server/access/gist_private.h b/install/include/postgresql/server/access/gist_private.h new file mode 100644 index 00000000000..3edc740a3f3 --- /dev/null +++ b/install/include/postgresql/server/access/gist_private.h @@ -0,0 +1,571 @@ +/*------------------------------------------------------------------------- + * + * gist_private.h + * private declarations for GiST -- declarations related to the + * internal implementation of GiST, not the public API + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/gist_private.h + * + *------------------------------------------------------------------------- + */ +#ifndef GIST_PRIVATE_H +#define GIST_PRIVATE_H + +#include "access/amapi.h" +#include "access/gist.h" +#include "access/itup.h" +#include "lib/pairingheap.h" +#include "storage/bufmgr.h" +#include "storage/buffile.h" +#include "utils/hsearch.h" +#include "access/genam.h" + +/* + * Maximum number of "halves" a page can be split into in one operation. + * Typically a split produces 2 halves, but can be more if keys have very + * different lengths, or when inserting multiple keys in one operation (as + * when inserting downlinks to an internal node). There is no theoretical + * limit on this, but in practice if you get more than a handful page halves + * in one split, there's something wrong with the opclass implementation. + * GIST_MAX_SPLIT_PAGES is an arbitrary limit on that, used to size some + * local arrays used during split. Note that there is also a limit on the + * number of buffers that can be held locked at a time, MAX_SIMUL_LWLOCKS, + * so if you raise this higher than that limit, you'll just get a different + * error. + */ +#define GIST_MAX_SPLIT_PAGES 75 + +/* Buffer lock modes */ +#define GIST_SHARE BUFFER_LOCK_SHARE +#define GIST_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE +#define GIST_UNLOCK BUFFER_LOCK_UNLOCK + +typedef struct +{ + BlockNumber prev; + uint32 freespace; + char tupledata[FLEXIBLE_ARRAY_MEMBER]; +} GISTNodeBufferPage; + +#define BUFFER_PAGE_DATA_OFFSET MAXALIGN(offsetof(GISTNodeBufferPage, tupledata)) +/* Returns free space in node buffer page */ +#define PAGE_FREE_SPACE(nbp) (nbp->freespace) +/* Checks if node buffer page is empty */ +#define PAGE_IS_EMPTY(nbp) (nbp->freespace == BLCKSZ - BUFFER_PAGE_DATA_OFFSET) +/* Checks if node buffers page don't contain sufficient space for index tuple */ +#define PAGE_NO_SPACE(nbp, itup) (PAGE_FREE_SPACE(nbp) < \ + MAXALIGN(IndexTupleSize(itup))) + +/* + * GISTSTATE: information needed for any GiST index operation + * + * This struct retains call info for the index's opclass-specific support + * functions (per index column), plus the index's tuple descriptor. + * + * scanCxt holds the GISTSTATE itself as well as any data that lives for the + * lifetime of the index operation. We pass this to the support functions + * via fn_mcxt, so that they can store scan-lifespan data in it. The + * functions are invoked in tempCxt, which is typically short-lifespan + * (that is, it's reset after each tuple). However, tempCxt can be the same + * as scanCxt if we're not bothering with per-tuple context resets. + */ +typedef struct GISTSTATE +{ + MemoryContext scanCxt; /* context for scan-lifespan data */ + MemoryContext tempCxt; /* short-term context for calling functions */ + + TupleDesc leafTupdesc; /* index's tuple descriptor */ + TupleDesc nonLeafTupdesc; /* truncated tuple descriptor for non-leaf + * pages */ + TupleDesc fetchTupdesc; /* tuple descriptor for tuples returned in an + * index-only scan */ + + FmgrInfo consistentFn[INDEX_MAX_KEYS]; + FmgrInfo unionFn[INDEX_MAX_KEYS]; + FmgrInfo compressFn[INDEX_MAX_KEYS]; + FmgrInfo decompressFn[INDEX_MAX_KEYS]; + FmgrInfo penaltyFn[INDEX_MAX_KEYS]; + FmgrInfo picksplitFn[INDEX_MAX_KEYS]; + FmgrInfo equalFn[INDEX_MAX_KEYS]; + FmgrInfo distanceFn[INDEX_MAX_KEYS]; + FmgrInfo fetchFn[INDEX_MAX_KEYS]; + + /* Collations to pass to the support functions */ + Oid supportCollation[INDEX_MAX_KEYS]; +} GISTSTATE; + + +/* + * During a GiST index search, we must maintain a queue of unvisited items, + * which can be either individual heap tuples or whole index pages. If it + * is an ordered search, the unvisited items should be visited in distance + * order. Unvisited items at the same distance should be visited in + * depth-first order, that is heap items first, then lower index pages, then + * upper index pages; this rule avoids doing extra work during a search that + * ends early due to LIMIT. + * + * To perform an ordered search, we use a pairing heap to manage the + * distance-order queue. In a non-ordered search (no order-by operators), + * we use it to return heap tuples before unvisited index pages, to + * ensure depth-first order, but all entries are otherwise considered + * equal. + */ + +/* Individual heap tuple to be visited */ +typedef struct GISTSearchHeapItem +{ + ItemPointerData heapPtr; + bool recheck; /* T if quals must be rechecked */ + bool recheckDistances; /* T if distances must be rechecked */ + HeapTuple recontup; /* data reconstructed from the index, used in + * index-only scans */ + OffsetNumber offnum; /* track offset in page to mark tuple as + * LP_DEAD */ +} GISTSearchHeapItem; + +/* Unvisited item, either index page or heap tuple */ +typedef struct GISTSearchItem +{ + pairingheap_node phNode; + BlockNumber blkno; /* index page number, or InvalidBlockNumber */ + union + { + GistNSN parentlsn; /* parent page's LSN, if index page */ + /* we must store parentlsn to detect whether a split occurred */ + GISTSearchHeapItem heap; /* heap info, if heap tuple */ + } data; + + /* numberOfOrderBys entries */ + IndexOrderByDistance distances[FLEXIBLE_ARRAY_MEMBER]; +} GISTSearchItem; + +#define GISTSearchItemIsHeap(item) ((item).blkno == InvalidBlockNumber) + +#define SizeOfGISTSearchItem(n_distances) \ + (offsetof(GISTSearchItem, distances) + \ + sizeof(IndexOrderByDistance) * (n_distances)) + +/* + * GISTScanOpaqueData: private state for a scan of a GiST index + */ +typedef struct GISTScanOpaqueData +{ + GISTSTATE *giststate; /* index information, see above */ + Oid *orderByTypes; /* datatypes of ORDER BY expressions */ + + pairingheap *queue; /* queue of unvisited items */ + MemoryContext queueCxt; /* context holding the queue */ + bool qual_ok; /* false if qual can never be satisfied */ + bool firstCall; /* true until first gistgettuple call */ + + /* pre-allocated workspace arrays */ + IndexOrderByDistance *distances; /* output area for gistindex_keytest */ + + /* info about killed items if any (killedItems is NULL if never used) */ + OffsetNumber *killedItems; /* offset numbers of killed items */ + int numKilled; /* number of currently stored items */ + BlockNumber curBlkno; /* current number of block */ + GistNSN curPageLSN; /* pos in the WAL stream when page was read */ + + /* In a non-ordered search, returnable heap items are stored here: */ + GISTSearchHeapItem pageData[BLCKSZ / sizeof(IndexTupleData)]; + OffsetNumber nPageData; /* number of valid items in array */ + OffsetNumber curPageData; /* next item to return */ + MemoryContext pageDataCxt; /* context holding the fetched tuples, for + * index-only scans */ +} GISTScanOpaqueData; + +typedef GISTScanOpaqueData *GISTScanOpaque; + +/* despite the name, gistxlogPage is not part of any xlog record */ +typedef struct gistxlogPage +{ + BlockNumber blkno; + int num; /* number of index tuples following */ +} gistxlogPage; + +/* SplitedPageLayout - gistSplit function result */ +typedef struct SplitedPageLayout +{ + gistxlogPage block; + IndexTupleData *list; + int lenlist; + IndexTuple itup; /* union key for page */ + Page page; /* to operate */ + Buffer buffer; /* to write after all proceed */ + + struct SplitedPageLayout *next; +} SplitedPageLayout; + +/* + * GISTInsertStack used for locking buffers and transfer arguments during + * insertion + */ +typedef struct GISTInsertStack +{ + /* current page */ + BlockNumber blkno; + Buffer buffer; + Page page; + + /* + * log sequence number from page->lsn to recognize page update and compare + * it with page's nsn to recognize page split + */ + GistNSN lsn; + + /* + * If set, we split the page while descending the tree to find an + * insertion target. It means that we need to retry from the parent, + * because the downlink of this page might no longer cover the new key. + */ + bool retry_from_parent; + + /* offset of the downlink in the parent page, that points to this page */ + OffsetNumber downlinkoffnum; + + /* pointer to parent */ + struct GISTInsertStack *parent; +} GISTInsertStack; + +/* Working state and results for multi-column split logic in gistsplit.c */ +typedef struct GistSplitVector +{ + GIST_SPLITVEC splitVector; /* passed to/from user PickSplit method */ + + Datum spl_lattr[INDEX_MAX_KEYS]; /* Union of subkeys in + * splitVector.spl_left */ + bool spl_lisnull[INDEX_MAX_KEYS]; + + Datum spl_rattr[INDEX_MAX_KEYS]; /* Union of subkeys in + * splitVector.spl_right */ + bool spl_risnull[INDEX_MAX_KEYS]; + + bool *spl_dontcare; /* flags tuples which could go to either side + * of the split for zero penalty */ +} GistSplitVector; + +typedef struct +{ + Relation r; + Relation heapRel; + Size freespace; /* free space to be left */ + bool is_build; + + GISTInsertStack *stack; +} GISTInsertState; + +/* root page of a gist index */ +#define GIST_ROOT_BLKNO 0 + +/* + * Before PostgreSQL 9.1, we used to rely on so-called "invalid tuples" on + * inner pages to finish crash recovery of incomplete page splits. If a crash + * happened in the middle of a page split, so that the downlink pointers were + * not yet inserted, crash recovery inserted a special downlink pointer. The + * semantics of an invalid tuple was that it if you encounter one in a scan, + * it must always be followed, because we don't know if the tuples on the + * child page match or not. + * + * We no longer create such invalid tuples, we now mark the left-half of such + * an incomplete split with the F_FOLLOW_RIGHT flag instead, and finish the + * split properly the next time we need to insert on that page. To retain + * on-disk compatibility for the sake of pg_upgrade, we still store 0xffff as + * the offset number of all inner tuples. If we encounter any invalid tuples + * with 0xfffe during insertion, we throw an error, though scans still handle + * them. You should only encounter invalid tuples if you pg_upgrade a pre-9.1 + * gist index which already has invalid tuples in it because of a crash. That + * should be rare, and you are recommended to REINDEX anyway if you have any + * invalid tuples in an index, so throwing an error is as far as we go with + * supporting that. + */ +#define TUPLE_IS_VALID 0xffff +#define TUPLE_IS_INVALID 0xfffe + +#define GistTupleIsInvalid(itup) ( ItemPointerGetOffsetNumber( &((itup)->t_tid) ) == TUPLE_IS_INVALID ) +#define GistTupleSetValid(itup) ItemPointerSetOffsetNumber( &((itup)->t_tid), TUPLE_IS_VALID ) + + + + +/* + * A buffer attached to an internal node, used when building an index in + * buffering mode. + */ +typedef struct +{ + BlockNumber nodeBlocknum; /* index block # this buffer is for */ + int32 blocksCount; /* current # of blocks occupied by buffer */ + + BlockNumber pageBlocknum; /* temporary file block # */ + GISTNodeBufferPage *pageBuffer; /* in-memory buffer page */ + + /* is this buffer queued for emptying? */ + bool queuedForEmptying; + + /* is this a temporary copy, not in the hash table? */ + bool isTemp; + + int level; /* 0 == leaf */ +} GISTNodeBuffer; + +/* + * Does specified level have buffers? (Beware of multiple evaluation of + * arguments.) + */ +#define LEVEL_HAS_BUFFERS(nlevel, gfbb) \ + ((nlevel) != 0 && (nlevel) % (gfbb)->levelStep == 0 && \ + (nlevel) != (gfbb)->rootlevel) + +/* Is specified buffer at least half-filled (should be queued for emptying)? */ +#define BUFFER_HALF_FILLED(nodeBuffer, gfbb) \ + ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer / 2) + +/* + * Is specified buffer full? Our buffers can actually grow indefinitely, + * beyond the "maximum" size, so this just means whether the buffer has grown + * beyond the nominal maximum size. + */ +#define BUFFER_OVERFLOWED(nodeBuffer, gfbb) \ + ((nodeBuffer)->blocksCount > (gfbb)->pagesPerBuffer) + +/* + * Data structure with general information about build buffers. + */ +typedef struct GISTBuildBuffers +{ + /* Persistent memory context for the buffers and metadata. */ + MemoryContext context; + + BufFile *pfile; /* Temporary file to store buffers in */ + long nFileBlocks; /* Current size of the temporary file */ + + /* + * resizable array of free blocks. + */ + long *freeBlocks; + int nFreeBlocks; /* # of currently free blocks in the array */ + int freeBlocksLen; /* current allocated length of the array */ + + /* Hash for buffers by block number */ + HTAB *nodeBuffersTab; + + /* List of buffers scheduled for emptying */ + List *bufferEmptyingQueue; + + /* + * Parameters to the buffering build algorithm. levelStep determines which + * levels in the tree have buffers, and pagesPerBuffer determines how + * large each buffer is. + */ + int levelStep; + int pagesPerBuffer; + + /* Array of lists of buffers on each level, for final emptying */ + List **buffersOnLevels; + int buffersOnLevelsLen; + + /* + * Dynamically-sized array of buffers that currently have their last page + * loaded in main memory. + */ + GISTNodeBuffer **loadedBuffers; + int loadedBuffersCount; /* # of entries in loadedBuffers */ + int loadedBuffersLen; /* allocated size of loadedBuffers */ + + /* Level of the current root node (= height of the index tree - 1) */ + int rootlevel; +} GISTBuildBuffers; + +/* GiSTOptions->buffering_mode values */ +typedef enum GistOptBufferingMode +{ + GIST_OPTION_BUFFERING_AUTO, + GIST_OPTION_BUFFERING_ON, + GIST_OPTION_BUFFERING_OFF +} GistOptBufferingMode; + +/* + * Storage type for GiST's reloptions + */ +typedef struct GiSTOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int fillfactor; /* page fill factor in percent (0..100) */ + GistOptBufferingMode buffering_mode; /* buffering build mode */ +} GiSTOptions; + +/* gist.c */ +extern void gistbuildempty(Relation index); +extern bool gistinsert(Relation r, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); +extern MemoryContext createTempGistContext(void); +extern GISTSTATE *initGISTstate(Relation index); +extern void freeGISTstate(GISTSTATE *giststate); +extern void gistdoinsert(Relation r, + IndexTuple itup, + Size freespace, + GISTSTATE *giststate, + Relation heapRel, + bool is_build); + +/* A List of these is returned from gistplacetopage() in *splitinfo */ +typedef struct +{ + Buffer buf; /* the split page "half" */ + IndexTuple downlink; /* downlink for this half. */ +} GISTPageSplitInfo; + +extern bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, + Buffer buffer, + IndexTuple *itup, int ntup, + OffsetNumber oldoffnum, BlockNumber *newblkno, + Buffer leftchildbuf, + List **splitinfo, + bool markfollowright, + Relation heapRel, + bool is_build); + +extern SplitedPageLayout *gistSplit(Relation r, Page page, IndexTuple *itup, + int len, GISTSTATE *giststate); + +/* gistxlog.c */ +extern XLogRecPtr gistXLogPageDelete(Buffer buffer, + FullTransactionId xid, Buffer parentBuffer, + OffsetNumber downlinkOffset); + +extern void gistXLogPageReuse(Relation rel, Relation heaprel, BlockNumber blkno, + FullTransactionId deleteXid); + +extern XLogRecPtr gistXLogUpdate(Buffer buffer, + OffsetNumber *todelete, int ntodelete, + IndexTuple *itup, int ituplen, + Buffer leftchildbuf); + +extern XLogRecPtr gistXLogDelete(Buffer buffer, OffsetNumber *todelete, + int ntodelete, TransactionId snapshotConflictHorizon, + Relation heaprel); + +extern XLogRecPtr gistXLogSplit(bool page_is_leaf, + SplitedPageLayout *dist, + BlockNumber origrlink, GistNSN orignsn, + Buffer leftchildbuf, bool markfollowright); + +extern XLogRecPtr gistXLogAssignLSN(void); + +/* gistget.c */ +extern bool gistgettuple(IndexScanDesc scan, ScanDirection dir); +extern int64 gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); +extern bool gistcanreturn(Relation index, int attno); + +/* gistvalidate.c */ +extern bool gistvalidate(Oid opclassoid); +extern void gistadjustmembers(Oid opfamilyoid, + Oid opclassoid, + List *operators, + List *functions); + +/* gistutil.c */ + +#define GiSTPageSize \ + ( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GISTPageOpaqueData)) ) + +#define GIST_MIN_FILLFACTOR 10 +#define GIST_DEFAULT_FILLFACTOR 90 + +extern bytea *gistoptions(Datum reloptions, bool validate); +extern bool gistproperty(Oid index_oid, int attno, + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); +extern bool gistfitpage(IndexTuple *itvec, int len); +extern bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace); +extern void gistcheckpage(Relation rel, Buffer buf); +extern Buffer gistNewBuffer(Relation r, Relation heaprel); +extern bool gistPageRecyclable(Page page); +extern void gistfillbuffer(Page page, IndexTuple *itup, int len, + OffsetNumber off); +extern IndexTuple *gistextractpage(Page page, int *len /* out */ ); +extern IndexTuple *gistjoinvector(IndexTuple *itvec, int *len, + IndexTuple *additvec, int addlen); +extern IndexTupleData *gistfillitupvec(IndexTuple *vec, int veclen, int *memlen); + +extern IndexTuple gistunion(Relation r, IndexTuple *itvec, + int len, GISTSTATE *giststate); +extern IndexTuple gistgetadjusted(Relation r, + IndexTuple oldtup, + IndexTuple addtup, + GISTSTATE *giststate); +extern IndexTuple gistFormTuple(GISTSTATE *giststate, + Relation r, Datum *attdata, bool *isnull, bool isleaf); +extern void gistCompressValues(GISTSTATE *giststate, Relation r, + Datum *attdata, bool *isnull, bool isleaf, Datum *compatt); + +extern OffsetNumber gistchoose(Relation r, Page p, + IndexTuple it, + GISTSTATE *giststate); + +extern void GISTInitBuffer(Buffer b, uint32 f); +extern void gistinitpage(Page page, uint32 f); +extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, + Datum k, Relation r, Page pg, OffsetNumber o, + bool l, bool isNull); + +extern float gistpenalty(GISTSTATE *giststate, int attno, + GISTENTRY *orig, bool isNullOrig, + GISTENTRY *add, bool isNullAdd); +extern void gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, + Datum *attr, bool *isnull); +extern bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b); +extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, + OffsetNumber o, GISTENTRY *attdata, bool *isnull); +extern HeapTuple gistFetchTuple(GISTSTATE *giststate, Relation r, + IndexTuple tuple); +extern void gistMakeUnionKey(GISTSTATE *giststate, int attno, + GISTENTRY *entry1, bool isnull1, + GISTENTRY *entry2, bool isnull2, + Datum *dst, bool *dstisnull); + +extern XLogRecPtr gistGetFakeLSN(Relation rel); + +/* gistvacuum.c */ +extern IndexBulkDeleteResult *gistbulkdelete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *gistvacuumcleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); + +/* gistsplit.c */ +extern void gistSplitByKey(Relation r, Page page, IndexTuple *itup, + int len, GISTSTATE *giststate, + GistSplitVector *v, + int attno); + +/* gistbuild.c */ +extern IndexBuildResult *gistbuild(Relation heap, Relation index, + struct IndexInfo *indexInfo); + +/* gistbuildbuffers.c */ +extern GISTBuildBuffers *gistInitBuildBuffers(int pagesPerBuffer, int levelStep, + int maxLevel); +extern GISTNodeBuffer *gistGetNodeBuffer(GISTBuildBuffers *gfbb, + GISTSTATE *giststate, + BlockNumber nodeBlocknum, int level); +extern void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb, + GISTNodeBuffer *nodeBuffer, IndexTuple itup); +extern bool gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb, + GISTNodeBuffer *nodeBuffer, IndexTuple *itup); +extern void gistFreeBuildBuffers(GISTBuildBuffers *gfbb); +extern void gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, + GISTSTATE *giststate, Relation r, + int level, Buffer buffer, + List *splitinfo); +extern void gistUnloadNodeBuffers(GISTBuildBuffers *gfbb); + +#endif /* GIST_PRIVATE_H */ diff --git a/install/include/postgresql/server/access/gistscan.h b/install/include/postgresql/server/access/gistscan.h new file mode 100644 index 00000000000..65911245f74 --- /dev/null +++ b/install/include/postgresql/server/access/gistscan.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * gistscan.h + * routines defined in access/gist/gistscan.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/gistscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef GISTSCAN_H +#define GISTSCAN_H + +#include "access/amapi.h" + +extern IndexScanDesc gistbeginscan(Relation r, int nkeys, int norderbys); +extern void gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, + ScanKey orderbys, int norderbys); +extern void gistendscan(IndexScanDesc scan); + +#endif /* GISTSCAN_H */ diff --git a/install/include/postgresql/server/access/gistxlog.h b/install/include/postgresql/server/access/gistxlog.h new file mode 100644 index 00000000000..aff2ffbdcc2 --- /dev/null +++ b/install/include/postgresql/server/access/gistxlog.h @@ -0,0 +1,117 @@ +/*------------------------------------------------------------------------- + * + * gistxlog.h + * gist xlog routines + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/gistxlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef GIST_XLOG_H +#define GIST_XLOG_H + +#include "access/gist.h" +#include "access/xlogreader.h" +#include "lib/stringinfo.h" + +#define XLOG_GIST_PAGE_UPDATE 0x00 +#define XLOG_GIST_DELETE 0x10 /* delete leaf index tuples for a + * page */ +#define XLOG_GIST_PAGE_REUSE 0x20 /* old page is about to be reused + * from FSM */ +#define XLOG_GIST_PAGE_SPLIT 0x30 + /* #define XLOG_GIST_INSERT_COMPLETE 0x40 */ /* not used anymore */ + /* #define XLOG_GIST_CREATE_INDEX 0x50 */ /* not used anymore */ +#define XLOG_GIST_PAGE_DELETE 0x60 +#define XLOG_GIST_ASSIGN_LSN 0x70 /* nop, assign new LSN */ + +/* + * Backup Blk 0: updated page. + * Backup Blk 1: If this operation completes a page split, by inserting a + * downlink for the split page, the left half of the split + */ +typedef struct gistxlogPageUpdate +{ + /* number of deleted offsets */ + uint16 ntodelete; + uint16 ntoinsert; + + /* + * In payload of blk 0 : 1. todelete OffsetNumbers 2. tuples to insert + */ +} gistxlogPageUpdate; + +/* + * Backup Blk 0: Leaf page, whose index tuples are deleted. + */ +typedef struct gistxlogDelete +{ + TransactionId snapshotConflictHorizon; + uint16 ntodelete; /* number of deleted offsets */ + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ + + /* TODELETE OFFSET NUMBERS */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} gistxlogDelete; + +#define SizeOfGistxlogDelete offsetof(gistxlogDelete, offsets) + +/* + * Backup Blk 0: If this operation completes a page split, by inserting a + * downlink for the split page, the left half of the split + * Backup Blk 1 - npage: split pages (1 is the original page) + */ +typedef struct gistxlogPageSplit +{ + BlockNumber origrlink; /* rightlink of the page before split */ + GistNSN orignsn; /* NSN of the page before split */ + bool origleaf; /* was splitted page a leaf page? */ + + uint16 npage; /* # of pages in the split */ + bool markfollowright; /* set F_FOLLOW_RIGHT flags */ + + /* + * follow: 1. gistxlogPage and array of IndexTupleData per page + */ +} gistxlogPageSplit; + +/* + * Backup Blk 0: page that was deleted. + * Backup Blk 1: parent page, containing the downlink to the deleted page. + */ +typedef struct gistxlogPageDelete +{ + FullTransactionId deleteXid; /* last Xid which could see page in scan */ + OffsetNumber downlinkOffset; /* Offset of downlink referencing this + * page */ +} gistxlogPageDelete; + +#define SizeOfGistxlogPageDelete (offsetof(gistxlogPageDelete, downlinkOffset) + sizeof(OffsetNumber)) + + +/* + * This is what we need to know about page reuse, for hot standby. + */ +typedef struct gistxlogPageReuse +{ + RelFileLocator locator; + BlockNumber block; + FullTransactionId snapshotConflictHorizon; + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ +} gistxlogPageReuse; + +#define SizeOfGistxlogPageReuse (offsetof(gistxlogPageReuse, isCatalogRel) + sizeof(bool)) + +extern void gist_redo(XLogReaderState *record); +extern void gist_desc(StringInfo buf, XLogReaderState *record); +extern const char *gist_identify(uint8 info); +extern void gist_xlog_startup(void); +extern void gist_xlog_cleanup(void); +extern void gist_mask(char *pagedata, BlockNumber blkno); + +#endif diff --git a/install/include/postgresql/server/access/hash.h b/install/include/postgresql/server/access/hash.h new file mode 100644 index 00000000000..9e035270a16 --- /dev/null +++ b/install/include/postgresql/server/access/hash.h @@ -0,0 +1,487 @@ +/*------------------------------------------------------------------------- + * + * hash.h + * header file for postgres hash access method implementation + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/hash.h + * + * NOTES + * modeled after Margo Seltzer's hash implementation for unix. + * + *------------------------------------------------------------------------- + */ +#ifndef HASH_H +#define HASH_H + +#include "access/amapi.h" +#include "access/itup.h" +#include "access/sdir.h" +#include "catalog/pg_am_d.h" +#include "common/hashfn.h" +#include "lib/stringinfo.h" +#include "storage/bufmgr.h" +#include "storage/lockdefs.h" +#include "utils/hsearch.h" +#include "utils/relcache.h" + +/* + * Mapping from hash bucket number to physical block number of bucket's + * starting page. Beware of multiple evaluations of argument! + */ +typedef uint32 Bucket; + +#define InvalidBucket ((Bucket) 0xFFFFFFFF) + +#define BUCKET_TO_BLKNO(metap,B) \ + ((BlockNumber) ((B) + ((B) ? (metap)->hashm_spares[_hash_spareindex((B)+1)-1] : 0)) + 1) + +/* + * Special space for hash index pages. + * + * hasho_flag's LH_PAGE_TYPE bits tell us which type of page we're looking at. + * Additional bits in the flag word are used for more transient purposes. + * + * To test a page's type, do (hasho_flag & LH_PAGE_TYPE) == LH_xxx_PAGE. + * However, we ensure that each used page type has a distinct bit so that + * we can OR together page types for uses such as the allowable-page-types + * argument of _hash_checkpage(). + */ +#define LH_UNUSED_PAGE (0) +#define LH_OVERFLOW_PAGE (1 << 0) +#define LH_BUCKET_PAGE (1 << 1) +#define LH_BITMAP_PAGE (1 << 2) +#define LH_META_PAGE (1 << 3) +#define LH_BUCKET_BEING_POPULATED (1 << 4) +#define LH_BUCKET_BEING_SPLIT (1 << 5) +#define LH_BUCKET_NEEDS_SPLIT_CLEANUP (1 << 6) +#define LH_PAGE_HAS_DEAD_TUPLES (1 << 7) + +#define LH_PAGE_TYPE \ + (LH_OVERFLOW_PAGE | LH_BUCKET_PAGE | LH_BITMAP_PAGE | LH_META_PAGE) + +/* + * In an overflow page, hasho_prevblkno stores the block number of the previous + * page in the bucket chain; in a bucket page, hasho_prevblkno stores the + * hashm_maxbucket value as of the last time the bucket was last split, or + * else as of the time the bucket was created. The latter convention is used + * to determine whether a cached copy of the metapage is too stale to be used + * without needing to lock or pin the metapage. + * + * hasho_nextblkno is always the block number of the next page in the + * bucket chain, or InvalidBlockNumber if there are no more such pages. + */ +typedef struct HashPageOpaqueData +{ + BlockNumber hasho_prevblkno; /* see above */ + BlockNumber hasho_nextblkno; /* see above */ + Bucket hasho_bucket; /* bucket number this pg belongs to */ + uint16 hasho_flag; /* page type code + flag bits, see above */ + uint16 hasho_page_id; /* for identification of hash indexes */ +} HashPageOpaqueData; + +typedef HashPageOpaqueData *HashPageOpaque; + +#define HashPageGetOpaque(page) ((HashPageOpaque) PageGetSpecialPointer(page)) + +#define H_NEEDS_SPLIT_CLEANUP(opaque) (((opaque)->hasho_flag & LH_BUCKET_NEEDS_SPLIT_CLEANUP) != 0) +#define H_BUCKET_BEING_SPLIT(opaque) (((opaque)->hasho_flag & LH_BUCKET_BEING_SPLIT) != 0) +#define H_BUCKET_BEING_POPULATED(opaque) (((opaque)->hasho_flag & LH_BUCKET_BEING_POPULATED) != 0) +#define H_HAS_DEAD_TUPLES(opaque) (((opaque)->hasho_flag & LH_PAGE_HAS_DEAD_TUPLES) != 0) + +/* + * The page ID is for the convenience of pg_filedump and similar utilities, + * which otherwise would have a hard time telling pages of different index + * types apart. It should be the last 2 bytes on the page. This is more or + * less "free" due to alignment considerations. + */ +#define HASHO_PAGE_ID 0xFF80 + +typedef struct HashScanPosItem /* what we remember about each match */ +{ + ItemPointerData heapTid; /* TID of referenced heap item */ + OffsetNumber indexOffset; /* index item's location within page */ +} HashScanPosItem; + +typedef struct HashScanPosData +{ + Buffer buf; /* if valid, the buffer is pinned */ + BlockNumber currPage; /* current hash index page */ + BlockNumber nextPage; /* next overflow page */ + BlockNumber prevPage; /* prev overflow or bucket page */ + + /* + * The items array is always ordered in index order (ie, increasing + * indexoffset). When scanning backwards it is convenient to fill the + * array back-to-front, so we start at the last slot and fill downwards. + * Hence we need both a first-valid-entry and a last-valid-entry counter. + * itemIndex is a cursor showing which entry was last returned to caller. + */ + int firstItem; /* first valid index in items[] */ + int lastItem; /* last valid index in items[] */ + int itemIndex; /* current index in items[] */ + + HashScanPosItem items[MaxIndexTuplesPerPage]; /* MUST BE LAST */ +} HashScanPosData; + +#define HashScanPosIsPinned(scanpos) \ +( \ + AssertMacro(BlockNumberIsValid((scanpos).currPage) || \ + !BufferIsValid((scanpos).buf)), \ + BufferIsValid((scanpos).buf) \ +) + +#define HashScanPosIsValid(scanpos) \ +( \ + AssertMacro(BlockNumberIsValid((scanpos).currPage) || \ + !BufferIsValid((scanpos).buf)), \ + BlockNumberIsValid((scanpos).currPage) \ +) + +#define HashScanPosInvalidate(scanpos) \ + do { \ + (scanpos).buf = InvalidBuffer; \ + (scanpos).currPage = InvalidBlockNumber; \ + (scanpos).nextPage = InvalidBlockNumber; \ + (scanpos).prevPage = InvalidBlockNumber; \ + (scanpos).firstItem = 0; \ + (scanpos).lastItem = 0; \ + (scanpos).itemIndex = 0; \ + } while (0) + +/* + * HashScanOpaqueData is private state for a hash index scan. + */ +typedef struct HashScanOpaqueData +{ + /* Hash value of the scan key, ie, the hash key we seek */ + uint32 hashso_sk_hash; + + /* remember the buffer associated with primary bucket */ + Buffer hashso_bucket_buf; + + /* + * remember the buffer associated with primary bucket page of bucket being + * split. it is required during the scan of the bucket which is being + * populated during split operation. + */ + Buffer hashso_split_bucket_buf; + + /* Whether scan starts on bucket being populated due to split */ + bool hashso_buc_populated; + + /* + * Whether scanning bucket being split? The value of this parameter is + * referred only when hashso_buc_populated is true. + */ + bool hashso_buc_split; + /* info about killed items if any (killedItems is NULL if never used) */ + int *killedItems; /* currPos.items indexes of killed items */ + int numKilled; /* number of currently stored items */ + + /* + * Identify all the matching items on a page and save them in + * HashScanPosData + */ + HashScanPosData currPos; /* current position data */ +} HashScanOpaqueData; + +typedef HashScanOpaqueData *HashScanOpaque; + +/* + * Definitions for metapage. + */ + +#define HASH_METAPAGE 0 /* metapage is always block 0 */ + +#define HASH_MAGIC 0x6440640 +#define HASH_VERSION 4 + +/* + * spares[] holds the number of overflow pages currently allocated at or + * before a certain splitpoint. For example, if spares[3] = 7 then there are + * 7 ovflpages before splitpoint 3 (compare BUCKET_TO_BLKNO macro). The + * value in spares[ovflpoint] increases as overflow pages are added at the + * end of the index. Once ovflpoint increases (ie, we have actually allocated + * the bucket pages belonging to that splitpoint) the number of spares at the + * prior splitpoint cannot change anymore. + * + * ovflpages that have been recycled for reuse can be found by looking at + * bitmaps that are stored within ovflpages dedicated for the purpose. + * The blknos of these bitmap pages are kept in mapp[]; nmaps is the + * number of currently existing bitmaps. + * + * The limitation on the size of spares[] comes from the fact that there's + * no point in having more than 2^32 buckets with only uint32 hashcodes. + * (Note: The value of HASH_MAX_SPLITPOINTS which is the size of spares[] is + * adjusted in such a way to accommodate multi phased allocation of buckets + * after HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE). + * + * There is no particular upper limit on the size of mapp[], other than + * needing to fit into the metapage. (With 8K block size, 1024 bitmaps + * limit us to 256 GB of overflow space...). For smaller block size we + * can not use 1024 bitmaps as it will lead to the meta page data crossing + * the block size boundary. So we use BLCKSZ to determine the maximum number + * of bitmaps. + */ +#define HASH_MAX_BITMAPS Min(BLCKSZ / 8, 1024) + +#define HASH_SPLITPOINT_PHASE_BITS 2 +#define HASH_SPLITPOINT_PHASES_PER_GRP (1 << HASH_SPLITPOINT_PHASE_BITS) +#define HASH_SPLITPOINT_PHASE_MASK (HASH_SPLITPOINT_PHASES_PER_GRP - 1) +#define HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE 10 + +/* defines max number of splitpoint phases a hash index can have */ +#define HASH_MAX_SPLITPOINT_GROUP 32 +#define HASH_MAX_SPLITPOINTS \ + (((HASH_MAX_SPLITPOINT_GROUP - HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE) * \ + HASH_SPLITPOINT_PHASES_PER_GRP) + \ + HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE) + +typedef struct HashMetaPageData +{ + uint32 hashm_magic; /* magic no. for hash tables */ + uint32 hashm_version; /* version ID */ + double hashm_ntuples; /* number of tuples stored in the table */ + uint16 hashm_ffactor; /* target fill factor (tuples/bucket) */ + uint16 hashm_bsize; /* index page size (bytes) */ + uint16 hashm_bmsize; /* bitmap array size (bytes) - must be a power + * of 2 */ + uint16 hashm_bmshift; /* log2(bitmap array size in BITS) */ + uint32 hashm_maxbucket; /* ID of maximum bucket in use */ + uint32 hashm_highmask; /* mask to modulo into entire table */ + uint32 hashm_lowmask; /* mask to modulo into lower half of table */ + uint32 hashm_ovflpoint; /* splitpoint from which ovflpage being + * allocated */ + uint32 hashm_firstfree; /* lowest-number free ovflpage (bit#) */ + uint32 hashm_nmaps; /* number of bitmap pages */ + RegProcedure hashm_procid; /* hash function id from pg_proc */ + uint32 hashm_spares[HASH_MAX_SPLITPOINTS]; /* spare pages before each + * splitpoint */ + BlockNumber hashm_mapp[HASH_MAX_BITMAPS]; /* blknos of ovfl bitmaps */ +} HashMetaPageData; + +typedef HashMetaPageData *HashMetaPage; + +typedef struct HashOptions +{ + int32 varlena_header_; /* varlena header (do not touch directly!) */ + int fillfactor; /* page fill factor in percent (0..100) */ +} HashOptions; + +#define HashGetFillFactor(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == HASH_AM_OID), \ + (relation)->rd_options ? \ + ((HashOptions *) (relation)->rd_options)->fillfactor : \ + HASH_DEFAULT_FILLFACTOR) +#define HashGetTargetPageUsage(relation) \ + (BLCKSZ * HashGetFillFactor(relation) / 100) + +/* + * Maximum size of a hash index item (it's okay to have only one per page) + */ +#define HashMaxItemSize(page) \ + MAXALIGN_DOWN(PageGetPageSize(page) - \ + SizeOfPageHeaderData - \ + sizeof(ItemIdData) - \ + MAXALIGN(sizeof(HashPageOpaqueData))) + +#define INDEX_MOVED_BY_SPLIT_MASK INDEX_AM_RESERVED_BIT + +#define HASH_MIN_FILLFACTOR 10 +#define HASH_DEFAULT_FILLFACTOR 75 + +/* + * Constants + */ +#define BYTE_TO_BIT 3 /* 2^3 bits/byte */ +#define ALL_SET ((uint32) ~0) + +/* + * Bitmap pages do not contain tuples. They do contain the standard + * page headers and trailers; however, everything in between is a + * giant bit array. The number of bits that fit on a page obviously + * depends on the page size and the header/trailer overhead. We require + * the number of bits per page to be a power of 2. + */ +#define BMPGSZ_BYTE(metap) ((metap)->hashm_bmsize) +#define BMPGSZ_BIT(metap) ((metap)->hashm_bmsize << BYTE_TO_BIT) +#define BMPG_SHIFT(metap) ((metap)->hashm_bmshift) +#define BMPG_MASK(metap) (BMPGSZ_BIT(metap) - 1) + +#define HashPageGetBitmap(page) \ + ((uint32 *) PageGetContents(page)) + +#define HashGetMaxBitmapSize(page) \ + (PageGetPageSize((Page) page) - \ + (MAXALIGN(SizeOfPageHeaderData) + MAXALIGN(sizeof(HashPageOpaqueData)))) + +#define HashPageGetMeta(page) \ + ((HashMetaPage) PageGetContents(page)) + +/* + * The number of bits in an ovflpage bitmap word. + */ +#define BITS_PER_MAP 32 /* Number of bits in uint32 */ + +/* Given the address of the beginning of a bit map, clear/set the nth bit */ +#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP))) +#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP))) +#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP))) + +/* + * page-level and high-level locking modes (see README) + */ +#define HASH_READ BUFFER_LOCK_SHARE +#define HASH_WRITE BUFFER_LOCK_EXCLUSIVE +#define HASH_NOLOCK (-1) + +/* + * When a new operator class is declared, we require that the user supply + * us with an amproc function for hashing a key of the new type, returning + * a 32-bit hash value. We call this the "standard" hash function. We + * also allow an optional "extended" hash function which accepts a salt and + * returns a 64-bit hash value. This is highly recommended but, for reasons + * of backward compatibility, optional. + * + * When the salt is 0, the low 32 bits of the value returned by the extended + * hash function should match the value that would have been returned by the + * standard hash function. + */ +#define HASHSTANDARD_PROC 1 +#define HASHEXTENDED_PROC 2 +#define HASHOPTIONS_PROC 3 +#define HASHNProcs 3 + + +/* public routines */ + +extern IndexBuildResult *hashbuild(Relation heap, Relation index, + struct IndexInfo *indexInfo); +extern void hashbuildempty(Relation index); +extern bool hashinsert(Relation rel, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); +extern bool hashgettuple(IndexScanDesc scan, ScanDirection dir); +extern int64 hashgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); +extern IndexScanDesc hashbeginscan(Relation rel, int nkeys, int norderbys); +extern void hashrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys); +extern void hashendscan(IndexScanDesc scan); +extern IndexBulkDeleteResult *hashbulkdelete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *hashvacuumcleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); +extern bytea *hashoptions(Datum reloptions, bool validate); +extern bool hashvalidate(Oid opclassoid); +extern void hashadjustmembers(Oid opfamilyoid, + Oid opclassoid, + List *operators, + List *functions); + +/* private routines */ + +/* hashinsert.c */ +extern void _hash_doinsert(Relation rel, IndexTuple itup, Relation heapRel, + bool sorted); +extern OffsetNumber _hash_pgaddtup(Relation rel, Buffer buf, + Size itemsize, IndexTuple itup, + bool appendtup); +extern void _hash_pgaddmultitup(Relation rel, Buffer buf, IndexTuple *itups, + OffsetNumber *itup_offsets, uint16 nitups); + +/* hashovfl.c */ +extern Buffer _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf, bool retain_pin); +extern BlockNumber _hash_freeovflpage(Relation rel, Buffer bucketbuf, Buffer ovflbuf, + Buffer wbuf, IndexTuple *itups, OffsetNumber *itup_offsets, + Size *tups_size, uint16 nitups, BufferAccessStrategy bstrategy); +extern void _hash_initbitmapbuffer(Buffer buf, uint16 bmsize, bool initpage); +extern void _hash_squeezebucket(Relation rel, + Bucket bucket, BlockNumber bucket_blkno, + Buffer bucket_buf, + BufferAccessStrategy bstrategy); +extern uint32 _hash_ovflblkno_to_bitno(HashMetaPage metap, BlockNumber ovflblkno); + +/* hashpage.c */ +extern Buffer _hash_getbuf(Relation rel, BlockNumber blkno, + int access, int flags); +extern Buffer _hash_getbuf_with_condlock_cleanup(Relation rel, + BlockNumber blkno, int flags); +extern HashMetaPage _hash_getcachedmetap(Relation rel, Buffer *metabuf, + bool force_refresh); +extern Buffer _hash_getbucketbuf_from_hashkey(Relation rel, uint32 hashkey, + int access, + HashMetaPage *cachedmetap); +extern Buffer _hash_getinitbuf(Relation rel, BlockNumber blkno); +extern void _hash_initbuf(Buffer buf, uint32 max_bucket, uint32 num_bucket, + uint32 flag, bool initpage); +extern Buffer _hash_getnewbuf(Relation rel, BlockNumber blkno, + ForkNumber forkNum); +extern Buffer _hash_getbuf_with_strategy(Relation rel, BlockNumber blkno, + int access, int flags, + BufferAccessStrategy bstrategy); +extern void _hash_relbuf(Relation rel, Buffer buf); +extern void _hash_dropbuf(Relation rel, Buffer buf); +extern void _hash_dropscanbuf(Relation rel, HashScanOpaque so); +extern uint32 _hash_init(Relation rel, double num_tuples, + ForkNumber forkNum); +extern void _hash_init_metabuffer(Buffer buf, double num_tuples, + RegProcedure procid, uint16 ffactor, bool initpage); +extern void _hash_pageinit(Page page, Size size); +extern void _hash_expandtable(Relation rel, Buffer metabuf); +extern void _hash_finish_split(Relation rel, Buffer metabuf, Buffer obuf, + Bucket obucket, uint32 maxbucket, uint32 highmask, + uint32 lowmask); + +/* hashsearch.c */ +extern bool _hash_next(IndexScanDesc scan, ScanDirection dir); +extern bool _hash_first(IndexScanDesc scan, ScanDirection dir); + +/* hashsort.c */ +typedef struct HSpool HSpool; /* opaque struct in hashsort.c */ + +extern HSpool *_h_spoolinit(Relation heap, Relation index, uint32 num_buckets); +extern void _h_spooldestroy(HSpool *hspool); +extern void _h_spool(HSpool *hspool, ItemPointer self, + Datum *values, bool *isnull); +extern void _h_indexbuild(HSpool *hspool, Relation heapRel); + +/* hashutil.c */ +extern bool _hash_checkqual(IndexScanDesc scan, IndexTuple itup); +extern uint32 _hash_datum2hashkey(Relation rel, Datum key); +extern uint32 _hash_datum2hashkey_type(Relation rel, Datum key, Oid keytype); +extern Bucket _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket, + uint32 highmask, uint32 lowmask); +extern uint32 _hash_spareindex(uint32 num_bucket); +extern uint32 _hash_get_totalbuckets(uint32 splitpoint_phase); +extern void _hash_checkpage(Relation rel, Buffer buf, int flags); +extern uint32 _hash_get_indextuple_hashkey(IndexTuple itup); +extern bool _hash_convert_tuple(Relation index, + Datum *user_values, bool *user_isnull, + Datum *index_values, bool *index_isnull); +extern OffsetNumber _hash_binsearch(Page page, uint32 hash_value); +extern OffsetNumber _hash_binsearch_last(Page page, uint32 hash_value); +extern BlockNumber _hash_get_oldblock_from_newbucket(Relation rel, Bucket new_bucket); +extern BlockNumber _hash_get_newblock_from_oldbucket(Relation rel, Bucket old_bucket); +extern Bucket _hash_get_newbucket_from_oldbucket(Relation rel, Bucket old_bucket, + uint32 lowmask, uint32 maxbucket); +extern void _hash_kill_items(IndexScanDesc scan); + +/* hash.c */ +extern void hashbucketcleanup(Relation rel, Bucket cur_bucket, + Buffer bucket_buf, BlockNumber bucket_blkno, + BufferAccessStrategy bstrategy, + uint32 maxbucket, uint32 highmask, uint32 lowmask, + double *tuples_removed, double *num_index_tuples, + bool split_cleanup, + IndexBulkDeleteCallback callback, void *callback_state); + +#endif /* HASH_H */ diff --git a/install/include/postgresql/server/access/hash_xlog.h b/install/include/postgresql/server/access/hash_xlog.h new file mode 100644 index 00000000000..03ad47af435 --- /dev/null +++ b/install/include/postgresql/server/access/hash_xlog.h @@ -0,0 +1,270 @@ +/*------------------------------------------------------------------------- + * + * hash_xlog.h + * header file for Postgres hash AM implementation + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/hash_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef HASH_XLOG_H +#define HASH_XLOG_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/off.h" + +/* Number of buffers required for XLOG_HASH_SQUEEZE_PAGE operation */ +#define HASH_XLOG_FREE_OVFL_BUFS 6 + +/* + * XLOG records for hash operations + */ +#define XLOG_HASH_INIT_META_PAGE 0x00 /* initialize the meta page */ +#define XLOG_HASH_INIT_BITMAP_PAGE 0x10 /* initialize the bitmap page */ +#define XLOG_HASH_INSERT 0x20 /* add index tuple without split */ +#define XLOG_HASH_ADD_OVFL_PAGE 0x30 /* add overflow page */ +#define XLOG_HASH_SPLIT_ALLOCATE_PAGE 0x40 /* allocate new page for split */ +#define XLOG_HASH_SPLIT_PAGE 0x50 /* split page */ +#define XLOG_HASH_SPLIT_COMPLETE 0x60 /* completion of split operation */ +#define XLOG_HASH_MOVE_PAGE_CONTENTS 0x70 /* remove tuples from one page + * and add to another page */ +#define XLOG_HASH_SQUEEZE_PAGE 0x80 /* add tuples to one of the previous + * pages in chain and free the ovfl + * page */ +#define XLOG_HASH_DELETE 0x90 /* delete index tuples from a page */ +#define XLOG_HASH_SPLIT_CLEANUP 0xA0 /* clear split-cleanup flag in primary + * bucket page after deleting tuples + * that are moved due to split */ +#define XLOG_HASH_UPDATE_META_PAGE 0xB0 /* update meta page after vacuum */ + +#define XLOG_HASH_VACUUM_ONE_PAGE 0xC0 /* remove dead tuples from index + * page */ + +/* + * xl_hash_split_allocate_page flag values, 8 bits are available. + */ +#define XLH_SPLIT_META_UPDATE_MASKS (1<<0) +#define XLH_SPLIT_META_UPDATE_SPLITPOINT (1<<1) + +/* + * This is what we need to know about simple (without split) insert. + * + * This data record is used for XLOG_HASH_INSERT + * + * Backup Blk 0: original page (data contains the inserted tuple) + * Backup Blk 1: metapage (HashMetaPageData) + */ +typedef struct xl_hash_insert +{ + OffsetNumber offnum; +} xl_hash_insert; + +#define SizeOfHashInsert (offsetof(xl_hash_insert, offnum) + sizeof(OffsetNumber)) + +/* + * This is what we need to know about addition of overflow page. + * + * This data record is used for XLOG_HASH_ADD_OVFL_PAGE + * + * Backup Blk 0: newly allocated overflow page + * Backup Blk 1: page before new overflow page in the bucket chain + * Backup Blk 2: bitmap page + * Backup Blk 3: new bitmap page + * Backup Blk 4: metapage + */ +typedef struct xl_hash_add_ovfl_page +{ + uint16 bmsize; + bool bmpage_found; +} xl_hash_add_ovfl_page; + +#define SizeOfHashAddOvflPage \ + (offsetof(xl_hash_add_ovfl_page, bmpage_found) + sizeof(bool)) + +/* + * This is what we need to know about allocating a page for split. + * + * This data record is used for XLOG_HASH_SPLIT_ALLOCATE_PAGE + * + * Backup Blk 0: page for old bucket + * Backup Blk 1: page for new bucket + * Backup Blk 2: metapage + */ +typedef struct xl_hash_split_allocate_page +{ + uint32 new_bucket; + uint16 old_bucket_flag; + uint16 new_bucket_flag; + uint8 flags; +} xl_hash_split_allocate_page; + +#define SizeOfHashSplitAllocPage \ + (offsetof(xl_hash_split_allocate_page, flags) + sizeof(uint8)) + +/* + * This is what we need to know about completing the split operation. + * + * This data record is used for XLOG_HASH_SPLIT_COMPLETE + * + * Backup Blk 0: page for old bucket + * Backup Blk 1: page for new bucket + */ +typedef struct xl_hash_split_complete +{ + uint16 old_bucket_flag; + uint16 new_bucket_flag; +} xl_hash_split_complete; + +#define SizeOfHashSplitComplete \ + (offsetof(xl_hash_split_complete, new_bucket_flag) + sizeof(uint16)) + +/* + * This is what we need to know about move page contents required during + * squeeze operation. + * + * This data record is used for XLOG_HASH_MOVE_PAGE_CONTENTS + * + * Backup Blk 0: primary bucket page + * Backup Blk 1: page containing moved tuples + * Backup Blk 2: page from which tuples will be removed + */ +typedef struct xl_hash_move_page_contents +{ + uint16 ntups; + bool is_prim_bucket_same_wrt; /* true if the page to which + * tuples are moved is same as + * primary bucket page */ +} xl_hash_move_page_contents; + +#define SizeOfHashMovePageContents \ + (offsetof(xl_hash_move_page_contents, is_prim_bucket_same_wrt) + sizeof(bool)) + +/* + * This is what we need to know about the squeeze page operation. + * + * This data record is used for XLOG_HASH_SQUEEZE_PAGE + * + * Backup Blk 0: primary bucket page + * Backup Blk 1: page containing tuples moved from freed overflow page + * Backup Blk 2: freed overflow page + * Backup Blk 3: page previous to the freed overflow page + * Backup Blk 4: page next to the freed overflow page + * Backup Blk 5: bitmap page containing info of freed overflow page + * Backup Blk 6: meta page + */ +typedef struct xl_hash_squeeze_page +{ + BlockNumber prevblkno; + BlockNumber nextblkno; + uint16 ntups; + bool is_prim_bucket_same_wrt; /* true if the page to which + * tuples are moved is same as + * primary bucket page */ + bool is_prev_bucket_same_wrt; /* true if the page to which + * tuples are moved is the page + * previous to the freed overflow + * page */ +} xl_hash_squeeze_page; + +#define SizeOfHashSqueezePage \ + (offsetof(xl_hash_squeeze_page, is_prev_bucket_same_wrt) + sizeof(bool)) + +/* + * This is what we need to know about the deletion of index tuples from a page. + * + * This data record is used for XLOG_HASH_DELETE + * + * Backup Blk 0: primary bucket page + * Backup Blk 1: page from which tuples are deleted + */ +typedef struct xl_hash_delete +{ + bool clear_dead_marking; /* true if this operation clears + * LH_PAGE_HAS_DEAD_TUPLES flag */ + bool is_primary_bucket_page; /* true if the operation is for + * primary bucket page */ +} xl_hash_delete; + +#define SizeOfHashDelete (offsetof(xl_hash_delete, is_primary_bucket_page) + sizeof(bool)) + +/* + * This is what we need for metapage update operation. + * + * This data record is used for XLOG_HASH_UPDATE_META_PAGE + * + * Backup Blk 0: meta page + */ +typedef struct xl_hash_update_meta_page +{ + double ntuples; +} xl_hash_update_meta_page; + +#define SizeOfHashUpdateMetaPage \ + (offsetof(xl_hash_update_meta_page, ntuples) + sizeof(double)) + +/* + * This is what we need to initialize metapage. + * + * This data record is used for XLOG_HASH_INIT_META_PAGE + * + * Backup Blk 0: meta page + */ +typedef struct xl_hash_init_meta_page +{ + double num_tuples; + RegProcedure procid; + uint16 ffactor; +} xl_hash_init_meta_page; + +#define SizeOfHashInitMetaPage \ + (offsetof(xl_hash_init_meta_page, ffactor) + sizeof(uint16)) + +/* + * This is what we need to initialize bitmap page. + * + * This data record is used for XLOG_HASH_INIT_BITMAP_PAGE + * + * Backup Blk 0: bitmap page + * Backup Blk 1: meta page + */ +typedef struct xl_hash_init_bitmap_page +{ + uint16 bmsize; +} xl_hash_init_bitmap_page; + +#define SizeOfHashInitBitmapPage \ + (offsetof(xl_hash_init_bitmap_page, bmsize) + sizeof(uint16)) + +/* + * This is what we need for index tuple deletion and to + * update the meta page. + * + * This data record is used for XLOG_HASH_VACUUM_ONE_PAGE + * + * Backup Blk 0: primary bucket page + * Backup Blk 1: meta page + */ +typedef struct xl_hash_vacuum_one_page +{ + TransactionId snapshotConflictHorizon; + uint16 ntuples; + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ + + /* TARGET OFFSET NUMBERS */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} xl_hash_vacuum_one_page; + +#define SizeOfHashVacuumOnePage offsetof(xl_hash_vacuum_one_page, offsets) + +extern void hash_redo(XLogReaderState *record); +extern void hash_desc(StringInfo buf, XLogReaderState *record); +extern const char *hash_identify(uint8 info); +extern void hash_mask(char *pagedata, BlockNumber blkno); + +#endif /* HASH_XLOG_H */ diff --git a/install/include/postgresql/server/access/heapam.h b/install/include/postgresql/server/access/heapam.h new file mode 100644 index 00000000000..edf8ec69b14 --- /dev/null +++ b/install/include/postgresql/server/access/heapam.h @@ -0,0 +1,341 @@ +/*------------------------------------------------------------------------- + * + * heapam.h + * POSTGRES heap access method definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/heapam.h + * + *------------------------------------------------------------------------- + */ +#ifndef HEAPAM_H +#define HEAPAM_H + +#include "access/relation.h" /* for backward compatibility */ +#include "access/relscan.h" +#include "access/sdir.h" +#include "access/skey.h" +#include "access/table.h" /* for backward compatibility */ +#include "access/tableam.h" +#include "nodes/lockoptions.h" +#include "nodes/primnodes.h" +#include "storage/bufpage.h" +#include "storage/dsm.h" +#include "storage/lockdefs.h" +#include "storage/shm_toc.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + + +/* "options" flag bits for heap_insert */ +#define HEAP_INSERT_SKIP_FSM TABLE_INSERT_SKIP_FSM +#define HEAP_INSERT_FROZEN TABLE_INSERT_FROZEN +#define HEAP_INSERT_NO_LOGICAL TABLE_INSERT_NO_LOGICAL +#define HEAP_INSERT_SPECULATIVE 0x0010 + +typedef struct BulkInsertStateData *BulkInsertState; +struct TupleTableSlot; +struct VacuumCutoffs; + +#define MaxLockTupleMode LockTupleExclusive + +/* + * Descriptor for heap table scans. + */ +typedef struct HeapScanDescData +{ + TableScanDescData rs_base; /* AM independent part of the descriptor */ + + /* state set up at initscan time */ + BlockNumber rs_nblocks; /* total number of blocks in rel */ + BlockNumber rs_startblock; /* block # to start at */ + BlockNumber rs_numblocks; /* max number of blocks to scan */ + /* rs_numblocks is usually InvalidBlockNumber, meaning "scan whole rel" */ + + /* scan current state */ + bool rs_inited; /* false = scan not init'd yet */ + OffsetNumber rs_coffset; /* current offset # in non-page-at-a-time mode */ + BlockNumber rs_cblock; /* current block # in scan, if any */ + Buffer rs_cbuf; /* current buffer in scan, if any */ + /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ + + BufferAccessStrategy rs_strategy; /* access strategy for reads */ + + HeapTupleData rs_ctup; /* current tuple in scan, if any */ + + /* + * For parallel scans to store page allocation data. NULL when not + * performing a parallel scan. + */ + ParallelBlockTableScanWorkerData *rs_parallelworkerdata; + + /* these fields only used in page-at-a-time mode and for bitmap scans */ + int rs_cindex; /* current tuple's index in vistuples */ + int rs_ntuples; /* number of visible tuples on page */ + OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]; /* their offsets */ +} HeapScanDescData; +typedef struct HeapScanDescData *HeapScanDesc; + +/* + * Descriptor for fetches from heap via an index. + */ +typedef struct IndexFetchHeapData +{ + IndexFetchTableData xs_base; /* AM independent part of the descriptor */ + + Buffer xs_cbuf; /* current heap buffer in scan, if any */ + /* NB: if xs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ +} IndexFetchHeapData; + +/* Result codes for HeapTupleSatisfiesVacuum */ +typedef enum +{ + HEAPTUPLE_DEAD, /* tuple is dead and deletable */ + HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */ + HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */ + HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */ + HEAPTUPLE_DELETE_IN_PROGRESS /* deleting xact is still in progress */ +} HTSV_Result; + +/* + * heap_prepare_freeze_tuple may request that heap_freeze_execute_prepared + * check any tuple's to-be-frozen xmin and/or xmax status using pg_xact + */ +#define HEAP_FREEZE_CHECK_XMIN_COMMITTED 0x01 +#define HEAP_FREEZE_CHECK_XMAX_ABORTED 0x02 + +/* heap_prepare_freeze_tuple state describing how to freeze a tuple */ +typedef struct HeapTupleFreeze +{ + /* Fields describing how to process tuple */ + TransactionId xmax; + uint16 t_infomask2; + uint16 t_infomask; + uint8 frzflags; + + /* xmin/xmax check flags */ + uint8 checkflags; + /* Page offset number for tuple */ + OffsetNumber offset; +} HeapTupleFreeze; + +/* + * State used by VACUUM to track the details of freezing all eligible tuples + * on a given heap page. + * + * VACUUM prepares freeze plans for each page via heap_prepare_freeze_tuple + * calls (every tuple with storage gets its own call). This page-level freeze + * state is updated across each call, which ultimately determines whether or + * not freezing the page is required. + * + * Aside from the basic question of whether or not freezing will go ahead, the + * state also tracks the oldest extant XID/MXID in the table as a whole, for + * the purposes of advancing relfrozenxid/relminmxid values in pg_class later + * on. Each heap_prepare_freeze_tuple call pushes NewRelfrozenXid and/or + * NewRelminMxid back as required to avoid unsafe final pg_class values. Any + * and all unfrozen XIDs or MXIDs that remain after VACUUM finishes _must_ + * have values >= the final relfrozenxid/relminmxid values in pg_class. This + * includes XIDs that remain as MultiXact members from any tuple's xmax. + * + * When 'freeze_required' flag isn't set after all tuples are examined, the + * final choice on freezing is made by vacuumlazy.c. It can decide to trigger + * freezing based on whatever criteria it deems appropriate. However, it is + * recommended that vacuumlazy.c avoid early freezing when freezing does not + * enable setting the target page all-frozen in the visibility map afterwards. + */ +typedef struct HeapPageFreeze +{ + /* Is heap_prepare_freeze_tuple caller required to freeze page? */ + bool freeze_required; + + /* + * "Freeze" NewRelfrozenXid/NewRelminMxid trackers. + * + * Trackers used when heap_freeze_execute_prepared freezes, or when there + * are zero freeze plans for a page. It is always valid for vacuumlazy.c + * to freeze any page, by definition. This even includes pages that have + * no tuples with storage to consider in the first place. That way the + * 'totally_frozen' results from heap_prepare_freeze_tuple can always be + * used in the same way, even when no freeze plans need to be executed to + * "freeze the page". Only the "freeze" path needs to consider the need + * to set pages all-frozen in the visibility map under this scheme. + * + * When we freeze a page, we generally freeze all XIDs < OldestXmin, only + * leaving behind XIDs that are ineligible for freezing, if any. And so + * you might wonder why these trackers are necessary at all; why should + * _any_ page that VACUUM freezes _ever_ be left with XIDs/MXIDs that + * ratchet back the top-level NewRelfrozenXid/NewRelminMxid trackers? + * + * It is useful to use a definition of "freeze the page" that does not + * overspecify how MultiXacts are affected. heap_prepare_freeze_tuple + * generally prefers to remove Multis eagerly, but lazy processing is used + * in cases where laziness allows VACUUM to avoid allocating a new Multi. + * The "freeze the page" trackers enable this flexibility. + */ + TransactionId FreezePageRelfrozenXid; + MultiXactId FreezePageRelminMxid; + + /* + * "No freeze" NewRelfrozenXid/NewRelminMxid trackers. + * + * These trackers are maintained in the same way as the trackers used when + * VACUUM scans a page that isn't cleanup locked. Both code paths are + * based on the same general idea (do less work for this page during the + * ongoing VACUUM, at the cost of having to accept older final values). + */ + TransactionId NoFreezePageRelfrozenXid; + MultiXactId NoFreezePageRelminMxid; + +} HeapPageFreeze; + +/* ---------------- + * function prototypes for heap access method + * + * heap_create, heap_create_with_catalog, and heap_drop_with_catalog + * are declared in catalog/heap.h + * ---------------- + */ + + +/* + * HeapScanIsValid + * True iff the heap scan is valid. + */ +#define HeapScanIsValid(scan) PointerIsValid(scan) + +extern TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot, + int nkeys, ScanKey key, + ParallelTableScanDesc parallel_scan, + uint32 flags); +extern void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, + BlockNumber numBlks); +extern void heapgetpage(TableScanDesc sscan, BlockNumber block); +extern void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params, + bool allow_strat, bool allow_sync, bool allow_pagemode); +extern void heap_endscan(TableScanDesc sscan); +extern HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction); +extern bool heap_getnextslot(TableScanDesc sscan, + ScanDirection direction, struct TupleTableSlot *slot); +extern void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid, + ItemPointer maxtid); +extern bool heap_getnextslot_tidrange(TableScanDesc sscan, + ScanDirection direction, + TupleTableSlot *slot); +extern bool heap_fetch(Relation relation, Snapshot snapshot, + HeapTuple tuple, Buffer *userbuf, bool keep_buf); +extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation, + Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, + bool *all_dead, bool first_call); + +extern void heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid); + +extern BulkInsertState GetBulkInsertState(void); +extern void FreeBulkInsertState(BulkInsertState); +extern void ReleaseBulkInsertStatePin(BulkInsertState bistate); + +extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid, + int options, BulkInsertState bistate); +extern void heap_multi_insert(Relation relation, struct TupleTableSlot **slots, + int ntuples, CommandId cid, int options, + BulkInsertState bistate); +extern TM_Result heap_delete(Relation relation, ItemPointer tid, + CommandId cid, Snapshot crosscheck, bool wait, + struct TM_FailureData *tmfd, bool changingPart); +extern void heap_finish_speculative(Relation relation, ItemPointer tid); +extern void heap_abort_speculative(Relation relation, ItemPointer tid); +extern TM_Result heap_update(Relation relation, ItemPointer otid, + HeapTuple newtup, + CommandId cid, Snapshot crosscheck, bool wait, + struct TM_FailureData *tmfd, LockTupleMode *lockmode, + TU_UpdateIndexes *update_indexes); +extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, + CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, + bool follow_updates, + Buffer *buffer, struct TM_FailureData *tmfd); + +extern bool heap_inplace_lock(Relation relation, + HeapTuple oldtup_ptr, Buffer buffer, + void (*release_callback) (void *), void *arg); +extern void heap_inplace_update_and_unlock(Relation relation, + HeapTuple oldtup, HeapTuple tuple, + Buffer buffer); +extern void heap_inplace_unlock(Relation relation, + HeapTuple oldtup, Buffer buffer); +extern void heap_inplace_update(Relation relation, HeapTuple tuple); +extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, + const struct VacuumCutoffs *cutoffs, + HeapPageFreeze *pagefrz, + HeapTupleFreeze *frz, bool *totally_frozen); +extern void heap_freeze_execute_prepared(Relation rel, Buffer buffer, + TransactionId snapshotConflictHorizon, + HeapTupleFreeze *tuples, int ntuples); +extern bool heap_freeze_tuple(HeapTupleHeader tuple, + TransactionId relfrozenxid, TransactionId relminmxid, + TransactionId FreezeLimit, TransactionId MultiXactCutoff); +extern bool heap_tuple_should_freeze(HeapTupleHeader tuple, + const struct VacuumCutoffs *cutoffs, + TransactionId *NoFreezePageRelfrozenXid, + MultiXactId *NoFreezePageRelminMxid); +extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple); + +extern void simple_heap_insert(Relation relation, HeapTuple tup); +extern void simple_heap_delete(Relation relation, ItemPointer tid); +extern void simple_heap_update(Relation relation, ItemPointer otid, + HeapTuple tup, TU_UpdateIndexes *update_indexes); + +extern TransactionId heap_index_delete_tuples(Relation rel, + TM_IndexDeleteOp *delstate); + +/* in heap/pruneheap.c */ +struct GlobalVisState; +extern void heap_page_prune_opt(Relation relation, Buffer buffer); +extern int heap_page_prune(Relation relation, Buffer buffer, + TransactionId oldest_xmin, + struct GlobalVisState *vistest, + TransactionId old_snap_xmin, + TimestampTz old_snap_ts, + int *nnewlpdead, + OffsetNumber *off_loc); +extern void heap_page_prune_execute(Buffer buffer, + OffsetNumber *redirected, int nredirected, + OffsetNumber *nowdead, int ndead, + OffsetNumber *nowunused, int nunused); +extern void heap_get_root_tuples(Page page, OffsetNumber *root_offsets); + +/* in heap/vacuumlazy.c */ +struct VacuumParams; +extern void heap_vacuum_rel(Relation rel, + struct VacuumParams *params, BufferAccessStrategy bstrategy); + +/* in heap/heapam_visibility.c */ +extern bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, + Buffer buffer); +extern TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, + Buffer buffer); +extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, + Buffer buffer); +extern HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, + TransactionId *dead_after); +extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, + uint16 infomask, TransactionId xid); +extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple); +extern bool HeapTupleIsSurelyDead(HeapTuple htup, + struct GlobalVisState *vistest); + +/* + * To avoid leaking too much knowledge about reorderbuffer implementation + * details this is implemented in reorderbuffer.c not heapam_visibility.c + */ +struct HTAB; +extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data, + Snapshot snapshot, + HeapTuple htup, + Buffer buffer, + CommandId *cmin, CommandId *cmax); +extern void HeapCheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple, + Buffer buffer, Snapshot snapshot); + +#endif /* HEAPAM_H */ diff --git a/install/include/postgresql/server/access/heapam_xlog.h b/install/include/postgresql/server/access/heapam_xlog.h new file mode 100644 index 00000000000..f17ffc61d25 --- /dev/null +++ b/install/include/postgresql/server/access/heapam_xlog.h @@ -0,0 +1,599 @@ +/*------------------------------------------------------------------------- + * + * heapam_xlog.h + * POSTGRES heap access XLOG definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/heapam_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef HEAPAM_XLOG_H +#define HEAPAM_XLOG_H + +#include "access/htup.h" +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/buf.h" +#include "storage/bufpage.h" +#include "storage/relfilelocator.h" +#include "utils/relcache.h" + + +/* + * WAL record definitions for heapam.c's WAL operations + * + * XLOG allows to store some information in high 4 bits of log + * record xl_info field. We use 3 for opcode and one for init bit. + */ +#define XLOG_HEAP_INSERT 0x00 +#define XLOG_HEAP_DELETE 0x10 +#define XLOG_HEAP_UPDATE 0x20 +#define XLOG_HEAP_TRUNCATE 0x30 +#define XLOG_HEAP_HOT_UPDATE 0x40 +#define XLOG_HEAP_CONFIRM 0x50 +#define XLOG_HEAP_LOCK 0x60 +#define XLOG_HEAP_INPLACE 0x70 + +#define XLOG_HEAP_OPMASK 0x70 +/* + * When we insert 1st item on new page in INSERT, UPDATE, HOT_UPDATE, + * or MULTI_INSERT, we can (and we do) restore entire page in redo + */ +#define XLOG_HEAP_INIT_PAGE 0x80 +/* + * We ran out of opcodes, so heapam.c now has a second RmgrId. These opcodes + * are associated with RM_HEAP2_ID, but are not logically different from + * the ones above associated with RM_HEAP_ID. XLOG_HEAP_OPMASK applies to + * these, too. + */ +#define XLOG_HEAP2_REWRITE 0x00 +#define XLOG_HEAP2_PRUNE 0x10 +#define XLOG_HEAP2_VACUUM 0x20 +#define XLOG_HEAP2_FREEZE_PAGE 0x30 +#define XLOG_HEAP2_VISIBLE 0x40 +#define XLOG_HEAP2_MULTI_INSERT 0x50 +#define XLOG_HEAP2_LOCK_UPDATED 0x60 +#define XLOG_HEAP2_NEW_CID 0x70 + +/* + * xl_heap_insert/xl_heap_multi_insert flag values, 8 bits are available. + */ +/* PD_ALL_VISIBLE was cleared */ +#define XLH_INSERT_ALL_VISIBLE_CLEARED (1<<0) +#define XLH_INSERT_LAST_IN_MULTI (1<<1) +#define XLH_INSERT_IS_SPECULATIVE (1<<2) +#define XLH_INSERT_CONTAINS_NEW_TUPLE (1<<3) +#define XLH_INSERT_ON_TOAST_RELATION (1<<4) + +/* all_frozen_set always implies all_visible_set */ +#define XLH_INSERT_ALL_FROZEN_SET (1<<5) + +#ifdef USE_PGRAC_CLUSTER +/* PGRAC (spec-3.4a D7): block-local ITL delta array attached to a + * mutated XLog block (xl_heap_itl_delta_block; see below). Spec body + * referenced bit 6 originally; bit 7 is used because UPDATE flags + * already consume bit 6 (XLH_UPDATE_SUFFIX_FROM_OLD). Three enum + * namespaces independent. */ +#define XLH_INSERT_ITL_DELTA (1<<7) +#endif + +/* + * xl_heap_update flag values, 8 bits are available. + */ +/* PD_ALL_VISIBLE was cleared */ +#define XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED (1<<0) +/* PD_ALL_VISIBLE was cleared in the 2nd page */ +#define XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED (1<<1) +#define XLH_UPDATE_CONTAINS_OLD_TUPLE (1<<2) +#define XLH_UPDATE_CONTAINS_OLD_KEY (1<<3) +#define XLH_UPDATE_CONTAINS_NEW_TUPLE (1<<4) +#define XLH_UPDATE_PREFIX_FROM_OLD (1<<5) +#define XLH_UPDATE_SUFFIX_FROM_OLD (1<<6) + +#ifdef USE_PGRAC_CLUSTER +/* PGRAC (spec-3.4a D7): block-local ITL delta array; see XLH_INSERT_ITL_DELTA. */ +#define XLH_UPDATE_ITL_DELTA (1<<7) +#endif + +/* convenience macro for checking whether any form of old tuple was logged */ +#define XLH_UPDATE_CONTAINS_OLD \ + (XLH_UPDATE_CONTAINS_OLD_TUPLE | XLH_UPDATE_CONTAINS_OLD_KEY) + +/* + * xl_heap_delete flag values, 8 bits are available. + */ +/* PD_ALL_VISIBLE was cleared */ +#define XLH_DELETE_ALL_VISIBLE_CLEARED (1<<0) +#define XLH_DELETE_CONTAINS_OLD_TUPLE (1<<1) +#define XLH_DELETE_CONTAINS_OLD_KEY (1<<2) +#define XLH_DELETE_IS_SUPER (1<<3) +#define XLH_DELETE_IS_PARTITION_MOVE (1<<4) + +#ifdef USE_PGRAC_CLUSTER +/* PGRAC (spec-3.4a D7): block-local ITL delta array; see XLH_INSERT_ITL_DELTA. */ +#define XLH_DELETE_ITL_DELTA (1<<7) +#endif + +/* convenience macro for checking whether any form of old tuple was logged */ +#define XLH_DELETE_CONTAINS_OLD \ + (XLH_DELETE_CONTAINS_OLD_TUPLE | XLH_DELETE_CONTAINS_OLD_KEY) + +/* This is what we need to know about delete */ +typedef struct xl_heap_delete +{ + TransactionId xmax; /* xmax of the deleted tuple */ + OffsetNumber offnum; /* deleted tuple's offset */ + uint8 infobits_set; /* infomask bits */ + uint8 flags; +} xl_heap_delete; + +#define SizeOfHeapDelete (offsetof(xl_heap_delete, flags) + sizeof(uint8)) + +/* + * xl_heap_truncate flag values, 8 bits are available. + */ +#define XLH_TRUNCATE_CASCADE (1<<0) +#define XLH_TRUNCATE_RESTART_SEQS (1<<1) + +/* + * For truncate we list all truncated relids in an array, followed by all + * sequence relids that need to be restarted, if any. + * All rels are always within the same database, so we just list dbid once. + */ +typedef struct xl_heap_truncate +{ + Oid dbId; + uint32 nrelids; + uint8 flags; + Oid relids[FLEXIBLE_ARRAY_MEMBER]; +} xl_heap_truncate; + +#define SizeOfHeapTruncate (offsetof(xl_heap_truncate, relids)) + +/* + * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted + * or updated tuple in WAL; we can save a few bytes by reconstructing the + * fields that are available elsewhere in the WAL record, or perhaps just + * plain needn't be reconstructed. These are the fields we must store. + */ +typedef struct xl_heap_header +{ + uint16 t_infomask2; + uint16 t_infomask; + uint8 t_hoff; +} xl_heap_header; + +#define SizeOfHeapHeader (offsetof(xl_heap_header, t_hoff) + sizeof(uint8)) + +/* This is what we need to know about insert */ +typedef struct xl_heap_insert +{ + OffsetNumber offnum; /* inserted tuple's offset */ + uint8 flags; + + /* xl_heap_header & TUPLE DATA in backup block 0 */ +} xl_heap_insert; + +#define SizeOfHeapInsert (offsetof(xl_heap_insert, flags) + sizeof(uint8)) + +/* + * This is what we need to know about a multi-insert. + * + * The main data of the record consists of this xl_heap_multi_insert header. + * 'offsets' array is omitted if the whole page is reinitialized + * (XLOG_HEAP_INIT_PAGE). + * + * In block 0's data portion, there is an xl_multi_insert_tuple struct, + * followed by the tuple data for each tuple. There is padding to align + * each xl_multi_insert_tuple struct. + */ +typedef struct xl_heap_multi_insert +{ + uint8 flags; + uint16 ntuples; + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} xl_heap_multi_insert; + +#define SizeOfHeapMultiInsert offsetof(xl_heap_multi_insert, offsets) + +typedef struct xl_multi_insert_tuple +{ + uint16 datalen; /* size of tuple data that follows */ + uint16 t_infomask2; + uint16 t_infomask; + uint8 t_hoff; + /* TUPLE DATA FOLLOWS AT END OF STRUCT */ +} xl_multi_insert_tuple; + +#define SizeOfMultiInsertTuple (offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8)) + +/* + * This is what we need to know about update|hot_update + * + * Backup blk 0: new page + * + * If XLH_UPDATE_PREFIX_FROM_OLD or XLH_UPDATE_SUFFIX_FROM_OLD flags are set, + * the prefix and/or suffix come first, as one or two uint16s. + * + * After that, xl_heap_header and new tuple data follow. The new tuple + * data doesn't include the prefix and suffix, which are copied from the + * old tuple on replay. + * + * If XLH_UPDATE_CONTAINS_NEW_TUPLE flag is given, the tuple data is + * included even if a full-page image was taken. + * + * Backup blk 1: old page, if different. (no data, just a reference to the blk) + */ +typedef struct xl_heap_update +{ + TransactionId old_xmax; /* xmax of the old tuple */ + OffsetNumber old_offnum; /* old tuple's offset */ + uint8 old_infobits_set; /* infomask bits to set on old tuple */ + uint8 flags; + TransactionId new_xmax; /* xmax of the new tuple */ + OffsetNumber new_offnum; /* new tuple's offset */ + + /* + * If XLH_UPDATE_CONTAINS_OLD_TUPLE or XLH_UPDATE_CONTAINS_OLD_KEY flags + * are set, xl_heap_header and tuple data for the old tuple follow. + */ +} xl_heap_update; + +#define SizeOfHeapUpdate (offsetof(xl_heap_update, new_offnum) + sizeof(OffsetNumber)) + +/* + * This is what we need to know about page pruning (both during VACUUM and + * during opportunistic pruning) + * + * The array of OffsetNumbers following the fixed part of the record contains: + * * for each redirected item: the item offset, then the offset redirected to + * * for each now-dead item: the item offset + * * for each now-unused item: the item offset + * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused. + * Note that nunused is not explicitly stored, but may be found by reference + * to the total record length. + * + * Acquires a full cleanup lock. + */ +typedef struct xl_heap_prune +{ + TransactionId snapshotConflictHorizon; + uint16 nredirected; + uint16 ndead; + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ + /* OFFSET NUMBERS are in the block reference 0 */ +} xl_heap_prune; + +#define SizeOfHeapPrune (offsetof(xl_heap_prune, isCatalogRel) + sizeof(bool)) + +/* + * The vacuum page record is similar to the prune record, but can only mark + * already LP_DEAD items LP_UNUSED (during VACUUM's second heap pass) + * + * Acquires an ordinary exclusive lock only. + */ +typedef struct xl_heap_vacuum +{ + uint16 nunused; + /* OFFSET NUMBERS are in the block reference 0 */ +} xl_heap_vacuum; + +#define SizeOfHeapVacuum (offsetof(xl_heap_vacuum, nunused) + sizeof(uint16)) + +/* flags for infobits_set */ +#define XLHL_XMAX_IS_MULTI 0x01 +#define XLHL_XMAX_LOCK_ONLY 0x02 +#define XLHL_XMAX_EXCL_LOCK 0x04 +#define XLHL_XMAX_KEYSHR_LOCK 0x08 +#define XLHL_KEYS_UPDATED 0x10 + +/* flag bits for xl_heap_lock / xl_heap_lock_updated's flag field */ +#define XLH_LOCK_ALL_FROZEN_CLEARED 0x01 + +/* + * PGRAC (spec-3.4d D6 / Q4 A2 / L184): ITL delta block follows xlrec. + * + * XLH_LOCK_ITL_DELTA — set on xl_heap_lock when heap_lock_tuple + * stamped a lock-only ITL slot under the + * cluster lock path (peer mode). The + * 40B v2 delta + 4B block header (spec-3.4b + * D6 layout) is appended to xlrec via + * XLogRegisterData and replayed by + * heap_xlog_lock to reconstruct the slot. + * + * XLH_LOCK_UPDATED_ITL_DELTA — same shape but on xl_heap_lock_updated + * (RM_HEAP2_ID / XLOG_HEAP2_LOCK_UPDATED + * namespace per F5). follow_updates=true + * path stamps successor tuples' ITL slots + * via heap_lock_updated_tuple_rec. + * + * bit 7 selected because: bit 0 = XLH_LOCK_ALL_FROZEN_CLEARED (existing + * PG); bit 7 free in both xl_heap_lock.flags and xl_heap_lock_updated.flags + * namespaces (grep verified; L184 inheritance from spec-3.4a/b); aligns + * with XLH_INSERT_ITL_DELTA / XLH_UPDATE_ITL_DELTA / XLH_DELETE_ITL_DELTA + * (spec-3.4a) bit 7 — namespace consistency helps reviewers grep / replay + * all ITL delta paths together. + */ +#define XLH_LOCK_ITL_DELTA (1 << 7) +#define XLH_LOCK_UPDATED_ITL_DELTA (1 << 7) + +/* This is what we need to know about lock */ +typedef struct xl_heap_lock +{ + TransactionId xmax; /* might be a MultiXactId */ + OffsetNumber offnum; /* locked tuple's offset on page */ + uint8 infobits_set; /* infomask and infomask2 bits to set */ + uint8 flags; /* XLH_LOCK_* flag bits */ +} xl_heap_lock; + +#define SizeOfHeapLock (offsetof(xl_heap_lock, flags) + sizeof(uint8)) + +/* This is what we need to know about locking an updated version of a row */ +typedef struct xl_heap_lock_updated +{ + TransactionId xmax; + OffsetNumber offnum; + uint8 infobits_set; + uint8 flags; +} xl_heap_lock_updated; + +#define SizeOfHeapLockUpdated (offsetof(xl_heap_lock_updated, flags) + sizeof(uint8)) + +/* This is what we need to know about confirmation of speculative insertion */ +typedef struct xl_heap_confirm +{ + OffsetNumber offnum; /* confirmed tuple's offset on page */ +} xl_heap_confirm; + +#define SizeOfHeapConfirm (offsetof(xl_heap_confirm, offnum) + sizeof(OffsetNumber)) + +/* This is what we need to know about in-place update */ +typedef struct xl_heap_inplace +{ + OffsetNumber offnum; /* updated tuple's offset on page */ +} xl_heap_inplace; + +#define SizeOfHeapInplace (offsetof(xl_heap_inplace, offnum) + sizeof(OffsetNumber)) + +/* + * This struct represents a 'freeze plan', which describes how to freeze a + * group of one or more heap tuples (appears in xl_heap_freeze_page record) + */ +/* 0x01 was XLH_FREEZE_XMIN */ +#define XLH_FREEZE_XVAC 0x02 +#define XLH_INVALID_XVAC 0x04 + +typedef struct xl_heap_freeze_plan +{ + TransactionId xmax; + uint16 t_infomask2; + uint16 t_infomask; + uint8 frzflags; + + /* Length of individual page offset numbers array for this plan */ + uint16 ntuples; +} xl_heap_freeze_plan; + +/* + * This is what we need to know about a block being frozen during vacuum + * + * Backup block 0's data contains an array of xl_heap_freeze_plan structs + * (with nplans elements), followed by one or more page offset number arrays. + * Each such page offset number array corresponds to a single freeze plan + * (REDO routine freezes corresponding heap tuples using freeze plan). + */ +typedef struct xl_heap_freeze_page +{ + TransactionId snapshotConflictHorizon; + uint16 nplans; + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ + + /* + * In payload of blk 0 : FREEZE PLANS and OFFSET NUMBER ARRAY + */ +} xl_heap_freeze_page; + +#define SizeOfHeapFreezePage (offsetof(xl_heap_freeze_page, isCatalogRel) + sizeof(bool)) + +/* + * This is what we need to know about setting a visibility map bit + * + * Backup blk 0: visibility map buffer + * Backup blk 1: heap buffer + */ +typedef struct xl_heap_visible +{ + TransactionId snapshotConflictHorizon; + uint8 flags; +} xl_heap_visible; + +#define SizeOfHeapVisible (offsetof(xl_heap_visible, flags) + sizeof(uint8)) + +typedef struct xl_heap_new_cid +{ + /* + * store toplevel xid so we don't have to merge cids from different + * transactions + */ + TransactionId top_xid; + CommandId cmin; + CommandId cmax; + CommandId combocid; /* just for debugging */ + + /* + * Store the relfilelocator/ctid pair to facilitate lookups. + */ + RelFileLocator target_locator; + ItemPointerData target_tid; +} xl_heap_new_cid; + +#define SizeOfHeapNewCid (offsetof(xl_heap_new_cid, target_tid) + sizeof(ItemPointerData)) + +/* logical rewrite xlog record header */ +typedef struct xl_heap_rewrite_mapping +{ + TransactionId mapped_xid; /* xid that might need to see the row */ + Oid mapped_db; /* DbOid or InvalidOid for shared rels */ + Oid mapped_rel; /* Oid of the mapped relation */ + off_t offset; /* How far have we written so far */ + uint32 num_mappings; /* Number of in-memory mappings */ + XLogRecPtr start_lsn; /* Insert LSN at begin of rewrite */ +} xl_heap_rewrite_mapping; + +extern void HeapTupleHeaderAdvanceConflictHorizon(HeapTupleHeader tuple, + TransactionId *snapshotConflictHorizon); + +extern void heap_redo(XLogReaderState *record); +extern void heap_desc(StringInfo buf, XLogReaderState *record); +extern const char *heap_identify(uint8 info); +extern void heap_mask(char *pagedata, BlockNumber blkno); +extern void heap2_redo(XLogReaderState *record); +extern void heap2_desc(StringInfo buf, XLogReaderState *record); +extern const char *heap2_identify(uint8 info); +extern void heap_xlog_logical_rewrite(XLogReaderState *r); + +extern XLogRecPtr log_heap_visible(Relation rel, Buffer heap_buffer, + Buffer vm_buffer, + TransactionId snapshotConflictHorizon, + uint8 vmflags); + +#ifdef USE_PGRAC_CLUSTER + +#include "cluster/cluster_itl_slot.h" /* ClusterItlFlags + UBA */ +#include "cluster/cluster_scn.h" /* SCN */ + +/* + * PGRAC (spec-3.4a D7): block-local ITL delta payload attached to a + * mutated XLog block when XLH_*_ITL_DELTA is set on the heap WAL + * record's flags. + * + * Per-XLog-block array because: + * - heap_update mutates two pages (old + new) on cross-page UPDATE; + * each block needs its own delta description. + * - heap_multi_insert mutates multiple pages in a single record; + * each page needs its own delta. + * + * A single delta describes one ITL slot transition (FREE->ACTIVE, + * ACTIVE->COMMITTED, ACTIVE->ABORTED). + * + * Wire-stable layout (HC: cluster_unit test_cluster_itl_wal enforces + * sizeof / offsetof): + * + * xl_heap_itl_delta (24 bytes): + * offset 0, 2B : slot_idx (uint16; 0..INITRANS-1) + * offset 2, 2B : flags_after (uint16; ClusterItlFlags value + * written by the redo) + * offset 4, 4B : xid (TransactionId of the slot owner) + * offset 8, 8B : write_scn (SCN; valid on ACTIVE transitions) + * offset 16, 8B : commit_scn (SCN; MUST be valid when + * flags_after == ITL_FLAG_COMMITTED, otherwise + * InvalidScn) + * + * xl_heap_itl_delta_block (4 + 24*N bytes): + * offset 0, 2B : ndeltas (uint16) + * offset 2, 2B : reserved (must be zero) + * offset 4, 24*N : deltas[ndeltas] + */ +typedef struct xl_heap_itl_delta +{ + uint16 slot_idx; /* offset 0, 2B */ + uint16 flags_after; /* offset 2, 2B (ClusterItlFlags) */ + TransactionId xid; /* offset 4, 4B */ + SCN write_scn; /* offset 8, 8B */ + SCN commit_scn; /* offset 16, 8B */ +} xl_heap_itl_delta; + +StaticAssertDecl(sizeof(xl_heap_itl_delta) == 24, + "spec-3.4a D7 — xl_heap_itl_delta must be 24 bytes"); +StaticAssertDecl(offsetof(xl_heap_itl_delta, slot_idx) == 0, + "spec-3.4a D7 — slot_idx at offset 0"); +StaticAssertDecl(offsetof(xl_heap_itl_delta, flags_after) == 2, + "spec-3.4a D7 — flags_after at offset 2"); +StaticAssertDecl(offsetof(xl_heap_itl_delta, xid) == 4, + "spec-3.4a D7 — xid at offset 4"); +StaticAssertDecl(offsetof(xl_heap_itl_delta, write_scn) == 8, + "spec-3.4a D7 — write_scn at offset 8"); +StaticAssertDecl(offsetof(xl_heap_itl_delta, commit_scn) == 16, + "spec-3.4a D7 — commit_scn at offset 16"); + +typedef struct xl_heap_itl_delta_block +{ + uint16 ndeltas; /* offset 0, 2B */ + uint16 reserved; /* offset 2, 2B (zero) */ + uint32 format_version; /* offset 4, 4B (spec-3.4a: 0; spec-3.4b: 1; F9) */ + xl_heap_itl_delta deltas[FLEXIBLE_ARRAY_MEMBER]; +} xl_heap_itl_delta_block; + +StaticAssertDecl(offsetof(xl_heap_itl_delta_block, deltas) == 8, + "spec-3.4a D7 — block-local array header is 8 bytes (4 + 4B pad for SCN alignment)"); + + +/* + * PGRAC (spec-3.4b D6, F9): v2 ITL delta carries the real UBA bytes + * (`undo_segment_head`) so crash recovery preserves the spec-3.4b + * production cross-node visibility chain. + * + * Wire format dispatch in heap_redo: + * xl_heap_itl_delta_block.format_version == 0 → legacy v1 (24B + * deltas; UBA is restored to InvalidUba, reader 3-branch (D7) + * falls back to zero triple → PG-native). + * xl_heap_itl_delta_block.format_version == 1 → v2 (40B deltas; + * UBA bytes restored from delta). + * Other values → PANIC (corruption). + * + * Wire-stable layout (cluster_unit test_cluster_itl_wal enforces): + * xl_heap_itl_delta_v2 (40 bytes): + * offset 0, 2B : slot_idx + * offset 2, 2B : flags_after + * offset 4, 4B : xid + * offset 8, 8B : write_scn + * offset 16, 8B : commit_scn + * offset 24, 16B : undo_segment_head (UBA; InvalidUba on + * COMMITTED/ABORTED finish deltas where the + * binding is already on the page from the + * ACTIVE delta -- redo MUST overwrite the slot + * UBA only when the delta's UBA is non-Invalid) + * + * COMMITTED/ABORTED finish deltas may emit InvalidUba so legacy v1 + * semantics (UBA carried on ACTIVE only) are preserved at redo time. + * Redo restores UBA only when the delta carries non-Invalid bytes; a + * finish delta with InvalidUba leaves the page's existing UBA intact. + */ +#define CLUSTER_ITL_DELTA_FORMAT_V1 ((uint32) 0) +#define CLUSTER_ITL_DELTA_FORMAT_V2 ((uint32) 1) + +typedef struct xl_heap_itl_delta_v2 +{ + uint16 slot_idx; /* offset 0, 2B */ + uint16 flags_after; /* offset 2, 2B (ClusterItlFlags) */ + TransactionId xid; /* offset 4, 4B */ + SCN write_scn; /* offset 8, 8B */ + SCN commit_scn; /* offset 16, 8B */ + UBA undo_segment_head; /* offset 24, 16B */ +} xl_heap_itl_delta_v2; + +StaticAssertDecl(sizeof(xl_heap_itl_delta_v2) == 40, + "spec-3.4b D6 F9 — xl_heap_itl_delta_v2 must be 40 bytes"); +StaticAssertDecl(offsetof(xl_heap_itl_delta_v2, slot_idx) == 0, + "spec-3.4b D6 — slot_idx at offset 0"); +StaticAssertDecl(offsetof(xl_heap_itl_delta_v2, flags_after) == 2, + "spec-3.4b D6 — flags_after at offset 2"); +StaticAssertDecl(offsetof(xl_heap_itl_delta_v2, xid) == 4, + "spec-3.4b D6 — xid at offset 4"); +StaticAssertDecl(offsetof(xl_heap_itl_delta_v2, write_scn) == 8, + "spec-3.4b D6 — write_scn at offset 8"); +StaticAssertDecl(offsetof(xl_heap_itl_delta_v2, commit_scn) == 16, + "spec-3.4b D6 — commit_scn at offset 16"); +StaticAssertDecl(offsetof(xl_heap_itl_delta_v2, undo_segment_head) == 24, + "spec-3.4b D6 — undo_segment_head at offset 24"); + + +#endif /* USE_PGRAC_CLUSTER */ + +#endif /* HEAPAM_XLOG_H */ diff --git a/install/include/postgresql/server/access/heaptoast.h b/install/include/postgresql/server/access/heaptoast.h new file mode 100644 index 00000000000..51b44bfa0d2 --- /dev/null +++ b/install/include/postgresql/server/access/heaptoast.h @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------- + * + * heaptoast.h + * Heap-specific definitions for external and compressed storage + * of variable size attributes. + * + * Copyright (c) 2000-2023, PostgreSQL Global Development Group + * + * src/include/access/heaptoast.h + * + *------------------------------------------------------------------------- + */ +#ifndef HEAPTOAST_H +#define HEAPTOAST_H + +#include "access/htup_details.h" +#include "storage/lockdefs.h" +#include "utils/relcache.h" + +#ifdef USE_PGRAC_CLUSTER +#include "cluster/cluster_itl_slot.h" /* PGRAC: CLUSTER_ITL_ARRAY_SIZE */ +#endif + +/* + * PGRAC (stage 1.5 hardening, codex review 2026-05-02 P2 #3): + * + * Heap pages reserve CLUSTER_ITL_SPECIAL_SIZE (spec-3.10 §v0.5: 392B = + * 384B slot array + 8B ITL page header) bytes of special space (PIVOT A: + * ITL lives in PG special area at page tail). All heap-only capacity + * formulas must subtract this reserved area; index am pages have separate + * special areas and are not affected by this macro. + * + * Spec: spec-stage1-codex-fixes.md §1.2 Deliverable 2 + spec-1.5 §11 + * + spec-3.10 §v0.5 (header grows special 384 -> 392) + */ +#ifdef USE_PGRAC_CLUSTER +#define HeapPageSpecialSize CLUSTER_ITL_SPECIAL_SIZE +#else +#define HeapPageSpecialSize 0 +#endif + +/* + * Find the maximum size of a tuple if there are to be N tuples per page. + * + * PGRAC: subtract HeapPageSpecialSize so toast thresholds reflect actual + * heap page capacity after ITL reservation. Pre-1.5 PG path used + * BLCKSZ - SizeOfPageHeaderData; pgrac heap path subtracts ITL. + */ +#define MaximumBytesPerTuple(tuplesPerPage) \ + MAXALIGN_DOWN((BLCKSZ - \ + MAXALIGN(SizeOfPageHeaderData + (tuplesPerPage) * sizeof(ItemIdData)) \ + - HeapPageSpecialSize) \ + / (tuplesPerPage)) + +/* + * These symbols control toaster activation. If a tuple is larger than + * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than + * TOAST_TUPLE_TARGET bytes through compressing compressible fields and + * moving EXTENDED and EXTERNAL data out-of-line. + * + * The numbers need not be the same, though they currently are. It doesn't + * make sense for TARGET to exceed THRESHOLD, but it could be useful to make + * it be smaller. + * + * Currently we choose both values to match the largest tuple size for which + * TOAST_TUPLES_PER_PAGE tuples can fit on a heap page. + * + * XXX while these can be modified without initdb, some thought needs to be + * given to needs_toast_table() in toasting.c before unleashing random + * changes. Also see LOBLKSIZE in large_object.h, which can *not* be + * changed without initdb. + */ +#define TOAST_TUPLES_PER_PAGE 4 + +#define TOAST_TUPLE_THRESHOLD MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE) + +#define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD + +/* + * The code will also consider moving MAIN data out-of-line, but only as a + * last resort if the previous steps haven't reached the target tuple size. + * In this phase we use a different target size, currently equal to the + * largest tuple that will fit on a heap page. This is reasonable since + * the user has told us to keep the data in-line if at all possible. + */ +#define TOAST_TUPLES_PER_PAGE_MAIN 1 + +#define TOAST_TUPLE_TARGET_MAIN MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE_MAIN) + +/* + * If an index value is larger than TOAST_INDEX_TARGET, we will try to + * compress it (we can't move it out-of-line, however). Note that this + * number is per-datum, not per-tuple, for simplicity in index_form_tuple(). + */ +#define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16) + +/* + * When we store an oversize datum externally, we divide it into chunks + * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must* + * be small enough that the completed toast-table tuple (including the + * ID and sequence fields and all overhead) will fit on a page. + * The coding here sets the size on the theory that we want to fit + * EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page. + * + * NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb. + */ +#define EXTERN_TUPLES_PER_PAGE 4 /* tweak only this */ + +#define EXTERN_TUPLE_MAX_SIZE MaximumBytesPerTuple(EXTERN_TUPLES_PER_PAGE) + +#define TOAST_MAX_CHUNK_SIZE \ + (EXTERN_TUPLE_MAX_SIZE - \ + MAXALIGN(SizeofHeapTupleHeader) - \ + sizeof(Oid) - \ + sizeof(int32) - \ + VARHDRSZ) + +/* ---------- + * heap_toast_insert_or_update - + * + * Called by heap_insert() and heap_update(). + * ---------- + */ +extern HeapTuple heap_toast_insert_or_update(Relation rel, HeapTuple newtup, + HeapTuple oldtup, int options); + +/* ---------- + * heap_toast_delete - + * + * Called by heap_delete(). + * ---------- + */ +extern void heap_toast_delete(Relation rel, HeapTuple oldtup, + bool is_speculative); + +/* ---------- + * toast_flatten_tuple - + * + * "Flatten" a tuple to contain no out-of-line toasted fields. + * (This does not eliminate compressed or short-header datums.) + * ---------- + */ +extern HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc); + +/* ---------- + * toast_flatten_tuple_to_datum - + * + * "Flatten" a tuple containing out-of-line toasted fields into a Datum. + * ---------- + */ +extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, + uint32 tup_len, + TupleDesc tupleDesc); + +/* ---------- + * toast_build_flattened_tuple - + * + * Build a tuple containing no out-of-line toasted fields. + * (This does not eliminate compressed or short-header datums.) + * ---------- + */ +extern HeapTuple toast_build_flattened_tuple(TupleDesc tupleDesc, + Datum *values, + bool *isnull); + +/* ---------- + * heap_fetch_toast_slice + * + * Fetch a slice from a toast value stored in a heap table. + * ---------- + */ +extern void heap_fetch_toast_slice(Relation toastrel, Oid valueid, + int32 attrsize, int32 sliceoffset, + int32 slicelength, struct varlena *result); + +#endif /* HEAPTOAST_H */ diff --git a/install/include/postgresql/server/access/hio.h b/install/include/postgresql/server/access/hio.h new file mode 100644 index 00000000000..9bc563b7628 --- /dev/null +++ b/install/include/postgresql/server/access/hio.h @@ -0,0 +1,62 @@ +/*------------------------------------------------------------------------- + * + * hio.h + * POSTGRES heap access method input/output definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/hio.h + * + *------------------------------------------------------------------------- + */ +#ifndef HIO_H +#define HIO_H + +#include "access/htup.h" +#include "storage/buf.h" +#include "utils/relcache.h" + +/* + * state for bulk inserts --- private to heapam.c and hio.c + * + * If current_buf isn't InvalidBuffer, then we are holding an extra pin + * on that buffer. + * + * "typedef struct BulkInsertStateData *BulkInsertState" is in heapam.h + */ +typedef struct BulkInsertStateData +{ + BufferAccessStrategy strategy; /* our BULKWRITE strategy object */ + Buffer current_buf; /* current insertion target page */ + + /* + * State for bulk extensions. + * + * last_free..next_free are further pages that were unused at the time of + * the last extension. They might be in use by the time we use them + * though, so rechecks are needed. + * + * XXX: Eventually these should probably live in RelationData instead, + * alongside targetblock. + * + * already_extended_by is the number of pages that this bulk inserted + * extended by. If we already extended by a significant number of pages, + * we can be more aggressive about extending going forward. + */ + BlockNumber next_free; + BlockNumber last_free; + uint32 already_extended_by; +} BulkInsertStateData; + + +extern void RelationPutHeapTuple(Relation relation, Buffer buffer, + HeapTuple tuple, bool token); +extern Buffer RelationGetBufferForTuple(Relation relation, Size len, + Buffer otherBuffer, int options, + BulkInsertStateData *bistate, + Buffer *vmbuffer, Buffer *vmbuffer_other, + int num_pages); + +#endif /* HIO_H */ diff --git a/install/include/postgresql/server/access/htup.h b/install/include/postgresql/server/access/htup.h new file mode 100644 index 00000000000..a8f7ff5dfe1 --- /dev/null +++ b/install/include/postgresql/server/access/htup.h @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------- + * + * htup.h + * POSTGRES heap tuple definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/htup.h + * + *------------------------------------------------------------------------- + */ +#ifndef HTUP_H +#define HTUP_H + +#include "storage/itemptr.h" + +/* typedefs and forward declarations for structs defined in htup_details.h */ + +typedef struct HeapTupleHeaderData HeapTupleHeaderData; + +typedef HeapTupleHeaderData *HeapTupleHeader; + +typedef struct MinimalTupleData MinimalTupleData; + +typedef MinimalTupleData *MinimalTuple; + + +/* + * HeapTupleData is an in-memory data structure that points to a tuple. + * + * There are several ways in which this data structure is used: + * + * * Pointer to a tuple in a disk buffer: t_data points directly into the + * buffer (which the code had better be holding a pin on, but this is not + * reflected in HeapTupleData itself). + * + * * Pointer to nothing: t_data is NULL. This is used as a failure indication + * in some functions. + * + * * Part of a palloc'd tuple: the HeapTupleData itself and the tuple + * form a single palloc'd chunk. t_data points to the memory location + * immediately following the HeapTupleData struct (at offset HEAPTUPLESIZE). + * This is the output format of heap_form_tuple and related routines. + * + * * Separately allocated tuple: t_data points to a palloc'd chunk that + * is not adjacent to the HeapTupleData. (This case is deprecated since + * it's difficult to tell apart from case #1. It should be used only in + * limited contexts where the code knows that case #1 will never apply.) + * + * * Separately allocated minimal tuple: t_data points MINIMAL_TUPLE_OFFSET + * bytes before the start of a MinimalTuple. As with the previous case, + * this can't be told apart from case #1 by inspection; code setting up + * or destroying this representation has to know what it's doing. + * + * t_len should always be valid, except in the pointer-to-nothing case. + * t_self and t_tableOid should be valid if the HeapTupleData points to + * a disk buffer, or if it represents a copy of a tuple on disk. They + * should be explicitly set invalid in manufactured tuples. + */ +typedef struct HeapTupleData +{ + uint32 t_len; /* length of *t_data */ + ItemPointerData t_self; /* SelfItemPointer */ + Oid t_tableOid; /* table the tuple came from */ +#define FIELDNO_HEAPTUPLEDATA_DATA 3 + HeapTupleHeader t_data; /* -> tuple header and data */ +} HeapTupleData; + +typedef HeapTupleData *HeapTuple; + +#define HEAPTUPLESIZE MAXALIGN(sizeof(HeapTupleData)) + +/* + * Accessor macros to be used with HeapTuple pointers. + */ +#define HeapTupleIsValid(tuple) PointerIsValid(tuple) + +/* HeapTupleHeader functions implemented in utils/time/combocid.c */ +extern CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup); +extern CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup); +extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup, + CommandId *cmax, bool *iscombo); + +/* Prototype for HeapTupleHeader accessors in heapam.c */ +extern TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple); + +#endif /* HTUP_H */ diff --git a/install/include/postgresql/server/access/htup_details.h b/install/include/postgresql/server/access/htup_details.h new file mode 100644 index 00000000000..d5150fe8631 --- /dev/null +++ b/install/include/postgresql/server/access/htup_details.h @@ -0,0 +1,975 @@ +/*------------------------------------------------------------------------- + * + * htup_details.h + * POSTGRES heap tuple header definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/htup_details.h + * + *------------------------------------------------------------------------- + * + * PGRAC MODIFICATIONS (9th): + * Modified by: SqlRush + * + * What changed: When USE_PGRAC_CLUSTER is defined, extend + * HeapTupleHeaderData with a 1-byte t_itl_slot_idx + * field after t_hoff and before the t_bits FAM. + * SizeofHeapTupleHeader (= offsetof t_bits) auto-grows + * from 23 to 24 bytes. Stage 1.5 ships only the field; + * heap_form_tuple / heap_modify_tuple write + * CLUSTER_ITL_SLOT_UNALLOCATED (= 255) as a placeholder + * (PGRAC MODIFICATIONS 10th in heaptuple.c). Stage 3 + * (AD-006 第五轮) populates real 0..N slot indexes when + * a transaction touches the row. + * Why: Stage 1.5 introduces ITL slot array for Oracle-style + * row-level locking + per-block transaction queue. + * Each tuple needs to record which ITL slot is "interested" + * in it; t_itl_slot_idx is that pointer (255 = unassigned). + * 1B is enough because INITRANS upper bound is ~169 + * slots/page (8192-byte page capacity), well under 256. + * Per spec-1.5 §8 Q3 = A. + * t_bits is FLEXIBLE_ARRAY_MEMBER, so adding a field + * before it is an ABI-safe PG modification pattern -- + * PG callers use SizeofHeapTupleHeader macro which + * recomputes via offsetof. + * See specs/spec-1.5-itl-slot.md §1.4 例外说明 #5, + * docs/block-format-design.md v1.2 §4.4. + * + * Per spec-1.5 §8 Q7 (user-revised hybrid A+B): trust PG's + * SizeofHeapTupleHeader macro as the primary mechanism, BUT do a + * targeted audit of 7 high-risk files (heaptoast.c / heaptuple.c / + * heapam_visibility.c / pruneheap.c / vacuumlazy.c / heapam.c / hio.c) + * for hardcoded `23` / `t_hoff >= 23` assumptions, and add 4 t_hoff + * boundary tests in 022_itl_slot.pl L15-L18 (no null bitmap / 1 null / + * 64+ nulls / max heap size). Audit deliverable: + * pgrac/docs/spec-1.5-tuple-header-audit.md. + */ +#ifndef HTUP_DETAILS_H +#define HTUP_DETAILS_H + +#include "access/htup.h" +#include "access/transam.h" +#include "access/tupdesc.h" +#include "access/tupmacs.h" +#include "storage/bufpage.h" +#include "varatt.h" + +#ifdef USE_PGRAC_CLUSTER +#include "cluster/cluster_itl_slot.h" /* PGRAC: CLUSTER_ITL_SLOT_UNALLOCATED for ClusterHeapTupleHeaderInitItlSlot helper */ +#endif + +/* + * MaxTupleAttributeNumber limits the number of (user) columns in a tuple. + * The key limit on this value is that the size of the fixed overhead for + * a tuple, plus the size of the null-values bitmap (at 1 bit per column), + * plus MAXALIGN alignment, must fit into t_hoff which is uint8. On most + * machines the upper limit without making t_hoff wider would be a little + * over 1700. We use round numbers here and for MaxHeapAttributeNumber + * so that alterations in HeapTupleHeaderData layout won't change the + * supported max number of columns. + */ +#define MaxTupleAttributeNumber 1664 /* 8 * 208 */ + +/* + * MaxHeapAttributeNumber limits the number of (user) columns in a table. + * This should be somewhat less than MaxTupleAttributeNumber. It must be + * at least one less, else we will fail to do UPDATEs on a maximal-width + * table (because UPDATE has to form working tuples that include CTID). + * In practice we want some additional daylight so that we can gracefully + * support operations that add hidden "resjunk" columns, for example + * SELECT * FROM wide_table ORDER BY foo, bar, baz. + * In any case, depending on column data types you will likely be running + * into the disk-block-based limit on overall tuple size if you have more + * than a thousand or so columns. TOAST won't help. + */ +#define MaxHeapAttributeNumber 1600 /* 8 * 200 */ + +/* + * Heap tuple header. To avoid wasting space, the fields should be + * laid out in such a way as to avoid structure padding. + * + * Datums of composite types (row types) share the same general structure + * as on-disk tuples, so that the same routines can be used to build and + * examine them. However the requirements are slightly different: a Datum + * does not need any transaction visibility information, and it does need + * a length word and some embedded type information. We can achieve this + * by overlaying the xmin/cmin/xmax/cmax/xvac fields of a heap tuple + * with the fields needed in the Datum case. Typically, all tuples built + * in-memory will be initialized with the Datum fields; but when a tuple is + * about to be inserted in a table, the transaction fields will be filled, + * overwriting the datum fields. + * + * The overall structure of a heap tuple looks like: + * fixed fields (HeapTupleHeaderData struct) + * nulls bitmap (if HEAP_HASNULL is set in t_infomask) + * alignment padding (as needed to make user data MAXALIGN'd) + * object ID (if HEAP_HASOID_OLD is set in t_infomask, not created + * anymore) + * user data fields + * + * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in three + * physical fields. Xmin and Xmax are always really stored, but Cmin, Cmax + * and Xvac share a field. This works because we know that Cmin and Cmax + * are only interesting for the lifetime of the inserting and deleting + * transaction respectively. If a tuple is inserted and deleted in the same + * transaction, we store a "combo" command id that can be mapped to the real + * cmin and cmax, but only by use of local state within the originating + * backend. See combocid.c for more details. Meanwhile, Xvac is only set by + * old-style VACUUM FULL, which does not have any command sub-structure and so + * does not need either Cmin or Cmax. (This requires that old-style VACUUM + * FULL never try to move a tuple whose Cmin or Cmax is still interesting, + * ie, an insert-in-progress or delete-in-progress tuple.) + * + * A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid + * is initialized with its own TID (location). If the tuple is ever updated, + * its t_ctid is changed to point to the replacement version of the tuple. Or + * if the tuple is moved from one partition to another, due to an update of + * the partition key, t_ctid is set to a special value to indicate that + * (see ItemPointerSetMovedPartitions). Thus, a tuple is the latest version + * of its row iff XMAX is invalid or + * t_ctid points to itself (in which case, if XMAX is valid, the tuple is + * either locked or deleted). One can follow the chain of t_ctid links + * to find the newest version of the row, unless it was moved to a different + * partition. Beware however that VACUUM might + * erase the pointed-to (newer) tuple before erasing the pointing (older) + * tuple. Hence, when following a t_ctid link, it is necessary to check + * to see if the referenced slot is empty or contains an unrelated tuple. + * Check that the referenced tuple has XMIN equal to the referencing tuple's + * XMAX to verify that it is actually the descendant version and not an + * unrelated tuple stored into a slot recently freed by VACUUM. If either + * check fails, one may assume that there is no live descendant version. + * + * t_ctid is sometimes used to store a speculative insertion token, instead + * of a real TID. A speculative token is set on a tuple that's being + * inserted, until the inserter is sure that it wants to go ahead with the + * insertion. Hence a token should only be seen on a tuple with an XMAX + * that's still in-progress, or invalid/aborted. The token is replaced with + * the tuple's real TID when the insertion is confirmed. One should never + * see a speculative insertion token while following a chain of t_ctid links, + * because they are not used on updates, only insertions. + * + * Following the fixed header fields, the nulls bitmap is stored (beginning + * at t_bits). The bitmap is *not* stored if t_infomask shows that there + * are no nulls in the tuple. If an OID field is present (as indicated by + * t_infomask), then it is stored just before the user data, which begins at + * the offset shown by t_hoff. Note that t_hoff must be a multiple of + * MAXALIGN. + */ + +typedef struct HeapTupleFields +{ + TransactionId t_xmin; /* inserting xact ID */ + TransactionId t_xmax; /* deleting or locking xact ID */ + + union + { + CommandId t_cid; /* inserting or deleting command ID, or both */ + TransactionId t_xvac; /* old-style VACUUM FULL xact ID */ + } t_field3; +} HeapTupleFields; + +typedef struct DatumTupleFields +{ + int32 datum_len_; /* varlena header (do not touch directly!) */ + + int32 datum_typmod; /* -1, or identifier of a record type */ + + Oid datum_typeid; /* composite type OID, or RECORDOID */ + + /* + * datum_typeid cannot be a domain over composite, only plain composite, + * even if the datum is meant as a value of a domain-over-composite type. + * This is in line with the general principle that CoerceToDomain does not + * change the physical representation of the base type value. + * + * Note: field ordering is chosen with thought that Oid might someday + * widen to 64 bits. + */ +} DatumTupleFields; + +struct HeapTupleHeaderData +{ + union + { + HeapTupleFields t_heap; + DatumTupleFields t_datum; + } t_choice; + + ItemPointerData t_ctid; /* current TID of this or newer tuple (or a + * speculative insertion token) */ + + /* Fields below here must match MinimalTupleData! */ + +#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2 2 + uint16 t_infomask2; /* number of attributes + various flags */ + +#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK 3 + uint16 t_infomask; /* various flag bits, see below */ + +#define FIELDNO_HEAPTUPLEHEADERDATA_HOFF 4 + uint8 t_hoff; /* sizeof header incl. bitmap, padding */ + +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC (stage 1.5): ITL slot index pointer. + * + * 255 = unallocated (Stage 1.5 placeholder; all heap_form_tuple / + * heap_modify_tuple paths write this value -- spec-1.5 §8 Q3). + * 0..7 = ITL slot index (Stage 3 AD-006 第五轮 populates real + * values when a transaction touches the row). + * + * 1 byte is sufficient: INITRANS upper bound is ~169/page (8192- + * byte page capacity), well under the 255 slot-id space; 255 is + * reserved as the "no slot" sentinel. + */ +#define FIELDNO_HEAPTUPLEHEADERDATA_ITL_SLOT_IDX 5 + uint8 t_itl_slot_idx; /* ITL slot index (255 = unallocated) */ +#endif + + /* ^ - 23 bytes (PG vanilla) / 24 bytes (USE_PGRAC_CLUSTER) - ^ */ + +#ifdef USE_PGRAC_CLUSTER +#define FIELDNO_HEAPTUPLEHEADERDATA_BITS 6 +#else +#define FIELDNO_HEAPTUPLEHEADERDATA_BITS 5 +#endif + bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]; /* bitmap of NULLs */ + + /* MORE DATA FOLLOWS AT END OF STRUCT */ +}; + +/* typedef appears in htup.h */ + +#define SizeofHeapTupleHeader offsetof(HeapTupleHeaderData, t_bits) + +/* + * PGRAC: ClusterHeapTupleHeaderInitItlSlot -- write the Stage 1.5 + * t_itl_slot_idx placeholder sentinel (255 = unallocated) on a + * freshly-allocated HeapTupleHeader. + * + * Spec-1.5 hardening (codex review 2026-05-02 P1 #1+#2): every code + * path that allocates a new HeapTupleHeader must call this helper so + * t_itl_slot_idx never carries the calloc/palloc0/MemSet zero default. + * Zero is a *valid* future ITL slot index (slot 0); 255 is the + * reserved "no slot assigned" sentinel for the Stage 1.5 placeholder + * era and Stage 3 visibility era alike. + * + * Callers (8 paths covered by spec-stage1-codex-fixes Deliverable 1): + * - heap_form_tuple (heaptuple.c, replaces explicit assignment) + * - expand_tuple heap target (heaptuple.c) + * - expand_tuple minimal target (heaptuple.c) + * - heap_form_minimal_tuple (heaptuple.c) + * - heap_xlog_insert / multi_insert / update redo paths (heapam.c) + * - logical decoding tuple reconstruction (decode.c) + * + * Disable-cluster builds: helper is a no-op (USE_PGRAC_CLUSTER guard). + * + * Spec: spec-stage1-codex-fixes.md §1.2 Deliverable 1 + spec-1.5 §11 hardening + */ +static inline void +ClusterHeapTupleHeaderInitItlSlot(HeapTupleHeader td) +{ +#ifdef USE_PGRAC_CLUSTER + td->t_itl_slot_idx = CLUSTER_ITL_SLOT_UNALLOCATED; +#endif +} + +/* ClusterMinimalTupleInitItlSlot: defined below after MinimalTupleData + * struct (which is defined later in this file). */ + +/* + * information stored in t_infomask: + */ +#define HEAP_HASNULL 0x0001 /* has null attribute(s) */ +#define HEAP_HASVARWIDTH 0x0002 /* has variable-width attribute(s) */ +#define HEAP_HASEXTERNAL 0x0004 /* has external stored attribute(s) */ +#define HEAP_HASOID_OLD 0x0008 /* has an object-id field */ +#define HEAP_XMAX_KEYSHR_LOCK 0x0010 /* xmax is a key-shared locker */ +#define HEAP_COMBOCID 0x0020 /* t_cid is a combo CID */ +#define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */ +#define HEAP_XMAX_LOCK_ONLY 0x0080 /* xmax, if valid, is only a locker */ + + /* xmax is a shared locker */ +#define HEAP_XMAX_SHR_LOCK (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK) + +#define HEAP_LOCK_MASK (HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | \ + HEAP_XMAX_KEYSHR_LOCK) +#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */ +#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */ +#define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID) +#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */ +#define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */ +#define HEAP_XMAX_IS_MULTI 0x1000 /* t_xmax is a MultiXactId */ +#define HEAP_UPDATED 0x2000 /* this is UPDATEd version of row */ +#define HEAP_MOVED_OFF 0x4000 /* moved to another place by pre-9.0 + * VACUUM FULL; kept for binary + * upgrade support */ +#define HEAP_MOVED_IN 0x8000 /* moved from another place by pre-9.0 + * VACUUM FULL; kept for binary + * upgrade support */ +#define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN) + +#define HEAP_XACT_MASK 0xFFF0 /* visibility-related bits */ + +/* + * A tuple is only locked (i.e. not updated by its Xmax) if the + * HEAP_XMAX_LOCK_ONLY bit is set; or, for pg_upgrade's sake, if the Xmax is + * not a multi and the EXCL_LOCK bit is set. + * + * See also HeapTupleHeaderIsOnlyLocked, which also checks for a possible + * aborted updater transaction. + * + * Beware of multiple evaluations of the argument. + */ +#define HEAP_XMAX_IS_LOCKED_ONLY(infomask) \ + (((infomask) & HEAP_XMAX_LOCK_ONLY) || \ + (((infomask) & (HEAP_XMAX_IS_MULTI | HEAP_LOCK_MASK)) == HEAP_XMAX_EXCL_LOCK)) + +/* + * A tuple that has HEAP_XMAX_IS_MULTI and HEAP_XMAX_LOCK_ONLY but neither of + * HEAP_XMAX_EXCL_LOCK and HEAP_XMAX_KEYSHR_LOCK must come from a tuple that was + * share-locked in 9.2 or earlier and then pg_upgrade'd. + * + * In 9.2 and prior, HEAP_XMAX_IS_MULTI was only set when there were multiple + * FOR SHARE lockers of that tuple. That set HEAP_XMAX_LOCK_ONLY (with a + * different name back then) but neither of HEAP_XMAX_EXCL_LOCK and + * HEAP_XMAX_KEYSHR_LOCK. That combination is no longer possible in 9.3 and + * up, so if we see that combination we know for certain that the tuple was + * locked in an earlier release; since all such lockers are gone (they cannot + * survive through pg_upgrade), such tuples can safely be considered not + * locked. + * + * We must not resolve such multixacts locally, because the result would be + * bogus, regardless of where they stand with respect to the current valid + * multixact range. + */ +#define HEAP_LOCKED_UPGRADED(infomask) \ +( \ + ((infomask) & HEAP_XMAX_IS_MULTI) != 0 && \ + ((infomask) & HEAP_XMAX_LOCK_ONLY) != 0 && \ + (((infomask) & (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)) == 0) \ +) + +/* + * Use these to test whether a particular lock is applied to a tuple + */ +#define HEAP_XMAX_IS_SHR_LOCKED(infomask) \ + (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_SHR_LOCK) +#define HEAP_XMAX_IS_EXCL_LOCKED(infomask) \ + (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_EXCL_LOCK) +#define HEAP_XMAX_IS_KEYSHR_LOCKED(infomask) \ + (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_KEYSHR_LOCK) + +/* turn these all off when Xmax is to change */ +#define HEAP_XMAX_BITS (HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID | \ + HEAP_XMAX_IS_MULTI | HEAP_LOCK_MASK | HEAP_XMAX_LOCK_ONLY) + +/* + * information stored in t_infomask2: + */ +#define HEAP_NATTS_MASK 0x07FF /* 11 bits for number of attributes */ +/* bits 0x1800 are available */ +#define HEAP_KEYS_UPDATED 0x2000 /* tuple was updated and key cols + * modified, or tuple deleted */ +#define HEAP_HOT_UPDATED 0x4000 /* tuple was HOT-updated */ +#define HEAP_ONLY_TUPLE 0x8000 /* this is heap-only tuple */ + +#define HEAP2_XACT_MASK 0xE000 /* visibility-related bits */ + +/* + * HEAP_TUPLE_HAS_MATCH is a temporary flag used during hash joins. It is + * only used in tuples that are in the hash table, and those don't need + * any visibility information, so we can overlay it on a visibility flag + * instead of using up a dedicated bit. + */ +#define HEAP_TUPLE_HAS_MATCH HEAP_ONLY_TUPLE /* tuple has a join match */ + +/* + * HeapTupleHeader accessor macros + * + * Note: beware of multiple evaluations of "tup" argument. But the Set + * macros evaluate their other argument only once. + */ + +/* + * HeapTupleHeaderGetRawXmin returns the "raw" xmin field, which is the xid + * originally used to insert the tuple. However, the tuple might actually + * be frozen (via HeapTupleHeaderSetXminFrozen) in which case the tuple's xmin + * is visible to every snapshot. Prior to PostgreSQL 9.4, we actually changed + * the xmin to FrozenTransactionId, and that value may still be encountered + * on disk. + */ +#define HeapTupleHeaderGetRawXmin(tup) \ +( \ + (tup)->t_choice.t_heap.t_xmin \ +) + +#define HeapTupleHeaderGetXmin(tup) \ +( \ + HeapTupleHeaderXminFrozen(tup) ? \ + FrozenTransactionId : HeapTupleHeaderGetRawXmin(tup) \ +) + +#define HeapTupleHeaderSetXmin(tup, xid) \ +( \ + (tup)->t_choice.t_heap.t_xmin = (xid) \ +) + +#define HeapTupleHeaderXminCommitted(tup) \ +( \ + ((tup)->t_infomask & HEAP_XMIN_COMMITTED) != 0 \ +) + +#define HeapTupleHeaderXminInvalid(tup) \ +( \ + ((tup)->t_infomask & (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)) == \ + HEAP_XMIN_INVALID \ +) + +#define HeapTupleHeaderXminFrozen(tup) \ +( \ + ((tup)->t_infomask & (HEAP_XMIN_FROZEN)) == HEAP_XMIN_FROZEN \ +) + +#define HeapTupleHeaderSetXminCommitted(tup) \ +( \ + AssertMacro(!HeapTupleHeaderXminInvalid(tup)), \ + ((tup)->t_infomask |= HEAP_XMIN_COMMITTED) \ +) + +#define HeapTupleHeaderSetXminInvalid(tup) \ +( \ + AssertMacro(!HeapTupleHeaderXminCommitted(tup)), \ + ((tup)->t_infomask |= HEAP_XMIN_INVALID) \ +) + +#define HeapTupleHeaderSetXminFrozen(tup) \ +( \ + AssertMacro(!HeapTupleHeaderXminInvalid(tup)), \ + ((tup)->t_infomask |= HEAP_XMIN_FROZEN) \ +) + +/* + * HeapTupleHeaderGetRawXmax gets you the raw Xmax field. To find out the Xid + * that updated a tuple, you might need to resolve the MultiXactId if certain + * bits are set. HeapTupleHeaderGetUpdateXid checks those bits and takes care + * to resolve the MultiXactId if necessary. This might involve multixact I/O, + * so it should only be used if absolutely necessary. + */ +#define HeapTupleHeaderGetUpdateXid(tup) \ +( \ + (!((tup)->t_infomask & HEAP_XMAX_INVALID) && \ + ((tup)->t_infomask & HEAP_XMAX_IS_MULTI) && \ + !((tup)->t_infomask & HEAP_XMAX_LOCK_ONLY)) ? \ + HeapTupleGetUpdateXid(tup) \ + : \ + HeapTupleHeaderGetRawXmax(tup) \ +) + +#define HeapTupleHeaderGetRawXmax(tup) \ +( \ + (tup)->t_choice.t_heap.t_xmax \ +) + +#define HeapTupleHeaderSetXmax(tup, xid) \ +( \ + (tup)->t_choice.t_heap.t_xmax = (xid) \ +) + +/* + * HeapTupleHeaderGetRawCommandId will give you what's in the header whether + * it is useful or not. Most code should use HeapTupleHeaderGetCmin or + * HeapTupleHeaderGetCmax instead, but note that those Assert that you can + * get a legitimate result, ie you are in the originating transaction! + */ +#define HeapTupleHeaderGetRawCommandId(tup) \ +( \ + (tup)->t_choice.t_heap.t_field3.t_cid \ +) + +/* SetCmin is reasonably simple since we never need a combo CID */ +#define HeapTupleHeaderSetCmin(tup, cid) \ +do { \ + Assert(!((tup)->t_infomask & HEAP_MOVED)); \ + (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \ + (tup)->t_infomask &= ~HEAP_COMBOCID; \ +} while (0) + +/* SetCmax must be used after HeapTupleHeaderAdjustCmax; see combocid.c */ +#define HeapTupleHeaderSetCmax(tup, cid, iscombo) \ +do { \ + Assert(!((tup)->t_infomask & HEAP_MOVED)); \ + (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \ + if (iscombo) \ + (tup)->t_infomask |= HEAP_COMBOCID; \ + else \ + (tup)->t_infomask &= ~HEAP_COMBOCID; \ +} while (0) + +#define HeapTupleHeaderGetXvac(tup) \ +( \ + ((tup)->t_infomask & HEAP_MOVED) ? \ + (tup)->t_choice.t_heap.t_field3.t_xvac \ + : \ + InvalidTransactionId \ +) + +#define HeapTupleHeaderSetXvac(tup, xid) \ +do { \ + Assert((tup)->t_infomask & HEAP_MOVED); \ + (tup)->t_choice.t_heap.t_field3.t_xvac = (xid); \ +} while (0) + +StaticAssertDecl(MaxOffsetNumber < SpecTokenOffsetNumber, + "invalid speculative token constant"); + +#define HeapTupleHeaderIsSpeculative(tup) \ +( \ + (ItemPointerGetOffsetNumberNoCheck(&(tup)->t_ctid) == SpecTokenOffsetNumber) \ +) + +#define HeapTupleHeaderGetSpeculativeToken(tup) \ +( \ + AssertMacro(HeapTupleHeaderIsSpeculative(tup)), \ + ItemPointerGetBlockNumber(&(tup)->t_ctid) \ +) + +#define HeapTupleHeaderSetSpeculativeToken(tup, token) \ +( \ + ItemPointerSet(&(tup)->t_ctid, token, SpecTokenOffsetNumber) \ +) + +#define HeapTupleHeaderIndicatesMovedPartitions(tup) \ + ItemPointerIndicatesMovedPartitions(&(tup)->t_ctid) + +#define HeapTupleHeaderSetMovedPartitions(tup) \ + ItemPointerSetMovedPartitions(&(tup)->t_ctid) + +#define HeapTupleHeaderGetDatumLength(tup) \ + VARSIZE(tup) + +#define HeapTupleHeaderSetDatumLength(tup, len) \ + SET_VARSIZE(tup, len) + +#define HeapTupleHeaderGetTypeId(tup) \ +( \ + (tup)->t_choice.t_datum.datum_typeid \ +) + +#define HeapTupleHeaderSetTypeId(tup, typeid) \ +( \ + (tup)->t_choice.t_datum.datum_typeid = (typeid) \ +) + +#define HeapTupleHeaderGetTypMod(tup) \ +( \ + (tup)->t_choice.t_datum.datum_typmod \ +) + +#define HeapTupleHeaderSetTypMod(tup, typmod) \ +( \ + (tup)->t_choice.t_datum.datum_typmod = (typmod) \ +) + +/* + * Note that we stop considering a tuple HOT-updated as soon as it is known + * aborted or the would-be updating transaction is known aborted. For best + * efficiency, check tuple visibility before using this macro, so that the + * INVALID bits will be as up to date as possible. + */ +#define HeapTupleHeaderIsHotUpdated(tup) \ +( \ + ((tup)->t_infomask2 & HEAP_HOT_UPDATED) != 0 && \ + ((tup)->t_infomask & HEAP_XMAX_INVALID) == 0 && \ + !HeapTupleHeaderXminInvalid(tup) \ +) + +#define HeapTupleHeaderSetHotUpdated(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_HOT_UPDATED \ +) + +#define HeapTupleHeaderClearHotUpdated(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_HOT_UPDATED \ +) + +#define HeapTupleHeaderIsHeapOnly(tup) \ +( \ + ((tup)->t_infomask2 & HEAP_ONLY_TUPLE) != 0 \ +) + +#define HeapTupleHeaderSetHeapOnly(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_ONLY_TUPLE \ +) + +#define HeapTupleHeaderClearHeapOnly(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_ONLY_TUPLE \ +) + +#define HeapTupleHeaderHasMatch(tup) \ +( \ + ((tup)->t_infomask2 & HEAP_TUPLE_HAS_MATCH) != 0 \ +) + +#define HeapTupleHeaderSetMatch(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_TUPLE_HAS_MATCH \ +) + +#define HeapTupleHeaderClearMatch(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_TUPLE_HAS_MATCH \ +) + +#define HeapTupleHeaderGetNatts(tup) \ + ((tup)->t_infomask2 & HEAP_NATTS_MASK) + +#define HeapTupleHeaderSetNatts(tup, natts) \ +( \ + (tup)->t_infomask2 = ((tup)->t_infomask2 & ~HEAP_NATTS_MASK) | (natts) \ +) + +#define HeapTupleHeaderHasExternal(tup) \ + (((tup)->t_infomask & HEAP_HASEXTERNAL) != 0) + + +/* + * BITMAPLEN(NATTS) - + * Computes size of null bitmap given number of data columns. + */ +#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8) + +/* + * MaxHeapTupleSize is the maximum allowed size of a heap tuple, including + * header and MAXALIGN alignment padding. Basically it's BLCKSZ minus the + * other stuff that has to be on a disk page. Since heap pages use no + * "special space", there's no deduction for that. + * + * NOTE: we allow for the ItemId that must point to the tuple, ensuring that + * an otherwise-empty page can indeed hold a tuple of this size. Because + * ItemIds and tuples have different alignment requirements, don't assume that + * you can, say, fit 2 tuples of size MaxHeapTupleSize/2 on the same page. + */ +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC (stage 1.5, PIVOT A 2026-05-02): heap pages reserve 384 bytes + * at the page TAIL for the ITL slot array (PG special area, set up by + * PageInitHeapPage). Using vanilla MaxHeapTupleSize would cause + * heap_insert to accept over-sized tuples that pass the check but + * then PANIC inside the critical section when they don't fit on the + * page (PANIC: tuple is too big at heapam.c:9854). + * + * MaxHeapTupleSize for pgrac heap pages = (spec-3.10 §v0.5: 384 -> 392) + * BLCKSZ - CLUSTER_ITL_SPECIAL_SIZE - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData)) + * = 8192 - 392 - MAXALIGN(32 + 4) + * = 8192 - 392 - 40 + * = 7760 + * + * Index pages don't subtract ITL (their special area is btree opaque + * etc.); MaxHeapTupleSize only governs heap_insert / heap_update. + * btree's own checks (e.g. BTMaxItemSize) are independent. + */ +#define MaxHeapTupleSize \ + (BLCKSZ - CLUSTER_ITL_SPECIAL_SIZE - \ + MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))) +#else +#define MaxHeapTupleSize (BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))) +#endif +#define MinHeapTupleSize MAXALIGN(SizeofHeapTupleHeader) + +/* + * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can + * fit on one heap page. (Note that indexes could have more, because they + * use a smaller tuple header.) We arrive at the divisor because each tuple + * must be maxaligned, and it must have an associated line pointer. + * + * Note: with HOT, there could theoretically be more line pointers (not actual + * tuples) than this on a heap page. However we constrain the number of line + * pointers to this anyway, to avoid excessive line-pointer bloat and not + * require increases in the size of work arrays. + * + * PGRAC (stage 1.5; spec-3.10 §v0.5: 384 -> 392): heap pages reserve + * CLUSTER_ITL_SPECIAL_SIZE bytes at the page tail (special area), so the + * usable space for tuples + ItemIds is reduced by that amount. + */ +#ifdef USE_PGRAC_CLUSTER +#define MaxHeapTuplesPerPage \ + ((int) ((BLCKSZ - CLUSTER_ITL_SPECIAL_SIZE - SizeOfPageHeaderData) / \ + (MAXALIGN(SizeofHeapTupleHeader) + sizeof(ItemIdData)))) +#else +#define MaxHeapTuplesPerPage \ + ((int) ((BLCKSZ - SizeOfPageHeaderData) / \ + (MAXALIGN(SizeofHeapTupleHeader) + sizeof(ItemIdData)))) +#endif + +/* + * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of + * data fields of char(n) and similar types. It need not have anything + * directly to do with the *actual* upper limit of varlena values, which + * is currently 1Gb (see TOAST structures in postgres.h). I've set it + * at 10Mb which seems like a reasonable number --- tgl 8/6/00. + */ +#define MaxAttrSize (10 * 1024 * 1024) + + +/* + * MinimalTuple is an alternative representation that is used for transient + * tuples inside the executor, in places where transaction status information + * is not required, the tuple rowtype is known, and shaving off a few bytes + * is worthwhile because we need to store many tuples. The representation + * is chosen so that tuple access routines can work with either full or + * minimal tuples via a HeapTupleData pointer structure. The access routines + * see no difference, except that they must not access the transaction status + * or t_ctid fields because those aren't there. + * + * For the most part, MinimalTuples should be accessed via TupleTableSlot + * routines. These routines will prevent access to the "system columns" + * and thereby prevent accidental use of the nonexistent fields. + * + * MinimalTupleData contains a length word, some padding, and fields matching + * HeapTupleHeaderData beginning with t_infomask2. The padding is chosen so + * that offsetof(t_infomask2) is the same modulo MAXIMUM_ALIGNOF in both + * structs. This makes data alignment rules equivalent in both cases. + * + * When a minimal tuple is accessed via a HeapTupleData pointer, t_data is + * set to point MINIMAL_TUPLE_OFFSET bytes before the actual start of the + * minimal tuple --- that is, where a full tuple matching the minimal tuple's + * data would start. This trick is what makes the structs seem equivalent. + * + * Note that t_hoff is computed the same as in a full tuple, hence it includes + * the MINIMAL_TUPLE_OFFSET distance. t_len does not include that, however. + * + * MINIMAL_TUPLE_DATA_OFFSET is the offset to the first useful (non-pad) data + * other than the length word. tuplesort.c and tuplestore.c use this to avoid + * writing the padding to disk. + */ +#define MINIMAL_TUPLE_OFFSET \ + ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF) +#define MINIMAL_TUPLE_PADDING \ + ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF) +#define MINIMAL_TUPLE_DATA_OFFSET \ + offsetof(MinimalTupleData, t_infomask2) + +struct MinimalTupleData +{ + uint32 t_len; /* actual length of minimal tuple */ + + char mt_padding[MINIMAL_TUPLE_PADDING]; + + /* Fields below here must match HeapTupleHeaderData! */ + + uint16 t_infomask2; /* number of attributes + various flags */ + + uint16 t_infomask; /* various flag bits, see below */ + + uint8 t_hoff; /* sizeof header incl. bitmap, padding */ + +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC (stage 1.5): MUST mirror HeapTupleHeaderData.t_itl_slot_idx + * because PG converts between HeapTuple and MinimalTuple by copying + * bytes starting at t_infomask2 (heap_to_minimal_tuple in + * heaptuple.c). In-memory MinimalTuples don't need ITL semantically, + * but the layout MUST match or conversion corrupts t_bits / data. + */ + uint8 t_itl_slot_idx; /* mirror of HeapTupleHeaderData; 255 placeholder */ +#endif + + /* ^ - 23 bytes (PG vanilla) / 24 bytes (USE_PGRAC_CLUSTER) - ^ */ + + bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]; /* bitmap of NULLs */ + + /* MORE DATA FOLLOWS AT END OF STRUCT */ +}; + +/* typedef appears in htup.h */ + +#define SizeofMinimalTupleHeader offsetof(MinimalTupleData, t_bits) + +/* + * PGRAC: ClusterMinimalTupleInitItlSlot -- mirror of + * ClusterHeapTupleHeaderInitItlSlot for MinimalTupleData (which embeds + * its own t_itl_slot_idx mirror field at the same offset relative to + * t_bits). + * + * Required because executor materialize paths produce minimal tuples + * that later get converted back to heap tuples via + * heap_tuple_from_minimal_tuple (memcpy-based copy preserves the + * mirror byte exactly). Without this helper, palloc0-zeroed minimal + * tuples carry t_itl_slot_idx = 0 (a valid future ITL slot index) into + * the converted heap tuple. + * + * Spec: spec-stage1-codex-fixes.md §1.2 Deliverable 1 + spec-1.5 §11 hardening + */ +static inline void +ClusterMinimalTupleInitItlSlot(MinimalTuple mtup) +{ +#ifdef USE_PGRAC_CLUSTER + mtup->t_itl_slot_idx = CLUSTER_ITL_SLOT_UNALLOCATED; +#endif +} + + +/* + * GETSTRUCT - given a HeapTuple pointer, return address of the user data + */ +#define GETSTRUCT(TUP) ((char *) ((TUP)->t_data) + (TUP)->t_data->t_hoff) + +/* + * Accessor macros to be used with HeapTuple pointers. + */ + +#define HeapTupleHasNulls(tuple) \ + (((tuple)->t_data->t_infomask & HEAP_HASNULL) != 0) + +#define HeapTupleNoNulls(tuple) \ + (!((tuple)->t_data->t_infomask & HEAP_HASNULL)) + +#define HeapTupleHasVarWidth(tuple) \ + (((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH) != 0) + +#define HeapTupleAllFixed(tuple) \ + (!((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH)) + +#define HeapTupleHasExternal(tuple) \ + (((tuple)->t_data->t_infomask & HEAP_HASEXTERNAL) != 0) + +#define HeapTupleIsHotUpdated(tuple) \ + HeapTupleHeaderIsHotUpdated((tuple)->t_data) + +#define HeapTupleSetHotUpdated(tuple) \ + HeapTupleHeaderSetHotUpdated((tuple)->t_data) + +#define HeapTupleClearHotUpdated(tuple) \ + HeapTupleHeaderClearHotUpdated((tuple)->t_data) + +#define HeapTupleIsHeapOnly(tuple) \ + HeapTupleHeaderIsHeapOnly((tuple)->t_data) + +#define HeapTupleSetHeapOnly(tuple) \ + HeapTupleHeaderSetHeapOnly((tuple)->t_data) + +#define HeapTupleClearHeapOnly(tuple) \ + HeapTupleHeaderClearHeapOnly((tuple)->t_data) + +/* prototypes for functions in common/heaptuple.c */ +extern Size heap_compute_data_size(TupleDesc tupleDesc, + Datum *values, bool *isnull); +extern void heap_fill_tuple(TupleDesc tupleDesc, + Datum *values, bool *isnull, + char *data, Size data_size, + uint16 *infomask, bits8 *bit); +extern bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc); +extern Datum nocachegetattr(HeapTuple tup, int attnum, + TupleDesc tupleDesc); +extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, + bool *isnull); +extern Datum getmissingattr(TupleDesc tupleDesc, + int attnum, bool *isnull); +extern HeapTuple heap_copytuple(HeapTuple tuple); +extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest); +extern Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc); +extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, + Datum *values, bool *isnull); +extern HeapTuple heap_modify_tuple(HeapTuple tuple, + TupleDesc tupleDesc, + Datum *replValues, + bool *replIsnull, + bool *doReplace); +extern HeapTuple heap_modify_tuple_by_cols(HeapTuple tuple, + TupleDesc tupleDesc, + int nCols, + int *replCols, + Datum *replValues, + bool *replIsnull); +extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, + Datum *values, bool *isnull); +extern void heap_freetuple(HeapTuple htup); +extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, + Datum *values, bool *isnull); +extern void heap_free_minimal_tuple(MinimalTuple mtup); +extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup); +extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup); +extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup); +extern size_t varsize_any(void *p); +extern HeapTuple heap_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc); +extern MinimalTuple minimal_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc); + +#ifndef FRONTEND +/* + * fastgetattr + * Fetch a user attribute's value as a Datum (might be either a + * value, or a pointer into the data area of the tuple). + * + * This must not be used when a system attribute might be requested. + * Furthermore, the passed attnum MUST be valid. Use heap_getattr() + * instead, if in doubt. + * + * This gets called many times, so we macro the cacheable and NULL + * lookups, and call nocachegetattr() for the rest. + */ +static inline Datum +fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull) +{ + Assert(attnum > 0); + + *isnull = false; + if (HeapTupleNoNulls(tup)) + { + Form_pg_attribute att; + + att = TupleDescAttr(tupleDesc, attnum - 1); + if (att->attcacheoff >= 0) + return fetchatt(att, (char *) tup->t_data + tup->t_data->t_hoff + + att->attcacheoff); + else + return nocachegetattr(tup, attnum, tupleDesc); + } + else + { + if (att_isnull(attnum - 1, tup->t_data->t_bits)) + { + *isnull = true; + return (Datum) NULL; + } + else + return nocachegetattr(tup, attnum, tupleDesc); + } +} + +/* + * heap_getattr + * Extract an attribute of a heap tuple and return it as a Datum. + * This works for either system or user attributes. The given attnum + * is properly range-checked. + * + * If the field in question has a NULL value, we return a zero Datum + * and set *isnull == true. Otherwise, we set *isnull == false. + * + * is the pointer to the heap tuple. is the attribute + * number of the column (field) caller wants. is a + * pointer to the structure describing the row and all its fields. + * + */ +static inline Datum +heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull) +{ + if (attnum > 0) + { + if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data)) + return getmissingattr(tupleDesc, attnum, isnull); + else + return fastgetattr(tup, attnum, tupleDesc, isnull); + } + else + return heap_getsysattr(tup, attnum, tupleDesc, isnull); +} +#endif /* FRONTEND */ + +#endif /* HTUP_DETAILS_H */ diff --git a/install/include/postgresql/server/access/itup.h b/install/include/postgresql/server/access/itup.h new file mode 100644 index 00000000000..2e2b8c7a470 --- /dev/null +++ b/install/include/postgresql/server/access/itup.h @@ -0,0 +1,170 @@ +/*------------------------------------------------------------------------- + * + * itup.h + * POSTGRES index tuple definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/itup.h + * + *------------------------------------------------------------------------- + */ +#ifndef ITUP_H +#define ITUP_H + +#include "access/tupdesc.h" +#include "access/tupmacs.h" +#include "storage/bufpage.h" +#include "storage/itemptr.h" + +/* + * Index tuple header structure + * + * All index tuples start with IndexTupleData. If the HasNulls bit is set, + * this is followed by an IndexAttributeBitMapData. The index attribute + * values follow, beginning at a MAXALIGN boundary. + * + * Note that the space allocated for the bitmap does not vary with the number + * of attributes; that is because we don't have room to store the number of + * attributes in the header. Given the MAXALIGN constraint there's no space + * savings to be had anyway, for usual values of INDEX_MAX_KEYS. + */ + +typedef struct IndexTupleData +{ + ItemPointerData t_tid; /* reference TID to heap tuple */ + + /* --------------- + * t_info is laid out in the following fashion: + * + * 15th (high) bit: has nulls + * 14th bit: has var-width attributes + * 13th bit: AM-defined meaning + * 12-0 bit: size of tuple + * --------------- + */ + + unsigned short t_info; /* various info about tuple */ + +} IndexTupleData; /* MORE DATA FOLLOWS AT END OF STRUCT */ + +typedef IndexTupleData *IndexTuple; + +typedef struct IndexAttributeBitMapData +{ + bits8 bits[(INDEX_MAX_KEYS + 8 - 1) / 8]; +} IndexAttributeBitMapData; + +typedef IndexAttributeBitMapData * IndexAttributeBitMap; + +/* + * t_info manipulation macros + */ +#define INDEX_SIZE_MASK 0x1FFF +#define INDEX_AM_RESERVED_BIT 0x2000 /* reserved for index-AM specific + * usage */ +#define INDEX_VAR_MASK 0x4000 +#define INDEX_NULL_MASK 0x8000 + +#define IndexTupleSize(itup) ((Size) ((itup)->t_info & INDEX_SIZE_MASK)) +#define IndexTupleHasNulls(itup) ((((IndexTuple) (itup))->t_info & INDEX_NULL_MASK)) +#define IndexTupleHasVarwidths(itup) ((((IndexTuple) (itup))->t_info & INDEX_VAR_MASK)) + + +/* routines in indextuple.c */ +extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor, + Datum *values, bool *isnull); +extern IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor, + Datum *values, bool *isnull, + MemoryContext context); +extern Datum nocache_index_getattr(IndexTuple tup, int attnum, + TupleDesc tupleDesc); +extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, + Datum *values, bool *isnull); +extern void index_deform_tuple_internal(TupleDesc tupleDescriptor, + Datum *values, bool *isnull, + char *tp, bits8 *bp, int hasnulls); +extern IndexTuple CopyIndexTuple(IndexTuple source); +extern IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor, + IndexTuple source, int leavenatts); + + +/* + * Takes an infomask as argument (primarily because this needs to be usable + * at index_form_tuple time so enough space is allocated). + */ +static inline Size +IndexInfoFindDataOffset(unsigned short t_info) +{ + if (!(t_info & INDEX_NULL_MASK)) + return MAXALIGN(sizeof(IndexTupleData)); + else + return MAXALIGN(sizeof(IndexTupleData) + sizeof(IndexAttributeBitMapData)); +} + +#ifndef FRONTEND + +/* ---------------- + * index_getattr + * + * This gets called many times, so we macro the cacheable and NULL + * lookups, and call nocache_index_getattr() for the rest. + * + * ---------------- + */ +static inline Datum +index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull) +{ + Assert(PointerIsValid(isnull)); + Assert(attnum > 0); + + *isnull = false; + + if (!IndexTupleHasNulls(tup)) + { + if (TupleDescAttr(tupleDesc, attnum - 1)->attcacheoff >= 0) + { + return fetchatt(TupleDescAttr(tupleDesc, attnum - 1), + (char *) tup + IndexInfoFindDataOffset(tup->t_info) + + TupleDescAttr(tupleDesc, attnum - 1)->attcacheoff); + } + else + return nocache_index_getattr(tup, attnum, tupleDesc); + } + else + { + if (att_isnull(attnum - 1, (bits8 *) tup + sizeof(IndexTupleData))) + { + *isnull = true; + return (Datum) NULL; + } + else + return nocache_index_getattr(tup, attnum, tupleDesc); + } +} + +#endif + +/* + * MaxIndexTuplesPerPage is an upper bound on the number of tuples that can + * fit on one index page. An index tuple must have either data or a null + * bitmap, so we can safely assume it's at least 1 byte bigger than a bare + * IndexTupleData struct. We arrive at the divisor because each tuple + * must be maxaligned, and it must have an associated line pointer. + * + * To be index-type-independent, this does not account for any special space + * on the page, and is thus conservative. + * + * Note: in btree non-leaf pages, the first tuple has no key (it's implicitly + * minus infinity), thus breaking the "at least 1 byte bigger" assumption. + * On such a page, N tuples could take one MAXALIGN quantum less space than + * estimated here, seemingly allowing one more tuple than estimated here. + * But such a page always has at least MAXALIGN special space, so we're safe. + */ +#define MaxIndexTuplesPerPage \ + ((int) ((BLCKSZ - SizeOfPageHeaderData) / \ + (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData)))) + +#endif /* ITUP_H */ diff --git a/install/include/postgresql/server/access/multixact.h b/install/include/postgresql/server/access/multixact.h new file mode 100644 index 00000000000..246f757f6ab --- /dev/null +++ b/install/include/postgresql/server/access/multixact.h @@ -0,0 +1,165 @@ +/* + * multixact.h + * + * PostgreSQL multi-transaction-log manager + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/multixact.h + */ +#ifndef MULTIXACT_H +#define MULTIXACT_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/sync.h" + + +/* + * The first two MultiXactId values are reserved to store the truncation Xid + * and epoch of the first segment, so we start assigning multixact values from + * 2. + */ +#define InvalidMultiXactId ((MultiXactId) 0) +#define FirstMultiXactId ((MultiXactId) 1) +#define MaxMultiXactId ((MultiXactId) 0xFFFFFFFF) + +#define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId) + +#define MaxMultiXactOffset ((MultiXactOffset) 0xFFFFFFFF) + +/* Number of SLRU buffers to use for multixact */ +#define NUM_MULTIXACTOFFSET_BUFFERS 8 +#define NUM_MULTIXACTMEMBER_BUFFERS 16 + +/* + * Possible multixact lock modes ("status"). The first four modes are for + * tuple locks (FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE); the + * next two are used for update and delete modes. + */ +typedef enum +{ + MultiXactStatusForKeyShare = 0x00, + MultiXactStatusForShare = 0x01, + MultiXactStatusForNoKeyUpdate = 0x02, + MultiXactStatusForUpdate = 0x03, + /* an update that doesn't touch "key" columns */ + MultiXactStatusNoKeyUpdate = 0x04, + /* other updates, and delete */ + MultiXactStatusUpdate = 0x05 +} MultiXactStatus; + +#define MaxMultiXactStatus MultiXactStatusUpdate + +/* does a status value correspond to a tuple update? */ +#define ISUPDATE_from_mxstatus(status) \ + ((status) > MultiXactStatusForUpdate) + + +typedef struct MultiXactMember +{ + TransactionId xid; + MultiXactStatus status; +} MultiXactMember; + + +/* ---------------- + * multixact-related XLOG entries + * ---------------- + */ + +#define XLOG_MULTIXACT_ZERO_OFF_PAGE 0x00 +#define XLOG_MULTIXACT_ZERO_MEM_PAGE 0x10 +#define XLOG_MULTIXACT_CREATE_ID 0x20 +#define XLOG_MULTIXACT_TRUNCATE_ID 0x30 + +typedef struct xl_multixact_create +{ + MultiXactId mid; /* new MultiXact's ID */ + MultiXactOffset moff; /* its starting offset in members file */ + int32 nmembers; /* number of member XIDs */ + MultiXactMember members[FLEXIBLE_ARRAY_MEMBER]; +} xl_multixact_create; + +#define SizeOfMultiXactCreate (offsetof(xl_multixact_create, members)) + +typedef struct xl_multixact_truncate +{ + Oid oldestMultiDB; + + /* to-be-truncated range of multixact offsets */ + MultiXactId startTruncOff; /* just for completeness' sake */ + MultiXactId endTruncOff; + + /* to-be-truncated range of multixact members */ + MultiXactOffset startTruncMemb; + MultiXactOffset endTruncMemb; +} xl_multixact_truncate; + +#define SizeOfMultiXactTruncate (sizeof(xl_multixact_truncate)) + + +extern MultiXactId MultiXactIdCreate(TransactionId xid1, + MultiXactStatus status1, TransactionId xid2, + MultiXactStatus status2); +extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid, + MultiXactStatus status); +extern MultiXactId MultiXactIdCreateFromMembers(int nmembers, + MultiXactMember *members); + +extern MultiXactId ReadNextMultiXactId(void); +extern void ReadMultiXactIdRange(MultiXactId *oldest, MultiXactId *next); +extern bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly); +extern void MultiXactIdSetOldestMember(void); +extern int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, + bool from_pgupgrade, bool isLockOnly); +extern bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2); +extern bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, + MultiXactId multi2); + +extern int multixactoffsetssyncfiletag(const FileTag *ftag, char *path); +extern int multixactmemberssyncfiletag(const FileTag *ftag, char *path); + +extern void AtEOXact_MultiXact(void); +extern void AtPrepare_MultiXact(void); +extern void PostPrepare_MultiXact(TransactionId xid); + +extern Size MultiXactShmemSize(void); +extern void MultiXactShmemInit(void); +extern void BootStrapMultiXact(void); +extern void StartupMultiXact(void); +extern void TrimMultiXact(void); +extern void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, + Oid oldest_datoid, + bool is_startup); +extern void MultiXactGetCheckptMulti(bool is_shutdown, + MultiXactId *nextMulti, + MultiXactOffset *nextMultiOffset, + MultiXactId *oldestMulti, + Oid *oldestMultiDB); +extern void CheckPointMultiXact(void); +extern MultiXactId GetOldestMultiXactId(void); +extern void TruncateMultiXact(MultiXactId newOldestMulti, + Oid newOldestMultiDB); +extern void MultiXactSetNextMXact(MultiXactId nextMulti, + MultiXactOffset nextMultiOffset); +extern void MultiXactAdvanceNextMXact(MultiXactId minMulti, + MultiXactOffset minMultiOffset); +extern void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB); +extern int MultiXactMemberFreezeThreshold(void); + +extern void multixact_twophase_recover(TransactionId xid, uint16 info, + void *recdata, uint32 len); +extern void multixact_twophase_postcommit(TransactionId xid, uint16 info, + void *recdata, uint32 len); +extern void multixact_twophase_postabort(TransactionId xid, uint16 info, + void *recdata, uint32 len); + +extern void multixact_redo(XLogReaderState *record); +extern void multixact_desc(StringInfo buf, XLogReaderState *record); +extern const char *multixact_identify(uint8 info); +extern char *mxid_to_string(MultiXactId multi, int nmembers, + MultiXactMember *members); + +#endif /* MULTIXACT_H */ diff --git a/install/include/postgresql/server/access/nbtree.h b/install/include/postgresql/server/access/nbtree.h new file mode 100644 index 00000000000..9020abebc92 --- /dev/null +++ b/install/include/postgresql/server/access/nbtree.h @@ -0,0 +1,1298 @@ +/*------------------------------------------------------------------------- + * + * nbtree.h + * header file for postgres btree access method implementation. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/nbtree.h + * + *------------------------------------------------------------------------- + */ +#ifndef NBTREE_H +#define NBTREE_H + +#include "access/amapi.h" +#include "access/itup.h" +#include "access/sdir.h" +#include "access/tableam.h" +#include "access/xlogreader.h" +#include "catalog/pg_am_d.h" +#include "catalog/pg_index.h" +#include "lib/stringinfo.h" +#include "storage/bufmgr.h" +#include "storage/shm_toc.h" + +/* There's room for a 16-bit vacuum cycle ID in BTPageOpaqueData */ +typedef uint16 BTCycleId; + +/* + * BTPageOpaqueData -- At the end of every page, we store a pointer + * to both siblings in the tree. This is used to do forward/backward + * index scans. The next-page link is also critical for recovery when + * a search has navigated to the wrong page due to concurrent page splits + * or deletions; see src/backend/access/nbtree/README for more info. + * + * In addition, we store the page's btree level (counting upwards from + * zero at a leaf page) as well as some flag bits indicating the page type + * and status. If the page is deleted, a BTDeletedPageData struct is stored + * in the page's tuple area, while a standard BTPageOpaqueData struct is + * stored in the page special area. + * + * We also store a "vacuum cycle ID". When a page is split while VACUUM is + * processing the index, a nonzero value associated with the VACUUM run is + * stored into both halves of the split page. (If VACUUM is not running, + * both pages receive zero cycleids.) This allows VACUUM to detect whether + * a page was split since it started, with a small probability of false match + * if the page was last split some exact multiple of MAX_BT_CYCLE_ID VACUUMs + * ago. Also, during a split, the BTP_SPLIT_END flag is cleared in the left + * (original) page, and set in the right page, but only if the next page + * to its right has a different cycleid. + * + * NOTE: the BTP_LEAF flag bit is redundant since level==0 could be tested + * instead. + * + * NOTE: the btpo_level field used to be a union type in order to allow + * deleted pages to store a 32-bit safexid in the same field. We now store + * 64-bit/full safexid values using BTDeletedPageData instead. + */ + +typedef struct BTPageOpaqueData +{ + BlockNumber btpo_prev; /* left sibling, or P_NONE if leftmost */ + BlockNumber btpo_next; /* right sibling, or P_NONE if rightmost */ + uint32 btpo_level; /* tree level --- zero for leaf pages */ + uint16 btpo_flags; /* flag bits, see below */ + BTCycleId btpo_cycleid; /* vacuum cycle ID of latest split */ +} BTPageOpaqueData; + +typedef BTPageOpaqueData *BTPageOpaque; + +#define BTPageGetOpaque(page) ((BTPageOpaque) PageGetSpecialPointer(page)) + +/* Bits defined in btpo_flags */ +#define BTP_LEAF (1 << 0) /* leaf page, i.e. not internal page */ +#define BTP_ROOT (1 << 1) /* root page (has no parent) */ +#define BTP_DELETED (1 << 2) /* page has been deleted from tree */ +#define BTP_META (1 << 3) /* meta-page */ +#define BTP_HALF_DEAD (1 << 4) /* empty, but still in tree */ +#define BTP_SPLIT_END (1 << 5) /* rightmost page of split group */ +#define BTP_HAS_GARBAGE (1 << 6) /* page has LP_DEAD tuples (deprecated) */ +#define BTP_INCOMPLETE_SPLIT (1 << 7) /* right sibling's downlink is missing */ +#define BTP_HAS_FULLXID (1 << 8) /* contains BTDeletedPageData */ + +/* + * The max allowed value of a cycle ID is a bit less than 64K. This is + * for convenience of pg_filedump and similar utilities: we want to use + * the last 2 bytes of special space as an index type indicator, and + * restricting cycle ID lets btree use that space for vacuum cycle IDs + * while still allowing index type to be identified. + */ +#define MAX_BT_CYCLE_ID 0xFF7F + + +/* + * The Meta page is always the first page in the btree index. + * Its primary purpose is to point to the location of the btree root page. + * We also point to the "fast" root, which is the current effective root; + * see README for discussion. + */ + +typedef struct BTMetaPageData +{ + uint32 btm_magic; /* should contain BTREE_MAGIC */ + uint32 btm_version; /* nbtree version (always <= BTREE_VERSION) */ + BlockNumber btm_root; /* current root location */ + uint32 btm_level; /* tree level of the root page */ + BlockNumber btm_fastroot; /* current "fast" root location */ + uint32 btm_fastlevel; /* tree level of the "fast" root page */ + /* remaining fields only valid when btm_version >= BTREE_NOVAC_VERSION */ + + /* number of deleted, non-recyclable pages during last cleanup */ + uint32 btm_last_cleanup_num_delpages; + /* number of heap tuples during last cleanup (deprecated) */ + float8 btm_last_cleanup_num_heap_tuples; + + bool btm_allequalimage; /* are all columns "equalimage"? */ +} BTMetaPageData; + +#define BTPageGetMeta(p) \ + ((BTMetaPageData *) PageGetContents(p)) + +/* + * The current Btree version is 4. That's what you'll get when you create + * a new index. + * + * Btree version 3 was used in PostgreSQL v11. It is mostly the same as + * version 4, but heap TIDs were not part of the keyspace. Index tuples + * with duplicate keys could be stored in any order. We continue to + * support reading and writing Btree versions 2 and 3, so that they don't + * need to be immediately re-indexed at pg_upgrade. In order to get the + * new heapkeyspace semantics, however, a REINDEX is needed. + * + * Deduplication is safe to use when the btm_allequalimage field is set to + * true. It's safe to read the btm_allequalimage field on version 3, but + * only version 4 indexes make use of deduplication. Even version 4 + * indexes created on PostgreSQL v12 will need a REINDEX to make use of + * deduplication, though, since there is no other way to set + * btm_allequalimage to true (pg_upgrade hasn't been taught to set the + * metapage field). + * + * Btree version 2 is mostly the same as version 3. There are two new + * fields in the metapage that were introduced in version 3. A version 2 + * metapage will be automatically upgraded to version 3 on the first + * insert to it. INCLUDE indexes cannot use version 2. + */ +#define BTREE_METAPAGE 0 /* first page is meta */ +#define BTREE_MAGIC 0x053162 /* magic number in metapage */ +#define BTREE_VERSION 4 /* current version number */ +#define BTREE_MIN_VERSION 2 /* minimum supported version */ +#define BTREE_NOVAC_VERSION 3 /* version with all meta fields set */ + +/* + * Maximum size of a btree index entry, including its tuple header. + * + * We actually need to be able to fit three items on every page, + * so restrict any one item to 1/3 the per-page available space. + * + * There are rare cases where _bt_truncate() will need to enlarge + * a heap index tuple to make space for a tiebreaker heap TID + * attribute, which we account for here. + */ +#define BTMaxItemSize(page) \ + (MAXALIGN_DOWN((PageGetPageSize(page) - \ + MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \ + MAXALIGN(sizeof(BTPageOpaqueData))) / 3) - \ + MAXALIGN(sizeof(ItemPointerData))) +#define BTMaxItemSizeNoHeapTid(page) \ + MAXALIGN_DOWN((PageGetPageSize(page) - \ + MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \ + MAXALIGN(sizeof(BTPageOpaqueData))) / 3) + +/* + * MaxTIDsPerBTreePage is an upper bound on the number of heap TIDs tuples + * that may be stored on a btree leaf page. It is used to size the + * per-page temporary buffers. + * + * Note: we don't bother considering per-tuple overheads here to keep + * things simple (value is based on how many elements a single array of + * heap TIDs must have to fill the space between the page header and + * special area). The value is slightly higher (i.e. more conservative) + * than necessary as a result, which is considered acceptable. + */ +#define MaxTIDsPerBTreePage \ + (int) ((BLCKSZ - SizeOfPageHeaderData - sizeof(BTPageOpaqueData)) / \ + sizeof(ItemPointerData)) + +/* + * The leaf-page fillfactor defaults to 90% but is user-adjustable. + * For pages above the leaf level, we use a fixed 70% fillfactor. + * The fillfactor is applied during index build and when splitting + * a rightmost page; when splitting non-rightmost pages we try to + * divide the data equally. When splitting a page that's entirely + * filled with a single value (duplicates), the effective leaf-page + * fillfactor is 96%, regardless of whether the page is a rightmost + * page. + */ +#define BTREE_MIN_FILLFACTOR 10 +#define BTREE_DEFAULT_FILLFACTOR 90 +#define BTREE_NONLEAF_FILLFACTOR 70 +#define BTREE_SINGLEVAL_FILLFACTOR 96 + +/* + * In general, the btree code tries to localize its knowledge about + * page layout to a couple of routines. However, we need a special + * value to indicate "no page number" in those places where we expect + * page numbers. We can use zero for this because we never need to + * make a pointer to the metadata page. + */ + +#define P_NONE 0 + +/* + * Macros to test whether a page is leftmost or rightmost on its tree level, + * as well as other state info kept in the opaque data. + */ +#define P_LEFTMOST(opaque) ((opaque)->btpo_prev == P_NONE) +#define P_RIGHTMOST(opaque) ((opaque)->btpo_next == P_NONE) +#define P_ISLEAF(opaque) (((opaque)->btpo_flags & BTP_LEAF) != 0) +#define P_ISROOT(opaque) (((opaque)->btpo_flags & BTP_ROOT) != 0) +#define P_ISDELETED(opaque) (((opaque)->btpo_flags & BTP_DELETED) != 0) +#define P_ISMETA(opaque) (((opaque)->btpo_flags & BTP_META) != 0) +#define P_ISHALFDEAD(opaque) (((opaque)->btpo_flags & BTP_HALF_DEAD) != 0) +#define P_IGNORE(opaque) (((opaque)->btpo_flags & (BTP_DELETED|BTP_HALF_DEAD)) != 0) +#define P_HAS_GARBAGE(opaque) (((opaque)->btpo_flags & BTP_HAS_GARBAGE) != 0) +#define P_INCOMPLETE_SPLIT(opaque) (((opaque)->btpo_flags & BTP_INCOMPLETE_SPLIT) != 0) +#define P_HAS_FULLXID(opaque) (((opaque)->btpo_flags & BTP_HAS_FULLXID) != 0) + +/* + * BTDeletedPageData is the page contents of a deleted page + */ +typedef struct BTDeletedPageData +{ + FullTransactionId safexid; /* See BTPageIsRecyclable() */ +} BTDeletedPageData; + +static inline void +BTPageSetDeleted(Page page, FullTransactionId safexid) +{ + BTPageOpaque opaque; + PageHeader header; + BTDeletedPageData *contents; + + opaque = BTPageGetOpaque(page); + header = ((PageHeader) page); + + opaque->btpo_flags &= ~BTP_HALF_DEAD; + opaque->btpo_flags |= BTP_DELETED | BTP_HAS_FULLXID; + header->pd_lower = MAXALIGN(SizeOfPageHeaderData) + + sizeof(BTDeletedPageData); + header->pd_upper = header->pd_special; + + /* Set safexid in deleted page */ + contents = ((BTDeletedPageData *) PageGetContents(page)); + contents->safexid = safexid; +} + +static inline FullTransactionId +BTPageGetDeleteXid(Page page) +{ + BTPageOpaque opaque; + BTDeletedPageData *contents; + + /* We only expect to be called with a deleted page */ + Assert(!PageIsNew(page)); + opaque = BTPageGetOpaque(page); + Assert(P_ISDELETED(opaque)); + + /* pg_upgrade'd deleted page -- must be safe to delete now */ + if (!P_HAS_FULLXID(opaque)) + return FirstNormalFullTransactionId; + + /* Get safexid from deleted page */ + contents = ((BTDeletedPageData *) PageGetContents(page)); + return contents->safexid; +} + +/* + * Is an existing page recyclable? + * + * This exists to centralize the policy on which deleted pages are now safe to + * re-use. However, _bt_pendingfsm_finalize() duplicates some of the same + * logic because it doesn't work directly with pages -- keep the two in sync. + * + * Note: PageIsNew() pages are always safe to recycle, but we can't deal with + * them here (caller is responsible for that case themselves). Caller might + * well need special handling for new pages anyway. + */ +static inline bool +BTPageIsRecyclable(Page page, Relation heaprel) +{ + BTPageOpaque opaque; + + Assert(!PageIsNew(page)); + Assert(heaprel != NULL); + + /* Recycling okay iff page is deleted and safexid is old enough */ + opaque = BTPageGetOpaque(page); + if (P_ISDELETED(opaque)) + { + FullTransactionId safexid = BTPageGetDeleteXid(page); + + /* + * The page was deleted, but when? If it was just deleted, a scan + * might have seen the downlink to it, and will read the page later. + * As long as that can happen, we must keep the deleted page around as + * a tombstone. + * + * For that check if the deletion XID could still be visible to + * anyone. If not, then no scan that's still in progress could have + * seen its downlink, and we can recycle it. + */ + return GlobalVisCheckRemovableFullXid(heaprel, safexid); + } + + return false; +} + +/* + * BTVacState and BTPendingFSM are private nbtree.c state used during VACUUM. + * They are exported for use by page deletion related code in nbtpage.c. + */ +typedef struct BTPendingFSM +{ + BlockNumber target; /* Page deleted by current VACUUM */ + FullTransactionId safexid; /* Page's BTDeletedPageData.safexid */ +} BTPendingFSM; + +typedef struct BTVacState +{ + IndexVacuumInfo *info; + IndexBulkDeleteResult *stats; + IndexBulkDeleteCallback callback; + void *callback_state; + BTCycleId cycleid; + MemoryContext pagedelcontext; + + /* + * _bt_pendingfsm_finalize() state + */ + int bufsize; /* pendingpages space (in # elements) */ + int maxbufsize; /* max bufsize that respects work_mem */ + BTPendingFSM *pendingpages; /* One entry per newly deleted page */ + int npendingpages; /* current # valid pendingpages */ +} BTVacState; + +/* + * Lehman and Yao's algorithm requires a ``high key'' on every non-rightmost + * page. The high key is not a tuple that is used to visit the heap. It is + * a pivot tuple (see "Notes on B-Tree tuple format" below for definition). + * The high key on a page is required to be greater than or equal to any + * other key that appears on the page. If we find ourselves trying to + * insert a key that is strictly > high key, we know we need to move right + * (this should only happen if the page was split since we examined the + * parent page). + * + * Our insertion algorithm guarantees that we can use the initial least key + * on our right sibling as the high key. Once a page is created, its high + * key changes only if the page is split. + * + * On a non-rightmost page, the high key lives in item 1 and data items + * start in item 2. Rightmost pages have no high key, so we store data + * items beginning in item 1. + */ + +#define P_HIKEY ((OffsetNumber) 1) +#define P_FIRSTKEY ((OffsetNumber) 2) +#define P_FIRSTDATAKEY(opaque) (P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY) + +/* + * Notes on B-Tree tuple format, and key and non-key attributes: + * + * INCLUDE B-Tree indexes have non-key attributes. These are extra + * attributes that may be returned by index-only scans, but do not influence + * the order of items in the index (formally, non-key attributes are not + * considered to be part of the key space). Non-key attributes are only + * present in leaf index tuples whose item pointers actually point to heap + * tuples (non-pivot tuples). _bt_check_natts() enforces the rules + * described here. + * + * Non-pivot tuple format (plain/non-posting variant): + * + * t_tid | t_info | key values | INCLUDE columns, if any + * + * t_tid points to the heap TID, which is a tiebreaker key column as of + * BTREE_VERSION 4. + * + * Non-pivot tuples complement pivot tuples, which only have key columns. + * The sole purpose of pivot tuples is to represent how the key space is + * separated. In general, any B-Tree index that has more than one level + * (i.e. any index that does not just consist of a metapage and a single + * leaf root page) must have some number of pivot tuples, since pivot + * tuples are used for traversing the tree. Suffix truncation can omit + * trailing key columns when a new pivot is formed, which makes minus + * infinity their logical value. Since BTREE_VERSION 4 indexes treat heap + * TID as a trailing key column that ensures that all index tuples are + * physically unique, it is necessary to represent heap TID as a trailing + * key column in pivot tuples, though very often this can be truncated + * away, just like any other key column. (Actually, the heap TID is + * omitted rather than truncated, since its representation is different to + * the non-pivot representation.) + * + * Pivot tuple format: + * + * t_tid | t_info | key values | [heap TID] + * + * We store the number of columns present inside pivot tuples by abusing + * their t_tid offset field, since pivot tuples never need to store a real + * offset (pivot tuples generally store a downlink in t_tid, though). The + * offset field only stores the number of columns/attributes when the + * INDEX_ALT_TID_MASK bit is set, which doesn't count the trailing heap + * TID column sometimes stored in pivot tuples -- that's represented by + * the presence of BT_PIVOT_HEAP_TID_ATTR. The INDEX_ALT_TID_MASK bit in + * t_info is always set on BTREE_VERSION 4 pivot tuples, since + * BTreeTupleIsPivot() must work reliably on heapkeyspace versions. + * + * In version 2 or version 3 (!heapkeyspace) indexes, INDEX_ALT_TID_MASK + * might not be set in pivot tuples. BTreeTupleIsPivot() won't work + * reliably as a result. The number of columns stored is implicitly the + * same as the number of columns in the index, just like any non-pivot + * tuple. (The number of columns stored should not vary, since suffix + * truncation of key columns is unsafe within any !heapkeyspace index.) + * + * The 12 least significant bits from t_tid's offset number are used to + * represent the number of key columns within a pivot tuple. This leaves 4 + * status bits (BT_STATUS_OFFSET_MASK bits), which are shared by all tuples + * that have the INDEX_ALT_TID_MASK bit set (set in t_info) to store basic + * tuple metadata. BTreeTupleIsPivot() and BTreeTupleIsPosting() use the + * BT_STATUS_OFFSET_MASK bits. + * + * Sometimes non-pivot tuples also use a representation that repurposes + * t_tid to store metadata rather than a TID. PostgreSQL v13 introduced a + * new non-pivot tuple format to support deduplication: posting list + * tuples. Deduplication merges together multiple equal non-pivot tuples + * into a logically equivalent, space efficient representation. A posting + * list is an array of ItemPointerData elements. Non-pivot tuples are + * merged together to form posting list tuples lazily, at the point where + * we'd otherwise have to split a leaf page. + * + * Posting tuple format (alternative non-pivot tuple representation): + * + * t_tid | t_info | key values | posting list (TID array) + * + * Posting list tuples are recognized as such by having the + * INDEX_ALT_TID_MASK status bit set in t_info and the BT_IS_POSTING status + * bit set in t_tid's offset number. These flags redefine the content of + * the posting tuple's t_tid to store the location of the posting list + * (instead of a block number), as well as the total number of heap TIDs + * present in the tuple (instead of a real offset number). + * + * The 12 least significant bits from t_tid's offset number are used to + * represent the number of heap TIDs present in the tuple, leaving 4 status + * bits (the BT_STATUS_OFFSET_MASK bits). Like any non-pivot tuple, the + * number of columns stored is always implicitly the total number in the + * index (in practice there can never be non-key columns stored, since + * deduplication is not supported with INCLUDE indexes). + */ +#define INDEX_ALT_TID_MASK INDEX_AM_RESERVED_BIT + +/* Item pointer offset bit masks */ +#define BT_OFFSET_MASK 0x0FFF +#define BT_STATUS_OFFSET_MASK 0xF000 +/* BT_STATUS_OFFSET_MASK status bits */ +#define BT_PIVOT_HEAP_TID_ATTR 0x1000 +#define BT_IS_POSTING 0x2000 + +/* + * Mask allocated for number of keys in index tuple must be able to fit + * maximum possible number of index attributes + */ +StaticAssertDecl(BT_OFFSET_MASK >= INDEX_MAX_KEYS, + "BT_OFFSET_MASK can't fit INDEX_MAX_KEYS"); + +/* + * Note: BTreeTupleIsPivot() can have false negatives (but not false + * positives) when used with !heapkeyspace indexes + */ +static inline bool +BTreeTupleIsPivot(IndexTuple itup) +{ + if ((itup->t_info & INDEX_ALT_TID_MASK) == 0) + return false; + /* absence of BT_IS_POSTING in offset number indicates pivot tuple */ + if ((ItemPointerGetOffsetNumberNoCheck(&itup->t_tid) & BT_IS_POSTING) != 0) + return false; + + return true; +} + +static inline bool +BTreeTupleIsPosting(IndexTuple itup) +{ + if ((itup->t_info & INDEX_ALT_TID_MASK) == 0) + return false; + /* presence of BT_IS_POSTING in offset number indicates posting tuple */ + if ((ItemPointerGetOffsetNumberNoCheck(&itup->t_tid) & BT_IS_POSTING) == 0) + return false; + + return true; +} + +static inline void +BTreeTupleSetPosting(IndexTuple itup, uint16 nhtids, int postingoffset) +{ + Assert(nhtids > 1); + Assert((nhtids & BT_STATUS_OFFSET_MASK) == 0); + Assert((size_t) postingoffset == MAXALIGN(postingoffset)); + Assert(postingoffset < INDEX_SIZE_MASK); + Assert(!BTreeTupleIsPivot(itup)); + + itup->t_info |= INDEX_ALT_TID_MASK; + ItemPointerSetOffsetNumber(&itup->t_tid, (nhtids | BT_IS_POSTING)); + ItemPointerSetBlockNumber(&itup->t_tid, postingoffset); +} + +static inline uint16 +BTreeTupleGetNPosting(IndexTuple posting) +{ + OffsetNumber existing; + + Assert(BTreeTupleIsPosting(posting)); + + existing = ItemPointerGetOffsetNumberNoCheck(&posting->t_tid); + return (existing & BT_OFFSET_MASK); +} + +static inline uint32 +BTreeTupleGetPostingOffset(IndexTuple posting) +{ + Assert(BTreeTupleIsPosting(posting)); + + return ItemPointerGetBlockNumberNoCheck(&posting->t_tid); +} + +static inline ItemPointer +BTreeTupleGetPosting(IndexTuple posting) +{ + return (ItemPointer) ((char *) posting + + BTreeTupleGetPostingOffset(posting)); +} + +static inline ItemPointer +BTreeTupleGetPostingN(IndexTuple posting, int n) +{ + return BTreeTupleGetPosting(posting) + n; +} + +/* + * Get/set downlink block number in pivot tuple. + * + * Note: Cannot assert that tuple is a pivot tuple. If we did so then + * !heapkeyspace indexes would exhibit false positive assertion failures. + */ +static inline BlockNumber +BTreeTupleGetDownLink(IndexTuple pivot) +{ + return ItemPointerGetBlockNumberNoCheck(&pivot->t_tid); +} + +static inline void +BTreeTupleSetDownLink(IndexTuple pivot, BlockNumber blkno) +{ + ItemPointerSetBlockNumber(&pivot->t_tid, blkno); +} + +/* + * Get number of attributes within tuple. + * + * Note that this does not include an implicit tiebreaker heap TID + * attribute, if any. Note also that the number of key attributes must be + * explicitly represented in all heapkeyspace pivot tuples. + * + * Note: This is defined as a macro rather than an inline function to + * avoid including rel.h. + */ +#define BTreeTupleGetNAtts(itup, rel) \ + ( \ + (BTreeTupleIsPivot(itup)) ? \ + ( \ + ItemPointerGetOffsetNumberNoCheck(&(itup)->t_tid) & BT_OFFSET_MASK \ + ) \ + : \ + IndexRelationGetNumberOfAttributes(rel) \ + ) + +/* + * Set number of key attributes in tuple. + * + * The heap TID tiebreaker attribute bit may also be set here, indicating that + * a heap TID value will be stored at the end of the tuple (i.e. using the + * special pivot tuple representation). + */ +static inline void +BTreeTupleSetNAtts(IndexTuple itup, uint16 nkeyatts, bool heaptid) +{ + Assert(nkeyatts <= INDEX_MAX_KEYS); + Assert((nkeyatts & BT_STATUS_OFFSET_MASK) == 0); + Assert(!heaptid || nkeyatts > 0); + Assert(!BTreeTupleIsPivot(itup) || nkeyatts == 0); + + itup->t_info |= INDEX_ALT_TID_MASK; + + if (heaptid) + nkeyatts |= BT_PIVOT_HEAP_TID_ATTR; + + /* BT_IS_POSTING bit is deliberately unset here */ + ItemPointerSetOffsetNumber(&itup->t_tid, nkeyatts); + Assert(BTreeTupleIsPivot(itup)); +} + +/* + * Get/set leaf page's "top parent" link from its high key. Used during page + * deletion. + * + * Note: Cannot assert that tuple is a pivot tuple. If we did so then + * !heapkeyspace indexes would exhibit false positive assertion failures. + */ +static inline BlockNumber +BTreeTupleGetTopParent(IndexTuple leafhikey) +{ + return ItemPointerGetBlockNumberNoCheck(&leafhikey->t_tid); +} + +static inline void +BTreeTupleSetTopParent(IndexTuple leafhikey, BlockNumber blkno) +{ + ItemPointerSetBlockNumber(&leafhikey->t_tid, blkno); + BTreeTupleSetNAtts(leafhikey, 0, false); +} + +/* + * Get tiebreaker heap TID attribute, if any. + * + * This returns the first/lowest heap TID in the case of a posting list tuple. + */ +static inline ItemPointer +BTreeTupleGetHeapTID(IndexTuple itup) +{ + if (BTreeTupleIsPivot(itup)) + { + /* Pivot tuple heap TID representation? */ + if ((ItemPointerGetOffsetNumberNoCheck(&itup->t_tid) & + BT_PIVOT_HEAP_TID_ATTR) != 0) + return (ItemPointer) ((char *) itup + IndexTupleSize(itup) - + sizeof(ItemPointerData)); + + /* Heap TID attribute was truncated */ + return NULL; + } + else if (BTreeTupleIsPosting(itup)) + return BTreeTupleGetPosting(itup); + + return &itup->t_tid; +} + +/* + * Get maximum heap TID attribute, which could be the only TID in the case of + * a non-pivot tuple that does not have a posting list tuple. + * + * Works with non-pivot tuples only. + */ +static inline ItemPointer +BTreeTupleGetMaxHeapTID(IndexTuple itup) +{ + Assert(!BTreeTupleIsPivot(itup)); + + if (BTreeTupleIsPosting(itup)) + { + uint16 nposting = BTreeTupleGetNPosting(itup); + + return BTreeTupleGetPostingN(itup, nposting - 1); + } + + return &itup->t_tid; +} + +/* + * Operator strategy numbers for B-tree have been moved to access/stratnum.h, + * because many places need to use them in ScanKeyInit() calls. + * + * The strategy numbers are chosen so that we can commute them by + * subtraction, thus: + */ +#define BTCommuteStrategyNumber(strat) (BTMaxStrategyNumber + 1 - (strat)) + +/* + * When a new operator class is declared, we require that the user + * supply us with an amproc procedure (BTORDER_PROC) for determining + * whether, for two keys a and b, a < b, a = b, or a > b. This routine + * must return < 0, 0, > 0, respectively, in these three cases. + * + * To facilitate accelerated sorting, an operator class may choose to + * offer a second procedure (BTSORTSUPPORT_PROC). For full details, see + * src/include/utils/sortsupport.h. + * + * To support window frames defined by "RANGE offset PRECEDING/FOLLOWING", + * an operator class may choose to offer a third amproc procedure + * (BTINRANGE_PROC), independently of whether it offers sortsupport. + * For full details, see doc/src/sgml/btree.sgml. + * + * To facilitate B-Tree deduplication, an operator class may choose to + * offer a forth amproc procedure (BTEQUALIMAGE_PROC). For full details, + * see doc/src/sgml/btree.sgml. + */ + +#define BTORDER_PROC 1 +#define BTSORTSUPPORT_PROC 2 +#define BTINRANGE_PROC 3 +#define BTEQUALIMAGE_PROC 4 +#define BTOPTIONS_PROC 5 +#define BTNProcs 5 + +/* + * We need to be able to tell the difference between read and write + * requests for pages, in order to do locking correctly. + */ + +#define BT_READ BUFFER_LOCK_SHARE +#define BT_WRITE BUFFER_LOCK_EXCLUSIVE + +/* + * BTStackData -- As we descend a tree, we push the location of pivot + * tuples whose downlink we are about to follow onto a private stack. If + * we split a leaf, we use this stack to walk back up the tree and insert + * data into its parent page at the correct location. We also have to + * recursively insert into the grandparent page if and when the parent page + * splits. Our private stack can become stale due to concurrent page + * splits and page deletions, but it should never give us an irredeemably + * bad picture. + */ +typedef struct BTStackData +{ + BlockNumber bts_blkno; + OffsetNumber bts_offset; + struct BTStackData *bts_parent; +} BTStackData; + +typedef BTStackData *BTStack; + +/* + * BTScanInsertData is the btree-private state needed to find an initial + * position for an indexscan, or to insert new tuples -- an "insertion + * scankey" (not to be confused with a search scankey). It's used to descend + * a B-Tree using _bt_search. + * + * heapkeyspace indicates if we expect all keys in the index to be physically + * unique because heap TID is used as a tiebreaker attribute, and if index may + * have truncated key attributes in pivot tuples. This is actually a property + * of the index relation itself (not an indexscan). heapkeyspace indexes are + * indexes whose version is >= version 4. It's convenient to keep this close + * by, rather than accessing the metapage repeatedly. + * + * allequalimage is set to indicate that deduplication is safe for the index. + * This is also a property of the index relation rather than an indexscan. + * + * anynullkeys indicates if any of the keys had NULL value when scankey was + * built from index tuple (note that already-truncated tuple key attributes + * set NULL as a placeholder key value, which also affects value of + * anynullkeys). This is a convenience for unique index non-pivot tuple + * insertion, which usually temporarily unsets scantid, but shouldn't iff + * anynullkeys is true. Value generally matches non-pivot tuple's HasNulls + * bit, but may not when inserting into an INCLUDE index (tuple header value + * is affected by the NULL-ness of both key and non-key attributes). + * + * When nextkey is false (the usual case), _bt_search and _bt_binsrch will + * locate the first item >= scankey. When nextkey is true, they will locate + * the first item > scan key. + * + * pivotsearch is set to true by callers that want to re-find a leaf page + * using a scankey built from a leaf page's high key. Most callers set this + * to false. + * + * scantid is the heap TID that is used as a final tiebreaker attribute. It + * is set to NULL when index scan doesn't need to find a position for a + * specific physical tuple. Must be set when inserting new tuples into + * heapkeyspace indexes, since every tuple in the tree unambiguously belongs + * in one exact position (it's never set with !heapkeyspace indexes, though). + * Despite the representational difference, nbtree search code considers + * scantid to be just another insertion scankey attribute. + * + * scankeys is an array of scan key entries for attributes that are compared + * before scantid (user-visible attributes). keysz is the size of the array. + * During insertion, there must be a scan key for every attribute, but when + * starting a regular index scan some can be omitted. The array is used as a + * flexible array member, though it's sized in a way that makes it possible to + * use stack allocations. See nbtree/README for full details. + */ +typedef struct BTScanInsertData +{ + bool heapkeyspace; + bool allequalimage; + bool anynullkeys; + bool nextkey; + bool pivotsearch; + ItemPointer scantid; /* tiebreaker for scankeys */ + int keysz; /* Size of scankeys array */ + ScanKeyData scankeys[INDEX_MAX_KEYS]; /* Must appear last */ +} BTScanInsertData; + +typedef BTScanInsertData *BTScanInsert; + +/* + * BTInsertStateData is a working area used during insertion. + * + * This is filled in after descending the tree to the first leaf page the new + * tuple might belong on. Tracks the current position while performing + * uniqueness check, before we have determined which exact page to insert + * to. + * + * (This should be private to nbtinsert.c, but it's also used by + * _bt_binsrch_insert) + */ +typedef struct BTInsertStateData +{ + IndexTuple itup; /* Item we're inserting */ + Size itemsz; /* Size of itup -- should be MAXALIGN()'d */ + BTScanInsert itup_key; /* Insertion scankey */ + + /* Buffer containing leaf page we're likely to insert itup on */ + Buffer buf; + + /* + * Cache of bounds within the current buffer. Only used for insertions + * where _bt_check_unique is called. See _bt_binsrch_insert and + * _bt_findinsertloc for details. + */ + bool bounds_valid; + OffsetNumber low; + OffsetNumber stricthigh; + + /* + * if _bt_binsrch_insert found the location inside existing posting list, + * save the position inside the list. -1 sentinel value indicates overlap + * with an existing posting list tuple that has its LP_DEAD bit set. + */ + int postingoff; +} BTInsertStateData; + +typedef BTInsertStateData *BTInsertState; + +/* + * State used to representing an individual pending tuple during + * deduplication. + */ +typedef struct BTDedupInterval +{ + OffsetNumber baseoff; + uint16 nitems; +} BTDedupInterval; + +/* + * BTDedupStateData is a working area used during deduplication. + * + * The status info fields track the state of a whole-page deduplication pass. + * State about the current pending posting list is also tracked. + * + * A pending posting list is comprised of a contiguous group of equal items + * from the page, starting from page offset number 'baseoff'. This is the + * offset number of the "base" tuple for new posting list. 'nitems' is the + * current total number of existing items from the page that will be merged to + * make a new posting list tuple, including the base tuple item. (Existing + * items may themselves be posting list tuples, or regular non-pivot tuples.) + * + * The total size of the existing tuples to be freed when pending posting list + * is processed gets tracked by 'phystupsize'. This information allows + * deduplication to calculate the space saving for each new posting list + * tuple, and for the entire pass over the page as a whole. + */ +typedef struct BTDedupStateData +{ + /* Deduplication status info for entire pass over page */ + bool deduplicate; /* Still deduplicating page? */ + int nmaxitems; /* Number of max-sized tuples so far */ + Size maxpostingsize; /* Limit on size of final tuple */ + + /* Metadata about base tuple of current pending posting list */ + IndexTuple base; /* Use to form new posting list */ + OffsetNumber baseoff; /* page offset of base */ + Size basetupsize; /* base size without original posting list */ + + /* Other metadata about pending posting list */ + ItemPointer htids; /* Heap TIDs in pending posting list */ + int nhtids; /* Number of heap TIDs in htids array */ + int nitems; /* Number of existing tuples/line pointers */ + Size phystupsize; /* Includes line pointer overhead */ + + /* + * Array of tuples to go on new version of the page. Contains one entry + * for each group of consecutive items. Note that existing tuples that + * will not become posting list tuples do not appear in the array (they + * are implicitly unchanged by deduplication pass). + */ + int nintervals; /* current number of intervals in array */ + BTDedupInterval intervals[MaxIndexTuplesPerPage]; +} BTDedupStateData; + +typedef BTDedupStateData *BTDedupState; + +/* + * BTVacuumPostingData is state that represents how to VACUUM (or delete) a + * posting list tuple when some (though not all) of its TIDs are to be + * deleted. + * + * Convention is that itup field is the original posting list tuple on input, + * and palloc()'d final tuple used to overwrite existing tuple on output. + */ +typedef struct BTVacuumPostingData +{ + /* Tuple that will be/was updated */ + IndexTuple itup; + OffsetNumber updatedoffset; + + /* State needed to describe final itup in WAL */ + uint16 ndeletedtids; + uint16 deletetids[FLEXIBLE_ARRAY_MEMBER]; +} BTVacuumPostingData; + +typedef BTVacuumPostingData *BTVacuumPosting; + +/* + * BTScanOpaqueData is the btree-private state needed for an indexscan. + * This consists of preprocessed scan keys (see _bt_preprocess_keys() for + * details of the preprocessing), information about the current location + * of the scan, and information about the marked location, if any. (We use + * BTScanPosData to represent the data needed for each of current and marked + * locations.) In addition we can remember some known-killed index entries + * that must be marked before we can move off the current page. + * + * Index scans work a page at a time: we pin and read-lock the page, identify + * all the matching items on the page and save them in BTScanPosData, then + * release the read-lock while returning the items to the caller for + * processing. This approach minimizes lock/unlock traffic. Note that we + * keep the pin on the index page until the caller is done with all the items + * (this is needed for VACUUM synchronization, see nbtree/README). When we + * are ready to step to the next page, if the caller has told us any of the + * items were killed, we re-lock the page to mark them killed, then unlock. + * Finally we drop the pin and step to the next page in the appropriate + * direction. + * + * If we are doing an index-only scan, we save the entire IndexTuple for each + * matched item, otherwise only its heap TID and offset. The IndexTuples go + * into a separate workspace array; each BTScanPosItem stores its tuple's + * offset within that array. Posting list tuples store a "base" tuple once, + * allowing the same key to be returned for each TID in the posting list + * tuple. + */ + +typedef struct BTScanPosItem /* what we remember about each match */ +{ + ItemPointerData heapTid; /* TID of referenced heap item */ + OffsetNumber indexOffset; /* index item's location within page */ + LocationIndex tupleOffset; /* IndexTuple's offset in workspace, if any */ +} BTScanPosItem; + +typedef struct BTScanPosData +{ + Buffer buf; /* if valid, the buffer is pinned */ + + XLogRecPtr lsn; /* pos in the WAL stream when page was read */ + BlockNumber currPage; /* page referenced by items array */ + BlockNumber nextPage; /* page's right link when we scanned it */ + + /* + * moreLeft and moreRight track whether we think there may be matching + * index entries to the left and right of the current page, respectively. + * We can clear the appropriate one of these flags when _bt_checkkeys() + * returns continuescan = false. + */ + bool moreLeft; + bool moreRight; + + /* + * If we are doing an index-only scan, nextTupleOffset is the first free + * location in the associated tuple storage workspace. + */ + int nextTupleOffset; + + /* + * The items array is always ordered in index order (ie, increasing + * indexoffset). When scanning backwards it is convenient to fill the + * array back-to-front, so we start at the last slot and fill downwards. + * Hence we need both a first-valid-entry and a last-valid-entry counter. + * itemIndex is a cursor showing which entry was last returned to caller. + */ + int firstItem; /* first valid index in items[] */ + int lastItem; /* last valid index in items[] */ + int itemIndex; /* current index in items[] */ + + BTScanPosItem items[MaxTIDsPerBTreePage]; /* MUST BE LAST */ +} BTScanPosData; + +typedef BTScanPosData *BTScanPos; + +#define BTScanPosIsPinned(scanpos) \ +( \ + AssertMacro(BlockNumberIsValid((scanpos).currPage) || \ + !BufferIsValid((scanpos).buf)), \ + BufferIsValid((scanpos).buf) \ +) +#define BTScanPosUnpin(scanpos) \ + do { \ + ReleaseBuffer((scanpos).buf); \ + (scanpos).buf = InvalidBuffer; \ + } while (0) +#define BTScanPosUnpinIfPinned(scanpos) \ + do { \ + if (BTScanPosIsPinned(scanpos)) \ + BTScanPosUnpin(scanpos); \ + } while (0) + +#define BTScanPosIsValid(scanpos) \ +( \ + AssertMacro(BlockNumberIsValid((scanpos).currPage) || \ + !BufferIsValid((scanpos).buf)), \ + BlockNumberIsValid((scanpos).currPage) \ +) +#define BTScanPosInvalidate(scanpos) \ + do { \ + (scanpos).currPage = InvalidBlockNumber; \ + (scanpos).nextPage = InvalidBlockNumber; \ + (scanpos).buf = InvalidBuffer; \ + (scanpos).lsn = InvalidXLogRecPtr; \ + (scanpos).nextTupleOffset = 0; \ + } while (0) + +/* We need one of these for each equality-type SK_SEARCHARRAY scan key */ +typedef struct BTArrayKeyInfo +{ + int scan_key; /* index of associated key in arrayKeyData */ + int cur_elem; /* index of current element in elem_values */ + int mark_elem; /* index of marked element in elem_values */ + int num_elems; /* number of elems in current array value */ + Datum *elem_values; /* array of num_elems Datums */ +} BTArrayKeyInfo; + +typedef struct BTScanOpaqueData +{ + /* all fields (except arraysStarted) are set by _bt_preprocess_keys(): */ + bool qual_ok; /* false if qual can never be satisfied */ + bool arraysStarted; /* Started array keys, but have yet to "reach + * past the end" of all arrays? */ + int numberOfKeys; /* number of preprocessed scan keys */ + ScanKey keyData; /* array of preprocessed scan keys */ + + /* workspace for SK_SEARCHARRAY support */ + ScanKey arrayKeyData; /* modified copy of scan->keyData */ + int numArrayKeys; /* number of equality-type array keys (-1 if + * there are any unsatisfiable array keys) */ + int arrayKeyCount; /* count indicating number of array scan keys + * processed */ + BTArrayKeyInfo *arrayKeys; /* info about each equality-type array key */ + MemoryContext arrayContext; /* scan-lifespan context for array data */ + + /* info about killed items if any (killedItems is NULL if never used) */ + int *killedItems; /* currPos.items indexes of killed items */ + int numKilled; /* number of currently stored items */ + + /* + * If we are doing an index-only scan, these are the tuple storage + * workspaces for the currPos and markPos respectively. Each is of size + * BLCKSZ, so it can hold as much as a full page's worth of tuples. + */ + char *currTuples; /* tuple storage for currPos */ + char *markTuples; /* tuple storage for markPos */ + + /* + * If the marked position is on the same page as current position, we + * don't use markPos, but just keep the marked itemIndex in markItemIndex + * (all the rest of currPos is valid for the mark position). Hence, to + * determine if there is a mark, first look at markItemIndex, then at + * markPos. + */ + int markItemIndex; /* itemIndex, or -1 if not valid */ + + /* keep these last in struct for efficiency */ + BTScanPosData currPos; /* current position data */ + BTScanPosData markPos; /* marked position, if any */ +} BTScanOpaqueData; + +typedef BTScanOpaqueData *BTScanOpaque; + +/* + * We use some private sk_flags bits in preprocessed scan keys. We're allowed + * to use bits 16-31 (see skey.h). The uppermost bits are copied from the + * index's indoption[] array entry for the index attribute. + */ +#define SK_BT_REQFWD 0x00010000 /* required to continue forward scan */ +#define SK_BT_REQBKWD 0x00020000 /* required to continue backward scan */ +#define SK_BT_INDOPTION_SHIFT 24 /* must clear the above bits */ +#define SK_BT_DESC (INDOPTION_DESC << SK_BT_INDOPTION_SHIFT) +#define SK_BT_NULLS_FIRST (INDOPTION_NULLS_FIRST << SK_BT_INDOPTION_SHIFT) + +typedef struct BTOptions +{ + int32 varlena_header_; /* varlena header (do not touch directly!) */ + int fillfactor; /* page fill factor in percent (0..100) */ + float8 vacuum_cleanup_index_scale_factor; /* deprecated */ + bool deduplicate_items; /* Try to deduplicate items? */ +} BTOptions; + +#define BTGetFillFactor(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == BTREE_AM_OID), \ + (relation)->rd_options ? \ + ((BTOptions *) (relation)->rd_options)->fillfactor : \ + BTREE_DEFAULT_FILLFACTOR) +#define BTGetTargetPageFreeSpace(relation) \ + (BLCKSZ * (100 - BTGetFillFactor(relation)) / 100) +#define BTGetDeduplicateItems(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == BTREE_AM_OID), \ + ((relation)->rd_options ? \ + ((BTOptions *) (relation)->rd_options)->deduplicate_items : true)) + +/* + * Constant definition for progress reporting. Phase numbers must match + * btbuildphasename. + */ +/* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 (see progress.h) */ +#define PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN 2 +#define PROGRESS_BTREE_PHASE_PERFORMSORT_1 3 +#define PROGRESS_BTREE_PHASE_PERFORMSORT_2 4 +#define PROGRESS_BTREE_PHASE_LEAF_LOAD 5 + +/* + * external entry points for btree, in nbtree.c + */ +extern void btbuildempty(Relation index); +extern bool btinsert(Relation rel, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); +extern IndexScanDesc btbeginscan(Relation rel, int nkeys, int norderbys); +extern Size btestimateparallelscan(void); +extern void btinitparallelscan(void *target); +extern bool btgettuple(IndexScanDesc scan, ScanDirection dir); +extern int64 btgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); +extern void btrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys); +extern void btparallelrescan(IndexScanDesc scan); +extern void btendscan(IndexScanDesc scan); +extern void btmarkpos(IndexScanDesc scan); +extern void btrestrpos(IndexScanDesc scan); +extern IndexBulkDeleteResult *btbulkdelete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *btvacuumcleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); +extern bool btcanreturn(Relation index, int attno); + +/* + * prototypes for internal functions in nbtree.c + */ +extern bool _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno); +extern void _bt_parallel_release(IndexScanDesc scan, BlockNumber scan_page); +extern void _bt_parallel_done(IndexScanDesc scan); +extern void _bt_parallel_advance_array_keys(IndexScanDesc scan); + +/* + * prototypes for functions in nbtdedup.c + */ +extern void _bt_dedup_pass(Relation rel, Buffer buf, IndexTuple newitem, + Size newitemsz, bool bottomupdedup); +extern bool _bt_bottomupdel_pass(Relation rel, Buffer buf, Relation heapRel, + Size newitemsz); +extern void _bt_dedup_start_pending(BTDedupState state, IndexTuple base, + OffsetNumber baseoff); +extern bool _bt_dedup_save_htid(BTDedupState state, IndexTuple itup); +extern Size _bt_dedup_finish_pending(Page newpage, BTDedupState state); +extern IndexTuple _bt_form_posting(IndexTuple base, ItemPointer htids, + int nhtids); +extern void _bt_update_posting(BTVacuumPosting vacposting); +extern IndexTuple _bt_swap_posting(IndexTuple newitem, IndexTuple oposting, + int postingoff); + +/* + * prototypes for functions in nbtinsert.c + */ +extern bool _bt_doinsert(Relation rel, IndexTuple itup, + IndexUniqueCheck checkUnique, bool indexUnchanged, + Relation heapRel); +extern void _bt_finish_split(Relation rel, Relation heaprel, Buffer lbuf, + BTStack stack); +extern Buffer _bt_getstackbuf(Relation rel, Relation heaprel, BTStack stack, + BlockNumber child); + +/* + * prototypes for functions in nbtsplitloc.c + */ +extern OffsetNumber _bt_findsplitloc(Relation rel, Page origpage, + OffsetNumber newitemoff, Size newitemsz, IndexTuple newitem, + bool *newitemonleft); + +/* + * prototypes for functions in nbtpage.c + */ +extern void _bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level, + bool allequalimage); +extern bool _bt_vacuum_needs_cleanup(Relation rel); +extern void _bt_set_cleanup_info(Relation rel, BlockNumber num_delpages); +extern void _bt_upgrademetapage(Page page); +extern Buffer _bt_getroot(Relation rel, Relation heaprel, int access); +extern Buffer _bt_gettrueroot(Relation rel); +extern int _bt_getrootheight(Relation rel); +extern void _bt_metaversion(Relation rel, bool *heapkeyspace, + bool *allequalimage); +extern void _bt_checkpage(Relation rel, Buffer buf); +extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access); +extern Buffer _bt_allocbuf(Relation rel, Relation heaprel); +extern Buffer _bt_relandgetbuf(Relation rel, Buffer obuf, + BlockNumber blkno, int access); +extern void _bt_relbuf(Relation rel, Buffer buf); +extern void _bt_lockbuf(Relation rel, Buffer buf, int access); +extern void _bt_unlockbuf(Relation rel, Buffer buf); +extern bool _bt_conditionallockbuf(Relation rel, Buffer buf); +extern void _bt_upgradelockbufcleanup(Relation rel, Buffer buf); +extern void _bt_pageinit(Page page, Size size); +extern void _bt_delitems_vacuum(Relation rel, Buffer buf, + OffsetNumber *deletable, int ndeletable, + BTVacuumPosting *updatable, int nupdatable); +extern void _bt_delitems_delete_check(Relation rel, Buffer buf, + Relation heapRel, + TM_IndexDeleteOp *delstate); +extern void _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate); +extern void _bt_pendingfsm_init(Relation rel, BTVacState *vstate, + bool cleanuponly); +extern void _bt_pendingfsm_finalize(Relation rel, BTVacState *vstate); + +/* + * prototypes for functions in nbtsearch.c + */ +extern BTStack _bt_search(Relation rel, Relation heaprel, BTScanInsert key, + Buffer *bufP, int access, Snapshot snapshot); +extern Buffer _bt_moveright(Relation rel, Relation heaprel, BTScanInsert key, + Buffer buf, bool forupdate, BTStack stack, + int access, Snapshot snapshot); +extern OffsetNumber _bt_binsrch_insert(Relation rel, BTInsertState insertstate); +extern int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum); +extern bool _bt_first(IndexScanDesc scan, ScanDirection dir); +extern bool _bt_next(IndexScanDesc scan, ScanDirection dir); +extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost, + Snapshot snapshot); + +/* + * prototypes for functions in nbtutils.c + */ +extern BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup); +extern void _bt_freestack(BTStack stack); +extern void _bt_preprocess_array_keys(IndexScanDesc scan); +extern void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir); +extern bool _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir); +extern void _bt_mark_array_keys(IndexScanDesc scan); +extern void _bt_restore_array_keys(IndexScanDesc scan); +extern void _bt_preprocess_keys(IndexScanDesc scan); +extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, + int tupnatts, ScanDirection dir, bool *continuescan); +extern void _bt_killitems(IndexScanDesc scan); +extern BTCycleId _bt_vacuum_cycleid(Relation rel); +extern BTCycleId _bt_start_vacuum(Relation rel); +extern void _bt_end_vacuum(Relation rel); +extern void _bt_end_vacuum_callback(int code, Datum arg); +extern Size BTreeShmemSize(void); +extern void BTreeShmemInit(void); +extern bytea *btoptions(Datum reloptions, bool validate); +extern bool btproperty(Oid index_oid, int attno, + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); +extern char *btbuildphasename(int64 phasenum); +extern IndexTuple _bt_truncate(Relation rel, IndexTuple lastleft, + IndexTuple firstright, BTScanInsert itup_key); +extern int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, + IndexTuple firstright); +extern bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, + OffsetNumber offnum); +extern void _bt_check_third_page(Relation rel, Relation heap, + bool needheaptidspace, Page page, IndexTuple newtup); +extern bool _bt_allequalimage(Relation rel, bool debugmessage); + +/* + * prototypes for functions in nbtvalidate.c + */ +extern bool btvalidate(Oid opclassoid); +extern void btadjustmembers(Oid opfamilyoid, + Oid opclassoid, + List *operators, + List *functions); + +/* + * prototypes for functions in nbtsort.c + */ +extern IndexBuildResult *btbuild(Relation heap, Relation index, + struct IndexInfo *indexInfo); +extern void _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc); + +#endif /* NBTREE_H */ diff --git a/install/include/postgresql/server/access/nbtxlog.h b/install/include/postgresql/server/access/nbtxlog.h new file mode 100644 index 00000000000..7dd9fd02065 --- /dev/null +++ b/install/include/postgresql/server/access/nbtxlog.h @@ -0,0 +1,367 @@ +/*------------------------------------------------------------------------- + * + * nbtxlog.h + * header file for postgres btree xlog routines + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/nbtxlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef NBTXLOG_H +#define NBTXLOG_H + +#include "access/transam.h" +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/off.h" + +/* + * XLOG records for btree operations + * + * XLOG allows to store some information in high 4 bits of log + * record xl_info field + */ +#define XLOG_BTREE_INSERT_LEAF 0x00 /* add index tuple without split */ +#define XLOG_BTREE_INSERT_UPPER 0x10 /* same, on a non-leaf page */ +#define XLOG_BTREE_INSERT_META 0x20 /* same, plus update metapage */ +#define XLOG_BTREE_SPLIT_L 0x30 /* add index tuple with split */ +#define XLOG_BTREE_SPLIT_R 0x40 /* as above, new item on right */ +#define XLOG_BTREE_INSERT_POST 0x50 /* add index tuple with posting split */ +#define XLOG_BTREE_DEDUP 0x60 /* deduplicate tuples for a page */ +#define XLOG_BTREE_DELETE 0x70 /* delete leaf index tuples for a page */ +#define XLOG_BTREE_UNLINK_PAGE 0x80 /* delete a half-dead page */ +#define XLOG_BTREE_UNLINK_PAGE_META 0x90 /* same, and update metapage */ +#define XLOG_BTREE_NEWROOT 0xA0 /* new root page */ +#define XLOG_BTREE_MARK_PAGE_HALFDEAD 0xB0 /* mark a leaf as half-dead */ +#define XLOG_BTREE_VACUUM 0xC0 /* delete entries on a page during + * vacuum */ +#define XLOG_BTREE_REUSE_PAGE 0xD0 /* old page is about to be reused from + * FSM */ +#define XLOG_BTREE_META_CLEANUP 0xE0 /* update cleanup-related data in the + * metapage */ + +/* + * All that we need to regenerate the meta-data page + */ +typedef struct xl_btree_metadata +{ + uint32 version; + BlockNumber root; + uint32 level; + BlockNumber fastroot; + uint32 fastlevel; + uint32 last_cleanup_num_delpages; + bool allequalimage; +} xl_btree_metadata; + +/* + * This is what we need to know about simple (without split) insert. + * + * This data record is used for INSERT_LEAF, INSERT_UPPER, INSERT_META, and + * INSERT_POST. Note that INSERT_META and INSERT_UPPER implies it's not a + * leaf page, while INSERT_POST and INSERT_LEAF imply that it must be a leaf + * page. + * + * Backup Blk 0: original page + * Backup Blk 1: child's left sibling, if INSERT_UPPER or INSERT_META + * Backup Blk 2: xl_btree_metadata, if INSERT_META + * + * Note: The new tuple is actually the "original" new item in the posting + * list split insert case (i.e. the INSERT_POST case). A split offset for + * the posting list is logged before the original new item. Recovery needs + * both, since it must do an in-place update of the existing posting list + * that was split as an extra step. Also, recovery generates a "final" + * newitem. See _bt_swap_posting() for details on posting list splits. + */ +typedef struct xl_btree_insert +{ + OffsetNumber offnum; + + /* POSTING SPLIT OFFSET FOLLOWS (INSERT_POST case) */ + /* NEW TUPLE ALWAYS FOLLOWS AT THE END */ +} xl_btree_insert; + +#define SizeOfBtreeInsert (offsetof(xl_btree_insert, offnum) + sizeof(OffsetNumber)) + +/* + * On insert with split, we save all the items going into the right sibling + * so that we can restore it completely from the log record. This way takes + * less xlog space than the normal approach, because if we did it standardly, + * XLogInsert would almost always think the right page is new and store its + * whole page image. The left page, however, is handled in the normal + * incremental-update fashion. + * + * Note: XLOG_BTREE_SPLIT_L and XLOG_BTREE_SPLIT_R share this data record. + * There are two variants to indicate whether the inserted tuple went into the + * left or right split page (and thus, whether the new item is stored or not). + * We always log the left page high key because suffix truncation can generate + * a new leaf high key using user-defined code. This is also necessary on + * internal pages, since the firstright item that the left page's high key was + * based on will have been truncated to zero attributes in the right page (the + * separator key is unavailable from the right page). + * + * Backup Blk 0: original page / new left page + * + * The left page's data portion contains the new item, if it's the _L variant. + * _R variant split records generally do not have a newitem (_R variant leaf + * page split records that must deal with a posting list split will include an + * explicit newitem, though it is never used on the right page -- it is + * actually an orignewitem needed to update existing posting list). The new + * high key of the left/original page appears last of all (and must always be + * present). + * + * Page split records that need the REDO routine to deal with a posting list + * split directly will have an explicit newitem, which is actually an + * orignewitem (the newitem as it was before the posting list split, not + * after). A posting list split always has a newitem that comes immediately + * after the posting list being split (which would have overlapped with + * orignewitem prior to split). Usually REDO must deal with posting list + * splits with an _L variant page split record, and usually both the new + * posting list and the final newitem go on the left page (the existing + * posting list will be inserted instead of the old, and the final newitem + * will be inserted next to that). However, _R variant split records will + * include an orignewitem when the split point for the page happens to have a + * lastleft tuple that is also the posting list being split (leaving newitem + * as the page split's firstright tuple). The existence of this corner case + * does not change the basic fact about newitem/orignewitem for the REDO + * routine: it is always state used for the left page alone. (This is why the + * record's postingoff field isn't a reliable indicator of whether or not a + * posting list split occurred during the page split; a non-zero value merely + * indicates that the REDO routine must reconstruct a new posting list tuple + * that is needed for the left page.) + * + * This posting list split handling is equivalent to the xl_btree_insert REDO + * routine's INSERT_POST handling. While the details are more complicated + * here, the concept and goals are exactly the same. See _bt_swap_posting() + * for details on posting list splits. + * + * Backup Blk 1: new right page + * + * The right page's data portion contains the right page's tuples in the form + * used by _bt_restore_page. This includes the new item, if it's the _R + * variant. The right page's tuples also include the right page's high key + * with either variant (moved from the left/original page during the split), + * unless the split happened to be of the rightmost page on its level, where + * there is no high key for new right page. + * + * Backup Blk 2: next block (orig page's rightlink), if any + * Backup Blk 3: child's left sibling, if non-leaf split + */ +typedef struct xl_btree_split +{ + uint32 level; /* tree level of page being split */ + OffsetNumber firstrightoff; /* first origpage item on rightpage */ + OffsetNumber newitemoff; /* new item's offset */ + uint16 postingoff; /* offset inside orig posting tuple */ +} xl_btree_split; + +#define SizeOfBtreeSplit (offsetof(xl_btree_split, postingoff) + sizeof(uint16)) + +/* + * When page is deduplicated, consecutive groups of tuples with equal keys are + * merged together into posting list tuples. + * + * The WAL record represents a deduplication pass for a leaf page. An array + * of BTDedupInterval structs follows. + */ +typedef struct xl_btree_dedup +{ + uint16 nintervals; + + /* DEDUPLICATION INTERVALS FOLLOW */ +} xl_btree_dedup; + +#define SizeOfBtreeDedup (offsetof(xl_btree_dedup, nintervals) + sizeof(uint16)) + +/* + * This is what we need to know about page reuse within btree. This record + * only exists to generate a conflict point for Hot Standby. + * + * Note that we must include a RelFileLocator in the record because we don't + * actually register the buffer with the record. + */ +typedef struct xl_btree_reuse_page +{ + RelFileLocator locator; + BlockNumber block; + FullTransactionId snapshotConflictHorizon; + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ +} xl_btree_reuse_page; + +#define SizeOfBtreeReusePage (offsetof(xl_btree_reuse_page, isCatalogRel) + sizeof(bool)) + +/* + * xl_btree_vacuum and xl_btree_delete records describe deletion of index + * tuples on a leaf page. The former variant is used by VACUUM, while the + * latter variant is used by the ad-hoc deletions that sometimes take place + * when btinsert() is called. + * + * The records are very similar. The only difference is that xl_btree_delete + * have snapshotConflictHorizon/isCatalogRel fields for recovery conflicts. + * (VACUUM operations can just rely on earlier conflicts generated during + * pruning of the table whose TIDs the to-be-deleted index tuples point to. + * There are also small differences between each REDO routine that we don't go + * into here.) + * + * xl_btree_vacuum and xl_btree_delete both represent deletion of any number + * of index tuples on a single leaf page using page offset numbers. Both also + * support "updates" of index tuples, which is how deletes of a subset of TIDs + * contained in an existing posting list tuple are implemented. + * + * Updated posting list tuples are represented using xl_btree_update metadata. + * The REDO routines each use the xl_btree_update entries (plus each + * corresponding original index tuple from the target leaf page) to generate + * the final updated tuple. + * + * Updates are only used when there will be some remaining TIDs left by the + * REDO routine. Otherwise the posting list tuple just gets deleted outright. + */ +typedef struct xl_btree_vacuum +{ + uint16 ndeleted; + uint16 nupdated; + + /*---- + * In payload of blk 0 : + * - DELETED TARGET OFFSET NUMBERS + * - UPDATED TARGET OFFSET NUMBERS + * - UPDATED TUPLES METADATA (xl_btree_update) ITEMS + *---- + */ +} xl_btree_vacuum; + +#define SizeOfBtreeVacuum (offsetof(xl_btree_vacuum, nupdated) + sizeof(uint16)) + +typedef struct xl_btree_delete +{ + TransactionId snapshotConflictHorizon; + uint16 ndeleted; + uint16 nupdated; + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ + + /*---- + * In payload of blk 0 : + * - DELETED TARGET OFFSET NUMBERS + * - UPDATED TARGET OFFSET NUMBERS + * - UPDATED TUPLES METADATA (xl_btree_update) ITEMS + *---- + */ +} xl_btree_delete; + +#define SizeOfBtreeDelete (offsetof(xl_btree_delete, isCatalogRel) + sizeof(bool)) + +/* + * The offsets that appear in xl_btree_update metadata are offsets into the + * original posting list from tuple, not page offset numbers. These are + * 0-based. The page offset number for the original posting list tuple comes + * from the main xl_btree_vacuum/xl_btree_delete record. + */ +typedef struct xl_btree_update +{ + uint16 ndeletedtids; + + /* POSTING LIST uint16 OFFSETS TO A DELETED TID FOLLOW */ +} xl_btree_update; + +#define SizeOfBtreeUpdate (offsetof(xl_btree_update, ndeletedtids) + sizeof(uint16)) + +/* + * This is what we need to know about marking an empty subtree for deletion. + * The target identifies the tuple removed from the parent page (note that we + * remove this tuple's downlink and the *following* tuple's key). Note that + * the leaf page is empty, so we don't need to store its content --- it is + * just reinitialized during recovery using the rest of the fields. + * + * Backup Blk 0: leaf block + * Backup Blk 1: top parent + */ +typedef struct xl_btree_mark_page_halfdead +{ + OffsetNumber poffset; /* deleted tuple id in parent page */ + + /* information needed to recreate the leaf page: */ + BlockNumber leafblk; /* leaf block ultimately being deleted */ + BlockNumber leftblk; /* leaf block's left sibling, if any */ + BlockNumber rightblk; /* leaf block's right sibling */ + BlockNumber topparent; /* topmost internal page in the subtree */ +} xl_btree_mark_page_halfdead; + +#define SizeOfBtreeMarkPageHalfDead (offsetof(xl_btree_mark_page_halfdead, topparent) + sizeof(BlockNumber)) + +/* + * This is what we need to know about deletion of a btree page. Note that we + * only leave behind a small amount of bookkeeping information in deleted + * pages (deleted pages must be kept around as tombstones for a while). It is + * convenient for the REDO routine to regenerate its target page from scratch. + * This is why WAL record describes certain details that are actually directly + * available from the target page. + * + * Backup Blk 0: target block being deleted + * Backup Blk 1: target block's left sibling, if any + * Backup Blk 2: target block's right sibling + * Backup Blk 3: leaf block (if different from target) + * Backup Blk 4: metapage (if rightsib becomes new fast root) + */ +typedef struct xl_btree_unlink_page +{ + BlockNumber leftsib; /* target block's left sibling, if any */ + BlockNumber rightsib; /* target block's right sibling */ + uint32 level; /* target block's level */ + FullTransactionId safexid; /* target block's BTPageSetDeleted() XID */ + + /* + * Information needed to recreate a half-dead leaf page with correct + * topparent link. The fields are only used when deletion operation's + * target page is an internal page. REDO routine creates half-dead page + * from scratch to keep things simple (this is the same convenient + * approach used for the target page itself). + */ + BlockNumber leafleftsib; + BlockNumber leafrightsib; + BlockNumber leaftopparent; /* next child down in the subtree */ + + /* xl_btree_metadata FOLLOWS IF XLOG_BTREE_UNLINK_PAGE_META */ +} xl_btree_unlink_page; + +#define SizeOfBtreeUnlinkPage (offsetof(xl_btree_unlink_page, leaftopparent) + sizeof(BlockNumber)) + +/* + * New root log record. There are zero tuples if this is to establish an + * empty root, or two if it is the result of splitting an old root. + * + * Note that although this implies rewriting the metadata page, we don't need + * an xl_btree_metadata record --- the rootblk and level are sufficient. + * + * Backup Blk 0: new root page (2 tuples as payload, if splitting old root) + * Backup Blk 1: left child (if splitting an old root) + * Backup Blk 2: metapage + */ +typedef struct xl_btree_newroot +{ + BlockNumber rootblk; /* location of new root (redundant with blk 0) */ + uint32 level; /* its tree level */ +} xl_btree_newroot; + +#define SizeOfBtreeNewroot (offsetof(xl_btree_newroot, level) + sizeof(uint32)) + + +/* + * prototypes for functions in nbtxlog.c + */ +extern void btree_redo(XLogReaderState *record); +extern void btree_xlog_startup(void); +extern void btree_xlog_cleanup(void); +extern void btree_mask(char *pagedata, BlockNumber blkno); + +/* + * prototypes for functions in nbtdesc.c + */ +extern void btree_desc(StringInfo buf, XLogReaderState *record); +extern const char *btree_identify(uint8 info); + +#endif /* NBTXLOG_H */ diff --git a/install/include/postgresql/server/access/parallel.h b/install/include/postgresql/server/access/parallel.h new file mode 100644 index 00000000000..061f8a4c4ca --- /dev/null +++ b/install/include/postgresql/server/access/parallel.h @@ -0,0 +1,82 @@ +/*------------------------------------------------------------------------- + * + * parallel.h + * Infrastructure for launching parallel workers + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/parallel.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PARALLEL_H +#define PARALLEL_H + +#include "access/xlogdefs.h" +#include "lib/ilist.h" +#include "postmaster/bgworker.h" +#include "storage/shm_mq.h" +#include "storage/shm_toc.h" + +typedef void (*parallel_worker_main_type) (dsm_segment *seg, shm_toc *toc); + +typedef struct ParallelWorkerInfo +{ + BackgroundWorkerHandle *bgwhandle; + shm_mq_handle *error_mqh; + int32 pid; +} ParallelWorkerInfo; + +typedef struct ParallelContext +{ + dlist_node node; + SubTransactionId subid; + int nworkers; /* Maximum number of workers to launch */ + int nworkers_to_launch; /* Actual number of workers to launch */ + int nworkers_launched; + char *library_name; + char *function_name; + ErrorContextCallback *error_context_stack; + shm_toc_estimator estimator; + dsm_segment *seg; + void *private_memory; + shm_toc *toc; + ParallelWorkerInfo *worker; + int nknown_attached_workers; + bool *known_attached_workers; +} ParallelContext; + +typedef struct ParallelWorkerContext +{ + dsm_segment *seg; + shm_toc *toc; +} ParallelWorkerContext; + +extern PGDLLIMPORT volatile sig_atomic_t ParallelMessagePending; +extern PGDLLIMPORT int ParallelWorkerNumber; +extern PGDLLIMPORT bool InitializingParallelWorker; + +#define IsParallelWorker() (ParallelWorkerNumber >= 0) + +extern ParallelContext *CreateParallelContext(const char *library_name, + const char *function_name, int nworkers); +extern void InitializeParallelDSM(ParallelContext *pcxt); +extern void ReinitializeParallelDSM(ParallelContext *pcxt); +extern void ReinitializeParallelWorkers(ParallelContext *pcxt, int nworkers_to_launch); +extern void LaunchParallelWorkers(ParallelContext *pcxt); +extern void WaitForParallelWorkersToAttach(ParallelContext *pcxt); +extern void WaitForParallelWorkersToFinish(ParallelContext *pcxt); +extern void DestroyParallelContext(ParallelContext *pcxt); +extern bool ParallelContextActive(void); + +extern void HandleParallelMessageInterrupt(void); +extern void HandleParallelMessages(void); +extern void AtEOXact_Parallel(bool isCommit); +extern void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId); +extern void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end); + +extern void ParallelWorkerMain(Datum main_arg); + +#endif /* PARALLEL_H */ diff --git a/install/include/postgresql/server/access/printsimple.h b/install/include/postgresql/server/access/printsimple.h new file mode 100644 index 00000000000..9883e72282b --- /dev/null +++ b/install/include/postgresql/server/access/printsimple.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * printsimple.h + * print simple tuples without catalog access + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/printsimple.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PRINTSIMPLE_H +#define PRINTSIMPLE_H + +#include "tcop/dest.h" + +extern bool printsimple(TupleTableSlot *slot, DestReceiver *self); +extern void printsimple_startup(DestReceiver *self, int operation, + TupleDesc tupdesc); + +#endif /* PRINTSIMPLE_H */ diff --git a/install/include/postgresql/server/access/printtup.h b/install/include/postgresql/server/access/printtup.h new file mode 100644 index 00000000000..747ecb800dc --- /dev/null +++ b/install/include/postgresql/server/access/printtup.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * printtup.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/printtup.h + * + *------------------------------------------------------------------------- + */ +#ifndef PRINTTUP_H +#define PRINTTUP_H + +#include "utils/portal.h" + +extern DestReceiver *printtup_create_DR(CommandDest dest); + +extern void SetRemoteDestReceiverParams(DestReceiver *self, Portal portal); + +extern void SendRowDescriptionMessage(StringInfo buf, + TupleDesc typeinfo, List *targetlist, int16 *formats); + +extern void debugStartup(DestReceiver *self, int operation, + TupleDesc typeinfo); +extern bool debugtup(TupleTableSlot *slot, DestReceiver *self); + +/* XXX these are really in executor/spi.c */ +extern void spi_dest_startup(DestReceiver *self, int operation, + TupleDesc typeinfo); +extern bool spi_printtup(TupleTableSlot *slot, DestReceiver *self); + +#endif /* PRINTTUP_H */ diff --git a/install/include/postgresql/server/access/relation.h b/install/include/postgresql/server/access/relation.h new file mode 100644 index 00000000000..66efd367046 --- /dev/null +++ b/install/include/postgresql/server/access/relation.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * relation.h + * Generic relation related routines. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/relation.h + * + *------------------------------------------------------------------------- + */ +#ifndef ACCESS_RELATION_H +#define ACCESS_RELATION_H + +#include "nodes/primnodes.h" +#include "storage/lockdefs.h" +#include "utils/relcache.h" + +extern Relation relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation try_relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation relation_openrv_extended(const RangeVar *relation, + LOCKMODE lockmode, bool missing_ok); +extern void relation_close(Relation relation, LOCKMODE lockmode); + +#endif /* ACCESS_RELATION_H */ diff --git a/install/include/postgresql/server/access/reloptions.h b/install/include/postgresql/server/access/reloptions.h new file mode 100644 index 00000000000..1d5bfa62ffc --- /dev/null +++ b/install/include/postgresql/server/access/reloptions.h @@ -0,0 +1,247 @@ +/*------------------------------------------------------------------------- + * + * reloptions.h + * Core support for relation and tablespace options (pg_class.reloptions + * and pg_tablespace.spcoptions) + * + * Note: the functions dealing with text-array reloptions values declare + * them as Datum, not ArrayType *, to avoid needing to include array.h + * into a lot of low-level code. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/reloptions.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELOPTIONS_H +#define RELOPTIONS_H + +#include "access/amapi.h" +#include "access/htup.h" +#include "access/tupdesc.h" +#include "nodes/pg_list.h" +#include "storage/lock.h" + +/* types supported by reloptions */ +typedef enum relopt_type +{ + RELOPT_TYPE_BOOL, + RELOPT_TYPE_INT, + RELOPT_TYPE_REAL, + RELOPT_TYPE_ENUM, + RELOPT_TYPE_STRING +} relopt_type; + +/* kinds supported by reloptions */ +typedef enum relopt_kind +{ + RELOPT_KIND_LOCAL = 0, + RELOPT_KIND_HEAP = (1 << 0), + RELOPT_KIND_TOAST = (1 << 1), + RELOPT_KIND_BTREE = (1 << 2), + RELOPT_KIND_HASH = (1 << 3), + RELOPT_KIND_GIN = (1 << 4), + RELOPT_KIND_GIST = (1 << 5), + RELOPT_KIND_ATTRIBUTE = (1 << 6), + RELOPT_KIND_TABLESPACE = (1 << 7), + RELOPT_KIND_SPGIST = (1 << 8), + RELOPT_KIND_VIEW = (1 << 9), + RELOPT_KIND_BRIN = (1 << 10), + RELOPT_KIND_PARTITIONED = (1 << 11), + /* if you add a new kind, make sure you update "last_default" too */ + RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, + /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ + RELOPT_KIND_MAX = (1 << 30) +} relopt_kind; + +/* reloption namespaces allowed for heaps -- currently only TOAST */ +#define HEAP_RELOPT_NAMESPACES { "toast", NULL } + +/* generic struct to hold shared data */ +typedef struct relopt_gen +{ + const char *name; /* must be first (used as list termination + * marker) */ + const char *desc; + bits32 kinds; + LOCKMODE lockmode; + int namelen; + relopt_type type; +} relopt_gen; + +/* holds a parsed value */ +typedef struct relopt_value +{ + relopt_gen *gen; + bool isset; + union + { + bool bool_val; + int int_val; + double real_val; + int enum_val; + char *string_val; /* allocated separately */ + } values; +} relopt_value; + +/* reloptions records for specific variable types */ +typedef struct relopt_bool +{ + relopt_gen gen; + bool default_val; +} relopt_bool; + +typedef struct relopt_int +{ + relopt_gen gen; + int default_val; + int min; + int max; +} relopt_int; + +typedef struct relopt_real +{ + relopt_gen gen; + double default_val; + double min; + double max; +} relopt_real; + +/* + * relopt_enum_elt_def -- One member of the array of acceptable values + * of an enum reloption. + */ +typedef struct relopt_enum_elt_def +{ + const char *string_val; + int symbol_val; +} relopt_enum_elt_def; + +typedef struct relopt_enum +{ + relopt_gen gen; + relopt_enum_elt_def *members; + int default_val; + const char *detailmsg; + /* null-terminated array of members */ +} relopt_enum; + +/* validation routines for strings */ +typedef void (*validate_string_relopt) (const char *value); +typedef Size (*fill_string_relopt) (const char *value, void *ptr); + +/* validation routine for the whole option set */ +typedef void (*relopts_validator) (void *parsed_options, relopt_value *vals, int nvals); + +typedef struct relopt_string +{ + relopt_gen gen; + int default_len; + bool default_isnull; + validate_string_relopt validate_cb; + fill_string_relopt fill_cb; + char *default_val; +} relopt_string; + +/* This is the table datatype for build_reloptions() */ +typedef struct +{ + const char *optname; /* option's name */ + relopt_type opttype; /* option's datatype */ + int offset; /* offset of field in result struct */ +} relopt_parse_elt; + +/* Local reloption definition */ +typedef struct local_relopt +{ + relopt_gen *option; /* option definition */ + int offset; /* offset of parsed value in bytea structure */ +} local_relopt; + +/* Structure to hold local reloption data for build_local_reloptions() */ +typedef struct local_relopts +{ + List *options; /* list of local_relopt definitions */ + List *validators; /* list of relopts_validator callbacks */ + Size relopt_struct_size; /* size of parsed bytea structure */ +} local_relopts; + +/* + * Utility macro to get a value for a string reloption once the options + * are parsed. This gets a pointer to the string value itself. "optstruct" + * is the StdRdOptions struct or equivalent, "member" is the struct member + * corresponding to the string option. + */ +#define GET_STRING_RELOPTION(optstruct, member) \ + ((optstruct)->member == 0 ? NULL : \ + (char *)(optstruct) + (optstruct)->member) + +extern relopt_kind add_reloption_kind(void); +extern void add_bool_reloption(bits32 kinds, const char *name, const char *desc, + bool default_val, LOCKMODE lockmode); +extern void add_int_reloption(bits32 kinds, const char *name, const char *desc, + int default_val, int min_val, int max_val, + LOCKMODE lockmode); +extern void add_real_reloption(bits32 kinds, const char *name, const char *desc, + double default_val, double min_val, double max_val, + LOCKMODE lockmode); +extern void add_enum_reloption(bits32 kinds, const char *name, const char *desc, + relopt_enum_elt_def *members, int default_val, + const char *detailmsg, LOCKMODE lockmode); +extern void add_string_reloption(bits32 kinds, const char *name, const char *desc, + const char *default_val, validate_string_relopt validator, + LOCKMODE lockmode); + +extern void init_local_reloptions(local_relopts *relopts, Size relopt_struct_size); +extern void register_reloptions_validator(local_relopts *relopts, + relopts_validator validator); +extern void add_local_bool_reloption(local_relopts *relopts, const char *name, + const char *desc, bool default_val, + int offset); +extern void add_local_int_reloption(local_relopts *relopts, const char *name, + const char *desc, int default_val, + int min_val, int max_val, int offset); +extern void add_local_real_reloption(local_relopts *relopts, const char *name, + const char *desc, double default_val, + double min_val, double max_val, + int offset); +extern void add_local_enum_reloption(local_relopts *relopts, + const char *name, const char *desc, + relopt_enum_elt_def *members, + int default_val, const char *detailmsg, + int offset); +extern void add_local_string_reloption(local_relopts *relopts, const char *name, + const char *desc, + const char *default_val, + validate_string_relopt validator, + fill_string_relopt filler, int offset); + +extern Datum transformRelOptions(Datum oldOptions, List *defList, + const char *namspace, char *validnsps[], + bool acceptOidsOff, bool isReset); +extern List *untransformRelOptions(Datum options); +extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, + amoptions_function amoptions); +extern void *build_reloptions(Datum reloptions, bool validate, + relopt_kind kind, + Size relopt_struct_size, + const relopt_parse_elt *relopt_elems, + int num_relopt_elems); +extern void *build_local_reloptions(local_relopts *relopts, Datum options, + bool validate); + +extern bytea *default_reloptions(Datum reloptions, bool validate, + relopt_kind kind); +extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate); +extern bytea *view_reloptions(Datum reloptions, bool validate); +extern bytea *partitioned_table_reloptions(Datum reloptions, bool validate); +extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions, + bool validate); +extern bytea *attribute_reloptions(Datum reloptions, bool validate); +extern bytea *tablespace_reloptions(Datum reloptions, bool validate); +extern LOCKMODE AlterTableGetRelOptionsLockLevel(List *defList); + +#endif /* RELOPTIONS_H */ diff --git a/install/include/postgresql/server/access/relscan.h b/install/include/postgresql/server/access/relscan.h new file mode 100644 index 00000000000..d03360eac04 --- /dev/null +++ b/install/include/postgresql/server/access/relscan.h @@ -0,0 +1,191 @@ +/*------------------------------------------------------------------------- + * + * relscan.h + * POSTGRES relation scan descriptor definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/relscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELSCAN_H +#define RELSCAN_H + +#include "access/htup_details.h" +#include "access/itup.h" +#include "port/atomics.h" +#include "storage/buf.h" +#include "storage/spin.h" +#include "utils/relcache.h" + + +struct ParallelTableScanDescData; + +/* + * Generic descriptor for table scans. This is the base-class for table scans, + * which needs to be embedded in the scans of individual AMs. + */ +typedef struct TableScanDescData +{ + /* scan parameters */ + Relation rs_rd; /* heap relation descriptor */ + struct SnapshotData *rs_snapshot; /* snapshot to see */ + int rs_nkeys; /* number of scan keys */ + struct ScanKeyData *rs_key; /* array of scan key descriptors */ + + /* Range of ItemPointers for table_scan_getnextslot_tidrange() to scan. */ + ItemPointerData rs_mintid; + ItemPointerData rs_maxtid; + + /* + * Information about type and behaviour of the scan, a bitmask of members + * of the ScanOptions enum (see tableam.h). + */ + uint32 rs_flags; + + struct ParallelTableScanDescData *rs_parallel; /* parallel scan + * information */ +} TableScanDescData; +typedef struct TableScanDescData *TableScanDesc; + +/* + * Shared state for parallel table scan. + * + * Each backend participating in a parallel table scan has its own + * TableScanDesc in backend-private memory, and those objects all contain a + * pointer to this structure. The information here must be sufficient to + * properly initialize each new TableScanDesc as workers join the scan, and it + * must act as a information what to scan for those workers. + */ +typedef struct ParallelTableScanDescData +{ + Oid phs_relid; /* OID of relation to scan */ + bool phs_syncscan; /* report location to syncscan logic? */ + bool phs_snapshot_any; /* SnapshotAny, not phs_snapshot_data? */ + Size phs_snapshot_off; /* data for snapshot */ +} ParallelTableScanDescData; +typedef struct ParallelTableScanDescData *ParallelTableScanDesc; + +/* + * Shared state for parallel table scans, for block oriented storage. + */ +typedef struct ParallelBlockTableScanDescData +{ + ParallelTableScanDescData base; + + BlockNumber phs_nblocks; /* # blocks in relation at start of scan */ + slock_t phs_mutex; /* mutual exclusion for setting startblock */ + BlockNumber phs_startblock; /* starting block number */ + pg_atomic_uint64 phs_nallocated; /* number of blocks allocated to + * workers so far. */ +} ParallelBlockTableScanDescData; +typedef struct ParallelBlockTableScanDescData *ParallelBlockTableScanDesc; + +/* + * Per backend state for parallel table scan, for block-oriented storage. + */ +typedef struct ParallelBlockTableScanWorkerData +{ + uint64 phsw_nallocated; /* Current # of blocks into the scan */ + uint32 phsw_chunk_remaining; /* # blocks left in this chunk */ + uint32 phsw_chunk_size; /* The number of blocks to allocate in + * each I/O chunk for the scan */ +} ParallelBlockTableScanWorkerData; +typedef struct ParallelBlockTableScanWorkerData *ParallelBlockTableScanWorker; + +/* + * Base class for fetches from a table via an index. This is the base-class + * for such scans, which needs to be embedded in the respective struct for + * individual AMs. + */ +typedef struct IndexFetchTableData +{ + Relation rel; +} IndexFetchTableData; + +/* + * We use the same IndexScanDescData structure for both amgettuple-based + * and amgetbitmap-based index scans. Some fields are only relevant in + * amgettuple-based scans. + */ +typedef struct IndexScanDescData +{ + /* scan parameters */ + Relation heapRelation; /* heap relation descriptor, or NULL */ + Relation indexRelation; /* index relation descriptor */ + struct SnapshotData *xs_snapshot; /* snapshot to see */ + int numberOfKeys; /* number of index qualifier conditions */ + int numberOfOrderBys; /* number of ordering operators */ + struct ScanKeyData *keyData; /* array of index qualifier descriptors */ + struct ScanKeyData *orderByData; /* array of ordering op descriptors */ + bool xs_want_itup; /* caller requests index tuples */ + bool xs_temp_snap; /* unregister snapshot at scan end? */ + + /* signaling to index AM about killing index tuples */ + bool kill_prior_tuple; /* last-returned tuple is dead */ + bool ignore_killed_tuples; /* do not return killed entries */ + bool xactStartedInRecovery; /* prevents killing/seeing killed + * tuples */ + + /* index access method's private state */ + void *opaque; /* access-method-specific info */ + + /* + * In an index-only scan, a successful amgettuple call must fill either + * xs_itup (and xs_itupdesc) or xs_hitup (and xs_hitupdesc) to provide the + * data returned by the scan. It can fill both, in which case the heap + * format will be used. + */ + IndexTuple xs_itup; /* index tuple returned by AM */ + struct TupleDescData *xs_itupdesc; /* rowtype descriptor of xs_itup */ + HeapTuple xs_hitup; /* index data returned by AM, as HeapTuple */ + struct TupleDescData *xs_hitupdesc; /* rowtype descriptor of xs_hitup */ + + ItemPointerData xs_heaptid; /* result */ + bool xs_heap_continue; /* T if must keep walking, potential + * further results */ + IndexFetchTableData *xs_heapfetch; + + bool xs_recheck; /* T means scan keys must be rechecked */ + + /* + * When fetching with an ordering operator, the values of the ORDER BY + * expressions of the last returned tuple, according to the index. If + * xs_recheckorderby is true, these need to be rechecked just like the + * scan keys, and the values returned here are a lower-bound on the actual + * values. + */ + Datum *xs_orderbyvals; + bool *xs_orderbynulls; + bool xs_recheckorderby; + + /* parallel index scan information, in shared memory */ + struct ParallelIndexScanDescData *parallel_scan; +} IndexScanDescData; + +/* Generic structure for parallel scans */ +typedef struct ParallelIndexScanDescData +{ + Oid ps_relid; + Oid ps_indexid; + Size ps_offset; /* Offset in bytes of am specific structure */ + char ps_snapshot_data[FLEXIBLE_ARRAY_MEMBER]; +} ParallelIndexScanDescData; + +struct TupleTableSlot; + +/* Struct for storage-or-index scans of system tables */ +typedef struct SysScanDescData +{ + Relation heap_rel; /* catalog being scanned */ + Relation irel; /* NULL if doing heap scan */ + struct TableScanDescData *scan; /* only valid in storage-scan case */ + struct IndexScanDescData *iscan; /* only valid in index-scan case */ + struct SnapshotData *snapshot; /* snapshot to unregister at end of scan */ + struct TupleTableSlot *slot; +} SysScanDescData; + +#endif /* RELSCAN_H */ diff --git a/install/include/postgresql/server/access/rewriteheap.h b/install/include/postgresql/server/access/rewriteheap.h new file mode 100644 index 00000000000..1125457053c --- /dev/null +++ b/install/include/postgresql/server/access/rewriteheap.h @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------- + * + * rewriteheap.h + * Declarations for heap rewrite support functions + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994-5, Regents of the University of California + * + * src/include/access/rewriteheap.h + * + *------------------------------------------------------------------------- + */ +#ifndef REWRITE_HEAP_H +#define REWRITE_HEAP_H + +#include "access/htup.h" +#include "storage/itemptr.h" +#include "storage/relfilelocator.h" +#include "utils/relcache.h" + +/* struct definition is private to rewriteheap.c */ +typedef struct RewriteStateData *RewriteState; + +extern RewriteState begin_heap_rewrite(Relation old_heap, Relation new_heap, + TransactionId oldest_xmin, TransactionId freeze_xid, + MultiXactId cutoff_multi); +extern void end_heap_rewrite(RewriteState state); +extern void rewrite_heap_tuple(RewriteState state, HeapTuple old_tuple, + HeapTuple new_tuple); +extern bool rewrite_heap_dead_tuple(RewriteState state, HeapTuple old_tuple); + +/* + * On-Disk data format for an individual logical rewrite mapping. + */ +typedef struct LogicalRewriteMappingData +{ + RelFileLocator old_locator; + RelFileLocator new_locator; + ItemPointerData old_tid; + ItemPointerData new_tid; +} LogicalRewriteMappingData; + +/* --- + * The filename consists of the following, dash separated, + * components: + * 1) database oid or InvalidOid for shared relations + * 2) the oid of the relation + * 3) upper 32bit of the LSN at which a rewrite started + * 4) lower 32bit of the LSN at which a rewrite started + * 5) xid we are mapping for + * 6) xid of the xact performing the mapping + * --- + */ +#define LOGICAL_REWRITE_FORMAT "map-%x-%x-%X_%X-%x-%x" +extern void CheckPointLogicalRewriteHeap(void); + +#endif /* REWRITE_HEAP_H */ diff --git a/install/include/postgresql/server/access/rmgr.h b/install/include/postgresql/server/access/rmgr.h new file mode 100644 index 00000000000..3b6a497e1b4 --- /dev/null +++ b/install/include/postgresql/server/access/rmgr.h @@ -0,0 +1,62 @@ +/* + * rmgr.h + * + * Resource managers definition + * + * src/include/access/rmgr.h + */ +#ifndef RMGR_H +#define RMGR_H + +typedef uint8 RmgrId; + +/* + * Built-in resource managers + * + * The actual numerical values for each rmgr ID are defined by the order + * of entries in rmgrlist.h. + * + * Note: RM_MAX_ID must fit in RmgrId; widening that type will affect the XLOG + * file format. + */ +#define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup,mask,decode) \ + symname, + +typedef enum RmgrIds +{ +#include "access/rmgrlist.h" + RM_NEXT_ID +} RmgrIds; + +#undef PG_RMGR + +#define RM_MAX_ID UINT8_MAX +#define RM_MAX_BUILTIN_ID (RM_NEXT_ID - 1) +#define RM_MIN_CUSTOM_ID 128 +#define RM_MAX_CUSTOM_ID UINT8_MAX +#define RM_N_IDS (UINT8_MAX + 1) +#define RM_N_BUILTIN_IDS (RM_MAX_BUILTIN_ID + 1) +#define RM_N_CUSTOM_IDS (RM_MAX_CUSTOM_ID - RM_MIN_CUSTOM_ID + 1) + +static inline bool +RmgrIdIsBuiltin(int rmid) +{ + return rmid <= RM_MAX_BUILTIN_ID; +} + +static inline bool +RmgrIdIsCustom(int rmid) +{ + return rmid >= RM_MIN_CUSTOM_ID && rmid <= RM_MAX_CUSTOM_ID; +} + +#define RmgrIdIsValid(rmid) (RmgrIdIsBuiltin((rmid)) || RmgrIdIsCustom((rmid))) + +/* + * RmgrId to use for extensions that require an RmgrId, but are still in + * development and have not reserved their own unique RmgrId yet. See: + * https://wiki.postgresql.org/wiki/CustomWALResourceManagers + */ +#define RM_EXPERIMENTAL_ID 128 + +#endif /* RMGR_H */ diff --git a/install/include/postgresql/server/access/rmgrdesc_utils.h b/install/include/postgresql/server/access/rmgrdesc_utils.h new file mode 100644 index 00000000000..bd414699f21 --- /dev/null +++ b/install/include/postgresql/server/access/rmgrdesc_utils.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------- + * + * rmgrdesc_utils.h + * Support functions for rmgrdesc routines + * + * Copyright (c) 2023, PostgreSQL Global Development Group + * + * src/include/access/rmgrdesc_utils.h + * + *------------------------------------------------------------------------- + */ +#ifndef RMGRDESC_UTILS_H_ +#define RMGRDESC_UTILS_H_ + +/* + * Guidelines for rmgrdesc routine authors: + * + * The goal of these guidelines is to avoid gratuitous inconsistencies across + * each rmgr, and to allow users to parse desc output strings without too much + * difficulty. This is not an API specification or an interchange format. + * (Only heapam and nbtree desc routines follow these guidelines at present, + * in any case.) + * + * Record descriptions are similar to JSON style key/value objects. However, + * there is no explicit "string" type/string escaping. Top-level { } brackets + * should be omitted. For example: + * + * snapshotConflictHorizon: 0, flags: 0x03 + * + * Record descriptions may contain variable-length arrays. For example: + * + * nunused: 5, unused: [1, 2, 3, 4, 5] + * + * Nested objects are supported via { } brackets. They generally appear + * inside variable-length arrays. For example: + * + * ndeleted: 0, nupdated: 1, deleted: [], updated: [{ off: 45, nptids: 1, ptids: [0] }] + * + * Try to output things in an order that faithfully represents the order of + * fields from the underlying physical WAL record struct. Key names should be + * unique (at the same nesting level) to make parsing easy. It's a good idea + * if the number of items in the array appears before the array. + * + * It's okay for individual WAL record types to invent their own conventions. + * For example, Heap2's PRUNE record descriptions use a custom array format + * for the record's "redirected" field: + * + * ... redirected: [1->4, 5->9], dead: [10, 11], unused: [3, 7, 8] + * + * Arguably the desc routine should be using object notation for this instead. + * However, there is value in using a custom format when it conveys useful + * information about the underlying physical data structures. + * + * This ad-hoc format has the advantage of being close to the format used for + * the "dead" and "unused" arrays (which follow the standard desc convention + * for page offset number arrays). It suggests that the "redirected" elements + * shown are just pairs of page offset numbers (which is how it really works). + */ +extern void array_desc(StringInfo buf, void *array, size_t elem_size, int count, + void (*elem_desc) (StringInfo buf, void *elem, void *data), + void *data); +extern void offset_elem_desc(StringInfo buf, void *offset, void *data); +extern void redirect_elem_desc(StringInfo buf, void *offset, void *data); +extern void oid_elem_desc(StringInfo buf, void *relid, void *data); + +#endif /* RMGRDESC_UTILS_H_ */ diff --git a/install/include/postgresql/server/access/rmgrlist.h b/install/include/postgresql/server/access/rmgrlist.h new file mode 100644 index 00000000000..fed680e939d --- /dev/null +++ b/install/include/postgresql/server/access/rmgrlist.h @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------- + * rmgrlist.h + * + * The resource manager list is kept in its own source file for possible + * use by automatic tools. The exact representation of a rmgr is determined + * by the PG_RMGR macro, which is not defined in this file; it can be + * defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/rmgrlist.h + *--------------------------------------------------------------------------- + * + * PGRAC MODIFICATIONS (Nth, stage 1.22): + * Modified by: SqlRush + * + * What changed: When USE_PGRAC_CLUSTER is defined, register a new + * built-in resource manager RM_CLUSTER_UNDO_ID with + * cluster_undo_redo / cluster_undo_desc / + * cluster_undo_identify (defined in + * src/backend/cluster/storage/cluster_undo_xlog.c). + * Why: Stage 1.22 ships dedicated undo tablespace + atomic + * batch on-disk format change (spec-1.22 Q-7 ★ B-LITE + * REVISED). The XLOG_FPI alternative depends on PG's + * WAL block tag (RelFileLocator/ForkNumber/BlockNumber) + * routing, which is incompatible with $PGDATA/pg_undo/ + * instance_N/seg_M.dat self-managed paths. A narrow + * custom RM with one subtype (XLOG_UNDO_SEGMENT_INIT) + * carries the page image directly; redo handler pwrites + * the file bypassing buffer manager + smgr. + * feature-117 / feature-120 add additional subtypes + * to this same RM (retention / recycling / TT slot + * binding / commit_scn write) without breaking the + * 1.22 ABI. + * See specs/spec-1.22-undo-tablespace-bootstrap.md + * §D14a, src/backend/cluster/storage/cluster_undo_xlog.c. + *--------------------------------------------------------------------------- + */ + +/* there is deliberately not an #ifndef RMGRLIST_H here */ + +/* + * List of resource manager entries. Note that order of entries defines the + * numerical values of each rmgr's ID, which is stored in WAL records. New + * entries should be added at the end, to avoid changing IDs of existing + * entries. + * + * Changes to this list possibly need an XLOG_PAGE_MAGIC bump. + */ + +/* symbol name, textual name, redo, desc, identify, startup, cleanup, mask, decode */ +PG_RMGR(RM_XLOG_ID, "XLOG", xlog_redo, xlog_desc, xlog_identify, NULL, NULL, NULL, xlog_decode) +PG_RMGR(RM_XACT_ID, "Transaction", xact_redo, xact_desc, xact_identify, NULL, NULL, NULL, xact_decode) +PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, smgr_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_CLOG_ID, "CLOG", clog_redo, clog_desc, clog_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_DBASE_ID, "Database", dbase_redo, dbase_desc, dbase_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_TBLSPC_ID, "Tablespace", tblspc_redo, tblspc_desc, tblspc_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_MULTIXACT_ID, "MultiXact", multixact_redo, multixact_desc, multixact_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_RELMAP_ID, "RelMap", relmap_redo, relmap_desc, relmap_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_STANDBY_ID, "Standby", standby_redo, standby_desc, standby_identify, NULL, NULL, NULL, standby_decode) +PG_RMGR(RM_HEAP2_ID, "Heap2", heap2_redo, heap2_desc, heap2_identify, NULL, NULL, heap_mask, heap2_decode) +PG_RMGR(RM_HEAP_ID, "Heap", heap_redo, heap_desc, heap_identify, NULL, NULL, heap_mask, heap_decode) +PG_RMGR(RM_BTREE_ID, "Btree", btree_redo, btree_desc, btree_identify, btree_xlog_startup, btree_xlog_cleanup, btree_mask, NULL) +PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, hash_identify, NULL, NULL, hash_mask, NULL) +PG_RMGR(RM_GIN_ID, "Gin", gin_redo, gin_desc, gin_identify, gin_xlog_startup, gin_xlog_cleanup, gin_mask, NULL) +PG_RMGR(RM_GIST_ID, "Gist", gist_redo, gist_desc, gist_identify, gist_xlog_startup, gist_xlog_cleanup, gist_mask, NULL) +PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, seq_identify, NULL, NULL, seq_mask, NULL) +PG_RMGR(RM_SPGIST_ID, "SPGist", spg_redo, spg_desc, spg_identify, spg_xlog_startup, spg_xlog_cleanup, spg_mask, NULL) +PG_RMGR(RM_BRIN_ID, "BRIN", brin_redo, brin_desc, brin_identify, NULL, NULL, brin_mask, NULL) +PG_RMGR(RM_COMMIT_TS_ID, "CommitTs", commit_ts_redo, commit_ts_desc, commit_ts_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_REPLORIGIN_ID, "ReplicationOrigin", replorigin_redo, replorigin_desc, replorigin_identify, NULL, NULL, NULL, NULL) +PG_RMGR(RM_GENERIC_ID, "Generic", generic_redo, generic_desc, generic_identify, NULL, NULL, generic_mask, NULL) +PG_RMGR(RM_LOGICALMSG_ID, "LogicalMessage", logicalmsg_redo, logicalmsg_desc, logicalmsg_identify, NULL, NULL, NULL, logicalmsg_decode) +#ifdef USE_PGRAC_CLUSTER +/* PGRAC stage 1.22: see banner above + spec-1.22 §D14a. */ +PG_RMGR(RM_CLUSTER_UNDO_ID, "ClusterUndo", cluster_undo_redo, cluster_undo_desc, cluster_undo_identify, NULL, NULL, NULL, NULL) +#endif diff --git a/install/include/postgresql/server/access/sdir.h b/install/include/postgresql/server/access/sdir.h new file mode 100644 index 00000000000..322aeb3ff9d --- /dev/null +++ b/install/include/postgresql/server/access/sdir.h @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------- + * + * sdir.h + * POSTGRES scan direction definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/sdir.h + * + *------------------------------------------------------------------------- + */ +#ifndef SDIR_H +#define SDIR_H + + +/* + * Defines the direction for scanning a table or an index. Scans are never + * invoked using NoMovementScanDirectionScans. For convenience, we use the + * values -1 and 1 for backward and forward scans. This allows us to perform + * a few mathematical tricks such as what is done in ScanDirectionCombine. + */ +typedef enum ScanDirection +{ + BackwardScanDirection = -1, + NoMovementScanDirection = 0, + ForwardScanDirection = 1 +} ScanDirection; + +/* + * Determine the net effect of two direction specifications. + * This relies on having ForwardScanDirection = +1, BackwardScanDirection = -1, + * and will probably not do what you want if applied to any other values. + */ +#define ScanDirectionCombine(a, b) ((a) * (b)) + +/* + * ScanDirectionIsValid + * True iff scan direction is valid. + */ +#define ScanDirectionIsValid(direction) \ + ((bool) (BackwardScanDirection <= (direction) && \ + (direction) <= ForwardScanDirection)) + +/* + * ScanDirectionIsBackward + * True iff scan direction is backward. + */ +#define ScanDirectionIsBackward(direction) \ + ((bool) ((direction) == BackwardScanDirection)) + +/* + * ScanDirectionIsNoMovement + * True iff scan direction indicates no movement. + */ +#define ScanDirectionIsNoMovement(direction) \ + ((bool) ((direction) == NoMovementScanDirection)) + +/* + * ScanDirectionIsForward + * True iff scan direction is forward. + */ +#define ScanDirectionIsForward(direction) \ + ((bool) ((direction) == ForwardScanDirection)) + +#endif /* SDIR_H */ diff --git a/install/include/postgresql/server/access/session.h b/install/include/postgresql/server/access/session.h new file mode 100644 index 00000000000..f905fe446e8 --- /dev/null +++ b/install/include/postgresql/server/access/session.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * session.h + * Encapsulation of user session. + * + * Copyright (c) 2017-2023, PostgreSQL Global Development Group + * + * src/include/access/session.h + * + *------------------------------------------------------------------------- + */ +#ifndef SESSION_H +#define SESSION_H + +#include "lib/dshash.h" + +/* Avoid including typcache.h */ +struct SharedRecordTypmodRegistry; + +/* + * A struct encapsulating some elements of a user's session. For now this + * manages state that applies to parallel query, but in principle it could + * include other things that are currently global variables. + */ +typedef struct Session +{ + dsm_segment *segment; /* The session-scoped DSM segment. */ + dsa_area *area; /* The session-scoped DSA area. */ + + /* State managed by typcache.c. */ + struct SharedRecordTypmodRegistry *shared_typmod_registry; + dshash_table *shared_record_table; + dshash_table *shared_typmod_table; +} Session; + +extern void InitializeSession(void); +extern dsm_handle GetSessionDsmHandle(void); +extern void AttachSession(dsm_handle handle); +extern void DetachSession(void); + +/* The current session, or NULL for none. */ +extern PGDLLIMPORT Session *CurrentSession; + +#endif /* SESSION_H */ diff --git a/install/include/postgresql/server/access/skey.h b/install/include/postgresql/server/access/skey.h new file mode 100644 index 00000000000..fbdb23c5c7e --- /dev/null +++ b/install/include/postgresql/server/access/skey.h @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------------- + * + * skey.h + * POSTGRES scan key definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/skey.h + * + *------------------------------------------------------------------------- + */ +#ifndef SKEY_H +#define SKEY_H + +#include "access/attnum.h" +#include "access/stratnum.h" +#include "fmgr.h" + + +/* + * A ScanKey represents the application of a comparison operator between + * a table or index column and a constant. When it's part of an array of + * ScanKeys, the comparison conditions are implicitly ANDed. The index + * column is the left argument of the operator, if it's a binary operator. + * (The data structure can support unary indexable operators too; in that + * case sk_argument would go unused. This is not currently implemented.) + * + * For an index scan, sk_strategy and sk_subtype must be set correctly for + * the operator. When using a ScanKey in a heap scan, these fields are not + * used and may be set to InvalidStrategy/InvalidOid. + * + * If the operator is collation-sensitive, sk_collation must be set + * correctly as well. + * + * A ScanKey can also represent a ScalarArrayOpExpr, that is a condition + * "column op ANY(ARRAY[...])". This is signaled by the SK_SEARCHARRAY + * flag bit. The sk_argument is not a value of the operator's right-hand + * argument type, but rather an array of such values, and the per-element + * comparisons are to be ORed together. + * + * A ScanKey can also represent a condition "column IS NULL" or "column + * IS NOT NULL"; these cases are signaled by the SK_SEARCHNULL and + * SK_SEARCHNOTNULL flag bits respectively. The argument is always NULL, + * and the sk_strategy, sk_subtype, sk_collation, and sk_func fields are + * not used (unless set by the index AM). + * + * SK_SEARCHARRAY, SK_SEARCHNULL and SK_SEARCHNOTNULL are supported only + * for index scans, not heap scans; and not all index AMs support them, + * only those that set amsearcharray or amsearchnulls respectively. + * + * A ScanKey can also represent an ordering operator invocation, that is + * an ordering requirement "ORDER BY indexedcol op constant". This looks + * the same as a comparison operator, except that the operator doesn't + * (usually) yield boolean. We mark such ScanKeys with SK_ORDER_BY. + * SK_SEARCHARRAY, SK_SEARCHNULL, SK_SEARCHNOTNULL cannot be used here. + * + * Note: in some places, ScanKeys are used as a convenient representation + * for the invocation of an access method support procedure. In this case + * sk_strategy/sk_subtype are not meaningful (but sk_collation can be); and + * sk_func may refer to a function that returns something other than boolean. + */ +typedef struct ScanKeyData +{ + int sk_flags; /* flags, see below */ + AttrNumber sk_attno; /* table or index column number */ + StrategyNumber sk_strategy; /* operator strategy number */ + Oid sk_subtype; /* strategy subtype */ + Oid sk_collation; /* collation to use, if needed */ + FmgrInfo sk_func; /* lookup info for function to call */ + Datum sk_argument; /* data to compare */ +} ScanKeyData; + +typedef ScanKeyData *ScanKey; + +/* + * About row comparisons: + * + * The ScanKey data structure also supports row comparisons, that is ordered + * tuple comparisons like (x, y) > (c1, c2), having the SQL-spec semantics + * "x > c1 OR (x = c1 AND y > c2)". Note that this is currently only + * implemented for btree index searches, not for heapscans or any other index + * type. A row comparison is represented by a "header" ScanKey entry plus + * a separate array of ScanKeys, one for each column of the row comparison. + * The header entry has these properties: + * sk_flags = SK_ROW_HEADER + * sk_attno = index column number for leading column of row comparison + * sk_strategy = btree strategy code for semantics of row comparison + * (ie, < <= > or >=) + * sk_subtype, sk_collation, sk_func: not used + * sk_argument: pointer to subsidiary ScanKey array + * If the header is part of a ScanKey array that's sorted by attno, it + * must be sorted according to the leading column number. + * + * The subsidiary ScanKey array appears in logical column order of the row + * comparison, which may be different from index column order. The array + * elements are like a normal ScanKey array except that: + * sk_flags must include SK_ROW_MEMBER, plus SK_ROW_END in the last + * element (needed since row header does not include a count) + * sk_func points to the btree comparison support function for the + * opclass, NOT the operator's implementation function. + * sk_strategy must be the same in all elements of the subsidiary array, + * that is, the same as in the header entry. + * SK_SEARCHARRAY, SK_SEARCHNULL, SK_SEARCHNOTNULL cannot be used here. + */ + +/* + * ScanKeyData sk_flags + * + * sk_flags bits 0-15 are reserved for system-wide use (symbols for those + * bits should be defined here). Bits 16-31 are reserved for use within + * individual index access methods. + */ +#define SK_ISNULL 0x0001 /* sk_argument is NULL */ +#define SK_UNARY 0x0002 /* unary operator (not supported!) */ +#define SK_ROW_HEADER 0x0004 /* row comparison header (see above) */ +#define SK_ROW_MEMBER 0x0008 /* row comparison member (see above) */ +#define SK_ROW_END 0x0010 /* last row comparison member */ +#define SK_SEARCHARRAY 0x0020 /* scankey represents ScalarArrayOp */ +#define SK_SEARCHNULL 0x0040 /* scankey represents "col IS NULL" */ +#define SK_SEARCHNOTNULL 0x0080 /* scankey represents "col IS NOT NULL" */ +#define SK_ORDER_BY 0x0100 /* scankey is for ORDER BY op */ + + +/* + * prototypes for functions in access/common/scankey.c + */ +extern void ScanKeyInit(ScanKey entry, + AttrNumber attributeNumber, + StrategyNumber strategy, + RegProcedure procedure, + Datum argument); +extern void ScanKeyEntryInitialize(ScanKey entry, + int flags, + AttrNumber attributeNumber, + StrategyNumber strategy, + Oid subtype, + Oid collation, + RegProcedure procedure, + Datum argument); +extern void ScanKeyEntryInitializeWithInfo(ScanKey entry, + int flags, + AttrNumber attributeNumber, + StrategyNumber strategy, + Oid subtype, + Oid collation, + FmgrInfo *finfo, + Datum argument); + +#endif /* SKEY_H */ diff --git a/install/include/postgresql/server/access/slru.h b/install/include/postgresql/server/access/slru.h new file mode 100644 index 00000000000..90b897a88ba --- /dev/null +++ b/install/include/postgresql/server/access/slru.h @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------- + * + * slru.h + * Simple LRU buffering for transaction status logfiles + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/slru.h + * + *------------------------------------------------------------------------- + */ +#ifndef SLRU_H +#define SLRU_H + +#include "access/xlogdefs.h" +#include "storage/lwlock.h" +#include "storage/sync.h" + + +/* + * Define SLRU segment size. A page is the same BLCKSZ as is used everywhere + * else in Postgres. The segment size can be chosen somewhat arbitrarily; + * we make it 32 pages by default, or 256Kb, i.e. 1M transactions for CLOG + * or 64K transactions for SUBTRANS. + * + * Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF, + * page numbering also wraps around at 0xFFFFFFFF/xxxx_XACTS_PER_PAGE (where + * xxxx is CLOG or SUBTRANS, respectively), and segment numbering at + * 0xFFFFFFFF/xxxx_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT. We need + * take no explicit notice of that fact in slru.c, except when comparing + * segment and page numbers in SimpleLruTruncate (see PagePrecedes()). + */ +#define SLRU_PAGES_PER_SEGMENT 32 + +/* + * Page status codes. Note that these do not include the "dirty" bit. + * page_dirty can be true only in the VALID or WRITE_IN_PROGRESS states; + * in the latter case it implies that the page has been re-dirtied since + * the write started. + */ +typedef enum +{ + SLRU_PAGE_EMPTY, /* buffer is not in use */ + SLRU_PAGE_READ_IN_PROGRESS, /* page is being read in */ + SLRU_PAGE_VALID, /* page is valid and not being written */ + SLRU_PAGE_WRITE_IN_PROGRESS /* page is being written out */ +} SlruPageStatus; + +/* + * Shared-memory state + */ +typedef struct SlruSharedData +{ + LWLock *ControlLock; + + /* Number of buffers managed by this SLRU structure */ + int num_slots; + + /* + * Arrays holding info for each buffer slot. Page number is undefined + * when status is EMPTY, as is page_lru_count. + */ + char **page_buffer; + SlruPageStatus *page_status; + bool *page_dirty; + int *page_number; + int *page_lru_count; + LWLockPadded *buffer_locks; + + /* + * Optional array of WAL flush LSNs associated with entries in the SLRU + * pages. If not zero/NULL, we must flush WAL before writing pages (true + * for pg_xact, false for multixact, pg_subtrans, pg_notify). group_lsn[] + * has lsn_groups_per_page entries per buffer slot, each containing the + * highest LSN known for a contiguous group of SLRU entries on that slot's + * page. + */ + XLogRecPtr *group_lsn; + int lsn_groups_per_page; + + /*---------- + * We mark a page "most recently used" by setting + * page_lru_count[slotno] = ++cur_lru_count; + * The oldest page is therefore the one with the highest value of + * cur_lru_count - page_lru_count[slotno] + * The counts will eventually wrap around, but this calculation still + * works as long as no page's age exceeds INT_MAX counts. + *---------- + */ + int cur_lru_count; + + /* + * latest_page_number is the page number of the current end of the log; + * this is not critical data, since we use it only to avoid swapping out + * the latest page. (An exception: an accurate latest_page_number is + * needed on pg_multixact/offsets to replay WAL generated with older minor + * versions correctly. See RecordNewMultiXact().) + */ + int latest_page_number; + + /* SLRU's index for statistics purposes (might not be unique) */ + int slru_stats_idx; +} SlruSharedData; + +typedef SlruSharedData *SlruShared; + +/* + * SlruCtlData is an unshared structure that points to the active information + * in shared memory. + */ +typedef struct SlruCtlData +{ + SlruShared shared; + + /* + * Which sync handler function to use when handing sync requests over to + * the checkpointer. SYNC_HANDLER_NONE to disable fsync (eg pg_notify). + */ + SyncRequestHandler sync_handler; + + /* + * Decide whether a page is "older" for truncation and as a hint for + * evicting pages in LRU order. Return true if every entry of the first + * argument is older than every entry of the second argument. Note that + * !PagePrecedes(a,b) && !PagePrecedes(b,a) need not imply a==b; it also + * arises when some entries are older and some are not. For SLRUs using + * SimpleLruTruncate(), this must use modular arithmetic. (For others, + * the behavior of this callback has no functional implications.) Use + * SlruPagePrecedesUnitTests() in SLRUs meeting its criteria. + */ + bool (*PagePrecedes) (int, int); + + /* + * Dir is set during SimpleLruInit and does not change thereafter. Since + * it's always the same, it doesn't need to be in shared memory. + */ + char Dir[64]; +} SlruCtlData; + +typedef SlruCtlData *SlruCtl; + + +extern Size SimpleLruShmemSize(int nslots, int nlsns); +extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, + LWLock *ctllock, const char *subdir, int tranche_id, + SyncRequestHandler sync_handler); +extern int SimpleLruZeroPage(SlruCtl ctl, int pageno); +extern int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, + TransactionId xid); +extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, + TransactionId xid); +extern void SimpleLruWritePage(SlruCtl ctl, int slotno); +extern void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied); +#ifdef USE_ASSERT_CHECKING +extern void SlruPagePrecedesUnitTests(SlruCtl ctl, int per_page); +#else +#define SlruPagePrecedesUnitTests(ctl, per_page) do {} while (0) +#endif +extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage); +extern bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno); + +typedef bool (*SlruScanCallback) (SlruCtl ctl, char *filename, int segpage, + void *data); +extern bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data); +extern void SlruDeleteSegment(SlruCtl ctl, int segno); + +extern int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path); + +/* SlruScanDirectory public callbacks */ +extern bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, + int segpage, void *data); +extern bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, + void *data); + +#endif /* SLRU_H */ diff --git a/install/include/postgresql/server/access/spgist.h b/install/include/postgresql/server/access/spgist.h new file mode 100644 index 00000000000..fe31d32dbe9 --- /dev/null +++ b/install/include/postgresql/server/access/spgist.h @@ -0,0 +1,229 @@ +/*------------------------------------------------------------------------- + * + * spgist.h + * Public header file for SP-GiST access method. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/spgist.h + * + *------------------------------------------------------------------------- + */ +#ifndef SPGIST_H +#define SPGIST_H + +#include "access/amapi.h" +#include "access/xlogreader.h" +#include "lib/stringinfo.h" + + +/* SPGiST opclass support function numbers */ +#define SPGIST_CONFIG_PROC 1 +#define SPGIST_CHOOSE_PROC 2 +#define SPGIST_PICKSPLIT_PROC 3 +#define SPGIST_INNER_CONSISTENT_PROC 4 +#define SPGIST_LEAF_CONSISTENT_PROC 5 +#define SPGIST_COMPRESS_PROC 6 +#define SPGIST_OPTIONS_PROC 7 +#define SPGISTNRequiredProc 5 +#define SPGISTNProc 7 + +/* + * Argument structs for spg_config method + */ +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; + +/* + * Argument structs for spg_choose method + */ +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; + +/* + * Argument structs for spg_picksplit method + */ +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; + +/* + * Argument structs for spg_inner_consistent method + */ +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; + +/* + * Argument structs for spg_leaf_consistent method + */ +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; + + +/* spgutils.c */ +extern bytea *spgoptions(Datum reloptions, bool validate); + +/* spginsert.c */ +extern IndexBuildResult *spgbuild(Relation heap, Relation index, + struct IndexInfo *indexInfo); +extern void spgbuildempty(Relation index); +extern bool spginsert(Relation index, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); + +/* spgscan.c */ +extern IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz); +extern void spgendscan(IndexScanDesc scan); +extern void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys); +extern int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm); +extern bool spggettuple(IndexScanDesc scan, ScanDirection dir); +extern bool spgcanreturn(Relation index, int attno); + +/* spgvacuum.c */ +extern IndexBulkDeleteResult *spgbulkdelete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); +extern IndexBulkDeleteResult *spgvacuumcleanup(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); + +/* spgvalidate.c */ +extern bool spgvalidate(Oid opclassoid); +extern void spgadjustmembers(Oid opfamilyoid, + Oid opclassoid, + List *operators, + List *functions); + +#endif /* SPGIST_H */ diff --git a/install/include/postgresql/server/access/spgist_private.h b/install/include/postgresql/server/access/spgist_private.h new file mode 100644 index 00000000000..0af801b75ba --- /dev/null +++ b/install/include/postgresql/server/access/spgist_private.h @@ -0,0 +1,549 @@ +/*------------------------------------------------------------------------- + * + * spgist_private.h + * Private declarations for SP-GiST access method. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/spgist_private.h + * + *------------------------------------------------------------------------- + */ +#ifndef SPGIST_PRIVATE_H +#define SPGIST_PRIVATE_H + +#include "access/itup.h" +#include "access/spgist.h" +#include "catalog/pg_am_d.h" +#include "nodes/tidbitmap.h" +#include "storage/buf.h" +#include "utils/geo_decls.h" +#include "utils/relcache.h" + + +typedef struct SpGistOptions +{ + int32 varlena_header_; /* varlena header (do not touch directly!) */ + int fillfactor; /* page fill factor in percent (0..100) */ +} SpGistOptions; + +#define SpGistGetFillFactor(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \ + relation->rd_rel->relam == SPGIST_AM_OID), \ + (relation)->rd_options ? \ + ((SpGistOptions *) (relation)->rd_options)->fillfactor : \ + SPGIST_DEFAULT_FILLFACTOR) +#define SpGistGetTargetPageFreeSpace(relation) \ + (BLCKSZ * (100 - SpGistGetFillFactor(relation)) / 100) + + +/* SPGiST leaf tuples have one key column, optionally have included columns */ +#define spgKeyColumn 0 +#define spgFirstIncludeColumn 1 + +/* Page numbers of fixed-location pages */ +#define SPGIST_METAPAGE_BLKNO (0) /* metapage */ +#define SPGIST_ROOT_BLKNO (1) /* root for normal entries */ +#define SPGIST_NULL_BLKNO (2) /* root for null-value entries */ +#define SPGIST_LAST_FIXED_BLKNO SPGIST_NULL_BLKNO + +#define SpGistBlockIsRoot(blkno) \ + ((blkno) == SPGIST_ROOT_BLKNO || (blkno) == SPGIST_NULL_BLKNO) +#define SpGistBlockIsFixed(blkno) \ + ((BlockNumber) (blkno) <= (BlockNumber) SPGIST_LAST_FIXED_BLKNO) + +/* + * Contents of page special space on SPGiST index pages + */ +typedef struct SpGistPageOpaqueData +{ + uint16 flags; /* see bit definitions below */ + uint16 nRedirection; /* number of redirection tuples on page */ + uint16 nPlaceholder; /* number of placeholder tuples on page */ + /* note there's no count of either LIVE or DEAD tuples ... */ + uint16 spgist_page_id; /* for identification of SP-GiST indexes */ +} SpGistPageOpaqueData; + +typedef SpGistPageOpaqueData *SpGistPageOpaque; + +/* Flag bits in page special space */ +#define SPGIST_META (1<<0) +#define SPGIST_DELETED (1<<1) /* never set, but keep for backwards + * compatibility */ +#define SPGIST_LEAF (1<<2) +#define SPGIST_NULLS (1<<3) + +#define SpGistPageGetOpaque(page) ((SpGistPageOpaque) PageGetSpecialPointer(page)) +#define SpGistPageIsMeta(page) (SpGistPageGetOpaque(page)->flags & SPGIST_META) +#define SpGistPageIsDeleted(page) (SpGistPageGetOpaque(page)->flags & SPGIST_DELETED) +#define SpGistPageIsLeaf(page) (SpGistPageGetOpaque(page)->flags & SPGIST_LEAF) +#define SpGistPageStoresNulls(page) (SpGistPageGetOpaque(page)->flags & SPGIST_NULLS) + +/* + * The page ID is for the convenience of pg_filedump and similar utilities, + * which otherwise would have a hard time telling pages of different index + * types apart. It should be the last 2 bytes on the page. This is more or + * less "free" due to alignment considerations. + * + * See comments above GinPageOpaqueData. + */ +#define SPGIST_PAGE_ID 0xFF82 + +/* + * Each backend keeps a cache of last-used page info in its index->rd_amcache + * area. This is initialized from, and occasionally written back to, + * shared storage in the index metapage. + */ +typedef struct SpGistLastUsedPage +{ + BlockNumber blkno; /* block number, or InvalidBlockNumber */ + int freeSpace; /* page's free space (could be obsolete!) */ +} SpGistLastUsedPage; + +/* Note: indexes in cachedPage[] match flag assignments for SpGistGetBuffer */ +#define SPGIST_CACHED_PAGES 8 + +typedef struct SpGistLUPCache +{ + SpGistLastUsedPage cachedPage[SPGIST_CACHED_PAGES]; +} SpGistLUPCache; + +/* + * metapage + */ +typedef struct SpGistMetaPageData +{ + uint32 magicNumber; /* for identity cross-check */ + SpGistLUPCache lastUsedPages; /* shared storage of last-used info */ +} SpGistMetaPageData; + +#define SPGIST_MAGIC_NUMBER (0xBA0BABEE) + +#define SpGistPageGetMeta(p) \ + ((SpGistMetaPageData *) PageGetContents(p)) + +/* + * Private state of index AM. SpGistState is common to both insert and + * search code; SpGistScanOpaque is for searches only. + */ + +typedef struct SpGistLeafTupleData *SpGistLeafTuple; /* forward reference */ + +/* Per-datatype info needed in SpGistState */ +typedef struct SpGistTypeDesc +{ + Oid type; + int16 attlen; + bool attbyval; + char attalign; + char attstorage; +} SpGistTypeDesc; + +typedef struct SpGistState +{ + Relation index; /* index we're working with */ + + spgConfigOut config; /* filled in by opclass config method */ + + SpGistTypeDesc attType; /* type of values to be indexed/restored */ + SpGistTypeDesc attLeafType; /* type of leaf-tuple values */ + SpGistTypeDesc attPrefixType; /* type of inner-tuple prefix values */ + SpGistTypeDesc attLabelType; /* type of node label values */ + + /* leafTupDesc typically points to index's tupdesc, but not always */ + TupleDesc leafTupDesc; /* descriptor for leaf-level tuples */ + + char *deadTupleStorage; /* workspace for spgFormDeadTuple */ + + TransactionId myXid; /* XID to use when creating a redirect tuple */ + bool isBuild; /* true if doing index build */ +} SpGistState; + +/* Item to be re-examined later during a search */ +typedef struct SpGistSearchItem +{ + pairingheap_node phNode; /* pairing heap node */ + Datum value; /* value reconstructed from parent, or + * leafValue if isLeaf */ + SpGistLeafTuple leafTuple; /* whole leaf tuple, if needed */ + void *traversalValue; /* opclass-specific traverse value */ + int level; /* level of items on this page */ + ItemPointerData heapPtr; /* heap info, if heap tuple */ + bool isNull; /* SearchItem is NULL item */ + bool isLeaf; /* SearchItem is heap item */ + bool recheck; /* qual recheck is needed */ + bool recheckDistances; /* distance recheck is needed */ + + /* array with numberOfOrderBys entries */ + double distances[FLEXIBLE_ARRAY_MEMBER]; +} SpGistSearchItem; + +#define SizeOfSpGistSearchItem(n_distances) \ + (offsetof(SpGistSearchItem, distances) + sizeof(double) * (n_distances)) + +/* + * Private state of an index scan + */ +typedef struct SpGistScanOpaqueData +{ + SpGistState state; /* see above */ + pairingheap *scanQueue; /* queue of to be visited items */ + MemoryContext tempCxt; /* short-lived memory context */ + MemoryContext traversalCxt; /* single scan lifetime memory context */ + + /* Control flags showing whether to search nulls and/or non-nulls */ + bool searchNulls; /* scan matches (all) null entries */ + bool searchNonNulls; /* scan matches (some) non-null entries */ + + /* Index quals to be passed to opclass (null-related quals removed) */ + int numberOfKeys; /* number of index qualifier conditions */ + ScanKey keyData; /* array of index qualifier descriptors */ + int numberOfOrderBys; /* number of ordering operators */ + int numberOfNonNullOrderBys; /* number of ordering operators + * with non-NULL arguments */ + ScanKey orderByData; /* array of ordering op descriptors */ + Oid *orderByTypes; /* array of ordering op return types */ + int *nonNullOrderByOffsets; /* array of offset of non-NULL + * ordering keys in the original array */ + Oid indexCollation; /* collation of index column */ + + /* Opclass defined functions: */ + FmgrInfo innerConsistentFn; + FmgrInfo leafConsistentFn; + + /* Pre-allocated workspace arrays: */ + double *zeroDistances; + double *infDistances; + + /* These fields are only used in amgetbitmap scans: */ + TIDBitmap *tbm; /* bitmap being filled */ + int64 ntids; /* number of TIDs passed to bitmap */ + + /* These fields are only used in amgettuple scans: */ + bool want_itup; /* are we reconstructing tuples? */ + TupleDesc reconTupDesc; /* if so, descriptor for reconstructed tuples */ + int nPtrs; /* number of TIDs found on current page */ + int iPtr; /* index for scanning through same */ + ItemPointerData heapPtrs[MaxIndexTuplesPerPage]; /* TIDs from cur page */ + bool recheck[MaxIndexTuplesPerPage]; /* their recheck flags */ + bool recheckDistances[MaxIndexTuplesPerPage]; /* distance recheck + * flags */ + HeapTuple reconTups[MaxIndexTuplesPerPage]; /* reconstructed tuples */ + + /* distances (for recheck) */ + IndexOrderByDistance *distances[MaxIndexTuplesPerPage]; + + /* + * Note: using MaxIndexTuplesPerPage above is a bit hokey since + * SpGistLeafTuples aren't exactly IndexTuples; however, they are larger, + * so this is safe. + */ +} SpGistScanOpaqueData; + +typedef SpGistScanOpaqueData *SpGistScanOpaque; + +/* + * This struct is what we actually keep in index->rd_amcache. It includes + * static configuration information as well as the lastUsedPages cache. + */ +typedef struct SpGistCache +{ + spgConfigOut config; /* filled in by opclass config method */ + + SpGistTypeDesc attType; /* type of values to be indexed/restored */ + SpGistTypeDesc attLeafType; /* type of leaf-tuple values */ + SpGistTypeDesc attPrefixType; /* type of inner-tuple prefix values */ + SpGistTypeDesc attLabelType; /* type of node label values */ + + SpGistLUPCache lastUsedPages; /* local storage of last-used info */ +} SpGistCache; + + +/* + * SPGiST tuple types. Note: inner, leaf, and dead tuple structs + * must have the same tupstate field in the same position! Real inner and + * leaf tuples always have tupstate = LIVE; if the state is something else, + * use the SpGistDeadTuple struct to inspect the tuple. + */ + +/* values of tupstate (see README for more info) */ +#define SPGIST_LIVE 0 /* normal live tuple (either inner or leaf) */ +#define SPGIST_REDIRECT 1 /* temporary redirection placeholder */ +#define SPGIST_DEAD 2 /* dead, cannot be removed because of links */ +#define SPGIST_PLACEHOLDER 3 /* placeholder, used to preserve offsets */ + +/* + * SPGiST inner tuple: list of "nodes" that subdivide a set of tuples + * + * Inner tuple layout: + * header/optional prefix/array of nodes, which are SpGistNodeTuples + * + * size and prefixSize must be multiples of MAXALIGN + * + * If the prefix datum is of a pass-by-value type, it is stored in its + * Datum representation, that is its on-disk representation is of length + * sizeof(Datum). This is a fairly unfortunate choice, because in no other + * place does Postgres use Datum as an on-disk representation; it creates + * an unnecessary incompatibility between 32-bit and 64-bit builds. But the + * compatibility loss is mostly theoretical since MAXIMUM_ALIGNOF typically + * differs between such builds, too. Anyway we're stuck with it now. + */ +typedef struct SpGistInnerTupleData +{ + unsigned int tupstate:2, /* LIVE/REDIRECT/DEAD/PLACEHOLDER */ + allTheSame:1, /* all nodes in tuple are equivalent */ + nNodes:13, /* number of nodes within inner tuple */ + prefixSize:16; /* size of prefix, or 0 if none */ + uint16 size; /* total size of inner tuple */ + /* On most machines there will be a couple of wasted bytes here */ + /* prefix datum follows, then nodes */ +} SpGistInnerTupleData; + +typedef SpGistInnerTupleData *SpGistInnerTuple; + +/* these must match largest values that fit in bit fields declared above */ +#define SGITMAXNNODES 0x1FFF +#define SGITMAXPREFIXSIZE 0xFFFF +#define SGITMAXSIZE 0xFFFF + +#define SGITHDRSZ MAXALIGN(sizeof(SpGistInnerTupleData)) +#define _SGITDATA(x) (((char *) (x)) + SGITHDRSZ) +#define SGITDATAPTR(x) ((x)->prefixSize ? _SGITDATA(x) : NULL) +#define SGITDATUM(x, s) ((x)->prefixSize ? \ + ((s)->attPrefixType.attbyval ? \ + *(Datum *) _SGITDATA(x) : \ + PointerGetDatum(_SGITDATA(x))) \ + : (Datum) 0) +#define SGITNODEPTR(x) ((SpGistNodeTuple) (_SGITDATA(x) + (x)->prefixSize)) + +/* Macro for iterating through the nodes of an inner tuple */ +#define SGITITERATE(x, i, nt) \ + for ((i) = 0, (nt) = SGITNODEPTR(x); \ + (i) < (x)->nNodes; \ + (i)++, (nt) = (SpGistNodeTuple) (((char *) (nt)) + IndexTupleSize(nt))) + +/* + * SPGiST node tuple: one node within an inner tuple + * + * Node tuples use the same header as ordinary Postgres IndexTuples, but + * we do not use a null bitmap, because we know there is only one column + * so the INDEX_NULL_MASK bit suffices. Also, pass-by-value datums are + * stored in Datum form, the same convention as for inner tuple prefixes. + */ + +typedef IndexTupleData SpGistNodeTupleData; + +typedef SpGistNodeTupleData *SpGistNodeTuple; + +#define SGNTHDRSZ MAXALIGN(sizeof(SpGistNodeTupleData)) +#define SGNTDATAPTR(x) (((char *) (x)) + SGNTHDRSZ) +#define SGNTDATUM(x, s) ((s)->attLabelType.attbyval ? \ + *(Datum *) SGNTDATAPTR(x) : \ + PointerGetDatum(SGNTDATAPTR(x))) + +/* + * SPGiST leaf tuple: carries a leaf datum and a heap tuple TID, + * and optionally some "included" columns. + * + * In the simplest case, the leaf datum is the same as the indexed value; + * but it could also be a suffix or some other sort of delta that permits + * reconstruction given knowledge of the prefix path traversed to get here. + * Any included columns are stored without modification. + * + * A nulls bitmap is present if there are included columns AND any of the + * datums are NULL. We do not need a nulls bitmap for the case of a null + * leaf datum without included columns, as we can infer whether the leaf + * datum is null from whether the tuple is stored on a nulls page. (This + * provision is mostly for backwards compatibility, but it does save space + * on 32-bit machines.) As with other PG index tuple designs, if the nulls + * bitmap exists then it's of size INDEX_MAX_KEYS bits regardless of the + * actual number of attributes. For the usual choice of INDEX_MAX_KEYS, + * this costs nothing because of alignment considerations. + * + * The size field is wider than could possibly be needed for an on-disk leaf + * tuple, but this allows us to form leaf tuples even when the datum is too + * wide to be stored immediately, and it costs nothing because of alignment + * considerations. + * + * t_info holds the nextOffset field (14 bits wide, enough for supported + * page sizes) plus the has-nulls-bitmap flag bit; another flag bit is free. + * + * Normally, nextOffset links to the next tuple belonging to the same parent + * node (which must be on the same page), or it's 0 if there is no next tuple. + * But when the root page is a leaf page, we don't chain its tuples, + * so nextOffset is always 0 on the root. + * + * size must be a multiple of MAXALIGN; also, it must be at least SGDTSIZE + * so that the tuple can be converted to REDIRECT status later. (This + * restriction only adds bytes for a NULL leaf datum stored on a 32-bit + * machine; otherwise alignment restrictions force it anyway.) + */ +typedef struct SpGistLeafTupleData +{ + unsigned int tupstate:2, /* LIVE/REDIRECT/DEAD/PLACEHOLDER */ + size:30; /* large enough for any palloc'able value */ + uint16 t_info; /* nextOffset, which links to the next tuple + * in chain, plus two flag bits */ + ItemPointerData heapPtr; /* TID of represented heap tuple */ + /* nulls bitmap follows if the flag bit for it is set */ + /* leaf datum, then any included datums, follows on a MAXALIGN boundary */ +} SpGistLeafTupleData; + +/* Macros to access nextOffset and bit fields inside t_info */ +#define SGLT_GET_NEXTOFFSET(spgLeafTuple) \ + ((spgLeafTuple)->t_info & 0x3FFF) +#define SGLT_GET_HASNULLMASK(spgLeafTuple) \ + (((spgLeafTuple)->t_info & 0x8000) ? true : false) +#define SGLT_SET_NEXTOFFSET(spgLeafTuple, offsetNumber) \ + ((spgLeafTuple)->t_info = \ + ((spgLeafTuple)->t_info & 0xC000) | ((offsetNumber) & 0x3FFF)) +#define SGLT_SET_HASNULLMASK(spgLeafTuple, hasnulls) \ + ((spgLeafTuple)->t_info = \ + ((spgLeafTuple)->t_info & 0x7FFF) | ((hasnulls) ? 0x8000 : 0)) + +#define SGLTHDRSZ(hasnulls) \ + ((hasnulls) ? MAXALIGN(sizeof(SpGistLeafTupleData) + \ + sizeof(IndexAttributeBitMapData)) : \ + MAXALIGN(sizeof(SpGistLeafTupleData))) +#define SGLTDATAPTR(x) (((char *) (x)) + SGLTHDRSZ(SGLT_GET_HASNULLMASK(x))) +#define SGLTDATUM(x, s) fetch_att(SGLTDATAPTR(x), \ + (s)->attLeafType.attbyval, \ + (s)->attLeafType.attlen) + +/* + * SPGiST dead tuple: declaration for examining non-live tuples + * + * The tupstate field of this struct must match those of regular inner and + * leaf tuples, and its size field must match a leaf tuple's. + * Also, the pointer field must be in the same place as a leaf tuple's heapPtr + * field, to satisfy some Asserts that we make when replacing a leaf tuple + * with a dead tuple. + * We don't use t_info, but it's needed to align the pointer field. + * pointer and xid are only valid when tupstate = REDIRECT, and in some + * cases xid can be InvalidTransactionId even then; see initSpGistState. + */ +typedef struct SpGistDeadTupleData +{ + unsigned int tupstate:2, /* LIVE/REDIRECT/DEAD/PLACEHOLDER */ + size:30; + uint16 t_info; /* not used in dead tuples */ + ItemPointerData pointer; /* redirection inside index */ + TransactionId xid; /* ID of xact that inserted this tuple */ +} SpGistDeadTupleData; + +typedef SpGistDeadTupleData *SpGistDeadTuple; + +#define SGDTSIZE MAXALIGN(sizeof(SpGistDeadTupleData)) + +/* + * Macros for doing free-space calculations. Note that when adding up the + * space needed for tuples, we always consider each tuple to need the tuple's + * size plus sizeof(ItemIdData) (for the line pointer). This works correctly + * so long as tuple sizes are always maxaligned. + */ + +/* Page capacity after allowing for fixed header and special space */ +#define SPGIST_PAGE_CAPACITY \ + MAXALIGN_DOWN(BLCKSZ - \ + SizeOfPageHeaderData - \ + MAXALIGN(sizeof(SpGistPageOpaqueData))) + +/* + * Compute free space on page, assuming that up to n placeholders can be + * recycled if present (n should be the number of tuples to be inserted) + */ +#define SpGistPageGetFreeSpace(p, n) \ + (PageGetExactFreeSpace(p) + \ + Min(SpGistPageGetOpaque(p)->nPlaceholder, n) * \ + (SGDTSIZE + sizeof(ItemIdData))) + +/* + * XLOG stuff + */ + +#define STORE_STATE(s, d) \ + do { \ + (d).myXid = (s)->myXid; \ + (d).isBuild = (s)->isBuild; \ + } while(0) + +/* + * The "flags" argument for SpGistGetBuffer should be either GBUF_LEAF to + * get a leaf page, or GBUF_INNER_PARITY(blockNumber) to get an inner + * page in the same triple-parity group as the specified block number. + * (Typically, this should be GBUF_INNER_PARITY(parentBlockNumber + 1) + * to follow the rule described in spgist/README.) + * In addition, GBUF_NULLS can be OR'd in to get a page for storage of + * null-valued tuples. + * + * Note: these flag values are used as indexes into lastUsedPages. + */ +#define GBUF_LEAF 0x03 +#define GBUF_INNER_PARITY(x) ((x) % 3) +#define GBUF_NULLS 0x04 + +#define GBUF_PARITY_MASK 0x03 +#define GBUF_REQ_LEAF(flags) (((flags) & GBUF_PARITY_MASK) == GBUF_LEAF) +#define GBUF_REQ_NULLS(flags) ((flags) & GBUF_NULLS) + +/* spgutils.c */ + +/* reloption parameters */ +#define SPGIST_MIN_FILLFACTOR 10 +#define SPGIST_DEFAULT_FILLFACTOR 80 + +extern SpGistCache *spgGetCache(Relation index); +extern TupleDesc getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType); +extern void initSpGistState(SpGistState *state, Relation index); +extern Buffer SpGistNewBuffer(Relation index); +extern void SpGistUpdateMetaPage(Relation index); +extern Buffer SpGistGetBuffer(Relation index, int flags, + int needSpace, bool *isNew); +extern void SpGistSetLastUsedPage(Relation index, Buffer buffer); +extern void SpGistInitPage(Page page, uint16 f); +extern void SpGistInitBuffer(Buffer b, uint16 f); +extern void SpGistInitMetapage(Page page); +extern unsigned int SpGistGetInnerTypeSize(SpGistTypeDesc *att, Datum datum); +extern Size SpGistGetLeafTupleSize(TupleDesc tupleDescriptor, + Datum *datums, bool *isnulls); +extern SpGistLeafTuple spgFormLeafTuple(SpGistState *state, + ItemPointer heapPtr, + Datum *datums, bool *isnulls); +extern SpGistNodeTuple spgFormNodeTuple(SpGistState *state, + Datum label, bool isnull); +extern SpGistInnerTuple spgFormInnerTuple(SpGistState *state, + bool hasPrefix, Datum prefix, + int nNodes, SpGistNodeTuple *nodes); +extern SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, + BlockNumber blkno, OffsetNumber offnum); +extern void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, + Datum *datums, bool *isnulls, + bool keyColumnIsNull); +extern Datum *spgExtractNodeLabels(SpGistState *state, + SpGistInnerTuple innerTuple); +extern OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, + Item item, Size size, + OffsetNumber *startOffset, + bool errorOK); +extern bool spgproperty(Oid index_oid, int attno, + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); + +/* spgdoinsert.c */ +extern void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN, + BlockNumber blkno, OffsetNumber offset); +extern void spgPageIndexMultiDelete(SpGistState *state, Page page, + OffsetNumber *itemnos, int nitems, + int firststate, int reststate, + BlockNumber blkno, OffsetNumber offnum); +extern bool spgdoinsert(Relation index, SpGistState *state, + ItemPointer heapPtr, Datum *datums, bool *isnulls); + +/* spgproc.c */ +extern double *spg_key_orderbys_distances(Datum key, bool isLeaf, + ScanKey orderbys, int norderbys); +extern BOX *box_copy(BOX *orig); + +#endif /* SPGIST_PRIVATE_H */ diff --git a/install/include/postgresql/server/access/spgxlog.h b/install/include/postgresql/server/access/spgxlog.h new file mode 100644 index 00000000000..a7f10bf2d3a --- /dev/null +++ b/install/include/postgresql/server/access/spgxlog.h @@ -0,0 +1,259 @@ +/*------------------------------------------------------------------------- + * + * spgxlog.h + * xlog declarations for SP-GiST access method. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/spgxlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef SPGXLOG_H +#define SPGXLOG_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/off.h" + +/* XLOG record types for SPGiST */ + /* #define XLOG_SPGIST_CREATE_INDEX 0x00 */ /* not used anymore */ +#define XLOG_SPGIST_ADD_LEAF 0x10 +#define XLOG_SPGIST_MOVE_LEAFS 0x20 +#define XLOG_SPGIST_ADD_NODE 0x30 +#define XLOG_SPGIST_SPLIT_TUPLE 0x40 +#define XLOG_SPGIST_PICKSPLIT 0x50 +#define XLOG_SPGIST_VACUUM_LEAF 0x60 +#define XLOG_SPGIST_VACUUM_ROOT 0x70 +#define XLOG_SPGIST_VACUUM_REDIRECT 0x80 + +/* + * Some redo functions need an SpGistState, although only a few of its fields + * need to be valid. spgxlogState carries the required info in xlog records. + * (See fillFakeState in spgxlog.c for more comments.) + */ +typedef struct spgxlogState +{ + TransactionId myXid; + bool isBuild; +} spgxlogState; + +/* + * Backup Blk 0: destination page for leaf tuple + * Backup Blk 1: parent page (if any) + */ +typedef struct spgxlogAddLeaf +{ + bool newPage; /* init dest page? */ + bool storesNulls; /* page is in the nulls tree? */ + OffsetNumber offnumLeaf; /* offset where leaf tuple gets placed */ + OffsetNumber offnumHeadLeaf; /* offset of head tuple in chain, if any */ + + OffsetNumber offnumParent; /* where the parent downlink is, if any */ + uint16 nodeI; + + /* new leaf tuple follows (unaligned!) */ +} spgxlogAddLeaf; + +/* + * Backup Blk 0: source leaf page + * Backup Blk 1: destination leaf page + * Backup Blk 2: parent page + */ +typedef struct spgxlogMoveLeafs +{ + uint16 nMoves; /* number of tuples moved from source page */ + bool newPage; /* init dest page? */ + bool replaceDead; /* are we replacing a DEAD source tuple? */ + bool storesNulls; /* pages are in the nulls tree? */ + + /* where the parent downlink is */ + OffsetNumber offnumParent; + uint16 nodeI; + + spgxlogState stateSrc; + + /*---------- + * data follows: + * array of deleted tuple numbers, length nMoves + * array of inserted tuple numbers, length nMoves + 1 or 1 + * list of leaf tuples, length nMoves + 1 or 1 (unaligned!) + * + * Note: if replaceDead is true then there is only one inserted tuple + * number and only one leaf tuple in the data, because we are not copying + * the dead tuple from the source + *---------- + */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} spgxlogMoveLeafs; + +#define SizeOfSpgxlogMoveLeafs offsetof(spgxlogMoveLeafs, offsets) + +/* + * Backup Blk 0: original page + * Backup Blk 1: where new tuple goes, if not same place + * Backup Blk 2: where parent downlink is, if updated and different from + * the old and new + */ +typedef struct spgxlogAddNode +{ + /* + * Offset of the original inner tuple, in the original page (on backup + * block 0). + */ + OffsetNumber offnum; + + /* + * Offset of the new tuple, on the new page (on backup block 1). Invalid, + * if we overwrote the old tuple in the original page). + */ + OffsetNumber offnumNew; + bool newPage; /* init new page? */ + + /*---- + * Where is the parent downlink? parentBlk indicates which page it's on, + * and offnumParent is the offset within the page. The possible values for + * parentBlk are: + * + * 0: parent == original page + * 1: parent == new page + * 2: parent == different page (blk ref 2) + * -1: parent not updated + *---- + */ + int8 parentBlk; + OffsetNumber offnumParent; /* offset within the parent page */ + + uint16 nodeI; + + spgxlogState stateSrc; + + /* + * updated inner tuple follows (unaligned!) + */ +} spgxlogAddNode; + +/* + * Backup Blk 0: where the prefix tuple goes + * Backup Blk 1: where the postfix tuple goes (if different page) + */ +typedef struct spgxlogSplitTuple +{ + /* where the prefix tuple goes */ + OffsetNumber offnumPrefix; + + /* where the postfix tuple goes */ + OffsetNumber offnumPostfix; + bool newPage; /* need to init that page? */ + bool postfixBlkSame; /* was postfix tuple put on same page as + * prefix? */ + + /* + * new prefix inner tuple follows, then new postfix inner tuple (both are + * unaligned!) + */ +} spgxlogSplitTuple; + +/* + * Buffer references in the rdata array are: + * Backup Blk 0: Src page (only if not root) + * Backup Blk 1: Dest page (if used) + * Backup Blk 2: Inner page + * Backup Blk 3: Parent page (if any, and different from Inner) + */ +typedef struct spgxlogPickSplit +{ + bool isRootSplit; + + uint16 nDelete; /* n to delete from Src */ + uint16 nInsert; /* n to insert on Src and/or Dest */ + bool initSrc; /* re-init the Src page? */ + bool initDest; /* re-init the Dest page? */ + + /* where to put new inner tuple */ + OffsetNumber offnumInner; + bool initInner; /* re-init the Inner page? */ + + bool storesNulls; /* pages are in the nulls tree? */ + + /* where the parent downlink is, if any */ + bool innerIsParent; /* is parent the same as inner page? */ + OffsetNumber offnumParent; + uint16 nodeI; + + spgxlogState stateSrc; + + /*---------- + * data follows: + * array of deleted tuple numbers, length nDelete + * array of inserted tuple numbers, length nInsert + * array of page selector bytes for inserted tuples, length nInsert + * new inner tuple (unaligned!) + * list of leaf tuples, length nInsert (unaligned!) + *---------- + */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} spgxlogPickSplit; + +#define SizeOfSpgxlogPickSplit offsetof(spgxlogPickSplit, offsets) + +typedef struct spgxlogVacuumLeaf +{ + uint16 nDead; /* number of tuples to become DEAD */ + uint16 nPlaceholder; /* number of tuples to become PLACEHOLDER */ + uint16 nMove; /* number of tuples to move */ + uint16 nChain; /* number of tuples to re-chain */ + + spgxlogState stateSrc; + + /*---------- + * data follows: + * tuple numbers to become DEAD + * tuple numbers to become PLACEHOLDER + * tuple numbers to move from (and replace with PLACEHOLDER) + * tuple numbers to move to (replacing what is there) + * tuple numbers to update nextOffset links of + * tuple numbers to insert in nextOffset links + *---------- + */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} spgxlogVacuumLeaf; + +#define SizeOfSpgxlogVacuumLeaf offsetof(spgxlogVacuumLeaf, offsets) + +typedef struct spgxlogVacuumRoot +{ + /* vacuum a root page when it is also a leaf */ + uint16 nDelete; /* number of tuples to delete */ + + spgxlogState stateSrc; + + /* offsets of tuples to delete follow */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} spgxlogVacuumRoot; + +#define SizeOfSpgxlogVacuumRoot offsetof(spgxlogVacuumRoot, offsets) + +typedef struct spgxlogVacuumRedirect +{ + uint16 nToPlaceholder; /* number of redirects to make placeholders */ + OffsetNumber firstPlaceholder; /* first placeholder tuple to remove */ + TransactionId snapshotConflictHorizon; /* newest XID of removed redirects */ + bool isCatalogRel; /* to handle recovery conflict during logical + * decoding on standby */ + + /* offsets of redirect tuples to make placeholders follow */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} spgxlogVacuumRedirect; + +#define SizeOfSpgxlogVacuumRedirect offsetof(spgxlogVacuumRedirect, offsets) + +extern void spg_redo(XLogReaderState *record); +extern void spg_desc(StringInfo buf, XLogReaderState *record); +extern const char *spg_identify(uint8 info); +extern void spg_xlog_startup(void); +extern void spg_xlog_cleanup(void); +extern void spg_mask(char *pagedata, BlockNumber blkno); + +#endif /* SPGXLOG_H */ diff --git a/install/include/postgresql/server/access/stratnum.h b/install/include/postgresql/server/access/stratnum.h new file mode 100644 index 00000000000..1b29653a8ab --- /dev/null +++ b/install/include/postgresql/server/access/stratnum.h @@ -0,0 +1,85 @@ +/*------------------------------------------------------------------------- + * + * stratnum.h + * POSTGRES strategy number definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/stratnum.h + * + *------------------------------------------------------------------------- + */ +#ifndef STRATNUM_H +#define STRATNUM_H + +/* + * Strategy numbers identify the semantics that particular operators have + * with respect to particular operator classes. In some cases a strategy + * subtype (an OID) is used as further information. + */ +typedef uint16 StrategyNumber; + +#define InvalidStrategy ((StrategyNumber) 0) + +/* + * Strategy numbers for B-tree indexes. + */ +#define BTLessStrategyNumber 1 +#define BTLessEqualStrategyNumber 2 +#define BTEqualStrategyNumber 3 +#define BTGreaterEqualStrategyNumber 4 +#define BTGreaterStrategyNumber 5 + +#define BTMaxStrategyNumber 5 + +/* + * Strategy numbers for hash indexes. There's only one valid strategy for + * hashing: equality. + */ +#define HTEqualStrategyNumber 1 + +#define HTMaxStrategyNumber 1 + +/* + * Strategy numbers common to (some) GiST, SP-GiST and BRIN opclasses. + * + * The first few of these come from the R-Tree indexing method (hence the + * names); the others have been added over time as they have been needed. + */ +#define RTLeftStrategyNumber 1 /* for << */ +#define RTOverLeftStrategyNumber 2 /* for &< */ +#define RTOverlapStrategyNumber 3 /* for && */ +#define RTOverRightStrategyNumber 4 /* for &> */ +#define RTRightStrategyNumber 5 /* for >> */ +#define RTSameStrategyNumber 6 /* for ~= */ +#define RTContainsStrategyNumber 7 /* for @> */ +#define RTContainedByStrategyNumber 8 /* for <@ */ +#define RTOverBelowStrategyNumber 9 /* for &<| */ +#define RTBelowStrategyNumber 10 /* for <<| */ +#define RTAboveStrategyNumber 11 /* for |>> */ +#define RTOverAboveStrategyNumber 12 /* for |&> */ +#define RTOldContainsStrategyNumber 13 /* for old spelling of @> */ +#define RTOldContainedByStrategyNumber 14 /* for old spelling of <@ */ +#define RTKNNSearchStrategyNumber 15 /* for <-> (distance) */ +#define RTContainsElemStrategyNumber 16 /* for range types @> elem */ +#define RTAdjacentStrategyNumber 17 /* for -|- */ +#define RTEqualStrategyNumber 18 /* for = */ +#define RTNotEqualStrategyNumber 19 /* for != */ +#define RTLessStrategyNumber 20 /* for < */ +#define RTLessEqualStrategyNumber 21 /* for <= */ +#define RTGreaterStrategyNumber 22 /* for > */ +#define RTGreaterEqualStrategyNumber 23 /* for >= */ +#define RTSubStrategyNumber 24 /* for inet >> */ +#define RTSubEqualStrategyNumber 25 /* for inet <<= */ +#define RTSuperStrategyNumber 26 /* for inet << */ +#define RTSuperEqualStrategyNumber 27 /* for inet >>= */ +#define RTPrefixStrategyNumber 28 /* for text ^@ */ +#define RTOldBelowStrategyNumber 29 /* for old spelling of <<| */ +#define RTOldAboveStrategyNumber 30 /* for old spelling of |>> */ + +#define RTMaxStrategyNumber 30 + + +#endif /* STRATNUM_H */ diff --git a/install/include/postgresql/server/access/subtrans.h b/install/include/postgresql/server/access/subtrans.h new file mode 100644 index 00000000000..46a473c77f5 --- /dev/null +++ b/install/include/postgresql/server/access/subtrans.h @@ -0,0 +1,29 @@ +/* + * subtrans.h + * + * PostgreSQL subtransaction-log manager + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/subtrans.h + */ +#ifndef SUBTRANS_H +#define SUBTRANS_H + +/* Number of SLRU buffers to use for subtrans */ +#define NUM_SUBTRANS_BUFFERS 32 + +extern void SubTransSetParent(TransactionId xid, TransactionId parent); +extern TransactionId SubTransGetParent(TransactionId xid); +extern TransactionId SubTransGetTopmostTransaction(TransactionId xid); + +extern Size SUBTRANSShmemSize(void); +extern void SUBTRANSShmemInit(void); +extern void BootStrapSUBTRANS(void); +extern void StartupSUBTRANS(TransactionId oldestActiveXID); +extern void CheckPointSUBTRANS(void); +extern void ExtendSUBTRANS(TransactionId newestXact); +extern void TruncateSUBTRANS(TransactionId oldestXact); + +#endif /* SUBTRANS_H */ diff --git a/install/include/postgresql/server/access/syncscan.h b/install/include/postgresql/server/access/syncscan.h new file mode 100644 index 00000000000..01a8eecbfe7 --- /dev/null +++ b/install/include/postgresql/server/access/syncscan.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * + * syncscan.h + * POSTGRES synchronous scan support functions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/syncscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef SYNCSCAN_H +#define SYNCSCAN_H + +#include "storage/block.h" +#include "utils/relcache.h" + +extern void ss_report_location(Relation rel, BlockNumber location); +extern BlockNumber ss_get_location(Relation rel, BlockNumber relnblocks); +extern void SyncScanShmemInit(void); +extern Size SyncScanShmemSize(void); + +#endif diff --git a/install/include/postgresql/server/access/sysattr.h b/install/include/postgresql/server/access/sysattr.h new file mode 100644 index 00000000000..8f08682750b --- /dev/null +++ b/install/include/postgresql/server/access/sysattr.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * sysattr.h + * POSTGRES system attribute definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/sysattr.h + * + *------------------------------------------------------------------------- + */ +#ifndef SYSATTR_H +#define SYSATTR_H + + +/* + * Attribute numbers for the system-defined attributes + */ +#define SelfItemPointerAttributeNumber (-1) +#define MinTransactionIdAttributeNumber (-2) +#define MinCommandIdAttributeNumber (-3) +#define MaxTransactionIdAttributeNumber (-4) +#define MaxCommandIdAttributeNumber (-5) +#define TableOidAttributeNumber (-6) +#define FirstLowInvalidHeapAttributeNumber (-7) + +#endif /* SYSATTR_H */ diff --git a/install/include/postgresql/server/access/table.h b/install/include/postgresql/server/access/table.h new file mode 100644 index 00000000000..e664c7b734c --- /dev/null +++ b/install/include/postgresql/server/access/table.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * table.h + * Generic routines for table related code. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/table.h + * + *------------------------------------------------------------------------- + */ +#ifndef TABLE_H +#define TABLE_H + +#include "nodes/primnodes.h" +#include "storage/lockdefs.h" +#include "utils/relcache.h" + +extern Relation table_open(Oid relationId, LOCKMODE lockmode); +extern Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation table_openrv_extended(const RangeVar *relation, + LOCKMODE lockmode, bool missing_ok); +extern Relation try_table_open(Oid relationId, LOCKMODE lockmode); +extern void table_close(Relation relation, LOCKMODE lockmode); + +#endif /* TABLE_H */ diff --git a/install/include/postgresql/server/access/tableam.h b/install/include/postgresql/server/access/tableam.h new file mode 100644 index 00000000000..3893c24a7e1 --- /dev/null +++ b/install/include/postgresql/server/access/tableam.h @@ -0,0 +1,2108 @@ +/*------------------------------------------------------------------------- + * + * tableam.h + * POSTGRES table access method definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/tableam.h + * + * NOTES + * See tableam.sgml for higher level documentation. + * + *------------------------------------------------------------------------- + */ +#ifndef TABLEAM_H +#define TABLEAM_H + +#include "access/relscan.h" +#include "access/sdir.h" +#include "access/xact.h" +#include "executor/tuptable.h" +#include "utils/rel.h" +#include "utils/snapshot.h" + + +#define DEFAULT_TABLE_ACCESS_METHOD "heap" + +/* GUCs */ +extern PGDLLIMPORT char *default_table_access_method; +extern PGDLLIMPORT bool synchronize_seqscans; + + +struct BulkInsertStateData; +struct IndexInfo; +struct SampleScanState; +struct TBMIterateResult; +struct VacuumParams; +struct ValidateIndexState; + +/* + * Bitmask values for the flags argument to the scan_begin callback. + */ +typedef enum ScanOptions +{ + /* one of SO_TYPE_* may be specified */ + SO_TYPE_SEQSCAN = 1 << 0, + SO_TYPE_BITMAPSCAN = 1 << 1, + SO_TYPE_SAMPLESCAN = 1 << 2, + SO_TYPE_TIDSCAN = 1 << 3, + SO_TYPE_TIDRANGESCAN = 1 << 4, + SO_TYPE_ANALYZE = 1 << 5, + + /* several of SO_ALLOW_* may be specified */ + /* allow or disallow use of access strategy */ + SO_ALLOW_STRAT = 1 << 6, + /* report location to syncscan logic? */ + SO_ALLOW_SYNC = 1 << 7, + /* verify visibility page-at-a-time? */ + SO_ALLOW_PAGEMODE = 1 << 8, + + /* unregister snapshot at scan end? */ + SO_TEMP_SNAPSHOT = 1 << 9 +} ScanOptions; + +/* + * Result codes for table_{update,delete,lock_tuple}, and for visibility + * routines inside table AMs. + */ +typedef enum TM_Result +{ + /* + * Signals that the action succeeded (i.e. update/delete performed, lock + * was acquired) + */ + TM_Ok, + + /* The affected tuple wasn't visible to the relevant snapshot */ + TM_Invisible, + + /* The affected tuple was already modified by the calling backend */ + TM_SelfModified, + + /* + * The affected tuple was updated by another transaction. This includes + * the case where tuple was moved to another partition. + */ + TM_Updated, + + /* The affected tuple was deleted by another transaction */ + TM_Deleted, + + /* + * The affected tuple is currently being modified by another session. This + * will only be returned if table_(update/delete/lock_tuple) are + * instructed not to wait. + */ + TM_BeingModified, + + /* lock couldn't be acquired, action skipped. Only used by lock_tuple */ + TM_WouldBlock +} TM_Result; + +/* + * Result codes for table_update(..., update_indexes*..). + * Used to determine which indexes to update. + */ +typedef enum TU_UpdateIndexes +{ + /* No indexed columns were updated (incl. TID addressing of tuple) */ + TU_None, + + /* A non-summarizing indexed column was updated, or the TID has changed */ + TU_All, + + /* Only summarized columns were updated, TID is unchanged */ + TU_Summarizing +} TU_UpdateIndexes; + +/* + * When table_tuple_update, table_tuple_delete, or table_tuple_lock fail + * because the target tuple is already outdated, they fill in this struct to + * provide information to the caller about what happened. When those functions + * succeed, the contents of this struct should not be relied upon, except for + * `traversed`, which may be set in both success and failure cases. + * + * ctid is the target's ctid link: it is the same as the target's TID if the + * target was deleted, or the location of the replacement tuple if the target + * was updated. + * + * xmax is the outdating transaction's XID. If the caller wants to visit the + * replacement tuple, it must check that this matches before believing the + * replacement is really a match. This is InvalidTransactionId if the target + * was !LP_NORMAL (expected only for a TID retrieved from syscache). + * + * cmax is the outdating command's CID, but only when the failure code is + * TM_SelfModified (i.e., something in the current transaction outdated the + * tuple); otherwise cmax is zero. (We make this restriction because + * HeapTupleHeaderGetCmax doesn't work for tuples outdated in other + * transactions.) + * + * traversed indicates if an update chain was followed in order to try to lock + * the target tuple. (This may be set in both success and failure cases.) + */ +typedef struct TM_FailureData +{ + ItemPointerData ctid; + TransactionId xmax; + CommandId cmax; + bool traversed; +} TM_FailureData; + +/* + * State used when calling table_index_delete_tuples(). + * + * Represents the status of table tuples, referenced by table TID and taken by + * index AM from index tuples. State consists of high level parameters of the + * deletion operation, plus two mutable palloc()'d arrays for information + * about the status of individual table tuples. These are conceptually one + * single array. Using two arrays keeps the TM_IndexDelete struct small, + * which makes sorting the first array (the deltids array) fast. + * + * Some index AM callers perform simple index tuple deletion (by specifying + * bottomup = false), and include only known-dead deltids. These known-dead + * entries are all marked knowndeletable = true directly (typically these are + * TIDs from LP_DEAD-marked index tuples), but that isn't strictly required. + * + * Callers that specify bottomup = true are "bottom-up index deletion" + * callers. The considerations for the tableam are more subtle with these + * callers because they ask the tableam to perform highly speculative work, + * and might only expect the tableam to check a small fraction of all entries. + * Caller is not allowed to specify knowndeletable = true for any entry + * because everything is highly speculative. Bottom-up caller provides + * context and hints to tableam -- see comments below for details on how index + * AMs and tableams should coordinate during bottom-up index deletion. + * + * Simple index deletion callers may ask the tableam to perform speculative + * work, too. This is a little like bottom-up deletion, but not too much. + * The tableam will only perform speculative work when it's practically free + * to do so in passing for simple deletion caller (while always performing + * whatever work is needed to enable knowndeletable/LP_DEAD index tuples to + * be deleted within index AM). This is the real reason why it's possible for + * simple index deletion caller to specify knowndeletable = false up front + * (this means "check if it's possible for me to delete corresponding index + * tuple when it's cheap to do so in passing"). The index AM should only + * include "extra" entries for index tuples whose TIDs point to a table block + * that tableam is expected to have to visit anyway (in the event of a block + * orientated tableam). The tableam isn't strictly obligated to check these + * "extra" TIDs, but a block-based AM should always manage to do so in + * practice. + * + * The final contents of the deltids/status arrays are interesting to callers + * that ask tableam to perform speculative work (i.e. when _any_ items have + * knowndeletable set to false up front). These index AM callers will + * naturally need to consult final state to determine which index tuples are + * in fact deletable. + * + * The index AM can keep track of which index tuple relates to which deltid by + * setting idxoffnum (and/or relying on each entry being uniquely identifiable + * using tid), which is important when the final contents of the array will + * need to be interpreted -- the array can shrink from initial size after + * tableam processing and/or have entries in a new order (tableam may sort + * deltids array for its own reasons). Bottom-up callers may find that final + * ndeltids is 0 on return from call to tableam, in which case no index tuple + * deletions are possible. Simple deletion callers can rely on any entries + * they know to be deletable appearing in the final array as deletable. + */ +typedef struct TM_IndexDelete +{ + ItemPointerData tid; /* table TID from index tuple */ + int16 id; /* Offset into TM_IndexStatus array */ +} TM_IndexDelete; + +typedef struct TM_IndexStatus +{ + OffsetNumber idxoffnum; /* Index am page offset number */ + bool knowndeletable; /* Currently known to be deletable? */ + + /* Bottom-up index deletion specific fields follow */ + bool promising; /* Promising (duplicate) index tuple? */ + int16 freespace; /* Space freed in index if deleted */ +} TM_IndexStatus; + +/* + * Index AM/tableam coordination is central to the design of bottom-up index + * deletion. The index AM provides hints about where to look to the tableam + * by marking some entries as "promising". Index AM does this with duplicate + * index tuples that are strongly suspected to be old versions left behind by + * UPDATEs that did not logically modify indexed values. Index AM may find it + * helpful to only mark entries as promising when they're thought to have been + * affected by such an UPDATE in the recent past. + * + * Bottom-up index deletion casts a wide net at first, usually by including + * all TIDs on a target index page. It is up to the tableam to worry about + * the cost of checking transaction status information. The tableam is in + * control, but needs careful guidance from the index AM. Index AM requests + * that bottomupfreespace target be met, while tableam measures progress + * towards that goal by tallying the per-entry freespace value for known + * deletable entries. (All !bottomup callers can just set these space related + * fields to zero.) + */ +typedef struct TM_IndexDeleteOp +{ + Relation irel; /* Target index relation */ + BlockNumber iblknum; /* Index block number (for error reports) */ + bool bottomup; /* Bottom-up (not simple) deletion? */ + int bottomupfreespace; /* Bottom-up space target */ + + /* Mutable per-TID information follows (index AM initializes entries) */ + int ndeltids; /* Current # of deltids/status elements */ + TM_IndexDelete *deltids; + TM_IndexStatus *status; +} TM_IndexDeleteOp; + +/* "options" flag bits for table_tuple_insert */ +/* TABLE_INSERT_SKIP_WAL was 0x0001; RelationNeedsWAL() now governs */ +#define TABLE_INSERT_SKIP_FSM 0x0002 +#define TABLE_INSERT_FROZEN 0x0004 +#define TABLE_INSERT_NO_LOGICAL 0x0008 + +/* flag bits for table_tuple_lock */ +/* Follow tuples whose update is in progress if lock modes don't conflict */ +#define TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS (1 << 0) +/* Follow update chain and lock latest version of tuple */ +#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) + + +/* Typedef for callback function for table_index_build_scan */ +typedef void (*IndexBuildCallback) (Relation index, + ItemPointer tid, + Datum *values, + bool *isnull, + bool tupleIsAlive, + void *state); + +/* + * API struct for a table AM. Note this must be allocated in a + * server-lifetime manner, typically as a static const struct, which then gets + * returned by FormData_pg_am.amhandler. + * + * In most cases it's not appropriate to call the callbacks directly, use the + * table_* wrapper functions instead. + * + * GetTableAmRoutine() asserts that required callbacks are filled in, remember + * to update when adding a callback. + */ +typedef struct TableAmRoutine +{ + /* this must be set to T_TableAmRoutine */ + NodeTag type; + + + /* ------------------------------------------------------------------------ + * Slot related callbacks. + * ------------------------------------------------------------------------ + */ + + /* + * Return slot implementation suitable for storing a tuple of this AM. + */ + const TupleTableSlotOps *(*slot_callbacks) (Relation rel); + + + /* ------------------------------------------------------------------------ + * Table scan callbacks. + * ------------------------------------------------------------------------ + */ + + /* + * Start a scan of `rel`. The callback has to return a TableScanDesc, + * which will typically be embedded in a larger, AM specific, struct. + * + * If nkeys != 0, the results need to be filtered by those scan keys. + * + * pscan, if not NULL, will have already been initialized with + * parallelscan_initialize(), and has to be for the same relation. Will + * only be set coming from table_beginscan_parallel(). + * + * `flags` is a bitmask indicating the type of scan (ScanOptions's + * SO_TYPE_*, currently only one may be specified), options controlling + * the scan's behaviour (ScanOptions's SO_ALLOW_*, several may be + * specified, an AM may ignore unsupported ones) and whether the snapshot + * needs to be deallocated at scan_end (ScanOptions's SO_TEMP_SNAPSHOT). + */ + TableScanDesc (*scan_begin) (Relation rel, + Snapshot snapshot, + int nkeys, struct ScanKeyData *key, + ParallelTableScanDesc pscan, + uint32 flags); + + /* + * Release resources and deallocate scan. If TableScanDesc.temp_snap, + * TableScanDesc.rs_snapshot needs to be unregistered. + */ + void (*scan_end) (TableScanDesc scan); + + /* + * Restart relation scan. If set_params is set to true, allow_{strat, + * sync, pagemode} (see scan_begin) changes should be taken into account. + */ + void (*scan_rescan) (TableScanDesc scan, struct ScanKeyData *key, + bool set_params, bool allow_strat, + bool allow_sync, bool allow_pagemode); + + /* + * Return next tuple from `scan`, store in slot. + */ + bool (*scan_getnextslot) (TableScanDesc scan, + ScanDirection direction, + TupleTableSlot *slot); + + /*----------- + * Optional functions to provide scanning for ranges of ItemPointers. + * Implementations must either provide both of these functions, or neither + * of them. + * + * Implementations of scan_set_tidrange must themselves handle + * ItemPointers of any value. i.e, they must handle each of the following: + * + * 1) mintid or maxtid is beyond the end of the table; and + * 2) mintid is above maxtid; and + * 3) item offset for mintid or maxtid is beyond the maximum offset + * allowed by the AM. + * + * Implementations can assume that scan_set_tidrange is always called + * before scan_getnextslot_tidrange or after scan_rescan and before any + * further calls to scan_getnextslot_tidrange. + */ + void (*scan_set_tidrange) (TableScanDesc scan, + ItemPointer mintid, + ItemPointer maxtid); + + /* + * Return next tuple from `scan` that's in the range of TIDs defined by + * scan_set_tidrange. + */ + bool (*scan_getnextslot_tidrange) (TableScanDesc scan, + ScanDirection direction, + TupleTableSlot *slot); + + /* ------------------------------------------------------------------------ + * Parallel table scan related functions. + * ------------------------------------------------------------------------ + */ + + /* + * Estimate the size of shared memory needed for a parallel scan of this + * relation. The snapshot does not need to be accounted for. + */ + Size (*parallelscan_estimate) (Relation rel); + + /* + * Initialize ParallelTableScanDesc for a parallel scan of this relation. + * `pscan` will be sized according to parallelscan_estimate() for the same + * relation. + */ + Size (*parallelscan_initialize) (Relation rel, + ParallelTableScanDesc pscan); + + /* + * Reinitialize `pscan` for a new scan. `rel` will be the same relation as + * when `pscan` was initialized by parallelscan_initialize. + */ + void (*parallelscan_reinitialize) (Relation rel, + ParallelTableScanDesc pscan); + + + /* ------------------------------------------------------------------------ + * Index Scan Callbacks + * ------------------------------------------------------------------------ + */ + + /* + * Prepare to fetch tuples from the relation, as needed when fetching + * tuples for an index scan. The callback has to return an + * IndexFetchTableData, which the AM will typically embed in a larger + * structure with additional information. + * + * Tuples for an index scan can then be fetched via index_fetch_tuple. + */ + struct IndexFetchTableData *(*index_fetch_begin) (Relation rel); + + /* + * Reset index fetch. Typically this will release cross index fetch + * resources held in IndexFetchTableData. + */ + void (*index_fetch_reset) (struct IndexFetchTableData *data); + + /* + * Release resources and deallocate index fetch. + */ + void (*index_fetch_end) (struct IndexFetchTableData *data); + + /* + * Fetch tuple at `tid` into `slot`, after doing a visibility test + * according to `snapshot`. If a tuple was found and passed the visibility + * test, return true, false otherwise. + * + * Note that AMs that do not necessarily update indexes when indexed + * columns do not change, need to return the current/correct version of + * the tuple that is visible to the snapshot, even if the tid points to an + * older version of the tuple. + * + * *call_again is false on the first call to index_fetch_tuple for a tid. + * If there potentially is another tuple matching the tid, *call_again + * needs to be set to true by index_fetch_tuple, signaling to the caller + * that index_fetch_tuple should be called again for the same tid. + * + * *all_dead, if all_dead is not NULL, should be set to true by + * index_fetch_tuple iff it is guaranteed that no backend needs to see + * that tuple. Index AMs can use that to avoid returning that tid in + * future searches. + */ + bool (*index_fetch_tuple) (struct IndexFetchTableData *scan, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot, + bool *call_again, bool *all_dead); + + + /* ------------------------------------------------------------------------ + * Callbacks for non-modifying operations on individual tuples + * ------------------------------------------------------------------------ + */ + + /* + * Fetch tuple at `tid` into `slot`, after doing a visibility test + * according to `snapshot`. If a tuple was found and passed the visibility + * test, returns true, false otherwise. + */ + bool (*tuple_fetch_row_version) (Relation rel, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot); + + /* + * Is tid valid for a scan of this relation. + */ + bool (*tuple_tid_valid) (TableScanDesc scan, + ItemPointer tid); + + /* + * Return the latest version of the tuple at `tid`, by updating `tid` to + * point at the newest version. + */ + void (*tuple_get_latest_tid) (TableScanDesc scan, + ItemPointer tid); + + /* + * Does the tuple in `slot` satisfy `snapshot`? The slot needs to be of + * the appropriate type for the AM. + */ + bool (*tuple_satisfies_snapshot) (Relation rel, + TupleTableSlot *slot, + Snapshot snapshot); + + /* see table_index_delete_tuples() */ + TransactionId (*index_delete_tuples) (Relation rel, + TM_IndexDeleteOp *delstate); + + + /* ------------------------------------------------------------------------ + * Manipulations of physical tuples. + * ------------------------------------------------------------------------ + */ + + /* see table_tuple_insert() for reference about parameters */ + void (*tuple_insert) (Relation rel, TupleTableSlot *slot, + CommandId cid, int options, + struct BulkInsertStateData *bistate); + + /* see table_tuple_insert_speculative() for reference about parameters */ + void (*tuple_insert_speculative) (Relation rel, + TupleTableSlot *slot, + CommandId cid, + int options, + struct BulkInsertStateData *bistate, + uint32 specToken); + + /* see table_tuple_complete_speculative() for reference about parameters */ + void (*tuple_complete_speculative) (Relation rel, + TupleTableSlot *slot, + uint32 specToken, + bool succeeded); + + /* see table_multi_insert() for reference about parameters */ + void (*multi_insert) (Relation rel, TupleTableSlot **slots, int nslots, + CommandId cid, int options, struct BulkInsertStateData *bistate); + + /* see table_tuple_delete() for reference about parameters */ + TM_Result (*tuple_delete) (Relation rel, + ItemPointer tid, + CommandId cid, + Snapshot snapshot, + Snapshot crosscheck, + bool wait, + TM_FailureData *tmfd, + bool changingPart); + + /* see table_tuple_update() for reference about parameters */ + TM_Result (*tuple_update) (Relation rel, + ItemPointer otid, + TupleTableSlot *slot, + CommandId cid, + Snapshot snapshot, + Snapshot crosscheck, + bool wait, + TM_FailureData *tmfd, + LockTupleMode *lockmode, + TU_UpdateIndexes *update_indexes); + + /* see table_tuple_lock() for reference about parameters */ + TM_Result (*tuple_lock) (Relation rel, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot, + CommandId cid, + LockTupleMode mode, + LockWaitPolicy wait_policy, + uint8 flags, + TM_FailureData *tmfd); + + /* + * Perform operations necessary to complete insertions made via + * tuple_insert and multi_insert with a BulkInsertState specified. In-tree + * access methods ceased to use this. + * + * Typically callers of tuple_insert and multi_insert will just pass all + * the flags that apply to them, and each AM has to decide which of them + * make sense for it, and then only take actions in finish_bulk_insert for + * those flags, and ignore others. + * + * Optional callback. + */ + void (*finish_bulk_insert) (Relation rel, int options); + + + /* ------------------------------------------------------------------------ + * DDL related functionality. + * ------------------------------------------------------------------------ + */ + + /* + * This callback needs to create new relation storage for `rel`, with + * appropriate durability behaviour for `persistence`. + * + * Note that only the subset of the relcache filled by + * RelationBuildLocalRelation() can be relied upon and that the relation's + * catalog entries will either not yet exist (new relation), or will still + * reference the old relfilelocator. + * + * As output *freezeXid, *minmulti must be set to the values appropriate + * for pg_class.{relfrozenxid, relminmxid}. For AMs that don't need those + * fields to be filled they can be set to InvalidTransactionId and + * InvalidMultiXactId, respectively. + * + * See also table_relation_set_new_filelocator(). + */ + void (*relation_set_new_filelocator) (Relation rel, + const RelFileLocator *newrlocator, + char persistence, + TransactionId *freezeXid, + MultiXactId *minmulti); + + /* + * This callback needs to remove all contents from `rel`'s current + * relfilelocator. No provisions for transactional behaviour need to be + * made. Often this can be implemented by truncating the underlying + * storage to its minimal size. + * + * See also table_relation_nontransactional_truncate(). + */ + void (*relation_nontransactional_truncate) (Relation rel); + + /* + * See table_relation_copy_data(). + * + * This can typically be implemented by directly copying the underlying + * storage, unless it contains references to the tablespace internally. + */ + void (*relation_copy_data) (Relation rel, + const RelFileLocator *newrlocator); + + /* See table_relation_copy_for_cluster() */ + void (*relation_copy_for_cluster) (Relation OldTable, + Relation NewTable, + Relation OldIndex, + bool use_sort, + TransactionId OldestXmin, + TransactionId *xid_cutoff, + MultiXactId *multi_cutoff, + double *num_tuples, + double *tups_vacuumed, + double *tups_recently_dead); + + /* + * React to VACUUM command on the relation. The VACUUM can be triggered by + * a user or by autovacuum. The specific actions performed by the AM will + * depend heavily on the individual AM. + * + * On entry a transaction is already established, and the relation is + * locked with a ShareUpdateExclusive lock. + * + * Note that neither VACUUM FULL (and CLUSTER), nor ANALYZE go through + * this routine, even if (for ANALYZE) it is part of the same VACUUM + * command. + * + * There probably, in the future, needs to be a separate callback to + * integrate with autovacuum's scheduling. + */ + void (*relation_vacuum) (Relation rel, + struct VacuumParams *params, + BufferAccessStrategy bstrategy); + + /* + * Prepare to analyze block `blockno` of `scan`. The scan has been started + * with table_beginscan_analyze(). See also + * table_scan_analyze_next_block(). + * + * The callback may acquire resources like locks that are held until + * table_scan_analyze_next_tuple() returns false. It e.g. can make sense + * to hold a lock until all tuples on a block have been analyzed by + * scan_analyze_next_tuple. + * + * The callback can return false if the block is not suitable for + * sampling, e.g. because it's a metapage that could never contain tuples. + * + * XXX: This obviously is primarily suited for block-based AMs. It's not + * clear what a good interface for non block based AMs would be, so there + * isn't one yet. + */ + bool (*scan_analyze_next_block) (TableScanDesc scan, + BlockNumber blockno, + BufferAccessStrategy bstrategy); + + /* + * See table_scan_analyze_next_tuple(). + * + * Not every AM might have a meaningful concept of dead rows, in which + * case it's OK to not increment *deadrows - but note that that may + * influence autovacuum scheduling (see comment for relation_vacuum + * callback). + */ + bool (*scan_analyze_next_tuple) (TableScanDesc scan, + TransactionId OldestXmin, + double *liverows, + double *deadrows, + TupleTableSlot *slot); + + /* see table_index_build_range_scan for reference about parameters */ + double (*index_build_range_scan) (Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + bool allow_sync, + bool anyvisible, + bool progress, + BlockNumber start_blockno, + BlockNumber numblocks, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan); + + /* see table_index_validate_scan for reference about parameters */ + void (*index_validate_scan) (Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + Snapshot snapshot, + struct ValidateIndexState *state); + + + /* ------------------------------------------------------------------------ + * Miscellaneous functions. + * ------------------------------------------------------------------------ + */ + + /* + * See table_relation_size(). + * + * Note that currently a few callers use the MAIN_FORKNUM size to figure + * out the range of potentially interesting blocks (brin, analyze). It's + * probable that we'll need to revise the interface for those at some + * point. + */ + uint64 (*relation_size) (Relation rel, ForkNumber forkNumber); + + + /* + * This callback should return true if the relation requires a TOAST table + * and false if it does not. It may wish to examine the relation's tuple + * descriptor before making a decision, but if it uses some other method + * of storing large values (or if it does not support them) it can simply + * return false. + */ + bool (*relation_needs_toast_table) (Relation rel); + + /* + * This callback should return the OID of the table AM that implements + * TOAST tables for this AM. If the relation_needs_toast_table callback + * always returns false, this callback is not required. + */ + Oid (*relation_toast_am) (Relation rel); + + /* + * This callback is invoked when detoasting a value stored in a toast + * table implemented by this AM. See table_relation_fetch_toast_slice() + * for more details. + */ + void (*relation_fetch_toast_slice) (Relation toastrel, Oid valueid, + int32 attrsize, + int32 sliceoffset, + int32 slicelength, + struct varlena *result); + + + /* ------------------------------------------------------------------------ + * Planner related functions. + * ------------------------------------------------------------------------ + */ + + /* + * See table_relation_estimate_size(). + * + * While block oriented, it shouldn't be too hard for an AM that doesn't + * internally use blocks to convert into a usable representation. + * + * This differs from the relation_size callback by returning size + * estimates (both relation size and tuple count) for planning purposes, + * rather than returning a currently correct estimate. + */ + void (*relation_estimate_size) (Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, + double *allvisfrac); + + + /* ------------------------------------------------------------------------ + * Executor related functions. + * ------------------------------------------------------------------------ + */ + + /* + * Prepare to fetch / check / return tuples from `tbmres->blockno` as part + * of a bitmap table scan. `scan` was started via table_beginscan_bm(). + * Return false if there are no tuples to be found on the page, true + * otherwise. + * + * This will typically read and pin the target block, and do the necessary + * work to allow scan_bitmap_next_tuple() to return tuples (e.g. it might + * make sense to perform tuple visibility checks at this time). For some + * AMs it will make more sense to do all the work referencing `tbmres` + * contents here, for others it might be better to defer more work to + * scan_bitmap_next_tuple. + * + * If `tbmres->blockno` is -1, this is a lossy scan and all visible tuples + * on the page have to be returned, otherwise the tuples at offsets in + * `tbmres->offsets` need to be returned. + * + * XXX: Currently this may only be implemented if the AM uses md.c as its + * storage manager, and uses ItemPointer->ip_blkid in a manner that maps + * blockids directly to the underlying storage. nodeBitmapHeapscan.c + * performs prefetching directly using that interface. This probably + * needs to be rectified at a later point. + * + * XXX: Currently this may only be implemented if the AM uses the + * visibilitymap, as nodeBitmapHeapscan.c unconditionally accesses it to + * perform prefetching. This probably needs to be rectified at a later + * point. + * + * Optional callback, but either both scan_bitmap_next_block and + * scan_bitmap_next_tuple need to exist, or neither. + */ + bool (*scan_bitmap_next_block) (TableScanDesc scan, + struct TBMIterateResult *tbmres); + + /* + * Fetch the next tuple of a bitmap table scan into `slot` and return true + * if a visible tuple was found, false otherwise. + * + * For some AMs it will make more sense to do all the work referencing + * `tbmres` contents in scan_bitmap_next_block, for others it might be + * better to defer more work to this callback. + * + * Optional callback, but either both scan_bitmap_next_block and + * scan_bitmap_next_tuple need to exist, or neither. + */ + bool (*scan_bitmap_next_tuple) (TableScanDesc scan, + struct TBMIterateResult *tbmres, + TupleTableSlot *slot); + + /* + * Prepare to fetch tuples from the next block in a sample scan. Return + * false if the sample scan is finished, true otherwise. `scan` was + * started via table_beginscan_sampling(). + * + * Typically this will first determine the target block by calling the + * TsmRoutine's NextSampleBlock() callback if not NULL, or alternatively + * perform a sequential scan over all blocks. The determined block is + * then typically read and pinned. + * + * As the TsmRoutine interface is block based, a block needs to be passed + * to NextSampleBlock(). If that's not appropriate for an AM, it + * internally needs to perform mapping between the internal and a block + * based representation. + * + * Note that it's not acceptable to hold deadlock prone resources such as + * lwlocks until scan_sample_next_tuple() has exhausted the tuples on the + * block - the tuple is likely to be returned to an upper query node, and + * the next call could be off a long while. Holding buffer pins and such + * is obviously OK. + * + * Currently it is required to implement this interface, as there's no + * alternative way (contrary e.g. to bitmap scans) to implement sample + * scans. If infeasible to implement, the AM may raise an error. + */ + bool (*scan_sample_next_block) (TableScanDesc scan, + struct SampleScanState *scanstate); + + /* + * This callback, only called after scan_sample_next_block has returned + * true, should determine the next tuple to be returned from the selected + * block using the TsmRoutine's NextSampleTuple() callback. + * + * The callback needs to perform visibility checks, and only return + * visible tuples. That obviously can mean calling NextSampleTuple() + * multiple times. + * + * The TsmRoutine interface assumes that there's a maximum offset on a + * given page, so if that doesn't apply to an AM, it needs to emulate that + * assumption somehow. + */ + bool (*scan_sample_next_tuple) (TableScanDesc scan, + struct SampleScanState *scanstate, + TupleTableSlot *slot); + +} TableAmRoutine; + + +/* ---------------------------------------------------------------------------- + * Slot functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Returns slot callbacks suitable for holding tuples of the appropriate type + * for the relation. Works for tables, views, foreign tables and partitioned + * tables. + */ +extern const TupleTableSlotOps *table_slot_callbacks(Relation relation); + +/* + * Returns slot using the callbacks returned by table_slot_callbacks(), and + * registers it on *reglist. + */ +extern TupleTableSlot *table_slot_create(Relation relation, List **reglist); + + +/* ---------------------------------------------------------------------------- + * Table scan functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Start a scan of `rel`. Returned tuples pass a visibility test of + * `snapshot`, and if nkeys != 0, the results are filtered by those scan keys. + */ +static inline TableScanDesc +table_beginscan(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key) +{ + uint32 flags = SO_TYPE_SEQSCAN | + SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * Like table_beginscan(), but for scanning catalog. It'll automatically use a + * snapshot appropriate for scanning catalog relations. + */ +extern TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, + struct ScanKeyData *key); + +/* + * Like table_beginscan(), but table_beginscan_strat() offers an extended API + * that lets the caller control whether a nondefault buffer access strategy + * can be used, and whether syncscan can be chosen (possibly resulting in the + * scan not starting from block zero). Both of these default to true with + * plain table_beginscan. + */ +static inline TableScanDesc +table_beginscan_strat(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key, + bool allow_strat, bool allow_sync) +{ + uint32 flags = SO_TYPE_SEQSCAN | SO_ALLOW_PAGEMODE; + + if (allow_strat) + flags |= SO_ALLOW_STRAT; + if (allow_sync) + flags |= SO_ALLOW_SYNC; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * table_beginscan_bm is an alternative entry point for setting up a + * TableScanDesc for a bitmap heap scan. Although that scan technology is + * really quite unlike a standard seqscan, there is just enough commonality to + * make it worth using the same data structure. + */ +static inline TableScanDesc +table_beginscan_bm(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key) +{ + uint32 flags = SO_TYPE_BITMAPSCAN | SO_ALLOW_PAGEMODE; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * table_beginscan_sampling is an alternative entry point for setting up a + * TableScanDesc for a TABLESAMPLE scan. As with bitmap scans, it's worth + * using the same data structure although the behavior is rather different. + * In addition to the options offered by table_beginscan_strat, this call + * also allows control of whether page-mode visibility checking is used. + */ +static inline TableScanDesc +table_beginscan_sampling(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key, + bool allow_strat, bool allow_sync, + bool allow_pagemode) +{ + uint32 flags = SO_TYPE_SAMPLESCAN; + + if (allow_strat) + flags |= SO_ALLOW_STRAT; + if (allow_sync) + flags |= SO_ALLOW_SYNC; + if (allow_pagemode) + flags |= SO_ALLOW_PAGEMODE; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * table_beginscan_tid is an alternative entry point for setting up a + * TableScanDesc for a Tid scan. As with bitmap scans, it's worth using + * the same data structure although the behavior is rather different. + */ +static inline TableScanDesc +table_beginscan_tid(Relation rel, Snapshot snapshot) +{ + uint32 flags = SO_TYPE_TIDSCAN; + + return rel->rd_tableam->scan_begin(rel, snapshot, 0, NULL, NULL, flags); +} + +/* + * table_beginscan_analyze is an alternative entry point for setting up a + * TableScanDesc for an ANALYZE scan. As with bitmap scans, it's worth using + * the same data structure although the behavior is rather different. + */ +static inline TableScanDesc +table_beginscan_analyze(Relation rel) +{ + uint32 flags = SO_TYPE_ANALYZE; + + return rel->rd_tableam->scan_begin(rel, NULL, 0, NULL, NULL, flags); +} + +/* + * End relation scan. + */ +static inline void +table_endscan(TableScanDesc scan) +{ + scan->rs_rd->rd_tableam->scan_end(scan); +} + +/* + * Restart a relation scan. + */ +static inline void +table_rescan(TableScanDesc scan, + struct ScanKeyData *key) +{ + scan->rs_rd->rd_tableam->scan_rescan(scan, key, false, false, false, false); +} + +/* + * Restart a relation scan after changing params. + * + * This call allows changing the buffer strategy, syncscan, and pagemode + * options before starting a fresh scan. Note that although the actual use of + * syncscan might change (effectively, enabling or disabling reporting), the + * previously selected startblock will be kept. + */ +static inline void +table_rescan_set_params(TableScanDesc scan, struct ScanKeyData *key, + bool allow_strat, bool allow_sync, bool allow_pagemode) +{ + scan->rs_rd->rd_tableam->scan_rescan(scan, key, true, + allow_strat, allow_sync, + allow_pagemode); +} + +/* + * Update snapshot used by the scan. + */ +extern void table_scan_update_snapshot(TableScanDesc scan, Snapshot snapshot); + +/* + * Return next tuple from `scan`, store in slot. + */ +static inline bool +table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot) +{ + slot->tts_tableOid = RelationGetRelid(sscan->rs_rd); + + /* We don't expect actual scans using NoMovementScanDirection */ + Assert(direction == ForwardScanDirection || + direction == BackwardScanDirection); + + /* + * We don't expect direct calls to table_scan_getnextslot with valid + * CheckXidAlive for catalog or regular tables. See detailed comments in + * xact.c where these variables are declared. + */ + if (unlikely(TransactionIdIsValid(CheckXidAlive) && !bsysscan)) + elog(ERROR, "unexpected table_scan_getnextslot call during logical decoding"); + + return sscan->rs_rd->rd_tableam->scan_getnextslot(sscan, direction, slot); +} + +/* ---------------------------------------------------------------------------- + * TID Range scanning related functions. + * ---------------------------------------------------------------------------- + */ + +/* + * table_beginscan_tidrange is the entry point for setting up a TableScanDesc + * for a TID range scan. + */ +static inline TableScanDesc +table_beginscan_tidrange(Relation rel, Snapshot snapshot, + ItemPointer mintid, + ItemPointer maxtid) +{ + TableScanDesc sscan; + uint32 flags = SO_TYPE_TIDRANGESCAN | SO_ALLOW_PAGEMODE; + + sscan = rel->rd_tableam->scan_begin(rel, snapshot, 0, NULL, NULL, flags); + + /* Set the range of TIDs to scan */ + sscan->rs_rd->rd_tableam->scan_set_tidrange(sscan, mintid, maxtid); + + return sscan; +} + +/* + * table_rescan_tidrange resets the scan position and sets the minimum and + * maximum TID range to scan for a TableScanDesc created by + * table_beginscan_tidrange. + */ +static inline void +table_rescan_tidrange(TableScanDesc sscan, ItemPointer mintid, + ItemPointer maxtid) +{ + /* Ensure table_beginscan_tidrange() was used. */ + Assert((sscan->rs_flags & SO_TYPE_TIDRANGESCAN) != 0); + + sscan->rs_rd->rd_tableam->scan_rescan(sscan, NULL, false, false, false, false); + sscan->rs_rd->rd_tableam->scan_set_tidrange(sscan, mintid, maxtid); +} + +/* + * Fetch the next tuple from `sscan` for a TID range scan created by + * table_beginscan_tidrange(). Stores the tuple in `slot` and returns true, + * or returns false if no more tuples exist in the range. + */ +static inline bool +table_scan_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction, + TupleTableSlot *slot) +{ + /* Ensure table_beginscan_tidrange() was used. */ + Assert((sscan->rs_flags & SO_TYPE_TIDRANGESCAN) != 0); + + /* We don't expect actual scans using NoMovementScanDirection */ + Assert(direction == ForwardScanDirection || + direction == BackwardScanDirection); + + return sscan->rs_rd->rd_tableam->scan_getnextslot_tidrange(sscan, + direction, + slot); +} + + +/* ---------------------------------------------------------------------------- + * Parallel table scan related functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Estimate the size of shared memory needed for a parallel scan of this + * relation. + */ +extern Size table_parallelscan_estimate(Relation rel, Snapshot snapshot); + +/* + * Initialize ParallelTableScanDesc for a parallel scan of this + * relation. `pscan` needs to be sized according to parallelscan_estimate() + * for the same relation. Call this just once in the leader process; then, + * individual workers attach via table_beginscan_parallel. + */ +extern void table_parallelscan_initialize(Relation rel, + ParallelTableScanDesc pscan, + Snapshot snapshot); + +/* + * Begin a parallel scan. `pscan` needs to have been initialized with + * table_parallelscan_initialize(), for the same relation. The initialization + * does not need to have happened in this backend. + * + * Caller must hold a suitable lock on the relation. + */ +extern TableScanDesc table_beginscan_parallel(Relation relation, + ParallelTableScanDesc pscan); + +/* + * Restart a parallel scan. Call this in the leader process. Caller is + * responsible for making sure that all workers have finished the scan + * beforehand. + */ +static inline void +table_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan) +{ + rel->rd_tableam->parallelscan_reinitialize(rel, pscan); +} + + +/* ---------------------------------------------------------------------------- + * Index scan related functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Prepare to fetch tuples from the relation, as needed when fetching tuples + * for an index scan. + * + * Tuples for an index scan can then be fetched via table_index_fetch_tuple(). + */ +static inline IndexFetchTableData * +table_index_fetch_begin(Relation rel) +{ + return rel->rd_tableam->index_fetch_begin(rel); +} + +/* + * Reset index fetch. Typically this will release cross index fetch resources + * held in IndexFetchTableData. + */ +static inline void +table_index_fetch_reset(struct IndexFetchTableData *scan) +{ + scan->rel->rd_tableam->index_fetch_reset(scan); +} + +/* + * Release resources and deallocate index fetch. + */ +static inline void +table_index_fetch_end(struct IndexFetchTableData *scan) +{ + scan->rel->rd_tableam->index_fetch_end(scan); +} + +/* + * Fetches, as part of an index scan, tuple at `tid` into `slot`, after doing + * a visibility test according to `snapshot`. If a tuple was found and passed + * the visibility test, returns true, false otherwise. Note that *tid may be + * modified when we return true (see later remarks on multiple row versions + * reachable via a single index entry). + * + * *call_again needs to be false on the first call to table_index_fetch_tuple() for + * a tid. If there potentially is another tuple matching the tid, *call_again + * will be set to true, signaling that table_index_fetch_tuple() should be called + * again for the same tid. + * + * *all_dead, if all_dead is not NULL, will be set to true by + * table_index_fetch_tuple() iff it is guaranteed that no backend needs to see + * that tuple. Index AMs can use that to avoid returning that tid in future + * searches. + * + * The difference between this function and table_tuple_fetch_row_version() + * is that this function returns the currently visible version of a row if + * the AM supports storing multiple row versions reachable via a single index + * entry (like heap's HOT). Whereas table_tuple_fetch_row_version() only + * evaluates the tuple exactly at `tid`. Outside of index entry ->table tuple + * lookups, table_tuple_fetch_row_version() is what's usually needed. + */ +static inline bool +table_index_fetch_tuple(struct IndexFetchTableData *scan, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot, + bool *call_again, bool *all_dead) +{ + /* + * We don't expect direct calls to table_index_fetch_tuple with valid + * CheckXidAlive for catalog or regular tables. See detailed comments in + * xact.c where these variables are declared. + */ + if (unlikely(TransactionIdIsValid(CheckXidAlive) && !bsysscan)) + elog(ERROR, "unexpected table_index_fetch_tuple call during logical decoding"); + + return scan->rel->rd_tableam->index_fetch_tuple(scan, tid, snapshot, + slot, call_again, + all_dead); +} + +/* + * This is a convenience wrapper around table_index_fetch_tuple() which + * returns whether there are table tuple items corresponding to an index + * entry. This likely is only useful to verify if there's a conflict in a + * unique index. + */ +extern bool table_index_fetch_tuple_check(Relation rel, + ItemPointer tid, + Snapshot snapshot, + bool *all_dead); + + +/* ------------------------------------------------------------------------ + * Functions for non-modifying operations on individual tuples + * ------------------------------------------------------------------------ + */ + + +/* + * Fetch tuple at `tid` into `slot`, after doing a visibility test according to + * `snapshot`. If a tuple was found and passed the visibility test, returns + * true, false otherwise. + * + * See table_index_fetch_tuple's comment about what the difference between + * these functions is. It is correct to use this function outside of index + * entry->table tuple lookups. + */ +static inline bool +table_tuple_fetch_row_version(Relation rel, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot) +{ + /* + * We don't expect direct calls to table_tuple_fetch_row_version with + * valid CheckXidAlive for catalog or regular tables. See detailed + * comments in xact.c where these variables are declared. + */ + if (unlikely(TransactionIdIsValid(CheckXidAlive) && !bsysscan)) + elog(ERROR, "unexpected table_tuple_fetch_row_version call during logical decoding"); + + return rel->rd_tableam->tuple_fetch_row_version(rel, tid, snapshot, slot); +} + +/* + * Verify that `tid` is a potentially valid tuple identifier. That doesn't + * mean that the pointed to row needs to exist or be visible, but that + * attempting to fetch the row (e.g. with table_tuple_get_latest_tid() or + * table_tuple_fetch_row_version()) should not error out if called with that + * tid. + * + * `scan` needs to have been started via table_beginscan(). + */ +static inline bool +table_tuple_tid_valid(TableScanDesc scan, ItemPointer tid) +{ + return scan->rs_rd->rd_tableam->tuple_tid_valid(scan, tid); +} + +/* + * Return the latest version of the tuple at `tid`, by updating `tid` to + * point at the newest version. + */ +extern void table_tuple_get_latest_tid(TableScanDesc scan, ItemPointer tid); + +/* + * Return true iff tuple in slot satisfies the snapshot. + * + * This assumes the slot's tuple is valid, and of the appropriate type for the + * AM. + * + * Some AMs might modify the data underlying the tuple as a side-effect. If so + * they ought to mark the relevant buffer dirty. + */ +static inline bool +table_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, + Snapshot snapshot) +{ + return rel->rd_tableam->tuple_satisfies_snapshot(rel, slot, snapshot); +} + +/* + * Determine which index tuples are safe to delete based on their table TID. + * + * Determines which entries from index AM caller's TM_IndexDeleteOp state + * point to vacuumable table tuples. Entries that are found by tableam to be + * vacuumable are naturally safe for index AM to delete, and so get directly + * marked as deletable. See comments above TM_IndexDelete and comments above + * TM_IndexDeleteOp for full details. + * + * Returns a snapshotConflictHorizon transaction ID that caller places in + * its index deletion WAL record. This might be used during subsequent REDO + * of the WAL record when in Hot Standby mode -- a recovery conflict for the + * index deletion operation might be required on the standby. + */ +static inline TransactionId +table_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate) +{ + return rel->rd_tableam->index_delete_tuples(rel, delstate); +} + + +/* ---------------------------------------------------------------------------- + * Functions for manipulations of physical tuples. + * ---------------------------------------------------------------------------- + */ + +/* + * Insert a tuple from a slot into table AM routine. + * + * The options bitmask allows the caller to specify options that may change the + * behaviour of the AM. The AM will ignore options that it does not support. + * + * If the TABLE_INSERT_SKIP_FSM option is specified, AMs are free to not reuse + * free space in the relation. This can save some cycles when we know the + * relation is new and doesn't contain useful amounts of free space. + * TABLE_INSERT_SKIP_FSM is commonly passed directly to + * RelationGetBufferForTuple. See that method for more information. + * + * TABLE_INSERT_FROZEN should only be specified for inserts into + * relation storage created during the current subtransaction and when + * there are no prior snapshots or pre-existing portals open. + * This causes rows to be frozen, which is an MVCC violation and + * requires explicit options chosen by user. + * + * TABLE_INSERT_NO_LOGICAL force-disables the emitting of logical decoding + * information for the tuple. This should solely be used during table rewrites + * where RelationIsLogicallyLogged(relation) is not yet accurate for the new + * relation. + * + * Note that most of these options will be applied when inserting into the + * heap's TOAST table, too, if the tuple requires any out-of-line data. + * + * The BulkInsertState object (if any; bistate can be NULL for default + * behavior) is also just passed through to RelationGetBufferForTuple. If + * `bistate` is provided, table_finish_bulk_insert() needs to be called. + * + * On return the slot's tts_tid and tts_tableOid are updated to reflect the + * insertion. But note that any toasting of fields within the slot is NOT + * reflected in the slots contents. + */ +static inline void +table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, + int options, struct BulkInsertStateData *bistate) +{ + rel->rd_tableam->tuple_insert(rel, slot, cid, options, + bistate); +} + +/* + * Perform a "speculative insertion". These can be backed out afterwards + * without aborting the whole transaction. Other sessions can wait for the + * speculative insertion to be confirmed, turning it into a regular tuple, or + * aborted, as if it never existed. Speculatively inserted tuples behave as + * "value locks" of short duration, used to implement INSERT .. ON CONFLICT. + * + * A transaction having performed a speculative insertion has to either abort, + * or finish the speculative insertion with + * table_tuple_complete_speculative(succeeded = ...). + */ +static inline void +table_tuple_insert_speculative(Relation rel, TupleTableSlot *slot, + CommandId cid, int options, + struct BulkInsertStateData *bistate, + uint32 specToken) +{ + rel->rd_tableam->tuple_insert_speculative(rel, slot, cid, options, + bistate, specToken); +} + +/* + * Complete "speculative insertion" started in the same transaction. If + * succeeded is true, the tuple is fully inserted, if false, it's removed. + */ +static inline void +table_tuple_complete_speculative(Relation rel, TupleTableSlot *slot, + uint32 specToken, bool succeeded) +{ + rel->rd_tableam->tuple_complete_speculative(rel, slot, specToken, + succeeded); +} + +/* + * Insert multiple tuples into a table. + * + * This is like table_tuple_insert(), but inserts multiple tuples in one + * operation. That's often faster than calling table_tuple_insert() in a loop, + * because e.g. the AM can reduce WAL logging and page locking overhead. + * + * Except for taking `nslots` tuples as input, and an array of TupleTableSlots + * in `slots`, the parameters for table_multi_insert() are the same as for + * table_tuple_insert(). + * + * Note: this leaks memory into the current memory context. You can create a + * temporary context before calling this, if that's a problem. + */ +static inline void +table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, + CommandId cid, int options, struct BulkInsertStateData *bistate) +{ + rel->rd_tableam->multi_insert(rel, slots, nslots, + cid, options, bistate); +} + +/* + * Delete a tuple. + * + * NB: do not call this directly unless prepared to deal with + * concurrent-update conditions. Use simple_table_tuple_delete instead. + * + * Input parameters: + * relation - table to be modified (caller must hold suitable lock) + * tid - TID of tuple to be deleted + * cid - delete command ID (used for visibility test, and stored into + * cmax if successful) + * crosscheck - if not InvalidSnapshot, also check tuple against this + * wait - true if should wait for any conflicting update to commit/abort + * Output parameters: + * tmfd - filled in failure cases (see below) + * changingPart - true iff the tuple is being moved to another partition + * table due to an update of the partition key. Otherwise, false. + * + * Normal, successful return value is TM_Ok, which means we did actually + * delete it. Failure return codes are TM_SelfModified, TM_Updated, and + * TM_BeingModified (the last only possible if wait == false). + * + * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, + * t_xmax, and, if possible, t_cmax. See comments for struct + * TM_FailureData for additional info. + */ +static inline TM_Result +table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, + Snapshot snapshot, Snapshot crosscheck, bool wait, + TM_FailureData *tmfd, bool changingPart) +{ + return rel->rd_tableam->tuple_delete(rel, tid, cid, + snapshot, crosscheck, + wait, tmfd, changingPart); +} + +/* + * Update a tuple. + * + * NB: do not call this directly unless you are prepared to deal with + * concurrent-update conditions. Use simple_table_tuple_update instead. + * + * Input parameters: + * relation - table to be modified (caller must hold suitable lock) + * otid - TID of old tuple to be replaced + * slot - newly constructed tuple data to store + * cid - update command ID (used for visibility test, and stored into + * cmax/cmin if successful) + * crosscheck - if not InvalidSnapshot, also check old tuple against this + * wait - true if should wait for any conflicting update to commit/abort + * Output parameters: + * tmfd - filled in failure cases (see below) + * lockmode - filled with lock mode acquired on tuple + * update_indexes - in success cases this is set if new index entries + * are required for this tuple; see TU_UpdateIndexes + * + * Normal, successful return value is TM_Ok, which means we did actually + * update it. Failure return codes are TM_SelfModified, TM_Updated, and + * TM_BeingModified (the last only possible if wait == false). + * + * On success, the slot's tts_tid and tts_tableOid are updated to match the new + * stored tuple; in particular, slot->tts_tid is set to the TID where the + * new tuple was inserted, and its HEAP_ONLY_TUPLE flag is set iff a HOT + * update was done. However, any TOAST changes in the new tuple's + * data are not reflected into *newtup. + * + * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, + * t_xmax, and, if possible, t_cmax. See comments for struct TM_FailureData + * for additional info. + */ +static inline TM_Result +table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, + CommandId cid, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, + TU_UpdateIndexes *update_indexes) +{ + return rel->rd_tableam->tuple_update(rel, otid, slot, + cid, snapshot, crosscheck, + wait, tmfd, + lockmode, update_indexes); +} + +/* + * Lock a tuple in the specified mode. + * + * Input parameters: + * relation: relation containing tuple (caller must hold suitable lock) + * tid: TID of tuple to lock (updated if an update chain was followed) + * snapshot: snapshot to use for visibility determinations + * cid: current command ID (used for visibility test, and stored into + * tuple's cmax if lock is successful) + * mode: lock mode desired + * wait_policy: what to do if tuple lock is not available + * flags: + * If TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS, follow the update chain to + * also lock descendant tuples if lock modes don't conflict. + * If TUPLE_LOCK_FLAG_FIND_LAST_VERSION, follow the update chain and lock + * latest version. + * + * Output parameters: + * *slot: contains the target tuple + * *tmfd: filled in failure cases (see below) + * + * Function result may be: + * TM_Ok: lock was successfully acquired + * TM_Invisible: lock failed because tuple was never visible to us + * TM_SelfModified: lock failed because tuple updated by self + * TM_Updated: lock failed because tuple updated by other xact + * TM_Deleted: lock failed because tuple deleted by other xact + * TM_WouldBlock: lock couldn't be acquired and wait_policy is skip + * + * In the failure cases other than TM_Invisible and TM_Deleted, the routine + * fills *tmfd with the tuple's t_ctid, t_xmax, and, if possible, t_cmax. + * Additionally, in both success and failure cases, tmfd->traversed is set if + * an update chain was followed. See comments for struct TM_FailureData for + * additional info. + */ +static inline TM_Result +table_tuple_lock(Relation rel, ItemPointer tid, Snapshot snapshot, + TupleTableSlot *slot, CommandId cid, LockTupleMode mode, + LockWaitPolicy wait_policy, uint8 flags, + TM_FailureData *tmfd) +{ + return rel->rd_tableam->tuple_lock(rel, tid, snapshot, slot, + cid, mode, wait_policy, + flags, tmfd); +} + +/* + * Perform operations necessary to complete insertions made via + * tuple_insert and multi_insert with a BulkInsertState specified. + */ +static inline void +table_finish_bulk_insert(Relation rel, int options) +{ + /* optional callback */ + if (rel->rd_tableam && rel->rd_tableam->finish_bulk_insert) + rel->rd_tableam->finish_bulk_insert(rel, options); +} + + +/* ------------------------------------------------------------------------ + * DDL related functionality. + * ------------------------------------------------------------------------ + */ + +/* + * Create storage for `rel` in `newrlocator`, with persistence set to + * `persistence`. + * + * This is used both during relation creation and various DDL operations to + * create new rel storage that can be filled from scratch. When creating + * new storage for an existing relfilelocator, this should be called before the + * relcache entry has been updated. + * + * *freezeXid, *minmulti are set to the xid / multixact horizon for the table + * that pg_class.{relfrozenxid, relminmxid} have to be set to. + */ +static inline void +table_relation_set_new_filelocator(Relation rel, + const RelFileLocator *newrlocator, + char persistence, + TransactionId *freezeXid, + MultiXactId *minmulti) +{ + rel->rd_tableam->relation_set_new_filelocator(rel, newrlocator, + persistence, freezeXid, + minmulti); +} + +/* + * Remove all table contents from `rel`, in a non-transactional manner. + * Non-transactional meaning that there's no need to support rollbacks. This + * commonly only is used to perform truncations for relation storage created in + * the current transaction. + */ +static inline void +table_relation_nontransactional_truncate(Relation rel) +{ + rel->rd_tableam->relation_nontransactional_truncate(rel); +} + +/* + * Copy data from `rel` into the new relfilelocator `newrlocator`. The new + * relfilelocator may not have storage associated before this function is + * called. This is only supposed to be used for low level operations like + * changing a relation's tablespace. + */ +static inline void +table_relation_copy_data(Relation rel, const RelFileLocator *newrlocator) +{ + rel->rd_tableam->relation_copy_data(rel, newrlocator); +} + +/* + * Copy data from `OldTable` into `NewTable`, as part of a CLUSTER or VACUUM + * FULL. + * + * Additional Input parameters: + * - use_sort - if true, the table contents are sorted appropriate for + * `OldIndex`; if false and OldIndex is not InvalidOid, the data is copied + * in that index's order; if false and OldIndex is InvalidOid, no sorting is + * performed + * - OldIndex - see use_sort + * - OldestXmin - computed by vacuum_get_cutoffs(), even when + * not needed for the relation's AM + * - *xid_cutoff - ditto + * - *multi_cutoff - ditto + * + * Output parameters: + * - *xid_cutoff - rel's new relfrozenxid value, may be invalid + * - *multi_cutoff - rel's new relminmxid value, may be invalid + * - *tups_vacuumed - stats, for logging, if appropriate for AM + * - *tups_recently_dead - stats, for logging, if appropriate for AM + */ +static inline void +table_relation_copy_for_cluster(Relation OldTable, Relation NewTable, + Relation OldIndex, + bool use_sort, + TransactionId OldestXmin, + TransactionId *xid_cutoff, + MultiXactId *multi_cutoff, + double *num_tuples, + double *tups_vacuumed, + double *tups_recently_dead) +{ + OldTable->rd_tableam->relation_copy_for_cluster(OldTable, NewTable, OldIndex, + use_sort, OldestXmin, + xid_cutoff, multi_cutoff, + num_tuples, tups_vacuumed, + tups_recently_dead); +} + +/* + * Perform VACUUM on the relation. The VACUUM can be triggered by a user or by + * autovacuum. The specific actions performed by the AM will depend heavily on + * the individual AM. + * + * On entry a transaction needs to already been established, and the + * table is locked with a ShareUpdateExclusive lock. + * + * Note that neither VACUUM FULL (and CLUSTER), nor ANALYZE go through this + * routine, even if (for ANALYZE) it is part of the same VACUUM command. + */ +static inline void +table_relation_vacuum(Relation rel, struct VacuumParams *params, + BufferAccessStrategy bstrategy) +{ + rel->rd_tableam->relation_vacuum(rel, params, bstrategy); +} + +/* + * Prepare to analyze block `blockno` of `scan`. The scan needs to have been + * started with table_beginscan_analyze(). Note that this routine might + * acquire resources like locks that are held until + * table_scan_analyze_next_tuple() returns false. + * + * Returns false if block is unsuitable for sampling, true otherwise. + */ +static inline bool +table_scan_analyze_next_block(TableScanDesc scan, BlockNumber blockno, + BufferAccessStrategy bstrategy) +{ + return scan->rs_rd->rd_tableam->scan_analyze_next_block(scan, blockno, + bstrategy); +} + +/* + * Iterate over tuples in the block selected with + * table_scan_analyze_next_block() (which needs to have returned true, and + * this routine may not have returned false for the same block before). If a + * tuple that's suitable for sampling is found, true is returned and a tuple + * is stored in `slot`. + * + * *liverows and *deadrows are incremented according to the encountered + * tuples. + */ +static inline bool +table_scan_analyze_next_tuple(TableScanDesc scan, TransactionId OldestXmin, + double *liverows, double *deadrows, + TupleTableSlot *slot) +{ + return scan->rs_rd->rd_tableam->scan_analyze_next_tuple(scan, OldestXmin, + liverows, deadrows, + slot); +} + +/* + * table_index_build_scan - scan the table to find tuples to be indexed + * + * This is called back from an access-method-specific index build procedure + * after the AM has done whatever setup it needs. The parent table relation + * is scanned to find tuples that should be entered into the index. Each + * such tuple is passed to the AM's callback routine, which does the right + * things to add it to the new index. After we return, the AM's index + * build procedure does whatever cleanup it needs. + * + * The total count of live tuples is returned. This is for updating pg_class + * statistics. (It's annoying not to be able to do that here, but we want to + * merge that update with others; see index_update_stats.) Note that the + * index AM itself must keep track of the number of index tuples; we don't do + * so here because the AM might reject some of the tuples for its own reasons, + * such as being unable to store NULLs. + * + * If 'progress', the PROGRESS_SCAN_BLOCKS_TOTAL counter is updated when + * starting the scan, and PROGRESS_SCAN_BLOCKS_DONE is updated as we go along. + * + * A side effect is to set indexInfo->ii_BrokenHotChain to true if we detect + * any potentially broken HOT chains. Currently, we set this if there are any + * RECENTLY_DEAD or DELETE_IN_PROGRESS entries in a HOT chain, without trying + * very hard to detect whether they're really incompatible with the chain tip. + * This only really makes sense for heap AM, it might need to be generalized + * for other AMs later. + */ +static inline double +table_index_build_scan(Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + bool allow_sync, + bool progress, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan) +{ + return table_rel->rd_tableam->index_build_range_scan(table_rel, + index_rel, + index_info, + allow_sync, + false, + progress, + 0, + InvalidBlockNumber, + callback, + callback_state, + scan); +} + +/* + * As table_index_build_scan(), except that instead of scanning the complete + * table, only the given number of blocks are scanned. Scan to end-of-rel can + * be signaled by passing InvalidBlockNumber as numblocks. Note that + * restricting the range to scan cannot be done when requesting syncscan. + * + * When "anyvisible" mode is requested, all tuples visible to any transaction + * are indexed and counted as live, including those inserted or deleted by + * transactions that are still in progress. + */ +static inline double +table_index_build_range_scan(Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + bool allow_sync, + bool anyvisible, + bool progress, + BlockNumber start_blockno, + BlockNumber numblocks, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan) +{ + return table_rel->rd_tableam->index_build_range_scan(table_rel, + index_rel, + index_info, + allow_sync, + anyvisible, + progress, + start_blockno, + numblocks, + callback, + callback_state, + scan); +} + +/* + * table_index_validate_scan - second table scan for concurrent index build + * + * See validate_index() for an explanation. + */ +static inline void +table_index_validate_scan(Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + Snapshot snapshot, + struct ValidateIndexState *state) +{ + table_rel->rd_tableam->index_validate_scan(table_rel, + index_rel, + index_info, + snapshot, + state); +} + + +/* ---------------------------------------------------------------------------- + * Miscellaneous functionality + * ---------------------------------------------------------------------------- + */ + +/* + * Return the current size of `rel` in bytes. If `forkNumber` is + * InvalidForkNumber, return the relation's overall size, otherwise the size + * for the indicated fork. + * + * Note that the overall size might not be the equivalent of the sum of sizes + * for the individual forks for some AMs, e.g. because the AMs storage does + * not neatly map onto the builtin types of forks. + */ +static inline uint64 +table_relation_size(Relation rel, ForkNumber forkNumber) +{ + return rel->rd_tableam->relation_size(rel, forkNumber); +} + +/* + * table_relation_needs_toast_table - does this relation need a toast table? + */ +static inline bool +table_relation_needs_toast_table(Relation rel) +{ + return rel->rd_tableam->relation_needs_toast_table(rel); +} + +/* + * Return the OID of the AM that should be used to implement the TOAST table + * for this relation. + */ +static inline Oid +table_relation_toast_am(Relation rel) +{ + return rel->rd_tableam->relation_toast_am(rel); +} + +/* + * Fetch all or part of a TOAST value from a TOAST table. + * + * If this AM is never used to implement a TOAST table, then this callback + * is not needed. But, if toasted values are ever stored in a table of this + * type, then you will need this callback. + * + * toastrel is the relation in which the toasted value is stored. + * + * valueid identifies which toast value is to be fetched. For the heap, + * this corresponds to the values stored in the chunk_id column. + * + * attrsize is the total size of the toast value to be fetched. + * + * sliceoffset is the offset within the toast value of the first byte that + * should be fetched. + * + * slicelength is the number of bytes from the toast value that should be + * fetched. + * + * result is caller-allocated space into which the fetched bytes should be + * stored. + */ +static inline void +table_relation_fetch_toast_slice(Relation toastrel, Oid valueid, + int32 attrsize, int32 sliceoffset, + int32 slicelength, struct varlena *result) +{ + toastrel->rd_tableam->relation_fetch_toast_slice(toastrel, valueid, + attrsize, + sliceoffset, slicelength, + result); +} + + +/* ---------------------------------------------------------------------------- + * Planner related functionality + * ---------------------------------------------------------------------------- + */ + +/* + * Estimate the current size of the relation, as an AM specific workhorse for + * estimate_rel_size(). Look there for an explanation of the parameters. + */ +static inline void +table_relation_estimate_size(Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, + double *allvisfrac) +{ + rel->rd_tableam->relation_estimate_size(rel, attr_widths, pages, tuples, + allvisfrac); +} + + +/* ---------------------------------------------------------------------------- + * Executor related functionality + * ---------------------------------------------------------------------------- + */ + +/* + * Prepare to fetch / check / return tuples from `tbmres->blockno` as part of + * a bitmap table scan. `scan` needs to have been started via + * table_beginscan_bm(). Returns false if there are no tuples to be found on + * the page, true otherwise. + * + * Note, this is an optionally implemented function, therefore should only be + * used after verifying the presence (at plan time or such). + */ +static inline bool +table_scan_bitmap_next_block(TableScanDesc scan, + struct TBMIterateResult *tbmres) +{ + /* + * We don't expect direct calls to table_scan_bitmap_next_block with valid + * CheckXidAlive for catalog or regular tables. See detailed comments in + * xact.c where these variables are declared. + */ + if (unlikely(TransactionIdIsValid(CheckXidAlive) && !bsysscan)) + elog(ERROR, "unexpected table_scan_bitmap_next_block call during logical decoding"); + + return scan->rs_rd->rd_tableam->scan_bitmap_next_block(scan, + tbmres); +} + +/* + * Fetch the next tuple of a bitmap table scan into `slot` and return true if + * a visible tuple was found, false otherwise. + * table_scan_bitmap_next_block() needs to previously have selected a + * block (i.e. returned true), and no previous + * table_scan_bitmap_next_tuple() for the same block may have + * returned false. + */ +static inline bool +table_scan_bitmap_next_tuple(TableScanDesc scan, + struct TBMIterateResult *tbmres, + TupleTableSlot *slot) +{ + /* + * We don't expect direct calls to table_scan_bitmap_next_tuple with valid + * CheckXidAlive for catalog or regular tables. See detailed comments in + * xact.c where these variables are declared. + */ + if (unlikely(TransactionIdIsValid(CheckXidAlive) && !bsysscan)) + elog(ERROR, "unexpected table_scan_bitmap_next_tuple call during logical decoding"); + + return scan->rs_rd->rd_tableam->scan_bitmap_next_tuple(scan, + tbmres, + slot); +} + +/* + * Prepare to fetch tuples from the next block in a sample scan. Returns false + * if the sample scan is finished, true otherwise. `scan` needs to have been + * started via table_beginscan_sampling(). + * + * This will call the TsmRoutine's NextSampleBlock() callback if necessary + * (i.e. NextSampleBlock is not NULL), or perform a sequential scan over the + * underlying relation. + */ +static inline bool +table_scan_sample_next_block(TableScanDesc scan, + struct SampleScanState *scanstate) +{ + /* + * We don't expect direct calls to table_scan_sample_next_block with valid + * CheckXidAlive for catalog or regular tables. See detailed comments in + * xact.c where these variables are declared. + */ + if (unlikely(TransactionIdIsValid(CheckXidAlive) && !bsysscan)) + elog(ERROR, "unexpected table_scan_sample_next_block call during logical decoding"); + return scan->rs_rd->rd_tableam->scan_sample_next_block(scan, scanstate); +} + +/* + * Fetch the next sample tuple into `slot` and return true if a visible tuple + * was found, false otherwise. table_scan_sample_next_block() needs to + * previously have selected a block (i.e. returned true), and no previous + * table_scan_sample_next_tuple() for the same block may have returned false. + * + * This will call the TsmRoutine's NextSampleTuple() callback. + */ +static inline bool +table_scan_sample_next_tuple(TableScanDesc scan, + struct SampleScanState *scanstate, + TupleTableSlot *slot) +{ + /* + * We don't expect direct calls to table_scan_sample_next_tuple with valid + * CheckXidAlive for catalog or regular tables. See detailed comments in + * xact.c where these variables are declared. + */ + if (unlikely(TransactionIdIsValid(CheckXidAlive) && !bsysscan)) + elog(ERROR, "unexpected table_scan_sample_next_tuple call during logical decoding"); + return scan->rs_rd->rd_tableam->scan_sample_next_tuple(scan, scanstate, + slot); +} + + +/* ---------------------------------------------------------------------------- + * Functions to make modifications a bit simpler. + * ---------------------------------------------------------------------------- + */ + +extern void simple_table_tuple_insert(Relation rel, TupleTableSlot *slot); +extern void simple_table_tuple_delete(Relation rel, ItemPointer tid, + Snapshot snapshot); +extern void simple_table_tuple_update(Relation rel, ItemPointer otid, + TupleTableSlot *slot, Snapshot snapshot, + TU_UpdateIndexes *update_indexes); + + +/* ---------------------------------------------------------------------------- + * Helper functions to implement parallel scans for block oriented AMs. + * ---------------------------------------------------------------------------- + */ + +extern Size table_block_parallelscan_estimate(Relation rel); +extern Size table_block_parallelscan_initialize(Relation rel, + ParallelTableScanDesc pscan); +extern void table_block_parallelscan_reinitialize(Relation rel, + ParallelTableScanDesc pscan); +extern BlockNumber table_block_parallelscan_nextpage(Relation rel, + ParallelBlockTableScanWorker pbscanwork, + ParallelBlockTableScanDesc pbscan); +extern void table_block_parallelscan_startblock_init(Relation rel, + ParallelBlockTableScanWorker pbscanwork, + ParallelBlockTableScanDesc pbscan); + + +/* ---------------------------------------------------------------------------- + * Helper functions to implement relation sizing for block oriented AMs. + * ---------------------------------------------------------------------------- + */ + +extern uint64 table_block_relation_size(Relation rel, ForkNumber forkNumber); +extern void table_block_relation_estimate_size(Relation rel, + int32 *attr_widths, + BlockNumber *pages, + double *tuples, + double *allvisfrac, + Size overhead_bytes_per_tuple, + Size usable_bytes_per_page); + +/* ---------------------------------------------------------------------------- + * Functions in tableamapi.c + * ---------------------------------------------------------------------------- + */ + +extern const TableAmRoutine *GetTableAmRoutine(Oid amhandler); +extern const TableAmRoutine *GetHeapamTableAmRoutine(void); + +#endif /* TABLEAM_H */ diff --git a/install/include/postgresql/server/access/timeline.h b/install/include/postgresql/server/access/timeline.h new file mode 100644 index 00000000000..72e3622b458 --- /dev/null +++ b/install/include/postgresql/server/access/timeline.h @@ -0,0 +1,44 @@ +/* + * timeline.h + * + * Functions for reading and writing timeline history files. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/timeline.h + */ +#ifndef TIMELINE_H +#define TIMELINE_H + +#include "access/xlogdefs.h" +#include "nodes/pg_list.h" + +/* + * A list of these structs describes the timeline history of the server. Each + * TimeLineHistoryEntry represents a piece of WAL belonging to the history, + * from newest to oldest. All WAL locations between 'begin' and 'end' belong to + * the timeline represented by the entry. Together the 'begin' and 'end' + * pointers of all the entries form a contiguous line from beginning of time + * to infinity. + */ +typedef struct +{ + TimeLineID tli; + XLogRecPtr begin; /* inclusive */ + XLogRecPtr end; /* exclusive, InvalidXLogRecPtr means infinity */ +} TimeLineHistoryEntry; + +extern List *readTimeLineHistory(TimeLineID targetTLI); +extern bool existsTimeLineHistory(TimeLineID probeTLI); +extern TimeLineID findNewestTimeLine(TimeLineID startTLI); +extern void writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, + XLogRecPtr switchpoint, char *reason); +extern void writeTimeLineHistoryFile(TimeLineID tli, char *content, int size); +extern void restoreTimeLineHistoryFiles(TimeLineID begin, TimeLineID end); +extern bool tliInHistory(TimeLineID tli, List *expectedTLEs); +extern TimeLineID tliOfPointInHistory(XLogRecPtr ptr, List *history); +extern XLogRecPtr tliSwitchPoint(TimeLineID tli, List *history, + TimeLineID *nextTLI); + +#endif /* TIMELINE_H */ diff --git a/install/include/postgresql/server/access/toast_compression.h b/install/include/postgresql/server/access/toast_compression.h new file mode 100644 index 00000000000..7f02820caff --- /dev/null +++ b/install/include/postgresql/server/access/toast_compression.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * toast_compression.h + * Functions for toast compression. + * + * Copyright (c) 2021-2023, PostgreSQL Global Development Group + * + * src/include/access/toast_compression.h + * + *------------------------------------------------------------------------- + */ + +#ifndef TOAST_COMPRESSION_H +#define TOAST_COMPRESSION_H + +/* + * GUC support. + * + * default_toast_compression is an integer for purposes of the GUC machinery, + * but the value is one of the char values defined below, as they appear in + * pg_attribute.attcompression, e.g. TOAST_PGLZ_COMPRESSION. + */ +extern PGDLLIMPORT int default_toast_compression; + +/* + * Built-in compression method ID. The toast compression header will store + * this in the first 2 bits of the raw length. These built-in compression + * method IDs are directly mapped to the built-in compression methods. + * + * Don't use these values for anything other than understanding the meaning + * of the raw bits from a varlena; in particular, if the goal is to identify + * a compression method, use the constants TOAST_PGLZ_COMPRESSION, etc. + * below. We might someday support more than 4 compression methods, but + * we can never have more than 4 values in this enum, because there are + * only 2 bits available in the places where this is stored. + */ +typedef enum ToastCompressionId +{ + TOAST_PGLZ_COMPRESSION_ID = 0, + TOAST_LZ4_COMPRESSION_ID = 1, + TOAST_INVALID_COMPRESSION_ID = 2 +} ToastCompressionId; + +/* + * Built-in compression methods. pg_attribute will store these in the + * attcompression column. In attcompression, InvalidCompressionMethod + * denotes the default behavior. + */ +#define TOAST_PGLZ_COMPRESSION 'p' +#define TOAST_LZ4_COMPRESSION 'l' +#define InvalidCompressionMethod '\0' + +#define CompressionMethodIsValid(cm) ((cm) != InvalidCompressionMethod) + + +/* pglz compression/decompression routines */ +extern struct varlena *pglz_compress_datum(const struct varlena *value); +extern struct varlena *pglz_decompress_datum(const struct varlena *value); +extern struct varlena *pglz_decompress_datum_slice(const struct varlena *value, + int32 slicelength); + +/* lz4 compression/decompression routines */ +extern struct varlena *lz4_compress_datum(const struct varlena *value); +extern struct varlena *lz4_decompress_datum(const struct varlena *value); +extern struct varlena *lz4_decompress_datum_slice(const struct varlena *value, + int32 slicelength); + +/* other stuff */ +extern ToastCompressionId toast_get_compression_id(struct varlena *attr); +extern char CompressionNameToMethod(const char *compression); +extern const char *GetCompressionMethodName(char method); + +#endif /* TOAST_COMPRESSION_H */ diff --git a/install/include/postgresql/server/access/toast_helper.h b/install/include/postgresql/server/access/toast_helper.h new file mode 100644 index 00000000000..e971bd2c8ef --- /dev/null +++ b/install/include/postgresql/server/access/toast_helper.h @@ -0,0 +1,116 @@ +/*------------------------------------------------------------------------- + * + * toast_helper.h + * Helper functions for table AMs implementing compressed or + * out-of-line storage of varlena attributes. + * + * Copyright (c) 2000-2023, PostgreSQL Global Development Group + * + * src/include/access/toast_helper.h + * + *------------------------------------------------------------------------- + */ + +#ifndef TOAST_HELPER_H +#define TOAST_HELPER_H + +#include "utils/rel.h" + +/* + * Information about one column of a tuple being toasted. + * + * NOTE: toast_action[i] can have these values: + * ' ' default handling + * TYPSTORAGE_PLAIN already processed --- don't touch it + * TYPSTORAGE_EXTENDED incompressible, but OK to move off + * + * NOTE: toast_attr[i].tai_size is only made valid for varlena attributes with + * toast_action[i] different from TYPSTORAGE_PLAIN. + */ +typedef struct +{ + struct varlena *tai_oldexternal; + int32 tai_size; + uint8 tai_colflags; + char tai_compression; +} ToastAttrInfo; + +/* + * Information about one tuple being toasted. + */ +typedef struct +{ + /* + * Before calling toast_tuple_init, the caller must initialize the + * following fields. Each array must have a length equal to + * ttc_rel->rd_att->natts. The ttc_oldvalues and ttc_oldisnull fields + * should be NULL in the case of an insert. + */ + Relation ttc_rel; /* the relation that contains the tuple */ + Datum *ttc_values; /* values from the tuple columns */ + bool *ttc_isnull; /* null flags for the tuple columns */ + Datum *ttc_oldvalues; /* values from previous tuple */ + bool *ttc_oldisnull; /* null flags from previous tuple */ + + /* + * Before calling toast_tuple_init, the caller should set ttc_attr to + * point to an array of ToastAttrInfo structures of a length equal to + * ttc_rel->rd_att->natts. The contents of the array need not be + * initialized. ttc_flags also does not need to be initialized. + */ + uint8 ttc_flags; + ToastAttrInfo *ttc_attr; +} ToastTupleContext; + +/* + * Flags indicating the overall state of a TOAST operation. + * + * TOAST_NEEDS_DELETE_OLD indicates that one or more old TOAST datums need + * to be deleted. + * + * TOAST_NEEDS_FREE indicates that one or more TOAST values need to be freed. + * + * TOAST_HAS_NULLS indicates that nulls were found in the tuple being toasted. + * + * TOAST_NEEDS_CHANGE indicates that a new tuple needs to built; in other + * words, the toaster did something. + */ +#define TOAST_NEEDS_DELETE_OLD 0x0001 +#define TOAST_NEEDS_FREE 0x0002 +#define TOAST_HAS_NULLS 0x0004 +#define TOAST_NEEDS_CHANGE 0x0008 + +/* + * Flags indicating the status of a TOAST operation with respect to a + * particular column. + * + * TOASTCOL_NEEDS_DELETE_OLD indicates that the old TOAST datums for this + * column need to be deleted. + * + * TOASTCOL_NEEDS_FREE indicates that the value for this column needs to + * be freed. + * + * TOASTCOL_IGNORE indicates that the toaster should not further process + * this column. + * + * TOASTCOL_INCOMPRESSIBLE indicates that this column has been found to + * be incompressible, but could be moved out-of-line. + */ +#define TOASTCOL_NEEDS_DELETE_OLD TOAST_NEEDS_DELETE_OLD +#define TOASTCOL_NEEDS_FREE TOAST_NEEDS_FREE +#define TOASTCOL_IGNORE 0x0010 +#define TOASTCOL_INCOMPRESSIBLE 0x0020 + +extern void toast_tuple_init(ToastTupleContext *ttc); +extern int toast_tuple_find_biggest_attribute(ToastTupleContext *ttc, + bool for_compression, + bool check_main); +extern void toast_tuple_try_compression(ToastTupleContext *ttc, int attribute); +extern void toast_tuple_externalize(ToastTupleContext *ttc, int attribute, + int options); +extern void toast_tuple_cleanup(ToastTupleContext *ttc); + +extern void toast_delete_external(Relation rel, Datum *values, bool *isnull, + bool is_speculative); + +#endif diff --git a/install/include/postgresql/server/access/toast_internals.h b/install/include/postgresql/server/access/toast_internals.h new file mode 100644 index 00000000000..30dba098936 --- /dev/null +++ b/install/include/postgresql/server/access/toast_internals.h @@ -0,0 +1,63 @@ +/*------------------------------------------------------------------------- + * + * toast_internals.h + * Internal definitions for the TOAST system. + * + * Copyright (c) 2000-2023, PostgreSQL Global Development Group + * + * src/include/access/toast_internals.h + * + *------------------------------------------------------------------------- + */ +#ifndef TOAST_INTERNALS_H +#define TOAST_INTERNALS_H + +#include "access/toast_compression.h" +#include "storage/lockdefs.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + +/* + * The information at the start of the compressed toast data. + */ +typedef struct toast_compress_header +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + uint32 tcinfo; /* 2 bits for compression method and 30 bits + * external size; see va_extinfo */ +} toast_compress_header; + +/* + * Utilities for manipulation of header information for compressed + * toast entries. + */ +#define TOAST_COMPRESS_EXTSIZE(ptr) \ + (((toast_compress_header *) (ptr))->tcinfo & VARLENA_EXTSIZE_MASK) +#define TOAST_COMPRESS_METHOD(ptr) \ + (((toast_compress_header *) (ptr))->tcinfo >> VARLENA_EXTSIZE_BITS) + +#define TOAST_COMPRESS_SET_SIZE_AND_COMPRESS_METHOD(ptr, len, cm_method) \ + do { \ + Assert((len) > 0 && (len) <= VARLENA_EXTSIZE_MASK); \ + Assert((cm_method) == TOAST_PGLZ_COMPRESSION_ID || \ + (cm_method) == TOAST_LZ4_COMPRESSION_ID); \ + ((toast_compress_header *) (ptr))->tcinfo = \ + (len) | ((uint32) (cm_method) << VARLENA_EXTSIZE_BITS); \ + } while (0) + +extern Datum toast_compress_datum(Datum value, char cmethod); +extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock); + +extern void toast_delete_datum(Relation rel, Datum value, bool is_speculative); +extern Datum toast_save_datum(Relation rel, Datum value, + struct varlena *oldexternal, int options); + +extern int toast_open_indexes(Relation toastrel, + LOCKMODE lock, + Relation **toastidxs, + int *num_indexes); +extern void toast_close_indexes(Relation *toastidxs, int num_indexes, + LOCKMODE lock); +extern void init_toast_snapshot(Snapshot toast_snapshot); + +#endif /* TOAST_INTERNALS_H */ diff --git a/install/include/postgresql/server/access/transam.h b/install/include/postgresql/server/access/transam.h new file mode 100644 index 00000000000..f5af6d30556 --- /dev/null +++ b/install/include/postgresql/server/access/transam.h @@ -0,0 +1,375 @@ +/*------------------------------------------------------------------------- + * + * transam.h + * postgres transaction access method support code + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/transam.h + * + *------------------------------------------------------------------------- + */ +#ifndef TRANSAM_H +#define TRANSAM_H + +#include "access/xlogdefs.h" + + +/* ---------------- + * Special transaction ID values + * + * BootstrapTransactionId is the XID for "bootstrap" operations, and + * FrozenTransactionId is used for very old tuples. Both should + * always be considered valid. + * + * FirstNormalTransactionId is the first "normal" transaction id. + * Note: if you need to change it, you must change pg_class.h as well. + * ---------------- + */ +#define InvalidTransactionId ((TransactionId) 0) +#define BootstrapTransactionId ((TransactionId) 1) +#define FrozenTransactionId ((TransactionId) 2) +#define FirstNormalTransactionId ((TransactionId) 3) +#define MaxTransactionId ((TransactionId) 0xFFFFFFFF) + +/* ---------------- + * transaction ID manipulation macros + * ---------------- + */ +#define TransactionIdIsValid(xid) ((xid) != InvalidTransactionId) +#define TransactionIdIsNormal(xid) ((xid) >= FirstNormalTransactionId) +#define TransactionIdEquals(id1, id2) ((id1) == (id2)) +#define TransactionIdStore(xid, dest) (*(dest) = (xid)) +#define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId) + +#define EpochFromFullTransactionId(x) ((uint32) ((x).value >> 32)) +#define XidFromFullTransactionId(x) ((uint32) (x).value) +#define U64FromFullTransactionId(x) ((x).value) +#define FullTransactionIdEquals(a, b) ((a).value == (b).value) +#define FullTransactionIdPrecedes(a, b) ((a).value < (b).value) +#define FullTransactionIdPrecedesOrEquals(a, b) ((a).value <= (b).value) +#define FullTransactionIdFollows(a, b) ((a).value > (b).value) +#define FullTransactionIdFollowsOrEquals(a, b) ((a).value >= (b).value) +#define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x)) +#define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId) +#define FirstNormalFullTransactionId FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId) +#define FullTransactionIdIsNormal(x) FullTransactionIdFollowsOrEquals(x, FirstNormalFullTransactionId) + +/* + * A 64 bit value that contains an epoch and a TransactionId. This is + * wrapped in a struct to prevent implicit conversion to/from TransactionId. + * Not all values represent valid normal XIDs. + */ +typedef struct FullTransactionId +{ + uint64 value; +} FullTransactionId; + +static inline FullTransactionId +FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid) +{ + FullTransactionId result; + + result.value = ((uint64) epoch) << 32 | xid; + + return result; +} + +static inline FullTransactionId +FullTransactionIdFromU64(uint64 value) +{ + FullTransactionId result; + + result.value = value; + + return result; +} + +/* advance a transaction ID variable, handling wraparound correctly */ +#define TransactionIdAdvance(dest) \ + do { \ + (dest)++; \ + if ((dest) < FirstNormalTransactionId) \ + (dest) = FirstNormalTransactionId; \ + } while(0) + +/* + * Retreat a FullTransactionId variable, stepping over xids that would appear + * to be special only when viewed as 32bit XIDs. + */ +static inline void +FullTransactionIdRetreat(FullTransactionId *dest) +{ + dest->value--; + + /* + * In contrast to 32bit XIDs don't step over the "actual" special xids. + * For 64bit xids these can't be reached as part of a wraparound as they + * can in the 32bit case. + */ + if (FullTransactionIdPrecedes(*dest, FirstNormalFullTransactionId)) + return; + + /* + * But we do need to step over XIDs that'd appear special only for 32bit + * XIDs. + */ + while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId) + dest->value--; +} + +/* + * Advance a FullTransactionId variable, stepping over xids that would appear + * to be special only when viewed as 32bit XIDs. + */ +static inline void +FullTransactionIdAdvance(FullTransactionId *dest) +{ + dest->value++; + + /* see FullTransactionIdAdvance() */ + if (FullTransactionIdPrecedes(*dest, FirstNormalFullTransactionId)) + return; + + while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId) + dest->value++; +} + +/* back up a transaction ID variable, handling wraparound correctly */ +#define TransactionIdRetreat(dest) \ + do { \ + (dest)--; \ + } while ((dest) < FirstNormalTransactionId) + +/* compare two XIDs already known to be normal; this is a macro for speed */ +#define NormalTransactionIdPrecedes(id1, id2) \ + (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \ + (int32) ((id1) - (id2)) < 0) + +/* compare two XIDs already known to be normal; this is a macro for speed */ +#define NormalTransactionIdFollows(id1, id2) \ + (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \ + (int32) ((id1) - (id2)) > 0) + +/* ---------- + * Object ID (OID) zero is InvalidOid. + * + * OIDs 1-9999 are reserved for manual assignment (see .dat files in + * src/include/catalog/). Of these, 8000-9999 are reserved for + * development purposes (such as in-progress patches and forks); + * they should not appear in released versions. + * + * OIDs 10000-11999 are reserved for assignment by genbki.pl, for use + * when the .dat files in src/include/catalog/ do not specify an OID + * for a catalog entry that requires one. Note that genbki.pl assigns + * these OIDs independently in each catalog, so they're not guaranteed + * to be globally unique. Furthermore, the bootstrap backend and + * initdb's post-bootstrap processing can also assign OIDs in this range. + * The normal OID-generation logic takes care of any OID conflicts that + * might arise from that. + * + * OIDs 12000-16383 are reserved for unpinned objects created by initdb's + * post-bootstrap processing. initdb forces the OID generator up to + * 12000 as soon as it's made the pinned objects it's responsible for. + * + * OIDs beginning at 16384 are assigned from the OID generator + * during normal multiuser operation. (We force the generator up to + * 16384 as soon as we are in normal operation.) + * + * The choices of 8000, 10000 and 12000 are completely arbitrary, and can be + * moved if we run low on OIDs in any category. Changing the macros below, + * and updating relevant documentation (see bki.sgml and RELEASE_CHANGES), + * should be sufficient to do this. Moving the 16384 boundary between + * initdb-assigned OIDs and user-defined objects would be substantially + * more painful, however, since some user-defined OIDs will appear in + * on-disk data; such a change would probably break pg_upgrade. + * + * NOTE: if the OID generator wraps around, we skip over OIDs 0-16383 + * and resume with 16384. This minimizes the odds of OID conflict, by not + * reassigning OIDs that might have been assigned during initdb. Critically, + * it also ensures that no user-created object will be considered pinned. + * ---------- + */ +#define FirstGenbkiObjectId 10000 +#define FirstUnpinnedObjectId 12000 +#define FirstNormalObjectId 16384 + +/* + * VariableCache is a data structure in shared memory that is used to track + * OID and XID assignment state. For largely historical reasons, there is + * just one struct with different fields that are protected by different + * LWLocks. + * + * Note: xidWrapLimit and oldestXidDB are not "active" values, but are + * used just to generate useful messages when xidWarnLimit or xidStopLimit + * are exceeded. + */ +typedef struct VariableCacheData +{ + /* + * These fields are protected by OidGenLock. + */ + Oid nextOid; /* next OID to assign */ + uint32 oidCount; /* OIDs available before must do XLOG work */ + + /* + * These fields are protected by XidGenLock. + */ + FullTransactionId nextXid; /* next XID to assign */ + + TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */ + TransactionId xidVacLimit; /* start forcing autovacuums here */ + TransactionId xidWarnLimit; /* start complaining here */ + TransactionId xidStopLimit; /* refuse to advance nextXid beyond here */ + TransactionId xidWrapLimit; /* where the world ends */ + Oid oldestXidDB; /* database with minimum datfrozenxid */ + + /* + * These fields are protected by CommitTsLock + */ + TransactionId oldestCommitTsXid; + TransactionId newestCommitTsXid; + + /* + * These fields are protected by ProcArrayLock. + */ + FullTransactionId latestCompletedXid; /* newest full XID that has + * committed or aborted */ + + /* + * Number of top-level transactions with xids (i.e. which may have + * modified the database) that completed in some form since the start of + * the server. This currently is solely used to check whether + * GetSnapshotData() needs to recompute the contents of the snapshot, or + * not. There are likely other users of this. Always above 1. + */ + uint64 xactCompletionCount; + + /* + * These fields are protected by XactTruncationLock + */ + TransactionId oldestClogXid; /* oldest it's safe to look up in clog */ + +} VariableCacheData; + +typedef VariableCacheData *VariableCache; + + +/* ---------------- + * extern declarations + * ---------------- + */ + +/* in transam/xact.c */ +extern bool TransactionStartedDuringRecovery(void); + +/* in transam/varsup.c */ +extern PGDLLIMPORT VariableCache ShmemVariableCache; + +/* + * prototypes for functions in transam/transam.c + */ +extern bool TransactionIdDidCommit(TransactionId transactionId); +extern bool TransactionIdDidAbort(TransactionId transactionId); +extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids); +extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn); +extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids); +extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2); +extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2); +extern bool TransactionIdFollows(TransactionId id1, TransactionId id2); +extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2); +extern TransactionId TransactionIdLatest(TransactionId mainxid, + int nxids, const TransactionId *xids); +extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid); + +/* in transam/varsup.c */ +extern FullTransactionId GetNewTransactionId(bool isSubXact); +extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid); +extern FullTransactionId ReadNextFullTransactionId(void); +extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, + Oid oldest_datoid); +extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid); +extern bool ForceTransactionIdLimitUpdate(void); +extern Oid GetNewObjectId(void); +extern void StopGeneratingPinnedObjectIds(void); + +#ifdef USE_ASSERT_CHECKING +extern void AssertTransactionIdInAllowableRange(TransactionId xid); +#else +#define AssertTransactionIdInAllowableRange(xid) ((void)true) +#endif + +/* + * Some frontend programs include this header. For compilers that emit static + * inline functions even when they're unused, that leads to unsatisfied + * external references; hence hide them with #ifndef FRONTEND. + */ +#ifndef FRONTEND + +/* + * For callers that just need the XID part of the next transaction ID. + */ +static inline TransactionId +ReadNextTransactionId(void) +{ + return XidFromFullTransactionId(ReadNextFullTransactionId()); +} + +/* return transaction ID backed up by amount, handling wraparound correctly */ +static inline TransactionId +TransactionIdRetreatedBy(TransactionId xid, uint32 amount) +{ + xid -= amount; + + while (xid < FirstNormalTransactionId) + xid--; + + return xid; +} + +/* return the older of the two IDs */ +static inline TransactionId +TransactionIdOlder(TransactionId a, TransactionId b) +{ + if (!TransactionIdIsValid(a)) + return b; + + if (!TransactionIdIsValid(b)) + return a; + + if (TransactionIdPrecedes(a, b)) + return a; + return b; +} + +/* return the older of the two IDs, assuming they're both normal */ +static inline TransactionId +NormalTransactionIdOlder(TransactionId a, TransactionId b) +{ + Assert(TransactionIdIsNormal(a)); + Assert(TransactionIdIsNormal(b)); + if (NormalTransactionIdPrecedes(a, b)) + return a; + return b; +} + +/* return the newer of the two IDs */ +static inline FullTransactionId +FullTransactionIdNewer(FullTransactionId a, FullTransactionId b) +{ + if (!FullTransactionIdIsValid(a)) + return b; + + if (!FullTransactionIdIsValid(b)) + return a; + + if (FullTransactionIdFollows(a, b)) + return a; + return b; +} + +#endif /* FRONTEND */ + +#endif /* TRANSAM_H */ diff --git a/install/include/postgresql/server/access/tsmapi.h b/install/include/postgresql/server/access/tsmapi.h new file mode 100644 index 00000000000..80784bed1eb --- /dev/null +++ b/install/include/postgresql/server/access/tsmapi.h @@ -0,0 +1,82 @@ +/*------------------------------------------------------------------------- + * + * tsmapi.h + * API for tablesample methods + * + * Copyright (c) 2015-2023, PostgreSQL Global Development Group + * + * src/include/access/tsmapi.h + * + *------------------------------------------------------------------------- + */ +#ifndef TSMAPI_H +#define TSMAPI_H + +#include "nodes/execnodes.h" +#include "nodes/pathnodes.h" + + +/* + * Callback function signatures --- see tablesample-method.sgml for more info. + */ + +typedef void (*SampleScanGetSampleSize_function) (PlannerInfo *root, + RelOptInfo *baserel, + List *paramexprs, + BlockNumber *pages, + double *tuples); + +typedef void (*InitSampleScan_function) (SampleScanState *node, + int eflags); + +typedef void (*BeginSampleScan_function) (SampleScanState *node, + Datum *params, + int nparams, + uint32 seed); + +typedef BlockNumber (*NextSampleBlock_function) (SampleScanState *node, + BlockNumber nblocks); + +typedef OffsetNumber (*NextSampleTuple_function) (SampleScanState *node, + BlockNumber blockno, + OffsetNumber maxoffset); + +typedef void (*EndSampleScan_function) (SampleScanState *node); + +/* + * TsmRoutine is the struct returned by a tablesample method's handler + * function. It provides pointers to the callback functions needed by the + * planner and executor, as well as additional information about the method. + * + * More function pointers are likely to be added in the future. + * Therefore it's recommended that the handler initialize the struct with + * makeNode(TsmRoutine) so that all fields are set to NULL. This will + * ensure that no fields are accidentally left undefined. + */ +typedef struct TsmRoutine +{ + NodeTag type; + + /* List of datatype OIDs for the arguments of the TABLESAMPLE clause */ + List *parameterTypes; + + /* Can method produce repeatable samples across, or even within, queries? */ + bool repeatable_across_queries; + bool repeatable_across_scans; + + /* Functions for planning a SampleScan on a physical table */ + SampleScanGetSampleSize_function SampleScanGetSampleSize; + + /* Functions for executing a SampleScan on a physical table */ + InitSampleScan_function InitSampleScan; /* can be NULL */ + BeginSampleScan_function BeginSampleScan; + NextSampleBlock_function NextSampleBlock; /* can be NULL */ + NextSampleTuple_function NextSampleTuple; + EndSampleScan_function EndSampleScan; /* can be NULL */ +} TsmRoutine; + + +/* Functions in access/tablesample/tablesample.c */ +extern TsmRoutine *GetTsmRoutine(Oid tsmhandler); + +#endif /* TSMAPI_H */ diff --git a/install/include/postgresql/server/access/tupconvert.h b/install/include/postgresql/server/access/tupconvert.h new file mode 100644 index 00000000000..f00918b5161 --- /dev/null +++ b/install/include/postgresql/server/access/tupconvert.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * tupconvert.h + * Tuple conversion support. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/tupconvert.h + * + *------------------------------------------------------------------------- + */ +#ifndef TUPCONVERT_H +#define TUPCONVERT_H + +#include "access/attmap.h" +#include "access/htup.h" +#include "access/tupdesc.h" +#include "executor/tuptable.h" +#include "nodes/bitmapset.h" + + +typedef struct TupleConversionMap +{ + TupleDesc indesc; /* tupdesc for source rowtype */ + TupleDesc outdesc; /* tupdesc for result rowtype */ + AttrMap *attrMap; /* indexes of input fields, or 0 for null */ + Datum *invalues; /* workspace for deconstructing source */ + bool *inisnull; + Datum *outvalues; /* workspace for constructing result */ + bool *outisnull; +} TupleConversionMap; + + +extern TupleConversionMap *convert_tuples_by_position(TupleDesc indesc, + TupleDesc outdesc, + const char *msg); + +extern TupleConversionMap *convert_tuples_by_name(TupleDesc indesc, + TupleDesc outdesc); +extern TupleConversionMap *convert_tuples_by_name_attrmap(TupleDesc indesc, + TupleDesc outdesc, + AttrMap *attrMap); + +extern HeapTuple execute_attr_map_tuple(HeapTuple tuple, TupleConversionMap *map); +extern TupleTableSlot *execute_attr_map_slot(AttrMap *attrMap, + TupleTableSlot *in_slot, + TupleTableSlot *out_slot); +extern Bitmapset *execute_attr_map_cols(AttrMap *attrMap, Bitmapset *in_cols); + +extern void free_conversion_map(TupleConversionMap *map); + +#endif /* TUPCONVERT_H */ diff --git a/install/include/postgresql/server/access/tupdesc.h b/install/include/postgresql/server/access/tupdesc.h new file mode 100644 index 00000000000..b4286cf9222 --- /dev/null +++ b/install/include/postgresql/server/access/tupdesc.h @@ -0,0 +1,154 @@ +/*------------------------------------------------------------------------- + * + * tupdesc.h + * POSTGRES tuple descriptor definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/tupdesc.h + * + *------------------------------------------------------------------------- + */ +#ifndef TUPDESC_H +#define TUPDESC_H + +#include "access/attnum.h" +#include "catalog/pg_attribute.h" +#include "nodes/pg_list.h" + + +typedef struct AttrDefault +{ + AttrNumber adnum; + char *adbin; /* nodeToString representation of expr */ +} AttrDefault; + +typedef struct ConstrCheck +{ + char *ccname; + char *ccbin; /* nodeToString representation of expr */ + bool ccvalid; + bool ccnoinherit; /* this is a non-inheritable constraint */ +} ConstrCheck; + +/* This structure contains constraints of a tuple */ +typedef struct TupleConstr +{ + AttrDefault *defval; /* array */ + ConstrCheck *check; /* array */ + struct AttrMissing *missing; /* missing attributes values, NULL if none */ + uint16 num_defval; + uint16 num_check; + bool has_not_null; + bool has_generated_stored; +} TupleConstr; + +/* + * This struct is passed around within the backend to describe the structure + * of tuples. For tuples coming from on-disk relations, the information is + * collected from the pg_attribute, pg_attrdef, and pg_constraint catalogs. + * Transient row types (such as the result of a join query) have anonymous + * TupleDesc structs that generally omit any constraint info; therefore the + * structure is designed to let the constraints be omitted efficiently. + * + * Note that only user attributes, not system attributes, are mentioned in + * TupleDesc. + * + * If the tupdesc is known to correspond to a named rowtype (such as a table's + * rowtype) then tdtypeid identifies that type and tdtypmod is -1. Otherwise + * tdtypeid is RECORDOID, and tdtypmod can be either -1 for a fully anonymous + * row type, or a value >= 0 to allow the rowtype to be looked up in the + * typcache.c type cache. + * + * Note that tdtypeid is never the OID of a domain over composite, even if + * we are dealing with values that are known (at some higher level) to be of + * a domain-over-composite type. This is because tdtypeid/tdtypmod need to + * match up with the type labeling of composite Datums, and those are never + * explicitly marked as being of a domain type, either. + * + * Tuple descriptors that live in caches (relcache or typcache, at present) + * are reference-counted: they can be deleted when their reference count goes + * to zero. Tuple descriptors created by the executor need no reference + * counting, however: they are simply created in the appropriate memory + * context and go away when the context is freed. We set the tdrefcount + * field of such a descriptor to -1, while reference-counted descriptors + * always have tdrefcount >= 0. + */ +typedef struct TupleDescData +{ + int natts; /* number of attributes in the tuple */ + Oid tdtypeid; /* composite type ID for tuple type */ + int32 tdtypmod; /* typmod for tuple type */ + int tdrefcount; /* reference count, or -1 if not counting */ + TupleConstr *constr; /* constraints, or NULL if none */ + /* attrs[N] is the description of Attribute Number N+1 */ + FormData_pg_attribute attrs[FLEXIBLE_ARRAY_MEMBER]; +} TupleDescData; +typedef struct TupleDescData *TupleDesc; + +/* Accessor for the i'th attribute of tupdesc. */ +#define TupleDescAttr(tupdesc, i) (&(tupdesc)->attrs[(i)]) + +extern TupleDesc CreateTemplateTupleDesc(int natts); + +extern TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs); + +extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc); + +extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc); + +#define TupleDescSize(src) \ + (offsetof(struct TupleDescData, attrs) + \ + (src)->natts * sizeof(FormData_pg_attribute)) + +extern void TupleDescCopy(TupleDesc dst, TupleDesc src); + +extern void TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno, + TupleDesc src, AttrNumber srcAttno); + +extern void FreeTupleDesc(TupleDesc tupdesc); + +extern void IncrTupleDescRefCount(TupleDesc tupdesc); +extern void DecrTupleDescRefCount(TupleDesc tupdesc); + +#define PinTupleDesc(tupdesc) \ + do { \ + if ((tupdesc)->tdrefcount >= 0) \ + IncrTupleDescRefCount(tupdesc); \ + } while (0) + +#define ReleaseTupleDesc(tupdesc) \ + do { \ + if ((tupdesc)->tdrefcount >= 0) \ + DecrTupleDescRefCount(tupdesc); \ + } while (0) + +extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2); + +extern uint32 hashTupleDesc(TupleDesc desc); + +extern void TupleDescInitEntry(TupleDesc desc, + AttrNumber attributeNumber, + const char *attributeName, + Oid oidtypeid, + int32 typmod, + int attdim); + +extern void TupleDescInitBuiltinEntry(TupleDesc desc, + AttrNumber attributeNumber, + const char *attributeName, + Oid oidtypeid, + int32 typmod, + int attdim); + +extern void TupleDescInitEntryCollation(TupleDesc desc, + AttrNumber attributeNumber, + Oid collationid); + +extern TupleDesc BuildDescForRelation(List *schema); + +extern TupleDesc BuildDescFromLists(List *names, List *types, List *typmods, List *collations); + +#endif /* TUPDESC_H */ diff --git a/install/include/postgresql/server/access/tupdesc_details.h b/install/include/postgresql/server/access/tupdesc_details.h new file mode 100644 index 00000000000..8d1b0985250 --- /dev/null +++ b/install/include/postgresql/server/access/tupdesc_details.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * tupdesc_details.h + * POSTGRES tuple descriptor definitions we can't include everywhere + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/tupdesc_details.h + * + *------------------------------------------------------------------------- + */ + +#ifndef TUPDESC_DETAILS_H +#define TUPDESC_DETAILS_H + +/* + * Structure used to represent value to be used when the attribute is not + * present at all in a tuple, i.e. when the column was created after the tuple + */ +typedef struct AttrMissing +{ + bool am_present; /* true if non-NULL missing value exists */ + Datum am_value; /* value when attribute is missing */ +} AttrMissing; + +#endif /* TUPDESC_DETAILS_H */ diff --git a/install/include/postgresql/server/access/tupmacs.h b/install/include/postgresql/server/access/tupmacs.h new file mode 100644 index 00000000000..3414446597e --- /dev/null +++ b/install/include/postgresql/server/access/tupmacs.h @@ -0,0 +1,207 @@ +/*------------------------------------------------------------------------- + * + * tupmacs.h + * Tuple macros used by both index tuples and heap tuples. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/tupmacs.h + * + *------------------------------------------------------------------------- + */ +#ifndef TUPMACS_H +#define TUPMACS_H + +#include "catalog/pg_type_d.h" /* for TYPALIGN macros */ + + +/* + * Check a tuple's null bitmap to determine whether the attribute is null. + * Note that a 0 in the null bitmap indicates a null, while 1 indicates + * non-null. + */ +static inline bool +att_isnull(int ATT, const bits8 *BITS) +{ + return !(BITS[ATT >> 3] & (1 << (ATT & 0x07))); +} + +#ifndef FRONTEND +/* + * Given a Form_pg_attribute and a pointer into a tuple's data area, + * return the correct value or pointer. + * + * We return a Datum value in all cases. If the attribute has "byval" false, + * we return the same pointer into the tuple data area that we're passed. + * Otherwise, we return the correct number of bytes fetched from the data + * area and extended to Datum form. + * + * On machines where Datum is 8 bytes, we support fetching 8-byte byval + * attributes; otherwise, only 1, 2, and 4-byte values are supported. + * + * Note that T must already be properly aligned for this to work correctly. + */ +#define fetchatt(A,T) fetch_att(T, (A)->attbyval, (A)->attlen) + +/* + * Same, but work from byval/len parameters rather than Form_pg_attribute. + */ +static inline Datum +fetch_att(const void *T, bool attbyval, int attlen) +{ + if (attbyval) + { + switch (attlen) + { + case sizeof(char): + return CharGetDatum(*((const char *) T)); + case sizeof(int16): + return Int16GetDatum(*((const int16 *) T)); + case sizeof(int32): + return Int32GetDatum(*((const int32 *) T)); +#if SIZEOF_DATUM == 8 + case sizeof(Datum): + return *((const Datum *) T); +#endif + default: + elog(ERROR, "unsupported byval length: %d", attlen); + return 0; + } + } + else + return PointerGetDatum(T); +} +#endif /* FRONTEND */ + +/* + * att_align_datum aligns the given offset as needed for a datum of alignment + * requirement attalign and typlen attlen. attdatum is the Datum variable + * we intend to pack into a tuple (it's only accessed if we are dealing with + * a varlena type). Note that this assumes the Datum will be stored as-is; + * callers that are intending to convert non-short varlena datums to short + * format have to account for that themselves. + */ +#define att_align_datum(cur_offset, attalign, attlen, attdatum) \ +( \ + ((attlen) == -1 && VARATT_IS_SHORT(DatumGetPointer(attdatum))) ? \ + (uintptr_t) (cur_offset) : \ + att_align_nominal(cur_offset, attalign) \ +) + +/* + * att_align_pointer performs the same calculation as att_align_datum, + * but is used when walking a tuple. attptr is the current actual data + * pointer; when accessing a varlena field we have to "peek" to see if we + * are looking at a pad byte or the first byte of a 1-byte-header datum. + * (A zero byte must be either a pad byte, or the first byte of a correctly + * aligned 4-byte length word; in either case we can align safely. A non-zero + * byte must be either a 1-byte length word, or the first byte of a correctly + * aligned 4-byte length word; in either case we need not align.) + * + * Note: some callers pass a "char *" pointer for cur_offset. This is + * a bit of a hack but should work all right as long as uintptr_t is the + * correct width. + */ +#define att_align_pointer(cur_offset, attalign, attlen, attptr) \ +( \ + ((attlen) == -1 && VARATT_NOT_PAD_BYTE(attptr)) ? \ + (uintptr_t) (cur_offset) : \ + att_align_nominal(cur_offset, attalign) \ +) + +/* + * att_align_nominal aligns the given offset as needed for a datum of alignment + * requirement attalign, ignoring any consideration of packed varlena datums. + * There are three main use cases for using this macro directly: + * * we know that the att in question is not varlena (attlen != -1); + * in this case it is cheaper than the above macros and just as good. + * * we need to estimate alignment padding cost abstractly, ie without + * reference to a real tuple. We must assume the worst case that + * all varlenas are aligned. + * * within arrays and multiranges, we unconditionally align varlenas (XXX this + * should be revisited, probably). + * + * The attalign cases are tested in what is hopefully something like their + * frequency of occurrence. + */ +#define att_align_nominal(cur_offset, attalign) \ +( \ + ((attalign) == TYPALIGN_INT) ? INTALIGN(cur_offset) : \ + (((attalign) == TYPALIGN_CHAR) ? (uintptr_t) (cur_offset) : \ + (((attalign) == TYPALIGN_DOUBLE) ? DOUBLEALIGN(cur_offset) : \ + ( \ + AssertMacro((attalign) == TYPALIGN_SHORT), \ + SHORTALIGN(cur_offset) \ + ))) \ +) + +/* + * att_addlength_datum increments the given offset by the space needed for + * the given Datum variable. attdatum is only accessed if we are dealing + * with a variable-length attribute. + */ +#define att_addlength_datum(cur_offset, attlen, attdatum) \ + att_addlength_pointer(cur_offset, attlen, DatumGetPointer(attdatum)) + +/* + * att_addlength_pointer performs the same calculation as att_addlength_datum, + * but is used when walking a tuple --- attptr is the pointer to the field + * within the tuple. + * + * Note: some callers pass a "char *" pointer for cur_offset. This is + * actually perfectly OK, but probably should be cleaned up along with + * the same practice for att_align_pointer. + */ +#define att_addlength_pointer(cur_offset, attlen, attptr) \ +( \ + ((attlen) > 0) ? \ + ( \ + (cur_offset) + (attlen) \ + ) \ + : (((attlen) == -1) ? \ + ( \ + (cur_offset) + VARSIZE_ANY(attptr) \ + ) \ + : \ + ( \ + AssertMacro((attlen) == -2), \ + (cur_offset) + (strlen((char *) (attptr)) + 1) \ + )) \ +) + +#ifndef FRONTEND +/* + * store_att_byval is a partial inverse of fetch_att: store a given Datum + * value into a tuple data area at the specified address. However, it only + * handles the byval case, because in typical usage the caller needs to + * distinguish by-val and by-ref cases anyway, and so a do-it-all function + * wouldn't be convenient. + */ +static inline void +store_att_byval(void *T, Datum newdatum, int attlen) +{ + switch (attlen) + { + case sizeof(char): + *(char *) T = DatumGetChar(newdatum); + break; + case sizeof(int16): + *(int16 *) T = DatumGetInt16(newdatum); + break; + case sizeof(int32): + *(int32 *) T = DatumGetInt32(newdatum); + break; +#if SIZEOF_DATUM == 8 + case sizeof(Datum): + *(Datum *) T = newdatum; + break; +#endif + default: + elog(ERROR, "unsupported byval length: %d", attlen); + } +} +#endif /* FRONTEND */ + +#endif /* TUPMACS_H */ diff --git a/install/include/postgresql/server/access/twophase.h b/install/include/postgresql/server/access/twophase.h new file mode 100644 index 00000000000..04c4295c904 --- /dev/null +++ b/install/include/postgresql/server/access/twophase.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------- + * + * twophase.h + * Two-phase-commit related declarations. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/twophase.h + * + *------------------------------------------------------------------------- + */ +#ifndef TWOPHASE_H +#define TWOPHASE_H + +#include "access/xact.h" +#include "access/xlogdefs.h" +#include "datatype/timestamp.h" +#include "storage/lock.h" + +/* + * GlobalTransactionData is defined in twophase.c; other places have no + * business knowing the internal definition. + */ +typedef struct GlobalTransactionData *GlobalTransaction; + +/* GUC variable */ +extern PGDLLIMPORT int max_prepared_xacts; + +extern Size TwoPhaseShmemSize(void); +extern void TwoPhaseShmemInit(void); + +extern void AtAbort_Twophase(void); +extern void PostPrepare_Twophase(void); + +extern TransactionId TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid, + bool *have_more); +extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid, bool lock_held); +extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held); + +extern GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, + TimestampTz prepared_at, + Oid owner, Oid databaseid); + +extern void StartPrepare(GlobalTransaction gxact); +extern void EndPrepare(GlobalTransaction gxact); +extern bool StandbyTransactionIdIsPrepared(TransactionId xid); + +extern TransactionId PrescanPreparedTransactions(TransactionId **xids_p, + int *nxids_p); +extern void StandbyRecoverPreparedTransactions(void); +extern void RecoverPreparedTransactions(void); + +extern void CheckPointTwoPhase(XLogRecPtr redo_horizon); + +extern void FinishPreparedTransaction(const char *gid, bool isCommit); + +extern void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, + XLogRecPtr end_lsn, RepOriginId origin_id); +extern void PrepareRedoRemove(TransactionId xid, bool giveWarning); +extern void restoreTwoPhaseData(void); +extern bool LookupGXact(const char *gid, XLogRecPtr prepare_end_lsn, + TimestampTz origin_prepare_timestamp); +#ifdef USE_PGRAC_CLUSTER +/* PGRAC (spec-4.12a D1): non-allocating prepared-xact count for the cluster + * undo record-segment drain gate (硬门 6). */ +extern int GetNumberOfPreparedTransactions(void); +#endif +#endif /* TWOPHASE_H */ diff --git a/install/include/postgresql/server/access/twophase_rmgr.h b/install/include/postgresql/server/access/twophase_rmgr.h new file mode 100644 index 00000000000..f9f55a8fd5c --- /dev/null +++ b/install/include/postgresql/server/access/twophase_rmgr.h @@ -0,0 +1,42 @@ +/*------------------------------------------------------------------------- + * + * twophase_rmgr.h + * Two-phase-commit resource managers definition + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/twophase_rmgr.h + * + *------------------------------------------------------------------------- + */ +#ifndef TWOPHASE_RMGR_H +#define TWOPHASE_RMGR_H + +typedef void (*TwoPhaseCallback) (TransactionId xid, uint16 info, + void *recdata, uint32 len); +typedef uint8 TwoPhaseRmgrId; + +/* + * Built-in resource managers + */ +#define TWOPHASE_RM_END_ID 0 +#define TWOPHASE_RM_LOCK_ID 1 +#define TWOPHASE_RM_PGSTAT_ID 2 +#define TWOPHASE_RM_MULTIXACT_ID 3 +#define TWOPHASE_RM_PREDICATELOCK_ID 4 +/* PGRAC (spec-3.15 D2): cluster TT bindings + SUBCOMMITTED links in 2PC. */ +#define TWOPHASE_RM_CLUSTER_TT_ID 5 +#define TWOPHASE_RM_MAX_ID TWOPHASE_RM_CLUSTER_TT_ID + +extern PGDLLIMPORT const TwoPhaseCallback twophase_recover_callbacks[]; +extern PGDLLIMPORT const TwoPhaseCallback twophase_postcommit_callbacks[]; +extern PGDLLIMPORT const TwoPhaseCallback twophase_postabort_callbacks[]; +extern PGDLLIMPORT const TwoPhaseCallback twophase_standby_recover_callbacks[]; + + +extern void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info, + const void *data, uint32 len); + +#endif /* TWOPHASE_RMGR_H */ diff --git a/install/include/postgresql/server/access/valid.h b/install/include/postgresql/server/access/valid.h new file mode 100644 index 00000000000..85d476aab58 --- /dev/null +++ b/install/include/postgresql/server/access/valid.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * valid.h + * POSTGRES tuple qualification validity definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/valid.h + * + *------------------------------------------------------------------------- + */ +#ifndef VALID_H +#define VALID_H + +#include "access/htup.h" +#include "access/htup_details.h" +#include "access/skey.h" +#include "access/tupdesc.h" + +/* + * HeapKeyTest + * + * Test a heap tuple to see if it satisfies a scan key. + */ +static inline bool +HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys) +{ + int cur_nkeys = nkeys; + ScanKey cur_key = keys; + + for (; cur_nkeys--; cur_key++) + { + Datum atp; + bool isnull; + Datum test; + + if (cur_key->sk_flags & SK_ISNULL) + return false; + + atp = heap_getattr(tuple, cur_key->sk_attno, tupdesc, &isnull); + + if (isnull) + return false; + + test = FunctionCall2Coll(&cur_key->sk_func, + cur_key->sk_collation, + atp, cur_key->sk_argument); + + if (!DatumGetBool(test)) + return false; + } + + return true; +} + +#endif /* VALID_H */ diff --git a/install/include/postgresql/server/access/visibilitymap.h b/install/include/postgresql/server/access/visibilitymap.h new file mode 100644 index 00000000000..daaa01a2578 --- /dev/null +++ b/install/include/postgresql/server/access/visibilitymap.h @@ -0,0 +1,42 @@ +/*------------------------------------------------------------------------- + * + * visibilitymap.h + * visibility map interface + * + * + * Portions Copyright (c) 2007-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/visibilitymap.h + * + *------------------------------------------------------------------------- + */ +#ifndef VISIBILITYMAP_H +#define VISIBILITYMAP_H + +#include "access/visibilitymapdefs.h" +#include "access/xlogdefs.h" +#include "storage/block.h" +#include "storage/buf.h" +#include "utils/relcache.h" + +/* Macros for visibilitymap test */ +#define VM_ALL_VISIBLE(r, b, v) \ + ((visibilitymap_get_status((r), (b), (v)) & VISIBILITYMAP_ALL_VISIBLE) != 0) +#define VM_ALL_FROZEN(r, b, v) \ + ((visibilitymap_get_status((r), (b), (v)) & VISIBILITYMAP_ALL_FROZEN) != 0) + +extern bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, + Buffer vmbuf, uint8 flags); +extern void visibilitymap_pin(Relation rel, BlockNumber heapBlk, + Buffer *vmbuf); +extern bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf); +extern void visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, + XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, + uint8 flags); +extern uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *vmbuf); +extern void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen); +extern BlockNumber visibilitymap_prepare_truncate(Relation rel, + BlockNumber nheapblocks); + +#endif /* VISIBILITYMAP_H */ diff --git a/install/include/postgresql/server/access/visibilitymapdefs.h b/install/include/postgresql/server/access/visibilitymapdefs.h new file mode 100644 index 00000000000..8dfdbfa71ef --- /dev/null +++ b/install/include/postgresql/server/access/visibilitymapdefs.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * visibilitymapdefs.h + * macros for accessing contents of visibility map pages + * + * + * Copyright (c) 2021-2023, PostgreSQL Global Development Group + * + * src/include/access/visibilitymapdefs.h + * + *------------------------------------------------------------------------- + */ +#ifndef VISIBILITYMAPDEFS_H +#define VISIBILITYMAPDEFS_H + +/* Number of bits for one heap page */ +#define BITS_PER_HEAPBLOCK 2 + +/* Flags for bit map */ +#define VISIBILITYMAP_ALL_VISIBLE 0x01 +#define VISIBILITYMAP_ALL_FROZEN 0x02 +#define VISIBILITYMAP_VALID_BITS 0x03 /* OR of all valid visibilitymap + * flags bits */ +/* + * To detect recovery conflicts during logical decoding on a standby, we need + * to know if a table is a user catalog table. For that we add an additional + * bit into xl_heap_visible.flags, in addition to the above. + * + * NB: VISIBILITYMAP_XLOG_* may not be passed to visibilitymap_set(). + */ +#define VISIBILITYMAP_XLOG_CATALOG_REL 0x04 +#define VISIBILITYMAP_XLOG_VALID_BITS (VISIBILITYMAP_VALID_BITS | VISIBILITYMAP_XLOG_CATALOG_REL) + +#endif /* VISIBILITYMAPDEFS_H */ diff --git a/install/include/postgresql/server/access/xact.h b/install/include/postgresql/server/access/xact.h new file mode 100644 index 00000000000..cb35a4a01f7 --- /dev/null +++ b/install/include/postgresql/server/access/xact.h @@ -0,0 +1,623 @@ +/*------------------------------------------------------------------------- + * + * xact.h + * postgres transaction system definitions + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xact.h + * + *------------------------------------------------------------------------- + */ +/*------------------------------------------------------------------------- + * PGRAC MODIFICATIONS (spec-1.18) + * + * Modified by: SqlRush + * + * What changed: + * 1. Pull in "cluster/cluster_scn.h" so the SCN typedef is reachable + * from xact.h consumers (backend + frontend pg_waldump). The + * header guards backend-only declarations behind #ifndef FRONTEND, + * so this include is safe from both build worlds. + * 2. Reserve bit 9 of xinfo as XACT_XINFO_HAS_SCN; signals an 8-byte + * xl_xact_scn section follows the xinfo when the cluster SCN + * subsystem captured a commit/abort SCN at WAL emit time. + * 3. Add xl_xact_scn struct (8 bytes; one SCN field) describing the + * optional WAL section. Follows the existing xl_xact_origin + * "stored unaligned!" convention; readers MUST memcpy. + * 4. Add `SCN scn` field to xl_xact_parsed_commit + xl_xact_parsed_abort + * so xact_redo_commit / xact_redo_abort can hand the value to the + * recovery-side observe wrapper without re-parsing the byte stream. + * 5. Extend XactLogCommitRecord / XactLogAbortRecord prototypes with + * a trailing `SCN commit_scn` / `SCN abort_scn` parameter. Callers + * pass InvalidScn when no SCN was captured (cluster.enabled=off, + * read-only commit, subxact commit) and the parameter is suppressed + * from WAL when InvalidScn (no XACT_XINFO_HAS_SCN bit set, zero + * bytes added to the record). + * + * Why: + * spec-1.18-wal-record-xl-scn.md §2 requires commit/abort WAL records + * to carry the cluster SCN so crash recovery + standby walreceivers + * can rebuild cluster_scn_state from WAL. HC1 (commit AND abort 双路径 + * 对称) drives the symmetric prototype change. HC3 documents that the + * overhead is +8B per commit/abort (when present) plus +4B for the + * xinfo header on the first record that uses xinfo. + * + * Spec: spec-1.18-wal-record-xl-scn.md + * Design: docs/scn-protocol-design.md §3.2 + §3.4 + * AD-008 (SCN protocol; Lamport-style distributed counters) + *------------------------------------------------------------------------- + */ +#ifndef XACT_H +#define XACT_H + +#include "access/transam.h" +#include "access/xlogreader.h" +#include "cluster/cluster_scn.h" /* PGRAC: SCN typedef for xl_xact_scn */ +#include "datatype/timestamp.h" +#include "lib/stringinfo.h" +#include "nodes/pg_list.h" +#include "storage/relfilelocator.h" +#include "storage/sinval.h" + +/* + * Maximum size of Global Transaction ID (including '\0'). + * + * Note that the max value of GIDSIZE must fit in the uint16 gidlen, + * specified in TwoPhaseFileHeader. + */ +#define GIDSIZE 200 + +/* + * Xact isolation levels + */ +#define XACT_READ_UNCOMMITTED 0 +#define XACT_READ_COMMITTED 1 +#define XACT_REPEATABLE_READ 2 +#define XACT_SERIALIZABLE 3 + +extern PGDLLIMPORT int DefaultXactIsoLevel; +extern PGDLLIMPORT int XactIsoLevel; + +/* + * We implement three isolation levels internally. + * The two stronger ones use one snapshot per database transaction; + * the others use one snapshot per statement. + * Serializable uses predicate locks in addition to snapshots. + * These macros should be used to check which isolation level is selected. + */ +#define IsolationUsesXactSnapshot() (XactIsoLevel >= XACT_REPEATABLE_READ) +#define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE) + +/* Xact read-only state */ +extern PGDLLIMPORT bool DefaultXactReadOnly; +extern PGDLLIMPORT bool XactReadOnly; + +/* flag for logging statements in this transaction */ +extern PGDLLIMPORT bool xact_is_sampled; + +/* + * Xact is deferrable -- only meaningful (currently) for read only + * SERIALIZABLE transactions + */ +extern PGDLLIMPORT bool DefaultXactDeferrable; +extern PGDLLIMPORT bool XactDeferrable; + +typedef enum +{ + SYNCHRONOUS_COMMIT_OFF, /* asynchronous commit */ + SYNCHRONOUS_COMMIT_LOCAL_FLUSH, /* wait for local flush only */ + SYNCHRONOUS_COMMIT_REMOTE_WRITE, /* wait for local flush and remote + * write */ + SYNCHRONOUS_COMMIT_REMOTE_FLUSH, /* wait for local and remote flush */ + SYNCHRONOUS_COMMIT_REMOTE_APPLY /* wait for local and remote flush and + * remote apply */ +} SyncCommitLevel; + +/* Define the default setting for synchronous_commit */ +#define SYNCHRONOUS_COMMIT_ON SYNCHRONOUS_COMMIT_REMOTE_FLUSH + +/* Synchronous commit level */ +extern PGDLLIMPORT int synchronous_commit; + +/* used during logical streaming of a transaction */ +extern PGDLLIMPORT TransactionId CheckXidAlive; +extern PGDLLIMPORT bool bsysscan; + +/* + * Miscellaneous flag bits to record events which occur on the top level + * transaction. These flags are only persisted in MyXactFlags and are intended + * so we remember to do certain things later in the transaction. This is + * globally accessible, so can be set from anywhere in the code which requires + * recording flags. + */ +extern PGDLLIMPORT int MyXactFlags; + +/* + * XACT_FLAGS_ACCESSEDTEMPNAMESPACE - set when a temporary object is accessed. + * We don't allow PREPARE TRANSACTION in that case. + */ +#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE (1U << 0) + +/* + * XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK - records whether the top level xact + * logged any Access Exclusive Locks. + */ +#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1) + +/* + * XACT_FLAGS_NEEDIMMEDIATECOMMIT - records whether the top level statement + * is one that requires immediate commit, such as CREATE DATABASE. + */ +#define XACT_FLAGS_NEEDIMMEDIATECOMMIT (1U << 2) + +/* + * XACT_FLAGS_PIPELINING - set when we complete an extended-query-protocol + * Execute message. This is useful for detecting that an implicit transaction + * block has been created via pipelining. + */ +#define XACT_FLAGS_PIPELINING (1U << 3) + +/* + * start- and end-of-transaction callbacks for dynamically loaded modules + */ +typedef enum +{ + XACT_EVENT_COMMIT, + XACT_EVENT_PARALLEL_COMMIT, + XACT_EVENT_ABORT, + XACT_EVENT_PARALLEL_ABORT, + XACT_EVENT_PREPARE, + XACT_EVENT_PRE_COMMIT, + XACT_EVENT_PARALLEL_PRE_COMMIT, + XACT_EVENT_PRE_PREPARE +} XactEvent; + +typedef void (*XactCallback) (XactEvent event, void *arg); + +typedef enum +{ + SUBXACT_EVENT_START_SUB, + SUBXACT_EVENT_COMMIT_SUB, + SUBXACT_EVENT_ABORT_SUB, + SUBXACT_EVENT_PRE_COMMIT_SUB +} SubXactEvent; + +typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid, + SubTransactionId parentSubid, void *arg); + +/* Data structure for Save/RestoreTransactionCharacteristics */ +typedef struct SavedTransactionCharacteristics +{ + int save_XactIsoLevel; + bool save_XactReadOnly; + bool save_XactDeferrable; +} SavedTransactionCharacteristics; + + +/* ---------------- + * transaction-related XLOG entries + * ---------------- + */ + +/* + * XLOG allows to store some information in high 4 bits of log record xl_info + * field. We use 3 for the opcode, and one about an optional flag variable. + */ +#define XLOG_XACT_COMMIT 0x00 +#define XLOG_XACT_PREPARE 0x10 +#define XLOG_XACT_ABORT 0x20 +#define XLOG_XACT_COMMIT_PREPARED 0x30 +#define XLOG_XACT_ABORT_PREPARED 0x40 +#define XLOG_XACT_ASSIGNMENT 0x50 +#define XLOG_XACT_INVALIDATIONS 0x60 +/* free opcode 0x70 */ + +/* mask for filtering opcodes out of xl_info */ +#define XLOG_XACT_OPMASK 0x70 + +/* does this record have a 'xinfo' field or not */ +#define XLOG_XACT_HAS_INFO 0x80 + +/* + * The following flags, stored in xinfo, determine which information is + * contained in commit/abort records. + */ +#define XACT_XINFO_HAS_DBINFO (1U << 0) +#define XACT_XINFO_HAS_SUBXACTS (1U << 1) +#define XACT_XINFO_HAS_RELFILELOCATORS (1U << 2) +#define XACT_XINFO_HAS_INVALS (1U << 3) +#define XACT_XINFO_HAS_TWOPHASE (1U << 4) +#define XACT_XINFO_HAS_ORIGIN (1U << 5) +#define XACT_XINFO_HAS_AE_LOCKS (1U << 6) +#define XACT_XINFO_HAS_GID (1U << 7) +#define XACT_XINFO_HAS_DROPPED_STATS (1U << 8) +/* PGRAC (spec-1.18): bit 9 -- cluster SCN section (xl_xact_scn, 8 bytes). */ +#define XACT_XINFO_HAS_SCN (1U << 9) +/* PGRAC (spec-3.18 D4.1): bit 10 -- durable TT-slot commit section + * (xl_xact_tt_commit), folded in from the standalone 0x30 WAL record. */ +#define XACT_XINFO_HAS_TT_COMMIT (1U << 10) + +/* + * Also stored in xinfo, these indicating a variety of additional actions that + * need to occur when emulating transaction effects during recovery. + * + * They are named XactCompletion... to differentiate them from + * EOXact... routines which run at the end of the original transaction + * completion. + */ +#define XACT_COMPLETION_APPLY_FEEDBACK (1U << 29) +#define XACT_COMPLETION_UPDATE_RELCACHE_FILE (1U << 30) +#define XACT_COMPLETION_FORCE_SYNC_COMMIT (1U << 31) + +/* Access macros for above flags */ +#define XactCompletionApplyFeedback(xinfo) \ + ((xinfo & XACT_COMPLETION_APPLY_FEEDBACK) != 0) +#define XactCompletionRelcacheInitFileInval(xinfo) \ + ((xinfo & XACT_COMPLETION_UPDATE_RELCACHE_FILE) != 0) +#define XactCompletionForceSyncCommit(xinfo) \ + ((xinfo & XACT_COMPLETION_FORCE_SYNC_COMMIT) != 0) + +typedef struct xl_xact_assignment +{ + TransactionId xtop; /* assigned XID's top-level XID */ + int nsubxacts; /* number of subtransaction XIDs */ + TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]; /* assigned subxids */ +} xl_xact_assignment; + +#define MinSizeOfXactAssignment offsetof(xl_xact_assignment, xsub) + +/* + * Commit and abort records can contain a lot of information. But a large + * portion of the records won't need all possible pieces of information. So we + * only include what's needed. + * + * A minimal commit/abort record only consists of a xl_xact_commit/abort + * struct. The presence of additional information is indicated by bits set in + * 'xl_xact_xinfo->xinfo'. The presence of the xinfo field itself is signaled + * by a set XLOG_XACT_HAS_INFO bit in the xl_info field. + * + * NB: All the individual data chunks should be sized to multiples of + * sizeof(int) and only require int32 alignment. If they require bigger + * alignment, they need to be copied upon reading. + */ + +/* sub-records for commit/abort */ + +typedef struct xl_xact_xinfo +{ + /* + * Even though we right now only require two bytes of space in xinfo we + * use four so following records don't have to care about alignment. + * Commit records can be large, so copying large portions isn't + * attractive. + */ + uint32 xinfo; +} xl_xact_xinfo; + +typedef struct xl_xact_dbinfo +{ + Oid dbId; /* MyDatabaseId */ + Oid tsId; /* MyDatabaseTableSpace */ +} xl_xact_dbinfo; + +typedef struct xl_xact_subxacts +{ + int nsubxacts; /* number of subtransaction XIDs */ + TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]; +} xl_xact_subxacts; +#define MinSizeOfXactSubxacts offsetof(xl_xact_subxacts, subxacts) + +typedef struct xl_xact_relfilelocators +{ + int nrels; /* number of relations */ + RelFileLocator xlocators[FLEXIBLE_ARRAY_MEMBER]; +} xl_xact_relfilelocators; +#define MinSizeOfXactRelfileLocators offsetof(xl_xact_relfilelocators, xlocators) + +/* + * A transactionally dropped statistics entry. + * + * Declared here rather than pgstat.h because pgstat.h can't be included from + * frontend code, but the WAL format needs to be readable by frontend + * programs. + */ +typedef struct xl_xact_stats_item +{ + int kind; + Oid dboid; + Oid objoid; +} xl_xact_stats_item; + +typedef struct xl_xact_stats_items +{ + int nitems; + xl_xact_stats_item items[FLEXIBLE_ARRAY_MEMBER]; +} xl_xact_stats_items; +#define MinSizeOfXactStatsItems offsetof(xl_xact_stats_items, items) + +typedef struct xl_xact_invals +{ + int nmsgs; /* number of shared inval msgs */ + SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]; +} xl_xact_invals; +#define MinSizeOfXactInvals offsetof(xl_xact_invals, msgs) + +typedef struct xl_xact_twophase +{ + TransactionId xid; +} xl_xact_twophase; + +typedef struct xl_xact_origin +{ + XLogRecPtr origin_lsn; + TimestampTz origin_timestamp; +} xl_xact_origin; + +/* + * PGRAC (spec-1.18): cluster SCN sub-record. Present iff XACT_XINFO_HAS_SCN + * bit is set in xinfo. Stored unaligned! -- placed after xl_xact_origin + * which itself documents the unaligned property; readers MUST use memcpy + * (see xactdesc.c ParseCommitRecord / ParseAbortRecord). + */ +typedef struct xl_xact_scn +{ + SCN scn; /* commit/abort SCN captured at WAL emit */ +} xl_xact_scn; + +/* + * PGRAC (spec-3.18 D4.1): durable-TT-slot commit sub-record, folded into the + * normal commit record instead of a standalone XLOG_UNDO_TT_SLOT_COMMIT (0x30) + * -- saves one WAL record + XLogInsert per commit. Present iff + * XACT_XINFO_HAS_TT_COMMIT. Stored unaligned (like xl_xact_scn) -- readers + * MUST memcpy. Mirrors xl_undo_tt_slot_commit so xact_redo_commit can reuse + * the existing redo decision (cluster_tt_durable_redo_decide). The 2PC path + * (PREPARE / COMMIT PREPARED) keeps the standalone 0x30 -- a prepared xact's + * TT durability is not in a normal commit record. + */ +typedef struct xl_xact_tt_commit +{ + uint32 segment_id; + uint16 slot_offset; + uint16 wrap; + TransactionId xid; /* slot owner xid; always == the committing xid (non-prepared) */ + uint8 instance; /* owner instance (1..128) for path resolution */ + uint8 _pad[3]; + SCN commit_scn; +} xl_xact_tt_commit; + +StaticAssertDecl(sizeof(xl_xact_tt_commit) == 24, + "xl_xact_tt_commit must be 24 bytes — mirrors xl_undo_tt_slot_commit (D4.1)"); +StaticAssertDecl(offsetof(xl_xact_tt_commit, commit_scn) == 16, + "xl_xact_tt_commit.commit_scn must be at offset 16 (SCN 8-byte alignment; D4.1)"); + +typedef struct xl_xact_commit +{ + TimestampTz xact_time; /* time of commit */ + + /* xl_xact_xinfo follows if XLOG_XACT_HAS_INFO */ + /* xl_xact_dbinfo follows if XINFO_HAS_DBINFO */ + /* xl_xact_subxacts follows if XINFO_HAS_SUBXACT */ + /* xl_xact_relfilelocators follows if XINFO_HAS_RELFILELOCATORS */ + /* xl_xact_stats_items follows if XINFO_HAS_DROPPED_STATS */ + /* xl_xact_invals follows if XINFO_HAS_INVALS */ + /* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */ + /* twophase_gid follows if XINFO_HAS_GID. As a null-terminated string. */ + /* xl_xact_origin follows if XINFO_HAS_ORIGIN, stored unaligned! */ + /* PGRAC: xl_xact_scn follows if XINFO_HAS_SCN, stored unaligned! */ +} xl_xact_commit; +#define MinSizeOfXactCommit (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz)) + +typedef struct xl_xact_abort +{ + TimestampTz xact_time; /* time of abort */ + + /* xl_xact_xinfo follows if XLOG_XACT_HAS_INFO */ + /* xl_xact_dbinfo follows if XINFO_HAS_DBINFO */ + /* xl_xact_subxacts follows if XINFO_HAS_SUBXACT */ + /* xl_xact_relfilelocators follows if XINFO_HAS_RELFILELOCATORS */ + /* xl_xact_stats_items follows if XINFO_HAS_DROPPED_STATS */ + /* No invalidation messages needed. */ + /* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */ + /* twophase_gid follows if XINFO_HAS_GID. As a null-terminated string. */ + /* xl_xact_origin follows if XINFO_HAS_ORIGIN, stored unaligned! */ + /* PGRAC: xl_xact_scn follows if XINFO_HAS_SCN, stored unaligned! */ +} xl_xact_abort; +#define MinSizeOfXactAbort sizeof(xl_xact_abort) + +typedef struct xl_xact_prepare +{ + uint32 magic; /* format identifier */ + uint32 total_len; /* actual file length */ + TransactionId xid; /* original transaction XID */ + Oid database; /* OID of database it was in */ + TimestampTz prepared_at; /* time of preparation */ + Oid owner; /* user running the transaction */ + int32 nsubxacts; /* number of following subxact XIDs */ + int32 ncommitrels; /* number of delete-on-commit rels */ + int32 nabortrels; /* number of delete-on-abort rels */ + int32 ncommitstats; /* number of stats to drop on commit */ + int32 nabortstats; /* number of stats to drop on abort */ + int32 ninvalmsgs; /* number of cache invalidation messages */ + bool initfileinval; /* does relcache init file need invalidation? */ + uint16 gidlen; /* length of the GID - GID follows the header */ + XLogRecPtr origin_lsn; /* lsn of this record at origin node */ + TimestampTz origin_timestamp; /* time of prepare at origin node */ +} xl_xact_prepare; + +/* + * Commit/Abort records in the above form are a bit verbose to parse, so + * there's a deconstructed versions generated by ParseCommit/AbortRecord() for + * easier consumption. + */ +typedef struct xl_xact_parsed_commit +{ + TimestampTz xact_time; + uint32 xinfo; + + Oid dbId; /* MyDatabaseId */ + Oid tsId; /* MyDatabaseTableSpace */ + + int nsubxacts; + TransactionId *subxacts; + + int nrels; + RelFileLocator *xlocators; + + int nstats; + xl_xact_stats_item *stats; + + int nmsgs; + SharedInvalidationMessage *msgs; + + TransactionId twophase_xid; /* only for 2PC */ + char twophase_gid[GIDSIZE]; /* only for 2PC */ + int nabortrels; /* only for 2PC */ + RelFileLocator *abortlocators; /* only for 2PC */ + int nabortstats; /* only for 2PC */ + xl_xact_stats_item *abortstats; /* only for 2PC */ + + XLogRecPtr origin_lsn; + TimestampTz origin_timestamp; + + SCN scn; /* PGRAC (spec-1.18): InvalidScn if !HAS_SCN */ + bool has_tt_commit; /* PGRAC (spec-3.18 D4.1): XACT_XINFO_HAS_TT_COMMIT set */ + xl_xact_tt_commit tt_commit; /* PGRAC (spec-3.18 D4.1): valid iff has_tt_commit */ +} xl_xact_parsed_commit; + +typedef xl_xact_parsed_commit xl_xact_parsed_prepare; + +typedef struct xl_xact_parsed_abort +{ + TimestampTz xact_time; + uint32 xinfo; + + Oid dbId; /* MyDatabaseId */ + Oid tsId; /* MyDatabaseTableSpace */ + + int nsubxacts; + TransactionId *subxacts; + + int nrels; + RelFileLocator *xlocators; + + int nstats; + xl_xact_stats_item *stats; + + TransactionId twophase_xid; /* only for 2PC */ + char twophase_gid[GIDSIZE]; /* only for 2PC */ + + XLogRecPtr origin_lsn; + TimestampTz origin_timestamp; + + SCN scn; /* PGRAC (spec-1.18): InvalidScn if !HAS_SCN */ +} xl_xact_parsed_abort; + + +/* ---------------- + * extern definitions + * ---------------- + */ +extern bool IsTransactionState(void); +extern bool IsAbortedTransactionBlockState(void); +extern TransactionId GetTopTransactionId(void); +extern TransactionId GetTopTransactionIdIfAny(void); +extern TransactionId GetCurrentTransactionId(void); +extern TransactionId GetCurrentTransactionIdIfAny(void); +extern TransactionId GetStableLatestTransactionId(void); +extern SubTransactionId GetCurrentSubTransactionId(void); +extern FullTransactionId GetTopFullTransactionId(void); +extern FullTransactionId GetTopFullTransactionIdIfAny(void); +extern FullTransactionId GetCurrentFullTransactionId(void); +extern FullTransactionId GetCurrentFullTransactionIdIfAny(void); +extern void MarkCurrentTransactionIdLoggedIfAny(void); +extern bool SubTransactionIsActive(SubTransactionId subxid); +extern CommandId GetCurrentCommandId(bool used); +extern void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts); +extern TimestampTz GetCurrentTransactionStartTimestamp(void); +extern TimestampTz GetCurrentStatementStartTimestamp(void); +extern TimestampTz GetCurrentTransactionStopTimestamp(void); +extern void SetCurrentStatementStartTimestamp(void); +extern int GetCurrentTransactionNestLevel(void); +extern bool TransactionIdIsCurrentTransactionId(TransactionId xid); +extern void CommandCounterIncrement(void); +extern void ForceSyncCommit(void); +extern void StartTransactionCommand(void); +extern void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s); +extern void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s); +extern void CommitTransactionCommand(void); +extern void AbortCurrentTransaction(void); +extern void BeginTransactionBlock(void); +extern bool EndTransactionBlock(bool chain); +extern bool PrepareTransactionBlock(const char *gid); +extern void UserAbortTransactionBlock(bool chain); +extern void BeginImplicitTransactionBlock(void); +extern void EndImplicitTransactionBlock(void); +extern void ReleaseSavepoint(const char *name); +extern void DefineSavepoint(const char *name); +extern void RollbackToSavepoint(const char *name); +extern void BeginInternalSubTransaction(const char *name); +extern void ReleaseCurrentSubTransaction(void); +extern void RollbackAndReleaseCurrentSubTransaction(void); +extern bool IsSubTransaction(void); +extern Size EstimateTransactionStateSpace(void); +extern void SerializeTransactionState(Size maxsize, char *start_address); +extern void StartParallelWorkerTransaction(char *tstatespace); +extern void EndParallelWorkerTransaction(void); +extern bool IsTransactionBlock(void); +extern bool IsTransactionOrTransactionBlock(void); +extern char TransactionBlockStatusCode(void); +extern void AbortOutOfAnyTransaction(void); +extern void PreventInTransactionBlock(bool isTopLevel, const char *stmtType); +extern void RequireTransactionBlock(bool isTopLevel, const char *stmtType); +extern void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType); +extern bool IsInTransactionBlock(bool isTopLevel); +extern void RegisterXactCallback(XactCallback callback, void *arg); +extern void UnregisterXactCallback(XactCallback callback, void *arg); +extern void RegisterSubXactCallback(SubXactCallback callback, void *arg); +extern void UnregisterSubXactCallback(SubXactCallback callback, void *arg); + +extern bool IsSubxactTopXidLogPending(void); +extern void MarkSubxactTopXidLogged(void); + +extern int xactGetCommittedChildren(TransactionId **ptr); + +extern XLogRecPtr XactLogCommitRecord(TimestampTz commit_time, + int nsubxacts, TransactionId *subxacts, + int nrels, RelFileLocator *rels, + int ndroppedstats, + xl_xact_stats_item *droppedstats, + int nmsgs, SharedInvalidationMessage *msgs, + bool relcacheInval, + int xactflags, + TransactionId twophase_xid, + const char *twophase_gid, + SCN commit_scn, /* PGRAC: spec-1.18 */ + const xl_xact_tt_commit *tt_commit); /* PGRAC: spec-3.18 D4.1 */ + +extern XLogRecPtr XactLogAbortRecord(TimestampTz abort_time, + int nsubxacts, TransactionId *subxacts, + int nrels, RelFileLocator *rels, + int ndroppedstats, + xl_xact_stats_item *droppedstats, + int xactflags, TransactionId twophase_xid, + const char *twophase_gid, + SCN abort_scn); /* PGRAC: spec-1.18 */ +extern void xact_redo(XLogReaderState *record); + +/* xactdesc.c */ +extern void xact_desc(StringInfo buf, XLogReaderState *record); +extern const char *xact_identify(uint8 info); + +/* also in xactdesc.c, so they can be shared between front/backend code */ +extern void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed); +extern void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed); +extern void ParsePrepareRecord(uint8 info, xl_xact_prepare *xlrec, xl_xact_parsed_prepare *parsed); + +extern void EnterParallelMode(void); +extern void ExitParallelMode(void); +extern bool IsInParallelMode(void); + +#endif /* XACT_H */ diff --git a/install/include/postgresql/server/access/xlog.h b/install/include/postgresql/server/access/xlog.h new file mode 100644 index 00000000000..ebb9eaade0a --- /dev/null +++ b/install/include/postgresql/server/access/xlog.h @@ -0,0 +1,303 @@ +/* + * xlog.h + * + * PostgreSQL write-ahead log manager + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xlog.h + */ +#ifndef XLOG_H +#define XLOG_H + +#include "access/xlogbackup.h" +#include "access/xlogdefs.h" +#include "datatype/timestamp.h" +#include "lib/stringinfo.h" +#include "nodes/pg_list.h" + + +/* Sync methods */ +#define SYNC_METHOD_FSYNC 0 +#define SYNC_METHOD_FDATASYNC 1 +#define SYNC_METHOD_OPEN 2 /* for O_SYNC */ +#define SYNC_METHOD_FSYNC_WRITETHROUGH 3 +#define SYNC_METHOD_OPEN_DSYNC 4 /* for O_DSYNC */ +extern PGDLLIMPORT int sync_method; + +extern PGDLLIMPORT XLogRecPtr ProcLastRecPtr; +extern PGDLLIMPORT XLogRecPtr XactLastRecEnd; +extern PGDLLIMPORT XLogRecPtr XactLastCommitEnd; + +/* these variables are GUC parameters related to XLOG */ +extern PGDLLIMPORT int wal_segment_size; +extern PGDLLIMPORT int min_wal_size_mb; +extern PGDLLIMPORT int max_wal_size_mb; +extern PGDLLIMPORT int wal_keep_size_mb; +extern PGDLLIMPORT int max_slot_wal_keep_size_mb; +extern PGDLLIMPORT int XLOGbuffers; +extern PGDLLIMPORT int XLogArchiveTimeout; +extern PGDLLIMPORT int wal_retrieve_retry_interval; +extern PGDLLIMPORT char *XLogArchiveCommand; +extern PGDLLIMPORT bool EnableHotStandby; +extern PGDLLIMPORT bool fullPageWrites; +extern PGDLLIMPORT bool wal_log_hints; +extern PGDLLIMPORT int wal_compression; +extern PGDLLIMPORT bool wal_init_zero; +extern PGDLLIMPORT bool wal_recycle; +extern PGDLLIMPORT bool *wal_consistency_checking; +extern PGDLLIMPORT char *wal_consistency_checking_string; +extern PGDLLIMPORT bool log_checkpoints; +extern PGDLLIMPORT bool track_wal_io_timing; +extern PGDLLIMPORT int wal_decode_buffer_size; + +extern PGDLLIMPORT int CheckPointSegments; + +/* Archive modes */ +typedef enum ArchiveMode +{ + ARCHIVE_MODE_OFF = 0, /* disabled */ + ARCHIVE_MODE_ON, /* enabled while server is running normally */ + ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */ +} ArchiveMode; +extern PGDLLIMPORT int XLogArchiveMode; + +/* WAL levels */ +typedef enum WalLevel +{ + WAL_LEVEL_MINIMAL = 0, + WAL_LEVEL_REPLICA, + WAL_LEVEL_LOGICAL +} WalLevel; + +/* Compression algorithms for WAL */ +typedef enum WalCompression +{ + WAL_COMPRESSION_NONE = 0, + WAL_COMPRESSION_PGLZ, + WAL_COMPRESSION_LZ4, + WAL_COMPRESSION_ZSTD +} WalCompression; + +/* Recovery states */ +typedef enum RecoveryState +{ + RECOVERY_STATE_CRASH = 0, /* crash recovery */ + RECOVERY_STATE_ARCHIVE, /* archive recovery */ + RECOVERY_STATE_DONE /* currently in production */ +} RecoveryState; + +extern PGDLLIMPORT int wal_level; + +/* Is WAL archiving enabled (always or only while server is running normally)? */ +#define XLogArchivingActive() \ + (AssertMacro(XLogArchiveMode == ARCHIVE_MODE_OFF || wal_level >= WAL_LEVEL_REPLICA), XLogArchiveMode > ARCHIVE_MODE_OFF) +/* Is WAL archiving enabled always (even during recovery)? */ +#define XLogArchivingAlways() \ + (AssertMacro(XLogArchiveMode == ARCHIVE_MODE_OFF || wal_level >= WAL_LEVEL_REPLICA), XLogArchiveMode == ARCHIVE_MODE_ALWAYS) + +/* + * Is WAL-logging necessary for archival or log-shipping, or can we skip + * WAL-logging if we fsync() the data before committing instead? + */ +#define XLogIsNeeded() (wal_level >= WAL_LEVEL_REPLICA) + +/* + * Is a full-page image needed for hint bit updates? + * + * Normally, we don't WAL-log hint bit updates, but if checksums are enabled, + * we have to protect them against torn page writes. When you only set + * individual bits on a page, it's still consistent no matter what combination + * of the bits make it to disk, but the checksum wouldn't match. Also WAL-log + * them if forced by wal_log_hints=on. + */ +#define XLogHintBitIsNeeded() (DataChecksumsEnabled() || wal_log_hints) + +/* Do we need to WAL-log information required only for Hot Standby and logical replication? */ +#define XLogStandbyInfoActive() (wal_level >= WAL_LEVEL_REPLICA) + +/* Do we need to WAL-log information required only for logical replication? */ +#define XLogLogicalInfoActive() (wal_level >= WAL_LEVEL_LOGICAL) + +#ifdef WAL_DEBUG +extern PGDLLIMPORT bool XLOG_DEBUG; +#endif + +/* + * OR-able request flag bits for checkpoints. The "cause" bits are used only + * for logging purposes. Note: the flags must be defined so that it's + * sensible to OR together request flags arising from different requestors. + */ + +/* These directly affect the behavior of CreateCheckPoint and subsidiaries */ +#define CHECKPOINT_IS_SHUTDOWN 0x0001 /* Checkpoint is for shutdown */ +#define CHECKPOINT_END_OF_RECOVERY 0x0002 /* Like shutdown checkpoint, but + * issued at end of WAL recovery */ +#define CHECKPOINT_IMMEDIATE 0x0004 /* Do it without delays */ +#define CHECKPOINT_FORCE 0x0008 /* Force even if no activity */ +#define CHECKPOINT_FLUSH_ALL 0x0010 /* Flush all pages, including those + * belonging to unlogged tables */ +/* These are important to RequestCheckpoint */ +#define CHECKPOINT_WAIT 0x0020 /* Wait for completion */ +#define CHECKPOINT_REQUESTED 0x0040 /* Checkpoint request has been made */ +/* These indicate the cause of a checkpoint request */ +#define CHECKPOINT_CAUSE_XLOG 0x0080 /* XLOG consumption */ +#define CHECKPOINT_CAUSE_TIME 0x0100 /* Elapsed time */ + +/* + * Flag bits for the record being inserted, set using XLogSetRecordFlags(). + */ +#define XLOG_INCLUDE_ORIGIN 0x01 /* include the replication origin */ +#define XLOG_MARK_UNIMPORTANT 0x02 /* record not important for durability */ + + +/* Checkpoint statistics */ +typedef struct CheckpointStatsData +{ + TimestampTz ckpt_start_t; /* start of checkpoint */ + TimestampTz ckpt_write_t; /* start of flushing buffers */ + TimestampTz ckpt_sync_t; /* start of fsyncs */ + TimestampTz ckpt_sync_end_t; /* end of fsyncs */ + TimestampTz ckpt_end_t; /* end of checkpoint */ + + int ckpt_bufs_written; /* # of buffers written */ + + int ckpt_segs_added; /* # of new xlog segments created */ + int ckpt_segs_removed; /* # of xlog segments deleted */ + int ckpt_segs_recycled; /* # of xlog segments recycled */ + + int ckpt_sync_rels; /* # of relations synced */ + uint64 ckpt_longest_sync; /* Longest sync for one relation */ + uint64 ckpt_agg_sync_time; /* The sum of all the individual sync + * times, which is not necessarily the + * same as the total elapsed time for the + * entire sync phase. */ +} CheckpointStatsData; + +extern PGDLLIMPORT CheckpointStatsData CheckpointStats; + +/* + * GetWALAvailability return codes + */ +typedef enum WALAvailability +{ + WALAVAIL_INVALID_LSN, /* parameter error */ + WALAVAIL_RESERVED, /* WAL segment is within max_wal_size */ + WALAVAIL_EXTENDED, /* WAL segment is reserved by a slot or + * wal_keep_size */ + WALAVAIL_UNRESERVED, /* no longer reserved, but not removed yet */ + WALAVAIL_REMOVED /* WAL segment has been removed */ +} WALAvailability; + +struct XLogRecData; +struct XLogReaderState; + +extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata, + XLogRecPtr fpw_lsn, + uint8 flags, + int num_fpi, + bool topxid_included); +extern void XLogFlush(XLogRecPtr record); +extern bool XLogBackgroundFlush(void); +extern bool XLogNeedsFlush(XLogRecPtr record); +extern int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli); +extern int XLogFileOpen(XLogSegNo segno, TimeLineID tli); + +extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli); +extern XLogSegNo XLogGetLastRemovedSegno(void); +extern void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN); +extern void XLogSetReplicationSlotMinimumLSN(XLogRecPtr lsn); + +extern void xlog_redo(struct XLogReaderState *record); +extern void xlog_desc(StringInfo buf, struct XLogReaderState *record); +extern const char *xlog_identify(uint8 info); + +extern void issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli); + +extern bool RecoveryInProgress(void); +extern RecoveryState GetRecoveryState(void); +extern bool XLogInsertAllowed(void); +extern XLogRecPtr GetXLogInsertRecPtr(void); +extern XLogRecPtr GetXLogWriteRecPtr(void); + +extern uint64 GetSystemIdentifier(void); +extern char *GetMockAuthenticationNonce(void); +extern bool DataChecksumsEnabled(void); +extern XLogRecPtr GetFakeLSNForUnloggedRel(void); +extern Size XLOGShmemSize(void); +extern void XLOGShmemInit(void); +extern void BootStrapXLOG(void); +extern void InitializeWalConsistencyChecking(void); +extern void LocalProcessControlFile(bool reset); +extern WalLevel GetActiveWalLevelOnStandby(void); +extern void StartupXLOG(void); +extern void ShutdownXLOG(int code, Datum arg); +extern void CreateCheckPoint(int flags); +extern bool CreateRestartPoint(int flags); +extern WALAvailability GetWALAvailability(XLogRecPtr targetLSN); +extern void XLogPutNextOid(Oid nextOid); +extern XLogRecPtr XLogRestorePoint(const char *rpName); +extern void UpdateFullPageWrites(void); +extern void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p); +extern XLogRecPtr GetRedoRecPtr(void); +extern XLogRecPtr GetInsertRecPtr(void); +extern XLogRecPtr GetFlushRecPtr(TimeLineID *insertTLI); +extern TimeLineID GetWALInsertionTimeLine(void); +extern XLogRecPtr GetLastImportantRecPtr(void); + +extern void SetWalWriterSleeping(bool sleeping); + +/* + * Routines used by xlogrecovery.c to call back into xlog.c during recovery. + */ +extern void RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI); +extern bool XLogCheckpointNeeded(XLogSegNo new_segno); +extern void SwitchIntoArchiveRecovery(XLogRecPtr EndRecPtr, TimeLineID replayTLI); +extern void ReachedEndOfBackup(XLogRecPtr EndRecPtr, TimeLineID tli); +extern void SetInstallXLogFileSegmentActive(void); +extern bool IsInstallXLogFileSegmentActive(void); +extern void ResetInstallXLogFileSegmentActive(void); +extern void XLogShutdownWalRcv(void); + +/* + * Routines to start, stop, and get status of a base backup. + */ + +/* + * Session-level status of base backups + * + * This is used in parallel with the shared memory status to control parallel + * execution of base backup functions for a given session, be it a backend + * dedicated to replication or a normal backend connected to a database. The + * update of the session-level status happens at the same time as the shared + * memory counters to keep a consistent global and local state of the backups + * running. + */ +typedef enum SessionBackupState +{ + SESSION_BACKUP_NONE, + SESSION_BACKUP_RUNNING, +} SessionBackupState; + +extern void do_pg_backup_start(const char *backupidstr, bool fast, + List **tablespaces, BackupState *state, + StringInfo tblspcmapfile); +extern void do_pg_backup_stop(BackupState *state, bool waitforarchive); +extern void do_pg_abort_backup(int code, Datum arg); +extern void register_persistent_abort_backup_handler(void); +extern SessionBackupState get_backup_status(void); + +/* File path names (all relative to $PGDATA) */ +#define RECOVERY_SIGNAL_FILE "recovery.signal" +#define STANDBY_SIGNAL_FILE "standby.signal" +#define BACKUP_LABEL_FILE "backup_label" +#define BACKUP_LABEL_OLD "backup_label.old" + +#define TABLESPACE_MAP "tablespace_map" +#define TABLESPACE_MAP_OLD "tablespace_map.old" + +/* files to signal promotion to primary */ +#define PROMOTE_SIGNAL_FILE "promote" + +#endif /* XLOG_H */ diff --git a/install/include/postgresql/server/access/xlog_internal.h b/install/include/postgresql/server/access/xlog_internal.h new file mode 100644 index 00000000000..a361088592c --- /dev/null +++ b/install/include/postgresql/server/access/xlog_internal.h @@ -0,0 +1,484 @@ +/* + * xlog_internal.h + * + * PostgreSQL write-ahead log internal declarations + * + * NOTE: this file is intended to contain declarations useful for + * manipulating the XLOG files directly, but it is not supposed to be + * needed by rmgr routines (redo support for individual record types). + * So the XLogRecord typedef and associated stuff appear in xlogrecord.h. + * + * Note: This file must be includable in both frontend and backend contexts, + * to allow stand-alone tools like pg_receivewal to deal with WAL files. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xlog_internal.h + */ +/*------------------------------------------------------------------------- + * PGRAC MODIFICATIONS (spec-1.19) + * + * Modified by: SqlRush + * + * What changed: + * 1. Extend XLogPageHeaderData with xlp_thread_id (uint16) and + * xlp_cluster_flags (uint16) at offsets 20 and 22. These two + * 2-byte fields occupy the previous MAXALIGN trailing padding so + * sizeof(XLogPageHeaderData) stays exactly 24 bytes — verified by + * StaticAssertDecl below. vanilla PG MemSet's the entire 8 KB + * page (xlog.c:1878 AdvanceXLInsertBuffer + xlog.c:4685 + * BootStrapXLOG + pg_resetwal.c:1059) before writing the named + * header fields, so the on-disk byte stream is byte-identical to + * vanilla PG when both new fields land as zero. + * 2. Define XLP_THREAD_ID_LEGACY (= 0) as the permanent sentinel for + * "legacy / single-thread / default" pages. Stage 1 always + * writes LEGACY; Stage 2+ feature-034 will assign real per-instance + * thread IDs starting at 1, mapping `thread_id = node_id + 1` so + * zero remains permanently reserved. + * + * Why: + * spec-1.19-wal-page-header-thread-id.md establishes the structural + * placeholder for AD-009 per-instance redo thread routing. Q1=A + * approve: reuse MAXALIGN padding (no on-disk growth, no catversion + * bump). Q2 sentinel rule: zero is permanently legacy; future Stage + * 2+ code MUST NOT assign zero to any real instance. + * + * Spec: spec-1.19-wal-page-header-thread-id.md APPROVED 2026-05-05 v0.2 + * Design: docs/wal-record-format-design.md §5.1 + * AD-009 (Per-instance redo thread + 共享存储 + merged recovery) + *------------------------------------------------------------------------- + */ +#ifndef XLOG_INTERNAL_H +#define XLOG_INTERNAL_H + +#include "access/xlogdefs.h" +#include "access/xlogreader.h" +#include "datatype/timestamp.h" +#include "lib/stringinfo.h" +#include "pgtime.h" +#include "storage/block.h" +#include "storage/relfilelocator.h" + + +/* + * Each page of XLOG file has a header like this: + */ +#define XLOG_PAGE_MAGIC 0xD114 /* PGRAC spec-4.5: xl_scn record header (was 0xD113) */ + +typedef struct XLogPageHeaderData +{ + uint16 xlp_magic; /* magic value for correctness checks */ + uint16 xlp_info; /* flag bits, see below */ + TimeLineID xlp_tli; /* TimeLineID of first record on page */ + XLogRecPtr xlp_pageaddr; /* XLOG address of this page */ + + /* + * When there is not enough space on current page for whole record, we + * continue on the next page. xlp_rem_len is the number of bytes + * remaining from a previous page; it tracks xl_tot_len in the initial + * header. Note that the continuation data isn't necessarily aligned. + */ + uint32 xlp_rem_len; /* total len of remaining data for record */ + + /* + * PGRAC (spec-1.19): cluster fields occupying the previous MAXALIGN + * trailing padding (offsets 20-23). sizeof(XLogPageHeaderData) is + * still 24 bytes — see StaticAssertDecl below. Both fields are + * permanently zero in Stage 1 (XLP_THREAD_ID_LEGACY + + * XLP_CLUSTER_FLAGS_RESERVED); Stage 2+ feature-034 activates real + * per-instance thread IDs starting at 1. + */ + uint16 xlp_thread_id; /* AD-009 thread/instance; 0 = legacy sentinel */ + uint16 xlp_cluster_flags; /* cluster flag bits; reserved = 0 */ +} XLogPageHeaderData; + +/* + * PGRAC (spec-1.19 Q1=A invariant): page header on-disk layout is + * preserved. The placeholder fields reuse the previous MAXALIGN tail + * padding; growth would force a catversion bump in a separate spec. + */ +StaticAssertDecl(sizeof(XLogPageHeaderData) == 24, + "spec-1.19 Q1=A invariant: XLogPageHeaderData on-disk size " + "MUST stay 24 bytes (padding reuse)"); +StaticAssertDecl(offsetof(XLogPageHeaderData, xlp_thread_id) == 20, + "spec-1.19 Q1=A invariant: xlp_thread_id occupies the " + "MAXALIGN tail padding starting at byte 20"); +StaticAssertDecl(offsetof(XLogPageHeaderData, xlp_cluster_flags) == 22, + "spec-1.19 Q1=A invariant: xlp_cluster_flags follows " + "thread_id at byte 22"); + +/* + * PGRAC (spec-1.19 Q2 v0.2 sentinel rule): xlp_thread_id semantics. + * + * XLP_THREAD_ID_LEGACY (= 0) is permanently reserved for "legacy / + * single-thread / default" pages. All Stage 1 pages, all PG 16 pages + * pre-spec-1.19 (the MAXALIGN padding bytes were always zero, see + * xlog.c:1878 MemSet), and all --disable-cluster builds emit LEGACY. + * + * Stage 2+ feature-034 activates real per-instance thread IDs in the + * range [XLP_THREAD_ID_FIRST_REAL, XLP_THREAD_ID_MAX_REAL] mapping + * thread_id = cluster_node_id + 1, so zero remains forever a + * sentinel. Future code MUST NOT reassign zero to any real instance. + */ +#define XLP_THREAD_ID_LEGACY ((uint16) 0) +#define XLP_THREAD_ID_FIRST_REAL ((uint16) 1) +#define XLP_THREAD_ID_MAX_REAL ((uint16) 0xFFFE) +#define XLP_THREAD_ID_INVALID ((uint16) 0xFFFF) + +/* Stage 1 cluster_flags is fully reserved (= 0); Stage 2+ may carve bits. */ +#define XLP_CLUSTER_FLAGS_RESERVED ((uint16) 0) + +#define SizeOfXLogShortPHD MAXALIGN(sizeof(XLogPageHeaderData)) + +typedef XLogPageHeaderData *XLogPageHeader; + +/* + * When the XLP_LONG_HEADER flag is set, we store additional fields in the + * page header. (This is ordinarily done just in the first page of an + * XLOG file.) The additional fields serve to identify the file accurately. + */ +typedef struct XLogLongPageHeaderData +{ + XLogPageHeaderData std; /* standard header fields */ + uint64 xlp_sysid; /* system identifier from pg_control */ + uint32 xlp_seg_size; /* just as a cross-check */ + uint32 xlp_xlog_blcksz; /* just as a cross-check */ +} XLogLongPageHeaderData; + +#define SizeOfXLogLongPHD MAXALIGN(sizeof(XLogLongPageHeaderData)) + +typedef XLogLongPageHeaderData *XLogLongPageHeader; + +/* When record crosses page boundary, set this flag in new page's header */ +#define XLP_FIRST_IS_CONTRECORD 0x0001 +/* This flag indicates a "long" page header */ +#define XLP_LONG_HEADER 0x0002 +/* This flag indicates backup blocks starting in this page are optional */ +#define XLP_BKP_REMOVABLE 0x0004 +/* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */ +#define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008 +/* All defined flag bits in xlp_info (used for validity checking of header) */ +#define XLP_ALL_FLAGS 0x000F + +#define XLogPageHeaderSize(hdr) \ + (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) + +/* wal_segment_size can range from 1MB to 1GB */ +#define WalSegMinSize 1024 * 1024 +#define WalSegMaxSize 1024 * 1024 * 1024 +/* default number of min and max wal segments */ +#define DEFAULT_MIN_WAL_SEGS 5 +#define DEFAULT_MAX_WAL_SEGS 64 + +/* check that the given size is a valid wal_segment_size */ +#define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0) +#define IsValidWalSegSize(size) \ + (IsPowerOf2(size) && \ + ((size) >= WalSegMinSize && (size) <= WalSegMaxSize)) + +#define XLogSegmentsPerXLogId(wal_segsz_bytes) \ + (UINT64CONST(0x100000000) / (wal_segsz_bytes)) + +#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \ + (dest) = (segno) * (wal_segsz_bytes) + (offset) + +#define XLogSegmentOffset(xlogptr, wal_segsz_bytes) \ + ((xlogptr) & ((wal_segsz_bytes) - 1)) + +/* + * Compute a segment number from an XLogRecPtr. + * + * For XLByteToSeg, do the computation at face value. For XLByteToPrevSeg, + * a boundary byte is taken to be in the previous segment. This is suitable + * for deciding which segment to write given a pointer to a record end, + * for example. + */ +#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \ + logSegNo = (xlrp) / (wal_segsz_bytes) + +#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ + logSegNo = ((xlrp) - 1) / (wal_segsz_bytes) + +/* + * Convert values of GUCs measured in megabytes to equiv. segment count. + * Rounds down. + */ +#define XLogMBVarToSegs(mbvar, wal_segsz_bytes) \ + ((mbvar) / ((wal_segsz_bytes) / (1024 * 1024))) + +/* + * Is an XLogRecPtr within a particular XLOG segment? + * + * For XLByteInSeg, do the computation at face value. For XLByteInPrevSeg, + * a boundary byte is taken to be in the previous segment. + */ +#define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \ + (((xlrp) / (wal_segsz_bytes)) == (logSegNo)) + +#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ + ((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo)) + +/* Check if an XLogRecPtr value is in a plausible range */ +#define XRecOffIsValid(xlrp) \ + ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD) + +/* + * The XLog directory and control file (relative to $PGDATA) + */ +#define XLOGDIR "pg_wal" +#define XLOG_CONTROL_FILE "global/pg_control" + +/* + * These macros encapsulate knowledge about the exact layout of XLog file + * names, timeline history file names, and archive-status file names. + */ +#define MAXFNAMELEN 64 + +/* Length of XLog file name */ +#define XLOG_FNAME_LEN 24 + +/* + * Generate a WAL segment file name. Do not use this function in a helper + * function allocating the result generated. + */ +static inline void +XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes) +{ + snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, + (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), + (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes))); +} + +static inline void +XLogFileNameById(char *fname, TimeLineID tli, uint32 log, uint32 seg) +{ + snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg); +} + +static inline bool +IsXLogFileName(const char *fname) +{ + return (strlen(fname) == XLOG_FNAME_LEN && \ + strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN); +} + +/* + * XLOG segment with .partial suffix. Used by pg_receivewal and at end of + * archive recovery, when we want to archive a WAL segment but it might not + * be complete yet. + */ +static inline bool +IsPartialXLogFileName(const char *fname) +{ + return (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") && + strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && + strcmp(fname + XLOG_FNAME_LEN, ".partial") == 0); +} + +static inline void +XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes) +{ + uint32 log; + uint32 seg; + + sscanf(fname, "%08X%08X%08X", tli, &log, &seg); + *logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg; +} + +static inline void +XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes) +{ + snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, + (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), + (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes))); +} + +static inline void +TLHistoryFileName(char *fname, TimeLineID tli) +{ + snprintf(fname, MAXFNAMELEN, "%08X.history", tli); +} + +static inline bool +IsTLHistoryFileName(const char *fname) +{ + return (strlen(fname) == 8 + strlen(".history") && + strspn(fname, "0123456789ABCDEF") == 8 && + strcmp(fname + 8, ".history") == 0); +} + +static inline void +TLHistoryFilePath(char *path, TimeLineID tli) +{ + snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli); +} + +static inline void +StatusFilePath(char *path, const char *xlog, const char *suffix) +{ + snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix); +} + +static inline void +BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes) +{ + snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, + (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), + (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)), + (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes))); +} + +static inline bool +IsBackupHistoryFileName(const char *fname) +{ + return (strlen(fname) > XLOG_FNAME_LEN && + strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && + strcmp(fname + strlen(fname) - strlen(".backup"), ".backup") == 0); +} + +static inline void +BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes) +{ + snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, + (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), + (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)), + (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes))); +} + +/* + * Information logged when we detect a change in one of the parameters + * important for Hot Standby. + */ +typedef struct xl_parameter_change +{ + int MaxConnections; + int max_worker_processes; + int max_wal_senders; + int max_prepared_xacts; + int max_locks_per_xact; + int wal_level; + bool wal_log_hints; + bool track_commit_timestamp; +} xl_parameter_change; + +/* logs restore point */ +typedef struct xl_restore_point +{ + TimestampTz rp_time; + char rp_name[MAXFNAMELEN]; +} xl_restore_point; + +/* Overwrite of prior contrecord */ +typedef struct xl_overwrite_contrecord +{ + XLogRecPtr overwritten_lsn; + TimestampTz overwrite_time; +} xl_overwrite_contrecord; + +/* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */ +typedef struct xl_end_of_recovery +{ + TimestampTz end_time; + TimeLineID ThisTimeLineID; /* new TLI */ + TimeLineID PrevTimeLineID; /* previous TLI we forked off from */ +} xl_end_of_recovery; + +/* + * The functions in xloginsert.c construct a chain of XLogRecData structs + * to represent the final WAL record. + */ +typedef struct XLogRecData +{ + struct XLogRecData *next; /* next struct in chain, or NULL */ + char *data; /* start of rmgr data to include */ + uint32 len; /* length of rmgr data to include */ +} XLogRecData; + +/* + * Recovery target action. + */ +typedef enum +{ + RECOVERY_TARGET_ACTION_PAUSE, + RECOVERY_TARGET_ACTION_PROMOTE, + RECOVERY_TARGET_ACTION_SHUTDOWN +} RecoveryTargetAction; + +struct LogicalDecodingContext; +struct XLogRecordBuffer; + +/* + * Method table for resource managers. + * + * This struct must be kept in sync with the PG_RMGR definition in + * rmgr.c. + * + * rm_identify must return a name for the record based on xl_info (without + * reference to the rmid). For example, XLOG_BTREE_VACUUM would be named + * "VACUUM". rm_desc can then be called to obtain additional detail for the + * record, if available (e.g. the last block). + * + * rm_mask takes as input a page modified by the resource manager and masks + * out bits that shouldn't be flagged by wal_consistency_checking. + * + * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). If rm_name is + * NULL, the corresponding RmgrTable entry is considered invalid. + */ +typedef struct RmgrData +{ + const char *rm_name; + void (*rm_redo) (XLogReaderState *record); + void (*rm_desc) (StringInfo buf, XLogReaderState *record); + const char *(*rm_identify) (uint8 info); + void (*rm_startup) (void); + void (*rm_cleanup) (void); + void (*rm_mask) (char *pagedata, BlockNumber blkno); + void (*rm_decode) (struct LogicalDecodingContext *ctx, + struct XLogRecordBuffer *buf); +} RmgrData; + +extern PGDLLIMPORT RmgrData RmgrTable[]; +extern void RmgrStartup(void); +extern void RmgrCleanup(void); +extern void RmgrNotFound(RmgrId rmid); +extern void RegisterCustomRmgr(RmgrId rmid, const RmgrData *rmgr); + +#ifndef FRONTEND +static inline bool +RmgrIdExists(RmgrId rmid) +{ + return RmgrTable[rmid].rm_name != NULL; +} + +static inline RmgrData +GetRmgr(RmgrId rmid) +{ + if (unlikely(!RmgrIdExists(rmid))) + RmgrNotFound(rmid); + return RmgrTable[rmid]; +} +#endif + +/* + * Exported to support xlog switching from checkpointer + */ +extern pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN); +extern XLogRecPtr RequestXLogSwitch(bool mark_unimportant); + +extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli); + +extern void XLogRecGetBlockRefInfo(XLogReaderState *record, bool pretty, + bool detailed_format, StringInfo buf, + uint32 *fpi_len); + +/* + * Exported for the functions in timeline.c and xlogarchive.c. Only valid + * in the startup process. + */ +extern PGDLLIMPORT bool ArchiveRecoveryRequested; +extern PGDLLIMPORT bool InArchiveRecovery; +extern PGDLLIMPORT bool StandbyMode; +extern PGDLLIMPORT char *recoveryRestoreCommand; + +#endif /* XLOG_INTERNAL_H */ diff --git a/install/include/postgresql/server/access/xlogarchive.h b/install/include/postgresql/server/access/xlogarchive.h new file mode 100644 index 00000000000..31ff2060340 --- /dev/null +++ b/install/include/postgresql/server/access/xlogarchive.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------ + * + * xlogarchive.h + * Prototypes for WAL archives in the backend + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/xlogarchive.h + * + *------------------------------------------------------------------------ + */ + +#ifndef XLOG_ARCHIVE_H +#define XLOG_ARCHIVE_H + +#include "access/xlogdefs.h" + +extern bool RestoreArchivedFile(char *path, const char *xlogfname, + const char *recovername, off_t expectedSize, + bool cleanupEnabled); +extern void ExecuteRecoveryCommand(const char *command, const char *commandName, + bool failOnSignal, uint32 wait_event_info); +extern void KeepFileRestoredFromArchive(const char *path, const char *xlogfname); +extern void XLogArchiveNotify(const char *xlog); +extern void XLogArchiveNotifySeg(XLogSegNo segno, TimeLineID tli); +extern void XLogArchiveForceDone(const char *xlog); +extern bool XLogArchiveCheckDone(const char *xlog); +extern bool XLogArchiveIsBusy(const char *xlog); +extern bool XLogArchiveIsReady(const char *xlog); +extern bool XLogArchiveIsReadyOrDone(const char *xlog); +extern void XLogArchiveCleanup(const char *xlog); + +#endif /* XLOG_ARCHIVE_H */ diff --git a/install/include/postgresql/server/access/xlogbackup.h b/install/include/postgresql/server/access/xlogbackup.h new file mode 100644 index 00000000000..1611358137b --- /dev/null +++ b/install/include/postgresql/server/access/xlogbackup.h @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------- + * + * xlogbackup.h + * Definitions for internals of base backups. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/xlogbackup.h + *------------------------------------------------------------------------- + */ + +#ifndef XLOG_BACKUP_H +#define XLOG_BACKUP_H + +#include "access/xlogdefs.h" +#include "pgtime.h" + +/* Structure to hold backup state. */ +typedef struct BackupState +{ + /* Fields saved at backup start */ + /* Backup label name one extra byte for null-termination */ + char name[MAXPGPATH + 1]; + XLogRecPtr startpoint; /* backup start WAL location */ + TimeLineID starttli; /* backup start TLI */ + XLogRecPtr checkpointloc; /* last checkpoint location */ + pg_time_t starttime; /* backup start time */ + bool started_in_recovery; /* backup started in recovery? */ + + /* Fields saved at the end of backup */ + XLogRecPtr stoppoint; /* backup stop WAL location */ + TimeLineID stoptli; /* backup stop TLI */ + pg_time_t stoptime; /* backup stop time */ +} BackupState; + +extern char *build_backup_content(BackupState *state, + bool ishistoryfile); + +#endif /* XLOG_BACKUP_H */ diff --git a/install/include/postgresql/server/access/xlogdefs.h b/install/include/postgresql/server/access/xlogdefs.h new file mode 100644 index 00000000000..bd2607512a0 --- /dev/null +++ b/install/include/postgresql/server/access/xlogdefs.h @@ -0,0 +1,83 @@ +/* + * xlogdefs.h + * + * Postgres write-ahead log manager record pointer and + * timeline number definitions + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xlogdefs.h + */ +#ifndef XLOG_DEFS_H +#define XLOG_DEFS_H + +#include /* need open() flags */ + +/* + * Pointer to a location in the XLOG. These pointers are 64 bits wide, + * because we don't want them ever to overflow. + */ +typedef uint64 XLogRecPtr; + +/* + * Zero is used indicate an invalid pointer. Bootstrap skips the first possible + * WAL segment, initializing the first WAL page at WAL segment size, so no XLOG + * record can begin at zero. + */ +#define InvalidXLogRecPtr 0 +#define XLogRecPtrIsValid(r) ((r) != InvalidXLogRecPtr) +#define XLogRecPtrIsInvalid(r) ((r) == InvalidXLogRecPtr) + +/* + * First LSN to use for "fake" LSNs. + * + * Values smaller than this can be used for special per-AM purposes. + */ +#define FirstNormalUnloggedLSN ((XLogRecPtr) 1000) + +/* + * Handy macro for printing XLogRecPtr in conventional format, e.g., + * + * printf("%X/%X", LSN_FORMAT_ARGS(lsn)); + */ +#define LSN_FORMAT_ARGS(lsn) (AssertVariableIsOfTypeMacro((lsn), XLogRecPtr), (uint32) ((lsn) >> 32)), ((uint32) (lsn)) + +/* + * XLogSegNo - physical log file sequence number. + */ +typedef uint64 XLogSegNo; + +/* + * TimeLineID (TLI) - identifies different database histories to prevent + * confusion after restoring a prior state of a database installation. + * TLI does not change in a normal stop/restart of the database (including + * crash-and-recover cases); but we must assign a new TLI after doing + * a recovery to a prior state, a/k/a point-in-time recovery. This makes + * the new WAL logfile sequence we generate distinguishable from the + * sequence that was generated in the previous incarnation. + */ +typedef uint32 TimeLineID; + +/* + * Replication origin id - this is located in this file to avoid having to + * include origin.h in a bunch of xlog related places. + */ +typedef uint16 RepOriginId; + +/* + * This chunk of hackery attempts to determine which file sync methods + * are available on the current platform, and to choose an appropriate + * default method. + * + * Note that we define our own O_DSYNC on Windows, but not O_SYNC. + */ +#if defined(PLATFORM_DEFAULT_SYNC_METHOD) +#define DEFAULT_SYNC_METHOD PLATFORM_DEFAULT_SYNC_METHOD +#elif defined(O_DSYNC) && (!defined(O_SYNC) || O_DSYNC != O_SYNC) +#define DEFAULT_SYNC_METHOD SYNC_METHOD_OPEN_DSYNC +#else +#define DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC +#endif + +#endif /* XLOG_DEFS_H */ diff --git a/install/include/postgresql/server/access/xloginsert.h b/install/include/postgresql/server/access/xloginsert.h new file mode 100644 index 00000000000..31785dc578f --- /dev/null +++ b/install/include/postgresql/server/access/xloginsert.h @@ -0,0 +1,66 @@ +/* + * xloginsert.h + * + * Functions for generating WAL records + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xloginsert.h + */ +#ifndef XLOGINSERT_H +#define XLOGINSERT_H + +#include "access/rmgr.h" +#include "access/xlogdefs.h" +#include "storage/block.h" +#include "storage/buf.h" +#include "storage/relfilelocator.h" +#include "utils/relcache.h" + +/* + * The minimum size of the WAL construction working area. If you need to + * register more than XLR_NORMAL_MAX_BLOCK_ID block references or have more + * than XLR_NORMAL_RDATAS data chunks in a single WAL record, you must call + * XLogEnsureRecordSpace() first to allocate more working memory. + */ +#define XLR_NORMAL_MAX_BLOCK_ID 4 +#define XLR_NORMAL_RDATAS 20 + +/* flags for XLogRegisterBuffer */ +#define REGBUF_FORCE_IMAGE 0x01 /* force a full-page image */ +#define REGBUF_NO_IMAGE 0x02 /* don't take a full-page image */ +#define REGBUF_WILL_INIT (0x04 | 0x02) /* page will be re-initialized at + * replay (implies NO_IMAGE) */ +#define REGBUF_STANDARD 0x08 /* page follows "standard" page layout, + * (data between pd_lower and pd_upper + * will be skipped) */ +#define REGBUF_KEEP_DATA 0x10 /* include data even if a full-page image + * is taken */ + +/* prototypes for public functions in xloginsert.c: */ +extern void XLogBeginInsert(void); +extern void XLogSetRecordFlags(uint8 flags); +extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info); +extern void XLogEnsureRecordSpace(int max_block_id, int ndatas); +extern void XLogRegisterData(char *data, uint32 len); +extern void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags); +extern void XLogRegisterBlock(uint8 block_id, RelFileLocator *rlocator, + ForkNumber forknum, BlockNumber blknum, char *page, + uint8 flags); +extern void XLogRegisterBufData(uint8 block_id, char *data, uint32 len); +extern void XLogResetInsertion(void); +extern bool XLogCheckBufferNeedsBackup(Buffer buffer); + +extern XLogRecPtr log_newpage(RelFileLocator *rlocator, ForkNumber forknum, + BlockNumber blkno, char *page, bool page_std); +extern void log_newpages(RelFileLocator *rlocator, ForkNumber forknum, int num_pages, + BlockNumber *blknos, char **pages, bool page_std); +extern XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std); +extern void log_newpage_range(Relation rel, ForkNumber forknum, + BlockNumber startblk, BlockNumber endblk, bool page_std); +extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std); + +extern void InitXLogInsert(void); + +#endif /* XLOGINSERT_H */ diff --git a/install/include/postgresql/server/access/xlogprefetcher.h b/install/include/postgresql/server/access/xlogprefetcher.h new file mode 100644 index 00000000000..7dd7f20ad06 --- /dev/null +++ b/install/include/postgresql/server/access/xlogprefetcher.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * xlogprefetcher.h + * Declarations for the recovery prefetching module. + * + * Portions Copyright (c) 2022-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/access/xlogprefetcher.h + *------------------------------------------------------------------------- + */ +#ifndef XLOGPREFETCHER_H +#define XLOGPREFETCHER_H + +#include "access/xlogdefs.h" +#include "access/xlogreader.h" +#include "access/xlogrecord.h" + +/* GUCs */ +extern PGDLLIMPORT int recovery_prefetch; + +/* Possible values for recovery_prefetch */ +typedef enum +{ + RECOVERY_PREFETCH_OFF, + RECOVERY_PREFETCH_ON, + RECOVERY_PREFETCH_TRY +} RecoveryPrefetchValue; + +struct XLogPrefetcher; +typedef struct XLogPrefetcher XLogPrefetcher; + + +extern void XLogPrefetchReconfigure(void); + +extern size_t XLogPrefetchShmemSize(void); +extern void XLogPrefetchShmemInit(void); + +extern void XLogPrefetchResetStats(void); + +extern XLogPrefetcher *XLogPrefetcherAllocate(XLogReaderState *reader); +extern void XLogPrefetcherFree(XLogPrefetcher *prefetcher); + +extern XLogReaderState *XLogPrefetcherGetReader(XLogPrefetcher *prefetcher); + +extern void XLogPrefetcherBeginRead(XLogPrefetcher *prefetcher, + XLogRecPtr recPtr); + +extern XLogRecord *XLogPrefetcherReadRecord(XLogPrefetcher *prefetcher, + char **errmsg); + +extern void XLogPrefetcherComputeStats(XLogPrefetcher *prefetcher); + +#endif diff --git a/install/include/postgresql/server/access/xlogreader.h b/install/include/postgresql/server/access/xlogreader.h new file mode 100644 index 00000000000..0ecfed25834 --- /dev/null +++ b/install/include/postgresql/server/access/xlogreader.h @@ -0,0 +1,493 @@ +/*------------------------------------------------------------------------- + * + * xlogreader.h + * Definitions for the generic XLog reading facility + * + * Portions Copyright (c) 2013-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/access/xlogreader.h + * + * NOTES + * See the definition of the XLogReaderState struct for instructions on + * how to use the XLogReader infrastructure. + * + * The basic idea is to allocate an XLogReaderState via + * XLogReaderAllocate(), position the reader to the first record with + * XLogBeginRead() or XLogFindNextRecord(), and call XLogReadRecord() + * until it returns NULL. + * + * Callers supply a page_read callback if they want to call + * XLogReadRecord or XLogFindNextRecord; it can be passed in as NULL + * otherwise. The WALRead function can be used as a helper to write + * page_read callbacks, but it is not mandatory; callers that use it, + * must supply segment_open callbacks. The segment_close callback + * must always be supplied. + * + * After reading a record with XLogReadRecord(), it's decomposed into + * the per-block and main data parts, and the parts can be accessed + * with the XLogRec* macros and functions. You can also decode a + * record that's already constructed in memory, without reading from + * disk, by calling the DecodeXLogRecord() function. + *------------------------------------------------------------------------- + */ +#ifndef XLOGREADER_H +#define XLOGREADER_H + +#ifndef FRONTEND +#include "access/transam.h" +#endif + +#include "access/xlogrecord.h" +#include "storage/buf.h" + +/* WALOpenSegment represents a WAL segment being read. */ +typedef struct WALOpenSegment +{ + int ws_file; /* segment file descriptor */ + XLogSegNo ws_segno; /* segment number */ + TimeLineID ws_tli; /* timeline ID of the currently open file */ +} WALOpenSegment; + +/* WALSegmentContext carries context information about WAL segments to read */ +typedef struct WALSegmentContext +{ + char ws_dir[MAXPGPATH]; + int ws_segsize; +} WALSegmentContext; + +typedef struct XLogReaderState XLogReaderState; + +/* Function type definitions for various xlogreader interactions */ +typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader, + XLogRecPtr targetPagePtr, + int reqLen, + XLogRecPtr targetRecPtr, + char *readBuf); +typedef void (*WALSegmentOpenCB) (XLogReaderState *xlogreader, + XLogSegNo nextSegNo, + TimeLineID *tli_p); +typedef void (*WALSegmentCloseCB) (XLogReaderState *xlogreader); + +typedef struct XLogReaderRoutine +{ + /* + * Data input callback + * + * This callback shall read at least reqLen valid bytes of the xlog page + * starting at targetPagePtr, and store them in readBuf. The callback + * shall return the number of bytes read (never more than XLOG_BLCKSZ), or + * -1 on failure. The callback shall sleep, if necessary, to wait for the + * requested bytes to become available. The callback will not be invoked + * again for the same page unless more than the returned number of bytes + * are needed. + * + * targetRecPtr is the position of the WAL record we're reading. Usually + * it is equal to targetPagePtr + reqLen, but sometimes xlogreader needs + * to read and verify the page or segment header, before it reads the + * actual WAL record it's interested in. In that case, targetRecPtr can + * be used to determine which timeline to read the page from. + * + * The callback shall set ->seg.ws_tli to the TLI of the file the page was + * read from. + */ + XLogPageReadCB page_read; + + /* + * Callback to open the specified WAL segment for reading. ->seg.ws_file + * shall be set to the file descriptor of the opened segment. In case of + * failure, an error shall be raised by the callback and it shall not + * return. + * + * "nextSegNo" is the number of the segment to be opened. + * + * "tli_p" is an input/output argument. WALRead() uses it to pass the + * timeline in which the new segment should be found, but the callback can + * use it to return the TLI that it actually opened. + */ + WALSegmentOpenCB segment_open; + + /* + * WAL segment close callback. ->seg.ws_file shall be set to a negative + * number. + */ + WALSegmentCloseCB segment_close; +} XLogReaderRoutine; + +#define XL_ROUTINE(...) &(XLogReaderRoutine){__VA_ARGS__} + +typedef struct +{ + /* Is this block ref in use? */ + bool in_use; + + /* Identify the block this refers to */ + RelFileLocator rlocator; + ForkNumber forknum; + BlockNumber blkno; + + /* Prefetching workspace. */ + Buffer prefetch_buffer; + + /* copy of the fork_flags field from the XLogRecordBlockHeader */ + uint8 flags; + + /* Information on full-page image, if any */ + bool has_image; /* has image, even for consistency checking */ + bool apply_image; /* has image that should be restored */ + char *bkp_image; + uint16 hole_offset; + uint16 hole_length; + uint16 bimg_len; + uint8 bimg_info; + + /* Buffer holding the rmgr-specific data associated with this block */ + bool has_data; + char *data; + uint16 data_len; + uint16 data_bufsz; +} DecodedBkpBlock; + +/* + * The decoded contents of a record. This occupies a contiguous region of + * memory, with main_data and blocks[n].data pointing to memory after the + * members declared here. + */ +typedef struct DecodedXLogRecord +{ + /* Private member used for resource management. */ + size_t size; /* total size of decoded record */ + bool oversized; /* outside the regular decode buffer? */ + struct DecodedXLogRecord *next; /* decoded record queue link */ + + /* Public members. */ + XLogRecPtr lsn; /* location */ + XLogRecPtr next_lsn; /* location of next record */ + XLogRecord header; /* header */ + RepOriginId record_origin; + TransactionId toplevel_xid; /* XID of top-level transaction */ + char *main_data; /* record's main data portion */ + uint32 main_data_len; /* main data portion's length */ + int max_block_id; /* highest block_id in use (-1 if none) */ + DecodedBkpBlock blocks[FLEXIBLE_ARRAY_MEMBER]; +} DecodedXLogRecord; + +struct XLogReaderState +{ + /* + * Operational callbacks + */ + XLogReaderRoutine routine; + + /* ---------------------------------------- + * Public parameters + * ---------------------------------------- + */ + + /* + * System identifier of the xlog files we're about to read. Set to zero + * (the default value) if unknown or unimportant. + */ + uint64 system_identifier; + + /* + * Opaque data for callbacks to use. Not used by XLogReader. + */ + void *private_data; + + /* + * Start and end point of last record read. EndRecPtr is also used as the + * position to read next. Calling XLogBeginRead() sets EndRecPtr to the + * starting position and ReadRecPtr to invalid. + * + * Start and end point of last record returned by XLogReadRecord(). These + * are also available as record->lsn and record->next_lsn. + */ + XLogRecPtr ReadRecPtr; /* start of last record read */ + XLogRecPtr EndRecPtr; /* end+1 of last record read */ + + /* + * Set at the end of recovery: the start point of a partial record at the + * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start + * location of its first contrecord that went missing. + */ + XLogRecPtr abortedRecPtr; + XLogRecPtr missingContrecPtr; + /* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */ + XLogRecPtr overwrittenRecPtr; + + + /* ---------------------------------------- + * Decoded representation of current record + * + * Use XLogRecGet* functions to investigate the record; these fields + * should not be accessed directly. + * ---------------------------------------- + * Start and end point of the last record read and decoded by + * XLogReadRecordInternal(). NextRecPtr is also used as the position to + * decode next. Calling XLogBeginRead() sets NextRecPtr and EndRecPtr to + * the requested starting position. + */ + XLogRecPtr DecodeRecPtr; /* start of last record decoded */ + XLogRecPtr NextRecPtr; /* end+1 of last record decoded */ + XLogRecPtr PrevRecPtr; /* start of previous record decoded */ + + /* Last record returned by XLogReadRecord(). */ + DecodedXLogRecord *record; + + /* ---------------------------------------- + * private/internal state + * ---------------------------------------- + */ + + /* + * Buffer for decoded records. This is a circular buffer, though + * individual records can't be split in the middle, so some space is often + * wasted at the end. Oversized records that don't fit in this space are + * allocated separately. + */ + char *decode_buffer; + size_t decode_buffer_size; + bool free_decode_buffer; /* need to free? */ + char *decode_buffer_head; /* data is read from the head */ + char *decode_buffer_tail; /* new data is written at the tail */ + + /* + * Queue of records that have been decoded. This is a linked list that + * usually consists of consecutive records in decode_buffer, but may also + * contain oversized records allocated with palloc(). + */ + DecodedXLogRecord *decode_queue_head; /* oldest decoded record */ + DecodedXLogRecord *decode_queue_tail; /* newest decoded record */ + + /* + * Buffer for currently read page (XLOG_BLCKSZ bytes, valid up to at least + * readLen bytes) + */ + char *readBuf; + uint32 readLen; + + /* last read XLOG position for data currently in readBuf */ + WALSegmentContext segcxt; + WALOpenSegment seg; + uint32 segoff; + + /* + * beginning of prior page read, and its TLI. Doesn't necessarily + * correspond to what's in readBuf; used for timeline sanity checks. + */ + XLogRecPtr latestPagePtr; + TimeLineID latestPageTLI; + + /* beginning of the WAL record being read. */ + XLogRecPtr currRecPtr; + /* timeline to read it from, 0 if a lookup is required */ + TimeLineID currTLI; + + /* + * Safe point to read to in currTLI if current TLI is historical + * (tliSwitchPoint) or InvalidXLogRecPtr if on current timeline. + * + * Actually set to the start of the segment containing the timeline switch + * that ends currTLI's validity, not the LSN of the switch its self, since + * we can't assume the old segment will be present. + */ + XLogRecPtr currTLIValidUntil; + + /* + * If currTLI is not the most recent known timeline, the next timeline to + * read from when currTLIValidUntil is reached. + */ + TimeLineID nextTLI; + + /* + * Buffer for current ReadRecord result (expandable), used when a record + * crosses a page boundary. + */ + char *readRecordBuf; + uint32 readRecordBufSize; + + /* Buffer to hold error message */ + char *errormsg_buf; + bool errormsg_deferred; + + /* + * Flag to indicate to XLogPageReadCB that it should not block waiting for + * data. + */ + bool nonblocking; + + /* + * PGRAC modifications by SqlRush : + * What changed: spec-4.1 -- own-stream strict thread-id acceptance. + * XLogReaderValidatePageHeader additionally requires a real (non + * legacy) xlp_thread_id to equal this value, unless it is + * XLP_THREAD_ID_INVALID (= accept any valid id, the + * XLogReaderAllocate default). Crash recovery reading this node's + * own stream sets it to cluster_wal_thread_id() + * (xlogrecovery.c::InitWalRecovery); frontend tools (pg_waldump / + * pg_rewind), walsenders and standby replay keep the permissive + * default so cross-thread diagnostics and physical replication of a + * stamped stream are never rejected with a local node_id (spec-4.1 + * RL1). + * Why: second defence (after the cluster_wal_thread_init startup + * validation) against a mis-linked pg_wal serving another thread's + * stream to recovery. Appended at the struct tail: heap-allocated + * via XLogReaderAllocate only, no embedded instances (spec-4.1 R7). + */ + uint16 cluster_expected_thread_id; + + /* + * PGRAC (spec-4.5 D3): last accepted xl_scn on this stream, for the + * per-thread monotonicity check (scn must be non-decreasing in LSN + * order; zero only as a stream prefix). Reset by XLogBeginRead. + */ + uint64 cluster_last_scn; +}; + +/* + * Check if XLogNextRecord() has any more queued records or an error to return. + */ +static inline bool +XLogReaderHasQueuedRecordOrError(XLogReaderState *state) +{ + return (state->decode_queue_head != NULL) || state->errormsg_deferred; +} + +/* Get a new XLogReader */ +extern XLogReaderState *XLogReaderAllocate(int wal_segment_size, + const char *waldir, + XLogReaderRoutine *routine, + void *private_data); + +/* Free an XLogReader */ +extern void XLogReaderFree(XLogReaderState *state); + +/* Optionally provide a circular decoding buffer to allow readahead. */ +extern void XLogReaderSetDecodeBuffer(XLogReaderState *state, + void *buffer, + size_t size); + +/* Position the XLogReader to given record */ +extern void XLogBeginRead(XLogReaderState *state, XLogRecPtr RecPtr); +extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr); + +/* Return values from XLogPageReadCB. */ +typedef enum XLogPageReadResult +{ + XLREAD_SUCCESS = 0, /* record is successfully read */ + XLREAD_FAIL = -1, /* failed during reading a record */ + XLREAD_WOULDBLOCK = -2 /* nonblocking mode only, no data */ +} XLogPageReadResult; + +/* Read the next XLog record. Returns NULL on end-of-WAL or failure */ +extern struct XLogRecord *XLogReadRecord(XLogReaderState *state, + char **errormsg); + +/* Consume the next record or error. */ +extern DecodedXLogRecord *XLogNextRecord(XLogReaderState *state, + char **errormsg); + +/* Release the previously returned record, if necessary. */ +extern XLogRecPtr XLogReleasePreviousRecord(XLogReaderState *state); + +/* Try to read ahead, if there is data and space. */ +extern DecodedXLogRecord *XLogReadAhead(XLogReaderState *state, + bool nonblocking); + +/* Validate a page */ +extern bool XLogReaderValidatePageHeader(XLogReaderState *state, + XLogRecPtr recptr, char *phdr); + +/* Forget error produced by XLogReaderValidatePageHeader(). */ +extern void XLogReaderResetError(XLogReaderState *state); + +/* + * PGRAC (spec-1.19): accessor returning the cluster thread_id of the page + * currently buffered in state->readBuf. Stage 1 always returns + * XLP_THREAD_ID_LEGACY (0); spec-1.21+ feature-037 merged-apply consumes + * this for routing. Caller MUST have a validated page in readBuf. + * + * API contract caveat (Hardening v1.0.1 P2-1; codex review 2026-05-05): + * readBuf is the *current buffered page* of the reader, not a stable + * property of the decoded record. When a record spans a page boundary + * (XLP_FIRST_IS_CONTRECORD), the record's "thread_id" is ambiguous — + * the start page and continuation page may belong to different threads + * in Stage 2+ (feature-034 / feature-037 routing). Stage 1 is safe + * because every page has thread_id = LEGACY (0), but spec-1.21+ users + * doing cross-page-boundary record routing MUST switch to consuming + * thread_id from DecodedXLogRecord (or define an explicit "record + * start page thread_id" accessor). TODO: track this via spec-1.21 + * forward-link. + */ +extern uint16 XLogReaderGetThreadId(XLogReaderState *state); + +/* + * Error information from WALRead that both backend and frontend caller can + * process. Currently only errors from pg_pread can be reported. + */ +typedef struct WALReadError +{ + int wre_errno; /* errno set by the last pg_pread() */ + int wre_off; /* Offset we tried to read from. */ + int wre_req; /* Bytes requested to be read. */ + int wre_read; /* Bytes read by the last read(). */ + WALOpenSegment wre_seg; /* Segment we tried to read from. */ +} WALReadError; + +extern bool WALRead(XLogReaderState *state, + char *buf, XLogRecPtr startptr, Size count, + TimeLineID tli, WALReadError *errinfo); + +/* Functions for decoding an XLogRecord */ + +extern size_t DecodeXLogRecordRequiredSpace(size_t xl_tot_len); +extern bool DecodeXLogRecord(XLogReaderState *state, + DecodedXLogRecord *decoded, + XLogRecord *record, + XLogRecPtr lsn, + char **errormsg); + +/* + * Macros that provide access to parts of the record most recently returned by + * XLogReadRecord() or XLogNextRecord(). + */ +#define XLogRecGetTotalLen(decoder) ((decoder)->record->header.xl_tot_len) +#define XLogRecGetPrev(decoder) ((decoder)->record->header.xl_prev) +/* PGRAC spec-4.5: merged-recovery ordering key accessor. */ +#define XLogRecGetScn(decoder) ((decoder)->record->header.xl_scn) +#define XLogRecGetInfo(decoder) ((decoder)->record->header.xl_info) +#define XLogRecGetRmid(decoder) ((decoder)->record->header.xl_rmid) +#define XLogRecGetXid(decoder) ((decoder)->record->header.xl_xid) +#define XLogRecGetOrigin(decoder) ((decoder)->record->record_origin) +#define XLogRecGetTopXid(decoder) ((decoder)->record->toplevel_xid) +#define XLogRecGetData(decoder) ((decoder)->record->main_data) +#define XLogRecGetDataLen(decoder) ((decoder)->record->main_data_len) +#define XLogRecHasAnyBlockRefs(decoder) ((decoder)->record->max_block_id >= 0) +#define XLogRecMaxBlockId(decoder) ((decoder)->record->max_block_id) +#define XLogRecGetBlock(decoder, i) (&(decoder)->record->blocks[(i)]) +#define XLogRecHasBlockRef(decoder, block_id) \ + (((decoder)->record->max_block_id >= (block_id)) && \ + ((decoder)->record->blocks[block_id].in_use)) +#define XLogRecHasBlockImage(decoder, block_id) \ + ((decoder)->record->blocks[block_id].has_image) +#define XLogRecBlockImageApply(decoder, block_id) \ + ((decoder)->record->blocks[block_id].apply_image) +#define XLogRecHasBlockData(decoder, block_id) \ + ((decoder)->record->blocks[block_id].has_data) + +#ifndef FRONTEND +extern FullTransactionId XLogRecGetFullXid(XLogReaderState *record); +#endif + +extern bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page); +extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len); +extern void XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, + RelFileLocator *rlocator, ForkNumber *forknum, + BlockNumber *blknum); +extern bool XLogRecGetBlockTagExtended(XLogReaderState *record, uint8 block_id, + RelFileLocator *rlocator, ForkNumber *forknum, + BlockNumber *blknum, + Buffer *prefetch_buffer); + +#endif /* XLOGREADER_H */ diff --git a/install/include/postgresql/server/access/xlogrecord.h b/install/include/postgresql/server/access/xlogrecord.h new file mode 100644 index 00000000000..5db14f53fab --- /dev/null +++ b/install/include/postgresql/server/access/xlogrecord.h @@ -0,0 +1,275 @@ +/* + * xlogrecord.h + * + * Definitions for the WAL record format. + * + * PGRAC MODIFICATIONS (spec-4.5 v1.0) + * Modified by: SqlRush + * Spec: spec-4.5-kway-scn-merge-replay.md + * What changed: XLogRecord grew an 8-byte xl_scn (24 -> 32 bytes) with + * xl_info/xl_rmid/xl_crc shifted so xl_crc remains the last header + * field (CRC coverage of the new field is automatic). Format break: + * XLOG_PAGE_MAGIC and catversion are bumped (spec-4.5 D4). + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xlogrecord.h + */ +#ifndef XLOGRECORD_H +#define XLOGRECORD_H + +#include "access/rmgr.h" +#include "access/xlogdefs.h" +#include "port/pg_crc32c.h" +#include "storage/block.h" +#include "storage/relfilelocator.h" + +/* + * The overall layout of an XLOG record is: + * Fixed-size header (XLogRecord struct) + * XLogRecordBlockHeader struct + * XLogRecordBlockHeader struct + * ... + * XLogRecordDataHeader[Short|Long] struct + * block data + * block data + * ... + * main data + * + * There can be zero or more XLogRecordBlockHeaders, and 0 or more bytes of + * rmgr-specific data not associated with a block. XLogRecord structs + * always start on MAXALIGN boundaries in the WAL files, but the rest of + * the fields are not aligned. + * + * The XLogRecordBlockHeader, XLogRecordDataHeaderShort and + * XLogRecordDataHeaderLong structs all begin with a single 'id' byte. It's + * used to distinguish between block references, and the main data structs. + */ +typedef struct XLogRecord +{ + uint32 xl_tot_len; /* total len of entire record */ + TransactionId xl_xid; /* xact id */ + XLogRecPtr xl_prev; /* ptr to previous record in log */ + + /* + * PGRAC (spec-4.5, AD-008/AD-009 second extensions): per-record + * Lamport SCN, stamped inside the WAL-insertion critical section so + * it is non-decreasing in LSN order within one WAL thread. This is + * the k-way merged-recovery ordering key (scn -> lsn -> node). + * InvalidScn (0) outside cluster mode / bootstrap / pg_resetwal; + * zero values may only appear as a stream prefix. xl_info/xl_rmid + * moved below so xl_crc stays the LAST header field and the + * existing CRC protocol (header bytes before xl_crc + payload) + * covers xl_scn with no code change. + */ + uint64 xl_scn; + + uint8 xl_info; /* flag bits, see below */ + RmgrId xl_rmid; /* resource manager for this record */ + /* 2 bytes of padding here, initialize to zero */ + pg_crc32c xl_crc; /* CRC for this record -- MUST stay last */ + + /* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */ + +} XLogRecord; + +StaticAssertDecl(sizeof(XLogRecord) == 32, "spec-4.5 XLogRecord is 32 bytes"); +StaticAssertDecl(offsetof(XLogRecord, xl_scn) == 16, "spec-4.5 xl_scn at offset 16"); +StaticAssertDecl(offsetof(XLogRecord, xl_crc) == 28, + "spec-4.5 xl_crc stays the last header field"); + +#define SizeOfXLogRecord (offsetof(XLogRecord, xl_crc) + sizeof(pg_crc32c)) + +/* + * The high 4 bits in xl_info may be used freely by rmgr. The + * XLR_SPECIAL_REL_UPDATE and XLR_CHECK_CONSISTENCY bits can be passed by + * XLogInsert caller. The rest are set internally by XLogInsert. + */ +#define XLR_INFO_MASK 0x0F +#define XLR_RMGR_INFO_MASK 0xF0 + +/* + * XLogReader needs to allocate all the data of a WAL record in a single + * chunk. This means that a single XLogRecord cannot exceed MaxAllocSize + * in length if we ignore any allocation overhead of the XLogReader. + * + * To accommodate some overhead, this value allows for 4M of allocation + * overhead, that should be plenty enough for what + * DecodeXLogRecordRequiredSpace() expects as extra. + */ +#define XLogRecordMaxSize (1020 * 1024 * 1024) + +/* + * If a WAL record modifies any relation files, in ways not covered by the + * usual block references, this flag is set. This is not used for anything + * by PostgreSQL itself, but it allows external tools that read WAL and keep + * track of modified blocks to recognize such special record types. + */ +#define XLR_SPECIAL_REL_UPDATE 0x01 + +/* + * Enforces consistency checks of replayed WAL at recovery. If enabled, + * each record will log a full-page write for each block modified by the + * record and will reuse it afterwards for consistency checks. The caller + * of XLogInsert can use this value if necessary, but if + * wal_consistency_checking is enabled for a rmgr this is set unconditionally. + */ +#define XLR_CHECK_CONSISTENCY 0x02 + +/* + * Header info for block data appended to an XLOG record. + * + * 'data_length' is the length of the rmgr-specific payload data associated + * with this block. It does not include the possible full page image, nor + * XLogRecordBlockHeader struct itself. + * + * Note that we don't attempt to align the XLogRecordBlockHeader struct! + * So, the struct must be copied to aligned local storage before use. + */ +typedef struct XLogRecordBlockHeader +{ + uint8 id; /* block reference ID */ + uint8 fork_flags; /* fork within the relation, and flags */ + uint16 data_length; /* number of payload bytes (not including page + * image) */ + + /* If BKPBLOCK_HAS_IMAGE, an XLogRecordBlockImageHeader struct follows */ + /* If BKPBLOCK_SAME_REL is not set, a RelFileLocator follows */ + /* BlockNumber follows */ +} XLogRecordBlockHeader; + +#define SizeOfXLogRecordBlockHeader (offsetof(XLogRecordBlockHeader, data_length) + sizeof(uint16)) + +/* + * Additional header information when a full-page image is included + * (i.e. when BKPBLOCK_HAS_IMAGE is set). + * + * The XLOG code is aware that PG data pages usually contain an unused "hole" + * in the middle, which contains only zero bytes. Since we know that the + * "hole" is all zeros, we remove it from the stored data (and it's not counted + * in the XLOG record's CRC, either). Hence, the amount of block data actually + * present is (BLCKSZ - ). + * + * Additionally, when wal_compression is enabled, we will try to compress full + * page images using one of the supported algorithms, after removing the + * "hole". This can reduce the WAL volume, but at some extra cost of CPU spent + * on the compression during WAL logging. In this case, since the "hole" + * length cannot be calculated by subtracting the number of page image bytes + * from BLCKSZ, basically it needs to be stored as an extra information. + * But when no "hole" exists, we can assume that the "hole" length is zero + * and no such an extra information needs to be stored. Note that + * the original version of page image is stored in WAL instead of the + * compressed one if the number of bytes saved by compression is less than + * the length of extra information. Hence, when a page image is successfully + * compressed, the amount of block data actually present is less than + * BLCKSZ - the length of "hole" bytes - the length of extra information. + */ +typedef struct XLogRecordBlockImageHeader +{ + uint16 length; /* number of page image bytes */ + uint16 hole_offset; /* number of bytes before "hole" */ + uint8 bimg_info; /* flag bits, see below */ + + /* + * If BKPIMAGE_HAS_HOLE and BKPIMAGE_COMPRESSED(), an + * XLogRecordBlockCompressHeader struct follows. + */ +} XLogRecordBlockImageHeader; + +#define SizeOfXLogRecordBlockImageHeader \ + (offsetof(XLogRecordBlockImageHeader, bimg_info) + sizeof(uint8)) + +/* Information stored in bimg_info */ +#define BKPIMAGE_HAS_HOLE 0x01 /* page image has "hole" */ +#define BKPIMAGE_APPLY 0x02 /* page image should be restored + * during replay */ +/* compression methods supported */ +#define BKPIMAGE_COMPRESS_PGLZ 0x04 +#define BKPIMAGE_COMPRESS_LZ4 0x08 +#define BKPIMAGE_COMPRESS_ZSTD 0x10 + +#define BKPIMAGE_COMPRESSED(info) \ + ((info & (BKPIMAGE_COMPRESS_PGLZ | BKPIMAGE_COMPRESS_LZ4 | \ + BKPIMAGE_COMPRESS_ZSTD)) != 0) + +/* + * Extra header information used when page image has "hole" and + * is compressed. + */ +typedef struct XLogRecordBlockCompressHeader +{ + uint16 hole_length; /* number of bytes in "hole" */ +} XLogRecordBlockCompressHeader; + +#define SizeOfXLogRecordBlockCompressHeader \ + sizeof(XLogRecordBlockCompressHeader) + +/* + * Maximum size of the header for a block reference. This is used to size a + * temporary buffer for constructing the header. + */ +#define MaxSizeOfXLogRecordBlockHeader \ + (SizeOfXLogRecordBlockHeader + \ + SizeOfXLogRecordBlockImageHeader + \ + SizeOfXLogRecordBlockCompressHeader + \ + sizeof(RelFileLocator) + \ + sizeof(BlockNumber)) + +/* + * The fork number fits in the lower 4 bits in the fork_flags field. The upper + * bits are used for flags. + */ +#define BKPBLOCK_FORK_MASK 0x0F +#define BKPBLOCK_FLAG_MASK 0xF0 +#define BKPBLOCK_HAS_IMAGE 0x10 /* block data is an XLogRecordBlockImage */ +#define BKPBLOCK_HAS_DATA 0x20 +#define BKPBLOCK_WILL_INIT 0x40 /* redo will re-init the page */ +#define BKPBLOCK_SAME_REL 0x80 /* RelFileLocator omitted, same as + * previous */ + +/* + * XLogRecordDataHeaderShort/Long are used for the "main data" portion of + * the record. If the length of the data is less than 256 bytes, the short + * form is used, with a single byte to hold the length. Otherwise the long + * form is used. + * + * (These structs are currently not used in the code, they are here just for + * documentation purposes). + */ +typedef struct XLogRecordDataHeaderShort +{ + uint8 id; /* XLR_BLOCK_ID_DATA_SHORT */ + uint8 data_length; /* number of payload bytes */ +} XLogRecordDataHeaderShort; + +#define SizeOfXLogRecordDataHeaderShort (sizeof(uint8) * 2) + +typedef struct XLogRecordDataHeaderLong +{ + uint8 id; /* XLR_BLOCK_ID_DATA_LONG */ + /* followed by uint32 data_length, unaligned */ +} XLogRecordDataHeaderLong; + +#define SizeOfXLogRecordDataHeaderLong (sizeof(uint8) + sizeof(uint32)) + +/* + * Block IDs used to distinguish different kinds of record fragments. Block + * references are numbered from 0 to XLR_MAX_BLOCK_ID. A rmgr is free to use + * any ID number in that range (although you should stick to small numbers, + * because the WAL machinery is optimized for that case). A few ID + * numbers are reserved to denote the "main" data portion of the record, + * as well as replication-supporting transaction metadata. + * + * The maximum is currently set at 32, quite arbitrarily. Most records only + * need a handful of block references, but there are a few exceptions that + * need more. + */ +#define XLR_MAX_BLOCK_ID 32 + +#define XLR_BLOCK_ID_DATA_SHORT 255 +#define XLR_BLOCK_ID_DATA_LONG 254 +#define XLR_BLOCK_ID_ORIGIN 253 +#define XLR_BLOCK_ID_TOPLEVEL_XID 252 + +#endif /* XLOGRECORD_H */ diff --git a/install/include/postgresql/server/access/xlogrecovery.h b/install/include/postgresql/server/access/xlogrecovery.h new file mode 100644 index 00000000000..47c29350f5d --- /dev/null +++ b/install/include/postgresql/server/access/xlogrecovery.h @@ -0,0 +1,158 @@ +/* + * xlogrecovery.h + * + * Functions for WAL recovery and standby mode + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xlogrecovery.h + */ +#ifndef XLOGRECOVERY_H +#define XLOGRECOVERY_H + +#include "access/xlogreader.h" +#include "catalog/pg_control.h" +#include "lib/stringinfo.h" +#include "utils/timestamp.h" + +/* + * Recovery target type. + * Only set during a Point in Time recovery, not when in standby mode. + */ +typedef enum +{ + RECOVERY_TARGET_UNSET, + RECOVERY_TARGET_XID, + RECOVERY_TARGET_TIME, + RECOVERY_TARGET_NAME, + RECOVERY_TARGET_LSN, + RECOVERY_TARGET_IMMEDIATE +} RecoveryTargetType; + +/* + * Recovery target TimeLine goal + */ +typedef enum +{ + RECOVERY_TARGET_TIMELINE_CONTROLFILE, + RECOVERY_TARGET_TIMELINE_LATEST, + RECOVERY_TARGET_TIMELINE_NUMERIC +} RecoveryTargetTimeLineGoal; + +/* Recovery pause states */ +typedef enum RecoveryPauseState +{ + RECOVERY_NOT_PAUSED, /* pause not requested */ + RECOVERY_PAUSE_REQUESTED, /* pause requested, but not yet paused */ + RECOVERY_PAUSED /* recovery is paused */ +} RecoveryPauseState; + +/* User-settable GUC parameters */ +extern PGDLLIMPORT bool recoveryTargetInclusive; +extern PGDLLIMPORT int recoveryTargetAction; +extern PGDLLIMPORT int recovery_min_apply_delay; +extern PGDLLIMPORT char *PrimaryConnInfo; +extern PGDLLIMPORT char *PrimarySlotName; +extern PGDLLIMPORT char *recoveryRestoreCommand; +extern PGDLLIMPORT char *recoveryEndCommand; +extern PGDLLIMPORT char *archiveCleanupCommand; + +/* indirectly set via GUC system */ +extern PGDLLIMPORT TransactionId recoveryTargetXid; +extern PGDLLIMPORT char *recovery_target_time_string; +extern PGDLLIMPORT TimestampTz recoveryTargetTime; +extern PGDLLIMPORT const char *recoveryTargetName; +extern PGDLLIMPORT XLogRecPtr recoveryTargetLSN; +extern PGDLLIMPORT RecoveryTargetType recoveryTarget; +extern PGDLLIMPORT bool wal_receiver_create_temp_slot; +extern PGDLLIMPORT RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal; +extern PGDLLIMPORT TimeLineID recoveryTargetTLIRequested; +extern PGDLLIMPORT TimeLineID recoveryTargetTLI; + +/* Have we already reached a consistent database state? */ +extern PGDLLIMPORT bool reachedConsistency; + +/* Are we currently in standby mode? */ +extern PGDLLIMPORT bool StandbyMode; + +extern Size XLogRecoveryShmemSize(void); +extern void XLogRecoveryShmemInit(void); + +extern void InitWalRecovery(ControlFileData *ControlFile, + bool *wasShutdown_ptr, bool *haveBackupLabel_ptr, + bool *haveTblspcMap_ptr); +extern void PerformWalRecovery(void); + +/* + * FinishWalRecovery() returns this. It contains information about the point + * where recovery ended, and why it ended. + */ +typedef struct +{ + /* + * Information about the last valid or applied record, after which new WAL + * can be appended. 'lastRec' is the position where the last record + * starts, and 'endOfLog' is its end. 'lastPage' is a copy of the last + * partial page that contains endOfLog (or NULL if endOfLog is exactly at + * page boundary). 'lastPageBeginPtr' is the position where the last page + * begins. + * + * endOfLogTLI is the TLI in the filename of the XLOG segment containing + * the last applied record. It could be different from lastRecTLI, if + * there was a timeline switch in that segment, and we were reading the + * old WAL from a segment belonging to a higher timeline. + */ + XLogRecPtr lastRec; /* start of last valid or applied record */ + TimeLineID lastRecTLI; + XLogRecPtr endOfLog; /* end of last valid or applied record */ + TimeLineID endOfLogTLI; + + XLogRecPtr lastPageBeginPtr; /* LSN of page that contains endOfLog */ + char *lastPage; /* copy of the last page, up to endOfLog */ + + /* + * abortedRecPtr is the start pointer of a broken record at end of WAL + * when recovery completes; missingContrecPtr is the location of the first + * contrecord that went missing. See CreateOverwriteContrecordRecord for + * details. + */ + XLogRecPtr abortedRecPtr; + XLogRecPtr missingContrecPtr; + + /* short human-readable string describing why recovery ended */ + char *recoveryStopReason; + + /* + * If standby or recovery signal file was found, these flags are set + * accordingly. + */ + bool standby_signal_file_found; + bool recovery_signal_file_found; +} EndOfWalRecoveryInfo; + +extern EndOfWalRecoveryInfo *FinishWalRecovery(void); +extern void ShutdownWalRecovery(void); +extern void RemovePromoteSignalFiles(void); + +extern bool HotStandbyActive(void); +extern XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI); +extern RecoveryPauseState GetRecoveryPauseState(void); +extern void SetRecoveryPause(bool recoveryPause); +extern void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream); +extern TimestampTz GetLatestXTime(void); +extern TimestampTz GetCurrentChunkReplayStartTime(void); +extern XLogRecPtr GetCurrentReplayRecPtr(TimeLineID *replayEndTLI); + +extern bool PromoteIsTriggered(void); +extern bool CheckPromoteSignal(void); +extern void WakeupRecovery(void); + +extern void StartupRequestWalReceiverRestart(void); +extern void XLogRequestWalReceiverReply(void); + +extern void RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue); + +extern void xlog_outdesc(StringInfo buf, XLogReaderState *record); + +#endif /* XLOGRECOVERY_H */ diff --git a/install/include/postgresql/server/access/xlogstats.h b/install/include/postgresql/server/access/xlogstats.h new file mode 100644 index 00000000000..a9d587cc66f --- /dev/null +++ b/install/include/postgresql/server/access/xlogstats.h @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------- + * + * xlogstats.h + * Definitions for WAL Statistics + * + * Copyright (c) 2022-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/access/xlogstats.h + * + *------------------------------------------------------------------------- + */ +#ifndef XLOGSTATS_H +#define XLOGSTATS_H + +#include "access/rmgr.h" +#include "access/xlogreader.h" + +#define MAX_XLINFO_TYPES 16 + +typedef struct XLogRecStats +{ + uint64 count; + uint64 rec_len; + uint64 fpi_len; +} XLogRecStats; + +typedef struct XLogStats +{ + uint64 count; +#ifdef FRONTEND + XLogRecPtr startptr; + XLogRecPtr endptr; +#endif + XLogRecStats rmgr_stats[RM_MAX_ID + 1]; + XLogRecStats record_stats[RM_MAX_ID + 1][MAX_XLINFO_TYPES]; +} XLogStats; + +extern void XLogRecGetLen(XLogReaderState *record, uint32 *rec_len, + uint32 *fpi_len); +extern void XLogRecStoreStats(XLogStats *stats, XLogReaderState *record); + +#endif /* XLOGSTATS_H */ diff --git a/install/include/postgresql/server/access/xlogutils.h b/install/include/postgresql/server/access/xlogutils.h new file mode 100644 index 00000000000..5b77b11f508 --- /dev/null +++ b/install/include/postgresql/server/access/xlogutils.h @@ -0,0 +1,118 @@ +/* + * xlogutils.h + * + * Utilities for replaying WAL records. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xlogutils.h + */ +#ifndef XLOG_UTILS_H +#define XLOG_UTILS_H + +#include "access/xlogreader.h" +#include "storage/bufmgr.h" + +/* + * Prior to 8.4, all activity during recovery was carried out by the startup + * process. This local variable continues to be used in many parts of the + * code to indicate actions taken by RecoveryManagers. Other processes that + * potentially perform work during recovery should check RecoveryInProgress(). + * See XLogCtl notes in xlog.c. + */ +extern PGDLLIMPORT bool InRecovery; + +/* + * Like InRecovery, standbyState is only valid in the startup process. + * In all other processes it will have the value STANDBY_DISABLED (so + * InHotStandby will read as false). + * + * In DISABLED state, we're performing crash recovery or hot standby was + * disabled in postgresql.conf. + * + * In INITIALIZED state, we've run InitRecoveryTransactionEnvironment, but + * we haven't yet processed a RUNNING_XACTS or shutdown-checkpoint WAL record + * to initialize our primary-transaction tracking system. + * + * When the transaction tracking is initialized, we enter the SNAPSHOT_PENDING + * state. The tracked information might still be incomplete, so we can't allow + * connections yet, but redo functions must update the in-memory state when + * appropriate. + * + * In SNAPSHOT_READY mode, we have full knowledge of transactions that are + * (or were) running on the primary at the current WAL location. Snapshots + * can be taken, and read-only queries can be run. + */ +typedef enum +{ + STANDBY_DISABLED, + STANDBY_INITIALIZED, + STANDBY_SNAPSHOT_PENDING, + STANDBY_SNAPSHOT_READY +} HotStandbyState; + +extern PGDLLIMPORT HotStandbyState standbyState; + +#define InHotStandby (standbyState >= STANDBY_SNAPSHOT_PENDING) + + +extern bool XLogHaveInvalidPages(void); +extern void XLogCheckInvalidPages(void); + +extern void XLogDropRelation(RelFileLocator rlocator, ForkNumber forknum); +extern void XLogDropDatabase(Oid dbid); +extern void XLogTruncateRelation(RelFileLocator rlocator, ForkNumber forkNum, + BlockNumber nblocks); + +/* Result codes for XLogReadBufferForRedo[Extended] */ +typedef enum +{ + BLK_NEEDS_REDO, /* changes from WAL record need to be applied */ + BLK_DONE, /* block is already up-to-date */ + BLK_RESTORED, /* block was restored from a full-page image */ + BLK_NOTFOUND /* block was not found (and hence does not + * need to be replayed) */ +} XLogRedoAction; + +/* Private data of the read_local_xlog_page_no_wait callback. */ +typedef struct ReadLocalXLogPageNoWaitPrivate +{ + bool end_of_wal; /* true, when end of WAL is reached */ +} ReadLocalXLogPageNoWaitPrivate; + +extern XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, + uint8 block_id, Buffer *buf); +extern Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id); +extern XLogRedoAction XLogReadBufferForRedoExtended(XLogReaderState *record, + uint8 block_id, + ReadBufferMode mode, bool get_cleanup_lock, + Buffer *buf); + +extern Buffer XLogReadBufferExtended(RelFileLocator rlocator, ForkNumber forknum, + BlockNumber blkno, ReadBufferMode mode, + Buffer recent_buffer); + +extern Relation CreateFakeRelcacheEntry(RelFileLocator rlocator); +extern void FreeFakeRelcacheEntry(Relation fakerel); + +extern int read_local_xlog_page(XLogReaderState *state, + XLogRecPtr targetPagePtr, int reqLen, + XLogRecPtr targetRecPtr, char *cur_page); +extern int read_local_xlog_page_no_wait(XLogReaderState *state, + XLogRecPtr targetPagePtr, int reqLen, + XLogRecPtr targetRecPtr, + char *cur_page); +extern void wal_segment_open(XLogReaderState *state, + XLogSegNo nextSegNo, + TimeLineID *tli_p); +extern void wal_segment_close(XLogReaderState *state); + +extern void XLogReadDetermineTimeline(XLogReaderState *state, + XLogRecPtr wantPage, + uint32 wantLength, + TimeLineID currTLI); + +extern void WALReadRaiseError(WALReadError *errinfo); + +#endif diff --git a/install/include/postgresql/server/archive/archive_module.h b/install/include/postgresql/server/archive/archive_module.h new file mode 100644 index 00000000000..679ce5a6dbd --- /dev/null +++ b/install/include/postgresql/server/archive/archive_module.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * archive_module.h + * Exports for archive modules. + * + * Copyright (c) 2022-2023, PostgreSQL Global Development Group + * + * src/include/archive/archive_module.h + * + *------------------------------------------------------------------------- + */ +#ifndef _ARCHIVE_MODULE_H +#define _ARCHIVE_MODULE_H + +/* + * The value of the archive_library GUC. + */ +extern PGDLLIMPORT char *XLogArchiveLibrary; + +typedef struct ArchiveModuleState +{ + /* + * Private data pointer for use by an archive module. This can be used to + * store state for the module that will be passed to each of its + * callbacks. + */ + void *private_data; +} ArchiveModuleState; + +/* + * Archive module callbacks + * + * These callback functions should be defined by archive libraries and returned + * via _PG_archive_module_init(). ArchiveFileCB is the only required callback. + * For more information about the purpose of each callback, refer to the + * archive modules documentation. + */ +typedef void (*ArchiveStartupCB) (ArchiveModuleState *state); +typedef bool (*ArchiveCheckConfiguredCB) (ArchiveModuleState *state); +typedef bool (*ArchiveFileCB) (ArchiveModuleState *state, const char *file, const char *path); +typedef void (*ArchiveShutdownCB) (ArchiveModuleState *state); + +typedef struct ArchiveModuleCallbacks +{ + ArchiveStartupCB startup_cb; + ArchiveCheckConfiguredCB check_configured_cb; + ArchiveFileCB archive_file_cb; + ArchiveShutdownCB shutdown_cb; +} ArchiveModuleCallbacks; + +/* + * Type of the shared library symbol _PG_archive_module_init that is looked + * up when loading an archive library. + */ +typedef const ArchiveModuleCallbacks *(*ArchiveModuleInit) (void); + +extern PGDLLEXPORT const ArchiveModuleCallbacks *_PG_archive_module_init(void); + +#endif /* _ARCHIVE_MODULE_H */ diff --git a/install/include/postgresql/server/archive/shell_archive.h b/install/include/postgresql/server/archive/shell_archive.h new file mode 100644 index 00000000000..9de6f769f12 --- /dev/null +++ b/install/include/postgresql/server/archive/shell_archive.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * shell_archive.h + * Exports for archiving via shell. + * + * Copyright (c) 2022-2023, PostgreSQL Global Development Group + * + * src/include/archive/shell_archive.h + * + *------------------------------------------------------------------------- + */ +#ifndef _SHELL_ARCHIVE_H +#define _SHELL_ARCHIVE_H + +#include "archive/archive_module.h" + +/* + * Since the logic for archiving via a shell command is in the core server + * and does not need to be loaded via a shared library, it has a special + * initialization function. + */ +extern const ArchiveModuleCallbacks *shell_archive_init(void); + +#endif /* _SHELL_ARCHIVE_H */ diff --git a/install/include/postgresql/server/bootstrap/bootstrap.h b/install/include/postgresql/server/bootstrap/bootstrap.h new file mode 100644 index 00000000000..2c28a52ce71 --- /dev/null +++ b/install/include/postgresql/server/bootstrap/bootstrap.h @@ -0,0 +1,62 @@ +/*------------------------------------------------------------------------- + * + * bootstrap.h + * include file for the bootstrapping code + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/bootstrap/bootstrap.h + * + *------------------------------------------------------------------------- + */ +#ifndef BOOTSTRAP_H +#define BOOTSTRAP_H + +#include "nodes/execnodes.h" + + +/* + * MAXATTR is the maximum number of attributes in a relation supported + * at bootstrap time (i.e., the max possible in a system table). + */ +#define MAXATTR 40 + +#define BOOTCOL_NULL_AUTO 1 +#define BOOTCOL_NULL_FORCE_NULL 2 +#define BOOTCOL_NULL_FORCE_NOT_NULL 3 + +extern PGDLLIMPORT Relation boot_reldesc; +extern PGDLLIMPORT Form_pg_attribute attrtypes[MAXATTR]; +extern PGDLLIMPORT int numattr; + + +extern void BootstrapModeMain(int argc, char *argv[], bool check_only) pg_attribute_noreturn(); + +extern void closerel(char *relname); +extern void boot_openrel(char *relname); + +extern void DefineAttr(char *name, char *type, int attnum, int nullness); +extern void InsertOneTuple(void); +extern void InsertOneValue(char *value, int i); +extern void InsertOneNull(int i); + +extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo); +extern void build_indices(void); + +extern void boot_get_type_io_data(Oid typid, + int16 *typlen, + bool *typbyval, + char *typalign, + char *typdelim, + Oid *typioparam, + Oid *typinput, + Oid *typoutput); + +extern int boot_yyparse(void); + +extern int boot_yylex(void); +extern void boot_yyerror(const char *message) pg_attribute_noreturn(); + +#endif /* BOOTSTRAP_H */ diff --git a/install/include/postgresql/server/c.h b/install/include/postgresql/server/c.h new file mode 100644 index 00000000000..a7258cce1fc --- /dev/null +++ b/install/include/postgresql/server/c.h @@ -0,0 +1,1377 @@ +/*------------------------------------------------------------------------- + * + * c.h + * Fundamental C definitions. This is included by every .c file in + * PostgreSQL (via either postgres.h or postgres_fe.h, as appropriate). + * + * Note that the definitions here are not intended to be exposed to clients + * of the frontend interface libraries --- so we don't worry much about + * polluting the namespace with lots of stuff... + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/c.h + * + *------------------------------------------------------------------------- + */ +/* + *---------------------------------------------------------------- + * TABLE OF CONTENTS + * + * When adding stuff to this file, please try to put stuff + * into the relevant section, or add new sections as appropriate. + * + * section description + * ------- ------------------------------------------------ + * 0) pg_config.h and standard system headers + * 1) compiler characteristics + * 2) bool, true, false + * 3) standard system types + * 4) IsValid macros for system types + * 5) lengthof, alignment + * 6) assertions + * 7) widely useful macros + * 8) random stuff + * 9) system-specific hacks + * + * NOTE: since this file is included by both frontend and backend modules, + * it's usually wrong to put an "extern" declaration here, unless it's + * ifdef'd so that it's seen in only one case or the other. + * typedefs and macros are the kind of thing that might go here. + * + *---------------------------------------------------------------- + */ +#ifndef C_H +#define C_H + +#include "postgres_ext.h" + +/* Must undef pg_config_ext.h symbols before including pg_config.h */ +#undef PG_INT64_TYPE + +#include "pg_config.h" +#include "pg_config_manual.h" /* must be after pg_config.h */ +#include "pg_config_os.h" /* must be before any system header files */ + +/* System header files that should be available everywhere in Postgres */ +#include +#include +#include +#include +#include +#ifdef HAVE_STRINGS_H +#include +#endif +#include +#include +#include +#if defined(WIN32) || defined(__CYGWIN__) +#include /* ensure O_BINARY is available */ +#endif +#include +#ifdef ENABLE_NLS +#include +#endif + + +/* ---------------------------------------------------------------- + * Section 1: compiler characteristics + * + * type prefixes (const, signed, volatile, inline) are handled in pg_config.h. + * ---------------------------------------------------------------- + */ + +/* + * Disable "inline" if PG_FORCE_DISABLE_INLINE is defined. + * This is used to work around compiler bugs and might also be useful for + * investigatory purposes. + */ +#ifdef PG_FORCE_DISABLE_INLINE +#undef inline +#define inline +#endif + +/* + * Attribute macros + * + * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html + * Clang: https://clang.llvm.org/docs/AttributeReference.html + * Sunpro: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html + * XLC: https://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.2/com.ibm.xlc131.aix.doc/language_ref/function_attributes.html + * XLC: https://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.2/com.ibm.xlc131.aix.doc/language_ref/type_attrib.html + */ + +/* + * For compilers which don't support __has_attribute, we just define + * __has_attribute(x) to 0 so that we can define macros for various + * __attribute__s more easily below. + */ +#ifndef __has_attribute +#define __has_attribute(attribute) 0 +#endif + +/* only GCC supports the unused attribute */ +#ifdef __GNUC__ +#define pg_attribute_unused() __attribute__((unused)) +#else +#define pg_attribute_unused() +#endif + +/* + * pg_nodiscard means the compiler should warn if the result of a function + * call is ignored. The name "nodiscard" is chosen in alignment with + * (possibly future) C and C++ standards. For maximum compatibility, use it + * as a function declaration specifier, so it goes before the return type. + */ +#ifdef __GNUC__ +#define pg_nodiscard __attribute__((warn_unused_result)) +#else +#define pg_nodiscard +#endif + +/* + * Place this macro before functions that should be allowed to make misaligned + * accesses. Think twice before using it on non-x86-specific code! + * Testing can be done with "-fsanitize=alignment -fsanitize-trap=alignment" + * on clang, or "-fsanitize=alignment -fno-sanitize-recover=alignment" on gcc. + */ +#if __clang_major__ >= 7 || __GNUC__ >= 8 +#define pg_attribute_no_sanitize_alignment() __attribute__((no_sanitize("alignment"))) +#else +#define pg_attribute_no_sanitize_alignment() +#endif + +/* + * pg_attribute_nonnull means the compiler should warn if the function is + * called with the listed arguments set to NULL. If no arguments are + * listed, the compiler should warn if any pointer arguments are set to NULL. + */ +#if __has_attribute (nonnull) +#define pg_attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) +#else +#define pg_attribute_nonnull(...) +#endif + +/* + * Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only + * used in assert-enabled builds, to avoid compiler warnings about unused + * variables in assert-disabled builds. + */ +#ifdef USE_ASSERT_CHECKING +#define PG_USED_FOR_ASSERTS_ONLY +#else +#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused() +#endif + +/* GCC and XLC support format attributes */ +#if defined(__GNUC__) || defined(__IBMC__) +#define pg_attribute_format_arg(a) __attribute__((format_arg(a))) +#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a))) +#else +#define pg_attribute_format_arg(a) +#define pg_attribute_printf(f,a) +#endif + +/* GCC, Sunpro and XLC support aligned, packed and noreturn */ +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__) +#define pg_attribute_aligned(a) __attribute__((aligned(a))) +#define pg_attribute_noreturn() __attribute__((noreturn)) +#define pg_attribute_packed() __attribute__((packed)) +#define HAVE_PG_ATTRIBUTE_NORETURN 1 +#elif defined(_MSC_VER) +/* + * MSVC supports aligned. noreturn is also possible but in MSVC it is + * declared before the definition while pg_attribute_noreturn() macro + * is currently used after the definition. + * + * Packing is also possible but only by wrapping the entire struct definition + * which doesn't fit into our current macro declarations. + */ +#define pg_attribute_aligned(a) __declspec(align(a)) +#define pg_attribute_noreturn() +#else +/* + * NB: aligned and packed are not given default definitions because they + * affect code functionality; they *must* be implemented by the compiler + * if they are to be used. + */ +#define pg_attribute_noreturn() +#endif + +/* + * Use "pg_attribute_always_inline" in place of "inline" for functions that + * we wish to force inlining of, even when the compiler's heuristics would + * choose not to. But, if possible, don't force inlining in unoptimized + * debug builds. + */ +#if (defined(__GNUC__) && __GNUC__ > 3 && defined(__OPTIMIZE__)) || defined(__SUNPRO_C) || defined(__IBMC__) +/* GCC > 3, Sunpro and XLC support always_inline via __attribute__ */ +#define pg_attribute_always_inline __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +/* MSVC has a special keyword for this */ +#define pg_attribute_always_inline __forceinline +#else +/* Otherwise, the best we can do is to say "inline" */ +#define pg_attribute_always_inline inline +#endif + +/* + * Forcing a function not to be inlined can be useful if it's the slow path of + * a performance-critical function, or should be visible in profiles to allow + * for proper cost attribution. Note that unlike the pg_attribute_XXX macros + * above, this should be placed before the function's return type and name. + */ +/* GCC, Sunpro and XLC support noinline via __attribute__ */ +#if (defined(__GNUC__) && __GNUC__ > 2) || defined(__SUNPRO_C) || defined(__IBMC__) +#define pg_noinline __attribute__((noinline)) +/* msvc via declspec */ +#elif defined(_MSC_VER) +#define pg_noinline __declspec(noinline) +#else +#define pg_noinline +#endif + +/* + * For now, just define pg_attribute_cold and pg_attribute_hot to be empty + * macros on minGW 8.1. There appears to be a compiler bug that results in + * compilation failure. At this time, we still have at least one buildfarm + * animal running that compiler, so this should make that green again. It's + * likely this compiler is not popular enough to warrant keeping this code + * around forever, so let's just remove it once the last buildfarm animal + * upgrades. + */ +#if defined(__MINGW64__) && __GNUC__ == 8 && __GNUC_MINOR__ == 1 + +#define pg_attribute_cold +#define pg_attribute_hot + +#else +/* + * Marking certain functions as "hot" or "cold" can be useful to assist the + * compiler in arranging the assembly code in a more efficient way. + */ +#if __has_attribute (cold) +#define pg_attribute_cold __attribute__((cold)) +#else +#define pg_attribute_cold +#endif + +#if __has_attribute (hot) +#define pg_attribute_hot __attribute__((hot)) +#else +#define pg_attribute_hot +#endif + +#endif /* defined(__MINGW64__) && __GNUC__ == 8 && + * __GNUC_MINOR__ == 1 */ +/* + * Mark a point as unreachable in a portable fashion. This should preferably + * be something that the compiler understands, to aid code generation. + * In assert-enabled builds, we prefer abort() for debugging reasons. + */ +#if defined(HAVE__BUILTIN_UNREACHABLE) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __builtin_unreachable() +#elif defined(_MSC_VER) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __assume(0) +#else +#define pg_unreachable() abort() +#endif + +/* + * Hints to the compiler about the likelihood of a branch. Both likely() and + * unlikely() return the boolean value of the contained expression. + * + * These should only be used sparingly, in very hot code paths. It's very easy + * to mis-estimate likelihoods. + */ +#if __GNUC__ >= 3 +#define likely(x) __builtin_expect((x) != 0, 1) +#define unlikely(x) __builtin_expect((x) != 0, 0) +#else +#define likely(x) ((x) != 0) +#define unlikely(x) ((x) != 0) +#endif + +/* + * CppAsString + * Convert the argument to a string, using the C preprocessor. + * CppAsString2 + * Convert the argument to a string, after one round of macro expansion. + * CppConcat + * Concatenate two arguments together, using the C preprocessor. + * + * Note: There used to be support here for pre-ANSI C compilers that didn't + * support # and ##. Nowadays, these macros are just for clarity and/or + * backward compatibility with existing PostgreSQL code. + */ +#define CppAsString(identifier) #identifier +#define CppAsString2(x) CppAsString(x) +#define CppConcat(x, y) x##y + +/* + * VA_ARGS_NARGS + * Returns the number of macro arguments it is passed. + * + * An empty argument still counts as an argument, so effectively, this is + * "one more than the number of commas in the argument list". + * + * This works for up to 63 arguments. Internally, VA_ARGS_NARGS_() is passed + * 64+N arguments, and the C99 standard only requires macros to allow up to + * 127 arguments, so we can't portably go higher. The implementation is + * pretty trivial: VA_ARGS_NARGS_() returns its 64th argument, and we set up + * the call so that that is the appropriate one of the list of constants. + * This idea is due to Laurent Deniau. + * + * MSVC has an implementation of __VA_ARGS__ that doesn't conform to the + * standard unless you use the /Zc:preprocessor compiler flag, but that + * isn't available before Visual Studio 2019. For now, use a different + * definition that also works on older compilers. + */ +#ifdef _MSC_VER +#define EXPAND(args) args +#define VA_ARGS_NARGS(...) \ + VA_ARGS_NARGS_ EXPAND((__VA_ARGS__, \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) +#else + +#define VA_ARGS_NARGS(...) \ + VA_ARGS_NARGS_(__VA_ARGS__, \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#endif + +#define VA_ARGS_NARGS_( \ + _01,_02,_03,_04,_05,_06,_07,_08,_09,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63, N, ...) \ + (N) + +/* + * Generic function pointer. This can be used in the rare cases where it's + * necessary to cast a function pointer to a seemingly incompatible function + * pointer type while avoiding gcc's -Wcast-function-type warnings. + */ +typedef void (*pg_funcptr_t) (void); + +/* + * We require C99, hence the compiler should understand flexible array + * members. However, for documentation purposes we still consider it to be + * project style to write "field[FLEXIBLE_ARRAY_MEMBER]" not just "field[]". + * When computing the size of such an object, use "offsetof(struct s, f)" + * for portability. Don't use "offsetof(struct s, f[0])", as this doesn't + * work with MSVC and with C++ compilers. + */ +#define FLEXIBLE_ARRAY_MEMBER /* empty */ + +/* + * Does the compiler support #pragma GCC system_header? We optionally use it + * to avoid warnings that we can't fix (e.g. in the perl headers). + * See https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html + * + * Headers for which we do not want to show compiler warnings can, + * conditionally, use #pragma GCC system_header to avoid warnings. Obviously + * this should only be used for external headers over which we do not have + * control. + * + * Support for the pragma is tested here, instead of during configure, as gcc + * also warns about the pragma being used in a .c file. It's surprisingly hard + * to get autoconf to use .h as the file-ending. Looks like gcc has + * implemented the pragma since the 2000, so this test should suffice. + * + * + * Alternatively, we could add the include paths for problematic headers with + * -isystem, but that is a larger hammer and is harder to search for. + * + * A more granular alternative would be to use #pragma GCC diagnostic + * push/ignored/pop, but gcc warns about unknown warnings being ignored, so + * every to-be-ignored-temporarily compiler warning would require its own + * pg_config.h symbol and #ifdef. + */ +#ifdef __GNUC__ +#define HAVE_PRAGMA_GCC_SYSTEM_HEADER 1 +#endif + + +/* ---------------------------------------------------------------- + * Section 2: bool, true, false + * ---------------------------------------------------------------- + */ + +/* + * bool + * Boolean value, either true or false. + * + * We use stdbool.h if bool has size 1 after including it. That's useful for + * better compiler and debugger output and for compatibility with third-party + * libraries. But PostgreSQL currently cannot deal with bool of other sizes; + * there are static assertions around the code to prevent that. + * + * For C++ compilers, we assume the compiler has a compatible built-in + * definition of bool. + * + * See also the version of this code in src/interfaces/ecpg/include/ecpglib.h. + */ + +#ifndef __cplusplus + +#ifdef PG_USE_STDBOOL +#include +#else + +#ifndef bool +typedef unsigned char bool; +#endif + +#ifndef true +#define true ((bool) 1) +#endif + +#ifndef false +#define false ((bool) 0) +#endif + +#endif /* not PG_USE_STDBOOL */ +#endif /* not C++ */ + + +/* ---------------------------------------------------------------- + * Section 3: standard system types + * ---------------------------------------------------------------- + */ + +/* + * Pointer + * Variable holding address of any memory resident object. + * + * XXX Pointer arithmetic is done with this, so it can't be void * + * under "true" ANSI compilers. + */ +typedef char *Pointer; + +/* + * intN + * Signed integer, EXACTLY N BITS IN SIZE, + * used for numerical computations and the + * frontend/backend protocol. + */ +#ifndef HAVE_INT8 +typedef signed char int8; /* == 8 bits */ +typedef signed short int16; /* == 16 bits */ +typedef signed int int32; /* == 32 bits */ +#endif /* not HAVE_INT8 */ + +/* + * uintN + * Unsigned integer, EXACTLY N BITS IN SIZE, + * used for numerical computations and the + * frontend/backend protocol. + */ +#ifndef HAVE_UINT8 +typedef unsigned char uint8; /* == 8 bits */ +typedef unsigned short uint16; /* == 16 bits */ +typedef unsigned int uint32; /* == 32 bits */ +#endif /* not HAVE_UINT8 */ + +/* + * bitsN + * Unit of bitwise operation, AT LEAST N BITS IN SIZE. + */ +typedef uint8 bits8; /* >= 8 bits */ +typedef uint16 bits16; /* >= 16 bits */ +typedef uint32 bits32; /* >= 32 bits */ + +/* + * 64-bit integers + */ +#ifdef HAVE_LONG_INT_64 +/* Plain "long int" fits, use it */ + +#ifndef HAVE_INT64 +typedef long int int64; +#endif +#ifndef HAVE_UINT64 +typedef unsigned long int uint64; +#endif +#define INT64CONST(x) (x##L) +#define UINT64CONST(x) (x##UL) +#elif defined(HAVE_LONG_LONG_INT_64) +/* We have working support for "long long int", use that */ + +#ifndef HAVE_INT64 +typedef long long int int64; +#endif +#ifndef HAVE_UINT64 +typedef unsigned long long int uint64; +#endif +#define INT64CONST(x) (x##LL) +#define UINT64CONST(x) (x##ULL) +#else +/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ +#error must have a working 64-bit integer datatype +#endif + +/* snprintf format strings to use for 64-bit integers */ +#define INT64_FORMAT "%" INT64_MODIFIER "d" +#define UINT64_FORMAT "%" INT64_MODIFIER "u" + +/* + * 128-bit signed and unsigned integers + * There currently is only limited support for such types. + * E.g. 128bit literals and snprintf are not supported; but math is. + * Also, because we exclude such types when choosing MAXIMUM_ALIGNOF, + * it must be possible to coerce the compiler to allocate them on no + * more than MAXALIGN boundaries. + */ +#if defined(PG_INT128_TYPE) +#if defined(pg_attribute_aligned) || ALIGNOF_PG_INT128_TYPE <= MAXIMUM_ALIGNOF +#define HAVE_INT128 1 + +typedef PG_INT128_TYPE int128 +#if defined(pg_attribute_aligned) + pg_attribute_aligned(MAXIMUM_ALIGNOF) +#endif + ; + +typedef unsigned PG_INT128_TYPE uint128 +#if defined(pg_attribute_aligned) + pg_attribute_aligned(MAXIMUM_ALIGNOF) +#endif + ; + +#endif +#endif + +/* + * stdint.h limits aren't guaranteed to have compatible types with our fixed + * width types. So just define our own. + */ +#define PG_INT8_MIN (-0x7F-1) +#define PG_INT8_MAX (0x7F) +#define PG_UINT8_MAX (0xFF) +#define PG_INT16_MIN (-0x7FFF-1) +#define PG_INT16_MAX (0x7FFF) +#define PG_UINT16_MAX (0xFFFF) +#define PG_INT32_MIN (-0x7FFFFFFF-1) +#define PG_INT32_MAX (0x7FFFFFFF) +#define PG_UINT32_MAX (0xFFFFFFFFU) +#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1) +#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF) +#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF) + +/* + * We now always use int64 timestamps, but keep this symbol defined for the + * benefit of external code that might test it. + */ +#define HAVE_INT64_TIMESTAMP + +/* + * Size + * Size of any memory resident object, as returned by sizeof. + */ +typedef size_t Size; + +/* + * Index + * Index into any memory resident array. + * + * Note: + * Indices are non negative. + */ +typedef unsigned int Index; + +/* + * Offset + * Offset into any memory resident array. + * + * Note: + * This differs from an Index in that an Index is always + * non negative, whereas Offset may be negative. + */ +typedef signed int Offset; + +/* + * Common Postgres datatype names (as used in the catalogs) + */ +typedef float float4; +typedef double float8; + +#ifdef USE_FLOAT8_BYVAL +#define FLOAT8PASSBYVAL true +#else +#define FLOAT8PASSBYVAL false +#endif + +/* + * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, + * CommandId + */ + +/* typedef Oid is in postgres_ext.h */ + +/* + * regproc is the type name used in the include/catalog headers, but + * RegProcedure is the preferred name in C code. + */ +typedef Oid regproc; +typedef regproc RegProcedure; + +typedef uint32 TransactionId; + +typedef uint32 LocalTransactionId; + +typedef uint32 SubTransactionId; + +#define InvalidSubTransactionId ((SubTransactionId) 0) +#define TopSubTransactionId ((SubTransactionId) 1) + +/* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */ +typedef TransactionId MultiXactId; + +typedef uint32 MultiXactOffset; + +typedef uint32 CommandId; + +#define FirstCommandId ((CommandId) 0) +#define InvalidCommandId (~(CommandId)0) + + +/* ---------------- + * Variable-length datatypes all share the 'struct varlena' header. + * + * NOTE: for TOASTable types, this is an oversimplification, since the value + * may be compressed or moved out-of-line. However datatype-specific routines + * are mostly content to deal with de-TOASTed values only, and of course + * client-side routines should never see a TOASTed value. But even in a + * de-TOASTed value, beware of touching vl_len_ directly, as its + * representation is no longer convenient. It's recommended that code always + * use macros VARDATA_ANY, VARSIZE_ANY, VARSIZE_ANY_EXHDR, VARDATA, VARSIZE, + * and SET_VARSIZE instead of relying on direct mentions of the struct fields. + * See postgres.h for details of the TOASTed form. + * ---------------- + */ +struct varlena +{ + char vl_len_[4]; /* Do not touch this field directly! */ + char vl_dat[FLEXIBLE_ARRAY_MEMBER]; /* Data content is here */ +}; + +#define VARHDRSZ ((int32) sizeof(int32)) + +/* + * These widely-used datatypes are just a varlena header and the data bytes. + * There is no terminating null or anything like that --- the data length is + * always VARSIZE_ANY_EXHDR(ptr). + */ +typedef struct varlena bytea; +typedef struct varlena text; +typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */ +typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */ + +/* + * Specialized array types. These are physically laid out just the same + * as regular arrays (so that the regular array subscripting code works + * with them). They exist as distinct types mostly for historical reasons: + * they have nonstandard I/O behavior which we don't want to change for fear + * of breaking applications that look at the system catalogs. There is also + * an implementation issue for oidvector: it's part of the primary key for + * pg_proc, and we can't use the normal btree array support routines for that + * without circularity. + */ +typedef struct +{ + int32 vl_len_; /* these fields must match ArrayType! */ + int ndim; /* always 1 for int2vector */ + int32 dataoffset; /* always 0 for int2vector */ + Oid elemtype; + int dim1; + int lbound1; + int16 values[FLEXIBLE_ARRAY_MEMBER]; +} int2vector; + +typedef struct +{ + int32 vl_len_; /* these fields must match ArrayType! */ + int ndim; /* always 1 for oidvector */ + int32 dataoffset; /* always 0 for oidvector */ + Oid elemtype; + int dim1; + int lbound1; + Oid values[FLEXIBLE_ARRAY_MEMBER]; +} oidvector; + +/* + * Representation of a Name: effectively just a C string, but null-padded to + * exactly NAMEDATALEN bytes. The use of a struct is historical. + */ +typedef struct nameData +{ + char data[NAMEDATALEN]; +} NameData; +typedef NameData *Name; + +#define NameStr(name) ((name).data) + + +/* ---------------------------------------------------------------- + * Section 4: IsValid macros for system types + * ---------------------------------------------------------------- + */ +/* + * BoolIsValid + * True iff bool is valid. + */ +#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true) + +/* + * PointerIsValid + * True iff pointer is valid. + */ +#define PointerIsValid(pointer) ((const void*)(pointer) != NULL) + +/* + * PointerIsAligned + * True iff pointer is properly aligned to point to the given type. + */ +#define PointerIsAligned(pointer, type) \ + (((uintptr_t)(pointer) % (sizeof (type))) == 0) + +#define OffsetToPointer(base, offset) \ + ((void *)((char *) base + offset)) + +#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) + +#define RegProcedureIsValid(p) OidIsValid(p) + + +/* ---------------------------------------------------------------- + * Section 5: lengthof, alignment + * ---------------------------------------------------------------- + */ +/* + * lengthof + * Number of elements in an array. + */ +#define lengthof(array) (sizeof (array) / sizeof ((array)[0])) + +/* ---------------- + * Alignment macros: align a length or address appropriately for a given type. + * The fooALIGN() macros round up to a multiple of the required alignment, + * while the fooALIGN_DOWN() macros round down. The latter are more useful + * for problems like "how many X-sized structures will fit in a page?". + * + * NOTE: TYPEALIGN[_DOWN] will not work if ALIGNVAL is not a power of 2. + * That case seems extremely unlikely to be needed in practice, however. + * + * NOTE: MAXIMUM_ALIGNOF, and hence MAXALIGN(), intentionally exclude any + * larger-than-8-byte types the compiler might have. + * ---------------- + */ + +#define TYPEALIGN(ALIGNVAL,LEN) \ + (((uintptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uintptr_t) ((ALIGNVAL) - 1))) + +#define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) +#define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) +#define LONGALIGN(LEN) TYPEALIGN(ALIGNOF_LONG, (LEN)) +#define DOUBLEALIGN(LEN) TYPEALIGN(ALIGNOF_DOUBLE, (LEN)) +#define MAXALIGN(LEN) TYPEALIGN(MAXIMUM_ALIGNOF, (LEN)) +/* MAXALIGN covers only built-in types, not buffers */ +#define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) +#define CACHELINEALIGN(LEN) TYPEALIGN(PG_CACHE_LINE_SIZE, (LEN)) + +#define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ + (((uintptr_t) (LEN)) & ~((uintptr_t) ((ALIGNVAL) - 1))) + +#define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) +#define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) +#define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN)) +#define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN)) +#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN)) +#define BUFFERALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_BUFFER, (LEN)) + +/* + * The above macros will not work with types wider than uintptr_t, like with + * uint64 on 32-bit platforms. That's not problem for the usual use where a + * pointer or a length is aligned, but for the odd case that you need to + * align something (potentially) wider, use TYPEALIGN64. + */ +#define TYPEALIGN64(ALIGNVAL,LEN) \ + (((uint64) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64) ((ALIGNVAL) - 1))) + +/* we don't currently need wider versions of the other ALIGN macros */ +#define MAXALIGN64(LEN) TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN)) + + +/* ---------------------------------------------------------------- + * Section 6: assertions + * ---------------------------------------------------------------- + */ + +/* + * USE_ASSERT_CHECKING, if defined, turns on all the assertions. + * - plai 9/5/90 + * + * It should _NOT_ be defined in releases or in benchmark copies + */ + +/* + * Assert() can be used in both frontend and backend code. In frontend code it + * just calls the standard assert, if it's available. If use of assertions is + * not configured, it does nothing. + */ +#ifndef USE_ASSERT_CHECKING + +#define Assert(condition) ((void)true) +#define AssertMacro(condition) ((void)true) + +#elif defined(FRONTEND) + +#include +#define Assert(p) assert(p) +#define AssertMacro(p) ((void) assert(p)) + +#else /* USE_ASSERT_CHECKING && !FRONTEND */ + +/* + * Assert + * Generates a fatal exception if the given condition is false. + */ +#define Assert(condition) \ + do { \ + if (!(condition)) \ + ExceptionalCondition(#condition, __FILE__, __LINE__); \ + } while (0) + +/* + * AssertMacro is the same as Assert but it's suitable for use in + * expression-like macros, for example: + * + * #define foo(x) (AssertMacro(x != 0), bar(x)) + */ +#define AssertMacro(condition) \ + ((void) ((condition) || \ + (ExceptionalCondition(#condition, __FILE__, __LINE__), 0))) + +#endif /* USE_ASSERT_CHECKING && !FRONTEND */ + +/* + * Check that `ptr' is `bndr' aligned. + */ +#define AssertPointerAlignment(ptr, bndr) \ + Assert(TYPEALIGN(bndr, (uintptr_t)(ptr)) == (uintptr_t)(ptr)) + +/* + * ExceptionalCondition is compiled into the backend whether or not + * USE_ASSERT_CHECKING is defined, so as to support use of extensions + * that are built with that #define with a backend that isn't. Hence, + * we should declare it as long as !FRONTEND. + */ +#ifndef FRONTEND +extern void ExceptionalCondition(const char *conditionName, + const char *fileName, int lineNumber) pg_attribute_noreturn(); +#endif + +/* + * Macros to support compile-time assertion checks. + * + * If the "condition" (a compile-time-constant expression) evaluates to false, + * throw a compile error using the "errmessage" (a string literal). + * + * C11 has _Static_assert(), and most C99 compilers already support that. For + * portability, we wrap it into StaticAssertDecl(). _Static_assert() is a + * "declaration", and so it must be placed where for example a variable + * declaration would be valid. As long as we compile with + * -Wno-declaration-after-statement, that also means it cannot be placed after + * statements in a function. Macros StaticAssertStmt() and StaticAssertExpr() + * make it safe to use as a statement or in an expression, respectively. + * + * For compilers without _Static_assert(), we fall back on a kluge that + * assumes the compiler will complain about a negative width for a struct + * bit-field. This will not include a helpful error message, but it beats not + * getting an error at all. + */ +#ifndef __cplusplus +#ifdef HAVE__STATIC_ASSERT +#define StaticAssertDecl(condition, errmessage) \ + _Static_assert(condition, errmessage) +#define StaticAssertStmt(condition, errmessage) \ + do { _Static_assert(condition, errmessage); } while(0) +#define StaticAssertExpr(condition, errmessage) \ + ((void) ({ StaticAssertStmt(condition, errmessage); true; })) +#else /* !HAVE__STATIC_ASSERT */ +#define StaticAssertDecl(condition, errmessage) \ + extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) +#define StaticAssertStmt(condition, errmessage) \ + ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) +#define StaticAssertExpr(condition, errmessage) \ + StaticAssertStmt(condition, errmessage) +#endif /* HAVE__STATIC_ASSERT */ +#else /* C++ */ +#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410 +#define StaticAssertDecl(condition, errmessage) \ + static_assert(condition, errmessage) +#define StaticAssertStmt(condition, errmessage) \ + static_assert(condition, errmessage) +#define StaticAssertExpr(condition, errmessage) \ + ({ static_assert(condition, errmessage); }) +#else /* !__cpp_static_assert */ +#define StaticAssertDecl(condition, errmessage) \ + extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) +#define StaticAssertStmt(condition, errmessage) \ + do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0) +#define StaticAssertExpr(condition, errmessage) \ + ((void) ({ StaticAssertStmt(condition, errmessage); })) +#endif /* __cpp_static_assert */ +#endif /* C++ */ + + +/* + * Compile-time checks that a variable (or expression) has the specified type. + * + * AssertVariableIsOfType() can be used as a statement. + * AssertVariableIsOfTypeMacro() is intended for use in macros, eg + * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) + * + * If we don't have __builtin_types_compatible_p, we can still assert that + * the types have the same size. This is far from ideal (especially on 32-bit + * platforms) but it provides at least some coverage. + */ +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + (StaticAssertExpr(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ + + +/* ---------------------------------------------------------------- + * Section 7: widely useful macros + * ---------------------------------------------------------------- + */ +/* + * Max + * Return the maximum of two numbers. + */ +#define Max(x, y) ((x) > (y) ? (x) : (y)) + +/* + * Min + * Return the minimum of two numbers. + */ +#define Min(x, y) ((x) < (y) ? (x) : (y)) + + +/* Get a bit mask of the bits set in non-long aligned addresses */ +#define LONG_ALIGN_MASK (sizeof(long) - 1) + +/* + * MemSet + * Exactly the same as standard library function memset(), but considerably + * faster for zeroing small word-aligned structures (such as parsetree nodes). + * This has to be a macro because the main point is to avoid function-call + * overhead. However, we have also found that the loop is faster than + * native libc memset() on some platforms, even those with assembler + * memset() functions. More research needs to be done, perhaps with + * MEMSET_LOOP_LIMIT tests in configure. + */ +#define MemSet(start, val, len) \ + do \ + { \ + /* must be void* because we don't know if it is integer aligned yet */ \ + void *_vstart = (void *) (start); \ + int _val = (val); \ + Size _len = (len); \ +\ + if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ + (_len & LONG_ALIGN_MASK) == 0 && \ + _val == 0 && \ + _len <= MEMSET_LOOP_LIMIT && \ + /* \ + * If MEMSET_LOOP_LIMIT == 0, optimizer should find \ + * the whole "if" false at compile time. \ + */ \ + MEMSET_LOOP_LIMIT != 0) \ + { \ + long *_start = (long *) _vstart; \ + long *_stop = (long *) ((char *) _start + _len); \ + while (_start < _stop) \ + *_start++ = 0; \ + } \ + else \ + memset(_vstart, _val, _len); \ + } while (0) + +/* + * MemSetAligned is the same as MemSet except it omits the test to see if + * "start" is word-aligned. This is okay to use if the caller knows a-priori + * that the pointer is suitably aligned (typically, because he just got it + * from palloc(), which always delivers a max-aligned pointer). + */ +#define MemSetAligned(start, val, len) \ + do \ + { \ + long *_start = (long *) (start); \ + int _val = (val); \ + Size _len = (len); \ +\ + if ((_len & LONG_ALIGN_MASK) == 0 && \ + _val == 0 && \ + _len <= MEMSET_LOOP_LIMIT && \ + MEMSET_LOOP_LIMIT != 0) \ + { \ + long *_stop = (long *) ((char *) _start + _len); \ + while (_start < _stop) \ + *_start++ = 0; \ + } \ + else \ + memset(_start, _val, _len); \ + } while (0) + + +/* + * MemSetTest/MemSetLoop are a variant version that allow all the tests in + * MemSet to be done at compile time in cases where "val" and "len" are + * constants *and* we know the "start" pointer must be word-aligned. + * If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use + * MemSetAligned. Beware of multiple evaluations of the arguments when using + * this approach. + */ +#define MemSetTest(val, len) \ + ( ((len) & LONG_ALIGN_MASK) == 0 && \ + (len) <= MEMSET_LOOP_LIMIT && \ + MEMSET_LOOP_LIMIT != 0 && \ + (val) == 0 ) + +#define MemSetLoop(start, val, len) \ + do \ + { \ + long * _start = (long *) (start); \ + long * _stop = (long *) ((char *) _start + (Size) (len)); \ + \ + while (_start < _stop) \ + *_start++ = 0; \ + } while (0) + +/* + * Macros for range-checking float values before converting to integer. + * We must be careful here that the boundary values are expressed exactly + * in the float domain. PG_INTnn_MIN is an exact power of 2, so it will + * be represented exactly; but PG_INTnn_MAX isn't, and might get rounded + * off, so avoid using that. + * The input must be rounded to an integer beforehand, typically with rint(), + * else we might draw the wrong conclusion about close-to-the-limit values. + * These macros will do the right thing for Inf, but not necessarily for NaN, + * so check isnan(num) first if that's a possibility. + */ +#define FLOAT4_FITS_IN_INT16(num) \ + ((num) >= (float4) PG_INT16_MIN && (num) < -((float4) PG_INT16_MIN)) +#define FLOAT4_FITS_IN_INT32(num) \ + ((num) >= (float4) PG_INT32_MIN && (num) < -((float4) PG_INT32_MIN)) +#define FLOAT4_FITS_IN_INT64(num) \ + ((num) >= (float4) PG_INT64_MIN && (num) < -((float4) PG_INT64_MIN)) +#define FLOAT8_FITS_IN_INT16(num) \ + ((num) >= (float8) PG_INT16_MIN && (num) < -((float8) PG_INT16_MIN)) +#define FLOAT8_FITS_IN_INT32(num) \ + ((num) >= (float8) PG_INT32_MIN && (num) < -((float8) PG_INT32_MIN)) +#define FLOAT8_FITS_IN_INT64(num) \ + ((num) >= (float8) PG_INT64_MIN && (num) < -((float8) PG_INT64_MIN)) + + +/* ---------------------------------------------------------------- + * Section 8: random stuff + * ---------------------------------------------------------------- + */ + +/* + * Invert the sign of a qsort-style comparison result, ie, exchange negative + * and positive integer values, being careful not to get the wrong answer + * for INT_MIN. The argument should be an integral variable. + */ +#define INVERT_COMPARE_RESULT(var) \ + ((var) = ((var) < 0) ? 1 : -(var)) + +/* + * Use this, not "char buf[BLCKSZ]", to declare a field or local variable + * holding a page buffer, if that page might be accessed as a page. Otherwise + * the variable might be under-aligned, causing problems on alignment-picky + * hardware. We include both "double" and "int64" in the union to ensure that + * the compiler knows the value must be MAXALIGN'ed (cf. configure's + * computation of MAXIMUM_ALIGNOF). + */ +typedef union PGAlignedBlock +{ + char data[BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGAlignedBlock; + +/* + * Use this to declare a field or local variable holding a page buffer, if that + * page might be accessed as a page or passed to an SMgr I/O function. If + * allocating using the MemoryContext API, the aligned allocation functions + * should be used with PG_IO_ALIGN_SIZE. This alignment may be more efficient + * for I/O in general, but may be strictly required on some platforms when + * using direct I/O. + */ +typedef union PGIOAlignedBlock +{ +#ifdef pg_attribute_aligned + pg_attribute_aligned(PG_IO_ALIGN_SIZE) +#endif + char data[BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGIOAlignedBlock; + +/* Same, but for an XLOG_BLCKSZ-sized buffer */ +typedef union PGAlignedXLogBlock +{ +#ifdef pg_attribute_aligned + pg_attribute_aligned(PG_IO_ALIGN_SIZE) +#endif + char data[XLOG_BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGAlignedXLogBlock; + +/* msb for char */ +#define HIGHBIT (0x80) +#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT) + +/* + * Support macros for escaping strings. escape_backslash should be true + * if generating a non-standard-conforming string. Prefixing a string + * with ESCAPE_STRING_SYNTAX guarantees it is non-standard-conforming. + * Beware of multiple evaluation of the "ch" argument! + */ +#define SQL_STR_DOUBLE(ch, escape_backslash) \ + ((ch) == '\'' || ((ch) == '\\' && (escape_backslash))) + +#define ESCAPE_STRING_SYNTAX 'E' + + +#define STATUS_OK (0) +#define STATUS_ERROR (-1) +#define STATUS_EOF (-2) + +/* + * gettext support + */ + +#ifndef ENABLE_NLS +/* stuff we'd otherwise get from */ +#define gettext(x) (x) +#define dgettext(d,x) (x) +#define ngettext(s,p,n) ((n) == 1 ? (s) : (p)) +#define dngettext(d,s,p,n) ((n) == 1 ? (s) : (p)) +#endif + +#define _(x) gettext(x) + +/* + * Use this to mark string constants as needing translation at some later + * time, rather than immediately. This is useful for cases where you need + * access to the original string and translated string, and for cases where + * immediate translation is not possible, like when initializing global + * variables. + * + * https://www.gnu.org/software/gettext/manual/html_node/Special-cases.html + */ +#define gettext_noop(x) (x) + +/* + * To better support parallel installations of major PostgreSQL + * versions as well as parallel installations of major library soname + * versions, we mangle the gettext domain name by appending those + * version numbers. The coding rule ought to be that wherever the + * domain name is mentioned as a literal, it must be wrapped into + * PG_TEXTDOMAIN(). The macros below do not work on non-literals; but + * that is somewhat intentional because it avoids having to worry + * about multiple states of premangling and postmangling as the values + * are being passed around. + * + * Make sure this matches the installation rules in nls-global.mk. + */ +#ifdef SO_MAJOR_VERSION +#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION) +#else +#define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) +#endif + +/* + * Macro that allows to cast constness and volatile away from an expression, but doesn't + * allow changing the underlying type. Enforcement of the latter + * currently only works for gcc like compilers. + * + * Please note IT IS NOT SAFE to cast constness away if the result will ever + * be modified (it would be undefined behaviour). Doing so anyway can cause + * compiler misoptimizations or runtime crashes (modifying readonly memory). + * It is only safe to use when the result will not be modified, but API + * design or language restrictions prevent you from declaring that + * (e.g. because a function returns both const and non-const variables). + * + * Note that this only works in function scope, not for global variables (it'd + * be nice, but not trivial, to improve that). + */ +#if defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P) +#define unconstify(underlying_type, expr) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), const underlying_type), \ + "wrong cast"), \ + (underlying_type) (expr)) +#define unvolatize(underlying_type, expr) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), volatile underlying_type), \ + "wrong cast"), \ + (underlying_type) (expr)) +#else +#define unconstify(underlying_type, expr) \ + ((underlying_type) (expr)) +#define unvolatize(underlying_type, expr) \ + ((underlying_type) (expr)) +#endif + +/* ---------------------------------------------------------------- + * Section 9: system-specific hacks + * + * This should be limited to things that absolutely have to be + * included in every source file. The port-specific header file + * is usually a better place for this sort of thing. + * ---------------------------------------------------------------- + */ + +/* + * NOTE: this is also used for opening text files. + * WIN32 treats Control-Z as EOF in files opened in text mode. + * Therefore, we open files in binary mode on Win32 so we can read + * literal control-Z. The other affect is that we see CRLF, but + * that is OK because we can already handle those cleanly. + */ +#if defined(WIN32) || defined(__CYGWIN__) +#define PG_BINARY O_BINARY +#define PG_BINARY_A "ab" +#define PG_BINARY_R "rb" +#define PG_BINARY_W "wb" +#else +#define PG_BINARY 0 +#define PG_BINARY_A "a" +#define PG_BINARY_R "r" +#define PG_BINARY_W "w" +#endif + +/* + * Provide prototypes for routines not present in a particular machine's + * standard C library. + */ + +#if !HAVE_DECL_FDATASYNC +extern int fdatasync(int fildes); +#endif + +/* + * Thin wrappers that convert strings to exactly 64-bit integers, matching our + * definition of int64. (For the naming, compare that POSIX has + * strtoimax()/strtoumax() which return intmax_t/uintmax_t.) + */ +#ifdef HAVE_LONG_INT_64 +#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base)) +#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base)) +#else +#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base)) +#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base)) +#endif + +/* + * Similarly, wrappers around labs()/llabs() matching our int64. + */ +#ifdef HAVE_LONG_INT_64 +#define i64abs(i) labs(i) +#else +#define i64abs(i) llabs(i) +#endif + +/* + * Use "extern PGDLLIMPORT ..." to declare variables that are defined + * in the core backend and need to be accessible by loadable modules. + * No special marking is required on most ports. + */ +#ifndef PGDLLIMPORT +#define PGDLLIMPORT +#endif + +/* + * Use "extern PGDLLEXPORT ..." to declare functions that are defined in + * loadable modules and need to be callable by the core backend or other + * loadable modules. + * If the compiler knows __attribute__((visibility("*"))), we use that, + * unless we already have a platform-specific definition. Otherwise, + * no special marking is required. + */ +#ifndef PGDLLEXPORT +#ifdef HAVE_VISIBILITY_ATTRIBUTE +#define PGDLLEXPORT __attribute__((visibility("default"))) +#else +#define PGDLLEXPORT +#endif +#endif + +/* + * The following is used as the arg list for signal handlers. Any ports + * that take something other than an int argument should override this in + * their pg_config_os.h file. Note that variable names are required + * because it is used in both the prototypes as well as the definitions. + * Note also the long name. We expect that this won't collide with + * other names causing compiler warnings. + */ + +#ifndef SIGNAL_ARGS +#define SIGNAL_ARGS int postgres_signal_arg +#endif + +/* + * When there is no sigsetjmp, its functionality is provided by plain + * setjmp. We now support the case only on Windows. However, it seems + * that MinGW-64 has some longstanding issues in its setjmp support, + * so on that toolchain we cheat and use gcc's builtins. + */ +#ifdef WIN32 +#ifdef __MINGW64__ +typedef intptr_t sigjmp_buf[5]; +#define sigsetjmp(x,y) __builtin_setjmp(x) +#define siglongjmp __builtin_longjmp +#else /* !__MINGW64__ */ +#define sigjmp_buf jmp_buf +#define sigsetjmp(x,y) setjmp(x) +#define siglongjmp longjmp +#endif /* __MINGW64__ */ +#endif /* WIN32 */ + +/* /port compatibility functions */ +#include "port.h" + +#endif /* C_H */ diff --git a/install/include/postgresql/server/catalog/binary_upgrade.h b/install/include/postgresql/server/catalog/binary_upgrade.h new file mode 100644 index 00000000000..82a9125ba9c --- /dev/null +++ b/install/include/postgresql/server/catalog/binary_upgrade.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * binary_upgrade.h + * variables used for binary upgrades + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/binary_upgrade.h + * + *------------------------------------------------------------------------- + */ +#ifndef BINARY_UPGRADE_H +#define BINARY_UPGRADE_H + +#include "common/relpath.h" + +extern PGDLLIMPORT Oid binary_upgrade_next_pg_tablespace_oid; + +extern PGDLLIMPORT Oid binary_upgrade_next_pg_type_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_array_pg_type_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_mrng_pg_type_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_mrng_array_pg_type_oid; + +extern PGDLLIMPORT Oid binary_upgrade_next_heap_pg_class_oid; +extern PGDLLIMPORT RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber; +extern PGDLLIMPORT Oid binary_upgrade_next_index_pg_class_oid; +extern PGDLLIMPORT RelFileNumber binary_upgrade_next_index_pg_class_relfilenumber; +extern PGDLLIMPORT Oid binary_upgrade_next_toast_pg_class_oid; +extern PGDLLIMPORT RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber; + +extern PGDLLIMPORT Oid binary_upgrade_next_pg_enum_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_pg_authid_oid; + +extern PGDLLIMPORT bool binary_upgrade_record_init_privs; + +#endif /* BINARY_UPGRADE_H */ diff --git a/install/include/postgresql/server/catalog/catalog.h b/install/include/postgresql/server/catalog/catalog.h new file mode 100644 index 00000000000..7ee8914be19 --- /dev/null +++ b/install/include/postgresql/server/catalog/catalog.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * catalog.h + * prototypes for functions in backend/catalog/catalog.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/catalog.h + * + *------------------------------------------------------------------------- + */ +#ifndef CATALOG_H +#define CATALOG_H + +#include "catalog/pg_class.h" +#include "utils/relcache.h" + + +extern bool IsSystemRelation(Relation relation); +extern bool IsToastRelation(Relation relation); +extern bool IsCatalogRelation(Relation relation); +extern bool IsInplaceUpdateRelation(Relation relation); + +extern bool IsSystemClass(Oid relid, Form_pg_class reltuple); +extern bool IsToastClass(Form_pg_class reltuple); + +extern bool IsCatalogRelationOid(Oid relid); +extern bool IsInplaceUpdateOid(Oid relid); + +extern bool IsCatalogNamespace(Oid namespaceId); +extern bool IsToastNamespace(Oid namespaceId); + +extern bool IsReservedName(const char *name); + +extern bool IsSharedRelation(Oid relationId); + +extern bool IsPinnedObject(Oid classId, Oid objectId); + +extern Oid GetNewOidWithIndex(Relation relation, Oid indexId, + AttrNumber oidcolumn); +extern RelFileNumber GetNewRelFileNumber(Oid reltablespace, + Relation pg_class, + char relpersistence); + +#endif /* CATALOG_H */ diff --git a/install/include/postgresql/server/catalog/catversion.h b/install/include/postgresql/server/catalog/catversion.h new file mode 100644 index 00000000000..2f59eab8b83 --- /dev/null +++ b/install/include/postgresql/server/catalog/catversion.h @@ -0,0 +1,679 @@ +/*------------------------------------------------------------------------- + * + * catversion.h + * "Catalog version number" for PostgreSQL. + * + * The catalog version number is used to flag incompatible changes in + * the PostgreSQL system catalogs. Whenever anyone changes the format of + * a system catalog relation, or adds, deletes, or modifies standard + * catalog entries in such a way that an updated backend wouldn't work + * with an old database (or vice versa), the catalog version number + * should be changed. The version number stored in pg_control by initdb + * is checked against the version number compiled into the backend at + * startup time, so that a backend can refuse to run in an incompatible + * database. + * + * The point of this feature is to provide a finer grain of compatibility + * checking than is possible from looking at the major version number + * stored in PG_VERSION. It shouldn't matter to end users, but during + * development cycles we usually make quite a few incompatible changes + * to the contents of the system catalogs, and we don't want to bump the + * major version number for each one. What we can do instead is bump + * this internal version number. This should save some grief for + * developers who might otherwise waste time tracking down "bugs" that + * are really just code-vs-database incompatibilities. + * + * The rule for developers is: if you commit a change that requires + * an initdb, you should update the catalog version number (as well as + * notifying the pgsql-hackers mailing list, which has been the + * informal practice for a long time). + * + * The catalog version number is placed here since modifying files in + * include/catalog is the most common kind of initdb-forcing change. + * But it could be used to protect any kind of incompatible change in + * database contents or layout, such as altering tuple headers. + * Another common reason for a catversion update is a change in parsetree + * external representation, since serialized parsetrees appear in stored + * rules and new-style SQL functions. Almost any change in primnodes.h or + * parsenodes.h will warrant a catversion update. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/catversion.h + * + *------------------------------------------------------------------------- + */ +#ifndef CATVERSION_H +#define CATVERSION_H + +/* + * We could use anything we wanted for version numbers, but I recommend + * following the "YYYYMMDDN" style often used for DNS zone serial numbers. + * YYYYMMDD are the date of the change, and N is the number of the change + * on that day. (Hopefully we'll never commit ten independent sets of + * catalog changes on the same day...) + */ + +/* yyyymmddN */ +/* PGRAC: bumped from PG 202307071. */ +/* - 202604270: cluster_get_wait_events SRF + pg_stat_cluster_wait_events */ +/* view (spec-0.16, stage 0.16). */ +/* - 202604271: cluster_get_gcluster_wait_events SRF + */ +/* pg_stat_gcluster_wait_events view (spec-0.17, stage 0.17). */ +/* - 202604280: cluster_get_nodes SRF + pg_cluster_nodes view */ +/* (spec-0.19, stage 0.19). */ +/* - 202604290: cluster_ic_mock_* test SRFs (spec-0.26, stage 0.26). */ +/* - 202604300: cluster_inject_fault + cluster_get_injection_state SRFs */ +/* + pg_stat_cluster_injections view (spec-0.27, stage 0.27). */ +/* - 202604310: cluster_get_stat_nodes + cluster_get_pgstat_counters SRFs */ +/* + pg_stat_cluster_nodes + pg_stat_cluster_counters views */ +/* (spec-0.28, stage 0.28). */ +/* - 202604320: cluster_dump_state SRF + pg_cluster_state view */ +/* (spec-0.29, stage 0.29). */ +/* - 202605010: cluster.shared_storage_backend GUC + 5 cluster_shared_fs */ +/* wait events (no new SRF; pg_cluster_state extended with */ +/* a shared_fs category) (spec-1.1, stage 1.1). */ +/* - 202605020: cluster_smgr bridge + cluster.smgr_user_relations GUC + */ +/* smgrsw[] extended to 2 entries + 3 cluster-smgr-* */ +/* injection points + pg_cluster_state shared_fs / guc */ +/* extended (spec-1.2, stage 1.2; 方案 C 单文件). */ +/* - 202605030: cluster shmem region registry + cluster_shmem_dump_regions */ +/* SRF (OID 8910) + pg_cluster_shmem view + */ +/* cluster.shmem_max_regions GUC + 4 cluster-shmem-* */ +/* injection points + pg_cluster_state.shmem extended with */ +/* region..* keys (spec-1.3, stage 1.3; registry */ +/* replaces hard-coded dispatch from spec-0.14). */ +/* - 202605040: cluster block format change: PageHeaderData +8B */ +/* pd_block_scn + PG_PAGE_LAYOUT_VERSION 4 -> 5 + */ +/* cluster_scn.h SCN typedef stub + pg_cluster_state.shmem */ +/* + block_format category 4 keys (spec-1.4, stage 1.4; */ +/* binary not compatible with vanilla PG 16; pgrac 1.3 */ +/* data must be dump+restore migrated to 1.4+). */ +/* - 202605050: cluster ITL slot array (stage 1.5): heap PageHeader */ +/* +384B ITL slot array (INITRANS=8 × 48B/slot) via */ +/* PageInitHeapPage + HeapTupleHeader +1B t_itl_slot_idx */ +/* + cluster_itl_slot.h ClusterItlSlotData typedef stub + */ +/* pd_flags PD_HAS_ITL bit (0x0008) + MaxHeapTupleSize */ +/* reduced 8152 -> 7768 + pg_cluster_state.block_format */ +/* extended 4 -> 9 keys (spec-1.5, stage 1.5; pgrac 1.4 */ +/* data must be dump+restore migrated to 1.5+). */ +/* */ +/* Stage 1.6 (BufferDesc cluster fields, BUFFERDESC_PAD_TO_SIZE 64->128, */ +/* cluster_buffer_desc.h, ClusterInitBufferDescFields, pg_cluster_state. */ +/* buffer_format category) does NOT bump catversion: it changes only */ +/* in-memory shared structures (BufferDescriptors array recreated on */ +/* every start) + a SRF return shape (new keys in existing function). */ +/* No on-disk format change (PageHeader / HeapTupleHeader / ITL / */ +/* catalog schema all unchanged), so 1.5 data dirs start cleanly under */ +/* 1.6+ binary. The catversion bump in initial 1.6 commit was reverted */ +/* by spec-stage1-codex-fixes Deliverable 6 (codex review 2026-05-02). */ +/* */ +/* Stage 1.6.1 hardening (spec-stage1-codex-fixes, codex review fixes): */ +/* Stage 1.5 t_itl_slot_idx WAL/MinimalTuple/expand_tuple coverage + */ +/* HeapPageUsableBytes capacity macro + Stage 1.6 AssertNotCatalogBuffer */ +/* Lock pcm_lock guard + LWTRANCHE_BUFFER_PCM_LOCK + "cache line" -> */ +/* "64B BufferDesc segment" terminology + pgrac-acceptance numbers */ +/* upgrade. All hardening fixes are runtime/inline level; no on-disk */ +/* format change. catversion stays at 202605050. */ +/* Stage 1.15: bump for cluster_scn_advance / current / observe SQL */ +/* UDFs (3 new pg_proc entries OID 8911-8913); spec-1.15 Q7+Q10+L1. */ +/* Stage 1.15.1 (round 8 P3): cluster_scn_current pg_proc.dat */ +/* provolatile s -> v + proparallel s -> r (it reads dynamically- */ +/* mutating shmem state). Catalog row attribute change => bump. */ +/* Stage 1.18: commit/abort WAL records carry an optional 8-byte */ +/* xl_xact_scn sub-record (spec-1.18, XACT_XINFO_HAS_SCN bit 9). */ +/* WAL record format is on-disk format -> bump. Old data dirs cannot */ +/* cross-replay 1.17->1.18 because parsers diverge; CATALOG_VERSION_NO */ +/* mismatch is the gate that makes pg_control reject mixed binaries. */ +/* Spec: spec-1.18-wal-record-xl-scn.md Q2 ★. */ +/* Stage 1.19: WAL Page Header xlp_thread_id + xlp_cluster_flags */ +/* placeholder fields reuse the existing MAXALIGN tail padding so */ +/* sizeof(XLogPageHeaderData) stays 24 bytes (StaticAssertDecl in */ +/* xlog_internal.h). vanilla PG MemSet's the entire 8 KB page before */ +/* writing fields (xlog.c:1878 + xlog.c:4685 + pg_resetwal.c:1059) so */ +/* pre-1.19 datadirs land both fields as 0 (= XLP_THREAD_ID_LEGACY + */ +/* XLP_CLUSTER_FLAGS_RESERVED) automatically. No on-disk format */ +/* change -> NO catversion bump (Q1=A approve). Spec: */ +/* spec-1.19-wal-page-header-thread-id.md APPROVED v0.2. */ +/* Stage 1.20: TTSlot type definition only (cluster_tt_slot.h NEW; 32 */ +/* byte struct + sentinel constants + StaticAssertDecl + inline */ +/* helpers). No on-disk artefact in Stage 1.20. Therefore: NO */ +/* catversion bump. Spec: spec-1.20-tt-slot-data-structure.md v0.2. */ +/* Stage 1.21: UndoSegmentHeaderData type definition only */ +/* (cluster_undo_segment.h NEW; 8192 byte struct + segment_state */ +/* enum + sentinels + StaticAssertDecl + inline helpers). No on- */ +/* disk artefact in Stage 1.21: undo tablespace and segment files */ +/* are created by spec-1.22 (atomic with PageInitUndoSegmentHeader */ +/* caller and PD_UNDO_SEG_HEADER bufpage.h definition). Therefore: */ +/* NO catversion bump. Spec: spec-1.21-undo-segment-header.md v0.2. */ +/* Stage 1.22: dedicated undo tablespace + atomic batch on-disk */ +/* format change. Bundles 7 atomic changes in a single commit, */ +/* any one of which would individually require a catversion bump: */ +/* 1. UNDOTABLESPACE_OID = 9100 added to pg_tablespace.dat (v0.2 */ +/* Hardening v1.0.2 amend: original 1665 conflicted with */ +/* pg_get_serial_sequence in pg_proc.dat; fallback to 9100 per */ +/* spec §6 R2). */ +/* 2. $PGDATA/pg_undo/instance_/seg_.dat layout established */ +/* at initdb time (subdirs[] += "pg_undo", "pg_undo/instance_0"). */ +/* 3. PD_UNDO_SEG_HEADER = 0x0010 added to bufpage.h pd_flags + */ +/* PD_VALID_FLAG_BITS bumped 0x000F -> 0x001F (cluster mode). */ +/* 4. PageInitUndoSegmentHeader() shipped (bufpage.c) + initdb seed */ +/* segment writer (initdb.c) -- both call shared frontend-safe */ +/* helper cluster_undo_segment_make_header_bytes (D14c). */ +/* 5. UndoSegmentHeaderData on-disk format (block 0 of every */ +/* seg_.dat) materialized -- spec-1.21 placeholder type now */ +/* written for real. */ +/* 6. RM_CLUSTER_UNDO_ID resource manager registered in rmgrlist.h */ +/* with one subtype XLOG_UNDO_SEGMENT_INIT (D14a B-lite; XLOG_FPI */ +/* was rejected per v0.2 P1-A because RelFileLocator routing */ +/* can't address $PGDATA/pg_undo paths). */ +/* 7. user-visible tablespace helpers special-case UNDOTABLESPACE_OID */ +/* (misc.c pg_tablespace_location + pg_tablespace_databases; */ +/* tablespace.c Alter*TableSpace* reject; D14b v0.2 P1-C 联动). */ +/* Stage 1.21 datadir cannot be opened by 1.22 binary (FATAL via */ +/* pg_control catversion check) and vice versa; users must dump+ */ +/* restore (pg_upgrade 1.21->1.22 lands in feature-117). */ +/* Spec: spec-1.22-undo-tablespace-bootstrap.md APPROVED v0.2. */ +/* + * spec-2.2 D10 (2026-05-07) -- bump 202605190 -> 202605200 for the + * pg_cluster_ic_peers SRF + view (D9) addition to pg_proc.dat + + * system_views.sql. Per L46 (atomic batch + catversion bump): + * downstream TAP / regress hardcoded catversion regex MUST be + * lower-bound (>= 202605200) not equal-bound; see grep audit in + * spec-2.2 §6 DoD. + * + * spec-2.3 D7 (2026-05-08) -- bump 202605200 -> 202605210 for the + * pg_cluster_ic_msg_types SRF + view (D8) addition to pg_proc.dat + + * system_views.sql, plus the wire-protocol pivot from spec-2.2 + * 24-byte ClusterMsgHeader to spec-2.3 36-byte ClusterICEnvelope + * (incompatible WAL/IC bytes -> datadir from a 202605200 binary + * cannot be opened by a 202605210 binary and vice versa). Per + * L46: downstream TAP / regress hardcoded catversion regex MUST + * remain lower-bound (>= 202605210) not equal-bound; see grep + * audit in spec-2.3 §7 DoD. + */ +/* + * spec-2.4 D7 (2026-05-08) -- bump 202605210 -> 202605220 for + * pg_cluster_ic_peers SRF/view extension to 23 columns + * (+ stale_epoch_drop_count + chunk_reassembly_active + + * chunk_reassembly_timeout_count + lamport_observe_advance_count) + + * 5 NEW PGC_POSTMASTER GUCs (interconnect_payload_max_bytes + + * chunk_reassembly_timeout_ms + tcp_keepidle_sec / keepintvl_sec / + * keepcnt) + 2 NEW SQLSTATE (53R20 + 53R21). Per L46:downstream + * TAP / regress hardcoded catversion regex MUST remain lower-bound + * (>= 202605220) not equal-bound;see grep audit in spec-2.4 §7 + * DoD. + */ +/* + * spec-2.6 D16 (2026-05-09) -- bump 202605230 -> 202605240 for Step 4 + * D15 NEW 2 SRFs (cluster_get_quorum_state OID 8917 + + * cluster_get_voting_disks OID 8918) + 2 views (pg_cluster_quorum_state + * + pg_cluster_voting_disks) + 4 NEW PGC_POSTMASTER GUCs + * (cluster.voting_disks + quorum_poll_interval_ms + + * voting_disk_io_timeout_ms + voting_disk_size_bytes) + 4 NEW SQLSTATE + * (53R40 ERRCODE_CLUSTER_QUORUM_LOST + 53R41 + 53R42 + 53R43) + 3 NEW + * wait events (BgProcQvotecMainLoop + VotingDiskRead/Write) + 5 NEW + * inject points + 4 NEW pgstat counters. Per L46 lower-bound regex + * convention. + */ +/* + * 202605250: spec-2.28 Sprint A Step 4 (fence-lite catalog surface) — + * 1 NEW SQLSTATE 53R50 ERRCODE_CLUSTER_QUORUM_LOST_BACKEND, 1 NEW wait + * event WAIT_EVENT_CLUSTER_FENCE_BACKEND_INTERRUPT_CHECK (60→61 → 64 + * spec-2.6 → 65 spec-2.28), 1 NEW SRF cluster_get_fence_state (oid + * 8919) + matching pg_cluster_fence_state view, 4 NEW pgstat counters + * (cluster.fence.{freeze_broadcast/thaw_broadcast/self_fence_initiated/ + * freeze_signal_received}_count), 3 NEW inject points (cluster-fence- + * pre-freeze-broadcast / -pre-self-fence-shutdown / -post-thaw-broadcast). + */ +/* + * spec-2.29 Sprint A Step 1 (2026-05-11): bump for catalog surface + * delta introduced by reconfig coordinator (internal-only A scope). + * + * Surface added across Sprint A: + * +1 SQLSTATE 53R60 ERRCODE_CLUSTER_RECONFIG_IN_PROGRESS (Step 3 D8) + * +1 wait event BgProcLmonReconfigTick (Step 3 D9) + * +1 shmem region "pgrac cluster reconfig" (Step 1 D2) + * +1 SRF pg_cluster_reconfig_state (oid 8920, 9 cols, Step 3 D5b/D6) + * +5 inject points (cluster-reconfig-*: tick-entry / decide-coord / + * epoch-bump-pre / broadcast-procsig-pre + cluster-cssd-mark-peer- + * dead for unit/inject tests) (Step 3 D10) + * +0 GUC (cssd_heartbeat_interval_ms from spec-2.5 reused) + * + * Step 1 bumps catversion as part of shmem region addition so that + * any catalog-aware tooling using CATALOG_VERSION_NO sees the spec- + * 2.29 surface from Sprint A inception;Steps 3-4 populate SRF / + * errcode / wait event / inject point catalog rows behind this + * already-bumped catversion. + */ +/* spec-2.14 D8 (2026-05-13): add cluster_get_grd_shards SRF + pg_cluster_grd_shards + * view + cluster_grd shmem region. catversion bump to invalidate any catalog- + * aware tooling caches when spec-2.14 GRD routing substrate lands. */ +/* spec-2.15 D9 (2026-05-13): add cluster_get_grd_entries SRF + pg_cluster_grd_entries + * view + cluster_grd entry HTAB + cluster.grd_max_entries GUC + named tranche + * ClusterGrdShard. catversion bump for catalog-aware tooling caches. */ +/* spec-2.17 D30 (2026-05-30): PGPROC.cluster_grd_generation uint64 + + * cluster_grd_bast_pending bool fields(P1.7 防 stale BAST/CANCEL); + * GesRequestOpcode 7 全集(NEW BAST=4/BAST_ACK=5/DEADLOCK_PROBE=6/ + * CANCEL_PENDING=7);PROCSIG_CLUSTER_GES_BAST + GES_CANCEL slot; + * 53R72/53R73 SQLSTATE;4 NEW wait events;7 NEW GUCs(BAST retry + + * deadlock budget). catversion bump for catalog tooling. */ +/* spec-2.19 D12 (2026-05-14): LMD daemon skeleton + deadlock-detection + * ownership migration from spec-2.17 caller-side placeholder. Adds + * pg_cluster_lmd view + cluster_get_lmd_state SRF (D11);3 NEW wait events + * (LMD_STARTUP/SCAN/IDLE);1 NEW GUC cluster.lmd_enabled PGC_POSTMASTER; + * 53R81 SQLSTATE cluster_lmd_unavailable;ClusterLmdShmem region + + * LWTRANCHE_CLUSTER_LMD;LmdProcess AuxProcType + NUM_AUXILIARY_PROCS + * 13 → 14. catversion bump for catalog tooling. */ +/* spec-2.27 D9 (2026-05-17): GES reliability hardening — master + * generation + retransmit + perpetual wait gated. GesRequestPayload wire + * ABI 48B -> 56B (NEW shard_master_generation field). NEW reserved + * opcode GES_REQ_OPCODE_PRIORITY_BOOST = 11 + GesPriorityBoostPayload 32B + * (RESERVED, NOT SENT — wire-with-stub-receiver反模式 enforcement L107 + * N+5). NEW shmem region 'pgrac cluster ges dedup' (LMS-owned dedup + * HTAB, key = 5-tuple {origin_node_id, opcode, request_id, cluster_epoch, + * shard_master_generation}). ClusterLmsNativeLockProbeSlot ABI 128B -> + * 256B (per-slot LWLockPadded spec-2.25 Hardening 候选 1 race fix). + * NEW 2 GUC cluster.ges_retransmit_max_attempts + cluster.ges_dedup_max_ + * entries + cluster.ges_request_timeout_ms range expand [-1, 600000] + * (perpetual wait gated, default 60000 不变). NEW LMS counter + * priority_starvation_observed_count + lms_restart_generation atomic. + * catversion bump for catalog tooling. */ +/* spec-2.30 D10 (2026-05-17): PCM 9-state machine activation — + * spec-1.7 PCM placeholder 4 stub bodies activated. GrdEntry struct + * file-private full layout (216B; BufferTag=20B PG 16.13 + atomic fields + * + LWLockPadded 128B; spec-2.30 §2.1 nominal 208B mismatch flagged for + * Hardening v1.0.1 F1 spec amend). NEW shmem region 'pgrac cluster pcm + * grd hdr' + HTAB 'pgrac cluster pcm grd htab' (was placeholder array in + * spec-1.7). NEW LWTRANCHE_CLUSTER_PCM (per-entry LWLockPadded HC57/HC61). + * 9 NEW transition counters (8 active + Trans-9 HC60永 0 until Stage 3). + * GUC cluster.pcm_grd_max_entries default 0 -> -1 sentinel (auto-resolve + * to NBuffers; 0 = explicit disable preserving spec-1.7 stub behavior; + * HC62 fail-closed FATAL on shortfall). 2 NEW wait events + * ClusterPcmGrdInit + ClusterPcmTransitionApply (CLUSTER_WAIT_EVENTS_COUNT + * 75 -> 77). cluster_pcm_lock_query 真 lookup (spec-1.7 always-N 行为 + * 撤销). catversion bump for catalog tooling. */ +/* spec-2.33 D11 (2026-05-19): Cache Fusion block-shipping data plane. + * NEW msg_type PGRAC_IC_MSG_GCS_BLOCK_REQUEST=14 + GCS_BLOCK_REPLY=15; + * NEW GcsBlockRequestPayload (64B) + GcsBlockReplyHeader (48B) + 8192B + * block_data; NEW GcsBlockReplyStatus 7-value enum (GRANTED + + * STORAGE_FALLBACK + 4 DENIED + MASTER_NOT_HOLDER); cluster_gcs_block + * shmem region + LWTRANCHE_CLUSTER_GCS_BLOCK; 8 NEW data-plane counters + * exposed via dump_gcs (14→22 rows); NEW GUC cluster.gcs_reply_timeout_ms + * (PGC_SUSET 5000ms); 4 NEW wait events + * (CLUSTER_WAIT_EVENTS_COUNT 79→83): ClusterGCSBlockShipWait + + * ClusterGCSBlockRequestDispatch + ClusterGCSBlockReplyDispatch + + * ClusterGCSBlockChecksumFail. cluster_pcm_lock_acquire_buffer NEW + * (BufferDesc-aware variant); tag-only cluster_pcm_lock_acquire fails + * closed on remote-master S/X with errhint. bufmgr cluster_bufmgr_ + * probe/copy_block_for_gcs helpers (HC82 XLogFlush(page_lsn) before ship + * + HC89 single-retry revalidation). catversion bump for catalog + * tooling. */ +/* spec-2.34 D11 (2026-05-19): GCS block reliability hardening. + * NEW GcsBlockReplyStatus value DENIED_DEDUP_FULL=7 (enum 7→8); + * NEW cluster_gcs_block_dedup shmem region (HTAB cap × 8312B fixed entry, + * default cap 1024 → 8.4MB per master node) + LWTRANCHE_CLUSTER_GCS_BLOCK_ + * DEDUP built-in tranche; 3 NEW GUC (cluster.gcs_block_retransmit_max_ + * retries PGC_SUSET 4 + ..._initial_backoff_ms PGC_SUSET 100 + ..._dedup_ + * max_entries PGC_POSTMASTER 1024); 2 NEW wait events + * (CLUSTER_WAIT_EVENTS_COUNT 83→85): ClusterGCSBlockRetransmitWait + + * ClusterGCSBlockEpochStaleRetry; 9 NEW data-plane reliability counters + * exposed via dump_gcs (22→31 rows): retransmit_attempt_count / + * retransmit_send_count / retransmit_exhausted_count / dedup_hit_count / + * dedup_miss_count / dedup_collision_count / dedup_full_count / + * epoch_invalidate_wake_count / stale_reply_drop_count; 1 NEW SQLSTATE + * 53R90 cluster_gcs_block_retransmit_exhausted; HC90-HC100 11 NEW. + * cluster_gcs_block_on_epoch_advance hook wired into spec-2.29 + * cluster_reconfig_apply_epoch_bump_as_coordinator after epoch + + * LSN stamp, before publish_event (HC95 ordering). 2 NEW inject + * points (cluster-gcs-block-drop-reply-before-send + + * cluster-gcs-block-force-epoch-stale-reply). catversion bump for + * catalog tooling. */ +/* spec-2.35 D14 (2026-05-19): Cache Fusion 2-way protocol S-to-S read sharing. + * NEW ClusterICMsgType PGRAC_IC_MSG_GCS_BLOCK_FORWARD=16 (master→holder); + * NEW GcsBlockReplyStatus value GRANTED_FROM_HOLDER=8 (enum 8→9); + * NEW GcsBlockForwardPayload struct 64B (HC102 wire ABI); + * GcsBlockReplyHeader.reserved_0[10] reserved 重解读 → forwarding_master_ + * node_bytes[4] + reserved_0[6] (HC109; sizeof 48B 不变 but semantic 变 → + * pg_upgrade catversion 强制 boundary; uses memcpy helpers to encode + * int32 little-endian and avoid struct padding alignment regression); + * NEW HC108 reply handler authorized chain validation (direct-from-master + * OR forwarded-by-expected-master with status in {GRANTED_FROM_HOLDER, + * DENIED_MASTER_NOT_HOLDER}); + * HC110 master_holder lifecycle real maintenance across 8 PCM transitions + * (was unset since spec-2.30); cluster_pcm_master_holder_node_by_tag + * helper exposed for master-side forward routing decision; + * HC111 s_holders_bitmap = "cache residency" 语义 (no longer transient + * content-lock holding; bit persists across UnlockBuffer for SCUR); + * HC112 bufmgr hook bifurcation: 撤 spec-2.31 D3 UnlockBuffer-triggered + * release; NEW cluster_pcm_lock_unlock_content_buffer no-op for SCUR + * (bit preserved) + delegate-to-eviction-release for XCUR; release + * hook moved to InvalidateBuffer + InvalidateVictimBuffer eviction + * paths (covers DropRelations*Buffers + DropDatabaseBuffers via + * InvalidateBuffer chain); rename cluster_pcm_lock_release_buffer → + * cluster_pcm_lock_release_buffer_for_eviction; + * HC113 dedup state machine extension: internal FORWARDED_IN_FLIGHT + * status via status==GRANTED_FROM_HOLDER on entry + holder_node stored + * in reply_header.sender_node; NEW GCS_BLOCK_DEDUP_FORWARDED_DUPLICATE + * return (distinct from CACHED_REPLY and IN_FLIGHT_DUPLICATE) so + * duplicate requests re-forward to holder instead of being silent- + * dropped; HC114 entry inspection must check status before treating + * as cached 8KB block; + * 7 NEW counters exposed via dump_gcs (31→38 rows): + * block_forward_sent_count / block_forward_received_count / + * block_from_holder_ship_count / block_forward_holder_evicted_count / + * s_holders_bitmap_redirect_count / master_holder_lifecycle_count / + * forward_replay_count; + * 0 NEW wait events (CLUSTER_WAIT_EVENTS_COUNT 保持 85; sender does not + * know forward path at sleep time so dedicated wait event would not + * be observable per Q-D11 rationale); + * 2 NEW inject points (cluster-gcs-block-forward-master-side + + * cluster-gcs-block-evict-holder-before-ship); + * HC101-HC114 14 NEW. catversion bump for catalog tooling + wire ABI + * reserved 重解读 + bufmgr hook 重构. */ +/* spec-2.36 D7 (2026-05-20): Cache Fusion 3-way protocol — X writer + * transfer + reader starvation guard. + * NEW ClusterICMsgType: PGRAC_IC_MSG_GCS_BLOCK_INVALIDATE=17 (master→ + * S/X holder invalidate request 64B) + PGRAC_IC_MSG_GCS_BLOCK_ + * INVALIDATE_ACK=18 (holder→master ack 64B); request+ack MUST be + * distinct msg_type because both are 64B fixed payload and IC + * dispatcher demuxes by msg_type only (codereview F1 P0). + * NEW GcsBlockReplyStatus values (8→11): X_GRANTED_FROM_HOLDER=9 + * (X-flavored holder direct ship for 3-way writer transfer; reuses + * spec-2.35 HC108 authorized chain) + DENIED_PENDING_X=10 (HC117 + * reader starvation guard transient deny + backoff retry) + + * DENIED_INVALIDATE_TIMEOUT=11 (master invalidate ack budget + * exhausted; sender maps to 53R91). + * NEW GcsBlockInvalidatePayload 64B + GcsBlockInvalidateAckPayload + * 64B (HC83 CRC32C @ offset 48; identical layout offsets for + * symmetric header parsing). + * GrdEntry layout extends 232→248 (+16B): new pending_x_requester_ + * node int32 (-1 = none) + pending_x_reserved int32 pad + + * pending_x_since_lsn uint64 (HC117 observability; LSN avoids clock + * drift, idle DB acceptable per Q7). + * NEW HC115 master decision tree X-state path + HC116 broadcast + * invalidate sync ack + HC117 S barrier reader starvation guard + + * HC118 X transfer holder direct ship + HC120 dedup INVALIDATE_IN_ + * FLIGHT state + HC121 ClusterTriple 3-node TAP fixture + HC123 + * XLogFlush-before-X-transfer invariant + HC124 node-dead pending_x + * sweep correctness contract. + * NEW cluster_bufmgr_invalidate_block_for_gcs(tag, expected_mode, + * *out_lsn) bufmgr internal helper (InvalidateBuffer is PG static, + * must wrap in bufmgr.c; mirrors spec-2.35 HC112 release_buffer_ + * for_eviction pattern). + * 3 NEW GUC: cluster.gcs_block_invalidate_ack_timeout_ms PGC_SUSET + * 1500 + cluster.gcs_block_starvation_backoff_ms PGC_SUSET 100 + + * cluster.gcs_block_starvation_max_retries PGC_SUSET 8. + * 2 NEW SQLSTATE: 53R91 cluster_gcs_block_invalidate_timeout + + * 53R92 cluster_gcs_block_starvation_exhausted. + * 3 NEW wait events (CLUSTER_WAIT_EVENTS_COUNT 85→88): + * ClusterGCSBlockInvalidateBroadcast + ClusterGCSBlockInvalidate + * AckWait + ClusterGCSBlockStarvationRetry. + * 6 NEW counters exposed via dump_gcs (31→37 rows): + * block_invalidate_broadcast_count / block_invalidate_ack_received_ + * count / block_invalidate_timeout_count / block_x_forward_sent_ + * count / block_x_granted_from_holder_count / starvation_denied_ + * pending_x_count. + * 4 NEW inject points (106→110): cluster-gcs-block-invalidate-drop- + * broadcast + cluster-gcs-block-invalidate-stall-ack + cluster-gcs- + * block-x-forward-master-side + cluster-gcs-block-starvation-force- + * denied. catversion bump for catalog tooling + wire ABI extension + * + GrdEntry sizeof bump. */ +/* spec-2.37 D10 (2026-05-20): PI simplified + lost-write detection + * (page_lsn watermark MVP). + * NEW GcsBlockReplyStatus value DENIED_LOST_WRITE=12 (enum 11→12); + * master direct ship 自校 失败 OR holder forward validate 失败 + * 都映射到这个 status,sender 走 HC131 terminal 53R93. + * GrdEntry layout extends 248→256 (+8B): new pi_watermark_lsn uint64 + * (InvalidXLogRecPtr=0 默认;single max-historical 模型 cover lost- + * write detection;Path X MVP 用 page_lsn 而非 pd_block_scn,后者 + * 真写入留独立 spec). Inserted between pending_x_since_lsn and + * wait_cv/entry_lock to keep LWLockPadded must-stay-last invariant. + * GcsBlockForwardPayload reserved_0[15] 重解读 (sizeof 64B 不变): + * first 8B 重解读为 expected_pi_watermark_lsn_bytes[8] at offset 49 + * (little-endian uint64);剩余 7B 保留 reserved_0[7]. Same HC109 + * pattern as spec-2.35 forwarding_master_node_bytes[4]. + * NEW HC125 (page_lsn = PI watermark MVP) + HC126 (single field max- + * historical) + HC127 (forward path 携 expected) + HC128 (holder/ + * master validate before ship) + HC129 (DENIED_LOST_WRITE status) + + * HC130 (retire only by tag lifecycle + storage durable-confirm, + * forbidden by epoch advance) + HC131 (sender 仅映射 SQLSTATE). + * 0 NEW wait events (CLUSTER_WAIT_EVENTS_COUNT 保持 88; lost-write + * check 是非阻塞 uint64 比较,不是 waiting state). + * 1 NEW GUC: cluster.gcs_block_lost_write_action enum {error,warn} + * default error; warn 仅 staging/diagnostic 用,production 必须 error. + * 1 NEW SQLSTATE: 53R93 cluster_lost_write_detected. + * 4 NEW counters exposed via dump_gcs (44→48 rows): + * pi_watermark_advance_count / pi_watermark_retire_count / + * lost_write_detected_count / lost_write_avoid_count. + * 2 NEW inject points (110→112): cluster-gcs-block-stale-ship + * (master direct ship 强制 page_lsn=0 模拟 stale source) + + * cluster-gcs-block-force-pi-watermark (master 端强制 high pi_ + * watermark 用于 negative TAP). + * catversion bump for catalog tooling + wire ABI reserved 重解读 + + * GrdEntry sizeof bump + reply status extension. */ +/* spec-2.38 D7 (2026-05-20): SI Broadcaster skeleton — 真激活 + * PGRAC_IC_MSG_SINVAL=7 wire msg type + B_SINVAL_BCAST aux process + + * LMON-mediated outbound fanout + 3 wait events (all 占位至 + * spec-2.38 起 wire-up real). + * NEW SinvalBroadcastHeader 24B fixed prefix + variable-length + * N × SharedInvalidationMessage (16B each, HC137 PG ABI 锁) tail; + * envelope.payload_length = 24 + 16 * nmsgs. + * NEW 2 shmem regions: ClusterSinvalOutbound + ClusterSinvalInbound + * (ring buffer + LWLockPadded; capacity = cluster.sinval_broadcast_ + * max_queue_size default 1024). + * NEW AuxProcType SinvalBcastProcess (inbound apply/reset owner; + * AuxiliaryProcessMain dispatch; postmaster Phase 4 spawn). + * NEW public API cluster_sinval_enqueue_batch() — only outbound entry + * point; returns bool (HC134 fail-closed,禁 silent drop). + * NEW IC handler cluster_sinval_handle_envelope — checksum L164 + epoch + * HC100 + source_node HC135 三层校验 + nonblocking try-enqueue + * (LWLockConditionalAcquire only) + SetLatch; inbound full → set + * inbound_overflow_reset_pending flag,SI Broadcaster aux proc 执行 + * SIResetAll() fail-safe. + * NEW HC132 outbound queue 独立(防 echo loop;唯一硬防线)+ HC133 IC + * handler nonblocking 约束 + HC134 fail-closed/fail-safe + HC135 + * source_node 辅助 echo defense + HC136 main loop drain pattern + + * HC137 SharedInvalidationMessage sizeof 锁 + HC138 wire ABI variable- + * length tail + HC139 producer mask/AuxProcType 双注册. + * NEW 3 GUC: cluster.sinval_broadcast_batch_size PGC_POSTMASTER 32 + * (1..CLUSTER_SINVAL_BATCH_MAX check hook) + cluster.sinval_broadcast_ + * batch_timeout_ms PGC_SIGHUP 10 + cluster.sinval_broadcast_max_queue_ + * size PGC_POSTMASTER 1024. + * NEW 1 SQLSTATE: 53R94 cluster_sinval_queue_full (caller of + * cluster_sinval_enqueue_batch maps to this on false return). + * NEW dump_sinval category +9 counter rows. + * NEW 2 inject points (110→112): cluster-sinval-broadcast-drop-send + + * cluster-sinval-receive-skip-validate. + * catversion bump for catalog tooling + wire ABI msg_type 7 真激活 + + * 2 shmem regions + new aux process boundary. */ +/* spec-3.2 hardening (2026-05-22): add test-only + * cluster_test_inject_visibility_tt_ref / cluster_test_clear_visibility_injects + * pg_proc rows so TAP can drive a real HeapTupleSatisfiesMVCC cluster-path + * miss and assert 53R97. Production builds link FEATURE_NOT_SUPPORTED + * stubs; --enable-injection-points builds wire the shmem implementation. */ +/* spec-3.3 D1 (2026-05-23): SnapshotData explicit 24B cluster tail + * (SCN read_scn + uint64 read_epoch + uint8 cluster_source + uint8 _pad[7]; + * spec-3.24 D1 repurposed one pad byte -> uint8 cluster_snapshot_session_local + * + uint8 _pad[6], same 24B tail, serialized payload unchanged). + * sizeof(SnapshotData) bump → catalog tooling that reads serialized snapshot + * payloads (snapbuild.c / pg_export_snapshot / parallel worker carry) must + * use the new layout. R4 P1 explicit layout + R9 P2 uint64 epoch (no + * uint32 wrap alias). See spec-3.3 §2.1 + D4 6-root ABI ripple audit. */ +/* spec-3.4b D6 + D3 (2026-05-24, F8/F9): ITL WAL ABI extends with v2 + * 40B delta (16B undo_segment_head) + xl_heap_itl_delta_block format_version + * field repurposed from _pad (legacy v1=0, v2=1). Legacy 24B parser retained + * for backward-compat replay. Additionally adds LWTRANCHE_CLUSTER_TT_SLOT + * tranche + per-node TT slot allocator shmem region. Catalog tooling that + * inspects heap WAL deltas or LWLock tranche names must use the new layout. */ +/* spec-3.4c D7 + D8 (2026-05-24, A1/F5): cluster_test_inject_visibility_tt_ref + * grows a 6th arg (commit_scn int8) so the inject UDF can synchronously install + * the TT status overlay entry (status=COMMITTED, commit_scn=) and verify + * via lookup_exact(). Without the 6-arg signature the inject path leaves the + * overlay empty -> lookup_exact miss -> 53R97 fail-closed even after a + * "successful" inject. Catalog tooling that introspects proargtypes / + * proargnames must use the new layout. Test-only UDF; production builds keep + * the FEATURE_NOT_SUPPORTED stub (same call shape). */ +/* spec-3.4d D8/D9 (2026-05-25, F2/F7): cluster_test_inject_visibility_tt_ref + * grows a 7th arg (is_lock_only bool) so the D5b inject UDF can install + * status=ACTIVE + commit_scn=InvalidScn for cross-node row lock tests (not + * just COMMITTED state from spec-3.4c). NEW 3 SQLSTATE 53R98 / 53R99 / 53R9A + * (cluster_remote_row_lock_wait_not_supported / cluster_multixact_lock_not_ + * supported / cluster_itl_slot_overflow); the latter does NOT reuse 53R94 + * sinval_queue_full per spec-3.4d F7. NEW 5 counter rows in dump_lock_path + * category (cluster_itl_overflow_lock_count, cluster_multixact_lock_reject_ + * count, cluster_remote_row_lock_fail_closed_count, cluster_lock_only_itl_ + * stamp_count, cluster_lock_only_tt_hint_emit_count). Tuple header NOT bumped + * (v0.1 t_lock_itl_slot_idx scheme rejected per F2 — raw_xmax + ITL slot scan + * derives lock-only ref without header growth, avoiding MAXALIGN tax + disk + * format break). Catalog tooling must use the new 7-arg layout. */ +/* + * 202605520 = 2026-05-27 spec-3.5 D11+D19: + * - NEW SQLSTATE 53R9B (ERRCODE_PREPARE_TRANSACTION_WITH_CLUSTER_SUBTRANS_STATE) + * - NEW pg_proc.dat entry oid=8927 cluster_test_inject_subtrans_subcommitted + * (TEST-ONLY SRF; --enable-injection-points wires real impl; production + * build emits FEATURE_NOT_SUPPORTED stub) + * - ClusterTTStatusResult struct extended with has_parent_key + parent_key + * (24B ClusterTTStatusKey; spec-3.5 D1) + * - TT_STATUS_HINT V3 wire ABI (64B; V2 0-39 byte-for-byte + parent_key + * appended @ offset 40; L203 progressive extend convention; spec-3.5 D3) + * - CLUSTER_TT_STATUS_SUBCOMMITTED = 5 enum value + * - cluster.subtrans_max_chain_depth NEW GUC + */ +/* + * 202605530 = 2026-05-27 spec-3.6 v0.3: + * - NEW SQLSTATE 53R9C (cluster_multixact_member_overlay_miss) + * - 3 NEW GUC (cluster.multixact_member_overlay_max_members / + * cluster.multixact_member_overlay_max_entries / + * cluster.multixact_hint_outbound_slots) + * - V4 sidecar wire variant (TT_STATUS_HINT msg_version=4; + * non-progressive — L204 NEW lesson family) + * - NEW page-format ITL flag ITL_FLAG_LOCK_ONLY_XMAX_IS_MULTI = 8 + * (lock-only ITL slot whose xid field stores MultiXactId for + * reader cluster origin marker; spec-3.6 D7b) + * - NEW shmem regions: cluster_multixact_member_overlay HTAB + + * ClusterMultiXactHintOutboundRing fixed-size queue (~4.1 MiB + * default with 1024 slots) + * + * 202605540: spec-3.7 D11 — Undo Record Format + Allocator runtime + * 真激活. NEW SQLSTATE 53R9D (cluster_undo_record_invalid_uba) + + * 3 NEW GUCs (undo_tablespace_path / undo_segment_size_mb / + * undo_record_inline_max_bytes; existing undo_segments_per_instance + * default 16 unchanged per Q9=A) + NEW shmem region + * ClusterUndoRecordShared (cursor state + 5 atomic counters + + * 1 LWLock tranche cluster_undo_record_cursor) + NEW page-format + * extension (UndoBlockHeader 40B + UndoSlotDirEntry 8B + UndoRecordHeader + * 64B per spec §2.1-2.2 + Hardening v1.0.1 H-1/H-2 arithmetic fix). + * PGRAC MODIFICATIONS in heapam.c heap_insert path (other 3 op + + * multi_insert deferred per Hardening v1.0.2 H-4/5/6/7). + */ +/* spec-3.8 Fix 6 (2026-05-29): cluster_undo_test_force_segment_end TEST-ONLY + * SQL function (oid 8929) to make autoextend / hard-cap path TAP-testable + * deterministically. Bumps CATALOG_VERSION_NO; pg_proc.dat gets one row. */ +/* spec-3.9 D10 (2026-05-30): TEST-ONLY cluster_cr_test_construct SQL + * function (oid 8930) to drive own-instance CR block construction from + * cluster_tap t/215. One pg_proc row → catversion bump. (The 2 NEW + * SQLSTATEs 53R9F/53R9G are in errcodes.h, not catalog, and do not by + * themselves require a bump.) */ +/* spec-3.10 §v0.5 (2026-06-02): slot-reuse fail-closed -- ITL special area + * grows 384 -> 392B (8B ClusterItlPageHeader.itl_recycle_watermark_scn placed + * after the 384B slot array). Heap page on-disk layout change -> bump forces + * re-initdb (no in-place upgrade; Stage 3 dev only). */ +/* spec-3.10 §v0.6 (2026-06-02): TEST-ONLY cluster_cr_test_image SQL function + * (oid 8931, SETOF record) so t/218 can assert CR-image CONTENT after the + * line-pointer-reuse rebuild fix. One pg_proc row -> catversion bump. */ +/* spec-3.13 D3: undo segment header wrap_count @2680 + XLOG_UNDO_SEGMENT_RECYCLE 0x40 */ +/* spec-3.18 D2 (2026-06-07): UndoBlockHeader += block_lsn @40 (40B->48B page-LSN + * for FPI-on-first-touch undo WAL) + XLOG_UNDO_BLOCK_WRITE 0x70. On-disk undo + * block layout change -> bump forces re-initdb (Stage 3 dev only). */ +/* spec-3.18 D4.1 (2026-06-08): XACT_XINFO_HAS_TT_COMMIT (xinfo bit 10) + + * xl_xact_tt_commit section folded into the normal commit record (TT-slot + * commit no longer a standalone XLOG_UNDO_TT_SLOT_COMMIT 0x30). Commit-record + * WAL format change -> bump forces re-initdb (A1: no mixed-version replay). */ +/* spec-4.10 D3b (2026-06-14): pg_proc gains TEST-ONLY + * cluster_block_apply_redo_test (oid 8932) -- the single-block redo-apply + * byte-for-byte differential driver. One pg_proc row -> bump. + * + * spec-4.10 D2: cluster_block_recovery_reconstruct_test (oid 8933) -- the + * online single-block recovery reconstruct differential driver. +1 row. */ +/* spec-4.11 D1 (2026-06-14): pg_proc gains TEST-ONLY + * cluster_thread_apply_redo_test (oid 8934) -- the LSN-gated online + * thread-recovery apply matrix byte-for-byte parity + idempotence differential + * driver. One pg_proc row -> bump. */ +/* spec-4.11 D1 increment 3a (2026-06-14): pg_proc gains TEST-ONLY + * cluster_thread_replay_test (oid 8935) -- drives the online thread-recovery RMW + * replay engine over WAL + shared storage (streaming + gates + idempotence + + * fail-closed differential). One pg_proc row -> bump. */ +/* spec-4.11 D1 increment 3b-1 (2026-06-15): pg_proc gains TEST-ONLY + * cluster_thread_drive_test (oid 8936) -- drives the online thread-recovery data + * driver over a dead thread's per-thread WAL under the R13 harness. One pg_proc + * row -> bump. */ +/* spec-4.11 D1 increment 3b-2 (2026-06-15): pg_proc gains two TEST-ONLY entries + * cluster_thread_replay_one_test (oid 8937) + cluster_thread_replay_one_auto_test + * (oid 8938) -- drive the online thread-recovery orchestrator (combined data + + * visibility pass + durability barrier + 3-way authority publish). Two pg_proc + * rows -> bump. */ +/* spec-4.11 D1 increment 3b-3 (2026-06-15): pg_proc gains two TEST-ONLY entries + * cluster_thread_local_complete_test (oid 8939) + cluster_thread_gate_unfreeze_test + * (oid 8940) -- exercise the D3 unfreeze gate (node-local merged authority + + * reconfig-FSM predicate). Two pg_proc rows -> bump. */ +/* spec-4.11 D1 increment 3b-4a (2026-06-15): pg_proc gains one TEST-ONLY entry + * cluster_thread_validated_end_test (oid 8941) -- drives the D4 validated + * torn-tail boundary pass. One pg_proc row -> bump. */ +/* spec-4.11 D1 increment 3b-4b Part 1 (2026-06-15): pg_proc gains one TEST-ONLY + * entry cluster_thread_replay_slot_test (oid 8942) -- exercises the per-thread + * online replay-state shmem slot round-trip. One pg_proc row -> bump. */ +/* spec-4.11 D1 increment 3b-4b Part 2 (2026-06-15): pg_proc gains one TEST-ONLY + * entry cluster_thread_recovery_worker_run_test (oid 8943) -- drives the + * executor worker's testable core. One pg_proc row -> bump. */ +/* spec-4.11 D1 increment 3b-4b Part 3 (2026-06-15): pg_proc gains one TEST-ONLY + * entry cluster_thread_recovery_launch_test (oid 8944) -- drives the lmon launch + * side (no-op out of scope). One pg_proc row -> bump. */ +/* spec-4.11 D1 increment 3b-4b Part 4 (2026-06-15): pg_proc gains two TEST-ONLY + * entries -- cluster_thread_replay_slot_state_test (oid 8945, read-only slot + * observer) and cluster_reconfig_inject_dead_node_test (oid 8946, synthetic + * reconfig inject) -- for the inject -> FSM -> launch -> fail-closed-frozen e2e. + * Two pg_proc rows -> bump. */ +/* spec-4.11 D1 increment 3b-4c (2026-06-15): D7 capability gate adds one + * TEST-ONLY entry -- cluster_thread_capability_gate_test (oid 8947) -- driving + * the FEATURE_NOT_SUPPORTED gate (no-shared-backend / >2-node) deterministically. + * One pg_proc row -> bump. */ +#define CATALOG_VERSION_NO 202606180 + +/* spec-2.39 D10 (2026-05-21): SI Broadcaster production activation — + * DDL commit hook (AtEOXact_Inval + COMMIT PREPARED via cluster-aware + * wrapper) + peer_enqueued ack/barrier (3-status enum DONE/DROPPED/ + * RESET_PENDING) + fanout 3-partial-fail counter + RESET-all broadcast + * fail-safe (v0.3 P1 SINVAL_RESET_ALL_BROADCAST flag走 msg_type 7 复用). + * NEW IC msg_type 19 SINVAL_ACK (HC140 LMON-only producer mask; + * SinvalAckHeader 24B fixed). + * NEW 2 shmem regions: ClusterSinvalAckWait (HTAB capacity GUC) + + * ClusterSinvalAckOutbound (small ring). + * NEW 3 GUC: cluster.sinval_ack_mode (enum none/peer_enqueued PGC_ + * SIGHUP default peer_enqueued) + cluster.sinval_ack_timeout_ms (int + * PGC_SIGHUP 5000 [100, 60000]) + cluster.sinval_ack_wait_slots (int + * PGC_POSTMASTER 256 [64, 4096]). + * NEW 1 SQLSTATE: 53R95 cluster_sinval_ack_timeout (WARN-path). + * NEW 3 wait events: SinvalAckWait / SinvalAckSend / SinvalAckReceive. + * NEW 6 counter (3 fanout would_block/hard_error/peer_down + 3 ack + * received/timeout/orphan); dump_sinval category 9 → 15 rows. + * NEW 2 inject points (112→114): cluster-sinval-ack-drop-send + + * cluster-sinval-ack-skip-validate. + * v0.3 P1 wire ABI extension: SINVAL_RESET_ALL_BROADCAST flag in + * existing msg_type 7 SinvalBroadcastHeader.flags (nmsgs=0 sentinel + * batch);remote handler 见此 flag → SIResetAll + bump existing + * inbound_overflow_reset_count (spec-2.38). SINVAL_KNOWN_FLAGS + * 扩 2 bits;HC135 validation refit. + * catversion bump for catalog tooling + dump_sinval row count change. */ + +/* spec-2.16 D19 (2026-05-29): GesRequestPayload + GesReplyPayload wire + * payload structs (48B each + StaticAssertDecl); ClusterGrdHolderId + * 4-tuple typedef (24B); cluster_grd 9 NEW counter (4 cap + 5 nofail); + * cluster_grd_pending + cluster_grd_outbound + cluster_grd_work_queue + * shmem regions + LWLock tranches; cluster.ges_request_timeout_ms GUC; + * 53R70/53R71 SQLSTATE. catversion bump for catalog tooling. */ +#define CATALOG_VERSION_NO_PRIOR 202605600 + +#endif diff --git a/install/include/postgresql/server/catalog/dependency.h b/install/include/postgresql/server/catalog/dependency.h new file mode 100644 index 00000000000..8993a75c06a --- /dev/null +++ b/install/include/postgresql/server/catalog/dependency.h @@ -0,0 +1,272 @@ +/*------------------------------------------------------------------------- + * + * dependency.h + * Routines to support inter-object dependencies. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/dependency.h + * + *------------------------------------------------------------------------- + */ +#ifndef DEPENDENCY_H +#define DEPENDENCY_H + +#include "catalog/objectaddress.h" + + +/* + * Precise semantics of a dependency relationship are specified by the + * DependencyType code (which is stored in a "char" field in pg_depend, + * so we assign ASCII-code values to the enumeration members). + * + * In all cases, a dependency relationship indicates that the referenced + * object may not be dropped without also dropping the dependent object. + * However, there are several subflavors; see the description of pg_depend + * in catalogs.sgml for details. + */ + +typedef enum DependencyType +{ + DEPENDENCY_NORMAL = 'n', + DEPENDENCY_AUTO = 'a', + DEPENDENCY_INTERNAL = 'i', + DEPENDENCY_PARTITION_PRI = 'P', + DEPENDENCY_PARTITION_SEC = 'S', + DEPENDENCY_EXTENSION = 'e', + DEPENDENCY_AUTO_EXTENSION = 'x' +} DependencyType; + +/* + * There is also a SharedDependencyType enum type that determines the exact + * semantics of an entry in pg_shdepend. Just like regular dependency entries, + * any pg_shdepend entry means that the referenced object cannot be dropped + * unless the dependent object is dropped at the same time. There are some + * additional rules however: + * + * (a) a SHARED_DEPENDENCY_OWNER entry means that the referenced object is + * the role owning the dependent object. The referenced object must be + * a pg_authid entry. + * + * (b) a SHARED_DEPENDENCY_ACL entry means that the referenced object is + * a role mentioned in the ACL field of the dependent object. The referenced + * object must be a pg_authid entry. (SHARED_DEPENDENCY_ACL entries are not + * created for the owner of an object; hence two objects may be linked by + * one or the other, but not both, of these dependency types.) + * + * (c) a SHARED_DEPENDENCY_POLICY entry means that the referenced object is + * a role mentioned in a policy object. The referenced object must be a + * pg_authid entry. + * + * (d) a SHARED_DEPENDENCY_TABLESPACE entry means that the referenced + * object is a tablespace mentioned in a relation without storage. The + * referenced object must be a pg_tablespace entry. (Relations that have + * storage don't need this: they are protected by the existence of a physical + * file in the tablespace.) + * + * SHARED_DEPENDENCY_INVALID is a value used as a parameter in internal + * routines, and is not valid in the catalog itself. + */ +typedef enum SharedDependencyType +{ + SHARED_DEPENDENCY_OWNER = 'o', + SHARED_DEPENDENCY_ACL = 'a', + SHARED_DEPENDENCY_POLICY = 'r', + SHARED_DEPENDENCY_TABLESPACE = 't', + SHARED_DEPENDENCY_INVALID = 0 +} SharedDependencyType; + +/* expansible list of ObjectAddresses (private in dependency.c) */ +typedef struct ObjectAddresses ObjectAddresses; + +/* + * This enum covers all system catalogs whose OIDs can appear in + * pg_depend.classId or pg_shdepend.classId. Keep object_classes[] in sync. + */ +typedef enum ObjectClass +{ + OCLASS_CLASS, /* pg_class */ + OCLASS_PROC, /* pg_proc */ + OCLASS_TYPE, /* pg_type */ + OCLASS_CAST, /* pg_cast */ + OCLASS_COLLATION, /* pg_collation */ + OCLASS_CONSTRAINT, /* pg_constraint */ + OCLASS_CONVERSION, /* pg_conversion */ + OCLASS_DEFAULT, /* pg_attrdef */ + OCLASS_LANGUAGE, /* pg_language */ + OCLASS_LARGEOBJECT, /* pg_largeobject */ + OCLASS_OPERATOR, /* pg_operator */ + OCLASS_OPCLASS, /* pg_opclass */ + OCLASS_OPFAMILY, /* pg_opfamily */ + OCLASS_AM, /* pg_am */ + OCLASS_AMOP, /* pg_amop */ + OCLASS_AMPROC, /* pg_amproc */ + OCLASS_REWRITE, /* pg_rewrite */ + OCLASS_TRIGGER, /* pg_trigger */ + OCLASS_SCHEMA, /* pg_namespace */ + OCLASS_STATISTIC_EXT, /* pg_statistic_ext */ + OCLASS_TSPARSER, /* pg_ts_parser */ + OCLASS_TSDICT, /* pg_ts_dict */ + OCLASS_TSTEMPLATE, /* pg_ts_template */ + OCLASS_TSCONFIG, /* pg_ts_config */ + OCLASS_ROLE, /* pg_authid */ + OCLASS_ROLE_MEMBERSHIP, /* pg_auth_members */ + OCLASS_DATABASE, /* pg_database */ + OCLASS_TBLSPACE, /* pg_tablespace */ + OCLASS_FDW, /* pg_foreign_data_wrapper */ + OCLASS_FOREIGN_SERVER, /* pg_foreign_server */ + OCLASS_USER_MAPPING, /* pg_user_mapping */ + OCLASS_DEFACL, /* pg_default_acl */ + OCLASS_EXTENSION, /* pg_extension */ + OCLASS_EVENT_TRIGGER, /* pg_event_trigger */ + OCLASS_PARAMETER_ACL, /* pg_parameter_acl */ + OCLASS_POLICY, /* pg_policy */ + OCLASS_PUBLICATION, /* pg_publication */ + OCLASS_PUBLICATION_NAMESPACE, /* pg_publication_namespace */ + OCLASS_PUBLICATION_REL, /* pg_publication_rel */ + OCLASS_SUBSCRIPTION, /* pg_subscription */ + OCLASS_TRANSFORM /* pg_transform */ +} ObjectClass; + +#define LAST_OCLASS OCLASS_TRANSFORM + +/* flag bits for performDeletion/performMultipleDeletions: */ +#define PERFORM_DELETION_INTERNAL 0x0001 /* internal action */ +#define PERFORM_DELETION_CONCURRENTLY 0x0002 /* concurrent drop */ +#define PERFORM_DELETION_QUIETLY 0x0004 /* suppress notices */ +#define PERFORM_DELETION_SKIP_ORIGINAL 0x0008 /* keep original obj */ +#define PERFORM_DELETION_SKIP_EXTENSIONS 0x0010 /* keep extensions */ +#define PERFORM_DELETION_CONCURRENT_LOCK 0x0020 /* normal drop with + * concurrent lock mode */ + + +/* in dependency.c */ + +extern void AcquireDeletionLock(const ObjectAddress *object, int flags); + +extern void ReleaseDeletionLock(const ObjectAddress *object); + +extern void performDeletion(const ObjectAddress *object, + DropBehavior behavior, int flags); + +extern void performMultipleDeletions(const ObjectAddresses *objects, + DropBehavior behavior, int flags); + +extern void recordDependencyOnExpr(const ObjectAddress *depender, + Node *expr, List *rtable, + DependencyType behavior); + +extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, + Node *expr, Oid relId, + DependencyType behavior, + DependencyType self_behavior, + bool reverse_self); + +extern ObjectClass getObjectClass(const ObjectAddress *object); + +extern ObjectAddresses *new_object_addresses(void); + +extern void add_exact_object_address(const ObjectAddress *object, + ObjectAddresses *addrs); + +extern bool object_address_present(const ObjectAddress *object, + const ObjectAddresses *addrs); + +extern void record_object_address_dependencies(const ObjectAddress *depender, + ObjectAddresses *referenced, + DependencyType behavior); + +extern void sort_object_addresses(ObjectAddresses *addrs); + +extern void free_object_addresses(ObjectAddresses *addrs); + +/* in pg_depend.c */ + +extern void recordDependencyOn(const ObjectAddress *depender, + const ObjectAddress *referenced, + DependencyType behavior); + +extern void recordMultipleDependencies(const ObjectAddress *depender, + const ObjectAddress *referenced, + int nreferenced, + DependencyType behavior); + +extern void recordDependencyOnCurrentExtension(const ObjectAddress *object, + bool isReplace); + +extern void checkMembershipInCurrentExtension(const ObjectAddress *object); + +extern long deleteDependencyRecordsFor(Oid classId, Oid objectId, + bool skipExtensionDeps); + +extern long deleteDependencyRecordsForClass(Oid classId, Oid objectId, + Oid refclassId, char deptype); + +extern long deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, + char deptype, + Oid refclassId, Oid refobjectId); + +extern long changeDependencyFor(Oid classId, Oid objectId, + Oid refClassId, Oid oldRefObjectId, + Oid newRefObjectId); + +extern long changeDependenciesOf(Oid classId, Oid oldObjectId, + Oid newObjectId); + +extern long changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, + Oid newRefObjectId); + +extern Oid getExtensionOfObject(Oid classId, Oid objectId); +extern List *getAutoExtensionsOfObject(Oid classId, Oid objectId); + +extern Oid getExtensionType(Oid extensionOid, const char *typname); + +extern bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId); +extern List *getOwnedSequences(Oid relid); +extern Oid getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok); + +extern Oid get_index_constraint(Oid indexId); + +extern List *get_index_ref_constraints(Oid indexId); + +/* in pg_shdepend.c */ + +extern void recordSharedDependencyOn(ObjectAddress *depender, + ObjectAddress *referenced, + SharedDependencyType deptype); + +extern void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, + int32 objectSubId); + +extern void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner); + +extern void changeDependencyOnOwner(Oid classId, Oid objectId, + Oid newOwnerId); + +extern void recordDependencyOnTablespace(Oid classId, Oid objectId, + Oid tablespace); + +extern void changeDependencyOnTablespace(Oid classId, Oid objectId, + Oid newTablespaceId); + +extern void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, + Oid ownerId, + int noldmembers, Oid *oldmembers, + int nnewmembers, Oid *newmembers); + +extern bool checkSharedDependencies(Oid classId, Oid objectId, + char **detail_msg, char **detail_log_msg); + +extern void shdepLockAndCheckObject(Oid classId, Oid objectId); + +extern void copyTemplateDependencies(Oid templateDbId, Oid newDbId); + +extern void dropDatabaseDependencies(Oid databaseId); + +extern void shdepDropOwned(List *roleids, DropBehavior behavior); + +extern void shdepReassignOwned(List *roleids, Oid newrole); + +#endif /* DEPENDENCY_H */ diff --git a/install/include/postgresql/server/catalog/genbki.h b/install/include/postgresql/server/catalog/genbki.h new file mode 100644 index 00000000000..c42ba0cea50 --- /dev/null +++ b/install/include/postgresql/server/catalog/genbki.h @@ -0,0 +1,143 @@ +/*------------------------------------------------------------------------- + * + * genbki.h + * Required include file for all POSTGRES catalog header files + * + * genbki.h defines CATALOG(), BKI_BOOTSTRAP and related macros + * so that the catalog header files can be read by the C compiler. + * (These same words are recognized by genbki.pl to build the BKI + * bootstrap file from these header files.) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/genbki.h + * + *------------------------------------------------------------------------- + */ +#ifndef GENBKI_H +#define GENBKI_H + +/* Introduces a catalog's structure definition */ +#define CATALOG(name,oid,oidmacro) typedef struct CppConcat(FormData_,name) + +/* Options that may appear after CATALOG (on the same line) */ +#define BKI_BOOTSTRAP +#define BKI_SHARED_RELATION +#define BKI_ROWTYPE_OID(oid,oidmacro) +#define BKI_SCHEMA_MACRO + +/* Options that may appear after an attribute (on the same line) */ +#define BKI_FORCE_NULL +#define BKI_FORCE_NOT_NULL +/* Specifies a default value for a catalog field */ +#define BKI_DEFAULT(value) +/* Specifies a default value for auto-generated array types */ +#define BKI_ARRAY_DEFAULT(value) +/* + * Indicates that the attribute contains OIDs referencing the named catalog; + * can be applied to columns of oid, regproc, oid[], or oidvector type. + * genbki.pl uses this to know how to perform name lookups in the initial + * data (if any), and it also feeds into regression-test validity checks. + * The _OPT suffix indicates that values can be zero instead of + * a valid OID reference. + */ +#define BKI_LOOKUP(catalog) +#define BKI_LOOKUP_OPT(catalog) + +/* + * These lines are processed by genbki.pl to create the statements + * the bootstrap parser will turn into BootstrapToastTable commands. + * Each line specifies the system catalog that needs a toast table, + * the OID to assign to the toast table, and the OID to assign to the + * toast table's index. The reason we hard-wire these OIDs is that we + * need stable OIDs for shared relations, and that includes toast tables + * of shared relations. + * + * The DECLARE_TOAST_WITH_MACRO variant is used when C macros are needed + * for the toast table/index OIDs (usually only for shared catalogs). + * + * The macro definitions are just to keep the C compiler from spitting up. + */ +#define DECLARE_TOAST(name,toastoid,indexoid) extern int no_such_variable +#define DECLARE_TOAST_WITH_MACRO(name,toastoid,indexoid,toastoidmacro,indexoidmacro) extern int no_such_variable + +/* + * These lines are processed by genbki.pl to create the statements + * the bootstrap parser will turn into DefineIndex calls. + * + * The keyword is DECLARE_INDEX or DECLARE_UNIQUE_INDEX or + * DECLARE_UNIQUE_INDEX_PKEY. ("PKEY" marks the index as being the catalog's + * primary key; currently this is only cosmetically different from a regular + * unique index. By convention, we usually make a catalog's OID column its + * pkey, if it has one.) + * + * The first two arguments are the index's name and OID. The third argument + * is the name of a #define to generate for its OID. References to the index + * in the C code should always use these #defines, not the actual index name + * (much less the numeric OID). The rest is much like a standard 'create + * index' SQL command. + * + * The macro definitions are just to keep the C compiler from spitting up. + */ +#define DECLARE_INDEX(name,oid,oidmacro,decl) extern int no_such_variable +#define DECLARE_UNIQUE_INDEX(name,oid,oidmacro,decl) extern int no_such_variable +#define DECLARE_UNIQUE_INDEX_PKEY(name,oid,oidmacro,decl) extern int no_such_variable + +/* + * These lines inform genbki.pl about manually-assigned OIDs that do not + * correspond to any entry in the catalog *.dat files, but should be subject + * to uniqueness verification and renumber_oids.pl renumbering. A C macro + * to #define the given name is emitted into the corresponding *_d.h file. + */ +#define DECLARE_OID_DEFINING_MACRO(name,oid) extern int no_such_variable + +/* + * These lines are processed by genbki.pl to create a table for use + * by the pg_get_catalog_foreign_keys() function. We do not have any + * mechanism that actually enforces foreign-key relationships in the + * system catalogs, but it is still useful to record the intended + * relationships in a machine-readable form. + * + * The keyword is DECLARE_FOREIGN_KEY[_OPT] or DECLARE_ARRAY_FOREIGN_KEY[_OPT]. + * The first argument is a parenthesized list of the referencing columns; + * the second, the name of the referenced table; the third, a parenthesized + * list of the referenced columns. Use of the ARRAY macros means that the + * last referencing column is an array, each of whose elements is supposed + * to match some entry in the last referenced column. Use of the OPT suffix + * indicates that the referencing column(s) can be zero instead of a valid + * reference. + * + * Columns that are marked with a BKI_LOOKUP rule do not need an explicit + * DECLARE_FOREIGN_KEY macro, as genbki.pl can infer the FK relationship + * from that. Thus, these macros are only needed in special cases. + * + * The macro definitions are just to keep the C compiler from spitting up. + */ +#define DECLARE_FOREIGN_KEY(cols,reftbl,refcols) extern int no_such_variable +#define DECLARE_FOREIGN_KEY_OPT(cols,reftbl,refcols) extern int no_such_variable +#define DECLARE_ARRAY_FOREIGN_KEY(cols,reftbl,refcols) extern int no_such_variable +#define DECLARE_ARRAY_FOREIGN_KEY_OPT(cols,reftbl,refcols) extern int no_such_variable + +/* The following are never defined; they are here only for documentation. */ + +/* + * Variable-length catalog fields (except possibly the first not nullable one) + * should not be visible in C structures, so they are made invisible by #ifdefs + * of an undefined symbol. See also the BOOTCOL_NULL_AUTO code in bootstrap.c + * for how this is handled. + */ +#undef CATALOG_VARLEN + +/* + * There is code in some catalog headers that needs to be visible to clients, + * but we don't want clients to include the full header because of safety + * issues with other code in the header. To handle that, surround code that + * should be visible to clients with "#ifdef EXPOSE_TO_CLIENT_CODE". That + * instructs genbki.pl to copy the section when generating the corresponding + * "_d" header, which can be included by both client and backend code. + */ +#undef EXPOSE_TO_CLIENT_CODE + +#endif /* GENBKI_H */ diff --git a/install/include/postgresql/server/catalog/heap.h b/install/include/postgresql/server/catalog/heap.h new file mode 100644 index 00000000000..61df22ba7e7 --- /dev/null +++ b/install/include/postgresql/server/catalog/heap.h @@ -0,0 +1,162 @@ +/*------------------------------------------------------------------------- + * + * heap.h + * prototypes for functions in backend/catalog/heap.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/heap.h + * + *------------------------------------------------------------------------- + */ +#ifndef HEAP_H +#define HEAP_H + +#include "catalog/indexing.h" +#include "catalog/objectaddress.h" +#include "parser/parse_node.h" + + +/* flag bits for CheckAttributeType/CheckAttributeNamesTypes */ +#define CHKATYPE_ANYARRAY 0x01 /* allow ANYARRAY */ +#define CHKATYPE_ANYRECORD 0x02 /* allow RECORD and RECORD[] */ +#define CHKATYPE_IS_PARTKEY 0x04 /* attname is part key # not column */ + +typedef struct RawColumnDefault +{ + AttrNumber attnum; /* attribute to attach default to */ + Node *raw_default; /* default value (untransformed parse tree) */ + bool missingMode; /* obsolete, no longer used */ + char generated; /* attgenerated setting */ +} RawColumnDefault; + +typedef struct CookedConstraint +{ + ConstrType contype; /* CONSTR_DEFAULT or CONSTR_CHECK */ + Oid conoid; /* constr OID if created, otherwise Invalid */ + char *name; /* name, or NULL if none */ + AttrNumber attnum; /* which attr (only for DEFAULT) */ + Node *expr; /* transformed default or check expr */ + bool skip_validation; /* skip validation? (only for CHECK) */ + bool is_local; /* constraint has local (non-inherited) def */ + int inhcount; /* number of times constraint is inherited */ + bool is_no_inherit; /* constraint has local def and cannot be + * inherited */ +} CookedConstraint; + +extern Relation heap_create(const char *relname, + Oid relnamespace, + Oid reltablespace, + Oid relid, + RelFileNumber relfilenumber, + Oid accessmtd, + TupleDesc tupDesc, + char relkind, + char relpersistence, + bool shared_relation, + bool mapped_relation, + bool allow_system_table_mods, + TransactionId *relfrozenxid, + MultiXactId *relminmxid, + bool create_storage); + +extern Oid heap_create_with_catalog(const char *relname, + Oid relnamespace, + Oid reltablespace, + Oid relid, + Oid reltypeid, + Oid reloftypeid, + Oid ownerid, + Oid accessmtd, + TupleDesc tupdesc, + List *cooked_constraints, + char relkind, + char relpersistence, + bool shared_relation, + bool mapped_relation, + OnCommitAction oncommit, + Datum reloptions, + bool use_user_acl, + bool allow_system_table_mods, + bool is_internal, + Oid relrewrite, + ObjectAddress *typaddress); + +extern void heap_drop_with_catalog(Oid relid); + +extern void heap_truncate(List *relids); + +extern void heap_truncate_one_rel(Relation rel); + +extern void heap_truncate_check_FKs(List *relations, bool tempTables); + +extern List *heap_truncate_find_FKs(List *relationIds); + +extern void InsertPgAttributeTuples(Relation pg_attribute_rel, + TupleDesc tupdesc, + Oid new_rel_oid, + Datum *attoptions, + CatalogIndexState indstate); + +extern void InsertPgClassTuple(Relation pg_class_desc, + Relation new_rel_desc, + Oid new_rel_oid, + Datum relacl, + Datum reloptions); + +extern List *AddRelationNewConstraints(Relation rel, + List *newColDefaults, + List *newConstraints, + bool allow_merge, + bool is_local, + bool is_internal, + const char *queryString); + +extern void RelationClearMissing(Relation rel); + +extern void StoreAttrMissingVal(Relation rel, AttrNumber attnum, + Datum missingval); +extern void SetAttrMissing(Oid relid, char *attname, char *value); + +extern Node *cookDefault(ParseState *pstate, + Node *raw_default, + Oid atttypid, + int32 atttypmod, + const char *attname, + char attgenerated); + +extern void DeleteRelationTuple(Oid relid); +extern void DeleteAttributeTuples(Oid relid); +extern void DeleteSystemAttributeTuples(Oid relid); +extern void RemoveAttributeById(Oid relid, AttrNumber attnum); + +extern void CopyStatistics(Oid fromrelid, Oid torelid); +extern void RemoveStatistics(Oid relid, AttrNumber attnum); + +extern const FormData_pg_attribute *SystemAttributeDefinition(AttrNumber attno); + +extern const FormData_pg_attribute *SystemAttributeByName(const char *attname); + +extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, + int flags); + +extern void CheckAttributeType(const char *attname, + Oid atttypid, Oid attcollation, + List *containing_rowtypes, + int flags); + +/* pg_partitioned_table catalog manipulation functions */ +extern void StorePartitionKey(Relation rel, + char strategy, + int16 partnatts, + AttrNumber *partattrs, + List *partexprs, + Oid *partopclass, + Oid *partcollation); +extern void RemovePartitionKeyByRelId(Oid relid); +extern void StorePartitionBound(Relation rel, Relation parent, + PartitionBoundSpec *bound); + +#endif /* HEAP_H */ diff --git a/install/include/postgresql/server/catalog/index.h b/install/include/postgresql/server/catalog/index.h new file mode 100644 index 00000000000..c8532fb97c8 --- /dev/null +++ b/install/include/postgresql/server/catalog/index.h @@ -0,0 +1,214 @@ +/*------------------------------------------------------------------------- + * + * index.h + * prototypes for catalog/index.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/index.h + * + *------------------------------------------------------------------------- + */ +#ifndef INDEX_H +#define INDEX_H + +#include "catalog/objectaddress.h" +#include "nodes/execnodes.h" + + +#define DEFAULT_INDEX_TYPE "btree" + +/* Action code for index_set_state_flags */ +typedef enum +{ + INDEX_CREATE_SET_READY, + INDEX_CREATE_SET_VALID, + INDEX_DROP_CLEAR_VALID, + INDEX_DROP_SET_DEAD +} IndexStateFlagsAction; + +/* options for REINDEX */ +typedef struct ReindexParams +{ + bits32 options; /* bitmask of REINDEXOPT_* */ + Oid tablespaceOid; /* New tablespace to move indexes to. + * InvalidOid to do nothing. */ +} ReindexParams; + +/* flag bits for ReindexParams->flags */ +#define REINDEXOPT_VERBOSE 0x01 /* print progress info */ +#define REINDEXOPT_REPORT_PROGRESS 0x02 /* report pgstat progress */ +#define REINDEXOPT_MISSING_OK 0x04 /* skip missing relations */ +#define REINDEXOPT_CONCURRENTLY 0x08 /* concurrent mode */ + +/* state info for validate_index bulkdelete callback */ +typedef struct ValidateIndexState +{ + Tuplesortstate *tuplesort; /* for sorting the index TIDs */ + /* statistics (for debug purposes only): */ + double htups, + itups, + tups_inserted; +} ValidateIndexState; + +extern void index_check_primary_key(Relation heapRel, + IndexInfo *indexInfo, + bool is_alter_table, + IndexStmt *stmt); + +#define INDEX_CREATE_IS_PRIMARY (1 << 0) +#define INDEX_CREATE_ADD_CONSTRAINT (1 << 1) +#define INDEX_CREATE_SKIP_BUILD (1 << 2) +#define INDEX_CREATE_CONCURRENT (1 << 3) +#define INDEX_CREATE_IF_NOT_EXISTS (1 << 4) +#define INDEX_CREATE_PARTITIONED (1 << 5) +#define INDEX_CREATE_INVALID (1 << 6) + +extern Oid index_create(Relation heapRelation, + const char *indexRelationName, + Oid indexRelationId, + Oid parentIndexRelid, + Oid parentConstraintId, + RelFileNumber relFileNumber, + IndexInfo *indexInfo, + List *indexColNames, + Oid accessMethodObjectId, + Oid tableSpaceId, + Oid *collationObjectId, + Oid *classObjectId, + int16 *coloptions, + Datum reloptions, + bits16 flags, + bits16 constr_flags, + bool allow_system_table_mods, + bool is_internal, + Oid *constraintId); + +#define INDEX_CONSTR_CREATE_MARK_AS_PRIMARY (1 << 0) +#define INDEX_CONSTR_CREATE_DEFERRABLE (1 << 1) +#define INDEX_CONSTR_CREATE_INIT_DEFERRED (1 << 2) +#define INDEX_CONSTR_CREATE_UPDATE_INDEX (1 << 3) +#define INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS (1 << 4) + +extern Oid index_concurrently_create_copy(Relation heapRelation, + Oid oldIndexId, + Oid tablespaceOid, + const char *newName); + +extern void index_concurrently_build(Oid heapRelationId, + Oid indexRelationId); + +extern void index_concurrently_swap(Oid newIndexId, + Oid oldIndexId, + const char *oldName); + +extern void index_concurrently_set_dead(Oid heapId, + Oid indexId); + +extern ObjectAddress index_constraint_create(Relation heapRelation, + Oid indexRelationId, + Oid parentConstraintId, + IndexInfo *indexInfo, + const char *constraintName, + char constraintType, + bits16 constr_flags, + bool allow_system_table_mods, + bool is_internal); + +extern void index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode); + +extern IndexInfo *BuildIndexInfo(Relation index); + +extern IndexInfo *BuildDummyIndexInfo(Relation index); + +extern bool CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, + Oid *collations1, Oid *collations2, + Oid *opfamilies1, Oid *opfamilies2, + AttrMap *attmap); + +extern void BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii); + +extern void FormIndexDatum(IndexInfo *indexInfo, + TupleTableSlot *slot, + EState *estate, + Datum *values, + bool *isnull); + +extern void index_build(Relation heapRelation, + Relation indexRelation, + IndexInfo *indexInfo, + bool isreindex, + bool parallel); + +extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot); + +extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action); + +extern Oid IndexGetRelation(Oid indexId, bool missing_ok); + +extern void reindex_index(Oid indexId, bool skip_constraint_checks, + char persistence, ReindexParams *params); + +/* Flag bits for reindex_relation(): */ +#define REINDEX_REL_PROCESS_TOAST 0x01 +#define REINDEX_REL_SUPPRESS_INDEX_USE 0x02 +#define REINDEX_REL_CHECK_CONSTRAINTS 0x04 +#define REINDEX_REL_FORCE_INDEXES_UNLOGGED 0x08 +#define REINDEX_REL_FORCE_INDEXES_PERMANENT 0x10 + +extern bool reindex_relation(Oid relid, int flags, ReindexParams *params); + +extern bool ReindexIsProcessingHeap(Oid heapOid); +extern bool ReindexIsProcessingIndex(Oid indexOid); + +extern void ResetReindexState(int nestLevel); +extern Size EstimateReindexStateSpace(void); +extern void SerializeReindexState(Size maxsize, char *start_address); +extern void RestoreReindexState(void *reindexstate); + +extern void IndexSetParentIndex(Relation partitionIdx, Oid parentOid); + + +/* + * itemptr_encode - Encode ItemPointer as int64/int8 + * + * This representation must produce values encoded as int64 that sort in the + * same order as their corresponding original TID values would (using the + * default int8 opclass to produce a result equivalent to the default TID + * opclass). + * + * As noted in validate_index(), this can be significantly faster. + */ +static inline int64 +itemptr_encode(ItemPointer itemptr) +{ + BlockNumber block = ItemPointerGetBlockNumber(itemptr); + OffsetNumber offset = ItemPointerGetOffsetNumber(itemptr); + int64 encoded; + + /* + * Use the 16 least significant bits for the offset. 32 adjacent bits are + * used for the block number. Since remaining bits are unused, there + * cannot be negative encoded values (We assume a two's complement + * representation). + */ + encoded = ((uint64) block << 16) | (uint16) offset; + + return encoded; +} + +/* + * itemptr_decode - Decode int64/int8 representation back to ItemPointer + */ +static inline void +itemptr_decode(ItemPointer itemptr, int64 encoded) +{ + BlockNumber block = (BlockNumber) (encoded >> 16); + OffsetNumber offset = (OffsetNumber) (encoded & 0xFFFF); + + ItemPointerSet(itemptr, block, offset); +} + +#endif /* INDEX_H */ diff --git a/install/include/postgresql/server/catalog/indexing.h b/install/include/postgresql/server/catalog/indexing.h new file mode 100644 index 00000000000..5c0693835cd --- /dev/null +++ b/install/include/postgresql/server/catalog/indexing.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * indexing.h + * This file provides some definitions to support indexing + * on system catalogs + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/indexing.h + * + *------------------------------------------------------------------------- + */ +#ifndef INDEXING_H +#define INDEXING_H + +#include "access/htup.h" +#include "nodes/execnodes.h" +#include "utils/relcache.h" + +/* + * The state object used by CatalogOpenIndexes and friends is actually the + * same as the executor's ResultRelInfo, but we give it another type name + * to decouple callers from that fact. + */ +typedef struct ResultRelInfo *CatalogIndexState; + +/* + * Cap the maximum amount of bytes allocated for multi-inserts with system + * catalogs, limiting the number of slots used. + */ +#define MAX_CATALOG_MULTI_INSERT_BYTES 65535 + +/* + * indexing.c prototypes + */ +extern CatalogIndexState CatalogOpenIndexes(Relation heapRel); +extern void CatalogCloseIndexes(CatalogIndexState indstate); +extern void CatalogTupleInsert(Relation heapRel, HeapTuple tup); +extern void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, + CatalogIndexState indstate); +extern void CatalogTuplesMultiInsertWithInfo(Relation heapRel, + TupleTableSlot **slot, + int ntuples, + CatalogIndexState indstate); +extern void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, + HeapTuple tup); +extern void CatalogTupleUpdateWithInfo(Relation heapRel, + ItemPointer otid, HeapTuple tup, + CatalogIndexState indstate); +extern void CatalogTupleDelete(Relation heapRel, ItemPointer tid); + +#endif /* INDEXING_H */ diff --git a/install/include/postgresql/server/catalog/namespace.h b/install/include/postgresql/server/catalog/namespace.h new file mode 100644 index 00000000000..f64a0ec26b9 --- /dev/null +++ b/install/include/postgresql/server/catalog/namespace.h @@ -0,0 +1,190 @@ +/*------------------------------------------------------------------------- + * + * namespace.h + * prototypes for functions in backend/catalog/namespace.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/namespace.h + * + *------------------------------------------------------------------------- + */ +#ifndef NAMESPACE_H +#define NAMESPACE_H + +#include "nodes/primnodes.h" +#include "storage/lock.h" + + +/* + * This structure holds a list of possible functions or operators + * found by namespace lookup. Each function/operator is identified + * by OID and by argument types; the list must be pruned by type + * resolution rules that are embodied in the parser, not here. + * See FuncnameGetCandidates's comments for more info. + */ +typedef struct _FuncCandidateList +{ + struct _FuncCandidateList *next; + int pathpos; /* for internal use of namespace lookup */ + Oid oid; /* the function or operator's OID */ + int nominalnargs; /* either pronargs or length(proallargtypes) */ + int nargs; /* number of arg types returned */ + int nvargs; /* number of args to become variadic array */ + int ndargs; /* number of defaulted args */ + int *argnumbers; /* args' positional indexes, if named call */ + Oid args[FLEXIBLE_ARRAY_MEMBER]; /* arg types */ +} *FuncCandidateList; + +/* + * Result of checkTempNamespaceStatus + */ +typedef enum TempNamespaceStatus +{ + TEMP_NAMESPACE_NOT_TEMP, /* nonexistent, or non-temp namespace */ + TEMP_NAMESPACE_IDLE, /* exists, belongs to no active session */ + TEMP_NAMESPACE_IN_USE /* belongs to some active session */ +} TempNamespaceStatus; + +/* + * Structure for xxxOverrideSearchPath functions + * + * The generation counter is private to namespace.c and shouldn't be touched + * by other code. It can be initialized to zero if necessary (that means + * "not known equal to the current active path"). + */ +typedef struct OverrideSearchPath +{ + List *schemas; /* OIDs of explicitly named schemas */ + bool addCatalog; /* implicitly prepend pg_catalog? */ + bool addTemp; /* implicitly prepend temp schema? */ + uint64 generation; /* for quick detection of equality to active */ +} OverrideSearchPath; + +/* + * Option flag bits for RangeVarGetRelidExtended(). + */ +typedef enum RVROption +{ + RVR_MISSING_OK = 1 << 0, /* don't error if relation doesn't exist */ + RVR_NOWAIT = 1 << 1, /* error if relation cannot be locked */ + RVR_SKIP_LOCKED = 1 << 2 /* skip if relation cannot be locked */ +} RVROption; + +typedef void (*RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, + Oid oldRelId, void *callback_arg); + +#define RangeVarGetRelid(relation, lockmode, missing_ok) \ + RangeVarGetRelidExtended(relation, lockmode, \ + (missing_ok) ? RVR_MISSING_OK : 0, NULL, NULL) + +extern Oid RangeVarGetRelidExtended(const RangeVar *relation, + LOCKMODE lockmode, uint32 flags, + RangeVarGetRelidCallback callback, + void *callback_arg); +extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation); +extern Oid RangeVarGetAndCheckCreationNamespace(RangeVar *relation, + LOCKMODE lockmode, + Oid *existing_relation_id); +extern void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid); +extern Oid RelnameGetRelid(const char *relname); +extern bool RelationIsVisible(Oid relid); + +extern Oid TypenameGetTypid(const char *typname); +extern Oid TypenameGetTypidExtended(const char *typname, bool temp_ok); +extern bool TypeIsVisible(Oid typid); + +extern FuncCandidateList FuncnameGetCandidates(List *names, + int nargs, List *argnames, + bool expand_variadic, + bool expand_defaults, + bool include_out_arguments, + bool missing_ok); +extern bool FunctionIsVisible(Oid funcid); + +extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright); +extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind, + bool missing_schema_ok); +extern bool OperatorIsVisible(Oid oprid); + +extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname); +extern bool OpclassIsVisible(Oid opcid); + +extern Oid OpfamilynameGetOpfid(Oid amid, const char *opfname); +extern bool OpfamilyIsVisible(Oid opfid); + +extern Oid CollationGetCollid(const char *collname); +extern bool CollationIsVisible(Oid collid); + +extern Oid ConversionGetConid(const char *conname); +extern bool ConversionIsVisible(Oid conid); + +extern Oid get_statistics_object_oid(List *names, bool missing_ok); +extern bool StatisticsObjIsVisible(Oid relid); + +extern Oid get_ts_parser_oid(List *names, bool missing_ok); +extern bool TSParserIsVisible(Oid prsId); + +extern Oid get_ts_dict_oid(List *names, bool missing_ok); +extern bool TSDictionaryIsVisible(Oid dictId); + +extern Oid get_ts_template_oid(List *names, bool missing_ok); +extern bool TSTemplateIsVisible(Oid tmplId); + +extern Oid get_ts_config_oid(List *names, bool missing_ok); +extern bool TSConfigIsVisible(Oid cfgid); + +extern void DeconstructQualifiedName(List *names, + char **nspname_p, + char **objname_p); +extern Oid LookupNamespaceNoError(const char *nspname); +extern Oid LookupExplicitNamespace(const char *nspname, bool missing_ok); +extern Oid get_namespace_oid(const char *nspname, bool missing_ok); + +extern Oid LookupCreationNamespace(const char *nspname); +extern void CheckSetNamespace(Oid oldNspOid, Oid nspOid); +extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p); +extern RangeVar *makeRangeVarFromNameList(List *names); +extern char *NameListToString(List *names); +extern char *NameListToQuotedString(List *names); + +extern bool isTempNamespace(Oid namespaceId); +extern bool isTempToastNamespace(Oid namespaceId); +extern bool isTempOrTempToastNamespace(Oid namespaceId); +extern bool isAnyTempNamespace(Oid namespaceId); +extern bool isOtherTempNamespace(Oid namespaceId); +extern TempNamespaceStatus checkTempNamespaceStatus(Oid namespaceId); +extern int GetTempNamespaceBackendId(Oid namespaceId); +extern Oid GetTempToastNamespace(void); +extern void GetTempNamespaceState(Oid *tempNamespaceId, + Oid *tempToastNamespaceId); +extern void SetTempNamespaceState(Oid tempNamespaceId, + Oid tempToastNamespaceId); +extern void ResetTempTableNamespace(void); + +extern OverrideSearchPath *GetOverrideSearchPath(MemoryContext context); +extern OverrideSearchPath *CopyOverrideSearchPath(OverrideSearchPath *path); +extern bool OverrideSearchPathMatchesCurrent(OverrideSearchPath *path); +extern void PushOverrideSearchPath(OverrideSearchPath *newpath); +extern void PopOverrideSearchPath(void); + +extern Oid get_collation_oid(List *collname, bool missing_ok); +extern Oid get_conversion_oid(List *conname, bool missing_ok); +extern Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding); + + +/* initialization & transaction cleanup code */ +extern void InitializeSearchPath(void); +extern void AtEOXact_Namespace(bool isCommit, bool parallel); +extern void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, + SubTransactionId parentSubid); + +/* stuff for search_path GUC variable */ +extern PGDLLIMPORT char *namespace_search_path; + +extern List *fetch_search_path(bool includeImplicit); +extern int fetch_search_path_array(Oid *sarray, int sarray_len); + +#endif /* NAMESPACE_H */ diff --git a/install/include/postgresql/server/catalog/objectaccess.h b/install/include/postgresql/server/catalog/objectaccess.h new file mode 100644 index 00000000000..d8145dd4c63 --- /dev/null +++ b/install/include/postgresql/server/catalog/objectaccess.h @@ -0,0 +1,267 @@ +/* + * objectaccess.h + * + * Object access hooks. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + */ + +#ifndef OBJECTACCESS_H +#define OBJECTACCESS_H + +/* + * Object access hooks are intended to be called just before or just after + * performing certain actions on a SQL object. This is intended as + * infrastructure for security or logging plugins. + * + * OAT_POST_CREATE should be invoked just after the object is created. + * Typically, this is done after inserting the primary catalog records and + * associated dependencies. The command counter may or may not be incremented + * at the time the hook is invoked; if not, the extension can use SnapshotSelf + * to get the new version of the tuple. + * + * OAT_DROP should be invoked just before deletion of objects; typically + * deleteOneObject(). Its arguments are packed within ObjectAccessDrop. + * + * OAT_POST_ALTER should be invoked just after the object is altered, + * but before the command counter is incremented. An extension using the + * hook can use a current MVCC snapshot to get the old version of the tuple, + * and can use SnapshotSelf to get the new version of the tuple. + * + * OAT_NAMESPACE_SEARCH should be invoked prior to object name lookup under + * a particular namespace. This event is equivalent to usage permission + * on a schema under the default access control mechanism. + * + * OAT_FUNCTION_EXECUTE should be invoked prior to function execution. + * This event is almost equivalent to execute permission on functions, + * except for the case when execute permission is checked during object + * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are + * sufficient for extensions to track these kind of checks. + * + * OAT_TRUNCATE should be invoked just before truncation of objects. This + * event is equivalent to truncate permission on a relation under the + * default access control mechanism. + * + * Other types may be added in the future. + */ +typedef enum ObjectAccessType +{ + OAT_POST_CREATE, + OAT_DROP, + OAT_POST_ALTER, + OAT_NAMESPACE_SEARCH, + OAT_FUNCTION_EXECUTE, + OAT_TRUNCATE +} ObjectAccessType; + +/* + * Arguments of OAT_POST_CREATE event + */ +typedef struct +{ + /* + * This flag informs extensions whether the context of this creation is + * invoked by user's operations, or not. E.g, it shall be dealt as + * internal stuff on toast tables or indexes due to type changes. + */ + bool is_internal; +} ObjectAccessPostCreate; + +/* + * Arguments of OAT_DROP event + */ +typedef struct +{ + /* + * Flags to inform extensions the context of this deletion. Also see + * PERFORM_DELETION_* in dependency.h + */ + int dropflags; +} ObjectAccessDrop; + +/* + * Arguments of OAT_POST_ALTER event + */ +typedef struct +{ + /* + * This identifier is used when system catalog takes two IDs to identify a + * particular tuple of the catalog. It is only used when the caller want + * to identify an entry of pg_inherits, pg_db_role_setting or + * pg_user_mapping. Elsewhere, InvalidOid should be set. + */ + Oid auxiliary_id; + + /* + * If this flag is set, the user hasn't requested that the object be + * altered, but we're doing it anyway for some internal reason. + * Permissions-checking hooks may want to skip checks if, say, we're alter + * the constraints of a temporary heap during CLUSTER. + */ + bool is_internal; +} ObjectAccessPostAlter; + +/* + * Arguments of OAT_NAMESPACE_SEARCH + */ +typedef struct +{ + /* + * If true, hook should report an error when permission to search this + * schema is denied. + */ + bool ereport_on_violation; + + /* + * This is, in essence, an out parameter. Core code should initialize + * this to true, and any extension that wants to deny access should reset + * it to false. But an extension should be careful never to store a true + * value here, so that in case there are multiple extensions access is + * only allowed if all extensions agree. + */ + bool result; +} ObjectAccessNamespaceSearch; + +/* Plugin provides a hook function matching one or both of these signatures. */ +typedef void (*object_access_hook_type) (ObjectAccessType access, + Oid classId, + Oid objectId, + int subId, + void *arg); + +typedef void (*object_access_hook_type_str) (ObjectAccessType access, + Oid classId, + const char *objectStr, + int subId, + void *arg); + +/* Plugin sets this variable to a suitable hook function. */ +extern PGDLLIMPORT object_access_hook_type object_access_hook; +extern PGDLLIMPORT object_access_hook_type_str object_access_hook_str; + + +/* Core code uses these functions to call the hook (see macros below). */ +extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId, + bool is_internal); +extern void RunObjectDropHook(Oid classId, Oid objectId, int subId, + int dropflags); +extern void RunObjectTruncateHook(Oid objectId); +extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId, + Oid auxiliaryId, bool is_internal); +extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation); +extern void RunFunctionExecuteHook(Oid objectId); + +/* String versions */ +extern void RunObjectPostCreateHookStr(Oid classId, const char *objectName, int subId, + bool is_internal); +extern void RunObjectDropHookStr(Oid classId, const char *objectName, int subId, + int dropflags); +extern void RunObjectTruncateHookStr(const char *objectName); +extern void RunObjectPostAlterHookStr(Oid classId, const char *objectName, int subId, + Oid auxiliaryId, bool is_internal); +extern bool RunNamespaceSearchHookStr(const char *objectName, bool ereport_on_violation); +extern void RunFunctionExecuteHookStr(const char *objectName); + + +/* + * The following macros are wrappers around the functions above; these should + * normally be used to invoke the hook in lieu of calling the above functions + * directly. + */ + +#define InvokeObjectPostCreateHook(classId,objectId,subId) \ + InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false) +#define InvokeObjectPostCreateHookArg(classId,objectId,subId,is_internal) \ + do { \ + if (object_access_hook) \ + RunObjectPostCreateHook((classId),(objectId),(subId), \ + (is_internal)); \ + } while(0) + +#define InvokeObjectDropHook(classId,objectId,subId) \ + InvokeObjectDropHookArg((classId),(objectId),(subId),0) +#define InvokeObjectDropHookArg(classId,objectId,subId,dropflags) \ + do { \ + if (object_access_hook) \ + RunObjectDropHook((classId),(objectId),(subId), \ + (dropflags)); \ + } while(0) + +#define InvokeObjectTruncateHook(objectId) \ + do { \ + if (object_access_hook) \ + RunObjectTruncateHook(objectId); \ + } while(0) + +#define InvokeObjectPostAlterHook(classId,objectId,subId) \ + InvokeObjectPostAlterHookArg((classId),(objectId),(subId), \ + InvalidOid,false) +#define InvokeObjectPostAlterHookArg(classId,objectId,subId, \ + auxiliaryId,is_internal) \ + do { \ + if (object_access_hook) \ + RunObjectPostAlterHook((classId),(objectId),(subId), \ + (auxiliaryId),(is_internal)); \ + } while(0) + +#define InvokeNamespaceSearchHook(objectId, ereport_on_violation) \ + (!object_access_hook \ + ? true \ + : RunNamespaceSearchHook((objectId), (ereport_on_violation))) + +#define InvokeFunctionExecuteHook(objectId) \ + do { \ + if (object_access_hook) \ + RunFunctionExecuteHook(objectId); \ + } while(0) + + +#define InvokeObjectPostCreateHookStr(classId,objectName,subId) \ + InvokeObjectPostCreateHookArgStr((classId),(objectName),(subId),false) +#define InvokeObjectPostCreateHookArgStr(classId,objectName,subId,is_internal) \ + do { \ + if (object_access_hook_str) \ + RunObjectPostCreateHookStr((classId),(objectName),(subId), \ + (is_internal)); \ + } while(0) + +#define InvokeObjectDropHookStr(classId,objectName,subId) \ + InvokeObjectDropHookArgStr((classId),(objectName),(subId),0) +#define InvokeObjectDropHookArgStr(classId,objectName,subId,dropflags) \ + do { \ + if (object_access_hook_str) \ + RunObjectDropHookStr((classId),(objectName),(subId), \ + (dropflags)); \ + } while(0) + +#define InvokeObjectTruncateHookStr(objectName) \ + do { \ + if (object_access_hook_str) \ + RunObjectTruncateHookStr(objectName); \ + } while(0) + +#define InvokeObjectPostAlterHookStr(classId,objectName,subId) \ + InvokeObjectPostAlterHookArgStr((classId),(objectName),(subId), \ + InvalidOid,false) +#define InvokeObjectPostAlterHookArgStr(classId,objectName,subId, \ + auxiliaryId,is_internal) \ + do { \ + if (object_access_hook_str) \ + RunObjectPostAlterHookStr((classId),(objectName),(subId), \ + (auxiliaryId),(is_internal)); \ + } while(0) + +#define InvokeNamespaceSearchHookStr(objectName, ereport_on_violation) \ + (!object_access_hook_str \ + ? true \ + : RunNamespaceSearchHookStr((objectName), (ereport_on_violation))) + +#define InvokeFunctionExecuteHookStr(objectName) \ + do { \ + if (object_access_hook_str) \ + RunFunctionExecuteHookStr(objectName); \ + } while(0) + + +#endif /* OBJECTACCESS_H */ diff --git a/install/include/postgresql/server/catalog/objectaddress.h b/install/include/postgresql/server/catalog/objectaddress.h new file mode 100644 index 00000000000..c387860813d --- /dev/null +++ b/install/include/postgresql/server/catalog/objectaddress.h @@ -0,0 +1,93 @@ +/*------------------------------------------------------------------------- + * + * objectaddress.h + * functions for working with object addresses + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/objectaddress.h + * + *------------------------------------------------------------------------- + */ +#ifndef OBJECTADDRESS_H +#define OBJECTADDRESS_H + +#include "access/htup.h" +#include "nodes/parsenodes.h" +#include "storage/lockdefs.h" +#include "utils/relcache.h" + +/* + * An ObjectAddress represents a database object of any type. + */ +typedef struct ObjectAddress +{ + Oid classId; /* Class Id from pg_class */ + Oid objectId; /* OID of the object */ + int32 objectSubId; /* Subitem within object (eg column), or 0 */ +} ObjectAddress; + +extern PGDLLIMPORT const ObjectAddress InvalidObjectAddress; + +#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id) \ + do { \ + (addr).classId = (class_id); \ + (addr).objectId = (object_id); \ + (addr).objectSubId = (object_sub_id); \ + } while (0) + +#define ObjectAddressSet(addr, class_id, object_id) \ + ObjectAddressSubSet(addr, class_id, object_id, 0) + +extern ObjectAddress get_object_address(ObjectType objtype, Node *object, + Relation *relp, + LOCKMODE lockmode, bool missing_ok); + +extern ObjectAddress get_object_address_rv(ObjectType objtype, RangeVar *rel, + List *object, Relation *relp, + LOCKMODE lockmode, bool missing_ok); + +extern void check_object_ownership(Oid roleid, + ObjectType objtype, ObjectAddress address, + Node *object, Relation relation); + +extern Oid get_object_namespace(const ObjectAddress *address); + +extern bool is_objectclass_supported(Oid class_id); +extern const char *get_object_class_descr(Oid class_id); +extern Oid get_object_oid_index(Oid class_id); +extern int get_object_catcache_oid(Oid class_id); +extern int get_object_catcache_name(Oid class_id); +extern AttrNumber get_object_attnum_oid(Oid class_id); +extern AttrNumber get_object_attnum_name(Oid class_id); +extern AttrNumber get_object_attnum_namespace(Oid class_id); +extern AttrNumber get_object_attnum_owner(Oid class_id); +extern AttrNumber get_object_attnum_acl(Oid class_id); +extern ObjectType get_object_type(Oid class_id, Oid object_id); +extern bool get_object_namensp_unique(Oid class_id); + +extern HeapTuple get_catalog_object_by_oid(Relation catalog, + AttrNumber oidcol, Oid objectId); +extern HeapTuple get_catalog_object_by_oid_extended(Relation catalog, + AttrNumber oidcol, + Oid objectId, + bool locktup); + +extern char *getObjectDescription(const ObjectAddress *object, + bool missing_ok); +extern char *getObjectDescriptionOids(Oid classid, Oid objid); + +extern int read_objtype_from_string(const char *objtype); +extern char *getObjectTypeDescription(const ObjectAddress *object, + bool missing_ok); +extern char *getObjectIdentity(const ObjectAddress *object, + bool missing_ok); +extern char *getObjectIdentityParts(const ObjectAddress *object, + List **objname, List **objargs, + bool missing_ok); +extern struct ArrayType *strlist_to_textarray(List *list); + +extern ObjectType get_relkind_objtype(char relkind); + +#endif /* OBJECTADDRESS_H */ diff --git a/install/include/postgresql/server/catalog/partition.h b/install/include/postgresql/server/catalog/partition.h new file mode 100644 index 00000000000..79ce7118023 --- /dev/null +++ b/install/include/postgresql/server/catalog/partition.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * partition.h + * Header file for structures and utility functions related to + * partitioning + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/include/catalog/partition.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARTITION_H +#define PARTITION_H + +#include "partitioning/partdefs.h" +#include "utils/relcache.h" + +/* Seed for the extended hash function */ +#define HASH_PARTITION_SEED UINT64CONST(0x7A5B22367996DCFD) + +extern Oid get_partition_parent(Oid relid, bool even_if_detached); +extern List *get_partition_ancestors(Oid relid); +extern Oid index_get_partition(Relation partition, Oid indexId); +extern List *map_partition_varattnos(List *expr, int fromrel_varno, + Relation to_rel, Relation from_rel); +extern bool has_partition_attrs(Relation rel, Bitmapset *attnums, + bool *used_in_expr); + +extern Oid get_default_partition_oid(Oid parentId); +extern void update_default_partition_oid(Oid parentId, Oid defaultPartId); +extern List *get_proposed_default_constraint(List *new_part_constraints); + +#endif /* PARTITION_H */ diff --git a/install/include/postgresql/server/catalog/pg_aggregate.h b/install/include/postgresql/server/catalog/pg_aggregate.h new file mode 100644 index 00000000000..31128811936 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_aggregate.h @@ -0,0 +1,180 @@ +/*------------------------------------------------------------------------- + * + * pg_aggregate.h + * definition of the "aggregate" system catalog (pg_aggregate) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_aggregate.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AGGREGATE_H +#define PG_AGGREGATE_H + +#include "catalog/genbki.h" +#include "catalog/pg_aggregate_d.h" + +#include "catalog/objectaddress.h" +#include "nodes/pg_list.h" + +/* ---------------------------------------------------------------- + * pg_aggregate definition. + * cpp turns this into typedef struct FormData_pg_aggregate + * ---------------------------------------------------------------- + */ +CATALOG(pg_aggregate,2600,AggregateRelationId) +{ + /* pg_proc OID of the aggregate itself */ + regproc aggfnoid BKI_LOOKUP(pg_proc); + + /* aggregate kind, see AGGKIND_ categories below */ + char aggkind BKI_DEFAULT(n); + + /* number of arguments that are "direct" arguments */ + int16 aggnumdirectargs BKI_DEFAULT(0); + + /* transition function */ + regproc aggtransfn BKI_LOOKUP(pg_proc); + + /* final function (0 if none) */ + regproc aggfinalfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* combine function (0 if none) */ + regproc aggcombinefn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* function to convert transtype to bytea (0 if none) */ + regproc aggserialfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* function to convert bytea to transtype (0 if none) */ + regproc aggdeserialfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* forward function for moving-aggregate mode (0 if none) */ + regproc aggmtransfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* inverse function for moving-aggregate mode (0 if none) */ + regproc aggminvtransfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* final function for moving-aggregate mode (0 if none) */ + regproc aggmfinalfn BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* true to pass extra dummy arguments to aggfinalfn */ + bool aggfinalextra BKI_DEFAULT(f); + + /* true to pass extra dummy arguments to aggmfinalfn */ + bool aggmfinalextra BKI_DEFAULT(f); + + /* tells whether aggfinalfn modifies transition state */ + char aggfinalmodify BKI_DEFAULT(r); + + /* tells whether aggmfinalfn modifies transition state */ + char aggmfinalmodify BKI_DEFAULT(r); + + /* associated sort operator (0 if none) */ + Oid aggsortop BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_operator); + + /* type of aggregate's transition (state) data */ + Oid aggtranstype BKI_LOOKUP(pg_type); + + /* estimated size of state data (0 for default estimate) */ + int32 aggtransspace BKI_DEFAULT(0); + + /* type of moving-aggregate state data (0 if none) */ + Oid aggmtranstype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); + + /* estimated size of moving-agg state (0 for default est) */ + int32 aggmtransspace BKI_DEFAULT(0); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + + /* initial value for transition state (can be NULL) */ + text agginitval BKI_DEFAULT(_null_); + + /* initial value for moving-agg state (can be NULL) */ + text aggminitval BKI_DEFAULT(_null_); +#endif +} FormData_pg_aggregate; + +/* ---------------- + * Form_pg_aggregate corresponds to a pointer to a tuple with + * the format of pg_aggregate relation. + * ---------------- + */ +typedef FormData_pg_aggregate *Form_pg_aggregate; + +DECLARE_TOAST(pg_aggregate, 4159, 4160); + +DECLARE_UNIQUE_INDEX_PKEY(pg_aggregate_fnoid_index, 2650, AggregateFnoidIndexId, on pg_aggregate using btree(aggfnoid oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * Symbolic values for aggkind column. We distinguish normal aggregates + * from ordered-set aggregates (which have two sets of arguments, namely + * direct and aggregated arguments) and from hypothetical-set aggregates + * (which are a subclass of ordered-set aggregates in which the last + * direct arguments have to match up in number and datatypes with the + * aggregated arguments). + */ +#define AGGKIND_NORMAL 'n' +#define AGGKIND_ORDERED_SET 'o' +#define AGGKIND_HYPOTHETICAL 'h' + +/* Use this macro to test for "ordered-set agg including hypothetical case" */ +#define AGGKIND_IS_ORDERED_SET(kind) ((kind) != AGGKIND_NORMAL) + +/* + * Symbolic values for aggfinalmodify and aggmfinalmodify columns. + * Preferably, finalfns do not modify the transition state value at all, + * but in some cases that would cost too much performance. We distinguish + * "pure read only" and "trashes it arbitrarily" cases, as well as the + * intermediate case where multiple finalfn calls are allowed but the + * transfn cannot be applied anymore after the first finalfn call. + */ +#define AGGMODIFY_READ_ONLY 'r' +#define AGGMODIFY_SHAREABLE 's' +#define AGGMODIFY_READ_WRITE 'w' + +#endif /* EXPOSE_TO_CLIENT_CODE */ + + +extern ObjectAddress AggregateCreate(const char *aggName, + Oid aggNamespace, + bool replace, + char aggKind, + int numArgs, + int numDirectArgs, + oidvector *parameterTypes, + Datum allParameterTypes, + Datum parameterModes, + Datum parameterNames, + List *parameterDefaults, + Oid variadicArgType, + List *aggtransfnName, + List *aggfinalfnName, + List *aggcombinefnName, + List *aggserialfnName, + List *aggdeserialfnName, + List *aggmtransfnName, + List *aggminvtransfnName, + List *aggmfinalfnName, + bool finalfnExtraArgs, + bool mfinalfnExtraArgs, + char finalfnModify, + char mfinalfnModify, + List *aggsortopName, + Oid aggTransType, + int32 aggTransSpace, + Oid aggmTransType, + int32 aggmTransSpace, + const char *agginitval, + const char *aggminitval, + char proparallel); + +#endif /* PG_AGGREGATE_H */ diff --git a/install/include/postgresql/server/catalog/pg_aggregate_d.h b/install/include/postgresql/server/catalog/pg_aggregate_d.h new file mode 100644 index 00000000000..b39c740b575 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_aggregate_d.h @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------- + * + * pg_aggregate_d.h + * Macro definitions for pg_aggregate + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AGGREGATE_D_H +#define PG_AGGREGATE_D_H + +#define AggregateRelationId 2600 +#define AggregateFnoidIndexId 2650 + +#define Anum_pg_aggregate_aggfnoid 1 +#define Anum_pg_aggregate_aggkind 2 +#define Anum_pg_aggregate_aggnumdirectargs 3 +#define Anum_pg_aggregate_aggtransfn 4 +#define Anum_pg_aggregate_aggfinalfn 5 +#define Anum_pg_aggregate_aggcombinefn 6 +#define Anum_pg_aggregate_aggserialfn 7 +#define Anum_pg_aggregate_aggdeserialfn 8 +#define Anum_pg_aggregate_aggmtransfn 9 +#define Anum_pg_aggregate_aggminvtransfn 10 +#define Anum_pg_aggregate_aggmfinalfn 11 +#define Anum_pg_aggregate_aggfinalextra 12 +#define Anum_pg_aggregate_aggmfinalextra 13 +#define Anum_pg_aggregate_aggfinalmodify 14 +#define Anum_pg_aggregate_aggmfinalmodify 15 +#define Anum_pg_aggregate_aggsortop 16 +#define Anum_pg_aggregate_aggtranstype 17 +#define Anum_pg_aggregate_aggtransspace 18 +#define Anum_pg_aggregate_aggmtranstype 19 +#define Anum_pg_aggregate_aggmtransspace 20 +#define Anum_pg_aggregate_agginitval 21 +#define Anum_pg_aggregate_aggminitval 22 + +#define Natts_pg_aggregate 22 + + +/* + * Symbolic values for aggkind column. We distinguish normal aggregates + * from ordered-set aggregates (which have two sets of arguments, namely + * direct and aggregated arguments) and from hypothetical-set aggregates + * (which are a subclass of ordered-set aggregates in which the last + * direct arguments have to match up in number and datatypes with the + * aggregated arguments). + */ +#define AGGKIND_NORMAL 'n' +#define AGGKIND_ORDERED_SET 'o' +#define AGGKIND_HYPOTHETICAL 'h' + +/* Use this macro to test for "ordered-set agg including hypothetical case" */ +#define AGGKIND_IS_ORDERED_SET(kind) ((kind) != AGGKIND_NORMAL) + +/* + * Symbolic values for aggfinalmodify and aggmfinalmodify columns. + * Preferably, finalfns do not modify the transition state value at all, + * but in some cases that would cost too much performance. We distinguish + * "pure read only" and "trashes it arbitrarily" cases, as well as the + * intermediate case where multiple finalfn calls are allowed but the + * transfn cannot be applied anymore after the first finalfn call. + */ +#define AGGMODIFY_READ_ONLY 'r' +#define AGGMODIFY_SHAREABLE 's' +#define AGGMODIFY_READ_WRITE 'w' + + +#endif /* PG_AGGREGATE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_am.h b/install/include/postgresql/server/catalog/pg_am.h new file mode 100644 index 00000000000..dab54be130c --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_am.h @@ -0,0 +1,63 @@ +/*------------------------------------------------------------------------- + * + * pg_am.h + * definition of the "access method" system catalog (pg_am) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_am.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AM_H +#define PG_AM_H + +#include "catalog/genbki.h" +#include "catalog/pg_am_d.h" + +/* ---------------- + * pg_am definition. cpp turns this into + * typedef struct FormData_pg_am + * ---------------- + */ +CATALOG(pg_am,2601,AccessMethodRelationId) +{ + Oid oid; /* oid */ + + /* access method name */ + NameData amname; + + /* handler function */ + regproc amhandler BKI_LOOKUP(pg_proc); + + /* see AMTYPE_xxx constants below */ + char amtype; +} FormData_pg_am; + +/* ---------------- + * Form_pg_am corresponds to a pointer to a tuple with + * the format of pg_am relation. + * ---------------- + */ +typedef FormData_pg_am *Form_pg_am; + +DECLARE_UNIQUE_INDEX(pg_am_name_index, 2651, AmNameIndexId, on pg_am using btree(amname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_am_oid_index, 2652, AmOidIndexId, on pg_am using btree(oid oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * Allowed values for amtype + */ +#define AMTYPE_INDEX 'i' /* index access method */ +#define AMTYPE_TABLE 't' /* table access method */ + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_AM_H */ diff --git a/install/include/postgresql/server/catalog/pg_am_d.h b/install/include/postgresql/server/catalog/pg_am_d.h new file mode 100644 index 00000000000..7059591de4b --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_am_d.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * pg_am_d.h + * Macro definitions for pg_am + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AM_D_H +#define PG_AM_D_H + +#define AccessMethodRelationId 2601 +#define AmNameIndexId 2651 +#define AmOidIndexId 2652 + +#define Anum_pg_am_oid 1 +#define Anum_pg_am_amname 2 +#define Anum_pg_am_amhandler 3 +#define Anum_pg_am_amtype 4 + +#define Natts_pg_am 4 + + +/* + * Allowed values for amtype + */ +#define AMTYPE_INDEX 'i' /* index access method */ +#define AMTYPE_TABLE 't' /* table access method */ + +#define HEAP_TABLE_AM_OID 2 +#define BTREE_AM_OID 403 +#define HASH_AM_OID 405 +#define GIST_AM_OID 783 +#define GIN_AM_OID 2742 +#define SPGIST_AM_OID 4000 +#define BRIN_AM_OID 3580 + +#endif /* PG_AM_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_amop.h b/install/include/postgresql/server/catalog/pg_amop.h new file mode 100644 index 00000000000..4ca7321409b --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_amop.h @@ -0,0 +1,102 @@ +/*------------------------------------------------------------------------- + * + * pg_amop.h + * definition of the "access method operator" system catalog (pg_amop) + * + * The amop table identifies the operators associated with each index operator + * family and operator class (classes are subsets of families). An associated + * operator can be either a search operator or an ordering operator, as + * identified by amoppurpose. + * + * The primary key for this table is . amoplefttype and amoprighttype are just copies of the + * operator's oprleft/oprright, ie its declared input data types. The + * "default" operators for a particular opclass within the family are those + * with amoplefttype = amoprighttype = opclass's opcintype. An opfamily may + * also contain other operators, typically cross-data-type operators. All the + * operators within a family are supposed to be compatible, in a way that is + * defined by each individual index AM. + * + * We also keep a unique index on , so that + * we can use a syscache to quickly answer questions of the form "is this + * operator in this opfamily, and if so what are its semantics with respect to + * the family?" This implies that the same operator cannot be listed for + * multiple strategy numbers within a single opfamily, with the exception that + * it's possible to list it for both search and ordering purposes (with + * different strategy numbers for the two purposes). + * + * amopmethod is a copy of the owning opfamily's opfmethod field. This is an + * intentional denormalization of the catalogs to buy lookup speed. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_amop.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AMOP_H +#define PG_AMOP_H + +#include "catalog/genbki.h" +#include "catalog/pg_amop_d.h" + +/* ---------------- + * pg_amop definition. cpp turns this into + * typedef struct FormData_pg_amop + * ---------------- + */ +CATALOG(pg_amop,2602,AccessMethodOperatorRelationId) +{ + Oid oid; /* oid */ + + /* the index opfamily this entry is for */ + Oid amopfamily BKI_LOOKUP(pg_opfamily); + + /* operator's left input data type */ + Oid amoplefttype BKI_LOOKUP(pg_type); + + /* operator's right input data type */ + Oid amoprighttype BKI_LOOKUP(pg_type); + + /* operator strategy number */ + int16 amopstrategy; + + /* is operator for 's'earch or 'o'rdering? */ + char amoppurpose BKI_DEFAULT(s); + + /* the operator's pg_operator OID */ + Oid amopopr BKI_LOOKUP(pg_operator); + + /* the index access method this entry is for */ + Oid amopmethod BKI_LOOKUP(pg_am); + + /* ordering opfamily OID, or 0 if search op */ + Oid amopsortfamily BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_opfamily); +} FormData_pg_amop; + +/* ---------------- + * Form_pg_amop corresponds to a pointer to a tuple with + * the format of pg_amop relation. + * ---------------- + */ +typedef FormData_pg_amop *Form_pg_amop; + +DECLARE_UNIQUE_INDEX(pg_amop_fam_strat_index, 2653, AccessMethodStrategyIndexId, on pg_amop using btree(amopfamily oid_ops, amoplefttype oid_ops, amoprighttype oid_ops, amopstrategy int2_ops)); +DECLARE_UNIQUE_INDEX(pg_amop_opr_fam_index, 2654, AccessMethodOperatorIndexId, on pg_amop using btree(amopopr oid_ops, amoppurpose char_ops, amopfamily oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_amop_oid_index, 2756, AccessMethodOperatorOidIndexId, on pg_amop using btree(oid oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* allowed values of amoppurpose: */ +#define AMOP_SEARCH 's' /* operator is for search */ +#define AMOP_ORDER 'o' /* operator is for ordering */ + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_AMOP_H */ diff --git a/install/include/postgresql/server/catalog/pg_amop_d.h b/install/include/postgresql/server/catalog/pg_amop_d.h new file mode 100644 index 00000000000..0e0d523eff8 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_amop_d.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * pg_amop_d.h + * Macro definitions for pg_amop + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AMOP_D_H +#define PG_AMOP_D_H + +#define AccessMethodOperatorRelationId 2602 +#define AccessMethodStrategyIndexId 2653 +#define AccessMethodOperatorIndexId 2654 +#define AccessMethodOperatorOidIndexId 2756 + +#define Anum_pg_amop_oid 1 +#define Anum_pg_amop_amopfamily 2 +#define Anum_pg_amop_amoplefttype 3 +#define Anum_pg_amop_amoprighttype 4 +#define Anum_pg_amop_amopstrategy 5 +#define Anum_pg_amop_amoppurpose 6 +#define Anum_pg_amop_amopopr 7 +#define Anum_pg_amop_amopmethod 8 +#define Anum_pg_amop_amopsortfamily 9 + +#define Natts_pg_amop 9 + + +/* allowed values of amoppurpose: */ +#define AMOP_SEARCH 's' /* operator is for search */ +#define AMOP_ORDER 'o' /* operator is for ordering */ + + +#endif /* PG_AMOP_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_amproc.h b/install/include/postgresql/server/catalog/pg_amproc.h new file mode 100644 index 00000000000..3307d5c8447 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_amproc.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * pg_amproc.h + * definition of the "access method procedure" system catalog (pg_amproc) + * + * The amproc table identifies support procedures associated with index + * operator families and classes. These procedures can't be listed in pg_amop + * since they are not the implementation of any indexable operator. + * + * The primary key for this table is . The "default" support functions for a + * particular opclass within the family are those with amproclefttype = + * amprocrighttype = opclass's opcintype. These are the ones loaded into the + * relcache for an index and typically used for internal index operations. + * Other support functions are typically used to handle cross-type indexable + * operators with oprleft/oprright matching the entry's amproclefttype and + * amprocrighttype. The exact behavior depends on the index AM, however, and + * some don't pay attention to non-default functions at all. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_amproc.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AMPROC_H +#define PG_AMPROC_H + +#include "catalog/genbki.h" +#include "catalog/pg_amproc_d.h" + +/* ---------------- + * pg_amproc definition. cpp turns this into + * typedef struct FormData_pg_amproc + * ---------------- + */ +CATALOG(pg_amproc,2603,AccessMethodProcedureRelationId) +{ + Oid oid; /* oid */ + + /* the index opfamily this entry is for */ + Oid amprocfamily BKI_LOOKUP(pg_opfamily); + + /* procedure's left input data type */ + Oid amproclefttype BKI_LOOKUP(pg_type); + + /* procedure's right input data type */ + Oid amprocrighttype BKI_LOOKUP(pg_type); + + /* support procedure index */ + int16 amprocnum; + + /* OID of the proc */ + regproc amproc BKI_LOOKUP(pg_proc); +} FormData_pg_amproc; + +/* ---------------- + * Form_pg_amproc corresponds to a pointer to a tuple with + * the format of pg_amproc relation. + * ---------------- + */ +typedef FormData_pg_amproc *Form_pg_amproc; + +DECLARE_UNIQUE_INDEX(pg_amproc_fam_proc_index, 2655, AccessMethodProcedureIndexId, on pg_amproc using btree(amprocfamily oid_ops, amproclefttype oid_ops, amprocrighttype oid_ops, amprocnum int2_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_amproc_oid_index, 2757, AccessMethodProcedureOidIndexId, on pg_amproc using btree(oid oid_ops)); + +#endif /* PG_AMPROC_H */ diff --git a/install/include/postgresql/server/catalog/pg_amproc_d.h b/install/include/postgresql/server/catalog/pg_amproc_d.h new file mode 100644 index 00000000000..41e9b5cfa76 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_amproc_d.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * pg_amproc_d.h + * Macro definitions for pg_amproc + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AMPROC_D_H +#define PG_AMPROC_D_H + +#define AccessMethodProcedureRelationId 2603 +#define AccessMethodProcedureIndexId 2655 +#define AccessMethodProcedureOidIndexId 2757 + +#define Anum_pg_amproc_oid 1 +#define Anum_pg_amproc_amprocfamily 2 +#define Anum_pg_amproc_amproclefttype 3 +#define Anum_pg_amproc_amprocrighttype 4 +#define Anum_pg_amproc_amprocnum 5 +#define Anum_pg_amproc_amproc 6 + +#define Natts_pg_amproc 6 + + +#endif /* PG_AMPROC_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_attrdef.h b/install/include/postgresql/server/catalog/pg_attrdef.h new file mode 100644 index 00000000000..9dc318ff939 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_attrdef.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------- + * + * pg_attrdef.h + * definition of the "attribute defaults" system catalog (pg_attrdef) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_attrdef.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_ATTRDEF_H +#define PG_ATTRDEF_H + +#include "catalog/genbki.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_attrdef_d.h" + +/* ---------------- + * pg_attrdef definition. cpp turns this into + * typedef struct FormData_pg_attrdef + * ---------------- + */ +CATALOG(pg_attrdef,2604,AttrDefaultRelationId) +{ + Oid oid; /* oid */ + + Oid adrelid BKI_LOOKUP(pg_class); /* OID of table containing + * attribute */ + int16 adnum; /* attnum of attribute */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + pg_node_tree adbin BKI_FORCE_NOT_NULL; /* nodeToString representation of + * default */ +#endif +} FormData_pg_attrdef; + +/* ---------------- + * Form_pg_attrdef corresponds to a pointer to a tuple with + * the format of pg_attrdef relation. + * ---------------- + */ +typedef FormData_pg_attrdef *Form_pg_attrdef; + +DECLARE_TOAST(pg_attrdef, 2830, 2831); + +DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index, 2656, AttrDefaultIndexId, on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_attrdef_oid_index, 2657, AttrDefaultOidIndexId, on pg_attrdef using btree(oid oid_ops)); + +DECLARE_FOREIGN_KEY((adrelid, adnum), pg_attribute, (attrelid, attnum)); + + +extern Oid StoreAttrDefault(Relation rel, AttrNumber attnum, + Node *expr, bool is_internal, + bool add_column_mode); +extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, + DropBehavior behavior, + bool complain, bool internal); +extern void RemoveAttrDefaultById(Oid attrdefId); + +extern Oid GetAttrDefaultOid(Oid relid, AttrNumber attnum); +extern ObjectAddress GetAttrDefaultColumnAddress(Oid attrdefoid); + +#endif /* PG_ATTRDEF_H */ diff --git a/install/include/postgresql/server/catalog/pg_attrdef_d.h b/install/include/postgresql/server/catalog/pg_attrdef_d.h new file mode 100644 index 00000000000..5221914afa5 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_attrdef_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_attrdef_d.h + * Macro definitions for pg_attrdef + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_ATTRDEF_D_H +#define PG_ATTRDEF_D_H + +#define AttrDefaultRelationId 2604 +#define AttrDefaultIndexId 2656 +#define AttrDefaultOidIndexId 2657 + +#define Anum_pg_attrdef_oid 1 +#define Anum_pg_attrdef_adrelid 2 +#define Anum_pg_attrdef_adnum 3 +#define Anum_pg_attrdef_adbin 4 + +#define Natts_pg_attrdef 4 + + +#endif /* PG_ATTRDEF_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_attribute.h b/install/include/postgresql/server/catalog/pg_attribute.h new file mode 100644 index 00000000000..f8b4861b94a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_attribute.h @@ -0,0 +1,223 @@ +/*------------------------------------------------------------------------- + * + * pg_attribute.h + * definition of the "attribute" system catalog (pg_attribute) + * + * The initial contents of pg_attribute are generated at compile time by + * genbki.pl, so there is no pg_attribute.dat file. Only "bootstrapped" + * relations need be included. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_attribute.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_ATTRIBUTE_H +#define PG_ATTRIBUTE_H + +#include "catalog/genbki.h" +#include "catalog/pg_attribute_d.h" + +/* ---------------- + * pg_attribute definition. cpp turns this into + * typedef struct FormData_pg_attribute + * + * If you change the following, make sure you change the structs for + * system attributes in catalog/heap.c also. + * You may need to change catalog/genbki.pl as well. + * ---------------- + */ +CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,AttributeRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + Oid attrelid BKI_LOOKUP(pg_class); /* OID of relation containing + * this attribute */ + NameData attname; /* name of attribute */ + + /* + * atttypid is the OID of the instance in Catalog Class pg_type that + * defines the data type of this attribute (e.g. int4). Information in + * that instance is redundant with the attlen, attbyval, and attalign + * attributes of this instance, so they had better match or Postgres will + * fail. In an entry for a dropped column, this field is set to zero + * since the pg_type entry may no longer exist; but we rely on attlen, + * attbyval, and attalign to still tell us how large the values in the + * table are. + */ + Oid atttypid BKI_LOOKUP_OPT(pg_type); + + /* + * attlen is a copy of the typlen field from pg_type for this attribute. + * See atttypid comments above. + */ + int16 attlen; + + /* + * attnum is the "attribute number" for the attribute: A value that + * uniquely identifies this attribute within its class. For user + * attributes, Attribute numbers are greater than 0 and not greater than + * the number of attributes in the class. I.e. if the Class pg_class says + * that Class XYZ has 10 attributes, then the user attribute numbers in + * Class pg_attribute must be 1-10. + * + * System attributes have attribute numbers less than 0 that are unique + * within the class, but not constrained to any particular range. + * + * Note that (attnum - 1) is often used as the index to an array. + */ + int16 attnum; + + /* + * fastgetattr() uses attcacheoff to cache byte offsets of attributes in + * heap tuples. The value actually stored in pg_attribute (-1) indicates + * no cached value. But when we copy these tuples into a tuple + * descriptor, we may then update attcacheoff in the copies. This speeds + * up the attribute walking process. + */ + int32 attcacheoff BKI_DEFAULT(-1); + + /* + * atttypmod records type-specific data supplied at table creation time + * (for example, the max length of a varchar field). It is passed to + * type-specific input and output functions as the third argument. The + * value will generally be -1 for types that do not need typmod. + */ + int32 atttypmod BKI_DEFAULT(-1); + + /* + * attndims is the declared number of dimensions, if an array type, + * otherwise zero. + */ + int16 attndims; + + /* + * attbyval is a copy of the typbyval field from pg_type for this + * attribute. See atttypid comments above. + */ + bool attbyval; + + /* + * attalign is a copy of the typalign field from pg_type for this + * attribute. See atttypid comments above. + */ + char attalign; + + /*---------- + * attstorage tells for VARLENA attributes, what the heap access + * methods can do to it if a given tuple doesn't fit into a page. + * Possible values are as for pg_type.typstorage (see TYPSTORAGE macros). + *---------- + */ + char attstorage; + + /* + * attcompression sets the current compression method of the attribute. + * Typically this is InvalidCompressionMethod ('\0') to specify use of the + * current default setting (see default_toast_compression). Otherwise, + * 'p' selects pglz compression, while 'l' selects LZ4 compression. + * However, this field is ignored whenever attstorage does not allow + * compression. + */ + char attcompression BKI_DEFAULT('\0'); + + /* This flag represents the "NOT NULL" constraint */ + bool attnotnull; + + /* Has DEFAULT value or not */ + bool atthasdef BKI_DEFAULT(f); + + /* Has a missing value or not */ + bool atthasmissing BKI_DEFAULT(f); + + /* One of the ATTRIBUTE_IDENTITY_* constants below, or '\0' */ + char attidentity BKI_DEFAULT('\0'); + + /* One of the ATTRIBUTE_GENERATED_* constants below, or '\0' */ + char attgenerated BKI_DEFAULT('\0'); + + /* Is dropped (ie, logically invisible) or not */ + bool attisdropped BKI_DEFAULT(f); + + /* + * This flag specifies whether this column has ever had a local + * definition. It is set for normal non-inherited columns, but also for + * columns that are inherited from parents if also explicitly listed in + * CREATE TABLE INHERITS. It is also set when inheritance is removed from + * a table with ALTER TABLE NO INHERIT. If the flag is set, the column is + * not dropped by a parent's DROP COLUMN even if this causes the column's + * attinhcount to become zero. + */ + bool attislocal BKI_DEFAULT(t); + + /* Number of times inherited from direct parent relation(s) */ + int16 attinhcount BKI_DEFAULT(0); + + /* + * attstattarget is the target number of statistics datapoints to collect + * during VACUUM ANALYZE of this column. A zero here indicates that we do + * not wish to collect any stats about this column. A "-1" here indicates + * that no value has been explicitly set for this column, so ANALYZE + * should use the default setting. + * + * int16 is sufficient because the max value is currently 10000. + */ + int16 attstattarget BKI_DEFAULT(-1); + + /* attribute's collation, if any */ + Oid attcollation BKI_LOOKUP_OPT(pg_collation); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* NOTE: The following fields are not present in tuple descriptors. */ + + /* Column-level access permissions */ + aclitem attacl[1] BKI_DEFAULT(_null_); + + /* Column-level options */ + text attoptions[1] BKI_DEFAULT(_null_); + + /* Column-level FDW options */ + text attfdwoptions[1] BKI_DEFAULT(_null_); + + /* + * Missing value for added columns. This is a one element array which lets + * us store a value of the attribute type here. + */ + anyarray attmissingval BKI_DEFAULT(_null_); +#endif +} FormData_pg_attribute; + +/* + * ATTRIBUTE_FIXED_PART_SIZE is the size of the fixed-layout, + * guaranteed-not-null part of a pg_attribute row. This is in fact as much + * of the row as gets copied into tuple descriptors, so don't expect you + * can access the variable-length fields except in a real tuple! + */ +#define ATTRIBUTE_FIXED_PART_SIZE \ + (offsetof(FormData_pg_attribute,attcollation) + sizeof(Oid)) + +/* ---------------- + * Form_pg_attribute corresponds to a pointer to a tuple with + * the format of pg_attribute relation. + * ---------------- + */ +typedef FormData_pg_attribute *Form_pg_attribute; + +DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index, 2658, AttributeRelidNameIndexId, on pg_attribute using btree(attrelid oid_ops, attname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_attribute_relid_attnum_index, 2659, AttributeRelidNumIndexId, on pg_attribute using btree(attrelid oid_ops, attnum int2_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +#define ATTRIBUTE_IDENTITY_ALWAYS 'a' +#define ATTRIBUTE_IDENTITY_BY_DEFAULT 'd' + +#define ATTRIBUTE_GENERATED_STORED 's' + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_ATTRIBUTE_H */ diff --git a/install/include/postgresql/server/catalog/pg_attribute_d.h b/install/include/postgresql/server/catalog/pg_attribute_d.h new file mode 100644 index 00000000000..c669c28c1dc --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_attribute_d.h @@ -0,0 +1,62 @@ +/*------------------------------------------------------------------------- + * + * pg_attribute_d.h + * Macro definitions for pg_attribute + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_ATTRIBUTE_D_H +#define PG_ATTRIBUTE_D_H + +#define AttributeRelationId 1249 +#define AttributeRelation_Rowtype_Id 75 +#define AttributeRelidNameIndexId 2658 +#define AttributeRelidNumIndexId 2659 + +#define Anum_pg_attribute_attrelid 1 +#define Anum_pg_attribute_attname 2 +#define Anum_pg_attribute_atttypid 3 +#define Anum_pg_attribute_attlen 4 +#define Anum_pg_attribute_attnum 5 +#define Anum_pg_attribute_attcacheoff 6 +#define Anum_pg_attribute_atttypmod 7 +#define Anum_pg_attribute_attndims 8 +#define Anum_pg_attribute_attbyval 9 +#define Anum_pg_attribute_attalign 10 +#define Anum_pg_attribute_attstorage 11 +#define Anum_pg_attribute_attcompression 12 +#define Anum_pg_attribute_attnotnull 13 +#define Anum_pg_attribute_atthasdef 14 +#define Anum_pg_attribute_atthasmissing 15 +#define Anum_pg_attribute_attidentity 16 +#define Anum_pg_attribute_attgenerated 17 +#define Anum_pg_attribute_attisdropped 18 +#define Anum_pg_attribute_attislocal 19 +#define Anum_pg_attribute_attinhcount 20 +#define Anum_pg_attribute_attstattarget 21 +#define Anum_pg_attribute_attcollation 22 +#define Anum_pg_attribute_attacl 23 +#define Anum_pg_attribute_attoptions 24 +#define Anum_pg_attribute_attfdwoptions 25 +#define Anum_pg_attribute_attmissingval 26 + +#define Natts_pg_attribute 26 + + +#define ATTRIBUTE_IDENTITY_ALWAYS 'a' +#define ATTRIBUTE_IDENTITY_BY_DEFAULT 'd' + +#define ATTRIBUTE_GENERATED_STORED 's' + + +#endif /* PG_ATTRIBUTE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_auth_members.h b/install/include/postgresql/server/catalog/pg_auth_members.h new file mode 100644 index 00000000000..df2b8b29e0d --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_auth_members.h @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * pg_auth_members.h + * definition of the "authorization identifier members" system catalog + * (pg_auth_members). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_auth_members.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AUTH_MEMBERS_H +#define PG_AUTH_MEMBERS_H + +#include "catalog/genbki.h" +#include "catalog/pg_auth_members_d.h" + +/* ---------------- + * pg_auth_members definition. cpp turns this into + * typedef struct FormData_pg_auth_members + * ---------------- + */ +CATALOG(pg_auth_members,1261,AuthMemRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2843,AuthMemRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + Oid oid; /* oid */ + Oid roleid BKI_LOOKUP(pg_authid); /* ID of a role */ + Oid member BKI_LOOKUP(pg_authid); /* ID of a member of that role */ + Oid grantor BKI_LOOKUP(pg_authid); /* who granted the membership */ + bool admin_option; /* granted with admin option? */ + bool inherit_option; /* exercise privileges without SET ROLE? */ + bool set_option; /* use SET ROLE to the target role? */ +} FormData_pg_auth_members; + +/* ---------------- + * Form_pg_auth_members corresponds to a pointer to a tuple with + * the format of pg_auth_members relation. + * ---------------- + */ +typedef FormData_pg_auth_members *Form_pg_auth_members; + +DECLARE_UNIQUE_INDEX_PKEY(pg_auth_members_oid_index, 6303, AuthMemOidIndexId, on pg_auth_members using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_auth_members_role_member_index, 2694, AuthMemRoleMemIndexId, on pg_auth_members using btree(roleid oid_ops, member oid_ops, grantor oid_ops)); +DECLARE_UNIQUE_INDEX(pg_auth_members_member_role_index, 2695, AuthMemMemRoleIndexId, on pg_auth_members using btree(member oid_ops, roleid oid_ops, grantor oid_ops)); +DECLARE_INDEX(pg_auth_members_grantor_index, 6302, AuthMemGrantorIndexId, on pg_auth_members using btree(grantor oid_ops)); + +#endif /* PG_AUTH_MEMBERS_H */ diff --git a/install/include/postgresql/server/catalog/pg_auth_members_d.h b/install/include/postgresql/server/catalog/pg_auth_members_d.h new file mode 100644 index 00000000000..528efe93782 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_auth_members_d.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * pg_auth_members_d.h + * Macro definitions for pg_auth_members + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AUTH_MEMBERS_D_H +#define PG_AUTH_MEMBERS_D_H + +#define AuthMemRelationId 1261 +#define AuthMemRelation_Rowtype_Id 2843 +#define AuthMemOidIndexId 6303 +#define AuthMemRoleMemIndexId 2694 +#define AuthMemMemRoleIndexId 2695 +#define AuthMemGrantorIndexId 6302 + +#define Anum_pg_auth_members_oid 1 +#define Anum_pg_auth_members_roleid 2 +#define Anum_pg_auth_members_member 3 +#define Anum_pg_auth_members_grantor 4 +#define Anum_pg_auth_members_admin_option 5 +#define Anum_pg_auth_members_inherit_option 6 +#define Anum_pg_auth_members_set_option 7 + +#define Natts_pg_auth_members 7 + + +#endif /* PG_AUTH_MEMBERS_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_authid.h b/install/include/postgresql/server/catalog/pg_authid.h new file mode 100644 index 00000000000..c70baf7887c --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_authid.h @@ -0,0 +1,63 @@ +/*------------------------------------------------------------------------- + * + * pg_authid.h + * definition of the "authorization identifier" system catalog (pg_authid) + * + * pg_shadow and pg_group are now publicly accessible views on pg_authid. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_authid.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AUTHID_H +#define PG_AUTHID_H + +#include "catalog/genbki.h" +#include "catalog/pg_authid_d.h" + +/* ---------------- + * pg_authid definition. cpp turns this into + * typedef struct FormData_pg_authid + * ---------------- + */ +CATALOG(pg_authid,1260,AuthIdRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842,AuthIdRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + Oid oid; /* oid */ + NameData rolname; /* name of role */ + bool rolsuper; /* read this field via superuser() only! */ + bool rolinherit; /* inherit privileges from other roles? */ + bool rolcreaterole; /* allowed to create more roles? */ + bool rolcreatedb; /* allowed to create databases? */ + bool rolcanlogin; /* allowed to log in as session user? */ + bool rolreplication; /* role used for streaming replication */ + bool rolbypassrls; /* bypasses row-level security? */ + int32 rolconnlimit; /* max connections allowed (-1=no limit) */ + + /* remaining fields may be null; use heap_getattr to read them! */ +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text rolpassword; /* password, if any */ + timestamptz rolvaliduntil; /* password expiration time, if any */ +#endif +} FormData_pg_authid; + +/* ---------------- + * Form_pg_authid corresponds to a pointer to a tuple with + * the format of pg_authid relation. + * ---------------- + */ +typedef FormData_pg_authid *Form_pg_authid; + +DECLARE_TOAST_WITH_MACRO(pg_authid, 4175, 4176, PgAuthidToastTable, PgAuthidToastIndex); + +DECLARE_UNIQUE_INDEX(pg_authid_rolname_index, 2676, AuthIdRolnameIndexId, on pg_authid using btree(rolname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_authid_oid_index, 2677, AuthIdOidIndexId, on pg_authid using btree(oid oid_ops)); + +#endif /* PG_AUTHID_H */ diff --git a/install/include/postgresql/server/catalog/pg_authid_d.h b/install/include/postgresql/server/catalog/pg_authid_d.h new file mode 100644 index 00000000000..26900a5c794 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_authid_d.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * pg_authid_d.h + * Macro definitions for pg_authid + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AUTHID_D_H +#define PG_AUTHID_D_H + +#define AuthIdRelationId 1260 +#define AuthIdRelation_Rowtype_Id 2842 +#define PgAuthidToastTable 4175 +#define PgAuthidToastIndex 4176 +#define AuthIdRolnameIndexId 2676 +#define AuthIdOidIndexId 2677 + +#define Anum_pg_authid_oid 1 +#define Anum_pg_authid_rolname 2 +#define Anum_pg_authid_rolsuper 3 +#define Anum_pg_authid_rolinherit 4 +#define Anum_pg_authid_rolcreaterole 5 +#define Anum_pg_authid_rolcreatedb 6 +#define Anum_pg_authid_rolcanlogin 7 +#define Anum_pg_authid_rolreplication 8 +#define Anum_pg_authid_rolbypassrls 9 +#define Anum_pg_authid_rolconnlimit 10 +#define Anum_pg_authid_rolpassword 11 +#define Anum_pg_authid_rolvaliduntil 12 + +#define Natts_pg_authid 12 + +#define BOOTSTRAP_SUPERUSERID 10 +#define ROLE_PG_DATABASE_OWNER 6171 +#define ROLE_PG_READ_ALL_DATA 6181 +#define ROLE_PG_WRITE_ALL_DATA 6182 +#define ROLE_PG_MONITOR 3373 +#define ROLE_PG_READ_ALL_SETTINGS 3374 +#define ROLE_PG_READ_ALL_STATS 3375 +#define ROLE_PG_STAT_SCAN_TABLES 3377 +#define ROLE_PG_READ_SERVER_FILES 4569 +#define ROLE_PG_WRITE_SERVER_FILES 4570 +#define ROLE_PG_EXECUTE_SERVER_PROGRAM 4571 +#define ROLE_PG_SIGNAL_BACKEND 4200 +#define ROLE_PG_CHECKPOINT 4544 +#define ROLE_PG_USE_RESERVED_CONNECTIONS 4550 +#define ROLE_PG_CREATE_SUBSCRIPTION 6304 + +#endif /* PG_AUTHID_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_cast.h b/install/include/postgresql/server/catalog/pg_cast.h new file mode 100644 index 00000000000..9ec2b5785b8 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_cast.h @@ -0,0 +1,104 @@ +/*------------------------------------------------------------------------- + * + * pg_cast.h + * definition of the "type casts" system catalog (pg_cast) + * + * As of Postgres 8.0, pg_cast describes not only type coercion functions + * but also length coercion functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_cast.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CAST_H +#define PG_CAST_H + +#include "catalog/dependency.h" +#include "catalog/genbki.h" +#include "catalog/pg_cast_d.h" + +/* ---------------- + * pg_cast definition. cpp turns this into + * typedef struct FormData_pg_cast + * ---------------- + */ +CATALOG(pg_cast,2605,CastRelationId) +{ + Oid oid; /* oid */ + + /* source datatype for cast */ + Oid castsource BKI_LOOKUP(pg_type); + + /* destination datatype for cast */ + Oid casttarget BKI_LOOKUP(pg_type); + + /* cast function; 0 = binary coercible */ + Oid castfunc BKI_LOOKUP_OPT(pg_proc); + + /* contexts in which cast can be used */ + char castcontext; + + /* cast method */ + char castmethod; +} FormData_pg_cast; + +/* ---------------- + * Form_pg_cast corresponds to a pointer to a tuple with + * the format of pg_cast relation. + * ---------------- + */ +typedef FormData_pg_cast *Form_pg_cast; + +DECLARE_UNIQUE_INDEX_PKEY(pg_cast_oid_index, 2660, CastOidIndexId, on pg_cast using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_cast_source_target_index, 2661, CastSourceTargetIndexId, on pg_cast using btree(castsource oid_ops, casttarget oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * The allowable values for pg_cast.castcontext are specified by this enum. + * Since castcontext is stored as a "char", we use ASCII codes for human + * convenience in reading the table. Note that internally to the backend, + * these values are converted to the CoercionContext enum (see primnodes.h), + * which is defined to sort in a convenient order; the ASCII codes don't + * have to sort in any special order. + */ + +typedef enum CoercionCodes +{ + COERCION_CODE_IMPLICIT = 'i', /* coercion in context of expression */ + COERCION_CODE_ASSIGNMENT = 'a', /* coercion in context of assignment */ + COERCION_CODE_EXPLICIT = 'e' /* explicit cast operation */ +} CoercionCodes; + +/* + * The allowable values for pg_cast.castmethod are specified by this enum. + * Since castmethod is stored as a "char", we use ASCII codes for human + * convenience in reading the table. + */ +typedef enum CoercionMethod +{ + COERCION_METHOD_FUNCTION = 'f', /* use a function */ + COERCION_METHOD_BINARY = 'b', /* types are binary-compatible */ + COERCION_METHOD_INOUT = 'i' /* use input/output functions */ +} CoercionMethod; + +#endif /* EXPOSE_TO_CLIENT_CODE */ + + +extern ObjectAddress CastCreate(Oid sourcetypeid, + Oid targettypeid, + Oid funcid, + Oid incastid, + Oid outcastid, + char castcontext, + char castmethod, + DependencyType behavior); + +#endif /* PG_CAST_H */ diff --git a/install/include/postgresql/server/catalog/pg_cast_d.h b/install/include/postgresql/server/catalog/pg_cast_d.h new file mode 100644 index 00000000000..d2be7cd8af2 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_cast_d.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * pg_cast_d.h + * Macro definitions for pg_cast + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CAST_D_H +#define PG_CAST_D_H + +#define CastRelationId 2605 +#define CastOidIndexId 2660 +#define CastSourceTargetIndexId 2661 + +#define Anum_pg_cast_oid 1 +#define Anum_pg_cast_castsource 2 +#define Anum_pg_cast_casttarget 3 +#define Anum_pg_cast_castfunc 4 +#define Anum_pg_cast_castcontext 5 +#define Anum_pg_cast_castmethod 6 + +#define Natts_pg_cast 6 + + +/* + * The allowable values for pg_cast.castcontext are specified by this enum. + * Since castcontext is stored as a "char", we use ASCII codes for human + * convenience in reading the table. Note that internally to the backend, + * these values are converted to the CoercionContext enum (see primnodes.h), + * which is defined to sort in a convenient order; the ASCII codes don't + * have to sort in any special order. + */ + +typedef enum CoercionCodes +{ + COERCION_CODE_IMPLICIT = 'i', /* coercion in context of expression */ + COERCION_CODE_ASSIGNMENT = 'a', /* coercion in context of assignment */ + COERCION_CODE_EXPLICIT = 'e' /* explicit cast operation */ +} CoercionCodes; + +/* + * The allowable values for pg_cast.castmethod are specified by this enum. + * Since castmethod is stored as a "char", we use ASCII codes for human + * convenience in reading the table. + */ +typedef enum CoercionMethod +{ + COERCION_METHOD_FUNCTION = 'f', /* use a function */ + COERCION_METHOD_BINARY = 'b', /* types are binary-compatible */ + COERCION_METHOD_INOUT = 'i' /* use input/output functions */ +} CoercionMethod; + + +#endif /* PG_CAST_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_class.h b/install/include/postgresql/server/catalog/pg_class.h new file mode 100644 index 00000000000..2d1bb7af3a9 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_class.h @@ -0,0 +1,230 @@ +/*------------------------------------------------------------------------- + * + * pg_class.h + * definition of the "relation" system catalog (pg_class) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_class.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CLASS_H +#define PG_CLASS_H + +#include "catalog/genbki.h" +#include "catalog/pg_class_d.h" + +/* ---------------- + * pg_class definition. cpp turns this into + * typedef struct FormData_pg_class + * + * Note that the BKI_DEFAULT values below are only used for rows describing + * BKI_BOOTSTRAP catalogs, since only those rows appear in pg_class.dat. + * ---------------- + */ +CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,RelationRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + /* oid */ + Oid oid; + + /* class name */ + NameData relname; + + /* OID of namespace containing this class */ + Oid relnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* OID of entry in pg_type for relation's implicit row type, if any */ + Oid reltype BKI_LOOKUP_OPT(pg_type); + + /* OID of entry in pg_type for underlying composite type, if any */ + Oid reloftype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); + + /* class owner */ + Oid relowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* access method; 0 if not a table / index */ + Oid relam BKI_DEFAULT(heap) BKI_LOOKUP_OPT(pg_am); + + /* identifier of physical storage file */ + /* relfilenode == 0 means it is a "mapped" relation, see relmapper.c */ + Oid relfilenode BKI_DEFAULT(0); + + /* identifier of table space for relation (0 means default for database) */ + Oid reltablespace BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_tablespace); + + /* # of blocks (not always up-to-date) */ + int32 relpages BKI_DEFAULT(0); + + /* # of tuples (not always up-to-date; -1 means "unknown") */ + float4 reltuples BKI_DEFAULT(-1); + + /* # of all-visible blocks (not always up-to-date) */ + int32 relallvisible BKI_DEFAULT(0); + + /* OID of toast table; 0 if none */ + Oid reltoastrelid BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class); + + /* T if has (or has had) any indexes */ + bool relhasindex BKI_DEFAULT(f); + + /* T if shared across databases */ + bool relisshared BKI_DEFAULT(f); + + /* see RELPERSISTENCE_xxx constants below */ + char relpersistence BKI_DEFAULT(p); + + /* see RELKIND_xxx constants below */ + char relkind BKI_DEFAULT(r); + + /* number of user attributes */ + int16 relnatts BKI_DEFAULT(0); /* genbki.pl will fill this in */ + + /* + * Class pg_attribute must contain exactly "relnatts" user attributes + * (with attnums ranging from 1 to relnatts) for this class. It may also + * contain entries with negative attnums for system attributes. + */ + + /* # of CHECK constraints for class */ + int16 relchecks BKI_DEFAULT(0); + + /* has (or has had) any rules */ + bool relhasrules BKI_DEFAULT(f); + + /* has (or has had) any TRIGGERs */ + bool relhastriggers BKI_DEFAULT(f); + + /* has (or has had) child tables or indexes */ + bool relhassubclass BKI_DEFAULT(f); + + /* row security is enabled or not */ + bool relrowsecurity BKI_DEFAULT(f); + + /* row security forced for owners or not */ + bool relforcerowsecurity BKI_DEFAULT(f); + + /* matview currently holds query results */ + bool relispopulated BKI_DEFAULT(t); + + /* see REPLICA_IDENTITY_xxx constants */ + char relreplident BKI_DEFAULT(n); + + /* is relation a partition? */ + bool relispartition BKI_DEFAULT(f); + + /* link to original rel during table rewrite; otherwise 0 */ + Oid relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class); + + /* all Xids < this are frozen in this rel */ + TransactionId relfrozenxid BKI_DEFAULT(3); /* FirstNormalTransactionId */ + + /* all multixacts in this rel are >= this; it is really a MultiXactId */ + TransactionId relminmxid BKI_DEFAULT(1); /* FirstMultiXactId */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* NOTE: These fields are not present in a relcache entry's rd_rel field. */ + /* access permissions */ + aclitem relacl[1] BKI_DEFAULT(_null_); + + /* access-method-specific options */ + text reloptions[1] BKI_DEFAULT(_null_); + + /* partition bound node tree */ + pg_node_tree relpartbound BKI_DEFAULT(_null_); +#endif +} FormData_pg_class; + +/* Size of fixed part of pg_class tuples, not counting var-length fields */ +#define CLASS_TUPLE_SIZE \ + (offsetof(FormData_pg_class,relminmxid) + sizeof(TransactionId)) + +/* ---------------- + * Form_pg_class corresponds to a pointer to a tuple with + * the format of pg_class relation. + * ---------------- + */ +typedef FormData_pg_class *Form_pg_class; + +DECLARE_UNIQUE_INDEX_PKEY(pg_class_oid_index, 2662, ClassOidIndexId, on pg_class using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index, 2663, ClassNameNspIndexId, on pg_class using btree(relname name_ops, relnamespace oid_ops)); +DECLARE_INDEX(pg_class_tblspc_relfilenode_index, 3455, ClassTblspcRelfilenodeIndexId, on pg_class using btree(reltablespace oid_ops, relfilenode oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +#define RELKIND_RELATION 'r' /* ordinary table */ +#define RELKIND_INDEX 'i' /* secondary index */ +#define RELKIND_SEQUENCE 'S' /* sequence object */ +#define RELKIND_TOASTVALUE 't' /* for out-of-line values */ +#define RELKIND_VIEW 'v' /* view */ +#define RELKIND_MATVIEW 'm' /* materialized view */ +#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ +#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ +#define RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */ +#define RELKIND_PARTITIONED_INDEX 'I' /* partitioned index */ + +#define RELPERSISTENCE_PERMANENT 'p' /* regular table */ +#define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */ +#define RELPERSISTENCE_TEMP 't' /* temporary table */ + +/* default selection for replica identity (primary key or nothing) */ +#define REPLICA_IDENTITY_DEFAULT 'd' +/* no replica identity is logged for this relation */ +#define REPLICA_IDENTITY_NOTHING 'n' +/* all columns are logged as replica identity */ +#define REPLICA_IDENTITY_FULL 'f' +/* + * an explicitly chosen candidate key's columns are used as replica identity. + * Note this will still be set if the index has been dropped; in that case it + * has the same meaning as 'n'. + */ +#define REPLICA_IDENTITY_INDEX 'i' + +/* + * Relation kinds that have physical storage. These relations normally have + * relfilenode set to non-zero, but it can also be zero if the relation is + * mapped. + */ +#define RELKIND_HAS_STORAGE(relkind) \ + ((relkind) == RELKIND_RELATION || \ + (relkind) == RELKIND_INDEX || \ + (relkind) == RELKIND_SEQUENCE || \ + (relkind) == RELKIND_TOASTVALUE || \ + (relkind) == RELKIND_MATVIEW) + +#define RELKIND_HAS_PARTITIONS(relkind) \ + ((relkind) == RELKIND_PARTITIONED_TABLE || \ + (relkind) == RELKIND_PARTITIONED_INDEX) + +/* + * Relation kinds that support tablespaces: All relation kinds with storage + * support tablespaces, except that we don't support moving sequences around + * into different tablespaces. Partitioned tables and indexes don't have + * physical storage, but they have a tablespace settings so that their + * children can inherit it. + */ +#define RELKIND_HAS_TABLESPACE(relkind) \ + ((RELKIND_HAS_STORAGE(relkind) || RELKIND_HAS_PARTITIONS(relkind)) \ + && (relkind) != RELKIND_SEQUENCE) + +/* + * Relation kinds with a table access method (rd_tableam). Although sequences + * use the heap table AM, they are enough of a special case in most uses that + * they are not included here. + */ +#define RELKIND_HAS_TABLE_AM(relkind) \ + ((relkind) == RELKIND_RELATION || \ + (relkind) == RELKIND_TOASTVALUE || \ + (relkind) == RELKIND_MATVIEW) + +extern int errdetail_relkind_not_supported(char relkind); + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_CLASS_H */ diff --git a/install/include/postgresql/server/catalog/pg_class_d.h b/install/include/postgresql/server/catalog/pg_class_d.h new file mode 100644 index 00000000000..51208d69800 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_class_d.h @@ -0,0 +1,132 @@ +/*------------------------------------------------------------------------- + * + * pg_class_d.h + * Macro definitions for pg_class + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CLASS_D_H +#define PG_CLASS_D_H + +#define RelationRelationId 1259 +#define RelationRelation_Rowtype_Id 83 +#define ClassOidIndexId 2662 +#define ClassNameNspIndexId 2663 +#define ClassTblspcRelfilenodeIndexId 3455 + +#define Anum_pg_class_oid 1 +#define Anum_pg_class_relname 2 +#define Anum_pg_class_relnamespace 3 +#define Anum_pg_class_reltype 4 +#define Anum_pg_class_reloftype 5 +#define Anum_pg_class_relowner 6 +#define Anum_pg_class_relam 7 +#define Anum_pg_class_relfilenode 8 +#define Anum_pg_class_reltablespace 9 +#define Anum_pg_class_relpages 10 +#define Anum_pg_class_reltuples 11 +#define Anum_pg_class_relallvisible 12 +#define Anum_pg_class_reltoastrelid 13 +#define Anum_pg_class_relhasindex 14 +#define Anum_pg_class_relisshared 15 +#define Anum_pg_class_relpersistence 16 +#define Anum_pg_class_relkind 17 +#define Anum_pg_class_relnatts 18 +#define Anum_pg_class_relchecks 19 +#define Anum_pg_class_relhasrules 20 +#define Anum_pg_class_relhastriggers 21 +#define Anum_pg_class_relhassubclass 22 +#define Anum_pg_class_relrowsecurity 23 +#define Anum_pg_class_relforcerowsecurity 24 +#define Anum_pg_class_relispopulated 25 +#define Anum_pg_class_relreplident 26 +#define Anum_pg_class_relispartition 27 +#define Anum_pg_class_relrewrite 28 +#define Anum_pg_class_relfrozenxid 29 +#define Anum_pg_class_relminmxid 30 +#define Anum_pg_class_relacl 31 +#define Anum_pg_class_reloptions 32 +#define Anum_pg_class_relpartbound 33 + +#define Natts_pg_class 33 + + +#define RELKIND_RELATION 'r' /* ordinary table */ +#define RELKIND_INDEX 'i' /* secondary index */ +#define RELKIND_SEQUENCE 'S' /* sequence object */ +#define RELKIND_TOASTVALUE 't' /* for out-of-line values */ +#define RELKIND_VIEW 'v' /* view */ +#define RELKIND_MATVIEW 'm' /* materialized view */ +#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ +#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ +#define RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */ +#define RELKIND_PARTITIONED_INDEX 'I' /* partitioned index */ + +#define RELPERSISTENCE_PERMANENT 'p' /* regular table */ +#define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */ +#define RELPERSISTENCE_TEMP 't' /* temporary table */ + +/* default selection for replica identity (primary key or nothing) */ +#define REPLICA_IDENTITY_DEFAULT 'd' +/* no replica identity is logged for this relation */ +#define REPLICA_IDENTITY_NOTHING 'n' +/* all columns are logged as replica identity */ +#define REPLICA_IDENTITY_FULL 'f' +/* + * an explicitly chosen candidate key's columns are used as replica identity. + * Note this will still be set if the index has been dropped; in that case it + * has the same meaning as 'n'. + */ +#define REPLICA_IDENTITY_INDEX 'i' + +/* + * Relation kinds that have physical storage. These relations normally have + * relfilenode set to non-zero, but it can also be zero if the relation is + * mapped. + */ +#define RELKIND_HAS_STORAGE(relkind) \ + ((relkind) == RELKIND_RELATION || \ + (relkind) == RELKIND_INDEX || \ + (relkind) == RELKIND_SEQUENCE || \ + (relkind) == RELKIND_TOASTVALUE || \ + (relkind) == RELKIND_MATVIEW) + +#define RELKIND_HAS_PARTITIONS(relkind) \ + ((relkind) == RELKIND_PARTITIONED_TABLE || \ + (relkind) == RELKIND_PARTITIONED_INDEX) + +/* + * Relation kinds that support tablespaces: All relation kinds with storage + * support tablespaces, except that we don't support moving sequences around + * into different tablespaces. Partitioned tables and indexes don't have + * physical storage, but they have a tablespace settings so that their + * children can inherit it. + */ +#define RELKIND_HAS_TABLESPACE(relkind) \ + ((RELKIND_HAS_STORAGE(relkind) || RELKIND_HAS_PARTITIONS(relkind)) \ + && (relkind) != RELKIND_SEQUENCE) + +/* + * Relation kinds with a table access method (rd_tableam). Although sequences + * use the heap table AM, they are enough of a special case in most uses that + * they are not included here. + */ +#define RELKIND_HAS_TABLE_AM(relkind) \ + ((relkind) == RELKIND_RELATION || \ + (relkind) == RELKIND_TOASTVALUE || \ + (relkind) == RELKIND_MATVIEW) + +extern int errdetail_relkind_not_supported(char relkind); + + +#endif /* PG_CLASS_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_collation.h b/install/include/postgresql/server/catalog/pg_collation.h new file mode 100644 index 00000000000..bfa35684515 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_collation.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------- + * + * pg_collation.h + * definition of the "collation" system catalog (pg_collation) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_collation.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_COLLATION_H +#define PG_COLLATION_H + +#include "catalog/genbki.h" +#include "catalog/pg_collation_d.h" + +/* ---------------- + * pg_collation definition. cpp turns this into + * typedef struct FormData_pg_collation + * ---------------- + */ +CATALOG(pg_collation,3456,CollationRelationId) +{ + Oid oid; /* oid */ + NameData collname; /* collation name */ + + /* OID of namespace containing this collation */ + Oid collnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* owner of collation */ + Oid collowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + char collprovider; /* see constants below */ + bool collisdeterministic BKI_DEFAULT(t); + int32 collencoding; /* encoding for this collation; -1 = "all" */ +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text collcollate BKI_DEFAULT(_null_); /* LC_COLLATE setting */ + text collctype BKI_DEFAULT(_null_); /* LC_CTYPE setting */ + text colliculocale BKI_DEFAULT(_null_); /* ICU locale ID */ + text collicurules BKI_DEFAULT(_null_); /* ICU collation rules */ + text collversion BKI_DEFAULT(_null_); /* provider-dependent + * version of collation + * data */ +#endif +} FormData_pg_collation; + +/* ---------------- + * Form_pg_collation corresponds to a pointer to a row with + * the format of pg_collation relation. + * ---------------- + */ +typedef FormData_pg_collation *Form_pg_collation; + +DECLARE_TOAST(pg_collation, 6175, 6176); + +DECLARE_UNIQUE_INDEX(pg_collation_name_enc_nsp_index, 3164, CollationNameEncNspIndexId, on pg_collation using btree(collname name_ops, collencoding int4_ops, collnamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_collation_oid_index, 3085, CollationOidIndexId, on pg_collation using btree(oid oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +#define COLLPROVIDER_DEFAULT 'd' +#define COLLPROVIDER_ICU 'i' +#define COLLPROVIDER_LIBC 'c' + +static inline const char * +collprovider_name(char c) +{ + switch (c) + { + case COLLPROVIDER_ICU: + return "icu"; + case COLLPROVIDER_LIBC: + return "libc"; + default: + return "???"; + } +} + +#endif /* EXPOSE_TO_CLIENT_CODE */ + + +extern Oid CollationCreate(const char *collname, Oid collnamespace, + Oid collowner, + char collprovider, + bool collisdeterministic, + int32 collencoding, + const char *collcollate, const char *collctype, + const char *colliculocale, + const char *collicurules, + const char *collversion, + bool if_not_exists, + bool quiet); + +#endif /* PG_COLLATION_H */ diff --git a/install/include/postgresql/server/catalog/pg_collation_d.h b/install/include/postgresql/server/catalog/pg_collation_d.h new file mode 100644 index 00000000000..a5a675b358d --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_collation_d.h @@ -0,0 +1,63 @@ +/*------------------------------------------------------------------------- + * + * pg_collation_d.h + * Macro definitions for pg_collation + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_COLLATION_D_H +#define PG_COLLATION_D_H + +#define CollationRelationId 3456 +#define CollationNameEncNspIndexId 3164 +#define CollationOidIndexId 3085 + +#define Anum_pg_collation_oid 1 +#define Anum_pg_collation_collname 2 +#define Anum_pg_collation_collnamespace 3 +#define Anum_pg_collation_collowner 4 +#define Anum_pg_collation_collprovider 5 +#define Anum_pg_collation_collisdeterministic 6 +#define Anum_pg_collation_collencoding 7 +#define Anum_pg_collation_collcollate 8 +#define Anum_pg_collation_collctype 9 +#define Anum_pg_collation_colliculocale 10 +#define Anum_pg_collation_collicurules 11 +#define Anum_pg_collation_collversion 12 + +#define Natts_pg_collation 12 + + +#define COLLPROVIDER_DEFAULT 'd' +#define COLLPROVIDER_ICU 'i' +#define COLLPROVIDER_LIBC 'c' + +static inline const char * +collprovider_name(char c) +{ + switch (c) + { + case COLLPROVIDER_ICU: + return "icu"; + case COLLPROVIDER_LIBC: + return "libc"; + default: + return "???"; + } +} + +#define DEFAULT_COLLATION_OID 100 +#define C_COLLATION_OID 950 +#define POSIX_COLLATION_OID 951 + +#endif /* PG_COLLATION_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_constraint.h b/install/include/postgresql/server/catalog/pg_constraint.h new file mode 100644 index 00000000000..16bf5f5576e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_constraint.h @@ -0,0 +1,273 @@ +/*------------------------------------------------------------------------- + * + * pg_constraint.h + * definition of the "constraint" system catalog (pg_constraint) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_constraint.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CONSTRAINT_H +#define PG_CONSTRAINT_H + +#include "catalog/dependency.h" +#include "catalog/genbki.h" +#include "catalog/pg_constraint_d.h" +#include "nodes/pg_list.h" + +/* ---------------- + * pg_constraint definition. cpp turns this into + * typedef struct FormData_pg_constraint + * ---------------- + */ +CATALOG(pg_constraint,2606,ConstraintRelationId) +{ + Oid oid; /* oid */ + + /* + * conname + connamespace is deliberately not unique; we allow, for + * example, the same name to be used for constraints of different + * relations. This is partly for backwards compatibility with past + * Postgres practice, and partly because we don't want to have to obtain a + * global lock to generate a globally unique name for a nameless + * constraint. We associate a namespace with constraint names only for + * SQL-spec compatibility. + * + * However, we do require conname to be unique among the constraints of a + * single relation or domain. This is enforced by a unique index on + * conrelid + contypid + conname. + */ + NameData conname; /* name of this constraint */ + Oid connamespace BKI_LOOKUP(pg_namespace); /* OID of namespace + * containing constraint */ + char contype; /* constraint type; see codes below */ + bool condeferrable; /* deferrable constraint? */ + bool condeferred; /* deferred by default? */ + bool convalidated; /* constraint has been validated? */ + + /* + * conrelid and conkey are only meaningful if the constraint applies to a + * specific relation (this excludes domain constraints and assertions). + * Otherwise conrelid is 0 and conkey is NULL. + */ + Oid conrelid BKI_LOOKUP_OPT(pg_class); /* relation this + * constraint constrains */ + + /* + * contypid links to the pg_type row for a domain if this is a domain + * constraint. Otherwise it's 0. + * + * For SQL-style global ASSERTIONs, both conrelid and contypid would be + * zero. This is not presently supported, however. + */ + Oid contypid BKI_LOOKUP_OPT(pg_type); /* domain this constraint + * constrains */ + + /* + * conindid links to the index supporting the constraint, if any; + * otherwise it's 0. This is used for unique, primary-key, and exclusion + * constraints, and less obviously for foreign-key constraints (where the + * index is a unique index on the referenced relation's referenced + * columns). Notice that the index is on conrelid in the first case but + * confrelid in the second. + */ + Oid conindid BKI_LOOKUP_OPT(pg_class); /* index supporting this + * constraint */ + + /* + * If this constraint is on a partition inherited from a partitioned + * table, this is the OID of the corresponding constraint in the parent. + */ + Oid conparentid BKI_LOOKUP_OPT(pg_constraint); + + /* + * These fields, plus confkey, are only meaningful for a foreign-key + * constraint. Otherwise confrelid is 0 and the char fields are spaces. + */ + Oid confrelid BKI_LOOKUP_OPT(pg_class); /* relation referenced by + * foreign key */ + char confupdtype; /* foreign key's ON UPDATE action */ + char confdeltype; /* foreign key's ON DELETE action */ + char confmatchtype; /* foreign key's match type */ + + /* Has a local definition (hence, do not drop when coninhcount is 0) */ + bool conislocal; + + /* Number of times inherited from direct parent relation(s) */ + int16 coninhcount; + + /* Has a local definition and cannot be inherited */ + bool connoinherit; + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + + /* + * Columns of conrelid that the constraint applies to, if known (this is + * NULL for trigger constraints) + */ + int16 conkey[1]; + + /* + * If a foreign key, the referenced columns of confrelid + */ + int16 confkey[1]; + + /* + * If a foreign key, the OIDs of the PK = FK equality operators for each + * column of the constraint + */ + Oid conpfeqop[1] BKI_LOOKUP(pg_operator); + + /* + * If a foreign key, the OIDs of the PK = PK equality operators for each + * column of the constraint (i.e., equality for the referenced columns) + */ + Oid conppeqop[1] BKI_LOOKUP(pg_operator); + + /* + * If a foreign key, the OIDs of the FK = FK equality operators for each + * column of the constraint (i.e., equality for the referencing columns) + */ + Oid conffeqop[1] BKI_LOOKUP(pg_operator); + + /* + * If a foreign key with an ON DELETE SET NULL/DEFAULT action, the subset + * of conkey to updated. If null, all columns are updated. + */ + int16 confdelsetcols[1]; + + /* + * If an exclusion constraint, the OIDs of the exclusion operators for + * each column of the constraint + */ + Oid conexclop[1] BKI_LOOKUP(pg_operator); + + /* + * If a check constraint, nodeToString representation of expression + */ + pg_node_tree conbin; +#endif +} FormData_pg_constraint; + +/* ---------------- + * Form_pg_constraint corresponds to a pointer to a tuple with + * the format of pg_constraint relation. + * ---------------- + */ +typedef FormData_pg_constraint *Form_pg_constraint; + +DECLARE_TOAST(pg_constraint, 2832, 2833); + +DECLARE_INDEX(pg_constraint_conname_nsp_index, 2664, ConstraintNameNspIndexId, on pg_constraint using btree(conname name_ops, connamespace oid_ops)); +DECLARE_UNIQUE_INDEX(pg_constraint_conrelid_contypid_conname_index, 2665, ConstraintRelidTypidNameIndexId, on pg_constraint using btree(conrelid oid_ops, contypid oid_ops, conname name_ops)); +DECLARE_INDEX(pg_constraint_contypid_index, 2666, ConstraintTypidIndexId, on pg_constraint using btree(contypid oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_constraint_oid_index, 2667, ConstraintOidIndexId, on pg_constraint using btree(oid oid_ops)); +DECLARE_INDEX(pg_constraint_conparentid_index, 2579, ConstraintParentIndexId, on pg_constraint using btree(conparentid oid_ops)); + +/* conkey can contain zero (InvalidAttrNumber) if a whole-row Var is used */ +DECLARE_ARRAY_FOREIGN_KEY_OPT((conrelid, conkey), pg_attribute, (attrelid, attnum)); +DECLARE_ARRAY_FOREIGN_KEY((confrelid, confkey), pg_attribute, (attrelid, attnum)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* Valid values for contype */ +#define CONSTRAINT_CHECK 'c' +#define CONSTRAINT_FOREIGN 'f' +#define CONSTRAINT_PRIMARY 'p' +#define CONSTRAINT_UNIQUE 'u' +#define CONSTRAINT_TRIGGER 't' +#define CONSTRAINT_EXCLUSION 'x' + +/* + * Valid values for confupdtype and confdeltype are the FKCONSTR_ACTION_xxx + * constants defined in parsenodes.h. Valid values for confmatchtype are + * the FKCONSTR_MATCH_xxx constants defined in parsenodes.h. + */ + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +/* + * Identify constraint type for lookup purposes + */ +typedef enum ConstraintCategory +{ + CONSTRAINT_RELATION, + CONSTRAINT_DOMAIN, + CONSTRAINT_ASSERTION /* for future expansion */ +} ConstraintCategory; + + +extern Oid CreateConstraintEntry(const char *constraintName, + Oid constraintNamespace, + char constraintType, + bool isDeferrable, + bool isDeferred, + bool isValidated, + Oid parentConstrId, + Oid relId, + const int16 *constraintKey, + int constraintNKeys, + int constraintNTotalKeys, + Oid domainId, + Oid indexRelId, + Oid foreignRelId, + const int16 *foreignKey, + const Oid *pfEqOp, + const Oid *ppEqOp, + const Oid *ffEqOp, + int foreignNKeys, + char foreignUpdateType, + char foreignDeleteType, + const int16 *fkDeleteSetCols, + int numFkDeleteSetCols, + char foreignMatchType, + const Oid *exclOp, + Node *conExpr, + const char *conBin, + bool conIsLocal, + int conInhCount, + bool conNoInherit, + bool is_internal); + +extern void RemoveConstraintById(Oid conId); +extern void RenameConstraintById(Oid conId, const char *newname); + +extern bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, + const char *conname); +extern bool ConstraintNameExists(const char *conname, Oid namespaceid); +extern char *ChooseConstraintName(const char *name1, const char *name2, + const char *label, Oid namespaceid, + List *others); + +extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, + Oid newNspId, bool isType, ObjectAddresses *objsMoved); +extern void ConstraintSetParentConstraint(Oid childConstrId, + Oid parentConstrId, + Oid childTableId); +extern Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok); +extern Bitmapset *get_relation_constraint_attnos(Oid relid, const char *conname, + bool missing_ok, Oid *constraintOid); +extern Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok); +extern Oid get_relation_idx_constraint_oid(Oid relationId, Oid indexId); + +extern Bitmapset *get_primary_key_attnos(Oid relid, bool deferrableOk, + Oid *constraintOid); +extern void DeconstructFkConstraintRow(HeapTuple tuple, int *numfks, + AttrNumber *conkey, AttrNumber *confkey, + Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs, + int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols); + +extern bool check_functional_grouping(Oid relid, + Index varno, Index varlevelsup, + List *grouping_columns, + List **constraintDeps); + +#endif /* PG_CONSTRAINT_H */ diff --git a/install/include/postgresql/server/catalog/pg_constraint_d.h b/install/include/postgresql/server/catalog/pg_constraint_d.h new file mode 100644 index 00000000000..ccd977b8943 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_constraint_d.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * pg_constraint_d.h + * Macro definitions for pg_constraint + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CONSTRAINT_D_H +#define PG_CONSTRAINT_D_H + +#define ConstraintRelationId 2606 +#define ConstraintNameNspIndexId 2664 +#define ConstraintRelidTypidNameIndexId 2665 +#define ConstraintTypidIndexId 2666 +#define ConstraintOidIndexId 2667 +#define ConstraintParentIndexId 2579 + +#define Anum_pg_constraint_oid 1 +#define Anum_pg_constraint_conname 2 +#define Anum_pg_constraint_connamespace 3 +#define Anum_pg_constraint_contype 4 +#define Anum_pg_constraint_condeferrable 5 +#define Anum_pg_constraint_condeferred 6 +#define Anum_pg_constraint_convalidated 7 +#define Anum_pg_constraint_conrelid 8 +#define Anum_pg_constraint_contypid 9 +#define Anum_pg_constraint_conindid 10 +#define Anum_pg_constraint_conparentid 11 +#define Anum_pg_constraint_confrelid 12 +#define Anum_pg_constraint_confupdtype 13 +#define Anum_pg_constraint_confdeltype 14 +#define Anum_pg_constraint_confmatchtype 15 +#define Anum_pg_constraint_conislocal 16 +#define Anum_pg_constraint_coninhcount 17 +#define Anum_pg_constraint_connoinherit 18 +#define Anum_pg_constraint_conkey 19 +#define Anum_pg_constraint_confkey 20 +#define Anum_pg_constraint_conpfeqop 21 +#define Anum_pg_constraint_conppeqop 22 +#define Anum_pg_constraint_conffeqop 23 +#define Anum_pg_constraint_confdelsetcols 24 +#define Anum_pg_constraint_conexclop 25 +#define Anum_pg_constraint_conbin 26 + +#define Natts_pg_constraint 26 + + +/* Valid values for contype */ +#define CONSTRAINT_CHECK 'c' +#define CONSTRAINT_FOREIGN 'f' +#define CONSTRAINT_PRIMARY 'p' +#define CONSTRAINT_UNIQUE 'u' +#define CONSTRAINT_TRIGGER 't' +#define CONSTRAINT_EXCLUSION 'x' + +/* + * Valid values for confupdtype and confdeltype are the FKCONSTR_ACTION_xxx + * constants defined in parsenodes.h. Valid values for confmatchtype are + * the FKCONSTR_MATCH_xxx constants defined in parsenodes.h. + */ + + +#endif /* PG_CONSTRAINT_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_control.h b/install/include/postgresql/server/catalog/pg_control.h new file mode 100644 index 00000000000..dc953977c5d --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_control.h @@ -0,0 +1,258 @@ +/*------------------------------------------------------------------------- + * + * pg_control.h + * The system control file "pg_control" is not a heap relation. + * However, we define it here so that the format is documented. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_control.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CONTROL_H +#define PG_CONTROL_H + +#include "access/transam.h" +#include "access/xlogdefs.h" +#include "pgtime.h" /* for pg_time_t */ +#include "port/pg_crc32c.h" + + +/* Version identifier for this pg_control format */ +#define PG_CONTROL_VERSION 1300 + +/* Nonce key length, see below */ +#define MOCK_AUTH_NONCE_LEN 32 + +/* + * Body of CheckPoint XLOG records. This is declared here because we keep + * a copy of the latest one in pg_control for possible disaster recovery. + * Changing this struct requires a PG_CONTROL_VERSION bump. + */ +typedef struct CheckPoint +{ + XLogRecPtr redo; /* next RecPtr available when we began to + * create CheckPoint (i.e. REDO start point) */ + TimeLineID ThisTimeLineID; /* current TLI */ + TimeLineID PrevTimeLineID; /* previous TLI, if this record begins a new + * timeline (equals ThisTimeLineID otherwise) */ + bool fullPageWrites; /* current full_page_writes */ + FullTransactionId nextXid; /* next free transaction ID */ + Oid nextOid; /* next free OID */ + MultiXactId nextMulti; /* next free MultiXactId */ + MultiXactOffset nextMultiOffset; /* next free MultiXact offset */ + TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */ + Oid oldestXidDB; /* database with minimum datfrozenxid */ + MultiXactId oldestMulti; /* cluster-wide minimum datminmxid */ + Oid oldestMultiDB; /* database with minimum datminmxid */ + pg_time_t time; /* time stamp of checkpoint */ + TransactionId oldestCommitTsXid; /* oldest Xid with valid commit + * timestamp */ + TransactionId newestCommitTsXid; /* newest Xid with valid commit + * timestamp */ + + /* + * Oldest XID still running. This is only needed to initialize hot standby + * mode from an online checkpoint, so we only bother calculating this for + * online checkpoints and only when wal_level is replica. Otherwise it's + * set to InvalidTransactionId. + */ + TransactionId oldestActiveXid; +} CheckPoint; + +/* XLOG info values for XLOG rmgr */ +#define XLOG_CHECKPOINT_SHUTDOWN 0x00 +#define XLOG_CHECKPOINT_ONLINE 0x10 +#define XLOG_NOOP 0x20 +#define XLOG_NEXTOID 0x30 +#define XLOG_SWITCH 0x40 +#define XLOG_BACKUP_END 0x50 +#define XLOG_PARAMETER_CHANGE 0x60 +#define XLOG_RESTORE_POINT 0x70 +#define XLOG_FPW_CHANGE 0x80 +#define XLOG_END_OF_RECOVERY 0x90 +#define XLOG_FPI_FOR_HINT 0xA0 +#define XLOG_FPI 0xB0 +/* 0xC0 is used in Postgres 9.5-11 */ +#define XLOG_OVERWRITE_CONTRECORD 0xD0 + + +/* + * System status indicator. Note this is stored in pg_control; if you change + * it, you must bump PG_CONTROL_VERSION + */ +typedef enum DBState +{ + DB_STARTUP = 0, + DB_SHUTDOWNED, + DB_SHUTDOWNED_IN_RECOVERY, + DB_SHUTDOWNING, + DB_IN_CRASH_RECOVERY, + DB_IN_ARCHIVE_RECOVERY, + DB_IN_PRODUCTION +} DBState; + +/* + * Contents of pg_control. + */ + +typedef struct ControlFileData +{ + /* + * Unique system identifier --- to ensure we match up xlog files with the + * installation that produced them. + */ + uint64 system_identifier; + + /* + * Version identifier information. Keep these fields at the same offset, + * especially pg_control_version; they won't be real useful if they move + * around. (For historical reasons they must be 8 bytes into the file + * rather than immediately at the front.) + * + * pg_control_version identifies the format of pg_control itself. + * catalog_version_no identifies the format of the system catalogs. + * + * There are additional version identifiers in individual files; for + * example, WAL logs contain per-page magic numbers that can serve as + * version cues for the WAL log. + */ + uint32 pg_control_version; /* PG_CONTROL_VERSION */ + uint32 catalog_version_no; /* see catversion.h */ + + /* + * System status data + */ + DBState state; /* see enum above */ + pg_time_t time; /* time stamp of last pg_control update */ + XLogRecPtr checkPoint; /* last check point record ptr */ + + CheckPoint checkPointCopy; /* copy of last check point record */ + + XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */ + + /* + * These two values determine the minimum point we must recover up to + * before starting up: + * + * minRecoveryPoint is updated to the latest replayed LSN whenever we + * flush a data change during archive recovery. That guards against + * starting archive recovery, aborting it, and restarting with an earlier + * stop location. If we've already flushed data changes from WAL record X + * to disk, we mustn't start up until we reach X again. Zero when not + * doing archive recovery. + * + * backupStartPoint is the redo pointer of the backup start checkpoint, if + * we are recovering from an online backup and haven't reached the end of + * backup yet. It is reset to zero when the end of backup is reached, and + * we mustn't start up before that. A boolean would suffice otherwise, but + * we use the redo pointer as a cross-check when we see an end-of-backup + * record, to make sure the end-of-backup record corresponds the base + * backup we're recovering from. + * + * backupEndPoint is the backup end location, if we are recovering from an + * online backup which was taken from the standby and haven't reached the + * end of backup yet. It is initialized to the minimum recovery point in + * pg_control which was backed up last. It is reset to zero when the end + * of backup is reached, and we mustn't start up before that. + * + * If backupEndRequired is true, we know for sure that we're restoring + * from a backup, and must see a backup-end record before we can safely + * start up. + */ + XLogRecPtr minRecoveryPoint; + TimeLineID minRecoveryPointTLI; + XLogRecPtr backupStartPoint; + XLogRecPtr backupEndPoint; + bool backupEndRequired; + + /* + * Parameter settings that determine if the WAL can be used for archival + * or hot standby. + */ + int wal_level; + bool wal_log_hints; + int MaxConnections; + int max_worker_processes; + int max_wal_senders; + int max_prepared_xacts; + int max_locks_per_xact; + bool track_commit_timestamp; + + /* + * This data is used to check for hardware-architecture compatibility of + * the database and the backend executable. We need not check endianness + * explicitly, since the pg_control version will surely look wrong to a + * machine of different endianness, but we do need to worry about MAXALIGN + * and floating-point format. (Note: storage layout nominally also + * depends on SHORTALIGN and INTALIGN, but in practice these are the same + * on all architectures of interest.) + * + * Testing just one double value is not a very bulletproof test for + * floating-point compatibility, but it will catch most cases. + */ + uint32 maxAlign; /* alignment requirement for tuples */ + double floatFormat; /* constant 1234567.0 */ +#define FLOATFORMAT_VALUE 1234567.0 + + /* + * This data is used to make sure that configuration of this database is + * compatible with the backend executable. + */ + uint32 blcksz; /* data block size for this DB */ + uint32 relseg_size; /* blocks per segment of large relation */ + + uint32 xlog_blcksz; /* block size within WAL files */ + uint32 xlog_seg_size; /* size of each WAL segment */ + + uint32 nameDataLen; /* catalog name field width */ + uint32 indexMaxKeys; /* max number of columns in an index */ + + uint32 toast_max_chunk_size; /* chunk size in TOAST tables */ + uint32 loblksize; /* chunk size in pg_largeobject */ + + bool float8ByVal; /* float8, int8, etc pass-by-value? */ + + /* Are data pages protected by checksums? Zero if no checksum version */ + uint32 data_checksum_version; + + /* + * Random nonce, used in authentication requests that need to proceed + * based on values that are cluster-unique, like a SASL exchange that + * failed at an early stage. + */ + char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]; + + /* CRC of all above ... MUST BE LAST! */ + pg_crc32c crc; +} ControlFileData; + +/* + * Maximum safe value of sizeof(ControlFileData). For reliability's sake, + * it's critical that pg_control updates be atomic writes. That generally + * means the active data can't be more than one disk sector, which is 512 + * bytes on common hardware. Be very careful about raising this limit. + */ +#define PG_CONTROL_MAX_SAFE_SIZE 512 + +/* + * Physical size of the pg_control file. Note that this is considerably + * bigger than the actually used size (ie, sizeof(ControlFileData)). + * The idea is to keep the physical size constant independent of format + * changes, so that ReadControlFile will deliver a suitable wrong-version + * message instead of a read error if it's looking at an incompatible file. + */ +#define PG_CONTROL_FILE_SIZE 8192 + +/* + * Ensure that the size of the pg_control data structure is sane. + */ +StaticAssertDecl(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE, + "pg_control is too large for atomic disk writes"); +StaticAssertDecl(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE, + "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE"); + +#endif /* PG_CONTROL_H */ diff --git a/install/include/postgresql/server/catalog/pg_conversion.h b/install/include/postgresql/server/catalog/pg_conversion.h new file mode 100644 index 00000000000..de40909dd3e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_conversion.h @@ -0,0 +1,75 @@ +/*------------------------------------------------------------------------- + * + * pg_conversion.h + * definition of the "conversion" system catalog (pg_conversion) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_conversion.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CONVERSION_H +#define PG_CONVERSION_H + +#include "catalog/genbki.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_conversion_d.h" + +/* ---------------- + * pg_conversion definition. cpp turns this into + * typedef struct FormData_pg_conversion + * ---------------- + */ +CATALOG(pg_conversion,2607,ConversionRelationId) +{ + /* oid */ + Oid oid; + + /* name of the conversion */ + NameData conname; + + /* namespace that the conversion belongs to */ + Oid connamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* owner of the conversion */ + Oid conowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* FOR encoding id */ + int32 conforencoding BKI_LOOKUP(encoding); + + /* TO encoding id */ + int32 contoencoding BKI_LOOKUP(encoding); + + /* OID of the conversion proc */ + regproc conproc BKI_LOOKUP(pg_proc); + + /* true if this is a default conversion */ + bool condefault BKI_DEFAULT(t); +} FormData_pg_conversion; + +/* ---------------- + * Form_pg_conversion corresponds to a pointer to a tuple with + * the format of pg_conversion relation. + * ---------------- + */ +typedef FormData_pg_conversion *Form_pg_conversion; + +DECLARE_UNIQUE_INDEX(pg_conversion_default_index, 2668, ConversionDefaultIndexId, on pg_conversion using btree(connamespace oid_ops, conforencoding int4_ops, contoencoding int4_ops, oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_conversion_name_nsp_index, 2669, ConversionNameNspIndexId, on pg_conversion using btree(conname name_ops, connamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_conversion_oid_index, 2670, ConversionOidIndexId, on pg_conversion using btree(oid oid_ops)); + + +extern ObjectAddress ConversionCreate(const char *conname, Oid connamespace, + Oid conowner, + int32 conforencoding, int32 contoencoding, + Oid conproc, bool def); +extern Oid FindDefaultConversion(Oid name_space, int32 for_encoding, + int32 to_encoding); + +#endif /* PG_CONVERSION_H */ diff --git a/install/include/postgresql/server/catalog/pg_conversion_d.h b/install/include/postgresql/server/catalog/pg_conversion_d.h new file mode 100644 index 00000000000..30857dd6bd0 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_conversion_d.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * pg_conversion_d.h + * Macro definitions for pg_conversion + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CONVERSION_D_H +#define PG_CONVERSION_D_H + +#define ConversionRelationId 2607 +#define ConversionDefaultIndexId 2668 +#define ConversionNameNspIndexId 2669 +#define ConversionOidIndexId 2670 + +#define Anum_pg_conversion_oid 1 +#define Anum_pg_conversion_conname 2 +#define Anum_pg_conversion_connamespace 3 +#define Anum_pg_conversion_conowner 4 +#define Anum_pg_conversion_conforencoding 5 +#define Anum_pg_conversion_contoencoding 6 +#define Anum_pg_conversion_conproc 7 +#define Anum_pg_conversion_condefault 8 + +#define Natts_pg_conversion 8 + + +#endif /* PG_CONVERSION_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_database.h b/install/include/postgresql/server/catalog/pg_database.h new file mode 100644 index 00000000000..ff5baaf5141 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_database.h @@ -0,0 +1,124 @@ +/*------------------------------------------------------------------------- + * + * pg_database.h + * definition of the "database" system catalog (pg_database) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_database.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DATABASE_H +#define PG_DATABASE_H + +#include "catalog/genbki.h" +#include "catalog/pg_database_d.h" + +/* ---------------- + * pg_database definition. cpp turns this into + * typedef struct FormData_pg_database + * ---------------- + */ +CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248,DatabaseRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + /* oid */ + Oid oid; + + /* database name */ + NameData datname; + + /* owner of database */ + Oid datdba BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* character encoding */ + int32 encoding; + + /* locale provider, see pg_collation.collprovider */ + char datlocprovider; + + /* allowed as CREATE DATABASE template? */ + bool datistemplate; + + /* new connections allowed? */ + bool datallowconn; + + /* + * Max connections allowed. Negative values have special meaning, see + * DATCONNLIMIT_* defines below. + */ + int32 datconnlimit; + + /* all Xids < this are frozen in this DB */ + TransactionId datfrozenxid; + + /* all multixacts in the DB are >= this */ + TransactionId datminmxid; + + /* default table space for this DB */ + Oid dattablespace BKI_LOOKUP(pg_tablespace); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* LC_COLLATE setting */ + text datcollate BKI_FORCE_NOT_NULL; + + /* LC_CTYPE setting */ + text datctype BKI_FORCE_NOT_NULL; + + /* ICU locale ID */ + text daticulocale; + + /* ICU collation rules */ + text daticurules; + + /* provider-dependent version of collation data */ + text datcollversion BKI_DEFAULT(_null_); + + /* access permissions */ + aclitem datacl[1]; +#endif +} FormData_pg_database; + +/* ---------------- + * Form_pg_database corresponds to a pointer to a tuple with + * the format of pg_database relation. + * ---------------- + */ +typedef FormData_pg_database *Form_pg_database; + +DECLARE_TOAST_WITH_MACRO(pg_database, 4177, 4178, PgDatabaseToastTable, PgDatabaseToastIndex); + +DECLARE_UNIQUE_INDEX(pg_database_datname_index, 2671, DatabaseNameIndexId, on pg_database using btree(datname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_database_oid_index, 2672, DatabaseOidIndexId, on pg_database using btree(oid oid_ops)); + +/* + * pg_database.dat contains an entry for template1, but not for the template0 + * or postgres databases, because those are created later in initdb. + * However, we still want to manually assign the OIDs for template0 and + * postgres, so declare those here. + */ +DECLARE_OID_DEFINING_MACRO(Template0DbOid, 4); +DECLARE_OID_DEFINING_MACRO(PostgresDbOid, 5); + +/* + * Special values for pg_database.datconnlimit. Normal values are >= 0. + */ +#define DATCONNLIMIT_UNLIMITED -1 /* no limit */ + +/* + * A database is set to invalid partway through being dropped. Using + * datconnlimit=-2 for this purpose isn't particularly clean, but is + * backpatchable. + */ +#define DATCONNLIMIT_INVALID_DB -2 + +extern bool database_is_invalid_form(Form_pg_database datform); +extern bool database_is_invalid_oid(Oid dboid); + +#endif /* PG_DATABASE_H */ diff --git a/install/include/postgresql/server/catalog/pg_database_d.h b/install/include/postgresql/server/catalog/pg_database_d.h new file mode 100644 index 00000000000..a3a68998174 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_database_d.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + * + * pg_database_d.h + * Macro definitions for pg_database + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DATABASE_D_H +#define PG_DATABASE_D_H + +#define DatabaseRelationId 1262 +#define DatabaseRelation_Rowtype_Id 1248 +#define PgDatabaseToastTable 4177 +#define PgDatabaseToastIndex 4178 +#define DatabaseNameIndexId 2671 +#define DatabaseOidIndexId 2672 +#define Template0DbOid 4 +#define PostgresDbOid 5 + +#define Anum_pg_database_oid 1 +#define Anum_pg_database_datname 2 +#define Anum_pg_database_datdba 3 +#define Anum_pg_database_encoding 4 +#define Anum_pg_database_datlocprovider 5 +#define Anum_pg_database_datistemplate 6 +#define Anum_pg_database_datallowconn 7 +#define Anum_pg_database_datconnlimit 8 +#define Anum_pg_database_datfrozenxid 9 +#define Anum_pg_database_datminmxid 10 +#define Anum_pg_database_dattablespace 11 +#define Anum_pg_database_datcollate 12 +#define Anum_pg_database_datctype 13 +#define Anum_pg_database_daticulocale 14 +#define Anum_pg_database_daticurules 15 +#define Anum_pg_database_datcollversion 16 +#define Anum_pg_database_datacl 17 + +#define Natts_pg_database 17 + +#define Template1DbOid 1 + +#endif /* PG_DATABASE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_db_role_setting.h b/install/include/postgresql/server/catalog/pg_db_role_setting.h new file mode 100644 index 00000000000..4ba0d69e762 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_db_role_setting.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * pg_db_role_setting.h + * definition of the system catalog for per-database/per-user + * configuration settings (pg_db_role_setting) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_db_role_setting.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DB_ROLE_SETTING_H +#define PG_DB_ROLE_SETTING_H + +#include "catalog/genbki.h" +#include "catalog/pg_db_role_setting_d.h" + +#include "utils/guc.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + +/* ---------------- + * pg_db_role_setting definition. cpp turns this into + * typedef struct FormData_pg_db_role_setting + * ---------------- + */ +CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION +{ + /* database, or 0 for a role-specific setting */ + Oid setdatabase BKI_LOOKUP_OPT(pg_database); + + /* role, or 0 for a database-specific setting */ + Oid setrole BKI_LOOKUP_OPT(pg_authid); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text setconfig[1]; /* GUC settings to apply at login */ +#endif +} FormData_pg_db_role_setting; + +typedef FormData_pg_db_role_setting * Form_pg_db_role_setting; + +DECLARE_TOAST_WITH_MACRO(pg_db_role_setting, 2966, 2967, PgDbRoleSettingToastTable, PgDbRoleSettingToastIndex); + +DECLARE_UNIQUE_INDEX_PKEY(pg_db_role_setting_databaseid_rol_index, 2965, DbRoleSettingDatidRolidIndexId, on pg_db_role_setting using btree(setdatabase oid_ops, setrole oid_ops)); + +/* + * prototypes for functions in pg_db_role_setting.c + */ +extern void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt); +extern void DropSetting(Oid databaseid, Oid roleid); +extern void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid, + Relation relsetting, GucSource source); + +#endif /* PG_DB_ROLE_SETTING_H */ diff --git a/install/include/postgresql/server/catalog/pg_db_role_setting_d.h b/install/include/postgresql/server/catalog/pg_db_role_setting_d.h new file mode 100644 index 00000000000..15b8bf96d41 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_db_role_setting_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_db_role_setting_d.h + * Macro definitions for pg_db_role_setting + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DB_ROLE_SETTING_D_H +#define PG_DB_ROLE_SETTING_D_H + +#define DbRoleSettingRelationId 2964 +#define PgDbRoleSettingToastTable 2966 +#define PgDbRoleSettingToastIndex 2967 +#define DbRoleSettingDatidRolidIndexId 2965 + +#define Anum_pg_db_role_setting_setdatabase 1 +#define Anum_pg_db_role_setting_setrole 2 +#define Anum_pg_db_role_setting_setconfig 3 + +#define Natts_pg_db_role_setting 3 + + +#endif /* PG_DB_ROLE_SETTING_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_default_acl.h b/install/include/postgresql/server/catalog/pg_default_acl.h new file mode 100644 index 00000000000..d6d0a03f0ce --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_default_acl.h @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------- + * + * pg_default_acl.h + * definition of the system catalog for default ACLs of new objects + * (pg_default_acl) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_default_acl.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DEFAULT_ACL_H +#define PG_DEFAULT_ACL_H + +#include "catalog/genbki.h" +#include "catalog/pg_default_acl_d.h" + +/* ---------------- + * pg_default_acl definition. cpp turns this into + * typedef struct FormData_pg_default_acl + * ---------------- + */ +CATALOG(pg_default_acl,826,DefaultAclRelationId) +{ + Oid oid; /* oid */ + Oid defaclrole BKI_LOOKUP(pg_authid); /* OID of role owning this + * ACL */ + Oid defaclnamespace BKI_LOOKUP_OPT(pg_namespace); /* OID of namespace, or + * 0 for all */ + char defaclobjtype; /* see DEFACLOBJ_xxx constants below */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + aclitem defaclacl[1] BKI_FORCE_NOT_NULL; /* permissions to add at + * CREATE time */ +#endif +} FormData_pg_default_acl; + +/* ---------------- + * Form_pg_default_acl corresponds to a pointer to a tuple with + * the format of pg_default_acl relation. + * ---------------- + */ +typedef FormData_pg_default_acl *Form_pg_default_acl; + +DECLARE_TOAST(pg_default_acl, 4143, 4144); + +DECLARE_UNIQUE_INDEX(pg_default_acl_role_nsp_obj_index, 827, DefaultAclRoleNspObjIndexId, on pg_default_acl using btree(defaclrole oid_ops, defaclnamespace oid_ops, defaclobjtype char_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_default_acl_oid_index, 828, DefaultAclOidIndexId, on pg_default_acl using btree(oid oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * Types of objects for which the user is allowed to specify default + * permissions through pg_default_acl. These codes are used in the + * defaclobjtype column. + */ +#define DEFACLOBJ_RELATION 'r' /* table, view */ +#define DEFACLOBJ_SEQUENCE 'S' /* sequence */ +#define DEFACLOBJ_FUNCTION 'f' /* function */ +#define DEFACLOBJ_TYPE 'T' /* type */ +#define DEFACLOBJ_NAMESPACE 'n' /* namespace */ + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_DEFAULT_ACL_H */ diff --git a/install/include/postgresql/server/catalog/pg_default_acl_d.h b/install/include/postgresql/server/catalog/pg_default_acl_d.h new file mode 100644 index 00000000000..28dba5f2b11 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_default_acl_d.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + * + * pg_default_acl_d.h + * Macro definitions for pg_default_acl + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DEFAULT_ACL_D_H +#define PG_DEFAULT_ACL_D_H + +#define DefaultAclRelationId 826 +#define DefaultAclRoleNspObjIndexId 827 +#define DefaultAclOidIndexId 828 + +#define Anum_pg_default_acl_oid 1 +#define Anum_pg_default_acl_defaclrole 2 +#define Anum_pg_default_acl_defaclnamespace 3 +#define Anum_pg_default_acl_defaclobjtype 4 +#define Anum_pg_default_acl_defaclacl 5 + +#define Natts_pg_default_acl 5 + + +/* + * Types of objects for which the user is allowed to specify default + * permissions through pg_default_acl. These codes are used in the + * defaclobjtype column. + */ +#define DEFACLOBJ_RELATION 'r' /* table, view */ +#define DEFACLOBJ_SEQUENCE 'S' /* sequence */ +#define DEFACLOBJ_FUNCTION 'f' /* function */ +#define DEFACLOBJ_TYPE 'T' /* type */ +#define DEFACLOBJ_NAMESPACE 'n' /* namespace */ + + +#endif /* PG_DEFAULT_ACL_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_depend.h b/install/include/postgresql/server/catalog/pg_depend.h new file mode 100644 index 00000000000..30dde6f8aa2 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_depend.h @@ -0,0 +1,77 @@ +/*------------------------------------------------------------------------- + * + * pg_depend.h + * definition of the "dependency" system catalog (pg_depend) + * + * pg_depend has no preloaded contents, so there is no pg_depend.dat + * file; dependencies for system-defined objects are loaded into it + * on-the-fly during initdb. Most built-in objects are pinned anyway, + * and hence need no explicit entries in pg_depend. + * + * NOTE: we do not represent all possible dependency pairs in pg_depend; + * for example, there's not much value in creating an explicit dependency + * from an attribute to its relation. Usually we make a dependency for + * cases where the relationship is conditional rather than essential + * (for example, not all triggers are dependent on constraints, but all + * attributes are dependent on relations) or where the dependency is not + * convenient to find from the contents of other catalogs. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_depend.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DEPEND_H +#define PG_DEPEND_H + +#include "catalog/genbki.h" +#include "catalog/pg_depend_d.h" + +/* ---------------- + * pg_depend definition. cpp turns this into + * typedef struct FormData_pg_depend + * ---------------- + */ +CATALOG(pg_depend,2608,DependRelationId) +{ + /* + * Identification of the dependent (referencing) object. + */ + Oid classid BKI_LOOKUP(pg_class); /* OID of table containing + * object */ + Oid objid; /* OID of object itself */ + int32 objsubid; /* column number, or 0 if not used */ + + /* + * Identification of the independent (referenced) object. + */ + Oid refclassid BKI_LOOKUP(pg_class); /* OID of table containing + * object */ + Oid refobjid; /* OID of object itself */ + int32 refobjsubid; /* column number, or 0 if not used */ + + /* + * Precise semantics of the relationship are specified by the deptype + * field. See DependencyType in catalog/dependency.h. + */ + char deptype; /* see codes in dependency.h */ +} FormData_pg_depend; + +/* ---------------- + * Form_pg_depend corresponds to a pointer to a row with + * the format of pg_depend relation. + * ---------------- + */ +typedef FormData_pg_depend *Form_pg_depend; + +DECLARE_INDEX(pg_depend_depender_index, 2673, DependDependerIndexId, on pg_depend using btree(classid oid_ops, objid oid_ops, objsubid int4_ops)); +DECLARE_INDEX(pg_depend_reference_index, 2674, DependReferenceIndexId, on pg_depend using btree(refclassid oid_ops, refobjid oid_ops, refobjsubid int4_ops)); + +#endif /* PG_DEPEND_H */ diff --git a/install/include/postgresql/server/catalog/pg_depend_d.h b/install/include/postgresql/server/catalog/pg_depend_d.h new file mode 100644 index 00000000000..f0c7a35e323 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_depend_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_depend_d.h + * Macro definitions for pg_depend + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DEPEND_D_H +#define PG_DEPEND_D_H + +#define DependRelationId 2608 +#define DependDependerIndexId 2673 +#define DependReferenceIndexId 2674 + +#define Anum_pg_depend_classid 1 +#define Anum_pg_depend_objid 2 +#define Anum_pg_depend_objsubid 3 +#define Anum_pg_depend_refclassid 4 +#define Anum_pg_depend_refobjid 5 +#define Anum_pg_depend_refobjsubid 6 +#define Anum_pg_depend_deptype 7 + +#define Natts_pg_depend 7 + + +#endif /* PG_DEPEND_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_description.h b/install/include/postgresql/server/catalog/pg_description.h new file mode 100644 index 00000000000..7545b92a159 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_description.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * pg_description.h + * definition of the "description" system catalog (pg_description) + * + * Because the contents of this table are taken from the *.dat files + * of other catalogs, there is no pg_description.dat file. The initial + * contents are assembled by genbki.pl and loaded during initdb. + * + * NOTE: an object is identified by the OID of the row that primarily + * defines the object, plus the OID of the table that that row appears in. + * For example, a function is identified by the OID of its pg_proc row + * plus the pg_class OID of table pg_proc. This allows unique identification + * of objects without assuming that OIDs are unique across tables. + * + * Since attributes don't have OIDs of their own, we identify an attribute + * comment by the objoid+classoid of its parent table, plus an "objsubid" + * giving the attribute column number. "objsubid" must be zero in a comment + * for a table itself, so that it is distinct from any column comment. + * Currently, objsubid is unused and zero for all other kinds of objects, + * but perhaps it might be useful someday to associate comments with + * constituent elements of other kinds of objects (arguments of a function, + * for example). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_description.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DESCRIPTION_H +#define PG_DESCRIPTION_H + +#include "catalog/genbki.h" +#include "catalog/pg_description_d.h" + +/* ---------------- + * pg_description definition. cpp turns this into + * typedef struct FormData_pg_description + * ---------------- + */ +CATALOG(pg_description,2609,DescriptionRelationId) +{ + Oid objoid; /* OID of object itself */ + Oid classoid; /* OID of table containing object */ + int32 objsubid; /* column number, or 0 if not used */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text description BKI_FORCE_NOT_NULL; /* description of object */ +#endif +} FormData_pg_description; + +/* ---------------- + * Form_pg_description corresponds to a pointer to a tuple with + * the format of pg_description relation. + * ---------------- + */ +typedef FormData_pg_description * Form_pg_description; + +DECLARE_TOAST(pg_description, 2834, 2835); + +DECLARE_UNIQUE_INDEX_PKEY(pg_description_o_c_o_index, 2675, DescriptionObjIndexId, on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops)); + +/* We do not use BKI_LOOKUP here because it causes problems for genbki.pl */ +DECLARE_FOREIGN_KEY((classoid), pg_class, (oid)); + +#endif /* PG_DESCRIPTION_H */ diff --git a/install/include/postgresql/server/catalog/pg_description_d.h b/install/include/postgresql/server/catalog/pg_description_d.h new file mode 100644 index 00000000000..2282ab4c287 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_description_d.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * pg_description_d.h + * Macro definitions for pg_description + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_DESCRIPTION_D_H +#define PG_DESCRIPTION_D_H + +#define DescriptionRelationId 2609 +#define DescriptionObjIndexId 2675 + +#define Anum_pg_description_objoid 1 +#define Anum_pg_description_classoid 2 +#define Anum_pg_description_objsubid 3 +#define Anum_pg_description_description 4 + +#define Natts_pg_description 4 + + +#endif /* PG_DESCRIPTION_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_enum.h b/install/include/postgresql/server/catalog/pg_enum.h new file mode 100644 index 00000000000..83a06682336 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_enum.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------- + * + * pg_enum.h + * definition of the "enum" system catalog (pg_enum) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_enum.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_ENUM_H +#define PG_ENUM_H + +#include "catalog/genbki.h" +#include "catalog/pg_enum_d.h" + +#include "nodes/pg_list.h" + +/* ---------------- + * pg_enum definition. cpp turns this into + * typedef struct FormData_pg_enum + * ---------------- + */ +CATALOG(pg_enum,3501,EnumRelationId) +{ + Oid oid; /* oid */ + Oid enumtypid BKI_LOOKUP(pg_type); /* OID of owning enum type */ + float4 enumsortorder; /* sort position of this enum value */ + NameData enumlabel; /* text representation of enum value */ +} FormData_pg_enum; + +/* ---------------- + * Form_pg_enum corresponds to a pointer to a tuple with + * the format of pg_enum relation. + * ---------------- + */ +typedef FormData_pg_enum *Form_pg_enum; + +DECLARE_UNIQUE_INDEX_PKEY(pg_enum_oid_index, 3502, EnumOidIndexId, on pg_enum using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_enum_typid_label_index, 3503, EnumTypIdLabelIndexId, on pg_enum using btree(enumtypid oid_ops, enumlabel name_ops)); +DECLARE_UNIQUE_INDEX(pg_enum_typid_sortorder_index, 3534, EnumTypIdSortOrderIndexId, on pg_enum using btree(enumtypid oid_ops, enumsortorder float4_ops)); + +/* + * prototypes for functions in pg_enum.c + */ +extern void EnumValuesCreate(Oid enumTypeOid, List *vals); +extern void EnumValuesDelete(Oid enumTypeOid); +extern void AddEnumLabel(Oid enumTypeOid, const char *newVal, + const char *neighbor, bool newValIsAfter, + bool skipIfExists); +extern void RenameEnumLabel(Oid enumTypeOid, + const char *oldVal, const char *newVal); +extern bool EnumUncommitted(Oid enum_id); +extern Size EstimateUncommittedEnumsSpace(void); +extern void SerializeUncommittedEnums(void *space, Size size); +extern void RestoreUncommittedEnums(void *space); +extern void AtEOXact_Enum(void); + +#endif /* PG_ENUM_H */ diff --git a/install/include/postgresql/server/catalog/pg_enum_d.h b/install/include/postgresql/server/catalog/pg_enum_d.h new file mode 100644 index 00000000000..56a81ea6e32 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_enum_d.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * pg_enum_d.h + * Macro definitions for pg_enum + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_ENUM_D_H +#define PG_ENUM_D_H + +#define EnumRelationId 3501 +#define EnumOidIndexId 3502 +#define EnumTypIdLabelIndexId 3503 +#define EnumTypIdSortOrderIndexId 3534 + +#define Anum_pg_enum_oid 1 +#define Anum_pg_enum_enumtypid 2 +#define Anum_pg_enum_enumsortorder 3 +#define Anum_pg_enum_enumlabel 4 + +#define Natts_pg_enum 4 + + +#endif /* PG_ENUM_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_event_trigger.h b/install/include/postgresql/server/catalog/pg_event_trigger.h new file mode 100644 index 00000000000..e30550f6e15 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_event_trigger.h @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------- + * + * pg_event_trigger.h + * definition of the "event trigger" system catalog (pg_event_trigger) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_event_trigger.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_EVENT_TRIGGER_H +#define PG_EVENT_TRIGGER_H + +#include "catalog/genbki.h" +#include "catalog/pg_event_trigger_d.h" + +/* ---------------- + * pg_event_trigger definition. cpp turns this into + * typedef struct FormData_pg_event_trigger + * ---------------- + */ +CATALOG(pg_event_trigger,3466,EventTriggerRelationId) +{ + Oid oid; /* oid */ + NameData evtname; /* trigger's name */ + NameData evtevent; /* trigger's event */ + Oid evtowner BKI_LOOKUP(pg_authid); /* trigger's owner */ + Oid evtfoid BKI_LOOKUP(pg_proc); /* OID of function to be + * called */ + char evtenabled; /* trigger's firing configuration WRT + * session_replication_role */ + +#ifdef CATALOG_VARLEN + text evttags[1]; /* command TAGs this event trigger targets */ +#endif +} FormData_pg_event_trigger; + +/* ---------------- + * Form_pg_event_trigger corresponds to a pointer to a tuple with + * the format of pg_event_trigger relation. + * ---------------- + */ +typedef FormData_pg_event_trigger *Form_pg_event_trigger; + +DECLARE_TOAST(pg_event_trigger, 4145, 4146); + +DECLARE_UNIQUE_INDEX(pg_event_trigger_evtname_index, 3467, EventTriggerNameIndexId, on pg_event_trigger using btree(evtname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_event_trigger_oid_index, 3468, EventTriggerOidIndexId, on pg_event_trigger using btree(oid oid_ops)); + +#endif /* PG_EVENT_TRIGGER_H */ diff --git a/install/include/postgresql/server/catalog/pg_event_trigger_d.h b/install/include/postgresql/server/catalog/pg_event_trigger_d.h new file mode 100644 index 00000000000..f66be700183 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_event_trigger_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_event_trigger_d.h + * Macro definitions for pg_event_trigger + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_EVENT_TRIGGER_D_H +#define PG_EVENT_TRIGGER_D_H + +#define EventTriggerRelationId 3466 +#define EventTriggerNameIndexId 3467 +#define EventTriggerOidIndexId 3468 + +#define Anum_pg_event_trigger_oid 1 +#define Anum_pg_event_trigger_evtname 2 +#define Anum_pg_event_trigger_evtevent 3 +#define Anum_pg_event_trigger_evtowner 4 +#define Anum_pg_event_trigger_evtfoid 5 +#define Anum_pg_event_trigger_evtenabled 6 +#define Anum_pg_event_trigger_evttags 7 + +#define Natts_pg_event_trigger 7 + + +#endif /* PG_EVENT_TRIGGER_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_extension.h b/install/include/postgresql/server/catalog/pg_extension.h new file mode 100644 index 00000000000..799c8ed9d09 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_extension.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * pg_extension.h + * definition of the "extension" system catalog (pg_extension) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_extension.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_EXTENSION_H +#define PG_EXTENSION_H + +#include "catalog/genbki.h" +#include "catalog/pg_extension_d.h" + +/* ---------------- + * pg_extension definition. cpp turns this into + * typedef struct FormData_pg_extension + * ---------------- + */ +CATALOG(pg_extension,3079,ExtensionRelationId) +{ + Oid oid; /* oid */ + NameData extname; /* extension name */ + Oid extowner BKI_LOOKUP(pg_authid); /* extension owner */ + Oid extnamespace BKI_LOOKUP(pg_namespace); /* namespace of + * contained objects */ + bool extrelocatable; /* if true, allow ALTER EXTENSION SET SCHEMA */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* extversion may never be null, but the others can be. */ + text extversion BKI_FORCE_NOT_NULL; /* extension version name */ + Oid extconfig[1] BKI_LOOKUP(pg_class); /* dumpable configuration + * tables */ + text extcondition[1]; /* WHERE clauses for config tables */ +#endif +} FormData_pg_extension; + +/* ---------------- + * Form_pg_extension corresponds to a pointer to a tuple with + * the format of pg_extension relation. + * ---------------- + */ +typedef FormData_pg_extension *Form_pg_extension; + +DECLARE_TOAST(pg_extension, 4147, 4148); + +DECLARE_UNIQUE_INDEX_PKEY(pg_extension_oid_index, 3080, ExtensionOidIndexId, on pg_extension using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_extension_name_index, 3081, ExtensionNameIndexId, on pg_extension using btree(extname name_ops)); + +#endif /* PG_EXTENSION_H */ diff --git a/install/include/postgresql/server/catalog/pg_extension_d.h b/install/include/postgresql/server/catalog/pg_extension_d.h new file mode 100644 index 00000000000..f1e8abb890f --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_extension_d.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * pg_extension_d.h + * Macro definitions for pg_extension + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_EXTENSION_D_H +#define PG_EXTENSION_D_H + +#define ExtensionRelationId 3079 +#define ExtensionOidIndexId 3080 +#define ExtensionNameIndexId 3081 + +#define Anum_pg_extension_oid 1 +#define Anum_pg_extension_extname 2 +#define Anum_pg_extension_extowner 3 +#define Anum_pg_extension_extnamespace 4 +#define Anum_pg_extension_extrelocatable 5 +#define Anum_pg_extension_extversion 6 +#define Anum_pg_extension_extconfig 7 +#define Anum_pg_extension_extcondition 8 + +#define Natts_pg_extension 8 + + +#endif /* PG_EXTENSION_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_foreign_data_wrapper.h b/install/include/postgresql/server/catalog/pg_foreign_data_wrapper.h new file mode 100644 index 00000000000..e7833ec8832 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_foreign_data_wrapper.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * pg_foreign_data_wrapper.h + * definition of the "foreign-data wrapper" system catalog (pg_foreign_data_wrapper) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_foreign_data_wrapper.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_FOREIGN_DATA_WRAPPER_H +#define PG_FOREIGN_DATA_WRAPPER_H + +#include "catalog/genbki.h" +#include "catalog/pg_foreign_data_wrapper_d.h" + +/* ---------------- + * pg_foreign_data_wrapper definition. cpp turns this into + * typedef struct FormData_pg_foreign_data_wrapper + * ---------------- + */ +CATALOG(pg_foreign_data_wrapper,2328,ForeignDataWrapperRelationId) +{ + Oid oid; /* oid */ + NameData fdwname; /* foreign-data wrapper name */ + Oid fdwowner BKI_LOOKUP(pg_authid); /* FDW owner */ + Oid fdwhandler BKI_LOOKUP_OPT(pg_proc); /* handler function, or 0 + * if none */ + Oid fdwvalidator BKI_LOOKUP_OPT(pg_proc); /* option validation + * function, or 0 if + * none */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + aclitem fdwacl[1]; /* access permissions */ + text fdwoptions[1]; /* FDW options */ +#endif +} FormData_pg_foreign_data_wrapper; + +/* ---------------- + * Form_pg_foreign_data_wrapper corresponds to a pointer to a tuple with + * the format of pg_foreign_data_wrapper relation. + * ---------------- + */ +typedef FormData_pg_foreign_data_wrapper *Form_pg_foreign_data_wrapper; + +DECLARE_TOAST(pg_foreign_data_wrapper, 4149, 4150); + +DECLARE_UNIQUE_INDEX_PKEY(pg_foreign_data_wrapper_oid_index, 112, ForeignDataWrapperOidIndexId, on pg_foreign_data_wrapper using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_foreign_data_wrapper_name_index, 548, ForeignDataWrapperNameIndexId, on pg_foreign_data_wrapper using btree(fdwname name_ops)); + +#endif /* PG_FOREIGN_DATA_WRAPPER_H */ diff --git a/install/include/postgresql/server/catalog/pg_foreign_data_wrapper_d.h b/install/include/postgresql/server/catalog/pg_foreign_data_wrapper_d.h new file mode 100644 index 00000000000..d62d72f967b --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_foreign_data_wrapper_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_foreign_data_wrapper_d.h + * Macro definitions for pg_foreign_data_wrapper + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_FOREIGN_DATA_WRAPPER_D_H +#define PG_FOREIGN_DATA_WRAPPER_D_H + +#define ForeignDataWrapperRelationId 2328 +#define ForeignDataWrapperOidIndexId 112 +#define ForeignDataWrapperNameIndexId 548 + +#define Anum_pg_foreign_data_wrapper_oid 1 +#define Anum_pg_foreign_data_wrapper_fdwname 2 +#define Anum_pg_foreign_data_wrapper_fdwowner 3 +#define Anum_pg_foreign_data_wrapper_fdwhandler 4 +#define Anum_pg_foreign_data_wrapper_fdwvalidator 5 +#define Anum_pg_foreign_data_wrapper_fdwacl 6 +#define Anum_pg_foreign_data_wrapper_fdwoptions 7 + +#define Natts_pg_foreign_data_wrapper 7 + + +#endif /* PG_FOREIGN_DATA_WRAPPER_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_foreign_server.h b/install/include/postgresql/server/catalog/pg_foreign_server.h new file mode 100644 index 00000000000..2a14871d742 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_foreign_server.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * pg_foreign_server.h + * definition of the "foreign server" system catalog (pg_foreign_server) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_foreign_server.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_FOREIGN_SERVER_H +#define PG_FOREIGN_SERVER_H + +#include "catalog/genbki.h" +#include "catalog/pg_foreign_server_d.h" + +/* ---------------- + * pg_foreign_server definition. cpp turns this into + * typedef struct FormData_pg_foreign_server + * ---------------- + */ +CATALOG(pg_foreign_server,1417,ForeignServerRelationId) +{ + Oid oid; /* oid */ + NameData srvname; /* foreign server name */ + Oid srvowner BKI_LOOKUP(pg_authid); /* server owner */ + Oid srvfdw BKI_LOOKUP(pg_foreign_data_wrapper); /* server FDW */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text srvtype; + text srvversion; + aclitem srvacl[1]; /* access permissions */ + text srvoptions[1]; /* FDW-specific options */ +#endif +} FormData_pg_foreign_server; + +/* ---------------- + * Form_pg_foreign_server corresponds to a pointer to a tuple with + * the format of pg_foreign_server relation. + * ---------------- + */ +typedef FormData_pg_foreign_server *Form_pg_foreign_server; + +DECLARE_TOAST(pg_foreign_server, 4151, 4152); + +DECLARE_UNIQUE_INDEX_PKEY(pg_foreign_server_oid_index, 113, ForeignServerOidIndexId, on pg_foreign_server using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_foreign_server_name_index, 549, ForeignServerNameIndexId, on pg_foreign_server using btree(srvname name_ops)); + +#endif /* PG_FOREIGN_SERVER_H */ diff --git a/install/include/postgresql/server/catalog/pg_foreign_server_d.h b/install/include/postgresql/server/catalog/pg_foreign_server_d.h new file mode 100644 index 00000000000..9d0559b4209 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_foreign_server_d.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * pg_foreign_server_d.h + * Macro definitions for pg_foreign_server + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_FOREIGN_SERVER_D_H +#define PG_FOREIGN_SERVER_D_H + +#define ForeignServerRelationId 1417 +#define ForeignServerOidIndexId 113 +#define ForeignServerNameIndexId 549 + +#define Anum_pg_foreign_server_oid 1 +#define Anum_pg_foreign_server_srvname 2 +#define Anum_pg_foreign_server_srvowner 3 +#define Anum_pg_foreign_server_srvfdw 4 +#define Anum_pg_foreign_server_srvtype 5 +#define Anum_pg_foreign_server_srvversion 6 +#define Anum_pg_foreign_server_srvacl 7 +#define Anum_pg_foreign_server_srvoptions 8 + +#define Natts_pg_foreign_server 8 + + +#endif /* PG_FOREIGN_SERVER_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_foreign_table.h b/install/include/postgresql/server/catalog/pg_foreign_table.h new file mode 100644 index 00000000000..cfa570a88c7 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_foreign_table.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * pg_foreign_table.h + * definition of the "foreign table" system catalog (pg_foreign_table) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_foreign_table.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_FOREIGN_TABLE_H +#define PG_FOREIGN_TABLE_H + +#include "catalog/genbki.h" +#include "catalog/pg_foreign_table_d.h" + +/* ---------------- + * pg_foreign_table definition. cpp turns this into + * typedef struct FormData_pg_foreign_table + * ---------------- + */ +CATALOG(pg_foreign_table,3118,ForeignTableRelationId) +{ + Oid ftrelid BKI_LOOKUP(pg_class); /* OID of foreign table */ + Oid ftserver BKI_LOOKUP(pg_foreign_server); /* OID of foreign server */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text ftoptions[1]; /* FDW-specific options */ +#endif +} FormData_pg_foreign_table; + +/* ---------------- + * Form_pg_foreign_table corresponds to a pointer to a tuple with + * the format of pg_foreign_table relation. + * ---------------- + */ +typedef FormData_pg_foreign_table *Form_pg_foreign_table; + +DECLARE_TOAST(pg_foreign_table, 4153, 4154); + +DECLARE_UNIQUE_INDEX_PKEY(pg_foreign_table_relid_index, 3119, ForeignTableRelidIndexId, on pg_foreign_table using btree(ftrelid oid_ops)); + +#endif /* PG_FOREIGN_TABLE_H */ diff --git a/install/include/postgresql/server/catalog/pg_foreign_table_d.h b/install/include/postgresql/server/catalog/pg_foreign_table_d.h new file mode 100644 index 00000000000..3e1f2dbbc9e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_foreign_table_d.h @@ -0,0 +1,31 @@ +/*------------------------------------------------------------------------- + * + * pg_foreign_table_d.h + * Macro definitions for pg_foreign_table + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_FOREIGN_TABLE_D_H +#define PG_FOREIGN_TABLE_D_H + +#define ForeignTableRelationId 3118 +#define ForeignTableRelidIndexId 3119 + +#define Anum_pg_foreign_table_ftrelid 1 +#define Anum_pg_foreign_table_ftserver 2 +#define Anum_pg_foreign_table_ftoptions 3 + +#define Natts_pg_foreign_table 3 + + +#endif /* PG_FOREIGN_TABLE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_index.h b/install/include/postgresql/server/catalog/pg_index.h new file mode 100644 index 00000000000..b0592571dae --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_index.h @@ -0,0 +1,90 @@ +/*------------------------------------------------------------------------- + * + * pg_index.h + * definition of the "index" system catalog (pg_index) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_index.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_INDEX_H +#define PG_INDEX_H + +#include "catalog/genbki.h" +#include "catalog/pg_index_d.h" + +/* ---------------- + * pg_index definition. cpp turns this into + * typedef struct FormData_pg_index. + * ---------------- + */ +CATALOG(pg_index,2610,IndexRelationId) BKI_SCHEMA_MACRO +{ + Oid indexrelid BKI_LOOKUP(pg_class); /* OID of the index */ + Oid indrelid BKI_LOOKUP(pg_class); /* OID of the relation it + * indexes */ + int16 indnatts; /* total number of columns in index */ + int16 indnkeyatts; /* number of key columns in index */ + bool indisunique; /* is this a unique index? */ + bool indnullsnotdistinct; /* null treatment in unique index */ + bool indisprimary; /* is this index for primary key? */ + bool indisexclusion; /* is this index for exclusion constraint? */ + bool indimmediate; /* is uniqueness enforced immediately? */ + bool indisclustered; /* is this the index last clustered by? */ + bool indisvalid; /* is this index valid for use by queries? */ + bool indcheckxmin; /* must we wait for xmin to be old? */ + bool indisready; /* is this index ready for inserts? */ + bool indislive; /* is this index alive at all? */ + bool indisreplident; /* is this index the identity for replication? */ + + /* variable-length fields start here, but we allow direct access to indkey */ + int2vector indkey BKI_FORCE_NOT_NULL; /* column numbers of indexed cols, + * or 0 */ + +#ifdef CATALOG_VARLEN + oidvector indcollation BKI_LOOKUP_OPT(pg_collation) BKI_FORCE_NOT_NULL; /* collation identifiers */ + oidvector indclass BKI_LOOKUP(pg_opclass) BKI_FORCE_NOT_NULL; /* opclass identifiers */ + int2vector indoption BKI_FORCE_NOT_NULL; /* per-column flags + * (AM-specific meanings) */ + pg_node_tree indexprs; /* expression trees for index attributes that + * are not simple column references; one for + * each zero entry in indkey[] */ + pg_node_tree indpred; /* expression tree for predicate, if a partial + * index; else NULL */ +#endif +} FormData_pg_index; + +/* ---------------- + * Form_pg_index corresponds to a pointer to a tuple with + * the format of pg_index relation. + * ---------------- + */ +typedef FormData_pg_index *Form_pg_index; + +DECLARE_INDEX(pg_index_indrelid_index, 2678, IndexIndrelidIndexId, on pg_index using btree(indrelid oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_index_indexrelid_index, 2679, IndexRelidIndexId, on pg_index using btree(indexrelid oid_ops)); + +/* indkey can contain zero (InvalidAttrNumber) to represent expressions */ +DECLARE_ARRAY_FOREIGN_KEY_OPT((indrelid, indkey), pg_attribute, (attrelid, attnum)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * Index AMs that support ordered scans must support these two indoption + * bits. Otherwise, the content of the per-column indoption fields is + * open for future definition. + */ +#define INDOPTION_DESC 0x0001 /* values are in reverse order */ +#define INDOPTION_NULLS_FIRST 0x0002 /* NULLs are first instead of last */ + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_INDEX_H */ diff --git a/install/include/postgresql/server/catalog/pg_index_d.h b/install/include/postgresql/server/catalog/pg_index_d.h new file mode 100644 index 00000000000..20927db1807 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_index_d.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * pg_index_d.h + * Macro definitions for pg_index + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_INDEX_D_H +#define PG_INDEX_D_H + +#define IndexRelationId 2610 +#define IndexIndrelidIndexId 2678 +#define IndexRelidIndexId 2679 + +#define Anum_pg_index_indexrelid 1 +#define Anum_pg_index_indrelid 2 +#define Anum_pg_index_indnatts 3 +#define Anum_pg_index_indnkeyatts 4 +#define Anum_pg_index_indisunique 5 +#define Anum_pg_index_indnullsnotdistinct 6 +#define Anum_pg_index_indisprimary 7 +#define Anum_pg_index_indisexclusion 8 +#define Anum_pg_index_indimmediate 9 +#define Anum_pg_index_indisclustered 10 +#define Anum_pg_index_indisvalid 11 +#define Anum_pg_index_indcheckxmin 12 +#define Anum_pg_index_indisready 13 +#define Anum_pg_index_indislive 14 +#define Anum_pg_index_indisreplident 15 +#define Anum_pg_index_indkey 16 +#define Anum_pg_index_indcollation 17 +#define Anum_pg_index_indclass 18 +#define Anum_pg_index_indoption 19 +#define Anum_pg_index_indexprs 20 +#define Anum_pg_index_indpred 21 + +#define Natts_pg_index 21 + + +/* + * Index AMs that support ordered scans must support these two indoption + * bits. Otherwise, the content of the per-column indoption fields is + * open for future definition. + */ +#define INDOPTION_DESC 0x0001 /* values are in reverse order */ +#define INDOPTION_NULLS_FIRST 0x0002 /* NULLs are first instead of last */ + + +#endif /* PG_INDEX_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_inherits.h b/install/include/postgresql/server/catalog/pg_inherits.h new file mode 100644 index 00000000000..ce154ab943b --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_inherits.h @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------- + * + * pg_inherits.h + * definition of the "inherits" system catalog (pg_inherits) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_inherits.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_INHERITS_H +#define PG_INHERITS_H + +#include "catalog/genbki.h" +#include "catalog/pg_inherits_d.h" + +#include "nodes/pg_list.h" +#include "storage/lock.h" + +/* ---------------- + * pg_inherits definition. cpp turns this into + * typedef struct FormData_pg_inherits + * ---------------- + */ +CATALOG(pg_inherits,2611,InheritsRelationId) +{ + Oid inhrelid BKI_LOOKUP(pg_class); + Oid inhparent BKI_LOOKUP(pg_class); + int32 inhseqno; + bool inhdetachpending; +} FormData_pg_inherits; + +/* ---------------- + * Form_pg_inherits corresponds to a pointer to a tuple with + * the format of pg_inherits relation. + * ---------------- + */ +typedef FormData_pg_inherits *Form_pg_inherits; + +DECLARE_UNIQUE_INDEX_PKEY(pg_inherits_relid_seqno_index, 2680, InheritsRelidSeqnoIndexId, on pg_inherits using btree(inhrelid oid_ops, inhseqno int4_ops)); +DECLARE_INDEX(pg_inherits_parent_index, 2187, InheritsParentIndexId, on pg_inherits using btree(inhparent oid_ops)); + + +extern List *find_inheritance_children(Oid parentrelId, LOCKMODE lockmode); +extern List *find_inheritance_children_extended(Oid parentrelId, bool omit_detached, + LOCKMODE lockmode, bool *detached_exist, TransactionId *detached_xmin); + +extern List *find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, + List **numparents); +extern bool has_subclass(Oid relationId); +extern bool has_superclass(Oid relationId); +extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId); +extern void StoreSingleInheritance(Oid relationId, Oid parentOid, + int32 seqNumber); +extern bool DeleteInheritsTuple(Oid inhrelid, Oid inhparent, + bool expect_detach_pending, + const char *childname); +extern bool PartitionHasPendingDetach(Oid partoid); + +#endif /* PG_INHERITS_H */ diff --git a/install/include/postgresql/server/catalog/pg_inherits_d.h b/install/include/postgresql/server/catalog/pg_inherits_d.h new file mode 100644 index 00000000000..2aef9af4603 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_inherits_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_inherits_d.h + * Macro definitions for pg_inherits + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_INHERITS_D_H +#define PG_INHERITS_D_H + +#define InheritsRelationId 2611 +#define InheritsRelidSeqnoIndexId 2680 +#define InheritsParentIndexId 2187 + +#define Anum_pg_inherits_inhrelid 1 +#define Anum_pg_inherits_inhparent 2 +#define Anum_pg_inherits_inhseqno 3 +#define Anum_pg_inherits_inhdetachpending 4 + +#define Natts_pg_inherits 4 + + +#endif /* PG_INHERITS_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_init_privs.h b/install/include/postgresql/server/catalog/pg_init_privs.h new file mode 100644 index 00000000000..34fe2b4d0e3 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_init_privs.h @@ -0,0 +1,83 @@ +/*------------------------------------------------------------------------- + * + * pg_init_privs.h + * definition of the "initial privileges" system catalog (pg_init_privs) + * + * NOTE: an object is identified by the OID of the row that primarily + * defines the object, plus the OID of the table that that row appears in. + * For example, a function is identified by the OID of its pg_proc row + * plus the pg_class OID of table pg_proc. This allows unique identification + * of objects without assuming that OIDs are unique across tables. + * + * Since attributes don't have OIDs of their own, we identify an attribute + * privilege by the objoid+classoid of its parent table, plus an "objsubid" + * giving the attribute column number. "objsubid" must be zero in a privilege + * for a table itself, so that it is distinct from any column privilege. + * Currently, objsubid is unused and zero for all other kinds of objects. + * + * Because the contents of this table depend on what is done with the other + * objects in the system (and, in particular, may change due to changes in + * system_views.sql), there is no pg_init_privs.dat file. The initial contents + * are loaded near the end of initdb. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_init_privs.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_INIT_PRIVS_H +#define PG_INIT_PRIVS_H + +#include "catalog/genbki.h" +#include "catalog/pg_init_privs_d.h" + +/* ---------------- + * pg_init_privs definition. cpp turns this into + * typedef struct FormData_pg_init_privs + * ---------------- + */ +CATALOG(pg_init_privs,3394,InitPrivsRelationId) +{ + Oid objoid; /* OID of object itself */ + Oid classoid BKI_LOOKUP(pg_class); /* OID of table containing + * object */ + int32 objsubid; /* column number, or 0 if not used */ + char privtype; /* from initdb or extension? */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + aclitem initprivs[1] BKI_FORCE_NOT_NULL; /* initial privs on object */ +#endif +} FormData_pg_init_privs; + +/* ---------------- + * Form_pg_init_privs corresponds to a pointer to a tuple with + * the format of pg_init_privs relation. + * ---------------- + */ +typedef FormData_pg_init_privs * Form_pg_init_privs; + +DECLARE_TOAST(pg_init_privs, 4155, 4156); + +DECLARE_UNIQUE_INDEX_PKEY(pg_init_privs_o_c_o_index, 3395, InitPrivsObjIndexId, on pg_init_privs using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops)); + +/* + * It is important to know if the initial privileges are from initdb or from an + * extension. This enum is used to provide that differentiation and the two + * places which populate this table (initdb and during CREATE EXTENSION, see + * recordExtensionInitPriv()) know to use the correct values. + */ + +typedef enum InitPrivsType +{ + INITPRIVS_INITDB = 'i', + INITPRIVS_EXTENSION = 'e' +} InitPrivsType; + +#endif /* PG_INIT_PRIVS_H */ diff --git a/install/include/postgresql/server/catalog/pg_init_privs_d.h b/install/include/postgresql/server/catalog/pg_init_privs_d.h new file mode 100644 index 00000000000..36906ee79bc --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_init_privs_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_init_privs_d.h + * Macro definitions for pg_init_privs + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_INIT_PRIVS_D_H +#define PG_INIT_PRIVS_D_H + +#define InitPrivsRelationId 3394 +#define InitPrivsObjIndexId 3395 + +#define Anum_pg_init_privs_objoid 1 +#define Anum_pg_init_privs_classoid 2 +#define Anum_pg_init_privs_objsubid 3 +#define Anum_pg_init_privs_privtype 4 +#define Anum_pg_init_privs_initprivs 5 + +#define Natts_pg_init_privs 5 + + +#endif /* PG_INIT_PRIVS_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_language.h b/install/include/postgresql/server/catalog/pg_language.h new file mode 100644 index 00000000000..02003b46276 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_language.h @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------- + * + * pg_language.h + * definition of the "language" system catalog (pg_language) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_language.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LANGUAGE_H +#define PG_LANGUAGE_H + +#include "catalog/genbki.h" +#include "catalog/pg_language_d.h" + +/* ---------------- + * pg_language definition. cpp turns this into + * typedef struct FormData_pg_language + * ---------------- + */ +CATALOG(pg_language,2612,LanguageRelationId) +{ + Oid oid; /* oid */ + + /* Language name */ + NameData lanname; + + /* Language's owner */ + Oid lanowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* Is a procedural language */ + bool lanispl BKI_DEFAULT(f); + + /* PL is trusted */ + bool lanpltrusted BKI_DEFAULT(f); + + /* Call handler, if it's a PL */ + Oid lanplcallfoid BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc); + + /* Optional anonymous-block handler function */ + Oid laninline BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc); + + /* Optional validation function */ + Oid lanvalidator BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* Access privileges */ + aclitem lanacl[1] BKI_DEFAULT(_null_); +#endif +} FormData_pg_language; + +/* ---------------- + * Form_pg_language corresponds to a pointer to a tuple with + * the format of pg_language relation. + * ---------------- + */ +typedef FormData_pg_language *Form_pg_language; + +DECLARE_TOAST(pg_language, 4157, 4158); + +DECLARE_UNIQUE_INDEX(pg_language_name_index, 2681, LanguageNameIndexId, on pg_language using btree(lanname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_language_oid_index, 2682, LanguageOidIndexId, on pg_language using btree(oid oid_ops)); + +#endif /* PG_LANGUAGE_H */ diff --git a/install/include/postgresql/server/catalog/pg_language_d.h b/install/include/postgresql/server/catalog/pg_language_d.h new file mode 100644 index 00000000000..2c87654103d --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_language_d.h @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------- + * + * pg_language_d.h + * Macro definitions for pg_language + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LANGUAGE_D_H +#define PG_LANGUAGE_D_H + +#define LanguageRelationId 2612 +#define LanguageNameIndexId 2681 +#define LanguageOidIndexId 2682 + +#define Anum_pg_language_oid 1 +#define Anum_pg_language_lanname 2 +#define Anum_pg_language_lanowner 3 +#define Anum_pg_language_lanispl 4 +#define Anum_pg_language_lanpltrusted 5 +#define Anum_pg_language_lanplcallfoid 6 +#define Anum_pg_language_laninline 7 +#define Anum_pg_language_lanvalidator 8 +#define Anum_pg_language_lanacl 9 + +#define Natts_pg_language 9 + +#define INTERNALlanguageId 12 +#define ClanguageId 13 +#define SQLlanguageId 14 + +#endif /* PG_LANGUAGE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_largeobject.h b/install/include/postgresql/server/catalog/pg_largeobject.h new file mode 100644 index 00000000000..95471073a8b --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_largeobject.h @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * pg_largeobject.h + * definition of the "large object" system catalog (pg_largeobject) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_largeobject.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LARGEOBJECT_H +#define PG_LARGEOBJECT_H + +#include "catalog/genbki.h" +#include "catalog/pg_largeobject_d.h" + +/* ---------------- + * pg_largeobject definition. cpp turns this into + * typedef struct FormData_pg_largeobject + * ---------------- + */ +CATALOG(pg_largeobject,2613,LargeObjectRelationId) +{ + Oid loid BKI_LOOKUP(pg_largeobject_metadata); /* Identifier of large + * object */ + int32 pageno; /* Page number (starting from 0) */ + + /* data has variable length, but we allow direct access; see inv_api.c */ + bytea data BKI_FORCE_NOT_NULL; /* Data for page (may be + * zero-length) */ +} FormData_pg_largeobject; + +/* ---------------- + * Form_pg_largeobject corresponds to a pointer to a tuple with + * the format of pg_largeobject relation. + * ---------------- + */ +typedef FormData_pg_largeobject *Form_pg_largeobject; + +DECLARE_UNIQUE_INDEX_PKEY(pg_largeobject_loid_pn_index, 2683, LargeObjectLOidPNIndexId, on pg_largeobject using btree(loid oid_ops, pageno int4_ops)); + +extern Oid LargeObjectCreate(Oid loid); +extern void LargeObjectDrop(Oid loid); +extern bool LargeObjectExists(Oid loid); + +#endif /* PG_LARGEOBJECT_H */ diff --git a/install/include/postgresql/server/catalog/pg_largeobject_d.h b/install/include/postgresql/server/catalog/pg_largeobject_d.h new file mode 100644 index 00000000000..1a1b086cbf5 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_largeobject_d.h @@ -0,0 +1,31 @@ +/*------------------------------------------------------------------------- + * + * pg_largeobject_d.h + * Macro definitions for pg_largeobject + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LARGEOBJECT_D_H +#define PG_LARGEOBJECT_D_H + +#define LargeObjectRelationId 2613 +#define LargeObjectLOidPNIndexId 2683 + +#define Anum_pg_largeobject_loid 1 +#define Anum_pg_largeobject_pageno 2 +#define Anum_pg_largeobject_data 3 + +#define Natts_pg_largeobject 3 + + +#endif /* PG_LARGEOBJECT_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_largeobject_metadata.h b/install/include/postgresql/server/catalog/pg_largeobject_metadata.h new file mode 100644 index 00000000000..80db926079f --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_largeobject_metadata.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * pg_largeobject_metadata.h + * definition of the "large object metadata" system catalog + * (pg_largeobject_metadata) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_largeobject_metadata.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LARGEOBJECT_METADATA_H +#define PG_LARGEOBJECT_METADATA_H + +#include "catalog/genbki.h" +#include "catalog/pg_largeobject_metadata_d.h" + +/* ---------------- + * pg_largeobject_metadata definition. cpp turns this into + * typedef struct FormData_pg_largeobject_metadata + * ---------------- + */ +CATALOG(pg_largeobject_metadata,2995,LargeObjectMetadataRelationId) +{ + Oid oid; /* oid */ + + Oid lomowner BKI_LOOKUP(pg_authid); /* OID of the largeobject + * owner */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + aclitem lomacl[1]; /* access permissions */ +#endif +} FormData_pg_largeobject_metadata; + +/* ---------------- + * Form_pg_largeobject_metadata corresponds to a pointer to a tuple + * with the format of pg_largeobject_metadata relation. + * ---------------- + */ +typedef FormData_pg_largeobject_metadata *Form_pg_largeobject_metadata; + +DECLARE_UNIQUE_INDEX_PKEY(pg_largeobject_metadata_oid_index, 2996, LargeObjectMetadataOidIndexId, on pg_largeobject_metadata using btree(oid oid_ops)); + +#endif /* PG_LARGEOBJECT_METADATA_H */ diff --git a/install/include/postgresql/server/catalog/pg_largeobject_metadata_d.h b/install/include/postgresql/server/catalog/pg_largeobject_metadata_d.h new file mode 100644 index 00000000000..ff92a0cf744 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_largeobject_metadata_d.h @@ -0,0 +1,31 @@ +/*------------------------------------------------------------------------- + * + * pg_largeobject_metadata_d.h + * Macro definitions for pg_largeobject_metadata + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LARGEOBJECT_METADATA_D_H +#define PG_LARGEOBJECT_METADATA_D_H + +#define LargeObjectMetadataRelationId 2995 +#define LargeObjectMetadataOidIndexId 2996 + +#define Anum_pg_largeobject_metadata_oid 1 +#define Anum_pg_largeobject_metadata_lomowner 2 +#define Anum_pg_largeobject_metadata_lomacl 3 + +#define Natts_pg_largeobject_metadata 3 + + +#endif /* PG_LARGEOBJECT_METADATA_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_namespace.h b/install/include/postgresql/server/catalog/pg_namespace.h new file mode 100644 index 00000000000..2b0c2431788 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_namespace.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * pg_namespace.h + * definition of the "namespace" system catalog (pg_namespace) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_namespace.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_NAMESPACE_H +#define PG_NAMESPACE_H + +#include "catalog/genbki.h" +#include "catalog/pg_namespace_d.h" +#include "utils/acl.h" + +/* ---------------------------------------------------------------- + * pg_namespace definition. + * + * cpp turns this into typedef struct FormData_pg_namespace + * + * nspname name of the namespace + * nspowner owner (creator) of the namespace + * nspacl access privilege list + * ---------------------------------------------------------------- + */ +CATALOG(pg_namespace,2615,NamespaceRelationId) +{ + Oid oid; /* oid */ + + NameData nspname; + Oid nspowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + aclitem nspacl[1]; +#endif +} FormData_pg_namespace; + +/* ---------------- + * Form_pg_namespace corresponds to a pointer to a tuple with + * the format of pg_namespace relation. + * ---------------- + */ +typedef FormData_pg_namespace *Form_pg_namespace; + +DECLARE_TOAST(pg_namespace, 4163, 4164); + +DECLARE_UNIQUE_INDEX(pg_namespace_nspname_index, 2684, NamespaceNameIndexId, on pg_namespace using btree(nspname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_namespace_oid_index, 2685, NamespaceOidIndexId, on pg_namespace using btree(oid oid_ops)); + +/* + * prototypes for functions in pg_namespace.c + */ +extern Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp); + +#endif /* PG_NAMESPACE_H */ diff --git a/install/include/postgresql/server/catalog/pg_namespace_d.h b/install/include/postgresql/server/catalog/pg_namespace_d.h new file mode 100644 index 00000000000..954c39d128f --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_namespace_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_namespace_d.h + * Macro definitions for pg_namespace + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_NAMESPACE_D_H +#define PG_NAMESPACE_D_H + +#define NamespaceRelationId 2615 +#define NamespaceNameIndexId 2684 +#define NamespaceOidIndexId 2685 + +#define Anum_pg_namespace_oid 1 +#define Anum_pg_namespace_nspname 2 +#define Anum_pg_namespace_nspowner 3 +#define Anum_pg_namespace_nspacl 4 + +#define Natts_pg_namespace 4 + +#define PG_CATALOG_NAMESPACE 11 +#define PG_TOAST_NAMESPACE 99 +#define PG_PUBLIC_NAMESPACE 2200 + +#endif /* PG_NAMESPACE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_opclass.h b/install/include/postgresql/server/catalog/pg_opclass.h new file mode 100644 index 00000000000..b4b6325c068 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_opclass.h @@ -0,0 +1,88 @@ +/*------------------------------------------------------------------------- + * + * pg_opclass.h + * definition of the "operator class" system catalog (pg_opclass) + * + * The primary key for this table is --- + * that is, there is a row for each valid combination of opclass name and + * index access method type. This row specifies the expected input data type + * for the opclass (the type of the heap column, or the expression output type + * in the case of an index expression). Note that types binary-coercible to + * the specified type will be accepted too. + * + * For a given pair, there can be at most one row that + * has opcdefault = true; this row is the default opclass for such data in + * such an index. (This is not currently enforced by an index, because we + * don't support partial indexes on system catalogs.) + * + * Normally opckeytype = InvalidOid (zero), indicating that the data stored + * in the index is the same as the data in the indexed column. If opckeytype + * is nonzero then it indicates that a conversion step is needed to produce + * the stored index data, which will be of type opckeytype (which might be + * the same or different from the input datatype). Performing such a + * conversion is the responsibility of the index access method --- not all + * AMs support this. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_opclass.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_OPCLASS_H +#define PG_OPCLASS_H + +#include "catalog/genbki.h" +#include "catalog/pg_opclass_d.h" + +/* ---------------- + * pg_opclass definition. cpp turns this into + * typedef struct FormData_pg_opclass + * ---------------- + */ +CATALOG(pg_opclass,2616,OperatorClassRelationId) +{ + Oid oid; /* oid */ + + /* index access method opclass is for */ + Oid opcmethod BKI_LOOKUP(pg_am); + + /* name of this opclass */ + NameData opcname; + + /* namespace of this opclass */ + Oid opcnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* opclass owner */ + Oid opcowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* containing operator family */ + Oid opcfamily BKI_LOOKUP(pg_opfamily); + + /* type of data indexed by opclass */ + Oid opcintype BKI_LOOKUP(pg_type); + + /* T if opclass is default for opcintype */ + bool opcdefault BKI_DEFAULT(t); + + /* type of data in index, or InvalidOid if same as input column type */ + Oid opckeytype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); +} FormData_pg_opclass; + +/* ---------------- + * Form_pg_opclass corresponds to a pointer to a tuple with + * the format of pg_opclass relation. + * ---------------- + */ +typedef FormData_pg_opclass *Form_pg_opclass; + +DECLARE_UNIQUE_INDEX(pg_opclass_am_name_nsp_index, 2686, OpclassAmNameNspIndexId, on pg_opclass using btree(opcmethod oid_ops, opcname name_ops, opcnamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_opclass_oid_index, 2687, OpclassOidIndexId, on pg_opclass using btree(oid oid_ops)); + +#endif /* PG_OPCLASS_H */ diff --git a/install/include/postgresql/server/catalog/pg_opclass_d.h b/install/include/postgresql/server/catalog/pg_opclass_d.h new file mode 100644 index 00000000000..707d3c9345f --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_opclass_d.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * pg_opclass_d.h + * Macro definitions for pg_opclass + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_OPCLASS_D_H +#define PG_OPCLASS_D_H + +#define OperatorClassRelationId 2616 +#define OpclassAmNameNspIndexId 2686 +#define OpclassOidIndexId 2687 + +#define Anum_pg_opclass_oid 1 +#define Anum_pg_opclass_opcmethod 2 +#define Anum_pg_opclass_opcname 3 +#define Anum_pg_opclass_opcnamespace 4 +#define Anum_pg_opclass_opcowner 5 +#define Anum_pg_opclass_opcfamily 6 +#define Anum_pg_opclass_opcintype 7 +#define Anum_pg_opclass_opcdefault 8 +#define Anum_pg_opclass_opckeytype 9 + +#define Natts_pg_opclass 9 + +#define DATE_BTREE_OPS_OID 3122 +#define FLOAT8_BTREE_OPS_OID 3123 +#define INT2_BTREE_OPS_OID 1979 +#define INT4_BTREE_OPS_OID 1978 +#define INT8_BTREE_OPS_OID 3124 +#define NUMERIC_BTREE_OPS_OID 3125 +#define OID_BTREE_OPS_OID 1981 +#define TEXT_BTREE_OPS_OID 3126 +#define TIMESTAMPTZ_BTREE_OPS_OID 3127 +#define TIMESTAMP_BTREE_OPS_OID 3128 +#define TEXT_BTREE_PATTERN_OPS_OID 4217 +#define VARCHAR_BTREE_PATTERN_OPS_OID 4218 +#define BPCHAR_BTREE_PATTERN_OPS_OID 4219 + +#endif /* PG_OPCLASS_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_operator.h b/install/include/postgresql/server/catalog/pg_operator.h new file mode 100644 index 00000000000..e60cf782a64 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_operator.h @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------------- + * + * pg_operator.h + * definition of the "operator" system catalog (pg_operator) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_operator.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_OPERATOR_H +#define PG_OPERATOR_H + +#include "catalog/genbki.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_operator_d.h" +#include "nodes/pg_list.h" + +/* ---------------- + * pg_operator definition. cpp turns this into + * typedef struct FormData_pg_operator + * ---------------- + */ +CATALOG(pg_operator,2617,OperatorRelationId) +{ + Oid oid; /* oid */ + + /* name of operator */ + NameData oprname; + + /* OID of namespace containing this oper */ + Oid oprnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* operator owner */ + Oid oprowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* 'l' for prefix or 'b' for infix */ + char oprkind BKI_DEFAULT(b); + + /* can be used in merge join? */ + bool oprcanmerge BKI_DEFAULT(f); + + /* can be used in hash join? */ + bool oprcanhash BKI_DEFAULT(f); + + /* left arg type, or 0 if prefix operator */ + Oid oprleft BKI_LOOKUP_OPT(pg_type); + + /* right arg type */ + Oid oprright BKI_LOOKUP(pg_type); + + /* result datatype; can be 0 in a "shell" operator */ + Oid oprresult BKI_LOOKUP_OPT(pg_type); + + /* OID of commutator oper, or 0 if none */ + Oid oprcom BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_operator); + + /* OID of negator oper, or 0 if none */ + Oid oprnegate BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_operator); + + /* OID of underlying function; can be 0 in a "shell" operator */ + regproc oprcode BKI_LOOKUP_OPT(pg_proc); + + /* OID of restriction estimator, or 0 */ + regproc oprrest BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* OID of join estimator, or 0 */ + regproc oprjoin BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); +} FormData_pg_operator; + +/* ---------------- + * Form_pg_operator corresponds to a pointer to a tuple with + * the format of pg_operator relation. + * ---------------- + */ +typedef FormData_pg_operator *Form_pg_operator; + +DECLARE_UNIQUE_INDEX_PKEY(pg_operator_oid_index, 2688, OperatorOidIndexId, on pg_operator using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_n_index, 2689, OperatorNameNspIndexId, on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprnamespace oid_ops)); + + +extern ObjectAddress OperatorCreate(const char *operatorName, + Oid operatorNamespace, + Oid leftTypeId, + Oid rightTypeId, + Oid procedureId, + List *commutatorName, + List *negatorName, + Oid restrictionId, + Oid joinId, + bool canMerge, + bool canHash); + +extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, + bool makeExtensionDep, + bool isUpdate); + +extern void OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete); + +#endif /* PG_OPERATOR_H */ diff --git a/install/include/postgresql/server/catalog/pg_operator_d.h b/install/include/postgresql/server/catalog/pg_operator_d.h new file mode 100644 index 00000000000..84ec7dc0ed0 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_operator_d.h @@ -0,0 +1,142 @@ +/*------------------------------------------------------------------------- + * + * pg_operator_d.h + * Macro definitions for pg_operator + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_OPERATOR_D_H +#define PG_OPERATOR_D_H + +#define OperatorRelationId 2617 +#define OperatorOidIndexId 2688 +#define OperatorNameNspIndexId 2689 + +#define Anum_pg_operator_oid 1 +#define Anum_pg_operator_oprname 2 +#define Anum_pg_operator_oprnamespace 3 +#define Anum_pg_operator_oprowner 4 +#define Anum_pg_operator_oprkind 5 +#define Anum_pg_operator_oprcanmerge 6 +#define Anum_pg_operator_oprcanhash 7 +#define Anum_pg_operator_oprleft 8 +#define Anum_pg_operator_oprright 9 +#define Anum_pg_operator_oprresult 10 +#define Anum_pg_operator_oprcom 11 +#define Anum_pg_operator_oprnegate 12 +#define Anum_pg_operator_oprcode 13 +#define Anum_pg_operator_oprrest 14 +#define Anum_pg_operator_oprjoin 15 + +#define Natts_pg_operator 15 + +#define BooleanNotEqualOperator 85 +#define BooleanEqualOperator 91 +#define Int4EqualOperator 96 +#define Int4LessOperator 97 +#define TextEqualOperator 98 +#define TextPrefixOperator 3877 +#define NameEqualTextOperator 254 +#define NameLessTextOperator 255 +#define NameGreaterEqualTextOperator 257 +#define TIDEqualOperator 387 +#define TIDLessOperator 2799 +#define TIDGreaterOperator 2800 +#define TIDLessEqOperator 2801 +#define TIDGreaterEqOperator 2802 +#define Int8LessOperator 412 +#define OID_NAME_REGEXEQ_OP 639 +#define OID_TEXT_REGEXEQ_OP 641 +#define TextLessOperator 664 +#define TextGreaterEqualOperator 667 +#define Float8LessOperator 672 +#define BpcharEqualOperator 1054 +#define OID_BPCHAR_REGEXEQ_OP 1055 +#define BpcharLessOperator 1058 +#define BpcharGreaterEqualOperator 1061 +#define ARRAY_EQ_OP 1070 +#define ARRAY_LT_OP 1072 +#define ARRAY_GT_OP 1073 +#define OID_NAME_LIKE_OP 1207 +#define OID_TEXT_LIKE_OP 1209 +#define OID_BPCHAR_LIKE_OP 1211 +#define OID_NAME_ICREGEXEQ_OP 1226 +#define OID_TEXT_ICREGEXEQ_OP 1228 +#define OID_BPCHAR_ICREGEXEQ_OP 1234 +#define OID_INET_SUB_OP 931 +#define OID_INET_SUBEQ_OP 932 +#define OID_INET_SUP_OP 933 +#define OID_INET_SUPEQ_OP 934 +#define OID_INET_OVERLAP_OP 3552 +#define OID_NAME_ICLIKE_OP 1625 +#define OID_TEXT_ICLIKE_OP 1627 +#define OID_BPCHAR_ICLIKE_OP 1629 +#define ByteaEqualOperator 1955 +#define ByteaLessOperator 1957 +#define ByteaGreaterEqualOperator 1960 +#define OID_BYTEA_LIKE_OP 2016 +#define TextPatternLessOperator 2314 +#define TextPatternGreaterEqualOperator 2317 +#define BpcharPatternLessOperator 2326 +#define BpcharPatternGreaterEqualOperator 2329 +#define OID_ARRAY_OVERLAP_OP 2750 +#define OID_ARRAY_CONTAINS_OP 2751 +#define OID_ARRAY_CONTAINED_OP 2752 +#define RECORD_EQ_OP 2988 +#define RECORD_LT_OP 2990 +#define RECORD_GT_OP 2991 +#define OID_RANGE_LESS_OP 3884 +#define OID_RANGE_LESS_EQUAL_OP 3885 +#define OID_RANGE_GREATER_EQUAL_OP 3886 +#define OID_RANGE_GREATER_OP 3887 +#define OID_RANGE_OVERLAP_OP 3888 +#define OID_RANGE_CONTAINS_ELEM_OP 3889 +#define OID_RANGE_CONTAINS_OP 3890 +#define OID_RANGE_ELEM_CONTAINED_OP 3891 +#define OID_RANGE_CONTAINED_OP 3892 +#define OID_RANGE_LEFT_OP 3893 +#define OID_RANGE_RIGHT_OP 3894 +#define OID_RANGE_OVERLAPS_LEFT_OP 3895 +#define OID_RANGE_OVERLAPS_RIGHT_OP 3896 +#define OID_MULTIRANGE_LESS_OP 2862 +#define OID_MULTIRANGE_LESS_EQUAL_OP 2863 +#define OID_MULTIRANGE_GREATER_EQUAL_OP 2864 +#define OID_MULTIRANGE_GREATER_OP 2865 +#define OID_RANGE_OVERLAPS_MULTIRANGE_OP 2866 +#define OID_MULTIRANGE_OVERLAPS_RANGE_OP 2867 +#define OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP 2868 +#define OID_MULTIRANGE_CONTAINS_ELEM_OP 2869 +#define OID_MULTIRANGE_CONTAINS_RANGE_OP 2870 +#define OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP 2871 +#define OID_MULTIRANGE_ELEM_CONTAINED_OP 2872 +#define OID_MULTIRANGE_RANGE_CONTAINED_OP 2873 +#define OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP 2874 +#define OID_RANGE_CONTAINS_MULTIRANGE_OP 4539 +#define OID_RANGE_MULTIRANGE_CONTAINED_OP 4540 +#define OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP 2875 +#define OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP 2876 +#define OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP 2877 +#define OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP 3585 +#define OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP 4035 +#define OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP 4142 +#define OID_RANGE_ADJACENT_MULTIRANGE_OP 4179 +#define OID_MULTIRANGE_ADJACENT_RANGE_OP 4180 +#define OID_MULTIRANGE_ADJACENT_MULTIRANGE_OP 4198 +#define OID_RANGE_LEFT_MULTIRANGE_OP 4395 +#define OID_MULTIRANGE_LEFT_RANGE_OP 4396 +#define OID_MULTIRANGE_LEFT_MULTIRANGE_OP 4397 +#define OID_RANGE_RIGHT_MULTIRANGE_OP 4398 +#define OID_MULTIRANGE_RIGHT_RANGE_OP 4399 +#define OID_MULTIRANGE_RIGHT_MULTIRANGE_OP 4400 + +#endif /* PG_OPERATOR_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_opfamily.h b/install/include/postgresql/server/catalog/pg_opfamily.h new file mode 100644 index 00000000000..39b8d7c2195 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_opfamily.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * pg_opfamily.h + * definition of the "operator family" system catalog (pg_opfamily) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_opfamily.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_OPFAMILY_H +#define PG_OPFAMILY_H + +#include "catalog/genbki.h" +#include "catalog/pg_opfamily_d.h" + +/* ---------------- + * pg_opfamily definition. cpp turns this into + * typedef struct FormData_pg_opfamily + * ---------------- + */ +CATALOG(pg_opfamily,2753,OperatorFamilyRelationId) +{ + Oid oid; /* oid */ + + /* index access method opfamily is for */ + Oid opfmethod BKI_LOOKUP(pg_am); + + /* name of this opfamily */ + NameData opfname; + + /* namespace of this opfamily */ + Oid opfnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* opfamily owner */ + Oid opfowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); +} FormData_pg_opfamily; + +/* ---------------- + * Form_pg_opfamily corresponds to a pointer to a tuple with + * the format of pg_opfamily relation. + * ---------------- + */ +typedef FormData_pg_opfamily *Form_pg_opfamily; + +DECLARE_UNIQUE_INDEX(pg_opfamily_am_name_nsp_index, 2754, OpfamilyAmNameNspIndexId, on pg_opfamily using btree(opfmethod oid_ops, opfname name_ops, opfnamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_opfamily_oid_index, 2755, OpfamilyOidIndexId, on pg_opfamily using btree(oid oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* This does not account for non-core opfamilies that might accept boolean */ +#define IsBuiltinBooleanOpfamily(opfamily) \ + ((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID) + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_OPFAMILY_H */ diff --git a/install/include/postgresql/server/catalog/pg_opfamily_d.h b/install/include/postgresql/server/catalog/pg_opfamily_d.h new file mode 100644 index 00000000000..7be8ff7a6eb --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_opfamily_d.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * pg_opfamily_d.h + * Macro definitions for pg_opfamily + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_OPFAMILY_D_H +#define PG_OPFAMILY_D_H + +#define OperatorFamilyRelationId 2753 +#define OpfamilyAmNameNspIndexId 2754 +#define OpfamilyOidIndexId 2755 + +#define Anum_pg_opfamily_oid 1 +#define Anum_pg_opfamily_opfmethod 2 +#define Anum_pg_opfamily_opfname 3 +#define Anum_pg_opfamily_opfnamespace 4 +#define Anum_pg_opfamily_opfowner 5 + +#define Natts_pg_opfamily 5 + + +/* This does not account for non-core opfamilies that might accept boolean */ +#define IsBuiltinBooleanOpfamily(opfamily) \ + ((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID) + +#define BOOL_BTREE_FAM_OID 424 +#define BPCHAR_BTREE_FAM_OID 426 +#define BYTEA_BTREE_FAM_OID 428 +#define NETWORK_BTREE_FAM_OID 1974 +#define INTEGER_BTREE_FAM_OID 1976 +#define INTERVAL_BTREE_FAM_OID 1982 +#define OID_BTREE_FAM_OID 1989 +#define TEXT_BTREE_FAM_OID 1994 +#define TEXT_PATTERN_BTREE_FAM_OID 2095 +#define BPCHAR_PATTERN_BTREE_FAM_OID 2097 +#define BOOL_HASH_FAM_OID 2222 +#define TEXT_SPGIST_FAM_OID 4017 + +#endif /* PG_OPFAMILY_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_parameter_acl.h b/install/include/postgresql/server/catalog/pg_parameter_acl.h new file mode 100644 index 00000000000..1612cebd0e2 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_parameter_acl.h @@ -0,0 +1,60 @@ +/*------------------------------------------------------------------------- + * + * pg_parameter_acl.h + * definition of the "configuration parameter ACL" system catalog + * (pg_parameter_acl). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_parameter_acl.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PARAMETER_ACL_H +#define PG_PARAMETER_ACL_H + +#include "catalog/genbki.h" +#include "catalog/pg_parameter_acl_d.h" + +/* ---------------- + * pg_parameter_acl definition. cpp turns this into + * typedef struct FormData_pg_parameter_acl + * ---------------- + */ +CATALOG(pg_parameter_acl,6243,ParameterAclRelationId) BKI_SHARED_RELATION +{ + Oid oid; /* oid */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* name of parameter */ + text parname BKI_FORCE_NOT_NULL; + + /* access permissions */ + aclitem paracl[1] BKI_DEFAULT(_null_); +#endif +} FormData_pg_parameter_acl; + + +/* ---------------- + * Form_pg_parameter_acl corresponds to a pointer to a tuple with + * the format of pg_parameter_acl relation. + * ---------------- + */ +typedef FormData_pg_parameter_acl * Form_pg_parameter_acl; + +DECLARE_TOAST_WITH_MACRO(pg_parameter_acl, 6244, 6245, PgParameterAclToastTable, PgParameterAclToastIndex); + +DECLARE_UNIQUE_INDEX(pg_parameter_acl_parname_index, 6246, ParameterAclParnameIndexId, on pg_parameter_acl using btree(parname text_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_parameter_acl_oid_index, 6247, ParameterAclOidIndexId, on pg_parameter_acl using btree(oid oid_ops)); + + +extern Oid ParameterAclLookup(const char *parameter, bool missing_ok); +extern Oid ParameterAclCreate(const char *parameter); + +#endif /* PG_PARAMETER_ACL_H */ diff --git a/install/include/postgresql/server/catalog/pg_parameter_acl_d.h b/install/include/postgresql/server/catalog/pg_parameter_acl_d.h new file mode 100644 index 00000000000..e457e211e69 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_parameter_acl_d.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * pg_parameter_acl_d.h + * Macro definitions for pg_parameter_acl + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PARAMETER_ACL_D_H +#define PG_PARAMETER_ACL_D_H + +#define ParameterAclRelationId 6243 +#define PgParameterAclToastTable 6244 +#define PgParameterAclToastIndex 6245 +#define ParameterAclParnameIndexId 6246 +#define ParameterAclOidIndexId 6247 + +#define Anum_pg_parameter_acl_oid 1 +#define Anum_pg_parameter_acl_parname 2 +#define Anum_pg_parameter_acl_paracl 3 + +#define Natts_pg_parameter_acl 3 + + +#endif /* PG_PARAMETER_ACL_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_partitioned_table.h b/install/include/postgresql/server/catalog/pg_partitioned_table.h new file mode 100644 index 00000000000..eb867ad62b0 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_partitioned_table.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * pg_partitioned_table.h + * definition of the "partitioned table" system catalog + * (pg_partitioned_table) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_partitioned_table.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PARTITIONED_TABLE_H +#define PG_PARTITIONED_TABLE_H + +#include "catalog/genbki.h" +#include "catalog/pg_partitioned_table_d.h" + +/* ---------------- + * pg_partitioned_table definition. cpp turns this into + * typedef struct FormData_pg_partitioned_table + * ---------------- + */ +CATALOG(pg_partitioned_table,3350,PartitionedRelationId) +{ + Oid partrelid BKI_LOOKUP(pg_class); /* partitioned table oid */ + char partstrat; /* partitioning strategy */ + int16 partnatts; /* number of partition key columns */ + Oid partdefid BKI_LOOKUP_OPT(pg_class); /* default partition oid; + * 0 if there isn't one */ + + /* + * variable-length fields start here, but we allow direct access to + * partattrs via the C struct. That's because the first variable-length + * field of a heap tuple can be reliably accessed using its C struct + * offset, as previous fields are all non-nullable fixed-length fields. + */ + int2vector partattrs BKI_FORCE_NOT_NULL; /* each member of the array is + * the attribute number of a + * partition key column, or 0 + * if the column is actually + * an expression */ + +#ifdef CATALOG_VARLEN + oidvector partclass BKI_LOOKUP(pg_opclass) BKI_FORCE_NOT_NULL; /* operator class to + * compare keys */ + oidvector partcollation BKI_LOOKUP_OPT(pg_collation) BKI_FORCE_NOT_NULL; /* user-specified + * collation for keys */ + pg_node_tree partexprs; /* list of expressions in the partition key; + * one item for each zero entry in partattrs[] */ +#endif +} FormData_pg_partitioned_table; + +/* ---------------- + * Form_pg_partitioned_table corresponds to a pointer to a tuple with + * the format of pg_partitioned_table relation. + * ---------------- + */ +typedef FormData_pg_partitioned_table *Form_pg_partitioned_table; + +DECLARE_TOAST(pg_partitioned_table, 4165, 4166); + +DECLARE_UNIQUE_INDEX_PKEY(pg_partitioned_table_partrelid_index, 3351, PartitionedRelidIndexId, on pg_partitioned_table using btree(partrelid oid_ops)); + +/* partattrs can contain zero (InvalidAttrNumber) to represent expressions */ +DECLARE_ARRAY_FOREIGN_KEY_OPT((partrelid, partattrs), pg_attribute, (attrelid, attnum)); + +#endif /* PG_PARTITIONED_TABLE_H */ diff --git a/install/include/postgresql/server/catalog/pg_partitioned_table_d.h b/install/include/postgresql/server/catalog/pg_partitioned_table_d.h new file mode 100644 index 00000000000..838a94e5303 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_partitioned_table_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_partitioned_table_d.h + * Macro definitions for pg_partitioned_table + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PARTITIONED_TABLE_D_H +#define PG_PARTITIONED_TABLE_D_H + +#define PartitionedRelationId 3350 +#define PartitionedRelidIndexId 3351 + +#define Anum_pg_partitioned_table_partrelid 1 +#define Anum_pg_partitioned_table_partstrat 2 +#define Anum_pg_partitioned_table_partnatts 3 +#define Anum_pg_partitioned_table_partdefid 4 +#define Anum_pg_partitioned_table_partattrs 5 +#define Anum_pg_partitioned_table_partclass 6 +#define Anum_pg_partitioned_table_partcollation 7 +#define Anum_pg_partitioned_table_partexprs 8 + +#define Natts_pg_partitioned_table 8 + + +#endif /* PG_PARTITIONED_TABLE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_policy.h b/install/include/postgresql/server/catalog/pg_policy.h new file mode 100644 index 00000000000..c9525ece74c --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_policy.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * pg_policy.h + * definition of the "policy" system catalog (pg_policy) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_policy.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_POLICY_H +#define PG_POLICY_H + +#include "catalog/genbki.h" +#include "catalog/pg_policy_d.h" + +/* ---------------- + * pg_policy definition. cpp turns this into + * typedef struct FormData_pg_policy + * ---------------- + */ +CATALOG(pg_policy,3256,PolicyRelationId) +{ + Oid oid; /* oid */ + NameData polname; /* Policy name. */ + Oid polrelid BKI_LOOKUP(pg_class); /* Oid of the relation with + * policy. */ + char polcmd; /* One of ACL_*_CHR, or '*' for all */ + bool polpermissive; /* restrictive or permissive policy */ + +#ifdef CATALOG_VARLEN + /* Roles to which the policy is applied; zero means PUBLIC */ + Oid polroles[1] BKI_LOOKUP_OPT(pg_authid) BKI_FORCE_NOT_NULL; + pg_node_tree polqual; /* Policy quals. */ + pg_node_tree polwithcheck; /* WITH CHECK quals. */ +#endif +} FormData_pg_policy; + +/* ---------------- + * Form_pg_policy corresponds to a pointer to a row with + * the format of pg_policy relation. + * ---------------- + */ +typedef FormData_pg_policy *Form_pg_policy; + +DECLARE_TOAST(pg_policy, 4167, 4168); + +DECLARE_UNIQUE_INDEX_PKEY(pg_policy_oid_index, 3257, PolicyOidIndexId, on pg_policy using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_policy_polrelid_polname_index, 3258, PolicyPolrelidPolnameIndexId, on pg_policy using btree(polrelid oid_ops, polname name_ops)); + +#endif /* PG_POLICY_H */ diff --git a/install/include/postgresql/server/catalog/pg_policy_d.h b/install/include/postgresql/server/catalog/pg_policy_d.h new file mode 100644 index 00000000000..1289f2e0b31 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_policy_d.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * pg_policy_d.h + * Macro definitions for pg_policy + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_POLICY_D_H +#define PG_POLICY_D_H + +#define PolicyRelationId 3256 +#define PolicyOidIndexId 3257 +#define PolicyPolrelidPolnameIndexId 3258 + +#define Anum_pg_policy_oid 1 +#define Anum_pg_policy_polname 2 +#define Anum_pg_policy_polrelid 3 +#define Anum_pg_policy_polcmd 4 +#define Anum_pg_policy_polpermissive 5 +#define Anum_pg_policy_polroles 6 +#define Anum_pg_policy_polqual 7 +#define Anum_pg_policy_polwithcheck 8 + +#define Natts_pg_policy 8 + + +#endif /* PG_POLICY_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_proc.h b/install/include/postgresql/server/catalog/pg_proc.h new file mode 100644 index 00000000000..e7abe0b497e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_proc.h @@ -0,0 +1,220 @@ +/*------------------------------------------------------------------------- + * + * pg_proc.h + * definition of the "procedure" system catalog (pg_proc) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_proc.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PROC_H +#define PG_PROC_H + +#include "catalog/genbki.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_proc_d.h" +#include "nodes/pg_list.h" + +/* ---------------- + * pg_proc definition. cpp turns this into + * typedef struct FormData_pg_proc + * ---------------- + */ +CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,ProcedureRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + Oid oid; /* oid */ + + /* procedure name */ + NameData proname; + + /* OID of namespace containing this proc */ + Oid pronamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* procedure owner */ + Oid proowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* OID of pg_language entry */ + Oid prolang BKI_DEFAULT(internal) BKI_LOOKUP(pg_language); + + /* estimated execution cost */ + float4 procost BKI_DEFAULT(1); + + /* estimated # of rows out (if proretset) */ + float4 prorows BKI_DEFAULT(0); + + /* element type of variadic array, or 0 if not variadic */ + Oid provariadic BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); + + /* planner support function for this function, or 0 if none */ + regproc prosupport BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_proc); + + /* see PROKIND_ categories below */ + char prokind BKI_DEFAULT(f); + + /* security definer */ + bool prosecdef BKI_DEFAULT(f); + + /* is it a leak-proof function? */ + bool proleakproof BKI_DEFAULT(f); + + /* strict with respect to NULLs? */ + bool proisstrict BKI_DEFAULT(t); + + /* returns a set? */ + bool proretset BKI_DEFAULT(f); + + /* see PROVOLATILE_ categories below */ + char provolatile BKI_DEFAULT(i); + + /* see PROPARALLEL_ categories below */ + char proparallel BKI_DEFAULT(s); + + /* number of arguments */ + /* Note: need not be given in pg_proc.dat; genbki.pl will compute it */ + int16 pronargs; + + /* number of arguments with defaults */ + int16 pronargdefaults BKI_DEFAULT(0); + + /* OID of result type */ + Oid prorettype BKI_LOOKUP(pg_type); + + /* + * variable-length fields start here, but we allow direct access to + * proargtypes + */ + + /* parameter types (excludes OUT params) */ + oidvector proargtypes BKI_LOOKUP(pg_type) BKI_FORCE_NOT_NULL; + +#ifdef CATALOG_VARLEN + + /* all param types (NULL if IN only) */ + Oid proallargtypes[1] BKI_DEFAULT(_null_) BKI_LOOKUP(pg_type); + + /* parameter modes (NULL if IN only) */ + char proargmodes[1] BKI_DEFAULT(_null_); + + /* parameter names (NULL if no names) */ + text proargnames[1] BKI_DEFAULT(_null_); + + /* list of expression trees for argument defaults (NULL if none) */ + pg_node_tree proargdefaults BKI_DEFAULT(_null_); + + /* types for which to apply transforms */ + Oid protrftypes[1] BKI_DEFAULT(_null_) BKI_LOOKUP(pg_type); + + /* procedure source text */ + text prosrc BKI_FORCE_NOT_NULL; + + /* secondary procedure info (can be NULL) */ + text probin BKI_DEFAULT(_null_); + + /* pre-parsed SQL function body */ + pg_node_tree prosqlbody BKI_DEFAULT(_null_); + + /* procedure-local GUC settings */ + text proconfig[1] BKI_DEFAULT(_null_); + + /* access permissions */ + aclitem proacl[1] BKI_DEFAULT(_null_); +#endif +} FormData_pg_proc; + +/* ---------------- + * Form_pg_proc corresponds to a pointer to a tuple with + * the format of pg_proc relation. + * ---------------- + */ +typedef FormData_pg_proc *Form_pg_proc; + +DECLARE_TOAST(pg_proc, 2836, 2837); + +DECLARE_UNIQUE_INDEX_PKEY(pg_proc_oid_index, 2690, ProcedureOidIndexId, on pg_proc using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_proc_proname_args_nsp_index, 2691, ProcedureNameArgsNspIndexId, on pg_proc using btree(proname name_ops, proargtypes oidvector_ops, pronamespace oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * Symbolic values for prokind column + */ +#define PROKIND_FUNCTION 'f' +#define PROKIND_AGGREGATE 'a' +#define PROKIND_WINDOW 'w' +#define PROKIND_PROCEDURE 'p' + +/* + * Symbolic values for provolatile column: these indicate whether the result + * of a function is dependent *only* on the values of its explicit arguments, + * or can change due to outside factors (such as parameter variables or + * table contents). NOTE: functions having side-effects, such as setval(), + * must be labeled volatile to ensure they will not get optimized away, + * even if the actual return value is not changeable. + */ +#define PROVOLATILE_IMMUTABLE 'i' /* never changes for given input */ +#define PROVOLATILE_STABLE 's' /* does not change within a scan */ +#define PROVOLATILE_VOLATILE 'v' /* can change even within a scan */ + +/* + * Symbolic values for proparallel column: these indicate whether a function + * can be safely be run in a parallel backend, during parallelism but + * necessarily in the leader, or only in non-parallel mode. + */ +#define PROPARALLEL_SAFE 's' /* can run in worker or leader */ +#define PROPARALLEL_RESTRICTED 'r' /* can run in parallel leader only */ +#define PROPARALLEL_UNSAFE 'u' /* banned while in parallel mode */ + +/* + * Symbolic values for proargmodes column. Note that these must agree with + * the FunctionParameterMode enum in parsenodes.h; we declare them here to + * be accessible from either header. + */ +#define PROARGMODE_IN 'i' +#define PROARGMODE_OUT 'o' +#define PROARGMODE_INOUT 'b' +#define PROARGMODE_VARIADIC 'v' +#define PROARGMODE_TABLE 't' + +#endif /* EXPOSE_TO_CLIENT_CODE */ + + +extern ObjectAddress ProcedureCreate(const char *procedureName, + Oid procNamespace, + bool replace, + bool returnsSet, + Oid returnType, + Oid proowner, + Oid languageObjectId, + Oid languageValidator, + const char *prosrc, + const char *probin, + Node *prosqlbody, + char prokind, + bool security_definer, + bool isLeakProof, + bool isStrict, + char volatility, + char parallel, + oidvector *parameterTypes, + Datum allParameterTypes, + Datum parameterModes, + Datum parameterNames, + List *parameterDefaults, + Datum trftypes, + Datum proconfig, + Oid prosupport, + float4 procost, + float4 prorows); + +extern bool function_parse_error_transpose(const char *prosrc); + +extern List *oid_array_to_list(Datum datum); + +#endif /* PG_PROC_H */ diff --git a/install/include/postgresql/server/catalog/pg_proc_d.h b/install/include/postgresql/server/catalog/pg_proc_d.h new file mode 100644 index 00000000000..d9beb520f0d --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_proc_d.h @@ -0,0 +1,101 @@ +/*------------------------------------------------------------------------- + * + * pg_proc_d.h + * Macro definitions for pg_proc + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PROC_D_H +#define PG_PROC_D_H + +#define ProcedureRelationId 1255 +#define ProcedureRelation_Rowtype_Id 81 +#define ProcedureOidIndexId 2690 +#define ProcedureNameArgsNspIndexId 2691 + +#define Anum_pg_proc_oid 1 +#define Anum_pg_proc_proname 2 +#define Anum_pg_proc_pronamespace 3 +#define Anum_pg_proc_proowner 4 +#define Anum_pg_proc_prolang 5 +#define Anum_pg_proc_procost 6 +#define Anum_pg_proc_prorows 7 +#define Anum_pg_proc_provariadic 8 +#define Anum_pg_proc_prosupport 9 +#define Anum_pg_proc_prokind 10 +#define Anum_pg_proc_prosecdef 11 +#define Anum_pg_proc_proleakproof 12 +#define Anum_pg_proc_proisstrict 13 +#define Anum_pg_proc_proretset 14 +#define Anum_pg_proc_provolatile 15 +#define Anum_pg_proc_proparallel 16 +#define Anum_pg_proc_pronargs 17 +#define Anum_pg_proc_pronargdefaults 18 +#define Anum_pg_proc_prorettype 19 +#define Anum_pg_proc_proargtypes 20 +#define Anum_pg_proc_proallargtypes 21 +#define Anum_pg_proc_proargmodes 22 +#define Anum_pg_proc_proargnames 23 +#define Anum_pg_proc_proargdefaults 24 +#define Anum_pg_proc_protrftypes 25 +#define Anum_pg_proc_prosrc 26 +#define Anum_pg_proc_probin 27 +#define Anum_pg_proc_prosqlbody 28 +#define Anum_pg_proc_proconfig 29 +#define Anum_pg_proc_proacl 30 + +#define Natts_pg_proc 30 + + +/* + * Symbolic values for prokind column + */ +#define PROKIND_FUNCTION 'f' +#define PROKIND_AGGREGATE 'a' +#define PROKIND_WINDOW 'w' +#define PROKIND_PROCEDURE 'p' + +/* + * Symbolic values for provolatile column: these indicate whether the result + * of a function is dependent *only* on the values of its explicit arguments, + * or can change due to outside factors (such as parameter variables or + * table contents). NOTE: functions having side-effects, such as setval(), + * must be labeled volatile to ensure they will not get optimized away, + * even if the actual return value is not changeable. + */ +#define PROVOLATILE_IMMUTABLE 'i' /* never changes for given input */ +#define PROVOLATILE_STABLE 's' /* does not change within a scan */ +#define PROVOLATILE_VOLATILE 'v' /* can change even within a scan */ + +/* + * Symbolic values for proparallel column: these indicate whether a function + * can be safely be run in a parallel backend, during parallelism but + * necessarily in the leader, or only in non-parallel mode. + */ +#define PROPARALLEL_SAFE 's' /* can run in worker or leader */ +#define PROPARALLEL_RESTRICTED 'r' /* can run in parallel leader only */ +#define PROPARALLEL_UNSAFE 'u' /* banned while in parallel mode */ + +/* + * Symbolic values for proargmodes column. Note that these must agree with + * the FunctionParameterMode enum in parsenodes.h; we declare them here to + * be accessible from either header. + */ +#define PROARGMODE_IN 'i' +#define PROARGMODE_OUT 'o' +#define PROARGMODE_INOUT 'b' +#define PROARGMODE_VARIADIC 'v' +#define PROARGMODE_TABLE 't' + + +#endif /* PG_PROC_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_publication.h b/install/include/postgresql/server/catalog/pg_publication.h new file mode 100644 index 00000000000..6ecaa2a01e7 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_publication.h @@ -0,0 +1,158 @@ +/*------------------------------------------------------------------------- + * + * pg_publication.h + * definition of the "publication" system catalog (pg_publication) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_publication.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PUBLICATION_H +#define PG_PUBLICATION_H + +#include "catalog/genbki.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_publication_d.h" + +/* ---------------- + * pg_publication definition. cpp turns this into + * typedef struct FormData_pg_publication + * ---------------- + */ +CATALOG(pg_publication,6104,PublicationRelationId) +{ + Oid oid; /* oid */ + + NameData pubname; /* name of the publication */ + + Oid pubowner BKI_LOOKUP(pg_authid); /* publication owner */ + + /* + * indicates that this is special publication which should encompass all + * tables in the database (except for the unlogged and temp ones) + */ + bool puballtables; + + /* true if inserts are published */ + bool pubinsert; + + /* true if updates are published */ + bool pubupdate; + + /* true if deletes are published */ + bool pubdelete; + + /* true if truncates are published */ + bool pubtruncate; + + /* true if partition changes are published using root schema */ + bool pubviaroot; +} FormData_pg_publication; + +/* ---------------- + * Form_pg_publication corresponds to a pointer to a tuple with + * the format of pg_publication relation. + * ---------------- + */ +typedef FormData_pg_publication *Form_pg_publication; + +DECLARE_UNIQUE_INDEX_PKEY(pg_publication_oid_index, 6110, PublicationObjectIndexId, on pg_publication using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_publication_pubname_index, 6111, PublicationNameIndexId, on pg_publication using btree(pubname name_ops)); + +typedef struct PublicationActions +{ + bool pubinsert; + bool pubupdate; + bool pubdelete; + bool pubtruncate; +} PublicationActions; + +typedef struct PublicationDesc +{ + PublicationActions pubactions; + + /* + * true if the columns referenced in row filters which are used for UPDATE + * or DELETE are part of the replica identity or the publication actions + * do not include UPDATE or DELETE. + */ + bool rf_valid_for_update; + bool rf_valid_for_delete; + + /* + * true if the columns are part of the replica identity or the publication + * actions do not include UPDATE or DELETE. + */ + bool cols_valid_for_update; + bool cols_valid_for_delete; +} PublicationDesc; + +typedef struct Publication +{ + Oid oid; + char *name; + bool alltables; + bool pubviaroot; + PublicationActions pubactions; +} Publication; + +typedef struct PublicationRelInfo +{ + Relation relation; + Node *whereClause; + List *columns; +} PublicationRelInfo; + +extern Publication *GetPublication(Oid pubid); +extern Publication *GetPublicationByName(const char *pubname, bool missing_ok); +extern List *GetRelationPublications(Oid relid); + +/*--------- + * Expected values for pub_partopt parameter of GetRelationPublications(), + * which allows callers to specify which partitions of partitioned tables + * mentioned in the publication they expect to see. + * + * ROOT: only the table explicitly mentioned in the publication + * LEAF: only leaf partitions in given tree + * ALL: all partitions in given tree + */ +typedef enum PublicationPartOpt +{ + PUBLICATION_PART_ROOT, + PUBLICATION_PART_LEAF, + PUBLICATION_PART_ALL, +} PublicationPartOpt; + +extern List *GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt); +extern List *GetAllTablesPublications(void); +extern List *GetAllTablesPublicationRelations(bool pubviaroot); +extern List *GetPublicationSchemas(Oid pubid); +extern List *GetSchemaPublications(Oid schemaid); +extern List *GetSchemaPublicationRelations(Oid schemaid, + PublicationPartOpt pub_partopt); +extern List *GetAllSchemaPublicationRelations(Oid pubid, + PublicationPartOpt pub_partopt); +extern List *GetPubPartitionOptionRelations(List *result, + PublicationPartOpt pub_partopt, + Oid relid); +extern Oid GetTopMostAncestorInPublication(Oid puboid, List *ancestors, + int *ancestor_level); + +extern bool is_publishable_relation(Relation rel); +extern bool is_schema_publication(Oid pubid); +extern ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *pri, + bool if_not_exists); +extern ObjectAddress publication_add_schema(Oid pubid, Oid schemaid, + bool if_not_exists); + +extern Bitmapset *pub_collist_to_bitmapset(Bitmapset *columns, Datum pubcols, + MemoryContext mcxt); + +#endif /* PG_PUBLICATION_H */ diff --git a/install/include/postgresql/server/catalog/pg_publication_d.h b/install/include/postgresql/server/catalog/pg_publication_d.h new file mode 100644 index 00000000000..be01c625b5a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_publication_d.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * pg_publication_d.h + * Macro definitions for pg_publication + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PUBLICATION_D_H +#define PG_PUBLICATION_D_H + +#define PublicationRelationId 6104 +#define PublicationObjectIndexId 6110 +#define PublicationNameIndexId 6111 + +#define Anum_pg_publication_oid 1 +#define Anum_pg_publication_pubname 2 +#define Anum_pg_publication_pubowner 3 +#define Anum_pg_publication_puballtables 4 +#define Anum_pg_publication_pubinsert 5 +#define Anum_pg_publication_pubupdate 6 +#define Anum_pg_publication_pubdelete 7 +#define Anum_pg_publication_pubtruncate 8 +#define Anum_pg_publication_pubviaroot 9 + +#define Natts_pg_publication 9 + + +#endif /* PG_PUBLICATION_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_publication_namespace.h b/install/include/postgresql/server/catalog/pg_publication_namespace.h new file mode 100644 index 00000000000..f1abcb9f169 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_publication_namespace.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * pg_publication_namespace.h + * definition of the system catalog for mappings between schemas and + * publications (pg_publication_namespace) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_publication_namespace.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PUBLICATION_NAMESPACE_H +#define PG_PUBLICATION_NAMESPACE_H + +#include "catalog/genbki.h" +#include "catalog/pg_publication_namespace_d.h" + + +/* ---------------- + * pg_publication_namespace definition. cpp turns this into + * typedef struct FormData_pg_publication_namespace + * ---------------- + */ +CATALOG(pg_publication_namespace,6237,PublicationNamespaceRelationId) +{ + Oid oid; /* oid */ + Oid pnpubid BKI_LOOKUP(pg_publication); /* Oid of the publication */ + Oid pnnspid BKI_LOOKUP(pg_namespace); /* Oid of the schema */ +} FormData_pg_publication_namespace; + +/* ---------------- + * Form_pg_publication_namespace corresponds to a pointer to a tuple with + * the format of pg_publication_namespace relation. + * ---------------- + */ +typedef FormData_pg_publication_namespace *Form_pg_publication_namespace; + +DECLARE_UNIQUE_INDEX_PKEY(pg_publication_namespace_oid_index, 6238, PublicationNamespaceObjectIndexId, on pg_publication_namespace using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_publication_namespace_pnnspid_pnpubid_index, 6239, PublicationNamespacePnnspidPnpubidIndexId, on pg_publication_namespace using btree(pnnspid oid_ops, pnpubid oid_ops)); + +#endif /* PG_PUBLICATION_NAMESPACE_H */ diff --git a/install/include/postgresql/server/catalog/pg_publication_namespace_d.h b/install/include/postgresql/server/catalog/pg_publication_namespace_d.h new file mode 100644 index 00000000000..00f2a2e451c --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_publication_namespace_d.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * pg_publication_namespace_d.h + * Macro definitions for pg_publication_namespace + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PUBLICATION_NAMESPACE_D_H +#define PG_PUBLICATION_NAMESPACE_D_H + +#define PublicationNamespaceRelationId 6237 +#define PublicationNamespaceObjectIndexId 6238 +#define PublicationNamespacePnnspidPnpubidIndexId 6239 + +#define Anum_pg_publication_namespace_oid 1 +#define Anum_pg_publication_namespace_pnpubid 2 +#define Anum_pg_publication_namespace_pnnspid 3 + +#define Natts_pg_publication_namespace 3 + + +#endif /* PG_PUBLICATION_NAMESPACE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_publication_rel.h b/install/include/postgresql/server/catalog/pg_publication_rel.h new file mode 100644 index 00000000000..613e9747c2a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_publication_rel.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * pg_publication_rel.h + * definition of the system catalog for mappings between relations and + * publications (pg_publication_rel) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_publication_rel.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PUBLICATION_REL_H +#define PG_PUBLICATION_REL_H + +#include "catalog/genbki.h" +#include "catalog/pg_publication_rel_d.h" + +/* ---------------- + * pg_publication_rel definition. cpp turns this into + * typedef struct FormData_pg_publication_rel + * ---------------- + */ +CATALOG(pg_publication_rel,6106,PublicationRelRelationId) +{ + Oid oid; /* oid */ + Oid prpubid BKI_LOOKUP(pg_publication); /* Oid of the publication */ + Oid prrelid BKI_LOOKUP(pg_class); /* Oid of the relation */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + pg_node_tree prqual; /* qualifications */ + int2vector prattrs; /* columns to replicate */ +#endif +} FormData_pg_publication_rel; + +/* ---------------- + * Form_pg_publication_rel corresponds to a pointer to a tuple with + * the format of pg_publication_rel relation. + * ---------------- + */ +typedef FormData_pg_publication_rel *Form_pg_publication_rel; + +DECLARE_TOAST(pg_publication_rel, 6228, 6229); + +DECLARE_UNIQUE_INDEX_PKEY(pg_publication_rel_oid_index, 6112, PublicationRelObjectIndexId, on pg_publication_rel using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_publication_rel_prrelid_prpubid_index, 6113, PublicationRelPrrelidPrpubidIndexId, on pg_publication_rel using btree(prrelid oid_ops, prpubid oid_ops)); +DECLARE_INDEX(pg_publication_rel_prpubid_index, 6116, PublicationRelPrpubidIndexId, on pg_publication_rel using btree(prpubid oid_ops)); + +#endif /* PG_PUBLICATION_REL_H */ diff --git a/install/include/postgresql/server/catalog/pg_publication_rel_d.h b/install/include/postgresql/server/catalog/pg_publication_rel_d.h new file mode 100644 index 00000000000..a90eef70336 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_publication_rel_d.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * pg_publication_rel_d.h + * Macro definitions for pg_publication_rel + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PUBLICATION_REL_D_H +#define PG_PUBLICATION_REL_D_H + +#define PublicationRelRelationId 6106 +#define PublicationRelObjectIndexId 6112 +#define PublicationRelPrrelidPrpubidIndexId 6113 +#define PublicationRelPrpubidIndexId 6116 + +#define Anum_pg_publication_rel_oid 1 +#define Anum_pg_publication_rel_prpubid 2 +#define Anum_pg_publication_rel_prrelid 3 +#define Anum_pg_publication_rel_prqual 4 +#define Anum_pg_publication_rel_prattrs 5 + +#define Natts_pg_publication_rel 5 + + +#endif /* PG_PUBLICATION_REL_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_range.h b/install/include/postgresql/server/catalog/pg_range.h new file mode 100644 index 00000000000..d03ef18851f --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_range.h @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------- + * + * pg_range.h + * definition of the "range type" system catalog (pg_range) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_range.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_RANGE_H +#define PG_RANGE_H + +#include "catalog/genbki.h" +#include "catalog/pg_range_d.h" + +/* ---------------- + * pg_range definition. cpp turns this into + * typedef struct FormData_pg_range + * ---------------- + */ +CATALOG(pg_range,3541,RangeRelationId) +{ + /* OID of owning range type */ + Oid rngtypid BKI_LOOKUP(pg_type); + + /* OID of range's element type (subtype) */ + Oid rngsubtype BKI_LOOKUP(pg_type); + + /* OID of the range's multirange type */ + Oid rngmultitypid BKI_LOOKUP(pg_type); + + /* collation for this range type, or 0 */ + Oid rngcollation BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_collation); + + /* subtype's btree opclass */ + Oid rngsubopc BKI_LOOKUP(pg_opclass); + + /* canonicalize range, or 0 */ + regproc rngcanonical BKI_LOOKUP_OPT(pg_proc); + + /* subtype difference as a float8, or 0 */ + regproc rngsubdiff BKI_LOOKUP_OPT(pg_proc); +} FormData_pg_range; + +/* ---------------- + * Form_pg_range corresponds to a pointer to a tuple with + * the format of pg_range relation. + * ---------------- + */ +typedef FormData_pg_range *Form_pg_range; + +DECLARE_UNIQUE_INDEX_PKEY(pg_range_rngtypid_index, 3542, RangeTypidIndexId, on pg_range using btree(rngtypid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_range_rngmultitypid_index, 2228, RangeMultirangeTypidIndexId, on pg_range using btree(rngmultitypid oid_ops)); + +/* + * prototypes for functions in pg_range.c + */ + +extern void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, + Oid rangeSubOpclass, RegProcedure rangeCanonical, + RegProcedure rangeSubDiff, Oid multirangeTypeOid); +extern void RangeDelete(Oid rangeTypeOid); + +#endif /* PG_RANGE_H */ diff --git a/install/include/postgresql/server/catalog/pg_range_d.h b/install/include/postgresql/server/catalog/pg_range_d.h new file mode 100644 index 00000000000..d2c7a06e0aa --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_range_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_range_d.h + * Macro definitions for pg_range + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_RANGE_D_H +#define PG_RANGE_D_H + +#define RangeRelationId 3541 +#define RangeTypidIndexId 3542 +#define RangeMultirangeTypidIndexId 2228 + +#define Anum_pg_range_rngtypid 1 +#define Anum_pg_range_rngsubtype 2 +#define Anum_pg_range_rngmultitypid 3 +#define Anum_pg_range_rngcollation 4 +#define Anum_pg_range_rngsubopc 5 +#define Anum_pg_range_rngcanonical 6 +#define Anum_pg_range_rngsubdiff 7 + +#define Natts_pg_range 7 + + +#endif /* PG_RANGE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_replication_origin.h b/install/include/postgresql/server/catalog/pg_replication_origin.h new file mode 100644 index 00000000000..fa54f120e6c --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_replication_origin.h @@ -0,0 +1,62 @@ +/*------------------------------------------------------------------------- + * + * pg_replication_origin.h + * definition of the "replication origin" system catalog + * (pg_replication_origin) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_replication_origin.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_REPLICATION_ORIGIN_H +#define PG_REPLICATION_ORIGIN_H + +#include "access/xlogdefs.h" +#include "catalog/genbki.h" +#include "catalog/pg_replication_origin_d.h" + +/* ---------------- + * pg_replication_origin. cpp turns this into + * typedef struct FormData_pg_replication_origin + * ---------------- + */ +CATALOG(pg_replication_origin,6000,ReplicationOriginRelationId) BKI_SHARED_RELATION +{ + /* + * Locally known id that get included into WAL. + * + * This should never leave the system. + * + * Needs to fit into an uint16, so we don't waste too much space in WAL + * records. For this reason we don't use a normal Oid column here, since + * we need to handle allocation of new values manually. + */ + Oid roident; + + /* + * Variable-length fields start here, but we allow direct access to + * roname. + */ + + /* external, free-format, name */ + text roname BKI_FORCE_NOT_NULL; + +#ifdef CATALOG_VARLEN /* further variable-length fields */ +#endif +} FormData_pg_replication_origin; + +typedef FormData_pg_replication_origin *Form_pg_replication_origin; + +DECLARE_TOAST_WITH_MACRO(pg_replication_origin, 4181, 4182, PgReplicationOriginToastTable, PgReplicationOriginToastIndex); + +DECLARE_UNIQUE_INDEX_PKEY(pg_replication_origin_roiident_index, 6001, ReplicationOriginIdentIndex, on pg_replication_origin using btree(roident oid_ops)); +DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, ReplicationOriginNameIndex, on pg_replication_origin using btree(roname text_ops)); + +#endif /* PG_REPLICATION_ORIGIN_H */ diff --git a/install/include/postgresql/server/catalog/pg_replication_origin_d.h b/install/include/postgresql/server/catalog/pg_replication_origin_d.h new file mode 100644 index 00000000000..55308ada5a2 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_replication_origin_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_replication_origin_d.h + * Macro definitions for pg_replication_origin + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_REPLICATION_ORIGIN_D_H +#define PG_REPLICATION_ORIGIN_D_H + +#define ReplicationOriginRelationId 6000 +#define PgReplicationOriginToastTable 4181 +#define PgReplicationOriginToastIndex 4182 +#define ReplicationOriginIdentIndex 6001 +#define ReplicationOriginNameIndex 6002 + +#define Anum_pg_replication_origin_roident 1 +#define Anum_pg_replication_origin_roname 2 + +#define Natts_pg_replication_origin 2 + + +#endif /* PG_REPLICATION_ORIGIN_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_rewrite.h b/install/include/postgresql/server/catalog/pg_rewrite.h new file mode 100644 index 00000000000..21f24e6d7e8 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_rewrite.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * pg_rewrite.h + * definition of the "rewrite rule" system catalog (pg_rewrite) + * + * As of Postgres 7.3, the primary key for this table is + * --- ie, rule names are only unique among the rules of a given table. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_rewrite.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_REWRITE_H +#define PG_REWRITE_H + +#include "catalog/genbki.h" +#include "catalog/pg_rewrite_d.h" + +/* ---------------- + * pg_rewrite definition. cpp turns this into + * typedef struct FormData_pg_rewrite + * ---------------- + */ +CATALOG(pg_rewrite,2618,RewriteRelationId) +{ + Oid oid; /* oid */ + NameData rulename; + Oid ev_class BKI_LOOKUP(pg_class); + char ev_type; + char ev_enabled; + bool is_instead; + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + pg_node_tree ev_qual BKI_FORCE_NOT_NULL; + pg_node_tree ev_action BKI_FORCE_NOT_NULL; +#endif +} FormData_pg_rewrite; + +/* ---------------- + * Form_pg_rewrite corresponds to a pointer to a tuple with + * the format of pg_rewrite relation. + * ---------------- + */ +typedef FormData_pg_rewrite *Form_pg_rewrite; + +DECLARE_TOAST(pg_rewrite, 2838, 2839); + +DECLARE_UNIQUE_INDEX_PKEY(pg_rewrite_oid_index, 2692, RewriteOidIndexId, on pg_rewrite using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index, 2693, RewriteRelRulenameIndexId, on pg_rewrite using btree(ev_class oid_ops, rulename name_ops)); + +#endif /* PG_REWRITE_H */ diff --git a/install/include/postgresql/server/catalog/pg_rewrite_d.h b/install/include/postgresql/server/catalog/pg_rewrite_d.h new file mode 100644 index 00000000000..2b9e10160bf --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_rewrite_d.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * pg_rewrite_d.h + * Macro definitions for pg_rewrite + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_REWRITE_D_H +#define PG_REWRITE_D_H + +#define RewriteRelationId 2618 +#define RewriteOidIndexId 2692 +#define RewriteRelRulenameIndexId 2693 + +#define Anum_pg_rewrite_oid 1 +#define Anum_pg_rewrite_rulename 2 +#define Anum_pg_rewrite_ev_class 3 +#define Anum_pg_rewrite_ev_type 4 +#define Anum_pg_rewrite_ev_enabled 5 +#define Anum_pg_rewrite_is_instead 6 +#define Anum_pg_rewrite_ev_qual 7 +#define Anum_pg_rewrite_ev_action 8 + +#define Natts_pg_rewrite 8 + + +#endif /* PG_REWRITE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_seclabel.h b/install/include/postgresql/server/catalog/pg_seclabel.h new file mode 100644 index 00000000000..74299cf85d1 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_seclabel.h @@ -0,0 +1,45 @@ +/* ------------------------------------------------------------------------- + * + * pg_seclabel.h + * definition of the "security label" system catalog (pg_seclabel) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_seclabel.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + * ------------------------------------------------------------------------- + */ +#ifndef PG_SECLABEL_H +#define PG_SECLABEL_H + +#include "catalog/genbki.h" +#include "catalog/pg_seclabel_d.h" + +/* ---------------- + * pg_seclabel definition. cpp turns this into + * typedef struct FormData_pg_seclabel + * ---------------- + */ +CATALOG(pg_seclabel,3596,SecLabelRelationId) +{ + Oid objoid; /* OID of the object itself */ + Oid classoid BKI_LOOKUP(pg_class); /* OID of table containing the + * object */ + int32 objsubid; /* column number, or 0 if not used */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text provider BKI_FORCE_NOT_NULL; /* name of label provider */ + text label BKI_FORCE_NOT_NULL; /* security label of the object */ +#endif +} FormData_pg_seclabel; + +DECLARE_TOAST(pg_seclabel, 3598, 3599); + +DECLARE_UNIQUE_INDEX_PKEY(pg_seclabel_object_index, 3597, SecLabelObjectIndexId, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_ops)); + +#endif /* PG_SECLABEL_H */ diff --git a/install/include/postgresql/server/catalog/pg_seclabel_d.h b/install/include/postgresql/server/catalog/pg_seclabel_d.h new file mode 100644 index 00000000000..0b6848a9907 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_seclabel_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_seclabel_d.h + * Macro definitions for pg_seclabel + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SECLABEL_D_H +#define PG_SECLABEL_D_H + +#define SecLabelRelationId 3596 +#define SecLabelObjectIndexId 3597 + +#define Anum_pg_seclabel_objoid 1 +#define Anum_pg_seclabel_classoid 2 +#define Anum_pg_seclabel_objsubid 3 +#define Anum_pg_seclabel_provider 4 +#define Anum_pg_seclabel_label 5 + +#define Natts_pg_seclabel 5 + + +#endif /* PG_SECLABEL_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_sequence.h b/install/include/postgresql/server/catalog/pg_sequence.h new file mode 100644 index 00000000000..d528c9122fa --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_sequence.h @@ -0,0 +1,44 @@ +/* ------------------------------------------------------------------------- + * + * pg_sequence.h + * definition of the "sequence" system catalog (pg_sequence) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_sequence.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + * ------------------------------------------------------------------------- + */ +#ifndef PG_SEQUENCE_H +#define PG_SEQUENCE_H + +#include "catalog/genbki.h" +#include "catalog/pg_sequence_d.h" + +CATALOG(pg_sequence,2224,SequenceRelationId) +{ + Oid seqrelid BKI_LOOKUP(pg_class); + Oid seqtypid BKI_LOOKUP(pg_type); + int64 seqstart; + int64 seqincrement; + int64 seqmax; + int64 seqmin; + int64 seqcache; + bool seqcycle; +} FormData_pg_sequence; + +/* ---------------- + * Form_pg_sequence corresponds to a pointer to a tuple with + * the format of pg_sequence relation. + * ---------------- + */ +typedef FormData_pg_sequence *Form_pg_sequence; + +DECLARE_UNIQUE_INDEX_PKEY(pg_sequence_seqrelid_index, 5002, SequenceRelidIndexId, on pg_sequence using btree(seqrelid oid_ops)); + +#endif /* PG_SEQUENCE_H */ diff --git a/install/include/postgresql/server/catalog/pg_sequence_d.h b/install/include/postgresql/server/catalog/pg_sequence_d.h new file mode 100644 index 00000000000..91df4e13e2a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_sequence_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_sequence_d.h + * Macro definitions for pg_sequence + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SEQUENCE_D_H +#define PG_SEQUENCE_D_H + +#define SequenceRelationId 2224 +#define SequenceRelidIndexId 5002 + +#define Anum_pg_sequence_seqrelid 1 +#define Anum_pg_sequence_seqtypid 2 +#define Anum_pg_sequence_seqstart 3 +#define Anum_pg_sequence_seqincrement 4 +#define Anum_pg_sequence_seqmax 5 +#define Anum_pg_sequence_seqmin 6 +#define Anum_pg_sequence_seqcache 7 +#define Anum_pg_sequence_seqcycle 8 + +#define Natts_pg_sequence 8 + + +#endif /* PG_SEQUENCE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_shdepend.h b/install/include/postgresql/server/catalog/pg_shdepend.h new file mode 100644 index 00000000000..35ba911a22a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_shdepend.h @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------- + * + * pg_shdepend.h + * definition of the "shared dependency" system catalog (pg_shdepend) + * + * pg_shdepend has no preloaded contents, so there is no pg_shdepend.dat + * file; dependencies for system-defined objects are loaded into it + * on-the-fly during initdb. Most built-in objects are pinned anyway, + * and hence need no explicit entries in pg_shdepend. + * + * NOTE: we do not represent all possible dependency pairs in pg_shdepend; + * for example, there's not much value in creating an explicit dependency + * from a relation to its database. Currently, only dependencies on roles + * are explicitly stored in pg_shdepend. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_shdepend.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHDEPEND_H +#define PG_SHDEPEND_H + +#include "catalog/genbki.h" +#include "catalog/pg_shdepend_d.h" + +/* ---------------- + * pg_shdepend definition. cpp turns this into + * typedef struct FormData_pg_shdepend + * ---------------- + */ +CATALOG(pg_shdepend,1214,SharedDependRelationId) BKI_SHARED_RELATION +{ + /* + * Identification of the dependent (referencing) object. + * + * Note that dbid can be zero to denote a shared object. + */ + Oid dbid BKI_LOOKUP_OPT(pg_database); /* OID of database + * containing object */ + Oid classid BKI_LOOKUP(pg_class); /* OID of table containing + * object */ + Oid objid; /* OID of object itself */ + int32 objsubid; /* column number, or 0 if not used */ + + /* + * Identification of the independent (referenced) object. This is always + * a shared object, so we need no database ID field. We don't bother with + * a sub-object ID either. + */ + Oid refclassid BKI_LOOKUP(pg_class); /* OID of table containing + * object */ + Oid refobjid; /* OID of object itself */ + + /* + * Precise semantics of the relationship are specified by the deptype + * field. See SharedDependencyType in catalog/dependency.h. + */ + char deptype; /* see codes in dependency.h */ +} FormData_pg_shdepend; + +/* ---------------- + * Form_pg_shdepend corresponds to a pointer to a row with + * the format of pg_shdepend relation. + * ---------------- + */ +typedef FormData_pg_shdepend *Form_pg_shdepend; + +DECLARE_INDEX(pg_shdepend_depender_index, 1232, SharedDependDependerIndexId, on pg_shdepend using btree(dbid oid_ops, classid oid_ops, objid oid_ops, objsubid int4_ops)); +DECLARE_INDEX(pg_shdepend_reference_index, 1233, SharedDependReferenceIndexId, on pg_shdepend using btree(refclassid oid_ops, refobjid oid_ops)); + +#endif /* PG_SHDEPEND_H */ diff --git a/install/include/postgresql/server/catalog/pg_shdepend_d.h b/install/include/postgresql/server/catalog/pg_shdepend_d.h new file mode 100644 index 00000000000..f4239edb65a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_shdepend_d.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pg_shdepend_d.h + * Macro definitions for pg_shdepend + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHDEPEND_D_H +#define PG_SHDEPEND_D_H + +#define SharedDependRelationId 1214 +#define SharedDependDependerIndexId 1232 +#define SharedDependReferenceIndexId 1233 + +#define Anum_pg_shdepend_dbid 1 +#define Anum_pg_shdepend_classid 2 +#define Anum_pg_shdepend_objid 3 +#define Anum_pg_shdepend_objsubid 4 +#define Anum_pg_shdepend_refclassid 5 +#define Anum_pg_shdepend_refobjid 6 +#define Anum_pg_shdepend_deptype 7 + +#define Natts_pg_shdepend 7 + + +#endif /* PG_SHDEPEND_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_shdescription.h b/install/include/postgresql/server/catalog/pg_shdescription.h new file mode 100644 index 00000000000..7b66c122244 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_shdescription.h @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------- + * + * pg_shdescription.h + * definition of the "shared description" system catalog + * (pg_shdescription) + * + * Because the contents of this table are taken from the *.dat files + * of other catalogs, there is no pg_shdescription.dat file. The initial + * contents are assembled by genbki.pl and loaded during initdb. + * + * NOTE: an object is identified by the OID of the row that primarily + * defines the object, plus the OID of the table that that row appears in. + * For example, a database is identified by the OID of its pg_database row + * plus the pg_class OID of table pg_database. This allows unique + * identification of objects without assuming that OIDs are unique + * across tables. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_shdescription.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHDESCRIPTION_H +#define PG_SHDESCRIPTION_H + +#include "catalog/genbki.h" +#include "catalog/pg_shdescription_d.h" + +/* ---------------- + * pg_shdescription definition. cpp turns this into + * typedef struct FormData_pg_shdescription + * ---------------- + */ +CATALOG(pg_shdescription,2396,SharedDescriptionRelationId) BKI_SHARED_RELATION +{ + Oid objoid; /* OID of object itself */ + Oid classoid; /* OID of table containing object */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text description BKI_FORCE_NOT_NULL; /* description of object */ +#endif +} FormData_pg_shdescription; + +/* ---------------- + * Form_pg_shdescription corresponds to a pointer to a tuple with + * the format of pg_shdescription relation. + * ---------------- + */ +typedef FormData_pg_shdescription * Form_pg_shdescription; + +DECLARE_TOAST_WITH_MACRO(pg_shdescription, 2846, 2847, PgShdescriptionToastTable, PgShdescriptionToastIndex); + +DECLARE_UNIQUE_INDEX_PKEY(pg_shdescription_o_c_index, 2397, SharedDescriptionObjIndexId, on pg_shdescription using btree(objoid oid_ops, classoid oid_ops)); + +/* We do not use BKI_LOOKUP here because it causes problems for genbki.pl */ +DECLARE_FOREIGN_KEY((classoid), pg_class, (oid)); + +#endif /* PG_SHDESCRIPTION_H */ diff --git a/install/include/postgresql/server/catalog/pg_shdescription_d.h b/install/include/postgresql/server/catalog/pg_shdescription_d.h new file mode 100644 index 00000000000..cc734aa736a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_shdescription_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_shdescription_d.h + * Macro definitions for pg_shdescription + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHDESCRIPTION_D_H +#define PG_SHDESCRIPTION_D_H + +#define SharedDescriptionRelationId 2396 +#define PgShdescriptionToastTable 2846 +#define PgShdescriptionToastIndex 2847 +#define SharedDescriptionObjIndexId 2397 + +#define Anum_pg_shdescription_objoid 1 +#define Anum_pg_shdescription_classoid 2 +#define Anum_pg_shdescription_description 3 + +#define Natts_pg_shdescription 3 + + +#endif /* PG_SHDESCRIPTION_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_shseclabel.h b/install/include/postgresql/server/catalog/pg_shseclabel.h new file mode 100644 index 00000000000..32b03de952e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_shseclabel.h @@ -0,0 +1,46 @@ +/* ------------------------------------------------------------------------- + * + * pg_shseclabel.h + * definition of the "shared security label" system catalog (pg_shseclabel) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_shseclabel.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + * ------------------------------------------------------------------------- + */ +#ifndef PG_SHSECLABEL_H +#define PG_SHSECLABEL_H + +#include "catalog/genbki.h" +#include "catalog/pg_shseclabel_d.h" + +/* ---------------- + * pg_shseclabel definition. cpp turns this into + * typedef struct FormData_pg_shseclabel + * ---------------- + */ +CATALOG(pg_shseclabel,3592,SharedSecLabelRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(4066,SharedSecLabelRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + Oid objoid; /* OID of the shared object itself */ + Oid classoid BKI_LOOKUP(pg_class); /* OID of table containing the + * shared object */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text provider BKI_FORCE_NOT_NULL; /* name of label provider */ + text label BKI_FORCE_NOT_NULL; /* security label of the object */ +#endif +} FormData_pg_shseclabel; + +typedef FormData_pg_shseclabel * Form_pg_shseclabel; + +DECLARE_TOAST_WITH_MACRO(pg_shseclabel, 4060, 4061, PgShseclabelToastTable, PgShseclabelToastIndex); + +DECLARE_UNIQUE_INDEX_PKEY(pg_shseclabel_object_index, 3593, SharedSecLabelObjectIndexId, on pg_shseclabel using btree(objoid oid_ops, classoid oid_ops, provider text_ops)); + +#endif /* PG_SHSECLABEL_H */ diff --git a/install/include/postgresql/server/catalog/pg_shseclabel_d.h b/install/include/postgresql/server/catalog/pg_shseclabel_d.h new file mode 100644 index 00000000000..2886846c63e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_shseclabel_d.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * pg_shseclabel_d.h + * Macro definitions for pg_shseclabel + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHSECLABEL_D_H +#define PG_SHSECLABEL_D_H + +#define SharedSecLabelRelationId 3592 +#define SharedSecLabelRelation_Rowtype_Id 4066 +#define PgShseclabelToastTable 4060 +#define PgShseclabelToastIndex 4061 +#define SharedSecLabelObjectIndexId 3593 + +#define Anum_pg_shseclabel_objoid 1 +#define Anum_pg_shseclabel_classoid 2 +#define Anum_pg_shseclabel_provider 3 +#define Anum_pg_shseclabel_label 4 + +#define Natts_pg_shseclabel 4 + + +#endif /* PG_SHSECLABEL_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_statistic.h b/install/include/postgresql/server/catalog/pg_statistic.h new file mode 100644 index 00000000000..8770c5b4c60 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_statistic.h @@ -0,0 +1,282 @@ +/*------------------------------------------------------------------------- + * + * pg_statistic.h + * definition of the "statistics" system catalog (pg_statistic) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_statistic.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_STATISTIC_H +#define PG_STATISTIC_H + +#include "catalog/genbki.h" +#include "catalog/pg_statistic_d.h" + +/* ---------------- + * pg_statistic definition. cpp turns this into + * typedef struct FormData_pg_statistic + * ---------------- + */ +CATALOG(pg_statistic,2619,StatisticRelationId) +{ + /* These fields form the unique key for the entry: */ + Oid starelid BKI_LOOKUP(pg_class); /* relation containing + * attribute */ + int16 staattnum; /* attribute (column) stats are for */ + bool stainherit; /* true if inheritance children are included */ + + /* the fraction of the column's entries that are NULL: */ + float4 stanullfrac; + + /* + * stawidth is the average width in bytes of non-null entries. For + * fixed-width datatypes this is of course the same as the typlen, but for + * var-width types it is more useful. Note that this is the average width + * of the data as actually stored, post-TOASTing (eg, for a + * moved-out-of-line value, only the size of the pointer object is + * counted). This is the appropriate definition for the primary use of + * the statistic, which is to estimate sizes of in-memory hash tables of + * tuples. + */ + int32 stawidth; + + /* ---------------- + * stadistinct indicates the (approximate) number of distinct non-null + * data values in the column. The interpretation is: + * 0 unknown or not computed + * > 0 actual number of distinct values + * < 0 negative of multiplier for number of rows + * The special negative case allows us to cope with columns that are + * unique (stadistinct = -1) or nearly so (for example, a column in which + * non-null values appear about twice on the average could be represented + * by stadistinct = -0.5 if there are no nulls, or -0.4 if 20% of the + * column is nulls). Because the number-of-rows statistic in pg_class may + * be updated more frequently than pg_statistic is, it's important to be + * able to describe such situations as a multiple of the number of rows, + * rather than a fixed number of distinct values. But in other cases a + * fixed number is correct (eg, a boolean column). + * ---------------- + */ + float4 stadistinct; + + /* ---------------- + * To allow keeping statistics on different kinds of datatypes, + * we do not hard-wire any particular meaning for the remaining + * statistical fields. Instead, we provide several "slots" in which + * statistical data can be placed. Each slot includes: + * kind integer code identifying kind of data (see below) + * op OID of associated operator, if needed + * coll OID of relevant collation, or 0 if none + * numbers float4 array (for statistical values) + * values anyarray (for representations of data values) + * The ID, operator, and collation fields are never NULL; they are zeroes + * in an unused slot. The numbers and values fields are NULL in an + * unused slot, and might also be NULL in a used slot if the slot kind + * has no need for one or the other. + * ---------------- + */ + + int16 stakind1; + int16 stakind2; + int16 stakind3; + int16 stakind4; + int16 stakind5; + + Oid staop1 BKI_LOOKUP_OPT(pg_operator); + Oid staop2 BKI_LOOKUP_OPT(pg_operator); + Oid staop3 BKI_LOOKUP_OPT(pg_operator); + Oid staop4 BKI_LOOKUP_OPT(pg_operator); + Oid staop5 BKI_LOOKUP_OPT(pg_operator); + + Oid stacoll1 BKI_LOOKUP_OPT(pg_collation); + Oid stacoll2 BKI_LOOKUP_OPT(pg_collation); + Oid stacoll3 BKI_LOOKUP_OPT(pg_collation); + Oid stacoll4 BKI_LOOKUP_OPT(pg_collation); + Oid stacoll5 BKI_LOOKUP_OPT(pg_collation); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + float4 stanumbers1[1]; + float4 stanumbers2[1]; + float4 stanumbers3[1]; + float4 stanumbers4[1]; + float4 stanumbers5[1]; + + /* + * Values in these arrays are values of the column's data type, or of some + * related type such as an array element type. We presently have to cheat + * quite a bit to allow polymorphic arrays of this kind, but perhaps + * someday it'll be a less bogus facility. + */ + anyarray stavalues1; + anyarray stavalues2; + anyarray stavalues3; + anyarray stavalues4; + anyarray stavalues5; +#endif +} FormData_pg_statistic; + +#define STATISTIC_NUM_SLOTS 5 + + +/* ---------------- + * Form_pg_statistic corresponds to a pointer to a tuple with + * the format of pg_statistic relation. + * ---------------- + */ +typedef FormData_pg_statistic *Form_pg_statistic; + +DECLARE_TOAST(pg_statistic, 2840, 2841); + +DECLARE_UNIQUE_INDEX_PKEY(pg_statistic_relid_att_inh_index, 2696, StatisticRelidAttnumInhIndexId, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops, stainherit bool_ops)); + +DECLARE_FOREIGN_KEY((starelid, staattnum), pg_attribute, (attrelid, attnum)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * Several statistical slot "kinds" are defined by core PostgreSQL, as + * documented below. Also, custom data types can define their own "kind" + * codes by mutual agreement between a custom typanalyze routine and the + * selectivity estimation functions of the type's operators. + * + * Code reading the pg_statistic relation should not assume that a particular + * data "kind" will appear in any particular slot. Instead, search the + * stakind fields to see if the desired data is available. (The standard + * function get_attstatsslot() may be used for this.) + */ + +/* + * The present allocation of "kind" codes is: + * + * 1-99: reserved for assignment by the core PostgreSQL project + * (values in this range will be documented in this file) + * 100-199: reserved for assignment by the PostGIS project + * (values to be documented in PostGIS documentation) + * 200-299: reserved for assignment by the ESRI ST_Geometry project + * (values to be documented in ESRI ST_Geometry documentation) + * 300-9999: reserved for future public assignments + * + * For private use you may choose a "kind" code at random in the range + * 10000-30000. However, for code that is to be widely disseminated it is + * better to obtain a publicly defined "kind" code by request from the + * PostgreSQL Global Development Group. + */ + +/* + * In a "most common values" slot, staop is the OID of the "=" operator + * used to decide whether values are the same or not, and stacoll is the + * collation used (same as column's collation). stavalues contains + * the K most common non-null values appearing in the column, and stanumbers + * contains their frequencies (fractions of total row count). The values + * shall be ordered in decreasing frequency. Note that since the arrays are + * variable-size, K may be chosen by the statistics collector. Values should + * not appear in MCV unless they have been observed to occur more than once; + * a unique column will have no MCV slot. + */ +#define STATISTIC_KIND_MCV 1 + +/* + * A "histogram" slot describes the distribution of scalar data. staop is + * the OID of the "<" operator that describes the sort ordering, and stacoll + * is the relevant collation. (In theory more than one histogram could appear, + * if a datatype has more than one useful sort operator or we care about more + * than one collation. Currently the collation will always be that of the + * underlying column.) stavalues contains M (>=2) non-null values that + * divide the non-null column data values into M-1 bins of approximately equal + * population. The first stavalues item is the MIN and the last is the MAX. + * stanumbers is not used and should be NULL. IMPORTANT POINT: if an MCV + * slot is also provided, then the histogram describes the data distribution + * *after removing the values listed in MCV* (thus, it's a "compressed + * histogram" in the technical parlance). This allows a more accurate + * representation of the distribution of a column with some very-common + * values. In a column with only a few distinct values, it's possible that + * the MCV list describes the entire data population; in this case the + * histogram reduces to empty and should be omitted. + */ +#define STATISTIC_KIND_HISTOGRAM 2 + +/* + * A "correlation" slot describes the correlation between the physical order + * of table tuples and the ordering of data values of this column, as seen + * by the "<" operator identified by staop with the collation identified by + * stacoll. (As with the histogram, more than one entry could theoretically + * appear.) stavalues is not used and should be NULL. stanumbers contains + * a single entry, the correlation coefficient between the sequence of data + * values and the sequence of their actual tuple positions. The coefficient + * ranges from +1 to -1. + */ +#define STATISTIC_KIND_CORRELATION 3 + +/* + * A "most common elements" slot is similar to a "most common values" slot, + * except that it stores the most common non-null *elements* of the column + * values. This is useful when the column datatype is an array or some other + * type with identifiable elements (for instance, tsvector). staop contains + * the equality operator appropriate to the element type, and stacoll + * contains the collation to use with it. stavalues contains + * the most common element values, and stanumbers their frequencies. Unlike + * MCV slots, frequencies are measured as the fraction of non-null rows the + * element value appears in, not the frequency of all rows. Also unlike + * MCV slots, the values are sorted into the element type's default order + * (to support binary search for a particular value). Since this puts the + * minimum and maximum frequencies at unpredictable spots in stanumbers, + * there are two extra members of stanumbers, holding copies of the minimum + * and maximum frequencies. Optionally, there can be a third extra member, + * which holds the frequency of null elements (expressed in the same terms: + * the fraction of non-null rows that contain at least one null element). If + * this member is omitted, the column is presumed to contain no null elements. + * + * Note: in current usage for tsvector columns, the stavalues elements are of + * type text, even though their representation within tsvector is not + * exactly text. + */ +#define STATISTIC_KIND_MCELEM 4 + +/* + * A "distinct elements count histogram" slot describes the distribution of + * the number of distinct element values present in each row of an array-type + * column. Only non-null rows are considered, and only non-null elements. + * staop contains the equality operator appropriate to the element type, + * and stacoll contains the collation to use with it. + * stavalues is not used and should be NULL. The last member of stanumbers is + * the average count of distinct element values over all non-null rows. The + * preceding M (>=2) members form a histogram that divides the population of + * distinct-elements counts into M-1 bins of approximately equal population. + * The first of these is the minimum observed count, and the last the maximum. + */ +#define STATISTIC_KIND_DECHIST 5 + +/* + * A "length histogram" slot describes the distribution of range lengths in + * rows of a range-type column. stanumbers contains a single entry, the + * fraction of empty ranges. stavalues is a histogram of non-empty lengths, in + * a format similar to STATISTIC_KIND_HISTOGRAM: it contains M (>=2) range + * values that divide the column data values into M-1 bins of approximately + * equal population. The lengths are stored as float8s, as measured by the + * range type's subdiff function. Only non-null rows are considered. + */ +#define STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM 6 + +/* + * A "bounds histogram" slot is similar to STATISTIC_KIND_HISTOGRAM, but for + * a range-type column. stavalues contains M (>=2) range values that divide + * the column data values into M-1 bins of approximately equal population. + * Unlike a regular scalar histogram, this is actually two histograms combined + * into a single array, with the lower bounds of each value forming a + * histogram of lower bounds, and the upper bounds a histogram of upper + * bounds. Only non-NULL, non-empty ranges are included. + */ +#define STATISTIC_KIND_BOUNDS_HISTOGRAM 7 + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_STATISTIC_H */ diff --git a/install/include/postgresql/server/catalog/pg_statistic_d.h b/install/include/postgresql/server/catalog/pg_statistic_d.h new file mode 100644 index 00000000000..5024895d9b5 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_statistic_d.h @@ -0,0 +1,195 @@ +/*------------------------------------------------------------------------- + * + * pg_statistic_d.h + * Macro definitions for pg_statistic + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_STATISTIC_D_H +#define PG_STATISTIC_D_H + +#define StatisticRelationId 2619 +#define StatisticRelidAttnumInhIndexId 2696 + +#define Anum_pg_statistic_starelid 1 +#define Anum_pg_statistic_staattnum 2 +#define Anum_pg_statistic_stainherit 3 +#define Anum_pg_statistic_stanullfrac 4 +#define Anum_pg_statistic_stawidth 5 +#define Anum_pg_statistic_stadistinct 6 +#define Anum_pg_statistic_stakind1 7 +#define Anum_pg_statistic_stakind2 8 +#define Anum_pg_statistic_stakind3 9 +#define Anum_pg_statistic_stakind4 10 +#define Anum_pg_statistic_stakind5 11 +#define Anum_pg_statistic_staop1 12 +#define Anum_pg_statistic_staop2 13 +#define Anum_pg_statistic_staop3 14 +#define Anum_pg_statistic_staop4 15 +#define Anum_pg_statistic_staop5 16 +#define Anum_pg_statistic_stacoll1 17 +#define Anum_pg_statistic_stacoll2 18 +#define Anum_pg_statistic_stacoll3 19 +#define Anum_pg_statistic_stacoll4 20 +#define Anum_pg_statistic_stacoll5 21 +#define Anum_pg_statistic_stanumbers1 22 +#define Anum_pg_statistic_stanumbers2 23 +#define Anum_pg_statistic_stanumbers3 24 +#define Anum_pg_statistic_stanumbers4 25 +#define Anum_pg_statistic_stanumbers5 26 +#define Anum_pg_statistic_stavalues1 27 +#define Anum_pg_statistic_stavalues2 28 +#define Anum_pg_statistic_stavalues3 29 +#define Anum_pg_statistic_stavalues4 30 +#define Anum_pg_statistic_stavalues5 31 + +#define Natts_pg_statistic 31 + + +/* + * Several statistical slot "kinds" are defined by core PostgreSQL, as + * documented below. Also, custom data types can define their own "kind" + * codes by mutual agreement between a custom typanalyze routine and the + * selectivity estimation functions of the type's operators. + * + * Code reading the pg_statistic relation should not assume that a particular + * data "kind" will appear in any particular slot. Instead, search the + * stakind fields to see if the desired data is available. (The standard + * function get_attstatsslot() may be used for this.) + */ + +/* + * The present allocation of "kind" codes is: + * + * 1-99: reserved for assignment by the core PostgreSQL project + * (values in this range will be documented in this file) + * 100-199: reserved for assignment by the PostGIS project + * (values to be documented in PostGIS documentation) + * 200-299: reserved for assignment by the ESRI ST_Geometry project + * (values to be documented in ESRI ST_Geometry documentation) + * 300-9999: reserved for future public assignments + * + * For private use you may choose a "kind" code at random in the range + * 10000-30000. However, for code that is to be widely disseminated it is + * better to obtain a publicly defined "kind" code by request from the + * PostgreSQL Global Development Group. + */ + +/* + * In a "most common values" slot, staop is the OID of the "=" operator + * used to decide whether values are the same or not, and stacoll is the + * collation used (same as column's collation). stavalues contains + * the K most common non-null values appearing in the column, and stanumbers + * contains their frequencies (fractions of total row count). The values + * shall be ordered in decreasing frequency. Note that since the arrays are + * variable-size, K may be chosen by the statistics collector. Values should + * not appear in MCV unless they have been observed to occur more than once; + * a unique column will have no MCV slot. + */ +#define STATISTIC_KIND_MCV 1 + +/* + * A "histogram" slot describes the distribution of scalar data. staop is + * the OID of the "<" operator that describes the sort ordering, and stacoll + * is the relevant collation. (In theory more than one histogram could appear, + * if a datatype has more than one useful sort operator or we care about more + * than one collation. Currently the collation will always be that of the + * underlying column.) stavalues contains M (>=2) non-null values that + * divide the non-null column data values into M-1 bins of approximately equal + * population. The first stavalues item is the MIN and the last is the MAX. + * stanumbers is not used and should be NULL. IMPORTANT POINT: if an MCV + * slot is also provided, then the histogram describes the data distribution + * *after removing the values listed in MCV* (thus, it's a "compressed + * histogram" in the technical parlance). This allows a more accurate + * representation of the distribution of a column with some very-common + * values. In a column with only a few distinct values, it's possible that + * the MCV list describes the entire data population; in this case the + * histogram reduces to empty and should be omitted. + */ +#define STATISTIC_KIND_HISTOGRAM 2 + +/* + * A "correlation" slot describes the correlation between the physical order + * of table tuples and the ordering of data values of this column, as seen + * by the "<" operator identified by staop with the collation identified by + * stacoll. (As with the histogram, more than one entry could theoretically + * appear.) stavalues is not used and should be NULL. stanumbers contains + * a single entry, the correlation coefficient between the sequence of data + * values and the sequence of their actual tuple positions. The coefficient + * ranges from +1 to -1. + */ +#define STATISTIC_KIND_CORRELATION 3 + +/* + * A "most common elements" slot is similar to a "most common values" slot, + * except that it stores the most common non-null *elements* of the column + * values. This is useful when the column datatype is an array or some other + * type with identifiable elements (for instance, tsvector). staop contains + * the equality operator appropriate to the element type, and stacoll + * contains the collation to use with it. stavalues contains + * the most common element values, and stanumbers their frequencies. Unlike + * MCV slots, frequencies are measured as the fraction of non-null rows the + * element value appears in, not the frequency of all rows. Also unlike + * MCV slots, the values are sorted into the element type's default order + * (to support binary search for a particular value). Since this puts the + * minimum and maximum frequencies at unpredictable spots in stanumbers, + * there are two extra members of stanumbers, holding copies of the minimum + * and maximum frequencies. Optionally, there can be a third extra member, + * which holds the frequency of null elements (expressed in the same terms: + * the fraction of non-null rows that contain at least one null element). If + * this member is omitted, the column is presumed to contain no null elements. + * + * Note: in current usage for tsvector columns, the stavalues elements are of + * type text, even though their representation within tsvector is not + * exactly text. + */ +#define STATISTIC_KIND_MCELEM 4 + +/* + * A "distinct elements count histogram" slot describes the distribution of + * the number of distinct element values present in each row of an array-type + * column. Only non-null rows are considered, and only non-null elements. + * staop contains the equality operator appropriate to the element type, + * and stacoll contains the collation to use with it. + * stavalues is not used and should be NULL. The last member of stanumbers is + * the average count of distinct element values over all non-null rows. The + * preceding M (>=2) members form a histogram that divides the population of + * distinct-elements counts into M-1 bins of approximately equal population. + * The first of these is the minimum observed count, and the last the maximum. + */ +#define STATISTIC_KIND_DECHIST 5 + +/* + * A "length histogram" slot describes the distribution of range lengths in + * rows of a range-type column. stanumbers contains a single entry, the + * fraction of empty ranges. stavalues is a histogram of non-empty lengths, in + * a format similar to STATISTIC_KIND_HISTOGRAM: it contains M (>=2) range + * values that divide the column data values into M-1 bins of approximately + * equal population. The lengths are stored as float8s, as measured by the + * range type's subdiff function. Only non-null rows are considered. + */ +#define STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM 6 + +/* + * A "bounds histogram" slot is similar to STATISTIC_KIND_HISTOGRAM, but for + * a range-type column. stavalues contains M (>=2) range values that divide + * the column data values into M-1 bins of approximately equal population. + * Unlike a regular scalar histogram, this is actually two histograms combined + * into a single array, with the lower bounds of each value forming a + * histogram of lower bounds, and the upper bounds a histogram of upper + * bounds. Only non-NULL, non-empty ranges are included. + */ +#define STATISTIC_KIND_BOUNDS_HISTOGRAM 7 + + +#endif /* PG_STATISTIC_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_statistic_ext.h b/install/include/postgresql/server/catalog/pg_statistic_ext.h new file mode 100644 index 00000000000..53eec9025a5 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_statistic_ext.h @@ -0,0 +1,88 @@ +/*------------------------------------------------------------------------- + * + * pg_statistic_ext.h + * definition of the "extended statistics" system catalog + * (pg_statistic_ext) + * + * Note that pg_statistic_ext contains the definitions of extended statistics + * objects, created by CREATE STATISTICS, but not the actual statistical data, + * created by running ANALYZE. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_statistic_ext.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_STATISTIC_EXT_H +#define PG_STATISTIC_EXT_H + +#include "catalog/genbki.h" +#include "catalog/pg_statistic_ext_d.h" + +/* ---------------- + * pg_statistic_ext definition. cpp turns this into + * typedef struct FormData_pg_statistic_ext + * ---------------- + */ +CATALOG(pg_statistic_ext,3381,StatisticExtRelationId) +{ + Oid oid; /* oid */ + + Oid stxrelid BKI_LOOKUP(pg_class); /* relation containing + * attributes */ + + /* These two fields form the unique key for the entry: */ + NameData stxname; /* statistics object name */ + Oid stxnamespace BKI_LOOKUP(pg_namespace); /* OID of statistics + * object's namespace */ + + Oid stxowner BKI_LOOKUP(pg_authid); /* statistics object's owner */ + int32 stxstattarget BKI_DEFAULT(-1); /* statistics target */ + + /* + * variable-length fields start here, but we allow direct access to + * stxkeys + */ + int2vector stxkeys BKI_FORCE_NOT_NULL; /* array of column keys */ + +#ifdef CATALOG_VARLEN + char stxkind[1] BKI_FORCE_NOT_NULL; /* statistics kinds requested + * to build */ + pg_node_tree stxexprs; /* A list of expression trees for stats + * attributes that are not simple column + * references. */ +#endif + +} FormData_pg_statistic_ext; + +/* ---------------- + * Form_pg_statistic_ext corresponds to a pointer to a tuple with + * the format of pg_statistic_ext relation. + * ---------------- + */ +typedef FormData_pg_statistic_ext *Form_pg_statistic_ext; + +DECLARE_TOAST(pg_statistic_ext, 3439, 3440); + +DECLARE_UNIQUE_INDEX_PKEY(pg_statistic_ext_oid_index, 3380, StatisticExtOidIndexId, on pg_statistic_ext using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_statistic_ext_name_index, 3997, StatisticExtNameIndexId, on pg_statistic_ext using btree(stxname name_ops, stxnamespace oid_ops)); +DECLARE_INDEX(pg_statistic_ext_relid_index, 3379, StatisticExtRelidIndexId, on pg_statistic_ext using btree(stxrelid oid_ops)); + +DECLARE_ARRAY_FOREIGN_KEY((stxrelid, stxkeys), pg_attribute, (attrelid, attnum)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +#define STATS_EXT_NDISTINCT 'd' +#define STATS_EXT_DEPENDENCIES 'f' +#define STATS_EXT_MCV 'm' +#define STATS_EXT_EXPRESSIONS 'e' + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_STATISTIC_EXT_H */ diff --git a/install/include/postgresql/server/catalog/pg_statistic_ext_d.h b/install/include/postgresql/server/catalog/pg_statistic_ext_d.h new file mode 100644 index 00000000000..055451d6c65 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_statistic_ext_d.h @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------- + * + * pg_statistic_ext_d.h + * Macro definitions for pg_statistic_ext + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_STATISTIC_EXT_D_H +#define PG_STATISTIC_EXT_D_H + +#define StatisticExtRelationId 3381 +#define StatisticExtOidIndexId 3380 +#define StatisticExtNameIndexId 3997 +#define StatisticExtRelidIndexId 3379 + +#define Anum_pg_statistic_ext_oid 1 +#define Anum_pg_statistic_ext_stxrelid 2 +#define Anum_pg_statistic_ext_stxname 3 +#define Anum_pg_statistic_ext_stxnamespace 4 +#define Anum_pg_statistic_ext_stxowner 5 +#define Anum_pg_statistic_ext_stxstattarget 6 +#define Anum_pg_statistic_ext_stxkeys 7 +#define Anum_pg_statistic_ext_stxkind 8 +#define Anum_pg_statistic_ext_stxexprs 9 + +#define Natts_pg_statistic_ext 9 + + +#define STATS_EXT_NDISTINCT 'd' +#define STATS_EXT_DEPENDENCIES 'f' +#define STATS_EXT_MCV 'm' +#define STATS_EXT_EXPRESSIONS 'e' + + +#endif /* PG_STATISTIC_EXT_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_statistic_ext_data.h b/install/include/postgresql/server/catalog/pg_statistic_ext_data.h new file mode 100644 index 00000000000..64d11a9c58c --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_statistic_ext_data.h @@ -0,0 +1,60 @@ +/*------------------------------------------------------------------------- + * + * pg_statistic_ext_data.h + * definition of the "extended statistics data" system catalog + * (pg_statistic_ext_data) + * + * This catalog stores the statistical data for extended statistics objects. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_statistic_ext_data.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_STATISTIC_EXT_DATA_H +#define PG_STATISTIC_EXT_DATA_H + +#include "catalog/genbki.h" +#include "catalog/pg_statistic_ext_data_d.h" + +/* ---------------- + * pg_statistic_ext_data definition. cpp turns this into + * typedef struct FormData_pg_statistic_ext_data + * ---------------- + */ +CATALOG(pg_statistic_ext_data,3429,StatisticExtDataRelationId) +{ + Oid stxoid BKI_LOOKUP(pg_statistic_ext); /* statistics object + * this data is for */ + bool stxdinherit; /* true if inheritance children are included */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + + pg_ndistinct stxdndistinct; /* ndistinct coefficients (serialized) */ + pg_dependencies stxddependencies; /* dependencies (serialized) */ + pg_mcv_list stxdmcv; /* MCV (serialized) */ + pg_statistic stxdexpr[1]; /* stats for expressions */ + +#endif + +} FormData_pg_statistic_ext_data; + +/* ---------------- + * Form_pg_statistic_ext_data corresponds to a pointer to a tuple with + * the format of pg_statistic_ext_data relation. + * ---------------- + */ +typedef FormData_pg_statistic_ext_data *Form_pg_statistic_ext_data; + +DECLARE_TOAST(pg_statistic_ext_data, 3430, 3431); + +DECLARE_UNIQUE_INDEX_PKEY(pg_statistic_ext_data_stxoid_inh_index, 3433, StatisticExtDataStxoidInhIndexId, on pg_statistic_ext_data using btree(stxoid oid_ops, stxdinherit bool_ops)); + + +#endif /* PG_STATISTIC_EXT_DATA_H */ diff --git a/install/include/postgresql/server/catalog/pg_statistic_ext_data_d.h b/install/include/postgresql/server/catalog/pg_statistic_ext_data_d.h new file mode 100644 index 00000000000..946b97ce355 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_statistic_ext_data_d.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * pg_statistic_ext_data_d.h + * Macro definitions for pg_statistic_ext_data + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_STATISTIC_EXT_DATA_D_H +#define PG_STATISTIC_EXT_DATA_D_H + +#define StatisticExtDataRelationId 3429 +#define StatisticExtDataStxoidInhIndexId 3433 + +#define Anum_pg_statistic_ext_data_stxoid 1 +#define Anum_pg_statistic_ext_data_stxdinherit 2 +#define Anum_pg_statistic_ext_data_stxdndistinct 3 +#define Anum_pg_statistic_ext_data_stxddependencies 4 +#define Anum_pg_statistic_ext_data_stxdmcv 5 +#define Anum_pg_statistic_ext_data_stxdexpr 6 + +#define Natts_pg_statistic_ext_data 6 + + +#endif /* PG_STATISTIC_EXT_DATA_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_subscription.h b/install/include/postgresql/server/catalog/pg_subscription.h new file mode 100644 index 00000000000..1d40eebc789 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_subscription.h @@ -0,0 +1,170 @@ +/* ------------------------------------------------------------------------- + * + * pg_subscription.h + * definition of the "subscription" system catalog (pg_subscription) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_subscription.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + * ------------------------------------------------------------------------- + */ +#ifndef PG_SUBSCRIPTION_H +#define PG_SUBSCRIPTION_H + +#include "access/xlogdefs.h" +#include "catalog/genbki.h" +#include "catalog/pg_subscription_d.h" + +#include "nodes/pg_list.h" + +/* + * two_phase tri-state values. See comments atop worker.c to know more about + * these states. + */ +#define LOGICALREP_TWOPHASE_STATE_DISABLED 'd' +#define LOGICALREP_TWOPHASE_STATE_PENDING 'p' +#define LOGICALREP_TWOPHASE_STATE_ENABLED 'e' + +/* + * The subscription will request the publisher to only send changes that do not + * have any origin. + */ +#define LOGICALREP_ORIGIN_NONE "none" + +/* + * The subscription will request the publisher to send changes regardless + * of their origin. + */ +#define LOGICALREP_ORIGIN_ANY "any" + +/* ---------------- + * pg_subscription definition. cpp turns this into + * typedef struct FormData_pg_subscription + * ---------------- + */ + +/* + * Technically, the subscriptions live inside the database, so a shared catalog + * seems weird, but the replication launcher process needs to access all of + * them to be able to start the workers, so we have to put them in a shared, + * nailed catalog. + * + * CAUTION: There is a GRANT in system_views.sql to grant public select + * access on all columns except subconninfo. When you add a new column + * here, be sure to update that (or, if the new column is not to be publicly + * readable, update associated comments and catalogs.sgml instead). + */ +CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(6101,SubscriptionRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + Oid oid; /* oid */ + + Oid subdbid BKI_LOOKUP(pg_database); /* Database the + * subscription is in. */ + + XLogRecPtr subskiplsn; /* All changes finished at this LSN are + * skipped */ + + NameData subname; /* Name of the subscription */ + + Oid subowner BKI_LOOKUP(pg_authid); /* Owner of the subscription */ + + bool subenabled; /* True if the subscription is enabled (the + * worker should be running) */ + + bool subbinary; /* True if the subscription wants the + * publisher to send data in binary */ + + char substream; /* Stream in-progress transactions. See + * LOGICALREP_STREAM_xxx constants. */ + + char subtwophasestate; /* Stream two-phase transactions */ + + bool subdisableonerr; /* True if a worker error should cause the + * subscription to be disabled */ + + bool subpasswordrequired; /* Must connection use a password? */ + + bool subrunasowner; /* True if replication should execute as the + * subscription owner */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* Connection string to the publisher */ + text subconninfo BKI_FORCE_NOT_NULL; + + /* Slot name on publisher */ + NameData subslotname BKI_FORCE_NULL; + + /* Synchronous commit setting for worker */ + text subsynccommit BKI_FORCE_NOT_NULL; + + /* List of publications subscribed to */ + text subpublications[1] BKI_FORCE_NOT_NULL; + + /* Only publish data originating from the specified origin */ + text suborigin BKI_DEFAULT(LOGICALREP_ORIGIN_ANY); +#endif +} FormData_pg_subscription; + +typedef FormData_pg_subscription *Form_pg_subscription; + +DECLARE_TOAST_WITH_MACRO(pg_subscription, 4183, 4184, PgSubscriptionToastTable, PgSubscriptionToastIndex); + +DECLARE_UNIQUE_INDEX_PKEY(pg_subscription_oid_index, 6114, SubscriptionObjectIndexId, on pg_subscription using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_subscription_subname_index, 6115, SubscriptionNameIndexId, on pg_subscription using btree(subdbid oid_ops, subname name_ops)); + +typedef struct Subscription +{ + Oid oid; /* Oid of the subscription */ + Oid dbid; /* Oid of the database which subscription is + * in */ + XLogRecPtr skiplsn; /* All changes finished at this LSN are + * skipped */ + char *name; /* Name of the subscription */ + Oid owner; /* Oid of the subscription owner */ + bool enabled; /* Indicates if the subscription is enabled */ + bool binary; /* Indicates if the subscription wants data in + * binary format */ + char stream; /* Allow streaming in-progress transactions. + * See LOGICALREP_STREAM_xxx constants. */ + char twophasestate; /* Allow streaming two-phase transactions */ + bool disableonerr; /* Indicates if the subscription should be + * automatically disabled if a worker error + * occurs */ + bool passwordrequired; /* Must connection use a password? */ + bool runasowner; /* Run replication as subscription owner */ + char *conninfo; /* Connection string to the publisher */ + char *slotname; /* Name of the replication slot */ + char *synccommit; /* Synchronous commit setting for worker */ + List *publications; /* List of publication names to subscribe to */ + char *origin; /* Only publish data originating from the + * specified origin */ +} Subscription; + +/* Disallow streaming in-progress transactions. */ +#define LOGICALREP_STREAM_OFF 'f' + +/* + * Streaming in-progress transactions are written to a temporary file and + * applied only after the transaction is committed on upstream. + */ +#define LOGICALREP_STREAM_ON 't' + +/* + * Streaming in-progress transactions are applied immediately via a parallel + * apply worker. + */ +#define LOGICALREP_STREAM_PARALLEL 'p' + +extern Subscription *GetSubscription(Oid subid, bool missing_ok); +extern void FreeSubscription(Subscription *sub); +extern void DisableSubscription(Oid subid); + +extern int CountDBSubscriptions(Oid dbid); + +#endif /* PG_SUBSCRIPTION_H */ diff --git a/install/include/postgresql/server/catalog/pg_subscription_d.h b/install/include/postgresql/server/catalog/pg_subscription_d.h new file mode 100644 index 00000000000..e09fcef6e53 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_subscription_d.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * pg_subscription_d.h + * Macro definitions for pg_subscription + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SUBSCRIPTION_D_H +#define PG_SUBSCRIPTION_D_H + +#define SubscriptionRelationId 6100 +#define SubscriptionRelation_Rowtype_Id 6101 +#define PgSubscriptionToastTable 4183 +#define PgSubscriptionToastIndex 4184 +#define SubscriptionObjectIndexId 6114 +#define SubscriptionNameIndexId 6115 + +#define Anum_pg_subscription_oid 1 +#define Anum_pg_subscription_subdbid 2 +#define Anum_pg_subscription_subskiplsn 3 +#define Anum_pg_subscription_subname 4 +#define Anum_pg_subscription_subowner 5 +#define Anum_pg_subscription_subenabled 6 +#define Anum_pg_subscription_subbinary 7 +#define Anum_pg_subscription_substream 8 +#define Anum_pg_subscription_subtwophasestate 9 +#define Anum_pg_subscription_subdisableonerr 10 +#define Anum_pg_subscription_subpasswordrequired 11 +#define Anum_pg_subscription_subrunasowner 12 +#define Anum_pg_subscription_subconninfo 13 +#define Anum_pg_subscription_subslotname 14 +#define Anum_pg_subscription_subsynccommit 15 +#define Anum_pg_subscription_subpublications 16 +#define Anum_pg_subscription_suborigin 17 + +#define Natts_pg_subscription 17 + + +#endif /* PG_SUBSCRIPTION_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_subscription_rel.h b/install/include/postgresql/server/catalog/pg_subscription_rel.h new file mode 100644 index 00000000000..9bced6697e9 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_subscription_rel.h @@ -0,0 +1,95 @@ +/* ------------------------------------------------------------------------- + * + * pg_subscription_rel.h + * definition of the system catalog containing the state for each + * replicated table in each subscription (pg_subscription_rel) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_subscription_rel.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + * ------------------------------------------------------------------------- + */ +#ifndef PG_SUBSCRIPTION_REL_H +#define PG_SUBSCRIPTION_REL_H + +#include "access/xlogdefs.h" +#include "catalog/genbki.h" +#include "catalog/pg_subscription_rel_d.h" +#include "nodes/pg_list.h" + +/* ---------------- + * pg_subscription_rel definition. cpp turns this into + * typedef struct FormData_pg_subscription_rel + * ---------------- + */ +CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId) +{ + Oid srsubid BKI_LOOKUP(pg_subscription); /* Oid of subscription */ + Oid srrelid BKI_LOOKUP(pg_class); /* Oid of relation */ + char srsubstate; /* state of the relation in subscription */ + + /* + * Although srsublsn is a fixed-width type, it is allowed to be NULL, so + * we prevent direct C code access to it just as for a varlena field. + */ +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + + XLogRecPtr srsublsn BKI_FORCE_NULL; /* remote LSN of the state change + * used for synchronization + * coordination, or NULL if not + * valid */ +#endif +} FormData_pg_subscription_rel; + +typedef FormData_pg_subscription_rel *Form_pg_subscription_rel; + +DECLARE_UNIQUE_INDEX_PKEY(pg_subscription_rel_srrelid_srsubid_index, 6117, SubscriptionRelSrrelidSrsubidIndexId, on pg_subscription_rel using btree(srrelid oid_ops, srsubid oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* ---------------- + * substate constants + * ---------------- + */ +#define SUBREL_STATE_INIT 'i' /* initializing (sublsn NULL) */ +#define SUBREL_STATE_DATASYNC 'd' /* data is being synchronized (sublsn + * NULL) */ +#define SUBREL_STATE_FINISHEDCOPY 'f' /* tablesync copy phase is completed + * (sublsn NULL) */ +#define SUBREL_STATE_SYNCDONE 's' /* synchronization finished in front of + * apply (sublsn set) */ +#define SUBREL_STATE_READY 'r' /* ready (sublsn set) */ + +/* These are never stored in the catalog, we only use them for IPC. */ +#define SUBREL_STATE_UNKNOWN '\0' /* unknown state */ +#define SUBREL_STATE_SYNCWAIT 'w' /* waiting for sync */ +#define SUBREL_STATE_CATCHUP 'c' /* catching up with apply */ + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +typedef struct SubscriptionRelState +{ + Oid relid; + XLogRecPtr lsn; + char state; +} SubscriptionRelState; + +extern void AddSubscriptionRelState(Oid subid, Oid relid, char state, + XLogRecPtr sublsn); +extern void UpdateSubscriptionRelState(Oid subid, Oid relid, char state, + XLogRecPtr sublsn); +extern void UpdateSubscriptionRelStateEx(Oid subid, Oid relid, char state, + XLogRecPtr sublsn, bool already_locked); +extern char GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn); +extern void RemoveSubscriptionRel(Oid subid, Oid relid); + +extern bool HasSubscriptionRelations(Oid subid); +extern List *GetSubscriptionRelations(Oid subid, bool not_ready); + +#endif /* PG_SUBSCRIPTION_REL_H */ diff --git a/install/include/postgresql/server/catalog/pg_subscription_rel_d.h b/install/include/postgresql/server/catalog/pg_subscription_rel_d.h new file mode 100644 index 00000000000..bc6c272c65a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_subscription_rel_d.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * pg_subscription_rel_d.h + * Macro definitions for pg_subscription_rel + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SUBSCRIPTION_REL_D_H +#define PG_SUBSCRIPTION_REL_D_H + +#define SubscriptionRelRelationId 6102 +#define SubscriptionRelSrrelidSrsubidIndexId 6117 + +#define Anum_pg_subscription_rel_srsubid 1 +#define Anum_pg_subscription_rel_srrelid 2 +#define Anum_pg_subscription_rel_srsubstate 3 +#define Anum_pg_subscription_rel_srsublsn 4 + +#define Natts_pg_subscription_rel 4 + + +/* ---------------- + * substate constants + * ---------------- + */ +#define SUBREL_STATE_INIT 'i' /* initializing (sublsn NULL) */ +#define SUBREL_STATE_DATASYNC 'd' /* data is being synchronized (sublsn + * NULL) */ +#define SUBREL_STATE_FINISHEDCOPY 'f' /* tablesync copy phase is completed + * (sublsn NULL) */ +#define SUBREL_STATE_SYNCDONE 's' /* synchronization finished in front of + * apply (sublsn set) */ +#define SUBREL_STATE_READY 'r' /* ready (sublsn set) */ + +/* These are never stored in the catalog, we only use them for IPC. */ +#define SUBREL_STATE_UNKNOWN '\0' /* unknown state */ +#define SUBREL_STATE_SYNCWAIT 'w' /* waiting for sync */ +#define SUBREL_STATE_CATCHUP 'c' /* catching up with apply */ + + +#endif /* PG_SUBSCRIPTION_REL_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_tablespace.h b/install/include/postgresql/server/catalog/pg_tablespace.h new file mode 100644 index 00000000000..ea1593d874e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_tablespace.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * pg_tablespace.h + * definition of the "tablespace" system catalog (pg_tablespace) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_tablespace.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TABLESPACE_H +#define PG_TABLESPACE_H + +#include "catalog/genbki.h" +#include "catalog/pg_tablespace_d.h" + +/* ---------------- + * pg_tablespace definition. cpp turns this into + * typedef struct FormData_pg_tablespace + * ---------------- + */ +CATALOG(pg_tablespace,1213,TableSpaceRelationId) BKI_SHARED_RELATION +{ + Oid oid; /* oid */ + NameData spcname; /* tablespace name */ + + /* owner of tablespace */ + Oid spcowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + aclitem spcacl[1]; /* access permissions */ + text spcoptions[1]; /* per-tablespace options */ +#endif +} FormData_pg_tablespace; + +/* ---------------- + * Form_pg_tablespace corresponds to a pointer to a tuple with + * the format of pg_tablespace relation. + * ---------------- + */ +typedef FormData_pg_tablespace *Form_pg_tablespace; + +DECLARE_TOAST_WITH_MACRO(pg_tablespace, 4185, 4186, PgTablespaceToastTable, PgTablespaceToastIndex); + +DECLARE_UNIQUE_INDEX_PKEY(pg_tablespace_oid_index, 2697, TablespaceOidIndexId, on pg_tablespace using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_tablespace_spcname_index, 2698, TablespaceNameIndexId, on pg_tablespace using btree(spcname name_ops)); + +#endif /* PG_TABLESPACE_H */ diff --git a/install/include/postgresql/server/catalog/pg_tablespace_d.h b/install/include/postgresql/server/catalog/pg_tablespace_d.h new file mode 100644 index 00000000000..daee40dd3f0 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_tablespace_d.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * pg_tablespace_d.h + * Macro definitions for pg_tablespace + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TABLESPACE_D_H +#define PG_TABLESPACE_D_H + +#define TableSpaceRelationId 1213 +#define PgTablespaceToastTable 4185 +#define PgTablespaceToastIndex 4186 +#define TablespaceOidIndexId 2697 +#define TablespaceNameIndexId 2698 + +#define Anum_pg_tablespace_oid 1 +#define Anum_pg_tablespace_spcname 2 +#define Anum_pg_tablespace_spcowner 3 +#define Anum_pg_tablespace_spcacl 4 +#define Anum_pg_tablespace_spcoptions 5 + +#define Natts_pg_tablespace 5 + +#define DEFAULTTABLESPACE_OID 1663 +#define GLOBALTABLESPACE_OID 1664 +#define UNDOTABLESPACE_OID 9100 + +#endif /* PG_TABLESPACE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_transform.h b/install/include/postgresql/server/catalog/pg_transform.h new file mode 100644 index 00000000000..6273b0a4912 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_transform.h @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------- + * + * pg_transform.h + * definition of the "transform" system catalog (pg_transform) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_transform.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TRANSFORM_H +#define PG_TRANSFORM_H + +#include "catalog/genbki.h" +#include "catalog/pg_transform_d.h" + +/* ---------------- + * pg_transform definition. cpp turns this into + * typedef struct FormData_pg_transform + * ---------------- + */ +CATALOG(pg_transform,3576,TransformRelationId) +{ + Oid oid; /* oid */ + Oid trftype BKI_LOOKUP(pg_type); + Oid trflang BKI_LOOKUP(pg_language); + regproc trffromsql BKI_LOOKUP_OPT(pg_proc); + regproc trftosql BKI_LOOKUP_OPT(pg_proc); +} FormData_pg_transform; + +/* ---------------- + * Form_pg_transform corresponds to a pointer to a tuple with + * the format of pg_transform relation. + * ---------------- + */ +typedef FormData_pg_transform *Form_pg_transform; + +DECLARE_UNIQUE_INDEX_PKEY(pg_transform_oid_index, 3574, TransformOidIndexId, on pg_transform using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_transform_type_lang_index, 3575, TransformTypeLangIndexId, on pg_transform using btree(trftype oid_ops, trflang oid_ops)); + +#endif /* PG_TRANSFORM_H */ diff --git a/install/include/postgresql/server/catalog/pg_transform_d.h b/install/include/postgresql/server/catalog/pg_transform_d.h new file mode 100644 index 00000000000..ddb3b9c2481 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_transform_d.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * pg_transform_d.h + * Macro definitions for pg_transform + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TRANSFORM_D_H +#define PG_TRANSFORM_D_H + +#define TransformRelationId 3576 +#define TransformOidIndexId 3574 +#define TransformTypeLangIndexId 3575 + +#define Anum_pg_transform_oid 1 +#define Anum_pg_transform_trftype 2 +#define Anum_pg_transform_trflang 3 +#define Anum_pg_transform_trffromsql 4 +#define Anum_pg_transform_trftosql 5 + +#define Natts_pg_transform 5 + + +#endif /* PG_TRANSFORM_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_trigger.h b/install/include/postgresql/server/catalog/pg_trigger.h new file mode 100644 index 00000000000..3679b0395f6 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_trigger.h @@ -0,0 +1,153 @@ +/*------------------------------------------------------------------------- + * + * pg_trigger.h + * definition of the "trigger" system catalog (pg_trigger) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_trigger.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TRIGGER_H +#define PG_TRIGGER_H + +#include "catalog/genbki.h" +#include "catalog/pg_trigger_d.h" + +/* ---------------- + * pg_trigger definition. cpp turns this into + * typedef struct FormData_pg_trigger + * + * Note: 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. + * ---------------- + */ +CATALOG(pg_trigger,2620,TriggerRelationId) +{ + Oid oid; /* oid */ + Oid tgrelid BKI_LOOKUP(pg_class); /* relation trigger is + * attached to */ + Oid tgparentid BKI_LOOKUP_OPT(pg_trigger); /* OID of parent + * trigger, if any */ + NameData tgname; /* trigger's name */ + Oid tgfoid BKI_LOOKUP(pg_proc); /* OID of function to be called */ + int16 tgtype; /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT, + * ROW/STATEMENT; see below */ + char tgenabled; /* trigger's firing configuration WRT + * session_replication_role */ + bool tgisinternal; /* trigger is system-generated */ + Oid tgconstrrelid BKI_LOOKUP_OPT(pg_class); /* constraint's FROM + * table, if any */ + Oid tgconstrindid BKI_LOOKUP_OPT(pg_class); /* constraint's + * supporting index, if + * any */ + Oid tgconstraint BKI_LOOKUP_OPT(pg_constraint); /* associated + * pg_constraint entry, + * if any */ + bool tgdeferrable; /* constraint trigger is deferrable */ + bool tginitdeferred; /* constraint trigger is deferred initially */ + int16 tgnargs; /* # of extra arguments in tgargs */ + + /* + * Variable-length fields start here, but we allow direct access to + * tgattr. Note: tgattr and tgargs must not be null. + */ + int2vector tgattr BKI_FORCE_NOT_NULL; /* column numbers, if trigger is + * on columns */ + +#ifdef CATALOG_VARLEN + bytea tgargs BKI_FORCE_NOT_NULL; /* first\000second\000tgnargs\000 */ + pg_node_tree tgqual; /* WHEN expression, or NULL if none */ + NameData tgoldtable; /* old transition table, or NULL if none */ + NameData tgnewtable; /* new transition table, or NULL if none */ +#endif +} FormData_pg_trigger; + +/* ---------------- + * Form_pg_trigger corresponds to a pointer to a tuple with + * the format of pg_trigger relation. + * ---------------- + */ +typedef FormData_pg_trigger *Form_pg_trigger; + +DECLARE_TOAST(pg_trigger, 2336, 2337); + +DECLARE_INDEX(pg_trigger_tgconstraint_index, 2699, TriggerConstraintIndexId, on pg_trigger using btree(tgconstraint oid_ops)); +DECLARE_UNIQUE_INDEX(pg_trigger_tgrelid_tgname_index, 2701, TriggerRelidNameIndexId, on pg_trigger using btree(tgrelid oid_ops, tgname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_trigger_oid_index, 2702, TriggerOidIndexId, on pg_trigger using btree(oid oid_ops)); + +DECLARE_ARRAY_FOREIGN_KEY((tgrelid, tgattr), pg_attribute, (attrelid, attnum)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* Bits within tgtype */ +#define TRIGGER_TYPE_ROW (1 << 0) +#define TRIGGER_TYPE_BEFORE (1 << 1) +#define TRIGGER_TYPE_INSERT (1 << 2) +#define TRIGGER_TYPE_DELETE (1 << 3) +#define TRIGGER_TYPE_UPDATE (1 << 4) +#define TRIGGER_TYPE_TRUNCATE (1 << 5) +#define TRIGGER_TYPE_INSTEAD (1 << 6) + +#define TRIGGER_TYPE_LEVEL_MASK (TRIGGER_TYPE_ROW) +#define TRIGGER_TYPE_STATEMENT 0 + +/* Note bits within TRIGGER_TYPE_TIMING_MASK aren't adjacent */ +#define TRIGGER_TYPE_TIMING_MASK \ + (TRIGGER_TYPE_BEFORE | TRIGGER_TYPE_INSTEAD) +#define TRIGGER_TYPE_AFTER 0 + +#define TRIGGER_TYPE_EVENT_MASK \ + (TRIGGER_TYPE_INSERT | TRIGGER_TYPE_DELETE | TRIGGER_TYPE_UPDATE | TRIGGER_TYPE_TRUNCATE) + +/* Macros for manipulating tgtype */ +#define TRIGGER_CLEAR_TYPE(type) ((type) = 0) + +#define TRIGGER_SETT_ROW(type) ((type) |= TRIGGER_TYPE_ROW) +#define TRIGGER_SETT_STATEMENT(type) ((type) |= TRIGGER_TYPE_STATEMENT) +#define TRIGGER_SETT_BEFORE(type) ((type) |= TRIGGER_TYPE_BEFORE) +#define TRIGGER_SETT_AFTER(type) ((type) |= TRIGGER_TYPE_AFTER) +#define TRIGGER_SETT_INSTEAD(type) ((type) |= TRIGGER_TYPE_INSTEAD) +#define TRIGGER_SETT_INSERT(type) ((type) |= TRIGGER_TYPE_INSERT) +#define TRIGGER_SETT_DELETE(type) ((type) |= TRIGGER_TYPE_DELETE) +#define TRIGGER_SETT_UPDATE(type) ((type) |= TRIGGER_TYPE_UPDATE) +#define TRIGGER_SETT_TRUNCATE(type) ((type) |= TRIGGER_TYPE_TRUNCATE) + +#define TRIGGER_FOR_ROW(type) ((type) & TRIGGER_TYPE_ROW) +#define TRIGGER_FOR_BEFORE(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_BEFORE) +#define TRIGGER_FOR_AFTER(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_AFTER) +#define TRIGGER_FOR_INSTEAD(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_INSTEAD) +#define TRIGGER_FOR_INSERT(type) ((type) & TRIGGER_TYPE_INSERT) +#define TRIGGER_FOR_DELETE(type) ((type) & TRIGGER_TYPE_DELETE) +#define TRIGGER_FOR_UPDATE(type) ((type) & TRIGGER_TYPE_UPDATE) +#define TRIGGER_FOR_TRUNCATE(type) ((type) & TRIGGER_TYPE_TRUNCATE) + +/* + * Efficient macro for checking if tgtype matches a particular level + * (TRIGGER_TYPE_ROW or TRIGGER_TYPE_STATEMENT), timing (TRIGGER_TYPE_BEFORE, + * TRIGGER_TYPE_AFTER or TRIGGER_TYPE_INSTEAD), and event (TRIGGER_TYPE_INSERT, + * TRIGGER_TYPE_DELETE, TRIGGER_TYPE_UPDATE, or TRIGGER_TYPE_TRUNCATE). Note + * that a tgtype can match more than one event, but only one level or timing. + */ +#define TRIGGER_TYPE_MATCHES(type, level, timing, event) \ + (((type) & (TRIGGER_TYPE_LEVEL_MASK | TRIGGER_TYPE_TIMING_MASK | (event))) == ((level) | (timing) | (event))) + +/* + * Macro to determine whether tgnewtable or tgoldtable has been specified for + * a trigger. + */ +#define TRIGGER_USES_TRANSITION_TABLE(namepointer) \ + ((namepointer) != (char *) NULL) + +#endif /* EXPOSE_TO_CLIENT_CODE */ + +#endif /* PG_TRIGGER_H */ diff --git a/install/include/postgresql/server/catalog/pg_trigger_d.h b/install/include/postgresql/server/catalog/pg_trigger_d.h new file mode 100644 index 00000000000..95109053eb4 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_trigger_d.h @@ -0,0 +1,109 @@ +/*------------------------------------------------------------------------- + * + * pg_trigger_d.h + * Macro definitions for pg_trigger + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TRIGGER_D_H +#define PG_TRIGGER_D_H + +#define TriggerRelationId 2620 +#define TriggerConstraintIndexId 2699 +#define TriggerRelidNameIndexId 2701 +#define TriggerOidIndexId 2702 + +#define Anum_pg_trigger_oid 1 +#define Anum_pg_trigger_tgrelid 2 +#define Anum_pg_trigger_tgparentid 3 +#define Anum_pg_trigger_tgname 4 +#define Anum_pg_trigger_tgfoid 5 +#define Anum_pg_trigger_tgtype 6 +#define Anum_pg_trigger_tgenabled 7 +#define Anum_pg_trigger_tgisinternal 8 +#define Anum_pg_trigger_tgconstrrelid 9 +#define Anum_pg_trigger_tgconstrindid 10 +#define Anum_pg_trigger_tgconstraint 11 +#define Anum_pg_trigger_tgdeferrable 12 +#define Anum_pg_trigger_tginitdeferred 13 +#define Anum_pg_trigger_tgnargs 14 +#define Anum_pg_trigger_tgattr 15 +#define Anum_pg_trigger_tgargs 16 +#define Anum_pg_trigger_tgqual 17 +#define Anum_pg_trigger_tgoldtable 18 +#define Anum_pg_trigger_tgnewtable 19 + +#define Natts_pg_trigger 19 + + +/* Bits within tgtype */ +#define TRIGGER_TYPE_ROW (1 << 0) +#define TRIGGER_TYPE_BEFORE (1 << 1) +#define TRIGGER_TYPE_INSERT (1 << 2) +#define TRIGGER_TYPE_DELETE (1 << 3) +#define TRIGGER_TYPE_UPDATE (1 << 4) +#define TRIGGER_TYPE_TRUNCATE (1 << 5) +#define TRIGGER_TYPE_INSTEAD (1 << 6) + +#define TRIGGER_TYPE_LEVEL_MASK (TRIGGER_TYPE_ROW) +#define TRIGGER_TYPE_STATEMENT 0 + +/* Note bits within TRIGGER_TYPE_TIMING_MASK aren't adjacent */ +#define TRIGGER_TYPE_TIMING_MASK \ + (TRIGGER_TYPE_BEFORE | TRIGGER_TYPE_INSTEAD) +#define TRIGGER_TYPE_AFTER 0 + +#define TRIGGER_TYPE_EVENT_MASK \ + (TRIGGER_TYPE_INSERT | TRIGGER_TYPE_DELETE | TRIGGER_TYPE_UPDATE | TRIGGER_TYPE_TRUNCATE) + +/* Macros for manipulating tgtype */ +#define TRIGGER_CLEAR_TYPE(type) ((type) = 0) + +#define TRIGGER_SETT_ROW(type) ((type) |= TRIGGER_TYPE_ROW) +#define TRIGGER_SETT_STATEMENT(type) ((type) |= TRIGGER_TYPE_STATEMENT) +#define TRIGGER_SETT_BEFORE(type) ((type) |= TRIGGER_TYPE_BEFORE) +#define TRIGGER_SETT_AFTER(type) ((type) |= TRIGGER_TYPE_AFTER) +#define TRIGGER_SETT_INSTEAD(type) ((type) |= TRIGGER_TYPE_INSTEAD) +#define TRIGGER_SETT_INSERT(type) ((type) |= TRIGGER_TYPE_INSERT) +#define TRIGGER_SETT_DELETE(type) ((type) |= TRIGGER_TYPE_DELETE) +#define TRIGGER_SETT_UPDATE(type) ((type) |= TRIGGER_TYPE_UPDATE) +#define TRIGGER_SETT_TRUNCATE(type) ((type) |= TRIGGER_TYPE_TRUNCATE) + +#define TRIGGER_FOR_ROW(type) ((type) & TRIGGER_TYPE_ROW) +#define TRIGGER_FOR_BEFORE(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_BEFORE) +#define TRIGGER_FOR_AFTER(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_AFTER) +#define TRIGGER_FOR_INSTEAD(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_INSTEAD) +#define TRIGGER_FOR_INSERT(type) ((type) & TRIGGER_TYPE_INSERT) +#define TRIGGER_FOR_DELETE(type) ((type) & TRIGGER_TYPE_DELETE) +#define TRIGGER_FOR_UPDATE(type) ((type) & TRIGGER_TYPE_UPDATE) +#define TRIGGER_FOR_TRUNCATE(type) ((type) & TRIGGER_TYPE_TRUNCATE) + +/* + * Efficient macro for checking if tgtype matches a particular level + * (TRIGGER_TYPE_ROW or TRIGGER_TYPE_STATEMENT), timing (TRIGGER_TYPE_BEFORE, + * TRIGGER_TYPE_AFTER or TRIGGER_TYPE_INSTEAD), and event (TRIGGER_TYPE_INSERT, + * TRIGGER_TYPE_DELETE, TRIGGER_TYPE_UPDATE, or TRIGGER_TYPE_TRUNCATE). Note + * that a tgtype can match more than one event, but only one level or timing. + */ +#define TRIGGER_TYPE_MATCHES(type, level, timing, event) \ + (((type) & (TRIGGER_TYPE_LEVEL_MASK | TRIGGER_TYPE_TIMING_MASK | (event))) == ((level) | (timing) | (event))) + +/* + * Macro to determine whether tgnewtable or tgoldtable has been specified for + * a trigger. + */ +#define TRIGGER_USES_TRANSITION_TABLE(namepointer) \ + ((namepointer) != (char *) NULL) + + +#endif /* PG_TRIGGER_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_config.h b/install/include/postgresql/server/catalog/pg_ts_config.h new file mode 100644 index 00000000000..aee0bf71af5 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_config.h @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_config.h + * definition of the "text search configuration" system catalog + * (pg_ts_config) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_ts_config.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_CONFIG_H +#define PG_TS_CONFIG_H + +#include "catalog/genbki.h" +#include "catalog/pg_ts_config_d.h" + +/* ---------------- + * pg_ts_config definition. cpp turns this into + * typedef struct FormData_pg_ts_config + * ---------------- + */ +CATALOG(pg_ts_config,3602,TSConfigRelationId) +{ + /* oid */ + Oid oid; + + /* name of configuration */ + NameData cfgname; + + /* name space */ + Oid cfgnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* owner */ + Oid cfgowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* OID of parser */ + Oid cfgparser BKI_LOOKUP(pg_ts_parser); +} FormData_pg_ts_config; + +typedef FormData_pg_ts_config *Form_pg_ts_config; + +DECLARE_UNIQUE_INDEX(pg_ts_config_cfgname_index, 3608, TSConfigNameNspIndexId, on pg_ts_config using btree(cfgname name_ops, cfgnamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_ts_config_oid_index, 3712, TSConfigOidIndexId, on pg_ts_config using btree(oid oid_ops)); + +#endif /* PG_TS_CONFIG_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_config_d.h b/install/include/postgresql/server/catalog/pg_ts_config_d.h new file mode 100644 index 00000000000..20cc7823e6f --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_config_d.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_config_d.h + * Macro definitions for pg_ts_config + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_CONFIG_D_H +#define PG_TS_CONFIG_D_H + +#define TSConfigRelationId 3602 +#define TSConfigNameNspIndexId 3608 +#define TSConfigOidIndexId 3712 + +#define Anum_pg_ts_config_oid 1 +#define Anum_pg_ts_config_cfgname 2 +#define Anum_pg_ts_config_cfgnamespace 3 +#define Anum_pg_ts_config_cfgowner 4 +#define Anum_pg_ts_config_cfgparser 5 + +#define Natts_pg_ts_config 5 + + +#endif /* PG_TS_CONFIG_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_config_map.h b/install/include/postgresql/server/catalog/pg_ts_config_map.h new file mode 100644 index 00000000000..359368ecd61 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_config_map.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_config_map.h + * definition of the system catalog for text search token mappings + * (pg_ts_config_map) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_ts_config_map.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_CONFIG_MAP_H +#define PG_TS_CONFIG_MAP_H + +#include "catalog/genbki.h" +#include "catalog/pg_ts_config_map_d.h" + +/* ---------------- + * pg_ts_config_map definition. cpp turns this into + * typedef struct FormData_pg_ts_config_map + * ---------------- + */ +CATALOG(pg_ts_config_map,3603,TSConfigMapRelationId) +{ + /* OID of configuration owning this entry */ + Oid mapcfg BKI_LOOKUP(pg_ts_config); + + /* token type from parser */ + int32 maptokentype; + + /* order in which to consult dictionaries */ + int32 mapseqno; + + /* dictionary to consult */ + Oid mapdict BKI_LOOKUP(pg_ts_dict); +} FormData_pg_ts_config_map; + +typedef FormData_pg_ts_config_map *Form_pg_ts_config_map; + +DECLARE_UNIQUE_INDEX_PKEY(pg_ts_config_map_index, 3609, TSConfigMapIndexId, on pg_ts_config_map using btree(mapcfg oid_ops, maptokentype int4_ops, mapseqno int4_ops)); + +#endif /* PG_TS_CONFIG_MAP_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_config_map_d.h b/install/include/postgresql/server/catalog/pg_ts_config_map_d.h new file mode 100644 index 00000000000..866f9c6846e --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_config_map_d.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_config_map_d.h + * Macro definitions for pg_ts_config_map + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_CONFIG_MAP_D_H +#define PG_TS_CONFIG_MAP_D_H + +#define TSConfigMapRelationId 3603 +#define TSConfigMapIndexId 3609 + +#define Anum_pg_ts_config_map_mapcfg 1 +#define Anum_pg_ts_config_map_maptokentype 2 +#define Anum_pg_ts_config_map_mapseqno 3 +#define Anum_pg_ts_config_map_mapdict 4 + +#define Natts_pg_ts_config_map 4 + + +#endif /* PG_TS_CONFIG_MAP_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_dict.h b/install/include/postgresql/server/catalog/pg_ts_dict.h new file mode 100644 index 00000000000..476325f0107 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_dict.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_dict.h + * definition of the "text search dictionary" system catalog (pg_ts_dict) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_ts_dict.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_DICT_H +#define PG_TS_DICT_H + +#include "catalog/genbki.h" +#include "catalog/pg_ts_dict_d.h" + +/* ---------------- + * pg_ts_dict definition. cpp turns this into + * typedef struct FormData_pg_ts_dict + * ---------------- + */ +CATALOG(pg_ts_dict,3600,TSDictionaryRelationId) +{ + /* oid */ + Oid oid; + + /* dictionary name */ + NameData dictname; + + /* name space */ + Oid dictnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* owner */ + Oid dictowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* dictionary's template */ + Oid dicttemplate BKI_LOOKUP(pg_ts_template); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + /* options passed to dict_init() */ + text dictinitoption; +#endif +} FormData_pg_ts_dict; + +typedef FormData_pg_ts_dict *Form_pg_ts_dict; + +DECLARE_TOAST(pg_ts_dict, 4169, 4170); + +DECLARE_UNIQUE_INDEX(pg_ts_dict_dictname_index, 3604, TSDictionaryNameNspIndexId, on pg_ts_dict using btree(dictname name_ops, dictnamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_ts_dict_oid_index, 3605, TSDictionaryOidIndexId, on pg_ts_dict using btree(oid oid_ops)); + +#endif /* PG_TS_DICT_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_dict_d.h b/install/include/postgresql/server/catalog/pg_ts_dict_d.h new file mode 100644 index 00000000000..c504853db0a --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_dict_d.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_dict_d.h + * Macro definitions for pg_ts_dict + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_DICT_D_H +#define PG_TS_DICT_D_H + +#define TSDictionaryRelationId 3600 +#define TSDictionaryNameNspIndexId 3604 +#define TSDictionaryOidIndexId 3605 + +#define Anum_pg_ts_dict_oid 1 +#define Anum_pg_ts_dict_dictname 2 +#define Anum_pg_ts_dict_dictnamespace 3 +#define Anum_pg_ts_dict_dictowner 4 +#define Anum_pg_ts_dict_dicttemplate 5 +#define Anum_pg_ts_dict_dictinitoption 6 + +#define Natts_pg_ts_dict 6 + + +#endif /* PG_TS_DICT_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_parser.h b/install/include/postgresql/server/catalog/pg_ts_parser.h new file mode 100644 index 00000000000..283de252b46 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_parser.h @@ -0,0 +1,60 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_parser.h + * definition of the "text search parser" system catalog (pg_ts_parser) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_ts_parser.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_PARSER_H +#define PG_TS_PARSER_H + +#include "catalog/genbki.h" +#include "catalog/pg_ts_parser_d.h" + +/* ---------------- + * pg_ts_parser definition. cpp turns this into + * typedef struct FormData_pg_ts_parser + * ---------------- + */ +CATALOG(pg_ts_parser,3601,TSParserRelationId) +{ + Oid oid; /* oid */ + + /* parser's name */ + NameData prsname; + + /* name space */ + Oid prsnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* init parsing session */ + regproc prsstart BKI_LOOKUP(pg_proc); + + /* return next token */ + regproc prstoken BKI_LOOKUP(pg_proc); + + /* finalize parsing session */ + regproc prsend BKI_LOOKUP(pg_proc); + + /* return data for headline creation */ + regproc prsheadline BKI_LOOKUP_OPT(pg_proc); + + /* return descriptions of lexeme's types */ + regproc prslextype BKI_LOOKUP(pg_proc); +} FormData_pg_ts_parser; + +typedef FormData_pg_ts_parser *Form_pg_ts_parser; + +DECLARE_UNIQUE_INDEX(pg_ts_parser_prsname_index, 3606, TSParserNameNspIndexId, on pg_ts_parser using btree(prsname name_ops, prsnamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_ts_parser_oid_index, 3607, TSParserOidIndexId, on pg_ts_parser using btree(oid oid_ops)); + +#endif /* PG_TS_PARSER_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_parser_d.h b/install/include/postgresql/server/catalog/pg_ts_parser_d.h new file mode 100644 index 00000000000..ff7d4638a46 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_parser_d.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_parser_d.h + * Macro definitions for pg_ts_parser + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_PARSER_D_H +#define PG_TS_PARSER_D_H + +#define TSParserRelationId 3601 +#define TSParserNameNspIndexId 3606 +#define TSParserOidIndexId 3607 + +#define Anum_pg_ts_parser_oid 1 +#define Anum_pg_ts_parser_prsname 2 +#define Anum_pg_ts_parser_prsnamespace 3 +#define Anum_pg_ts_parser_prsstart 4 +#define Anum_pg_ts_parser_prstoken 5 +#define Anum_pg_ts_parser_prsend 6 +#define Anum_pg_ts_parser_prsheadline 7 +#define Anum_pg_ts_parser_prslextype 8 + +#define Natts_pg_ts_parser 8 + + +#endif /* PG_TS_PARSER_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_template.h b/install/include/postgresql/server/catalog/pg_ts_template.h new file mode 100644 index 00000000000..f4e510c8f91 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_template.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_template.h + * definition of the "text search template" system catalog (pg_ts_template) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_ts_template.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_TEMPLATE_H +#define PG_TS_TEMPLATE_H + +#include "catalog/genbki.h" +#include "catalog/pg_ts_template_d.h" + +/* ---------------- + * pg_ts_template definition. cpp turns this into + * typedef struct FormData_pg_ts_template + * ---------------- + */ +CATALOG(pg_ts_template,3764,TSTemplateRelationId) +{ + Oid oid; /* oid */ + + /* template name */ + NameData tmplname; + + /* name space */ + Oid tmplnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* initialization method of dict (may be 0) */ + regproc tmplinit BKI_LOOKUP_OPT(pg_proc); + + /* base method of dictionary */ + regproc tmpllexize BKI_LOOKUP(pg_proc); +} FormData_pg_ts_template; + +typedef FormData_pg_ts_template *Form_pg_ts_template; + +DECLARE_UNIQUE_INDEX(pg_ts_template_tmplname_index, 3766, TSTemplateNameNspIndexId, on pg_ts_template using btree(tmplname name_ops, tmplnamespace oid_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_ts_template_oid_index, 3767, TSTemplateOidIndexId, on pg_ts_template using btree(oid oid_ops)); + +#endif /* PG_TS_TEMPLATE_H */ diff --git a/install/include/postgresql/server/catalog/pg_ts_template_d.h b/install/include/postgresql/server/catalog/pg_ts_template_d.h new file mode 100644 index 00000000000..e32b88a61b4 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_ts_template_d.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * pg_ts_template_d.h + * Macro definitions for pg_ts_template + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TS_TEMPLATE_D_H +#define PG_TS_TEMPLATE_D_H + +#define TSTemplateRelationId 3764 +#define TSTemplateNameNspIndexId 3766 +#define TSTemplateOidIndexId 3767 + +#define Anum_pg_ts_template_oid 1 +#define Anum_pg_ts_template_tmplname 2 +#define Anum_pg_ts_template_tmplnamespace 3 +#define Anum_pg_ts_template_tmplinit 4 +#define Anum_pg_ts_template_tmpllexize 5 + +#define Natts_pg_ts_template 5 + + +#endif /* PG_TS_TEMPLATE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_type.h b/install/include/postgresql/server/catalog/pg_type.h new file mode 100644 index 00000000000..519e570c8ce --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_type.h @@ -0,0 +1,404 @@ +/*------------------------------------------------------------------------- + * + * pg_type.h + * definition of the "type" system catalog (pg_type) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_type.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TYPE_H +#define PG_TYPE_H + +#include "catalog/genbki.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_type_d.h" +#include "nodes/nodes.h" + +/* ---------------- + * pg_type definition. cpp turns this into + * typedef struct FormData_pg_type + * + * Some of the values in a pg_type instance are copied into + * pg_attribute instances. Some parts of Postgres use the pg_type copy, + * while others use the pg_attribute copy, so they must match. + * See struct FormData_pg_attribute for details. + * ---------------- + */ +CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelation_Rowtype_Id) BKI_SCHEMA_MACRO +{ + Oid oid; /* oid */ + + /* type name */ + NameData typname; + + /* OID of namespace containing this type */ + Oid typnamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* type owner */ + Oid typowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* + * For a fixed-size type, typlen is the number of bytes we use to + * represent a value of this type, e.g. 4 for an int4. But for a + * variable-length type, typlen is negative. We use -1 to indicate a + * "varlena" type (one that has a length word), -2 to indicate a + * null-terminated C string. + */ + int16 typlen BKI_ARRAY_DEFAULT(-1); + + /* + * typbyval determines whether internal Postgres routines pass a value of + * this type by value or by reference. typbyval had better be false if + * the length is not 1, 2, or 4 (or 8 on 8-byte-Datum machines). + * Variable-length types are always passed by reference. Note that + * typbyval can be false even if the length would allow pass-by-value; for + * example, type macaddr8 is pass-by-ref even when Datum is 8 bytes. + */ + bool typbyval BKI_ARRAY_DEFAULT(f); + + /* + * typtype is 'b' for a base type, 'c' for a composite type (e.g., a + * table's rowtype), 'd' for a domain, 'e' for an enum type, 'p' for a + * pseudo-type, or 'r' for a range type. (Use the TYPTYPE macros below.) + * + * If typtype is 'c', typrelid is the OID of the class' entry in pg_class. + */ + char typtype BKI_DEFAULT(b) BKI_ARRAY_DEFAULT(b); + + /* + * typcategory and typispreferred help the parser distinguish preferred + * and non-preferred coercions. The category can be any single ASCII + * character (but not \0). The categories used for built-in types are + * identified by the TYPCATEGORY macros below. + */ + + /* arbitrary type classification */ + char typcategory BKI_ARRAY_DEFAULT(A); + + /* is type "preferred" within its category? */ + bool typispreferred BKI_DEFAULT(f) BKI_ARRAY_DEFAULT(f); + + /* + * If typisdefined is false, the entry is only a placeholder (forward + * reference). We know the type's name and owner, but not yet anything + * else about it. + */ + bool typisdefined BKI_DEFAULT(t); + + /* delimiter for arrays of this type */ + char typdelim BKI_DEFAULT(','); + + /* associated pg_class OID if a composite type, else 0 */ + Oid typrelid BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP_OPT(pg_class); + + /* + * Type-specific subscripting handler. If typsubscript is 0, it means + * that this type doesn't support subscripting. Note that various parts + * of the system deem types to be "true" array types only if their + * typsubscript is array_subscript_handler. + */ + regproc typsubscript BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_subscript_handler) BKI_LOOKUP_OPT(pg_proc); + + /* + * If typelem is not 0 then it identifies another row in pg_type, defining + * the type yielded by subscripting. This should be 0 if typsubscript is + * 0. However, it can be 0 when typsubscript isn't 0, 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. + */ + Oid typelem BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); + + /* + * If there is a "true" array type having this type as element type, + * typarray links to it. Zero if no associated "true" array type. + */ + Oid typarray BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); + + /* + * I/O conversion procedures for the datatype. + */ + + /* text format (required) */ + regproc typinput BKI_ARRAY_DEFAULT(array_in) BKI_LOOKUP(pg_proc); + regproc typoutput BKI_ARRAY_DEFAULT(array_out) BKI_LOOKUP(pg_proc); + + /* binary format (optional) */ + regproc typreceive BKI_ARRAY_DEFAULT(array_recv) BKI_LOOKUP_OPT(pg_proc); + regproc typsend BKI_ARRAY_DEFAULT(array_send) BKI_LOOKUP_OPT(pg_proc); + + /* + * I/O functions for optional type modifiers. + */ + regproc typmodin BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + regproc typmodout BKI_DEFAULT(-) BKI_LOOKUP_OPT(pg_proc); + + /* + * Custom ANALYZE procedure for the datatype (0 selects the default). + */ + regproc typanalyze BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_typanalyze) BKI_LOOKUP_OPT(pg_proc); + + /* ---------------- + * 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 Postgres. 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. + * + * 'c' = CHAR alignment, ie 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). + * (Use the TYPALIGN macros below for these.) + * + * See include/access/tupmacs.h for the macros that compute these + * alignment requirements. Note also that we allow the nominal alignment + * to be violated when storing "packed" varlenas; the TOAST mechanism + * takes care of hiding that from most code. + * + * NOTE: for 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 field in a struct representing a table row. + * ---------------- + */ + char typalign; + + /* ---------------- + * typstorage tells if the type is prepared for toasting and what + * the default strategy for attributes of this type should be. + * + * 'p' PLAIN type not prepared for toasting + * 'e' EXTERNAL external storage possible, don't try to compress + * 'x' EXTENDED try to compress and store external if required + * 'm' MAIN like 'x' but try to keep in main tuple + * (Use the TYPSTORAGE macros below for these.) + * + * Note that 'm' fields can also be moved out to secondary storage, + * but only as a last resort ('e' and 'x' fields are moved first). + * ---------------- + */ + char typstorage BKI_DEFAULT(p) BKI_ARRAY_DEFAULT(x); + + /* + * This flag represents a "NOT NULL" constraint against this datatype. + * + * If true, the attnotnull column for a corresponding table column using + * this datatype will always enforce the NOT NULL constraint. + * + * Used primarily for domain types. + */ + bool typnotnull BKI_DEFAULT(f); + + /* + * Domains use typbasetype to show the base (or domain) type that the + * domain is based on. Zero if the type is not a domain. + */ + Oid typbasetype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); + + /* + * 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. + */ + int32 typtypmod BKI_DEFAULT(-1); + + /* + * typndims is the declared number of dimensions for an array domain type + * (i.e., typbasetype is an array type). Otherwise zero. + */ + int32 typndims BKI_DEFAULT(0); + + /* + * Collation: 0 if type cannot use collations, nonzero (typically + * DEFAULT_COLLATION_OID) for collatable base types, possibly some other + * OID for domains over collatable types + */ + Oid typcollation BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_collation); + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + + /* + * If typdefaultbin is not NULL, it is the nodeToString representation of + * a default expression for the type. Currently this is only used for + * domains. + */ + pg_node_tree typdefaultbin BKI_DEFAULT(_null_) BKI_ARRAY_DEFAULT(_null_); + + /* + * 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 may be fed + * to the type's input converter to produce a constant. + */ + text typdefault BKI_DEFAULT(_null_) BKI_ARRAY_DEFAULT(_null_); + + /* + * Access permissions + */ + aclitem typacl[1] BKI_DEFAULT(_null_); +#endif +} FormData_pg_type; + +/* ---------------- + * Form_pg_type corresponds to a pointer to a row with + * the format of pg_type relation. + * ---------------- + */ +typedef FormData_pg_type *Form_pg_type; + +DECLARE_TOAST(pg_type, 4171, 4172); + +DECLARE_UNIQUE_INDEX_PKEY(pg_type_oid_index, 2703, TypeOidIndexId, on pg_type using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index, 2704, TypeNameNspIndexId, on pg_type using btree(typname name_ops, typnamespace oid_ops)); + +#ifdef EXPOSE_TO_CLIENT_CODE + +/* + * macros for values of poor-mans-enumerated-type columns + */ +#define TYPTYPE_BASE 'b' /* base type (ordinary scalar type) */ +#define TYPTYPE_COMPOSITE 'c' /* composite (e.g., table's rowtype) */ +#define TYPTYPE_DOMAIN 'd' /* domain over another type */ +#define TYPTYPE_ENUM 'e' /* enumerated type */ +#define TYPTYPE_MULTIRANGE 'm' /* multirange type */ +#define TYPTYPE_PSEUDO 'p' /* pseudo-type */ +#define TYPTYPE_RANGE 'r' /* range type */ + +#define TYPCATEGORY_INVALID '\0' /* not an allowed category */ +#define TYPCATEGORY_ARRAY 'A' +#define TYPCATEGORY_BOOLEAN 'B' +#define TYPCATEGORY_COMPOSITE 'C' +#define TYPCATEGORY_DATETIME 'D' +#define TYPCATEGORY_ENUM 'E' +#define TYPCATEGORY_GEOMETRIC 'G' +#define TYPCATEGORY_NETWORK 'I' /* think INET */ +#define TYPCATEGORY_NUMERIC 'N' +#define TYPCATEGORY_PSEUDOTYPE 'P' +#define TYPCATEGORY_RANGE 'R' +#define TYPCATEGORY_STRING 'S' +#define TYPCATEGORY_TIMESPAN 'T' +#define TYPCATEGORY_USER 'U' +#define TYPCATEGORY_BITSTRING 'V' /* er ... "varbit"? */ +#define TYPCATEGORY_UNKNOWN 'X' +#define TYPCATEGORY_INTERNAL 'Z' + +#define TYPALIGN_CHAR 'c' /* char alignment (i.e. unaligned) */ +#define TYPALIGN_SHORT 's' /* short alignment (typically 2 bytes) */ +#define TYPALIGN_INT 'i' /* int alignment (typically 4 bytes) */ +#define TYPALIGN_DOUBLE 'd' /* double alignment (often 8 bytes) */ + +#define TYPSTORAGE_PLAIN 'p' /* type not prepared for toasting */ +#define TYPSTORAGE_EXTERNAL 'e' /* toastable, don't try to compress */ +#define TYPSTORAGE_EXTENDED 'x' /* fully toastable */ +#define TYPSTORAGE_MAIN 'm' /* like 'x' but try to store inline */ + +/* Is a type OID a polymorphic pseudotype? (Beware of multiple evaluation) */ +#define IsPolymorphicType(typid) \ + (IsPolymorphicTypeFamily1(typid) || \ + IsPolymorphicTypeFamily2(typid)) + +/* Code not part of polymorphic type resolution should not use these macros: */ +#define IsPolymorphicTypeFamily1(typid) \ + ((typid) == ANYELEMENTOID || \ + (typid) == ANYARRAYOID || \ + (typid) == ANYNONARRAYOID || \ + (typid) == ANYENUMOID || \ + (typid) == ANYRANGEOID || \ + (typid) == ANYMULTIRANGEOID) + +#define IsPolymorphicTypeFamily2(typid) \ + ((typid) == ANYCOMPATIBLEOID || \ + (typid) == ANYCOMPATIBLEARRAYOID || \ + (typid) == ANYCOMPATIBLENONARRAYOID || \ + (typid) == ANYCOMPATIBLERANGEOID || \ + (typid) == ANYCOMPATIBLEMULTIRANGEOID) + +/* Is this a "true" array type? (Requires fmgroids.h) */ +#define IsTrueArrayType(typeForm) \ + (OidIsValid((typeForm)->typelem) && \ + (typeForm)->typsubscript == F_ARRAY_SUBSCRIPT_HANDLER) + +/* + * Backwards compatibility for ancient random spellings of pg_type OID macros. + * Don't use these names in new code. + */ +#define CASHOID MONEYOID +#define LSNOID PG_LSNOID + +#endif /* EXPOSE_TO_CLIENT_CODE */ + + +extern ObjectAddress TypeShellMake(const char *typeName, + Oid typeNamespace, + Oid ownerId); + +extern ObjectAddress TypeCreate(Oid newTypeOid, + const char *typeName, + Oid typeNamespace, + Oid relationOid, + char relationKind, + Oid ownerId, + int16 internalSize, + char typeType, + char typeCategory, + bool typePreferred, + char typDelim, + Oid inputProcedure, + Oid outputProcedure, + Oid receiveProcedure, + Oid sendProcedure, + Oid typmodinProcedure, + Oid typmodoutProcedure, + Oid analyzeProcedure, + Oid subscriptProcedure, + Oid elementType, + bool isImplicitArray, + Oid arrayType, + Oid baseType, + const char *defaultTypeValue, + char *defaultTypeBin, + bool passedByValue, + char alignment, + char storage, + int32 typeMod, + int32 typNDims, + bool typeNotNull, + Oid typeCollation); + +extern void GenerateTypeDependencies(HeapTuple typeTuple, + Relation typeCatalog, + Node *defaultExpr, + void *typacl, + char relationKind, /* only for relation + * rowtypes */ + bool isImplicitArray, + bool isDependentType, + bool makeExtensionDep, + bool rebuild); + +extern void RenameTypeInternal(Oid typeOid, const char *newTypeName, + Oid typeNamespace); + +extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace); + +extern bool moveArrayTypeName(Oid typeOid, const char *typeName, + Oid typeNamespace); + +extern char *makeMultirangeTypeName(const char *rangeTypeName, + Oid typeNamespace); + +#endif /* PG_TYPE_H */ diff --git a/install/include/postgresql/server/catalog/pg_type_d.h b/install/include/postgresql/server/catalog/pg_type_d.h new file mode 100644 index 00000000000..d0f8d034a94 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_type_d.h @@ -0,0 +1,324 @@ +/*------------------------------------------------------------------------- + * + * pg_type_d.h + * Macro definitions for pg_type + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TYPE_D_H +#define PG_TYPE_D_H + +#define TypeRelationId 1247 +#define TypeRelation_Rowtype_Id 71 +#define TypeOidIndexId 2703 +#define TypeNameNspIndexId 2704 + +#define Anum_pg_type_oid 1 +#define Anum_pg_type_typname 2 +#define Anum_pg_type_typnamespace 3 +#define Anum_pg_type_typowner 4 +#define Anum_pg_type_typlen 5 +#define Anum_pg_type_typbyval 6 +#define Anum_pg_type_typtype 7 +#define Anum_pg_type_typcategory 8 +#define Anum_pg_type_typispreferred 9 +#define Anum_pg_type_typisdefined 10 +#define Anum_pg_type_typdelim 11 +#define Anum_pg_type_typrelid 12 +#define Anum_pg_type_typsubscript 13 +#define Anum_pg_type_typelem 14 +#define Anum_pg_type_typarray 15 +#define Anum_pg_type_typinput 16 +#define Anum_pg_type_typoutput 17 +#define Anum_pg_type_typreceive 18 +#define Anum_pg_type_typsend 19 +#define Anum_pg_type_typmodin 20 +#define Anum_pg_type_typmodout 21 +#define Anum_pg_type_typanalyze 22 +#define Anum_pg_type_typalign 23 +#define Anum_pg_type_typstorage 24 +#define Anum_pg_type_typnotnull 25 +#define Anum_pg_type_typbasetype 26 +#define Anum_pg_type_typtypmod 27 +#define Anum_pg_type_typndims 28 +#define Anum_pg_type_typcollation 29 +#define Anum_pg_type_typdefaultbin 30 +#define Anum_pg_type_typdefault 31 +#define Anum_pg_type_typacl 32 + +#define Natts_pg_type 32 + + +/* + * macros for values of poor-mans-enumerated-type columns + */ +#define TYPTYPE_BASE 'b' /* base type (ordinary scalar type) */ +#define TYPTYPE_COMPOSITE 'c' /* composite (e.g., table's rowtype) */ +#define TYPTYPE_DOMAIN 'd' /* domain over another type */ +#define TYPTYPE_ENUM 'e' /* enumerated type */ +#define TYPTYPE_MULTIRANGE 'm' /* multirange type */ +#define TYPTYPE_PSEUDO 'p' /* pseudo-type */ +#define TYPTYPE_RANGE 'r' /* range type */ + +#define TYPCATEGORY_INVALID '\0' /* not an allowed category */ +#define TYPCATEGORY_ARRAY 'A' +#define TYPCATEGORY_BOOLEAN 'B' +#define TYPCATEGORY_COMPOSITE 'C' +#define TYPCATEGORY_DATETIME 'D' +#define TYPCATEGORY_ENUM 'E' +#define TYPCATEGORY_GEOMETRIC 'G' +#define TYPCATEGORY_NETWORK 'I' /* think INET */ +#define TYPCATEGORY_NUMERIC 'N' +#define TYPCATEGORY_PSEUDOTYPE 'P' +#define TYPCATEGORY_RANGE 'R' +#define TYPCATEGORY_STRING 'S' +#define TYPCATEGORY_TIMESPAN 'T' +#define TYPCATEGORY_USER 'U' +#define TYPCATEGORY_BITSTRING 'V' /* er ... "varbit"? */ +#define TYPCATEGORY_UNKNOWN 'X' +#define TYPCATEGORY_INTERNAL 'Z' + +#define TYPALIGN_CHAR 'c' /* char alignment (i.e. unaligned) */ +#define TYPALIGN_SHORT 's' /* short alignment (typically 2 bytes) */ +#define TYPALIGN_INT 'i' /* int alignment (typically 4 bytes) */ +#define TYPALIGN_DOUBLE 'd' /* double alignment (often 8 bytes) */ + +#define TYPSTORAGE_PLAIN 'p' /* type not prepared for toasting */ +#define TYPSTORAGE_EXTERNAL 'e' /* toastable, don't try to compress */ +#define TYPSTORAGE_EXTENDED 'x' /* fully toastable */ +#define TYPSTORAGE_MAIN 'm' /* like 'x' but try to store inline */ + +/* Is a type OID a polymorphic pseudotype? (Beware of multiple evaluation) */ +#define IsPolymorphicType(typid) \ + (IsPolymorphicTypeFamily1(typid) || \ + IsPolymorphicTypeFamily2(typid)) + +/* Code not part of polymorphic type resolution should not use these macros: */ +#define IsPolymorphicTypeFamily1(typid) \ + ((typid) == ANYELEMENTOID || \ + (typid) == ANYARRAYOID || \ + (typid) == ANYNONARRAYOID || \ + (typid) == ANYENUMOID || \ + (typid) == ANYRANGEOID || \ + (typid) == ANYMULTIRANGEOID) + +#define IsPolymorphicTypeFamily2(typid) \ + ((typid) == ANYCOMPATIBLEOID || \ + (typid) == ANYCOMPATIBLEARRAYOID || \ + (typid) == ANYCOMPATIBLENONARRAYOID || \ + (typid) == ANYCOMPATIBLERANGEOID || \ + (typid) == ANYCOMPATIBLEMULTIRANGEOID) + +/* Is this a "true" array type? (Requires fmgroids.h) */ +#define IsTrueArrayType(typeForm) \ + (OidIsValid((typeForm)->typelem) && \ + (typeForm)->typsubscript == F_ARRAY_SUBSCRIPT_HANDLER) + +/* + * Backwards compatibility for ancient random spellings of pg_type OID macros. + * Don't use these names in new code. + */ +#define CASHOID MONEYOID +#define LSNOID PG_LSNOID + +#define BOOLOID 16 +#define BYTEAOID 17 +#define CHAROID 18 +#define NAMEOID 19 +#define INT8OID 20 +#define INT2OID 21 +#define INT2VECTOROID 22 +#define INT4OID 23 +#define REGPROCOID 24 +#define TEXTOID 25 +#define OIDOID 26 +#define TIDOID 27 +#define XIDOID 28 +#define CIDOID 29 +#define OIDVECTOROID 30 +#define JSONOID 114 +#define XMLOID 142 +#define PG_NODE_TREEOID 194 +#define PG_NDISTINCTOID 3361 +#define PG_DEPENDENCIESOID 3402 +#define PG_MCV_LISTOID 5017 +#define PG_DDL_COMMANDOID 32 +#define XID8OID 5069 +#define POINTOID 600 +#define LSEGOID 601 +#define PATHOID 602 +#define BOXOID 603 +#define POLYGONOID 604 +#define LINEOID 628 +#define FLOAT4OID 700 +#define FLOAT8OID 701 +#define UNKNOWNOID 705 +#define CIRCLEOID 718 +#define MONEYOID 790 +#define MACADDROID 829 +#define INETOID 869 +#define CIDROID 650 +#define MACADDR8OID 774 +#define ACLITEMOID 1033 +#define BPCHAROID 1042 +#define VARCHAROID 1043 +#define DATEOID 1082 +#define TIMEOID 1083 +#define TIMESTAMPOID 1114 +#define TIMESTAMPTZOID 1184 +#define INTERVALOID 1186 +#define TIMETZOID 1266 +#define BITOID 1560 +#define VARBITOID 1562 +#define NUMERICOID 1700 +#define REFCURSOROID 1790 +#define REGPROCEDUREOID 2202 +#define REGOPEROID 2203 +#define REGOPERATOROID 2204 +#define REGCLASSOID 2205 +#define REGCOLLATIONOID 4191 +#define REGTYPEOID 2206 +#define REGROLEOID 4096 +#define REGNAMESPACEOID 4089 +#define UUIDOID 2950 +#define PG_LSNOID 3220 +#define TSVECTOROID 3614 +#define GTSVECTOROID 3642 +#define TSQUERYOID 3615 +#define REGCONFIGOID 3734 +#define REGDICTIONARYOID 3769 +#define JSONBOID 3802 +#define JSONPATHOID 4072 +#define TXID_SNAPSHOTOID 2970 +#define PG_SNAPSHOTOID 5038 +#define INT4RANGEOID 3904 +#define NUMRANGEOID 3906 +#define TSRANGEOID 3908 +#define TSTZRANGEOID 3910 +#define DATERANGEOID 3912 +#define INT8RANGEOID 3926 +#define INT4MULTIRANGEOID 4451 +#define NUMMULTIRANGEOID 4532 +#define TSMULTIRANGEOID 4533 +#define TSTZMULTIRANGEOID 4534 +#define DATEMULTIRANGEOID 4535 +#define INT8MULTIRANGEOID 4536 +#define RECORDOID 2249 +#define RECORDARRAYOID 2287 +#define CSTRINGOID 2275 +#define ANYOID 2276 +#define ANYARRAYOID 2277 +#define VOIDOID 2278 +#define TRIGGEROID 2279 +#define EVENT_TRIGGEROID 3838 +#define LANGUAGE_HANDLEROID 2280 +#define INTERNALOID 2281 +#define ANYELEMENTOID 2283 +#define ANYNONARRAYOID 2776 +#define ANYENUMOID 3500 +#define FDW_HANDLEROID 3115 +#define INDEX_AM_HANDLEROID 325 +#define TSM_HANDLEROID 3310 +#define TABLE_AM_HANDLEROID 269 +#define ANYRANGEOID 3831 +#define ANYCOMPATIBLEOID 5077 +#define ANYCOMPATIBLEARRAYOID 5078 +#define ANYCOMPATIBLENONARRAYOID 5079 +#define ANYCOMPATIBLERANGEOID 5080 +#define ANYMULTIRANGEOID 4537 +#define ANYCOMPATIBLEMULTIRANGEOID 4538 +#define PG_BRIN_BLOOM_SUMMARYOID 4600 +#define PG_BRIN_MINMAX_MULTI_SUMMARYOID 4601 +#define BOOLARRAYOID 1000 +#define BYTEAARRAYOID 1001 +#define CHARARRAYOID 1002 +#define NAMEARRAYOID 1003 +#define INT8ARRAYOID 1016 +#define INT2ARRAYOID 1005 +#define INT2VECTORARRAYOID 1006 +#define INT4ARRAYOID 1007 +#define REGPROCARRAYOID 1008 +#define TEXTARRAYOID 1009 +#define OIDARRAYOID 1028 +#define TIDARRAYOID 1010 +#define XIDARRAYOID 1011 +#define CIDARRAYOID 1012 +#define OIDVECTORARRAYOID 1013 +#define PG_TYPEARRAYOID 210 +#define PG_ATTRIBUTEARRAYOID 270 +#define PG_PROCARRAYOID 272 +#define PG_CLASSARRAYOID 273 +#define JSONARRAYOID 199 +#define XMLARRAYOID 143 +#define XID8ARRAYOID 271 +#define POINTARRAYOID 1017 +#define LSEGARRAYOID 1018 +#define PATHARRAYOID 1019 +#define BOXARRAYOID 1020 +#define POLYGONARRAYOID 1027 +#define LINEARRAYOID 629 +#define FLOAT4ARRAYOID 1021 +#define FLOAT8ARRAYOID 1022 +#define CIRCLEARRAYOID 719 +#define MONEYARRAYOID 791 +#define MACADDRARRAYOID 1040 +#define INETARRAYOID 1041 +#define CIDRARRAYOID 651 +#define MACADDR8ARRAYOID 775 +#define ACLITEMARRAYOID 1034 +#define BPCHARARRAYOID 1014 +#define VARCHARARRAYOID 1015 +#define DATEARRAYOID 1182 +#define TIMEARRAYOID 1183 +#define TIMESTAMPARRAYOID 1115 +#define TIMESTAMPTZARRAYOID 1185 +#define INTERVALARRAYOID 1187 +#define TIMETZARRAYOID 1270 +#define BITARRAYOID 1561 +#define VARBITARRAYOID 1563 +#define NUMERICARRAYOID 1231 +#define REFCURSORARRAYOID 2201 +#define REGPROCEDUREARRAYOID 2207 +#define REGOPERARRAYOID 2208 +#define REGOPERATORARRAYOID 2209 +#define REGCLASSARRAYOID 2210 +#define REGCOLLATIONARRAYOID 4192 +#define REGTYPEARRAYOID 2211 +#define REGROLEARRAYOID 4097 +#define REGNAMESPACEARRAYOID 4090 +#define UUIDARRAYOID 2951 +#define PG_LSNARRAYOID 3221 +#define TSVECTORARRAYOID 3643 +#define GTSVECTORARRAYOID 3644 +#define TSQUERYARRAYOID 3645 +#define REGCONFIGARRAYOID 3735 +#define REGDICTIONARYARRAYOID 3770 +#define JSONBARRAYOID 3807 +#define JSONPATHARRAYOID 4073 +#define TXID_SNAPSHOTARRAYOID 2949 +#define PG_SNAPSHOTARRAYOID 5039 +#define INT4RANGEARRAYOID 3905 +#define NUMRANGEARRAYOID 3907 +#define TSRANGEARRAYOID 3909 +#define TSTZRANGEARRAYOID 3911 +#define DATERANGEARRAYOID 3913 +#define INT8RANGEARRAYOID 3927 +#define INT4MULTIRANGEARRAYOID 6150 +#define NUMMULTIRANGEARRAYOID 6151 +#define TSMULTIRANGEARRAYOID 6152 +#define TSTZMULTIRANGEARRAYOID 6153 +#define DATEMULTIRANGEARRAYOID 6155 +#define INT8MULTIRANGEARRAYOID 6157 +#define CSTRINGARRAYOID 1263 + +#endif /* PG_TYPE_D_H */ diff --git a/install/include/postgresql/server/catalog/pg_user_mapping.h b/install/include/postgresql/server/catalog/pg_user_mapping.h new file mode 100644 index 00000000000..528c94a7c4b --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_user_mapping.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * pg_user_mapping.h + * definition of the "user mapping" system catalog (pg_user_mapping) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_user_mapping.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_USER_MAPPING_H +#define PG_USER_MAPPING_H + +#include "catalog/genbki.h" +#include "catalog/pg_user_mapping_d.h" + +/* ---------------- + * pg_user_mapping definition. cpp turns this into + * typedef struct FormData_pg_user_mapping + * ---------------- + */ +CATALOG(pg_user_mapping,1418,UserMappingRelationId) +{ + Oid oid; /* oid */ + + Oid umuser BKI_LOOKUP_OPT(pg_authid); /* Id of the user, + * InvalidOid if PUBLIC is + * wanted */ + Oid umserver BKI_LOOKUP(pg_foreign_server); /* server of this + * mapping */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + text umoptions[1]; /* user mapping options */ +#endif +} FormData_pg_user_mapping; + +/* ---------------- + * Form_pg_user_mapping corresponds to a pointer to a tuple with + * the format of pg_user_mapping relation. + * ---------------- + */ +typedef FormData_pg_user_mapping *Form_pg_user_mapping; + +DECLARE_TOAST(pg_user_mapping, 4173, 4174); + +DECLARE_UNIQUE_INDEX_PKEY(pg_user_mapping_oid_index, 174, UserMappingOidIndexId, on pg_user_mapping using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_user_mapping_user_server_index, 175, UserMappingUserServerIndexId, on pg_user_mapping using btree(umuser oid_ops, umserver oid_ops)); + +#endif /* PG_USER_MAPPING_H */ diff --git a/install/include/postgresql/server/catalog/pg_user_mapping_d.h b/install/include/postgresql/server/catalog/pg_user_mapping_d.h new file mode 100644 index 00000000000..15d2436efd3 --- /dev/null +++ b/install/include/postgresql/server/catalog/pg_user_mapping_d.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * pg_user_mapping_d.h + * Macro definitions for pg_user_mapping + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef PG_USER_MAPPING_D_H +#define PG_USER_MAPPING_D_H + +#define UserMappingRelationId 1418 +#define UserMappingOidIndexId 174 +#define UserMappingUserServerIndexId 175 + +#define Anum_pg_user_mapping_oid 1 +#define Anum_pg_user_mapping_umuser 2 +#define Anum_pg_user_mapping_umserver 3 +#define Anum_pg_user_mapping_umoptions 4 + +#define Natts_pg_user_mapping 4 + + +#endif /* PG_USER_MAPPING_D_H */ diff --git a/install/include/postgresql/server/catalog/schemapg.h b/install/include/postgresql/server/catalog/schemapg.h new file mode 100644 index 00000000000..5c2bd21ed9d --- /dev/null +++ b/install/include/postgresql/server/catalog/schemapg.h @@ -0,0 +1,240 @@ +/*------------------------------------------------------------------------- + * + * schemapg.h + * Schema_pg_xxx macros for use by relcache.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef SCHEMAPG_H +#define SCHEMAPG_H + +#define Schema_pg_proc \ +{ 1255, {"oid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proname"}, 19, NAMEDATALEN, 2, -1, -1, 0, false, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1255, {"pronamespace"}, 26, 4, 3, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proowner"}, 26, 4, 4, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"prolang"}, 26, 4, 5, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"procost"}, 700, 4, 6, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"prorows"}, 700, 4, 7, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"provariadic"}, 26, 4, 8, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"prosupport"}, 24, 4, 9, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"prokind"}, 18, 1, 10, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"prosecdef"}, 16, 1, 11, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proleakproof"}, 16, 1, 12, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proisstrict"}, 16, 1, 13, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proretset"}, 16, 1, 14, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"provolatile"}, 18, 1, 15, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proparallel"}, 18, 1, 16, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"pronargs"}, 21, 2, 17, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"pronargdefaults"}, 21, 2, 18, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"prorettype"}, 26, 4, 19, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proargtypes"}, 30, -1, 20, -1, -1, 1, false, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proallargtypes"}, 1028, -1, 21, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proargmodes"}, 1002, -1, 22, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"proargnames"}, 1009, -1, 23, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1255, {"proargdefaults"}, 194, -1, 24, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1255, {"protrftypes"}, 1028, -1, 25, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1255, {"prosrc"}, 25, -1, 26, -1, -1, 0, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1255, {"probin"}, 25, -1, 27, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1255, {"prosqlbody"}, 194, -1, 28, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1255, {"proconfig"}, 1009, -1, 29, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1255, {"proacl"}, 1034, -1, 30, -1, -1, 1, false, 'd', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 } + +#define Schema_pg_type \ +{ 1247, {"oid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typname"}, 19, NAMEDATALEN, 2, -1, -1, 0, false, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1247, {"typnamespace"}, 26, 4, 3, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typowner"}, 26, 4, 4, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typlen"}, 21, 2, 5, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typbyval"}, 16, 1, 6, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typtype"}, 18, 1, 7, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typcategory"}, 18, 1, 8, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typispreferred"}, 16, 1, 9, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typisdefined"}, 16, 1, 10, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typdelim"}, 18, 1, 11, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typrelid"}, 26, 4, 12, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typsubscript"}, 24, 4, 13, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typelem"}, 26, 4, 14, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typarray"}, 26, 4, 15, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typinput"}, 24, 4, 16, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typoutput"}, 24, 4, 17, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typreceive"}, 24, 4, 18, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typsend"}, 24, 4, 19, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typmodin"}, 24, 4, 20, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typmodout"}, 24, 4, 21, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typanalyze"}, 24, 4, 22, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typalign"}, 18, 1, 23, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typstorage"}, 18, 1, 24, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typnotnull"}, 16, 1, 25, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typbasetype"}, 26, 4, 26, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typtypmod"}, 23, 4, 27, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typndims"}, 23, 4, 28, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typcollation"}, 26, 4, 29, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1247, {"typdefaultbin"}, 194, -1, 30, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1247, {"typdefault"}, 25, -1, 31, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1247, {"typacl"}, 1034, -1, 32, -1, -1, 1, false, 'd', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 } + +#define Schema_pg_attribute \ +{ 1249, {"attrelid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attname"}, 19, NAMEDATALEN, 2, -1, -1, 0, false, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1249, {"atttypid"}, 26, 4, 3, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attlen"}, 21, 2, 4, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attnum"}, 21, 2, 5, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attcacheoff"}, 23, 4, 6, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"atttypmod"}, 23, 4, 7, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attndims"}, 21, 2, 8, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attbyval"}, 16, 1, 9, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attalign"}, 18, 1, 10, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attstorage"}, 18, 1, 11, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attcompression"}, 18, 1, 12, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attnotnull"}, 16, 1, 13, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"atthasdef"}, 16, 1, 14, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"atthasmissing"}, 16, 1, 15, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attidentity"}, 18, 1, 16, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attgenerated"}, 18, 1, 17, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attisdropped"}, 16, 1, 18, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attislocal"}, 16, 1, 19, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attinhcount"}, 21, 2, 20, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attstattarget"}, 21, 2, 21, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attcollation"}, 26, 4, 22, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attacl"}, 1034, -1, 23, -1, -1, 1, false, 'd', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1249, {"attoptions"}, 1009, -1, 24, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1249, {"attfdwoptions"}, 1009, -1, 25, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1249, {"attmissingval"}, 2277, -1, 26, -1, -1, 0, false, 'd', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 } + +#define Schema_pg_class \ +{ 1259, {"oid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relname"}, 19, NAMEDATALEN, 2, -1, -1, 0, false, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1259, {"relnamespace"}, 26, 4, 3, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"reltype"}, 26, 4, 4, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"reloftype"}, 26, 4, 5, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relowner"}, 26, 4, 6, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relam"}, 26, 4, 7, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relfilenode"}, 26, 4, 8, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"reltablespace"}, 26, 4, 9, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relpages"}, 23, 4, 10, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"reltuples"}, 700, 4, 11, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relallvisible"}, 23, 4, 12, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"reltoastrelid"}, 26, 4, 13, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relhasindex"}, 16, 1, 14, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relisshared"}, 16, 1, 15, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relpersistence"}, 18, 1, 16, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relkind"}, 18, 1, 17, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relnatts"}, 21, 2, 18, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relchecks"}, 21, 2, 19, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relhasrules"}, 16, 1, 20, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relhastriggers"}, 16, 1, 21, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relhassubclass"}, 16, 1, 22, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relrowsecurity"}, 16, 1, 23, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relforcerowsecurity"}, 16, 1, 24, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relispopulated"}, 16, 1, 25, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relreplident"}, 18, 1, 26, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relispartition"}, 16, 1, 27, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relrewrite"}, 26, 4, 28, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relfrozenxid"}, 28, 4, 29, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relminmxid"}, 28, 4, 30, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"relacl"}, 1034, -1, 31, -1, -1, 1, false, 'd', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1259, {"reloptions"}, 1009, -1, 32, -1, -1, 1, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1259, {"relpartbound"}, 194, -1, 33, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 } + +#define Schema_pg_index \ +{ 2610, {"indexrelid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indrelid"}, 26, 4, 2, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indnatts"}, 21, 2, 3, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indnkeyatts"}, 21, 2, 4, -1, -1, 0, true, 's', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indisunique"}, 16, 1, 5, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indnullsnotdistinct"}, 16, 1, 6, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indisprimary"}, 16, 1, 7, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indisexclusion"}, 16, 1, 8, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indimmediate"}, 16, 1, 9, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indisclustered"}, 16, 1, 10, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indisvalid"}, 16, 1, 11, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indcheckxmin"}, 16, 1, 12, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indisready"}, 16, 1, 13, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indislive"}, 16, 1, 14, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indisreplident"}, 16, 1, 15, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indkey"}, 22, -1, 16, -1, -1, 1, false, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indcollation"}, 30, -1, 17, -1, -1, 1, false, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indclass"}, 30, -1, 18, -1, -1, 1, false, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indoption"}, 22, -1, 19, -1, -1, 1, false, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 2610, {"indexprs"}, 194, -1, 20, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 2610, {"indpred"}, 194, -1, 21, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 } + +#define Schema_pg_database \ +{ 1262, {"oid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datname"}, 19, NAMEDATALEN, 2, -1, -1, 0, false, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1262, {"datdba"}, 26, 4, 3, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"encoding"}, 23, 4, 4, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datlocprovider"}, 18, 1, 5, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datistemplate"}, 16, 1, 6, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datallowconn"}, 16, 1, 7, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datconnlimit"}, 23, 4, 8, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datfrozenxid"}, 28, 4, 9, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datminmxid"}, 28, 4, 10, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"dattablespace"}, 26, 4, 11, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1262, {"datcollate"}, 25, -1, 12, -1, -1, 0, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1262, {"datctype"}, 25, -1, 13, -1, -1, 0, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1262, {"daticulocale"}, 25, -1, 14, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1262, {"daticurules"}, 25, -1, 15, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1262, {"datcollversion"}, 25, -1, 16, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1262, {"datacl"}, 1034, -1, 17, -1, -1, 1, false, 'd', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 } + +#define Schema_pg_authid \ +{ 1260, {"oid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolname"}, 19, NAMEDATALEN, 2, -1, -1, 0, false, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1260, {"rolsuper"}, 16, 1, 3, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolinherit"}, 16, 1, 4, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolcreaterole"}, 16, 1, 5, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolcreatedb"}, 16, 1, 6, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolcanlogin"}, 16, 1, 7, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolreplication"}, 16, 1, 8, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolbypassrls"}, 16, 1, 9, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolconnlimit"}, 23, 4, 10, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1260, {"rolpassword"}, 25, -1, 11, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 1260, {"rolvaliduntil"}, 1184, 8, 12, -1, -1, 0, FLOAT8PASSBYVAL, 'd', 'p', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 0 } + +#define Schema_pg_auth_members \ +{ 1261, {"oid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1261, {"roleid"}, 26, 4, 2, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1261, {"member"}, 26, 4, 3, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1261, {"grantor"}, 26, 4, 4, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1261, {"admin_option"}, 16, 1, 5, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1261, {"inherit_option"}, 16, 1, 6, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 1261, {"set_option"}, 16, 1, 7, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 } + +#define Schema_pg_shseclabel \ +{ 3592, {"objoid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 3592, {"classoid"}, 26, 4, 2, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 3592, {"provider"}, 25, -1, 3, -1, -1, 0, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 3592, {"label"}, 25, -1, 4, -1, -1, 0, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 } + +#define Schema_pg_subscription \ +{ 6100, {"oid"}, 26, 4, 1, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subdbid"}, 26, 4, 2, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subskiplsn"}, 3220, 8, 3, -1, -1, 0, FLOAT8PASSBYVAL, 'd', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subname"}, 19, NAMEDATALEN, 4, -1, -1, 0, false, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 6100, {"subowner"}, 26, 4, 5, -1, -1, 0, true, 'i', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subenabled"}, 16, 1, 6, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subbinary"}, 16, 1, 7, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"substream"}, 18, 1, 8, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subtwophasestate"}, 18, 1, 9, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subdisableonerr"}, 16, 1, 10, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subpasswordrequired"}, 16, 1, 11, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subrunasowner"}, 16, 1, 12, -1, -1, 0, true, 'c', 'p', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 0 }, \ +{ 6100, {"subconninfo"}, 25, -1, 13, -1, -1, 0, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 6100, {"subslotname"}, 19, NAMEDATALEN, 14, -1, -1, 0, false, 'c', 'p', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 6100, {"subsynccommit"}, 25, -1, 15, -1, -1, 0, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 6100, {"subpublications"}, 1009, -1, 16, -1, -1, 1, false, 'i', 'x', '\0', true, false, false, '\0', '\0', false, true, 0, -1, 950 }, \ +{ 6100, {"suborigin"}, 25, -1, 17, -1, -1, 0, false, 'i', 'x', '\0', false, false, false, '\0', '\0', false, true, 0, -1, 950 } + +#endif /* SCHEMAPG_H */ diff --git a/install/include/postgresql/server/catalog/storage.h b/install/include/postgresql/server/catalog/storage.h new file mode 100644 index 00000000000..45a3c7835cb --- /dev/null +++ b/install/include/postgresql/server/catalog/storage.h @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------- + * + * storage.h + * prototypes for functions in backend/catalog/storage.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/storage.h + * + *------------------------------------------------------------------------- + */ +#ifndef STORAGE_H +#define STORAGE_H + +#include "storage/block.h" +#include "storage/relfilelocator.h" +#include "storage/smgr.h" +#include "utils/relcache.h" + +/* GUC variables */ +extern PGDLLIMPORT int wal_skip_threshold; + +extern SMgrRelation RelationCreateStorage(RelFileLocator rlocator, + char relpersistence, + bool register_delete); +extern void RelationDropStorage(Relation rel); +extern void RelationPreserveStorage(RelFileLocator rlocator, bool atCommit); +extern void RelationPreTruncate(Relation rel); +extern void RelationTruncate(Relation rel, BlockNumber nblocks); +extern void RelationCopyStorage(SMgrRelation src, SMgrRelation dst, + ForkNumber forkNum, char relpersistence); +extern bool RelFileLocatorSkippingWAL(RelFileLocator rlocator); +extern Size EstimatePendingSyncsSpace(void); +extern void SerializePendingSyncs(Size maxSize, char *startAddress); +extern void RestorePendingSyncs(char *startAddress); + +/* + * These functions used to be in storage/smgr/smgr.c, which explains the + * naming + */ +extern void smgrDoPendingDeletes(bool isCommit); +extern void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker); +extern int smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr); +extern void AtSubCommit_smgr(void); +extern void AtSubAbort_smgr(void); +extern void PostPrepare_smgr(void); + +#endif /* STORAGE_H */ diff --git a/install/include/postgresql/server/catalog/storage_xlog.h b/install/include/postgresql/server/catalog/storage_xlog.h new file mode 100644 index 00000000000..6b0a7aa3dfa --- /dev/null +++ b/install/include/postgresql/server/catalog/storage_xlog.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * storage_xlog.h + * prototypes for XLog support for backend/catalog/storage.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/storage_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef STORAGE_XLOG_H +#define STORAGE_XLOG_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/block.h" +#include "storage/relfilelocator.h" + +/* + * Declarations for smgr-related XLOG records + * + * Note: we log file creation and truncation here, but logging of deletion + * actions is handled by xact.c, because it is part of transaction commit. + */ + +/* XLOG gives us high 4 bits */ +#define XLOG_SMGR_CREATE 0x10 +#define XLOG_SMGR_TRUNCATE 0x20 + +typedef struct xl_smgr_create +{ + RelFileLocator rlocator; + ForkNumber forkNum; +} xl_smgr_create; + +/* flags for xl_smgr_truncate */ +#define SMGR_TRUNCATE_HEAP 0x0001 +#define SMGR_TRUNCATE_VM 0x0002 +#define SMGR_TRUNCATE_FSM 0x0004 +#define SMGR_TRUNCATE_ALL \ + (SMGR_TRUNCATE_HEAP|SMGR_TRUNCATE_VM|SMGR_TRUNCATE_FSM) + +typedef struct xl_smgr_truncate +{ + BlockNumber blkno; + RelFileLocator rlocator; + int flags; +} xl_smgr_truncate; + +extern void log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum); + +extern void smgr_redo(XLogReaderState *record); +extern void smgr_desc(StringInfo buf, XLogReaderState *record); +extern const char *smgr_identify(uint8 info); + +#endif /* STORAGE_XLOG_H */ diff --git a/install/include/postgresql/server/catalog/system_fk_info.h b/install/include/postgresql/server/catalog/system_fk_info.h new file mode 100644 index 00000000000..f6ec90843dc --- /dev/null +++ b/install/include/postgresql/server/catalog/system_fk_info.h @@ -0,0 +1,253 @@ +/*------------------------------------------------------------------------- + * + * system_fk_info.h + * Data about the foreign-key relationships in the system catalogs + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/catalog/genbki.pl + * + *------------------------------------------------------------------------- + */ +#ifndef SYSTEM_FK_INFO_H +#define SYSTEM_FK_INFO_H + +typedef struct SysFKRelationship +{ + Oid fk_table; /* referencing catalog */ + Oid pk_table; /* referenced catalog */ + const char *fk_columns; /* referencing column name(s) */ + const char *pk_columns; /* referenced column name(s) */ + bool is_array; /* if true, last fk_column is an array */ + bool is_opt; /* if true, fk_column can be zero */ +} SysFKRelationship; + +static const SysFKRelationship sys_fk_relationships[] = { + { /* pg_proc */ 1255, /* pg_namespace */ 2615, "{pronamespace}", "{oid}", false, false}, + { /* pg_proc */ 1255, /* pg_authid */ 1260, "{proowner}", "{oid}", false, false}, + { /* pg_proc */ 1255, /* pg_language */ 2612, "{prolang}", "{oid}", false, false}, + { /* pg_proc */ 1255, /* pg_type */ 1247, "{provariadic}", "{oid}", false, true}, + { /* pg_proc */ 1255, /* pg_proc */ 1255, "{prosupport}", "{oid}", false, true}, + { /* pg_proc */ 1255, /* pg_type */ 1247, "{prorettype}", "{oid}", false, false}, + { /* pg_proc */ 1255, /* pg_type */ 1247, "{proargtypes}", "{oid}", true, false}, + { /* pg_proc */ 1255, /* pg_type */ 1247, "{proallargtypes}", "{oid}", true, false}, + { /* pg_proc */ 1255, /* pg_type */ 1247, "{protrftypes}", "{oid}", true, false}, + { /* pg_type */ 1247, /* pg_namespace */ 2615, "{typnamespace}", "{oid}", false, false}, + { /* pg_type */ 1247, /* pg_authid */ 1260, "{typowner}", "{oid}", false, false}, + { /* pg_type */ 1247, /* pg_class */ 1259, "{typrelid}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typsubscript}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_type */ 1247, "{typelem}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_type */ 1247, "{typarray}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typinput}", "{oid}", false, false}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typoutput}", "{oid}", false, false}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typreceive}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typsend}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typmodin}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typmodout}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_proc */ 1255, "{typanalyze}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_type */ 1247, "{typbasetype}", "{oid}", false, true}, + { /* pg_type */ 1247, /* pg_collation */ 3456, "{typcollation}", "{oid}", false, true}, + { /* pg_attribute */ 1249, /* pg_class */ 1259, "{attrelid}", "{oid}", false, false}, + { /* pg_attribute */ 1249, /* pg_type */ 1247, "{atttypid}", "{oid}", false, true}, + { /* pg_attribute */ 1249, /* pg_collation */ 3456, "{attcollation}", "{oid}", false, true}, + { /* pg_class */ 1259, /* pg_namespace */ 2615, "{relnamespace}", "{oid}", false, false}, + { /* pg_class */ 1259, /* pg_type */ 1247, "{reltype}", "{oid}", false, true}, + { /* pg_class */ 1259, /* pg_type */ 1247, "{reloftype}", "{oid}", false, true}, + { /* pg_class */ 1259, /* pg_authid */ 1260, "{relowner}", "{oid}", false, false}, + { /* pg_class */ 1259, /* pg_am */ 2601, "{relam}", "{oid}", false, true}, + { /* pg_class */ 1259, /* pg_tablespace */ 1213, "{reltablespace}", "{oid}", false, true}, + { /* pg_class */ 1259, /* pg_class */ 1259, "{reltoastrelid}", "{oid}", false, true}, + { /* pg_class */ 1259, /* pg_class */ 1259, "{relrewrite}", "{oid}", false, true}, + { /* pg_attrdef */ 2604, /* pg_class */ 1259, "{adrelid}", "{oid}", false, false}, + { /* pg_attrdef */ 2604, /* pg_attribute */ 1249, "{adrelid, adnum}", "{attrelid, attnum}", false, false}, + { /* pg_constraint */ 2606, /* pg_namespace */ 2615, "{connamespace}", "{oid}", false, false}, + { /* pg_constraint */ 2606, /* pg_class */ 1259, "{conrelid}", "{oid}", false, true}, + { /* pg_constraint */ 2606, /* pg_type */ 1247, "{contypid}", "{oid}", false, true}, + { /* pg_constraint */ 2606, /* pg_class */ 1259, "{conindid}", "{oid}", false, true}, + { /* pg_constraint */ 2606, /* pg_constraint */ 2606, "{conparentid}", "{oid}", false, true}, + { /* pg_constraint */ 2606, /* pg_class */ 1259, "{confrelid}", "{oid}", false, true}, + { /* pg_constraint */ 2606, /* pg_operator */ 2617, "{conpfeqop}", "{oid}", true, false}, + { /* pg_constraint */ 2606, /* pg_operator */ 2617, "{conppeqop}", "{oid}", true, false}, + { /* pg_constraint */ 2606, /* pg_operator */ 2617, "{conffeqop}", "{oid}", true, false}, + { /* pg_constraint */ 2606, /* pg_operator */ 2617, "{conexclop}", "{oid}", true, false}, + { /* pg_constraint */ 2606, /* pg_attribute */ 1249, "{conrelid, conkey}", "{attrelid, attnum}", true, true}, + { /* pg_constraint */ 2606, /* pg_attribute */ 1249, "{confrelid, confkey}", "{attrelid, attnum}", true, false}, + { /* pg_inherits */ 2611, /* pg_class */ 1259, "{inhrelid}", "{oid}", false, false}, + { /* pg_inherits */ 2611, /* pg_class */ 1259, "{inhparent}", "{oid}", false, false}, + { /* pg_index */ 2610, /* pg_class */ 1259, "{indexrelid}", "{oid}", false, false}, + { /* pg_index */ 2610, /* pg_class */ 1259, "{indrelid}", "{oid}", false, false}, + { /* pg_index */ 2610, /* pg_collation */ 3456, "{indcollation}", "{oid}", true, true}, + { /* pg_index */ 2610, /* pg_opclass */ 2616, "{indclass}", "{oid}", true, false}, + { /* pg_index */ 2610, /* pg_attribute */ 1249, "{indrelid, indkey}", "{attrelid, attnum}", true, true}, + { /* pg_operator */ 2617, /* pg_namespace */ 2615, "{oprnamespace}", "{oid}", false, false}, + { /* pg_operator */ 2617, /* pg_authid */ 1260, "{oprowner}", "{oid}", false, false}, + { /* pg_operator */ 2617, /* pg_type */ 1247, "{oprleft}", "{oid}", false, true}, + { /* pg_operator */ 2617, /* pg_type */ 1247, "{oprright}", "{oid}", false, false}, + { /* pg_operator */ 2617, /* pg_type */ 1247, "{oprresult}", "{oid}", false, true}, + { /* pg_operator */ 2617, /* pg_operator */ 2617, "{oprcom}", "{oid}", false, true}, + { /* pg_operator */ 2617, /* pg_operator */ 2617, "{oprnegate}", "{oid}", false, true}, + { /* pg_operator */ 2617, /* pg_proc */ 1255, "{oprcode}", "{oid}", false, true}, + { /* pg_operator */ 2617, /* pg_proc */ 1255, "{oprrest}", "{oid}", false, true}, + { /* pg_operator */ 2617, /* pg_proc */ 1255, "{oprjoin}", "{oid}", false, true}, + { /* pg_opfamily */ 2753, /* pg_am */ 2601, "{opfmethod}", "{oid}", false, false}, + { /* pg_opfamily */ 2753, /* pg_namespace */ 2615, "{opfnamespace}", "{oid}", false, false}, + { /* pg_opfamily */ 2753, /* pg_authid */ 1260, "{opfowner}", "{oid}", false, false}, + { /* pg_opclass */ 2616, /* pg_am */ 2601, "{opcmethod}", "{oid}", false, false}, + { /* pg_opclass */ 2616, /* pg_namespace */ 2615, "{opcnamespace}", "{oid}", false, false}, + { /* pg_opclass */ 2616, /* pg_authid */ 1260, "{opcowner}", "{oid}", false, false}, + { /* pg_opclass */ 2616, /* pg_opfamily */ 2753, "{opcfamily}", "{oid}", false, false}, + { /* pg_opclass */ 2616, /* pg_type */ 1247, "{opcintype}", "{oid}", false, false}, + { /* pg_opclass */ 2616, /* pg_type */ 1247, "{opckeytype}", "{oid}", false, true}, + { /* pg_am */ 2601, /* pg_proc */ 1255, "{amhandler}", "{oid}", false, false}, + { /* pg_amop */ 2602, /* pg_opfamily */ 2753, "{amopfamily}", "{oid}", false, false}, + { /* pg_amop */ 2602, /* pg_type */ 1247, "{amoplefttype}", "{oid}", false, false}, + { /* pg_amop */ 2602, /* pg_type */ 1247, "{amoprighttype}", "{oid}", false, false}, + { /* pg_amop */ 2602, /* pg_operator */ 2617, "{amopopr}", "{oid}", false, false}, + { /* pg_amop */ 2602, /* pg_am */ 2601, "{amopmethod}", "{oid}", false, false}, + { /* pg_amop */ 2602, /* pg_opfamily */ 2753, "{amopsortfamily}", "{oid}", false, true}, + { /* pg_amproc */ 2603, /* pg_opfamily */ 2753, "{amprocfamily}", "{oid}", false, false}, + { /* pg_amproc */ 2603, /* pg_type */ 1247, "{amproclefttype}", "{oid}", false, false}, + { /* pg_amproc */ 2603, /* pg_type */ 1247, "{amprocrighttype}", "{oid}", false, false}, + { /* pg_amproc */ 2603, /* pg_proc */ 1255, "{amproc}", "{oid}", false, false}, + { /* pg_language */ 2612, /* pg_authid */ 1260, "{lanowner}", "{oid}", false, false}, + { /* pg_language */ 2612, /* pg_proc */ 1255, "{lanplcallfoid}", "{oid}", false, true}, + { /* pg_language */ 2612, /* pg_proc */ 1255, "{laninline}", "{oid}", false, true}, + { /* pg_language */ 2612, /* pg_proc */ 1255, "{lanvalidator}", "{oid}", false, true}, + { /* pg_largeobject_metadata */ 2995, /* pg_authid */ 1260, "{lomowner}", "{oid}", false, false}, + { /* pg_largeobject */ 2613, /* pg_largeobject_metadata */ 2995, "{loid}", "{oid}", false, false}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggfnoid}", "{oid}", false, false}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggtransfn}", "{oid}", false, false}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggfinalfn}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggcombinefn}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggserialfn}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggdeserialfn}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggmtransfn}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggminvtransfn}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_proc */ 1255, "{aggmfinalfn}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_operator */ 2617, "{aggsortop}", "{oid}", false, true}, + { /* pg_aggregate */ 2600, /* pg_type */ 1247, "{aggtranstype}", "{oid}", false, false}, + { /* pg_aggregate */ 2600, /* pg_type */ 1247, "{aggmtranstype}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_class */ 1259, "{starelid}", "{oid}", false, false}, + { /* pg_statistic */ 2619, /* pg_operator */ 2617, "{staop1}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_operator */ 2617, "{staop2}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_operator */ 2617, "{staop3}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_operator */ 2617, "{staop4}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_operator */ 2617, "{staop5}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_collation */ 3456, "{stacoll1}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_collation */ 3456, "{stacoll2}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_collation */ 3456, "{stacoll3}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_collation */ 3456, "{stacoll4}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_collation */ 3456, "{stacoll5}", "{oid}", false, true}, + { /* pg_statistic */ 2619, /* pg_attribute */ 1249, "{starelid, staattnum}", "{attrelid, attnum}", false, false}, + { /* pg_statistic_ext */ 3381, /* pg_class */ 1259, "{stxrelid}", "{oid}", false, false}, + { /* pg_statistic_ext */ 3381, /* pg_namespace */ 2615, "{stxnamespace}", "{oid}", false, false}, + { /* pg_statistic_ext */ 3381, /* pg_authid */ 1260, "{stxowner}", "{oid}", false, false}, + { /* pg_statistic_ext */ 3381, /* pg_attribute */ 1249, "{stxrelid, stxkeys}", "{attrelid, attnum}", true, false}, + { /* pg_statistic_ext_data */ 3429, /* pg_statistic_ext */ 3381, "{stxoid}", "{oid}", false, false}, + { /* pg_rewrite */ 2618, /* pg_class */ 1259, "{ev_class}", "{oid}", false, false}, + { /* pg_trigger */ 2620, /* pg_class */ 1259, "{tgrelid}", "{oid}", false, false}, + { /* pg_trigger */ 2620, /* pg_trigger */ 2620, "{tgparentid}", "{oid}", false, true}, + { /* pg_trigger */ 2620, /* pg_proc */ 1255, "{tgfoid}", "{oid}", false, false}, + { /* pg_trigger */ 2620, /* pg_class */ 1259, "{tgconstrrelid}", "{oid}", false, true}, + { /* pg_trigger */ 2620, /* pg_class */ 1259, "{tgconstrindid}", "{oid}", false, true}, + { /* pg_trigger */ 2620, /* pg_constraint */ 2606, "{tgconstraint}", "{oid}", false, true}, + { /* pg_trigger */ 2620, /* pg_attribute */ 1249, "{tgrelid, tgattr}", "{attrelid, attnum}", true, false}, + { /* pg_event_trigger */ 3466, /* pg_authid */ 1260, "{evtowner}", "{oid}", false, false}, + { /* pg_event_trigger */ 3466, /* pg_proc */ 1255, "{evtfoid}", "{oid}", false, false}, + { /* pg_description */ 2609, /* pg_class */ 1259, "{classoid}", "{oid}", false, false}, + { /* pg_cast */ 2605, /* pg_type */ 1247, "{castsource}", "{oid}", false, false}, + { /* pg_cast */ 2605, /* pg_type */ 1247, "{casttarget}", "{oid}", false, false}, + { /* pg_cast */ 2605, /* pg_proc */ 1255, "{castfunc}", "{oid}", false, true}, + { /* pg_enum */ 3501, /* pg_type */ 1247, "{enumtypid}", "{oid}", false, false}, + { /* pg_namespace */ 2615, /* pg_authid */ 1260, "{nspowner}", "{oid}", false, false}, + { /* pg_conversion */ 2607, /* pg_namespace */ 2615, "{connamespace}", "{oid}", false, false}, + { /* pg_conversion */ 2607, /* pg_authid */ 1260, "{conowner}", "{oid}", false, false}, + { /* pg_conversion */ 2607, /* pg_proc */ 1255, "{conproc}", "{oid}", false, false}, + { /* pg_depend */ 2608, /* pg_class */ 1259, "{classid}", "{oid}", false, false}, + { /* pg_depend */ 2608, /* pg_class */ 1259, "{refclassid}", "{oid}", false, false}, + { /* pg_database */ 1262, /* pg_authid */ 1260, "{datdba}", "{oid}", false, false}, + { /* pg_database */ 1262, /* pg_tablespace */ 1213, "{dattablespace}", "{oid}", false, false}, + { /* pg_db_role_setting */ 2964, /* pg_database */ 1262, "{setdatabase}", "{oid}", false, true}, + { /* pg_db_role_setting */ 2964, /* pg_authid */ 1260, "{setrole}", "{oid}", false, true}, + { /* pg_tablespace */ 1213, /* pg_authid */ 1260, "{spcowner}", "{oid}", false, false}, + { /* pg_auth_members */ 1261, /* pg_authid */ 1260, "{roleid}", "{oid}", false, false}, + { /* pg_auth_members */ 1261, /* pg_authid */ 1260, "{member}", "{oid}", false, false}, + { /* pg_auth_members */ 1261, /* pg_authid */ 1260, "{grantor}", "{oid}", false, false}, + { /* pg_shdepend */ 1214, /* pg_database */ 1262, "{dbid}", "{oid}", false, true}, + { /* pg_shdepend */ 1214, /* pg_class */ 1259, "{classid}", "{oid}", false, false}, + { /* pg_shdepend */ 1214, /* pg_class */ 1259, "{refclassid}", "{oid}", false, false}, + { /* pg_shdescription */ 2396, /* pg_class */ 1259, "{classoid}", "{oid}", false, false}, + { /* pg_ts_config */ 3602, /* pg_namespace */ 2615, "{cfgnamespace}", "{oid}", false, false}, + { /* pg_ts_config */ 3602, /* pg_authid */ 1260, "{cfgowner}", "{oid}", false, false}, + { /* pg_ts_config */ 3602, /* pg_ts_parser */ 3601, "{cfgparser}", "{oid}", false, false}, + { /* pg_ts_config_map */ 3603, /* pg_ts_config */ 3602, "{mapcfg}", "{oid}", false, false}, + { /* pg_ts_config_map */ 3603, /* pg_ts_dict */ 3600, "{mapdict}", "{oid}", false, false}, + { /* pg_ts_dict */ 3600, /* pg_namespace */ 2615, "{dictnamespace}", "{oid}", false, false}, + { /* pg_ts_dict */ 3600, /* pg_authid */ 1260, "{dictowner}", "{oid}", false, false}, + { /* pg_ts_dict */ 3600, /* pg_ts_template */ 3764, "{dicttemplate}", "{oid}", false, false}, + { /* pg_ts_parser */ 3601, /* pg_namespace */ 2615, "{prsnamespace}", "{oid}", false, false}, + { /* pg_ts_parser */ 3601, /* pg_proc */ 1255, "{prsstart}", "{oid}", false, false}, + { /* pg_ts_parser */ 3601, /* pg_proc */ 1255, "{prstoken}", "{oid}", false, false}, + { /* pg_ts_parser */ 3601, /* pg_proc */ 1255, "{prsend}", "{oid}", false, false}, + { /* pg_ts_parser */ 3601, /* pg_proc */ 1255, "{prsheadline}", "{oid}", false, true}, + { /* pg_ts_parser */ 3601, /* pg_proc */ 1255, "{prslextype}", "{oid}", false, false}, + { /* pg_ts_template */ 3764, /* pg_namespace */ 2615, "{tmplnamespace}", "{oid}", false, false}, + { /* pg_ts_template */ 3764, /* pg_proc */ 1255, "{tmplinit}", "{oid}", false, true}, + { /* pg_ts_template */ 3764, /* pg_proc */ 1255, "{tmpllexize}", "{oid}", false, false}, + { /* pg_extension */ 3079, /* pg_authid */ 1260, "{extowner}", "{oid}", false, false}, + { /* pg_extension */ 3079, /* pg_namespace */ 2615, "{extnamespace}", "{oid}", false, false}, + { /* pg_extension */ 3079, /* pg_class */ 1259, "{extconfig}", "{oid}", true, false}, + { /* pg_foreign_data_wrapper */ 2328, /* pg_authid */ 1260, "{fdwowner}", "{oid}", false, false}, + { /* pg_foreign_data_wrapper */ 2328, /* pg_proc */ 1255, "{fdwhandler}", "{oid}", false, true}, + { /* pg_foreign_data_wrapper */ 2328, /* pg_proc */ 1255, "{fdwvalidator}", "{oid}", false, true}, + { /* pg_foreign_server */ 1417, /* pg_authid */ 1260, "{srvowner}", "{oid}", false, false}, + { /* pg_foreign_server */ 1417, /* pg_foreign_data_wrapper */ 2328, "{srvfdw}", "{oid}", false, false}, + { /* pg_user_mapping */ 1418, /* pg_authid */ 1260, "{umuser}", "{oid}", false, true}, + { /* pg_user_mapping */ 1418, /* pg_foreign_server */ 1417, "{umserver}", "{oid}", false, false}, + { /* pg_foreign_table */ 3118, /* pg_class */ 1259, "{ftrelid}", "{oid}", false, false}, + { /* pg_foreign_table */ 3118, /* pg_foreign_server */ 1417, "{ftserver}", "{oid}", false, false}, + { /* pg_policy */ 3256, /* pg_class */ 1259, "{polrelid}", "{oid}", false, false}, + { /* pg_policy */ 3256, /* pg_authid */ 1260, "{polroles}", "{oid}", true, true}, + { /* pg_default_acl */ 826, /* pg_authid */ 1260, "{defaclrole}", "{oid}", false, false}, + { /* pg_default_acl */ 826, /* pg_namespace */ 2615, "{defaclnamespace}", "{oid}", false, true}, + { /* pg_init_privs */ 3394, /* pg_class */ 1259, "{classoid}", "{oid}", false, false}, + { /* pg_seclabel */ 3596, /* pg_class */ 1259, "{classoid}", "{oid}", false, false}, + { /* pg_shseclabel */ 3592, /* pg_class */ 1259, "{classoid}", "{oid}", false, false}, + { /* pg_collation */ 3456, /* pg_namespace */ 2615, "{collnamespace}", "{oid}", false, false}, + { /* pg_collation */ 3456, /* pg_authid */ 1260, "{collowner}", "{oid}", false, false}, + { /* pg_partitioned_table */ 3350, /* pg_class */ 1259, "{partrelid}", "{oid}", false, false}, + { /* pg_partitioned_table */ 3350, /* pg_class */ 1259, "{partdefid}", "{oid}", false, true}, + { /* pg_partitioned_table */ 3350, /* pg_opclass */ 2616, "{partclass}", "{oid}", true, false}, + { /* pg_partitioned_table */ 3350, /* pg_collation */ 3456, "{partcollation}", "{oid}", true, true}, + { /* pg_partitioned_table */ 3350, /* pg_attribute */ 1249, "{partrelid, partattrs}", "{attrelid, attnum}", true, true}, + { /* pg_range */ 3541, /* pg_type */ 1247, "{rngtypid}", "{oid}", false, false}, + { /* pg_range */ 3541, /* pg_type */ 1247, "{rngsubtype}", "{oid}", false, false}, + { /* pg_range */ 3541, /* pg_type */ 1247, "{rngmultitypid}", "{oid}", false, false}, + { /* pg_range */ 3541, /* pg_collation */ 3456, "{rngcollation}", "{oid}", false, true}, + { /* pg_range */ 3541, /* pg_opclass */ 2616, "{rngsubopc}", "{oid}", false, false}, + { /* pg_range */ 3541, /* pg_proc */ 1255, "{rngcanonical}", "{oid}", false, true}, + { /* pg_range */ 3541, /* pg_proc */ 1255, "{rngsubdiff}", "{oid}", false, true}, + { /* pg_transform */ 3576, /* pg_type */ 1247, "{trftype}", "{oid}", false, false}, + { /* pg_transform */ 3576, /* pg_language */ 2612, "{trflang}", "{oid}", false, false}, + { /* pg_transform */ 3576, /* pg_proc */ 1255, "{trffromsql}", "{oid}", false, true}, + { /* pg_transform */ 3576, /* pg_proc */ 1255, "{trftosql}", "{oid}", false, true}, + { /* pg_sequence */ 2224, /* pg_class */ 1259, "{seqrelid}", "{oid}", false, false}, + { /* pg_sequence */ 2224, /* pg_type */ 1247, "{seqtypid}", "{oid}", false, false}, + { /* pg_publication */ 6104, /* pg_authid */ 1260, "{pubowner}", "{oid}", false, false}, + { /* pg_publication_namespace */ 6237, /* pg_publication */ 6104, "{pnpubid}", "{oid}", false, false}, + { /* pg_publication_namespace */ 6237, /* pg_namespace */ 2615, "{pnnspid}", "{oid}", false, false}, + { /* pg_publication_rel */ 6106, /* pg_publication */ 6104, "{prpubid}", "{oid}", false, false}, + { /* pg_publication_rel */ 6106, /* pg_class */ 1259, "{prrelid}", "{oid}", false, false}, + { /* pg_subscription */ 6100, /* pg_database */ 1262, "{subdbid}", "{oid}", false, false}, + { /* pg_subscription */ 6100, /* pg_authid */ 1260, "{subowner}", "{oid}", false, false}, + { /* pg_subscription_rel */ 6102, /* pg_subscription */ 6100, "{srsubid}", "{oid}", false, false}, + { /* pg_subscription_rel */ 6102, /* pg_class */ 1259, "{srrelid}", "{oid}", false, false}, +}; + +#endif /* SYSTEM_FK_INFO_H */ diff --git a/install/include/postgresql/server/catalog/toasting.h b/install/include/postgresql/server/catalog/toasting.h new file mode 100644 index 00000000000..5880ec67524 --- /dev/null +++ b/install/include/postgresql/server/catalog/toasting.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * toasting.h + * This file provides some definitions to support creation of toast tables + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/toasting.h + * + *------------------------------------------------------------------------- + */ +#ifndef TOASTING_H +#define TOASTING_H + +#include "storage/lock.h" + +/* + * toasting.c prototypes + */ +extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); +extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, + LOCKMODE lockmode, Oid OIDOldToast); +extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, + LOCKMODE lockmode); +extern void BootstrapToastTable(char *relName, + Oid toastOid, Oid toastIndexOid); + +#endif /* TOASTING_H */ diff --git a/install/include/postgresql/server/commands/alter.h b/install/include/postgresql/server/commands/alter.h new file mode 100644 index 00000000000..ae79968fadd --- /dev/null +++ b/install/include/postgresql/server/commands/alter.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * alter.h + * prototypes for commands/alter.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/alter.h + * + *------------------------------------------------------------------------- + */ +#ifndef ALTER_H +#define ALTER_H + +#include "catalog/dependency.h" +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" +#include "utils/relcache.h" + +extern ObjectAddress ExecRenameStmt(RenameStmt *stmt); + +extern ObjectAddress ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, + ObjectAddress *refAddress); +extern ObjectAddress ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, + ObjectAddress *oldSchemaAddr); +extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, + ObjectAddresses *objsMoved); + +extern ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt); +extern void AlterObjectOwner_internal(Relation rel, Oid objectId, + Oid new_ownerId); + +#endif /* ALTER_H */ diff --git a/install/include/postgresql/server/commands/async.h b/install/include/postgresql/server/commands/async.h new file mode 100644 index 00000000000..fbf091e1226 --- /dev/null +++ b/install/include/postgresql/server/commands/async.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * async.h + * Asynchronous notification: NOTIFY, LISTEN, UNLISTEN + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/async.h + * + *------------------------------------------------------------------------- + */ +#ifndef ASYNC_H +#define ASYNC_H + +#include + +/* + * The number of SLRU page buffers we use for the notification queue. + */ +#define NUM_NOTIFY_BUFFERS 8 + +extern PGDLLIMPORT bool Trace_notify; +extern PGDLLIMPORT volatile sig_atomic_t notifyInterruptPending; + +extern Size AsyncShmemSize(void); +extern void AsyncShmemInit(void); + +extern void NotifyMyFrontEnd(const char *channel, + const char *payload, + int32 srcPid); + +/* notify-related SQL statements */ +extern void Async_Notify(const char *channel, const char *payload); +extern void Async_Listen(const char *channel); +extern void Async_Unlisten(const char *channel); +extern void Async_UnlistenAll(void); + +/* perform (or cancel) outbound notify processing at transaction commit */ +extern void PreCommit_Notify(void); +extern void AtCommit_Notify(void); +extern void AtAbort_Notify(void); +extern void AtSubCommit_Notify(void); +extern void AtSubAbort_Notify(void); +extern void AtPrepare_Notify(void); + +/* signal handler for inbound notifies (PROCSIG_NOTIFY_INTERRUPT) */ +extern void HandleNotifyInterrupt(void); + +/* process interrupts */ +extern void ProcessNotifyInterrupt(bool flush); + +/* freeze old transaction IDs in notify queue (called by VACUUM) */ +extern void AsyncNotifyFreezeXids(TransactionId newFrozenXid); + +#endif /* ASYNC_H */ diff --git a/install/include/postgresql/server/commands/cluster.h b/install/include/postgresql/server/commands/cluster.h new file mode 100644 index 00000000000..f92ae8f25a6 --- /dev/null +++ b/install/include/postgresql/server/commands/cluster.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * cluster.h + * header file for postgres cluster command stuff + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994-5, Regents of the University of California + * + * src/include/commands/cluster.h + * + *------------------------------------------------------------------------- + */ +#ifndef CLUSTER_H +#define CLUSTER_H + +#include "nodes/parsenodes.h" +#include "parser/parse_node.h" +#include "storage/lock.h" +#include "utils/relcache.h" + + +/* flag bits for ClusterParams->options */ +#define CLUOPT_VERBOSE 0x01 /* print progress info */ +#define CLUOPT_RECHECK 0x02 /* recheck relation state */ +#define CLUOPT_RECHECK_ISCLUSTERED 0x04 /* recheck relation state for + * indisclustered */ + +/* options for CLUSTER */ +typedef struct ClusterParams +{ + bits32 options; /* bitmask of CLUOPT_* */ +} ClusterParams; + +extern void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel); +extern void cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params); +extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid, + LOCKMODE lockmode); +extern void mark_index_clustered(Relation rel, Oid indexOid, bool is_internal); + +extern Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, + char relpersistence, LOCKMODE lockmode); +extern void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, + bool is_system_catalog, + bool swap_toast_by_content, + bool check_constraints, + bool is_internal, + TransactionId frozenXid, + MultiXactId cutoffMulti, + char newrelpersistence); + +#endif /* CLUSTER_H */ diff --git a/install/include/postgresql/server/commands/collationcmds.h b/install/include/postgresql/server/commands/collationcmds.h new file mode 100644 index 00000000000..b76c7b3dc3c --- /dev/null +++ b/install/include/postgresql/server/commands/collationcmds.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * + * collationcmds.h + * prototypes for collationcmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/collationcmds.h + * + *------------------------------------------------------------------------- + */ + +#ifndef COLLATIONCMDS_H +#define COLLATIONCMDS_H + +#include "catalog/objectaddress.h" +#include "parser/parse_node.h" + +extern ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists); +extern void IsThereCollationInNamespace(const char *collname, Oid nspOid); +extern ObjectAddress AlterCollation(AlterCollationStmt *stmt); + +#endif /* COLLATIONCMDS_H */ diff --git a/install/include/postgresql/server/commands/comment.h b/install/include/postgresql/server/commands/comment.h new file mode 100644 index 00000000000..1a4ca71e76e --- /dev/null +++ b/install/include/postgresql/server/commands/comment.h @@ -0,0 +1,45 @@ +/* + * src/include/commands/comment.h + * + *------------------------------------------------------------------------- + * + * comment.h + * + * Prototypes for functions in commands/comment.c + * + * Copyright (c) 1999-2023, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ + +#ifndef COMMENT_H +#define COMMENT_H + +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" + +/*------------------------------------------------------------------ + * Function Prototypes -- + * + * The following prototypes define the public functions of the comment + * related routines. CommentObject() implements the SQL "COMMENT ON" + * command. DeleteComments() deletes all comments for an object. + * CreateComments creates (or deletes, if comment is NULL) a comment + * for a specific key. There are versions of these two methods for + * both normal and shared objects. + *------------------------------------------------------------------ + */ + +extern ObjectAddress CommentObject(CommentStmt *stmt); + +extern void DeleteComments(Oid oid, Oid classoid, int32 subid); + +extern void CreateComments(Oid oid, Oid classoid, int32 subid, const char *comment); + +extern void DeleteSharedComments(Oid oid, Oid classoid); + +extern void CreateSharedComments(Oid oid, Oid classoid, const char *comment); + +extern char *GetComment(Oid oid, Oid classoid, int32 subid); + +#endif /* COMMENT_H */ diff --git a/install/include/postgresql/server/commands/conversioncmds.h b/install/include/postgresql/server/commands/conversioncmds.h new file mode 100644 index 00000000000..0e5534da34c --- /dev/null +++ b/install/include/postgresql/server/commands/conversioncmds.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * conversioncmds.h + * prototypes for conversioncmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/conversioncmds.h + * + *------------------------------------------------------------------------- + */ + +#ifndef CONVERSIONCMDS_H +#define CONVERSIONCMDS_H + +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" + +extern ObjectAddress CreateConversionCommand(CreateConversionStmt *stmt); + +#endif /* CONVERSIONCMDS_H */ diff --git a/install/include/postgresql/server/commands/copy.h b/install/include/postgresql/server/commands/copy.h new file mode 100644 index 00000000000..33175868f65 --- /dev/null +++ b/install/include/postgresql/server/commands/copy.h @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------------- + * + * copy.h + * Definitions for using the POSTGRES copy command. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/copy.h + * + *------------------------------------------------------------------------- + */ +#ifndef COPY_H +#define COPY_H + +#include "nodes/execnodes.h" +#include "nodes/parsenodes.h" +#include "parser/parse_node.h" +#include "tcop/dest.h" + +/* + * Represents whether a header line should be present, and whether it must + * match the actual names (which implies "true"). + */ +typedef enum CopyHeaderChoice +{ + COPY_HEADER_FALSE = 0, + COPY_HEADER_TRUE, + COPY_HEADER_MATCH, +} CopyHeaderChoice; + +/* + * A struct to hold COPY options, in a parsed form. All of these are related + * to formatting, except for 'freeze', which doesn't really belong here, but + * it's expedient to parse it along with all the other options. + */ +typedef struct CopyFormatOptions +{ + /* parameters from the COPY command */ + int file_encoding; /* file or remote side's character encoding, + * -1 if not specified */ + bool binary; /* binary format? */ + bool freeze; /* freeze rows on loading? */ + bool csv_mode; /* Comma Separated Value format? */ + CopyHeaderChoice header_line; /* header line? */ + char *null_print; /* NULL marker string (server encoding!) */ + int null_print_len; /* length of same */ + char *null_print_client; /* same converted to file encoding */ + char *default_print; /* DEFAULT marker string */ + int default_print_len; /* length of same */ + char *delim; /* column delimiter (must be 1 byte) */ + char *quote; /* CSV quote char (must be 1 byte) */ + char *escape; /* CSV escape char (must be 1 byte) */ + List *force_quote; /* list of column names */ + bool force_quote_all; /* FORCE_QUOTE *? */ + bool *force_quote_flags; /* per-column CSV FQ flags */ + List *force_notnull; /* list of column names */ + bool *force_notnull_flags; /* per-column CSV FNN flags */ + List *force_null; /* list of column names */ + bool *force_null_flags; /* per-column CSV FN flags */ + bool convert_selectively; /* do selective binary conversion? */ + List *convert_select; /* list of column names (can be NIL) */ +} CopyFormatOptions; + +/* These are private in commands/copy[from|to].c */ +typedef struct CopyFromStateData *CopyFromState; +typedef struct CopyToStateData *CopyToState; + +typedef int (*copy_data_source_cb) (void *outbuf, int minread, int maxread); +typedef void (*copy_data_dest_cb) (void *data, int len); + +extern void DoCopy(ParseState *pstate, const CopyStmt *stmt, + int stmt_location, int stmt_len, + uint64 *processed); + +extern void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, List *options); +extern 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); +extern void EndCopyFrom(CopyFromState cstate); +extern bool NextCopyFrom(CopyFromState cstate, ExprContext *econtext, + Datum *values, bool *nulls); +extern bool NextCopyFromRawFields(CopyFromState cstate, + char ***fields, int *nfields); +extern void CopyFromErrorCallback(void *arg); + +extern uint64 CopyFrom(CopyFromState cstate); + +extern DestReceiver *CreateCopyDestReceiver(void); + +/* + * internal prototypes + */ +extern CopyToState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *raw_query, + Oid queryRelId, const char *filename, bool is_program, + copy_data_dest_cb data_dest_cb, List *attnamelist, List *options); +extern void EndCopyTo(CopyToState cstate); +extern uint64 DoCopyTo(CopyToState cstate); +extern List *CopyGetAttnums(TupleDesc tupDesc, Relation rel, + List *attnamelist); + +#endif /* COPY_H */ diff --git a/install/include/postgresql/server/commands/copyfrom_internal.h b/install/include/postgresql/server/commands/copyfrom_internal.h new file mode 100644 index 00000000000..ac2c16f8b86 --- /dev/null +++ b/install/include/postgresql/server/commands/copyfrom_internal.h @@ -0,0 +1,181 @@ +/*------------------------------------------------------------------------- + * + * copyfrom_internal.h + * Internal definitions for COPY FROM command. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/copyfrom_internal.h + * + *------------------------------------------------------------------------- + */ +#ifndef COPYFROM_INTERNAL_H +#define COPYFROM_INTERNAL_H + +#include "commands/copy.h" +#include "commands/trigger.h" + +/* + * Represents the different source cases we need to worry about at + * the bottom level + */ +typedef enum CopySource +{ + COPY_FILE, /* from file (or a piped program) */ + COPY_FRONTEND, /* from frontend */ + COPY_CALLBACK /* from callback function */ +} CopySource; + +/* + * Represents the end-of-line terminator type of the input + */ +typedef enum EolType +{ + EOL_UNKNOWN, + EOL_NL, + EOL_CR, + EOL_CRNL +} EolType; + +/* + * Represents the insert method to be used during COPY FROM. + */ +typedef enum CopyInsertMethod +{ + CIM_SINGLE, /* use table_tuple_insert or ExecForeignInsert */ + CIM_MULTI, /* always use table_multi_insert or + * ExecForeignBatchInsert */ + CIM_MULTI_CONDITIONAL /* use table_multi_insert or + * ExecForeignBatchInsert only if valid */ +} CopyInsertMethod; + +/* + * This struct contains all the state variables used throughout a COPY FROM + * operation. + */ +typedef struct CopyFromStateData +{ + /* low-level state data */ + CopySource copy_src; /* type of copy source */ + FILE *copy_file; /* used if copy_src == COPY_FILE */ + StringInfo fe_msgbuf; /* used if copy_src == COPY_FRONTEND */ + + EolType eol_type; /* EOL type of input */ + int file_encoding; /* file or remote side's character encoding */ + bool need_transcoding; /* file encoding diff from server? */ + Oid conversion_proc; /* encoding conversion function */ + + /* parameters from the COPY command */ + Relation rel; /* relation to copy from */ + List *attnumlist; /* integer list of attnums to copy */ + char *filename; /* filename, or NULL for STDIN */ + bool is_program; /* is 'filename' a program to popen? */ + copy_data_source_cb data_source_cb; /* function for reading data */ + + CopyFormatOptions opts; + bool *convert_select_flags; /* per-column CSV/TEXT CS flags */ + Node *whereClause; /* WHERE condition (or NULL) */ + + /* these are just for error messages, see CopyFromErrorCallback */ + const char *cur_relname; /* table name for error messages */ + uint64 cur_lineno; /* line number for error messages */ + const char *cur_attname; /* current att for error messages */ + const char *cur_attval; /* current att value for error messages */ + bool relname_only; /* don't output line number, att, etc. */ + + /* + * Working state + */ + MemoryContext copycontext; /* per-copy execution context */ + + AttrNumber num_defaults; /* count of att that are missing and have + * default value */ + FmgrInfo *in_functions; /* array of input functions for each attrs */ + Oid *typioparams; /* array of element types for in_functions */ + int *defmap; /* array of default att numbers related to + * missing att */ + ExprState **defexprs; /* array of default att expressions for all + * att */ + bool *defaults; /* if DEFAULT marker was found for + * corresponding att */ + bool volatile_defexprs; /* is any of defexprs volatile? */ + List *range_table; /* single element list of RangeTblEntry */ + List *rteperminfos; /* single element list of RTEPermissionInfo */ + ExprState *qualexpr; + + TransitionCaptureState *transition_capture; + + /* + * These variables are used to reduce overhead in COPY FROM. + * + * attribute_buf holds the separated, de-escaped text for each field of + * the current line. The CopyReadAttributes functions return arrays of + * pointers into this buffer. We avoid palloc/pfree overhead by re-using + * the buffer on each cycle. + * + * In binary COPY FROM, attribute_buf holds the binary data for the + * current field, but the usage is otherwise similar. + */ + StringInfoData attribute_buf; + + /* field raw data pointers found by COPY FROM */ + + int max_fields; + char **raw_fields; + + /* + * Similarly, line_buf holds the whole input line being processed. The + * input cycle is first to read the whole line into line_buf, and then + * extract the individual attribute fields into attribute_buf. line_buf + * is preserved unmodified so that we can display it in error messages if + * appropriate. (In binary mode, line_buf is not used.) + */ + StringInfoData line_buf; + bool line_buf_valid; /* contains the row being processed? */ + + /* + * input_buf holds input data, already converted to database encoding. + * + * In text mode, CopyReadLine parses this data sufficiently to locate line + * boundaries, then transfers the data to line_buf. We guarantee that + * there is a \0 at input_buf[input_buf_len] at all times. (In binary + * mode, input_buf is not used.) + * + * If encoding conversion is not required, input_buf is not a separate + * buffer but points directly to raw_buf. In that case, input_buf_len + * tracks the number of bytes that have been verified as valid in the + * database encoding, and raw_buf_len is the total number of bytes stored + * in the buffer. + */ +#define INPUT_BUF_SIZE 65536 /* we palloc INPUT_BUF_SIZE+1 bytes */ + char *input_buf; + int input_buf_index; /* next byte to process */ + int input_buf_len; /* total # of bytes stored */ + bool input_reached_eof; /* true if we reached EOF */ + bool input_reached_error; /* true if a conversion error happened */ + /* Shorthand for number of unconsumed bytes available in input_buf */ +#define INPUT_BUF_BYTES(cstate) ((cstate)->input_buf_len - (cstate)->input_buf_index) + + /* + * raw_buf holds raw input data read from the data source (file or client + * connection), not yet converted to the database encoding. Like with + * 'input_buf', we guarantee that there is a \0 at raw_buf[raw_buf_len]. + */ +#define RAW_BUF_SIZE 65536 /* we palloc RAW_BUF_SIZE+1 bytes */ + char *raw_buf; + int raw_buf_index; /* next byte to process */ + int raw_buf_len; /* total # of bytes stored */ + bool raw_reached_eof; /* true if we reached EOF */ + + /* Shorthand for number of unconsumed bytes available in raw_buf */ +#define RAW_BUF_BYTES(cstate) ((cstate)->raw_buf_len - (cstate)->raw_buf_index) + + uint64 bytes_processed; /* number of bytes processed so far */ +} CopyFromStateData; + +extern void ReceiveCopyBegin(CopyFromState cstate); +extern void ReceiveCopyBinaryHeader(CopyFromState cstate); + +#endif /* COPYFROM_INTERNAL_H */ diff --git a/install/include/postgresql/server/commands/createas.h b/install/include/postgresql/server/commands/createas.h new file mode 100644 index 00000000000..3647f96f733 --- /dev/null +++ b/install/include/postgresql/server/commands/createas.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * createas.h + * prototypes for createas.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/createas.h + * + *------------------------------------------------------------------------- + */ +#ifndef CREATEAS_H +#define CREATEAS_H + +#include "catalog/objectaddress.h" +#include "nodes/params.h" +#include "parser/parse_node.h" +#include "tcop/dest.h" +#include "utils/queryenvironment.h" + + +extern ObjectAddress ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, + ParamListInfo params, QueryEnvironment *queryEnv, + QueryCompletion *qc); + +extern int GetIntoRelEFlags(IntoClause *intoClause); + +extern DestReceiver *CreateIntoRelDestReceiver(IntoClause *intoClause); + +extern bool CreateTableAsRelExists(CreateTableAsStmt *ctas); + +#endif /* CREATEAS_H */ diff --git a/install/include/postgresql/server/commands/dbcommands.h b/install/include/postgresql/server/commands/dbcommands.h new file mode 100644 index 00000000000..5fbc3ca7528 --- /dev/null +++ b/install/include/postgresql/server/commands/dbcommands.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * dbcommands.h + * Database management commands (create/drop database). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/dbcommands.h + * + *------------------------------------------------------------------------- + */ +#ifndef DBCOMMANDS_H +#define DBCOMMANDS_H + +#include "access/xlogreader.h" +#include "catalog/objectaddress.h" +#include "lib/stringinfo.h" +#include "parser/parse_node.h" + +extern Oid createdb(ParseState *pstate, const CreatedbStmt *stmt); +extern void dropdb(const char *dbname, bool missing_ok, bool force); +extern void DropDatabase(ParseState *pstate, DropdbStmt *stmt); +extern ObjectAddress RenameDatabase(const char *oldname, const char *newname); +extern Oid AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel); +extern ObjectAddress AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt); +extern Oid AlterDatabaseSet(AlterDatabaseSetStmt *stmt); +extern ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId); + +extern Oid get_database_oid(const char *dbname, bool missing_ok); +extern char *get_database_name(Oid dbid); +extern bool have_createdb_privilege(void); + +extern void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype); + +#endif /* DBCOMMANDS_H */ diff --git a/install/include/postgresql/server/commands/dbcommands_xlog.h b/install/include/postgresql/server/commands/dbcommands_xlog.h new file mode 100644 index 00000000000..a1433275f5f --- /dev/null +++ b/install/include/postgresql/server/commands/dbcommands_xlog.h @@ -0,0 +1,60 @@ +/*------------------------------------------------------------------------- + * + * dbcommands_xlog.h + * Database resource manager XLOG definitions (create/drop database). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/dbcommands_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef DBCOMMANDS_XLOG_H +#define DBCOMMANDS_XLOG_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" + +/* record types */ +#define XLOG_DBASE_CREATE_FILE_COPY 0x00 +#define XLOG_DBASE_CREATE_WAL_LOG 0x10 +#define XLOG_DBASE_DROP 0x20 + +/* + * Single WAL record for an entire CREATE DATABASE operation. This is used + * by the FILE_COPY strategy. + */ +typedef struct xl_dbase_create_file_copy_rec +{ + Oid db_id; + Oid tablespace_id; + Oid src_db_id; + Oid src_tablespace_id; +} xl_dbase_create_file_copy_rec; + +/* + * WAL record for the beginning of a CREATE DATABASE operation, when the + * WAL_LOG strategy is used. Each individual block will be logged separately + * afterward. + */ +typedef struct xl_dbase_create_wal_log_rec +{ + Oid db_id; + Oid tablespace_id; +} xl_dbase_create_wal_log_rec; + +typedef struct xl_dbase_drop_rec +{ + Oid db_id; + int ntablespaces; /* number of tablespace IDs */ + Oid tablespace_ids[FLEXIBLE_ARRAY_MEMBER]; +} xl_dbase_drop_rec; +#define MinSizeOfDbaseDropRec offsetof(xl_dbase_drop_rec, tablespace_ids) + +extern void dbase_redo(XLogReaderState *record); +extern void dbase_desc(StringInfo buf, XLogReaderState *record); +extern const char *dbase_identify(uint8 info); + +#endif /* DBCOMMANDS_XLOG_H */ diff --git a/install/include/postgresql/server/commands/defrem.h b/install/include/postgresql/server/commands/defrem.h new file mode 100644 index 00000000000..83423d3ba13 --- /dev/null +++ b/install/include/postgresql/server/commands/defrem.h @@ -0,0 +1,161 @@ +/*------------------------------------------------------------------------- + * + * defrem.h + * POSTGRES define and remove utility definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/defrem.h + * + *------------------------------------------------------------------------- + */ +#ifndef DEFREM_H +#define DEFREM_H + +#include "catalog/objectaddress.h" +#include "nodes/params.h" +#include "parser/parse_node.h" +#include "tcop/dest.h" +#include "utils/array.h" + +/* commands/dropcmds.c */ +extern void RemoveObjects(DropStmt *stmt); + +/* commands/indexcmds.c */ +extern ObjectAddress DefineIndex(Oid relationId, + IndexStmt *stmt, + Oid indexRelationId, + Oid parentIndexId, + Oid parentConstraintId, + int total_parts, + bool is_alter_table, + bool check_rights, + bool check_not_in_use, + bool skip_build, + bool quiet); +extern void ExecReindex(ParseState *pstate, ReindexStmt *stmt, bool isTopLevel); +extern char *makeObjectName(const char *name1, const char *name2, + const char *label); +extern char *ChooseRelationName(const char *name1, const char *name2, + const char *label, Oid namespaceid, + bool isconstraint); +extern bool CheckIndexCompatible(Oid oldId, + const char *accessMethodName, + List *attributeList, + List *exclusionOpNames); +extern Oid GetDefaultOpClass(Oid type_id, Oid am_id); +extern Oid ResolveOpClass(List *opclass, Oid attrType, + const char *accessMethodName, Oid accessMethodId); + +/* commands/functioncmds.c */ +extern ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt); +extern void RemoveFunctionById(Oid funcOid); +extern ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt); +extern ObjectAddress CreateCast(CreateCastStmt *stmt); +extern ObjectAddress CreateTransform(CreateTransformStmt *stmt); +extern void IsThereFunctionInNamespace(const char *proname, int pronargs, + oidvector *proargtypes, Oid nspOid); +extern void ExecuteDoStmt(ParseState *pstate, DoStmt *stmt, bool atomic); +extern void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest); +extern TupleDesc CallStmtResultDesc(CallStmt *stmt); +extern Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok); +extern void interpret_function_parameter_list(ParseState *pstate, + List *parameters, + Oid languageOid, + ObjectType objtype, + oidvector **parameterTypes, + List **parameterTypes_list, + ArrayType **allParameterTypes, + ArrayType **parameterModes, + ArrayType **parameterNames, + List **inParameterNames_list, + List **parameterDefaults, + Oid *variadicArgType, + Oid *requiredResultType); + +/* commands/operatorcmds.c */ +extern ObjectAddress DefineOperator(List *names, List *parameters); +extern void RemoveOperatorById(Oid operOid); +extern ObjectAddress AlterOperator(AlterOperatorStmt *stmt); + +/* commands/statscmds.c */ +extern ObjectAddress CreateStatistics(CreateStatsStmt *stmt, bool check_rights); +extern ObjectAddress AlterStatistics(AlterStatsStmt *stmt); +extern void RemoveStatisticsById(Oid statsOid); +extern void RemoveStatisticsDataById(Oid statsOid, bool inh); +extern Oid StatisticsGetRelation(Oid statId, bool missing_ok); + +/* commands/aggregatecmds.c */ +extern ObjectAddress DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, + List *parameters, bool replace); + +/* commands/opclasscmds.c */ +extern ObjectAddress DefineOpClass(CreateOpClassStmt *stmt); +extern ObjectAddress DefineOpFamily(CreateOpFamilyStmt *stmt); +extern Oid AlterOpFamily(AlterOpFamilyStmt *stmt); +extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, + Oid opcnamespace); +extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, + Oid opfnamespace); +extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok); +extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok); + +/* commands/tsearchcmds.c */ +extern ObjectAddress DefineTSParser(List *names, List *parameters); + +extern ObjectAddress DefineTSDictionary(List *names, List *parameters); +extern ObjectAddress AlterTSDictionary(AlterTSDictionaryStmt *stmt); + +extern ObjectAddress DefineTSTemplate(List *names, List *parameters); + +extern ObjectAddress DefineTSConfiguration(List *names, List *parameters, + ObjectAddress *copied); +extern void RemoveTSConfigurationById(Oid cfgId); +extern ObjectAddress AlterTSConfiguration(AlterTSConfigurationStmt *stmt); + +extern text *serialize_deflist(List *deflist); +extern List *deserialize_deflist(Datum txt); + +/* commands/foreigncmds.c */ +extern ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId); +extern void AlterForeignServerOwner_oid(Oid, Oid newOwnerId); +extern ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId); +extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId); +extern ObjectAddress CreateForeignDataWrapper(ParseState *pstate, CreateFdwStmt *stmt); +extern ObjectAddress AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt); +extern ObjectAddress CreateForeignServer(CreateForeignServerStmt *stmt); +extern ObjectAddress AlterForeignServer(AlterForeignServerStmt *stmt); +extern ObjectAddress CreateUserMapping(CreateUserMappingStmt *stmt); +extern ObjectAddress AlterUserMapping(AlterUserMappingStmt *stmt); +extern Oid RemoveUserMapping(DropUserMappingStmt *stmt); +extern void CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid); +extern void ImportForeignSchema(ImportForeignSchemaStmt *stmt); +extern Datum transformGenericOptions(Oid catalogId, + Datum oldOptions, + List *options, + Oid fdwvalidator); + +/* commands/amcmds.c */ +extern ObjectAddress CreateAccessMethod(CreateAmStmt *stmt); +extern Oid get_index_am_oid(const char *amname, bool missing_ok); +extern Oid get_table_am_oid(const char *amname, bool missing_ok); +extern Oid get_am_oid(const char *amname, bool missing_ok); +extern char *get_am_name(Oid amOid); + +/* support routines in commands/define.c */ + +extern char *defGetString(DefElem *def); +extern double defGetNumeric(DefElem *def); +extern bool defGetBoolean(DefElem *def); +extern int32 defGetInt32(DefElem *def); +extern int64 defGetInt64(DefElem *def); +extern Oid defGetObjectId(DefElem *def); +extern List *defGetQualifiedName(DefElem *def); +extern TypeName *defGetTypeName(DefElem *def); +extern int defGetTypeLength(DefElem *def); +extern List *defGetStringList(DefElem *def); +extern void errorConflictingDefElem(DefElem *defel, ParseState *pstate) pg_attribute_noreturn(); + +#endif /* DEFREM_H */ diff --git a/install/include/postgresql/server/commands/discard.h b/install/include/postgresql/server/commands/discard.h new file mode 100644 index 00000000000..68fbbce521c --- /dev/null +++ b/install/include/postgresql/server/commands/discard.h @@ -0,0 +1,20 @@ +/*------------------------------------------------------------------------- + * + * discard.h + * prototypes for discard.c. + * + * + * Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/commands/discard.h + * + *------------------------------------------------------------------------- + */ +#ifndef DISCARD_H +#define DISCARD_H + +#include "nodes/parsenodes.h" + +extern void DiscardCommand(DiscardStmt *stmt, bool isTopLevel); + +#endif /* DISCARD_H */ diff --git a/install/include/postgresql/server/commands/event_trigger.h b/install/include/postgresql/server/commands/event_trigger.h new file mode 100644 index 00000000000..eb84a1a9dc4 --- /dev/null +++ b/install/include/postgresql/server/commands/event_trigger.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------- + * + * event_trigger.h + * Declarations for command trigger handling. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/event_trigger.h + * + *------------------------------------------------------------------------- + */ +#ifndef EVENT_TRIGGER_H +#define EVENT_TRIGGER_H + +#include "catalog/dependency.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_event_trigger.h" +#include "nodes/parsenodes.h" +#include "tcop/cmdtag.h" +#include "tcop/deparse_utility.h" +#include "utils/aclchk_internal.h" + +typedef struct EventTriggerData +{ + NodeTag type; + const char *event; /* event name */ + Node *parsetree; /* parse tree */ + CommandTag tag; +} EventTriggerData; + +/* + * Reasons for relation rewrites. + * + * pg_event_trigger_table_rewrite_reason() uses these values, so make sure to + * update the documentation when changing this list. + */ +#define AT_REWRITE_ALTER_PERSISTENCE 0x01 +#define AT_REWRITE_DEFAULT_VAL 0x02 +#define AT_REWRITE_COLUMN_REWRITE 0x04 +#define AT_REWRITE_ACCESS_METHOD 0x08 + +/* + * EventTriggerData is the node type that is passed as fmgr "context" info + * when a function is called by the event trigger manager. + */ +#define CALLED_AS_EVENT_TRIGGER(fcinfo) \ + ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) + +extern Oid CreateEventTrigger(CreateEventTrigStmt *stmt); +extern Oid get_event_trigger_oid(const char *trigname, bool missing_ok); + +extern Oid AlterEventTrigger(AlterEventTrigStmt *stmt); +extern ObjectAddress AlterEventTriggerOwner(const char *name, Oid newOwnerId); +extern void AlterEventTriggerOwner_oid(Oid, Oid newOwnerId); + +extern bool EventTriggerSupportsObjectType(ObjectType obtype); +extern bool EventTriggerSupportsObjectClass(ObjectClass objclass); +extern void EventTriggerDDLCommandStart(Node *parsetree); +extern void EventTriggerDDLCommandEnd(Node *parsetree); +extern void EventTriggerSQLDrop(Node *parsetree); +extern void EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason); + +extern bool EventTriggerBeginCompleteQuery(void); +extern void EventTriggerEndCompleteQuery(void); +extern bool trackDroppedObjectsNeeded(void); +extern void EventTriggerSQLDropAddObject(const ObjectAddress *object, + bool original, bool normal); + +extern void EventTriggerInhibitCommandCollection(void); +extern void EventTriggerUndoInhibitCommandCollection(void); + +extern void EventTriggerCollectSimpleCommand(ObjectAddress address, + ObjectAddress secondaryObject, + Node *parsetree); + +extern void EventTriggerAlterTableStart(Node *parsetree); +extern void EventTriggerAlterTableRelid(Oid objectId); +extern void EventTriggerCollectAlterTableSubcmd(Node *subcmd, + ObjectAddress address); +extern void EventTriggerAlterTableEnd(void); + +extern void EventTriggerCollectGrant(InternalGrant *istmt); +extern void EventTriggerCollectAlterOpFam(AlterOpFamilyStmt *stmt, + Oid opfamoid, List *operators, + List *procedures); +extern void EventTriggerCollectCreateOpClass(CreateOpClassStmt *stmt, + Oid opcoid, List *operators, + List *procedures); +extern void EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, + Oid cfgId, Oid *dictIds, int ndicts); +extern void EventTriggerCollectAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt); + +#endif /* EVENT_TRIGGER_H */ diff --git a/install/include/postgresql/server/commands/explain.h b/install/include/postgresql/server/commands/explain.h new file mode 100644 index 00000000000..3d3e632a0cc --- /dev/null +++ b/install/include/postgresql/server/commands/explain.h @@ -0,0 +1,129 @@ +/*------------------------------------------------------------------------- + * + * explain.h + * prototypes for explain.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994-5, Regents of the University of California + * + * src/include/commands/explain.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXPLAIN_H +#define EXPLAIN_H + +#include "executor/executor.h" +#include "lib/stringinfo.h" +#include "parser/parse_node.h" + +typedef enum ExplainFormat +{ + EXPLAIN_FORMAT_TEXT, + EXPLAIN_FORMAT_XML, + EXPLAIN_FORMAT_JSON, + EXPLAIN_FORMAT_YAML +} ExplainFormat; + +typedef struct ExplainWorkersState +{ + int num_workers; /* # of worker processes the plan used */ + bool *worker_inited; /* per-worker state-initialized flags */ + StringInfoData *worker_str; /* per-worker transient output buffers */ + int *worker_state_save; /* per-worker grouping state save areas */ + StringInfo prev_str; /* saved output buffer while redirecting */ +} ExplainWorkersState; + +typedef struct ExplainState +{ + StringInfo str; /* output buffer */ + /* options */ + bool verbose; /* be verbose */ + bool analyze; /* print actual times */ + bool costs; /* print estimated costs */ + bool buffers; /* print buffer usage */ + bool wal; /* print WAL usage */ + bool timing; /* print detailed node timing */ + bool summary; /* print total planning and execution timing */ + bool settings; /* print modified settings */ + bool generic; /* generate a generic plan */ + ExplainFormat format; /* output format */ + /* state for output formatting --- not reset for each new plan tree */ + int indent; /* current indentation level */ + List *grouping_stack; /* format-specific grouping state */ + /* state related to the current plan tree (filled by ExplainPrintPlan) */ + PlannedStmt *pstmt; /* top of plan */ + List *rtable; /* range table */ + List *rtable_names; /* alias names for RTEs */ + List *deparse_cxt; /* context list for deparsing expressions */ + Bitmapset *printed_subplans; /* ids of SubPlans we've printed */ + bool hide_workers; /* set if we find an invisible Gather */ + /* state related to the current plan node */ + ExplainWorkersState *workers_state; /* needed if parallel plan */ +} ExplainState; + +/* Hook for plugins to get control in ExplainOneQuery() */ +typedef void (*ExplainOneQuery_hook_type) (Query *query, + int cursorOptions, + IntoClause *into, + ExplainState *es, + const char *queryString, + ParamListInfo params, + QueryEnvironment *queryEnv); +extern PGDLLIMPORT ExplainOneQuery_hook_type ExplainOneQuery_hook; + +/* Hook for plugins to get control in explain_get_index_name() */ +typedef const char *(*explain_get_index_name_hook_type) (Oid indexId); +extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook; + + +extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt, + ParamListInfo params, DestReceiver *dest); + +extern ExplainState *NewExplainState(void); + +extern TupleDesc ExplainResultDesc(ExplainStmt *stmt); + +extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into, + ExplainState *es, const char *queryString, + ParamListInfo params, QueryEnvironment *queryEnv); + +extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, + ExplainState *es, const char *queryString, + ParamListInfo params, QueryEnvironment *queryEnv, + const instr_time *planduration, + const BufferUsage *bufusage); + +extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc); +extern void ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc); + +extern void ExplainPrintJITSummary(ExplainState *es, QueryDesc *queryDesc); + +extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc); +extern void ExplainQueryParameters(ExplainState *es, ParamListInfo params, int maxlen); + +extern void ExplainBeginOutput(ExplainState *es); +extern void ExplainEndOutput(ExplainState *es); +extern void ExplainSeparatePlans(ExplainState *es); + +extern void ExplainPropertyList(const char *qlabel, List *data, + ExplainState *es); +extern void ExplainPropertyListNested(const char *qlabel, List *data, + ExplainState *es); +extern void ExplainPropertyText(const char *qlabel, const char *value, + ExplainState *es); +extern void ExplainPropertyInteger(const char *qlabel, const char *unit, + int64 value, ExplainState *es); +extern void ExplainPropertyUInteger(const char *qlabel, const char *unit, + uint64 value, ExplainState *es); +extern void ExplainPropertyFloat(const char *qlabel, const char *unit, + double value, int ndigits, ExplainState *es); +extern void ExplainPropertyBool(const char *qlabel, bool value, + ExplainState *es); + +extern void ExplainOpenGroup(const char *objtype, const char *labelname, + bool labeled, ExplainState *es); +extern void ExplainCloseGroup(const char *objtype, const char *labelname, + bool labeled, ExplainState *es); + +#endif /* EXPLAIN_H */ diff --git a/install/include/postgresql/server/commands/extension.h b/install/include/postgresql/server/commands/extension.h new file mode 100644 index 00000000000..ac664879287 --- /dev/null +++ b/install/include/postgresql/server/commands/extension.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * extension.h + * Extension management commands (create/drop extension). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/extension.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXTENSION_H +#define EXTENSION_H + +#include "catalog/objectaddress.h" +#include "parser/parse_node.h" + + +/* + * creating_extension is only true while running a CREATE EXTENSION or ALTER + * EXTENSION UPDATE command. It instructs recordDependencyOnCurrentExtension() + * to register a dependency on the current pg_extension object for each SQL + * object created by an extension script. It also instructs performDeletion() + * to remove such dependencies without following them, so that extension + * scripts can drop member objects without having to explicitly dissociate + * them from the extension first. + */ +extern PGDLLIMPORT bool creating_extension; +extern PGDLLIMPORT Oid CurrentExtensionObject; + + +extern ObjectAddress CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt); + +extern void RemoveExtensionById(Oid extId); + +extern ObjectAddress InsertExtensionTuple(const char *extName, Oid extOwner, + Oid schemaOid, bool relocatable, const char *extVersion, + Datum extConfig, Datum extCondition, + List *requiredExtensions); + +extern ObjectAddress ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt); + +extern ObjectAddress ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, + ObjectAddress *objAddr); + +extern Oid get_extension_oid(const char *extname, bool missing_ok); +extern char *get_extension_name(Oid ext_oid); +extern Oid get_extension_schema(Oid ext_oid); +extern bool extension_file_exists(const char *extensionName); + +extern Oid get_function_sibling_type(Oid funcoid, const char *typname); + +extern ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, + Oid *oldschema); + +#endif /* EXTENSION_H */ diff --git a/install/include/postgresql/server/commands/lockcmds.h b/install/include/postgresql/server/commands/lockcmds.h new file mode 100644 index 00000000000..6c298c71b36 --- /dev/null +++ b/install/include/postgresql/server/commands/lockcmds.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * lockcmds.h + * prototypes for lockcmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/lockcmds.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOCKCMDS_H +#define LOCKCMDS_H + +#include "nodes/parsenodes.h" + +/* + * LOCK + */ +extern void LockTableCommand(LockStmt *lockstmt); + +#endif /* LOCKCMDS_H */ diff --git a/install/include/postgresql/server/commands/matview.h b/install/include/postgresql/server/commands/matview.h new file mode 100644 index 00000000000..9eaa6212a19 --- /dev/null +++ b/install/include/postgresql/server/commands/matview.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * matview.h + * prototypes for matview.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/matview.h + * + *------------------------------------------------------------------------- + */ +#ifndef MATVIEW_H +#define MATVIEW_H + +#include "catalog/objectaddress.h" +#include "nodes/params.h" +#include "nodes/parsenodes.h" +#include "tcop/dest.h" +#include "utils/relcache.h" + + +extern void SetMatViewPopulatedState(Relation relation, bool newstate); + +extern ObjectAddress ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, + ParamListInfo params, QueryCompletion *qc); + +extern DestReceiver *CreateTransientRelDestReceiver(Oid transientoid); + +extern bool MatViewIncrementalMaintenanceIsEnabled(void); + +#endif /* MATVIEW_H */ diff --git a/install/include/postgresql/server/commands/policy.h b/install/include/postgresql/server/commands/policy.h new file mode 100644 index 00000000000..f3533920b6a --- /dev/null +++ b/install/include/postgresql/server/commands/policy.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * policy.h + * prototypes for policy.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/policy.h + * + *------------------------------------------------------------------------- + */ + +#ifndef POLICY_H +#define POLICY_H + +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" +#include "utils/relcache.h" + +extern void RelationBuildRowSecurity(Relation relation); + +extern void RemovePolicyById(Oid policy_id); + +extern bool RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id); + +extern ObjectAddress CreatePolicy(CreatePolicyStmt *stmt); +extern ObjectAddress AlterPolicy(AlterPolicyStmt *stmt); + +extern Oid get_relation_policy_oid(Oid relid, const char *policy_name, + bool missing_ok); + +extern ObjectAddress rename_policy(RenameStmt *stmt); + +extern bool relation_has_policies(Relation rel); + +#endif /* POLICY_H */ diff --git a/install/include/postgresql/server/commands/portalcmds.h b/install/include/postgresql/server/commands/portalcmds.h new file mode 100644 index 00000000000..96ade48d08a --- /dev/null +++ b/install/include/postgresql/server/commands/portalcmds.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * portalcmds.h + * prototypes for portalcmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/portalcmds.h + * + *------------------------------------------------------------------------- + */ +#ifndef PORTALCMDS_H +#define PORTALCMDS_H + +#include "nodes/parsenodes.h" +#include "parser/parse_node.h" +#include "utils/portal.h" + + +extern void PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo params, + bool isTopLevel); + +extern void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest, + QueryCompletion *qc); + +extern void PerformPortalClose(const char *name); + +extern void PortalCleanup(Portal portal); + +extern void PersistHoldablePortal(Portal portal); + +#endif /* PORTALCMDS_H */ diff --git a/install/include/postgresql/server/commands/prepare.h b/install/include/postgresql/server/commands/prepare.h new file mode 100644 index 00000000000..79f161561e5 --- /dev/null +++ b/install/include/postgresql/server/commands/prepare.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * prepare.h + * PREPARE, EXECUTE and DEALLOCATE commands, and prepared-stmt storage + * + * + * Copyright (c) 2002-2023, PostgreSQL Global Development Group + * + * src/include/commands/prepare.h + * + *------------------------------------------------------------------------- + */ +#ifndef PREPARE_H +#define PREPARE_H + +#include "commands/explain.h" +#include "datatype/timestamp.h" +#include "utils/plancache.h" + +/* + * The data structure representing a prepared statement. This is now just + * a thin veneer over a plancache entry --- the main addition is that of + * a name. + * + * Note: all subsidiary storage lives in the referenced plancache entry. + */ +typedef struct +{ + /* dynahash.c requires key to be first field */ + char stmt_name[NAMEDATALEN]; + CachedPlanSource *plansource; /* the actual cached plan */ + bool from_sql; /* prepared via SQL, not FE/BE protocol? */ + TimestampTz prepare_time; /* the time when the stmt was prepared */ +} PreparedStatement; + + +/* Utility statements PREPARE, EXECUTE, DEALLOCATE, EXPLAIN EXECUTE */ +extern void PrepareQuery(ParseState *pstate, PrepareStmt *stmt, + int stmt_location, int stmt_len); +extern void ExecuteQuery(ParseState *pstate, + ExecuteStmt *stmt, IntoClause *intoClause, + ParamListInfo params, + DestReceiver *dest, QueryCompletion *qc); +extern void DeallocateQuery(DeallocateStmt *stmt); +extern void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, + ExplainState *es, const char *queryString, + ParamListInfo params, QueryEnvironment *queryEnv); + +/* Low-level access to stored prepared statements */ +extern void StorePreparedStatement(const char *stmt_name, + CachedPlanSource *plansource, + bool from_sql); +extern PreparedStatement *FetchPreparedStatement(const char *stmt_name, + bool throwError); +extern void DropPreparedStatement(const char *stmt_name, bool showError); +extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt); +extern List *FetchPreparedStatementTargetList(PreparedStatement *stmt); + +extern void DropAllPreparedStatements(void); + +#endif /* PREPARE_H */ diff --git a/install/include/postgresql/server/commands/proclang.h b/install/include/postgresql/server/commands/proclang.h new file mode 100644 index 00000000000..08c68b8c177 --- /dev/null +++ b/install/include/postgresql/server/commands/proclang.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * proclang.h + * prototypes for proclang.c. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/proclang.h + * + *------------------------------------------------------------------------- + */ +#ifndef PROCLANG_H +#define PROCLANG_H + +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" + +extern ObjectAddress CreateProceduralLanguage(CreatePLangStmt *stmt); + +extern Oid get_language_oid(const char *langname, bool missing_ok); + +#endif /* PROCLANG_H */ diff --git a/install/include/postgresql/server/commands/progress.h b/install/include/postgresql/server/commands/progress.h new file mode 100644 index 00000000000..e5add413527 --- /dev/null +++ b/install/include/postgresql/server/commands/progress.h @@ -0,0 +1,154 @@ +/*------------------------------------------------------------------------- + * + * progress.h + * Constants used with the progress reporting facilities defined in + * backend_status.h. These are possibly interesting to extensions, so we + * expose them via this header file. Note that if you update these + * constants, you probably also need to update the views based on them + * in system_views.sql. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/progress.h + * + *------------------------------------------------------------------------- + */ +#ifndef PROGRESS_H +#define PROGRESS_H + +/* Progress parameters for (lazy) vacuum */ +#define PROGRESS_VACUUM_PHASE 0 +#define PROGRESS_VACUUM_TOTAL_HEAP_BLKS 1 +#define PROGRESS_VACUUM_HEAP_BLKS_SCANNED 2 +#define PROGRESS_VACUUM_HEAP_BLKS_VACUUMED 3 +#define PROGRESS_VACUUM_NUM_INDEX_VACUUMS 4 +#define PROGRESS_VACUUM_MAX_DEAD_TUPLES 5 +#define PROGRESS_VACUUM_NUM_DEAD_TUPLES 6 + +/* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */ +#define PROGRESS_VACUUM_PHASE_SCAN_HEAP 1 +#define PROGRESS_VACUUM_PHASE_VACUUM_INDEX 2 +#define PROGRESS_VACUUM_PHASE_VACUUM_HEAP 3 +#define PROGRESS_VACUUM_PHASE_INDEX_CLEANUP 4 +#define PROGRESS_VACUUM_PHASE_TRUNCATE 5 +#define PROGRESS_VACUUM_PHASE_FINAL_CLEANUP 6 + +/* Progress parameters for analyze */ +#define PROGRESS_ANALYZE_PHASE 0 +#define PROGRESS_ANALYZE_BLOCKS_TOTAL 1 +#define PROGRESS_ANALYZE_BLOCKS_DONE 2 +#define PROGRESS_ANALYZE_EXT_STATS_TOTAL 3 +#define PROGRESS_ANALYZE_EXT_STATS_COMPUTED 4 +#define PROGRESS_ANALYZE_CHILD_TABLES_TOTAL 5 +#define PROGRESS_ANALYZE_CHILD_TABLES_DONE 6 +#define PROGRESS_ANALYZE_CURRENT_CHILD_TABLE_RELID 7 + +/* Phases of analyze (as advertised via PROGRESS_ANALYZE_PHASE) */ +#define PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS 1 +#define PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS_INH 2 +#define PROGRESS_ANALYZE_PHASE_COMPUTE_STATS 3 +#define PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS 4 +#define PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE 5 + +/* Progress parameters for cluster */ +#define PROGRESS_CLUSTER_COMMAND 0 +#define PROGRESS_CLUSTER_PHASE 1 +#define PROGRESS_CLUSTER_INDEX_RELID 2 +#define PROGRESS_CLUSTER_HEAP_TUPLES_SCANNED 3 +#define PROGRESS_CLUSTER_HEAP_TUPLES_WRITTEN 4 +#define PROGRESS_CLUSTER_TOTAL_HEAP_BLKS 5 +#define PROGRESS_CLUSTER_HEAP_BLKS_SCANNED 6 +#define PROGRESS_CLUSTER_INDEX_REBUILD_COUNT 7 + +/* Phases of cluster (as advertised via PROGRESS_CLUSTER_PHASE) */ +#define PROGRESS_CLUSTER_PHASE_SEQ_SCAN_HEAP 1 +#define PROGRESS_CLUSTER_PHASE_INDEX_SCAN_HEAP 2 +#define PROGRESS_CLUSTER_PHASE_SORT_TUPLES 3 +#define PROGRESS_CLUSTER_PHASE_WRITE_NEW_HEAP 4 +#define PROGRESS_CLUSTER_PHASE_SWAP_REL_FILES 5 +#define PROGRESS_CLUSTER_PHASE_REBUILD_INDEX 6 +#define PROGRESS_CLUSTER_PHASE_FINAL_CLEANUP 7 + +/* Commands of PROGRESS_CLUSTER */ +#define PROGRESS_CLUSTER_COMMAND_CLUSTER 1 +#define PROGRESS_CLUSTER_COMMAND_VACUUM_FULL 2 + +/* Progress parameters for CREATE INDEX */ +/* 3, 4 and 5 reserved for "waitfor" metrics */ +#define PROGRESS_CREATEIDX_COMMAND 0 +#define PROGRESS_CREATEIDX_INDEX_OID 6 +#define PROGRESS_CREATEIDX_ACCESS_METHOD_OID 8 +#define PROGRESS_CREATEIDX_PHASE 9 /* AM-agnostic phase # */ +#define PROGRESS_CREATEIDX_SUBPHASE 10 /* phase # filled by AM */ +#define PROGRESS_CREATEIDX_TUPLES_TOTAL 11 +#define PROGRESS_CREATEIDX_TUPLES_DONE 12 +#define PROGRESS_CREATEIDX_PARTITIONS_TOTAL 13 +#define PROGRESS_CREATEIDX_PARTITIONS_DONE 14 +/* 15 and 16 reserved for "block number" metrics */ + +/* Phases of CREATE INDEX (as advertised via PROGRESS_CREATEIDX_PHASE) */ +#define PROGRESS_CREATEIDX_PHASE_WAIT_1 1 +#define PROGRESS_CREATEIDX_PHASE_BUILD 2 +#define PROGRESS_CREATEIDX_PHASE_WAIT_2 3 +#define PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN 4 +#define PROGRESS_CREATEIDX_PHASE_VALIDATE_SORT 5 +#define PROGRESS_CREATEIDX_PHASE_VALIDATE_TABLESCAN 6 +#define PROGRESS_CREATEIDX_PHASE_WAIT_3 7 +#define PROGRESS_CREATEIDX_PHASE_WAIT_4 8 +#define PROGRESS_CREATEIDX_PHASE_WAIT_5 9 + +/* + * Subphases of CREATE INDEX, for index_build. + */ +#define PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE 1 +/* Additional phases are defined by each AM */ + +/* Commands of PROGRESS_CREATEIDX */ +#define PROGRESS_CREATEIDX_COMMAND_CREATE 1 +#define PROGRESS_CREATEIDX_COMMAND_CREATE_CONCURRENTLY 2 +#define PROGRESS_CREATEIDX_COMMAND_REINDEX 3 +#define PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY 4 + +/* Lock holder wait counts */ +#define PROGRESS_WAITFOR_TOTAL 3 +#define PROGRESS_WAITFOR_DONE 4 +#define PROGRESS_WAITFOR_CURRENT_PID 5 + +/* Block numbers in a generic relation scan */ +#define PROGRESS_SCAN_BLOCKS_TOTAL 15 +#define PROGRESS_SCAN_BLOCKS_DONE 16 + +/* Progress parameters for pg_basebackup */ +#define PROGRESS_BASEBACKUP_PHASE 0 +#define PROGRESS_BASEBACKUP_BACKUP_TOTAL 1 +#define PROGRESS_BASEBACKUP_BACKUP_STREAMED 2 +#define PROGRESS_BASEBACKUP_TBLSPC_TOTAL 3 +#define PROGRESS_BASEBACKUP_TBLSPC_STREAMED 4 + +/* Phases of pg_basebackup (as advertised via PROGRESS_BASEBACKUP_PHASE) */ +#define PROGRESS_BASEBACKUP_PHASE_WAIT_CHECKPOINT 1 +#define PROGRESS_BASEBACKUP_PHASE_ESTIMATE_BACKUP_SIZE 2 +#define PROGRESS_BASEBACKUP_PHASE_STREAM_BACKUP 3 +#define PROGRESS_BASEBACKUP_PHASE_WAIT_WAL_ARCHIVE 4 +#define PROGRESS_BASEBACKUP_PHASE_TRANSFER_WAL 5 + +/* Progress parameters for PROGRESS_COPY */ +#define PROGRESS_COPY_BYTES_PROCESSED 0 +#define PROGRESS_COPY_BYTES_TOTAL 1 +#define PROGRESS_COPY_TUPLES_PROCESSED 2 +#define PROGRESS_COPY_TUPLES_EXCLUDED 3 +#define PROGRESS_COPY_COMMAND 4 +#define PROGRESS_COPY_TYPE 5 + +/* Commands of COPY (as advertised via PROGRESS_COPY_COMMAND) */ +#define PROGRESS_COPY_COMMAND_FROM 1 +#define PROGRESS_COPY_COMMAND_TO 2 + +/* Types of COPY commands (as advertised via PROGRESS_COPY_TYPE) */ +#define PROGRESS_COPY_TYPE_FILE 1 +#define PROGRESS_COPY_TYPE_PROGRAM 2 +#define PROGRESS_COPY_TYPE_PIPE 3 +#define PROGRESS_COPY_TYPE_CALLBACK 4 + +#endif diff --git a/install/include/postgresql/server/commands/publicationcmds.h b/install/include/postgresql/server/commands/publicationcmds.h new file mode 100644 index 00000000000..70d5e3680a2 --- /dev/null +++ b/install/include/postgresql/server/commands/publicationcmds.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * publicationcmds.h + * prototypes for publicationcmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/publicationcmds.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PUBLICATIONCMDS_H +#define PUBLICATIONCMDS_H + +#include "catalog/objectaddress.h" +#include "parser/parse_node.h" +#include "utils/inval.h" + +/* Same as MAXNUMMESSAGES in sinvaladt.c */ +#define MAX_RELCACHE_INVAL_MSGS 4096 + +extern ObjectAddress CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt); +extern void AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt); +extern void RemovePublicationById(Oid pubid); +extern void RemovePublicationRelById(Oid proid); +extern void RemovePublicationSchemaById(Oid psoid); + +extern ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId); +extern void AlterPublicationOwner_oid(Oid subid, Oid newOwnerId); +extern void InvalidatePublicationRels(List *relids); +extern bool pub_rf_contains_invalid_column(Oid pubid, Relation relation, + List *ancestors, bool pubviaroot); +extern bool pub_collist_contains_invalid_column(Oid pubid, Relation relation, + List *ancestors, bool pubviaroot); + +#endif /* PUBLICATIONCMDS_H */ diff --git a/install/include/postgresql/server/commands/schemacmds.h b/install/include/postgresql/server/commands/schemacmds.h new file mode 100644 index 00000000000..c8c771cef94 --- /dev/null +++ b/install/include/postgresql/server/commands/schemacmds.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * schemacmds.h + * prototypes for schemacmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/schemacmds.h + * + *------------------------------------------------------------------------- + */ + +#ifndef SCHEMACMDS_H +#define SCHEMACMDS_H + +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" + +extern Oid CreateSchemaCommand(CreateSchemaStmt *stmt, + const char *queryString, + int stmt_location, int stmt_len); + +extern ObjectAddress RenameSchema(const char *oldname, const char *newname); +extern ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId); +extern void AlterSchemaOwner_oid(Oid schemaoid, Oid newOwnerId); + +#endif /* SCHEMACMDS_H */ diff --git a/install/include/postgresql/server/commands/seclabel.h b/install/include/postgresql/server/commands/seclabel.h new file mode 100644 index 00000000000..e819fe99207 --- /dev/null +++ b/install/include/postgresql/server/commands/seclabel.h @@ -0,0 +1,34 @@ +/* + * seclabel.h + * + * Prototypes for functions in commands/seclabel.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + */ +#ifndef SECLABEL_H +#define SECLABEL_H + +#include "catalog/objectaddress.h" + +/* + * Internal APIs + */ +extern char *GetSecurityLabel(const ObjectAddress *object, + const char *provider); +extern void SetSecurityLabel(const ObjectAddress *object, + const char *provider, const char *label); +extern void DeleteSecurityLabel(const ObjectAddress *object); +extern void DeleteSharedSecurityLabel(Oid objectId, Oid classId); + +/* + * Statement and ESP hook support + */ +extern ObjectAddress ExecSecLabelStmt(SecLabelStmt *stmt); + +typedef void (*check_object_relabel_type) (const ObjectAddress *object, + const char *seclabel); +extern void register_label_provider(const char *provider_name, + check_object_relabel_type hook); + +#endif /* SECLABEL_H */ diff --git a/install/include/postgresql/server/commands/sequence.h b/install/include/postgresql/server/commands/sequence.h new file mode 100644 index 00000000000..7db7b3da7bc --- /dev/null +++ b/install/include/postgresql/server/commands/sequence.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------- + * + * sequence.h + * prototypes for sequence.c. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/sequence.h + * + *------------------------------------------------------------------------- + */ +#ifndef SEQUENCE_H +#define SEQUENCE_H + +#include "access/xlogreader.h" +#include "catalog/objectaddress.h" +#include "fmgr.h" +#include "lib/stringinfo.h" +#include "nodes/parsenodes.h" +#include "parser/parse_node.h" +#include "storage/relfilelocator.h" + + +typedef struct FormData_pg_sequence_data +{ + int64 last_value; + int64 log_cnt; + bool is_called; +} FormData_pg_sequence_data; + +typedef FormData_pg_sequence_data *Form_pg_sequence_data; + +/* + * Columns of a sequence relation + */ + +#define SEQ_COL_LASTVAL 1 +#define SEQ_COL_LOG 2 +#define SEQ_COL_CALLED 3 + +#define SEQ_COL_FIRSTCOL SEQ_COL_LASTVAL +#define SEQ_COL_LASTCOL SEQ_COL_CALLED + +/* XLOG stuff */ +#define XLOG_SEQ_LOG 0x00 + +typedef struct xl_seq_rec +{ + RelFileLocator locator; + /* SEQUENCE TUPLE DATA FOLLOWS AT THE END */ +} xl_seq_rec; + +extern int64 nextval_internal(Oid relid, bool check_permissions); +extern Datum nextval(PG_FUNCTION_ARGS); +extern List *sequence_options(Oid relid); + +extern ObjectAddress DefineSequence(ParseState *pstate, CreateSeqStmt *seq); +extern ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt); +extern void SequenceChangePersistence(Oid relid, char newrelpersistence); +extern void DeleteSequenceTuple(Oid relid); +extern void ResetSequence(Oid seq_relid); +extern void ResetSequenceCaches(void); + +extern void seq_redo(XLogReaderState *record); +extern void seq_desc(StringInfo buf, XLogReaderState *record); +extern const char *seq_identify(uint8 info); +extern void seq_mask(char *page, BlockNumber blkno); + +#endif /* SEQUENCE_H */ diff --git a/install/include/postgresql/server/commands/subscriptioncmds.h b/install/include/postgresql/server/commands/subscriptioncmds.h new file mode 100644 index 00000000000..214dc6c29e4 --- /dev/null +++ b/install/include/postgresql/server/commands/subscriptioncmds.h @@ -0,0 +1,31 @@ +/*------------------------------------------------------------------------- + * + * subscriptioncmds.h + * prototypes for subscriptioncmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/subscriptioncmds.h + * + *------------------------------------------------------------------------- + */ + +#ifndef SUBSCRIPTIONCMDS_H +#define SUBSCRIPTIONCMDS_H + +#include "catalog/objectaddress.h" +#include "parser/parse_node.h" + +extern ObjectAddress CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, + bool isTopLevel); +extern ObjectAddress AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, bool isTopLevel); +extern void DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel); + +extern ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId); +extern void AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId); + +extern char defGetStreamingMode(DefElem *def); + +#endif /* SUBSCRIPTIONCMDS_H */ diff --git a/install/include/postgresql/server/commands/tablecmds.h b/install/include/postgresql/server/commands/tablecmds.h new file mode 100644 index 00000000000..16b61266690 --- /dev/null +++ b/install/include/postgresql/server/commands/tablecmds.h @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------------- + * + * tablecmds.h + * prototypes for tablecmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/tablecmds.h + * + *------------------------------------------------------------------------- + */ +#ifndef TABLECMDS_H +#define TABLECMDS_H + +#include "access/htup.h" +#include "catalog/dependency.h" +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" +#include "storage/lock.h" +#include "utils/relcache.h" + +struct AlterTableUtilityContext; /* avoid including tcop/utility.h here */ + + +extern ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, + ObjectAddress *typaddress, const char *queryString); + +extern void RemoveRelations(DropStmt *drop); + +extern Oid AlterTableLookupRelation(AlterTableStmt *stmt, LOCKMODE lockmode); + +extern void AlterTable(AlterTableStmt *stmt, LOCKMODE lockmode, + struct AlterTableUtilityContext *context); + +extern LOCKMODE AlterTableGetLockLevel(List *cmds); + +extern void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode); + +extern void AlterTableInternal(Oid relid, List *cmds, bool recurse); + +extern Oid AlterTableMoveAll(AlterTableMoveAllStmt *stmt); + +extern ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, + Oid *oldschema); + +extern void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, + Oid nspOid, ObjectAddresses *objsMoved); + +extern void AlterRelationNamespaceInternal(Relation classRel, Oid relOid, + Oid oldNspOid, Oid newNspOid, + bool hasDependEntry, + ObjectAddresses *objsMoved); + +extern void CheckTableNotInUse(Relation rel, const char *stmt); + +extern void ExecuteTruncate(TruncateStmt *stmt); +extern void ExecuteTruncateGuts(List *explicit_rels, + List *relids, + List *relids_logged, + DropBehavior behavior, + bool restart_seqs, + bool run_as_table_owner); + +extern void SetRelationHasSubclass(Oid relationId, bool relhassubclass); + +extern bool CheckRelationTableSpaceMove(Relation rel, Oid newTableSpaceId); +extern void SetRelationTableSpace(Relation rel, Oid newTableSpaceId, + RelFileNumber newRelFilenumber); + +extern ObjectAddress renameatt(RenameStmt *stmt); + +extern ObjectAddress RenameConstraint(RenameStmt *stmt); + +extern ObjectAddress RenameRelation(RenameStmt *stmt); + +extern void RenameRelationInternal(Oid myrelid, + const char *newrelname, bool is_internal, + bool is_index); + +extern void ResetRelRewrite(Oid myrelid); + +extern void find_composite_type_dependencies(Oid typeOid, + Relation origRelation, + const char *origTypeName); + +extern void check_of_type(HeapTuple typetuple); + +extern void register_on_commit_action(Oid relid, OnCommitAction action); +extern void remove_on_commit_action(Oid relid); + +extern void PreCommit_on_commit_actions(void); +extern void AtEOXact_on_commit_actions(bool isCommit); +extern void AtEOSubXact_on_commit_actions(bool isCommit, + SubTransactionId mySubid, + SubTransactionId parentSubid); + +extern void RangeVarCallbackOwnsTable(const RangeVar *relation, + Oid relId, Oid oldRelId, void *arg); + +extern void RangeVarCallbackOwnsRelation(const RangeVar *relation, + Oid relId, Oid oldRelId, void *arg); +extern bool PartConstraintImpliedByRelConstraint(Relation scanrel, + List *partConstraint); + +#endif /* TABLECMDS_H */ diff --git a/install/include/postgresql/server/commands/tablespace.h b/install/include/postgresql/server/commands/tablespace.h new file mode 100644 index 00000000000..f1961c18130 --- /dev/null +++ b/install/include/postgresql/server/commands/tablespace.h @@ -0,0 +1,69 @@ +/*------------------------------------------------------------------------- + * + * tablespace.h + * Tablespace management commands (create/drop tablespace). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/tablespace.h + * + *------------------------------------------------------------------------- + */ +#ifndef TABLESPACE_H +#define TABLESPACE_H + +#include "access/xlogreader.h" +#include "catalog/objectaddress.h" +#include "lib/stringinfo.h" +#include "nodes/parsenodes.h" + +extern PGDLLIMPORT bool allow_in_place_tablespaces; + +/* XLOG stuff */ +#define XLOG_TBLSPC_CREATE 0x00 +#define XLOG_TBLSPC_DROP 0x10 + +typedef struct xl_tblspc_create_rec +{ + Oid ts_id; + char ts_path[FLEXIBLE_ARRAY_MEMBER]; /* null-terminated string */ +} xl_tblspc_create_rec; + +typedef struct xl_tblspc_drop_rec +{ + Oid ts_id; +} xl_tblspc_drop_rec; + +typedef struct TableSpaceOpts +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + float8 random_page_cost; + float8 seq_page_cost; + int effective_io_concurrency; + int maintenance_io_concurrency; +} TableSpaceOpts; + +extern Oid CreateTableSpace(CreateTableSpaceStmt *stmt); +extern void DropTableSpace(DropTableSpaceStmt *stmt); +extern ObjectAddress RenameTableSpace(const char *oldname, const char *newname); +extern Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); + +extern void TablespaceCreateDbspace(Oid spcOid, Oid dbOid, bool isRedo); + +extern Oid GetDefaultTablespace(char relpersistence, bool partitioned); + +extern void PrepareTempTablespaces(void); + +extern Oid get_tablespace_oid(const char *tablespacename, bool missing_ok); +extern char *get_tablespace_name(Oid spc_oid); + +extern bool directory_is_empty(const char *path); +extern void remove_tablespace_symlink(const char *linkloc); + +extern void tblspc_redo(XLogReaderState *record); +extern void tblspc_desc(StringInfo buf, XLogReaderState *record); +extern const char *tblspc_identify(uint8 info); + +#endif /* TABLESPACE_H */ diff --git a/install/include/postgresql/server/commands/trigger.h b/install/include/postgresql/server/commands/trigger.h new file mode 100644 index 00000000000..d45fa49ac35 --- /dev/null +++ b/install/include/postgresql/server/commands/trigger.h @@ -0,0 +1,290 @@ +/*------------------------------------------------------------------------- + * + * trigger.h + * Declarations for trigger handling. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/trigger.h + * + *------------------------------------------------------------------------- + */ +#ifndef TRIGGER_H +#define TRIGGER_H + +#include "access/tableam.h" +#include "catalog/objectaddress.h" +#include "nodes/execnodes.h" +#include "nodes/parsenodes.h" + +/* + * TriggerData is the node type that is passed as fmgr "context" info + * when a function is called by the trigger manager. + */ + +#define CALLED_AS_TRIGGER(fcinfo) \ + ((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData)) + +typedef uint32 TriggerEvent; + +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; + +/* + * The state for capturing old and new tuples into transition tables for a + * single ModifyTable node (or other operation source, e.g. copyfrom.c). + * + * This is per-caller to avoid conflicts in setting + * tcs_original_insert_tuple. Note, however, that the pointed-to + * private data may be shared across multiple callers. + */ +struct AfterTriggersTableData; /* private in trigger.c */ + +typedef struct TransitionCaptureState +{ + /* + * Is there at least one trigger specifying each transition relation on + * the relation explicitly named in the DML statement or COPY command? + * Note: in current usage, these flags could be part of the private state, + * but it seems possibly useful to let callers see them. + */ + bool tcs_delete_old_table; + bool tcs_update_old_table; + bool tcs_update_new_table; + bool tcs_insert_new_table; + + /* + * For INSERT and COPY, it would be wasteful to convert tuples from child + * format to parent format after they have already been converted in the + * opposite direction during routing. In that case we bypass conversion + * and allow the inserting code (copyfrom.c and nodeModifyTable.c) to + * provide a slot containing the original tuple directly. + */ + TupleTableSlot *tcs_original_insert_tuple; + + /* + * Private data including the tuplestore(s) into which to insert tuples. + */ + struct AfterTriggersTableData *tcs_insert_private; + struct AfterTriggersTableData *tcs_update_private; + struct AfterTriggersTableData *tcs_delete_private; +} TransitionCaptureState; + +/* + * TriggerEvent bit flags + * + * Note that we assume different event types (INSERT/DELETE/UPDATE/TRUNCATE) + * can't be OR'd together in a single TriggerEvent. This is unlike the + * situation for pg_trigger rows, so pg_trigger.tgtype uses a different + * representation! + */ +#define TRIGGER_EVENT_INSERT 0x00000000 +#define TRIGGER_EVENT_DELETE 0x00000001 +#define TRIGGER_EVENT_UPDATE 0x00000002 +#define TRIGGER_EVENT_TRUNCATE 0x00000003 +#define TRIGGER_EVENT_OPMASK 0x00000003 + +#define TRIGGER_EVENT_ROW 0x00000004 + +#define TRIGGER_EVENT_BEFORE 0x00000008 +#define TRIGGER_EVENT_AFTER 0x00000000 +#define TRIGGER_EVENT_INSTEAD 0x00000010 +#define TRIGGER_EVENT_TIMINGMASK 0x00000018 + +/* More TriggerEvent flags, used only within trigger.c */ + +#define AFTER_TRIGGER_DEFERRABLE 0x00000020 +#define AFTER_TRIGGER_INITDEFERRED 0x00000040 + +#define TRIGGER_FIRED_BY_INSERT(event) \ + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_INSERT) + +#define TRIGGER_FIRED_BY_DELETE(event) \ + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_DELETE) + +#define TRIGGER_FIRED_BY_UPDATE(event) \ + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE) + +#define TRIGGER_FIRED_BY_TRUNCATE(event) \ + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_TRUNCATE) + +#define TRIGGER_FIRED_FOR_ROW(event) \ + ((event) & TRIGGER_EVENT_ROW) + +#define TRIGGER_FIRED_FOR_STATEMENT(event) \ + (!TRIGGER_FIRED_FOR_ROW(event)) + +#define TRIGGER_FIRED_BEFORE(event) \ + (((event) & TRIGGER_EVENT_TIMINGMASK) == TRIGGER_EVENT_BEFORE) + +#define TRIGGER_FIRED_AFTER(event) \ + (((event) & TRIGGER_EVENT_TIMINGMASK) == TRIGGER_EVENT_AFTER) + +#define TRIGGER_FIRED_INSTEAD(event) \ + (((event) & TRIGGER_EVENT_TIMINGMASK) == TRIGGER_EVENT_INSTEAD) + +/* + * Definitions for replication role based firing. + */ +#define SESSION_REPLICATION_ROLE_ORIGIN 0 +#define SESSION_REPLICATION_ROLE_REPLICA 1 +#define SESSION_REPLICATION_ROLE_LOCAL 2 +extern PGDLLIMPORT int SessionReplicationRole; + +/* + * States at which a trigger can be fired. These are the + * possible values for pg_trigger.tgenabled. + */ +#define TRIGGER_FIRES_ON_ORIGIN 'O' +#define TRIGGER_FIRES_ALWAYS 'A' +#define TRIGGER_FIRES_ON_REPLICA 'R' +#define TRIGGER_DISABLED 'D' + +extern ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString, + Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, + Oid funcoid, Oid parentTriggerOid, Node *whenClause, + bool isInternal, bool in_partition); +extern ObjectAddress CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, + Oid relOid, Oid refRelOid, Oid constraintOid, + Oid indexOid, Oid funcoid, Oid parentTriggerOid, + Node *whenClause, bool isInternal, bool in_partition, + char trigger_fires_when); + +extern void TriggerSetParentTrigger(Relation trigRel, + Oid childTrigId, + Oid parentTrigId, + Oid childTableId); +extern void RemoveTriggerById(Oid trigOid); +extern Oid get_trigger_oid(Oid relid, const char *trigname, bool missing_ok); + +extern ObjectAddress renametrig(RenameStmt *stmt); + +extern void EnableDisableTrigger(Relation rel, const char *tgname, Oid tgparent, + char fires_when, bool skip_system, bool recurse, + LOCKMODE lockmode); + +extern void RelationBuildTriggers(Relation relation); + +extern TriggerDesc *CopyTriggerDesc(TriggerDesc *trigdesc); + +extern const char *FindTriggerIncompatibleWithInheritance(TriggerDesc *trigdesc); + +extern TransitionCaptureState *MakeTransitionCaptureState(TriggerDesc *trigdesc, + Oid relid, CmdType cmdType); + +extern void FreeTriggerDesc(TriggerDesc *trigdesc); + +extern void ExecBSInsertTriggers(EState *estate, + ResultRelInfo *relinfo); +extern void ExecASInsertTriggers(EState *estate, + ResultRelInfo *relinfo, + TransitionCaptureState *transition_capture); +extern bool ExecBRInsertTriggers(EState *estate, + ResultRelInfo *relinfo, + TupleTableSlot *slot); +extern void ExecARInsertTriggers(EState *estate, + ResultRelInfo *relinfo, + TupleTableSlot *slot, + List *recheckIndexes, + TransitionCaptureState *transition_capture); +extern bool ExecIRInsertTriggers(EState *estate, + ResultRelInfo *relinfo, + TupleTableSlot *slot); +extern void ExecBSDeleteTriggers(EState *estate, + ResultRelInfo *relinfo); +extern void ExecASDeleteTriggers(EState *estate, + ResultRelInfo *relinfo, + TransitionCaptureState *transition_capture); +extern bool ExecBRDeleteTriggers(EState *estate, + EPQState *epqstate, + ResultRelInfo *relinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TupleTableSlot **epqslot, + TM_Result *tmresult, + TM_FailureData *tmfd); +extern void ExecARDeleteTriggers(EState *estate, + ResultRelInfo *relinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TransitionCaptureState *transition_capture, + bool is_crosspart_update); +extern bool ExecIRDeleteTriggers(EState *estate, + ResultRelInfo *relinfo, + HeapTuple trigtuple); +extern void ExecBSUpdateTriggers(EState *estate, + ResultRelInfo *relinfo); +extern void ExecASUpdateTriggers(EState *estate, + ResultRelInfo *relinfo, + TransitionCaptureState *transition_capture); +extern bool ExecBRUpdateTriggers(EState *estate, + EPQState *epqstate, + ResultRelInfo *relinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TupleTableSlot *newslot, + TM_Result *tmresult, + TM_FailureData *tmfd); +extern void ExecARUpdateTriggers(EState *estate, + ResultRelInfo *relinfo, + ResultRelInfo *src_partinfo, + ResultRelInfo *dst_partinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TupleTableSlot *newslot, + List *recheckIndexes, + TransitionCaptureState *transition_capture, + bool is_crosspart_update); +extern bool ExecIRUpdateTriggers(EState *estate, + ResultRelInfo *relinfo, + HeapTuple trigtuple, + TupleTableSlot *newslot); +extern void ExecBSTruncateTriggers(EState *estate, + ResultRelInfo *relinfo); +extern void ExecASTruncateTriggers(EState *estate, + ResultRelInfo *relinfo); + +extern void AfterTriggerBeginXact(void); +extern void AfterTriggerBeginQuery(void); +extern void AfterTriggerEndQuery(EState *estate); +extern void AfterTriggerFireDeferred(void); +extern void AfterTriggerEndXact(bool isCommit); +extern void AfterTriggerBeginSubXact(void); +extern void AfterTriggerEndSubXact(bool isCommit); +extern void AfterTriggerSetState(ConstraintsSetStmt *stmt); +extern bool AfterTriggerPendingOnRel(Oid relid); + + +/* + * in utils/adt/ri_triggers.c + */ +extern bool RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel, + TupleTableSlot *oldslot, TupleTableSlot *newslot); +extern bool RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel, + TupleTableSlot *oldslot, TupleTableSlot *newslot); +extern bool RI_Initial_Check(Trigger *trigger, + Relation fk_rel, Relation pk_rel); +extern void RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, + Relation pk_rel); + +/* result values for RI_FKey_trigger_type: */ +#define RI_TRIGGER_PK 1 /* is a trigger on the PK relation */ +#define RI_TRIGGER_FK 2 /* is a trigger on the FK relation */ +#define RI_TRIGGER_NONE 0 /* is not an RI trigger function */ + +extern int RI_FKey_trigger_type(Oid tgfoid); + +#endif /* TRIGGER_H */ diff --git a/install/include/postgresql/server/commands/typecmds.h b/install/include/postgresql/server/commands/typecmds.h new file mode 100644 index 00000000000..1313d6485e3 --- /dev/null +++ b/install/include/postgresql/server/commands/typecmds.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * typecmds.h + * prototypes for typecmds.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/typecmds.h + * + *------------------------------------------------------------------------- + */ +#ifndef TYPECMDS_H +#define TYPECMDS_H + +#include "access/htup.h" +#include "catalog/dependency.h" +#include "parser/parse_node.h" + + +#define DEFAULT_TYPDELIM ',' + +extern ObjectAddress DefineType(ParseState *pstate, List *names, List *parameters); +extern void RemoveTypeById(Oid typeOid); +extern ObjectAddress DefineDomain(CreateDomainStmt *stmt); +extern ObjectAddress DefineEnum(CreateEnumStmt *stmt); +extern ObjectAddress DefineRange(ParseState *pstate, CreateRangeStmt *stmt); +extern ObjectAddress AlterEnum(AlterEnumStmt *stmt); +extern ObjectAddress DefineCompositeType(RangeVar *typevar, List *coldeflist); +extern Oid AssignTypeArrayOid(void); +extern Oid AssignTypeMultirangeOid(void); +extern Oid AssignTypeMultirangeArrayOid(void); + +extern ObjectAddress AlterDomainDefault(List *names, Node *defaultRaw); +extern ObjectAddress AlterDomainNotNull(List *names, bool notNull); +extern ObjectAddress AlterDomainAddConstraint(List *names, Node *newConstraint, + ObjectAddress *constrAddr); +extern ObjectAddress AlterDomainValidateConstraint(List *names, const char *constrName); +extern ObjectAddress AlterDomainDropConstraint(List *names, const char *constrName, + DropBehavior behavior, bool missing_ok); + +extern void checkDomainOwner(HeapTuple tup); + +extern ObjectAddress RenameType(RenameStmt *stmt); + +extern ObjectAddress AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype); +extern void AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry); +extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId); + +extern ObjectAddress AlterTypeNamespace(List *names, const char *newschema, + ObjectType objecttype, Oid *oldschema); +extern Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved); +extern Oid AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, + bool isImplicitArray, + bool errorOnTableType, + ObjectAddresses *objsMoved); + +extern ObjectAddress AlterType(AlterTypeStmt *stmt); + +#endif /* TYPECMDS_H */ diff --git a/install/include/postgresql/server/commands/user.h b/install/include/postgresql/server/commands/user.h new file mode 100644 index 00000000000..97dcb93791b --- /dev/null +++ b/install/include/postgresql/server/commands/user.h @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------- + * + * user.h + * Commands for manipulating roles (formerly called users). + * + * + * src/include/commands/user.h + * + *------------------------------------------------------------------------- + */ +#ifndef USER_H +#define USER_H + +#include "catalog/objectaddress.h" +#include "libpq/crypt.h" +#include "nodes/parsenodes.h" +#include "parser/parse_node.h" +#include "utils/guc.h" + +/* GUCs */ +extern PGDLLIMPORT int Password_encryption; /* values from enum PasswordType */ +extern PGDLLIMPORT char *createrole_self_grant; + +/* Hook to check passwords in CreateRole() and AlterRole() */ +typedef void (*check_password_hook_type) (const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null); + +extern PGDLLIMPORT check_password_hook_type check_password_hook; + +extern Oid CreateRole(ParseState *pstate, CreateRoleStmt *stmt); +extern Oid AlterRole(ParseState *pstate, AlterRoleStmt *stmt); +extern Oid AlterRoleSet(AlterRoleSetStmt *stmt); +extern void DropRole(DropRoleStmt *stmt); +extern void GrantRole(ParseState *pstate, GrantRoleStmt *stmt); +extern ObjectAddress RenameRole(const char *oldname, const char *newname); +extern void DropOwnedObjects(DropOwnedStmt *stmt); +extern void ReassignOwnedObjects(ReassignOwnedStmt *stmt); +extern List *roleSpecsToIds(List *memberNames); + +extern bool check_createrole_self_grant(char **newval, void **extra, + GucSource source); +extern void assign_createrole_self_grant(const char *newval, void *extra); + +#endif /* USER_H */ diff --git a/install/include/postgresql/server/commands/vacuum.h b/install/include/postgresql/server/commands/vacuum.h new file mode 100644 index 00000000000..39fbd5f10a5 --- /dev/null +++ b/install/include/postgresql/server/commands/vacuum.h @@ -0,0 +1,386 @@ +/*------------------------------------------------------------------------- + * + * vacuum.h + * header file for postgres vacuum cleaner and statistics analyzer + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/vacuum.h + * + *------------------------------------------------------------------------- + */ +#ifndef VACUUM_H +#define VACUUM_H + +#include "access/htup.h" +#include "access/genam.h" +#include "access/parallel.h" +#include "catalog/pg_class.h" +#include "catalog/pg_statistic.h" +#include "catalog/pg_type.h" +#include "parser/parse_node.h" +#include "storage/buf.h" +#include "storage/lock.h" +#include "utils/relcache.h" + +/* + * Flags for amparallelvacuumoptions to control the participation of bulkdelete + * and vacuumcleanup in parallel vacuum. + */ + +/* + * Both bulkdelete and vacuumcleanup are disabled by default. This will be + * used by IndexAM's that don't want to or cannot participate in parallel + * vacuum. For example, if an index AM doesn't have a way to communicate the + * index statistics allocated by the first ambulkdelete call to the subsequent + * ones until amvacuumcleanup, the index AM cannot participate in parallel + * vacuum. + */ +#define VACUUM_OPTION_NO_PARALLEL 0 + +/* + * bulkdelete can be performed in parallel. This option can be used by + * index AMs that need to scan indexes to delete tuples. + */ +#define VACUUM_OPTION_PARALLEL_BULKDEL (1 << 0) + +/* + * vacuumcleanup can be performed in parallel if bulkdelete is not performed + * yet. This will be used by IndexAM's that can scan the index if the + * bulkdelete is not performed. + */ +#define VACUUM_OPTION_PARALLEL_COND_CLEANUP (1 << 1) + +/* + * vacuumcleanup can be performed in parallel even if bulkdelete has already + * processed the index. This will be used by IndexAM's that scan the index + * during the cleanup phase of index irrespective of whether the index is + * already scanned or not during bulkdelete phase. + */ +#define VACUUM_OPTION_PARALLEL_CLEANUP (1 << 2) + +/* value for checking vacuum flags */ +#define VACUUM_OPTION_MAX_VALID_VALUE ((1 << 3) - 1) + +/* Abstract type for parallel vacuum state */ +typedef struct ParallelVacuumState ParallelVacuumState; + +/*---------- + * ANALYZE builds one of these structs for each attribute (column) that is + * to be analyzed. The struct and subsidiary data are in anl_context, + * so they live until the end of the ANALYZE operation. + * + * The type-specific typanalyze function is passed a pointer to this struct + * and must return true to continue analysis, false to skip analysis of this + * column. In the true case it must set the compute_stats and minrows fields, + * and can optionally set extra_data to pass additional info to compute_stats. + * minrows is its request for the minimum number of sample rows to be gathered + * (but note this request might not be honored, eg if there are fewer rows + * than that in the table). + * + * The compute_stats routine will be called after sample rows have been + * gathered. Aside from this struct, it is passed: + * fetchfunc: a function for accessing the column values from the + * sample rows + * samplerows: the number of sample tuples + * totalrows: estimated total number of rows in relation + * The fetchfunc may be called with rownum running from 0 to samplerows-1. + * It returns a Datum and an isNull flag. + * + * compute_stats should set stats_valid true if it is able to compute + * any useful statistics. If it does, the remainder of the struct holds + * the information to be stored in a pg_statistic row for the column. Be + * careful to allocate any pointed-to data in anl_context, which will NOT + * be CurrentMemoryContext when compute_stats is called. + * + * Note: all comparisons done for statistical purposes should use the + * underlying column's collation (attcollation), except in situations + * where a noncollatable container type contains a collatable type; + * in that case use the type's default collation. Be sure to record + * the appropriate collation in stacoll. + *---------- + */ +typedef struct VacAttrStats *VacAttrStatsP; + +typedef Datum (*AnalyzeAttrFetchFunc) (VacAttrStatsP stats, int rownum, + bool *isNull); + +typedef void (*AnalyzeAttrComputeStatsFunc) (VacAttrStatsP stats, + AnalyzeAttrFetchFunc fetchfunc, + int samplerows, + double totalrows); + +typedef struct VacAttrStats +{ + /* + * These fields are set up by the main ANALYZE code before invoking the + * type-specific typanalyze function. + * + * Note: do not assume that the data being analyzed has the same datatype + * shown in attr, ie do not trust attr->atttypid, attlen, etc. This is + * because some index opclasses store a different type than the underlying + * column/expression. Instead use attrtypid, attrtypmod, and attrtype for + * information about the datatype being fed to the typanalyze function. + * Likewise, use attrcollid not attr->attcollation. + */ + Form_pg_attribute attr; /* copy of pg_attribute row for column */ + Oid attrtypid; /* type of data being analyzed */ + int32 attrtypmod; /* typmod of data being analyzed */ + Form_pg_type attrtype; /* copy of pg_type row for attrtypid */ + Oid attrcollid; /* collation of data being analyzed */ + MemoryContext anl_context; /* where to save long-lived data */ + + /* + * These fields must be filled in by the typanalyze routine, unless it + * returns false. + */ + AnalyzeAttrComputeStatsFunc compute_stats; /* function pointer */ + int minrows; /* Minimum # of rows wanted for stats */ + void *extra_data; /* for extra type-specific data */ + + /* + * These fields are to be filled in by the compute_stats routine. (They + * are initialized to zero when the struct is created.) + */ + bool stats_valid; + float4 stanullfrac; /* fraction of entries that are NULL */ + int32 stawidth; /* average width of column values */ + float4 stadistinct; /* # distinct values */ + int16 stakind[STATISTIC_NUM_SLOTS]; + Oid staop[STATISTIC_NUM_SLOTS]; + Oid stacoll[STATISTIC_NUM_SLOTS]; + int numnumbers[STATISTIC_NUM_SLOTS]; + float4 *stanumbers[STATISTIC_NUM_SLOTS]; + int numvalues[STATISTIC_NUM_SLOTS]; + Datum *stavalues[STATISTIC_NUM_SLOTS]; + + /* + * These fields describe the stavalues[n] element types. They will be + * initialized to match attrtypid, but a custom typanalyze function might + * want to store an array of something other than the analyzed column's + * elements. It should then overwrite these fields. + */ + Oid statypid[STATISTIC_NUM_SLOTS]; + int16 statyplen[STATISTIC_NUM_SLOTS]; + bool statypbyval[STATISTIC_NUM_SLOTS]; + char statypalign[STATISTIC_NUM_SLOTS]; + + /* + * These fields are private to the main ANALYZE code and should not be + * looked at by type-specific functions. + */ + int tupattnum; /* attribute number within tuples */ + HeapTuple *rows; /* access info for std fetch function */ + TupleDesc tupDesc; + Datum *exprvals; /* access info for index fetch function */ + bool *exprnulls; + int rowstride; +} VacAttrStats; + +/* flag bits for VacuumParams->options */ +#define VACOPT_VACUUM 0x01 /* do VACUUM */ +#define VACOPT_ANALYZE 0x02 /* do ANALYZE */ +#define VACOPT_VERBOSE 0x04 /* output INFO instrumentation messages */ +#define VACOPT_FREEZE 0x08 /* FREEZE option */ +#define VACOPT_FULL 0x10 /* FULL (non-concurrent) vacuum */ +#define VACOPT_SKIP_LOCKED 0x20 /* skip if cannot get lock */ +#define VACOPT_PROCESS_MAIN 0x40 /* process main relation */ +#define VACOPT_PROCESS_TOAST 0x80 /* process the TOAST table, if any */ +#define VACOPT_DISABLE_PAGE_SKIPPING 0x100 /* don't skip any pages */ +#define VACOPT_SKIP_DATABASE_STATS 0x200 /* skip vac_update_datfrozenxid() */ +#define VACOPT_ONLY_DATABASE_STATS 0x400 /* only vac_update_datfrozenxid() */ + +/* + * Values used by index_cleanup and truncate params. + * + * VACOPTVALUE_UNSPECIFIED is used as an initial placeholder when VACUUM + * command has no explicit value. When that happens the final usable value + * comes from the corresponding reloption (though the reloption default is + * usually used). + */ +typedef enum VacOptValue +{ + VACOPTVALUE_UNSPECIFIED = 0, + VACOPTVALUE_AUTO, + VACOPTVALUE_DISABLED, + VACOPTVALUE_ENABLED, +} VacOptValue; + +/* + * Parameters customizing behavior of VACUUM and ANALYZE. + * + * Note that at least one of VACOPT_VACUUM and VACOPT_ANALYZE must be set + * in options. + * + * When adding a new VacuumParam member, consider adding it to vacuumdb as + * well. + */ +typedef struct VacuumParams +{ + bits32 options; /* bitmask of VACOPT_* */ + int freeze_min_age; /* min freeze age, -1 to use default */ + int freeze_table_age; /* age at which to scan whole table */ + int multixact_freeze_min_age; /* min multixact freeze age, -1 to + * use default */ + int multixact_freeze_table_age; /* multixact age at which to scan + * whole table */ + bool is_wraparound; /* force a for-wraparound vacuum */ + int log_min_duration; /* minimum execution threshold in ms at + * which autovacuum is logged, -1 to use + * default */ + VacOptValue index_cleanup; /* Do index vacuum and cleanup */ + VacOptValue truncate; /* Truncate empty pages at the end */ + + /* + * The number of parallel vacuum workers. 0 by default which means choose + * based on the number of indexes. -1 indicates parallel vacuum is + * disabled. + */ + int nworkers; +} VacuumParams; + +/* + * VacuumCutoffs is immutable state that describes the cutoffs used by VACUUM. + * Established at the beginning of each VACUUM operation. + */ +struct VacuumCutoffs +{ + /* + * Existing pg_class fields at start of VACUUM + */ + TransactionId relfrozenxid; + MultiXactId relminmxid; + + /* + * OldestXmin is the Xid below which tuples deleted by any xact (that + * committed) should be considered DEAD, not just RECENTLY_DEAD. + * + * OldestMxact is the Mxid below which MultiXacts are definitely not seen + * as visible by any running transaction. + * + * OldestXmin and OldestMxact are also the most recent values that can + * ever be passed to vac_update_relstats() as frozenxid and minmulti + * arguments at the end of VACUUM. These same values should be passed + * when it turns out that VACUUM will leave no unfrozen XIDs/MXIDs behind + * in the table. + */ + TransactionId OldestXmin; + MultiXactId OldestMxact; + + /* + * FreezeLimit is the Xid below which all Xids are definitely frozen or + * removed in pages VACUUM scans and cleanup locks. + * + * MultiXactCutoff is the value below which all MultiXactIds are + * definitely removed from Xmax in pages VACUUM scans and cleanup locks. + */ + TransactionId FreezeLimit; + MultiXactId MultiXactCutoff; +}; + +/* + * VacDeadItems stores TIDs whose index tuples are deleted by index vacuuming. + */ +typedef struct VacDeadItems +{ + int max_items; /* # slots allocated in array */ + int num_items; /* current # of entries */ + + /* Sorted array of TIDs to delete from indexes */ + ItemPointerData items[FLEXIBLE_ARRAY_MEMBER]; +} VacDeadItems; + +#define MAXDEADITEMS(avail_mem) \ + (((avail_mem) - offsetof(VacDeadItems, items)) / sizeof(ItemPointerData)) + +/* GUC parameters */ +extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */ +extern PGDLLIMPORT int vacuum_freeze_min_age; +extern PGDLLIMPORT int vacuum_freeze_table_age; +extern PGDLLIMPORT int vacuum_multixact_freeze_min_age; +extern PGDLLIMPORT int vacuum_multixact_freeze_table_age; +extern PGDLLIMPORT int vacuum_failsafe_age; +extern PGDLLIMPORT int vacuum_multixact_failsafe_age; + +/* Variables for cost-based parallel vacuum */ +extern PGDLLIMPORT pg_atomic_uint32 *VacuumSharedCostBalance; +extern PGDLLIMPORT pg_atomic_uint32 *VacuumActiveNWorkers; +extern PGDLLIMPORT int VacuumCostBalanceLocal; + +extern PGDLLIMPORT bool VacuumFailsafeActive; +extern PGDLLIMPORT double vacuum_cost_delay; +extern PGDLLIMPORT int vacuum_cost_limit; + +/* in commands/vacuum.c */ +extern void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel); +extern void vacuum(List *relations, VacuumParams *params, + BufferAccessStrategy bstrategy, MemoryContext vac_context, + bool isTopLevel); +extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, + int *nindexes, Relation **Irel); +extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); +extern double vac_estimate_reltuples(Relation relation, + BlockNumber total_pages, + BlockNumber scanned_pages, + double scanned_tuples); +extern void vac_update_relstats(Relation relation, + BlockNumber num_pages, + double num_tuples, + BlockNumber num_all_visible_pages, + bool hasindex, + TransactionId frozenxid, + MultiXactId minmulti, + bool *frozenxid_updated, + bool *minmulti_updated, + bool in_outer_xact); +extern bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params, + struct VacuumCutoffs *cutoffs); +extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); +extern void vac_update_datfrozenxid(void); +extern void vacuum_delay_point(void); +extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, + bits32 options); +extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, + bits32 options, bool verbose, + LOCKMODE lmode); +extern IndexBulkDeleteResult *vac_bulkdel_one_index(IndexVacuumInfo *ivinfo, + IndexBulkDeleteResult *istat, + VacDeadItems *dead_items); +extern IndexBulkDeleteResult *vac_cleanup_one_index(IndexVacuumInfo *ivinfo, + IndexBulkDeleteResult *istat); +extern Size vac_max_items_to_alloc_size(int max_items); + +/* In postmaster/autovacuum.c */ +extern void AutoVacuumUpdateCostLimit(void); +extern void VacuumUpdateCosts(void); + +/* in commands/vacuumparallel.c */ +extern ParallelVacuumState *parallel_vacuum_init(Relation rel, Relation *indrels, + int nindexes, int nrequested_workers, + int max_items, int elevel, + BufferAccessStrategy bstrategy); +extern void parallel_vacuum_end(ParallelVacuumState *pvs, IndexBulkDeleteResult **istats); +extern VacDeadItems *parallel_vacuum_get_dead_items(ParallelVacuumState *pvs); +extern void parallel_vacuum_bulkdel_all_indexes(ParallelVacuumState *pvs, + long num_table_tuples, + int num_index_scans); +extern void parallel_vacuum_cleanup_all_indexes(ParallelVacuumState *pvs, + long num_table_tuples, + int num_index_scans, + bool estimated_count); +extern void parallel_vacuum_main(dsm_segment *seg, shm_toc *toc); + +/* in commands/analyze.c */ +extern void analyze_rel(Oid relid, RangeVar *relation, + VacuumParams *params, List *va_cols, bool in_outer_xact, + BufferAccessStrategy bstrategy); +extern bool std_typanalyze(VacAttrStats *stats); + +/* in utils/misc/sampling.c --- duplicate of declarations in utils/sampling.h */ +extern double anl_random_fract(void); +extern double anl_init_selection_state(int n); +extern double anl_get_next_S(double t, int n, double *stateptr); + +#endif /* VACUUM_H */ diff --git a/install/include/postgresql/server/commands/view.h b/install/include/postgresql/server/commands/view.h new file mode 100644 index 00000000000..c3a713e165f --- /dev/null +++ b/install/include/postgresql/server/commands/view.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * + * view.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/view.h + * + *------------------------------------------------------------------------- + */ +#ifndef VIEW_H +#define VIEW_H + +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" + +extern ObjectAddress DefineView(ViewStmt *stmt, const char *queryString, + int stmt_location, int stmt_len); + +extern void StoreViewQuery(Oid viewOid, Query *viewParse, bool replace); + +#endif /* VIEW_H */ diff --git a/install/include/postgresql/server/common/archive.h b/install/include/postgresql/server/common/archive.h new file mode 100644 index 00000000000..95196772c95 --- /dev/null +++ b/install/include/postgresql/server/common/archive.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * archive.h + * Common WAL archive routines + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/archive.h + * + *------------------------------------------------------------------------- + */ +#ifndef ARCHIVE_H +#define ARCHIVE_H + +extern char *BuildRestoreCommand(const char *restoreCommand, + const char *xlogpath, /* %p */ + const char *xlogfname, /* %f */ + const char *lastRestartPointFname); /* %r */ + +#endif /* ARCHIVE_H */ diff --git a/install/include/postgresql/server/common/base64.h b/install/include/postgresql/server/common/base64.h new file mode 100644 index 00000000000..5bd8186c79c --- /dev/null +++ b/install/include/postgresql/server/common/base64.h @@ -0,0 +1,19 @@ +/* + * base64.h + * Encoding and decoding routines for base64 without whitespace + * support. + * + * Portions Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/common/base64.h + */ +#ifndef BASE64_H +#define BASE64_H + +/* base 64 */ +extern int pg_b64_encode(const char *src, int len, char *dst, int dstlen); +extern int pg_b64_decode(const char *src, int len, char *dst, int dstlen); +extern int pg_b64_enc_len(int srclen); +extern int pg_b64_dec_len(int srclen); + +#endif /* BASE64_H */ diff --git a/install/include/postgresql/server/common/checksum_helper.h b/install/include/postgresql/server/common/checksum_helper.h new file mode 100644 index 00000000000..a74deef67b6 --- /dev/null +++ b/install/include/postgresql/server/common/checksum_helper.h @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------- + * + * checksum_helper.h + * Compute a checksum of any of various types using common routines + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/common/checksum_helper.h + * + *------------------------------------------------------------------------- + */ + +#ifndef CHECKSUM_HELPER_H +#define CHECKSUM_HELPER_H + +#include "common/cryptohash.h" +#include "common/sha2.h" +#include "port/pg_crc32c.h" + +/* + * Supported checksum types. It's not necessarily the case that code using + * these functions needs a cryptographically strong checksum; it may only + * need to detect accidental modification. That's why we include CRC-32C: it's + * much faster than any of the other algorithms. On the other hand, we omit + * MD5 here because any new that does need a cryptographically strong checksum + * should use something better. + */ +typedef enum pg_checksum_type +{ + CHECKSUM_TYPE_NONE, + CHECKSUM_TYPE_CRC32C, + CHECKSUM_TYPE_SHA224, + CHECKSUM_TYPE_SHA256, + CHECKSUM_TYPE_SHA384, + CHECKSUM_TYPE_SHA512 +} pg_checksum_type; + +/* + * This is just a union of all applicable context types. + */ +typedef union pg_checksum_raw_context +{ + pg_crc32c c_crc32c; + pg_cryptohash_ctx *c_sha2; +} pg_checksum_raw_context; + +/* + * This structure provides a convenient way to pass the checksum type and the + * checksum context around together. + */ +typedef struct pg_checksum_context +{ + pg_checksum_type type; + pg_checksum_raw_context raw_context; +} pg_checksum_context; + +/* + * This is the longest possible output for any checksum algorithm supported + * by this file. + */ +#define PG_CHECKSUM_MAX_LENGTH PG_SHA512_DIGEST_LENGTH + +extern bool pg_checksum_parse_type(char *name, pg_checksum_type *); +extern char *pg_checksum_type_name(pg_checksum_type); + +extern int pg_checksum_init(pg_checksum_context *, pg_checksum_type); +extern int pg_checksum_update(pg_checksum_context *, const uint8 *input, + size_t len); +extern int pg_checksum_final(pg_checksum_context *, uint8 *output); + +#endif diff --git a/install/include/postgresql/server/common/compression.h b/install/include/postgresql/server/common/compression.h new file mode 100644 index 00000000000..38aae9dd873 --- /dev/null +++ b/install/include/postgresql/server/common/compression.h @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * compression.h + * + * Shared definitions for compression methods and specifications. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/common/compression.h + *------------------------------------------------------------------------- + */ + +#ifndef PG_COMPRESSION_H +#define PG_COMPRESSION_H + +/* + * These values are stored in disk, for example in files generated by pg_dump. + * Create the necessary backwards compatibility layers if their order changes. + */ +typedef enum pg_compress_algorithm +{ + PG_COMPRESSION_NONE, + PG_COMPRESSION_GZIP, + PG_COMPRESSION_LZ4, + PG_COMPRESSION_ZSTD +} pg_compress_algorithm; + +#define PG_COMPRESSION_OPTION_WORKERS (1 << 0) +#define PG_COMPRESSION_OPTION_LONG_DISTANCE (1 << 1) + +typedef struct pg_compress_specification +{ + pg_compress_algorithm algorithm; + unsigned options; /* OR of PG_COMPRESSION_OPTION constants */ + int level; + int workers; + bool long_distance; + char *parse_error; /* NULL if parsing was OK, else message */ +} pg_compress_specification; + +extern void parse_compress_options(const char *option, char **algorithm, + char **detail); +extern bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm); +extern const char *get_compress_algorithm_name(pg_compress_algorithm algorithm); + +extern void parse_compress_specification(pg_compress_algorithm algorithm, + char *specification, + pg_compress_specification *result); + +extern char *validate_compress_specification(pg_compress_specification *); + +#endif diff --git a/install/include/postgresql/server/common/config_info.h b/install/include/postgresql/server/common/config_info.h new file mode 100644 index 00000000000..a6d076d5e9f --- /dev/null +++ b/install/include/postgresql/server/common/config_info.h @@ -0,0 +1,21 @@ +/* + * config_info.h + * Common code for pg_config output + * + * Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/common/config_info.h + */ +#ifndef COMMON_CONFIG_INFO_H +#define COMMON_CONFIG_INFO_H + +typedef struct ConfigData +{ + char *name; + char *setting; +} ConfigData; + +extern ConfigData *get_configdata(const char *my_exec_path, + size_t *configdata_len); + +#endif /* COMMON_CONFIG_INFO_H */ diff --git a/install/include/postgresql/server/common/connect.h b/install/include/postgresql/server/common/connect.h new file mode 100644 index 00000000000..5913c548b61 --- /dev/null +++ b/install/include/postgresql/server/common/connect.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * Interfaces in support of FE/BE connections. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/connect.h + * + *------------------------------------------------------------------------- + */ +#ifndef CONNECT_H +#define CONNECT_H + +/* + * This SQL statement installs an always-secure search path, so malicious + * users can't take control. CREATE of an unqualified name will fail, because + * this selects no creation schema. This does not demote pg_temp, so it is + * suitable where we control the entire FE/BE connection but not suitable in + * SECURITY DEFINER functions. This is portable to PostgreSQL 7.3, which + * introduced schemas. When connected to an older version from code that + * might work with the old server, skip this. + */ +#define ALWAYS_SECURE_SEARCH_PATH_SQL \ + "SELECT pg_catalog.set_config('search_path', '', false);" + +#endif /* CONNECT_H */ diff --git a/install/include/postgresql/server/common/controldata_utils.h b/install/include/postgresql/server/common/controldata_utils.h new file mode 100644 index 00000000000..49e7c52d312 --- /dev/null +++ b/install/include/postgresql/server/common/controldata_utils.h @@ -0,0 +1,19 @@ +/* + * controldata_utils.h + * Common code for pg_controldata output + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/controldata_utils.h + */ +#ifndef COMMON_CONTROLDATA_UTILS_H +#define COMMON_CONTROLDATA_UTILS_H + +#include "catalog/pg_control.h" + +extern ControlFileData *get_controlfile(const char *DataDir, bool *crc_ok_p); +extern void update_controlfile(const char *DataDir, + ControlFileData *ControlFile, bool do_sync); + +#endif /* COMMON_CONTROLDATA_UTILS_H */ diff --git a/install/include/postgresql/server/common/cryptohash.h b/install/include/postgresql/server/common/cryptohash.h new file mode 100644 index 00000000000..24b6dbebbd8 --- /dev/null +++ b/install/include/postgresql/server/common/cryptohash.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * cryptohash.h + * Generic headers for cryptographic hash functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/common/cryptohash.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PG_CRYPTOHASH_H +#define PG_CRYPTOHASH_H + +/* Context Structures for each hash function */ +typedef enum +{ + PG_MD5 = 0, + PG_SHA1, + PG_SHA224, + PG_SHA256, + PG_SHA384, + PG_SHA512 +} pg_cryptohash_type; + +/* opaque context, private to each cryptohash implementation */ +typedef struct pg_cryptohash_ctx pg_cryptohash_ctx; + +extern pg_cryptohash_ctx *pg_cryptohash_create(pg_cryptohash_type type); +extern int pg_cryptohash_init(pg_cryptohash_ctx *ctx); +extern int pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len); +extern int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len); +extern void pg_cryptohash_free(pg_cryptohash_ctx *ctx); +extern const char *pg_cryptohash_error(pg_cryptohash_ctx *ctx); + +#endif /* PG_CRYPTOHASH_H */ diff --git a/install/include/postgresql/server/common/fe_memutils.h b/install/include/postgresql/server/common/fe_memutils.h new file mode 100644 index 00000000000..89601cc778f --- /dev/null +++ b/install/include/postgresql/server/common/fe_memutils.h @@ -0,0 +1,73 @@ +/* + * fe_memutils.h + * memory management support for frontend code + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/common/fe_memutils.h + */ +#ifndef FE_MEMUTILS_H +#define FE_MEMUTILS_H + +/* + * Flags for pg_malloc_extended and palloc_extended, deliberately named + * the same as the backend flags. + */ +#define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) not + * actually used for frontends */ +#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ +#define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */ + +/* + * "Safe" memory allocation functions --- these exit(1) on failure + * (except pg_malloc_extended with MCXT_ALLOC_NO_OOM) + */ +extern char *pg_strdup(const char *in); +extern void *pg_malloc(size_t size); +extern void *pg_malloc0(size_t size); +extern void *pg_malloc_extended(size_t size, int flags); +extern void *pg_realloc(void *ptr, size_t size); +extern void pg_free(void *ptr); + +/* + * Variants with easier notation and more type safety + */ + +/* + * Allocate space for one object of type "type" + */ +#define pg_malloc_object(type) ((type *) pg_malloc(sizeof(type))) +#define pg_malloc0_object(type) ((type *) pg_malloc0(sizeof(type))) + +/* + * Allocate space for "count" objects of type "type" + */ +#define pg_malloc_array(type, count) ((type *) pg_malloc(sizeof(type) * (count))) +#define pg_malloc0_array(type, count) ((type *) pg_malloc0(sizeof(type) * (count))) + +/* + * Change size of allocation pointed to by "pointer" to have space for "count" + * objects of type "type" + */ +#define pg_realloc_array(pointer, type, count) ((type *) pg_realloc(pointer, sizeof(type) * (count))) + +/* Equivalent functions, deliberately named the same as backend functions */ +extern char *pstrdup(const char *in); +extern char *pnstrdup(const char *in, Size size); +extern void *palloc(Size size); +extern void *palloc0(Size size); +extern void *palloc_extended(Size size, int flags); +extern void *repalloc(void *pointer, Size size); +extern void pfree(void *pointer); + +#define palloc_object(type) ((type *) palloc(sizeof(type))) +#define palloc0_object(type) ((type *) palloc0(sizeof(type))) +#define palloc_array(type, count) ((type *) palloc(sizeof(type) * (count))) +#define palloc0_array(type, count) ((type *) palloc0(sizeof(type) * (count))) +#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count))) + +/* sprintf into a palloc'd buffer --- these are in psprintf.c */ +extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2); +extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0); + +#endif /* FE_MEMUTILS_H */ diff --git a/install/include/postgresql/server/common/file_perm.h b/install/include/postgresql/server/common/file_perm.h new file mode 100644 index 00000000000..978c0d072f1 --- /dev/null +++ b/install/include/postgresql/server/common/file_perm.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * File and directory permission definitions + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/file_perm.h + * + *------------------------------------------------------------------------- + */ +#ifndef FILE_PERM_H +#define FILE_PERM_H + +#include + +/* + * Mode mask for data directory permissions that only allows the owner to + * read/write directories and files. + * + * This is the default. + */ +#define PG_MODE_MASK_OWNER (S_IRWXG | S_IRWXO) + +/* + * Mode mask for data directory permissions that also allows group read/execute. + */ +#define PG_MODE_MASK_GROUP (S_IWGRP | S_IRWXO) + +/* Default mode for creating directories */ +#define PG_DIR_MODE_OWNER S_IRWXU + +/* Mode for creating directories that allows group read/execute */ +#define PG_DIR_MODE_GROUP (S_IRWXU | S_IRGRP | S_IXGRP) + +/* Default mode for creating files */ +#define PG_FILE_MODE_OWNER (S_IRUSR | S_IWUSR) + +/* Mode for creating files that allows group read */ +#define PG_FILE_MODE_GROUP (S_IRUSR | S_IWUSR | S_IRGRP) + +/* Modes for creating directories and files in the data directory */ +extern PGDLLIMPORT int pg_dir_create_mode; +extern PGDLLIMPORT int pg_file_create_mode; + +/* Mode mask to pass to umask() */ +extern PGDLLIMPORT int pg_mode_mask; + +/* Set permissions and mask based on the provided mode */ +extern void SetDataDirectoryCreatePerm(int dataDirMode); + +/* Set permissions and mask based on the mode of the data directory */ +extern bool GetDataDirectoryCreatePerm(const char *dataDir); + +#endif /* FILE_PERM_H */ diff --git a/install/include/postgresql/server/common/file_utils.h b/install/include/postgresql/server/common/file_utils.h new file mode 100644 index 00000000000..b7efa1226d6 --- /dev/null +++ b/install/include/postgresql/server/common/file_utils.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * Assorted utility functions to work on files. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/file_utils.h + * + *------------------------------------------------------------------------- + */ +#ifndef FILE_UTILS_H +#define FILE_UTILS_H + +#include + +typedef enum PGFileType +{ + PGFILETYPE_ERROR, + PGFILETYPE_UNKNOWN, + PGFILETYPE_REG, + PGFILETYPE_DIR, + PGFILETYPE_LNK +} PGFileType; + +struct iovec; /* avoid including port/pg_iovec.h here */ + +#ifdef FRONTEND +extern int fsync_fname(const char *fname, bool isdir); +extern void fsync_pgdata(const char *pg_data, int serverVersion); +extern void fsync_dir_recurse(const char *dir); +extern int durable_rename(const char *oldfile, const char *newfile); +extern int fsync_parent_path(const char *fname); +#endif + +extern PGFileType get_dirent_type(const char *path, + const struct dirent *de, + bool look_through_symlinks, + int elevel); + +extern ssize_t pg_pwritev_with_retry(int fd, + const struct iovec *iov, + int iovcnt, + off_t offset); + +extern ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset); + +#endif /* FILE_UTILS_H */ diff --git a/install/include/postgresql/server/common/hashfn.h b/install/include/postgresql/server/common/hashfn.h new file mode 100644 index 00000000000..5e89aef987f --- /dev/null +++ b/install/include/postgresql/server/common/hashfn.h @@ -0,0 +1,104 @@ +/* + * Utilities for working with hash values. + * + * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group + */ + +#ifndef HASHFN_H +#define HASHFN_H + + +/* + * Rotate the high 32 bits and the low 32 bits separately. The standard + * hash function sometimes rotates the low 32 bits by one bit when + * combining elements. We want extended hash functions to be compatible with + * that algorithm when the seed is 0, so we can't just do a normal rotation. + * This works, though. + */ +#define ROTATE_HIGH_AND_LOW_32BITS(v) \ + ((((v) << 1) & UINT64CONST(0xfffffffefffffffe)) | \ + (((v) >> 31) & UINT64CONST(0x100000001))) + + +extern uint32 hash_bytes(const unsigned char *k, int keylen); +extern uint64 hash_bytes_extended(const unsigned char *k, + int keylen, uint64 seed); +extern uint32 hash_bytes_uint32(uint32 k); +extern uint64 hash_bytes_uint32_extended(uint32 k, uint64 seed); + +#ifndef FRONTEND +static inline Datum +hash_any(const unsigned char *k, int keylen) +{ + return UInt32GetDatum(hash_bytes(k, keylen)); +} + +static inline Datum +hash_any_extended(const unsigned char *k, int keylen, uint64 seed) +{ + return UInt64GetDatum(hash_bytes_extended(k, keylen, seed)); +} + +static inline Datum +hash_uint32(uint32 k) +{ + return UInt32GetDatum(hash_bytes_uint32(k)); +} + +static inline Datum +hash_uint32_extended(uint32 k, uint64 seed) +{ + return UInt64GetDatum(hash_bytes_uint32_extended(k, seed)); +} +#endif + +extern uint32 string_hash(const void *key, Size keysize); +extern uint32 tag_hash(const void *key, Size keysize); +extern uint32 uint32_hash(const void *key, Size keysize); + +#define oid_hash uint32_hash /* Remove me eventually */ + +/* + * Combine two 32-bit hash values, resulting in another hash value, with + * decent bit mixing. + * + * Similar to boost's hash_combine(). + */ +static inline uint32 +hash_combine(uint32 a, uint32 b) +{ + a ^= b + 0x9e3779b9 + (a << 6) + (a >> 2); + return a; +} + +/* + * Combine two 64-bit hash values, resulting in another hash value, using the + * same kind of technique as hash_combine(). Testing shows that this also + * produces good bit mixing. + */ +static inline uint64 +hash_combine64(uint64 a, uint64 b) +{ + /* 0x49a0f4dd15e5a8e3 is 64bit random data */ + a ^= b + UINT64CONST(0x49a0f4dd15e5a8e3) + (a << 54) + (a >> 7); + return a; +} + +/* + * Simple inline murmur hash implementation hashing a 32 bit integer, for + * performance. + */ +static inline uint32 +murmurhash32(uint32 data) +{ + uint32 h = data; + + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + return h; +} + +#endif /* HASHFN_H */ diff --git a/install/include/postgresql/server/common/hmac.h b/install/include/postgresql/server/common/hmac.h new file mode 100644 index 00000000000..e0b2ed20241 --- /dev/null +++ b/install/include/postgresql/server/common/hmac.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * hmac.h + * Generic headers for HMAC + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/common/hmac.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PG_HMAC_H +#define PG_HMAC_H + +#include "common/cryptohash.h" + +/* opaque context, private to each HMAC implementation */ +typedef struct pg_hmac_ctx pg_hmac_ctx; + +extern pg_hmac_ctx *pg_hmac_create(pg_cryptohash_type type); +extern int pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len); +extern int pg_hmac_update(pg_hmac_ctx *ctx, const uint8 *data, size_t len); +extern int pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len); +extern void pg_hmac_free(pg_hmac_ctx *ctx); +extern const char *pg_hmac_error(pg_hmac_ctx *ctx); + +#endif /* PG_HMAC_H */ diff --git a/install/include/postgresql/server/common/int.h b/install/include/postgresql/server/common/int.h new file mode 100644 index 00000000000..487124473d2 --- /dev/null +++ b/install/include/postgresql/server/common/int.h @@ -0,0 +1,441 @@ +/*------------------------------------------------------------------------- + * + * int.h + * Routines to perform integer math, while checking for overflows. + * + * The routines in this file are intended to be well defined C, without + * relying on compiler flags like -fwrapv. + * + * To reduce the overhead of these routines try to use compiler intrinsics + * where available. That's not that important for the 16, 32 bit cases, but + * the 64 bit cases can be considerably faster with intrinsics. In case no + * intrinsics are available 128 bit math is used where available. + * + * Copyright (c) 2017-2023, PostgreSQL Global Development Group + * + * src/include/common/int.h + * + *------------------------------------------------------------------------- + */ +#ifndef COMMON_INT_H +#define COMMON_INT_H + + +/*--------- + * The following guidelines apply to all the routines: + * - If a + b overflows, return true, otherwise store the result of a + b + * into *result. The content of *result is implementation defined in case of + * overflow. + * - If a - b overflows, return true, otherwise store the result of a - b + * into *result. The content of *result is implementation defined in case of + * overflow. + * - If a * b overflows, return true, otherwise store the result of a * b + * into *result. The content of *result is implementation defined in case of + * overflow. + *--------- + */ + +/*------------------------------------------------------------------------ + * Overflow routines for signed integers + *------------------------------------------------------------------------ + */ + +/* + * INT16 + */ +static inline bool +pg_add_s16_overflow(int16 a, int16 b, int16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + int32 res = (int32) a + (int32) b; + + if (res > PG_INT16_MAX || res < PG_INT16_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int16) res; + return false; +#endif +} + +static inline bool +pg_sub_s16_overflow(int16 a, int16 b, int16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + int32 res = (int32) a - (int32) b; + + if (res > PG_INT16_MAX || res < PG_INT16_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int16) res; + return false; +#endif +} + +static inline bool +pg_mul_s16_overflow(int16 a, int16 b, int16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#else + int32 res = (int32) a * (int32) b; + + if (res > PG_INT16_MAX || res < PG_INT16_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int16) res; + return false; +#endif +} + +/* + * INT32 + */ +static inline bool +pg_add_s32_overflow(int32 a, int32 b, int32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + int64 res = (int64) a + (int64) b; + + if (res > PG_INT32_MAX || res < PG_INT32_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int32) res; + return false; +#endif +} + +static inline bool +pg_sub_s32_overflow(int32 a, int32 b, int32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + int64 res = (int64) a - (int64) b; + + if (res > PG_INT32_MAX || res < PG_INT32_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int32) res; + return false; +#endif +} + +static inline bool +pg_mul_s32_overflow(int32 a, int32 b, int32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#else + int64 res = (int64) a * (int64) b; + + if (res > PG_INT32_MAX || res < PG_INT32_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int32) res; + return false; +#endif +} + +/* + * INT64 + */ +static inline bool +pg_add_s64_overflow(int64 a, int64 b, int64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#elif defined(HAVE_INT128) + int128 res = (int128) a + (int128) b; + + if (res > PG_INT64_MAX || res < PG_INT64_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int64) res; + return false; +#else + if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) || + (a < 0 && b < 0 && a < PG_INT64_MIN - b)) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a + b; + return false; +#endif +} + +static inline bool +pg_sub_s64_overflow(int64 a, int64 b, int64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#elif defined(HAVE_INT128) + int128 res = (int128) a - (int128) b; + + if (res > PG_INT64_MAX || res < PG_INT64_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int64) res; + return false; +#else + /* + * Note: overflow is also possible when a == 0 and b < 0 (specifically, + * when b == PG_INT64_MIN). + */ + if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) || + (a >= 0 && b < 0 && a > PG_INT64_MAX + b)) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a - b; + return false; +#endif +} + +static inline bool +pg_mul_s64_overflow(int64 a, int64 b, int64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#elif defined(HAVE_INT128) + int128 res = (int128) a * (int128) b; + + if (res > PG_INT64_MAX || res < PG_INT64_MIN) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (int64) res; + return false; +#else + /* + * Overflow can only happen if at least one value is outside the range + * sqrt(min)..sqrt(max) so check that first as the division can be quite a + * bit more expensive than the multiplication. + * + * Multiplying by 0 or 1 can't overflow of course and checking for 0 + * separately avoids any risk of dividing by 0. Be careful about dividing + * INT_MIN by -1 also, note reversing the a and b to ensure we're always + * dividing it by a positive value. + * + */ + if ((a > PG_INT32_MAX || a < PG_INT32_MIN || + b > PG_INT32_MAX || b < PG_INT32_MIN) && + a != 0 && a != 1 && b != 0 && b != 1 && + ((a > 0 && b > 0 && a > PG_INT64_MAX / b) || + (a > 0 && b < 0 && b < PG_INT64_MIN / a) || + (a < 0 && b > 0 && a < PG_INT64_MIN / b) || + (a < 0 && b < 0 && a < PG_INT64_MAX / b))) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a * b; + return false; +#endif +} + +/*------------------------------------------------------------------------ + * Overflow routines for unsigned integers + *------------------------------------------------------------------------ + */ + +/* + * UINT16 + */ +static inline bool +pg_add_u16_overflow(uint16 a, uint16 b, uint16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + uint16 res = a + b; + + if (res < a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + +static inline bool +pg_sub_u16_overflow(uint16 a, uint16 b, uint16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + if (b > a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a - b; + return false; +#endif +} + +static inline bool +pg_mul_u16_overflow(uint16 a, uint16 b, uint16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#else + uint32 res = (uint32) a * (uint32) b; + + if (res > PG_UINT16_MAX) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (uint16) res; + return false; +#endif +} + +/* + * INT32 + */ +static inline bool +pg_add_u32_overflow(uint32 a, uint32 b, uint32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + uint32 res = a + b; + + if (res < a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + +static inline bool +pg_sub_u32_overflow(uint32 a, uint32 b, uint32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + if (b > a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a - b; + return false; +#endif +} + +static inline bool +pg_mul_u32_overflow(uint32 a, uint32 b, uint32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#else + uint64 res = (uint64) a * (uint64) b; + + if (res > PG_UINT32_MAX) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (uint32) res; + return false; +#endif +} + +/* + * UINT64 + */ +static inline bool +pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + uint64 res = a + b; + + if (res < a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + +static inline bool +pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + if (b > a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a - b; + return false; +#endif +} + +static inline bool +pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#elif defined(HAVE_INT128) + uint128 res = (uint128) a * (uint128) b; + + if (res > PG_UINT64_MAX) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (uint64) res; + return false; +#else + uint64 res = a * b; + + if (a != 0 && b != res / a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + +#endif /* COMMON_INT_H */ diff --git a/install/include/postgresql/server/common/int128.h b/install/include/postgresql/server/common/int128.h new file mode 100644 index 00000000000..eca694b631d --- /dev/null +++ b/install/include/postgresql/server/common/int128.h @@ -0,0 +1,276 @@ +/*------------------------------------------------------------------------- + * + * int128.h + * Roll-our-own 128-bit integer arithmetic. + * + * We make use of the native int128 type if there is one, otherwise + * implement things the hard way based on two int64 halves. + * + * See src/tools/testint128.c for a simple test harness for this file. + * + * Copyright (c) 2017-2023, PostgreSQL Global Development Group + * + * src/include/common/int128.h + * + *------------------------------------------------------------------------- + */ +#ifndef INT128_H +#define INT128_H + +/* + * For testing purposes, use of native int128 can be switched on/off by + * predefining USE_NATIVE_INT128. + */ +#ifndef USE_NATIVE_INT128 +#ifdef HAVE_INT128 +#define USE_NATIVE_INT128 1 +#else +#define USE_NATIVE_INT128 0 +#endif +#endif + + +#if USE_NATIVE_INT128 + +typedef int128 INT128; + +/* + * Add an unsigned int64 value into an INT128 variable. + */ +static inline void +int128_add_uint64(INT128 *i128, uint64 v) +{ + *i128 += v; +} + +/* + * Add a signed int64 value into an INT128 variable. + */ +static inline void +int128_add_int64(INT128 *i128, int64 v) +{ + *i128 += v; +} + +/* + * Add the 128-bit product of two int64 values into an INT128 variable. + * + * XXX with a stupid compiler, this could actually be less efficient than + * the other implementation; maybe we should do it by hand always? + */ +static inline void +int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y) +{ + *i128 += (int128) x * (int128) y; +} + +/* + * Compare two INT128 values, return -1, 0, or +1. + */ +static inline int +int128_compare(INT128 x, INT128 y) +{ + if (x < y) + return -1; + if (x > y) + return 1; + return 0; +} + +/* + * Widen int64 to INT128. + */ +static inline INT128 +int64_to_int128(int64 v) +{ + return (INT128) v; +} + +/* + * Convert INT128 to int64 (losing any high-order bits). + * This also works fine for casting down to uint64. + */ +static inline int64 +int128_to_int64(INT128 val) +{ + return (int64) val; +} + +#else /* !USE_NATIVE_INT128 */ + +/* + * We lay out the INT128 structure with the same content and byte ordering + * that a native int128 type would (probably) have. This makes no difference + * for ordinary use of INT128, but allows union'ing INT128 with int128 for + * testing purposes. + */ +typedef struct +{ +#ifdef WORDS_BIGENDIAN + int64 hi; /* most significant 64 bits, including sign */ + uint64 lo; /* least significant 64 bits, without sign */ +#else + uint64 lo; /* least significant 64 bits, without sign */ + int64 hi; /* most significant 64 bits, including sign */ +#endif +} INT128; + +/* + * Add an unsigned int64 value into an INT128 variable. + */ +static inline void +int128_add_uint64(INT128 *i128, uint64 v) +{ + /* + * First add the value to the .lo part, then check to see if a carry needs + * to be propagated into the .hi part. A carry is needed if both inputs + * have high bits set, or if just one input has high bit set while the new + * .lo part doesn't. Remember that .lo part is unsigned; we cast to + * signed here just as a cheap way to check the high bit. + */ + uint64 oldlo = i128->lo; + + i128->lo += v; + if (((int64) v < 0 && (int64) oldlo < 0) || + (((int64) v < 0 || (int64) oldlo < 0) && (int64) i128->lo >= 0)) + i128->hi++; +} + +/* + * Add a signed int64 value into an INT128 variable. + */ +static inline void +int128_add_int64(INT128 *i128, int64 v) +{ + /* + * This is much like the above except that the carry logic differs for + * negative v. Ordinarily we'd need to subtract 1 from the .hi part + * (corresponding to adding the sign-extended bits of v to it); but if + * there is a carry out of the .lo part, that cancels and we do nothing. + */ + uint64 oldlo = i128->lo; + + i128->lo += v; + if (v >= 0) + { + if ((int64) oldlo < 0 && (int64) i128->lo >= 0) + i128->hi++; + } + else + { + if (!((int64) oldlo < 0 || (int64) i128->lo >= 0)) + i128->hi--; + } +} + +/* + * INT64_AU32 extracts the most significant 32 bits of int64 as int64, while + * INT64_AL32 extracts the least significant 32 bits as uint64. + */ +#define INT64_AU32(i64) ((i64) >> 32) +#define INT64_AL32(i64) ((i64) & UINT64CONST(0xFFFFFFFF)) + +/* + * Add the 128-bit product of two int64 values into an INT128 variable. + */ +static inline void +int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y) +{ + /* INT64_AU32 must use arithmetic right shift */ + StaticAssertDecl(((int64) -1 >> 1) == (int64) -1, + "arithmetic right shift is needed"); + + /*---------- + * Form the 128-bit product x * y using 64-bit arithmetic. + * Considering each 64-bit input as having 32-bit high and low parts, + * we can compute + * + * x * y = ((x.hi << 32) + x.lo) * (((y.hi << 32) + y.lo) + * = (x.hi * y.hi) << 64 + + * (x.hi * y.lo) << 32 + + * (x.lo * y.hi) << 32 + + * x.lo * y.lo + * + * Each individual product is of 32-bit terms so it won't overflow when + * computed in 64-bit arithmetic. Then we just have to shift it to the + * correct position while adding into the 128-bit result. We must also + * keep in mind that the "lo" parts must be treated as unsigned. + *---------- + */ + + /* No need to work hard if product must be zero */ + if (x != 0 && y != 0) + { + int64 x_u32 = INT64_AU32(x); + uint64 x_l32 = INT64_AL32(x); + int64 y_u32 = INT64_AU32(y); + uint64 y_l32 = INT64_AL32(y); + int64 tmp; + + /* the first term */ + i128->hi += x_u32 * y_u32; + + /* the second term: sign-extend it only if x is negative */ + tmp = x_u32 * y_l32; + if (x < 0) + i128->hi += INT64_AU32(tmp); + else + i128->hi += ((uint64) tmp) >> 32; + int128_add_uint64(i128, ((uint64) INT64_AL32(tmp)) << 32); + + /* the third term: sign-extend it only if y is negative */ + tmp = x_l32 * y_u32; + if (y < 0) + i128->hi += INT64_AU32(tmp); + else + i128->hi += ((uint64) tmp) >> 32; + int128_add_uint64(i128, ((uint64) INT64_AL32(tmp)) << 32); + + /* the fourth term: always unsigned */ + int128_add_uint64(i128, x_l32 * y_l32); + } +} + +/* + * Compare two INT128 values, return -1, 0, or +1. + */ +static inline int +int128_compare(INT128 x, INT128 y) +{ + if (x.hi < y.hi) + return -1; + if (x.hi > y.hi) + return 1; + if (x.lo < y.lo) + return -1; + if (x.lo > y.lo) + return 1; + return 0; +} + +/* + * Widen int64 to INT128. + */ +static inline INT128 +int64_to_int128(int64 v) +{ + INT128 val; + + val.lo = (uint64) v; + val.hi = (v < 0) ? -INT64CONST(1) : INT64CONST(0); + return val; +} + +/* + * Convert INT128 to int64 (losing any high-order bits). + * This also works fine for casting down to uint64. + */ +static inline int64 +int128_to_int64(INT128 val) +{ + return (int64) val.lo; +} + +#endif /* USE_NATIVE_INT128 */ + +#endif /* INT128_H */ diff --git a/install/include/postgresql/server/common/ip.h b/install/include/postgresql/server/common/ip.h new file mode 100644 index 00000000000..9f2ed5fe0aa --- /dev/null +++ b/install/include/postgresql/server/common/ip.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * ip.h + * Definitions for IPv6-aware network access. + * + * These definitions are used by both frontend and backend code. + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/common/ip.h + * + *------------------------------------------------------------------------- + */ +#ifndef IP_H +#define IP_H + +#include +#include + +#include "libpq/pqcomm.h" /* pgrminclude ignore */ + + +extern int pg_getaddrinfo_all(const char *hostname, const char *servname, + const struct addrinfo *hintp, + struct addrinfo **result); +extern void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai); + +extern int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags); + +#endif /* IP_H */ diff --git a/install/include/postgresql/server/common/jsonapi.h b/install/include/postgresql/server/common/jsonapi.h new file mode 100644 index 00000000000..4310084b2bd --- /dev/null +++ b/install/include/postgresql/server/common/jsonapi.h @@ -0,0 +1,177 @@ +/*------------------------------------------------------------------------- + * + * jsonapi.h + * Declarations for JSON API support. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/jsonapi.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSONAPI_H +#define JSONAPI_H + +#include "lib/stringinfo.h" + +typedef enum JsonTokenType +{ + JSON_TOKEN_INVALID, + JSON_TOKEN_STRING, + JSON_TOKEN_NUMBER, + JSON_TOKEN_OBJECT_START, + JSON_TOKEN_OBJECT_END, + JSON_TOKEN_ARRAY_START, + JSON_TOKEN_ARRAY_END, + JSON_TOKEN_COMMA, + JSON_TOKEN_COLON, + JSON_TOKEN_TRUE, + JSON_TOKEN_FALSE, + JSON_TOKEN_NULL, + JSON_TOKEN_END +} JsonTokenType; + +typedef enum JsonParseErrorType +{ + JSON_SUCCESS, + JSON_ESCAPING_INVALID, + JSON_ESCAPING_REQUIRED, + JSON_EXPECTED_ARRAY_FIRST, + JSON_EXPECTED_ARRAY_NEXT, + JSON_EXPECTED_COLON, + JSON_EXPECTED_END, + JSON_EXPECTED_JSON, + JSON_EXPECTED_MORE, + JSON_EXPECTED_OBJECT_FIRST, + JSON_EXPECTED_OBJECT_NEXT, + JSON_EXPECTED_STRING, + JSON_INVALID_TOKEN, + JSON_UNICODE_CODE_POINT_ZERO, + JSON_UNICODE_ESCAPE_FORMAT, + JSON_UNICODE_HIGH_ESCAPE, + JSON_UNICODE_UNTRANSLATABLE, + JSON_UNICODE_HIGH_SURROGATE, + JSON_UNICODE_LOW_SURROGATE, + JSON_SEM_ACTION_FAILED /* error should already be reported */ +} JsonParseErrorType; + + +/* + * All the fields in this structure should be treated as read-only. + * + * If strval is not null, then it should contain the de-escaped value + * of the lexeme if it's a string. Otherwise most of these field names + * should be self-explanatory. + * + * line_number and line_start are principally for use by the parser's + * error reporting routines. + * token_terminator and prev_token_terminator point to the character + * AFTER the end of the token, i.e. where there would be a nul byte + * if we were using nul-terminated strings. + */ +typedef struct JsonLexContext +{ + char *input; + int input_length; + int input_encoding; + char *token_start; + char *token_terminator; + char *prev_token_terminator; + JsonTokenType token_type; + int lex_level; + int line_number; /* line number, starting from 1 */ + char *line_start; /* where that line starts within input */ + StringInfo strval; +} JsonLexContext; + +typedef JsonParseErrorType (*json_struct_action) (void *state); +typedef JsonParseErrorType (*json_ofield_action) (void *state, char *fname, bool isnull); +typedef JsonParseErrorType (*json_aelem_action) (void *state, bool isnull); +typedef JsonParseErrorType (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype); + + +/* + * Semantic Action structure for use in parsing json. + * + * Any of these actions can be NULL, in which case nothing is done at that + * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts + * to doing a pure parse with no side-effects, and is therefore exactly + * what the json input routines do. + * + * The 'fname' and 'token' strings passed to these actions are palloc'd. + * They are not free'd or used further by the parser, so the action function + * is free to do what it wishes with them. + * + * All action functions return JsonParseErrorType. If the result isn't + * JSON_SUCCESS, the parse is abandoned and that error code is returned. + * If it is JSON_SEM_ACTION_FAILED, the action function is responsible + * for having reported the error in some appropriate way. + */ +typedef struct JsonSemAction +{ + void *semstate; + json_struct_action object_start; + json_struct_action object_end; + json_struct_action array_start; + json_struct_action array_end; + json_ofield_action object_field_start; + json_ofield_action object_field_end; + json_aelem_action array_element_start; + json_aelem_action array_element_end; + json_scalar_action scalar; +} JsonSemAction; + +/* + * pg_parse_json will parse the string in the lex calling the + * action functions in sem at the appropriate points. It is + * up to them to keep what state they need in semstate. If they + * need access to the state of the lexer, then its pointer + * should be passed to them as a member of whatever semstate + * points to. If the action pointers are NULL the parser + * does nothing and just continues. + */ +extern JsonParseErrorType pg_parse_json(JsonLexContext *lex, + JsonSemAction *sem); + +/* the null action object used for pure validation */ +extern PGDLLIMPORT JsonSemAction nullSemAction; + +/* + * json_count_array_elements performs a fast secondary parse to determine the + * number of elements in passed array lex context. It should be called from an + * array_start action. + * + * The return value indicates whether any error occurred, while the number + * of elements is stored into *elements (but only if the return value is + * JSON_SUCCESS). + */ +extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex, + int *elements); + +/* + * constructor for JsonLexContext, with or without strval element. + * If supplied, the strval element will contain a de-escaped version of + * the lexeme. However, doing this imposes a performance penalty, so + * it should be avoided if the de-escaped lexeme is not required. + */ +extern JsonLexContext *makeJsonLexContextCstringLen(char *json, + int len, + int encoding, + bool need_escapes); + +/* lex one token */ +extern JsonParseErrorType json_lex(JsonLexContext *lex); + +/* construct an error detail string for a json error */ +extern char *json_errdetail(JsonParseErrorType error, JsonLexContext *lex); + +/* + * Utility function to check if a string is a valid JSON number. + * + * str argument does not need to be nul-terminated. + */ +extern bool IsValidJsonNumber(const char *str, int len); + +#endif /* JSONAPI_H */ diff --git a/install/include/postgresql/server/common/keywords.h b/install/include/postgresql/server/common/keywords.h new file mode 100644 index 00000000000..6bb12d8edb3 --- /dev/null +++ b/install/include/postgresql/server/common/keywords.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * keywords.h + * PostgreSQL's list of SQL keywords + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/keywords.h + * + *------------------------------------------------------------------------- + */ +#ifndef KEYWORDS_H +#define KEYWORDS_H + +#include "common/kwlookup.h" + +/* Keyword categories --- should match lists in gram.y */ +#define UNRESERVED_KEYWORD 0 +#define COL_NAME_KEYWORD 1 +#define TYPE_FUNC_NAME_KEYWORD 2 +#define RESERVED_KEYWORD 3 + +extern PGDLLIMPORT const ScanKeywordList ScanKeywords; +extern PGDLLIMPORT const uint8 ScanKeywordCategories[]; +extern PGDLLIMPORT const bool ScanKeywordBareLabel[]; + +#endif /* KEYWORDS_H */ diff --git a/install/include/postgresql/server/common/kwlookup.h b/install/include/postgresql/server/common/kwlookup.h new file mode 100644 index 00000000000..3fc3faa0434 --- /dev/null +++ b/install/include/postgresql/server/common/kwlookup.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * kwlookup.h + * Key word lookup for PostgreSQL + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/kwlookup.h + * + *------------------------------------------------------------------------- + */ +#ifndef KWLOOKUP_H +#define KWLOOKUP_H + +/* Hash function used by ScanKeywordLookup */ +typedef int (*ScanKeywordHashFunc) (const void *key, size_t keylen); + +/* + * This struct contains the data needed by ScanKeywordLookup to perform a + * search within a set of keywords. The contents are typically generated by + * src/tools/gen_keywordlist.pl from a header containing PG_KEYWORD macros. + */ +typedef struct ScanKeywordList +{ + const char *kw_string; /* all keywords in order, separated by \0 */ + const uint16 *kw_offsets; /* offsets to the start of each keyword */ + ScanKeywordHashFunc hash; /* perfect hash function for keywords */ + int num_keywords; /* number of keywords */ + int max_kw_len; /* length of longest keyword */ +} ScanKeywordList; + + +extern int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords); + +/* Code that wants to retrieve the text of the N'th keyword should use this. */ +static inline const char * +GetScanKeyword(int n, const ScanKeywordList *keywords) +{ + return keywords->kw_string + keywords->kw_offsets[n]; +} + +#endif /* KWLOOKUP_H */ diff --git a/install/include/postgresql/server/common/link-canary.h b/install/include/postgresql/server/common/link-canary.h new file mode 100644 index 00000000000..178d123b1a0 --- /dev/null +++ b/install/include/postgresql/server/common/link-canary.h @@ -0,0 +1,17 @@ +/*------------------------------------------------------------------------- + * + * link-canary.h + * Detect whether src/common functions came from frontend or backend. + * + * Copyright (c) 2018-2023, PostgreSQL Global Development Group + * + * src/include/common/link-canary.h + * + *------------------------------------------------------------------------- + */ +#ifndef LINK_CANARY_H +#define LINK_CANARY_H + +extern bool pg_link_canary_is_frontend(void); + +#endif /* LINK_CANARY_H */ diff --git a/install/include/postgresql/server/common/logging.h b/install/include/postgresql/server/common/logging.h new file mode 100644 index 00000000000..99e888af93d --- /dev/null +++ b/install/include/postgresql/server/common/logging.h @@ -0,0 +1,156 @@ +/*------------------------------------------------------------------------- + * Logging framework for frontend programs + * + * Copyright (c) 2018-2023, PostgreSQL Global Development Group + * + * src/include/common/logging.h + * + *------------------------------------------------------------------------- + */ +#ifndef COMMON_LOGGING_H +#define COMMON_LOGGING_H + +/* + * Log levels are informational only. They do not affect program flow. + */ +enum pg_log_level +{ + /* + * Not initialized yet (not to be used as an actual message log level). + */ + PG_LOG_NOTSET = 0, + + /* + * Low level messages that are normally off by default. + */ + PG_LOG_DEBUG, + + /* + * Any program messages that go to stderr, shown by default. (The + * program's normal output should go to stdout and not use the logging + * system.) + */ + PG_LOG_INFO, + + /* + * Warnings and "almost" errors, depends on the program + */ + PG_LOG_WARNING, + + /* + * Errors + */ + PG_LOG_ERROR, + + /* + * Turn all logging off (not to be used as an actual message log level). + */ + PG_LOG_OFF, +}; + +/* + * __pg_log_level is the minimum log level that will actually be shown. + */ +extern enum pg_log_level __pg_log_level; + +/* + * A log message can have several parts. The primary message is required, + * others are optional. When emitting multiple parts, do so in the order of + * this enum, for consistency. + */ +enum pg_log_part +{ + /* + * The primary message. Try to keep it to one line; follow the backend's + * style guideline for primary messages. + */ + PG_LOG_PRIMARY, + + /* + * Additional detail. Follow the backend's style guideline for detail + * messages. + */ + PG_LOG_DETAIL, + + /* + * Hint (not guaranteed correct) about how to fix the problem. Follow the + * backend's style guideline for hint messages. + */ + PG_LOG_HINT, +}; + +/* + * Kind of a hack to be able to produce the psql output exactly as required by + * the regression tests. + */ +#define PG_LOG_FLAG_TERSE 1 + +void pg_logging_init(const char *argv0); +void pg_logging_config(int new_flags); +void pg_logging_set_level(enum pg_log_level new_level); +void pg_logging_increase_verbosity(void); +void pg_logging_set_pre_callback(void (*cb) (void)); +void pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno)); + +void pg_log_generic(enum pg_log_level level, enum pg_log_part part, + const char *pg_restrict fmt,...) + pg_attribute_printf(3, 4); +void pg_log_generic_v(enum pg_log_level level, enum pg_log_part part, + const char *pg_restrict fmt, va_list ap) + pg_attribute_printf(3, 0); + +/* + * Preferred style is to use these macros to perform logging; don't call + * pg_log_generic[_v] directly, except perhaps in error interface code. + */ +#define pg_log_error(...) \ + pg_log_generic(PG_LOG_ERROR, PG_LOG_PRIMARY, __VA_ARGS__) + +#define pg_log_error_detail(...) \ + pg_log_generic(PG_LOG_ERROR, PG_LOG_DETAIL, __VA_ARGS__) + +#define pg_log_error_hint(...) \ + pg_log_generic(PG_LOG_ERROR, PG_LOG_HINT, __VA_ARGS__) + +#define pg_log_warning(...) \ + pg_log_generic(PG_LOG_WARNING, PG_LOG_PRIMARY, __VA_ARGS__) + +#define pg_log_warning_detail(...) \ + pg_log_generic(PG_LOG_WARNING, PG_LOG_DETAIL, __VA_ARGS__) + +#define pg_log_warning_hint(...) \ + pg_log_generic(PG_LOG_WARNING, PG_LOG_HINT, __VA_ARGS__) + +#define pg_log_info(...) \ + pg_log_generic(PG_LOG_INFO, PG_LOG_PRIMARY, __VA_ARGS__) + +#define pg_log_info_detail(...) \ + pg_log_generic(PG_LOG_INFO, PG_LOG_DETAIL, __VA_ARGS__) + +#define pg_log_info_hint(...) \ + pg_log_generic(PG_LOG_INFO, PG_LOG_HINT, __VA_ARGS__) + +#define pg_log_debug(...) do { \ + if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) \ + pg_log_generic(PG_LOG_DEBUG, PG_LOG_PRIMARY, __VA_ARGS__); \ + } while(0) + +#define pg_log_debug_detail(...) do { \ + if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) \ + pg_log_generic(PG_LOG_DEBUG, PG_LOG_DETAIL, __VA_ARGS__); \ + } while(0) + +#define pg_log_debug_hint(...) do { \ + if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) \ + pg_log_generic(PG_LOG_DEBUG, PG_LOG_HINT, __VA_ARGS__); \ + } while(0) + +/* + * A common shortcut: pg_log_error() and immediately exit(1). + */ +#define pg_fatal(...) do { \ + pg_log_generic(PG_LOG_ERROR, PG_LOG_PRIMARY, __VA_ARGS__); \ + exit(1); \ + } while(0) + +#endif /* COMMON_LOGGING_H */ diff --git a/install/include/postgresql/server/common/md5.h b/install/include/postgresql/server/common/md5.h new file mode 100644 index 00000000000..b6089bacff5 --- /dev/null +++ b/install/include/postgresql/server/common/md5.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * md5.h + * Constants and common utilities related to MD5. + * + * These definitions are needed by both frontend and backend code to work + * with MD5-encrypted passwords. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/md5.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_MD5_H +#define PG_MD5_H + +/* Size of result generated by MD5 computation */ +#define MD5_DIGEST_LENGTH 16 +/* Block size for MD5 */ +#define MD5_BLOCK_SIZE 64 + +/* password-related data */ +#define MD5_PASSWD_CHARSET "0123456789abcdef" +#define MD5_PASSWD_LEN 35 + +/* Utilities common to all the MD5 implementations, as of md5_common.c */ +extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum, + const char **errstr); +extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf, + const char **errstr); +extern bool pg_md5_encrypt(const char *passwd, const char *salt, + size_t salt_len, char *buf, + const char **errstr); + +#endif /* PG_MD5_H */ diff --git a/install/include/postgresql/server/common/openssl.h b/install/include/postgresql/server/common/openssl.h new file mode 100644 index 00000000000..060675ab33b --- /dev/null +++ b/install/include/postgresql/server/common/openssl.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * openssl.h + * OpenSSL supporting functionality shared between frontend and backend + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/common/openssl.h + * + *------------------------------------------------------------------------- + */ +#ifndef COMMON_OPENSSL_H +#define COMMON_OPENSSL_H + +#ifdef USE_OPENSSL +#include + +/* + * OpenSSL doesn't provide any very nice way to identify the min/max + * protocol versions the library supports, so we fake it as best we can. + * Note in particular that this doesn't account for restrictions that + * might be specified in the installation's openssl.cnf. + * + * We disable SSLv3 and older in library setup, so TLSv1 is the oldest + * protocol version of interest. + */ +#define MIN_OPENSSL_TLS_VERSION "TLSv1" + +#if defined(TLS1_3_VERSION) +#define MAX_OPENSSL_TLS_VERSION "TLSv1.3" +#elif defined(TLS1_2_VERSION) +#define MAX_OPENSSL_TLS_VERSION "TLSv1.2" +#elif defined(TLS1_1_VERSION) +#define MAX_OPENSSL_TLS_VERSION "TLSv1.1" +#else +#define MAX_OPENSSL_TLS_VERSION "TLSv1" +#endif + +/* src/common/protocol_openssl.c */ +#ifndef SSL_CTX_set_min_proto_version +extern int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version); +extern int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version); +#endif + +#endif /* USE_OPENSSL */ + +#endif /* COMMON_OPENSSL_H */ diff --git a/install/include/postgresql/server/common/percentrepl.h b/install/include/postgresql/server/common/percentrepl.h new file mode 100644 index 00000000000..0efb6ecb5ba --- /dev/null +++ b/install/include/postgresql/server/common/percentrepl.h @@ -0,0 +1,18 @@ +/*------------------------------------------------------------------------- + * + * percentrepl.h + * Common routines to replace percent placeholders in strings + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/percentrepl.h + * + *------------------------------------------------------------------------- + */ +#ifndef PERCENTREPL_H +#define PERCENTREPL_H + +extern char *replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...); + +#endif /* PERCENTREPL_H */ diff --git a/install/include/postgresql/server/common/pg_lzcompress.h b/install/include/postgresql/server/common/pg_lzcompress.h new file mode 100644 index 00000000000..2a12b33a008 --- /dev/null +++ b/install/include/postgresql/server/common/pg_lzcompress.h @@ -0,0 +1,93 @@ +/* ---------- + * pg_lzcompress.h - + * + * Definitions for the builtin LZ compressor + * + * src/include/common/pg_lzcompress.h + * ---------- + */ + +#ifndef _PG_LZCOMPRESS_H_ +#define _PG_LZCOMPRESS_H_ + + +/* ---------- + * PGLZ_MAX_OUTPUT - + * + * Macro to compute the buffer size required by pglz_compress(). + * We allow 4 bytes for overrun before detecting compression failure. + * ---------- + */ +#define PGLZ_MAX_OUTPUT(_dlen) ((_dlen) + 4) + + +/* ---------- + * PGLZ_Strategy - + * + * Some values that control the compression algorithm. + * + * min_input_size Minimum input data size to consider compression. + * + * max_input_size Maximum input data size to consider compression. + * + * min_comp_rate Minimum compression rate (0-99%) to require. + * Regardless of min_comp_rate, the output must be + * smaller than the input, else we don't store + * compressed. + * + * first_success_by Abandon compression if we find no compressible + * data within the first this-many bytes. + * + * match_size_good The initial GOOD match size when starting history + * lookup. When looking up the history to find a + * match that could be expressed as a tag, the + * algorithm does not always walk back entirely. + * A good match fast is usually better than the + * best possible one very late. For each iteration + * in the lookup, this value is lowered so the + * longer the lookup takes, the smaller matches + * are considered good. + * + * match_size_drop The percentage by which match_size_good is lowered + * after each history check. Allowed values are + * 0 (no change until end) to 100 (only check + * latest history entry at all). + * ---------- + */ +typedef struct PGLZ_Strategy +{ + int32 min_input_size; + int32 max_input_size; + int32 min_comp_rate; + int32 first_success_by; + int32 match_size_good; + int32 match_size_drop; +} PGLZ_Strategy; + + +/* ---------- + * The standard strategies + * + * PGLZ_strategy_default Recommended default strategy for TOAST. + * + * PGLZ_strategy_always Try to compress inputs of any length. + * Fallback to uncompressed storage only if + * output would be larger than input. + * ---------- + */ +extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_default; +extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_always; + + +/* ---------- + * Global function declarations + * ---------- + */ +extern int32 pglz_compress(const char *source, int32 slen, char *dest, + const PGLZ_Strategy *strategy); +extern int32 pglz_decompress(const char *source, int32 slen, char *dest, + int32 rawsize, bool check_complete); +extern int32 pglz_maximum_compressed_size(int32 rawsize, + int32 total_compressed_size); + +#endif /* _PG_LZCOMPRESS_H_ */ diff --git a/install/include/postgresql/server/common/pg_prng.h b/install/include/postgresql/server/common/pg_prng.h new file mode 100644 index 00000000000..b5c0b8d2883 --- /dev/null +++ b/install/include/postgresql/server/common/pg_prng.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * Pseudo-Random Number Generator + * + * Copyright (c) 2021-2023, PostgreSQL Global Development Group + * + * src/include/common/pg_prng.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PRNG_H +#define PG_PRNG_H + +/* + * State vector for PRNG generation. Callers should treat this as an + * opaque typedef, but we expose its definition to allow it to be + * embedded in other structs. + */ +typedef struct pg_prng_state +{ + uint64 s0, + s1; +} pg_prng_state; + +/* + * Callers not needing local PRNG series may use this global state vector, + * after initializing it with one of the pg_prng_...seed functions. + */ +extern PGDLLIMPORT pg_prng_state pg_global_prng_state; + +extern void pg_prng_seed(pg_prng_state *state, uint64 seed); +extern void pg_prng_fseed(pg_prng_state *state, double fseed); +extern bool pg_prng_seed_check(pg_prng_state *state); + +/* + * Initialize the PRNG state from the pg_strong_random source, + * taking care that we don't produce all-zeroes. If this returns false, + * caller should initialize the PRNG state from some other random seed, + * using pg_prng_[f]seed. + * + * We implement this as a macro, so that the pg_strong_random() call is + * in the caller. If it were in pg_prng.c, programs using pg_prng.c + * but not needing strong seeding would nonetheless be forced to pull in + * pg_strong_random.c and thence OpenSSL. + */ +#define pg_prng_strong_seed(state) \ + (pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \ + pg_prng_seed_check(state) : false) + +extern uint64 pg_prng_uint64(pg_prng_state *state); +extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax); +extern int64 pg_prng_int64(pg_prng_state *state); +extern int64 pg_prng_int64p(pg_prng_state *state); +extern uint32 pg_prng_uint32(pg_prng_state *state); +extern int32 pg_prng_int32(pg_prng_state *state); +extern int32 pg_prng_int32p(pg_prng_state *state); +extern double pg_prng_double(pg_prng_state *state); +extern double pg_prng_double_normal(pg_prng_state *state); +extern bool pg_prng_bool(pg_prng_state *state); + +#endif /* PG_PRNG_H */ diff --git a/install/include/postgresql/server/common/relpath.h b/install/include/postgresql/server/common/relpath.h new file mode 100644 index 00000000000..511c21682ec --- /dev/null +++ b/install/include/postgresql/server/common/relpath.h @@ -0,0 +1,97 @@ +/*------------------------------------------------------------------------- + * + * relpath.h + * Declarations for GetRelationPath() and friends + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/relpath.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELPATH_H +#define RELPATH_H + +/* + * 'pgrminclude ignore' needed here because CppAsString2() does not throw + * an error if the symbol is not defined. + */ +#include "catalog/catversion.h" /* pgrminclude ignore */ + +/* + * RelFileNumber data type identifies the specific relation file name. + */ +typedef Oid RelFileNumber; +#define InvalidRelFileNumber ((RelFileNumber) InvalidOid) +#define RelFileNumberIsValid(relnumber) \ + ((bool) ((relnumber) != InvalidRelFileNumber)) + +/* + * Name of major-version-specific tablespace subdirectories + */ +#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \ + CppAsString2(CATALOG_VERSION_NO) + +/* Characters to allow for an OID in a relation path */ +#define OIDCHARS 10 /* max chars printed by %u */ + +/* + * Stuff for fork names. + * + * The physical storage of a relation consists of one or more forks. + * The main fork is always created, but in addition to that there can be + * additional forks for storing various metadata. ForkNumber is used when + * we need to refer to a specific fork in a relation. + */ +typedef enum ForkNumber +{ + InvalidForkNumber = -1, + MAIN_FORKNUM = 0, + FSM_FORKNUM, + VISIBILITYMAP_FORKNUM, + INIT_FORKNUM + + /* + * NOTE: if you add a new fork, change MAX_FORKNUM and possibly + * FORKNAMECHARS below, and update the forkNames array in + * src/common/relpath.c + */ +} ForkNumber; + +#define MAX_FORKNUM INIT_FORKNUM + +#define FORKNAMECHARS 4 /* max chars for a fork name */ + +extern PGDLLIMPORT const char *const forkNames[]; + +extern ForkNumber forkname_to_number(const char *forkName); +extern int forkname_chars(const char *str, ForkNumber *fork); + +/* + * Stuff for computing filesystem pathnames for relations. + */ +extern char *GetDatabasePath(Oid dbOid, Oid spcOid); + +extern char *GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber, + int backendId, ForkNumber forkNumber); + +/* + * Wrapper macros for GetRelationPath. Beware of multiple + * evaluation of the RelFileLocator or RelFileLocatorBackend argument! + */ + +/* First argument is a RelFileLocator */ +#define relpathbackend(rlocator, backend, forknum) \ + GetRelationPath((rlocator).dbOid, (rlocator).spcOid, (rlocator).relNumber, \ + backend, forknum) + +/* First argument is a RelFileLocator */ +#define relpathperm(rlocator, forknum) \ + relpathbackend(rlocator, InvalidBackendId, forknum) + +/* First argument is a RelFileLocatorBackend */ +#define relpath(rlocator, forknum) \ + relpathbackend((rlocator).locator, (rlocator).backend, forknum) + +#endif /* RELPATH_H */ diff --git a/install/include/postgresql/server/common/restricted_token.h b/install/include/postgresql/server/common/restricted_token.h new file mode 100644 index 00000000000..d4077c76613 --- /dev/null +++ b/install/include/postgresql/server/common/restricted_token.h @@ -0,0 +1,24 @@ +/* + * restricted_token.h + * helper routine to ensure restricted token on Windows + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/restricted_token.h + */ +#ifndef COMMON_RESTRICTED_TOKEN_H +#define COMMON_RESTRICTED_TOKEN_H + +/* + * On Windows make sure that we are running with a restricted token, + * On other platforms do nothing. + */ +void get_restricted_token(void); + +#ifdef WIN32 +/* Create a restricted token and execute the specified process with it. */ +HANDLE CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo); +#endif + +#endif /* COMMON_RESTRICTED_TOKEN_H */ diff --git a/install/include/postgresql/server/common/saslprep.h b/install/include/postgresql/server/common/saslprep.h new file mode 100644 index 00000000000..f622db962f8 --- /dev/null +++ b/install/include/postgresql/server/common/saslprep.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * saslprep.h + * SASLprep normalization, for SCRAM authentication + * + * These definitions are used by both frontend and backend code. + * + * Copyright (c) 2017-2023, PostgreSQL Global Development Group + * + * src/include/common/saslprep.h + * + *------------------------------------------------------------------------- + */ +#ifndef SASLPREP_H +#define SASLPREP_H + +/* + * Return codes for pg_saslprep() function. + */ +typedef enum +{ + SASLPREP_SUCCESS = 0, + SASLPREP_OOM = -1, /* out of memory (only in frontend) */ + SASLPREP_INVALID_UTF8 = -2, /* input is not a valid UTF-8 string */ + SASLPREP_PROHIBITED = -3 /* output would contain prohibited characters */ +} pg_saslprep_rc; + +extern pg_saslprep_rc pg_saslprep(const char *input, char **output); + +#endif /* SASLPREP_H */ diff --git a/install/include/postgresql/server/common/scram-common.h b/install/include/postgresql/server/common/scram-common.h new file mode 100644 index 00000000000..5ccff96ecee --- /dev/null +++ b/install/include/postgresql/server/common/scram-common.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------- + * + * scram-common.h + * Declarations for helper functions used for SCRAM authentication + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/scram-common.h + * + *------------------------------------------------------------------------- + */ +#ifndef SCRAM_COMMON_H +#define SCRAM_COMMON_H + +#include "common/cryptohash.h" +#include "common/sha2.h" + +/* Name of SCRAM mechanisms per IANA */ +#define SCRAM_SHA_256_NAME "SCRAM-SHA-256" +#define SCRAM_SHA_256_PLUS_NAME "SCRAM-SHA-256-PLUS" /* with channel binding */ + +/* Length of SCRAM keys (client and server) */ +#define SCRAM_SHA_256_KEY_LEN PG_SHA256_DIGEST_LENGTH + +/* + * Size of buffers used internally by SCRAM routines, that should be the + * maximum of SCRAM_SHA_*_KEY_LEN among the hash methods supported. + */ +#define SCRAM_MAX_KEY_LEN SCRAM_SHA_256_KEY_LEN + +/* + * Size of random nonce generated in the authentication exchange. This + * is in "raw" number of bytes, the actual nonces sent over the wire are + * encoded using only ASCII-printable characters. + */ +#define SCRAM_RAW_NONCE_LEN 18 + +/* + * Length of salt when generating new secrets, in bytes. (It will be stored + * and sent over the wire encoded in Base64.) 16 bytes is what the example in + * RFC 7677 uses. + */ +#define SCRAM_DEFAULT_SALT_LEN 16 + +/* + * Default number of iterations when generating secret. Should be at least + * 4096 per RFC 7677. + */ +#define SCRAM_SHA_256_DEFAULT_ITERATIONS 4096 + +extern int scram_SaltedPassword(const char *password, + pg_cryptohash_type hash_type, int key_length, + const char *salt, int saltlen, int iterations, + uint8 *result, const char **errstr); +extern int scram_H(const uint8 *input, pg_cryptohash_type hash_type, + int key_length, uint8 *result, + const char **errstr); +extern int scram_ClientKey(const uint8 *salted_password, + pg_cryptohash_type hash_type, int key_length, + uint8 *result, const char **errstr); +extern int scram_ServerKey(const uint8 *salted_password, + pg_cryptohash_type hash_type, int key_length, + uint8 *result, const char **errstr); + +extern char *scram_build_secret(pg_cryptohash_type hash_type, int key_length, + const char *salt, int saltlen, int iterations, + const char *password, const char **errstr); + +#endif /* SCRAM_COMMON_H */ diff --git a/install/include/postgresql/server/common/sha1.h b/install/include/postgresql/server/common/sha1.h new file mode 100644 index 00000000000..e6933d96bbc --- /dev/null +++ b/install/include/postgresql/server/common/sha1.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * sha1.h + * Constants related to SHA1. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/sha1.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHA1_H +#define PG_SHA1_H + +/* Size of result generated by SHA1 computation */ +#define SHA1_DIGEST_LENGTH 20 +/* Block size for SHA1 */ +#define SHA1_BLOCK_SIZE 64 + +#endif /* PG_SHA1_H */ diff --git a/install/include/postgresql/server/common/sha2.h b/install/include/postgresql/server/common/sha2.h new file mode 100644 index 00000000000..9b46cd1a373 --- /dev/null +++ b/install/include/postgresql/server/common/sha2.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * sha2.h + * Constants related to SHA224, 256, 384 AND 512. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/common/sha2.h + * + *------------------------------------------------------------------------- + */ + +#ifndef _PG_SHA2_H_ +#define _PG_SHA2_H_ + +/*** SHA224/256/384/512 Various Length Definitions ***********************/ +#define PG_SHA224_BLOCK_LENGTH 64 +#define PG_SHA224_DIGEST_LENGTH 28 +#define PG_SHA224_DIGEST_STRING_LENGTH (PG_SHA224_DIGEST_LENGTH * 2 + 1) +#define PG_SHA256_BLOCK_LENGTH 64 +#define PG_SHA256_DIGEST_LENGTH 32 +#define PG_SHA256_DIGEST_STRING_LENGTH (PG_SHA256_DIGEST_LENGTH * 2 + 1) +#define PG_SHA384_BLOCK_LENGTH 128 +#define PG_SHA384_DIGEST_LENGTH 48 +#define PG_SHA384_DIGEST_STRING_LENGTH (PG_SHA384_DIGEST_LENGTH * 2 + 1) +#define PG_SHA512_BLOCK_LENGTH 128 +#define PG_SHA512_DIGEST_LENGTH 64 +#define PG_SHA512_DIGEST_STRING_LENGTH (PG_SHA512_DIGEST_LENGTH * 2 + 1) + +#endif /* _PG_SHA2_H_ */ diff --git a/install/include/postgresql/server/common/shortest_dec.h b/install/include/postgresql/server/common/shortest_dec.h new file mode 100644 index 00000000000..8479b98575f --- /dev/null +++ b/install/include/postgresql/server/common/shortest_dec.h @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------- + * + * Ryu floating-point output. + * + * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/common/shortest_dec.h + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ +#ifndef SHORTEST_DEC_H +#define SHORTEST_DEC_H + +/*---- + * The length of 25 comes from: + * + * Case 1: -9.9999999999999999e-299 = 24 bytes, plus 1 for null + * + * Case 2: -0.00099999999999999999 = 23 bytes, plus 1 for null + */ +#define DOUBLE_SHORTEST_DECIMAL_LEN 25 + +int double_to_shortest_decimal_bufn(double f, char *result); +int double_to_shortest_decimal_buf(double f, char *result); +char *double_to_shortest_decimal(double f); + +/* + * The length of 16 comes from: + * + * Case 1: -9.99999999e+29 = 15 bytes, plus 1 for null + * + * Case 2: -0.000999999999 = 15 bytes, plus 1 for null + */ +#define FLOAT_SHORTEST_DECIMAL_LEN 16 + +int float_to_shortest_decimal_bufn(float f, char *result); +int float_to_shortest_decimal_buf(float f, char *result); +char *float_to_shortest_decimal(float f); + +#endif /* SHORTEST_DEC_H */ diff --git a/install/include/postgresql/server/common/string.h b/install/include/postgresql/server/common/string.h new file mode 100644 index 00000000000..977ef327d0f --- /dev/null +++ b/install/include/postgresql/server/common/string.h @@ -0,0 +1,44 @@ +/* + * string.h + * string handling helpers + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/string.h + */ +#ifndef COMMON_STRING_H +#define COMMON_STRING_H + +#include + +struct StringInfoData; /* avoid including stringinfo.h here */ + +typedef struct PromptInterruptContext +{ + /* To avoid including here, jmpbuf is declared "void *" */ + void *jmpbuf; /* existing longjmp buffer */ + volatile sig_atomic_t *enabled; /* flag that enables longjmp-on-interrupt */ + bool canceled; /* indicates whether cancellation occurred */ +} PromptInterruptContext; + +/* functions in src/common/string.c */ +extern bool pg_str_endswith(const char *str, const char *end); +extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, + int base); +extern char *pg_clean_ascii(const char *str, int alloc_flags); +extern int pg_strip_crlf(char *str); +extern bool pg_is_ascii(const char *str); + +/* functions in src/common/pg_get_line.c */ +extern char *pg_get_line(FILE *stream, PromptInterruptContext *prompt_ctx); +extern bool pg_get_line_buf(FILE *stream, struct StringInfoData *buf); +extern bool pg_get_line_append(FILE *stream, struct StringInfoData *buf, + PromptInterruptContext *prompt_ctx); + +/* functions in src/common/sprompt.c */ +extern char *simple_prompt(const char *prompt, bool echo); +extern char *simple_prompt_extended(const char *prompt, bool echo, + PromptInterruptContext *prompt_ctx); + +#endif /* COMMON_STRING_H */ diff --git a/install/include/postgresql/server/common/unicode_east_asian_fw_table.h b/install/include/postgresql/server/common/unicode_east_asian_fw_table.h new file mode 100644 index 00000000000..f77e6dfd423 --- /dev/null +++ b/install/include/postgresql/server/common/unicode_east_asian_fw_table.h @@ -0,0 +1,125 @@ +/* generated by src/common/unicode/generate-unicode_east_asian_fw_table.pl, do not edit */ + +static const struct mbinterval east_asian_fw[] = { + {0x1100, 0x115F}, + {0x231A, 0x231B}, + {0x2329, 0x232A}, + {0x23E9, 0x23EC}, + {0x23F0, 0x23F0}, + {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, + {0x2614, 0x2615}, + {0x2648, 0x2653}, + {0x267F, 0x267F}, + {0x2693, 0x2693}, + {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, + {0x26BD, 0x26BE}, + {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, + {0x26D4, 0x26D4}, + {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, + {0x26F5, 0x26F5}, + {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, + {0x2705, 0x2705}, + {0x270A, 0x270B}, + {0x2728, 0x2728}, + {0x274C, 0x274C}, + {0x274E, 0x274E}, + {0x2753, 0x2755}, + {0x2757, 0x2757}, + {0x2795, 0x2797}, + {0x27B0, 0x27B0}, + {0x27BF, 0x27BF}, + {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, + {0x2B55, 0x2B55}, + {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, + {0x2F00, 0x2FD5}, + {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, + {0x3041, 0x3096}, + {0x3099, 0x30FF}, + {0x3105, 0x312F}, + {0x3131, 0x318E}, + {0x3190, 0x31E3}, + {0x31F0, 0x321E}, + {0x3220, 0x3247}, + {0x3250, 0x4DBF}, + {0x4E00, 0xA48C}, + {0xA490, 0xA4C6}, + {0xA960, 0xA97C}, + {0xAC00, 0xD7A3}, + {0xF900, 0xFAFF}, + {0xFE10, 0xFE19}, + {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, + {0xFE68, 0xFE6B}, + {0xFF01, 0xFF60}, + {0xFFE0, 0xFFE6}, + {0x16FE0, 0x16FE4}, + {0x16FF0, 0x16FF1}, + {0x17000, 0x187F7}, + {0x18800, 0x18CD5}, + {0x18D00, 0x18D08}, + {0x1AFF0, 0x1AFF3}, + {0x1AFF5, 0x1AFFB}, + {0x1AFFD, 0x1AFFE}, + {0x1B000, 0x1B122}, + {0x1B132, 0x1B132}, + {0x1B150, 0x1B152}, + {0x1B155, 0x1B155}, + {0x1B164, 0x1B167}, + {0x1B170, 0x1B2FB}, + {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, + {0x1F18E, 0x1F18E}, + {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, + {0x1F210, 0x1F23B}, + {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, + {0x1F260, 0x1F265}, + {0x1F300, 0x1F320}, + {0x1F32D, 0x1F335}, + {0x1F337, 0x1F37C}, + {0x1F37E, 0x1F393}, + {0x1F3A0, 0x1F3CA}, + {0x1F3CF, 0x1F3D3}, + {0x1F3E0, 0x1F3F0}, + {0x1F3F4, 0x1F3F4}, + {0x1F3F8, 0x1F43E}, + {0x1F440, 0x1F440}, + {0x1F442, 0x1F4FC}, + {0x1F4FF, 0x1F53D}, + {0x1F54B, 0x1F54E}, + {0x1F550, 0x1F567}, + {0x1F57A, 0x1F57A}, + {0x1F595, 0x1F596}, + {0x1F5A4, 0x1F5A4}, + {0x1F5FB, 0x1F64F}, + {0x1F680, 0x1F6C5}, + {0x1F6CC, 0x1F6CC}, + {0x1F6D0, 0x1F6D2}, + {0x1F6D5, 0x1F6D7}, + {0x1F6DC, 0x1F6DF}, + {0x1F6EB, 0x1F6EC}, + {0x1F6F4, 0x1F6FC}, + {0x1F7E0, 0x1F7EB}, + {0x1F7F0, 0x1F7F0}, + {0x1F90C, 0x1F93A}, + {0x1F93C, 0x1F945}, + {0x1F947, 0x1F9FF}, + {0x1FA70, 0x1FA7C}, + {0x1FA80, 0x1FA88}, + {0x1FA90, 0x1FABD}, + {0x1FABF, 0x1FAC5}, + {0x1FACE, 0x1FADB}, + {0x1FAE0, 0x1FAE8}, + {0x1FAF0, 0x1FAF8}, + {0x20000, 0x2FFFD}, + {0x30000, 0x3FFFD}, +}; diff --git a/install/include/postgresql/server/common/unicode_nonspacing_table.h b/install/include/postgresql/server/common/unicode_nonspacing_table.h new file mode 100644 index 00000000000..8d00e127fcd --- /dev/null +++ b/install/include/postgresql/server/common/unicode_nonspacing_table.h @@ -0,0 +1,326 @@ +/* generated by src/common/unicode/generate-unicode_nonspacing_table.pl, do not edit */ + +static const struct mbinterval nonspacing[] = { + {0x00AD, 0x00AD}, + {0x0300, 0x036F}, + {0x0483, 0x0489}, + {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, + {0x05C1, 0x05C2}, + {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, + {0x0600, 0x0605}, + {0x0610, 0x061A}, + {0x061C, 0x061C}, + {0x064B, 0x065F}, + {0x0670, 0x0670}, + {0x06D6, 0x06DD}, + {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, + {0x06EA, 0x06ED}, + {0x070F, 0x070F}, + {0x0711, 0x0711}, + {0x0730, 0x074A}, + {0x07A6, 0x07B0}, + {0x07EB, 0x07F3}, + {0x07FD, 0x07FD}, + {0x0816, 0x0819}, + {0x081B, 0x0823}, + {0x0825, 0x0827}, + {0x0829, 0x082D}, + {0x0859, 0x085B}, + {0x0890, 0x089F}, + {0x08CA, 0x0902}, + {0x093A, 0x093A}, + {0x093C, 0x093C}, + {0x0941, 0x0948}, + {0x094D, 0x094D}, + {0x0951, 0x0957}, + {0x0962, 0x0963}, + {0x0981, 0x0981}, + {0x09BC, 0x09BC}, + {0x09C1, 0x09C4}, + {0x09CD, 0x09CD}, + {0x09E2, 0x09E3}, + {0x09FE, 0x0A02}, + {0x0A3C, 0x0A3C}, + {0x0A41, 0x0A51}, + {0x0A70, 0x0A71}, + {0x0A75, 0x0A75}, + {0x0A81, 0x0A82}, + {0x0ABC, 0x0ABC}, + {0x0AC1, 0x0AC8}, + {0x0ACD, 0x0ACD}, + {0x0AE2, 0x0AE3}, + {0x0AFA, 0x0B01}, + {0x0B3C, 0x0B3C}, + {0x0B3F, 0x0B3F}, + {0x0B41, 0x0B44}, + {0x0B4D, 0x0B56}, + {0x0B62, 0x0B63}, + {0x0B82, 0x0B82}, + {0x0BC0, 0x0BC0}, + {0x0BCD, 0x0BCD}, + {0x0C00, 0x0C00}, + {0x0C04, 0x0C04}, + {0x0C3C, 0x0C3C}, + {0x0C3E, 0x0C40}, + {0x0C46, 0x0C56}, + {0x0C62, 0x0C63}, + {0x0C81, 0x0C81}, + {0x0CBC, 0x0CBC}, + {0x0CBF, 0x0CBF}, + {0x0CC6, 0x0CC6}, + {0x0CCC, 0x0CCD}, + {0x0CE2, 0x0CE3}, + {0x0D00, 0x0D01}, + {0x0D3B, 0x0D3C}, + {0x0D41, 0x0D44}, + {0x0D4D, 0x0D4D}, + {0x0D62, 0x0D63}, + {0x0D81, 0x0D81}, + {0x0DCA, 0x0DCA}, + {0x0DD2, 0x0DD6}, + {0x0E31, 0x0E31}, + {0x0E34, 0x0E3A}, + {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, + {0x0EB4, 0x0EBC}, + {0x0EC8, 0x0ECE}, + {0x0F18, 0x0F19}, + {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, + {0x0F39, 0x0F39}, + {0x0F71, 0x0F7E}, + {0x0F80, 0x0F84}, + {0x0F86, 0x0F87}, + {0x0F8D, 0x0FBC}, + {0x0FC6, 0x0FC6}, + {0x102D, 0x1030}, + {0x1032, 0x1037}, + {0x1039, 0x103A}, + {0x103D, 0x103E}, + {0x1058, 0x1059}, + {0x105E, 0x1060}, + {0x1071, 0x1074}, + {0x1082, 0x1082}, + {0x1085, 0x1086}, + {0x108D, 0x108D}, + {0x109D, 0x109D}, + {0x135D, 0x135F}, + {0x1712, 0x1714}, + {0x1732, 0x1733}, + {0x1752, 0x1753}, + {0x1772, 0x1773}, + {0x17B4, 0x17B5}, + {0x17B7, 0x17BD}, + {0x17C6, 0x17C6}, + {0x17C9, 0x17D3}, + {0x17DD, 0x17DD}, + {0x180B, 0x180F}, + {0x1885, 0x1886}, + {0x18A9, 0x18A9}, + {0x1920, 0x1922}, + {0x1927, 0x1928}, + {0x1932, 0x1932}, + {0x1939, 0x193B}, + {0x1A17, 0x1A18}, + {0x1A1B, 0x1A1B}, + {0x1A56, 0x1A56}, + {0x1A58, 0x1A60}, + {0x1A62, 0x1A62}, + {0x1A65, 0x1A6C}, + {0x1A73, 0x1A7F}, + {0x1AB0, 0x1B03}, + {0x1B34, 0x1B34}, + {0x1B36, 0x1B3A}, + {0x1B3C, 0x1B3C}, + {0x1B42, 0x1B42}, + {0x1B6B, 0x1B73}, + {0x1B80, 0x1B81}, + {0x1BA2, 0x1BA5}, + {0x1BA8, 0x1BA9}, + {0x1BAB, 0x1BAD}, + {0x1BE6, 0x1BE6}, + {0x1BE8, 0x1BE9}, + {0x1BED, 0x1BED}, + {0x1BEF, 0x1BF1}, + {0x1C2C, 0x1C33}, + {0x1C36, 0x1C37}, + {0x1CD0, 0x1CD2}, + {0x1CD4, 0x1CE0}, + {0x1CE2, 0x1CE8}, + {0x1CED, 0x1CED}, + {0x1CF4, 0x1CF4}, + {0x1CF8, 0x1CF9}, + {0x1DC0, 0x1DFF}, + {0x200B, 0x200F}, + {0x202A, 0x202E}, + {0x2060, 0x206F}, + {0x20D0, 0x20F0}, + {0x2CEF, 0x2CF1}, + {0x2D7F, 0x2D7F}, + {0x2DE0, 0x2DFF}, + {0x302A, 0x302D}, + {0x3099, 0x309A}, + {0xA66F, 0xA672}, + {0xA674, 0xA67D}, + {0xA69E, 0xA69F}, + {0xA6F0, 0xA6F1}, + {0xA802, 0xA802}, + {0xA806, 0xA806}, + {0xA80B, 0xA80B}, + {0xA825, 0xA826}, + {0xA82C, 0xA82C}, + {0xA8C4, 0xA8C5}, + {0xA8E0, 0xA8F1}, + {0xA8FF, 0xA8FF}, + {0xA926, 0xA92D}, + {0xA947, 0xA951}, + {0xA980, 0xA982}, + {0xA9B3, 0xA9B3}, + {0xA9B6, 0xA9B9}, + {0xA9BC, 0xA9BD}, + {0xA9E5, 0xA9E5}, + {0xAA29, 0xAA2E}, + {0xAA31, 0xAA32}, + {0xAA35, 0xAA36}, + {0xAA43, 0xAA43}, + {0xAA4C, 0xAA4C}, + {0xAA7C, 0xAA7C}, + {0xAAB0, 0xAAB0}, + {0xAAB2, 0xAAB4}, + {0xAAB7, 0xAAB8}, + {0xAABE, 0xAABF}, + {0xAAC1, 0xAAC1}, + {0xAAEC, 0xAAED}, + {0xAAF6, 0xAAF6}, + {0xABE5, 0xABE5}, + {0xABE8, 0xABE8}, + {0xABED, 0xABED}, + {0xFB1E, 0xFB1E}, + {0xFE00, 0xFE0F}, + {0xFE20, 0xFE2F}, + {0xFEFF, 0xFEFF}, + {0xFFF9, 0xFFFB}, + {0x101FD, 0x101FD}, + {0x102E0, 0x102E0}, + {0x10376, 0x1037A}, + {0x10A01, 0x10A0F}, + {0x10A38, 0x10A3F}, + {0x10AE5, 0x10AE6}, + {0x10D24, 0x10D27}, + {0x10EAB, 0x10EAC}, + {0x10EFD, 0x10EFF}, + {0x10F46, 0x10F50}, + {0x10F82, 0x10F85}, + {0x11001, 0x11001}, + {0x11038, 0x11046}, + {0x11070, 0x11070}, + {0x11073, 0x11074}, + {0x1107F, 0x11081}, + {0x110B3, 0x110B6}, + {0x110B9, 0x110BA}, + {0x110BD, 0x110BD}, + {0x110C2, 0x110CD}, + {0x11100, 0x11102}, + {0x11127, 0x1112B}, + {0x1112D, 0x11134}, + {0x11173, 0x11173}, + {0x11180, 0x11181}, + {0x111B6, 0x111BE}, + {0x111C9, 0x111CC}, + {0x111CF, 0x111CF}, + {0x1122F, 0x11231}, + {0x11234, 0x11234}, + {0x11236, 0x11237}, + {0x1123E, 0x1123E}, + {0x11241, 0x11241}, + {0x112DF, 0x112DF}, + {0x112E3, 0x112EA}, + {0x11300, 0x11301}, + {0x1133B, 0x1133C}, + {0x11340, 0x11340}, + {0x11366, 0x11374}, + {0x11438, 0x1143F}, + {0x11442, 0x11444}, + {0x11446, 0x11446}, + {0x1145E, 0x1145E}, + {0x114B3, 0x114B8}, + {0x114BA, 0x114BA}, + {0x114BF, 0x114C0}, + {0x114C2, 0x114C3}, + {0x115B2, 0x115B5}, + {0x115BC, 0x115BD}, + {0x115BF, 0x115C0}, + {0x115DC, 0x115DD}, + {0x11633, 0x1163A}, + {0x1163D, 0x1163D}, + {0x1163F, 0x11640}, + {0x116AB, 0x116AB}, + {0x116AD, 0x116AD}, + {0x116B0, 0x116B5}, + {0x116B7, 0x116B7}, + {0x1171D, 0x1171F}, + {0x11722, 0x11725}, + {0x11727, 0x1172B}, + {0x1182F, 0x11837}, + {0x11839, 0x1183A}, + {0x1193B, 0x1193C}, + {0x1193E, 0x1193E}, + {0x11943, 0x11943}, + {0x119D4, 0x119DB}, + {0x119E0, 0x119E0}, + {0x11A01, 0x11A0A}, + {0x11A33, 0x11A38}, + {0x11A3B, 0x11A3E}, + {0x11A47, 0x11A47}, + {0x11A51, 0x11A56}, + {0x11A59, 0x11A5B}, + {0x11A8A, 0x11A96}, + {0x11A98, 0x11A99}, + {0x11C30, 0x11C3D}, + {0x11C3F, 0x11C3F}, + {0x11C92, 0x11CA7}, + {0x11CAA, 0x11CB0}, + {0x11CB2, 0x11CB3}, + {0x11CB5, 0x11CB6}, + {0x11D31, 0x11D45}, + {0x11D47, 0x11D47}, + {0x11D90, 0x11D91}, + {0x11D95, 0x11D95}, + {0x11D97, 0x11D97}, + {0x11EF3, 0x11EF4}, + {0x11F00, 0x11F01}, + {0x11F36, 0x11F3A}, + {0x11F40, 0x11F40}, + {0x11F42, 0x11F42}, + {0x13430, 0x13440}, + {0x13447, 0x13455}, + {0x16AF0, 0x16AF4}, + {0x16B30, 0x16B36}, + {0x16F4F, 0x16F4F}, + {0x16F8F, 0x16F92}, + {0x16FE4, 0x16FE4}, + {0x1BC9D, 0x1BC9E}, + {0x1BCA0, 0x1CF46}, + {0x1D167, 0x1D169}, + {0x1D173, 0x1D182}, + {0x1D185, 0x1D18B}, + {0x1D1AA, 0x1D1AD}, + {0x1D242, 0x1D244}, + {0x1DA00, 0x1DA36}, + {0x1DA3B, 0x1DA6C}, + {0x1DA75, 0x1DA75}, + {0x1DA84, 0x1DA84}, + {0x1DA9B, 0x1DAAF}, + {0x1E000, 0x1E02A}, + {0x1E08F, 0x1E08F}, + {0x1E130, 0x1E136}, + {0x1E2AE, 0x1E2AE}, + {0x1E2EC, 0x1E2EF}, + {0x1E4EC, 0x1E4EF}, + {0x1E8D0, 0x1E8D6}, + {0x1E944, 0x1E94A}, + {0xE0001, 0xE01EF}, +}; diff --git a/install/include/postgresql/server/common/unicode_norm.h b/install/include/postgresql/server/common/unicode_norm.h new file mode 100644 index 00000000000..c6627aeb7c5 --- /dev/null +++ b/install/include/postgresql/server/common/unicode_norm.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * unicode_norm.h + * Routines for normalizing Unicode strings + * + * These definitions are used by both frontend and backend code. + * + * Copyright (c) 2017-2023, PostgreSQL Global Development Group + * + * src/include/common/unicode_norm.h + * + *------------------------------------------------------------------------- + */ +#ifndef UNICODE_NORM_H +#define UNICODE_NORM_H + +#include "mb/pg_wchar.h" + +typedef enum +{ + UNICODE_NFC = 0, + UNICODE_NFD = 1, + UNICODE_NFKC = 2, + UNICODE_NFKD = 3, +} UnicodeNormalizationForm; + +/* see UAX #15 */ +typedef enum +{ + UNICODE_NORM_QC_NO = 0, + UNICODE_NORM_QC_YES = 1, + UNICODE_NORM_QC_MAYBE = -1, +} UnicodeNormalizationQC; + +extern pg_wchar *unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input); + +extern UnicodeNormalizationQC unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input); + +#endif /* UNICODE_NORM_H */ diff --git a/install/include/postgresql/server/common/unicode_norm_hashfunc.h b/install/include/postgresql/server/common/unicode_norm_hashfunc.h new file mode 100644 index 00000000000..8c824a63218 --- /dev/null +++ b/install/include/postgresql/server/common/unicode_norm_hashfunc.h @@ -0,0 +1,2974 @@ +/*------------------------------------------------------------------------- + * + * unicode_norm_hashfunc.h + * Perfect hash functions used for Unicode normalization + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/unicode_norm_hashfunc.h + * + *------------------------------------------------------------------------- + */ + +/* + * File auto-generated by src/common/unicode/generate-unicode_norm_table.pl, + * do not edit. There is deliberately not an #ifndef PG_UNICODE_NORM_HASHFUNC_H + * here. + */ + +#include "common/unicode_norm_table.h" + +/* Typedef for perfect hash functions */ +typedef int (*cp_hash_func) (const void *key); + +/* Information for lookups with perfect hash functions */ +typedef struct +{ + const pg_unicode_decomposition *decomps; + cp_hash_func hash; + int num_decomps; +} pg_unicode_decompinfo; + +typedef struct +{ + const uint16 *inverse_lookup; + cp_hash_func hash; + int num_recomps; +} pg_unicode_recompinfo; + +/* Perfect hash function for decomposition */ +static int +Decomp_hash_func(const void *key) +{ + static const int16 h[13551] = { + 6102, 6103, 6104, 6105, 6106, 11163, 11164, 9247, + 3108, 32767, 32767, 5839, 5840, 11166, 3130, 3130, + 3130, 3130, -1926, -1926, 9274, 9275, 9276, 9277, + 9278, 473, 473, 6107, 0, 6110, 6111, -1569, + 9287, 9288, 9289, 9290, 9291, 9292, 9293, 9294, + 9295, 11077, 11078, 11079, 11080, 9300, 9301, 9302, + 9303, 9304, 9305, 9306, 9307, 9308, 9309, 9310, + 9311, 9312, 9313, 9314, 9315, 9316, 9317, 9318, + 9319, 9320, 4265, 4266, -1834, 4268, 4269, 4270, + 4271, 4272, 9329, 9330, 7413, 1274, 1274, 1274, + 5264, 1274, 9337, 1301, 1301, 1301, 1301, 8982, + -3754, 11381, 11382, 11383, 11384, 10049, 11386, 5605, + 5606, 5607, 5608, 5609, 5610, 5611, 5612, 465, + 465, 5617, 5618, 5619, 5620, 5621, 5622, 5623, + 465, 465, 465, 465, 465, 465, 465, 465, + 465, 465, 465, 465, 465, 465, 465, 465, + 465, 465, 465, 465, 465, 465, 465, 465, + 465, 465, 465, 465, 465, 465, 5256, 5256, + -10103,5256, 465, 465, 5256, 5256, 465, 5939, + 465, 465, 465, 465, 465, 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, -71, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -884, -884, -884, -884, -884, -884, + 0, -885, -885, -885, -885, -885, -885, 0, + 0, -886, -886, -886, -886, -886, -4378, 0, + -888, -888, 422, -888, -888, -888, 0, -7896, + -7896, -7896, 0, 0, 0, 0, 0, 1463, + 1463, 1463, 1463, 2951, 1464, 1464, -18469,1464, + 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, + 1215, 1216, 1464, 1464, 1464, 1464, 1464, 1464, + 1464, 1464, 0, 1465, 1465, 1465, 80, 1464, + 1464, 1464, 7565, 1464, 1464, 1464, 1464, 1464, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 32767, + 32767, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 32767, 112, 113, 114, 115, 116, + 117, 32767, 118, 119, 120, 121, 122, 123, + 124, 0, 0, 0, 126, 0, 0, 0, + 0, 0, 0, 0, 4145, 4146, 4147, 4148, + 4149, 4150, 4151, 4152, 4153, 4154, 0, 0, + 0, 0, 0, 0, 4155, 4156, 4157, 4158, + 4159, 4160, 4161, 4162, 4163, 4164, 4165, 4166, + 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, + 4175, 4176, 4177, 4178, 4179, 4180, 4181, 4182, + 4183, 4184, 4185, 4186, 4187, 4188, 4189, 179, + 180, 32767, 32767, 4192, 4193, 4194, 4195, 4196, + 4197, 4198, 4199, 4200, 4201, 4202, 4203, 32767, + 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, + 4212, 4213, 4214, 4215, 4216, 4217, 4218, 4219, + 4220, 4221, 4222, 32767, 4223, 4224, 4225, 4226, + 32767, 32767, 32767, 32767, 4227, 4228, 4229, 32767, + -4545, -5662, -5662, -5662, -5662, -5662, -5662, -5662, + -5662, 4238, 4239, -5664, -5664, -5664, -5664, -5664, + -5664, -5664, -5664, 4248, 4249, 4250, 4251, 4252, + 4253, -6935, -1879, -1879, 4222, -1879, -1879, -1879, + -1879, -1879, -6935, -6935, 4265, 4266, 4267, 4268, + 4269, -4536, -4536, 1098, 1099, 1100, 1101, -6579, + 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, + 4285, 6067, 6068, 6069, 6070, 4290, 4291, 4292, + 4293, 4294, 4295, 4296, 4297, 4298, 4299, 4300, + 4301, 4302, 4303, 4304, 4305, 4306, 4307, 4308, + 4309, 4310, -745, -744, -6844, -742, -741, -740, + -739, -738, 4319, 4320, 2403, -3736, -3736, -3736, + 254, -3736, 4327, -3709, -3709, 4330, 0, 0, + 0, 0, 0, 0, 0, -2997, -2997, 2705, + 2705, 2705, 2705, 2705, 2705, 2705, 2705, 2705, + 0, 0, 0, 0, 0, 0, -4452, 0, + 0, 0, 0, 0, 2716, 0, 0, 0, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 1841, + 32767, 32767, 4710, 32767, 0, 32767, 32767, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 32767, 1845, 32767, 32767, 32767, 32767, 32767, 0, + 0, 32767, 0, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 1850, 32767, 32767, 0, + 32767, 32767, 0, 32767, 1853, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 0, 32767, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 0, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 0, 0, 32767, 32767, 0, + 0, 32767, 32767, 0, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 567, 567, 567, 567, -1649, -4447, + 32767, 32767, 566, 566, -1644, 566, 566, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 0, -1144, 0, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 0, 0, + 0, 0, 0, 304, 305, 306, -2209, -2208, + 309, 2223, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, -550, 328, 329, 330, 331, 332, + 333, 334, 335, 0, 0, 0, 0, 340, + 341, 342, 343, -534, 345, 0, 0, 0, + 0, -6511, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, + 381, 382, 32767, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, + 404, 405, 406, 407, 408, 4654, 410, 4655, + 412, 413, 414, 32767, 32767, 32767, 32767, 415, + 32767, 32767, 32767, 32767, 32767, 416, 32767, 32767, + 32767, -464, 32767, 32767, 32767, 32767, 32767, 418, + 419, 420, 421, 422, 423, 424, 32767, 425, + 32767, 426, 427, 428, 32767, 32767, 32767, 32767, + 4656, 4657, 4658, 32767, 32767, 32767, 32767, 4659, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 429, 430, 431, + 432, 433, 434, 435, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -2290, -2290, -2290, + -2290, -2290, 32767, -2291, -2291, -2291, -2291, -2291, + -2291, 2502, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 733, 733, 733, 32767, 732, + 732, 32767, 32767, 32767, 729, 32767, 0, 0, + 32767, 32767, 32767, 32767, -241, -241, 32767, -242, + 32767, 32767, 32767, -4550, 32767, 32767, 32767, 32767, + -249, -1737, -1737, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -1747, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -291, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 4660, 4661, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 3982, 3982, 3982, 32767, -1149, -1148, 32767, -1147, + 32767, 32767, 32767, -1146, 32767, 32767, 32767, 32767, + -1145, -1144, -1143, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, -4642, -1836, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, -1839, + -4651, -1838, -1838, 476, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 4708, 4709, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -4703, -1851, 32767, + 32767, 32767, 32767, 32767, 4710, 4711, 4712, 32767, + 32767, 32767, 32767, 32767, -1857, -4716, -1856, -4716, + 32767, 32767, -4718, -1855, 32767, 32767, -4720, -905, + -4720, -4720, -4720, -4720, 32767, 32767, -894, -893, + 4714, 4715, 4716, 1689, 8219, 4719, -4724, -1850, + -1850, 3912, 4721, 4722, 4723, 4724, -4724, -4724, + -4724, -4724, 32767, 32767, -4726, -4726, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + -1149, -1396, -1395, -1394, -1393, -1392, -1391, -1390, + -1389, 76, -1388, -1387, -1386, 0, -1383, -1382, + 32767, 32767, -1381, -1380, -1379, -1378, -1377, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32767, 32767, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32767, 0, 0, 0, 0, 0, 0, + 32767, 0, 0, 0, 0, 0, 0, 0, + 125, 32767, 32767, 0, 127, 128, 129, 130, + 131, 132, 32767, 32767, -4013, -4013, -4013, -4013, + -4013, -4013, 32767, 32767, -4015, 140, 141, 142, + 143, 144, 145, -4009, -4009, -4009, -4009, -4009, + -4009, -4009, -4009, -4009, -4009, -4009, 32767, 32767, + -4011, -4011, -4011, -4011, -4011, -4011, -4011, -4011, + -4011, -4011, -4011, -4011, -4011, -4011, -4011, -4011, + -4011, -4011, -4011, -4011, -4011, -4011, 0, 0, + -2541, 32767, 32767, 32767, 32767, 32767, 512, 513, + 514, 515, 516, 517, -441, -441, 520, 521, + 522, 523, 524, 525, 526, 527, 528, 529, + 530, 531, 532, 533, 534, 535, 536, 537, + -4040, -4040, 540, 541, 542, 543, 544, 545, + 546, 547, 548, 549, 550, 551, 552, 4728, + 5846, 555, 556, 32767, 557, 32767, 558, 559, + 32767, 560, 561, 32767, 562, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -4065, -4065, -4065, -4065, + 7124, 2069, 2070, -4030, 2072, 2073, 2074, 2075, + 2076, 7133, 7134, -4065, -4065, -4065, -4065, -4065, + 4741, 4742, -891, -891, -891, 32767, 6789, -4066, + -4066, -4066, -4066, -4066, 32767, 32767, -4068, -4068, + -5849, -5849, -5849, -5849, -4068, -4068, -4068, -4068, + -4068, -4068, -4068, -4068, -4068, -4068, 5832, 5833, + -4070, -4070, -4070, -4070, -4070, -4070, -4070, -4070, + 5842, 5843, 5844, 5845, 5846, 5847, -5341, -285, + -285, 5816, -285, -285, -285, -285, -285, -5341, + -5341, 5859, 5860, 5861, 5862, 5863, -2942, -2942, + 2692, 2693, 2694, 2695, -4985, 5871, 5872, 5873, + 5874, 5875, 5876, 5877, 5878, 5879, 7661, 7662, + 7663, 7664, 5884, 5885, 5886, 5887, 5888, 5889, + 5890, 5891, 5892, 5893, 5894, 5895, 5896, 5897, + 5898, 5899, 5900, 5901, 5902, 5903, 5904, 849, + 850, -5250, 852, 853, 854, 855, 856, 5913, + 5914, 3997, -2142, -2142, 590, 591, 592, 5918, + -2118, -2118, -2118, -2118, 5563, -7173, 7962, 7963, + 7964, 7965, 6630, 7967, 2186, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 4034, 32767, + 32767, 32767, 5815, 5816, 5817, 5818, 5819, 5820, + 5821, 32767, 5822, 5823, 5824, 5825, 5826, 5827, + 5828, 5829, -272, -272, -272, -272, -272, -5328, + -5328, -3410, 2730, 2731, 0, 0, 0, -5325, + 2712, 2713, 2714, 2715, -4965, 7772, -3427, 32767, + -3428, -3428, -3428, 5378, 5379, 32767, 32767, 32767, + 32767, 32767, -3434, -3434, -3434, -3434, -3434, -3434, + -3434, -3434, -3434, -5215, -5215, -5215, -5215, -3434, + -3434, -3434, -3434, -3434, -3434, -3434, -3434, -3434, + -3434, -3434, -3434, -3434, -3434, -3434, -3434, -3434, + -3434, -3434, -3434, -3434, 1622, 1622, 7723, 1622, + 1622, 1622, 1622, 1622, -3434, -3434, -1516, 4624, + 4625, 4626, 637, 4628, -3434, 4603, 4604, 4605, + 4606, -3074, 9663, -5471, -5471, -5471, -5471, -4135, + 618, -4134, -4134, 32767, 32767, 621, 622, 32767, + 623, 624, 625, 626, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 4039, 32767, + 4040, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 5450, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, -4019, 32767, 32767, 4042, -3994, -3994, -3994, + -3994, 3687, -9049, 32767, 32767, 6086, 6087, 4752, + 0, 4753, 4754, 32767, 32767, 0, 0, 32767, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 6862, + 6863, 6864, 6865, 1810, 1811, -4289, 1813, 1814, + 1815, 1816, 1817, 6874, 6875, 4958, -1181, -1181, + -1181, 2809, -1181, 6882, -1154, -1154, -1154, -1154, + 6527, -6209, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 82, 32767, 32767, 11618, 11619, 11620, 5919, 5920, + 5921, 5922, 32767, 32767, 786, 32767, 32767, 787, + 788, 789, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 790, 791, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, -1151, -1151, -1151, -1151, -1151, -1151, + -1151, -1400, -1399, 32767, 32767, 32767, 32767, 32767, + 792, 32767, 32767, 32767, -1159, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 4666, + 4667, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 665, 666, + 667, 668, 32767, 669, 670, 671, 672, 673, + 674, 675, 676, 677, 32767, 678, 679, 680, + 32767, 681, 682, 683, 684, 685, -1578, -5751, + -5751, -5751, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + -1193, 32767, 32767, 32767, 32767, -5986, -5986, -5986, + -5986, -5986, -5986, -5986, -5986, -5986, -5986, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 686, 687, 688, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -174, 1314, -173, + -173, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 689, 690, 691, 692, 693, 694, 695, 696, + 32767, 32767, 32767, 4671, 4672, 4673, 4674, 4675, + 4676, 4677, 4678, 4679, 4680, 4681, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, -1552, -1552, 32767, 32767, 32767, 32767, 32767, + 32767, 0, 697, 533, 533, 700, 701, 702, + 703, 704, 705, 706, 707, 708, 709, 710, + 711, 712, 713, 714, 715, 716, 717, 4682, + 6946, 2158, 4685, 721, 722, 723, 724, 725, + 726, 727, 728, 729, 730, 731, 732, 733, + 734, 735, 736, 737, 738, 739, 740, 741, + 742, 743, 744, 745, 746, 747, 748, 749, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 32767, 32767, 5923, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 4215, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 4181, 32767, 32767, -1922, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 4218, 32767, 32767, + 32767, 32767, 2986, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 4219, 32767, + 32767, 32767, 6001, 4221, 4222, 4223, 32767, 32767, + 32767, 4224, 4225, 4226, 4227, 4228, 4229, 4230, + 4231, 5925, 5926, 5927, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 1170, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -901, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 767, 32767, 32767, + 32767, 32767, 32767, 32767, -5005, -4757, -4757, 32767, + 32767, 32767, -4760, -4760, 68, 68, 68, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 287, 32767, 32767, 32767, 58, 58, 32767, + 57, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 4689, 32767, 4690, 32767, 32767, 32767, 32767, -1717, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 4691, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 6903, + 4693, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 775, 32767, 32767, + 776, 32767, 32767, 32767, 32767, 32767, 777, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 778, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 779, 780, 781, 32767, 4694, + 4695, 4696, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 4697, 4698, 32767, + 32767, 32767, 4699, 4700, 32767, 32767, 32767, 2428, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 2995, 2996, 2997, 2998, 2999, + 2696, 2696, 2696, 5212, 5212, 2696, 783, 2696, + 2696, 2696, 2696, 2696, 2696, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 784, + 32767, 32767, 4701, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 3013, + 3014, 3015, 32767, 32767, 32767, 0, 0, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 2139, 2140, -808, + 681, 682, 683, 684, 32767, 32767, 32767, 2633, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 3016, + 685, 686, 936, 936, 689, 32767, 32767, 32767, + 32767, 32767, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, -5401, 701, 702, 703, + 704, 705, 706, 707, -779, 709, 80, -7189, + -7189, -7189, 0, 0, 32767, 0, 0, 0, + 0, 0, 32767, 0, 32767, 0, 0, 32767, + 0, 0, 32767, 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, 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, 1310, 0, + 0, 0, 0, -7007, -7007, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6538, + 6539, 6540, 6541, 6542, 6543, 2371, 6545, 6546, + 6547, 6548, 6549, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1693, 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, 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, + -6893, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -6902, 0, 0, 0, + 0, -2600, 0, 1974, 1974, 0, 0, 0, + 0, -6912, -5556, 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, 3019, 0, 3020, + 3021, 3022, 0, 0, 3023, 3024, 0, 0, + 0, 0, 0, 2206, 3026, 0, 3027, 0, + 0, 0, 32767, 32767, 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, + -3504, 0, 0, 0, -6893, 0, 0, 5606, + 0, 0, 0, 3028, -3501, 0, -3500, -3499, + 0, 808, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32767, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 0, 0, 0, 0, 0, 0, + 32767, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1619, 1620, 32767, 32767, 1621, 1622, + 1623, 32767, 1624, 1625, 1626, 1627, 1628, 1629, + 0, 0, 1632, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 3029, 3030, 3031, 3032, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 3033, + -1994, 810, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 811, + 1188, -1999, 814, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 2778, 32767, 32767, 32767, + 2775, 32767, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2863, -2863, -2863, -2863, + -2863, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 986, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 815, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 817, 818, 819, 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, -2752, 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, 4452, 0, + 4451, 0, 0, 0, 4448, 4732, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2022, 0, 32767, 32767, 32767, + 32767, -7994, 32767, 32767, 32767, 32767, -4824, -4824, + 2857, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, -8011, -8011, + -8011, -8011, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, -251, -251, -251, -251, -251, -251, 4127, + 3239, 3239, 4549, 4549, 32767, 32767, 32767, 32767, + 32767, -3773, 4123, 4123, 4123, 4123, 4123, 5586, + 5586, 5586, 5586, 7074, 5587, 5587, -14346,5587, + 5587, 5587, 5587, 5587, 5587, 5587, 5587, 5587, + 5338, 0, 0, 0, 0, 0, 0, 0, + 32767, 0, 4131, 0, 0, 0, 0, 0, + 0, 828, 0, 0, 0, 0, 829, 830, + -3958, 0, 0, 8614, 4312, 0, 0, 0, + 0, 0, 4619, 0, 0, 0, 832, 833, + 834, 835, 32767, 32767, 32767, 32767, -215, -215, + 4094, 4630, -213, -213, -213, 32767, 32767, 32767, + 32767, 32767, -3542, -2653, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, -21505,-1572, -1572, 32767, 32767, + 32767, 32767, 32767, 32767, 0, 32767, 0, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, -977, 32767, -2211, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 4386, 4386, -2210, + -2209, 32767, 4735, 4736, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -5881, 32767, 4018, 32767, + -5885, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 4020, 1382, 1382, 1382, 1382, 1382, + 5938, 32767, 32767, 32767, -2118, 32767, 32767, 32767, + 32767, 4022, 32767, 32767, 32767, 32767, -4783, 32767, + 32767, 32767, 32767, 850, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 5806, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, + 4034, 4035, 4036, 4037, 4038, 32767, 32767, -1017, + -1016, -7116, -1014, -1013, 32767, -1012, -1011, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, -3993, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 4737, 302, 32767, 32767, 32767, + 32767, 303, 32767, 32767, 32767, 32767, 306, 32767, + 32767, 32767, 32767, 307, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 5939, + -4862, 5941, -388, -388, -388, -388, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -4874, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 0, 0, 2516, 2516, 0, -1913, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 877, 0, + 0, 0, 0, 0, 0, 0, 0, 336, + 337, 338, 339, 0, 0, 0, 0, 878, + 0, 346, 347, 348, 349, 6861, 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, 32767, 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, -4245, 0, -4244, 0, 0, 0, 32767, + 32767, 32767, 32767, 0, 32767, 32767, 32767, 32767, + 3833, 0, 32767, 32767, 32767, 881, 32767, 32767, + 32767, 0, 32767, 0, 0, 0, 0, 0, + 0, 0, 32767, 0, 32767, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 2713, -2075, -2074, -2073, + -2072, -2071, -2070, 2720, -2068, -2067, -2066, 2724, + 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, + 2733, 2734, 2735, 2736, 2737, -2055, -2054, 2740, + -2052, 2742, 2743, 2744, 2745, 2746, 2747, -1630, + -741, -740, -2049, -2048, -738, -737, -1624, 6273, + 6274, -291, -290, -289, -288, -287, -286, -285, + -284, -283, -282, -281, -280, -279, -278, -277, + -276, 2772, 0, 0, 0, 0, 2779, -5015, + -269, -268, 0, 0, -2210, 0, 0, -262, + -261, -260, -259, -258, 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, 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, 0, 0, 0, 0, 2040, 2040, + 2040, 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, 32767, + 32767, 32767, 32767, 32767, 32767, 0, 0, 0, + 0, 0, 0, 0, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 165, 166, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3964, -6227, -1438, 32767, + 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, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 2824, 2825, 5791, 3454, + 3455, 3456, 32767, 10734, -115, 3459, 1375, 32767, + 32767, 3461, 10743, 5953, 3464, 3465, 3466, 3467, + 10751, 32767, 10753, 3470, 3471, 3472, 3473, 3474, + 3475, 32767, 3476, 5980, 10770, 5982, 7789, 7790, + 3482, 0, 2797, 0, 2798, 0, 2799, 0, + 2800, 0, 2801, 0, 2802, 0, 2803, 0, + 2804, 0, 0, 2806, 0, 2807, 32767, 2807, + 0, 0, 0, 32767, 0, 0, -376, 2812, + 0, 32767, 2812, 32767, 32767, 32767, 0, 2811, + 2811, 0, 2812, 2812, 0, 32767, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2833, 0, 0, 0, 0, 3781, + 2837, 3782, 2837, 0, 3784, 3785, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2850, 0, 2851, 0, 2852, 0, + 2853, 0, 2854, 0, 2855, 0, 2856, 0, + 2857, 0, 2858, 0, 2859, 0, 2860, 0, + 2861, 0, 0, 2863, 0, 2864, 0, 3815, + 0, 0, 0, 0, 0, 0, 3828, 3829, + 9436, 9437, 9438, 6411, 2873, 2873, 0, 2874, + 2874, 8636, 9445, 9446, 9447, 9448, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2897, 0, 0, 660, 7421, 7236, + 2899, 0, 0, 0, 2902, 816, 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, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 2013, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 5486, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 4750, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 1009, -417, -417, -417, 32767, 3553, -9183, 5952, + 5953, 5954, 5955, 4620, 5957, 176, 177, 178, + 179, 180, 181, 182, 183, -4964, -4964, 188, + 189, 190, 191, 192, 193, 194, -4964, -4964, + 32767, -4965, -4965, 32767, -4966, 32767, 32767, -4968, + 32767, -4969, -4969, -4969, -4969, -4969, -4969, -4969, + -4969, -4969, -4969, 32767, -4970, -4970, -4970, -4970, + 32767, -4971, 32767, -4972, 32767, 32767, 32767, 32767, + 32767, 32767, -187, 32767, 32767, 32767, 32767, -4980, + 32767, -4981, 32767, -4982, 32767, -194, -194, -194, + 32767, -195, -195, 32767, -196, 32767, 32767, -4987, + 32767, -4988, 32767, -4989, 32767, -4990, 32767, -4991, + 32767, -4992, -4992, 0, -4993, 32767, 32767, -4995, + -202, -4995, -4995, 32767, -4996, -4996, -4996, -618, + -1506, -1506, -196, 32767, -1506, -1506, -618, -8514, + 32767, -8515, -619, -619, -619, 32767, 6034, 32767, + -455, -455, -455, -455, -455, -455, -455, -455, + -455, -455, 32767, -456, -456, -456, -456, -456, + -456, -456, -456, -456, -456, -456, -456, -456, + -456, -456, -456, -456, 32767, 32767, 32767, 32767, + 32767, -461, -461, -461, 32767, -7469, -462, -462, + -462, -462, 32767, -463, -463, -463, -463, -463, + 6075, 6076, 6077, 6078, 6079, 6080, 1908, 6082, + 6083, 6084, 6085, 6086, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, -9650, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 4751, 32767, 32767, -6842, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 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, + 3990, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2002, 2002, 2002, 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, 32767, 32767, 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, 4118, 0, + 0, 0, 0, 0, 0, 0, 4126, 0, + 0, 2728, 0, 0, 32767, 32767, 32767, 32767, + 32767, 0, 5928, 5929, 5930, 5931, 0, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 4755, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 4132, 4133, 4134, 4135, + 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, + 4144, 32767, 32767, 886, 5880, 32767, 32767, 32767, + 32767, 32767, 32767, 1132, 1132, 1132, 1132, 32767, + 6280, 1129, 1129, 32767, 1128, 1128, 1128, 1128, + 6287, 6288, 6289, 6290, 6291, 6292, 6293, 32767, + 6294, 6295, 32767, 1343, 6296, 6297, 6298, 6299, + 6300, 32767, 32767, 6301, 6302, 6303, 32767, 6304, + 32767, 6305, 32767, 6306, 32767, 6307, 1517, 1518, + 16878, 32767, 6311, 6312, 1522, 32767, 6314, 1524, + 1525, 6315, 6316, 6317, 6318, 32767, 6319, 1531, + 1532, 1533, 1534, 1535, 32767, 32767, 32767, 32767, + 1536, 6326, 6327, 6328, 6329, 32767, 0, 32767, + 0, 10802, 0, 6330, 6331, 6332, 6333, 1541, + 1542, 6336, 1544, 6338, 6339, 6340, 6341, 6342, + 6343, 1966, 2855, 2856, 1547, 1548, 2858, 2859, + 1972, 9869, 9870, 9871, 1976, 1977, 1978, 1979, + 1980, 518, 519, 520, 521, -966, 522, 523, + 20457, 525, 526, 527, 528, 529, 530, 531, + 532, 533, 783, 6122, 6123, 6124, 6125, 6126, + 6127, 6128, 32767, 6129, 1999, 6131, 6132, 6133, + 6134, 6135, 6136, 5309, 6138, 6139, 6140, 6141, + 5313, 5313, 10102, 6145, 6146, -2467, 1836, 6149, + 6150, 6151, 6152, 6153, 1535, 6155, 6156, 6157, + 5326, 5326, 5326, 32767, 32767, 32767, 32767, 32767, + 32767, 1837, 32767, 1741, 32767, 32767, 32767, 32767, + 10538, 10539, 9184, 9185, 6237, 7726, 7727, 7728, + 7729, 7730, 6243, 7731, 7732, 27666, 7734, 7735, + 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7992, + 7992, 7745, 7746, 7747, 7748, 7749, 7750, 7751, + 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, + 7760, 1660, 7762, 7763, 7764, 7765, 7766, 7767, + 7768, 6282, 7770, 7141, -128, -128, -128, 7768, + 7768, 7768, 4803, 7141, 7141, 7141, 5529, -136, + 10714, 7141, 9226, -10707,4652, 7141, -140, 4651, + 7141, 7141, 7141, 7141, -142, 5529, -143, 7141, + 7141, 7141, 6315, 7140, 7140, 6318, 6319, 4635, + 6321, 6322, 6323, 6324, 6325, 6326, 6327, 6328, + 6329, 6330, 9168, 9169, 9170, 15325, 15078, 15079, + 9174, 9175, 9176, 6539, 9178, 9179, 9180, 6344, + 6345, 6346, 6347, 8761, 6349, 6350, 6351, 9193, + 9194, 9195, 4634, 4634, 9196, 9197, 9198, -1165, + -1165, -1165, 4937, 6364, 6365, 6366, 10077, 2397, + 15134, 0, 0, 0, 0, 1336, 0, 5782, + 5782, 5782, 5782, 5782, 5782, 5782, 5782, 10930, + 10931, 5780, 5780, 5780, 5780, 5780, 5780, 5780, + 10939, 10940, 10941, 10942, 10943, 10944, 10945, 10946, + 10947, 10948, 10949, 10950, 10951, 10952, 10953, 10954, + 10955, 10956, 10957, 10958, 10959, 10960, 10961, 10962, + 10963, 10964, 10965, 10966, 10967, 10968, 6178, 6179, + 21539, 6181, 10973, 10974, 6184, 6185, 10977, 6187, + 6188, 10978, 10979, 10980, 10981, 10982, 10983, 6195, + 6196, 6197, 6198, 6199, 6200, 10990, 6202, 6203, + 6204, 10994, 10995, 10996, 10997, 10998, 10999, 11000, + 11001, 11002, 11003, 11004, 11005, 11006, 11007, 6215, + 6216, 11010, 6218, 11012, 11013, 11014, 11015, 11016, + 11017, 6640, 7529, 7530, 6221, 6222, 7532, 7533, + 6646, 14543, 14544, 14545, 6650, 6651, 6652, 6653, + 0, 6489, 6490, 6491, 6492, 6493, 6494, 6495, + 6496, 6497, 6498, 6499, 6500, 6501, 6502, 6503, + 6504, 6505, 6506, 6507, 6508, 6509, 6510, 6511, + 6512, 6513, 6514, 6515, 6516, 6517, 6518, 6519, + 6520, 5211, 6522, 6523, 6524, 6525, 13533, 13534, + 6528, 6529, 6530, 6531, 6532, 6533, 6534, 6535, + 6536, 6537, 0, 0, 0, 0, 0, 0, + 4173, 0, 0, 0, 0, 0, 6550, 6551, + 6552, 6553, 6554, 6555, 6556, 6557, 6558, 6559, + 6560, 6561, 6562, 6563, 6564, 6565, 4873, 6567, + 6568, 6569, 6570, 6571, 6572, 6573, 6574, 6575, + 6576, 6577, 6578, 6579, 6580, 6581, 6582, 6583, + 6584, 6585, 6586, 6587, 6588, 6589, 6590, 6591, + 6592, 6593, 6594, 6595, 6596, 6597, 6598, 6599, + 6600, 6601, 6602, 6603, 6604, 6605, 6606, 6607, + 6608, 6609, 6610, 6611, 6612, 6613, 6614, 6615, + 6616, 6617, 6618, 6619, 6620, 6621, 6622, 6623, + 6624, 6625, 6626, 6627, 6628, 6629, 6630, 6631, + 6632, 6633, 6634, 6635, 6636, 6637, 6638, 6639, + 6640, 6641, 6642, 6643, 6644, 6645, 6646, 6647, + 6648, 6649, 6650, 6651, 6652, 6653, 6654, 6655, + 6656, 6657, 6658, 13552, 6660, 6661, 6662, 6663, + 6664, 6665, 6666, 6667, 6668, 6669, 6670, 13573, + 6672, 6673, 6674, 6675, 9276, 6677, 4704, 4705, + 6680, 6681, 6682, 6683, 13596, 12241, 6686, 6687, + 6688, 6689, 6690, 6691, 6692, 6693, 6694, 6695, + 6696, 6697, 6698, 6699, 6700, 6701, 6702, 6703, + 6704, 6705, 6706, 6707, 6708, 6709, 6710, 6711, + 6712, 6713, 6714, 6715, 6716, 6717, 6718, 6719, + 6720, 6721, 6722, 6723, 6724, 6725, 6726, 6727, + 3709, 6729, 3710, 3710, 3710, 6733, 6734, 3712, + 3712, 6737, 6738, 6739, 6740, 6741, 4536, 3717, + 6744, 32767, 6745, 6746, 6747, 6748, 6749, 6750, + 6751, 6752, 6753, 6754, 6755, 6756, 6757, 6758, + 6759, 6760, 6761, 6762, 6763, 6764, 6765, 6766, + 6767, 6768, 6769, -2005, 6771, -3121, -3121, -3121, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 895, 896, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 4706, 4707, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 897, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 898, + 899, 900, 901, 902, 903, 904, 905, 32767, + 32767, 906, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 1, 32767, 2, 32767, 32767, 32767, 32767, 3, + 32767, 32767, 4, 5, 6, 7, 32767, 32767, + 8, 9, 10, 32767, 11, 83, 13, 32767, + 14, 15, 16, 17, 18, 19, 32767, 20, + 21, 22, 907, 908, 909, 910, 911, 912, + 913, 914, 915, 916, 917, 918, 919, 920, + 32767, 921, 922, 923, 924, 925, 926, 927, + 928, 929, -380, 931, 932, 933, 934, 7942, + 7943, 7944, 49, 50, 51, 52, 53, -1409, + 32767, -1408, -1407, -2894, -1406, -1405, 18529, 3171, + 32767, -1403, -1402, -1401, -1400, -1399, 32767, -1398, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 683, 32767, 7976, 32767, 4994, 32767, 686, + 32767, 0, 32767, 0, 32767, 0, 32767, 0, + 32767, 0, 32767, 0, 32767, 0, 32767, 0, + 32767, 937, 0, -3182, 0, -3183, 0, -3184, + 32767, 941, 32767, 32767, 32767, -3188, 0, 32767, + 0, 0, 32767, 0, 0, 32767, 0, 0, + 32767, 0, 0, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 943, + 32767, 0, 32767, 32767, 32767, 32767, 944, 0, + 945, 0, 32767, 946, 947, 32767, 948, 949, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 0, 32767, 0, 32767, 0, 32767, 0, + 32767, 0, 32767, 0, 32767, 0, 32767, 0, + 32767, 0, 32767, 0, 32767, 0, 32767, 0, + 32767, 32767, 0, 32767, 0, 32767, 950, 951, + 952, 953, 954, 955, 956, 957, 958, 32767, + 6565, 6566, 32767, 0, 0, 32767, 0, 0, + 32767, 6570, 6571, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 0, 32767, 32767, -2239, 4522, 4337, 0, + 32767, 32767, 32767, 0, -2086, 32767, 32767, 0, + 0, 0, 0, 0, 0, 959, 960, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4578, 4579, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4175, -5292, 0, 0, 32767, 0, 32767, 0, + 0, 32767, 0, 0, 32767, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 961, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 0, 962, 963, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 964, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 32767, 32767, 0, 32767, 32767, 32767, 32767, 32767, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 0, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 0, 0, 0, + 32767, 32767, -3913, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 965, 966, 967, 32767, + 968, 969, 970, 971, 972, 973, 974, 975, + 976, 977, 978, 979, 980, 32767, 981, 982, + 983, 984, 985, 986, 987, 32767, 32767, 32767, + 32767, 988, 32767, 32767, 32767, 32767, 32767, 32767, + 989, 32767, 32767, 32767, -4941, 991, 32767, 32767, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 992, 993, 994, 32767, 995, 996, 997, + 998, 999, 1000, 1001, -3143, -3143, -3143, -3143, + 32767, -3144, -3144, -3144, -3144, -3144, 1011, 1012, + 1013, 1014, 1015, 1016, -3138, -3138, -3138, -3138, + -3138, -3138, -3138, 32767, -3139, -3139, -3139, -3139, + -3139, -3139, -3139, -3139, -3139, -3139, -3139, -3139, + -3139, -3139, -3139, -3139, -3139, -3139, -3139, -3139, + -3139, -3139, -3139, -3139, -3139, -3139, -3139, 872, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 3049, 3049, -3150, 3049, 3049, + 3049, 3049, 3049, 3049, 3049, 3049, 3049, 3049, + 3049, 3049, 3049, 3049, 3049, 3049, 3049, 3049, + 3049, 3049, 3049, 3049, 3049, 0, 0, 0, + 0, 0, 0, 0, 0, 3057, 5596, 5597, + 5598, 6716, 6717, 6718, 6719, 6720, 6721, 6722, + 6723, -3176, -3176, 6728, 6729, 6730, 6731, 6732, + 6733, 6734, 6735, -3176, -3176, -3176, -3176, -3176, + -3176, 8013, 2958, 2959, -3141, 2961, 2962, 2963, + 2964, 2965, 8022, 8023, -3176, -3176, -3176, -3176, + -3176, 5630, 5631, -2, -2, -2, -2, 7679, + -3176, -3176, -3176, -3176, -3176, -3176, -3176, -3176, + -3176, -4957, -4957, -4957, -4957, -3176, -3176, -3176, + -3176, -3176, -3176, -3176, -3176, -3176, -3176, -3176, + -3176, -3176, -3176, -3176, -3176, -3176, -3176, -3176, + -3176, -3176, 1880, 1880, 7981, 1880, 1880, 1880, + 1880, 1880, -3176, -3176, -1258, 4882, 4883, 4884, + 895, 4886, -3176, 4861, 4862, 4863, 4864, -2816, + 9921, -5213, -5213, -5213, -5213, -3877, -5213, 569, + 569, 569, 569, 569, 569, 569, 569, 5717, + 5718, 567, 567, 567, 567, 567, 567, 567, + 5726, 5727, 5728, 5729, 5730, 5731, 5732, 5733, + 5734, 5735, 5736, 5737, 5738, 5739, 5740, 5741, + 5742, 5743, 5744, 5745, 5746, 5747, 5748, 5749, + 5750, 5751, 5752, 5753, 5754, 5755, 965, 966, + 16326, 968, 5760, 5761, 971, 972, 5764, 974, + 975, 5765, 5766, 5767, 5768, 5769, 5770, 982, + 983, 984, 985, 986, 987, 5777, 989, 990, + 991, 5781, 5782, 5783, 5784, 5785, 5786, 5787, + 5788, 5789, 5790, 5791, 5792, 5793, 5794, 1002, + 1003, 5797, 1005, 5799, 5800, 5801, 5802, 5803, + 5804, 1427, 2316, 2317, 1008, 1009, 2319, 2320, + 1433, 9330, 9331, 9332, 1437, 1438, 1439, 1440, + 1441, -21, -20, -19, -18, -1505, -17, -16, + 19918, -14, -13, -12, -11, -10, -9, -8, + -7, -6, 244, 244, -3, -2, -1, 0, + 1, 2, 3, 4, 1469, 5, 6, 7, + 8, 9, 32767, 32767, 32767, 32767, 10, 11, + 12, 13, 5070, 5071, 3154, -2985, 1318, 1319, + 1320, -2988, 5075, -2961, -2961, -2961, -2961, 1327, + 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, + 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, + 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, + 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, + 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, + 7522, 7275, 7276, 1371, 1372, 1373, -1264, 1375, + 1376, 1377, 1378, 1379, 1380, 1381, 1382, 957, + -14402,957, 1386, 1387, 1388, 1389, 1390, 1391, + 1392, 1393, -8970, -8970, -8970, 1397, 1398, 948, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 1400, + 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, + 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, + 1417, 1418, 1419, 1420, 1421, 32767, 32767, 1422, + 1423, 1424, 1425, 1426, 1427, 32767, 32767, 1428, + 1429, 1430, 1431, 8325, 1433, 1434, 1435, 1436, + 1437, 1438, 1439, 1440, 1441, 1442, 1443, 8346, + 1445, 1446, 1447, 1448, 4049, 1450, -523, -522, + 1453, 1454, 1455, 1456, 8369, 7014, 1459, 1460, + 1461, 1462, 1463, 1464, 1465, 32767, 32767, 1466, + 1467, 1468, 1469, 1470, 1471, 32767, 32767, 1472, + 1473, 1474, 1475, 1476, 1477, 1478, 1479, 32767, + 1480, 32767, 1481, 32767, 1482, 32767, 1483, 1484, + 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, + -1526, 1494, -1525, -1525, -1525, 1498, 1499, -1523, + -1523, 1502, 1503, 1504, 1505, 1506, -699, -1518, + 1509, -1517, 1511, 1512, 1513, 32767, 32767, 1514, + 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, + 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, + 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, + 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, + 1547, 1548, 1549, 5054, 1551, 1552, 1553, 8447, + 1555, 1556, -4049, 1558, 1559, 1560, -1467, 5063, + 1563, 5064, 5064, 1566, 32767, 1567, 1568, 1569, + 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, + 1578, 1579, 1580, 1581, 32767, 1582, 1583, 1584, + 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, + 1593, 1594, 1595, 32767, 32767, 1596, 1597, 1598, + 1599, 1600, 1601, 32767, 1602, 1603, 1604, 1605, + 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, + 1614, 1615, 1616, 1617, 1618, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1630, 1631, 0, 32767, -5702, + -5702, -5702, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32767, 0, 32767, 0, + 32767, -7163, 0, 0, 32767, 32767, 32767, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -7269, -7269, -7269, 627, + 627, 627, -2338, 0, 0, 0, -1612, -7277, + 3573, 0, 2085, -17848,-2489, 0, -7281, -2490, + 0, 0, 0, 0, -7283, -1612, -7284, 0, + 0, 0, 0, 0, 0, 0, 0, -2503, + -7292, -2503, -4309, -4309, 0, 536, -4307, -4307, + -4307, -4307, 677, -4306, -4306, -4306, -4306, -7305, + 0, -4306, -4306, 32767, 32767, -4308, -4308, -7312, + -4307, 690, -4306, -6530, 0, -4306, 0, 0, + -4306, 0, -4305, -4305, -4305, -4305, -4305, -4305, + -2949, -2949, 0, -1488, -1488, -1488, -1488, -1488, + 0, -1487, -1487, -21420,-1487, -1487, -1487, -1487, + -1487, -1487, -1487, -1487, -1487, -1736, -1735, -1487, + -1487, -1487, -1487, -1487, -1487, -1487, -1487, -1487, + -1487, -1487, -1487, -1487, -1487, -1487, -1487, 4614, + -1487, -1487, -1487, -1487, -1487, -1487, -1487, 0, + -1487, -857, 6413, 6414, 6415, -1480, -1479, -1478, + 1488, -849, -848, -847, 766, 6432, -4417, -843, + -2927, 17007, 1649, -839, 6443, 1653, -836, -835, + -834, -833, 6451, 781, 6454, -829, -828, -827, + 0, -824, -823, 0, 0, 1685, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2837, -2837, -2837, -8991, -8743, -8743, -2837, -2837, + -2837, -199, -2837, -2837, -2837, 0, 0, 0, + 0, -2413, 0, 0, 0, -2841, -2841, -2841, + 1721, 1722, -2839, -2839, -2839, 7525, 7526, 7527, + 1426, 0, 0, 0, -3710, 3971, -8765, 6370, + 6371, 6372, 6373, 5038, 6375, 594, 595, 596, + 597, 598, 599, 600, 601, -4546, -4546, 606, + 607, 608, 609, 610, 611, 612, -4546, -4546, + -4546, -4546, -4546, -4546, -4546, -4546, -4546, -4546, + -4546, -4546, -4546, -4546, -4546, -4546, -4546, -4546, + -4546, -4546, -4546, -4546, -4546, -4546, -4546, -4546, + -4546, -4546, -4546, -4546, 245, 245, -15114,245, + -4546, -4546, 245, 245, -4546, 245, 245, -4544, + -4544, -4544, -4544, -4544, -4544, 245, 245, 245, + 245, 245, 245, -4544, 245, 245, 245, -4544, + -4544, -4544, -4544, -4544, -4544, -4544, -4544, -4544, + -4544, -4544, -4544, -4544, -4544, 249, 249, -4544, + 249, -4544, -4544, -4544, -4544, -4544, -4544, -166, + -1054, -1054, 256, 256, -1053, -1053, -165, -8061, + -8061, -8061, -165, -165, -165, -165, -165, 1298, + 1298, 1298, 1298, 2786, 1299, 1299, -18634,1299, + 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, + 1050, 1051, 1299, 1299, 1299, 1299, 1299, 1299, + 1299, 1299, -165, 1300, 1300, 1300, 1300, 1300, + 1300, 1300, 7401, 1300, 1300, 1300, 1300, 1300, + -3756, -3756, -1838, 4302, 0, 0, 0, 4309, + -3753, 4284, 4285, 4286, 4287, 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, -6154, -5906, + -5906, 0, 0, 0, 2638, 0, 0, 0, + 0, 0, 0, 0, 0, 426, 15786, 428, + 0, 0, 0, 0, 0, 0, 0, 0, + 10364, 10365, 10366, 0, 0, 451, 452, 453, + 454, 455, 456, 32767, 32767, 0, 0, 0, + 32767, 32767, 32767, 0, 0, 0, 0, 0, + 0, 0, 32767, 0, 0, 0, 0, 0, + 0, 0, 32767, 1842, 32767, 32767, 1843, 32767, + 32767, 0, 32767, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 1844, 32767, + 0, 0, 0, 32767, 32767, 32767, 1846, 1847, + 32767, 1848, 1849, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 0, 0, 0, 32767, + 32767, 32767, 32767, 0, 32767, 32767, 1851, 32767, + 32767, 1852, 32767, 0, 0, 32767, 32767, 32767, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 1854, 32767, 1855, 6223, 6224, 6225, + 6226, 6227, 6228, 6229, 6230, 6231, 6232, 1856, + 1857, 1574, 1574, 1574, 32767, 32767, 1572, 1572, + 32767, 32767, 1863, 1864, 32767, 32767, 32767, 32767, + 32767, 32767, 1865, 1866, 32767, 32767, 1867, 1868, + 32767, 32767, 1869, 1870, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 1871, 1872, + 3017, 1874, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 3018, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 1875, 1876, 1877, 1878, 32767, 32767, + 32767, 0, 0, 32767, 1879, 1880, 1881, 1882, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 1883, 1884, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 0, -2263, 2526, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 1885, 1886, 1887, 1888, + 1889, 1890, 1891, 1892, 1893, 1894, 4758, 4759, + 4760, 4761, 4762, 1900, 1901, 1902, 1903, 1904, + 1905, 1906, 1907, 1908, 1909, 924, 1911, 1912, + 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, + 1921, 1107, 1923, 1924, 1925, 1926, 1927, 1928, + 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, + 1937, 1938, 1939, 1123, 1123, 1123, 1943, 1944, + 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, + 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, + 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, + 1969, 1970, 1971, 1972, 1973, 1974, 4727, 1976, + 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, + 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, + 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + -2451, 2002, -2448, 2004, 2005, 2006, -2441, -2724, + 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, + 2017, 2018, 2019, 2020, 2021, 0, 2023, 985, + 985, 7086, 985, 985, 985, 985, 985, -4071, + -4071, -2153, 3987, 3988, 3989, 0, 3991, -4071, + 3966, 3967, -4071, 260, 261, 262, 263, 264, + 265, 266, 3264, 32767, 32767, -2437, -2436, 32767, + 32767, 32767, 32767, 32767, 32767, 270, 271, 272, + 273, 274, 275, 4728, 277, 278, 279, 280, + 281, -2434, 283, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 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, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 0, 0, 32767, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 1329, 441, 441, 1751, + 1751, 442, 442, 1330, -6566, -6566, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -3047, -274, + -273, -272, -271, 1946, 4745, 0, 0, -267, + -266, 1945, -264, -263, 0, 0, 0, 0, + 0, 0, 0, 0, -6199, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 0, 2539, 2540, 2541, + 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, + -6233, -6233, 3671, 3672, 3673, 3674, 3675, 3676, + 3677, 3678, -6233, -6233, -6233, -6233, -6233, -6233, + 4956, -99, -98, -6198, -96, -95, -94, -93, + -92, 4965, 4966, -6233, -6233, -6233, -6233, -6233, + 2573, 2574, -3059, 3049, -3060, -3060, 4621, -6234, + -6234, -6234, -6234, -6234, -6234, -6234, -6234, -6234, + -8015, -8015, -8015, -8015, -6234, -6234, -6234, -6234, + -6234, -6234, -6234, -6234, -6234, -6234, -6234, -6234, + -6234, -6234, -6234, -6234, -6234, -6234, -6234, -6234, + -6234, -1178, -1178, 4923, -1178, -1178, -1178, -1178, + -1178, -6234, -6234, -4316, 1824, 1825, 1826, -2163, + 1828, -6234, 1803, 1804, 1805, 1806, -5874, 6863, + -8271, -8271, -8271, -8271, -6935, -8271, -2489, -2489, + -2489, -2489, -2489, -2489, -2489, -2489, 2659, 2660, + -2491, -2491, -2491, -2491, -2491, -2491, -2491, 2668, + 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, + 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684, + 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, + 2693, 2694, 2695, 2696, 2697, -2093, -2092, 13268, + -2090, 2702, 2703, -2087, -2086, 2706, -2767, 2708, + 2709, 2710, 2711, 2712, 3178, 3179, 3180, 3181, + 3182, 3183, 3184, 3185, 3186, 3187, 3188, 3189, + 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, + 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, + 3206, 3207, 3208, 3209, 3281, 3211, 3212, 3213, + 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, + 3222, 4107, 4108, 4109, 4110, 4111, 4112, 3229, + 4115, 4116, 4117, 4118, 4119, 4120, 3236, 3237, + 4124, 4125, 4126, 4127, 4128, 7621, 3244, 4133, + 4134, 2825, 4136, 4137, 4138, 3251, 11148, 11149, + 11150, 3255, 3256, 3257, 3258, 3259, 1797, 1798, + 1799, 1800, 313, 1801, 1802, 21736, 1804, 1805, + 1806, 1807, 1808, 1809, 1810, 1811, 1812, 2062, + 2062, 1815, 1816, 1817, 1818, 1819, 1820, 1821, + 1822, 3287, 1823, 1824, 1825, 32767, 3291, 3292, + 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, + 3301, 3302, 3303, 3304, 32767, 32767, 3305, 32767, + 9008, 32767, 32767, 3307, 3308, 3309, 3310, 3311, + 3312, 3313, 3314, 3315, 3316, 32767, 3317, 32767, + 3318, 32767, 32767, 3319, 3320, 32767, 32767, 32767, + 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, + 3329, 3330, 3331, 3332, 3333, 10603, 10604, 10605, + 2710, 2711, 2712, 5678, 3341, 3342, 3343, 4956, + 10622, -227, 3347, 1263, 21197, 5839, 3351, 10633, + 5843, 3354, 3355, 3356, 3357, 10641, 4971, 10644, + 3361, 3362, 3363, 3364, 3365, 3366, 3367, 3368, + 5872, 10662, 5874, 7681, 7682, 3374, 2839, 7683, + 7684, 7685, 7686, 2703, 7687, 7688, 7689, 7690, + 10690, 3386, 7693, 7694, 7695, 0, 7697, 7698, + 10703, 7699, 2703, 7700, 9925, 3396, 7703, 3398, + 3399, 7706, 3401, 7707, 7708, 7709, 7710, 7711, + 7712, 6357, 6358, 3410, 4899, 4900, 4901, 4902, + 4903, 3416, 4904, 4905, 24839, 4907, 4908, 4909, + 4910, 4911, 4912, 4913, 4914, 4915, 5165, 5165, + 4918, 4919, 4920, 4921, 4922, 4923, 4924, 4925, + 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, + -1167, 4935, 4936, 4937, 4938, 4939, 4940, 4941, + 3455, 4943, 4314, -2955, -2955, -2955, 4941, 4941, + 4941, 1976, 4314, 4314, 4314, 2702, -2963, 7887, + 4314, 6399, -13534,1825, 4314, -2967, 1824, 4314, + 4314, 4314, 4314, -2969, 2702, -2970, 4314, 4314, + 4314, 3488, 4313, 4313, 3491, 3492, 1808, 3494, + 32767, 0, 0, 32767, 32767, 0, 0, 0, + 0, 32767, 0, 0, 0, 0, -2999, 4306, + 0, 0, 0, 7696, 0, 0, 32767, 0, + 32767, 0, -2224, 4306, 0, 4306, 4306, 0, + 0, 0, 0, 0, 0, 0, 0, 1356, + 1356, 4305, 2817, 2817, 2817, 2817, 2817, 2817, + 2817, 2817, -17116,2817, 2817, 2817, 2817, 2817, + 2817, 2817, 2817, 2817, 2568, 2569, 2817, 2817, + 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, + 2817, 2817, 2817, 2817, 2817, 2817, 8918, 2817, + 2817, 2817, 2817, 2817, 2817, 2817, 4304, 2817, + 3447, 10717, 10718, 10719, 3531, 3532, 32767, 3533, + 3534, 3535, 3536, 3537, 32767, 3538, 32767, 3539, + 3540, 32767, 3541, 3542, 32767, 3543, 3544, 3545, + 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3553, + 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, + 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, + 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, + 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, + 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, + 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, + 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, + 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, + 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, + 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, + 2324, 3635, 3636, 3637, 3638, 10646, 10647, 3641, + 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, + 3650, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 3651, 3652, 3653, 3654, 3655, 3656, + 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, + 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, + 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, + 3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, + 3689, 3690, 3691, 3692, 3693, 3694, 3695, 32767, + 3696, 3697, 3698, 3699, 3700, 3701, 3702, 3703, + 3704, 3705, 3706, 3707, 3708, 3709, 3710, 3711, + 3712, 3713, 3714, 3715, 3716, 3717, 3718, 3719, + 3720, 3721, 3722, 3723, 3724, 3725, 3726, 3727, + 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, + 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, + 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, + 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, + 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, + 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, + 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, + 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, + 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, + 3800, -210, -209, 3803, 3804, 3805, 3806, 3807, + 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, + 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, + 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, + 3832, 3833, 3834, 3835, 3836, 3837, 3838, 3839, + 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, + 3848, 3849, -4925, 3851, -6041, -6041, -6041, -6041, + -6041, -6041, -6041, 3859, 3860, -6043, -6043, -6043, + -6043, -6043, -6043, -6043, -6043, 3869, 3870, 3871, + 3872, 3873, 3874, -7314, -2258, -2258, 3843, -2258, + -2258, -2258, -2258, -2258, -7314, -7314, 3886, 3887, + 3888, 3889, 3890, -4915, -4915, 719, 720, 721, + 722, -6958, 3898, 3899, 3900, 3901, 3902, 3903, + 3904, 3905, 3906, 5688, 5689, 5690, 5691, 3911, + 3912, 3913, 3914, 3915, 3916, 3917, 3918, 3919, + 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927, + 3928, 3929, 3930, 3931, -1124, -1123, -7223, -1121, + -1120, -1119, -1118, -1117, 3940, 3941, 2024, -4115, + -4115, -4115, -125, -4115, 3948, -4088, -4088, 3951, + 32767, 3952, 3953, 3954, 3955, 3956, 3957, 3958, + 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, + 3967, 3968, 3969, 3970, 3971, 3972, 3973, 3974, + 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, + 3983, 3984, 3985, 3986, 3987, 3988, 3989, 3990, + 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, + 3999, 4000, 4001, 4002, 4003, 14, 4005, 4006, + 4007, 4008, 4009, 4010, 4011, 4012, 4013, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 4014, 4015, 4016, 4017, 4018, 4019, 4020, + 4021, 4022, 4023, 4024, 4025, 4026, 2025, 2026, + 2027, 4030, 4031, 4032, 4033, 4034, 4035, 4036, + 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, + 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, + 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, + 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, + 4077, 32767, 32767, 4078, 4079, 4080, 4081, 4082, + 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, + 4091, 4092, 4093, 4094, 4095, 4096, 4097, 4098, + 4099, 4100, 4101, 4102, 4103, 4104, 4105, 4106, + 4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, + 4115, 4116, 4117, 0, 4119, 4120, 4121, 4122, + 4123, 4124, 4125, 0, 4127, 4128, 1401, 4130, + 4131, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 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, 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, 4011, 4011, 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, 8775, 0, + 9893, 9894, 9895, 9896, 9897, 9898, 9899, 0, + 0, 9904, 9905, 9906, 9907, 9908, 9909, 9910, + 9911, 0, 0, 0, 0, 0, 0, 11189, + 6134, 6135, 35, 6137, 6138, 6139, 6140, 6141, + 11198, 11199, 0, 0, 0, 0, 0, 8806, + 8807, 3174, 3174, 3174, 3174, 10855, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1781, + -1781, -1781, -1781, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5056, 5056, 11157, 5056, 5056, 5056, 5056, 5056, + 0, 0, 1918, 8058, 8059, 8060, 4071, 8062, + 0, 8037, 8038, 0, 4331, 4332, 4333, 4334, + 4335, 4336, 4337, 7335, 7336, 1635, 1636, 1637, + 1638, 1639, 1640, 1641, 1642, 1643, 4349, 4350, + 4351, 4352, 4353, 4354, 8807, 4356, 4357, 4358, + 4359, 4360, 1645, 4362, 4363, 4364, 4365, 32767, + 32767, 32767, 32767, 32767, 8912, 8913, 8914, 8915, + 8916, 8917, 8918, 8919, 8920, 8921, 8922, 8923, + 8924, 8925, 8926, 8927, 4137, 4138, 19498, 4140, + 8932, 8933, 4143, 4144, 8936, 4146, 4147, 8937, + 8938, 8939, 8940, 8941, 8942, 4154, 4155, 4156, + 4157, 4158, 4159, 8949, 4161, 4162, 4163, 8953, + 8954, 8955, 8956, 8957, 8958, 8959, 8960, 8961, + 8962, 8963, 8964, 8965, 8966, 4174, 4175, 8969, + 4177, 8971, 8972, 8973, 8974, 8975, 8976, 4599, + 5488, 5489, 4180, 4181, 5491, 5492, 4605, 12502, + 12503, 12504, 4609, 4610, 4611, 4612, 4613, 3151, + 3152, 3153, 3154, 1667, 3155, 3156, 23090, 3158, + 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, + 3416, 3416, 3169, 3170, 3171, 3172, 3173, 3174, + 3175, 3176, 4641, 3177, 3178, 3179, 3180, 3181, + 3182, 3183, -2917, 3185, 3186, 3187, 3188, 3189, + 8246, 8247, 6330, 191, 4494, 4495, 4496, 188, + 8251, 215, 215, 215, 215, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4519, 4520, 4521, + 4522, 4523, 4524, 4525, 4526, 4527, 4528, 4529, + 4530, 4531, 4532, 4533, 4534, 4535, 4536, 4537, + 4538, 4539, 4540, 4541, 4542, 4543, 10698, 10451, + 10452, 4547, 4548, 4549, 1912, 4551, 4552, 4553, + 4554, 4555, 0, 32767, 4130, 4130, -11229,4130, + 4559, 4560, 4561, 0, 0, 4562, 4563, 4564, + -5799, -5799, -5799, 303, 32767, 4117, 4117, 4117, + 4117, 4117, 4117, 2031, 2032, 4574, 4575, 4576, + 32767, 32767, 32767, 4577, 4578, 4579, 4580, 4581, + 4582, 4583, 32767, 4584, 4585, 4586, 4587, 4588, + 4589, 4590, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 2034, 4816, 4817, 4818, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 2035, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 2036, 2037, 2038, + 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, + 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, + 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, + 2063, 2064, 2065, 2066, 2067, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 0, 0, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + -4778, -4778, -4778, 0, 32767, 32767, 32767, 0, + 0, 32767, 32767, 32767, 0, 0, 32767, 32767, + -4791, -4791, -4791, -4791, -4791, -4791, -4791, -4791, + -4791, -4791, 0, 0, -15359,0, -4791, -4791, + 0, 0, -4791, 0, 0, -4789, -4789, -4789, + -4789, -4789, -4789, 0, 0, 0, 0, 0, + 0, -4789, 0, 0, 0, -4789, -4789, -4789, + -4789, -4789, -4789, -4789, 32767, 32767, 32767, 32767, + -4793, -4793, -4793, 0, 0, -4793, 0, -4793, + -4793, 32767, 32767, 32767, 0, 32767, 32767, 32767, + 0, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 0, 0, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 2069, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 4017, 32767, 32767, 32767, 2070, + 2071, 2072, 2073, 2074, 2075, 2076, 2077, 22011, + 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, + 2087, 2337, 2337, 2090, 2091, 2092, 2093, 2094, + 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, + 2103, 2104, 2105, -3995, 2107, 2108, 2109, 2110, + 2111, 2112, 2113, 627, 2115, 1486, -5783, -5783, + -5783, 2113, 2113, 2113, -852, 1486, 1486, 1486, + -126, -5791, 5059, 1486, 3571, -16362,-1003, 1486, + -5795, -1004, 1486, 1486, 1486, 1486, -5797, -126, + -5798, 1486, 1486, 1486, 1486, 1486, 1486, 1486, + 1486, -1017, -5806, -1017, -2823, -2823, 1486, 2022, + -2821, -2821, -2821, -2821, 2163, -2820, -2820, -2820, + -2820, -5819, 1486, -2820, -2820, -2820, 4876, -2820, + -2820, -5824, -2819, 2178, -2818, -5042, 1488, -2818, + 1488, 1488, -2818, 1488, -2817, -2817, -2817, -2817, + -2817, -2817, -1461, -1461, 1488, 0, 0, 0, + 0, 0, 0, 0, 0, -19933,0, 0, + 0, 0, 0, 0, 0, 0, 0, -249, + -248, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6101, 0, 0, 0, 0, 0, 0, + 0, 1487, 0, 630, 7900, 7901, 7902, 7, + 8, 9, 2975, 638, 639, 640, 2253, 7919, + -2930, 644, -1440, 18494, 3136, 648, 7930, 3140, + 651, 652, 653, 654, 7938, 2268, 7941, 658, + 659, 660, 661, 662, 663, 664, 665, 3169, + 7959, 3171, 4978, 4979, 671, 136, 4980, 4981, + 4982, 4983, 0, 4984, 4985, 4986, 4987, 7987, + 683, 4990, 4991, 4992, -2703, 4994, 4995, 8000, + 4996, 0, 4997, 7222, 693, 5000, 695, 696, + 5003, 698, 5004, 5005, 5006, 5007, 5008, 5009, + 3654, 3655, 707, 2196, 2197, 2198, 2199, 2200, + 2201, 2202, 2203, 22137, 2205, 2206, 2207, 2208, + 2209, 2210, 2211, 2212, 2213, 2463, 2463, 2216, + 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, + 2225, 2226, 2227, 2228, 2229, 2230, 2231, -3869, + 2233, 2234, 2235, 2236, 2237, 2238, 2239, 753, + 2241, 1612, -5657, -5657, -5657, 2239, 2239, 2239, + -726, 1612, 1612, 1612, 0, -5665, 5185, 1612, + 3697, -16236,-877, 1612, -5669, -878, 1612, 1612, + 1612, 1612, -5671, 0, -5672, 1612, 1612, 1612, + 1612, 1612, 1612, 1612, 1612, -891, -5680, -891, + -2697, -2697, 1612, 5095, 2299, 5097, 2300, 5099, + 2301, 5101, 2302, 5103, 2303, 5105, 2304, 5107, + 2305, 5109, 2306, 5111, 5112, 2307, 5114, 2308, + 32767, 2309, 5117, 5118, 5119, 32767, 5120, 5121, + 5498, 2311, 5124, 2312, 2313, 0, 2314, 2315, + 5126, 2316, 2317, 5129, 2318, 2319, 5132, 32767, + 5133, 5134, 5135, 5136, 5137, 5138, 5139, 5140, + 5141, 5142, 5143, 5144, 5145, 5146, 5147, 5148, + 5149, 5150, 5151, 5152, 2320, 5154, 5155, 5156, + 5157, 1377, 2322, 1378, 2324, 5162, 1379, 1379, + 5165, 5166, 5167, 5168, 5169, 5170, 5171, 5172, + 5173, 5174, 5175, 5176, 2327, 5178, 2328, 5180, + 2329, 5182, 2330, 5184, 2331, 5186, 2332, 5188, + 2333, 5190, 2334, 5192, 2335, 5194, 2336, 5196, + 2337, 5198, 2338, 5200, 5201, 2339, 5203, 2340, + 5205, 1391, 5207, 5208, 5209, 5210, 5211, 5212, + 1385, 1385, -4221, -4221, -4221, -1193, 2346, 2347, + 5221, 2348, 2349, -3412, -4220, -4220, -4220, -4220, + 5229, 5230, 5231, 5232, 5233, 5234, 5235, 5236, + 5237, 5238, 5239, 5240, 5241, 5242, 5243, 5244, + 5245, 5246, 5247, 5248, 2352, 5250, 5251, 4592, + -2168, -1982, 2356, 5256, 5257, 5258, 2357, 4444, + 5261, 5262, 5263, 5264, 5265, 5266, 5267, 5268, + 5269, 5270, 5271, 5272, 5273, 5274, 5275, 5276, + 5277, 5278, 5279, 5280, 5281, 5282, 5283, 5284, + 5285, 5286, 5287, 5288, 5289, 5290, 5291, 5292, + 5293, 5294, 5295, 5296, 5297, 5298, 5299, 5300, + 5301, 5302, 5303, 5304, 5305, 5306, 32767, 5307, + 5308, 5309, 6427, 6428, 6429, 6430, 6431, 6432, + 6433, 6434, -3465, -3465, 6439, 6440, 6441, 6442, + 6443, 6444, 6445, 6446, -3465, -3465, -3465, -3465, + -3465, -3465, 7724, 2669, 2670, -3430, 2672, 2673, + 2674, 2675, 2676, 7733, 7734, -3465, -3465, -3465, + -3465, -3465, 5341, 5342, -291, -291, -291, -291, + 7390, -3465, -3465, -3465, -3465, -3465, -3465, -3465, + -3465, -3465, -5246, -5246, -5246, -5246, -3465, -3465, + -3465, -3465, -3465, -3465, -3465, -3465, -3465, -3465, + -3465, -3465, -3465, -3465, -3465, -3465, -3465, -3465, + -3465, -3465, -3465, 1591, 1591, 7692, 1591, 1591, + 1591, 1591, 1591, -3465, -3465, -1547, 4593, 4594, + 4595, 606, 4597, -3465, 4572, 4573, 4574, 4575, + -3105, 9632, -5502, -5502, -5502, -5502, -4166, -5502, + 280, 280, 280, 280, 280, 280, 280, 280, + 5428, 5429, 278, 278, 278, 278, 278, 278, + 278, 5437, 5438, 5439, 5440, 5441, 5442, 5443, + 5444, 5445, 5446, 5447, 5448, 5449, 5450, 5451, + 5452, 5453, 5454, 5455, 5456, 5457, 5458, 5459, + 5460, 5461, 5462, 5463, 5464, 5465, 5466, 676, + 677, 16037, 679, 5471, 5472, 32767, 32767, 5473, + 0, 5475, 5476, 5477, 5478, 5479, 5480, 5481, + 693, 694, 695, 696, 697, 698, 5488, 700, + 701, 702, 5492, 5493, 5494, 5495, 5496, 5497, + 5498, 5499, 5500, 5501, 5502, 5503, 5504, 5505, + 713, 714, 5508, 716, 5510, 5511, 5512, 5513, + 5514, 5515, 1138, 2027, 2028, 719, 720, 2030, + 2031, 1144, 9041, 9042, 2477, 2478, 2479, 2480, + 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, + 2489, 2490, 2491, 2492, 5540, 2768, 2768, 2768, + 2768, 5547, -2247, 2499, 2500, 2768, 2768, 558, + 2768, 2768, 2506, 2507, 2508, 2509, 2510, 2511, + 2512, 2513, 8713, 2515, 2516, 2517, 2518, 2519, + 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, + 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, + 2536, 2537, 5587, 5588, 5589, 5590, 5591, 5592, + 5593, 5594, 2538, 0, 0, 0, -1117, -1117, + -1117, -1117, -1117, -1117, -1117, -1117, 8783, 8784, + -1119, -1119, -1119, -1119, -1119, -1119, -1119, -1119, + 8793, 8794, 8795, 8796, 8797, 8798, -2390, 2666, + 2666, 8767, 2666, 2666, 2666, 2666, 2666, -2390, + -2390, 8810, 8811, 8812, 8813, 8814, 9, 9, + 5643, 5644, 5645, 5646, -2034, 8822, 8823, 8824, + 8825, 8826, 8827, 8828, 8829, 8830, 10612, 10613, + 10614, 10615, 8835, 8836, 8837, 8838, 8839, 8840, + 8841, 8842, 8843, 8844, 8845, 8846, 8847, 8848, + 8849, 8850, 8851, 8852, 8853, 8854, 8855, 3800, + 3801, -2299, 3803, 3804, 3805, 3806, 3807, 8864, + 8865, 6948, 809, 809, 809, 4799, 809, 8872, + 836, 836, 836, 836, 8517, -4219, 10916, 10917, + 10918, 10919, 9584, 10921, 5140, 5141, 5142, 5143, + 5144, 5145, 5146, 5147, 0, 0, 5152, 5153, + 5154, 5155, 5156, 5157, 5158, 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, 4791, 4791, -10568,4791, 0, + 0, 4791, 4791, 0, 5474, 0, 0, 0, + 0, 0, 0, 0, 4789, 4789, 4789, 4789, + 4789, 4789, 0, 4789, 4789, 4789, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4793, 4793, 0, 4793, + 0, 0, 0, 0, 0, 0, 4378, 3490, + 3490, 4800, 4800, 3491, 3491, 4379, -3517, -3517, + 3049, 3049, 3049, 3049, 3049, 3049, 3049, 3049, + 3049, 3049, 3049, 3049, 3049, 3049, 3049, 3049, + 2, 2775, 2776, 2777, 2778, 0, 7795, 3050, + 3050, 2783, 2784, 4995, 2786, 2787, 3050, 3050, + 3050, 3050, 3050, 2793, 2794, 2795, 2796, 2797, + 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, + 2806, 2807, 2808, 2809, 2810, 2811, 2812, 2813, + 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, + 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, + 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, + 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, + 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, + 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, + 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, + 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, + 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, + 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, + 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, + 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, + 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, + 2918, 2919, 2920, 2921, 2922, 883, 884, 885, + 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, + 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, + 2942, 2943, 2944, 2945, 2946, 2947, 2948, 2949, + 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, + 2958, 2959, 2960, 2961, 2962, 2963, 2964, 2965, + 2966, 2967, 2968, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 4770, 4771, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 0, 0, 0, 0, 0, 0, 32767, 0, + 0, 0, 0, 0, 0, 0, 0 + }; + + const unsigned char *k = (const unsigned char *) key; + size_t keylen = 4; + uint32 a = 0; + uint32 b = 1; + + while (keylen--) + { + unsigned char c = *k++; + + a = a * 257 + c; + b = b * 8191 + c; + } + return h[a % 13551] + h[b % 13551]; +} + +/* Hash lookup information for decomposition */ +static const pg_unicode_decompinfo UnicodeDecompInfo = +{ + UnicodeDecompMain, + Decomp_hash_func, + 6775 +}; + +/* Inverse lookup array -- contains indexes into UnicodeDecompMain[] */ +static const uint16 RecompInverseLookup[941] = +{ + /* U+003C+0338 -> U+226E */ 1857, + /* U+003D+0338 -> U+2260 */ 1854, + /* U+003E+0338 -> U+226F */ 1858, + /* U+0041+0300 -> U+00C0 */ 14, + /* U+0041+0301 -> U+00C1 */ 15, + /* U+0041+0302 -> U+00C2 */ 16, + /* U+0041+0303 -> U+00C3 */ 17, + /* U+0041+0304 -> U+0100 */ 67, + /* U+0041+0306 -> U+0102 */ 69, + /* U+0041+0307 -> U+0226 */ 270, + /* U+0041+0308 -> U+00C4 */ 18, + /* U+0041+0309 -> U+1EA2 */ 1312, + /* U+0041+030A -> U+00C5 */ 19, + /* U+0041+030C -> U+01CD */ 194, + /* U+0041+030F -> U+0200 */ 240, + /* U+0041+0311 -> U+0202 */ 242, + /* U+0041+0323 -> U+1EA0 */ 1310, + /* U+0041+0325 -> U+1E00 */ 1154, + /* U+0041+0328 -> U+0104 */ 71, + /* U+0042+0307 -> U+1E02 */ 1156, + /* U+0042+0323 -> U+1E04 */ 1158, + /* U+0042+0331 -> U+1E06 */ 1160, + /* U+0043+0301 -> U+0106 */ 73, + /* U+0043+0302 -> U+0108 */ 75, + /* U+0043+0307 -> U+010A */ 77, + /* U+0043+030C -> U+010C */ 79, + /* U+0043+0327 -> U+00C7 */ 20, + /* U+0044+0307 -> U+1E0A */ 1164, + /* U+0044+030C -> U+010E */ 81, + /* U+0044+0323 -> U+1E0C */ 1166, + /* U+0044+0327 -> U+1E10 */ 1170, + /* U+0044+032D -> U+1E12 */ 1172, + /* U+0044+0331 -> U+1E0E */ 1168, + /* U+0045+0300 -> U+00C8 */ 21, + /* U+0045+0301 -> U+00C9 */ 22, + /* U+0045+0302 -> U+00CA */ 23, + /* U+0045+0303 -> U+1EBC */ 1338, + /* U+0045+0304 -> U+0112 */ 83, + /* U+0045+0306 -> U+0114 */ 85, + /* U+0045+0307 -> U+0116 */ 87, + /* U+0045+0308 -> U+00CB */ 24, + /* U+0045+0309 -> U+1EBA */ 1336, + /* U+0045+030C -> U+011A */ 91, + /* U+0045+030F -> U+0204 */ 244, + /* U+0045+0311 -> U+0206 */ 246, + /* U+0045+0323 -> U+1EB8 */ 1334, + /* U+0045+0327 -> U+0228 */ 272, + /* U+0045+0328 -> U+0118 */ 89, + /* U+0045+032D -> U+1E18 */ 1178, + /* U+0045+0330 -> U+1E1A */ 1180, + /* U+0046+0307 -> U+1E1E */ 1184, + /* U+0047+0301 -> U+01F4 */ 230, + /* U+0047+0302 -> U+011C */ 93, + /* U+0047+0304 -> U+1E20 */ 1186, + /* U+0047+0306 -> U+011E */ 95, + /* U+0047+0307 -> U+0120 */ 97, + /* U+0047+030C -> U+01E6 */ 216, + /* U+0047+0327 -> U+0122 */ 99, + /* U+0048+0302 -> U+0124 */ 101, + /* U+0048+0307 -> U+1E22 */ 1188, + /* U+0048+0308 -> U+1E26 */ 1192, + /* U+0048+030C -> U+021E */ 268, + /* U+0048+0323 -> U+1E24 */ 1190, + /* U+0048+0327 -> U+1E28 */ 1194, + /* U+0048+032E -> U+1E2A */ 1196, + /* U+0049+0300 -> U+00CC */ 25, + /* U+0049+0301 -> U+00CD */ 26, + /* U+0049+0302 -> U+00CE */ 27, + /* U+0049+0303 -> U+0128 */ 103, + /* U+0049+0304 -> U+012A */ 105, + /* U+0049+0306 -> U+012C */ 107, + /* U+0049+0307 -> U+0130 */ 111, + /* U+0049+0308 -> U+00CF */ 28, + /* U+0049+0309 -> U+1EC8 */ 1350, + /* U+0049+030C -> U+01CF */ 196, + /* U+0049+030F -> U+0208 */ 248, + /* U+0049+0311 -> U+020A */ 250, + /* U+0049+0323 -> U+1ECA */ 1352, + /* U+0049+0328 -> U+012E */ 109, + /* U+0049+0330 -> U+1E2C */ 1198, + /* U+004A+0302 -> U+0134 */ 114, + /* U+004B+0301 -> U+1E30 */ 1202, + /* U+004B+030C -> U+01E8 */ 218, + /* U+004B+0323 -> U+1E32 */ 1204, + /* U+004B+0327 -> U+0136 */ 116, + /* U+004B+0331 -> U+1E34 */ 1206, + /* U+004C+0301 -> U+0139 */ 118, + /* U+004C+030C -> U+013D */ 122, + /* U+004C+0323 -> U+1E36 */ 1208, + /* U+004C+0327 -> U+013B */ 120, + /* U+004C+032D -> U+1E3C */ 1214, + /* U+004C+0331 -> U+1E3A */ 1212, + /* U+004D+0301 -> U+1E3E */ 1216, + /* U+004D+0307 -> U+1E40 */ 1218, + /* U+004D+0323 -> U+1E42 */ 1220, + /* U+004E+0300 -> U+01F8 */ 232, + /* U+004E+0301 -> U+0143 */ 126, + /* U+004E+0303 -> U+00D1 */ 29, + /* U+004E+0307 -> U+1E44 */ 1222, + /* U+004E+030C -> U+0147 */ 130, + /* U+004E+0323 -> U+1E46 */ 1224, + /* U+004E+0327 -> U+0145 */ 128, + /* U+004E+032D -> U+1E4A */ 1228, + /* U+004E+0331 -> U+1E48 */ 1226, + /* U+004F+0300 -> U+00D2 */ 30, + /* U+004F+0301 -> U+00D3 */ 31, + /* U+004F+0302 -> U+00D4 */ 32, + /* U+004F+0303 -> U+00D5 */ 33, + /* U+004F+0304 -> U+014C */ 133, + /* U+004F+0306 -> U+014E */ 135, + /* U+004F+0307 -> U+022E */ 278, + /* U+004F+0308 -> U+00D6 */ 34, + /* U+004F+0309 -> U+1ECE */ 1356, + /* U+004F+030B -> U+0150 */ 137, + /* U+004F+030C -> U+01D1 */ 198, + /* U+004F+030F -> U+020C */ 252, + /* U+004F+0311 -> U+020E */ 254, + /* U+004F+031B -> U+01A0 */ 181, + /* U+004F+0323 -> U+1ECC */ 1354, + /* U+004F+0328 -> U+01EA */ 220, + /* U+0050+0301 -> U+1E54 */ 1238, + /* U+0050+0307 -> U+1E56 */ 1240, + /* U+0052+0301 -> U+0154 */ 139, + /* U+0052+0307 -> U+1E58 */ 1242, + /* U+0052+030C -> U+0158 */ 143, + /* U+0052+030F -> U+0210 */ 256, + /* U+0052+0311 -> U+0212 */ 258, + /* U+0052+0323 -> U+1E5A */ 1244, + /* U+0052+0327 -> U+0156 */ 141, + /* U+0052+0331 -> U+1E5E */ 1248, + /* U+0053+0301 -> U+015A */ 145, + /* U+0053+0302 -> U+015C */ 147, + /* U+0053+0307 -> U+1E60 */ 1250, + /* U+0053+030C -> U+0160 */ 151, + /* U+0053+0323 -> U+1E62 */ 1252, + /* U+0053+0326 -> U+0218 */ 264, + /* U+0053+0327 -> U+015E */ 149, + /* U+0054+0307 -> U+1E6A */ 1260, + /* U+0054+030C -> U+0164 */ 155, + /* U+0054+0323 -> U+1E6C */ 1262, + /* U+0054+0326 -> U+021A */ 266, + /* U+0054+0327 -> U+0162 */ 153, + /* U+0054+032D -> U+1E70 */ 1266, + /* U+0054+0331 -> U+1E6E */ 1264, + /* U+0055+0300 -> U+00D9 */ 35, + /* U+0055+0301 -> U+00DA */ 36, + /* U+0055+0302 -> U+00DB */ 37, + /* U+0055+0303 -> U+0168 */ 157, + /* U+0055+0304 -> U+016A */ 159, + /* U+0055+0306 -> U+016C */ 161, + /* U+0055+0308 -> U+00DC */ 38, + /* U+0055+0309 -> U+1EE6 */ 1380, + /* U+0055+030A -> U+016E */ 163, + /* U+0055+030B -> U+0170 */ 165, + /* U+0055+030C -> U+01D3 */ 200, + /* U+0055+030F -> U+0214 */ 260, + /* U+0055+0311 -> U+0216 */ 262, + /* U+0055+031B -> U+01AF */ 183, + /* U+0055+0323 -> U+1EE4 */ 1378, + /* U+0055+0324 -> U+1E72 */ 1268, + /* U+0055+0328 -> U+0172 */ 167, + /* U+0055+032D -> U+1E76 */ 1272, + /* U+0055+0330 -> U+1E74 */ 1270, + /* U+0056+0303 -> U+1E7C */ 1278, + /* U+0056+0323 -> U+1E7E */ 1280, + /* U+0057+0300 -> U+1E80 */ 1282, + /* U+0057+0301 -> U+1E82 */ 1284, + /* U+0057+0302 -> U+0174 */ 169, + /* U+0057+0307 -> U+1E86 */ 1288, + /* U+0057+0308 -> U+1E84 */ 1286, + /* U+0057+0323 -> U+1E88 */ 1290, + /* U+0058+0307 -> U+1E8A */ 1292, + /* U+0058+0308 -> U+1E8C */ 1294, + /* U+0059+0300 -> U+1EF2 */ 1392, + /* U+0059+0301 -> U+00DD */ 39, + /* U+0059+0302 -> U+0176 */ 171, + /* U+0059+0303 -> U+1EF8 */ 1398, + /* U+0059+0304 -> U+0232 */ 282, + /* U+0059+0307 -> U+1E8E */ 1296, + /* U+0059+0308 -> U+0178 */ 173, + /* U+0059+0309 -> U+1EF6 */ 1396, + /* U+0059+0323 -> U+1EF4 */ 1394, + /* U+005A+0301 -> U+0179 */ 174, + /* U+005A+0302 -> U+1E90 */ 1298, + /* U+005A+0307 -> U+017B */ 176, + /* U+005A+030C -> U+017D */ 178, + /* U+005A+0323 -> U+1E92 */ 1300, + /* U+005A+0331 -> U+1E94 */ 1302, + /* U+0061+0300 -> U+00E0 */ 40, + /* U+0061+0301 -> U+00E1 */ 41, + /* U+0061+0302 -> U+00E2 */ 42, + /* U+0061+0303 -> U+00E3 */ 43, + /* U+0061+0304 -> U+0101 */ 68, + /* U+0061+0306 -> U+0103 */ 70, + /* U+0061+0307 -> U+0227 */ 271, + /* U+0061+0308 -> U+00E4 */ 44, + /* U+0061+0309 -> U+1EA3 */ 1313, + /* U+0061+030A -> U+00E5 */ 45, + /* U+0061+030C -> U+01CE */ 195, + /* U+0061+030F -> U+0201 */ 241, + /* U+0061+0311 -> U+0203 */ 243, + /* U+0061+0323 -> U+1EA1 */ 1311, + /* U+0061+0325 -> U+1E01 */ 1155, + /* U+0061+0328 -> U+0105 */ 72, + /* U+0062+0307 -> U+1E03 */ 1157, + /* U+0062+0323 -> U+1E05 */ 1159, + /* U+0062+0331 -> U+1E07 */ 1161, + /* U+0063+0301 -> U+0107 */ 74, + /* U+0063+0302 -> U+0109 */ 76, + /* U+0063+0307 -> U+010B */ 78, + /* U+0063+030C -> U+010D */ 80, + /* U+0063+0327 -> U+00E7 */ 46, + /* U+0064+0307 -> U+1E0B */ 1165, + /* U+0064+030C -> U+010F */ 82, + /* U+0064+0323 -> U+1E0D */ 1167, + /* U+0064+0327 -> U+1E11 */ 1171, + /* U+0064+032D -> U+1E13 */ 1173, + /* U+0064+0331 -> U+1E0F */ 1169, + /* U+0065+0300 -> U+00E8 */ 47, + /* U+0065+0301 -> U+00E9 */ 48, + /* U+0065+0302 -> U+00EA */ 49, + /* U+0065+0303 -> U+1EBD */ 1339, + /* U+0065+0304 -> U+0113 */ 84, + /* U+0065+0306 -> U+0115 */ 86, + /* U+0065+0307 -> U+0117 */ 88, + /* U+0065+0308 -> U+00EB */ 50, + /* U+0065+0309 -> U+1EBB */ 1337, + /* U+0065+030C -> U+011B */ 92, + /* U+0065+030F -> U+0205 */ 245, + /* U+0065+0311 -> U+0207 */ 247, + /* U+0065+0323 -> U+1EB9 */ 1335, + /* U+0065+0327 -> U+0229 */ 273, + /* U+0065+0328 -> U+0119 */ 90, + /* U+0065+032D -> U+1E19 */ 1179, + /* U+0065+0330 -> U+1E1B */ 1181, + /* U+0066+0307 -> U+1E1F */ 1185, + /* U+0067+0301 -> U+01F5 */ 231, + /* U+0067+0302 -> U+011D */ 94, + /* U+0067+0304 -> U+1E21 */ 1187, + /* U+0067+0306 -> U+011F */ 96, + /* U+0067+0307 -> U+0121 */ 98, + /* U+0067+030C -> U+01E7 */ 217, + /* U+0067+0327 -> U+0123 */ 100, + /* U+0068+0302 -> U+0125 */ 102, + /* U+0068+0307 -> U+1E23 */ 1189, + /* U+0068+0308 -> U+1E27 */ 1193, + /* U+0068+030C -> U+021F */ 269, + /* U+0068+0323 -> U+1E25 */ 1191, + /* U+0068+0327 -> U+1E29 */ 1195, + /* U+0068+032E -> U+1E2B */ 1197, + /* U+0068+0331 -> U+1E96 */ 1304, + /* U+0069+0300 -> U+00EC */ 51, + /* U+0069+0301 -> U+00ED */ 52, + /* U+0069+0302 -> U+00EE */ 53, + /* U+0069+0303 -> U+0129 */ 104, + /* U+0069+0304 -> U+012B */ 106, + /* U+0069+0306 -> U+012D */ 108, + /* U+0069+0308 -> U+00EF */ 54, + /* U+0069+0309 -> U+1EC9 */ 1351, + /* U+0069+030C -> U+01D0 */ 197, + /* U+0069+030F -> U+0209 */ 249, + /* U+0069+0311 -> U+020B */ 251, + /* U+0069+0323 -> U+1ECB */ 1353, + /* U+0069+0328 -> U+012F */ 110, + /* U+0069+0330 -> U+1E2D */ 1199, + /* U+006A+0302 -> U+0135 */ 115, + /* U+006A+030C -> U+01F0 */ 226, + /* U+006B+0301 -> U+1E31 */ 1203, + /* U+006B+030C -> U+01E9 */ 219, + /* U+006B+0323 -> U+1E33 */ 1205, + /* U+006B+0327 -> U+0137 */ 117, + /* U+006B+0331 -> U+1E35 */ 1207, + /* U+006C+0301 -> U+013A */ 119, + /* U+006C+030C -> U+013E */ 123, + /* U+006C+0323 -> U+1E37 */ 1209, + /* U+006C+0327 -> U+013C */ 121, + /* U+006C+032D -> U+1E3D */ 1215, + /* U+006C+0331 -> U+1E3B */ 1213, + /* U+006D+0301 -> U+1E3F */ 1217, + /* U+006D+0307 -> U+1E41 */ 1219, + /* U+006D+0323 -> U+1E43 */ 1221, + /* U+006E+0300 -> U+01F9 */ 233, + /* U+006E+0301 -> U+0144 */ 127, + /* U+006E+0303 -> U+00F1 */ 55, + /* U+006E+0307 -> U+1E45 */ 1223, + /* U+006E+030C -> U+0148 */ 131, + /* U+006E+0323 -> U+1E47 */ 1225, + /* U+006E+0327 -> U+0146 */ 129, + /* U+006E+032D -> U+1E4B */ 1229, + /* U+006E+0331 -> U+1E49 */ 1227, + /* U+006F+0300 -> U+00F2 */ 56, + /* U+006F+0301 -> U+00F3 */ 57, + /* U+006F+0302 -> U+00F4 */ 58, + /* U+006F+0303 -> U+00F5 */ 59, + /* U+006F+0304 -> U+014D */ 134, + /* U+006F+0306 -> U+014F */ 136, + /* U+006F+0307 -> U+022F */ 279, + /* U+006F+0308 -> U+00F6 */ 60, + /* U+006F+0309 -> U+1ECF */ 1357, + /* U+006F+030B -> U+0151 */ 138, + /* U+006F+030C -> U+01D2 */ 199, + /* U+006F+030F -> U+020D */ 253, + /* U+006F+0311 -> U+020F */ 255, + /* U+006F+031B -> U+01A1 */ 182, + /* U+006F+0323 -> U+1ECD */ 1355, + /* U+006F+0328 -> U+01EB */ 221, + /* U+0070+0301 -> U+1E55 */ 1239, + /* U+0070+0307 -> U+1E57 */ 1241, + /* U+0072+0301 -> U+0155 */ 140, + /* U+0072+0307 -> U+1E59 */ 1243, + /* U+0072+030C -> U+0159 */ 144, + /* U+0072+030F -> U+0211 */ 257, + /* U+0072+0311 -> U+0213 */ 259, + /* U+0072+0323 -> U+1E5B */ 1245, + /* U+0072+0327 -> U+0157 */ 142, + /* U+0072+0331 -> U+1E5F */ 1249, + /* U+0073+0301 -> U+015B */ 146, + /* U+0073+0302 -> U+015D */ 148, + /* U+0073+0307 -> U+1E61 */ 1251, + /* U+0073+030C -> U+0161 */ 152, + /* U+0073+0323 -> U+1E63 */ 1253, + /* U+0073+0326 -> U+0219 */ 265, + /* U+0073+0327 -> U+015F */ 150, + /* U+0074+0307 -> U+1E6B */ 1261, + /* U+0074+0308 -> U+1E97 */ 1305, + /* U+0074+030C -> U+0165 */ 156, + /* U+0074+0323 -> U+1E6D */ 1263, + /* U+0074+0326 -> U+021B */ 267, + /* U+0074+0327 -> U+0163 */ 154, + /* U+0074+032D -> U+1E71 */ 1267, + /* U+0074+0331 -> U+1E6F */ 1265, + /* U+0075+0300 -> U+00F9 */ 61, + /* U+0075+0301 -> U+00FA */ 62, + /* U+0075+0302 -> U+00FB */ 63, + /* U+0075+0303 -> U+0169 */ 158, + /* U+0075+0304 -> U+016B */ 160, + /* U+0075+0306 -> U+016D */ 162, + /* U+0075+0308 -> U+00FC */ 64, + /* U+0075+0309 -> U+1EE7 */ 1381, + /* U+0075+030A -> U+016F */ 164, + /* U+0075+030B -> U+0171 */ 166, + /* U+0075+030C -> U+01D4 */ 201, + /* U+0075+030F -> U+0215 */ 261, + /* U+0075+0311 -> U+0217 */ 263, + /* U+0075+031B -> U+01B0 */ 184, + /* U+0075+0323 -> U+1EE5 */ 1379, + /* U+0075+0324 -> U+1E73 */ 1269, + /* U+0075+0328 -> U+0173 */ 168, + /* U+0075+032D -> U+1E77 */ 1273, + /* U+0075+0330 -> U+1E75 */ 1271, + /* U+0076+0303 -> U+1E7D */ 1279, + /* U+0076+0323 -> U+1E7F */ 1281, + /* U+0077+0300 -> U+1E81 */ 1283, + /* U+0077+0301 -> U+1E83 */ 1285, + /* U+0077+0302 -> U+0175 */ 170, + /* U+0077+0307 -> U+1E87 */ 1289, + /* U+0077+0308 -> U+1E85 */ 1287, + /* U+0077+030A -> U+1E98 */ 1306, + /* U+0077+0323 -> U+1E89 */ 1291, + /* U+0078+0307 -> U+1E8B */ 1293, + /* U+0078+0308 -> U+1E8D */ 1295, + /* U+0079+0300 -> U+1EF3 */ 1393, + /* U+0079+0301 -> U+00FD */ 65, + /* U+0079+0302 -> U+0177 */ 172, + /* U+0079+0303 -> U+1EF9 */ 1399, + /* U+0079+0304 -> U+0233 */ 283, + /* U+0079+0307 -> U+1E8F */ 1297, + /* U+0079+0308 -> U+00FF */ 66, + /* U+0079+0309 -> U+1EF7 */ 1397, + /* U+0079+030A -> U+1E99 */ 1307, + /* U+0079+0323 -> U+1EF5 */ 1395, + /* U+007A+0301 -> U+017A */ 175, + /* U+007A+0302 -> U+1E91 */ 1299, + /* U+007A+0307 -> U+017C */ 177, + /* U+007A+030C -> U+017E */ 179, + /* U+007A+0323 -> U+1E93 */ 1301, + /* U+007A+0331 -> U+1E95 */ 1303, + /* U+00A8+0300 -> U+1FED */ 1618, + /* U+00A8+0301 -> U+0385 */ 419, + /* U+00A8+0342 -> U+1FC1 */ 1578, + /* U+00C2+0300 -> U+1EA6 */ 1316, + /* U+00C2+0301 -> U+1EA4 */ 1314, + /* U+00C2+0303 -> U+1EAA */ 1320, + /* U+00C2+0309 -> U+1EA8 */ 1318, + /* U+00C4+0304 -> U+01DE */ 210, + /* U+00C5+0301 -> U+01FA */ 234, + /* U+00C6+0301 -> U+01FC */ 236, + /* U+00C6+0304 -> U+01E2 */ 214, + /* U+00C7+0301 -> U+1E08 */ 1162, + /* U+00CA+0300 -> U+1EC0 */ 1342, + /* U+00CA+0301 -> U+1EBE */ 1340, + /* U+00CA+0303 -> U+1EC4 */ 1346, + /* U+00CA+0309 -> U+1EC2 */ 1344, + /* U+00CF+0301 -> U+1E2E */ 1200, + /* U+00D4+0300 -> U+1ED2 */ 1360, + /* U+00D4+0301 -> U+1ED0 */ 1358, + /* U+00D4+0303 -> U+1ED6 */ 1364, + /* U+00D4+0309 -> U+1ED4 */ 1362, + /* U+00D5+0301 -> U+1E4C */ 1230, + /* U+00D5+0304 -> U+022C */ 276, + /* U+00D5+0308 -> U+1E4E */ 1232, + /* U+00D6+0304 -> U+022A */ 274, + /* U+00D8+0301 -> U+01FE */ 238, + /* U+00DC+0300 -> U+01DB */ 208, + /* U+00DC+0301 -> U+01D7 */ 204, + /* U+00DC+0304 -> U+01D5 */ 202, + /* U+00DC+030C -> U+01D9 */ 206, + /* U+00E2+0300 -> U+1EA7 */ 1317, + /* U+00E2+0301 -> U+1EA5 */ 1315, + /* U+00E2+0303 -> U+1EAB */ 1321, + /* U+00E2+0309 -> U+1EA9 */ 1319, + /* U+00E4+0304 -> U+01DF */ 211, + /* U+00E5+0301 -> U+01FB */ 235, + /* U+00E6+0301 -> U+01FD */ 237, + /* U+00E6+0304 -> U+01E3 */ 215, + /* U+00E7+0301 -> U+1E09 */ 1163, + /* U+00EA+0300 -> U+1EC1 */ 1343, + /* U+00EA+0301 -> U+1EBF */ 1341, + /* U+00EA+0303 -> U+1EC5 */ 1347, + /* U+00EA+0309 -> U+1EC3 */ 1345, + /* U+00EF+0301 -> U+1E2F */ 1201, + /* U+00F4+0300 -> U+1ED3 */ 1361, + /* U+00F4+0301 -> U+1ED1 */ 1359, + /* U+00F4+0303 -> U+1ED7 */ 1365, + /* U+00F4+0309 -> U+1ED5 */ 1363, + /* U+00F5+0301 -> U+1E4D */ 1231, + /* U+00F5+0304 -> U+022D */ 277, + /* U+00F5+0308 -> U+1E4F */ 1233, + /* U+00F6+0304 -> U+022B */ 275, + /* U+00F8+0301 -> U+01FF */ 239, + /* U+00FC+0300 -> U+01DC */ 209, + /* U+00FC+0301 -> U+01D8 */ 205, + /* U+00FC+0304 -> U+01D6 */ 203, + /* U+00FC+030C -> U+01DA */ 207, + /* U+0102+0300 -> U+1EB0 */ 1326, + /* U+0102+0301 -> U+1EAE */ 1324, + /* U+0102+0303 -> U+1EB4 */ 1330, + /* U+0102+0309 -> U+1EB2 */ 1328, + /* U+0103+0300 -> U+1EB1 */ 1327, + /* U+0103+0301 -> U+1EAF */ 1325, + /* U+0103+0303 -> U+1EB5 */ 1331, + /* U+0103+0309 -> U+1EB3 */ 1329, + /* U+0112+0300 -> U+1E14 */ 1174, + /* U+0112+0301 -> U+1E16 */ 1176, + /* U+0113+0300 -> U+1E15 */ 1175, + /* U+0113+0301 -> U+1E17 */ 1177, + /* U+014C+0300 -> U+1E50 */ 1234, + /* U+014C+0301 -> U+1E52 */ 1236, + /* U+014D+0300 -> U+1E51 */ 1235, + /* U+014D+0301 -> U+1E53 */ 1237, + /* U+015A+0307 -> U+1E64 */ 1254, + /* U+015B+0307 -> U+1E65 */ 1255, + /* U+0160+0307 -> U+1E66 */ 1256, + /* U+0161+0307 -> U+1E67 */ 1257, + /* U+0168+0301 -> U+1E78 */ 1274, + /* U+0169+0301 -> U+1E79 */ 1275, + /* U+016A+0308 -> U+1E7A */ 1276, + /* U+016B+0308 -> U+1E7B */ 1277, + /* U+017F+0307 -> U+1E9B */ 1309, + /* U+01A0+0300 -> U+1EDC */ 1370, + /* U+01A0+0301 -> U+1EDA */ 1368, + /* U+01A0+0303 -> U+1EE0 */ 1374, + /* U+01A0+0309 -> U+1EDE */ 1372, + /* U+01A0+0323 -> U+1EE2 */ 1376, + /* U+01A1+0300 -> U+1EDD */ 1371, + /* U+01A1+0301 -> U+1EDB */ 1369, + /* U+01A1+0303 -> U+1EE1 */ 1375, + /* U+01A1+0309 -> U+1EDF */ 1373, + /* U+01A1+0323 -> U+1EE3 */ 1377, + /* U+01AF+0300 -> U+1EEA */ 1384, + /* U+01AF+0301 -> U+1EE8 */ 1382, + /* U+01AF+0303 -> U+1EEE */ 1388, + /* U+01AF+0309 -> U+1EEC */ 1386, + /* U+01AF+0323 -> U+1EF0 */ 1390, + /* U+01B0+0300 -> U+1EEB */ 1385, + /* U+01B0+0301 -> U+1EE9 */ 1383, + /* U+01B0+0303 -> U+1EEF */ 1389, + /* U+01B0+0309 -> U+1EED */ 1387, + /* U+01B0+0323 -> U+1EF1 */ 1391, + /* U+01B7+030C -> U+01EE */ 224, + /* U+01EA+0304 -> U+01EC */ 222, + /* U+01EB+0304 -> U+01ED */ 223, + /* U+0226+0304 -> U+01E0 */ 212, + /* U+0227+0304 -> U+01E1 */ 213, + /* U+0228+0306 -> U+1E1C */ 1182, + /* U+0229+0306 -> U+1E1D */ 1183, + /* U+022E+0304 -> U+0230 */ 280, + /* U+022F+0304 -> U+0231 */ 281, + /* U+0292+030C -> U+01EF */ 225, + /* U+0391+0300 -> U+1FBA */ 1571, + /* U+0391+0301 -> U+0386 */ 420, + /* U+0391+0304 -> U+1FB9 */ 1570, + /* U+0391+0306 -> U+1FB8 */ 1569, + /* U+0391+0313 -> U+1F08 */ 1408, + /* U+0391+0314 -> U+1F09 */ 1409, + /* U+0391+0345 -> U+1FBC */ 1573, + /* U+0395+0300 -> U+1FC8 */ 1584, + /* U+0395+0301 -> U+0388 */ 422, + /* U+0395+0313 -> U+1F18 */ 1422, + /* U+0395+0314 -> U+1F19 */ 1423, + /* U+0397+0300 -> U+1FCA */ 1586, + /* U+0397+0301 -> U+0389 */ 423, + /* U+0397+0313 -> U+1F28 */ 1436, + /* U+0397+0314 -> U+1F29 */ 1437, + /* U+0397+0345 -> U+1FCC */ 1588, + /* U+0399+0300 -> U+1FDA */ 1600, + /* U+0399+0301 -> U+038A */ 424, + /* U+0399+0304 -> U+1FD9 */ 1599, + /* U+0399+0306 -> U+1FD8 */ 1598, + /* U+0399+0308 -> U+03AA */ 429, + /* U+0399+0313 -> U+1F38 */ 1452, + /* U+0399+0314 -> U+1F39 */ 1453, + /* U+039F+0300 -> U+1FF8 */ 1626, + /* U+039F+0301 -> U+038C */ 425, + /* U+039F+0313 -> U+1F48 */ 1466, + /* U+039F+0314 -> U+1F49 */ 1467, + /* U+03A1+0314 -> U+1FEC */ 1617, + /* U+03A5+0300 -> U+1FEA */ 1615, + /* U+03A5+0301 -> U+038E */ 426, + /* U+03A5+0304 -> U+1FE9 */ 1614, + /* U+03A5+0306 -> U+1FE8 */ 1613, + /* U+03A5+0308 -> U+03AB */ 430, + /* U+03A5+0314 -> U+1F59 */ 1480, + /* U+03A9+0300 -> U+1FFA */ 1628, + /* U+03A9+0301 -> U+038F */ 427, + /* U+03A9+0313 -> U+1F68 */ 1492, + /* U+03A9+0314 -> U+1F69 */ 1493, + /* U+03A9+0345 -> U+1FFC */ 1630, + /* U+03AC+0345 -> U+1FB4 */ 1566, + /* U+03AE+0345 -> U+1FC4 */ 1581, + /* U+03B1+0300 -> U+1F70 */ 1500, + /* U+03B1+0301 -> U+03AC */ 431, + /* U+03B1+0304 -> U+1FB1 */ 1563, + /* U+03B1+0306 -> U+1FB0 */ 1562, + /* U+03B1+0313 -> U+1F00 */ 1400, + /* U+03B1+0314 -> U+1F01 */ 1401, + /* U+03B1+0342 -> U+1FB6 */ 1567, + /* U+03B1+0345 -> U+1FB3 */ 1565, + /* U+03B5+0300 -> U+1F72 */ 1502, + /* U+03B5+0301 -> U+03AD */ 432, + /* U+03B5+0313 -> U+1F10 */ 1416, + /* U+03B5+0314 -> U+1F11 */ 1417, + /* U+03B7+0300 -> U+1F74 */ 1504, + /* U+03B7+0301 -> U+03AE */ 433, + /* U+03B7+0313 -> U+1F20 */ 1428, + /* U+03B7+0314 -> U+1F21 */ 1429, + /* U+03B7+0342 -> U+1FC6 */ 1582, + /* U+03B7+0345 -> U+1FC3 */ 1580, + /* U+03B9+0300 -> U+1F76 */ 1506, + /* U+03B9+0301 -> U+03AF */ 434, + /* U+03B9+0304 -> U+1FD1 */ 1593, + /* U+03B9+0306 -> U+1FD0 */ 1592, + /* U+03B9+0308 -> U+03CA */ 436, + /* U+03B9+0313 -> U+1F30 */ 1444, + /* U+03B9+0314 -> U+1F31 */ 1445, + /* U+03B9+0342 -> U+1FD6 */ 1596, + /* U+03BF+0300 -> U+1F78 */ 1508, + /* U+03BF+0301 -> U+03CC */ 438, + /* U+03BF+0313 -> U+1F40 */ 1460, + /* U+03BF+0314 -> U+1F41 */ 1461, + /* U+03C1+0313 -> U+1FE4 */ 1609, + /* U+03C1+0314 -> U+1FE5 */ 1610, + /* U+03C5+0300 -> U+1F7A */ 1510, + /* U+03C5+0301 -> U+03CD */ 439, + /* U+03C5+0304 -> U+1FE1 */ 1606, + /* U+03C5+0306 -> U+1FE0 */ 1605, + /* U+03C5+0308 -> U+03CB */ 437, + /* U+03C5+0313 -> U+1F50 */ 1472, + /* U+03C5+0314 -> U+1F51 */ 1473, + /* U+03C5+0342 -> U+1FE6 */ 1611, + /* U+03C9+0300 -> U+1F7C */ 1512, + /* U+03C9+0301 -> U+03CE */ 440, + /* U+03C9+0313 -> U+1F60 */ 1484, + /* U+03C9+0314 -> U+1F61 */ 1485, + /* U+03C9+0342 -> U+1FF6 */ 1624, + /* U+03C9+0345 -> U+1FF3 */ 1622, + /* U+03CA+0300 -> U+1FD2 */ 1594, + /* U+03CA+0301 -> U+0390 */ 428, + /* U+03CA+0342 -> U+1FD7 */ 1597, + /* U+03CB+0300 -> U+1FE2 */ 1607, + /* U+03CB+0301 -> U+03B0 */ 435, + /* U+03CB+0342 -> U+1FE7 */ 1612, + /* U+03CE+0345 -> U+1FF4 */ 1623, + /* U+03D2+0301 -> U+03D3 */ 444, + /* U+03D2+0308 -> U+03D4 */ 445, + /* U+0406+0308 -> U+0407 */ 457, + /* U+0410+0306 -> U+04D0 */ 479, + /* U+0410+0308 -> U+04D2 */ 481, + /* U+0413+0301 -> U+0403 */ 456, + /* U+0415+0300 -> U+0400 */ 454, + /* U+0415+0306 -> U+04D6 */ 483, + /* U+0415+0308 -> U+0401 */ 455, + /* U+0416+0306 -> U+04C1 */ 477, + /* U+0416+0308 -> U+04DC */ 487, + /* U+0417+0308 -> U+04DE */ 489, + /* U+0418+0300 -> U+040D */ 459, + /* U+0418+0304 -> U+04E2 */ 491, + /* U+0418+0306 -> U+0419 */ 461, + /* U+0418+0308 -> U+04E4 */ 493, + /* U+041A+0301 -> U+040C */ 458, + /* U+041E+0308 -> U+04E6 */ 495, + /* U+0423+0304 -> U+04EE */ 501, + /* U+0423+0306 -> U+040E */ 460, + /* U+0423+0308 -> U+04F0 */ 503, + /* U+0423+030B -> U+04F2 */ 505, + /* U+0427+0308 -> U+04F4 */ 507, + /* U+042B+0308 -> U+04F8 */ 509, + /* U+042D+0308 -> U+04EC */ 499, + /* U+0430+0306 -> U+04D1 */ 480, + /* U+0430+0308 -> U+04D3 */ 482, + /* U+0433+0301 -> U+0453 */ 465, + /* U+0435+0300 -> U+0450 */ 463, + /* U+0435+0306 -> U+04D7 */ 484, + /* U+0435+0308 -> U+0451 */ 464, + /* U+0436+0306 -> U+04C2 */ 478, + /* U+0436+0308 -> U+04DD */ 488, + /* U+0437+0308 -> U+04DF */ 490, + /* U+0438+0300 -> U+045D */ 468, + /* U+0438+0304 -> U+04E3 */ 492, + /* U+0438+0306 -> U+0439 */ 462, + /* U+0438+0308 -> U+04E5 */ 494, + /* U+043A+0301 -> U+045C */ 467, + /* U+043E+0308 -> U+04E7 */ 496, + /* U+0443+0304 -> U+04EF */ 502, + /* U+0443+0306 -> U+045E */ 469, + /* U+0443+0308 -> U+04F1 */ 504, + /* U+0443+030B -> U+04F3 */ 506, + /* U+0447+0308 -> U+04F5 */ 508, + /* U+044B+0308 -> U+04F9 */ 510, + /* U+044D+0308 -> U+04ED */ 500, + /* U+0456+0308 -> U+0457 */ 466, + /* U+0474+030F -> U+0476 */ 470, + /* U+0475+030F -> U+0477 */ 471, + /* U+04D8+0308 -> U+04DA */ 485, + /* U+04D9+0308 -> U+04DB */ 486, + /* U+04E8+0308 -> U+04EA */ 497, + /* U+04E9+0308 -> U+04EB */ 498, + /* U+0627+0653 -> U+0622 */ 574, + /* U+0627+0654 -> U+0623 */ 575, + /* U+0627+0655 -> U+0625 */ 577, + /* U+0648+0654 -> U+0624 */ 576, + /* U+064A+0654 -> U+0626 */ 578, + /* U+06C1+0654 -> U+06C2 */ 606, + /* U+06D2+0654 -> U+06D3 */ 607, + /* U+06D5+0654 -> U+06C0 */ 605, + /* U+0928+093C -> U+0929 */ 750, + /* U+0930+093C -> U+0931 */ 751, + /* U+0933+093C -> U+0934 */ 752, + /* U+09C7+09BE -> U+09CB */ 768, + /* U+09C7+09D7 -> U+09CC */ 769, + /* U+0B47+0B3E -> U+0B4B */ 787, + /* U+0B47+0B56 -> U+0B48 */ 786, + /* U+0B47+0B57 -> U+0B4C */ 788, + /* U+0B92+0BD7 -> U+0B94 */ 792, + /* U+0BC6+0BBE -> U+0BCA */ 793, + /* U+0BC6+0BD7 -> U+0BCC */ 795, + /* U+0BC7+0BBE -> U+0BCB */ 794, + /* U+0C46+0C56 -> U+0C48 */ 798, + /* U+0CBF+0CD5 -> U+0CC0 */ 803, + /* U+0CC6+0CC2 -> U+0CCA */ 806, + /* U+0CC6+0CD5 -> U+0CC7 */ 804, + /* U+0CC6+0CD6 -> U+0CC8 */ 805, + /* U+0CCA+0CD5 -> U+0CCB */ 807, + /* U+0D46+0D3E -> U+0D4A */ 811, + /* U+0D46+0D57 -> U+0D4C */ 813, + /* U+0D47+0D3E -> U+0D4B */ 812, + /* U+0DD9+0DCA -> U+0DDA */ 816, + /* U+0DD9+0DCF -> U+0DDC */ 817, + /* U+0DD9+0DDF -> U+0DDE */ 819, + /* U+0DDC+0DCA -> U+0DDD */ 818, + /* U+1025+102E -> U+1026 */ 877, + /* U+1B05+1B35 -> U+1B06 */ 937, + /* U+1B07+1B35 -> U+1B08 */ 938, + /* U+1B09+1B35 -> U+1B0A */ 939, + /* U+1B0B+1B35 -> U+1B0C */ 940, + /* U+1B0D+1B35 -> U+1B0E */ 941, + /* U+1B11+1B35 -> U+1B12 */ 942, + /* U+1B3A+1B35 -> U+1B3B */ 944, + /* U+1B3C+1B35 -> U+1B3D */ 945, + /* U+1B3E+1B35 -> U+1B40 */ 946, + /* U+1B3F+1B35 -> U+1B41 */ 947, + /* U+1B42+1B35 -> U+1B43 */ 948, + /* U+1E36+0304 -> U+1E38 */ 1210, + /* U+1E37+0304 -> U+1E39 */ 1211, + /* U+1E5A+0304 -> U+1E5C */ 1246, + /* U+1E5B+0304 -> U+1E5D */ 1247, + /* U+1E62+0307 -> U+1E68 */ 1258, + /* U+1E63+0307 -> U+1E69 */ 1259, + /* U+1EA0+0302 -> U+1EAC */ 1322, + /* U+1EA0+0306 -> U+1EB6 */ 1332, + /* U+1EA1+0302 -> U+1EAD */ 1323, + /* U+1EA1+0306 -> U+1EB7 */ 1333, + /* U+1EB8+0302 -> U+1EC6 */ 1348, + /* U+1EB9+0302 -> U+1EC7 */ 1349, + /* U+1ECC+0302 -> U+1ED8 */ 1366, + /* U+1ECD+0302 -> U+1ED9 */ 1367, + /* U+1F00+0300 -> U+1F02 */ 1402, + /* U+1F00+0301 -> U+1F04 */ 1404, + /* U+1F00+0342 -> U+1F06 */ 1406, + /* U+1F00+0345 -> U+1F80 */ 1514, + /* U+1F01+0300 -> U+1F03 */ 1403, + /* U+1F01+0301 -> U+1F05 */ 1405, + /* U+1F01+0342 -> U+1F07 */ 1407, + /* U+1F01+0345 -> U+1F81 */ 1515, + /* U+1F02+0345 -> U+1F82 */ 1516, + /* U+1F03+0345 -> U+1F83 */ 1517, + /* U+1F04+0345 -> U+1F84 */ 1518, + /* U+1F05+0345 -> U+1F85 */ 1519, + /* U+1F06+0345 -> U+1F86 */ 1520, + /* U+1F07+0345 -> U+1F87 */ 1521, + /* U+1F08+0300 -> U+1F0A */ 1410, + /* U+1F08+0301 -> U+1F0C */ 1412, + /* U+1F08+0342 -> U+1F0E */ 1414, + /* U+1F08+0345 -> U+1F88 */ 1522, + /* U+1F09+0300 -> U+1F0B */ 1411, + /* U+1F09+0301 -> U+1F0D */ 1413, + /* U+1F09+0342 -> U+1F0F */ 1415, + /* U+1F09+0345 -> U+1F89 */ 1523, + /* U+1F0A+0345 -> U+1F8A */ 1524, + /* U+1F0B+0345 -> U+1F8B */ 1525, + /* U+1F0C+0345 -> U+1F8C */ 1526, + /* U+1F0D+0345 -> U+1F8D */ 1527, + /* U+1F0E+0345 -> U+1F8E */ 1528, + /* U+1F0F+0345 -> U+1F8F */ 1529, + /* U+1F10+0300 -> U+1F12 */ 1418, + /* U+1F10+0301 -> U+1F14 */ 1420, + /* U+1F11+0300 -> U+1F13 */ 1419, + /* U+1F11+0301 -> U+1F15 */ 1421, + /* U+1F18+0300 -> U+1F1A */ 1424, + /* U+1F18+0301 -> U+1F1C */ 1426, + /* U+1F19+0300 -> U+1F1B */ 1425, + /* U+1F19+0301 -> U+1F1D */ 1427, + /* U+1F20+0300 -> U+1F22 */ 1430, + /* U+1F20+0301 -> U+1F24 */ 1432, + /* U+1F20+0342 -> U+1F26 */ 1434, + /* U+1F20+0345 -> U+1F90 */ 1530, + /* U+1F21+0300 -> U+1F23 */ 1431, + /* U+1F21+0301 -> U+1F25 */ 1433, + /* U+1F21+0342 -> U+1F27 */ 1435, + /* U+1F21+0345 -> U+1F91 */ 1531, + /* U+1F22+0345 -> U+1F92 */ 1532, + /* U+1F23+0345 -> U+1F93 */ 1533, + /* U+1F24+0345 -> U+1F94 */ 1534, + /* U+1F25+0345 -> U+1F95 */ 1535, + /* U+1F26+0345 -> U+1F96 */ 1536, + /* U+1F27+0345 -> U+1F97 */ 1537, + /* U+1F28+0300 -> U+1F2A */ 1438, + /* U+1F28+0301 -> U+1F2C */ 1440, + /* U+1F28+0342 -> U+1F2E */ 1442, + /* U+1F28+0345 -> U+1F98 */ 1538, + /* U+1F29+0300 -> U+1F2B */ 1439, + /* U+1F29+0301 -> U+1F2D */ 1441, + /* U+1F29+0342 -> U+1F2F */ 1443, + /* U+1F29+0345 -> U+1F99 */ 1539, + /* U+1F2A+0345 -> U+1F9A */ 1540, + /* U+1F2B+0345 -> U+1F9B */ 1541, + /* U+1F2C+0345 -> U+1F9C */ 1542, + /* U+1F2D+0345 -> U+1F9D */ 1543, + /* U+1F2E+0345 -> U+1F9E */ 1544, + /* U+1F2F+0345 -> U+1F9F */ 1545, + /* U+1F30+0300 -> U+1F32 */ 1446, + /* U+1F30+0301 -> U+1F34 */ 1448, + /* U+1F30+0342 -> U+1F36 */ 1450, + /* U+1F31+0300 -> U+1F33 */ 1447, + /* U+1F31+0301 -> U+1F35 */ 1449, + /* U+1F31+0342 -> U+1F37 */ 1451, + /* U+1F38+0300 -> U+1F3A */ 1454, + /* U+1F38+0301 -> U+1F3C */ 1456, + /* U+1F38+0342 -> U+1F3E */ 1458, + /* U+1F39+0300 -> U+1F3B */ 1455, + /* U+1F39+0301 -> U+1F3D */ 1457, + /* U+1F39+0342 -> U+1F3F */ 1459, + /* U+1F40+0300 -> U+1F42 */ 1462, + /* U+1F40+0301 -> U+1F44 */ 1464, + /* U+1F41+0300 -> U+1F43 */ 1463, + /* U+1F41+0301 -> U+1F45 */ 1465, + /* U+1F48+0300 -> U+1F4A */ 1468, + /* U+1F48+0301 -> U+1F4C */ 1470, + /* U+1F49+0300 -> U+1F4B */ 1469, + /* U+1F49+0301 -> U+1F4D */ 1471, + /* U+1F50+0300 -> U+1F52 */ 1474, + /* U+1F50+0301 -> U+1F54 */ 1476, + /* U+1F50+0342 -> U+1F56 */ 1478, + /* U+1F51+0300 -> U+1F53 */ 1475, + /* U+1F51+0301 -> U+1F55 */ 1477, + /* U+1F51+0342 -> U+1F57 */ 1479, + /* U+1F59+0300 -> U+1F5B */ 1481, + /* U+1F59+0301 -> U+1F5D */ 1482, + /* U+1F59+0342 -> U+1F5F */ 1483, + /* U+1F60+0300 -> U+1F62 */ 1486, + /* U+1F60+0301 -> U+1F64 */ 1488, + /* U+1F60+0342 -> U+1F66 */ 1490, + /* U+1F60+0345 -> U+1FA0 */ 1546, + /* U+1F61+0300 -> U+1F63 */ 1487, + /* U+1F61+0301 -> U+1F65 */ 1489, + /* U+1F61+0342 -> U+1F67 */ 1491, + /* U+1F61+0345 -> U+1FA1 */ 1547, + /* U+1F62+0345 -> U+1FA2 */ 1548, + /* U+1F63+0345 -> U+1FA3 */ 1549, + /* U+1F64+0345 -> U+1FA4 */ 1550, + /* U+1F65+0345 -> U+1FA5 */ 1551, + /* U+1F66+0345 -> U+1FA6 */ 1552, + /* U+1F67+0345 -> U+1FA7 */ 1553, + /* U+1F68+0300 -> U+1F6A */ 1494, + /* U+1F68+0301 -> U+1F6C */ 1496, + /* U+1F68+0342 -> U+1F6E */ 1498, + /* U+1F68+0345 -> U+1FA8 */ 1554, + /* U+1F69+0300 -> U+1F6B */ 1495, + /* U+1F69+0301 -> U+1F6D */ 1497, + /* U+1F69+0342 -> U+1F6F */ 1499, + /* U+1F69+0345 -> U+1FA9 */ 1555, + /* U+1F6A+0345 -> U+1FAA */ 1556, + /* U+1F6B+0345 -> U+1FAB */ 1557, + /* U+1F6C+0345 -> U+1FAC */ 1558, + /* U+1F6D+0345 -> U+1FAD */ 1559, + /* U+1F6E+0345 -> U+1FAE */ 1560, + /* U+1F6F+0345 -> U+1FAF */ 1561, + /* U+1F70+0345 -> U+1FB2 */ 1564, + /* U+1F74+0345 -> U+1FC2 */ 1579, + /* U+1F7C+0345 -> U+1FF2 */ 1621, + /* U+1FB6+0345 -> U+1FB7 */ 1568, + /* U+1FBF+0300 -> U+1FCD */ 1589, + /* U+1FBF+0301 -> U+1FCE */ 1590, + /* U+1FBF+0342 -> U+1FCF */ 1591, + /* U+1FC6+0345 -> U+1FC7 */ 1583, + /* U+1FF6+0345 -> U+1FF7 */ 1625, + /* U+1FFE+0300 -> U+1FDD */ 1602, + /* U+1FFE+0301 -> U+1FDE */ 1603, + /* U+1FFE+0342 -> U+1FDF */ 1604, + /* U+2190+0338 -> U+219A */ 1835, + /* U+2192+0338 -> U+219B */ 1836, + /* U+2194+0338 -> U+21AE */ 1837, + /* U+21D0+0338 -> U+21CD */ 1838, + /* U+21D2+0338 -> U+21CF */ 1840, + /* U+21D4+0338 -> U+21CE */ 1839, + /* U+2203+0338 -> U+2204 */ 1841, + /* U+2208+0338 -> U+2209 */ 1842, + /* U+220B+0338 -> U+220C */ 1843, + /* U+2223+0338 -> U+2224 */ 1844, + /* U+2225+0338 -> U+2226 */ 1845, + /* U+223C+0338 -> U+2241 */ 1850, + /* U+2243+0338 -> U+2244 */ 1851, + /* U+2245+0338 -> U+2247 */ 1852, + /* U+2248+0338 -> U+2249 */ 1853, + /* U+224D+0338 -> U+226D */ 1856, + /* U+2261+0338 -> U+2262 */ 1855, + /* U+2264+0338 -> U+2270 */ 1859, + /* U+2265+0338 -> U+2271 */ 1860, + /* U+2272+0338 -> U+2274 */ 1861, + /* U+2273+0338 -> U+2275 */ 1862, + /* U+2276+0338 -> U+2278 */ 1863, + /* U+2277+0338 -> U+2279 */ 1864, + /* U+227A+0338 -> U+2280 */ 1865, + /* U+227B+0338 -> U+2281 */ 1866, + /* U+227C+0338 -> U+22E0 */ 1875, + /* U+227D+0338 -> U+22E1 */ 1876, + /* U+2282+0338 -> U+2284 */ 1867, + /* U+2283+0338 -> U+2285 */ 1868, + /* U+2286+0338 -> U+2288 */ 1869, + /* U+2287+0338 -> U+2289 */ 1870, + /* U+2291+0338 -> U+22E2 */ 1877, + /* U+2292+0338 -> U+22E3 */ 1878, + /* U+22A2+0338 -> U+22AC */ 1871, + /* U+22A8+0338 -> U+22AD */ 1872, + /* U+22A9+0338 -> U+22AE */ 1873, + /* U+22AB+0338 -> U+22AF */ 1874, + /* U+22B2+0338 -> U+22EA */ 1879, + /* U+22B3+0338 -> U+22EB */ 1880, + /* U+22B4+0338 -> U+22EC */ 1881, + /* U+22B5+0338 -> U+22ED */ 1882, + /* U+3046+3099 -> U+3094 */ 2320, + /* U+304B+3099 -> U+304C */ 2295, + /* U+304D+3099 -> U+304E */ 2296, + /* U+304F+3099 -> U+3050 */ 2297, + /* U+3051+3099 -> U+3052 */ 2298, + /* U+3053+3099 -> U+3054 */ 2299, + /* U+3055+3099 -> U+3056 */ 2300, + /* U+3057+3099 -> U+3058 */ 2301, + /* U+3059+3099 -> U+305A */ 2302, + /* U+305B+3099 -> U+305C */ 2303, + /* U+305D+3099 -> U+305E */ 2304, + /* U+305F+3099 -> U+3060 */ 2305, + /* U+3061+3099 -> U+3062 */ 2306, + /* U+3064+3099 -> U+3065 */ 2307, + /* U+3066+3099 -> U+3067 */ 2308, + /* U+3068+3099 -> U+3069 */ 2309, + /* U+306F+3099 -> U+3070 */ 2310, + /* U+306F+309A -> U+3071 */ 2311, + /* U+3072+3099 -> U+3073 */ 2312, + /* U+3072+309A -> U+3074 */ 2313, + /* U+3075+3099 -> U+3076 */ 2314, + /* U+3075+309A -> U+3077 */ 2315, + /* U+3078+3099 -> U+3079 */ 2316, + /* U+3078+309A -> U+307A */ 2317, + /* U+307B+3099 -> U+307C */ 2318, + /* U+307B+309A -> U+307D */ 2319, + /* U+309D+3099 -> U+309E */ 2325, + /* U+30A6+3099 -> U+30F4 */ 2352, + /* U+30AB+3099 -> U+30AC */ 2327, + /* U+30AD+3099 -> U+30AE */ 2328, + /* U+30AF+3099 -> U+30B0 */ 2329, + /* U+30B1+3099 -> U+30B2 */ 2330, + /* U+30B3+3099 -> U+30B4 */ 2331, + /* U+30B5+3099 -> U+30B6 */ 2332, + /* U+30B7+3099 -> U+30B8 */ 2333, + /* U+30B9+3099 -> U+30BA */ 2334, + /* U+30BB+3099 -> U+30BC */ 2335, + /* U+30BD+3099 -> U+30BE */ 2336, + /* U+30BF+3099 -> U+30C0 */ 2337, + /* U+30C1+3099 -> U+30C2 */ 2338, + /* U+30C4+3099 -> U+30C5 */ 2339, + /* U+30C6+3099 -> U+30C7 */ 2340, + /* U+30C8+3099 -> U+30C9 */ 2341, + /* U+30CF+3099 -> U+30D0 */ 2342, + /* U+30CF+309A -> U+30D1 */ 2343, + /* U+30D2+3099 -> U+30D3 */ 2344, + /* U+30D2+309A -> U+30D4 */ 2345, + /* U+30D5+3099 -> U+30D6 */ 2346, + /* U+30D5+309A -> U+30D7 */ 2347, + /* U+30D8+3099 -> U+30D9 */ 2348, + /* U+30D8+309A -> U+30DA */ 2349, + /* U+30DB+3099 -> U+30DC */ 2350, + /* U+30DB+309A -> U+30DD */ 2351, + /* U+30EF+3099 -> U+30F7 */ 2353, + /* U+30F0+3099 -> U+30F8 */ 2354, + /* U+30F1+3099 -> U+30F9 */ 2355, + /* U+30F2+3099 -> U+30FA */ 2356, + /* U+30FD+3099 -> U+30FE */ 2357, + /* U+11099+110BA -> U+1109A */ 4689, + /* U+1109B+110BA -> U+1109C */ 4690, + /* U+110A5+110BA -> U+110AB */ 4691, + /* U+11131+11127 -> U+1112E */ 4697, + /* U+11132+11127 -> U+1112F */ 4698, + /* U+11347+1133E -> U+1134B */ 4710, + /* U+11347+11357 -> U+1134C */ 4711, + /* U+114B9+114B0 -> U+114BC */ 4729, + /* U+114B9+114BA -> U+114BB */ 4728, + /* U+114B9+114BD -> U+114BE */ 4730, + /* U+115B8+115AF -> U+115BA */ 4733, + /* U+115B9+115AF -> U+115BB */ 4734, + /* U+11935+11930 -> U+11938 */ 4743 +}; + +/* Perfect hash function for recomposition */ +static int +Recomp_hash_func(const void *key) +{ + static const int16 h[1883] = { + 772, 773, 621, 32767, 32767, 387, 653, 196, + 32767, 32767, 855, 463, -19, 651, 32767, 32767, + 32767, 364, 32767, 32767, -108, 32767, 32767, 32767, + 32767, 0, -568, 32767, 32767, 32767, 0, 0, + 0, -103, 364, 0, 210, 732, 0, 0, + -506, 0, 0, 0, 32767, 32767, 0, 32767, + 407, -140, 32767, 409, 32767, 772, 0, 86, + 842, 934, 32767, 32767, -499, -355, 32767, 32767, + 532, 138, 174, -243, 860, 1870, 742, 32767, + 32767, 339, 32767, 1290, 0, 32767, 32767, 0, + -449, -1386, 1633, 560, 561, 32767, 1219, 1004, + 139, -804, 32767, -179, 141, 579, 1586, 32767, + 32767, 32767, 142, 199, 32767, 32767, 143, 0, + 32767, 32767, 314, 896, 32767, 32767, 428, 129, + 286, -58, 0, 68, 32767, 0, 244, -566, + 32767, 32767, 32767, 246, 32767, 32767, 0, 32767, + 32767, 271, -108, 928, 32767, 715, 32767, 32767, + -211, -497, 32767, 0, 1055, 1339, 32767, 0, + 32767, 32767, -968, -144, 32767, 32767, 248, 32767, + -161, 32767, 32767, 282, 32767, -372, 0, 2, + -137, 1116, 32767, 687, 32767, 459, 913, 0, + 461, 879, -816, 443, 32767, 32767, 462, 1089, + 32767, 1054, 0, 314, 447, -26, 480, 32767, + 64, 0, 0, 112, 32767, 66, 0, 646, + 603, 22, -292, 0, 710, 475, 32767, 24, + -781, 32767, 32767, 32767, 281, 307, 32767, 1289, + 32767, 0, 1064, -149, 454, 118, 32767, 32767, + 0, 32767, -126, 0, 32767, 32767, 858, 32767, + 32767, 32767, 1029, 886, 665, 209, 0, 26, + 359, 0, 0, -108, -508, -603, 894, 906, + 32767, 32767, 14, 0, 0, 534, 984, 876, + 32767, -93, 110, -367, 167, 843, 32767, 32767, + -947, -290, 169, 0, 0, 32767, -42, 564, + 0, -927, 32767, 817, 32767, 32767, 32767, 110, + 0, 32767, 32767, -38, 32767, 32767, -101, 694, + -142, 190, 191, 1288, 32767, -687, 194, -579, + 534, -452, 0, -72, 536, 765, 823, 266, + -259, 684, 767, 32767, 654, 32767, 32767, 64, + 920, 32767, 32767, 32767, 0, 1653, 0, 0, + 32767, 32767, -452, -222, 855, 0, 32767, -1153, + 127, 490, 449, 863, 32767, -144, 32767, -379, + 545, 32767, 32767, 32767, 530, 32767, 32767, 1331, + 611, -612, 332, 545, -73, 0, 604, 201, + 32767, -279, 338, 836, 340, 408, 32767, -60, + -358, 32767, 343, 69, 707, 0, -129, 582, + 32767, 0, 32767, 96, 392, 490, 639, 157, + -4, 406, 32767, 32767, -571, 1077, 546, 32767, + 551, 0, 0, 0, 32767, 32767, 348, 32767, + 498, -181, 0, -433, 1057, 260, 0, 32767, + 32767, 397, 32767, 816, -130, 32767, 624, 0, + 0, 32767, 32767, 32767, 485, 0, 32767, 32767, + 32767, 32767, 32767, 0, 32767, 32767, 32767, 1222, + -230, 32767, 797, -538, 32767, 974, 32767, 32767, + 831, 70, -658, 145, 0, 147, 0, 32767, + 1295, 32767, 0, 0, 895, 0, 0, -385, + 491, -287, 32767, -587, 32767, 32767, 32767, 813, + -471, -13, 32767, 32767, 32767, 0, 203, 411, + 470, 0, -546, -179, 146, 0, 0, 32767, + -468, 32767, 0, 0, 32767, 32767, 32767, 211, + 32767, 32767, 0, 32767, 0, 52, 32767, 0, + 32767, 0, 692, 990, 32767, 32767, 32767, 56, + -507, 784, 951, 0, 32767, 0, 697, 32767, + 187, 0, 32767, 32767, 430, 1209, 682, 32767, + 130, 0, -25, 0, -1006, 0, 32767, 214, + 433, 22, 0, -1119, 32767, 285, 32767, 32767, + 32767, 216, 32767, 32767, 32767, 217, 527, 32767, + 32767, 32767, 829, 485, 419, 717, 620, 731, + 32767, 470, 0, -145, -620, 1162, -644, 848, + 287, -632, 32767, 32767, 32767, 32767, 381, 32767, + 510, 511, -554, -2, 32767, 0, 0, 698, + 32767, 32767, 436, 1154, 32767, 463, 32767, 32767, + 627, 517, 32767, 32767, 854, 579, 723, 396, + 110, -42, 354, 32767, 664, 32767, 32767, 0, + 0, 32767, 65, -163, 67, 140, 69, 341, + 70, 71, 402, 73, 623, 544, 624, 417, + -1375, 648, 32767, -26, 904, 0, 548, 0, + 0, 32767, 32767, 855, 32767, 488, -524, 599, + 130, 131, 32767, 32767, 542, -1110, -324, -462, + 32767, -405, -440, 0, 0, 629, 850, 0, + 741, 257, 258, 32767, 32767, 0, 32767, 923, + 0, 32767, 0, 32767, 1559, 32767, 32767, 32767, + 671, 32767, 134, 32767, 32767, -336, -104, 576, + 577, 829, 32767, 32767, 762, 902, 32767, 0, + 32767, 0, 1506, 887, 32767, 636, 601, 2465, + 426, 0, 236, 317, 427, 968, 32767, -975, + -559, -343, 341, 32767, 937, 241, 0, 32767, + 32767, 547, 32767, 32767, 32767, 32767, 32767, 789, + 0, 32767, 32767, 32767, 0, 0, 0, 32767, + -192, 859, 1185, 1153, 69, 32767, 32767, 32767, + -539, 32767, 32767, 0, 32767, 32767, 32767, 32767, + 640, 578, 32767, 32767, -766, 32767, 32767, 32767, + 32767, 1050, -572, 32767, 32767, 32767, 32767, 1268, + 32767, 32767, 32767, 754, 32767, 32767, 1640, 179, + 804, 32767, 32767, 32767, 32767, 0, 684, 943, + 1006, 32767, 32767, 652, 0, 32767, 1041, 32767, + 718, 791, 32767, 274, 697, 32767, 32767, 0, + 32767, 32767, 32767, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 735, + 0, 32767, 32767, 32767, 275, 358, 688, 32767, + 32767, 32767, 548, -87, 770, 32767, -42, 0, + 551, 32767, 691, 222, 32767, 32767, 32767, 32767, + 0, 1273, 403, -121, 806, 553, 554, 163, + 32767, 32767, 892, 825, 32767, 32767, -490, 32767, + 32767, 32767, 32767, 32767, -109, 744, 910, 32767, + 91, 32767, 32767, 0, 0, 32767, 32767, 32767, + 1521, 50, 701, 32767, 32767, 32767, 32767, 164, + 658, 32767, 288, 0, 32767, 0, 51, 0, + 32767, 32767, 32767, 32767, 555, 1547, 32767, 32767, + 595, 585, 429, 32767, -80, 32767, 1258, 0, + 540, 486, -434, 865, 0, 192, 0, 884, + 0, 0, 0, 175, 555, 0, 32767, 32767, + 0, 32767, -566, 866, 591, 32767, 32767, 32767, + 32767, 32767, 496, 495, -215, 32767, 849, -772, + 32767, 32767, 502, 178, 483, 32767, 912, 793, + 794, 0, 32767, 32767, 32767, -556, 499, 838, + 32767, 32767, -506, 331, 0, 0, -1096, 512, + 880, 0, 774, -338, 649, 32767, 270, 32767, + 32767, -624, 328, 459, 32767, 32767, 32767, 32767, + 329, -201, -835, 813, -879, 560, 0, -212, + -114, 35, -494, 37, 523, 653, 751, -653, + -743, 32767, 1356, 818, 32767, 32767, 856, 0, + 44, 902, 0, 0, 0, 0, 32767, -26, + 526, 795, 456, 32767, 104, -209, -341, 133, + -372, 0, 45, 110, 111, 0, 511, 47, + 114, 32767, 32767, 93, 48, 116, -1031, -279, + 32767, 192, 0, 32767, 453, 415, 0, -190, + 32767, 471, 240, 175, 29, 665, 684, 0, + -11, -95, -344, 32767, 245, 148, 0, 530, + 0, 1185, -615, -712, 693, 784, 32767, 0, + -776, 32767, 32767, -813, 0, 0, 0, 207, + 208, 32767, 674, 32767, 742, -289, 249, 32767, + 520, 929, -50, 781, 0, -778, 32767, 0, + 302, 32767, 720, -465, 0, 32767, 32767, 32767, + 0, 0, 32767, 833, 328, 806, 32767, -403, + 0, 32767, -77, 32767, 0, 441, 930, 32767, + 643, 0, 32767, 1938, 0, 1334, 381, 32767, + 216, 32767, 32767, 0, 32767, 484, 383, 0, + 242, 395, 0, 32767, 32767, 32767, -781, 355, + 356, 32767, 292, 706, 32767, 32767, 32767, 32767, + 32767, -410, 32767, 32767, 782, 32767, 189, 32767, + 32767, 943, 0, -212, 407, 335, 0, 135, + 32767, 616, 0, -497, 0, -67, 853, 32767, + 700, 32767, 0, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 0, 459, -48, 32767, 58, 0, + -856, 1017, 32767, 59, 916, -731, 32767, 940, + -855, 347, 650, 0, 678, 32767, 0, 32767, + 32767, 530, 32767, 0, -80, 32767, -730, 32767, + 1214, 799, 58, 651, 841, 0, 0, -589, + -1530, -478, 651, 652, 93, 576, -1215, 32767, + 125, 32767, 1279, 32767, 32767, 0, 32767, 0, + -367, 416, -1236, 32767, 418, 32767, 815, 558, + 559, 781, 419, 32767, 739, 32767, 0, 32767, + 128, 570, 1349, -298, -66, 0, 147, -488, + 32767, 590, 189, 274, 524, 32767, 1082, -209, + 32767, 423, 32767, 32767, 975, 573, 32767, 424, + 32767, 32767, 1241, 32767, 32767, 32767, 32767, 32767, + 612, 391, 32767, 0, -803, 1004, -561, 32767, + 32767, 735, 870, 32767, 0, 32767, 32767, -123, + 99, 210, 600, 1294, 109, 1053, 32767, 307, + 834, 32767, 0, 1651, 32767, 644, 32767, 32767, + 0, 32767, -801, 385, 379, 32767, -368, 32767, + 32767, 830, 0, 32767, 32767, 739, 371, 372, + -275, 32767, 32767, 331, -780, 32767, 0, 1229, + -1462, 913, 266, 827, 125, 32767, 32767, 32767, + 393, 32767, 631, -33, -883, -661, -204, 6, + -19, 257, 8, 9, 118, 519, 615, -541, + -893, 0, 32767, 0, 1156, 15, 900, 32767, + 32767, 32767, 32767, 32767, 32767, 1022, 376, 0, + 32767, 32767, -972, 676, 840, -661, 631, 58, + 0, 17, 32767, 0, -799, 82, 0, 32767, + 32767, 680, 32767, 905, 0, 0, 32767, 32767, + 0, 0, 32767, 0, 828, 386, 802, 0, + 146, 0, 148, 32767, -1146, 0, 150, 151, + -743, 153, 154, 32767, 32767, 442, 32767, 743, + 0, 0, 746, 0, 32767, 32767, 32767, 98, + 32767, 157, 0, 696, 0, 32767, 32767, -294, + 32767, 158, 159, 32767, 0, 32767, 160, 32767, + 933, 32767, 32767, -50, 759, 824, 162, 672, + 32767, 356, 0, 356, 32767, 32767, 0, 0, + 656, 692, 253, 254, -374, 102, 256, 32767, + 0, 0, 32767, 32767, 259, 32767, 63, 260, + 510, 261, 32767, 0, 32767, 1061, 32767, 521, + 32767, 32767, 32767, 32767, 32767, 32767, 316, 317, + 846, 0, 32767, -500, 318, 0, 32767, 32767, + 263, 0, 790, 872, 32767, 32767, 32767, 2171, + 264, 32767, 32767, 32767, 32767, 486, 334, 465, + 32767, 466, 32767, 444, 606, 32767, 0, 445, + 320, -317, 0, 520, 322, 718, 32767, 32767, + 32767, 0, 1013, 32767, 32767, 32767, 32767, 32767, + 32767, 611, 32767, 0, 0, 32767, 32767, -120, + 156, 613, 0, 0, 32767, -68, 32767, 622, + 32767, 32767, 32767, 32767, 32767, 455, 32767, 32767, + 32767, 403, 533, 0, -161, 405, 95, 96, + 32767, 97, 32767, 0, 29, 0, 32767, 32767, + 30, 32767, 99, 32767, 32767, 0, 161, 32767, + 97, 0, 32, 32767, 32767, 0, 0, 315, + 32767, 32767, 414, 966, 0, 585, 32767, 32767, + -616, -256, 171, 172, 666, 101, 562, 563, + 32767, 95, 0, 0, 1492, 390, -251, 103, + 32767, 0, 32767, 188, 1487, 32767, 0, 0, + 586, 668, -126, 0, 0, 32767, 32767, 204, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 656, 32767, 32767, + 599, 0, 222, 32767, 0, 1368, -412, 435, + 32767, 936, 32767, -17, 32767, 832, 32767, 437, + 0, -518, 787, 32767, 864, -449, 0, 636, + 713, 206, 592, 572, 0, 483, -139, 32767, + 32767, 180, 818, 32767, 32767, 1304, 0, 32767, + 274, 0, 0, 0, 0, 705, 32767, 32767, + 32767, 0, -272, 0, 502, 503, 319, 0, + 32767, 0, 13, 32767, 32767, 0, 32767, 270, + 737, 0, 32767, 32767, 32767, 901, 32767, 616, + 180, 32767, 721, 353, 32767, 0, 32767, 32767, + -199, 0, 280, 788, 32767, 940, 32767, 51, + 0, 400, 53, 0, 54, -637, 0, -453, + 0, 0, 0, 380, 0, 32767, 504, 0, + 2049, 0, -964, 32767, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 798, 32767, 32767, 32767, 0, + 538, 488, 0, 32767, -528, 57, 819, 32767, + 32767, 1244, 0, 488, 739, 908, 32767, 32767, + 0, 32767, 32767, 0, 55, 533, 0, 32767, + 814, 0, 32767, 458, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 776, 777, 920, 0, + 0, 755, 32767, 0, 32767, 32767, 0, 32767, + 55, -954, 0, 372, 166, 218, 165, 857, + 221, 675, 0, 223, 224, -155, 226, 32767, + 1851, 227, 32767, 32767, 1192, 0, 229, 0, + -72, 0, 865, 0, 0, -330, 0, 683, + 32767, -550, -196, 725, -573, 293, 102, 32767, + -589, 296, 297, 298, 231, -256, 300, 32767, + 32767, 301, 233, 868, 32767, 234, 0, 811, + 1187, 32767, 32767, 0, 32767, 518, 0, 361, + 362, 466, 0, 365, 32767, -179, 366, 367, + 874, 369, 305, 0, 32767, 0, 32767, 0, + 32767, 2000, 1215, 451, 652, 0, 0, 799, + 32767, 32767, 32767 + }; + + const unsigned char *k = (const unsigned char *) key; + size_t keylen = 8; + uint32 a = 0; + uint32 b = 0; + + while (keylen--) + { + unsigned char c = *k++; + + a = a * 257 + c; + b = b * 17 + c; + } + return h[a % 1883] + h[b % 1883]; +} + +/* Hash lookup information for recomposition */ +static const pg_unicode_recompinfo UnicodeRecompInfo = +{ + RecompInverseLookup, + Recomp_hash_func, + 941 +}; diff --git a/install/include/postgresql/server/common/unicode_norm_table.h b/install/include/postgresql/server/common/unicode_norm_table.h new file mode 100644 index 00000000000..36b6ca40446 --- /dev/null +++ b/install/include/postgresql/server/common/unicode_norm_table.h @@ -0,0 +1,9114 @@ +/*------------------------------------------------------------------------- + * + * unicode_norm_table.h + * Composition table used for Unicode normalization + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/unicode_norm_table.h + * + *------------------------------------------------------------------------- + */ + +/* + * File auto-generated by src/common/unicode/generate-unicode_norm_table.pl, + * do not edit. There is deliberately not an #ifndef PG_UNICODE_NORM_TABLE_H + * here. + */ +typedef struct +{ + uint32 codepoint; /* Unicode codepoint */ + uint8 comb_class; /* combining class of character */ + uint8 dec_size_flags; /* size and flags of decomposition code list */ + uint16 dec_index; /* index into UnicodeDecomp_codepoints, or the + * decomposition itself if DECOMP_INLINE */ +} pg_unicode_decomposition; + +#define DECOMP_NO_COMPOSE 0x80 /* don't use for re-composition */ +#define DECOMP_INLINE 0x40 /* decomposition is stored inline in + * dec_index */ +#define DECOMP_COMPAT 0x20 /* compatibility mapping */ + +#define DECOMPOSITION_SIZE(x) ((x)->dec_size_flags & 0x1F) +#define DECOMPOSITION_NO_COMPOSE(x) (((x)->dec_size_flags & (DECOMP_NO_COMPOSE | DECOMP_COMPAT)) != 0) +#define DECOMPOSITION_IS_INLINE(x) (((x)->dec_size_flags & DECOMP_INLINE) != 0) +#define DECOMPOSITION_IS_COMPAT(x) (((x)->dec_size_flags & DECOMP_COMPAT) != 0) + +/* Table of Unicode codepoints and their decompositions */ +static const pg_unicode_decomposition UnicodeDecompMain[6775] = +{ + {0x00A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x00A8, 0, 2 | DECOMP_COMPAT, 0}, + {0x00AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x00AF, 0, 2 | DECOMP_COMPAT, 2}, + {0x00B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x00B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x00B4, 0, 2 | DECOMP_COMPAT, 4}, + {0x00B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, + {0x00B8, 0, 2 | DECOMP_COMPAT, 6}, + {0x00B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x00BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x00BC, 0, 3 | DECOMP_COMPAT, 8}, + {0x00BD, 0, 3 | DECOMP_COMPAT, 11}, + {0x00BE, 0, 3 | DECOMP_COMPAT, 14}, + {0x00C0, 0, 2, 17}, + {0x00C1, 0, 2, 19}, + {0x00C2, 0, 2, 21}, + {0x00C3, 0, 2, 23}, + {0x00C4, 0, 2, 25}, + {0x00C5, 0, 2, 27}, + {0x00C7, 0, 2, 29}, + {0x00C8, 0, 2, 31}, + {0x00C9, 0, 2, 33}, + {0x00CA, 0, 2, 35}, + {0x00CB, 0, 2, 37}, + {0x00CC, 0, 2, 39}, + {0x00CD, 0, 2, 41}, + {0x00CE, 0, 2, 43}, + {0x00CF, 0, 2, 45}, + {0x00D1, 0, 2, 47}, + {0x00D2, 0, 2, 49}, + {0x00D3, 0, 2, 51}, + {0x00D4, 0, 2, 53}, + {0x00D5, 0, 2, 55}, + {0x00D6, 0, 2, 57}, + {0x00D9, 0, 2, 59}, + {0x00DA, 0, 2, 61}, + {0x00DB, 0, 2, 63}, + {0x00DC, 0, 2, 65}, + {0x00DD, 0, 2, 67}, + {0x00E0, 0, 2, 69}, + {0x00E1, 0, 2, 71}, + {0x00E2, 0, 2, 73}, + {0x00E3, 0, 2, 75}, + {0x00E4, 0, 2, 77}, + {0x00E5, 0, 2, 79}, + {0x00E7, 0, 2, 81}, + {0x00E8, 0, 2, 83}, + {0x00E9, 0, 2, 85}, + {0x00EA, 0, 2, 87}, + {0x00EB, 0, 2, 89}, + {0x00EC, 0, 2, 91}, + {0x00ED, 0, 2, 93}, + {0x00EE, 0, 2, 95}, + {0x00EF, 0, 2, 97}, + {0x00F1, 0, 2, 99}, + {0x00F2, 0, 2, 101}, + {0x00F3, 0, 2, 103}, + {0x00F4, 0, 2, 105}, + {0x00F5, 0, 2, 107}, + {0x00F6, 0, 2, 109}, + {0x00F9, 0, 2, 111}, + {0x00FA, 0, 2, 113}, + {0x00FB, 0, 2, 115}, + {0x00FC, 0, 2, 117}, + {0x00FD, 0, 2, 119}, + {0x00FF, 0, 2, 121}, + {0x0100, 0, 2, 123}, + {0x0101, 0, 2, 125}, + {0x0102, 0, 2, 127}, + {0x0103, 0, 2, 129}, + {0x0104, 0, 2, 131}, + {0x0105, 0, 2, 133}, + {0x0106, 0, 2, 135}, + {0x0107, 0, 2, 137}, + {0x0108, 0, 2, 139}, + {0x0109, 0, 2, 141}, + {0x010A, 0, 2, 143}, + {0x010B, 0, 2, 145}, + {0x010C, 0, 2, 147}, + {0x010D, 0, 2, 149}, + {0x010E, 0, 2, 151}, + {0x010F, 0, 2, 153}, + {0x0112, 0, 2, 155}, + {0x0113, 0, 2, 157}, + {0x0114, 0, 2, 159}, + {0x0115, 0, 2, 161}, + {0x0116, 0, 2, 163}, + {0x0117, 0, 2, 165}, + {0x0118, 0, 2, 167}, + {0x0119, 0, 2, 169}, + {0x011A, 0, 2, 171}, + {0x011B, 0, 2, 173}, + {0x011C, 0, 2, 175}, + {0x011D, 0, 2, 177}, + {0x011E, 0, 2, 179}, + {0x011F, 0, 2, 181}, + {0x0120, 0, 2, 183}, + {0x0121, 0, 2, 185}, + {0x0122, 0, 2, 187}, + {0x0123, 0, 2, 189}, + {0x0124, 0, 2, 191}, + {0x0125, 0, 2, 193}, + {0x0128, 0, 2, 195}, + {0x0129, 0, 2, 197}, + {0x012A, 0, 2, 199}, + {0x012B, 0, 2, 201}, + {0x012C, 0, 2, 203}, + {0x012D, 0, 2, 205}, + {0x012E, 0, 2, 207}, + {0x012F, 0, 2, 209}, + {0x0130, 0, 2, 211}, + {0x0132, 0, 2 | DECOMP_COMPAT, 213}, + {0x0133, 0, 2 | DECOMP_COMPAT, 215}, + {0x0134, 0, 2, 217}, + {0x0135, 0, 2, 219}, + {0x0136, 0, 2, 221}, + {0x0137, 0, 2, 223}, + {0x0139, 0, 2, 225}, + {0x013A, 0, 2, 227}, + {0x013B, 0, 2, 229}, + {0x013C, 0, 2, 231}, + {0x013D, 0, 2, 233}, + {0x013E, 0, 2, 235}, + {0x013F, 0, 2 | DECOMP_COMPAT, 237}, + {0x0140, 0, 2 | DECOMP_COMPAT, 239}, + {0x0143, 0, 2, 241}, + {0x0144, 0, 2, 243}, + {0x0145, 0, 2, 245}, + {0x0146, 0, 2, 247}, + {0x0147, 0, 2, 249}, + {0x0148, 0, 2, 251}, + {0x0149, 0, 2 | DECOMP_COMPAT, 253}, + {0x014C, 0, 2, 255}, + {0x014D, 0, 2, 257}, + {0x014E, 0, 2, 259}, + {0x014F, 0, 2, 261}, + {0x0150, 0, 2, 263}, + {0x0151, 0, 2, 265}, + {0x0154, 0, 2, 267}, + {0x0155, 0, 2, 269}, + {0x0156, 0, 2, 271}, + {0x0157, 0, 2, 273}, + {0x0158, 0, 2, 275}, + {0x0159, 0, 2, 277}, + {0x015A, 0, 2, 279}, + {0x015B, 0, 2, 281}, + {0x015C, 0, 2, 283}, + {0x015D, 0, 2, 285}, + {0x015E, 0, 2, 287}, + {0x015F, 0, 2, 289}, + {0x0160, 0, 2, 291}, + {0x0161, 0, 2, 293}, + {0x0162, 0, 2, 295}, + {0x0163, 0, 2, 297}, + {0x0164, 0, 2, 299}, + {0x0165, 0, 2, 301}, + {0x0168, 0, 2, 303}, + {0x0169, 0, 2, 305}, + {0x016A, 0, 2, 307}, + {0x016B, 0, 2, 309}, + {0x016C, 0, 2, 311}, + {0x016D, 0, 2, 313}, + {0x016E, 0, 2, 315}, + {0x016F, 0, 2, 317}, + {0x0170, 0, 2, 319}, + {0x0171, 0, 2, 321}, + {0x0172, 0, 2, 323}, + {0x0173, 0, 2, 325}, + {0x0174, 0, 2, 327}, + {0x0175, 0, 2, 329}, + {0x0176, 0, 2, 331}, + {0x0177, 0, 2, 333}, + {0x0178, 0, 2, 335}, + {0x0179, 0, 2, 337}, + {0x017A, 0, 2, 339}, + {0x017B, 0, 2, 341}, + {0x017C, 0, 2, 343}, + {0x017D, 0, 2, 345}, + {0x017E, 0, 2, 347}, + {0x017F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x01A0, 0, 2, 349}, + {0x01A1, 0, 2, 351}, + {0x01AF, 0, 2, 353}, + {0x01B0, 0, 2, 355}, + {0x01C4, 0, 2 | DECOMP_COMPAT, 357}, + {0x01C5, 0, 2 | DECOMP_COMPAT, 359}, + {0x01C6, 0, 2 | DECOMP_COMPAT, 361}, + {0x01C7, 0, 2 | DECOMP_COMPAT, 363}, + {0x01C8, 0, 2 | DECOMP_COMPAT, 365}, + {0x01C9, 0, 2 | DECOMP_COMPAT, 367}, + {0x01CA, 0, 2 | DECOMP_COMPAT, 369}, + {0x01CB, 0, 2 | DECOMP_COMPAT, 371}, + {0x01CC, 0, 2 | DECOMP_COMPAT, 373}, + {0x01CD, 0, 2, 375}, + {0x01CE, 0, 2, 377}, + {0x01CF, 0, 2, 379}, + {0x01D0, 0, 2, 381}, + {0x01D1, 0, 2, 383}, + {0x01D2, 0, 2, 385}, + {0x01D3, 0, 2, 387}, + {0x01D4, 0, 2, 389}, + {0x01D5, 0, 2, 391}, + {0x01D6, 0, 2, 393}, + {0x01D7, 0, 2, 395}, + {0x01D8, 0, 2, 397}, + {0x01D9, 0, 2, 399}, + {0x01DA, 0, 2, 401}, + {0x01DB, 0, 2, 403}, + {0x01DC, 0, 2, 405}, + {0x01DE, 0, 2, 407}, + {0x01DF, 0, 2, 409}, + {0x01E0, 0, 2, 411}, + {0x01E1, 0, 2, 413}, + {0x01E2, 0, 2, 415}, + {0x01E3, 0, 2, 417}, + {0x01E6, 0, 2, 419}, + {0x01E7, 0, 2, 421}, + {0x01E8, 0, 2, 423}, + {0x01E9, 0, 2, 425}, + {0x01EA, 0, 2, 427}, + {0x01EB, 0, 2, 429}, + {0x01EC, 0, 2, 431}, + {0x01ED, 0, 2, 433}, + {0x01EE, 0, 2, 435}, + {0x01EF, 0, 2, 437}, + {0x01F0, 0, 2, 439}, + {0x01F1, 0, 2 | DECOMP_COMPAT, 441}, + {0x01F2, 0, 2 | DECOMP_COMPAT, 443}, + {0x01F3, 0, 2 | DECOMP_COMPAT, 445}, + {0x01F4, 0, 2, 447}, + {0x01F5, 0, 2, 449}, + {0x01F8, 0, 2, 451}, + {0x01F9, 0, 2, 453}, + {0x01FA, 0, 2, 455}, + {0x01FB, 0, 2, 457}, + {0x01FC, 0, 2, 459}, + {0x01FD, 0, 2, 461}, + {0x01FE, 0, 2, 463}, + {0x01FF, 0, 2, 465}, + {0x0200, 0, 2, 467}, + {0x0201, 0, 2, 469}, + {0x0202, 0, 2, 471}, + {0x0203, 0, 2, 473}, + {0x0204, 0, 2, 475}, + {0x0205, 0, 2, 477}, + {0x0206, 0, 2, 479}, + {0x0207, 0, 2, 481}, + {0x0208, 0, 2, 483}, + {0x0209, 0, 2, 485}, + {0x020A, 0, 2, 487}, + {0x020B, 0, 2, 489}, + {0x020C, 0, 2, 491}, + {0x020D, 0, 2, 493}, + {0x020E, 0, 2, 495}, + {0x020F, 0, 2, 497}, + {0x0210, 0, 2, 499}, + {0x0211, 0, 2, 501}, + {0x0212, 0, 2, 503}, + {0x0213, 0, 2, 505}, + {0x0214, 0, 2, 507}, + {0x0215, 0, 2, 509}, + {0x0216, 0, 2, 511}, + {0x0217, 0, 2, 513}, + {0x0218, 0, 2, 515}, + {0x0219, 0, 2, 517}, + {0x021A, 0, 2, 519}, + {0x021B, 0, 2, 521}, + {0x021E, 0, 2, 523}, + {0x021F, 0, 2, 525}, + {0x0226, 0, 2, 527}, + {0x0227, 0, 2, 529}, + {0x0228, 0, 2, 531}, + {0x0229, 0, 2, 533}, + {0x022A, 0, 2, 535}, + {0x022B, 0, 2, 537}, + {0x022C, 0, 2, 539}, + {0x022D, 0, 2, 541}, + {0x022E, 0, 2, 543}, + {0x022F, 0, 2, 545}, + {0x0230, 0, 2, 547}, + {0x0231, 0, 2, 549}, + {0x0232, 0, 2, 551}, + {0x0233, 0, 2, 553}, + {0x02B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x02B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0266}, + {0x02B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x02B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x02B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0279}, + {0x02B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027B}, + {0x02B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0281}, + {0x02B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x02B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x02D8, 0, 2 | DECOMP_COMPAT, 555}, + {0x02D9, 0, 2 | DECOMP_COMPAT, 557}, + {0x02DA, 0, 2 | DECOMP_COMPAT, 559}, + {0x02DB, 0, 2 | DECOMP_COMPAT, 561}, + {0x02DC, 0, 2 | DECOMP_COMPAT, 563}, + {0x02DD, 0, 2 | DECOMP_COMPAT, 565}, + {0x02E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0263}, + {0x02E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x02E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x02E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x02E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0295}, + {0x0300, 230, 0, 0}, + {0x0301, 230, 0, 0}, + {0x0302, 230, 0, 0}, + {0x0303, 230, 0, 0}, + {0x0304, 230, 0, 0}, + {0x0305, 230, 0, 0}, + {0x0306, 230, 0, 0}, + {0x0307, 230, 0, 0}, + {0x0308, 230, 0, 0}, + {0x0309, 230, 0, 0}, + {0x030A, 230, 0, 0}, + {0x030B, 230, 0, 0}, + {0x030C, 230, 0, 0}, + {0x030D, 230, 0, 0}, + {0x030E, 230, 0, 0}, + {0x030F, 230, 0, 0}, + {0x0310, 230, 0, 0}, + {0x0311, 230, 0, 0}, + {0x0312, 230, 0, 0}, + {0x0313, 230, 0, 0}, + {0x0314, 230, 0, 0}, + {0x0315, 232, 0, 0}, + {0x0316, 220, 0, 0}, + {0x0317, 220, 0, 0}, + {0x0318, 220, 0, 0}, + {0x0319, 220, 0, 0}, + {0x031A, 232, 0, 0}, + {0x031B, 216, 0, 0}, + {0x031C, 220, 0, 0}, + {0x031D, 220, 0, 0}, + {0x031E, 220, 0, 0}, + {0x031F, 220, 0, 0}, + {0x0320, 220, 0, 0}, + {0x0321, 202, 0, 0}, + {0x0322, 202, 0, 0}, + {0x0323, 220, 0, 0}, + {0x0324, 220, 0, 0}, + {0x0325, 220, 0, 0}, + {0x0326, 220, 0, 0}, + {0x0327, 202, 0, 0}, + {0x0328, 202, 0, 0}, + {0x0329, 220, 0, 0}, + {0x032A, 220, 0, 0}, + {0x032B, 220, 0, 0}, + {0x032C, 220, 0, 0}, + {0x032D, 220, 0, 0}, + {0x032E, 220, 0, 0}, + {0x032F, 220, 0, 0}, + {0x0330, 220, 0, 0}, + {0x0331, 220, 0, 0}, + {0x0332, 220, 0, 0}, + {0x0333, 220, 0, 0}, + {0x0334, 1, 0, 0}, + {0x0335, 1, 0, 0}, + {0x0336, 1, 0, 0}, + {0x0337, 1, 0, 0}, + {0x0338, 1, 0, 0}, + {0x0339, 220, 0, 0}, + {0x033A, 220, 0, 0}, + {0x033B, 220, 0, 0}, + {0x033C, 220, 0, 0}, + {0x033D, 230, 0, 0}, + {0x033E, 230, 0, 0}, + {0x033F, 230, 0, 0}, + {0x0340, 230, 1 | DECOMP_INLINE, 0x0300}, + {0x0341, 230, 1 | DECOMP_INLINE, 0x0301}, + {0x0342, 230, 0, 0}, + {0x0343, 230, 1 | DECOMP_INLINE, 0x0313}, + {0x0344, 230, 2 | DECOMP_NO_COMPOSE, 567}, /* non-starter decomposition */ + {0x0345, 240, 0, 0}, + {0x0346, 230, 0, 0}, + {0x0347, 220, 0, 0}, + {0x0348, 220, 0, 0}, + {0x0349, 220, 0, 0}, + {0x034A, 230, 0, 0}, + {0x034B, 230, 0, 0}, + {0x034C, 230, 0, 0}, + {0x034D, 220, 0, 0}, + {0x034E, 220, 0, 0}, + {0x0350, 230, 0, 0}, + {0x0351, 230, 0, 0}, + {0x0352, 230, 0, 0}, + {0x0353, 220, 0, 0}, + {0x0354, 220, 0, 0}, + {0x0355, 220, 0, 0}, + {0x0356, 220, 0, 0}, + {0x0357, 230, 0, 0}, + {0x0358, 232, 0, 0}, + {0x0359, 220, 0, 0}, + {0x035A, 220, 0, 0}, + {0x035B, 230, 0, 0}, + {0x035C, 233, 0, 0}, + {0x035D, 234, 0, 0}, + {0x035E, 234, 0, 0}, + {0x035F, 233, 0, 0}, + {0x0360, 234, 0, 0}, + {0x0361, 234, 0, 0}, + {0x0362, 233, 0, 0}, + {0x0363, 230, 0, 0}, + {0x0364, 230, 0, 0}, + {0x0365, 230, 0, 0}, + {0x0366, 230, 0, 0}, + {0x0367, 230, 0, 0}, + {0x0368, 230, 0, 0}, + {0x0369, 230, 0, 0}, + {0x036A, 230, 0, 0}, + {0x036B, 230, 0, 0}, + {0x036C, 230, 0, 0}, + {0x036D, 230, 0, 0}, + {0x036E, 230, 0, 0}, + {0x036F, 230, 0, 0}, + {0x0374, 0, 1 | DECOMP_INLINE, 0x02B9}, + {0x037A, 0, 2 | DECOMP_COMPAT, 569}, + {0x037E, 0, 1 | DECOMP_INLINE, 0x003B}, + {0x0384, 0, 2 | DECOMP_COMPAT, 571}, + {0x0385, 0, 2, 573}, + {0x0386, 0, 2, 575}, + {0x0387, 0, 1 | DECOMP_INLINE, 0x00B7}, + {0x0388, 0, 2, 577}, + {0x0389, 0, 2, 579}, + {0x038A, 0, 2, 581}, + {0x038C, 0, 2, 583}, + {0x038E, 0, 2, 585}, + {0x038F, 0, 2, 587}, + {0x0390, 0, 2, 589}, + {0x03AA, 0, 2, 591}, + {0x03AB, 0, 2, 593}, + {0x03AC, 0, 2, 595}, + {0x03AD, 0, 2, 597}, + {0x03AE, 0, 2, 599}, + {0x03AF, 0, 2, 601}, + {0x03B0, 0, 2, 603}, + {0x03CA, 0, 2, 605}, + {0x03CB, 0, 2, 607}, + {0x03CC, 0, 2, 609}, + {0x03CD, 0, 2, 611}, + {0x03CE, 0, 2, 613}, + {0x03D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x03D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, + {0x03D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, + {0x03D3, 0, 2, 615}, + {0x03D4, 0, 2, 617}, + {0x03D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x03D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, + {0x03F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, + {0x03F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, + {0x03F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, + {0x03F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, + {0x03F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, + {0x03F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, + {0x0400, 0, 2, 619}, + {0x0401, 0, 2, 621}, + {0x0403, 0, 2, 623}, + {0x0407, 0, 2, 625}, + {0x040C, 0, 2, 627}, + {0x040D, 0, 2, 629}, + {0x040E, 0, 2, 631}, + {0x0419, 0, 2, 633}, + {0x0439, 0, 2, 635}, + {0x0450, 0, 2, 637}, + {0x0451, 0, 2, 639}, + {0x0453, 0, 2, 641}, + {0x0457, 0, 2, 643}, + {0x045C, 0, 2, 645}, + {0x045D, 0, 2, 647}, + {0x045E, 0, 2, 649}, + {0x0476, 0, 2, 651}, + {0x0477, 0, 2, 653}, + {0x0483, 230, 0, 0}, + {0x0484, 230, 0, 0}, + {0x0485, 230, 0, 0}, + {0x0486, 230, 0, 0}, + {0x0487, 230, 0, 0}, + {0x04C1, 0, 2, 655}, + {0x04C2, 0, 2, 657}, + {0x04D0, 0, 2, 659}, + {0x04D1, 0, 2, 661}, + {0x04D2, 0, 2, 663}, + {0x04D3, 0, 2, 665}, + {0x04D6, 0, 2, 667}, + {0x04D7, 0, 2, 669}, + {0x04DA, 0, 2, 671}, + {0x04DB, 0, 2, 673}, + {0x04DC, 0, 2, 675}, + {0x04DD, 0, 2, 677}, + {0x04DE, 0, 2, 679}, + {0x04DF, 0, 2, 681}, + {0x04E2, 0, 2, 683}, + {0x04E3, 0, 2, 685}, + {0x04E4, 0, 2, 687}, + {0x04E5, 0, 2, 689}, + {0x04E6, 0, 2, 691}, + {0x04E7, 0, 2, 693}, + {0x04EA, 0, 2, 695}, + {0x04EB, 0, 2, 697}, + {0x04EC, 0, 2, 699}, + {0x04ED, 0, 2, 701}, + {0x04EE, 0, 2, 703}, + {0x04EF, 0, 2, 705}, + {0x04F0, 0, 2, 707}, + {0x04F1, 0, 2, 709}, + {0x04F2, 0, 2, 711}, + {0x04F3, 0, 2, 713}, + {0x04F4, 0, 2, 715}, + {0x04F5, 0, 2, 717}, + {0x04F8, 0, 2, 719}, + {0x04F9, 0, 2, 721}, + {0x0587, 0, 2 | DECOMP_COMPAT, 723}, + {0x0591, 220, 0, 0}, + {0x0592, 230, 0, 0}, + {0x0593, 230, 0, 0}, + {0x0594, 230, 0, 0}, + {0x0595, 230, 0, 0}, + {0x0596, 220, 0, 0}, + {0x0597, 230, 0, 0}, + {0x0598, 230, 0, 0}, + {0x0599, 230, 0, 0}, + {0x059A, 222, 0, 0}, + {0x059B, 220, 0, 0}, + {0x059C, 230, 0, 0}, + {0x059D, 230, 0, 0}, + {0x059E, 230, 0, 0}, + {0x059F, 230, 0, 0}, + {0x05A0, 230, 0, 0}, + {0x05A1, 230, 0, 0}, + {0x05A2, 220, 0, 0}, + {0x05A3, 220, 0, 0}, + {0x05A4, 220, 0, 0}, + {0x05A5, 220, 0, 0}, + {0x05A6, 220, 0, 0}, + {0x05A7, 220, 0, 0}, + {0x05A8, 230, 0, 0}, + {0x05A9, 230, 0, 0}, + {0x05AA, 220, 0, 0}, + {0x05AB, 230, 0, 0}, + {0x05AC, 230, 0, 0}, + {0x05AD, 222, 0, 0}, + {0x05AE, 228, 0, 0}, + {0x05AF, 230, 0, 0}, + {0x05B0, 10, 0, 0}, + {0x05B1, 11, 0, 0}, + {0x05B2, 12, 0, 0}, + {0x05B3, 13, 0, 0}, + {0x05B4, 14, 0, 0}, + {0x05B5, 15, 0, 0}, + {0x05B6, 16, 0, 0}, + {0x05B7, 17, 0, 0}, + {0x05B8, 18, 0, 0}, + {0x05B9, 19, 0, 0}, + {0x05BA, 19, 0, 0}, + {0x05BB, 20, 0, 0}, + {0x05BC, 21, 0, 0}, + {0x05BD, 22, 0, 0}, + {0x05BF, 23, 0, 0}, + {0x05C1, 24, 0, 0}, + {0x05C2, 25, 0, 0}, + {0x05C4, 230, 0, 0}, + {0x05C5, 220, 0, 0}, + {0x05C7, 18, 0, 0}, + {0x0610, 230, 0, 0}, + {0x0611, 230, 0, 0}, + {0x0612, 230, 0, 0}, + {0x0613, 230, 0, 0}, + {0x0614, 230, 0, 0}, + {0x0615, 230, 0, 0}, + {0x0616, 230, 0, 0}, + {0x0617, 230, 0, 0}, + {0x0618, 30, 0, 0}, + {0x0619, 31, 0, 0}, + {0x061A, 32, 0, 0}, + {0x0622, 0, 2, 725}, + {0x0623, 0, 2, 727}, + {0x0624, 0, 2, 729}, + {0x0625, 0, 2, 731}, + {0x0626, 0, 2, 733}, + {0x064B, 27, 0, 0}, + {0x064C, 28, 0, 0}, + {0x064D, 29, 0, 0}, + {0x064E, 30, 0, 0}, + {0x064F, 31, 0, 0}, + {0x0650, 32, 0, 0}, + {0x0651, 33, 0, 0}, + {0x0652, 34, 0, 0}, + {0x0653, 230, 0, 0}, + {0x0654, 230, 0, 0}, + {0x0655, 220, 0, 0}, + {0x0656, 220, 0, 0}, + {0x0657, 230, 0, 0}, + {0x0658, 230, 0, 0}, + {0x0659, 230, 0, 0}, + {0x065A, 230, 0, 0}, + {0x065B, 230, 0, 0}, + {0x065C, 220, 0, 0}, + {0x065D, 230, 0, 0}, + {0x065E, 230, 0, 0}, + {0x065F, 220, 0, 0}, + {0x0670, 35, 0, 0}, + {0x0675, 0, 2 | DECOMP_COMPAT, 735}, + {0x0676, 0, 2 | DECOMP_COMPAT, 737}, + {0x0677, 0, 2 | DECOMP_COMPAT, 739}, + {0x0678, 0, 2 | DECOMP_COMPAT, 741}, + {0x06C0, 0, 2, 743}, + {0x06C2, 0, 2, 745}, + {0x06D3, 0, 2, 747}, + {0x06D6, 230, 0, 0}, + {0x06D7, 230, 0, 0}, + {0x06D8, 230, 0, 0}, + {0x06D9, 230, 0, 0}, + {0x06DA, 230, 0, 0}, + {0x06DB, 230, 0, 0}, + {0x06DC, 230, 0, 0}, + {0x06DF, 230, 0, 0}, + {0x06E0, 230, 0, 0}, + {0x06E1, 230, 0, 0}, + {0x06E2, 230, 0, 0}, + {0x06E3, 220, 0, 0}, + {0x06E4, 230, 0, 0}, + {0x06E7, 230, 0, 0}, + {0x06E8, 230, 0, 0}, + {0x06EA, 220, 0, 0}, + {0x06EB, 230, 0, 0}, + {0x06EC, 230, 0, 0}, + {0x06ED, 220, 0, 0}, + {0x0711, 36, 0, 0}, + {0x0730, 230, 0, 0}, + {0x0731, 220, 0, 0}, + {0x0732, 230, 0, 0}, + {0x0733, 230, 0, 0}, + {0x0734, 220, 0, 0}, + {0x0735, 230, 0, 0}, + {0x0736, 230, 0, 0}, + {0x0737, 220, 0, 0}, + {0x0738, 220, 0, 0}, + {0x0739, 220, 0, 0}, + {0x073A, 230, 0, 0}, + {0x073B, 220, 0, 0}, + {0x073C, 220, 0, 0}, + {0x073D, 230, 0, 0}, + {0x073E, 220, 0, 0}, + {0x073F, 230, 0, 0}, + {0x0740, 230, 0, 0}, + {0x0741, 230, 0, 0}, + {0x0742, 220, 0, 0}, + {0x0743, 230, 0, 0}, + {0x0744, 220, 0, 0}, + {0x0745, 230, 0, 0}, + {0x0746, 220, 0, 0}, + {0x0747, 230, 0, 0}, + {0x0748, 220, 0, 0}, + {0x0749, 230, 0, 0}, + {0x074A, 230, 0, 0}, + {0x07EB, 230, 0, 0}, + {0x07EC, 230, 0, 0}, + {0x07ED, 230, 0, 0}, + {0x07EE, 230, 0, 0}, + {0x07EF, 230, 0, 0}, + {0x07F0, 230, 0, 0}, + {0x07F1, 230, 0, 0}, + {0x07F2, 220, 0, 0}, + {0x07F3, 230, 0, 0}, + {0x07FD, 220, 0, 0}, + {0x0816, 230, 0, 0}, + {0x0817, 230, 0, 0}, + {0x0818, 230, 0, 0}, + {0x0819, 230, 0, 0}, + {0x081B, 230, 0, 0}, + {0x081C, 230, 0, 0}, + {0x081D, 230, 0, 0}, + {0x081E, 230, 0, 0}, + {0x081F, 230, 0, 0}, + {0x0820, 230, 0, 0}, + {0x0821, 230, 0, 0}, + {0x0822, 230, 0, 0}, + {0x0823, 230, 0, 0}, + {0x0825, 230, 0, 0}, + {0x0826, 230, 0, 0}, + {0x0827, 230, 0, 0}, + {0x0829, 230, 0, 0}, + {0x082A, 230, 0, 0}, + {0x082B, 230, 0, 0}, + {0x082C, 230, 0, 0}, + {0x082D, 230, 0, 0}, + {0x0859, 220, 0, 0}, + {0x085A, 220, 0, 0}, + {0x085B, 220, 0, 0}, + {0x0898, 230, 0, 0}, + {0x0899, 220, 0, 0}, + {0x089A, 220, 0, 0}, + {0x089B, 220, 0, 0}, + {0x089C, 230, 0, 0}, + {0x089D, 230, 0, 0}, + {0x089E, 230, 0, 0}, + {0x089F, 230, 0, 0}, + {0x08CA, 230, 0, 0}, + {0x08CB, 230, 0, 0}, + {0x08CC, 230, 0, 0}, + {0x08CD, 230, 0, 0}, + {0x08CE, 230, 0, 0}, + {0x08CF, 220, 0, 0}, + {0x08D0, 220, 0, 0}, + {0x08D1, 220, 0, 0}, + {0x08D2, 220, 0, 0}, + {0x08D3, 220, 0, 0}, + {0x08D4, 230, 0, 0}, + {0x08D5, 230, 0, 0}, + {0x08D6, 230, 0, 0}, + {0x08D7, 230, 0, 0}, + {0x08D8, 230, 0, 0}, + {0x08D9, 230, 0, 0}, + {0x08DA, 230, 0, 0}, + {0x08DB, 230, 0, 0}, + {0x08DC, 230, 0, 0}, + {0x08DD, 230, 0, 0}, + {0x08DE, 230, 0, 0}, + {0x08DF, 230, 0, 0}, + {0x08E0, 230, 0, 0}, + {0x08E1, 230, 0, 0}, + {0x08E3, 220, 0, 0}, + {0x08E4, 230, 0, 0}, + {0x08E5, 230, 0, 0}, + {0x08E6, 220, 0, 0}, + {0x08E7, 230, 0, 0}, + {0x08E8, 230, 0, 0}, + {0x08E9, 220, 0, 0}, + {0x08EA, 230, 0, 0}, + {0x08EB, 230, 0, 0}, + {0x08EC, 230, 0, 0}, + {0x08ED, 220, 0, 0}, + {0x08EE, 220, 0, 0}, + {0x08EF, 220, 0, 0}, + {0x08F0, 27, 0, 0}, + {0x08F1, 28, 0, 0}, + {0x08F2, 29, 0, 0}, + {0x08F3, 230, 0, 0}, + {0x08F4, 230, 0, 0}, + {0x08F5, 230, 0, 0}, + {0x08F6, 220, 0, 0}, + {0x08F7, 230, 0, 0}, + {0x08F8, 230, 0, 0}, + {0x08F9, 220, 0, 0}, + {0x08FA, 220, 0, 0}, + {0x08FB, 230, 0, 0}, + {0x08FC, 230, 0, 0}, + {0x08FD, 230, 0, 0}, + {0x08FE, 230, 0, 0}, + {0x08FF, 230, 0, 0}, + {0x0929, 0, 2, 749}, + {0x0931, 0, 2, 751}, + {0x0934, 0, 2, 753}, + {0x093C, 7, 0, 0}, + {0x094D, 9, 0, 0}, + {0x0951, 230, 0, 0}, + {0x0952, 220, 0, 0}, + {0x0953, 230, 0, 0}, + {0x0954, 230, 0, 0}, + {0x0958, 0, 2 | DECOMP_NO_COMPOSE, 755}, /* in exclusion list */ + {0x0959, 0, 2 | DECOMP_NO_COMPOSE, 757}, /* in exclusion list */ + {0x095A, 0, 2 | DECOMP_NO_COMPOSE, 759}, /* in exclusion list */ + {0x095B, 0, 2 | DECOMP_NO_COMPOSE, 761}, /* in exclusion list */ + {0x095C, 0, 2 | DECOMP_NO_COMPOSE, 763}, /* in exclusion list */ + {0x095D, 0, 2 | DECOMP_NO_COMPOSE, 765}, /* in exclusion list */ + {0x095E, 0, 2 | DECOMP_NO_COMPOSE, 767}, /* in exclusion list */ + {0x095F, 0, 2 | DECOMP_NO_COMPOSE, 769}, /* in exclusion list */ + {0x09BC, 7, 0, 0}, + {0x09CB, 0, 2, 771}, + {0x09CC, 0, 2, 773}, + {0x09CD, 9, 0, 0}, + {0x09DC, 0, 2 | DECOMP_NO_COMPOSE, 775}, /* in exclusion list */ + {0x09DD, 0, 2 | DECOMP_NO_COMPOSE, 777}, /* in exclusion list */ + {0x09DF, 0, 2 | DECOMP_NO_COMPOSE, 779}, /* in exclusion list */ + {0x09FE, 230, 0, 0}, + {0x0A33, 0, 2 | DECOMP_NO_COMPOSE, 781}, /* in exclusion list */ + {0x0A36, 0, 2 | DECOMP_NO_COMPOSE, 783}, /* in exclusion list */ + {0x0A3C, 7, 0, 0}, + {0x0A4D, 9, 0, 0}, + {0x0A59, 0, 2 | DECOMP_NO_COMPOSE, 785}, /* in exclusion list */ + {0x0A5A, 0, 2 | DECOMP_NO_COMPOSE, 787}, /* in exclusion list */ + {0x0A5B, 0, 2 | DECOMP_NO_COMPOSE, 789}, /* in exclusion list */ + {0x0A5E, 0, 2 | DECOMP_NO_COMPOSE, 791}, /* in exclusion list */ + {0x0ABC, 7, 0, 0}, + {0x0ACD, 9, 0, 0}, + {0x0B3C, 7, 0, 0}, + {0x0B48, 0, 2, 793}, + {0x0B4B, 0, 2, 795}, + {0x0B4C, 0, 2, 797}, + {0x0B4D, 9, 0, 0}, + {0x0B5C, 0, 2 | DECOMP_NO_COMPOSE, 799}, /* in exclusion list */ + {0x0B5D, 0, 2 | DECOMP_NO_COMPOSE, 801}, /* in exclusion list */ + {0x0B94, 0, 2, 803}, + {0x0BCA, 0, 2, 805}, + {0x0BCB, 0, 2, 807}, + {0x0BCC, 0, 2, 809}, + {0x0BCD, 9, 0, 0}, + {0x0C3C, 7, 0, 0}, + {0x0C48, 0, 2, 811}, + {0x0C4D, 9, 0, 0}, + {0x0C55, 84, 0, 0}, + {0x0C56, 91, 0, 0}, + {0x0CBC, 7, 0, 0}, + {0x0CC0, 0, 2, 813}, + {0x0CC7, 0, 2, 815}, + {0x0CC8, 0, 2, 817}, + {0x0CCA, 0, 2, 819}, + {0x0CCB, 0, 2, 821}, + {0x0CCD, 9, 0, 0}, + {0x0D3B, 9, 0, 0}, + {0x0D3C, 9, 0, 0}, + {0x0D4A, 0, 2, 823}, + {0x0D4B, 0, 2, 825}, + {0x0D4C, 0, 2, 827}, + {0x0D4D, 9, 0, 0}, + {0x0DCA, 9, 0, 0}, + {0x0DDA, 0, 2, 829}, + {0x0DDC, 0, 2, 831}, + {0x0DDD, 0, 2, 833}, + {0x0DDE, 0, 2, 835}, + {0x0E33, 0, 2 | DECOMP_COMPAT, 837}, + {0x0E38, 103, 0, 0}, + {0x0E39, 103, 0, 0}, + {0x0E3A, 9, 0, 0}, + {0x0E48, 107, 0, 0}, + {0x0E49, 107, 0, 0}, + {0x0E4A, 107, 0, 0}, + {0x0E4B, 107, 0, 0}, + {0x0EB3, 0, 2 | DECOMP_COMPAT, 839}, + {0x0EB8, 118, 0, 0}, + {0x0EB9, 118, 0, 0}, + {0x0EBA, 9, 0, 0}, + {0x0EC8, 122, 0, 0}, + {0x0EC9, 122, 0, 0}, + {0x0ECA, 122, 0, 0}, + {0x0ECB, 122, 0, 0}, + {0x0EDC, 0, 2 | DECOMP_COMPAT, 841}, + {0x0EDD, 0, 2 | DECOMP_COMPAT, 843}, + {0x0F0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0F0B}, + {0x0F18, 220, 0, 0}, + {0x0F19, 220, 0, 0}, + {0x0F35, 220, 0, 0}, + {0x0F37, 220, 0, 0}, + {0x0F39, 216, 0, 0}, + {0x0F43, 0, 2 | DECOMP_NO_COMPOSE, 845}, /* in exclusion list */ + {0x0F4D, 0, 2 | DECOMP_NO_COMPOSE, 847}, /* in exclusion list */ + {0x0F52, 0, 2 | DECOMP_NO_COMPOSE, 849}, /* in exclusion list */ + {0x0F57, 0, 2 | DECOMP_NO_COMPOSE, 851}, /* in exclusion list */ + {0x0F5C, 0, 2 | DECOMP_NO_COMPOSE, 853}, /* in exclusion list */ + {0x0F69, 0, 2 | DECOMP_NO_COMPOSE, 855}, /* in exclusion list */ + {0x0F71, 129, 0, 0}, + {0x0F72, 130, 0, 0}, + {0x0F73, 0, 2 | DECOMP_NO_COMPOSE, 857}, /* non-starter decomposition */ + {0x0F74, 132, 0, 0}, + {0x0F75, 0, 2 | DECOMP_NO_COMPOSE, 859}, /* non-starter decomposition */ + {0x0F76, 0, 2 | DECOMP_NO_COMPOSE, 861}, /* in exclusion list */ + {0x0F77, 0, 2 | DECOMP_COMPAT, 863}, + {0x0F78, 0, 2 | DECOMP_NO_COMPOSE, 865}, /* in exclusion list */ + {0x0F79, 0, 2 | DECOMP_COMPAT, 867}, + {0x0F7A, 130, 0, 0}, + {0x0F7B, 130, 0, 0}, + {0x0F7C, 130, 0, 0}, + {0x0F7D, 130, 0, 0}, + {0x0F80, 130, 0, 0}, + {0x0F81, 0, 2 | DECOMP_NO_COMPOSE, 869}, /* non-starter decomposition */ + {0x0F82, 230, 0, 0}, + {0x0F83, 230, 0, 0}, + {0x0F84, 9, 0, 0}, + {0x0F86, 230, 0, 0}, + {0x0F87, 230, 0, 0}, + {0x0F93, 0, 2 | DECOMP_NO_COMPOSE, 871}, /* in exclusion list */ + {0x0F9D, 0, 2 | DECOMP_NO_COMPOSE, 873}, /* in exclusion list */ + {0x0FA2, 0, 2 | DECOMP_NO_COMPOSE, 875}, /* in exclusion list */ + {0x0FA7, 0, 2 | DECOMP_NO_COMPOSE, 877}, /* in exclusion list */ + {0x0FAC, 0, 2 | DECOMP_NO_COMPOSE, 879}, /* in exclusion list */ + {0x0FB9, 0, 2 | DECOMP_NO_COMPOSE, 881}, /* in exclusion list */ + {0x0FC6, 220, 0, 0}, + {0x1026, 0, 2, 883}, + {0x1037, 7, 0, 0}, + {0x1039, 9, 0, 0}, + {0x103A, 9, 0, 0}, + {0x108D, 220, 0, 0}, + {0x10FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x10DC}, + {0x135D, 230, 0, 0}, + {0x135E, 230, 0, 0}, + {0x135F, 230, 0, 0}, + {0x1714, 9, 0, 0}, + {0x1715, 9, 0, 0}, + {0x1734, 9, 0, 0}, + {0x17D2, 9, 0, 0}, + {0x17DD, 230, 0, 0}, + {0x18A9, 228, 0, 0}, + {0x1939, 222, 0, 0}, + {0x193A, 230, 0, 0}, + {0x193B, 220, 0, 0}, + {0x1A17, 230, 0, 0}, + {0x1A18, 220, 0, 0}, + {0x1A60, 9, 0, 0}, + {0x1A75, 230, 0, 0}, + {0x1A76, 230, 0, 0}, + {0x1A77, 230, 0, 0}, + {0x1A78, 230, 0, 0}, + {0x1A79, 230, 0, 0}, + {0x1A7A, 230, 0, 0}, + {0x1A7B, 230, 0, 0}, + {0x1A7C, 230, 0, 0}, + {0x1A7F, 220, 0, 0}, + {0x1AB0, 230, 0, 0}, + {0x1AB1, 230, 0, 0}, + {0x1AB2, 230, 0, 0}, + {0x1AB3, 230, 0, 0}, + {0x1AB4, 230, 0, 0}, + {0x1AB5, 220, 0, 0}, + {0x1AB6, 220, 0, 0}, + {0x1AB7, 220, 0, 0}, + {0x1AB8, 220, 0, 0}, + {0x1AB9, 220, 0, 0}, + {0x1ABA, 220, 0, 0}, + {0x1ABB, 230, 0, 0}, + {0x1ABC, 230, 0, 0}, + {0x1ABD, 220, 0, 0}, + {0x1ABF, 220, 0, 0}, + {0x1AC0, 220, 0, 0}, + {0x1AC1, 230, 0, 0}, + {0x1AC2, 230, 0, 0}, + {0x1AC3, 220, 0, 0}, + {0x1AC4, 220, 0, 0}, + {0x1AC5, 230, 0, 0}, + {0x1AC6, 230, 0, 0}, + {0x1AC7, 230, 0, 0}, + {0x1AC8, 230, 0, 0}, + {0x1AC9, 230, 0, 0}, + {0x1ACA, 220, 0, 0}, + {0x1ACB, 230, 0, 0}, + {0x1ACC, 230, 0, 0}, + {0x1ACD, 230, 0, 0}, + {0x1ACE, 230, 0, 0}, + {0x1B06, 0, 2, 885}, + {0x1B08, 0, 2, 887}, + {0x1B0A, 0, 2, 889}, + {0x1B0C, 0, 2, 891}, + {0x1B0E, 0, 2, 893}, + {0x1B12, 0, 2, 895}, + {0x1B34, 7, 0, 0}, + {0x1B3B, 0, 2, 897}, + {0x1B3D, 0, 2, 899}, + {0x1B40, 0, 2, 901}, + {0x1B41, 0, 2, 903}, + {0x1B43, 0, 2, 905}, + {0x1B44, 9, 0, 0}, + {0x1B6B, 230, 0, 0}, + {0x1B6C, 220, 0, 0}, + {0x1B6D, 230, 0, 0}, + {0x1B6E, 230, 0, 0}, + {0x1B6F, 230, 0, 0}, + {0x1B70, 230, 0, 0}, + {0x1B71, 230, 0, 0}, + {0x1B72, 230, 0, 0}, + {0x1B73, 230, 0, 0}, + {0x1BAA, 9, 0, 0}, + {0x1BAB, 9, 0, 0}, + {0x1BE6, 7, 0, 0}, + {0x1BF2, 9, 0, 0}, + {0x1BF3, 9, 0, 0}, + {0x1C37, 7, 0, 0}, + {0x1CD0, 230, 0, 0}, + {0x1CD1, 230, 0, 0}, + {0x1CD2, 230, 0, 0}, + {0x1CD4, 1, 0, 0}, + {0x1CD5, 220, 0, 0}, + {0x1CD6, 220, 0, 0}, + {0x1CD7, 220, 0, 0}, + {0x1CD8, 220, 0, 0}, + {0x1CD9, 220, 0, 0}, + {0x1CDA, 230, 0, 0}, + {0x1CDB, 230, 0, 0}, + {0x1CDC, 220, 0, 0}, + {0x1CDD, 220, 0, 0}, + {0x1CDE, 220, 0, 0}, + {0x1CDF, 220, 0, 0}, + {0x1CE0, 230, 0, 0}, + {0x1CE2, 1, 0, 0}, + {0x1CE3, 1, 0, 0}, + {0x1CE4, 1, 0, 0}, + {0x1CE5, 1, 0, 0}, + {0x1CE6, 1, 0, 0}, + {0x1CE7, 1, 0, 0}, + {0x1CE8, 1, 0, 0}, + {0x1CED, 220, 0, 0}, + {0x1CF4, 230, 0, 0}, + {0x1CF8, 230, 0, 0}, + {0x1CF9, 230, 0, 0}, + {0x1D2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00C6}, + {0x1D2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x018E}, + {0x1D33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0222}, + {0x1D3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0250}, + {0x1D45, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0251}, + {0x1D46, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D02}, + {0x1D47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0259}, + {0x1D4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025B}, + {0x1D4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025C}, + {0x1D4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x014B}, + {0x1D52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0254}, + {0x1D54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D16}, + {0x1D55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D17}, + {0x1D56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D1D}, + {0x1D5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026F}, + {0x1D5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D25}, + {0x1D5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x1D5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x1D5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, + {0x1D60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x1D61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, + {0x1D62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x1D67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x1D68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, + {0x1D69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x1D6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, + {0x1D78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043D}, + {0x1D9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0252}, + {0x1D9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0255}, + {0x1D9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00F0}, + {0x1D9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025C}, + {0x1DA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1DA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025F}, + {0x1DA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0261}, + {0x1DA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0265}, + {0x1DA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0268}, + {0x1DA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0269}, + {0x1DA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026A}, + {0x1DA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D7B}, + {0x1DA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029D}, + {0x1DA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026D}, + {0x1DAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D85}, + {0x1DAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029F}, + {0x1DAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0271}, + {0x1DAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0270}, + {0x1DAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0272}, + {0x1DAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0273}, + {0x1DB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0274}, + {0x1DB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0275}, + {0x1DB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0278}, + {0x1DB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0282}, + {0x1DB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0283}, + {0x1DB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01AB}, + {0x1DB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0289}, + {0x1DB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028A}, + {0x1DB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D1C}, + {0x1DB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028B}, + {0x1DBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028C}, + {0x1DBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1DBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0290}, + {0x1DBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0291}, + {0x1DBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0292}, + {0x1DBF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, + {0x1DC0, 230, 0, 0}, + {0x1DC1, 230, 0, 0}, + {0x1DC2, 220, 0, 0}, + {0x1DC3, 230, 0, 0}, + {0x1DC4, 230, 0, 0}, + {0x1DC5, 230, 0, 0}, + {0x1DC6, 230, 0, 0}, + {0x1DC7, 230, 0, 0}, + {0x1DC8, 230, 0, 0}, + {0x1DC9, 230, 0, 0}, + {0x1DCA, 220, 0, 0}, + {0x1DCB, 230, 0, 0}, + {0x1DCC, 230, 0, 0}, + {0x1DCD, 234, 0, 0}, + {0x1DCE, 214, 0, 0}, + {0x1DCF, 220, 0, 0}, + {0x1DD0, 202, 0, 0}, + {0x1DD1, 230, 0, 0}, + {0x1DD2, 230, 0, 0}, + {0x1DD3, 230, 0, 0}, + {0x1DD4, 230, 0, 0}, + {0x1DD5, 230, 0, 0}, + {0x1DD6, 230, 0, 0}, + {0x1DD7, 230, 0, 0}, + {0x1DD8, 230, 0, 0}, + {0x1DD9, 230, 0, 0}, + {0x1DDA, 230, 0, 0}, + {0x1DDB, 230, 0, 0}, + {0x1DDC, 230, 0, 0}, + {0x1DDD, 230, 0, 0}, + {0x1DDE, 230, 0, 0}, + {0x1DDF, 230, 0, 0}, + {0x1DE0, 230, 0, 0}, + {0x1DE1, 230, 0, 0}, + {0x1DE2, 230, 0, 0}, + {0x1DE3, 230, 0, 0}, + {0x1DE4, 230, 0, 0}, + {0x1DE5, 230, 0, 0}, + {0x1DE6, 230, 0, 0}, + {0x1DE7, 230, 0, 0}, + {0x1DE8, 230, 0, 0}, + {0x1DE9, 230, 0, 0}, + {0x1DEA, 230, 0, 0}, + {0x1DEB, 230, 0, 0}, + {0x1DEC, 230, 0, 0}, + {0x1DED, 230, 0, 0}, + {0x1DEE, 230, 0, 0}, + {0x1DEF, 230, 0, 0}, + {0x1DF0, 230, 0, 0}, + {0x1DF1, 230, 0, 0}, + {0x1DF2, 230, 0, 0}, + {0x1DF3, 230, 0, 0}, + {0x1DF4, 230, 0, 0}, + {0x1DF5, 230, 0, 0}, + {0x1DF6, 232, 0, 0}, + {0x1DF7, 228, 0, 0}, + {0x1DF8, 228, 0, 0}, + {0x1DF9, 220, 0, 0}, + {0x1DFA, 218, 0, 0}, + {0x1DFB, 230, 0, 0}, + {0x1DFC, 233, 0, 0}, + {0x1DFD, 220, 0, 0}, + {0x1DFE, 230, 0, 0}, + {0x1DFF, 220, 0, 0}, + {0x1E00, 0, 2, 907}, + {0x1E01, 0, 2, 909}, + {0x1E02, 0, 2, 911}, + {0x1E03, 0, 2, 913}, + {0x1E04, 0, 2, 915}, + {0x1E05, 0, 2, 917}, + {0x1E06, 0, 2, 919}, + {0x1E07, 0, 2, 921}, + {0x1E08, 0, 2, 923}, + {0x1E09, 0, 2, 925}, + {0x1E0A, 0, 2, 927}, + {0x1E0B, 0, 2, 929}, + {0x1E0C, 0, 2, 931}, + {0x1E0D, 0, 2, 933}, + {0x1E0E, 0, 2, 935}, + {0x1E0F, 0, 2, 937}, + {0x1E10, 0, 2, 939}, + {0x1E11, 0, 2, 941}, + {0x1E12, 0, 2, 943}, + {0x1E13, 0, 2, 945}, + {0x1E14, 0, 2, 947}, + {0x1E15, 0, 2, 949}, + {0x1E16, 0, 2, 951}, + {0x1E17, 0, 2, 953}, + {0x1E18, 0, 2, 955}, + {0x1E19, 0, 2, 957}, + {0x1E1A, 0, 2, 959}, + {0x1E1B, 0, 2, 961}, + {0x1E1C, 0, 2, 963}, + {0x1E1D, 0, 2, 965}, + {0x1E1E, 0, 2, 967}, + {0x1E1F, 0, 2, 969}, + {0x1E20, 0, 2, 971}, + {0x1E21, 0, 2, 973}, + {0x1E22, 0, 2, 975}, + {0x1E23, 0, 2, 977}, + {0x1E24, 0, 2, 979}, + {0x1E25, 0, 2, 981}, + {0x1E26, 0, 2, 983}, + {0x1E27, 0, 2, 985}, + {0x1E28, 0, 2, 987}, + {0x1E29, 0, 2, 989}, + {0x1E2A, 0, 2, 991}, + {0x1E2B, 0, 2, 993}, + {0x1E2C, 0, 2, 995}, + {0x1E2D, 0, 2, 997}, + {0x1E2E, 0, 2, 999}, + {0x1E2F, 0, 2, 1001}, + {0x1E30, 0, 2, 1003}, + {0x1E31, 0, 2, 1005}, + {0x1E32, 0, 2, 1007}, + {0x1E33, 0, 2, 1009}, + {0x1E34, 0, 2, 1011}, + {0x1E35, 0, 2, 1013}, + {0x1E36, 0, 2, 1015}, + {0x1E37, 0, 2, 1017}, + {0x1E38, 0, 2, 1019}, + {0x1E39, 0, 2, 1021}, + {0x1E3A, 0, 2, 1023}, + {0x1E3B, 0, 2, 1025}, + {0x1E3C, 0, 2, 1027}, + {0x1E3D, 0, 2, 1029}, + {0x1E3E, 0, 2, 1031}, + {0x1E3F, 0, 2, 1033}, + {0x1E40, 0, 2, 1035}, + {0x1E41, 0, 2, 1037}, + {0x1E42, 0, 2, 1039}, + {0x1E43, 0, 2, 1041}, + {0x1E44, 0, 2, 1043}, + {0x1E45, 0, 2, 1045}, + {0x1E46, 0, 2, 1047}, + {0x1E47, 0, 2, 1049}, + {0x1E48, 0, 2, 1051}, + {0x1E49, 0, 2, 1053}, + {0x1E4A, 0, 2, 1055}, + {0x1E4B, 0, 2, 1057}, + {0x1E4C, 0, 2, 1059}, + {0x1E4D, 0, 2, 1061}, + {0x1E4E, 0, 2, 1063}, + {0x1E4F, 0, 2, 1065}, + {0x1E50, 0, 2, 1067}, + {0x1E51, 0, 2, 1069}, + {0x1E52, 0, 2, 1071}, + {0x1E53, 0, 2, 1073}, + {0x1E54, 0, 2, 1075}, + {0x1E55, 0, 2, 1077}, + {0x1E56, 0, 2, 1079}, + {0x1E57, 0, 2, 1081}, + {0x1E58, 0, 2, 1083}, + {0x1E59, 0, 2, 1085}, + {0x1E5A, 0, 2, 1087}, + {0x1E5B, 0, 2, 1089}, + {0x1E5C, 0, 2, 1091}, + {0x1E5D, 0, 2, 1093}, + {0x1E5E, 0, 2, 1095}, + {0x1E5F, 0, 2, 1097}, + {0x1E60, 0, 2, 1099}, + {0x1E61, 0, 2, 1101}, + {0x1E62, 0, 2, 1103}, + {0x1E63, 0, 2, 1105}, + {0x1E64, 0, 2, 1107}, + {0x1E65, 0, 2, 1109}, + {0x1E66, 0, 2, 1111}, + {0x1E67, 0, 2, 1113}, + {0x1E68, 0, 2, 1115}, + {0x1E69, 0, 2, 1117}, + {0x1E6A, 0, 2, 1119}, + {0x1E6B, 0, 2, 1121}, + {0x1E6C, 0, 2, 1123}, + {0x1E6D, 0, 2, 1125}, + {0x1E6E, 0, 2, 1127}, + {0x1E6F, 0, 2, 1129}, + {0x1E70, 0, 2, 1131}, + {0x1E71, 0, 2, 1133}, + {0x1E72, 0, 2, 1135}, + {0x1E73, 0, 2, 1137}, + {0x1E74, 0, 2, 1139}, + {0x1E75, 0, 2, 1141}, + {0x1E76, 0, 2, 1143}, + {0x1E77, 0, 2, 1145}, + {0x1E78, 0, 2, 1147}, + {0x1E79, 0, 2, 1149}, + {0x1E7A, 0, 2, 1151}, + {0x1E7B, 0, 2, 1153}, + {0x1E7C, 0, 2, 1155}, + {0x1E7D, 0, 2, 1157}, + {0x1E7E, 0, 2, 1159}, + {0x1E7F, 0, 2, 1161}, + {0x1E80, 0, 2, 1163}, + {0x1E81, 0, 2, 1165}, + {0x1E82, 0, 2, 1167}, + {0x1E83, 0, 2, 1169}, + {0x1E84, 0, 2, 1171}, + {0x1E85, 0, 2, 1173}, + {0x1E86, 0, 2, 1175}, + {0x1E87, 0, 2, 1177}, + {0x1E88, 0, 2, 1179}, + {0x1E89, 0, 2, 1181}, + {0x1E8A, 0, 2, 1183}, + {0x1E8B, 0, 2, 1185}, + {0x1E8C, 0, 2, 1187}, + {0x1E8D, 0, 2, 1189}, + {0x1E8E, 0, 2, 1191}, + {0x1E8F, 0, 2, 1193}, + {0x1E90, 0, 2, 1195}, + {0x1E91, 0, 2, 1197}, + {0x1E92, 0, 2, 1199}, + {0x1E93, 0, 2, 1201}, + {0x1E94, 0, 2, 1203}, + {0x1E95, 0, 2, 1205}, + {0x1E96, 0, 2, 1207}, + {0x1E97, 0, 2, 1209}, + {0x1E98, 0, 2, 1211}, + {0x1E99, 0, 2, 1213}, + {0x1E9A, 0, 2 | DECOMP_COMPAT, 1215}, + {0x1E9B, 0, 2, 1217}, + {0x1EA0, 0, 2, 1219}, + {0x1EA1, 0, 2, 1221}, + {0x1EA2, 0, 2, 1223}, + {0x1EA3, 0, 2, 1225}, + {0x1EA4, 0, 2, 1227}, + {0x1EA5, 0, 2, 1229}, + {0x1EA6, 0, 2, 1231}, + {0x1EA7, 0, 2, 1233}, + {0x1EA8, 0, 2, 1235}, + {0x1EA9, 0, 2, 1237}, + {0x1EAA, 0, 2, 1239}, + {0x1EAB, 0, 2, 1241}, + {0x1EAC, 0, 2, 1243}, + {0x1EAD, 0, 2, 1245}, + {0x1EAE, 0, 2, 1247}, + {0x1EAF, 0, 2, 1249}, + {0x1EB0, 0, 2, 1251}, + {0x1EB1, 0, 2, 1253}, + {0x1EB2, 0, 2, 1255}, + {0x1EB3, 0, 2, 1257}, + {0x1EB4, 0, 2, 1259}, + {0x1EB5, 0, 2, 1261}, + {0x1EB6, 0, 2, 1263}, + {0x1EB7, 0, 2, 1265}, + {0x1EB8, 0, 2, 1267}, + {0x1EB9, 0, 2, 1269}, + {0x1EBA, 0, 2, 1271}, + {0x1EBB, 0, 2, 1273}, + {0x1EBC, 0, 2, 1275}, + {0x1EBD, 0, 2, 1277}, + {0x1EBE, 0, 2, 1279}, + {0x1EBF, 0, 2, 1281}, + {0x1EC0, 0, 2, 1283}, + {0x1EC1, 0, 2, 1285}, + {0x1EC2, 0, 2, 1287}, + {0x1EC3, 0, 2, 1289}, + {0x1EC4, 0, 2, 1291}, + {0x1EC5, 0, 2, 1293}, + {0x1EC6, 0, 2, 1295}, + {0x1EC7, 0, 2, 1297}, + {0x1EC8, 0, 2, 1299}, + {0x1EC9, 0, 2, 1301}, + {0x1ECA, 0, 2, 1303}, + {0x1ECB, 0, 2, 1305}, + {0x1ECC, 0, 2, 1307}, + {0x1ECD, 0, 2, 1309}, + {0x1ECE, 0, 2, 1311}, + {0x1ECF, 0, 2, 1313}, + {0x1ED0, 0, 2, 1315}, + {0x1ED1, 0, 2, 1317}, + {0x1ED2, 0, 2, 1319}, + {0x1ED3, 0, 2, 1321}, + {0x1ED4, 0, 2, 1323}, + {0x1ED5, 0, 2, 1325}, + {0x1ED6, 0, 2, 1327}, + {0x1ED7, 0, 2, 1329}, + {0x1ED8, 0, 2, 1331}, + {0x1ED9, 0, 2, 1333}, + {0x1EDA, 0, 2, 1335}, + {0x1EDB, 0, 2, 1337}, + {0x1EDC, 0, 2, 1339}, + {0x1EDD, 0, 2, 1341}, + {0x1EDE, 0, 2, 1343}, + {0x1EDF, 0, 2, 1345}, + {0x1EE0, 0, 2, 1347}, + {0x1EE1, 0, 2, 1349}, + {0x1EE2, 0, 2, 1351}, + {0x1EE3, 0, 2, 1353}, + {0x1EE4, 0, 2, 1355}, + {0x1EE5, 0, 2, 1357}, + {0x1EE6, 0, 2, 1359}, + {0x1EE7, 0, 2, 1361}, + {0x1EE8, 0, 2, 1363}, + {0x1EE9, 0, 2, 1365}, + {0x1EEA, 0, 2, 1367}, + {0x1EEB, 0, 2, 1369}, + {0x1EEC, 0, 2, 1371}, + {0x1EED, 0, 2, 1373}, + {0x1EEE, 0, 2, 1375}, + {0x1EEF, 0, 2, 1377}, + {0x1EF0, 0, 2, 1379}, + {0x1EF1, 0, 2, 1381}, + {0x1EF2, 0, 2, 1383}, + {0x1EF3, 0, 2, 1385}, + {0x1EF4, 0, 2, 1387}, + {0x1EF5, 0, 2, 1389}, + {0x1EF6, 0, 2, 1391}, + {0x1EF7, 0, 2, 1393}, + {0x1EF8, 0, 2, 1395}, + {0x1EF9, 0, 2, 1397}, + {0x1F00, 0, 2, 1399}, + {0x1F01, 0, 2, 1401}, + {0x1F02, 0, 2, 1403}, + {0x1F03, 0, 2, 1405}, + {0x1F04, 0, 2, 1407}, + {0x1F05, 0, 2, 1409}, + {0x1F06, 0, 2, 1411}, + {0x1F07, 0, 2, 1413}, + {0x1F08, 0, 2, 1415}, + {0x1F09, 0, 2, 1417}, + {0x1F0A, 0, 2, 1419}, + {0x1F0B, 0, 2, 1421}, + {0x1F0C, 0, 2, 1423}, + {0x1F0D, 0, 2, 1425}, + {0x1F0E, 0, 2, 1427}, + {0x1F0F, 0, 2, 1429}, + {0x1F10, 0, 2, 1431}, + {0x1F11, 0, 2, 1433}, + {0x1F12, 0, 2, 1435}, + {0x1F13, 0, 2, 1437}, + {0x1F14, 0, 2, 1439}, + {0x1F15, 0, 2, 1441}, + {0x1F18, 0, 2, 1443}, + {0x1F19, 0, 2, 1445}, + {0x1F1A, 0, 2, 1447}, + {0x1F1B, 0, 2, 1449}, + {0x1F1C, 0, 2, 1451}, + {0x1F1D, 0, 2, 1453}, + {0x1F20, 0, 2, 1455}, + {0x1F21, 0, 2, 1457}, + {0x1F22, 0, 2, 1459}, + {0x1F23, 0, 2, 1461}, + {0x1F24, 0, 2, 1463}, + {0x1F25, 0, 2, 1465}, + {0x1F26, 0, 2, 1467}, + {0x1F27, 0, 2, 1469}, + {0x1F28, 0, 2, 1471}, + {0x1F29, 0, 2, 1473}, + {0x1F2A, 0, 2, 1475}, + {0x1F2B, 0, 2, 1477}, + {0x1F2C, 0, 2, 1479}, + {0x1F2D, 0, 2, 1481}, + {0x1F2E, 0, 2, 1483}, + {0x1F2F, 0, 2, 1485}, + {0x1F30, 0, 2, 1487}, + {0x1F31, 0, 2, 1489}, + {0x1F32, 0, 2, 1491}, + {0x1F33, 0, 2, 1493}, + {0x1F34, 0, 2, 1495}, + {0x1F35, 0, 2, 1497}, + {0x1F36, 0, 2, 1499}, + {0x1F37, 0, 2, 1501}, + {0x1F38, 0, 2, 1503}, + {0x1F39, 0, 2, 1505}, + {0x1F3A, 0, 2, 1507}, + {0x1F3B, 0, 2, 1509}, + {0x1F3C, 0, 2, 1511}, + {0x1F3D, 0, 2, 1513}, + {0x1F3E, 0, 2, 1515}, + {0x1F3F, 0, 2, 1517}, + {0x1F40, 0, 2, 1519}, + {0x1F41, 0, 2, 1521}, + {0x1F42, 0, 2, 1523}, + {0x1F43, 0, 2, 1525}, + {0x1F44, 0, 2, 1527}, + {0x1F45, 0, 2, 1529}, + {0x1F48, 0, 2, 1531}, + {0x1F49, 0, 2, 1533}, + {0x1F4A, 0, 2, 1535}, + {0x1F4B, 0, 2, 1537}, + {0x1F4C, 0, 2, 1539}, + {0x1F4D, 0, 2, 1541}, + {0x1F50, 0, 2, 1543}, + {0x1F51, 0, 2, 1545}, + {0x1F52, 0, 2, 1547}, + {0x1F53, 0, 2, 1549}, + {0x1F54, 0, 2, 1551}, + {0x1F55, 0, 2, 1553}, + {0x1F56, 0, 2, 1555}, + {0x1F57, 0, 2, 1557}, + {0x1F59, 0, 2, 1559}, + {0x1F5B, 0, 2, 1561}, + {0x1F5D, 0, 2, 1563}, + {0x1F5F, 0, 2, 1565}, + {0x1F60, 0, 2, 1567}, + {0x1F61, 0, 2, 1569}, + {0x1F62, 0, 2, 1571}, + {0x1F63, 0, 2, 1573}, + {0x1F64, 0, 2, 1575}, + {0x1F65, 0, 2, 1577}, + {0x1F66, 0, 2, 1579}, + {0x1F67, 0, 2, 1581}, + {0x1F68, 0, 2, 1583}, + {0x1F69, 0, 2, 1585}, + {0x1F6A, 0, 2, 1587}, + {0x1F6B, 0, 2, 1589}, + {0x1F6C, 0, 2, 1591}, + {0x1F6D, 0, 2, 1593}, + {0x1F6E, 0, 2, 1595}, + {0x1F6F, 0, 2, 1597}, + {0x1F70, 0, 2, 1599}, + {0x1F71, 0, 1 | DECOMP_INLINE, 0x03AC}, + {0x1F72, 0, 2, 1601}, + {0x1F73, 0, 1 | DECOMP_INLINE, 0x03AD}, + {0x1F74, 0, 2, 1603}, + {0x1F75, 0, 1 | DECOMP_INLINE, 0x03AE}, + {0x1F76, 0, 2, 1605}, + {0x1F77, 0, 1 | DECOMP_INLINE, 0x03AF}, + {0x1F78, 0, 2, 1607}, + {0x1F79, 0, 1 | DECOMP_INLINE, 0x03CC}, + {0x1F7A, 0, 2, 1609}, + {0x1F7B, 0, 1 | DECOMP_INLINE, 0x03CD}, + {0x1F7C, 0, 2, 1611}, + {0x1F7D, 0, 1 | DECOMP_INLINE, 0x03CE}, + {0x1F80, 0, 2, 1613}, + {0x1F81, 0, 2, 1615}, + {0x1F82, 0, 2, 1617}, + {0x1F83, 0, 2, 1619}, + {0x1F84, 0, 2, 1621}, + {0x1F85, 0, 2, 1623}, + {0x1F86, 0, 2, 1625}, + {0x1F87, 0, 2, 1627}, + {0x1F88, 0, 2, 1629}, + {0x1F89, 0, 2, 1631}, + {0x1F8A, 0, 2, 1633}, + {0x1F8B, 0, 2, 1635}, + {0x1F8C, 0, 2, 1637}, + {0x1F8D, 0, 2, 1639}, + {0x1F8E, 0, 2, 1641}, + {0x1F8F, 0, 2, 1643}, + {0x1F90, 0, 2, 1645}, + {0x1F91, 0, 2, 1647}, + {0x1F92, 0, 2, 1649}, + {0x1F93, 0, 2, 1651}, + {0x1F94, 0, 2, 1653}, + {0x1F95, 0, 2, 1655}, + {0x1F96, 0, 2, 1657}, + {0x1F97, 0, 2, 1659}, + {0x1F98, 0, 2, 1661}, + {0x1F99, 0, 2, 1663}, + {0x1F9A, 0, 2, 1665}, + {0x1F9B, 0, 2, 1667}, + {0x1F9C, 0, 2, 1669}, + {0x1F9D, 0, 2, 1671}, + {0x1F9E, 0, 2, 1673}, + {0x1F9F, 0, 2, 1675}, + {0x1FA0, 0, 2, 1677}, + {0x1FA1, 0, 2, 1679}, + {0x1FA2, 0, 2, 1681}, + {0x1FA3, 0, 2, 1683}, + {0x1FA4, 0, 2, 1685}, + {0x1FA5, 0, 2, 1687}, + {0x1FA6, 0, 2, 1689}, + {0x1FA7, 0, 2, 1691}, + {0x1FA8, 0, 2, 1693}, + {0x1FA9, 0, 2, 1695}, + {0x1FAA, 0, 2, 1697}, + {0x1FAB, 0, 2, 1699}, + {0x1FAC, 0, 2, 1701}, + {0x1FAD, 0, 2, 1703}, + {0x1FAE, 0, 2, 1705}, + {0x1FAF, 0, 2, 1707}, + {0x1FB0, 0, 2, 1709}, + {0x1FB1, 0, 2, 1711}, + {0x1FB2, 0, 2, 1713}, + {0x1FB3, 0, 2, 1715}, + {0x1FB4, 0, 2, 1717}, + {0x1FB6, 0, 2, 1719}, + {0x1FB7, 0, 2, 1721}, + {0x1FB8, 0, 2, 1723}, + {0x1FB9, 0, 2, 1725}, + {0x1FBA, 0, 2, 1727}, + {0x1FBB, 0, 1 | DECOMP_INLINE, 0x0386}, + {0x1FBC, 0, 2, 1729}, + {0x1FBD, 0, 2 | DECOMP_COMPAT, 1731}, + {0x1FBE, 0, 1 | DECOMP_INLINE, 0x03B9}, + {0x1FBF, 0, 2 | DECOMP_COMPAT, 1733}, + {0x1FC0, 0, 2 | DECOMP_COMPAT, 1735}, + {0x1FC1, 0, 2, 1737}, + {0x1FC2, 0, 2, 1739}, + {0x1FC3, 0, 2, 1741}, + {0x1FC4, 0, 2, 1743}, + {0x1FC6, 0, 2, 1745}, + {0x1FC7, 0, 2, 1747}, + {0x1FC8, 0, 2, 1749}, + {0x1FC9, 0, 1 | DECOMP_INLINE, 0x0388}, + {0x1FCA, 0, 2, 1751}, + {0x1FCB, 0, 1 | DECOMP_INLINE, 0x0389}, + {0x1FCC, 0, 2, 1753}, + {0x1FCD, 0, 2, 1755}, + {0x1FCE, 0, 2, 1757}, + {0x1FCF, 0, 2, 1759}, + {0x1FD0, 0, 2, 1761}, + {0x1FD1, 0, 2, 1763}, + {0x1FD2, 0, 2, 1765}, + {0x1FD3, 0, 1 | DECOMP_INLINE, 0x0390}, + {0x1FD6, 0, 2, 1767}, + {0x1FD7, 0, 2, 1769}, + {0x1FD8, 0, 2, 1771}, + {0x1FD9, 0, 2, 1773}, + {0x1FDA, 0, 2, 1775}, + {0x1FDB, 0, 1 | DECOMP_INLINE, 0x038A}, + {0x1FDD, 0, 2, 1777}, + {0x1FDE, 0, 2, 1779}, + {0x1FDF, 0, 2, 1781}, + {0x1FE0, 0, 2, 1783}, + {0x1FE1, 0, 2, 1785}, + {0x1FE2, 0, 2, 1787}, + {0x1FE3, 0, 1 | DECOMP_INLINE, 0x03B0}, + {0x1FE4, 0, 2, 1789}, + {0x1FE5, 0, 2, 1791}, + {0x1FE6, 0, 2, 1793}, + {0x1FE7, 0, 2, 1795}, + {0x1FE8, 0, 2, 1797}, + {0x1FE9, 0, 2, 1799}, + {0x1FEA, 0, 2, 1801}, + {0x1FEB, 0, 1 | DECOMP_INLINE, 0x038E}, + {0x1FEC, 0, 2, 1803}, + {0x1FED, 0, 2, 1805}, + {0x1FEE, 0, 1 | DECOMP_INLINE, 0x0385}, + {0x1FEF, 0, 1 | DECOMP_INLINE, 0x0060}, + {0x1FF2, 0, 2, 1807}, + {0x1FF3, 0, 2, 1809}, + {0x1FF4, 0, 2, 1811}, + {0x1FF6, 0, 2, 1813}, + {0x1FF7, 0, 2, 1815}, + {0x1FF8, 0, 2, 1817}, + {0x1FF9, 0, 1 | DECOMP_INLINE, 0x038C}, + {0x1FFA, 0, 2, 1819}, + {0x1FFB, 0, 1 | DECOMP_INLINE, 0x038F}, + {0x1FFC, 0, 2, 1821}, + {0x1FFD, 0, 1 | DECOMP_INLINE, 0x00B4}, + {0x1FFE, 0, 2 | DECOMP_COMPAT, 1823}, + {0x2000, 0, 1 | DECOMP_INLINE, 0x2002}, + {0x2001, 0, 1 | DECOMP_INLINE, 0x2003}, + {0x2002, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2003, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2004, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2005, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2006, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2007, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2008, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2009, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x200A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2011, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2010}, + {0x2017, 0, 2 | DECOMP_COMPAT, 1825}, + {0x2024, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002E}, + {0x2025, 0, 2 | DECOMP_COMPAT, 1827}, + {0x2026, 0, 3 | DECOMP_COMPAT, 1829}, + {0x202F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2033, 0, 2 | DECOMP_COMPAT, 1832}, + {0x2034, 0, 3 | DECOMP_COMPAT, 1834}, + {0x2036, 0, 2 | DECOMP_COMPAT, 1837}, + {0x2037, 0, 3 | DECOMP_COMPAT, 1839}, + {0x203C, 0, 2 | DECOMP_COMPAT, 1842}, + {0x203E, 0, 2 | DECOMP_COMPAT, 1844}, + {0x2047, 0, 2 | DECOMP_COMPAT, 1846}, + {0x2048, 0, 2 | DECOMP_COMPAT, 1848}, + {0x2049, 0, 2 | DECOMP_COMPAT, 1850}, + {0x2057, 0, 4 | DECOMP_COMPAT, 1852}, + {0x205F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x2070, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x2071, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x2074, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x2075, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x2076, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x2077, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x2078, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x2079, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x207A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, + {0x207B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2212}, + {0x207C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, + {0x207D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, + {0x207E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, + {0x207F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x2080, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x2081, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x2082, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x2083, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x2084, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x2085, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x2086, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x2087, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x2088, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x2089, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x208A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, + {0x208B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2212}, + {0x208C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, + {0x208D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, + {0x208E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, + {0x2090, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x2091, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x2092, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x2093, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x2094, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0259}, + {0x2095, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x2096, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x2097, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x2098, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x2099, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x209A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x209B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x209C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x20A8, 0, 2 | DECOMP_COMPAT, 1856}, + {0x20D0, 230, 0, 0}, + {0x20D1, 230, 0, 0}, + {0x20D2, 1, 0, 0}, + {0x20D3, 1, 0, 0}, + {0x20D4, 230, 0, 0}, + {0x20D5, 230, 0, 0}, + {0x20D6, 230, 0, 0}, + {0x20D7, 230, 0, 0}, + {0x20D8, 1, 0, 0}, + {0x20D9, 1, 0, 0}, + {0x20DA, 1, 0, 0}, + {0x20DB, 230, 0, 0}, + {0x20DC, 230, 0, 0}, + {0x20E1, 230, 0, 0}, + {0x20E5, 1, 0, 0}, + {0x20E6, 1, 0, 0}, + {0x20E7, 230, 0, 0}, + {0x20E8, 220, 0, 0}, + {0x20E9, 230, 0, 0}, + {0x20EA, 1, 0, 0}, + {0x20EB, 1, 0, 0}, + {0x20EC, 220, 0, 0}, + {0x20ED, 220, 0, 0}, + {0x20EE, 220, 0, 0}, + {0x20EF, 220, 0, 0}, + {0x20F0, 230, 0, 0}, + {0x2100, 0, 3 | DECOMP_COMPAT, 1858}, + {0x2101, 0, 3 | DECOMP_COMPAT, 1861}, + {0x2102, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x2103, 0, 2 | DECOMP_COMPAT, 1864}, + {0x2105, 0, 3 | DECOMP_COMPAT, 1866}, + {0x2106, 0, 3 | DECOMP_COMPAT, 1869}, + {0x2107, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0190}, + {0x2109, 0, 2 | DECOMP_COMPAT, 1872}, + {0x210A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x210B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x210C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x210D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x210E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x210F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0127}, + {0x2110, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x2111, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x2112, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x2113, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x2115, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x2116, 0, 2 | DECOMP_COMPAT, 1874}, + {0x2119, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x211A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x211B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x211C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x211D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x2120, 0, 2 | DECOMP_COMPAT, 1876}, + {0x2121, 0, 3 | DECOMP_COMPAT, 1878}, + {0x2122, 0, 2 | DECOMP_COMPAT, 1881}, + {0x2124, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x2126, 0, 1 | DECOMP_INLINE, 0x03A9}, + {0x2128, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x212A, 0, 1 | DECOMP_INLINE, 0x004B}, + {0x212B, 0, 1 | DECOMP_INLINE, 0x00C5}, + {0x212C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x212D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x212F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x2130, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x2131, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x2133, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x2134, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x2135, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D0}, + {0x2136, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D1}, + {0x2137, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D2}, + {0x2138, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D3}, + {0x2139, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x213B, 0, 3 | DECOMP_COMPAT, 1883}, + {0x213C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, + {0x213D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x213E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, + {0x213F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, + {0x2140, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2211}, + {0x2145, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x2146, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x2147, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x2148, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x2149, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x2150, 0, 3 | DECOMP_COMPAT, 1886}, + {0x2151, 0, 3 | DECOMP_COMPAT, 1889}, + {0x2152, 0, 4 | DECOMP_COMPAT, 1892}, + {0x2153, 0, 3 | DECOMP_COMPAT, 1896}, + {0x2154, 0, 3 | DECOMP_COMPAT, 1899}, + {0x2155, 0, 3 | DECOMP_COMPAT, 1902}, + {0x2156, 0, 3 | DECOMP_COMPAT, 1905}, + {0x2157, 0, 3 | DECOMP_COMPAT, 1908}, + {0x2158, 0, 3 | DECOMP_COMPAT, 1911}, + {0x2159, 0, 3 | DECOMP_COMPAT, 1914}, + {0x215A, 0, 3 | DECOMP_COMPAT, 1917}, + {0x215B, 0, 3 | DECOMP_COMPAT, 1920}, + {0x215C, 0, 3 | DECOMP_COMPAT, 1923}, + {0x215D, 0, 3 | DECOMP_COMPAT, 1926}, + {0x215E, 0, 3 | DECOMP_COMPAT, 1929}, + {0x215F, 0, 2 | DECOMP_COMPAT, 1932}, + {0x2160, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x2161, 0, 2 | DECOMP_COMPAT, 1934}, + {0x2162, 0, 3 | DECOMP_COMPAT, 1936}, + {0x2163, 0, 2 | DECOMP_COMPAT, 1939}, + {0x2164, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x2165, 0, 2 | DECOMP_COMPAT, 1941}, + {0x2166, 0, 3 | DECOMP_COMPAT, 1943}, + {0x2167, 0, 4 | DECOMP_COMPAT, 1946}, + {0x2168, 0, 2 | DECOMP_COMPAT, 1950}, + {0x2169, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x216A, 0, 2 | DECOMP_COMPAT, 1952}, + {0x216B, 0, 3 | DECOMP_COMPAT, 1954}, + {0x216C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x216D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x216E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x216F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x2170, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x2171, 0, 2 | DECOMP_COMPAT, 1957}, + {0x2172, 0, 3 | DECOMP_COMPAT, 1959}, + {0x2173, 0, 2 | DECOMP_COMPAT, 1962}, + {0x2174, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x2175, 0, 2 | DECOMP_COMPAT, 1964}, + {0x2176, 0, 3 | DECOMP_COMPAT, 1966}, + {0x2177, 0, 4 | DECOMP_COMPAT, 1969}, + {0x2178, 0, 2 | DECOMP_COMPAT, 1973}, + {0x2179, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x217A, 0, 2 | DECOMP_COMPAT, 1975}, + {0x217B, 0, 3 | DECOMP_COMPAT, 1977}, + {0x217C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x217D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x217E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x217F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x2189, 0, 3 | DECOMP_COMPAT, 1980}, + {0x219A, 0, 2, 1983}, + {0x219B, 0, 2, 1985}, + {0x21AE, 0, 2, 1987}, + {0x21CD, 0, 2, 1989}, + {0x21CE, 0, 2, 1991}, + {0x21CF, 0, 2, 1993}, + {0x2204, 0, 2, 1995}, + {0x2209, 0, 2, 1997}, + {0x220C, 0, 2, 1999}, + {0x2224, 0, 2, 2001}, + {0x2226, 0, 2, 2003}, + {0x222C, 0, 2 | DECOMP_COMPAT, 2005}, + {0x222D, 0, 3 | DECOMP_COMPAT, 2007}, + {0x222F, 0, 2 | DECOMP_COMPAT, 2010}, + {0x2230, 0, 3 | DECOMP_COMPAT, 2012}, + {0x2241, 0, 2, 2015}, + {0x2244, 0, 2, 2017}, + {0x2247, 0, 2, 2019}, + {0x2249, 0, 2, 2021}, + {0x2260, 0, 2, 2023}, + {0x2262, 0, 2, 2025}, + {0x226D, 0, 2, 2027}, + {0x226E, 0, 2, 2029}, + {0x226F, 0, 2, 2031}, + {0x2270, 0, 2, 2033}, + {0x2271, 0, 2, 2035}, + {0x2274, 0, 2, 2037}, + {0x2275, 0, 2, 2039}, + {0x2278, 0, 2, 2041}, + {0x2279, 0, 2, 2043}, + {0x2280, 0, 2, 2045}, + {0x2281, 0, 2, 2047}, + {0x2284, 0, 2, 2049}, + {0x2285, 0, 2, 2051}, + {0x2288, 0, 2, 2053}, + {0x2289, 0, 2, 2055}, + {0x22AC, 0, 2, 2057}, + {0x22AD, 0, 2, 2059}, + {0x22AE, 0, 2, 2061}, + {0x22AF, 0, 2, 2063}, + {0x22E0, 0, 2, 2065}, + {0x22E1, 0, 2, 2067}, + {0x22E2, 0, 2, 2069}, + {0x22E3, 0, 2, 2071}, + {0x22EA, 0, 2, 2073}, + {0x22EB, 0, 2, 2075}, + {0x22EC, 0, 2, 2077}, + {0x22ED, 0, 2, 2079}, + {0x2329, 0, 1 | DECOMP_INLINE, 0x3008}, + {0x232A, 0, 1 | DECOMP_INLINE, 0x3009}, + {0x2460, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x2461, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x2462, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x2463, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x2464, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x2465, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x2466, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x2467, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x2468, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x2469, 0, 2 | DECOMP_COMPAT, 2081}, + {0x246A, 0, 2 | DECOMP_COMPAT, 2083}, + {0x246B, 0, 2 | DECOMP_COMPAT, 2085}, + {0x246C, 0, 2 | DECOMP_COMPAT, 2087}, + {0x246D, 0, 2 | DECOMP_COMPAT, 2089}, + {0x246E, 0, 2 | DECOMP_COMPAT, 2091}, + {0x246F, 0, 2 | DECOMP_COMPAT, 2093}, + {0x2470, 0, 2 | DECOMP_COMPAT, 2095}, + {0x2471, 0, 2 | DECOMP_COMPAT, 2097}, + {0x2472, 0, 2 | DECOMP_COMPAT, 2099}, + {0x2473, 0, 2 | DECOMP_COMPAT, 2101}, + {0x2474, 0, 3 | DECOMP_COMPAT, 2103}, + {0x2475, 0, 3 | DECOMP_COMPAT, 2106}, + {0x2476, 0, 3 | DECOMP_COMPAT, 2109}, + {0x2477, 0, 3 | DECOMP_COMPAT, 2112}, + {0x2478, 0, 3 | DECOMP_COMPAT, 2115}, + {0x2479, 0, 3 | DECOMP_COMPAT, 2118}, + {0x247A, 0, 3 | DECOMP_COMPAT, 2121}, + {0x247B, 0, 3 | DECOMP_COMPAT, 2124}, + {0x247C, 0, 3 | DECOMP_COMPAT, 2127}, + {0x247D, 0, 4 | DECOMP_COMPAT, 2130}, + {0x247E, 0, 4 | DECOMP_COMPAT, 2134}, + {0x247F, 0, 4 | DECOMP_COMPAT, 2138}, + {0x2480, 0, 4 | DECOMP_COMPAT, 2142}, + {0x2481, 0, 4 | DECOMP_COMPAT, 2146}, + {0x2482, 0, 4 | DECOMP_COMPAT, 2150}, + {0x2483, 0, 4 | DECOMP_COMPAT, 2154}, + {0x2484, 0, 4 | DECOMP_COMPAT, 2158}, + {0x2485, 0, 4 | DECOMP_COMPAT, 2162}, + {0x2486, 0, 4 | DECOMP_COMPAT, 2166}, + {0x2487, 0, 4 | DECOMP_COMPAT, 2170}, + {0x2488, 0, 2 | DECOMP_COMPAT, 2174}, + {0x2489, 0, 2 | DECOMP_COMPAT, 2176}, + {0x248A, 0, 2 | DECOMP_COMPAT, 2178}, + {0x248B, 0, 2 | DECOMP_COMPAT, 2180}, + {0x248C, 0, 2 | DECOMP_COMPAT, 2182}, + {0x248D, 0, 2 | DECOMP_COMPAT, 2184}, + {0x248E, 0, 2 | DECOMP_COMPAT, 2186}, + {0x248F, 0, 2 | DECOMP_COMPAT, 2188}, + {0x2490, 0, 2 | DECOMP_COMPAT, 2190}, + {0x2491, 0, 3 | DECOMP_COMPAT, 2192}, + {0x2492, 0, 3 | DECOMP_COMPAT, 2195}, + {0x2493, 0, 3 | DECOMP_COMPAT, 2198}, + {0x2494, 0, 3 | DECOMP_COMPAT, 2201}, + {0x2495, 0, 3 | DECOMP_COMPAT, 2204}, + {0x2496, 0, 3 | DECOMP_COMPAT, 2207}, + {0x2497, 0, 3 | DECOMP_COMPAT, 2210}, + {0x2498, 0, 3 | DECOMP_COMPAT, 2213}, + {0x2499, 0, 3 | DECOMP_COMPAT, 2216}, + {0x249A, 0, 3 | DECOMP_COMPAT, 2219}, + {0x249B, 0, 3 | DECOMP_COMPAT, 2222}, + {0x249C, 0, 3 | DECOMP_COMPAT, 2225}, + {0x249D, 0, 3 | DECOMP_COMPAT, 2228}, + {0x249E, 0, 3 | DECOMP_COMPAT, 2231}, + {0x249F, 0, 3 | DECOMP_COMPAT, 2234}, + {0x24A0, 0, 3 | DECOMP_COMPAT, 2237}, + {0x24A1, 0, 3 | DECOMP_COMPAT, 2240}, + {0x24A2, 0, 3 | DECOMP_COMPAT, 2243}, + {0x24A3, 0, 3 | DECOMP_COMPAT, 2246}, + {0x24A4, 0, 3 | DECOMP_COMPAT, 2249}, + {0x24A5, 0, 3 | DECOMP_COMPAT, 2252}, + {0x24A6, 0, 3 | DECOMP_COMPAT, 2255}, + {0x24A7, 0, 3 | DECOMP_COMPAT, 2258}, + {0x24A8, 0, 3 | DECOMP_COMPAT, 2261}, + {0x24A9, 0, 3 | DECOMP_COMPAT, 2264}, + {0x24AA, 0, 3 | DECOMP_COMPAT, 2267}, + {0x24AB, 0, 3 | DECOMP_COMPAT, 2270}, + {0x24AC, 0, 3 | DECOMP_COMPAT, 2273}, + {0x24AD, 0, 3 | DECOMP_COMPAT, 2276}, + {0x24AE, 0, 3 | DECOMP_COMPAT, 2279}, + {0x24AF, 0, 3 | DECOMP_COMPAT, 2282}, + {0x24B0, 0, 3 | DECOMP_COMPAT, 2285}, + {0x24B1, 0, 3 | DECOMP_COMPAT, 2288}, + {0x24B2, 0, 3 | DECOMP_COMPAT, 2291}, + {0x24B3, 0, 3 | DECOMP_COMPAT, 2294}, + {0x24B4, 0, 3 | DECOMP_COMPAT, 2297}, + {0x24B5, 0, 3 | DECOMP_COMPAT, 2300}, + {0x24B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x24B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x24B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x24B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x24BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x24BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x24BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x24BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x24BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x24BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x24C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x24C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x24C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x24C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x24C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x24C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x24C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x24C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x24C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x24C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x24CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x24CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x24CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x24CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x24CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x24CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x24D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x24D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x24D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x24D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x24D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x24D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x24D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x24D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x24D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x24D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x24DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x24DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x24DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x24DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x24DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x24DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x24E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x24E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x24E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x24E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x24E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x24E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x24E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x24E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x24E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x24E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x24EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x2A0C, 0, 4 | DECOMP_COMPAT, 2303}, + {0x2A74, 0, 3 | DECOMP_COMPAT, 2307}, + {0x2A75, 0, 2 | DECOMP_COMPAT, 2310}, + {0x2A76, 0, 3 | DECOMP_COMPAT, 2312}, + {0x2ADC, 0, 2 | DECOMP_NO_COMPOSE, 2315}, /* in exclusion list */ + {0x2C7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x2C7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x2CEF, 230, 0, 0}, + {0x2CF0, 230, 0, 0}, + {0x2CF1, 230, 0, 0}, + {0x2D6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2D61}, + {0x2D7F, 9, 0, 0}, + {0x2DE0, 230, 0, 0}, + {0x2DE1, 230, 0, 0}, + {0x2DE2, 230, 0, 0}, + {0x2DE3, 230, 0, 0}, + {0x2DE4, 230, 0, 0}, + {0x2DE5, 230, 0, 0}, + {0x2DE6, 230, 0, 0}, + {0x2DE7, 230, 0, 0}, + {0x2DE8, 230, 0, 0}, + {0x2DE9, 230, 0, 0}, + {0x2DEA, 230, 0, 0}, + {0x2DEB, 230, 0, 0}, + {0x2DEC, 230, 0, 0}, + {0x2DED, 230, 0, 0}, + {0x2DEE, 230, 0, 0}, + {0x2DEF, 230, 0, 0}, + {0x2DF0, 230, 0, 0}, + {0x2DF1, 230, 0, 0}, + {0x2DF2, 230, 0, 0}, + {0x2DF3, 230, 0, 0}, + {0x2DF4, 230, 0, 0}, + {0x2DF5, 230, 0, 0}, + {0x2DF6, 230, 0, 0}, + {0x2DF7, 230, 0, 0}, + {0x2DF8, 230, 0, 0}, + {0x2DF9, 230, 0, 0}, + {0x2DFA, 230, 0, 0}, + {0x2DFB, 230, 0, 0}, + {0x2DFC, 230, 0, 0}, + {0x2DFD, 230, 0, 0}, + {0x2DFE, 230, 0, 0}, + {0x2DFF, 230, 0, 0}, + {0x2E9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BCD}, + {0x2EF3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F9F}, + {0x2F00, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, + {0x2F01, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E28}, + {0x2F02, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E36}, + {0x2F03, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E3F}, + {0x2F04, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E59}, + {0x2F05, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E85}, + {0x2F06, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, + {0x2F07, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EA0}, + {0x2F08, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EBA}, + {0x2F09, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x513F}, + {0x2F0A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5165}, + {0x2F0B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x516B}, + {0x2F0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5182}, + {0x2F0D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5196}, + {0x2F0E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x51AB}, + {0x2F0F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x51E0}, + {0x2F10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x51F5}, + {0x2F11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5200}, + {0x2F12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x529B}, + {0x2F13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x52F9}, + {0x2F14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5315}, + {0x2F15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x531A}, + {0x2F16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5338}, + {0x2F17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5341}, + {0x2F18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x535C}, + {0x2F19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5369}, + {0x2F1A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5382}, + {0x2F1B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53B6}, + {0x2F1C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53C8}, + {0x2F1D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53E3}, + {0x2F1E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x56D7}, + {0x2F1F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x571F}, + {0x2F20, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x58EB}, + {0x2F21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5902}, + {0x2F22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x590A}, + {0x2F23, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5915}, + {0x2F24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5927}, + {0x2F25, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5973}, + {0x2F26, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B50}, + {0x2F27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B80}, + {0x2F28, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5BF8}, + {0x2F29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C0F}, + {0x2F2A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C22}, + {0x2F2B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C38}, + {0x2F2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C6E}, + {0x2F2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C71}, + {0x2F2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DDB}, + {0x2F2F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DE5}, + {0x2F30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DF1}, + {0x2F31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DFE}, + {0x2F32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E72}, + {0x2F33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E7A}, + {0x2F34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E7F}, + {0x2F35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5EF4}, + {0x2F36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5EFE}, + {0x2F37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F0B}, + {0x2F38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F13}, + {0x2F39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F50}, + {0x2F3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F61}, + {0x2F3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F73}, + {0x2F3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5FC3}, + {0x2F3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6208}, + {0x2F3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6236}, + {0x2F3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x624B}, + {0x2F40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x652F}, + {0x2F41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6534}, + {0x2F42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6587}, + {0x2F43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6597}, + {0x2F44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65A4}, + {0x2F45, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65B9}, + {0x2F46, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65E0}, + {0x2F47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65E5}, + {0x2F48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x66F0}, + {0x2F49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6708}, + {0x2F4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6728}, + {0x2F4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B20}, + {0x2F4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B62}, + {0x2F4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B79}, + {0x2F4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BB3}, + {0x2F4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BCB}, + {0x2F50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BD4}, + {0x2F51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BDB}, + {0x2F52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C0F}, + {0x2F53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C14}, + {0x2F54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C34}, + {0x2F55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x706B}, + {0x2F56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x722A}, + {0x2F57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7236}, + {0x2F58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x723B}, + {0x2F59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x723F}, + {0x2F5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7247}, + {0x2F5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7259}, + {0x2F5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x725B}, + {0x2F5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x72AC}, + {0x2F5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7384}, + {0x2F5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7389}, + {0x2F60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x74DC}, + {0x2F61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x74E6}, + {0x2F62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7518}, + {0x2F63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x751F}, + {0x2F64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7528}, + {0x2F65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7530}, + {0x2F66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x758B}, + {0x2F67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7592}, + {0x2F68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7676}, + {0x2F69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x767D}, + {0x2F6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76AE}, + {0x2F6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76BF}, + {0x2F6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76EE}, + {0x2F6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x77DB}, + {0x2F6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x77E2}, + {0x2F6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x77F3}, + {0x2F70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x793A}, + {0x2F71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x79B8}, + {0x2F72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x79BE}, + {0x2F73, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7A74}, + {0x2F74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7ACB}, + {0x2F75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7AF9}, + {0x2F76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7C73}, + {0x2F77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7CF8}, + {0x2F78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7F36}, + {0x2F79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7F51}, + {0x2F7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7F8A}, + {0x2F7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7FBD}, + {0x2F7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8001}, + {0x2F7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x800C}, + {0x2F7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8012}, + {0x2F7F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8033}, + {0x2F80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x807F}, + {0x2F81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8089}, + {0x2F82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81E3}, + {0x2F83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81EA}, + {0x2F84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81F3}, + {0x2F85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81FC}, + {0x2F86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x820C}, + {0x2F87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x821B}, + {0x2F88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x821F}, + {0x2F89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x826E}, + {0x2F8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8272}, + {0x2F8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8278}, + {0x2F8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x864D}, + {0x2F8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x866B}, + {0x2F8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8840}, + {0x2F8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x884C}, + {0x2F90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8863}, + {0x2F91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x897E}, + {0x2F92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x898B}, + {0x2F93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x89D2}, + {0x2F94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8A00}, + {0x2F95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C37}, + {0x2F96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C46}, + {0x2F97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C55}, + {0x2F98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C78}, + {0x2F99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C9D}, + {0x2F9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8D64}, + {0x2F9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8D70}, + {0x2F9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8DB3}, + {0x2F9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8EAB}, + {0x2F9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8ECA}, + {0x2F9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8F9B}, + {0x2FA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8FB0}, + {0x2FA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8FB5}, + {0x2FA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9091}, + {0x2FA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9149}, + {0x2FA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91C6}, + {0x2FA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91CC}, + {0x2FA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91D1}, + {0x2FA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9577}, + {0x2FA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9580}, + {0x2FA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x961C}, + {0x2FAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x96B6}, + {0x2FAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x96B9}, + {0x2FAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x96E8}, + {0x2FAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9751}, + {0x2FAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x975E}, + {0x2FAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9762}, + {0x2FB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9769}, + {0x2FB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x97CB}, + {0x2FB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x97ED}, + {0x2FB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x97F3}, + {0x2FB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9801}, + {0x2FB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x98A8}, + {0x2FB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x98DB}, + {0x2FB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x98DF}, + {0x2FB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9996}, + {0x2FB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9999}, + {0x2FBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x99AC}, + {0x2FBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9AA8}, + {0x2FBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9AD8}, + {0x2FBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9ADF}, + {0x2FBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B25}, + {0x2FBF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B2F}, + {0x2FC0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B32}, + {0x2FC1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B3C}, + {0x2FC2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B5A}, + {0x2FC3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9CE5}, + {0x2FC4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9E75}, + {0x2FC5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9E7F}, + {0x2FC6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EA5}, + {0x2FC7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EBB}, + {0x2FC8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EC3}, + {0x2FC9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9ECD}, + {0x2FCA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9ED1}, + {0x2FCB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EF9}, + {0x2FCC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EFD}, + {0x2FCD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F0E}, + {0x2FCE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F13}, + {0x2FCF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F20}, + {0x2FD0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F3B}, + {0x2FD1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F4A}, + {0x2FD2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F52}, + {0x2FD3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F8D}, + {0x2FD4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F9C}, + {0x2FD5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9FA0}, + {0x3000, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, + {0x302A, 218, 0, 0}, + {0x302B, 228, 0, 0}, + {0x302C, 232, 0, 0}, + {0x302D, 222, 0, 0}, + {0x302E, 224, 0, 0}, + {0x302F, 224, 0, 0}, + {0x3036, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3012}, + {0x3038, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5341}, + {0x3039, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5344}, + {0x303A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5345}, + {0x304C, 0, 2, 2317}, + {0x304E, 0, 2, 2319}, + {0x3050, 0, 2, 2321}, + {0x3052, 0, 2, 2323}, + {0x3054, 0, 2, 2325}, + {0x3056, 0, 2, 2327}, + {0x3058, 0, 2, 2329}, + {0x305A, 0, 2, 2331}, + {0x305C, 0, 2, 2333}, + {0x305E, 0, 2, 2335}, + {0x3060, 0, 2, 2337}, + {0x3062, 0, 2, 2339}, + {0x3065, 0, 2, 2341}, + {0x3067, 0, 2, 2343}, + {0x3069, 0, 2, 2345}, + {0x3070, 0, 2, 2347}, + {0x3071, 0, 2, 2349}, + {0x3073, 0, 2, 2351}, + {0x3074, 0, 2, 2353}, + {0x3076, 0, 2, 2355}, + {0x3077, 0, 2, 2357}, + {0x3079, 0, 2, 2359}, + {0x307A, 0, 2, 2361}, + {0x307C, 0, 2, 2363}, + {0x307D, 0, 2, 2365}, + {0x3094, 0, 2, 2367}, + {0x3099, 8, 0, 0}, + {0x309A, 8, 0, 0}, + {0x309B, 0, 2 | DECOMP_COMPAT, 2369}, + {0x309C, 0, 2 | DECOMP_COMPAT, 2371}, + {0x309E, 0, 2, 2373}, + {0x309F, 0, 2 | DECOMP_COMPAT, 2375}, + {0x30AC, 0, 2, 2377}, + {0x30AE, 0, 2, 2379}, + {0x30B0, 0, 2, 2381}, + {0x30B2, 0, 2, 2383}, + {0x30B4, 0, 2, 2385}, + {0x30B6, 0, 2, 2387}, + {0x30B8, 0, 2, 2389}, + {0x30BA, 0, 2, 2391}, + {0x30BC, 0, 2, 2393}, + {0x30BE, 0, 2, 2395}, + {0x30C0, 0, 2, 2397}, + {0x30C2, 0, 2, 2399}, + {0x30C5, 0, 2, 2401}, + {0x30C7, 0, 2, 2403}, + {0x30C9, 0, 2, 2405}, + {0x30D0, 0, 2, 2407}, + {0x30D1, 0, 2, 2409}, + {0x30D3, 0, 2, 2411}, + {0x30D4, 0, 2, 2413}, + {0x30D6, 0, 2, 2415}, + {0x30D7, 0, 2, 2417}, + {0x30D9, 0, 2, 2419}, + {0x30DA, 0, 2, 2421}, + {0x30DC, 0, 2, 2423}, + {0x30DD, 0, 2, 2425}, + {0x30F4, 0, 2, 2427}, + {0x30F7, 0, 2, 2429}, + {0x30F8, 0, 2, 2431}, + {0x30F9, 0, 2, 2433}, + {0x30FA, 0, 2, 2435}, + {0x30FE, 0, 2, 2437}, + {0x30FF, 0, 2 | DECOMP_COMPAT, 2439}, + {0x3131, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1100}, + {0x3132, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1101}, + {0x3133, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11AA}, + {0x3134, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1102}, + {0x3135, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11AC}, + {0x3136, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11AD}, + {0x3137, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1103}, + {0x3138, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1104}, + {0x3139, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1105}, + {0x313A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B0}, + {0x313B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B1}, + {0x313C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B2}, + {0x313D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B3}, + {0x313E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B4}, + {0x313F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B5}, + {0x3140, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111A}, + {0x3141, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1106}, + {0x3142, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1107}, + {0x3143, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1108}, + {0x3144, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1121}, + {0x3145, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1109}, + {0x3146, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110A}, + {0x3147, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110B}, + {0x3148, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110C}, + {0x3149, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110D}, + {0x314A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110E}, + {0x314B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110F}, + {0x314C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1110}, + {0x314D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1111}, + {0x314E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1112}, + {0x314F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1161}, + {0x3150, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1162}, + {0x3151, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1163}, + {0x3152, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1164}, + {0x3153, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1165}, + {0x3154, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1166}, + {0x3155, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1167}, + {0x3156, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1168}, + {0x3157, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1169}, + {0x3158, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116A}, + {0x3159, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116B}, + {0x315A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116C}, + {0x315B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116D}, + {0x315C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116E}, + {0x315D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116F}, + {0x315E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1170}, + {0x315F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1171}, + {0x3160, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1172}, + {0x3161, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1173}, + {0x3162, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1174}, + {0x3163, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1175}, + {0x3164, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1160}, + {0x3165, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1114}, + {0x3166, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1115}, + {0x3167, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11C7}, + {0x3168, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11C8}, + {0x3169, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11CC}, + {0x316A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11CE}, + {0x316B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11D3}, + {0x316C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11D7}, + {0x316D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11D9}, + {0x316E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111C}, + {0x316F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11DD}, + {0x3170, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11DF}, + {0x3171, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111D}, + {0x3172, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111E}, + {0x3173, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1120}, + {0x3174, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1122}, + {0x3175, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1123}, + {0x3176, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1127}, + {0x3177, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1129}, + {0x3178, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112B}, + {0x3179, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112C}, + {0x317A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112D}, + {0x317B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112E}, + {0x317C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112F}, + {0x317D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1132}, + {0x317E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1136}, + {0x317F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1140}, + {0x3180, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1147}, + {0x3181, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x114C}, + {0x3182, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11F1}, + {0x3183, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11F2}, + {0x3184, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1157}, + {0x3185, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1158}, + {0x3186, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1159}, + {0x3187, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1184}, + {0x3188, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1185}, + {0x3189, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1188}, + {0x318A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1191}, + {0x318B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1192}, + {0x318C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1194}, + {0x318D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x119E}, + {0x318E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11A1}, + {0x3192, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, + {0x3193, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, + {0x3194, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E09}, + {0x3195, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x56DB}, + {0x3196, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0A}, + {0x3197, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E2D}, + {0x3198, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0B}, + {0x3199, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7532}, + {0x319A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E59}, + {0x319B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E19}, + {0x319C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E01}, + {0x319D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5929}, + {0x319E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5730}, + {0x319F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EBA}, + {0x3200, 0, 3 | DECOMP_COMPAT, 2441}, + {0x3201, 0, 3 | DECOMP_COMPAT, 2444}, + {0x3202, 0, 3 | DECOMP_COMPAT, 2447}, + {0x3203, 0, 3 | DECOMP_COMPAT, 2450}, + {0x3204, 0, 3 | DECOMP_COMPAT, 2453}, + {0x3205, 0, 3 | DECOMP_COMPAT, 2456}, + {0x3206, 0, 3 | DECOMP_COMPAT, 2459}, + {0x3207, 0, 3 | DECOMP_COMPAT, 2462}, + {0x3208, 0, 3 | DECOMP_COMPAT, 2465}, + {0x3209, 0, 3 | DECOMP_COMPAT, 2468}, + {0x320A, 0, 3 | DECOMP_COMPAT, 2471}, + {0x320B, 0, 3 | DECOMP_COMPAT, 2474}, + {0x320C, 0, 3 | DECOMP_COMPAT, 2477}, + {0x320D, 0, 3 | DECOMP_COMPAT, 2480}, + {0x320E, 0, 4 | DECOMP_COMPAT, 2483}, + {0x320F, 0, 4 | DECOMP_COMPAT, 2487}, + {0x3210, 0, 4 | DECOMP_COMPAT, 2491}, + {0x3211, 0, 4 | DECOMP_COMPAT, 2495}, + {0x3212, 0, 4 | DECOMP_COMPAT, 2499}, + {0x3213, 0, 4 | DECOMP_COMPAT, 2503}, + {0x3214, 0, 4 | DECOMP_COMPAT, 2507}, + {0x3215, 0, 4 | DECOMP_COMPAT, 2511}, + {0x3216, 0, 4 | DECOMP_COMPAT, 2515}, + {0x3217, 0, 4 | DECOMP_COMPAT, 2519}, + {0x3218, 0, 4 | DECOMP_COMPAT, 2523}, + {0x3219, 0, 4 | DECOMP_COMPAT, 2527}, + {0x321A, 0, 4 | DECOMP_COMPAT, 2531}, + {0x321B, 0, 4 | DECOMP_COMPAT, 2535}, + {0x321C, 0, 4 | DECOMP_COMPAT, 2539}, + {0x321D, 0, 7 | DECOMP_COMPAT, 2543}, + {0x321E, 0, 6 | DECOMP_COMPAT, 2550}, + {0x3220, 0, 3 | DECOMP_COMPAT, 2556}, + {0x3221, 0, 3 | DECOMP_COMPAT, 2559}, + {0x3222, 0, 3 | DECOMP_COMPAT, 2562}, + {0x3223, 0, 3 | DECOMP_COMPAT, 2565}, + {0x3224, 0, 3 | DECOMP_COMPAT, 2568}, + {0x3225, 0, 3 | DECOMP_COMPAT, 2571}, + {0x3226, 0, 3 | DECOMP_COMPAT, 2574}, + {0x3227, 0, 3 | DECOMP_COMPAT, 2577}, + {0x3228, 0, 3 | DECOMP_COMPAT, 2580}, + {0x3229, 0, 3 | DECOMP_COMPAT, 2583}, + {0x322A, 0, 3 | DECOMP_COMPAT, 2586}, + {0x322B, 0, 3 | DECOMP_COMPAT, 2589}, + {0x322C, 0, 3 | DECOMP_COMPAT, 2592}, + {0x322D, 0, 3 | DECOMP_COMPAT, 2595}, + {0x322E, 0, 3 | DECOMP_COMPAT, 2598}, + {0x322F, 0, 3 | DECOMP_COMPAT, 2601}, + {0x3230, 0, 3 | DECOMP_COMPAT, 2604}, + {0x3231, 0, 3 | DECOMP_COMPAT, 2607}, + {0x3232, 0, 3 | DECOMP_COMPAT, 2610}, + {0x3233, 0, 3 | DECOMP_COMPAT, 2613}, + {0x3234, 0, 3 | DECOMP_COMPAT, 2616}, + {0x3235, 0, 3 | DECOMP_COMPAT, 2619}, + {0x3236, 0, 3 | DECOMP_COMPAT, 2622}, + {0x3237, 0, 3 | DECOMP_COMPAT, 2625}, + {0x3238, 0, 3 | DECOMP_COMPAT, 2628}, + {0x3239, 0, 3 | DECOMP_COMPAT, 2631}, + {0x323A, 0, 3 | DECOMP_COMPAT, 2634}, + {0x323B, 0, 3 | DECOMP_COMPAT, 2637}, + {0x323C, 0, 3 | DECOMP_COMPAT, 2640}, + {0x323D, 0, 3 | DECOMP_COMPAT, 2643}, + {0x323E, 0, 3 | DECOMP_COMPAT, 2646}, + {0x323F, 0, 3 | DECOMP_COMPAT, 2649}, + {0x3240, 0, 3 | DECOMP_COMPAT, 2652}, + {0x3241, 0, 3 | DECOMP_COMPAT, 2655}, + {0x3242, 0, 3 | DECOMP_COMPAT, 2658}, + {0x3243, 0, 3 | DECOMP_COMPAT, 2661}, + {0x3244, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x554F}, + {0x3245, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E7C}, + {0x3246, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6587}, + {0x3247, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7B8F}, + {0x3250, 0, 3 | DECOMP_COMPAT, 2664}, + {0x3251, 0, 2 | DECOMP_COMPAT, 2667}, + {0x3252, 0, 2 | DECOMP_COMPAT, 2669}, + {0x3253, 0, 2 | DECOMP_COMPAT, 2671}, + {0x3254, 0, 2 | DECOMP_COMPAT, 2673}, + {0x3255, 0, 2 | DECOMP_COMPAT, 2675}, + {0x3256, 0, 2 | DECOMP_COMPAT, 2677}, + {0x3257, 0, 2 | DECOMP_COMPAT, 2679}, + {0x3258, 0, 2 | DECOMP_COMPAT, 2681}, + {0x3259, 0, 2 | DECOMP_COMPAT, 2683}, + {0x325A, 0, 2 | DECOMP_COMPAT, 2685}, + {0x325B, 0, 2 | DECOMP_COMPAT, 2687}, + {0x325C, 0, 2 | DECOMP_COMPAT, 2689}, + {0x325D, 0, 2 | DECOMP_COMPAT, 2691}, + {0x325E, 0, 2 | DECOMP_COMPAT, 2693}, + {0x325F, 0, 2 | DECOMP_COMPAT, 2695}, + {0x3260, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1100}, + {0x3261, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1102}, + {0x3262, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1103}, + {0x3263, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1105}, + {0x3264, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1106}, + {0x3265, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1107}, + {0x3266, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1109}, + {0x3267, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110B}, + {0x3268, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110C}, + {0x3269, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110E}, + {0x326A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110F}, + {0x326B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1110}, + {0x326C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1111}, + {0x326D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1112}, + {0x326E, 0, 2 | DECOMP_COMPAT, 2697}, + {0x326F, 0, 2 | DECOMP_COMPAT, 2699}, + {0x3270, 0, 2 | DECOMP_COMPAT, 2701}, + {0x3271, 0, 2 | DECOMP_COMPAT, 2703}, + {0x3272, 0, 2 | DECOMP_COMPAT, 2705}, + {0x3273, 0, 2 | DECOMP_COMPAT, 2707}, + {0x3274, 0, 2 | DECOMP_COMPAT, 2709}, + {0x3275, 0, 2 | DECOMP_COMPAT, 2711}, + {0x3276, 0, 2 | DECOMP_COMPAT, 2713}, + {0x3277, 0, 2 | DECOMP_COMPAT, 2715}, + {0x3278, 0, 2 | DECOMP_COMPAT, 2717}, + {0x3279, 0, 2 | DECOMP_COMPAT, 2719}, + {0x327A, 0, 2 | DECOMP_COMPAT, 2721}, + {0x327B, 0, 2 | DECOMP_COMPAT, 2723}, + {0x327C, 0, 5 | DECOMP_COMPAT, 2725}, + {0x327D, 0, 4 | DECOMP_COMPAT, 2730}, + {0x327E, 0, 2 | DECOMP_COMPAT, 2734}, + {0x3280, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, + {0x3281, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, + {0x3282, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E09}, + {0x3283, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x56DB}, + {0x3284, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E94}, + {0x3285, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x516D}, + {0x3286, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E03}, + {0x3287, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x516B}, + {0x3288, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E5D}, + {0x3289, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5341}, + {0x328A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6708}, + {0x328B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x706B}, + {0x328C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C34}, + {0x328D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6728}, + {0x328E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91D1}, + {0x328F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x571F}, + {0x3290, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65E5}, + {0x3291, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x682A}, + {0x3292, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6709}, + {0x3293, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x793E}, + {0x3294, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x540D}, + {0x3295, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7279}, + {0x3296, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8CA1}, + {0x3297, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x795D}, + {0x3298, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x52B4}, + {0x3299, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x79D8}, + {0x329A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7537}, + {0x329B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5973}, + {0x329C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9069}, + {0x329D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x512A}, + {0x329E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5370}, + {0x329F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6CE8}, + {0x32A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9805}, + {0x32A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4F11}, + {0x32A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5199}, + {0x32A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B63}, + {0x32A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0A}, + {0x32A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E2D}, + {0x32A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0B}, + {0x32A7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DE6}, + {0x32A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53F3}, + {0x32A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x533B}, + {0x32AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B97}, + {0x32AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B66}, + {0x32AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76E3}, + {0x32AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4F01}, + {0x32AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8CC7}, + {0x32AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5354}, + {0x32B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x591C}, + {0x32B1, 0, 2 | DECOMP_COMPAT, 2736}, + {0x32B2, 0, 2 | DECOMP_COMPAT, 2738}, + {0x32B3, 0, 2 | DECOMP_COMPAT, 2740}, + {0x32B4, 0, 2 | DECOMP_COMPAT, 2742}, + {0x32B5, 0, 2 | DECOMP_COMPAT, 2744}, + {0x32B6, 0, 2 | DECOMP_COMPAT, 2746}, + {0x32B7, 0, 2 | DECOMP_COMPAT, 2748}, + {0x32B8, 0, 2 | DECOMP_COMPAT, 2750}, + {0x32B9, 0, 2 | DECOMP_COMPAT, 2752}, + {0x32BA, 0, 2 | DECOMP_COMPAT, 2754}, + {0x32BB, 0, 2 | DECOMP_COMPAT, 2756}, + {0x32BC, 0, 2 | DECOMP_COMPAT, 2758}, + {0x32BD, 0, 2 | DECOMP_COMPAT, 2760}, + {0x32BE, 0, 2 | DECOMP_COMPAT, 2762}, + {0x32BF, 0, 2 | DECOMP_COMPAT, 2764}, + {0x32C0, 0, 2 | DECOMP_COMPAT, 2766}, + {0x32C1, 0, 2 | DECOMP_COMPAT, 2768}, + {0x32C2, 0, 2 | DECOMP_COMPAT, 2770}, + {0x32C3, 0, 2 | DECOMP_COMPAT, 2772}, + {0x32C4, 0, 2 | DECOMP_COMPAT, 2774}, + {0x32C5, 0, 2 | DECOMP_COMPAT, 2776}, + {0x32C6, 0, 2 | DECOMP_COMPAT, 2778}, + {0x32C7, 0, 2 | DECOMP_COMPAT, 2780}, + {0x32C8, 0, 2 | DECOMP_COMPAT, 2782}, + {0x32C9, 0, 3 | DECOMP_COMPAT, 2784}, + {0x32CA, 0, 3 | DECOMP_COMPAT, 2787}, + {0x32CB, 0, 3 | DECOMP_COMPAT, 2790}, + {0x32CC, 0, 2 | DECOMP_COMPAT, 2793}, + {0x32CD, 0, 3 | DECOMP_COMPAT, 2795}, + {0x32CE, 0, 2 | DECOMP_COMPAT, 2798}, + {0x32CF, 0, 3 | DECOMP_COMPAT, 2800}, + {0x32D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A2}, + {0x32D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A4}, + {0x32D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A6}, + {0x32D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A8}, + {0x32D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AA}, + {0x32D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AB}, + {0x32D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AD}, + {0x32D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AF}, + {0x32D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B1}, + {0x32D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B3}, + {0x32DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B5}, + {0x32DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B7}, + {0x32DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B9}, + {0x32DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BB}, + {0x32DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BD}, + {0x32DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BF}, + {0x32E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C1}, + {0x32E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C4}, + {0x32E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C6}, + {0x32E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C8}, + {0x32E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CA}, + {0x32E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CB}, + {0x32E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CC}, + {0x32E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CD}, + {0x32E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CE}, + {0x32E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CF}, + {0x32EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D2}, + {0x32EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D5}, + {0x32EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D8}, + {0x32ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DB}, + {0x32EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DE}, + {0x32EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DF}, + {0x32F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E0}, + {0x32F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E1}, + {0x32F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E2}, + {0x32F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E4}, + {0x32F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E6}, + {0x32F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E8}, + {0x32F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E9}, + {0x32F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EA}, + {0x32F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EB}, + {0x32F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EC}, + {0x32FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30ED}, + {0x32FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EF}, + {0x32FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F0}, + {0x32FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F1}, + {0x32FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F2}, + {0x32FF, 0, 2 | DECOMP_COMPAT, 2803}, + {0x3300, 0, 4 | DECOMP_COMPAT, 2805}, + {0x3301, 0, 4 | DECOMP_COMPAT, 2809}, + {0x3302, 0, 4 | DECOMP_COMPAT, 2813}, + {0x3303, 0, 3 | DECOMP_COMPAT, 2817}, + {0x3304, 0, 4 | DECOMP_COMPAT, 2820}, + {0x3305, 0, 3 | DECOMP_COMPAT, 2824}, + {0x3306, 0, 3 | DECOMP_COMPAT, 2827}, + {0x3307, 0, 5 | DECOMP_COMPAT, 2830}, + {0x3308, 0, 4 | DECOMP_COMPAT, 2835}, + {0x3309, 0, 3 | DECOMP_COMPAT, 2839}, + {0x330A, 0, 3 | DECOMP_COMPAT, 2842}, + {0x330B, 0, 3 | DECOMP_COMPAT, 2845}, + {0x330C, 0, 4 | DECOMP_COMPAT, 2848}, + {0x330D, 0, 4 | DECOMP_COMPAT, 2852}, + {0x330E, 0, 3 | DECOMP_COMPAT, 2856}, + {0x330F, 0, 3 | DECOMP_COMPAT, 2859}, + {0x3310, 0, 2 | DECOMP_COMPAT, 2862}, + {0x3311, 0, 3 | DECOMP_COMPAT, 2864}, + {0x3312, 0, 4 | DECOMP_COMPAT, 2867}, + {0x3313, 0, 4 | DECOMP_COMPAT, 2871}, + {0x3314, 0, 2 | DECOMP_COMPAT, 2875}, + {0x3315, 0, 5 | DECOMP_COMPAT, 2877}, + {0x3316, 0, 6 | DECOMP_COMPAT, 2882}, + {0x3317, 0, 5 | DECOMP_COMPAT, 2888}, + {0x3318, 0, 3 | DECOMP_COMPAT, 2893}, + {0x3319, 0, 5 | DECOMP_COMPAT, 2896}, + {0x331A, 0, 5 | DECOMP_COMPAT, 2901}, + {0x331B, 0, 4 | DECOMP_COMPAT, 2906}, + {0x331C, 0, 3 | DECOMP_COMPAT, 2910}, + {0x331D, 0, 3 | DECOMP_COMPAT, 2913}, + {0x331E, 0, 3 | DECOMP_COMPAT, 2916}, + {0x331F, 0, 4 | DECOMP_COMPAT, 2919}, + {0x3320, 0, 5 | DECOMP_COMPAT, 2923}, + {0x3321, 0, 4 | DECOMP_COMPAT, 2928}, + {0x3322, 0, 3 | DECOMP_COMPAT, 2932}, + {0x3323, 0, 3 | DECOMP_COMPAT, 2935}, + {0x3324, 0, 3 | DECOMP_COMPAT, 2938}, + {0x3325, 0, 2 | DECOMP_COMPAT, 2941}, + {0x3326, 0, 2 | DECOMP_COMPAT, 2943}, + {0x3327, 0, 2 | DECOMP_COMPAT, 2945}, + {0x3328, 0, 2 | DECOMP_COMPAT, 2947}, + {0x3329, 0, 3 | DECOMP_COMPAT, 2949}, + {0x332A, 0, 3 | DECOMP_COMPAT, 2952}, + {0x332B, 0, 5 | DECOMP_COMPAT, 2955}, + {0x332C, 0, 3 | DECOMP_COMPAT, 2960}, + {0x332D, 0, 4 | DECOMP_COMPAT, 2963}, + {0x332E, 0, 5 | DECOMP_COMPAT, 2967}, + {0x332F, 0, 3 | DECOMP_COMPAT, 2972}, + {0x3330, 0, 2 | DECOMP_COMPAT, 2975}, + {0x3331, 0, 2 | DECOMP_COMPAT, 2977}, + {0x3332, 0, 5 | DECOMP_COMPAT, 2979}, + {0x3333, 0, 4 | DECOMP_COMPAT, 2984}, + {0x3334, 0, 5 | DECOMP_COMPAT, 2988}, + {0x3335, 0, 3 | DECOMP_COMPAT, 2993}, + {0x3336, 0, 5 | DECOMP_COMPAT, 2996}, + {0x3337, 0, 2 | DECOMP_COMPAT, 3001}, + {0x3338, 0, 3 | DECOMP_COMPAT, 3003}, + {0x3339, 0, 3 | DECOMP_COMPAT, 3006}, + {0x333A, 0, 3 | DECOMP_COMPAT, 3009}, + {0x333B, 0, 3 | DECOMP_COMPAT, 3012}, + {0x333C, 0, 3 | DECOMP_COMPAT, 3015}, + {0x333D, 0, 4 | DECOMP_COMPAT, 3018}, + {0x333E, 0, 3 | DECOMP_COMPAT, 3022}, + {0x333F, 0, 2 | DECOMP_COMPAT, 3025}, + {0x3340, 0, 3 | DECOMP_COMPAT, 3027}, + {0x3341, 0, 3 | DECOMP_COMPAT, 3030}, + {0x3342, 0, 3 | DECOMP_COMPAT, 3033}, + {0x3343, 0, 4 | DECOMP_COMPAT, 3036}, + {0x3344, 0, 3 | DECOMP_COMPAT, 3040}, + {0x3345, 0, 3 | DECOMP_COMPAT, 3043}, + {0x3346, 0, 3 | DECOMP_COMPAT, 3046}, + {0x3347, 0, 5 | DECOMP_COMPAT, 3049}, + {0x3348, 0, 4 | DECOMP_COMPAT, 3054}, + {0x3349, 0, 2 | DECOMP_COMPAT, 3058}, + {0x334A, 0, 5 | DECOMP_COMPAT, 3060}, + {0x334B, 0, 2 | DECOMP_COMPAT, 3065}, + {0x334C, 0, 4 | DECOMP_COMPAT, 3067}, + {0x334D, 0, 4 | DECOMP_COMPAT, 3071}, + {0x334E, 0, 3 | DECOMP_COMPAT, 3075}, + {0x334F, 0, 3 | DECOMP_COMPAT, 3078}, + {0x3350, 0, 3 | DECOMP_COMPAT, 3081}, + {0x3351, 0, 4 | DECOMP_COMPAT, 3084}, + {0x3352, 0, 2 | DECOMP_COMPAT, 3088}, + {0x3353, 0, 3 | DECOMP_COMPAT, 3090}, + {0x3354, 0, 4 | DECOMP_COMPAT, 3093}, + {0x3355, 0, 2 | DECOMP_COMPAT, 3097}, + {0x3356, 0, 5 | DECOMP_COMPAT, 3099}, + {0x3357, 0, 3 | DECOMP_COMPAT, 3104}, + {0x3358, 0, 2 | DECOMP_COMPAT, 3107}, + {0x3359, 0, 2 | DECOMP_COMPAT, 3109}, + {0x335A, 0, 2 | DECOMP_COMPAT, 3111}, + {0x335B, 0, 2 | DECOMP_COMPAT, 3113}, + {0x335C, 0, 2 | DECOMP_COMPAT, 3115}, + {0x335D, 0, 2 | DECOMP_COMPAT, 3117}, + {0x335E, 0, 2 | DECOMP_COMPAT, 3119}, + {0x335F, 0, 2 | DECOMP_COMPAT, 3121}, + {0x3360, 0, 2 | DECOMP_COMPAT, 3123}, + {0x3361, 0, 2 | DECOMP_COMPAT, 3125}, + {0x3362, 0, 3 | DECOMP_COMPAT, 3127}, + {0x3363, 0, 3 | DECOMP_COMPAT, 3130}, + {0x3364, 0, 3 | DECOMP_COMPAT, 3133}, + {0x3365, 0, 3 | DECOMP_COMPAT, 3136}, + {0x3366, 0, 3 | DECOMP_COMPAT, 3139}, + {0x3367, 0, 3 | DECOMP_COMPAT, 3142}, + {0x3368, 0, 3 | DECOMP_COMPAT, 3145}, + {0x3369, 0, 3 | DECOMP_COMPAT, 3148}, + {0x336A, 0, 3 | DECOMP_COMPAT, 3151}, + {0x336B, 0, 3 | DECOMP_COMPAT, 3154}, + {0x336C, 0, 3 | DECOMP_COMPAT, 3157}, + {0x336D, 0, 3 | DECOMP_COMPAT, 3160}, + {0x336E, 0, 3 | DECOMP_COMPAT, 3163}, + {0x336F, 0, 3 | DECOMP_COMPAT, 3166}, + {0x3370, 0, 3 | DECOMP_COMPAT, 3169}, + {0x3371, 0, 3 | DECOMP_COMPAT, 3172}, + {0x3372, 0, 2 | DECOMP_COMPAT, 3175}, + {0x3373, 0, 2 | DECOMP_COMPAT, 3177}, + {0x3374, 0, 3 | DECOMP_COMPAT, 3179}, + {0x3375, 0, 2 | DECOMP_COMPAT, 3182}, + {0x3376, 0, 2 | DECOMP_COMPAT, 3184}, + {0x3377, 0, 2 | DECOMP_COMPAT, 3186}, + {0x3378, 0, 3 | DECOMP_COMPAT, 3188}, + {0x3379, 0, 3 | DECOMP_COMPAT, 3191}, + {0x337A, 0, 2 | DECOMP_COMPAT, 3194}, + {0x337B, 0, 2 | DECOMP_COMPAT, 3196}, + {0x337C, 0, 2 | DECOMP_COMPAT, 3198}, + {0x337D, 0, 2 | DECOMP_COMPAT, 3200}, + {0x337E, 0, 2 | DECOMP_COMPAT, 3202}, + {0x337F, 0, 4 | DECOMP_COMPAT, 3204}, + {0x3380, 0, 2 | DECOMP_COMPAT, 3208}, + {0x3381, 0, 2 | DECOMP_COMPAT, 3210}, + {0x3382, 0, 2 | DECOMP_COMPAT, 3212}, + {0x3383, 0, 2 | DECOMP_COMPAT, 3214}, + {0x3384, 0, 2 | DECOMP_COMPAT, 3216}, + {0x3385, 0, 2 | DECOMP_COMPAT, 3218}, + {0x3386, 0, 2 | DECOMP_COMPAT, 3220}, + {0x3387, 0, 2 | DECOMP_COMPAT, 3222}, + {0x3388, 0, 3 | DECOMP_COMPAT, 3224}, + {0x3389, 0, 4 | DECOMP_COMPAT, 3227}, + {0x338A, 0, 2 | DECOMP_COMPAT, 3231}, + {0x338B, 0, 2 | DECOMP_COMPAT, 3233}, + {0x338C, 0, 2 | DECOMP_COMPAT, 3235}, + {0x338D, 0, 2 | DECOMP_COMPAT, 3237}, + {0x338E, 0, 2 | DECOMP_COMPAT, 3239}, + {0x338F, 0, 2 | DECOMP_COMPAT, 3241}, + {0x3390, 0, 2 | DECOMP_COMPAT, 3243}, + {0x3391, 0, 3 | DECOMP_COMPAT, 3245}, + {0x3392, 0, 3 | DECOMP_COMPAT, 3248}, + {0x3393, 0, 3 | DECOMP_COMPAT, 3251}, + {0x3394, 0, 3 | DECOMP_COMPAT, 3254}, + {0x3395, 0, 2 | DECOMP_COMPAT, 3257}, + {0x3396, 0, 2 | DECOMP_COMPAT, 3259}, + {0x3397, 0, 2 | DECOMP_COMPAT, 3261}, + {0x3398, 0, 2 | DECOMP_COMPAT, 3263}, + {0x3399, 0, 2 | DECOMP_COMPAT, 3265}, + {0x339A, 0, 2 | DECOMP_COMPAT, 3267}, + {0x339B, 0, 2 | DECOMP_COMPAT, 3269}, + {0x339C, 0, 2 | DECOMP_COMPAT, 3271}, + {0x339D, 0, 2 | DECOMP_COMPAT, 3273}, + {0x339E, 0, 2 | DECOMP_COMPAT, 3275}, + {0x339F, 0, 3 | DECOMP_COMPAT, 3277}, + {0x33A0, 0, 3 | DECOMP_COMPAT, 3280}, + {0x33A1, 0, 2 | DECOMP_COMPAT, 3283}, + {0x33A2, 0, 3 | DECOMP_COMPAT, 3285}, + {0x33A3, 0, 3 | DECOMP_COMPAT, 3288}, + {0x33A4, 0, 3 | DECOMP_COMPAT, 3291}, + {0x33A5, 0, 2 | DECOMP_COMPAT, 3294}, + {0x33A6, 0, 3 | DECOMP_COMPAT, 3296}, + {0x33A7, 0, 3 | DECOMP_COMPAT, 3299}, + {0x33A8, 0, 4 | DECOMP_COMPAT, 3302}, + {0x33A9, 0, 2 | DECOMP_COMPAT, 3306}, + {0x33AA, 0, 3 | DECOMP_COMPAT, 3308}, + {0x33AB, 0, 3 | DECOMP_COMPAT, 3311}, + {0x33AC, 0, 3 | DECOMP_COMPAT, 3314}, + {0x33AD, 0, 3 | DECOMP_COMPAT, 3317}, + {0x33AE, 0, 5 | DECOMP_COMPAT, 3320}, + {0x33AF, 0, 6 | DECOMP_COMPAT, 3325}, + {0x33B0, 0, 2 | DECOMP_COMPAT, 3331}, + {0x33B1, 0, 2 | DECOMP_COMPAT, 3333}, + {0x33B2, 0, 2 | DECOMP_COMPAT, 3335}, + {0x33B3, 0, 2 | DECOMP_COMPAT, 3337}, + {0x33B4, 0, 2 | DECOMP_COMPAT, 3339}, + {0x33B5, 0, 2 | DECOMP_COMPAT, 3341}, + {0x33B6, 0, 2 | DECOMP_COMPAT, 3343}, + {0x33B7, 0, 2 | DECOMP_COMPAT, 3345}, + {0x33B8, 0, 2 | DECOMP_COMPAT, 3347}, + {0x33B9, 0, 2 | DECOMP_COMPAT, 3349}, + {0x33BA, 0, 2 | DECOMP_COMPAT, 3351}, + {0x33BB, 0, 2 | DECOMP_COMPAT, 3353}, + {0x33BC, 0, 2 | DECOMP_COMPAT, 3355}, + {0x33BD, 0, 2 | DECOMP_COMPAT, 3357}, + {0x33BE, 0, 2 | DECOMP_COMPAT, 3359}, + {0x33BF, 0, 2 | DECOMP_COMPAT, 3361}, + {0x33C0, 0, 2 | DECOMP_COMPAT, 3363}, + {0x33C1, 0, 2 | DECOMP_COMPAT, 3365}, + {0x33C2, 0, 4 | DECOMP_COMPAT, 3367}, + {0x33C3, 0, 2 | DECOMP_COMPAT, 3371}, + {0x33C4, 0, 2 | DECOMP_COMPAT, 3373}, + {0x33C5, 0, 2 | DECOMP_COMPAT, 3375}, + {0x33C6, 0, 4 | DECOMP_COMPAT, 3377}, + {0x33C7, 0, 3 | DECOMP_COMPAT, 3381}, + {0x33C8, 0, 2 | DECOMP_COMPAT, 3384}, + {0x33C9, 0, 2 | DECOMP_COMPAT, 3386}, + {0x33CA, 0, 2 | DECOMP_COMPAT, 3388}, + {0x33CB, 0, 2 | DECOMP_COMPAT, 3390}, + {0x33CC, 0, 2 | DECOMP_COMPAT, 3392}, + {0x33CD, 0, 2 | DECOMP_COMPAT, 3394}, + {0x33CE, 0, 2 | DECOMP_COMPAT, 3396}, + {0x33CF, 0, 2 | DECOMP_COMPAT, 3398}, + {0x33D0, 0, 2 | DECOMP_COMPAT, 3400}, + {0x33D1, 0, 2 | DECOMP_COMPAT, 3402}, + {0x33D2, 0, 3 | DECOMP_COMPAT, 3404}, + {0x33D3, 0, 2 | DECOMP_COMPAT, 3407}, + {0x33D4, 0, 2 | DECOMP_COMPAT, 3409}, + {0x33D5, 0, 3 | DECOMP_COMPAT, 3411}, + {0x33D6, 0, 3 | DECOMP_COMPAT, 3414}, + {0x33D7, 0, 2 | DECOMP_COMPAT, 3417}, + {0x33D8, 0, 4 | DECOMP_COMPAT, 3419}, + {0x33D9, 0, 3 | DECOMP_COMPAT, 3423}, + {0x33DA, 0, 2 | DECOMP_COMPAT, 3426}, + {0x33DB, 0, 2 | DECOMP_COMPAT, 3428}, + {0x33DC, 0, 2 | DECOMP_COMPAT, 3430}, + {0x33DD, 0, 2 | DECOMP_COMPAT, 3432}, + {0x33DE, 0, 3 | DECOMP_COMPAT, 3434}, + {0x33DF, 0, 3 | DECOMP_COMPAT, 3437}, + {0x33E0, 0, 2 | DECOMP_COMPAT, 3440}, + {0x33E1, 0, 2 | DECOMP_COMPAT, 3442}, + {0x33E2, 0, 2 | DECOMP_COMPAT, 3444}, + {0x33E3, 0, 2 | DECOMP_COMPAT, 3446}, + {0x33E4, 0, 2 | DECOMP_COMPAT, 3448}, + {0x33E5, 0, 2 | DECOMP_COMPAT, 3450}, + {0x33E6, 0, 2 | DECOMP_COMPAT, 3452}, + {0x33E7, 0, 2 | DECOMP_COMPAT, 3454}, + {0x33E8, 0, 2 | DECOMP_COMPAT, 3456}, + {0x33E9, 0, 3 | DECOMP_COMPAT, 3458}, + {0x33EA, 0, 3 | DECOMP_COMPAT, 3461}, + {0x33EB, 0, 3 | DECOMP_COMPAT, 3464}, + {0x33EC, 0, 3 | DECOMP_COMPAT, 3467}, + {0x33ED, 0, 3 | DECOMP_COMPAT, 3470}, + {0x33EE, 0, 3 | DECOMP_COMPAT, 3473}, + {0x33EF, 0, 3 | DECOMP_COMPAT, 3476}, + {0x33F0, 0, 3 | DECOMP_COMPAT, 3479}, + {0x33F1, 0, 3 | DECOMP_COMPAT, 3482}, + {0x33F2, 0, 3 | DECOMP_COMPAT, 3485}, + {0x33F3, 0, 3 | DECOMP_COMPAT, 3488}, + {0x33F4, 0, 3 | DECOMP_COMPAT, 3491}, + {0x33F5, 0, 3 | DECOMP_COMPAT, 3494}, + {0x33F6, 0, 3 | DECOMP_COMPAT, 3497}, + {0x33F7, 0, 3 | DECOMP_COMPAT, 3500}, + {0x33F8, 0, 3 | DECOMP_COMPAT, 3503}, + {0x33F9, 0, 3 | DECOMP_COMPAT, 3506}, + {0x33FA, 0, 3 | DECOMP_COMPAT, 3509}, + {0x33FB, 0, 3 | DECOMP_COMPAT, 3512}, + {0x33FC, 0, 3 | DECOMP_COMPAT, 3515}, + {0x33FD, 0, 3 | DECOMP_COMPAT, 3518}, + {0x33FE, 0, 3 | DECOMP_COMPAT, 3521}, + {0x33FF, 0, 3 | DECOMP_COMPAT, 3524}, + {0xA66F, 230, 0, 0}, + {0xA674, 230, 0, 0}, + {0xA675, 230, 0, 0}, + {0xA676, 230, 0, 0}, + {0xA677, 230, 0, 0}, + {0xA678, 230, 0, 0}, + {0xA679, 230, 0, 0}, + {0xA67A, 230, 0, 0}, + {0xA67B, 230, 0, 0}, + {0xA67C, 230, 0, 0}, + {0xA67D, 230, 0, 0}, + {0xA69C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044A}, + {0xA69D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044C}, + {0xA69E, 230, 0, 0}, + {0xA69F, 230, 0, 0}, + {0xA6F0, 230, 0, 0}, + {0xA6F1, 230, 0, 0}, + {0xA770, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA76F}, + {0xA7F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0xA7F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0xA7F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0xA7F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0126}, + {0xA7F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0153}, + {0xA806, 9, 0, 0}, + {0xA82C, 9, 0, 0}, + {0xA8C4, 9, 0, 0}, + {0xA8E0, 230, 0, 0}, + {0xA8E1, 230, 0, 0}, + {0xA8E2, 230, 0, 0}, + {0xA8E3, 230, 0, 0}, + {0xA8E4, 230, 0, 0}, + {0xA8E5, 230, 0, 0}, + {0xA8E6, 230, 0, 0}, + {0xA8E7, 230, 0, 0}, + {0xA8E8, 230, 0, 0}, + {0xA8E9, 230, 0, 0}, + {0xA8EA, 230, 0, 0}, + {0xA8EB, 230, 0, 0}, + {0xA8EC, 230, 0, 0}, + {0xA8ED, 230, 0, 0}, + {0xA8EE, 230, 0, 0}, + {0xA8EF, 230, 0, 0}, + {0xA8F0, 230, 0, 0}, + {0xA8F1, 230, 0, 0}, + {0xA92B, 220, 0, 0}, + {0xA92C, 220, 0, 0}, + {0xA92D, 220, 0, 0}, + {0xA953, 9, 0, 0}, + {0xA9B3, 7, 0, 0}, + {0xA9C0, 9, 0, 0}, + {0xAAB0, 230, 0, 0}, + {0xAAB2, 230, 0, 0}, + {0xAAB3, 230, 0, 0}, + {0xAAB4, 220, 0, 0}, + {0xAAB7, 230, 0, 0}, + {0xAAB8, 230, 0, 0}, + {0xAABE, 230, 0, 0}, + {0xAABF, 230, 0, 0}, + {0xAAC1, 230, 0, 0}, + {0xAAF6, 9, 0, 0}, + {0xAB5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA727}, + {0xAB5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB37}, + {0xAB5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026B}, + {0xAB5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB52}, + {0xAB69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028D}, + {0xABED, 9, 0, 0}, + {0xF900, 0, 1 | DECOMP_INLINE, 0x8C48}, + {0xF901, 0, 1 | DECOMP_INLINE, 0x66F4}, + {0xF902, 0, 1 | DECOMP_INLINE, 0x8ECA}, + {0xF903, 0, 1 | DECOMP_INLINE, 0x8CC8}, + {0xF904, 0, 1 | DECOMP_INLINE, 0x6ED1}, + {0xF905, 0, 1 | DECOMP_INLINE, 0x4E32}, + {0xF906, 0, 1 | DECOMP_INLINE, 0x53E5}, + {0xF907, 0, 1 | DECOMP_INLINE, 0x9F9C}, + {0xF908, 0, 1 | DECOMP_INLINE, 0x9F9C}, + {0xF909, 0, 1 | DECOMP_INLINE, 0x5951}, + {0xF90A, 0, 1 | DECOMP_INLINE, 0x91D1}, + {0xF90B, 0, 1 | DECOMP_INLINE, 0x5587}, + {0xF90C, 0, 1 | DECOMP_INLINE, 0x5948}, + {0xF90D, 0, 1 | DECOMP_INLINE, 0x61F6}, + {0xF90E, 0, 1 | DECOMP_INLINE, 0x7669}, + {0xF90F, 0, 1 | DECOMP_INLINE, 0x7F85}, + {0xF910, 0, 1 | DECOMP_INLINE, 0x863F}, + {0xF911, 0, 1 | DECOMP_INLINE, 0x87BA}, + {0xF912, 0, 1 | DECOMP_INLINE, 0x88F8}, + {0xF913, 0, 1 | DECOMP_INLINE, 0x908F}, + {0xF914, 0, 1 | DECOMP_INLINE, 0x6A02}, + {0xF915, 0, 1 | DECOMP_INLINE, 0x6D1B}, + {0xF916, 0, 1 | DECOMP_INLINE, 0x70D9}, + {0xF917, 0, 1 | DECOMP_INLINE, 0x73DE}, + {0xF918, 0, 1 | DECOMP_INLINE, 0x843D}, + {0xF919, 0, 1 | DECOMP_INLINE, 0x916A}, + {0xF91A, 0, 1 | DECOMP_INLINE, 0x99F1}, + {0xF91B, 0, 1 | DECOMP_INLINE, 0x4E82}, + {0xF91C, 0, 1 | DECOMP_INLINE, 0x5375}, + {0xF91D, 0, 1 | DECOMP_INLINE, 0x6B04}, + {0xF91E, 0, 1 | DECOMP_INLINE, 0x721B}, + {0xF91F, 0, 1 | DECOMP_INLINE, 0x862D}, + {0xF920, 0, 1 | DECOMP_INLINE, 0x9E1E}, + {0xF921, 0, 1 | DECOMP_INLINE, 0x5D50}, + {0xF922, 0, 1 | DECOMP_INLINE, 0x6FEB}, + {0xF923, 0, 1 | DECOMP_INLINE, 0x85CD}, + {0xF924, 0, 1 | DECOMP_INLINE, 0x8964}, + {0xF925, 0, 1 | DECOMP_INLINE, 0x62C9}, + {0xF926, 0, 1 | DECOMP_INLINE, 0x81D8}, + {0xF927, 0, 1 | DECOMP_INLINE, 0x881F}, + {0xF928, 0, 1 | DECOMP_INLINE, 0x5ECA}, + {0xF929, 0, 1 | DECOMP_INLINE, 0x6717}, + {0xF92A, 0, 1 | DECOMP_INLINE, 0x6D6A}, + {0xF92B, 0, 1 | DECOMP_INLINE, 0x72FC}, + {0xF92C, 0, 1 | DECOMP_INLINE, 0x90CE}, + {0xF92D, 0, 1 | DECOMP_INLINE, 0x4F86}, + {0xF92E, 0, 1 | DECOMP_INLINE, 0x51B7}, + {0xF92F, 0, 1 | DECOMP_INLINE, 0x52DE}, + {0xF930, 0, 1 | DECOMP_INLINE, 0x64C4}, + {0xF931, 0, 1 | DECOMP_INLINE, 0x6AD3}, + {0xF932, 0, 1 | DECOMP_INLINE, 0x7210}, + {0xF933, 0, 1 | DECOMP_INLINE, 0x76E7}, + {0xF934, 0, 1 | DECOMP_INLINE, 0x8001}, + {0xF935, 0, 1 | DECOMP_INLINE, 0x8606}, + {0xF936, 0, 1 | DECOMP_INLINE, 0x865C}, + {0xF937, 0, 1 | DECOMP_INLINE, 0x8DEF}, + {0xF938, 0, 1 | DECOMP_INLINE, 0x9732}, + {0xF939, 0, 1 | DECOMP_INLINE, 0x9B6F}, + {0xF93A, 0, 1 | DECOMP_INLINE, 0x9DFA}, + {0xF93B, 0, 1 | DECOMP_INLINE, 0x788C}, + {0xF93C, 0, 1 | DECOMP_INLINE, 0x797F}, + {0xF93D, 0, 1 | DECOMP_INLINE, 0x7DA0}, + {0xF93E, 0, 1 | DECOMP_INLINE, 0x83C9}, + {0xF93F, 0, 1 | DECOMP_INLINE, 0x9304}, + {0xF940, 0, 1 | DECOMP_INLINE, 0x9E7F}, + {0xF941, 0, 1 | DECOMP_INLINE, 0x8AD6}, + {0xF942, 0, 1 | DECOMP_INLINE, 0x58DF}, + {0xF943, 0, 1 | DECOMP_INLINE, 0x5F04}, + {0xF944, 0, 1 | DECOMP_INLINE, 0x7C60}, + {0xF945, 0, 1 | DECOMP_INLINE, 0x807E}, + {0xF946, 0, 1 | DECOMP_INLINE, 0x7262}, + {0xF947, 0, 1 | DECOMP_INLINE, 0x78CA}, + {0xF948, 0, 1 | DECOMP_INLINE, 0x8CC2}, + {0xF949, 0, 1 | DECOMP_INLINE, 0x96F7}, + {0xF94A, 0, 1 | DECOMP_INLINE, 0x58D8}, + {0xF94B, 0, 1 | DECOMP_INLINE, 0x5C62}, + {0xF94C, 0, 1 | DECOMP_INLINE, 0x6A13}, + {0xF94D, 0, 1 | DECOMP_INLINE, 0x6DDA}, + {0xF94E, 0, 1 | DECOMP_INLINE, 0x6F0F}, + {0xF94F, 0, 1 | DECOMP_INLINE, 0x7D2F}, + {0xF950, 0, 1 | DECOMP_INLINE, 0x7E37}, + {0xF951, 0, 1 | DECOMP_INLINE, 0x964B}, + {0xF952, 0, 1 | DECOMP_INLINE, 0x52D2}, + {0xF953, 0, 1 | DECOMP_INLINE, 0x808B}, + {0xF954, 0, 1 | DECOMP_INLINE, 0x51DC}, + {0xF955, 0, 1 | DECOMP_INLINE, 0x51CC}, + {0xF956, 0, 1 | DECOMP_INLINE, 0x7A1C}, + {0xF957, 0, 1 | DECOMP_INLINE, 0x7DBE}, + {0xF958, 0, 1 | DECOMP_INLINE, 0x83F1}, + {0xF959, 0, 1 | DECOMP_INLINE, 0x9675}, + {0xF95A, 0, 1 | DECOMP_INLINE, 0x8B80}, + {0xF95B, 0, 1 | DECOMP_INLINE, 0x62CF}, + {0xF95C, 0, 1 | DECOMP_INLINE, 0x6A02}, + {0xF95D, 0, 1 | DECOMP_INLINE, 0x8AFE}, + {0xF95E, 0, 1 | DECOMP_INLINE, 0x4E39}, + {0xF95F, 0, 1 | DECOMP_INLINE, 0x5BE7}, + {0xF960, 0, 1 | DECOMP_INLINE, 0x6012}, + {0xF961, 0, 1 | DECOMP_INLINE, 0x7387}, + {0xF962, 0, 1 | DECOMP_INLINE, 0x7570}, + {0xF963, 0, 1 | DECOMP_INLINE, 0x5317}, + {0xF964, 0, 1 | DECOMP_INLINE, 0x78FB}, + {0xF965, 0, 1 | DECOMP_INLINE, 0x4FBF}, + {0xF966, 0, 1 | DECOMP_INLINE, 0x5FA9}, + {0xF967, 0, 1 | DECOMP_INLINE, 0x4E0D}, + {0xF968, 0, 1 | DECOMP_INLINE, 0x6CCC}, + {0xF969, 0, 1 | DECOMP_INLINE, 0x6578}, + {0xF96A, 0, 1 | DECOMP_INLINE, 0x7D22}, + {0xF96B, 0, 1 | DECOMP_INLINE, 0x53C3}, + {0xF96C, 0, 1 | DECOMP_INLINE, 0x585E}, + {0xF96D, 0, 1 | DECOMP_INLINE, 0x7701}, + {0xF96E, 0, 1 | DECOMP_INLINE, 0x8449}, + {0xF96F, 0, 1 | DECOMP_INLINE, 0x8AAA}, + {0xF970, 0, 1 | DECOMP_INLINE, 0x6BBA}, + {0xF971, 0, 1 | DECOMP_INLINE, 0x8FB0}, + {0xF972, 0, 1 | DECOMP_INLINE, 0x6C88}, + {0xF973, 0, 1 | DECOMP_INLINE, 0x62FE}, + {0xF974, 0, 1 | DECOMP_INLINE, 0x82E5}, + {0xF975, 0, 1 | DECOMP_INLINE, 0x63A0}, + {0xF976, 0, 1 | DECOMP_INLINE, 0x7565}, + {0xF977, 0, 1 | DECOMP_INLINE, 0x4EAE}, + {0xF978, 0, 1 | DECOMP_INLINE, 0x5169}, + {0xF979, 0, 1 | DECOMP_INLINE, 0x51C9}, + {0xF97A, 0, 1 | DECOMP_INLINE, 0x6881}, + {0xF97B, 0, 1 | DECOMP_INLINE, 0x7CE7}, + {0xF97C, 0, 1 | DECOMP_INLINE, 0x826F}, + {0xF97D, 0, 1 | DECOMP_INLINE, 0x8AD2}, + {0xF97E, 0, 1 | DECOMP_INLINE, 0x91CF}, + {0xF97F, 0, 1 | DECOMP_INLINE, 0x52F5}, + {0xF980, 0, 1 | DECOMP_INLINE, 0x5442}, + {0xF981, 0, 1 | DECOMP_INLINE, 0x5973}, + {0xF982, 0, 1 | DECOMP_INLINE, 0x5EEC}, + {0xF983, 0, 1 | DECOMP_INLINE, 0x65C5}, + {0xF984, 0, 1 | DECOMP_INLINE, 0x6FFE}, + {0xF985, 0, 1 | DECOMP_INLINE, 0x792A}, + {0xF986, 0, 1 | DECOMP_INLINE, 0x95AD}, + {0xF987, 0, 1 | DECOMP_INLINE, 0x9A6A}, + {0xF988, 0, 1 | DECOMP_INLINE, 0x9E97}, + {0xF989, 0, 1 | DECOMP_INLINE, 0x9ECE}, + {0xF98A, 0, 1 | DECOMP_INLINE, 0x529B}, + {0xF98B, 0, 1 | DECOMP_INLINE, 0x66C6}, + {0xF98C, 0, 1 | DECOMP_INLINE, 0x6B77}, + {0xF98D, 0, 1 | DECOMP_INLINE, 0x8F62}, + {0xF98E, 0, 1 | DECOMP_INLINE, 0x5E74}, + {0xF98F, 0, 1 | DECOMP_INLINE, 0x6190}, + {0xF990, 0, 1 | DECOMP_INLINE, 0x6200}, + {0xF991, 0, 1 | DECOMP_INLINE, 0x649A}, + {0xF992, 0, 1 | DECOMP_INLINE, 0x6F23}, + {0xF993, 0, 1 | DECOMP_INLINE, 0x7149}, + {0xF994, 0, 1 | DECOMP_INLINE, 0x7489}, + {0xF995, 0, 1 | DECOMP_INLINE, 0x79CA}, + {0xF996, 0, 1 | DECOMP_INLINE, 0x7DF4}, + {0xF997, 0, 1 | DECOMP_INLINE, 0x806F}, + {0xF998, 0, 1 | DECOMP_INLINE, 0x8F26}, + {0xF999, 0, 1 | DECOMP_INLINE, 0x84EE}, + {0xF99A, 0, 1 | DECOMP_INLINE, 0x9023}, + {0xF99B, 0, 1 | DECOMP_INLINE, 0x934A}, + {0xF99C, 0, 1 | DECOMP_INLINE, 0x5217}, + {0xF99D, 0, 1 | DECOMP_INLINE, 0x52A3}, + {0xF99E, 0, 1 | DECOMP_INLINE, 0x54BD}, + {0xF99F, 0, 1 | DECOMP_INLINE, 0x70C8}, + {0xF9A0, 0, 1 | DECOMP_INLINE, 0x88C2}, + {0xF9A1, 0, 1 | DECOMP_INLINE, 0x8AAA}, + {0xF9A2, 0, 1 | DECOMP_INLINE, 0x5EC9}, + {0xF9A3, 0, 1 | DECOMP_INLINE, 0x5FF5}, + {0xF9A4, 0, 1 | DECOMP_INLINE, 0x637B}, + {0xF9A5, 0, 1 | DECOMP_INLINE, 0x6BAE}, + {0xF9A6, 0, 1 | DECOMP_INLINE, 0x7C3E}, + {0xF9A7, 0, 1 | DECOMP_INLINE, 0x7375}, + {0xF9A8, 0, 1 | DECOMP_INLINE, 0x4EE4}, + {0xF9A9, 0, 1 | DECOMP_INLINE, 0x56F9}, + {0xF9AA, 0, 1 | DECOMP_INLINE, 0x5BE7}, + {0xF9AB, 0, 1 | DECOMP_INLINE, 0x5DBA}, + {0xF9AC, 0, 1 | DECOMP_INLINE, 0x601C}, + {0xF9AD, 0, 1 | DECOMP_INLINE, 0x73B2}, + {0xF9AE, 0, 1 | DECOMP_INLINE, 0x7469}, + {0xF9AF, 0, 1 | DECOMP_INLINE, 0x7F9A}, + {0xF9B0, 0, 1 | DECOMP_INLINE, 0x8046}, + {0xF9B1, 0, 1 | DECOMP_INLINE, 0x9234}, + {0xF9B2, 0, 1 | DECOMP_INLINE, 0x96F6}, + {0xF9B3, 0, 1 | DECOMP_INLINE, 0x9748}, + {0xF9B4, 0, 1 | DECOMP_INLINE, 0x9818}, + {0xF9B5, 0, 1 | DECOMP_INLINE, 0x4F8B}, + {0xF9B6, 0, 1 | DECOMP_INLINE, 0x79AE}, + {0xF9B7, 0, 1 | DECOMP_INLINE, 0x91B4}, + {0xF9B8, 0, 1 | DECOMP_INLINE, 0x96B8}, + {0xF9B9, 0, 1 | DECOMP_INLINE, 0x60E1}, + {0xF9BA, 0, 1 | DECOMP_INLINE, 0x4E86}, + {0xF9BB, 0, 1 | DECOMP_INLINE, 0x50DA}, + {0xF9BC, 0, 1 | DECOMP_INLINE, 0x5BEE}, + {0xF9BD, 0, 1 | DECOMP_INLINE, 0x5C3F}, + {0xF9BE, 0, 1 | DECOMP_INLINE, 0x6599}, + {0xF9BF, 0, 1 | DECOMP_INLINE, 0x6A02}, + {0xF9C0, 0, 1 | DECOMP_INLINE, 0x71CE}, + {0xF9C1, 0, 1 | DECOMP_INLINE, 0x7642}, + {0xF9C2, 0, 1 | DECOMP_INLINE, 0x84FC}, + {0xF9C3, 0, 1 | DECOMP_INLINE, 0x907C}, + {0xF9C4, 0, 1 | DECOMP_INLINE, 0x9F8D}, + {0xF9C5, 0, 1 | DECOMP_INLINE, 0x6688}, + {0xF9C6, 0, 1 | DECOMP_INLINE, 0x962E}, + {0xF9C7, 0, 1 | DECOMP_INLINE, 0x5289}, + {0xF9C8, 0, 1 | DECOMP_INLINE, 0x677B}, + {0xF9C9, 0, 1 | DECOMP_INLINE, 0x67F3}, + {0xF9CA, 0, 1 | DECOMP_INLINE, 0x6D41}, + {0xF9CB, 0, 1 | DECOMP_INLINE, 0x6E9C}, + {0xF9CC, 0, 1 | DECOMP_INLINE, 0x7409}, + {0xF9CD, 0, 1 | DECOMP_INLINE, 0x7559}, + {0xF9CE, 0, 1 | DECOMP_INLINE, 0x786B}, + {0xF9CF, 0, 1 | DECOMP_INLINE, 0x7D10}, + {0xF9D0, 0, 1 | DECOMP_INLINE, 0x985E}, + {0xF9D1, 0, 1 | DECOMP_INLINE, 0x516D}, + {0xF9D2, 0, 1 | DECOMP_INLINE, 0x622E}, + {0xF9D3, 0, 1 | DECOMP_INLINE, 0x9678}, + {0xF9D4, 0, 1 | DECOMP_INLINE, 0x502B}, + {0xF9D5, 0, 1 | DECOMP_INLINE, 0x5D19}, + {0xF9D6, 0, 1 | DECOMP_INLINE, 0x6DEA}, + {0xF9D7, 0, 1 | DECOMP_INLINE, 0x8F2A}, + {0xF9D8, 0, 1 | DECOMP_INLINE, 0x5F8B}, + {0xF9D9, 0, 1 | DECOMP_INLINE, 0x6144}, + {0xF9DA, 0, 1 | DECOMP_INLINE, 0x6817}, + {0xF9DB, 0, 1 | DECOMP_INLINE, 0x7387}, + {0xF9DC, 0, 1 | DECOMP_INLINE, 0x9686}, + {0xF9DD, 0, 1 | DECOMP_INLINE, 0x5229}, + {0xF9DE, 0, 1 | DECOMP_INLINE, 0x540F}, + {0xF9DF, 0, 1 | DECOMP_INLINE, 0x5C65}, + {0xF9E0, 0, 1 | DECOMP_INLINE, 0x6613}, + {0xF9E1, 0, 1 | DECOMP_INLINE, 0x674E}, + {0xF9E2, 0, 1 | DECOMP_INLINE, 0x68A8}, + {0xF9E3, 0, 1 | DECOMP_INLINE, 0x6CE5}, + {0xF9E4, 0, 1 | DECOMP_INLINE, 0x7406}, + {0xF9E5, 0, 1 | DECOMP_INLINE, 0x75E2}, + {0xF9E6, 0, 1 | DECOMP_INLINE, 0x7F79}, + {0xF9E7, 0, 1 | DECOMP_INLINE, 0x88CF}, + {0xF9E8, 0, 1 | DECOMP_INLINE, 0x88E1}, + {0xF9E9, 0, 1 | DECOMP_INLINE, 0x91CC}, + {0xF9EA, 0, 1 | DECOMP_INLINE, 0x96E2}, + {0xF9EB, 0, 1 | DECOMP_INLINE, 0x533F}, + {0xF9EC, 0, 1 | DECOMP_INLINE, 0x6EBA}, + {0xF9ED, 0, 1 | DECOMP_INLINE, 0x541D}, + {0xF9EE, 0, 1 | DECOMP_INLINE, 0x71D0}, + {0xF9EF, 0, 1 | DECOMP_INLINE, 0x7498}, + {0xF9F0, 0, 1 | DECOMP_INLINE, 0x85FA}, + {0xF9F1, 0, 1 | DECOMP_INLINE, 0x96A3}, + {0xF9F2, 0, 1 | DECOMP_INLINE, 0x9C57}, + {0xF9F3, 0, 1 | DECOMP_INLINE, 0x9E9F}, + {0xF9F4, 0, 1 | DECOMP_INLINE, 0x6797}, + {0xF9F5, 0, 1 | DECOMP_INLINE, 0x6DCB}, + {0xF9F6, 0, 1 | DECOMP_INLINE, 0x81E8}, + {0xF9F7, 0, 1 | DECOMP_INLINE, 0x7ACB}, + {0xF9F8, 0, 1 | DECOMP_INLINE, 0x7B20}, + {0xF9F9, 0, 1 | DECOMP_INLINE, 0x7C92}, + {0xF9FA, 0, 1 | DECOMP_INLINE, 0x72C0}, + {0xF9FB, 0, 1 | DECOMP_INLINE, 0x7099}, + {0xF9FC, 0, 1 | DECOMP_INLINE, 0x8B58}, + {0xF9FD, 0, 1 | DECOMP_INLINE, 0x4EC0}, + {0xF9FE, 0, 1 | DECOMP_INLINE, 0x8336}, + {0xF9FF, 0, 1 | DECOMP_INLINE, 0x523A}, + {0xFA00, 0, 1 | DECOMP_INLINE, 0x5207}, + {0xFA01, 0, 1 | DECOMP_INLINE, 0x5EA6}, + {0xFA02, 0, 1 | DECOMP_INLINE, 0x62D3}, + {0xFA03, 0, 1 | DECOMP_INLINE, 0x7CD6}, + {0xFA04, 0, 1 | DECOMP_INLINE, 0x5B85}, + {0xFA05, 0, 1 | DECOMP_INLINE, 0x6D1E}, + {0xFA06, 0, 1 | DECOMP_INLINE, 0x66B4}, + {0xFA07, 0, 1 | DECOMP_INLINE, 0x8F3B}, + {0xFA08, 0, 1 | DECOMP_INLINE, 0x884C}, + {0xFA09, 0, 1 | DECOMP_INLINE, 0x964D}, + {0xFA0A, 0, 1 | DECOMP_INLINE, 0x898B}, + {0xFA0B, 0, 1 | DECOMP_INLINE, 0x5ED3}, + {0xFA0C, 0, 1 | DECOMP_INLINE, 0x5140}, + {0xFA0D, 0, 1 | DECOMP_INLINE, 0x55C0}, + {0xFA10, 0, 1 | DECOMP_INLINE, 0x585A}, + {0xFA12, 0, 1 | DECOMP_INLINE, 0x6674}, + {0xFA15, 0, 1 | DECOMP_INLINE, 0x51DE}, + {0xFA16, 0, 1 | DECOMP_INLINE, 0x732A}, + {0xFA17, 0, 1 | DECOMP_INLINE, 0x76CA}, + {0xFA18, 0, 1 | DECOMP_INLINE, 0x793C}, + {0xFA19, 0, 1 | DECOMP_INLINE, 0x795E}, + {0xFA1A, 0, 1 | DECOMP_INLINE, 0x7965}, + {0xFA1B, 0, 1 | DECOMP_INLINE, 0x798F}, + {0xFA1C, 0, 1 | DECOMP_INLINE, 0x9756}, + {0xFA1D, 0, 1 | DECOMP_INLINE, 0x7CBE}, + {0xFA1E, 0, 1 | DECOMP_INLINE, 0x7FBD}, + {0xFA20, 0, 1 | DECOMP_INLINE, 0x8612}, + {0xFA22, 0, 1 | DECOMP_INLINE, 0x8AF8}, + {0xFA25, 0, 1 | DECOMP_INLINE, 0x9038}, + {0xFA26, 0, 1 | DECOMP_INLINE, 0x90FD}, + {0xFA2A, 0, 1 | DECOMP_INLINE, 0x98EF}, + {0xFA2B, 0, 1 | DECOMP_INLINE, 0x98FC}, + {0xFA2C, 0, 1 | DECOMP_INLINE, 0x9928}, + {0xFA2D, 0, 1 | DECOMP_INLINE, 0x9DB4}, + {0xFA2E, 0, 1 | DECOMP_INLINE, 0x90DE}, + {0xFA2F, 0, 1 | DECOMP_INLINE, 0x96B7}, + {0xFA30, 0, 1 | DECOMP_INLINE, 0x4FAE}, + {0xFA31, 0, 1 | DECOMP_INLINE, 0x50E7}, + {0xFA32, 0, 1 | DECOMP_INLINE, 0x514D}, + {0xFA33, 0, 1 | DECOMP_INLINE, 0x52C9}, + {0xFA34, 0, 1 | DECOMP_INLINE, 0x52E4}, + {0xFA35, 0, 1 | DECOMP_INLINE, 0x5351}, + {0xFA36, 0, 1 | DECOMP_INLINE, 0x559D}, + {0xFA37, 0, 1 | DECOMP_INLINE, 0x5606}, + {0xFA38, 0, 1 | DECOMP_INLINE, 0x5668}, + {0xFA39, 0, 1 | DECOMP_INLINE, 0x5840}, + {0xFA3A, 0, 1 | DECOMP_INLINE, 0x58A8}, + {0xFA3B, 0, 1 | DECOMP_INLINE, 0x5C64}, + {0xFA3C, 0, 1 | DECOMP_INLINE, 0x5C6E}, + {0xFA3D, 0, 1 | DECOMP_INLINE, 0x6094}, + {0xFA3E, 0, 1 | DECOMP_INLINE, 0x6168}, + {0xFA3F, 0, 1 | DECOMP_INLINE, 0x618E}, + {0xFA40, 0, 1 | DECOMP_INLINE, 0x61F2}, + {0xFA41, 0, 1 | DECOMP_INLINE, 0x654F}, + {0xFA42, 0, 1 | DECOMP_INLINE, 0x65E2}, + {0xFA43, 0, 1 | DECOMP_INLINE, 0x6691}, + {0xFA44, 0, 1 | DECOMP_INLINE, 0x6885}, + {0xFA45, 0, 1 | DECOMP_INLINE, 0x6D77}, + {0xFA46, 0, 1 | DECOMP_INLINE, 0x6E1A}, + {0xFA47, 0, 1 | DECOMP_INLINE, 0x6F22}, + {0xFA48, 0, 1 | DECOMP_INLINE, 0x716E}, + {0xFA49, 0, 1 | DECOMP_INLINE, 0x722B}, + {0xFA4A, 0, 1 | DECOMP_INLINE, 0x7422}, + {0xFA4B, 0, 1 | DECOMP_INLINE, 0x7891}, + {0xFA4C, 0, 1 | DECOMP_INLINE, 0x793E}, + {0xFA4D, 0, 1 | DECOMP_INLINE, 0x7949}, + {0xFA4E, 0, 1 | DECOMP_INLINE, 0x7948}, + {0xFA4F, 0, 1 | DECOMP_INLINE, 0x7950}, + {0xFA50, 0, 1 | DECOMP_INLINE, 0x7956}, + {0xFA51, 0, 1 | DECOMP_INLINE, 0x795D}, + {0xFA52, 0, 1 | DECOMP_INLINE, 0x798D}, + {0xFA53, 0, 1 | DECOMP_INLINE, 0x798E}, + {0xFA54, 0, 1 | DECOMP_INLINE, 0x7A40}, + {0xFA55, 0, 1 | DECOMP_INLINE, 0x7A81}, + {0xFA56, 0, 1 | DECOMP_INLINE, 0x7BC0}, + {0xFA57, 0, 1 | DECOMP_INLINE, 0x7DF4}, + {0xFA58, 0, 1 | DECOMP_INLINE, 0x7E09}, + {0xFA59, 0, 1 | DECOMP_INLINE, 0x7E41}, + {0xFA5A, 0, 1 | DECOMP_INLINE, 0x7F72}, + {0xFA5B, 0, 1 | DECOMP_INLINE, 0x8005}, + {0xFA5C, 0, 1 | DECOMP_INLINE, 0x81ED}, + {0xFA5D, 0, 1 | DECOMP_INLINE, 0x8279}, + {0xFA5E, 0, 1 | DECOMP_INLINE, 0x8279}, + {0xFA5F, 0, 1 | DECOMP_INLINE, 0x8457}, + {0xFA60, 0, 1 | DECOMP_INLINE, 0x8910}, + {0xFA61, 0, 1 | DECOMP_INLINE, 0x8996}, + {0xFA62, 0, 1 | DECOMP_INLINE, 0x8B01}, + {0xFA63, 0, 1 | DECOMP_INLINE, 0x8B39}, + {0xFA64, 0, 1 | DECOMP_INLINE, 0x8CD3}, + {0xFA65, 0, 1 | DECOMP_INLINE, 0x8D08}, + {0xFA66, 0, 1 | DECOMP_INLINE, 0x8FB6}, + {0xFA67, 0, 1 | DECOMP_INLINE, 0x9038}, + {0xFA68, 0, 1 | DECOMP_INLINE, 0x96E3}, + {0xFA69, 0, 1 | DECOMP_INLINE, 0x97FF}, + {0xFA6A, 0, 1 | DECOMP_INLINE, 0x983B}, + {0xFA6B, 0, 1 | DECOMP_INLINE, 0x6075}, + {0xFA6C, 0, 1, 3527}, + {0xFA6D, 0, 1 | DECOMP_INLINE, 0x8218}, + {0xFA70, 0, 1 | DECOMP_INLINE, 0x4E26}, + {0xFA71, 0, 1 | DECOMP_INLINE, 0x51B5}, + {0xFA72, 0, 1 | DECOMP_INLINE, 0x5168}, + {0xFA73, 0, 1 | DECOMP_INLINE, 0x4F80}, + {0xFA74, 0, 1 | DECOMP_INLINE, 0x5145}, + {0xFA75, 0, 1 | DECOMP_INLINE, 0x5180}, + {0xFA76, 0, 1 | DECOMP_INLINE, 0x52C7}, + {0xFA77, 0, 1 | DECOMP_INLINE, 0x52FA}, + {0xFA78, 0, 1 | DECOMP_INLINE, 0x559D}, + {0xFA79, 0, 1 | DECOMP_INLINE, 0x5555}, + {0xFA7A, 0, 1 | DECOMP_INLINE, 0x5599}, + {0xFA7B, 0, 1 | DECOMP_INLINE, 0x55E2}, + {0xFA7C, 0, 1 | DECOMP_INLINE, 0x585A}, + {0xFA7D, 0, 1 | DECOMP_INLINE, 0x58B3}, + {0xFA7E, 0, 1 | DECOMP_INLINE, 0x5944}, + {0xFA7F, 0, 1 | DECOMP_INLINE, 0x5954}, + {0xFA80, 0, 1 | DECOMP_INLINE, 0x5A62}, + {0xFA81, 0, 1 | DECOMP_INLINE, 0x5B28}, + {0xFA82, 0, 1 | DECOMP_INLINE, 0x5ED2}, + {0xFA83, 0, 1 | DECOMP_INLINE, 0x5ED9}, + {0xFA84, 0, 1 | DECOMP_INLINE, 0x5F69}, + {0xFA85, 0, 1 | DECOMP_INLINE, 0x5FAD}, + {0xFA86, 0, 1 | DECOMP_INLINE, 0x60D8}, + {0xFA87, 0, 1 | DECOMP_INLINE, 0x614E}, + {0xFA88, 0, 1 | DECOMP_INLINE, 0x6108}, + {0xFA89, 0, 1 | DECOMP_INLINE, 0x618E}, + {0xFA8A, 0, 1 | DECOMP_INLINE, 0x6160}, + {0xFA8B, 0, 1 | DECOMP_INLINE, 0x61F2}, + {0xFA8C, 0, 1 | DECOMP_INLINE, 0x6234}, + {0xFA8D, 0, 1 | DECOMP_INLINE, 0x63C4}, + {0xFA8E, 0, 1 | DECOMP_INLINE, 0x641C}, + {0xFA8F, 0, 1 | DECOMP_INLINE, 0x6452}, + {0xFA90, 0, 1 | DECOMP_INLINE, 0x6556}, + {0xFA91, 0, 1 | DECOMP_INLINE, 0x6674}, + {0xFA92, 0, 1 | DECOMP_INLINE, 0x6717}, + {0xFA93, 0, 1 | DECOMP_INLINE, 0x671B}, + {0xFA94, 0, 1 | DECOMP_INLINE, 0x6756}, + {0xFA95, 0, 1 | DECOMP_INLINE, 0x6B79}, + {0xFA96, 0, 1 | DECOMP_INLINE, 0x6BBA}, + {0xFA97, 0, 1 | DECOMP_INLINE, 0x6D41}, + {0xFA98, 0, 1 | DECOMP_INLINE, 0x6EDB}, + {0xFA99, 0, 1 | DECOMP_INLINE, 0x6ECB}, + {0xFA9A, 0, 1 | DECOMP_INLINE, 0x6F22}, + {0xFA9B, 0, 1 | DECOMP_INLINE, 0x701E}, + {0xFA9C, 0, 1 | DECOMP_INLINE, 0x716E}, + {0xFA9D, 0, 1 | DECOMP_INLINE, 0x77A7}, + {0xFA9E, 0, 1 | DECOMP_INLINE, 0x7235}, + {0xFA9F, 0, 1 | DECOMP_INLINE, 0x72AF}, + {0xFAA0, 0, 1 | DECOMP_INLINE, 0x732A}, + {0xFAA1, 0, 1 | DECOMP_INLINE, 0x7471}, + {0xFAA2, 0, 1 | DECOMP_INLINE, 0x7506}, + {0xFAA3, 0, 1 | DECOMP_INLINE, 0x753B}, + {0xFAA4, 0, 1 | DECOMP_INLINE, 0x761D}, + {0xFAA5, 0, 1 | DECOMP_INLINE, 0x761F}, + {0xFAA6, 0, 1 | DECOMP_INLINE, 0x76CA}, + {0xFAA7, 0, 1 | DECOMP_INLINE, 0x76DB}, + {0xFAA8, 0, 1 | DECOMP_INLINE, 0x76F4}, + {0xFAA9, 0, 1 | DECOMP_INLINE, 0x774A}, + {0xFAAA, 0, 1 | DECOMP_INLINE, 0x7740}, + {0xFAAB, 0, 1 | DECOMP_INLINE, 0x78CC}, + {0xFAAC, 0, 1 | DECOMP_INLINE, 0x7AB1}, + {0xFAAD, 0, 1 | DECOMP_INLINE, 0x7BC0}, + {0xFAAE, 0, 1 | DECOMP_INLINE, 0x7C7B}, + {0xFAAF, 0, 1 | DECOMP_INLINE, 0x7D5B}, + {0xFAB0, 0, 1 | DECOMP_INLINE, 0x7DF4}, + {0xFAB1, 0, 1 | DECOMP_INLINE, 0x7F3E}, + {0xFAB2, 0, 1 | DECOMP_INLINE, 0x8005}, + {0xFAB3, 0, 1 | DECOMP_INLINE, 0x8352}, + {0xFAB4, 0, 1 | DECOMP_INLINE, 0x83EF}, + {0xFAB5, 0, 1 | DECOMP_INLINE, 0x8779}, + {0xFAB6, 0, 1 | DECOMP_INLINE, 0x8941}, + {0xFAB7, 0, 1 | DECOMP_INLINE, 0x8986}, + {0xFAB8, 0, 1 | DECOMP_INLINE, 0x8996}, + {0xFAB9, 0, 1 | DECOMP_INLINE, 0x8ABF}, + {0xFABA, 0, 1 | DECOMP_INLINE, 0x8AF8}, + {0xFABB, 0, 1 | DECOMP_INLINE, 0x8ACB}, + {0xFABC, 0, 1 | DECOMP_INLINE, 0x8B01}, + {0xFABD, 0, 1 | DECOMP_INLINE, 0x8AFE}, + {0xFABE, 0, 1 | DECOMP_INLINE, 0x8AED}, + {0xFABF, 0, 1 | DECOMP_INLINE, 0x8B39}, + {0xFAC0, 0, 1 | DECOMP_INLINE, 0x8B8A}, + {0xFAC1, 0, 1 | DECOMP_INLINE, 0x8D08}, + {0xFAC2, 0, 1 | DECOMP_INLINE, 0x8F38}, + {0xFAC3, 0, 1 | DECOMP_INLINE, 0x9072}, + {0xFAC4, 0, 1 | DECOMP_INLINE, 0x9199}, + {0xFAC5, 0, 1 | DECOMP_INLINE, 0x9276}, + {0xFAC6, 0, 1 | DECOMP_INLINE, 0x967C}, + {0xFAC7, 0, 1 | DECOMP_INLINE, 0x96E3}, + {0xFAC8, 0, 1 | DECOMP_INLINE, 0x9756}, + {0xFAC9, 0, 1 | DECOMP_INLINE, 0x97DB}, + {0xFACA, 0, 1 | DECOMP_INLINE, 0x97FF}, + {0xFACB, 0, 1 | DECOMP_INLINE, 0x980B}, + {0xFACC, 0, 1 | DECOMP_INLINE, 0x983B}, + {0xFACD, 0, 1 | DECOMP_INLINE, 0x9B12}, + {0xFACE, 0, 1 | DECOMP_INLINE, 0x9F9C}, + {0xFACF, 0, 1, 3528}, + {0xFAD0, 0, 1, 3529}, + {0xFAD1, 0, 1, 3530}, + {0xFAD2, 0, 1 | DECOMP_INLINE, 0x3B9D}, + {0xFAD3, 0, 1 | DECOMP_INLINE, 0x4018}, + {0xFAD4, 0, 1 | DECOMP_INLINE, 0x4039}, + {0xFAD5, 0, 1, 3531}, + {0xFAD6, 0, 1, 3532}, + {0xFAD7, 0, 1, 3533}, + {0xFAD8, 0, 1 | DECOMP_INLINE, 0x9F43}, + {0xFAD9, 0, 1 | DECOMP_INLINE, 0x9F8E}, + {0xFB00, 0, 2 | DECOMP_COMPAT, 3534}, + {0xFB01, 0, 2 | DECOMP_COMPAT, 3536}, + {0xFB02, 0, 2 | DECOMP_COMPAT, 3538}, + {0xFB03, 0, 3 | DECOMP_COMPAT, 3540}, + {0xFB04, 0, 3 | DECOMP_COMPAT, 3543}, + {0xFB05, 0, 2 | DECOMP_COMPAT, 3546}, + {0xFB06, 0, 2 | DECOMP_COMPAT, 3548}, + {0xFB13, 0, 2 | DECOMP_COMPAT, 3550}, + {0xFB14, 0, 2 | DECOMP_COMPAT, 3552}, + {0xFB15, 0, 2 | DECOMP_COMPAT, 3554}, + {0xFB16, 0, 2 | DECOMP_COMPAT, 3556}, + {0xFB17, 0, 2 | DECOMP_COMPAT, 3558}, + {0xFB1D, 0, 2 | DECOMP_NO_COMPOSE, 3560}, /* in exclusion list */ + {0xFB1E, 26, 0, 0}, + {0xFB1F, 0, 2 | DECOMP_NO_COMPOSE, 3562}, /* in exclusion list */ + {0xFB20, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05E2}, + {0xFB21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D0}, + {0xFB22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D3}, + {0xFB23, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D4}, + {0xFB24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05DB}, + {0xFB25, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05DC}, + {0xFB26, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05DD}, + {0xFB27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05E8}, + {0xFB28, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05EA}, + {0xFB29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, + {0xFB2A, 0, 2 | DECOMP_NO_COMPOSE, 3564}, /* in exclusion list */ + {0xFB2B, 0, 2 | DECOMP_NO_COMPOSE, 3566}, /* in exclusion list */ + {0xFB2C, 0, 2 | DECOMP_NO_COMPOSE, 3568}, /* in exclusion list */ + {0xFB2D, 0, 2 | DECOMP_NO_COMPOSE, 3570}, /* in exclusion list */ + {0xFB2E, 0, 2 | DECOMP_NO_COMPOSE, 3572}, /* in exclusion list */ + {0xFB2F, 0, 2 | DECOMP_NO_COMPOSE, 3574}, /* in exclusion list */ + {0xFB30, 0, 2 | DECOMP_NO_COMPOSE, 3576}, /* in exclusion list */ + {0xFB31, 0, 2 | DECOMP_NO_COMPOSE, 3578}, /* in exclusion list */ + {0xFB32, 0, 2 | DECOMP_NO_COMPOSE, 3580}, /* in exclusion list */ + {0xFB33, 0, 2 | DECOMP_NO_COMPOSE, 3582}, /* in exclusion list */ + {0xFB34, 0, 2 | DECOMP_NO_COMPOSE, 3584}, /* in exclusion list */ + {0xFB35, 0, 2 | DECOMP_NO_COMPOSE, 3586}, /* in exclusion list */ + {0xFB36, 0, 2 | DECOMP_NO_COMPOSE, 3588}, /* in exclusion list */ + {0xFB38, 0, 2 | DECOMP_NO_COMPOSE, 3590}, /* in exclusion list */ + {0xFB39, 0, 2 | DECOMP_NO_COMPOSE, 3592}, /* in exclusion list */ + {0xFB3A, 0, 2 | DECOMP_NO_COMPOSE, 3594}, /* in exclusion list */ + {0xFB3B, 0, 2 | DECOMP_NO_COMPOSE, 3596}, /* in exclusion list */ + {0xFB3C, 0, 2 | DECOMP_NO_COMPOSE, 3598}, /* in exclusion list */ + {0xFB3E, 0, 2 | DECOMP_NO_COMPOSE, 3600}, /* in exclusion list */ + {0xFB40, 0, 2 | DECOMP_NO_COMPOSE, 3602}, /* in exclusion list */ + {0xFB41, 0, 2 | DECOMP_NO_COMPOSE, 3604}, /* in exclusion list */ + {0xFB43, 0, 2 | DECOMP_NO_COMPOSE, 3606}, /* in exclusion list */ + {0xFB44, 0, 2 | DECOMP_NO_COMPOSE, 3608}, /* in exclusion list */ + {0xFB46, 0, 2 | DECOMP_NO_COMPOSE, 3610}, /* in exclusion list */ + {0xFB47, 0, 2 | DECOMP_NO_COMPOSE, 3612}, /* in exclusion list */ + {0xFB48, 0, 2 | DECOMP_NO_COMPOSE, 3614}, /* in exclusion list */ + {0xFB49, 0, 2 | DECOMP_NO_COMPOSE, 3616}, /* in exclusion list */ + {0xFB4A, 0, 2 | DECOMP_NO_COMPOSE, 3618}, /* in exclusion list */ + {0xFB4B, 0, 2 | DECOMP_NO_COMPOSE, 3620}, /* in exclusion list */ + {0xFB4C, 0, 2 | DECOMP_NO_COMPOSE, 3622}, /* in exclusion list */ + {0xFB4D, 0, 2 | DECOMP_NO_COMPOSE, 3624}, /* in exclusion list */ + {0xFB4E, 0, 2 | DECOMP_NO_COMPOSE, 3626}, /* in exclusion list */ + {0xFB4F, 0, 2 | DECOMP_COMPAT, 3628}, + {0xFB50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0671}, + {0xFB51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0671}, + {0xFB52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, + {0xFB53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, + {0xFB54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, + {0xFB55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, + {0xFB56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, + {0xFB57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, + {0xFB58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, + {0xFB59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, + {0xFB5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, + {0xFB5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, + {0xFB5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, + {0xFB5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, + {0xFB5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, + {0xFB5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, + {0xFB60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, + {0xFB61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, + {0xFB62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, + {0xFB63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, + {0xFB64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, + {0xFB65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, + {0xFB66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, + {0xFB67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, + {0xFB68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, + {0xFB69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, + {0xFB6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, + {0xFB6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, + {0xFB6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, + {0xFB6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, + {0xFB6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, + {0xFB6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, + {0xFB70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, + {0xFB71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, + {0xFB72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, + {0xFB73, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, + {0xFB74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, + {0xFB75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, + {0xFB76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, + {0xFB77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, + {0xFB78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, + {0xFB79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, + {0xFB7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, + {0xFB7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, + {0xFB7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, + {0xFB7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, + {0xFB7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, + {0xFB7F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, + {0xFB80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, + {0xFB81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, + {0xFB82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068D}, + {0xFB83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068D}, + {0xFB84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068C}, + {0xFB85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068C}, + {0xFB86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068E}, + {0xFB87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068E}, + {0xFB88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0688}, + {0xFB89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0688}, + {0xFB8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0698}, + {0xFB8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0698}, + {0xFB8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0691}, + {0xFB8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0691}, + {0xFB8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, + {0xFB8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, + {0xFB90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, + {0xFB91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, + {0xFB92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, + {0xFB93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, + {0xFB94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, + {0xFB95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, + {0xFB96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, + {0xFB97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, + {0xFB98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, + {0xFB99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, + {0xFB9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, + {0xFB9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, + {0xFB9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, + {0xFB9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, + {0xFB9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, + {0xFB9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, + {0xFBA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, + {0xFBA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, + {0xFBA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, + {0xFBA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, + {0xFBA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C0}, + {0xFBA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C0}, + {0xFBA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, + {0xFBA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, + {0xFBA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, + {0xFBA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, + {0xFBAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, + {0xFBAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, + {0xFBAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, + {0xFBAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, + {0xFBAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D2}, + {0xFBAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D2}, + {0xFBB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D3}, + {0xFBB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D3}, + {0xFBD3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, + {0xFBD4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, + {0xFBD5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, + {0xFBD6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, + {0xFBD7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C7}, + {0xFBD8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C7}, + {0xFBD9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C6}, + {0xFBDA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C6}, + {0xFBDB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C8}, + {0xFBDC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C8}, + {0xFBDD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0677}, + {0xFBDE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CB}, + {0xFBDF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CB}, + {0xFBE0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C5}, + {0xFBE1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C5}, + {0xFBE2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C9}, + {0xFBE3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C9}, + {0xFBE4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, + {0xFBE5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, + {0xFBE6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, + {0xFBE7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, + {0xFBE8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, + {0xFBE9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, + {0xFBEA, 0, 2 | DECOMP_COMPAT, 3630}, + {0xFBEB, 0, 2 | DECOMP_COMPAT, 3632}, + {0xFBEC, 0, 2 | DECOMP_COMPAT, 3634}, + {0xFBED, 0, 2 | DECOMP_COMPAT, 3636}, + {0xFBEE, 0, 2 | DECOMP_COMPAT, 3638}, + {0xFBEF, 0, 2 | DECOMP_COMPAT, 3640}, + {0xFBF0, 0, 2 | DECOMP_COMPAT, 3642}, + {0xFBF1, 0, 2 | DECOMP_COMPAT, 3644}, + {0xFBF2, 0, 2 | DECOMP_COMPAT, 3646}, + {0xFBF3, 0, 2 | DECOMP_COMPAT, 3648}, + {0xFBF4, 0, 2 | DECOMP_COMPAT, 3650}, + {0xFBF5, 0, 2 | DECOMP_COMPAT, 3652}, + {0xFBF6, 0, 2 | DECOMP_COMPAT, 3654}, + {0xFBF7, 0, 2 | DECOMP_COMPAT, 3656}, + {0xFBF8, 0, 2 | DECOMP_COMPAT, 3658}, + {0xFBF9, 0, 2 | DECOMP_COMPAT, 3660}, + {0xFBFA, 0, 2 | DECOMP_COMPAT, 3662}, + {0xFBFB, 0, 2 | DECOMP_COMPAT, 3664}, + {0xFBFC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, + {0xFBFD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, + {0xFBFE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, + {0xFBFF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, + {0xFC00, 0, 2 | DECOMP_COMPAT, 3666}, + {0xFC01, 0, 2 | DECOMP_COMPAT, 3668}, + {0xFC02, 0, 2 | DECOMP_COMPAT, 3670}, + {0xFC03, 0, 2 | DECOMP_COMPAT, 3672}, + {0xFC04, 0, 2 | DECOMP_COMPAT, 3674}, + {0xFC05, 0, 2 | DECOMP_COMPAT, 3676}, + {0xFC06, 0, 2 | DECOMP_COMPAT, 3678}, + {0xFC07, 0, 2 | DECOMP_COMPAT, 3680}, + {0xFC08, 0, 2 | DECOMP_COMPAT, 3682}, + {0xFC09, 0, 2 | DECOMP_COMPAT, 3684}, + {0xFC0A, 0, 2 | DECOMP_COMPAT, 3686}, + {0xFC0B, 0, 2 | DECOMP_COMPAT, 3688}, + {0xFC0C, 0, 2 | DECOMP_COMPAT, 3690}, + {0xFC0D, 0, 2 | DECOMP_COMPAT, 3692}, + {0xFC0E, 0, 2 | DECOMP_COMPAT, 3694}, + {0xFC0F, 0, 2 | DECOMP_COMPAT, 3696}, + {0xFC10, 0, 2 | DECOMP_COMPAT, 3698}, + {0xFC11, 0, 2 | DECOMP_COMPAT, 3700}, + {0xFC12, 0, 2 | DECOMP_COMPAT, 3702}, + {0xFC13, 0, 2 | DECOMP_COMPAT, 3704}, + {0xFC14, 0, 2 | DECOMP_COMPAT, 3706}, + {0xFC15, 0, 2 | DECOMP_COMPAT, 3708}, + {0xFC16, 0, 2 | DECOMP_COMPAT, 3710}, + {0xFC17, 0, 2 | DECOMP_COMPAT, 3712}, + {0xFC18, 0, 2 | DECOMP_COMPAT, 3714}, + {0xFC19, 0, 2 | DECOMP_COMPAT, 3716}, + {0xFC1A, 0, 2 | DECOMP_COMPAT, 3718}, + {0xFC1B, 0, 2 | DECOMP_COMPAT, 3720}, + {0xFC1C, 0, 2 | DECOMP_COMPAT, 3722}, + {0xFC1D, 0, 2 | DECOMP_COMPAT, 3724}, + {0xFC1E, 0, 2 | DECOMP_COMPAT, 3726}, + {0xFC1F, 0, 2 | DECOMP_COMPAT, 3728}, + {0xFC20, 0, 2 | DECOMP_COMPAT, 3730}, + {0xFC21, 0, 2 | DECOMP_COMPAT, 3732}, + {0xFC22, 0, 2 | DECOMP_COMPAT, 3734}, + {0xFC23, 0, 2 | DECOMP_COMPAT, 3736}, + {0xFC24, 0, 2 | DECOMP_COMPAT, 3738}, + {0xFC25, 0, 2 | DECOMP_COMPAT, 3740}, + {0xFC26, 0, 2 | DECOMP_COMPAT, 3742}, + {0xFC27, 0, 2 | DECOMP_COMPAT, 3744}, + {0xFC28, 0, 2 | DECOMP_COMPAT, 3746}, + {0xFC29, 0, 2 | DECOMP_COMPAT, 3748}, + {0xFC2A, 0, 2 | DECOMP_COMPAT, 3750}, + {0xFC2B, 0, 2 | DECOMP_COMPAT, 3752}, + {0xFC2C, 0, 2 | DECOMP_COMPAT, 3754}, + {0xFC2D, 0, 2 | DECOMP_COMPAT, 3756}, + {0xFC2E, 0, 2 | DECOMP_COMPAT, 3758}, + {0xFC2F, 0, 2 | DECOMP_COMPAT, 3760}, + {0xFC30, 0, 2 | DECOMP_COMPAT, 3762}, + {0xFC31, 0, 2 | DECOMP_COMPAT, 3764}, + {0xFC32, 0, 2 | DECOMP_COMPAT, 3766}, + {0xFC33, 0, 2 | DECOMP_COMPAT, 3768}, + {0xFC34, 0, 2 | DECOMP_COMPAT, 3770}, + {0xFC35, 0, 2 | DECOMP_COMPAT, 3772}, + {0xFC36, 0, 2 | DECOMP_COMPAT, 3774}, + {0xFC37, 0, 2 | DECOMP_COMPAT, 3776}, + {0xFC38, 0, 2 | DECOMP_COMPAT, 3778}, + {0xFC39, 0, 2 | DECOMP_COMPAT, 3780}, + {0xFC3A, 0, 2 | DECOMP_COMPAT, 3782}, + {0xFC3B, 0, 2 | DECOMP_COMPAT, 3784}, + {0xFC3C, 0, 2 | DECOMP_COMPAT, 3786}, + {0xFC3D, 0, 2 | DECOMP_COMPAT, 3788}, + {0xFC3E, 0, 2 | DECOMP_COMPAT, 3790}, + {0xFC3F, 0, 2 | DECOMP_COMPAT, 3792}, + {0xFC40, 0, 2 | DECOMP_COMPAT, 3794}, + {0xFC41, 0, 2 | DECOMP_COMPAT, 3796}, + {0xFC42, 0, 2 | DECOMP_COMPAT, 3798}, + {0xFC43, 0, 2 | DECOMP_COMPAT, 3800}, + {0xFC44, 0, 2 | DECOMP_COMPAT, 3802}, + {0xFC45, 0, 2 | DECOMP_COMPAT, 3804}, + {0xFC46, 0, 2 | DECOMP_COMPAT, 3806}, + {0xFC47, 0, 2 | DECOMP_COMPAT, 3808}, + {0xFC48, 0, 2 | DECOMP_COMPAT, 3810}, + {0xFC49, 0, 2 | DECOMP_COMPAT, 3812}, + {0xFC4A, 0, 2 | DECOMP_COMPAT, 3814}, + {0xFC4B, 0, 2 | DECOMP_COMPAT, 3816}, + {0xFC4C, 0, 2 | DECOMP_COMPAT, 3818}, + {0xFC4D, 0, 2 | DECOMP_COMPAT, 3820}, + {0xFC4E, 0, 2 | DECOMP_COMPAT, 3822}, + {0xFC4F, 0, 2 | DECOMP_COMPAT, 3824}, + {0xFC50, 0, 2 | DECOMP_COMPAT, 3826}, + {0xFC51, 0, 2 | DECOMP_COMPAT, 3828}, + {0xFC52, 0, 2 | DECOMP_COMPAT, 3830}, + {0xFC53, 0, 2 | DECOMP_COMPAT, 3832}, + {0xFC54, 0, 2 | DECOMP_COMPAT, 3834}, + {0xFC55, 0, 2 | DECOMP_COMPAT, 3836}, + {0xFC56, 0, 2 | DECOMP_COMPAT, 3838}, + {0xFC57, 0, 2 | DECOMP_COMPAT, 3840}, + {0xFC58, 0, 2 | DECOMP_COMPAT, 3842}, + {0xFC59, 0, 2 | DECOMP_COMPAT, 3844}, + {0xFC5A, 0, 2 | DECOMP_COMPAT, 3846}, + {0xFC5B, 0, 2 | DECOMP_COMPAT, 3848}, + {0xFC5C, 0, 2 | DECOMP_COMPAT, 3850}, + {0xFC5D, 0, 2 | DECOMP_COMPAT, 3852}, + {0xFC5E, 0, 3 | DECOMP_COMPAT, 3854}, + {0xFC5F, 0, 3 | DECOMP_COMPAT, 3857}, + {0xFC60, 0, 3 | DECOMP_COMPAT, 3860}, + {0xFC61, 0, 3 | DECOMP_COMPAT, 3863}, + {0xFC62, 0, 3 | DECOMP_COMPAT, 3866}, + {0xFC63, 0, 3 | DECOMP_COMPAT, 3869}, + {0xFC64, 0, 2 | DECOMP_COMPAT, 3872}, + {0xFC65, 0, 2 | DECOMP_COMPAT, 3874}, + {0xFC66, 0, 2 | DECOMP_COMPAT, 3876}, + {0xFC67, 0, 2 | DECOMP_COMPAT, 3878}, + {0xFC68, 0, 2 | DECOMP_COMPAT, 3880}, + {0xFC69, 0, 2 | DECOMP_COMPAT, 3882}, + {0xFC6A, 0, 2 | DECOMP_COMPAT, 3884}, + {0xFC6B, 0, 2 | DECOMP_COMPAT, 3886}, + {0xFC6C, 0, 2 | DECOMP_COMPAT, 3888}, + {0xFC6D, 0, 2 | DECOMP_COMPAT, 3890}, + {0xFC6E, 0, 2 | DECOMP_COMPAT, 3892}, + {0xFC6F, 0, 2 | DECOMP_COMPAT, 3894}, + {0xFC70, 0, 2 | DECOMP_COMPAT, 3896}, + {0xFC71, 0, 2 | DECOMP_COMPAT, 3898}, + {0xFC72, 0, 2 | DECOMP_COMPAT, 3900}, + {0xFC73, 0, 2 | DECOMP_COMPAT, 3902}, + {0xFC74, 0, 2 | DECOMP_COMPAT, 3904}, + {0xFC75, 0, 2 | DECOMP_COMPAT, 3906}, + {0xFC76, 0, 2 | DECOMP_COMPAT, 3908}, + {0xFC77, 0, 2 | DECOMP_COMPAT, 3910}, + {0xFC78, 0, 2 | DECOMP_COMPAT, 3912}, + {0xFC79, 0, 2 | DECOMP_COMPAT, 3914}, + {0xFC7A, 0, 2 | DECOMP_COMPAT, 3916}, + {0xFC7B, 0, 2 | DECOMP_COMPAT, 3918}, + {0xFC7C, 0, 2 | DECOMP_COMPAT, 3920}, + {0xFC7D, 0, 2 | DECOMP_COMPAT, 3922}, + {0xFC7E, 0, 2 | DECOMP_COMPAT, 3924}, + {0xFC7F, 0, 2 | DECOMP_COMPAT, 3926}, + {0xFC80, 0, 2 | DECOMP_COMPAT, 3928}, + {0xFC81, 0, 2 | DECOMP_COMPAT, 3930}, + {0xFC82, 0, 2 | DECOMP_COMPAT, 3932}, + {0xFC83, 0, 2 | DECOMP_COMPAT, 3934}, + {0xFC84, 0, 2 | DECOMP_COMPAT, 3936}, + {0xFC85, 0, 2 | DECOMP_COMPAT, 3938}, + {0xFC86, 0, 2 | DECOMP_COMPAT, 3940}, + {0xFC87, 0, 2 | DECOMP_COMPAT, 3942}, + {0xFC88, 0, 2 | DECOMP_COMPAT, 3944}, + {0xFC89, 0, 2 | DECOMP_COMPAT, 3946}, + {0xFC8A, 0, 2 | DECOMP_COMPAT, 3948}, + {0xFC8B, 0, 2 | DECOMP_COMPAT, 3950}, + {0xFC8C, 0, 2 | DECOMP_COMPAT, 3952}, + {0xFC8D, 0, 2 | DECOMP_COMPAT, 3954}, + {0xFC8E, 0, 2 | DECOMP_COMPAT, 3956}, + {0xFC8F, 0, 2 | DECOMP_COMPAT, 3958}, + {0xFC90, 0, 2 | DECOMP_COMPAT, 3960}, + {0xFC91, 0, 2 | DECOMP_COMPAT, 3962}, + {0xFC92, 0, 2 | DECOMP_COMPAT, 3964}, + {0xFC93, 0, 2 | DECOMP_COMPAT, 3966}, + {0xFC94, 0, 2 | DECOMP_COMPAT, 3968}, + {0xFC95, 0, 2 | DECOMP_COMPAT, 3970}, + {0xFC96, 0, 2 | DECOMP_COMPAT, 3972}, + {0xFC97, 0, 2 | DECOMP_COMPAT, 3974}, + {0xFC98, 0, 2 | DECOMP_COMPAT, 3976}, + {0xFC99, 0, 2 | DECOMP_COMPAT, 3978}, + {0xFC9A, 0, 2 | DECOMP_COMPAT, 3980}, + {0xFC9B, 0, 2 | DECOMP_COMPAT, 3982}, + {0xFC9C, 0, 2 | DECOMP_COMPAT, 3984}, + {0xFC9D, 0, 2 | DECOMP_COMPAT, 3986}, + {0xFC9E, 0, 2 | DECOMP_COMPAT, 3988}, + {0xFC9F, 0, 2 | DECOMP_COMPAT, 3990}, + {0xFCA0, 0, 2 | DECOMP_COMPAT, 3992}, + {0xFCA1, 0, 2 | DECOMP_COMPAT, 3994}, + {0xFCA2, 0, 2 | DECOMP_COMPAT, 3996}, + {0xFCA3, 0, 2 | DECOMP_COMPAT, 3998}, + {0xFCA4, 0, 2 | DECOMP_COMPAT, 4000}, + {0xFCA5, 0, 2 | DECOMP_COMPAT, 4002}, + {0xFCA6, 0, 2 | DECOMP_COMPAT, 4004}, + {0xFCA7, 0, 2 | DECOMP_COMPAT, 4006}, + {0xFCA8, 0, 2 | DECOMP_COMPAT, 4008}, + {0xFCA9, 0, 2 | DECOMP_COMPAT, 4010}, + {0xFCAA, 0, 2 | DECOMP_COMPAT, 4012}, + {0xFCAB, 0, 2 | DECOMP_COMPAT, 4014}, + {0xFCAC, 0, 2 | DECOMP_COMPAT, 4016}, + {0xFCAD, 0, 2 | DECOMP_COMPAT, 4018}, + {0xFCAE, 0, 2 | DECOMP_COMPAT, 4020}, + {0xFCAF, 0, 2 | DECOMP_COMPAT, 4022}, + {0xFCB0, 0, 2 | DECOMP_COMPAT, 4024}, + {0xFCB1, 0, 2 | DECOMP_COMPAT, 4026}, + {0xFCB2, 0, 2 | DECOMP_COMPAT, 4028}, + {0xFCB3, 0, 2 | DECOMP_COMPAT, 4030}, + {0xFCB4, 0, 2 | DECOMP_COMPAT, 4032}, + {0xFCB5, 0, 2 | DECOMP_COMPAT, 4034}, + {0xFCB6, 0, 2 | DECOMP_COMPAT, 4036}, + {0xFCB7, 0, 2 | DECOMP_COMPAT, 4038}, + {0xFCB8, 0, 2 | DECOMP_COMPAT, 4040}, + {0xFCB9, 0, 2 | DECOMP_COMPAT, 4042}, + {0xFCBA, 0, 2 | DECOMP_COMPAT, 4044}, + {0xFCBB, 0, 2 | DECOMP_COMPAT, 4046}, + {0xFCBC, 0, 2 | DECOMP_COMPAT, 4048}, + {0xFCBD, 0, 2 | DECOMP_COMPAT, 4050}, + {0xFCBE, 0, 2 | DECOMP_COMPAT, 4052}, + {0xFCBF, 0, 2 | DECOMP_COMPAT, 4054}, + {0xFCC0, 0, 2 | DECOMP_COMPAT, 4056}, + {0xFCC1, 0, 2 | DECOMP_COMPAT, 4058}, + {0xFCC2, 0, 2 | DECOMP_COMPAT, 4060}, + {0xFCC3, 0, 2 | DECOMP_COMPAT, 4062}, + {0xFCC4, 0, 2 | DECOMP_COMPAT, 4064}, + {0xFCC5, 0, 2 | DECOMP_COMPAT, 4066}, + {0xFCC6, 0, 2 | DECOMP_COMPAT, 4068}, + {0xFCC7, 0, 2 | DECOMP_COMPAT, 4070}, + {0xFCC8, 0, 2 | DECOMP_COMPAT, 4072}, + {0xFCC9, 0, 2 | DECOMP_COMPAT, 4074}, + {0xFCCA, 0, 2 | DECOMP_COMPAT, 4076}, + {0xFCCB, 0, 2 | DECOMP_COMPAT, 4078}, + {0xFCCC, 0, 2 | DECOMP_COMPAT, 4080}, + {0xFCCD, 0, 2 | DECOMP_COMPAT, 4082}, + {0xFCCE, 0, 2 | DECOMP_COMPAT, 4084}, + {0xFCCF, 0, 2 | DECOMP_COMPAT, 4086}, + {0xFCD0, 0, 2 | DECOMP_COMPAT, 4088}, + {0xFCD1, 0, 2 | DECOMP_COMPAT, 4090}, + {0xFCD2, 0, 2 | DECOMP_COMPAT, 4092}, + {0xFCD3, 0, 2 | DECOMP_COMPAT, 4094}, + {0xFCD4, 0, 2 | DECOMP_COMPAT, 4096}, + {0xFCD5, 0, 2 | DECOMP_COMPAT, 4098}, + {0xFCD6, 0, 2 | DECOMP_COMPAT, 4100}, + {0xFCD7, 0, 2 | DECOMP_COMPAT, 4102}, + {0xFCD8, 0, 2 | DECOMP_COMPAT, 4104}, + {0xFCD9, 0, 2 | DECOMP_COMPAT, 4106}, + {0xFCDA, 0, 2 | DECOMP_COMPAT, 4108}, + {0xFCDB, 0, 2 | DECOMP_COMPAT, 4110}, + {0xFCDC, 0, 2 | DECOMP_COMPAT, 4112}, + {0xFCDD, 0, 2 | DECOMP_COMPAT, 4114}, + {0xFCDE, 0, 2 | DECOMP_COMPAT, 4116}, + {0xFCDF, 0, 2 | DECOMP_COMPAT, 4118}, + {0xFCE0, 0, 2 | DECOMP_COMPAT, 4120}, + {0xFCE1, 0, 2 | DECOMP_COMPAT, 4122}, + {0xFCE2, 0, 2 | DECOMP_COMPAT, 4124}, + {0xFCE3, 0, 2 | DECOMP_COMPAT, 4126}, + {0xFCE4, 0, 2 | DECOMP_COMPAT, 4128}, + {0xFCE5, 0, 2 | DECOMP_COMPAT, 4130}, + {0xFCE6, 0, 2 | DECOMP_COMPAT, 4132}, + {0xFCE7, 0, 2 | DECOMP_COMPAT, 4134}, + {0xFCE8, 0, 2 | DECOMP_COMPAT, 4136}, + {0xFCE9, 0, 2 | DECOMP_COMPAT, 4138}, + {0xFCEA, 0, 2 | DECOMP_COMPAT, 4140}, + {0xFCEB, 0, 2 | DECOMP_COMPAT, 4142}, + {0xFCEC, 0, 2 | DECOMP_COMPAT, 4144}, + {0xFCED, 0, 2 | DECOMP_COMPAT, 4146}, + {0xFCEE, 0, 2 | DECOMP_COMPAT, 4148}, + {0xFCEF, 0, 2 | DECOMP_COMPAT, 4150}, + {0xFCF0, 0, 2 | DECOMP_COMPAT, 4152}, + {0xFCF1, 0, 2 | DECOMP_COMPAT, 4154}, + {0xFCF2, 0, 3 | DECOMP_COMPAT, 4156}, + {0xFCF3, 0, 3 | DECOMP_COMPAT, 4159}, + {0xFCF4, 0, 3 | DECOMP_COMPAT, 4162}, + {0xFCF5, 0, 2 | DECOMP_COMPAT, 4165}, + {0xFCF6, 0, 2 | DECOMP_COMPAT, 4167}, + {0xFCF7, 0, 2 | DECOMP_COMPAT, 4169}, + {0xFCF8, 0, 2 | DECOMP_COMPAT, 4171}, + {0xFCF9, 0, 2 | DECOMP_COMPAT, 4173}, + {0xFCFA, 0, 2 | DECOMP_COMPAT, 4175}, + {0xFCFB, 0, 2 | DECOMP_COMPAT, 4177}, + {0xFCFC, 0, 2 | DECOMP_COMPAT, 4179}, + {0xFCFD, 0, 2 | DECOMP_COMPAT, 4181}, + {0xFCFE, 0, 2 | DECOMP_COMPAT, 4183}, + {0xFCFF, 0, 2 | DECOMP_COMPAT, 4185}, + {0xFD00, 0, 2 | DECOMP_COMPAT, 4187}, + {0xFD01, 0, 2 | DECOMP_COMPAT, 4189}, + {0xFD02, 0, 2 | DECOMP_COMPAT, 4191}, + {0xFD03, 0, 2 | DECOMP_COMPAT, 4193}, + {0xFD04, 0, 2 | DECOMP_COMPAT, 4195}, + {0xFD05, 0, 2 | DECOMP_COMPAT, 4197}, + {0xFD06, 0, 2 | DECOMP_COMPAT, 4199}, + {0xFD07, 0, 2 | DECOMP_COMPAT, 4201}, + {0xFD08, 0, 2 | DECOMP_COMPAT, 4203}, + {0xFD09, 0, 2 | DECOMP_COMPAT, 4205}, + {0xFD0A, 0, 2 | DECOMP_COMPAT, 4207}, + {0xFD0B, 0, 2 | DECOMP_COMPAT, 4209}, + {0xFD0C, 0, 2 | DECOMP_COMPAT, 4211}, + {0xFD0D, 0, 2 | DECOMP_COMPAT, 4213}, + {0xFD0E, 0, 2 | DECOMP_COMPAT, 4215}, + {0xFD0F, 0, 2 | DECOMP_COMPAT, 4217}, + {0xFD10, 0, 2 | DECOMP_COMPAT, 4219}, + {0xFD11, 0, 2 | DECOMP_COMPAT, 4221}, + {0xFD12, 0, 2 | DECOMP_COMPAT, 4223}, + {0xFD13, 0, 2 | DECOMP_COMPAT, 4225}, + {0xFD14, 0, 2 | DECOMP_COMPAT, 4227}, + {0xFD15, 0, 2 | DECOMP_COMPAT, 4229}, + {0xFD16, 0, 2 | DECOMP_COMPAT, 4231}, + {0xFD17, 0, 2 | DECOMP_COMPAT, 4233}, + {0xFD18, 0, 2 | DECOMP_COMPAT, 4235}, + {0xFD19, 0, 2 | DECOMP_COMPAT, 4237}, + {0xFD1A, 0, 2 | DECOMP_COMPAT, 4239}, + {0xFD1B, 0, 2 | DECOMP_COMPAT, 4241}, + {0xFD1C, 0, 2 | DECOMP_COMPAT, 4243}, + {0xFD1D, 0, 2 | DECOMP_COMPAT, 4245}, + {0xFD1E, 0, 2 | DECOMP_COMPAT, 4247}, + {0xFD1F, 0, 2 | DECOMP_COMPAT, 4249}, + {0xFD20, 0, 2 | DECOMP_COMPAT, 4251}, + {0xFD21, 0, 2 | DECOMP_COMPAT, 4253}, + {0xFD22, 0, 2 | DECOMP_COMPAT, 4255}, + {0xFD23, 0, 2 | DECOMP_COMPAT, 4257}, + {0xFD24, 0, 2 | DECOMP_COMPAT, 4259}, + {0xFD25, 0, 2 | DECOMP_COMPAT, 4261}, + {0xFD26, 0, 2 | DECOMP_COMPAT, 4263}, + {0xFD27, 0, 2 | DECOMP_COMPAT, 4265}, + {0xFD28, 0, 2 | DECOMP_COMPAT, 4267}, + {0xFD29, 0, 2 | DECOMP_COMPAT, 4269}, + {0xFD2A, 0, 2 | DECOMP_COMPAT, 4271}, + {0xFD2B, 0, 2 | DECOMP_COMPAT, 4273}, + {0xFD2C, 0, 2 | DECOMP_COMPAT, 4275}, + {0xFD2D, 0, 2 | DECOMP_COMPAT, 4277}, + {0xFD2E, 0, 2 | DECOMP_COMPAT, 4279}, + {0xFD2F, 0, 2 | DECOMP_COMPAT, 4281}, + {0xFD30, 0, 2 | DECOMP_COMPAT, 4283}, + {0xFD31, 0, 2 | DECOMP_COMPAT, 4285}, + {0xFD32, 0, 2 | DECOMP_COMPAT, 4287}, + {0xFD33, 0, 2 | DECOMP_COMPAT, 4289}, + {0xFD34, 0, 2 | DECOMP_COMPAT, 4291}, + {0xFD35, 0, 2 | DECOMP_COMPAT, 4293}, + {0xFD36, 0, 2 | DECOMP_COMPAT, 4295}, + {0xFD37, 0, 2 | DECOMP_COMPAT, 4297}, + {0xFD38, 0, 2 | DECOMP_COMPAT, 4299}, + {0xFD39, 0, 2 | DECOMP_COMPAT, 4301}, + {0xFD3A, 0, 2 | DECOMP_COMPAT, 4303}, + {0xFD3B, 0, 2 | DECOMP_COMPAT, 4305}, + {0xFD3C, 0, 2 | DECOMP_COMPAT, 4307}, + {0xFD3D, 0, 2 | DECOMP_COMPAT, 4309}, + {0xFD50, 0, 3 | DECOMP_COMPAT, 4311}, + {0xFD51, 0, 3 | DECOMP_COMPAT, 4314}, + {0xFD52, 0, 3 | DECOMP_COMPAT, 4317}, + {0xFD53, 0, 3 | DECOMP_COMPAT, 4320}, + {0xFD54, 0, 3 | DECOMP_COMPAT, 4323}, + {0xFD55, 0, 3 | DECOMP_COMPAT, 4326}, + {0xFD56, 0, 3 | DECOMP_COMPAT, 4329}, + {0xFD57, 0, 3 | DECOMP_COMPAT, 4332}, + {0xFD58, 0, 3 | DECOMP_COMPAT, 4335}, + {0xFD59, 0, 3 | DECOMP_COMPAT, 4338}, + {0xFD5A, 0, 3 | DECOMP_COMPAT, 4341}, + {0xFD5B, 0, 3 | DECOMP_COMPAT, 4344}, + {0xFD5C, 0, 3 | DECOMP_COMPAT, 4347}, + {0xFD5D, 0, 3 | DECOMP_COMPAT, 4350}, + {0xFD5E, 0, 3 | DECOMP_COMPAT, 4353}, + {0xFD5F, 0, 3 | DECOMP_COMPAT, 4356}, + {0xFD60, 0, 3 | DECOMP_COMPAT, 4359}, + {0xFD61, 0, 3 | DECOMP_COMPAT, 4362}, + {0xFD62, 0, 3 | DECOMP_COMPAT, 4365}, + {0xFD63, 0, 3 | DECOMP_COMPAT, 4368}, + {0xFD64, 0, 3 | DECOMP_COMPAT, 4371}, + {0xFD65, 0, 3 | DECOMP_COMPAT, 4374}, + {0xFD66, 0, 3 | DECOMP_COMPAT, 4377}, + {0xFD67, 0, 3 | DECOMP_COMPAT, 4380}, + {0xFD68, 0, 3 | DECOMP_COMPAT, 4383}, + {0xFD69, 0, 3 | DECOMP_COMPAT, 4386}, + {0xFD6A, 0, 3 | DECOMP_COMPAT, 4389}, + {0xFD6B, 0, 3 | DECOMP_COMPAT, 4392}, + {0xFD6C, 0, 3 | DECOMP_COMPAT, 4395}, + {0xFD6D, 0, 3 | DECOMP_COMPAT, 4398}, + {0xFD6E, 0, 3 | DECOMP_COMPAT, 4401}, + {0xFD6F, 0, 3 | DECOMP_COMPAT, 4404}, + {0xFD70, 0, 3 | DECOMP_COMPAT, 4407}, + {0xFD71, 0, 3 | DECOMP_COMPAT, 4410}, + {0xFD72, 0, 3 | DECOMP_COMPAT, 4413}, + {0xFD73, 0, 3 | DECOMP_COMPAT, 4416}, + {0xFD74, 0, 3 | DECOMP_COMPAT, 4419}, + {0xFD75, 0, 3 | DECOMP_COMPAT, 4422}, + {0xFD76, 0, 3 | DECOMP_COMPAT, 4425}, + {0xFD77, 0, 3 | DECOMP_COMPAT, 4428}, + {0xFD78, 0, 3 | DECOMP_COMPAT, 4431}, + {0xFD79, 0, 3 | DECOMP_COMPAT, 4434}, + {0xFD7A, 0, 3 | DECOMP_COMPAT, 4437}, + {0xFD7B, 0, 3 | DECOMP_COMPAT, 4440}, + {0xFD7C, 0, 3 | DECOMP_COMPAT, 4443}, + {0xFD7D, 0, 3 | DECOMP_COMPAT, 4446}, + {0xFD7E, 0, 3 | DECOMP_COMPAT, 4449}, + {0xFD7F, 0, 3 | DECOMP_COMPAT, 4452}, + {0xFD80, 0, 3 | DECOMP_COMPAT, 4455}, + {0xFD81, 0, 3 | DECOMP_COMPAT, 4458}, + {0xFD82, 0, 3 | DECOMP_COMPAT, 4461}, + {0xFD83, 0, 3 | DECOMP_COMPAT, 4464}, + {0xFD84, 0, 3 | DECOMP_COMPAT, 4467}, + {0xFD85, 0, 3 | DECOMP_COMPAT, 4470}, + {0xFD86, 0, 3 | DECOMP_COMPAT, 4473}, + {0xFD87, 0, 3 | DECOMP_COMPAT, 4476}, + {0xFD88, 0, 3 | DECOMP_COMPAT, 4479}, + {0xFD89, 0, 3 | DECOMP_COMPAT, 4482}, + {0xFD8A, 0, 3 | DECOMP_COMPAT, 4485}, + {0xFD8B, 0, 3 | DECOMP_COMPAT, 4488}, + {0xFD8C, 0, 3 | DECOMP_COMPAT, 4491}, + {0xFD8D, 0, 3 | DECOMP_COMPAT, 4494}, + {0xFD8E, 0, 3 | DECOMP_COMPAT, 4497}, + {0xFD8F, 0, 3 | DECOMP_COMPAT, 4500}, + {0xFD92, 0, 3 | DECOMP_COMPAT, 4503}, + {0xFD93, 0, 3 | DECOMP_COMPAT, 4506}, + {0xFD94, 0, 3 | DECOMP_COMPAT, 4509}, + {0xFD95, 0, 3 | DECOMP_COMPAT, 4512}, + {0xFD96, 0, 3 | DECOMP_COMPAT, 4515}, + {0xFD97, 0, 3 | DECOMP_COMPAT, 4518}, + {0xFD98, 0, 3 | DECOMP_COMPAT, 4521}, + {0xFD99, 0, 3 | DECOMP_COMPAT, 4524}, + {0xFD9A, 0, 3 | DECOMP_COMPAT, 4527}, + {0xFD9B, 0, 3 | DECOMP_COMPAT, 4530}, + {0xFD9C, 0, 3 | DECOMP_COMPAT, 4533}, + {0xFD9D, 0, 3 | DECOMP_COMPAT, 4536}, + {0xFD9E, 0, 3 | DECOMP_COMPAT, 4539}, + {0xFD9F, 0, 3 | DECOMP_COMPAT, 4542}, + {0xFDA0, 0, 3 | DECOMP_COMPAT, 4545}, + {0xFDA1, 0, 3 | DECOMP_COMPAT, 4548}, + {0xFDA2, 0, 3 | DECOMP_COMPAT, 4551}, + {0xFDA3, 0, 3 | DECOMP_COMPAT, 4554}, + {0xFDA4, 0, 3 | DECOMP_COMPAT, 4557}, + {0xFDA5, 0, 3 | DECOMP_COMPAT, 4560}, + {0xFDA6, 0, 3 | DECOMP_COMPAT, 4563}, + {0xFDA7, 0, 3 | DECOMP_COMPAT, 4566}, + {0xFDA8, 0, 3 | DECOMP_COMPAT, 4569}, + {0xFDA9, 0, 3 | DECOMP_COMPAT, 4572}, + {0xFDAA, 0, 3 | DECOMP_COMPAT, 4575}, + {0xFDAB, 0, 3 | DECOMP_COMPAT, 4578}, + {0xFDAC, 0, 3 | DECOMP_COMPAT, 4581}, + {0xFDAD, 0, 3 | DECOMP_COMPAT, 4584}, + {0xFDAE, 0, 3 | DECOMP_COMPAT, 4587}, + {0xFDAF, 0, 3 | DECOMP_COMPAT, 4590}, + {0xFDB0, 0, 3 | DECOMP_COMPAT, 4593}, + {0xFDB1, 0, 3 | DECOMP_COMPAT, 4596}, + {0xFDB2, 0, 3 | DECOMP_COMPAT, 4599}, + {0xFDB3, 0, 3 | DECOMP_COMPAT, 4602}, + {0xFDB4, 0, 3 | DECOMP_COMPAT, 4605}, + {0xFDB5, 0, 3 | DECOMP_COMPAT, 4608}, + {0xFDB6, 0, 3 | DECOMP_COMPAT, 4611}, + {0xFDB7, 0, 3 | DECOMP_COMPAT, 4614}, + {0xFDB8, 0, 3 | DECOMP_COMPAT, 4617}, + {0xFDB9, 0, 3 | DECOMP_COMPAT, 4620}, + {0xFDBA, 0, 3 | DECOMP_COMPAT, 4623}, + {0xFDBB, 0, 3 | DECOMP_COMPAT, 4626}, + {0xFDBC, 0, 3 | DECOMP_COMPAT, 4629}, + {0xFDBD, 0, 3 | DECOMP_COMPAT, 4632}, + {0xFDBE, 0, 3 | DECOMP_COMPAT, 4635}, + {0xFDBF, 0, 3 | DECOMP_COMPAT, 4638}, + {0xFDC0, 0, 3 | DECOMP_COMPAT, 4641}, + {0xFDC1, 0, 3 | DECOMP_COMPAT, 4644}, + {0xFDC2, 0, 3 | DECOMP_COMPAT, 4647}, + {0xFDC3, 0, 3 | DECOMP_COMPAT, 4650}, + {0xFDC4, 0, 3 | DECOMP_COMPAT, 4653}, + {0xFDC5, 0, 3 | DECOMP_COMPAT, 4656}, + {0xFDC6, 0, 3 | DECOMP_COMPAT, 4659}, + {0xFDC7, 0, 3 | DECOMP_COMPAT, 4662}, + {0xFDF0, 0, 3 | DECOMP_COMPAT, 4665}, + {0xFDF1, 0, 3 | DECOMP_COMPAT, 4668}, + {0xFDF2, 0, 4 | DECOMP_COMPAT, 4671}, + {0xFDF3, 0, 4 | DECOMP_COMPAT, 4675}, + {0xFDF4, 0, 4 | DECOMP_COMPAT, 4679}, + {0xFDF5, 0, 4 | DECOMP_COMPAT, 4683}, + {0xFDF6, 0, 4 | DECOMP_COMPAT, 4687}, + {0xFDF7, 0, 4 | DECOMP_COMPAT, 4691}, + {0xFDF8, 0, 4 | DECOMP_COMPAT, 4695}, + {0xFDF9, 0, 3 | DECOMP_COMPAT, 4699}, + {0xFDFA, 0, 18 | DECOMP_COMPAT, 4702}, + {0xFDFB, 0, 8 | DECOMP_COMPAT, 4720}, + {0xFDFC, 0, 4 | DECOMP_COMPAT, 4728}, + {0xFE10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002C}, + {0xFE11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3001}, + {0xFE12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3002}, + {0xFE13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003A}, + {0xFE14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003B}, + {0xFE15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0021}, + {0xFE16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003F}, + {0xFE17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3016}, + {0xFE18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3017}, + {0xFE19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2026}, + {0xFE20, 230, 0, 0}, + {0xFE21, 230, 0, 0}, + {0xFE22, 230, 0, 0}, + {0xFE23, 230, 0, 0}, + {0xFE24, 230, 0, 0}, + {0xFE25, 230, 0, 0}, + {0xFE26, 230, 0, 0}, + {0xFE27, 220, 0, 0}, + {0xFE28, 220, 0, 0}, + {0xFE29, 220, 0, 0}, + {0xFE2A, 220, 0, 0}, + {0xFE2B, 220, 0, 0}, + {0xFE2C, 220, 0, 0}, + {0xFE2D, 220, 0, 0}, + {0xFE2E, 230, 0, 0}, + {0xFE2F, 230, 0, 0}, + {0xFE30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2025}, + {0xFE31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2014}, + {0xFE32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2013}, + {0xFE33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, + {0xFE34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, + {0xFE35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, + {0xFE36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, + {0xFE37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007B}, + {0xFE38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007D}, + {0xFE39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3014}, + {0xFE3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3015}, + {0xFE3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3010}, + {0xFE3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3011}, + {0xFE3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300A}, + {0xFE3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300B}, + {0xFE3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3008}, + {0xFE40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3009}, + {0xFE41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300C}, + {0xFE42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300D}, + {0xFE43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300E}, + {0xFE44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300F}, + {0xFE47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005B}, + {0xFE48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005D}, + {0xFE49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, + {0xFE4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, + {0xFE4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, + {0xFE4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, + {0xFE4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, + {0xFE4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, + {0xFE4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, + {0xFE50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002C}, + {0xFE51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3001}, + {0xFE52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002E}, + {0xFE54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003B}, + {0xFE55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003A}, + {0xFE56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003F}, + {0xFE57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0021}, + {0xFE58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2014}, + {0xFE59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, + {0xFE5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, + {0xFE5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007B}, + {0xFE5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007D}, + {0xFE5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3014}, + {0xFE5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3015}, + {0xFE5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0023}, + {0xFE60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0026}, + {0xFE61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002A}, + {0xFE62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, + {0xFE63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002D}, + {0xFE64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003C}, + {0xFE65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003E}, + {0xFE66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, + {0xFE68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005C}, + {0xFE69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0024}, + {0xFE6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0025}, + {0xFE6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0040}, + {0xFE70, 0, 2 | DECOMP_COMPAT, 4732}, + {0xFE71, 0, 2 | DECOMP_COMPAT, 4734}, + {0xFE72, 0, 2 | DECOMP_COMPAT, 4736}, + {0xFE74, 0, 2 | DECOMP_COMPAT, 4738}, + {0xFE76, 0, 2 | DECOMP_COMPAT, 4740}, + {0xFE77, 0, 2 | DECOMP_COMPAT, 4742}, + {0xFE78, 0, 2 | DECOMP_COMPAT, 4744}, + {0xFE79, 0, 2 | DECOMP_COMPAT, 4746}, + {0xFE7A, 0, 2 | DECOMP_COMPAT, 4748}, + {0xFE7B, 0, 2 | DECOMP_COMPAT, 4750}, + {0xFE7C, 0, 2 | DECOMP_COMPAT, 4752}, + {0xFE7D, 0, 2 | DECOMP_COMPAT, 4754}, + {0xFE7E, 0, 2 | DECOMP_COMPAT, 4756}, + {0xFE7F, 0, 2 | DECOMP_COMPAT, 4758}, + {0xFE80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0621}, + {0xFE81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0622}, + {0xFE82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0622}, + {0xFE83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0623}, + {0xFE84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0623}, + {0xFE85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0624}, + {0xFE86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0624}, + {0xFE87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0625}, + {0xFE88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0625}, + {0xFE89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, + {0xFE8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, + {0xFE8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, + {0xFE8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, + {0xFE8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, + {0xFE8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, + {0xFE8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0xFE90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0xFE91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0xFE92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0xFE93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0629}, + {0xFE94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0629}, + {0xFE95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0xFE96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0xFE97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0xFE98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0xFE99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0xFE9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0xFE9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0xFE9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0xFE9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0xFE9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0xFE9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0xFEA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0xFEA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0xFEA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0xFEA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0xFEA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0xFEA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0xFEA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0xFEA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0xFEA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0xFEA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, + {0xFEAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, + {0xFEAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, + {0xFEAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, + {0xFEAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, + {0xFEAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, + {0xFEAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, + {0xFEB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, + {0xFEB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0xFEB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0xFEB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0xFEB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0xFEB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0xFEB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0xFEB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0xFEB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0xFEB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0xFEBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0xFEBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0xFEBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0xFEBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0xFEBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0xFEBF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0xFEC0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0xFEC1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0xFEC2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0xFEC3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0xFEC4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0xFEC5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0xFEC6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0xFEC7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0xFEC8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0xFEC9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0xFECA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0xFECB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0xFECC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0xFECD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0xFECE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0xFECF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0xFED0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0xFED1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0xFED2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0xFED3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0xFED4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0xFED5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0xFED6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0xFED7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0xFED8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0xFED9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, + {0xFEDA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, + {0xFEDB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, + {0xFEDC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, + {0xFEDD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0xFEDE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0xFEDF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0xFEE0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0xFEE1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0xFEE2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0xFEE3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0xFEE4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0xFEE5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0xFEE6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0xFEE7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0xFEE8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0xFEE9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, + {0xFEEA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, + {0xFEEB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, + {0xFEEC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, + {0xFEED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, + {0xFEEE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, + {0xFEEF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, + {0xFEF0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, + {0xFEF1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0xFEF2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0xFEF3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0xFEF4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0xFEF5, 0, 2 | DECOMP_COMPAT, 4760}, + {0xFEF6, 0, 2 | DECOMP_COMPAT, 4762}, + {0xFEF7, 0, 2 | DECOMP_COMPAT, 4764}, + {0xFEF8, 0, 2 | DECOMP_COMPAT, 4766}, + {0xFEF9, 0, 2 | DECOMP_COMPAT, 4768}, + {0xFEFA, 0, 2 | DECOMP_COMPAT, 4770}, + {0xFEFB, 0, 2 | DECOMP_COMPAT, 4772}, + {0xFEFC, 0, 2 | DECOMP_COMPAT, 4774}, + {0xFF01, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0021}, + {0xFF02, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0022}, + {0xFF03, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0023}, + {0xFF04, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0024}, + {0xFF05, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0025}, + {0xFF06, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0026}, + {0xFF07, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0027}, + {0xFF08, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, + {0xFF09, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, + {0xFF0A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002A}, + {0xFF0B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, + {0xFF0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002C}, + {0xFF0D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002D}, + {0xFF0E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002E}, + {0xFF0F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002F}, + {0xFF10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0xFF11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0xFF12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0xFF13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0xFF14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0xFF15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0xFF16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0xFF17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0xFF18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0xFF19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0xFF1A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003A}, + {0xFF1B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003B}, + {0xFF1C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003C}, + {0xFF1D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, + {0xFF1E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003E}, + {0xFF1F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003F}, + {0xFF20, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0040}, + {0xFF21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0xFF22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0xFF23, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0xFF24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0xFF25, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0xFF26, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0xFF27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0xFF28, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0xFF29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0xFF2A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0xFF2B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0xFF2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0xFF2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0xFF2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0xFF2F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0xFF30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0xFF31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0xFF32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0xFF33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0xFF34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0xFF35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0xFF36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0xFF37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0xFF38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0xFF39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0xFF3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0xFF3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005B}, + {0xFF3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005C}, + {0xFF3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005D}, + {0xFF3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005E}, + {0xFF3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, + {0xFF40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0060}, + {0xFF41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0xFF42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0xFF43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0xFF44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0xFF45, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0xFF46, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0xFF47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0xFF48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0xFF49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0xFF4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0xFF4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0xFF4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0xFF4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0xFF4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0xFF4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0xFF50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0xFF51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0xFF52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0xFF53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0xFF54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0xFF55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0xFF56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0xFF57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0xFF58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0xFF59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0xFF5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0xFF5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007B}, + {0xFF5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007C}, + {0xFF5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007D}, + {0xFF5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007E}, + {0xFF5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2985}, + {0xFF60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2986}, + {0xFF61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3002}, + {0xFF62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300C}, + {0xFF63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300D}, + {0xFF64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3001}, + {0xFF65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30FB}, + {0xFF66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F2}, + {0xFF67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A1}, + {0xFF68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A3}, + {0xFF69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A5}, + {0xFF6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A7}, + {0xFF6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A9}, + {0xFF6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E3}, + {0xFF6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E5}, + {0xFF6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E7}, + {0xFF6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C3}, + {0xFF70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30FC}, + {0xFF71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A2}, + {0xFF72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A4}, + {0xFF73, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A6}, + {0xFF74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A8}, + {0xFF75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AA}, + {0xFF76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AB}, + {0xFF77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AD}, + {0xFF78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AF}, + {0xFF79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B1}, + {0xFF7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B3}, + {0xFF7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B5}, + {0xFF7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B7}, + {0xFF7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B9}, + {0xFF7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BB}, + {0xFF7F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BD}, + {0xFF80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BF}, + {0xFF81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C1}, + {0xFF82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C4}, + {0xFF83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C6}, + {0xFF84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C8}, + {0xFF85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CA}, + {0xFF86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CB}, + {0xFF87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CC}, + {0xFF88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CD}, + {0xFF89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CE}, + {0xFF8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CF}, + {0xFF8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D2}, + {0xFF8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D5}, + {0xFF8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D8}, + {0xFF8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DB}, + {0xFF8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DE}, + {0xFF90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DF}, + {0xFF91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E0}, + {0xFF92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E1}, + {0xFF93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E2}, + {0xFF94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E4}, + {0xFF95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E6}, + {0xFF96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E8}, + {0xFF97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E9}, + {0xFF98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EA}, + {0xFF99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EB}, + {0xFF9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EC}, + {0xFF9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30ED}, + {0xFF9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EF}, + {0xFF9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F3}, + {0xFF9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3099}, + {0xFF9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x309A}, + {0xFFA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3164}, + {0xFFA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3131}, + {0xFFA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3132}, + {0xFFA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3133}, + {0xFFA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3134}, + {0xFFA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3135}, + {0xFFA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3136}, + {0xFFA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3137}, + {0xFFA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3138}, + {0xFFA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3139}, + {0xFFAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313A}, + {0xFFAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313B}, + {0xFFAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313C}, + {0xFFAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313D}, + {0xFFAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313E}, + {0xFFAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313F}, + {0xFFB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3140}, + {0xFFB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3141}, + {0xFFB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3142}, + {0xFFB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3143}, + {0xFFB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3144}, + {0xFFB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3145}, + {0xFFB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3146}, + {0xFFB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3147}, + {0xFFB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3148}, + {0xFFB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3149}, + {0xFFBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314A}, + {0xFFBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314B}, + {0xFFBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314C}, + {0xFFBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314D}, + {0xFFBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314E}, + {0xFFC2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314F}, + {0xFFC3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3150}, + {0xFFC4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3151}, + {0xFFC5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3152}, + {0xFFC6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3153}, + {0xFFC7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3154}, + {0xFFCA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3155}, + {0xFFCB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3156}, + {0xFFCC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3157}, + {0xFFCD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3158}, + {0xFFCE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3159}, + {0xFFCF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315A}, + {0xFFD2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315B}, + {0xFFD3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315C}, + {0xFFD4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315D}, + {0xFFD5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315E}, + {0xFFD6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315F}, + {0xFFD7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3160}, + {0xFFDA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3161}, + {0xFFDB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3162}, + {0xFFDC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3163}, + {0xFFE0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A2}, + {0xFFE1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A3}, + {0xFFE2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00AC}, + {0xFFE3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00AF}, + {0xFFE4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A6}, + {0xFFE5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A5}, + {0xFFE6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x20A9}, + {0xFFE8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2502}, + {0xFFE9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2190}, + {0xFFEA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2191}, + {0xFFEB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2192}, + {0xFFEC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2193}, + {0xFFED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x25A0}, + {0xFFEE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x25CB}, + {0x101FD, 220, 0, 0}, + {0x102E0, 220, 0, 0}, + {0x10376, 230, 0, 0}, + {0x10377, 230, 0, 0}, + {0x10378, 230, 0, 0}, + {0x10379, 230, 0, 0}, + {0x1037A, 230, 0, 0}, + {0x10781, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02D0}, + {0x10782, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02D1}, + {0x10783, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00E6}, + {0x10784, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0299}, + {0x10785, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0253}, + {0x10787, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A3}, + {0x10788, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB66}, + {0x10789, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A5}, + {0x1078A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A4}, + {0x1078B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0256}, + {0x1078C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0257}, + {0x1078D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D91}, + {0x1078E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0258}, + {0x1078F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025E}, + {0x10790, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A9}, + {0x10791, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0264}, + {0x10792, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0262}, + {0x10793, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0260}, + {0x10794, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029B}, + {0x10795, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0127}, + {0x10796, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029C}, + {0x10797, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0267}, + {0x10798, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0284}, + {0x10799, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02AA}, + {0x1079A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02AB}, + {0x1079B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026C}, + {0x1079C, 0, 1 | DECOMP_COMPAT, 4776}, + {0x1079D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA78E}, + {0x1079E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026E}, + {0x1079F, 0, 1 | DECOMP_COMPAT, 4777}, + {0x107A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028E}, + {0x107A1, 0, 1 | DECOMP_COMPAT, 4778}, + {0x107A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00F8}, + {0x107A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0276}, + {0x107A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0277}, + {0x107A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x107A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027A}, + {0x107A7, 0, 1 | DECOMP_COMPAT, 4779}, + {0x107A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027D}, + {0x107A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027E}, + {0x107AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0280}, + {0x107AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A8}, + {0x107AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A6}, + {0x107AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB67}, + {0x107AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A7}, + {0x107AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0288}, + {0x107B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2C71}, + {0x107B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028F}, + {0x107B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A1}, + {0x107B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A2}, + {0x107B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0298}, + {0x107B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01C0}, + {0x107B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01C1}, + {0x107B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01C2}, + {0x107B9, 0, 1 | DECOMP_COMPAT, 4780}, + {0x107BA, 0, 1 | DECOMP_COMPAT, 4781}, + {0x10A0D, 220, 0, 0}, + {0x10A0F, 230, 0, 0}, + {0x10A38, 230, 0, 0}, + {0x10A39, 1, 0, 0}, + {0x10A3A, 220, 0, 0}, + {0x10A3F, 9, 0, 0}, + {0x10AE5, 230, 0, 0}, + {0x10AE6, 220, 0, 0}, + {0x10D24, 230, 0, 0}, + {0x10D25, 230, 0, 0}, + {0x10D26, 230, 0, 0}, + {0x10D27, 230, 0, 0}, + {0x10EAB, 230, 0, 0}, + {0x10EAC, 230, 0, 0}, + {0x10EFD, 220, 0, 0}, + {0x10EFE, 220, 0, 0}, + {0x10EFF, 220, 0, 0}, + {0x10F46, 220, 0, 0}, + {0x10F47, 220, 0, 0}, + {0x10F48, 230, 0, 0}, + {0x10F49, 230, 0, 0}, + {0x10F4A, 230, 0, 0}, + {0x10F4B, 220, 0, 0}, + {0x10F4C, 230, 0, 0}, + {0x10F4D, 220, 0, 0}, + {0x10F4E, 220, 0, 0}, + {0x10F4F, 220, 0, 0}, + {0x10F50, 220, 0, 0}, + {0x10F82, 230, 0, 0}, + {0x10F83, 220, 0, 0}, + {0x10F84, 230, 0, 0}, + {0x10F85, 220, 0, 0}, + {0x11046, 9, 0, 0}, + {0x11070, 9, 0, 0}, + {0x1107F, 9, 0, 0}, + {0x1109A, 0, 2, 4782}, + {0x1109C, 0, 2, 4784}, + {0x110AB, 0, 2, 4786}, + {0x110B9, 9, 0, 0}, + {0x110BA, 7, 0, 0}, + {0x11100, 230, 0, 0}, + {0x11101, 230, 0, 0}, + {0x11102, 230, 0, 0}, + {0x1112E, 0, 2, 4788}, + {0x1112F, 0, 2, 4790}, + {0x11133, 9, 0, 0}, + {0x11134, 9, 0, 0}, + {0x11173, 7, 0, 0}, + {0x111C0, 9, 0, 0}, + {0x111CA, 7, 0, 0}, + {0x11235, 9, 0, 0}, + {0x11236, 7, 0, 0}, + {0x112E9, 7, 0, 0}, + {0x112EA, 9, 0, 0}, + {0x1133B, 7, 0, 0}, + {0x1133C, 7, 0, 0}, + {0x1134B, 0, 2, 4792}, + {0x1134C, 0, 2, 4794}, + {0x1134D, 9, 0, 0}, + {0x11366, 230, 0, 0}, + {0x11367, 230, 0, 0}, + {0x11368, 230, 0, 0}, + {0x11369, 230, 0, 0}, + {0x1136A, 230, 0, 0}, + {0x1136B, 230, 0, 0}, + {0x1136C, 230, 0, 0}, + {0x11370, 230, 0, 0}, + {0x11371, 230, 0, 0}, + {0x11372, 230, 0, 0}, + {0x11373, 230, 0, 0}, + {0x11374, 230, 0, 0}, + {0x11442, 9, 0, 0}, + {0x11446, 7, 0, 0}, + {0x1145E, 230, 0, 0}, + {0x114BB, 0, 2, 4796}, + {0x114BC, 0, 2, 4798}, + {0x114BE, 0, 2, 4800}, + {0x114C2, 9, 0, 0}, + {0x114C3, 7, 0, 0}, + {0x115BA, 0, 2, 4802}, + {0x115BB, 0, 2, 4804}, + {0x115BF, 9, 0, 0}, + {0x115C0, 7, 0, 0}, + {0x1163F, 9, 0, 0}, + {0x116B6, 9, 0, 0}, + {0x116B7, 7, 0, 0}, + {0x1172B, 9, 0, 0}, + {0x11839, 9, 0, 0}, + {0x1183A, 7, 0, 0}, + {0x11938, 0, 2, 4806}, + {0x1193D, 9, 0, 0}, + {0x1193E, 9, 0, 0}, + {0x11943, 7, 0, 0}, + {0x119E0, 9, 0, 0}, + {0x11A34, 9, 0, 0}, + {0x11A47, 9, 0, 0}, + {0x11A99, 9, 0, 0}, + {0x11C3F, 9, 0, 0}, + {0x11D42, 7, 0, 0}, + {0x11D44, 9, 0, 0}, + {0x11D45, 9, 0, 0}, + {0x11D97, 9, 0, 0}, + {0x11F41, 9, 0, 0}, + {0x11F42, 9, 0, 0}, + {0x16AF0, 1, 0, 0}, + {0x16AF1, 1, 0, 0}, + {0x16AF2, 1, 0, 0}, + {0x16AF3, 1, 0, 0}, + {0x16AF4, 1, 0, 0}, + {0x16B30, 230, 0, 0}, + {0x16B31, 230, 0, 0}, + {0x16B32, 230, 0, 0}, + {0x16B33, 230, 0, 0}, + {0x16B34, 230, 0, 0}, + {0x16B35, 230, 0, 0}, + {0x16B36, 230, 0, 0}, + {0x16FF0, 6, 0, 0}, + {0x16FF1, 6, 0, 0}, + {0x1BC9E, 1, 0, 0}, + {0x1D15E, 0, 2 | DECOMP_NO_COMPOSE, 4808}, /* in exclusion list */ + {0x1D15F, 0, 2 | DECOMP_NO_COMPOSE, 4810}, /* in exclusion list */ + {0x1D160, 0, 2 | DECOMP_NO_COMPOSE, 4812}, /* in exclusion list */ + {0x1D161, 0, 2 | DECOMP_NO_COMPOSE, 4814}, /* in exclusion list */ + {0x1D162, 0, 2 | DECOMP_NO_COMPOSE, 4816}, /* in exclusion list */ + {0x1D163, 0, 2 | DECOMP_NO_COMPOSE, 4818}, /* in exclusion list */ + {0x1D164, 0, 2 | DECOMP_NO_COMPOSE, 4820}, /* in exclusion list */ + {0x1D165, 216, 0, 0}, + {0x1D166, 216, 0, 0}, + {0x1D167, 1, 0, 0}, + {0x1D168, 1, 0, 0}, + {0x1D169, 1, 0, 0}, + {0x1D16D, 226, 0, 0}, + {0x1D16E, 216, 0, 0}, + {0x1D16F, 216, 0, 0}, + {0x1D170, 216, 0, 0}, + {0x1D171, 216, 0, 0}, + {0x1D172, 216, 0, 0}, + {0x1D17B, 220, 0, 0}, + {0x1D17C, 220, 0, 0}, + {0x1D17D, 220, 0, 0}, + {0x1D17E, 220, 0, 0}, + {0x1D17F, 220, 0, 0}, + {0x1D180, 220, 0, 0}, + {0x1D181, 220, 0, 0}, + {0x1D182, 220, 0, 0}, + {0x1D185, 230, 0, 0}, + {0x1D186, 230, 0, 0}, + {0x1D187, 230, 0, 0}, + {0x1D188, 230, 0, 0}, + {0x1D189, 230, 0, 0}, + {0x1D18A, 220, 0, 0}, + {0x1D18B, 220, 0, 0}, + {0x1D1AA, 230, 0, 0}, + {0x1D1AB, 230, 0, 0}, + {0x1D1AC, 230, 0, 0}, + {0x1D1AD, 230, 0, 0}, + {0x1D1BB, 0, 2 | DECOMP_NO_COMPOSE, 4822}, /* in exclusion list */ + {0x1D1BC, 0, 2 | DECOMP_NO_COMPOSE, 4824}, /* in exclusion list */ + {0x1D1BD, 0, 2 | DECOMP_NO_COMPOSE, 4826}, /* in exclusion list */ + {0x1D1BE, 0, 2 | DECOMP_NO_COMPOSE, 4828}, /* in exclusion list */ + {0x1D1BF, 0, 2 | DECOMP_NO_COMPOSE, 4830}, /* in exclusion list */ + {0x1D1C0, 0, 2 | DECOMP_NO_COMPOSE, 4832}, /* in exclusion list */ + {0x1D242, 230, 0, 0}, + {0x1D243, 230, 0, 0}, + {0x1D244, 230, 0, 0}, + {0x1D400, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D401, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D402, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D403, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D404, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D405, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D406, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D407, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D408, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D409, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D40A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D40B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D40C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D40D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D40E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D40F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D410, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D411, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D412, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D413, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D414, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D415, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D416, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D417, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D418, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D419, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D41A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D41B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D41C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D41D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D41E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D41F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D420, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D421, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D422, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D423, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D424, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D425, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D426, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D427, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D428, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D429, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D42A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D42B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D42C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D42D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D42E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D42F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D430, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D431, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D432, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D433, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D434, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D435, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D436, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D437, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D438, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D439, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D43A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D43B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D43C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D43D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D43E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D43F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D440, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D441, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D442, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D443, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D444, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D445, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D446, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D447, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D448, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D449, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D44A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D44B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D44C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D44D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D44E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D44F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D450, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D451, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D452, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D453, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D454, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D456, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D457, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D458, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D459, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D45A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D45B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D45C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D45D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D45E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D45F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D460, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D461, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D462, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D463, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D464, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D465, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D466, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D467, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D468, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D469, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D46A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D46B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D46C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D46D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D46E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D46F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D470, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D471, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D472, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D473, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D474, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D475, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D476, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D477, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D478, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D479, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D47A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D47B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D47C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D47D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D47E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D47F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D480, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D481, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D482, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D483, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D484, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D485, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D486, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D487, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D488, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D489, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D48A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D48B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D48C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D48D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D48E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D48F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D490, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D491, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D492, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D493, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D494, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D495, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D496, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D497, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D498, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D499, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D49A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D49B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D49C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D49E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D49F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D4A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D4A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D4A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D4A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D4AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D4AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D4AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D4AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D4AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D4B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D4B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D4B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D4B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D4B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D4B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D4B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D4B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D4B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D4B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D4BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D4BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D4BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D4BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D4C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D4C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D4C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D4C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D4C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D4C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D4C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D4C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D4C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D4CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D4CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D4CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D4CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D4CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D4CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D4D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D4D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D4D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D4D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D4D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D4D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D4D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D4D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D4D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D4D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D4DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D4DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D4DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D4DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D4DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D4DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D4E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D4E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D4E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D4E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D4E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D4E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D4E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D4E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D4E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D4E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D4EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D4EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D4EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D4ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D4EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D4EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D4F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D4F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D4F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D4F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D4F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D4F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D4F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D4F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D4F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D4F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D4FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D4FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D4FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D4FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D4FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D4FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D500, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D501, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D502, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D503, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D504, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D505, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D507, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D508, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D509, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D50A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D50D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D50E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D50F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D510, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D511, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D512, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D513, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D514, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D516, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D517, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D518, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D519, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D51A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D51B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D51C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D51E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D51F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D520, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D521, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D522, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D523, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D524, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D525, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D526, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D527, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D528, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D529, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D52A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D52B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D52C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D52D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D52E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D52F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D530, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D531, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D532, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D533, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D534, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D535, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D536, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D537, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D538, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D539, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D53B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D53C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D53D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D53E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D540, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D541, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D542, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D543, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D544, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D546, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D54A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D54B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D54C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D54D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D54E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D54F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D550, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D552, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D553, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D554, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D555, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D556, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D557, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D558, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D559, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D55A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D55B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D55C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D55D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D55E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D55F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D560, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D561, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D562, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D563, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D564, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D565, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D566, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D567, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D568, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D569, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D56A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D56B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D56C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D56D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D56E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D56F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D570, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D571, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D572, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D573, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D574, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D575, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D576, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D577, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D578, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D579, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D57A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D57B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D57C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D57D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D57E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D57F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D580, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D581, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D582, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D583, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D584, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D585, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D586, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D587, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D588, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D589, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D58A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D58B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D58C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D58D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D58E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D58F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D590, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D591, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D592, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D593, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D594, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D595, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D596, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D597, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D598, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D599, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D59A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D59B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D59C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D59D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D59E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D59F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D5A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D5A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D5A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D5A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D5A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D5A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D5A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D5A7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D5A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D5A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D5AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D5AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D5AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D5AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D5AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D5AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D5B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D5B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D5B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D5B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D5B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D5B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D5B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D5B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D5B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D5B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D5BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D5BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D5BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D5BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D5BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D5BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D5C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D5C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D5C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D5C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D5C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D5C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D5C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D5C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D5C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D5C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D5CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D5CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D5CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D5CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D5CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D5CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D5D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D5D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D5D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D5D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D5D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D5D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D5D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D5D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D5D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D5D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D5DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D5DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D5DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D5DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D5DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D5DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D5E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D5E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D5E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D5E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D5E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D5E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D5E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D5E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D5E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D5E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D5EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D5EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D5EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D5ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D5EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D5EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D5F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D5F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D5F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D5F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D5F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D5F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D5F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D5F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D5F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D5F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D5FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D5FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D5FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D5FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D5FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D5FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D600, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D601, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D602, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D603, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D604, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D605, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D606, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D607, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D608, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D609, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D60A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D60B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D60C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D60D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D60E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D60F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D610, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D611, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D612, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D613, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D614, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D615, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D616, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D617, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D618, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D619, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D61A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D61B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D61C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D61D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D61E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D61F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D620, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D621, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D622, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D623, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D624, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D625, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D626, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D627, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D628, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D629, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D62A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D62B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D62C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D62D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D62E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D62F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D630, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D631, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D632, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D633, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D634, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D635, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D636, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D637, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D638, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D639, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D63A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D63B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D63C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D63D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D63E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D63F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D640, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D641, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D642, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D643, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D644, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D645, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D646, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D647, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D648, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D649, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D64A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D64B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D64C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D64D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D64E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D64F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D650, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D651, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D652, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D653, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D654, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D655, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D656, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D657, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D658, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D659, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D65A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D65B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D65C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D65D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D65E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D65F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D660, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D661, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D662, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D663, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D664, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D665, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D666, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D667, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D668, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D669, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D66A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D66B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D66C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D66D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D66E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D66F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D670, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1D671, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1D672, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1D673, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1D674, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1D675, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1D676, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1D677, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1D678, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1D679, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1D67A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1D67B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1D67C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1D67D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1D67E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1D67F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1D680, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1D681, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1D682, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1D683, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1D684, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1D685, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1D686, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1D687, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1D688, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1D689, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1D68A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, + {0x1D68B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, + {0x1D68C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, + {0x1D68D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, + {0x1D68E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, + {0x1D68F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, + {0x1D690, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, + {0x1D691, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, + {0x1D692, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, + {0x1D693, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, + {0x1D694, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, + {0x1D695, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, + {0x1D696, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, + {0x1D697, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, + {0x1D698, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, + {0x1D699, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, + {0x1D69A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, + {0x1D69B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, + {0x1D69C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, + {0x1D69D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, + {0x1D69E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, + {0x1D69F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, + {0x1D6A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, + {0x1D6A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, + {0x1D6A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, + {0x1D6A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, + {0x1D6A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0131}, + {0x1D6A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0237}, + {0x1D6A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, + {0x1D6A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, + {0x1D6AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, + {0x1D6AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, + {0x1D6AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, + {0x1D6AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, + {0x1D6AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, + {0x1D6AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, + {0x1D6B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, + {0x1D6B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, + {0x1D6B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, + {0x1D6B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, + {0x1D6B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, + {0x1D6B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, + {0x1D6B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, + {0x1D6B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, + {0x1D6B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, + {0x1D6B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, + {0x1D6BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, + {0x1D6BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, + {0x1D6BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, + {0x1D6BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, + {0x1D6BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, + {0x1D6BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, + {0x1D6C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, + {0x1D6C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, + {0x1D6C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, + {0x1D6C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x1D6C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x1D6C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, + {0x1D6C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, + {0x1D6C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, + {0x1D6C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, + {0x1D6C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, + {0x1D6CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, + {0x1D6CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, + {0x1D6CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, + {0x1D6CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, + {0x1D6CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, + {0x1D6CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, + {0x1D6D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, + {0x1D6D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, + {0x1D6D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, + {0x1D6D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, + {0x1D6D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, + {0x1D6D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, + {0x1D6D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, + {0x1D6D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x1D6D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, + {0x1D6D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, + {0x1D6DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, + {0x1D6DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, + {0x1D6DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, + {0x1D6DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, + {0x1D6DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, + {0x1D6DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, + {0x1D6E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, + {0x1D6E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, + {0x1D6E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, + {0x1D6E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, + {0x1D6E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, + {0x1D6E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, + {0x1D6E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, + {0x1D6E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, + {0x1D6E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, + {0x1D6E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, + {0x1D6EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, + {0x1D6EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, + {0x1D6EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, + {0x1D6ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, + {0x1D6EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, + {0x1D6EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, + {0x1D6F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, + {0x1D6F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, + {0x1D6F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, + {0x1D6F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, + {0x1D6F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, + {0x1D6F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, + {0x1D6F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, + {0x1D6F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, + {0x1D6F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, + {0x1D6F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, + {0x1D6FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, + {0x1D6FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, + {0x1D6FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, + {0x1D6FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x1D6FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x1D6FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, + {0x1D700, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, + {0x1D701, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, + {0x1D702, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, + {0x1D703, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, + {0x1D704, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, + {0x1D705, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, + {0x1D706, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, + {0x1D707, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, + {0x1D708, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, + {0x1D709, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, + {0x1D70A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, + {0x1D70B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, + {0x1D70C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, + {0x1D70D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, + {0x1D70E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, + {0x1D70F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, + {0x1D710, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, + {0x1D711, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x1D712, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, + {0x1D713, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, + {0x1D714, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, + {0x1D715, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, + {0x1D716, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, + {0x1D717, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, + {0x1D718, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, + {0x1D719, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, + {0x1D71A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, + {0x1D71B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, + {0x1D71C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, + {0x1D71D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, + {0x1D71E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, + {0x1D71F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, + {0x1D720, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, + {0x1D721, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, + {0x1D722, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, + {0x1D723, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, + {0x1D724, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, + {0x1D725, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, + {0x1D726, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, + {0x1D727, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, + {0x1D728, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, + {0x1D729, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, + {0x1D72A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, + {0x1D72B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, + {0x1D72C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, + {0x1D72D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, + {0x1D72E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, + {0x1D72F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, + {0x1D730, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, + {0x1D731, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, + {0x1D732, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, + {0x1D733, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, + {0x1D734, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, + {0x1D735, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, + {0x1D736, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, + {0x1D737, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x1D738, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x1D739, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, + {0x1D73A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, + {0x1D73B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, + {0x1D73C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, + {0x1D73D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, + {0x1D73E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, + {0x1D73F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, + {0x1D740, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, + {0x1D741, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, + {0x1D742, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, + {0x1D743, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, + {0x1D744, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, + {0x1D745, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, + {0x1D746, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, + {0x1D747, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, + {0x1D748, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, + {0x1D749, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, + {0x1D74A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, + {0x1D74B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x1D74C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, + {0x1D74D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, + {0x1D74E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, + {0x1D74F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, + {0x1D750, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, + {0x1D751, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, + {0x1D752, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, + {0x1D753, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, + {0x1D754, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, + {0x1D755, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, + {0x1D756, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, + {0x1D757, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, + {0x1D758, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, + {0x1D759, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, + {0x1D75A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, + {0x1D75B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, + {0x1D75C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, + {0x1D75D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, + {0x1D75E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, + {0x1D75F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, + {0x1D760, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, + {0x1D761, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, + {0x1D762, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, + {0x1D763, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, + {0x1D764, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, + {0x1D765, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, + {0x1D766, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, + {0x1D767, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, + {0x1D768, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, + {0x1D769, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, + {0x1D76A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, + {0x1D76B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, + {0x1D76C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, + {0x1D76D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, + {0x1D76E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, + {0x1D76F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, + {0x1D770, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, + {0x1D771, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x1D772, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x1D773, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, + {0x1D774, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, + {0x1D775, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, + {0x1D776, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, + {0x1D777, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, + {0x1D778, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, + {0x1D779, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, + {0x1D77A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, + {0x1D77B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, + {0x1D77C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, + {0x1D77D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, + {0x1D77E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, + {0x1D77F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, + {0x1D780, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, + {0x1D781, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, + {0x1D782, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, + {0x1D783, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, + {0x1D784, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, + {0x1D785, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x1D786, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, + {0x1D787, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, + {0x1D788, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, + {0x1D789, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, + {0x1D78A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, + {0x1D78B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, + {0x1D78C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, + {0x1D78D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, + {0x1D78E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, + {0x1D78F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, + {0x1D790, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, + {0x1D791, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, + {0x1D792, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, + {0x1D793, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, + {0x1D794, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, + {0x1D795, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, + {0x1D796, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, + {0x1D797, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, + {0x1D798, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, + {0x1D799, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, + {0x1D79A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, + {0x1D79B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, + {0x1D79C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, + {0x1D79D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, + {0x1D79E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, + {0x1D79F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, + {0x1D7A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, + {0x1D7A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, + {0x1D7A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, + {0x1D7A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, + {0x1D7A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, + {0x1D7A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, + {0x1D7A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, + {0x1D7A7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, + {0x1D7A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, + {0x1D7A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, + {0x1D7AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, + {0x1D7AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, + {0x1D7AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, + {0x1D7AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, + {0x1D7AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, + {0x1D7AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, + {0x1D7B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, + {0x1D7B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, + {0x1D7B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, + {0x1D7B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, + {0x1D7B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, + {0x1D7B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, + {0x1D7B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, + {0x1D7B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, + {0x1D7B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, + {0x1D7B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, + {0x1D7BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, + {0x1D7BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, + {0x1D7BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, + {0x1D7BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, + {0x1D7BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, + {0x1D7BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, + {0x1D7C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, + {0x1D7C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, + {0x1D7C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, + {0x1D7C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, + {0x1D7C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, + {0x1D7C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, + {0x1D7C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, + {0x1D7C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, + {0x1D7C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, + {0x1D7C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, + {0x1D7CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03DC}, + {0x1D7CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03DD}, + {0x1D7CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x1D7CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x1D7D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x1D7D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x1D7D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x1D7D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x1D7D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x1D7D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x1D7D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x1D7D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x1D7D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x1D7D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x1D7DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x1D7DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x1D7DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x1D7DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x1D7DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x1D7DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x1D7E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x1D7E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x1D7E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x1D7E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x1D7E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x1D7E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x1D7E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x1D7E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x1D7E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x1D7E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x1D7EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x1D7EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x1D7EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x1D7ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x1D7EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x1D7EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x1D7F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x1D7F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x1D7F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x1D7F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x1D7F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x1D7F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x1D7F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x1D7F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x1D7F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x1D7F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x1D7FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x1D7FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x1D7FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x1D7FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x1D7FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x1D7FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x1E000, 230, 0, 0}, + {0x1E001, 230, 0, 0}, + {0x1E002, 230, 0, 0}, + {0x1E003, 230, 0, 0}, + {0x1E004, 230, 0, 0}, + {0x1E005, 230, 0, 0}, + {0x1E006, 230, 0, 0}, + {0x1E008, 230, 0, 0}, + {0x1E009, 230, 0, 0}, + {0x1E00A, 230, 0, 0}, + {0x1E00B, 230, 0, 0}, + {0x1E00C, 230, 0, 0}, + {0x1E00D, 230, 0, 0}, + {0x1E00E, 230, 0, 0}, + {0x1E00F, 230, 0, 0}, + {0x1E010, 230, 0, 0}, + {0x1E011, 230, 0, 0}, + {0x1E012, 230, 0, 0}, + {0x1E013, 230, 0, 0}, + {0x1E014, 230, 0, 0}, + {0x1E015, 230, 0, 0}, + {0x1E016, 230, 0, 0}, + {0x1E017, 230, 0, 0}, + {0x1E018, 230, 0, 0}, + {0x1E01B, 230, 0, 0}, + {0x1E01C, 230, 0, 0}, + {0x1E01D, 230, 0, 0}, + {0x1E01E, 230, 0, 0}, + {0x1E01F, 230, 0, 0}, + {0x1E020, 230, 0, 0}, + {0x1E021, 230, 0, 0}, + {0x1E023, 230, 0, 0}, + {0x1E024, 230, 0, 0}, + {0x1E026, 230, 0, 0}, + {0x1E027, 230, 0, 0}, + {0x1E028, 230, 0, 0}, + {0x1E029, 230, 0, 0}, + {0x1E02A, 230, 0, 0}, + {0x1E030, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0430}, + {0x1E031, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0431}, + {0x1E032, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0432}, + {0x1E033, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0433}, + {0x1E034, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0434}, + {0x1E035, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0435}, + {0x1E036, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0436}, + {0x1E037, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0437}, + {0x1E038, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0438}, + {0x1E039, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043A}, + {0x1E03A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043B}, + {0x1E03B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043C}, + {0x1E03C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043E}, + {0x1E03D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043F}, + {0x1E03E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0440}, + {0x1E03F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0441}, + {0x1E040, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0442}, + {0x1E041, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0443}, + {0x1E042, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0444}, + {0x1E043, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0445}, + {0x1E044, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0446}, + {0x1E045, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0447}, + {0x1E046, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0448}, + {0x1E047, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044B}, + {0x1E048, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044D}, + {0x1E049, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044E}, + {0x1E04A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA689}, + {0x1E04B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04D9}, + {0x1E04C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0456}, + {0x1E04D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0458}, + {0x1E04E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04E9}, + {0x1E04F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04AF}, + {0x1E050, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04CF}, + {0x1E051, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0430}, + {0x1E052, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0431}, + {0x1E053, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0432}, + {0x1E054, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0433}, + {0x1E055, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0434}, + {0x1E056, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0435}, + {0x1E057, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0436}, + {0x1E058, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0437}, + {0x1E059, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0438}, + {0x1E05A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043A}, + {0x1E05B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043B}, + {0x1E05C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043E}, + {0x1E05D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043F}, + {0x1E05E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0441}, + {0x1E05F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0443}, + {0x1E060, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0444}, + {0x1E061, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0445}, + {0x1E062, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0446}, + {0x1E063, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0447}, + {0x1E064, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0448}, + {0x1E065, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044A}, + {0x1E066, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044B}, + {0x1E067, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0491}, + {0x1E068, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0456}, + {0x1E069, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0455}, + {0x1E06A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x045F}, + {0x1E06B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04AB}, + {0x1E06C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA651}, + {0x1E06D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04B1}, + {0x1E08F, 230, 0, 0}, + {0x1E130, 230, 0, 0}, + {0x1E131, 230, 0, 0}, + {0x1E132, 230, 0, 0}, + {0x1E133, 230, 0, 0}, + {0x1E134, 230, 0, 0}, + {0x1E135, 230, 0, 0}, + {0x1E136, 230, 0, 0}, + {0x1E2AE, 230, 0, 0}, + {0x1E2EC, 230, 0, 0}, + {0x1E2ED, 230, 0, 0}, + {0x1E2EE, 230, 0, 0}, + {0x1E2EF, 230, 0, 0}, + {0x1E4EC, 232, 0, 0}, + {0x1E4ED, 232, 0, 0}, + {0x1E4EE, 220, 0, 0}, + {0x1E4EF, 230, 0, 0}, + {0x1E8D0, 220, 0, 0}, + {0x1E8D1, 220, 0, 0}, + {0x1E8D2, 220, 0, 0}, + {0x1E8D3, 220, 0, 0}, + {0x1E8D4, 220, 0, 0}, + {0x1E8D5, 220, 0, 0}, + {0x1E8D6, 220, 0, 0}, + {0x1E944, 230, 0, 0}, + {0x1E945, 230, 0, 0}, + {0x1E946, 230, 0, 0}, + {0x1E947, 230, 0, 0}, + {0x1E948, 230, 0, 0}, + {0x1E949, 230, 0, 0}, + {0x1E94A, 7, 0, 0}, + {0x1EE00, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, + {0x1EE01, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0x1EE02, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0x1EE03, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, + {0x1EE05, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, + {0x1EE06, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, + {0x1EE07, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0x1EE08, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0x1EE09, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0x1EE0A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, + {0x1EE0B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0x1EE0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0x1EE0D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0x1EE0E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0x1EE0F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0x1EE10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0x1EE11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0x1EE12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0x1EE13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, + {0x1EE14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0x1EE15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0x1EE16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0x1EE17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0x1EE18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, + {0x1EE19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0x1EE1A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0x1EE1B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0x1EE1C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066E}, + {0x1EE1D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, + {0x1EE1E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A1}, + {0x1EE1F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066F}, + {0x1EE21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0x1EE22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0x1EE24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, + {0x1EE27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0x1EE29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0x1EE2A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, + {0x1EE2B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0x1EE2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0x1EE2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0x1EE2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0x1EE2F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0x1EE30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0x1EE31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0x1EE32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0x1EE34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0x1EE35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0x1EE36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0x1EE37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0x1EE39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0x1EE3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0x1EE42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0x1EE47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0x1EE49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0x1EE4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0x1EE4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0x1EE4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0x1EE4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0x1EE51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0x1EE52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0x1EE54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0x1EE57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0x1EE59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0x1EE5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0x1EE5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, + {0x1EE5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066F}, + {0x1EE61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0x1EE62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0x1EE64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, + {0x1EE67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0x1EE68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0x1EE69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0x1EE6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, + {0x1EE6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0x1EE6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0x1EE6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0x1EE6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0x1EE70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0x1EE71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0x1EE72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0x1EE74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0x1EE75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0x1EE76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0x1EE77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0x1EE79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0x1EE7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0x1EE7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0x1EE7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066E}, + {0x1EE7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A1}, + {0x1EE80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, + {0x1EE81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0x1EE82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0x1EE83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, + {0x1EE84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, + {0x1EE85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, + {0x1EE86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, + {0x1EE87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0x1EE88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0x1EE89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0x1EE8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0x1EE8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0x1EE8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0x1EE8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0x1EE8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0x1EE90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0x1EE91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0x1EE92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0x1EE93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, + {0x1EE94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0x1EE95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0x1EE96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0x1EE97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0x1EE98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, + {0x1EE99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0x1EE9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0x1EE9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0x1EEA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, + {0x1EEA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, + {0x1EEA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, + {0x1EEA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, + {0x1EEA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, + {0x1EEA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, + {0x1EEA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, + {0x1EEA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, + {0x1EEAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, + {0x1EEAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, + {0x1EEAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, + {0x1EEAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, + {0x1EEAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, + {0x1EEB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, + {0x1EEB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, + {0x1EEB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, + {0x1EEB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, + {0x1EEB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, + {0x1EEB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, + {0x1EEB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, + {0x1EEB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, + {0x1EEB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, + {0x1EEB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, + {0x1EEBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, + {0x1EEBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, + {0x1F100, 0, 2 | DECOMP_COMPAT, 4834}, + {0x1F101, 0, 2 | DECOMP_COMPAT, 4836}, + {0x1F102, 0, 2 | DECOMP_COMPAT, 4838}, + {0x1F103, 0, 2 | DECOMP_COMPAT, 4840}, + {0x1F104, 0, 2 | DECOMP_COMPAT, 4842}, + {0x1F105, 0, 2 | DECOMP_COMPAT, 4844}, + {0x1F106, 0, 2 | DECOMP_COMPAT, 4846}, + {0x1F107, 0, 2 | DECOMP_COMPAT, 4848}, + {0x1F108, 0, 2 | DECOMP_COMPAT, 4850}, + {0x1F109, 0, 2 | DECOMP_COMPAT, 4852}, + {0x1F10A, 0, 2 | DECOMP_COMPAT, 4854}, + {0x1F110, 0, 3 | DECOMP_COMPAT, 4856}, + {0x1F111, 0, 3 | DECOMP_COMPAT, 4859}, + {0x1F112, 0, 3 | DECOMP_COMPAT, 4862}, + {0x1F113, 0, 3 | DECOMP_COMPAT, 4865}, + {0x1F114, 0, 3 | DECOMP_COMPAT, 4868}, + {0x1F115, 0, 3 | DECOMP_COMPAT, 4871}, + {0x1F116, 0, 3 | DECOMP_COMPAT, 4874}, + {0x1F117, 0, 3 | DECOMP_COMPAT, 4877}, + {0x1F118, 0, 3 | DECOMP_COMPAT, 4880}, + {0x1F119, 0, 3 | DECOMP_COMPAT, 4883}, + {0x1F11A, 0, 3 | DECOMP_COMPAT, 4886}, + {0x1F11B, 0, 3 | DECOMP_COMPAT, 4889}, + {0x1F11C, 0, 3 | DECOMP_COMPAT, 4892}, + {0x1F11D, 0, 3 | DECOMP_COMPAT, 4895}, + {0x1F11E, 0, 3 | DECOMP_COMPAT, 4898}, + {0x1F11F, 0, 3 | DECOMP_COMPAT, 4901}, + {0x1F120, 0, 3 | DECOMP_COMPAT, 4904}, + {0x1F121, 0, 3 | DECOMP_COMPAT, 4907}, + {0x1F122, 0, 3 | DECOMP_COMPAT, 4910}, + {0x1F123, 0, 3 | DECOMP_COMPAT, 4913}, + {0x1F124, 0, 3 | DECOMP_COMPAT, 4916}, + {0x1F125, 0, 3 | DECOMP_COMPAT, 4919}, + {0x1F126, 0, 3 | DECOMP_COMPAT, 4922}, + {0x1F127, 0, 3 | DECOMP_COMPAT, 4925}, + {0x1F128, 0, 3 | DECOMP_COMPAT, 4928}, + {0x1F129, 0, 3 | DECOMP_COMPAT, 4931}, + {0x1F12A, 0, 3 | DECOMP_COMPAT, 4934}, + {0x1F12B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1F12C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1F12D, 0, 2 | DECOMP_COMPAT, 4937}, + {0x1F12E, 0, 2 | DECOMP_COMPAT, 4939}, + {0x1F130, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, + {0x1F131, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, + {0x1F132, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, + {0x1F133, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, + {0x1F134, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, + {0x1F135, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, + {0x1F136, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, + {0x1F137, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, + {0x1F138, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, + {0x1F139, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, + {0x1F13A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, + {0x1F13B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, + {0x1F13C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, + {0x1F13D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, + {0x1F13E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, + {0x1F13F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, + {0x1F140, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, + {0x1F141, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, + {0x1F142, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, + {0x1F143, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, + {0x1F144, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, + {0x1F145, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, + {0x1F146, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, + {0x1F147, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, + {0x1F148, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, + {0x1F149, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, + {0x1F14A, 0, 2 | DECOMP_COMPAT, 4941}, + {0x1F14B, 0, 2 | DECOMP_COMPAT, 4943}, + {0x1F14C, 0, 2 | DECOMP_COMPAT, 4945}, + {0x1F14D, 0, 2 | DECOMP_COMPAT, 4947}, + {0x1F14E, 0, 3 | DECOMP_COMPAT, 4949}, + {0x1F14F, 0, 2 | DECOMP_COMPAT, 4952}, + {0x1F16A, 0, 2 | DECOMP_COMPAT, 4954}, + {0x1F16B, 0, 2 | DECOMP_COMPAT, 4956}, + {0x1F16C, 0, 2 | DECOMP_COMPAT, 4958}, + {0x1F190, 0, 2 | DECOMP_COMPAT, 4960}, + {0x1F200, 0, 2 | DECOMP_COMPAT, 4962}, + {0x1F201, 0, 2 | DECOMP_COMPAT, 4964}, + {0x1F202, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B5}, + {0x1F210, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x624B}, + {0x1F211, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B57}, + {0x1F212, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53CC}, + {0x1F213, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C7}, + {0x1F214, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, + {0x1F215, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x591A}, + {0x1F216, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x89E3}, + {0x1F217, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5929}, + {0x1F218, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EA4}, + {0x1F219, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6620}, + {0x1F21A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7121}, + {0x1F21B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6599}, + {0x1F21C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x524D}, + {0x1F21D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F8C}, + {0x1F21E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x518D}, + {0x1F21F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65B0}, + {0x1F220, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x521D}, + {0x1F221, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7D42}, + {0x1F222, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x751F}, + {0x1F223, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8CA9}, + {0x1F224, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x58F0}, + {0x1F225, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5439}, + {0x1F226, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6F14}, + {0x1F227, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6295}, + {0x1F228, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6355}, + {0x1F229, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, + {0x1F22A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E09}, + {0x1F22B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x904A}, + {0x1F22C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DE6}, + {0x1F22D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E2D}, + {0x1F22E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53F3}, + {0x1F22F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6307}, + {0x1F230, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8D70}, + {0x1F231, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6253}, + {0x1F232, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7981}, + {0x1F233, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7A7A}, + {0x1F234, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5408}, + {0x1F235, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6E80}, + {0x1F236, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6709}, + {0x1F237, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6708}, + {0x1F238, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7533}, + {0x1F239, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5272}, + {0x1F23A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x55B6}, + {0x1F23B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x914D}, + {0x1F240, 0, 3 | DECOMP_COMPAT, 4966}, + {0x1F241, 0, 3 | DECOMP_COMPAT, 4969}, + {0x1F242, 0, 3 | DECOMP_COMPAT, 4972}, + {0x1F243, 0, 3 | DECOMP_COMPAT, 4975}, + {0x1F244, 0, 3 | DECOMP_COMPAT, 4978}, + {0x1F245, 0, 3 | DECOMP_COMPAT, 4981}, + {0x1F246, 0, 3 | DECOMP_COMPAT, 4984}, + {0x1F247, 0, 3 | DECOMP_COMPAT, 4987}, + {0x1F248, 0, 3 | DECOMP_COMPAT, 4990}, + {0x1F250, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F97}, + {0x1F251, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53EF}, + {0x1FBF0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, + {0x1FBF1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, + {0x1FBF2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, + {0x1FBF3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, + {0x1FBF4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, + {0x1FBF5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, + {0x1FBF6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, + {0x1FBF7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, + {0x1FBF8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, + {0x1FBF9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, + {0x2F800, 0, 1 | DECOMP_INLINE, 0x4E3D}, + {0x2F801, 0, 1 | DECOMP_INLINE, 0x4E38}, + {0x2F802, 0, 1 | DECOMP_INLINE, 0x4E41}, + {0x2F803, 0, 1, 4993}, + {0x2F804, 0, 1 | DECOMP_INLINE, 0x4F60}, + {0x2F805, 0, 1 | DECOMP_INLINE, 0x4FAE}, + {0x2F806, 0, 1 | DECOMP_INLINE, 0x4FBB}, + {0x2F807, 0, 1 | DECOMP_INLINE, 0x5002}, + {0x2F808, 0, 1 | DECOMP_INLINE, 0x507A}, + {0x2F809, 0, 1 | DECOMP_INLINE, 0x5099}, + {0x2F80A, 0, 1 | DECOMP_INLINE, 0x50E7}, + {0x2F80B, 0, 1 | DECOMP_INLINE, 0x50CF}, + {0x2F80C, 0, 1 | DECOMP_INLINE, 0x349E}, + {0x2F80D, 0, 1, 4994}, + {0x2F80E, 0, 1 | DECOMP_INLINE, 0x514D}, + {0x2F80F, 0, 1 | DECOMP_INLINE, 0x5154}, + {0x2F810, 0, 1 | DECOMP_INLINE, 0x5164}, + {0x2F811, 0, 1 | DECOMP_INLINE, 0x5177}, + {0x2F812, 0, 1, 4995}, + {0x2F813, 0, 1 | DECOMP_INLINE, 0x34B9}, + {0x2F814, 0, 1 | DECOMP_INLINE, 0x5167}, + {0x2F815, 0, 1 | DECOMP_INLINE, 0x518D}, + {0x2F816, 0, 1, 4996}, + {0x2F817, 0, 1 | DECOMP_INLINE, 0x5197}, + {0x2F818, 0, 1 | DECOMP_INLINE, 0x51A4}, + {0x2F819, 0, 1 | DECOMP_INLINE, 0x4ECC}, + {0x2F81A, 0, 1 | DECOMP_INLINE, 0x51AC}, + {0x2F81B, 0, 1 | DECOMP_INLINE, 0x51B5}, + {0x2F81C, 0, 1, 4997}, + {0x2F81D, 0, 1 | DECOMP_INLINE, 0x51F5}, + {0x2F81E, 0, 1 | DECOMP_INLINE, 0x5203}, + {0x2F81F, 0, 1 | DECOMP_INLINE, 0x34DF}, + {0x2F820, 0, 1 | DECOMP_INLINE, 0x523B}, + {0x2F821, 0, 1 | DECOMP_INLINE, 0x5246}, + {0x2F822, 0, 1 | DECOMP_INLINE, 0x5272}, + {0x2F823, 0, 1 | DECOMP_INLINE, 0x5277}, + {0x2F824, 0, 1 | DECOMP_INLINE, 0x3515}, + {0x2F825, 0, 1 | DECOMP_INLINE, 0x52C7}, + {0x2F826, 0, 1 | DECOMP_INLINE, 0x52C9}, + {0x2F827, 0, 1 | DECOMP_INLINE, 0x52E4}, + {0x2F828, 0, 1 | DECOMP_INLINE, 0x52FA}, + {0x2F829, 0, 1 | DECOMP_INLINE, 0x5305}, + {0x2F82A, 0, 1 | DECOMP_INLINE, 0x5306}, + {0x2F82B, 0, 1 | DECOMP_INLINE, 0x5317}, + {0x2F82C, 0, 1 | DECOMP_INLINE, 0x5349}, + {0x2F82D, 0, 1 | DECOMP_INLINE, 0x5351}, + {0x2F82E, 0, 1 | DECOMP_INLINE, 0x535A}, + {0x2F82F, 0, 1 | DECOMP_INLINE, 0x5373}, + {0x2F830, 0, 1 | DECOMP_INLINE, 0x537D}, + {0x2F831, 0, 1 | DECOMP_INLINE, 0x537F}, + {0x2F832, 0, 1 | DECOMP_INLINE, 0x537F}, + {0x2F833, 0, 1 | DECOMP_INLINE, 0x537F}, + {0x2F834, 0, 1, 4998}, + {0x2F835, 0, 1 | DECOMP_INLINE, 0x7070}, + {0x2F836, 0, 1 | DECOMP_INLINE, 0x53CA}, + {0x2F837, 0, 1 | DECOMP_INLINE, 0x53DF}, + {0x2F838, 0, 1, 4999}, + {0x2F839, 0, 1 | DECOMP_INLINE, 0x53EB}, + {0x2F83A, 0, 1 | DECOMP_INLINE, 0x53F1}, + {0x2F83B, 0, 1 | DECOMP_INLINE, 0x5406}, + {0x2F83C, 0, 1 | DECOMP_INLINE, 0x549E}, + {0x2F83D, 0, 1 | DECOMP_INLINE, 0x5438}, + {0x2F83E, 0, 1 | DECOMP_INLINE, 0x5448}, + {0x2F83F, 0, 1 | DECOMP_INLINE, 0x5468}, + {0x2F840, 0, 1 | DECOMP_INLINE, 0x54A2}, + {0x2F841, 0, 1 | DECOMP_INLINE, 0x54F6}, + {0x2F842, 0, 1 | DECOMP_INLINE, 0x5510}, + {0x2F843, 0, 1 | DECOMP_INLINE, 0x5553}, + {0x2F844, 0, 1 | DECOMP_INLINE, 0x5563}, + {0x2F845, 0, 1 | DECOMP_INLINE, 0x5584}, + {0x2F846, 0, 1 | DECOMP_INLINE, 0x5584}, + {0x2F847, 0, 1 | DECOMP_INLINE, 0x5599}, + {0x2F848, 0, 1 | DECOMP_INLINE, 0x55AB}, + {0x2F849, 0, 1 | DECOMP_INLINE, 0x55B3}, + {0x2F84A, 0, 1 | DECOMP_INLINE, 0x55C2}, + {0x2F84B, 0, 1 | DECOMP_INLINE, 0x5716}, + {0x2F84C, 0, 1 | DECOMP_INLINE, 0x5606}, + {0x2F84D, 0, 1 | DECOMP_INLINE, 0x5717}, + {0x2F84E, 0, 1 | DECOMP_INLINE, 0x5651}, + {0x2F84F, 0, 1 | DECOMP_INLINE, 0x5674}, + {0x2F850, 0, 1 | DECOMP_INLINE, 0x5207}, + {0x2F851, 0, 1 | DECOMP_INLINE, 0x58EE}, + {0x2F852, 0, 1 | DECOMP_INLINE, 0x57CE}, + {0x2F853, 0, 1 | DECOMP_INLINE, 0x57F4}, + {0x2F854, 0, 1 | DECOMP_INLINE, 0x580D}, + {0x2F855, 0, 1 | DECOMP_INLINE, 0x578B}, + {0x2F856, 0, 1 | DECOMP_INLINE, 0x5832}, + {0x2F857, 0, 1 | DECOMP_INLINE, 0x5831}, + {0x2F858, 0, 1 | DECOMP_INLINE, 0x58AC}, + {0x2F859, 0, 1, 5000}, + {0x2F85A, 0, 1 | DECOMP_INLINE, 0x58F2}, + {0x2F85B, 0, 1 | DECOMP_INLINE, 0x58F7}, + {0x2F85C, 0, 1 | DECOMP_INLINE, 0x5906}, + {0x2F85D, 0, 1 | DECOMP_INLINE, 0x591A}, + {0x2F85E, 0, 1 | DECOMP_INLINE, 0x5922}, + {0x2F85F, 0, 1 | DECOMP_INLINE, 0x5962}, + {0x2F860, 0, 1, 5001}, + {0x2F861, 0, 1, 5002}, + {0x2F862, 0, 1 | DECOMP_INLINE, 0x59EC}, + {0x2F863, 0, 1 | DECOMP_INLINE, 0x5A1B}, + {0x2F864, 0, 1 | DECOMP_INLINE, 0x5A27}, + {0x2F865, 0, 1 | DECOMP_INLINE, 0x59D8}, + {0x2F866, 0, 1 | DECOMP_INLINE, 0x5A66}, + {0x2F867, 0, 1 | DECOMP_INLINE, 0x36EE}, + {0x2F868, 0, 1 | DECOMP_INLINE, 0x36FC}, + {0x2F869, 0, 1 | DECOMP_INLINE, 0x5B08}, + {0x2F86A, 0, 1 | DECOMP_INLINE, 0x5B3E}, + {0x2F86B, 0, 1 | DECOMP_INLINE, 0x5B3E}, + {0x2F86C, 0, 1, 5003}, + {0x2F86D, 0, 1 | DECOMP_INLINE, 0x5BC3}, + {0x2F86E, 0, 1 | DECOMP_INLINE, 0x5BD8}, + {0x2F86F, 0, 1 | DECOMP_INLINE, 0x5BE7}, + {0x2F870, 0, 1 | DECOMP_INLINE, 0x5BF3}, + {0x2F871, 0, 1, 5004}, + {0x2F872, 0, 1 | DECOMP_INLINE, 0x5BFF}, + {0x2F873, 0, 1 | DECOMP_INLINE, 0x5C06}, + {0x2F874, 0, 1 | DECOMP_INLINE, 0x5F53}, + {0x2F875, 0, 1 | DECOMP_INLINE, 0x5C22}, + {0x2F876, 0, 1 | DECOMP_INLINE, 0x3781}, + {0x2F877, 0, 1 | DECOMP_INLINE, 0x5C60}, + {0x2F878, 0, 1 | DECOMP_INLINE, 0x5C6E}, + {0x2F879, 0, 1 | DECOMP_INLINE, 0x5CC0}, + {0x2F87A, 0, 1 | DECOMP_INLINE, 0x5C8D}, + {0x2F87B, 0, 1, 5005}, + {0x2F87C, 0, 1 | DECOMP_INLINE, 0x5D43}, + {0x2F87D, 0, 1, 5006}, + {0x2F87E, 0, 1 | DECOMP_INLINE, 0x5D6E}, + {0x2F87F, 0, 1 | DECOMP_INLINE, 0x5D6B}, + {0x2F880, 0, 1 | DECOMP_INLINE, 0x5D7C}, + {0x2F881, 0, 1 | DECOMP_INLINE, 0x5DE1}, + {0x2F882, 0, 1 | DECOMP_INLINE, 0x5DE2}, + {0x2F883, 0, 1 | DECOMP_INLINE, 0x382F}, + {0x2F884, 0, 1 | DECOMP_INLINE, 0x5DFD}, + {0x2F885, 0, 1 | DECOMP_INLINE, 0x5E28}, + {0x2F886, 0, 1 | DECOMP_INLINE, 0x5E3D}, + {0x2F887, 0, 1 | DECOMP_INLINE, 0x5E69}, + {0x2F888, 0, 1 | DECOMP_INLINE, 0x3862}, + {0x2F889, 0, 1, 5007}, + {0x2F88A, 0, 1 | DECOMP_INLINE, 0x387C}, + {0x2F88B, 0, 1 | DECOMP_INLINE, 0x5EB0}, + {0x2F88C, 0, 1 | DECOMP_INLINE, 0x5EB3}, + {0x2F88D, 0, 1 | DECOMP_INLINE, 0x5EB6}, + {0x2F88E, 0, 1 | DECOMP_INLINE, 0x5ECA}, + {0x2F88F, 0, 1, 5008}, + {0x2F890, 0, 1 | DECOMP_INLINE, 0x5EFE}, + {0x2F891, 0, 1, 5009}, + {0x2F892, 0, 1, 5010}, + {0x2F893, 0, 1 | DECOMP_INLINE, 0x8201}, + {0x2F894, 0, 1 | DECOMP_INLINE, 0x5F22}, + {0x2F895, 0, 1 | DECOMP_INLINE, 0x5F22}, + {0x2F896, 0, 1 | DECOMP_INLINE, 0x38C7}, + {0x2F897, 0, 1, 5011}, + {0x2F898, 0, 1, 5012}, + {0x2F899, 0, 1 | DECOMP_INLINE, 0x5F62}, + {0x2F89A, 0, 1 | DECOMP_INLINE, 0x5F6B}, + {0x2F89B, 0, 1 | DECOMP_INLINE, 0x38E3}, + {0x2F89C, 0, 1 | DECOMP_INLINE, 0x5F9A}, + {0x2F89D, 0, 1 | DECOMP_INLINE, 0x5FCD}, + {0x2F89E, 0, 1 | DECOMP_INLINE, 0x5FD7}, + {0x2F89F, 0, 1 | DECOMP_INLINE, 0x5FF9}, + {0x2F8A0, 0, 1 | DECOMP_INLINE, 0x6081}, + {0x2F8A1, 0, 1 | DECOMP_INLINE, 0x393A}, + {0x2F8A2, 0, 1 | DECOMP_INLINE, 0x391C}, + {0x2F8A3, 0, 1 | DECOMP_INLINE, 0x6094}, + {0x2F8A4, 0, 1, 5013}, + {0x2F8A5, 0, 1 | DECOMP_INLINE, 0x60C7}, + {0x2F8A6, 0, 1 | DECOMP_INLINE, 0x6148}, + {0x2F8A7, 0, 1 | DECOMP_INLINE, 0x614C}, + {0x2F8A8, 0, 1 | DECOMP_INLINE, 0x614E}, + {0x2F8A9, 0, 1 | DECOMP_INLINE, 0x614C}, + {0x2F8AA, 0, 1 | DECOMP_INLINE, 0x617A}, + {0x2F8AB, 0, 1 | DECOMP_INLINE, 0x618E}, + {0x2F8AC, 0, 1 | DECOMP_INLINE, 0x61B2}, + {0x2F8AD, 0, 1 | DECOMP_INLINE, 0x61A4}, + {0x2F8AE, 0, 1 | DECOMP_INLINE, 0x61AF}, + {0x2F8AF, 0, 1 | DECOMP_INLINE, 0x61DE}, + {0x2F8B0, 0, 1 | DECOMP_INLINE, 0x61F2}, + {0x2F8B1, 0, 1 | DECOMP_INLINE, 0x61F6}, + {0x2F8B2, 0, 1 | DECOMP_INLINE, 0x6210}, + {0x2F8B3, 0, 1 | DECOMP_INLINE, 0x621B}, + {0x2F8B4, 0, 1 | DECOMP_INLINE, 0x625D}, + {0x2F8B5, 0, 1 | DECOMP_INLINE, 0x62B1}, + {0x2F8B6, 0, 1 | DECOMP_INLINE, 0x62D4}, + {0x2F8B7, 0, 1 | DECOMP_INLINE, 0x6350}, + {0x2F8B8, 0, 1, 5014}, + {0x2F8B9, 0, 1 | DECOMP_INLINE, 0x633D}, + {0x2F8BA, 0, 1 | DECOMP_INLINE, 0x62FC}, + {0x2F8BB, 0, 1 | DECOMP_INLINE, 0x6368}, + {0x2F8BC, 0, 1 | DECOMP_INLINE, 0x6383}, + {0x2F8BD, 0, 1 | DECOMP_INLINE, 0x63E4}, + {0x2F8BE, 0, 1, 5015}, + {0x2F8BF, 0, 1 | DECOMP_INLINE, 0x6422}, + {0x2F8C0, 0, 1 | DECOMP_INLINE, 0x63C5}, + {0x2F8C1, 0, 1 | DECOMP_INLINE, 0x63A9}, + {0x2F8C2, 0, 1 | DECOMP_INLINE, 0x3A2E}, + {0x2F8C3, 0, 1 | DECOMP_INLINE, 0x6469}, + {0x2F8C4, 0, 1 | DECOMP_INLINE, 0x647E}, + {0x2F8C5, 0, 1 | DECOMP_INLINE, 0x649D}, + {0x2F8C6, 0, 1 | DECOMP_INLINE, 0x6477}, + {0x2F8C7, 0, 1 | DECOMP_INLINE, 0x3A6C}, + {0x2F8C8, 0, 1 | DECOMP_INLINE, 0x654F}, + {0x2F8C9, 0, 1 | DECOMP_INLINE, 0x656C}, + {0x2F8CA, 0, 1, 5016}, + {0x2F8CB, 0, 1 | DECOMP_INLINE, 0x65E3}, + {0x2F8CC, 0, 1 | DECOMP_INLINE, 0x66F8}, + {0x2F8CD, 0, 1 | DECOMP_INLINE, 0x6649}, + {0x2F8CE, 0, 1 | DECOMP_INLINE, 0x3B19}, + {0x2F8CF, 0, 1 | DECOMP_INLINE, 0x6691}, + {0x2F8D0, 0, 1 | DECOMP_INLINE, 0x3B08}, + {0x2F8D1, 0, 1 | DECOMP_INLINE, 0x3AE4}, + {0x2F8D2, 0, 1 | DECOMP_INLINE, 0x5192}, + {0x2F8D3, 0, 1 | DECOMP_INLINE, 0x5195}, + {0x2F8D4, 0, 1 | DECOMP_INLINE, 0x6700}, + {0x2F8D5, 0, 1 | DECOMP_INLINE, 0x669C}, + {0x2F8D6, 0, 1 | DECOMP_INLINE, 0x80AD}, + {0x2F8D7, 0, 1 | DECOMP_INLINE, 0x43D9}, + {0x2F8D8, 0, 1 | DECOMP_INLINE, 0x6717}, + {0x2F8D9, 0, 1 | DECOMP_INLINE, 0x671B}, + {0x2F8DA, 0, 1 | DECOMP_INLINE, 0x6721}, + {0x2F8DB, 0, 1 | DECOMP_INLINE, 0x675E}, + {0x2F8DC, 0, 1 | DECOMP_INLINE, 0x6753}, + {0x2F8DD, 0, 1, 5017}, + {0x2F8DE, 0, 1 | DECOMP_INLINE, 0x3B49}, + {0x2F8DF, 0, 1 | DECOMP_INLINE, 0x67FA}, + {0x2F8E0, 0, 1 | DECOMP_INLINE, 0x6785}, + {0x2F8E1, 0, 1 | DECOMP_INLINE, 0x6852}, + {0x2F8E2, 0, 1 | DECOMP_INLINE, 0x6885}, + {0x2F8E3, 0, 1, 5018}, + {0x2F8E4, 0, 1 | DECOMP_INLINE, 0x688E}, + {0x2F8E5, 0, 1 | DECOMP_INLINE, 0x681F}, + {0x2F8E6, 0, 1 | DECOMP_INLINE, 0x6914}, + {0x2F8E7, 0, 1 | DECOMP_INLINE, 0x3B9D}, + {0x2F8E8, 0, 1 | DECOMP_INLINE, 0x6942}, + {0x2F8E9, 0, 1 | DECOMP_INLINE, 0x69A3}, + {0x2F8EA, 0, 1 | DECOMP_INLINE, 0x69EA}, + {0x2F8EB, 0, 1 | DECOMP_INLINE, 0x6AA8}, + {0x2F8EC, 0, 1, 5019}, + {0x2F8ED, 0, 1 | DECOMP_INLINE, 0x6ADB}, + {0x2F8EE, 0, 1 | DECOMP_INLINE, 0x3C18}, + {0x2F8EF, 0, 1 | DECOMP_INLINE, 0x6B21}, + {0x2F8F0, 0, 1, 5020}, + {0x2F8F1, 0, 1 | DECOMP_INLINE, 0x6B54}, + {0x2F8F2, 0, 1 | DECOMP_INLINE, 0x3C4E}, + {0x2F8F3, 0, 1 | DECOMP_INLINE, 0x6B72}, + {0x2F8F4, 0, 1 | DECOMP_INLINE, 0x6B9F}, + {0x2F8F5, 0, 1 | DECOMP_INLINE, 0x6BBA}, + {0x2F8F6, 0, 1 | DECOMP_INLINE, 0x6BBB}, + {0x2F8F7, 0, 1, 5021}, + {0x2F8F8, 0, 1, 5022}, + {0x2F8F9, 0, 1, 5023}, + {0x2F8FA, 0, 1 | DECOMP_INLINE, 0x6C4E}, + {0x2F8FB, 0, 1, 5024}, + {0x2F8FC, 0, 1 | DECOMP_INLINE, 0x6CBF}, + {0x2F8FD, 0, 1 | DECOMP_INLINE, 0x6CCD}, + {0x2F8FE, 0, 1 | DECOMP_INLINE, 0x6C67}, + {0x2F8FF, 0, 1 | DECOMP_INLINE, 0x6D16}, + {0x2F900, 0, 1 | DECOMP_INLINE, 0x6D3E}, + {0x2F901, 0, 1 | DECOMP_INLINE, 0x6D77}, + {0x2F902, 0, 1 | DECOMP_INLINE, 0x6D41}, + {0x2F903, 0, 1 | DECOMP_INLINE, 0x6D69}, + {0x2F904, 0, 1 | DECOMP_INLINE, 0x6D78}, + {0x2F905, 0, 1 | DECOMP_INLINE, 0x6D85}, + {0x2F906, 0, 1, 5025}, + {0x2F907, 0, 1 | DECOMP_INLINE, 0x6D34}, + {0x2F908, 0, 1 | DECOMP_INLINE, 0x6E2F}, + {0x2F909, 0, 1 | DECOMP_INLINE, 0x6E6E}, + {0x2F90A, 0, 1 | DECOMP_INLINE, 0x3D33}, + {0x2F90B, 0, 1 | DECOMP_INLINE, 0x6ECB}, + {0x2F90C, 0, 1 | DECOMP_INLINE, 0x6EC7}, + {0x2F90D, 0, 1, 5026}, + {0x2F90E, 0, 1 | DECOMP_INLINE, 0x6DF9}, + {0x2F90F, 0, 1 | DECOMP_INLINE, 0x6F6E}, + {0x2F910, 0, 1, 5027}, + {0x2F911, 0, 1, 5028}, + {0x2F912, 0, 1 | DECOMP_INLINE, 0x6FC6}, + {0x2F913, 0, 1 | DECOMP_INLINE, 0x7039}, + {0x2F914, 0, 1 | DECOMP_INLINE, 0x701E}, + {0x2F915, 0, 1 | DECOMP_INLINE, 0x701B}, + {0x2F916, 0, 1 | DECOMP_INLINE, 0x3D96}, + {0x2F917, 0, 1 | DECOMP_INLINE, 0x704A}, + {0x2F918, 0, 1 | DECOMP_INLINE, 0x707D}, + {0x2F919, 0, 1 | DECOMP_INLINE, 0x7077}, + {0x2F91A, 0, 1 | DECOMP_INLINE, 0x70AD}, + {0x2F91B, 0, 1, 5029}, + {0x2F91C, 0, 1 | DECOMP_INLINE, 0x7145}, + {0x2F91D, 0, 1, 5030}, + {0x2F91E, 0, 1 | DECOMP_INLINE, 0x719C}, + {0x2F91F, 0, 1, 5031}, + {0x2F920, 0, 1 | DECOMP_INLINE, 0x7228}, + {0x2F921, 0, 1 | DECOMP_INLINE, 0x7235}, + {0x2F922, 0, 1 | DECOMP_INLINE, 0x7250}, + {0x2F923, 0, 1, 5032}, + {0x2F924, 0, 1 | DECOMP_INLINE, 0x7280}, + {0x2F925, 0, 1 | DECOMP_INLINE, 0x7295}, + {0x2F926, 0, 1, 5033}, + {0x2F927, 0, 1, 5034}, + {0x2F928, 0, 1 | DECOMP_INLINE, 0x737A}, + {0x2F929, 0, 1 | DECOMP_INLINE, 0x738B}, + {0x2F92A, 0, 1 | DECOMP_INLINE, 0x3EAC}, + {0x2F92B, 0, 1 | DECOMP_INLINE, 0x73A5}, + {0x2F92C, 0, 1 | DECOMP_INLINE, 0x3EB8}, + {0x2F92D, 0, 1 | DECOMP_INLINE, 0x3EB8}, + {0x2F92E, 0, 1 | DECOMP_INLINE, 0x7447}, + {0x2F92F, 0, 1 | DECOMP_INLINE, 0x745C}, + {0x2F930, 0, 1 | DECOMP_INLINE, 0x7471}, + {0x2F931, 0, 1 | DECOMP_INLINE, 0x7485}, + {0x2F932, 0, 1 | DECOMP_INLINE, 0x74CA}, + {0x2F933, 0, 1 | DECOMP_INLINE, 0x3F1B}, + {0x2F934, 0, 1 | DECOMP_INLINE, 0x7524}, + {0x2F935, 0, 1, 5035}, + {0x2F936, 0, 1 | DECOMP_INLINE, 0x753E}, + {0x2F937, 0, 1, 5036}, + {0x2F938, 0, 1 | DECOMP_INLINE, 0x7570}, + {0x2F939, 0, 1, 5037}, + {0x2F93A, 0, 1 | DECOMP_INLINE, 0x7610}, + {0x2F93B, 0, 1, 5038}, + {0x2F93C, 0, 1, 5039}, + {0x2F93D, 0, 1, 5040}, + {0x2F93E, 0, 1 | DECOMP_INLINE, 0x3FFC}, + {0x2F93F, 0, 1 | DECOMP_INLINE, 0x4008}, + {0x2F940, 0, 1 | DECOMP_INLINE, 0x76F4}, + {0x2F941, 0, 1, 5041}, + {0x2F942, 0, 1, 5042}, + {0x2F943, 0, 1, 5043}, + {0x2F944, 0, 1, 5044}, + {0x2F945, 0, 1 | DECOMP_INLINE, 0x771E}, + {0x2F946, 0, 1 | DECOMP_INLINE, 0x771F}, + {0x2F947, 0, 1 | DECOMP_INLINE, 0x771F}, + {0x2F948, 0, 1 | DECOMP_INLINE, 0x774A}, + {0x2F949, 0, 1 | DECOMP_INLINE, 0x4039}, + {0x2F94A, 0, 1 | DECOMP_INLINE, 0x778B}, + {0x2F94B, 0, 1 | DECOMP_INLINE, 0x4046}, + {0x2F94C, 0, 1 | DECOMP_INLINE, 0x4096}, + {0x2F94D, 0, 1, 5045}, + {0x2F94E, 0, 1 | DECOMP_INLINE, 0x784E}, + {0x2F94F, 0, 1 | DECOMP_INLINE, 0x788C}, + {0x2F950, 0, 1 | DECOMP_INLINE, 0x78CC}, + {0x2F951, 0, 1 | DECOMP_INLINE, 0x40E3}, + {0x2F952, 0, 1, 5046}, + {0x2F953, 0, 1 | DECOMP_INLINE, 0x7956}, + {0x2F954, 0, 1, 5047}, + {0x2F955, 0, 1, 5048}, + {0x2F956, 0, 1 | DECOMP_INLINE, 0x798F}, + {0x2F957, 0, 1 | DECOMP_INLINE, 0x79EB}, + {0x2F958, 0, 1 | DECOMP_INLINE, 0x412F}, + {0x2F959, 0, 1 | DECOMP_INLINE, 0x7A40}, + {0x2F95A, 0, 1 | DECOMP_INLINE, 0x7A4A}, + {0x2F95B, 0, 1 | DECOMP_INLINE, 0x7A4F}, + {0x2F95C, 0, 1, 5049}, + {0x2F95D, 0, 1, 5050}, + {0x2F95E, 0, 1, 5051}, + {0x2F95F, 0, 1 | DECOMP_INLINE, 0x7AEE}, + {0x2F960, 0, 1 | DECOMP_INLINE, 0x4202}, + {0x2F961, 0, 1, 5052}, + {0x2F962, 0, 1 | DECOMP_INLINE, 0x7BC6}, + {0x2F963, 0, 1 | DECOMP_INLINE, 0x7BC9}, + {0x2F964, 0, 1 | DECOMP_INLINE, 0x4227}, + {0x2F965, 0, 1, 5053}, + {0x2F966, 0, 1 | DECOMP_INLINE, 0x7CD2}, + {0x2F967, 0, 1 | DECOMP_INLINE, 0x42A0}, + {0x2F968, 0, 1 | DECOMP_INLINE, 0x7CE8}, + {0x2F969, 0, 1 | DECOMP_INLINE, 0x7CE3}, + {0x2F96A, 0, 1 | DECOMP_INLINE, 0x7D00}, + {0x2F96B, 0, 1, 5054}, + {0x2F96C, 0, 1 | DECOMP_INLINE, 0x7D63}, + {0x2F96D, 0, 1 | DECOMP_INLINE, 0x4301}, + {0x2F96E, 0, 1 | DECOMP_INLINE, 0x7DC7}, + {0x2F96F, 0, 1 | DECOMP_INLINE, 0x7E02}, + {0x2F970, 0, 1 | DECOMP_INLINE, 0x7E45}, + {0x2F971, 0, 1 | DECOMP_INLINE, 0x4334}, + {0x2F972, 0, 1, 5055}, + {0x2F973, 0, 1, 5056}, + {0x2F974, 0, 1 | DECOMP_INLINE, 0x4359}, + {0x2F975, 0, 1, 5057}, + {0x2F976, 0, 1 | DECOMP_INLINE, 0x7F7A}, + {0x2F977, 0, 1, 5058}, + {0x2F978, 0, 1 | DECOMP_INLINE, 0x7F95}, + {0x2F979, 0, 1 | DECOMP_INLINE, 0x7FFA}, + {0x2F97A, 0, 1 | DECOMP_INLINE, 0x8005}, + {0x2F97B, 0, 1, 5059}, + {0x2F97C, 0, 1, 5060}, + {0x2F97D, 0, 1 | DECOMP_INLINE, 0x8060}, + {0x2F97E, 0, 1, 5061}, + {0x2F97F, 0, 1 | DECOMP_INLINE, 0x8070}, + {0x2F980, 0, 1, 5062}, + {0x2F981, 0, 1 | DECOMP_INLINE, 0x43D5}, + {0x2F982, 0, 1 | DECOMP_INLINE, 0x80B2}, + {0x2F983, 0, 1 | DECOMP_INLINE, 0x8103}, + {0x2F984, 0, 1 | DECOMP_INLINE, 0x440B}, + {0x2F985, 0, 1 | DECOMP_INLINE, 0x813E}, + {0x2F986, 0, 1 | DECOMP_INLINE, 0x5AB5}, + {0x2F987, 0, 1, 5063}, + {0x2F988, 0, 1, 5064}, + {0x2F989, 0, 1, 5065}, + {0x2F98A, 0, 1, 5066}, + {0x2F98B, 0, 1 | DECOMP_INLINE, 0x8201}, + {0x2F98C, 0, 1 | DECOMP_INLINE, 0x8204}, + {0x2F98D, 0, 1 | DECOMP_INLINE, 0x8F9E}, + {0x2F98E, 0, 1 | DECOMP_INLINE, 0x446B}, + {0x2F98F, 0, 1 | DECOMP_INLINE, 0x8291}, + {0x2F990, 0, 1 | DECOMP_INLINE, 0x828B}, + {0x2F991, 0, 1 | DECOMP_INLINE, 0x829D}, + {0x2F992, 0, 1 | DECOMP_INLINE, 0x52B3}, + {0x2F993, 0, 1 | DECOMP_INLINE, 0x82B1}, + {0x2F994, 0, 1 | DECOMP_INLINE, 0x82B3}, + {0x2F995, 0, 1 | DECOMP_INLINE, 0x82BD}, + {0x2F996, 0, 1 | DECOMP_INLINE, 0x82E6}, + {0x2F997, 0, 1, 5067}, + {0x2F998, 0, 1 | DECOMP_INLINE, 0x82E5}, + {0x2F999, 0, 1 | DECOMP_INLINE, 0x831D}, + {0x2F99A, 0, 1 | DECOMP_INLINE, 0x8363}, + {0x2F99B, 0, 1 | DECOMP_INLINE, 0x83AD}, + {0x2F99C, 0, 1 | DECOMP_INLINE, 0x8323}, + {0x2F99D, 0, 1 | DECOMP_INLINE, 0x83BD}, + {0x2F99E, 0, 1 | DECOMP_INLINE, 0x83E7}, + {0x2F99F, 0, 1 | DECOMP_INLINE, 0x8457}, + {0x2F9A0, 0, 1 | DECOMP_INLINE, 0x8353}, + {0x2F9A1, 0, 1 | DECOMP_INLINE, 0x83CA}, + {0x2F9A2, 0, 1 | DECOMP_INLINE, 0x83CC}, + {0x2F9A3, 0, 1 | DECOMP_INLINE, 0x83DC}, + {0x2F9A4, 0, 1, 5068}, + {0x2F9A5, 0, 1, 5069}, + {0x2F9A6, 0, 1, 5070}, + {0x2F9A7, 0, 1 | DECOMP_INLINE, 0x452B}, + {0x2F9A8, 0, 1 | DECOMP_INLINE, 0x84F1}, + {0x2F9A9, 0, 1 | DECOMP_INLINE, 0x84F3}, + {0x2F9AA, 0, 1 | DECOMP_INLINE, 0x8516}, + {0x2F9AB, 0, 1, 5071}, + {0x2F9AC, 0, 1 | DECOMP_INLINE, 0x8564}, + {0x2F9AD, 0, 1, 5072}, + {0x2F9AE, 0, 1 | DECOMP_INLINE, 0x455D}, + {0x2F9AF, 0, 1 | DECOMP_INLINE, 0x4561}, + {0x2F9B0, 0, 1, 5073}, + {0x2F9B1, 0, 1, 5074}, + {0x2F9B2, 0, 1 | DECOMP_INLINE, 0x456B}, + {0x2F9B3, 0, 1 | DECOMP_INLINE, 0x8650}, + {0x2F9B4, 0, 1 | DECOMP_INLINE, 0x865C}, + {0x2F9B5, 0, 1 | DECOMP_INLINE, 0x8667}, + {0x2F9B6, 0, 1 | DECOMP_INLINE, 0x8669}, + {0x2F9B7, 0, 1 | DECOMP_INLINE, 0x86A9}, + {0x2F9B8, 0, 1 | DECOMP_INLINE, 0x8688}, + {0x2F9B9, 0, 1 | DECOMP_INLINE, 0x870E}, + {0x2F9BA, 0, 1 | DECOMP_INLINE, 0x86E2}, + {0x2F9BB, 0, 1 | DECOMP_INLINE, 0x8779}, + {0x2F9BC, 0, 1 | DECOMP_INLINE, 0x8728}, + {0x2F9BD, 0, 1 | DECOMP_INLINE, 0x876B}, + {0x2F9BE, 0, 1 | DECOMP_INLINE, 0x8786}, + {0x2F9BF, 0, 1 | DECOMP_INLINE, 0x45D7}, + {0x2F9C0, 0, 1 | DECOMP_INLINE, 0x87E1}, + {0x2F9C1, 0, 1 | DECOMP_INLINE, 0x8801}, + {0x2F9C2, 0, 1 | DECOMP_INLINE, 0x45F9}, + {0x2F9C3, 0, 1 | DECOMP_INLINE, 0x8860}, + {0x2F9C4, 0, 1 | DECOMP_INLINE, 0x8863}, + {0x2F9C5, 0, 1, 5075}, + {0x2F9C6, 0, 1 | DECOMP_INLINE, 0x88D7}, + {0x2F9C7, 0, 1 | DECOMP_INLINE, 0x88DE}, + {0x2F9C8, 0, 1 | DECOMP_INLINE, 0x4635}, + {0x2F9C9, 0, 1 | DECOMP_INLINE, 0x88FA}, + {0x2F9CA, 0, 1 | DECOMP_INLINE, 0x34BB}, + {0x2F9CB, 0, 1, 5076}, + {0x2F9CC, 0, 1, 5077}, + {0x2F9CD, 0, 1 | DECOMP_INLINE, 0x46BE}, + {0x2F9CE, 0, 1 | DECOMP_INLINE, 0x46C7}, + {0x2F9CF, 0, 1 | DECOMP_INLINE, 0x8AA0}, + {0x2F9D0, 0, 1 | DECOMP_INLINE, 0x8AED}, + {0x2F9D1, 0, 1 | DECOMP_INLINE, 0x8B8A}, + {0x2F9D2, 0, 1 | DECOMP_INLINE, 0x8C55}, + {0x2F9D3, 0, 1, 5078}, + {0x2F9D4, 0, 1 | DECOMP_INLINE, 0x8CAB}, + {0x2F9D5, 0, 1 | DECOMP_INLINE, 0x8CC1}, + {0x2F9D6, 0, 1 | DECOMP_INLINE, 0x8D1B}, + {0x2F9D7, 0, 1 | DECOMP_INLINE, 0x8D77}, + {0x2F9D8, 0, 1, 5079}, + {0x2F9D9, 0, 1, 5080}, + {0x2F9DA, 0, 1 | DECOMP_INLINE, 0x8DCB}, + {0x2F9DB, 0, 1 | DECOMP_INLINE, 0x8DBC}, + {0x2F9DC, 0, 1 | DECOMP_INLINE, 0x8DF0}, + {0x2F9DD, 0, 1, 5081}, + {0x2F9DE, 0, 1 | DECOMP_INLINE, 0x8ED4}, + {0x2F9DF, 0, 1 | DECOMP_INLINE, 0x8F38}, + {0x2F9E0, 0, 1, 5082}, + {0x2F9E1, 0, 1, 5083}, + {0x2F9E2, 0, 1 | DECOMP_INLINE, 0x9094}, + {0x2F9E3, 0, 1 | DECOMP_INLINE, 0x90F1}, + {0x2F9E4, 0, 1 | DECOMP_INLINE, 0x9111}, + {0x2F9E5, 0, 1, 5084}, + {0x2F9E6, 0, 1 | DECOMP_INLINE, 0x911B}, + {0x2F9E7, 0, 1 | DECOMP_INLINE, 0x9238}, + {0x2F9E8, 0, 1 | DECOMP_INLINE, 0x92D7}, + {0x2F9E9, 0, 1 | DECOMP_INLINE, 0x92D8}, + {0x2F9EA, 0, 1 | DECOMP_INLINE, 0x927C}, + {0x2F9EB, 0, 1 | DECOMP_INLINE, 0x93F9}, + {0x2F9EC, 0, 1 | DECOMP_INLINE, 0x9415}, + {0x2F9ED, 0, 1, 5085}, + {0x2F9EE, 0, 1 | DECOMP_INLINE, 0x958B}, + {0x2F9EF, 0, 1 | DECOMP_INLINE, 0x4995}, + {0x2F9F0, 0, 1 | DECOMP_INLINE, 0x95B7}, + {0x2F9F1, 0, 1, 5086}, + {0x2F9F2, 0, 1 | DECOMP_INLINE, 0x49E6}, + {0x2F9F3, 0, 1 | DECOMP_INLINE, 0x96C3}, + {0x2F9F4, 0, 1 | DECOMP_INLINE, 0x5DB2}, + {0x2F9F5, 0, 1 | DECOMP_INLINE, 0x9723}, + {0x2F9F6, 0, 1, 5087}, + {0x2F9F7, 0, 1, 5088}, + {0x2F9F8, 0, 1 | DECOMP_INLINE, 0x4A6E}, + {0x2F9F9, 0, 1 | DECOMP_INLINE, 0x4A76}, + {0x2F9FA, 0, 1 | DECOMP_INLINE, 0x97E0}, + {0x2F9FB, 0, 1, 5089}, + {0x2F9FC, 0, 1 | DECOMP_INLINE, 0x4AB2}, + {0x2F9FD, 0, 1, 5090}, + {0x2F9FE, 0, 1 | DECOMP_INLINE, 0x980B}, + {0x2F9FF, 0, 1 | DECOMP_INLINE, 0x980B}, + {0x2FA00, 0, 1 | DECOMP_INLINE, 0x9829}, + {0x2FA01, 0, 1, 5091}, + {0x2FA02, 0, 1 | DECOMP_INLINE, 0x98E2}, + {0x2FA03, 0, 1 | DECOMP_INLINE, 0x4B33}, + {0x2FA04, 0, 1 | DECOMP_INLINE, 0x9929}, + {0x2FA05, 0, 1 | DECOMP_INLINE, 0x99A7}, + {0x2FA06, 0, 1 | DECOMP_INLINE, 0x99C2}, + {0x2FA07, 0, 1 | DECOMP_INLINE, 0x99FE}, + {0x2FA08, 0, 1 | DECOMP_INLINE, 0x4BCE}, + {0x2FA09, 0, 1, 5092}, + {0x2FA0A, 0, 1 | DECOMP_INLINE, 0x9B12}, + {0x2FA0B, 0, 1 | DECOMP_INLINE, 0x9C40}, + {0x2FA0C, 0, 1 | DECOMP_INLINE, 0x9CFD}, + {0x2FA0D, 0, 1 | DECOMP_INLINE, 0x4CCE}, + {0x2FA0E, 0, 1 | DECOMP_INLINE, 0x4CED}, + {0x2FA0F, 0, 1 | DECOMP_INLINE, 0x9D67}, + {0x2FA10, 0, 1, 5093}, + {0x2FA11, 0, 1 | DECOMP_INLINE, 0x4CF8}, + {0x2FA12, 0, 1, 5094}, + {0x2FA13, 0, 1, 5095}, + {0x2FA14, 0, 1, 5096}, + {0x2FA15, 0, 1 | DECOMP_INLINE, 0x9EBB}, + {0x2FA16, 0, 1 | DECOMP_INLINE, 0x4D56}, + {0x2FA17, 0, 1 | DECOMP_INLINE, 0x9EF9}, + {0x2FA18, 0, 1 | DECOMP_INLINE, 0x9EFE}, + {0x2FA19, 0, 1 | DECOMP_INLINE, 0x9F05}, + {0x2FA1A, 0, 1 | DECOMP_INLINE, 0x9F0F}, + {0x2FA1B, 0, 1 | DECOMP_INLINE, 0x9F16}, + {0x2FA1C, 0, 1 | DECOMP_INLINE, 0x9F3B}, + {0x2FA1D, 0, 1, 5097} + +}; + +/* codepoints array */ +static const uint32 UnicodeDecomp_codepoints[5098] = +{ + /* 0 */ 0x0020, 0x0308, + /* 2 */ 0x0020, 0x0304, + /* 4 */ 0x0020, 0x0301, + /* 6 */ 0x0020, 0x0327, + /* 8 */ 0x0031, 0x2044, 0x0034, + /* 11 */ 0x0031, 0x2044, 0x0032, + /* 14 */ 0x0033, 0x2044, 0x0034, + /* 17 */ 0x0041, 0x0300, + /* 19 */ 0x0041, 0x0301, + /* 21 */ 0x0041, 0x0302, + /* 23 */ 0x0041, 0x0303, + /* 25 */ 0x0041, 0x0308, + /* 27 */ 0x0041, 0x030A, + /* 29 */ 0x0043, 0x0327, + /* 31 */ 0x0045, 0x0300, + /* 33 */ 0x0045, 0x0301, + /* 35 */ 0x0045, 0x0302, + /* 37 */ 0x0045, 0x0308, + /* 39 */ 0x0049, 0x0300, + /* 41 */ 0x0049, 0x0301, + /* 43 */ 0x0049, 0x0302, + /* 45 */ 0x0049, 0x0308, + /* 47 */ 0x004E, 0x0303, + /* 49 */ 0x004F, 0x0300, + /* 51 */ 0x004F, 0x0301, + /* 53 */ 0x004F, 0x0302, + /* 55 */ 0x004F, 0x0303, + /* 57 */ 0x004F, 0x0308, + /* 59 */ 0x0055, 0x0300, + /* 61 */ 0x0055, 0x0301, + /* 63 */ 0x0055, 0x0302, + /* 65 */ 0x0055, 0x0308, + /* 67 */ 0x0059, 0x0301, + /* 69 */ 0x0061, 0x0300, + /* 71 */ 0x0061, 0x0301, + /* 73 */ 0x0061, 0x0302, + /* 75 */ 0x0061, 0x0303, + /* 77 */ 0x0061, 0x0308, + /* 79 */ 0x0061, 0x030A, + /* 81 */ 0x0063, 0x0327, + /* 83 */ 0x0065, 0x0300, + /* 85 */ 0x0065, 0x0301, + /* 87 */ 0x0065, 0x0302, + /* 89 */ 0x0065, 0x0308, + /* 91 */ 0x0069, 0x0300, + /* 93 */ 0x0069, 0x0301, + /* 95 */ 0x0069, 0x0302, + /* 97 */ 0x0069, 0x0308, + /* 99 */ 0x006E, 0x0303, + /* 101 */ 0x006F, 0x0300, + /* 103 */ 0x006F, 0x0301, + /* 105 */ 0x006F, 0x0302, + /* 107 */ 0x006F, 0x0303, + /* 109 */ 0x006F, 0x0308, + /* 111 */ 0x0075, 0x0300, + /* 113 */ 0x0075, 0x0301, + /* 115 */ 0x0075, 0x0302, + /* 117 */ 0x0075, 0x0308, + /* 119 */ 0x0079, 0x0301, + /* 121 */ 0x0079, 0x0308, + /* 123 */ 0x0041, 0x0304, + /* 125 */ 0x0061, 0x0304, + /* 127 */ 0x0041, 0x0306, + /* 129 */ 0x0061, 0x0306, + /* 131 */ 0x0041, 0x0328, + /* 133 */ 0x0061, 0x0328, + /* 135 */ 0x0043, 0x0301, + /* 137 */ 0x0063, 0x0301, + /* 139 */ 0x0043, 0x0302, + /* 141 */ 0x0063, 0x0302, + /* 143 */ 0x0043, 0x0307, + /* 145 */ 0x0063, 0x0307, + /* 147 */ 0x0043, 0x030C, + /* 149 */ 0x0063, 0x030C, + /* 151 */ 0x0044, 0x030C, + /* 153 */ 0x0064, 0x030C, + /* 155 */ 0x0045, 0x0304, + /* 157 */ 0x0065, 0x0304, + /* 159 */ 0x0045, 0x0306, + /* 161 */ 0x0065, 0x0306, + /* 163 */ 0x0045, 0x0307, + /* 165 */ 0x0065, 0x0307, + /* 167 */ 0x0045, 0x0328, + /* 169 */ 0x0065, 0x0328, + /* 171 */ 0x0045, 0x030C, + /* 173 */ 0x0065, 0x030C, + /* 175 */ 0x0047, 0x0302, + /* 177 */ 0x0067, 0x0302, + /* 179 */ 0x0047, 0x0306, + /* 181 */ 0x0067, 0x0306, + /* 183 */ 0x0047, 0x0307, + /* 185 */ 0x0067, 0x0307, + /* 187 */ 0x0047, 0x0327, + /* 189 */ 0x0067, 0x0327, + /* 191 */ 0x0048, 0x0302, + /* 193 */ 0x0068, 0x0302, + /* 195 */ 0x0049, 0x0303, + /* 197 */ 0x0069, 0x0303, + /* 199 */ 0x0049, 0x0304, + /* 201 */ 0x0069, 0x0304, + /* 203 */ 0x0049, 0x0306, + /* 205 */ 0x0069, 0x0306, + /* 207 */ 0x0049, 0x0328, + /* 209 */ 0x0069, 0x0328, + /* 211 */ 0x0049, 0x0307, + /* 213 */ 0x0049, 0x004A, + /* 215 */ 0x0069, 0x006A, + /* 217 */ 0x004A, 0x0302, + /* 219 */ 0x006A, 0x0302, + /* 221 */ 0x004B, 0x0327, + /* 223 */ 0x006B, 0x0327, + /* 225 */ 0x004C, 0x0301, + /* 227 */ 0x006C, 0x0301, + /* 229 */ 0x004C, 0x0327, + /* 231 */ 0x006C, 0x0327, + /* 233 */ 0x004C, 0x030C, + /* 235 */ 0x006C, 0x030C, + /* 237 */ 0x004C, 0x00B7, + /* 239 */ 0x006C, 0x00B7, + /* 241 */ 0x004E, 0x0301, + /* 243 */ 0x006E, 0x0301, + /* 245 */ 0x004E, 0x0327, + /* 247 */ 0x006E, 0x0327, + /* 249 */ 0x004E, 0x030C, + /* 251 */ 0x006E, 0x030C, + /* 253 */ 0x02BC, 0x006E, + /* 255 */ 0x004F, 0x0304, + /* 257 */ 0x006F, 0x0304, + /* 259 */ 0x004F, 0x0306, + /* 261 */ 0x006F, 0x0306, + /* 263 */ 0x004F, 0x030B, + /* 265 */ 0x006F, 0x030B, + /* 267 */ 0x0052, 0x0301, + /* 269 */ 0x0072, 0x0301, + /* 271 */ 0x0052, 0x0327, + /* 273 */ 0x0072, 0x0327, + /* 275 */ 0x0052, 0x030C, + /* 277 */ 0x0072, 0x030C, + /* 279 */ 0x0053, 0x0301, + /* 281 */ 0x0073, 0x0301, + /* 283 */ 0x0053, 0x0302, + /* 285 */ 0x0073, 0x0302, + /* 287 */ 0x0053, 0x0327, + /* 289 */ 0x0073, 0x0327, + /* 291 */ 0x0053, 0x030C, + /* 293 */ 0x0073, 0x030C, + /* 295 */ 0x0054, 0x0327, + /* 297 */ 0x0074, 0x0327, + /* 299 */ 0x0054, 0x030C, + /* 301 */ 0x0074, 0x030C, + /* 303 */ 0x0055, 0x0303, + /* 305 */ 0x0075, 0x0303, + /* 307 */ 0x0055, 0x0304, + /* 309 */ 0x0075, 0x0304, + /* 311 */ 0x0055, 0x0306, + /* 313 */ 0x0075, 0x0306, + /* 315 */ 0x0055, 0x030A, + /* 317 */ 0x0075, 0x030A, + /* 319 */ 0x0055, 0x030B, + /* 321 */ 0x0075, 0x030B, + /* 323 */ 0x0055, 0x0328, + /* 325 */ 0x0075, 0x0328, + /* 327 */ 0x0057, 0x0302, + /* 329 */ 0x0077, 0x0302, + /* 331 */ 0x0059, 0x0302, + /* 333 */ 0x0079, 0x0302, + /* 335 */ 0x0059, 0x0308, + /* 337 */ 0x005A, 0x0301, + /* 339 */ 0x007A, 0x0301, + /* 341 */ 0x005A, 0x0307, + /* 343 */ 0x007A, 0x0307, + /* 345 */ 0x005A, 0x030C, + /* 347 */ 0x007A, 0x030C, + /* 349 */ 0x004F, 0x031B, + /* 351 */ 0x006F, 0x031B, + /* 353 */ 0x0055, 0x031B, + /* 355 */ 0x0075, 0x031B, + /* 357 */ 0x0044, 0x017D, + /* 359 */ 0x0044, 0x017E, + /* 361 */ 0x0064, 0x017E, + /* 363 */ 0x004C, 0x004A, + /* 365 */ 0x004C, 0x006A, + /* 367 */ 0x006C, 0x006A, + /* 369 */ 0x004E, 0x004A, + /* 371 */ 0x004E, 0x006A, + /* 373 */ 0x006E, 0x006A, + /* 375 */ 0x0041, 0x030C, + /* 377 */ 0x0061, 0x030C, + /* 379 */ 0x0049, 0x030C, + /* 381 */ 0x0069, 0x030C, + /* 383 */ 0x004F, 0x030C, + /* 385 */ 0x006F, 0x030C, + /* 387 */ 0x0055, 0x030C, + /* 389 */ 0x0075, 0x030C, + /* 391 */ 0x00DC, 0x0304, + /* 393 */ 0x00FC, 0x0304, + /* 395 */ 0x00DC, 0x0301, + /* 397 */ 0x00FC, 0x0301, + /* 399 */ 0x00DC, 0x030C, + /* 401 */ 0x00FC, 0x030C, + /* 403 */ 0x00DC, 0x0300, + /* 405 */ 0x00FC, 0x0300, + /* 407 */ 0x00C4, 0x0304, + /* 409 */ 0x00E4, 0x0304, + /* 411 */ 0x0226, 0x0304, + /* 413 */ 0x0227, 0x0304, + /* 415 */ 0x00C6, 0x0304, + /* 417 */ 0x00E6, 0x0304, + /* 419 */ 0x0047, 0x030C, + /* 421 */ 0x0067, 0x030C, + /* 423 */ 0x004B, 0x030C, + /* 425 */ 0x006B, 0x030C, + /* 427 */ 0x004F, 0x0328, + /* 429 */ 0x006F, 0x0328, + /* 431 */ 0x01EA, 0x0304, + /* 433 */ 0x01EB, 0x0304, + /* 435 */ 0x01B7, 0x030C, + /* 437 */ 0x0292, 0x030C, + /* 439 */ 0x006A, 0x030C, + /* 441 */ 0x0044, 0x005A, + /* 443 */ 0x0044, 0x007A, + /* 445 */ 0x0064, 0x007A, + /* 447 */ 0x0047, 0x0301, + /* 449 */ 0x0067, 0x0301, + /* 451 */ 0x004E, 0x0300, + /* 453 */ 0x006E, 0x0300, + /* 455 */ 0x00C5, 0x0301, + /* 457 */ 0x00E5, 0x0301, + /* 459 */ 0x00C6, 0x0301, + /* 461 */ 0x00E6, 0x0301, + /* 463 */ 0x00D8, 0x0301, + /* 465 */ 0x00F8, 0x0301, + /* 467 */ 0x0041, 0x030F, + /* 469 */ 0x0061, 0x030F, + /* 471 */ 0x0041, 0x0311, + /* 473 */ 0x0061, 0x0311, + /* 475 */ 0x0045, 0x030F, + /* 477 */ 0x0065, 0x030F, + /* 479 */ 0x0045, 0x0311, + /* 481 */ 0x0065, 0x0311, + /* 483 */ 0x0049, 0x030F, + /* 485 */ 0x0069, 0x030F, + /* 487 */ 0x0049, 0x0311, + /* 489 */ 0x0069, 0x0311, + /* 491 */ 0x004F, 0x030F, + /* 493 */ 0x006F, 0x030F, + /* 495 */ 0x004F, 0x0311, + /* 497 */ 0x006F, 0x0311, + /* 499 */ 0x0052, 0x030F, + /* 501 */ 0x0072, 0x030F, + /* 503 */ 0x0052, 0x0311, + /* 505 */ 0x0072, 0x0311, + /* 507 */ 0x0055, 0x030F, + /* 509 */ 0x0075, 0x030F, + /* 511 */ 0x0055, 0x0311, + /* 513 */ 0x0075, 0x0311, + /* 515 */ 0x0053, 0x0326, + /* 517 */ 0x0073, 0x0326, + /* 519 */ 0x0054, 0x0326, + /* 521 */ 0x0074, 0x0326, + /* 523 */ 0x0048, 0x030C, + /* 525 */ 0x0068, 0x030C, + /* 527 */ 0x0041, 0x0307, + /* 529 */ 0x0061, 0x0307, + /* 531 */ 0x0045, 0x0327, + /* 533 */ 0x0065, 0x0327, + /* 535 */ 0x00D6, 0x0304, + /* 537 */ 0x00F6, 0x0304, + /* 539 */ 0x00D5, 0x0304, + /* 541 */ 0x00F5, 0x0304, + /* 543 */ 0x004F, 0x0307, + /* 545 */ 0x006F, 0x0307, + /* 547 */ 0x022E, 0x0304, + /* 549 */ 0x022F, 0x0304, + /* 551 */ 0x0059, 0x0304, + /* 553 */ 0x0079, 0x0304, + /* 555 */ 0x0020, 0x0306, + /* 557 */ 0x0020, 0x0307, + /* 559 */ 0x0020, 0x030A, + /* 561 */ 0x0020, 0x0328, + /* 563 */ 0x0020, 0x0303, + /* 565 */ 0x0020, 0x030B, + /* 567 */ 0x0308, 0x0301, + /* 569 */ 0x0020, 0x0345, + /* 571 */ 0x0020, 0x0301, + /* 573 */ 0x00A8, 0x0301, + /* 575 */ 0x0391, 0x0301, + /* 577 */ 0x0395, 0x0301, + /* 579 */ 0x0397, 0x0301, + /* 581 */ 0x0399, 0x0301, + /* 583 */ 0x039F, 0x0301, + /* 585 */ 0x03A5, 0x0301, + /* 587 */ 0x03A9, 0x0301, + /* 589 */ 0x03CA, 0x0301, + /* 591 */ 0x0399, 0x0308, + /* 593 */ 0x03A5, 0x0308, + /* 595 */ 0x03B1, 0x0301, + /* 597 */ 0x03B5, 0x0301, + /* 599 */ 0x03B7, 0x0301, + /* 601 */ 0x03B9, 0x0301, + /* 603 */ 0x03CB, 0x0301, + /* 605 */ 0x03B9, 0x0308, + /* 607 */ 0x03C5, 0x0308, + /* 609 */ 0x03BF, 0x0301, + /* 611 */ 0x03C5, 0x0301, + /* 613 */ 0x03C9, 0x0301, + /* 615 */ 0x03D2, 0x0301, + /* 617 */ 0x03D2, 0x0308, + /* 619 */ 0x0415, 0x0300, + /* 621 */ 0x0415, 0x0308, + /* 623 */ 0x0413, 0x0301, + /* 625 */ 0x0406, 0x0308, + /* 627 */ 0x041A, 0x0301, + /* 629 */ 0x0418, 0x0300, + /* 631 */ 0x0423, 0x0306, + /* 633 */ 0x0418, 0x0306, + /* 635 */ 0x0438, 0x0306, + /* 637 */ 0x0435, 0x0300, + /* 639 */ 0x0435, 0x0308, + /* 641 */ 0x0433, 0x0301, + /* 643 */ 0x0456, 0x0308, + /* 645 */ 0x043A, 0x0301, + /* 647 */ 0x0438, 0x0300, + /* 649 */ 0x0443, 0x0306, + /* 651 */ 0x0474, 0x030F, + /* 653 */ 0x0475, 0x030F, + /* 655 */ 0x0416, 0x0306, + /* 657 */ 0x0436, 0x0306, + /* 659 */ 0x0410, 0x0306, + /* 661 */ 0x0430, 0x0306, + /* 663 */ 0x0410, 0x0308, + /* 665 */ 0x0430, 0x0308, + /* 667 */ 0x0415, 0x0306, + /* 669 */ 0x0435, 0x0306, + /* 671 */ 0x04D8, 0x0308, + /* 673 */ 0x04D9, 0x0308, + /* 675 */ 0x0416, 0x0308, + /* 677 */ 0x0436, 0x0308, + /* 679 */ 0x0417, 0x0308, + /* 681 */ 0x0437, 0x0308, + /* 683 */ 0x0418, 0x0304, + /* 685 */ 0x0438, 0x0304, + /* 687 */ 0x0418, 0x0308, + /* 689 */ 0x0438, 0x0308, + /* 691 */ 0x041E, 0x0308, + /* 693 */ 0x043E, 0x0308, + /* 695 */ 0x04E8, 0x0308, + /* 697 */ 0x04E9, 0x0308, + /* 699 */ 0x042D, 0x0308, + /* 701 */ 0x044D, 0x0308, + /* 703 */ 0x0423, 0x0304, + /* 705 */ 0x0443, 0x0304, + /* 707 */ 0x0423, 0x0308, + /* 709 */ 0x0443, 0x0308, + /* 711 */ 0x0423, 0x030B, + /* 713 */ 0x0443, 0x030B, + /* 715 */ 0x0427, 0x0308, + /* 717 */ 0x0447, 0x0308, + /* 719 */ 0x042B, 0x0308, + /* 721 */ 0x044B, 0x0308, + /* 723 */ 0x0565, 0x0582, + /* 725 */ 0x0627, 0x0653, + /* 727 */ 0x0627, 0x0654, + /* 729 */ 0x0648, 0x0654, + /* 731 */ 0x0627, 0x0655, + /* 733 */ 0x064A, 0x0654, + /* 735 */ 0x0627, 0x0674, + /* 737 */ 0x0648, 0x0674, + /* 739 */ 0x06C7, 0x0674, + /* 741 */ 0x064A, 0x0674, + /* 743 */ 0x06D5, 0x0654, + /* 745 */ 0x06C1, 0x0654, + /* 747 */ 0x06D2, 0x0654, + /* 749 */ 0x0928, 0x093C, + /* 751 */ 0x0930, 0x093C, + /* 753 */ 0x0933, 0x093C, + /* 755 */ 0x0915, 0x093C, + /* 757 */ 0x0916, 0x093C, + /* 759 */ 0x0917, 0x093C, + /* 761 */ 0x091C, 0x093C, + /* 763 */ 0x0921, 0x093C, + /* 765 */ 0x0922, 0x093C, + /* 767 */ 0x092B, 0x093C, + /* 769 */ 0x092F, 0x093C, + /* 771 */ 0x09C7, 0x09BE, + /* 773 */ 0x09C7, 0x09D7, + /* 775 */ 0x09A1, 0x09BC, + /* 777 */ 0x09A2, 0x09BC, + /* 779 */ 0x09AF, 0x09BC, + /* 781 */ 0x0A32, 0x0A3C, + /* 783 */ 0x0A38, 0x0A3C, + /* 785 */ 0x0A16, 0x0A3C, + /* 787 */ 0x0A17, 0x0A3C, + /* 789 */ 0x0A1C, 0x0A3C, + /* 791 */ 0x0A2B, 0x0A3C, + /* 793 */ 0x0B47, 0x0B56, + /* 795 */ 0x0B47, 0x0B3E, + /* 797 */ 0x0B47, 0x0B57, + /* 799 */ 0x0B21, 0x0B3C, + /* 801 */ 0x0B22, 0x0B3C, + /* 803 */ 0x0B92, 0x0BD7, + /* 805 */ 0x0BC6, 0x0BBE, + /* 807 */ 0x0BC7, 0x0BBE, + /* 809 */ 0x0BC6, 0x0BD7, + /* 811 */ 0x0C46, 0x0C56, + /* 813 */ 0x0CBF, 0x0CD5, + /* 815 */ 0x0CC6, 0x0CD5, + /* 817 */ 0x0CC6, 0x0CD6, + /* 819 */ 0x0CC6, 0x0CC2, + /* 821 */ 0x0CCA, 0x0CD5, + /* 823 */ 0x0D46, 0x0D3E, + /* 825 */ 0x0D47, 0x0D3E, + /* 827 */ 0x0D46, 0x0D57, + /* 829 */ 0x0DD9, 0x0DCA, + /* 831 */ 0x0DD9, 0x0DCF, + /* 833 */ 0x0DDC, 0x0DCA, + /* 835 */ 0x0DD9, 0x0DDF, + /* 837 */ 0x0E4D, 0x0E32, + /* 839 */ 0x0ECD, 0x0EB2, + /* 841 */ 0x0EAB, 0x0E99, + /* 843 */ 0x0EAB, 0x0EA1, + /* 845 */ 0x0F42, 0x0FB7, + /* 847 */ 0x0F4C, 0x0FB7, + /* 849 */ 0x0F51, 0x0FB7, + /* 851 */ 0x0F56, 0x0FB7, + /* 853 */ 0x0F5B, 0x0FB7, + /* 855 */ 0x0F40, 0x0FB5, + /* 857 */ 0x0F71, 0x0F72, + /* 859 */ 0x0F71, 0x0F74, + /* 861 */ 0x0FB2, 0x0F80, + /* 863 */ 0x0FB2, 0x0F81, + /* 865 */ 0x0FB3, 0x0F80, + /* 867 */ 0x0FB3, 0x0F81, + /* 869 */ 0x0F71, 0x0F80, + /* 871 */ 0x0F92, 0x0FB7, + /* 873 */ 0x0F9C, 0x0FB7, + /* 875 */ 0x0FA1, 0x0FB7, + /* 877 */ 0x0FA6, 0x0FB7, + /* 879 */ 0x0FAB, 0x0FB7, + /* 881 */ 0x0F90, 0x0FB5, + /* 883 */ 0x1025, 0x102E, + /* 885 */ 0x1B05, 0x1B35, + /* 887 */ 0x1B07, 0x1B35, + /* 889 */ 0x1B09, 0x1B35, + /* 891 */ 0x1B0B, 0x1B35, + /* 893 */ 0x1B0D, 0x1B35, + /* 895 */ 0x1B11, 0x1B35, + /* 897 */ 0x1B3A, 0x1B35, + /* 899 */ 0x1B3C, 0x1B35, + /* 901 */ 0x1B3E, 0x1B35, + /* 903 */ 0x1B3F, 0x1B35, + /* 905 */ 0x1B42, 0x1B35, + /* 907 */ 0x0041, 0x0325, + /* 909 */ 0x0061, 0x0325, + /* 911 */ 0x0042, 0x0307, + /* 913 */ 0x0062, 0x0307, + /* 915 */ 0x0042, 0x0323, + /* 917 */ 0x0062, 0x0323, + /* 919 */ 0x0042, 0x0331, + /* 921 */ 0x0062, 0x0331, + /* 923 */ 0x00C7, 0x0301, + /* 925 */ 0x00E7, 0x0301, + /* 927 */ 0x0044, 0x0307, + /* 929 */ 0x0064, 0x0307, + /* 931 */ 0x0044, 0x0323, + /* 933 */ 0x0064, 0x0323, + /* 935 */ 0x0044, 0x0331, + /* 937 */ 0x0064, 0x0331, + /* 939 */ 0x0044, 0x0327, + /* 941 */ 0x0064, 0x0327, + /* 943 */ 0x0044, 0x032D, + /* 945 */ 0x0064, 0x032D, + /* 947 */ 0x0112, 0x0300, + /* 949 */ 0x0113, 0x0300, + /* 951 */ 0x0112, 0x0301, + /* 953 */ 0x0113, 0x0301, + /* 955 */ 0x0045, 0x032D, + /* 957 */ 0x0065, 0x032D, + /* 959 */ 0x0045, 0x0330, + /* 961 */ 0x0065, 0x0330, + /* 963 */ 0x0228, 0x0306, + /* 965 */ 0x0229, 0x0306, + /* 967 */ 0x0046, 0x0307, + /* 969 */ 0x0066, 0x0307, + /* 971 */ 0x0047, 0x0304, + /* 973 */ 0x0067, 0x0304, + /* 975 */ 0x0048, 0x0307, + /* 977 */ 0x0068, 0x0307, + /* 979 */ 0x0048, 0x0323, + /* 981 */ 0x0068, 0x0323, + /* 983 */ 0x0048, 0x0308, + /* 985 */ 0x0068, 0x0308, + /* 987 */ 0x0048, 0x0327, + /* 989 */ 0x0068, 0x0327, + /* 991 */ 0x0048, 0x032E, + /* 993 */ 0x0068, 0x032E, + /* 995 */ 0x0049, 0x0330, + /* 997 */ 0x0069, 0x0330, + /* 999 */ 0x00CF, 0x0301, + /* 1001 */ 0x00EF, 0x0301, + /* 1003 */ 0x004B, 0x0301, + /* 1005 */ 0x006B, 0x0301, + /* 1007 */ 0x004B, 0x0323, + /* 1009 */ 0x006B, 0x0323, + /* 1011 */ 0x004B, 0x0331, + /* 1013 */ 0x006B, 0x0331, + /* 1015 */ 0x004C, 0x0323, + /* 1017 */ 0x006C, 0x0323, + /* 1019 */ 0x1E36, 0x0304, + /* 1021 */ 0x1E37, 0x0304, + /* 1023 */ 0x004C, 0x0331, + /* 1025 */ 0x006C, 0x0331, + /* 1027 */ 0x004C, 0x032D, + /* 1029 */ 0x006C, 0x032D, + /* 1031 */ 0x004D, 0x0301, + /* 1033 */ 0x006D, 0x0301, + /* 1035 */ 0x004D, 0x0307, + /* 1037 */ 0x006D, 0x0307, + /* 1039 */ 0x004D, 0x0323, + /* 1041 */ 0x006D, 0x0323, + /* 1043 */ 0x004E, 0x0307, + /* 1045 */ 0x006E, 0x0307, + /* 1047 */ 0x004E, 0x0323, + /* 1049 */ 0x006E, 0x0323, + /* 1051 */ 0x004E, 0x0331, + /* 1053 */ 0x006E, 0x0331, + /* 1055 */ 0x004E, 0x032D, + /* 1057 */ 0x006E, 0x032D, + /* 1059 */ 0x00D5, 0x0301, + /* 1061 */ 0x00F5, 0x0301, + /* 1063 */ 0x00D5, 0x0308, + /* 1065 */ 0x00F5, 0x0308, + /* 1067 */ 0x014C, 0x0300, + /* 1069 */ 0x014D, 0x0300, + /* 1071 */ 0x014C, 0x0301, + /* 1073 */ 0x014D, 0x0301, + /* 1075 */ 0x0050, 0x0301, + /* 1077 */ 0x0070, 0x0301, + /* 1079 */ 0x0050, 0x0307, + /* 1081 */ 0x0070, 0x0307, + /* 1083 */ 0x0052, 0x0307, + /* 1085 */ 0x0072, 0x0307, + /* 1087 */ 0x0052, 0x0323, + /* 1089 */ 0x0072, 0x0323, + /* 1091 */ 0x1E5A, 0x0304, + /* 1093 */ 0x1E5B, 0x0304, + /* 1095 */ 0x0052, 0x0331, + /* 1097 */ 0x0072, 0x0331, + /* 1099 */ 0x0053, 0x0307, + /* 1101 */ 0x0073, 0x0307, + /* 1103 */ 0x0053, 0x0323, + /* 1105 */ 0x0073, 0x0323, + /* 1107 */ 0x015A, 0x0307, + /* 1109 */ 0x015B, 0x0307, + /* 1111 */ 0x0160, 0x0307, + /* 1113 */ 0x0161, 0x0307, + /* 1115 */ 0x1E62, 0x0307, + /* 1117 */ 0x1E63, 0x0307, + /* 1119 */ 0x0054, 0x0307, + /* 1121 */ 0x0074, 0x0307, + /* 1123 */ 0x0054, 0x0323, + /* 1125 */ 0x0074, 0x0323, + /* 1127 */ 0x0054, 0x0331, + /* 1129 */ 0x0074, 0x0331, + /* 1131 */ 0x0054, 0x032D, + /* 1133 */ 0x0074, 0x032D, + /* 1135 */ 0x0055, 0x0324, + /* 1137 */ 0x0075, 0x0324, + /* 1139 */ 0x0055, 0x0330, + /* 1141 */ 0x0075, 0x0330, + /* 1143 */ 0x0055, 0x032D, + /* 1145 */ 0x0075, 0x032D, + /* 1147 */ 0x0168, 0x0301, + /* 1149 */ 0x0169, 0x0301, + /* 1151 */ 0x016A, 0x0308, + /* 1153 */ 0x016B, 0x0308, + /* 1155 */ 0x0056, 0x0303, + /* 1157 */ 0x0076, 0x0303, + /* 1159 */ 0x0056, 0x0323, + /* 1161 */ 0x0076, 0x0323, + /* 1163 */ 0x0057, 0x0300, + /* 1165 */ 0x0077, 0x0300, + /* 1167 */ 0x0057, 0x0301, + /* 1169 */ 0x0077, 0x0301, + /* 1171 */ 0x0057, 0x0308, + /* 1173 */ 0x0077, 0x0308, + /* 1175 */ 0x0057, 0x0307, + /* 1177 */ 0x0077, 0x0307, + /* 1179 */ 0x0057, 0x0323, + /* 1181 */ 0x0077, 0x0323, + /* 1183 */ 0x0058, 0x0307, + /* 1185 */ 0x0078, 0x0307, + /* 1187 */ 0x0058, 0x0308, + /* 1189 */ 0x0078, 0x0308, + /* 1191 */ 0x0059, 0x0307, + /* 1193 */ 0x0079, 0x0307, + /* 1195 */ 0x005A, 0x0302, + /* 1197 */ 0x007A, 0x0302, + /* 1199 */ 0x005A, 0x0323, + /* 1201 */ 0x007A, 0x0323, + /* 1203 */ 0x005A, 0x0331, + /* 1205 */ 0x007A, 0x0331, + /* 1207 */ 0x0068, 0x0331, + /* 1209 */ 0x0074, 0x0308, + /* 1211 */ 0x0077, 0x030A, + /* 1213 */ 0x0079, 0x030A, + /* 1215 */ 0x0061, 0x02BE, + /* 1217 */ 0x017F, 0x0307, + /* 1219 */ 0x0041, 0x0323, + /* 1221 */ 0x0061, 0x0323, + /* 1223 */ 0x0041, 0x0309, + /* 1225 */ 0x0061, 0x0309, + /* 1227 */ 0x00C2, 0x0301, + /* 1229 */ 0x00E2, 0x0301, + /* 1231 */ 0x00C2, 0x0300, + /* 1233 */ 0x00E2, 0x0300, + /* 1235 */ 0x00C2, 0x0309, + /* 1237 */ 0x00E2, 0x0309, + /* 1239 */ 0x00C2, 0x0303, + /* 1241 */ 0x00E2, 0x0303, + /* 1243 */ 0x1EA0, 0x0302, + /* 1245 */ 0x1EA1, 0x0302, + /* 1247 */ 0x0102, 0x0301, + /* 1249 */ 0x0103, 0x0301, + /* 1251 */ 0x0102, 0x0300, + /* 1253 */ 0x0103, 0x0300, + /* 1255 */ 0x0102, 0x0309, + /* 1257 */ 0x0103, 0x0309, + /* 1259 */ 0x0102, 0x0303, + /* 1261 */ 0x0103, 0x0303, + /* 1263 */ 0x1EA0, 0x0306, + /* 1265 */ 0x1EA1, 0x0306, + /* 1267 */ 0x0045, 0x0323, + /* 1269 */ 0x0065, 0x0323, + /* 1271 */ 0x0045, 0x0309, + /* 1273 */ 0x0065, 0x0309, + /* 1275 */ 0x0045, 0x0303, + /* 1277 */ 0x0065, 0x0303, + /* 1279 */ 0x00CA, 0x0301, + /* 1281 */ 0x00EA, 0x0301, + /* 1283 */ 0x00CA, 0x0300, + /* 1285 */ 0x00EA, 0x0300, + /* 1287 */ 0x00CA, 0x0309, + /* 1289 */ 0x00EA, 0x0309, + /* 1291 */ 0x00CA, 0x0303, + /* 1293 */ 0x00EA, 0x0303, + /* 1295 */ 0x1EB8, 0x0302, + /* 1297 */ 0x1EB9, 0x0302, + /* 1299 */ 0x0049, 0x0309, + /* 1301 */ 0x0069, 0x0309, + /* 1303 */ 0x0049, 0x0323, + /* 1305 */ 0x0069, 0x0323, + /* 1307 */ 0x004F, 0x0323, + /* 1309 */ 0x006F, 0x0323, + /* 1311 */ 0x004F, 0x0309, + /* 1313 */ 0x006F, 0x0309, + /* 1315 */ 0x00D4, 0x0301, + /* 1317 */ 0x00F4, 0x0301, + /* 1319 */ 0x00D4, 0x0300, + /* 1321 */ 0x00F4, 0x0300, + /* 1323 */ 0x00D4, 0x0309, + /* 1325 */ 0x00F4, 0x0309, + /* 1327 */ 0x00D4, 0x0303, + /* 1329 */ 0x00F4, 0x0303, + /* 1331 */ 0x1ECC, 0x0302, + /* 1333 */ 0x1ECD, 0x0302, + /* 1335 */ 0x01A0, 0x0301, + /* 1337 */ 0x01A1, 0x0301, + /* 1339 */ 0x01A0, 0x0300, + /* 1341 */ 0x01A1, 0x0300, + /* 1343 */ 0x01A0, 0x0309, + /* 1345 */ 0x01A1, 0x0309, + /* 1347 */ 0x01A0, 0x0303, + /* 1349 */ 0x01A1, 0x0303, + /* 1351 */ 0x01A0, 0x0323, + /* 1353 */ 0x01A1, 0x0323, + /* 1355 */ 0x0055, 0x0323, + /* 1357 */ 0x0075, 0x0323, + /* 1359 */ 0x0055, 0x0309, + /* 1361 */ 0x0075, 0x0309, + /* 1363 */ 0x01AF, 0x0301, + /* 1365 */ 0x01B0, 0x0301, + /* 1367 */ 0x01AF, 0x0300, + /* 1369 */ 0x01B0, 0x0300, + /* 1371 */ 0x01AF, 0x0309, + /* 1373 */ 0x01B0, 0x0309, + /* 1375 */ 0x01AF, 0x0303, + /* 1377 */ 0x01B0, 0x0303, + /* 1379 */ 0x01AF, 0x0323, + /* 1381 */ 0x01B0, 0x0323, + /* 1383 */ 0x0059, 0x0300, + /* 1385 */ 0x0079, 0x0300, + /* 1387 */ 0x0059, 0x0323, + /* 1389 */ 0x0079, 0x0323, + /* 1391 */ 0x0059, 0x0309, + /* 1393 */ 0x0079, 0x0309, + /* 1395 */ 0x0059, 0x0303, + /* 1397 */ 0x0079, 0x0303, + /* 1399 */ 0x03B1, 0x0313, + /* 1401 */ 0x03B1, 0x0314, + /* 1403 */ 0x1F00, 0x0300, + /* 1405 */ 0x1F01, 0x0300, + /* 1407 */ 0x1F00, 0x0301, + /* 1409 */ 0x1F01, 0x0301, + /* 1411 */ 0x1F00, 0x0342, + /* 1413 */ 0x1F01, 0x0342, + /* 1415 */ 0x0391, 0x0313, + /* 1417 */ 0x0391, 0x0314, + /* 1419 */ 0x1F08, 0x0300, + /* 1421 */ 0x1F09, 0x0300, + /* 1423 */ 0x1F08, 0x0301, + /* 1425 */ 0x1F09, 0x0301, + /* 1427 */ 0x1F08, 0x0342, + /* 1429 */ 0x1F09, 0x0342, + /* 1431 */ 0x03B5, 0x0313, + /* 1433 */ 0x03B5, 0x0314, + /* 1435 */ 0x1F10, 0x0300, + /* 1437 */ 0x1F11, 0x0300, + /* 1439 */ 0x1F10, 0x0301, + /* 1441 */ 0x1F11, 0x0301, + /* 1443 */ 0x0395, 0x0313, + /* 1445 */ 0x0395, 0x0314, + /* 1447 */ 0x1F18, 0x0300, + /* 1449 */ 0x1F19, 0x0300, + /* 1451 */ 0x1F18, 0x0301, + /* 1453 */ 0x1F19, 0x0301, + /* 1455 */ 0x03B7, 0x0313, + /* 1457 */ 0x03B7, 0x0314, + /* 1459 */ 0x1F20, 0x0300, + /* 1461 */ 0x1F21, 0x0300, + /* 1463 */ 0x1F20, 0x0301, + /* 1465 */ 0x1F21, 0x0301, + /* 1467 */ 0x1F20, 0x0342, + /* 1469 */ 0x1F21, 0x0342, + /* 1471 */ 0x0397, 0x0313, + /* 1473 */ 0x0397, 0x0314, + /* 1475 */ 0x1F28, 0x0300, + /* 1477 */ 0x1F29, 0x0300, + /* 1479 */ 0x1F28, 0x0301, + /* 1481 */ 0x1F29, 0x0301, + /* 1483 */ 0x1F28, 0x0342, + /* 1485 */ 0x1F29, 0x0342, + /* 1487 */ 0x03B9, 0x0313, + /* 1489 */ 0x03B9, 0x0314, + /* 1491 */ 0x1F30, 0x0300, + /* 1493 */ 0x1F31, 0x0300, + /* 1495 */ 0x1F30, 0x0301, + /* 1497 */ 0x1F31, 0x0301, + /* 1499 */ 0x1F30, 0x0342, + /* 1501 */ 0x1F31, 0x0342, + /* 1503 */ 0x0399, 0x0313, + /* 1505 */ 0x0399, 0x0314, + /* 1507 */ 0x1F38, 0x0300, + /* 1509 */ 0x1F39, 0x0300, + /* 1511 */ 0x1F38, 0x0301, + /* 1513 */ 0x1F39, 0x0301, + /* 1515 */ 0x1F38, 0x0342, + /* 1517 */ 0x1F39, 0x0342, + /* 1519 */ 0x03BF, 0x0313, + /* 1521 */ 0x03BF, 0x0314, + /* 1523 */ 0x1F40, 0x0300, + /* 1525 */ 0x1F41, 0x0300, + /* 1527 */ 0x1F40, 0x0301, + /* 1529 */ 0x1F41, 0x0301, + /* 1531 */ 0x039F, 0x0313, + /* 1533 */ 0x039F, 0x0314, + /* 1535 */ 0x1F48, 0x0300, + /* 1537 */ 0x1F49, 0x0300, + /* 1539 */ 0x1F48, 0x0301, + /* 1541 */ 0x1F49, 0x0301, + /* 1543 */ 0x03C5, 0x0313, + /* 1545 */ 0x03C5, 0x0314, + /* 1547 */ 0x1F50, 0x0300, + /* 1549 */ 0x1F51, 0x0300, + /* 1551 */ 0x1F50, 0x0301, + /* 1553 */ 0x1F51, 0x0301, + /* 1555 */ 0x1F50, 0x0342, + /* 1557 */ 0x1F51, 0x0342, + /* 1559 */ 0x03A5, 0x0314, + /* 1561 */ 0x1F59, 0x0300, + /* 1563 */ 0x1F59, 0x0301, + /* 1565 */ 0x1F59, 0x0342, + /* 1567 */ 0x03C9, 0x0313, + /* 1569 */ 0x03C9, 0x0314, + /* 1571 */ 0x1F60, 0x0300, + /* 1573 */ 0x1F61, 0x0300, + /* 1575 */ 0x1F60, 0x0301, + /* 1577 */ 0x1F61, 0x0301, + /* 1579 */ 0x1F60, 0x0342, + /* 1581 */ 0x1F61, 0x0342, + /* 1583 */ 0x03A9, 0x0313, + /* 1585 */ 0x03A9, 0x0314, + /* 1587 */ 0x1F68, 0x0300, + /* 1589 */ 0x1F69, 0x0300, + /* 1591 */ 0x1F68, 0x0301, + /* 1593 */ 0x1F69, 0x0301, + /* 1595 */ 0x1F68, 0x0342, + /* 1597 */ 0x1F69, 0x0342, + /* 1599 */ 0x03B1, 0x0300, + /* 1601 */ 0x03B5, 0x0300, + /* 1603 */ 0x03B7, 0x0300, + /* 1605 */ 0x03B9, 0x0300, + /* 1607 */ 0x03BF, 0x0300, + /* 1609 */ 0x03C5, 0x0300, + /* 1611 */ 0x03C9, 0x0300, + /* 1613 */ 0x1F00, 0x0345, + /* 1615 */ 0x1F01, 0x0345, + /* 1617 */ 0x1F02, 0x0345, + /* 1619 */ 0x1F03, 0x0345, + /* 1621 */ 0x1F04, 0x0345, + /* 1623 */ 0x1F05, 0x0345, + /* 1625 */ 0x1F06, 0x0345, + /* 1627 */ 0x1F07, 0x0345, + /* 1629 */ 0x1F08, 0x0345, + /* 1631 */ 0x1F09, 0x0345, + /* 1633 */ 0x1F0A, 0x0345, + /* 1635 */ 0x1F0B, 0x0345, + /* 1637 */ 0x1F0C, 0x0345, + /* 1639 */ 0x1F0D, 0x0345, + /* 1641 */ 0x1F0E, 0x0345, + /* 1643 */ 0x1F0F, 0x0345, + /* 1645 */ 0x1F20, 0x0345, + /* 1647 */ 0x1F21, 0x0345, + /* 1649 */ 0x1F22, 0x0345, + /* 1651 */ 0x1F23, 0x0345, + /* 1653 */ 0x1F24, 0x0345, + /* 1655 */ 0x1F25, 0x0345, + /* 1657 */ 0x1F26, 0x0345, + /* 1659 */ 0x1F27, 0x0345, + /* 1661 */ 0x1F28, 0x0345, + /* 1663 */ 0x1F29, 0x0345, + /* 1665 */ 0x1F2A, 0x0345, + /* 1667 */ 0x1F2B, 0x0345, + /* 1669 */ 0x1F2C, 0x0345, + /* 1671 */ 0x1F2D, 0x0345, + /* 1673 */ 0x1F2E, 0x0345, + /* 1675 */ 0x1F2F, 0x0345, + /* 1677 */ 0x1F60, 0x0345, + /* 1679 */ 0x1F61, 0x0345, + /* 1681 */ 0x1F62, 0x0345, + /* 1683 */ 0x1F63, 0x0345, + /* 1685 */ 0x1F64, 0x0345, + /* 1687 */ 0x1F65, 0x0345, + /* 1689 */ 0x1F66, 0x0345, + /* 1691 */ 0x1F67, 0x0345, + /* 1693 */ 0x1F68, 0x0345, + /* 1695 */ 0x1F69, 0x0345, + /* 1697 */ 0x1F6A, 0x0345, + /* 1699 */ 0x1F6B, 0x0345, + /* 1701 */ 0x1F6C, 0x0345, + /* 1703 */ 0x1F6D, 0x0345, + /* 1705 */ 0x1F6E, 0x0345, + /* 1707 */ 0x1F6F, 0x0345, + /* 1709 */ 0x03B1, 0x0306, + /* 1711 */ 0x03B1, 0x0304, + /* 1713 */ 0x1F70, 0x0345, + /* 1715 */ 0x03B1, 0x0345, + /* 1717 */ 0x03AC, 0x0345, + /* 1719 */ 0x03B1, 0x0342, + /* 1721 */ 0x1FB6, 0x0345, + /* 1723 */ 0x0391, 0x0306, + /* 1725 */ 0x0391, 0x0304, + /* 1727 */ 0x0391, 0x0300, + /* 1729 */ 0x0391, 0x0345, + /* 1731 */ 0x0020, 0x0313, + /* 1733 */ 0x0020, 0x0313, + /* 1735 */ 0x0020, 0x0342, + /* 1737 */ 0x00A8, 0x0342, + /* 1739 */ 0x1F74, 0x0345, + /* 1741 */ 0x03B7, 0x0345, + /* 1743 */ 0x03AE, 0x0345, + /* 1745 */ 0x03B7, 0x0342, + /* 1747 */ 0x1FC6, 0x0345, + /* 1749 */ 0x0395, 0x0300, + /* 1751 */ 0x0397, 0x0300, + /* 1753 */ 0x0397, 0x0345, + /* 1755 */ 0x1FBF, 0x0300, + /* 1757 */ 0x1FBF, 0x0301, + /* 1759 */ 0x1FBF, 0x0342, + /* 1761 */ 0x03B9, 0x0306, + /* 1763 */ 0x03B9, 0x0304, + /* 1765 */ 0x03CA, 0x0300, + /* 1767 */ 0x03B9, 0x0342, + /* 1769 */ 0x03CA, 0x0342, + /* 1771 */ 0x0399, 0x0306, + /* 1773 */ 0x0399, 0x0304, + /* 1775 */ 0x0399, 0x0300, + /* 1777 */ 0x1FFE, 0x0300, + /* 1779 */ 0x1FFE, 0x0301, + /* 1781 */ 0x1FFE, 0x0342, + /* 1783 */ 0x03C5, 0x0306, + /* 1785 */ 0x03C5, 0x0304, + /* 1787 */ 0x03CB, 0x0300, + /* 1789 */ 0x03C1, 0x0313, + /* 1791 */ 0x03C1, 0x0314, + /* 1793 */ 0x03C5, 0x0342, + /* 1795 */ 0x03CB, 0x0342, + /* 1797 */ 0x03A5, 0x0306, + /* 1799 */ 0x03A5, 0x0304, + /* 1801 */ 0x03A5, 0x0300, + /* 1803 */ 0x03A1, 0x0314, + /* 1805 */ 0x00A8, 0x0300, + /* 1807 */ 0x1F7C, 0x0345, + /* 1809 */ 0x03C9, 0x0345, + /* 1811 */ 0x03CE, 0x0345, + /* 1813 */ 0x03C9, 0x0342, + /* 1815 */ 0x1FF6, 0x0345, + /* 1817 */ 0x039F, 0x0300, + /* 1819 */ 0x03A9, 0x0300, + /* 1821 */ 0x03A9, 0x0345, + /* 1823 */ 0x0020, 0x0314, + /* 1825 */ 0x0020, 0x0333, + /* 1827 */ 0x002E, 0x002E, + /* 1829 */ 0x002E, 0x002E, 0x002E, + /* 1832 */ 0x2032, 0x2032, + /* 1834 */ 0x2032, 0x2032, 0x2032, + /* 1837 */ 0x2035, 0x2035, + /* 1839 */ 0x2035, 0x2035, 0x2035, + /* 1842 */ 0x0021, 0x0021, + /* 1844 */ 0x0020, 0x0305, + /* 1846 */ 0x003F, 0x003F, + /* 1848 */ 0x003F, 0x0021, + /* 1850 */ 0x0021, 0x003F, + /* 1852 */ 0x2032, 0x2032, 0x2032, 0x2032, + /* 1856 */ 0x0052, 0x0073, + /* 1858 */ 0x0061, 0x002F, 0x0063, + /* 1861 */ 0x0061, 0x002F, 0x0073, + /* 1864 */ 0x00B0, 0x0043, + /* 1866 */ 0x0063, 0x002F, 0x006F, + /* 1869 */ 0x0063, 0x002F, 0x0075, + /* 1872 */ 0x00B0, 0x0046, + /* 1874 */ 0x004E, 0x006F, + /* 1876 */ 0x0053, 0x004D, + /* 1878 */ 0x0054, 0x0045, 0x004C, + /* 1881 */ 0x0054, 0x004D, + /* 1883 */ 0x0046, 0x0041, 0x0058, + /* 1886 */ 0x0031, 0x2044, 0x0037, + /* 1889 */ 0x0031, 0x2044, 0x0039, + /* 1892 */ 0x0031, 0x2044, 0x0031, 0x0030, + /* 1896 */ 0x0031, 0x2044, 0x0033, + /* 1899 */ 0x0032, 0x2044, 0x0033, + /* 1902 */ 0x0031, 0x2044, 0x0035, + /* 1905 */ 0x0032, 0x2044, 0x0035, + /* 1908 */ 0x0033, 0x2044, 0x0035, + /* 1911 */ 0x0034, 0x2044, 0x0035, + /* 1914 */ 0x0031, 0x2044, 0x0036, + /* 1917 */ 0x0035, 0x2044, 0x0036, + /* 1920 */ 0x0031, 0x2044, 0x0038, + /* 1923 */ 0x0033, 0x2044, 0x0038, + /* 1926 */ 0x0035, 0x2044, 0x0038, + /* 1929 */ 0x0037, 0x2044, 0x0038, + /* 1932 */ 0x0031, 0x2044, + /* 1934 */ 0x0049, 0x0049, + /* 1936 */ 0x0049, 0x0049, 0x0049, + /* 1939 */ 0x0049, 0x0056, + /* 1941 */ 0x0056, 0x0049, + /* 1943 */ 0x0056, 0x0049, 0x0049, + /* 1946 */ 0x0056, 0x0049, 0x0049, 0x0049, + /* 1950 */ 0x0049, 0x0058, + /* 1952 */ 0x0058, 0x0049, + /* 1954 */ 0x0058, 0x0049, 0x0049, + /* 1957 */ 0x0069, 0x0069, + /* 1959 */ 0x0069, 0x0069, 0x0069, + /* 1962 */ 0x0069, 0x0076, + /* 1964 */ 0x0076, 0x0069, + /* 1966 */ 0x0076, 0x0069, 0x0069, + /* 1969 */ 0x0076, 0x0069, 0x0069, 0x0069, + /* 1973 */ 0x0069, 0x0078, + /* 1975 */ 0x0078, 0x0069, + /* 1977 */ 0x0078, 0x0069, 0x0069, + /* 1980 */ 0x0030, 0x2044, 0x0033, + /* 1983 */ 0x2190, 0x0338, + /* 1985 */ 0x2192, 0x0338, + /* 1987 */ 0x2194, 0x0338, + /* 1989 */ 0x21D0, 0x0338, + /* 1991 */ 0x21D4, 0x0338, + /* 1993 */ 0x21D2, 0x0338, + /* 1995 */ 0x2203, 0x0338, + /* 1997 */ 0x2208, 0x0338, + /* 1999 */ 0x220B, 0x0338, + /* 2001 */ 0x2223, 0x0338, + /* 2003 */ 0x2225, 0x0338, + /* 2005 */ 0x222B, 0x222B, + /* 2007 */ 0x222B, 0x222B, 0x222B, + /* 2010 */ 0x222E, 0x222E, + /* 2012 */ 0x222E, 0x222E, 0x222E, + /* 2015 */ 0x223C, 0x0338, + /* 2017 */ 0x2243, 0x0338, + /* 2019 */ 0x2245, 0x0338, + /* 2021 */ 0x2248, 0x0338, + /* 2023 */ 0x003D, 0x0338, + /* 2025 */ 0x2261, 0x0338, + /* 2027 */ 0x224D, 0x0338, + /* 2029 */ 0x003C, 0x0338, + /* 2031 */ 0x003E, 0x0338, + /* 2033 */ 0x2264, 0x0338, + /* 2035 */ 0x2265, 0x0338, + /* 2037 */ 0x2272, 0x0338, + /* 2039 */ 0x2273, 0x0338, + /* 2041 */ 0x2276, 0x0338, + /* 2043 */ 0x2277, 0x0338, + /* 2045 */ 0x227A, 0x0338, + /* 2047 */ 0x227B, 0x0338, + /* 2049 */ 0x2282, 0x0338, + /* 2051 */ 0x2283, 0x0338, + /* 2053 */ 0x2286, 0x0338, + /* 2055 */ 0x2287, 0x0338, + /* 2057 */ 0x22A2, 0x0338, + /* 2059 */ 0x22A8, 0x0338, + /* 2061 */ 0x22A9, 0x0338, + /* 2063 */ 0x22AB, 0x0338, + /* 2065 */ 0x227C, 0x0338, + /* 2067 */ 0x227D, 0x0338, + /* 2069 */ 0x2291, 0x0338, + /* 2071 */ 0x2292, 0x0338, + /* 2073 */ 0x22B2, 0x0338, + /* 2075 */ 0x22B3, 0x0338, + /* 2077 */ 0x22B4, 0x0338, + /* 2079 */ 0x22B5, 0x0338, + /* 2081 */ 0x0031, 0x0030, + /* 2083 */ 0x0031, 0x0031, + /* 2085 */ 0x0031, 0x0032, + /* 2087 */ 0x0031, 0x0033, + /* 2089 */ 0x0031, 0x0034, + /* 2091 */ 0x0031, 0x0035, + /* 2093 */ 0x0031, 0x0036, + /* 2095 */ 0x0031, 0x0037, + /* 2097 */ 0x0031, 0x0038, + /* 2099 */ 0x0031, 0x0039, + /* 2101 */ 0x0032, 0x0030, + /* 2103 */ 0x0028, 0x0031, 0x0029, + /* 2106 */ 0x0028, 0x0032, 0x0029, + /* 2109 */ 0x0028, 0x0033, 0x0029, + /* 2112 */ 0x0028, 0x0034, 0x0029, + /* 2115 */ 0x0028, 0x0035, 0x0029, + /* 2118 */ 0x0028, 0x0036, 0x0029, + /* 2121 */ 0x0028, 0x0037, 0x0029, + /* 2124 */ 0x0028, 0x0038, 0x0029, + /* 2127 */ 0x0028, 0x0039, 0x0029, + /* 2130 */ 0x0028, 0x0031, 0x0030, 0x0029, + /* 2134 */ 0x0028, 0x0031, 0x0031, 0x0029, + /* 2138 */ 0x0028, 0x0031, 0x0032, 0x0029, + /* 2142 */ 0x0028, 0x0031, 0x0033, 0x0029, + /* 2146 */ 0x0028, 0x0031, 0x0034, 0x0029, + /* 2150 */ 0x0028, 0x0031, 0x0035, 0x0029, + /* 2154 */ 0x0028, 0x0031, 0x0036, 0x0029, + /* 2158 */ 0x0028, 0x0031, 0x0037, 0x0029, + /* 2162 */ 0x0028, 0x0031, 0x0038, 0x0029, + /* 2166 */ 0x0028, 0x0031, 0x0039, 0x0029, + /* 2170 */ 0x0028, 0x0032, 0x0030, 0x0029, + /* 2174 */ 0x0031, 0x002E, + /* 2176 */ 0x0032, 0x002E, + /* 2178 */ 0x0033, 0x002E, + /* 2180 */ 0x0034, 0x002E, + /* 2182 */ 0x0035, 0x002E, + /* 2184 */ 0x0036, 0x002E, + /* 2186 */ 0x0037, 0x002E, + /* 2188 */ 0x0038, 0x002E, + /* 2190 */ 0x0039, 0x002E, + /* 2192 */ 0x0031, 0x0030, 0x002E, + /* 2195 */ 0x0031, 0x0031, 0x002E, + /* 2198 */ 0x0031, 0x0032, 0x002E, + /* 2201 */ 0x0031, 0x0033, 0x002E, + /* 2204 */ 0x0031, 0x0034, 0x002E, + /* 2207 */ 0x0031, 0x0035, 0x002E, + /* 2210 */ 0x0031, 0x0036, 0x002E, + /* 2213 */ 0x0031, 0x0037, 0x002E, + /* 2216 */ 0x0031, 0x0038, 0x002E, + /* 2219 */ 0x0031, 0x0039, 0x002E, + /* 2222 */ 0x0032, 0x0030, 0x002E, + /* 2225 */ 0x0028, 0x0061, 0x0029, + /* 2228 */ 0x0028, 0x0062, 0x0029, + /* 2231 */ 0x0028, 0x0063, 0x0029, + /* 2234 */ 0x0028, 0x0064, 0x0029, + /* 2237 */ 0x0028, 0x0065, 0x0029, + /* 2240 */ 0x0028, 0x0066, 0x0029, + /* 2243 */ 0x0028, 0x0067, 0x0029, + /* 2246 */ 0x0028, 0x0068, 0x0029, + /* 2249 */ 0x0028, 0x0069, 0x0029, + /* 2252 */ 0x0028, 0x006A, 0x0029, + /* 2255 */ 0x0028, 0x006B, 0x0029, + /* 2258 */ 0x0028, 0x006C, 0x0029, + /* 2261 */ 0x0028, 0x006D, 0x0029, + /* 2264 */ 0x0028, 0x006E, 0x0029, + /* 2267 */ 0x0028, 0x006F, 0x0029, + /* 2270 */ 0x0028, 0x0070, 0x0029, + /* 2273 */ 0x0028, 0x0071, 0x0029, + /* 2276 */ 0x0028, 0x0072, 0x0029, + /* 2279 */ 0x0028, 0x0073, 0x0029, + /* 2282 */ 0x0028, 0x0074, 0x0029, + /* 2285 */ 0x0028, 0x0075, 0x0029, + /* 2288 */ 0x0028, 0x0076, 0x0029, + /* 2291 */ 0x0028, 0x0077, 0x0029, + /* 2294 */ 0x0028, 0x0078, 0x0029, + /* 2297 */ 0x0028, 0x0079, 0x0029, + /* 2300 */ 0x0028, 0x007A, 0x0029, + /* 2303 */ 0x222B, 0x222B, 0x222B, 0x222B, + /* 2307 */ 0x003A, 0x003A, 0x003D, + /* 2310 */ 0x003D, 0x003D, + /* 2312 */ 0x003D, 0x003D, 0x003D, + /* 2315 */ 0x2ADD, 0x0338, + /* 2317 */ 0x304B, 0x3099, + /* 2319 */ 0x304D, 0x3099, + /* 2321 */ 0x304F, 0x3099, + /* 2323 */ 0x3051, 0x3099, + /* 2325 */ 0x3053, 0x3099, + /* 2327 */ 0x3055, 0x3099, + /* 2329 */ 0x3057, 0x3099, + /* 2331 */ 0x3059, 0x3099, + /* 2333 */ 0x305B, 0x3099, + /* 2335 */ 0x305D, 0x3099, + /* 2337 */ 0x305F, 0x3099, + /* 2339 */ 0x3061, 0x3099, + /* 2341 */ 0x3064, 0x3099, + /* 2343 */ 0x3066, 0x3099, + /* 2345 */ 0x3068, 0x3099, + /* 2347 */ 0x306F, 0x3099, + /* 2349 */ 0x306F, 0x309A, + /* 2351 */ 0x3072, 0x3099, + /* 2353 */ 0x3072, 0x309A, + /* 2355 */ 0x3075, 0x3099, + /* 2357 */ 0x3075, 0x309A, + /* 2359 */ 0x3078, 0x3099, + /* 2361 */ 0x3078, 0x309A, + /* 2363 */ 0x307B, 0x3099, + /* 2365 */ 0x307B, 0x309A, + /* 2367 */ 0x3046, 0x3099, + /* 2369 */ 0x0020, 0x3099, + /* 2371 */ 0x0020, 0x309A, + /* 2373 */ 0x309D, 0x3099, + /* 2375 */ 0x3088, 0x308A, + /* 2377 */ 0x30AB, 0x3099, + /* 2379 */ 0x30AD, 0x3099, + /* 2381 */ 0x30AF, 0x3099, + /* 2383 */ 0x30B1, 0x3099, + /* 2385 */ 0x30B3, 0x3099, + /* 2387 */ 0x30B5, 0x3099, + /* 2389 */ 0x30B7, 0x3099, + /* 2391 */ 0x30B9, 0x3099, + /* 2393 */ 0x30BB, 0x3099, + /* 2395 */ 0x30BD, 0x3099, + /* 2397 */ 0x30BF, 0x3099, + /* 2399 */ 0x30C1, 0x3099, + /* 2401 */ 0x30C4, 0x3099, + /* 2403 */ 0x30C6, 0x3099, + /* 2405 */ 0x30C8, 0x3099, + /* 2407 */ 0x30CF, 0x3099, + /* 2409 */ 0x30CF, 0x309A, + /* 2411 */ 0x30D2, 0x3099, + /* 2413 */ 0x30D2, 0x309A, + /* 2415 */ 0x30D5, 0x3099, + /* 2417 */ 0x30D5, 0x309A, + /* 2419 */ 0x30D8, 0x3099, + /* 2421 */ 0x30D8, 0x309A, + /* 2423 */ 0x30DB, 0x3099, + /* 2425 */ 0x30DB, 0x309A, + /* 2427 */ 0x30A6, 0x3099, + /* 2429 */ 0x30EF, 0x3099, + /* 2431 */ 0x30F0, 0x3099, + /* 2433 */ 0x30F1, 0x3099, + /* 2435 */ 0x30F2, 0x3099, + /* 2437 */ 0x30FD, 0x3099, + /* 2439 */ 0x30B3, 0x30C8, + /* 2441 */ 0x0028, 0x1100, 0x0029, + /* 2444 */ 0x0028, 0x1102, 0x0029, + /* 2447 */ 0x0028, 0x1103, 0x0029, + /* 2450 */ 0x0028, 0x1105, 0x0029, + /* 2453 */ 0x0028, 0x1106, 0x0029, + /* 2456 */ 0x0028, 0x1107, 0x0029, + /* 2459 */ 0x0028, 0x1109, 0x0029, + /* 2462 */ 0x0028, 0x110B, 0x0029, + /* 2465 */ 0x0028, 0x110C, 0x0029, + /* 2468 */ 0x0028, 0x110E, 0x0029, + /* 2471 */ 0x0028, 0x110F, 0x0029, + /* 2474 */ 0x0028, 0x1110, 0x0029, + /* 2477 */ 0x0028, 0x1111, 0x0029, + /* 2480 */ 0x0028, 0x1112, 0x0029, + /* 2483 */ 0x0028, 0x1100, 0x1161, 0x0029, + /* 2487 */ 0x0028, 0x1102, 0x1161, 0x0029, + /* 2491 */ 0x0028, 0x1103, 0x1161, 0x0029, + /* 2495 */ 0x0028, 0x1105, 0x1161, 0x0029, + /* 2499 */ 0x0028, 0x1106, 0x1161, 0x0029, + /* 2503 */ 0x0028, 0x1107, 0x1161, 0x0029, + /* 2507 */ 0x0028, 0x1109, 0x1161, 0x0029, + /* 2511 */ 0x0028, 0x110B, 0x1161, 0x0029, + /* 2515 */ 0x0028, 0x110C, 0x1161, 0x0029, + /* 2519 */ 0x0028, 0x110E, 0x1161, 0x0029, + /* 2523 */ 0x0028, 0x110F, 0x1161, 0x0029, + /* 2527 */ 0x0028, 0x1110, 0x1161, 0x0029, + /* 2531 */ 0x0028, 0x1111, 0x1161, 0x0029, + /* 2535 */ 0x0028, 0x1112, 0x1161, 0x0029, + /* 2539 */ 0x0028, 0x110C, 0x116E, 0x0029, + /* 2543 */ 0x0028, 0x110B, 0x1169, 0x110C, 0x1165, 0x11AB, 0x0029, + /* 2550 */ 0x0028, 0x110B, 0x1169, 0x1112, 0x116E, 0x0029, + /* 2556 */ 0x0028, 0x4E00, 0x0029, + /* 2559 */ 0x0028, 0x4E8C, 0x0029, + /* 2562 */ 0x0028, 0x4E09, 0x0029, + /* 2565 */ 0x0028, 0x56DB, 0x0029, + /* 2568 */ 0x0028, 0x4E94, 0x0029, + /* 2571 */ 0x0028, 0x516D, 0x0029, + /* 2574 */ 0x0028, 0x4E03, 0x0029, + /* 2577 */ 0x0028, 0x516B, 0x0029, + /* 2580 */ 0x0028, 0x4E5D, 0x0029, + /* 2583 */ 0x0028, 0x5341, 0x0029, + /* 2586 */ 0x0028, 0x6708, 0x0029, + /* 2589 */ 0x0028, 0x706B, 0x0029, + /* 2592 */ 0x0028, 0x6C34, 0x0029, + /* 2595 */ 0x0028, 0x6728, 0x0029, + /* 2598 */ 0x0028, 0x91D1, 0x0029, + /* 2601 */ 0x0028, 0x571F, 0x0029, + /* 2604 */ 0x0028, 0x65E5, 0x0029, + /* 2607 */ 0x0028, 0x682A, 0x0029, + /* 2610 */ 0x0028, 0x6709, 0x0029, + /* 2613 */ 0x0028, 0x793E, 0x0029, + /* 2616 */ 0x0028, 0x540D, 0x0029, + /* 2619 */ 0x0028, 0x7279, 0x0029, + /* 2622 */ 0x0028, 0x8CA1, 0x0029, + /* 2625 */ 0x0028, 0x795D, 0x0029, + /* 2628 */ 0x0028, 0x52B4, 0x0029, + /* 2631 */ 0x0028, 0x4EE3, 0x0029, + /* 2634 */ 0x0028, 0x547C, 0x0029, + /* 2637 */ 0x0028, 0x5B66, 0x0029, + /* 2640 */ 0x0028, 0x76E3, 0x0029, + /* 2643 */ 0x0028, 0x4F01, 0x0029, + /* 2646 */ 0x0028, 0x8CC7, 0x0029, + /* 2649 */ 0x0028, 0x5354, 0x0029, + /* 2652 */ 0x0028, 0x796D, 0x0029, + /* 2655 */ 0x0028, 0x4F11, 0x0029, + /* 2658 */ 0x0028, 0x81EA, 0x0029, + /* 2661 */ 0x0028, 0x81F3, 0x0029, + /* 2664 */ 0x0050, 0x0054, 0x0045, + /* 2667 */ 0x0032, 0x0031, + /* 2669 */ 0x0032, 0x0032, + /* 2671 */ 0x0032, 0x0033, + /* 2673 */ 0x0032, 0x0034, + /* 2675 */ 0x0032, 0x0035, + /* 2677 */ 0x0032, 0x0036, + /* 2679 */ 0x0032, 0x0037, + /* 2681 */ 0x0032, 0x0038, + /* 2683 */ 0x0032, 0x0039, + /* 2685 */ 0x0033, 0x0030, + /* 2687 */ 0x0033, 0x0031, + /* 2689 */ 0x0033, 0x0032, + /* 2691 */ 0x0033, 0x0033, + /* 2693 */ 0x0033, 0x0034, + /* 2695 */ 0x0033, 0x0035, + /* 2697 */ 0x1100, 0x1161, + /* 2699 */ 0x1102, 0x1161, + /* 2701 */ 0x1103, 0x1161, + /* 2703 */ 0x1105, 0x1161, + /* 2705 */ 0x1106, 0x1161, + /* 2707 */ 0x1107, 0x1161, + /* 2709 */ 0x1109, 0x1161, + /* 2711 */ 0x110B, 0x1161, + /* 2713 */ 0x110C, 0x1161, + /* 2715 */ 0x110E, 0x1161, + /* 2717 */ 0x110F, 0x1161, + /* 2719 */ 0x1110, 0x1161, + /* 2721 */ 0x1111, 0x1161, + /* 2723 */ 0x1112, 0x1161, + /* 2725 */ 0x110E, 0x1161, 0x11B7, 0x1100, 0x1169, + /* 2730 */ 0x110C, 0x116E, 0x110B, 0x1174, + /* 2734 */ 0x110B, 0x116E, + /* 2736 */ 0x0033, 0x0036, + /* 2738 */ 0x0033, 0x0037, + /* 2740 */ 0x0033, 0x0038, + /* 2742 */ 0x0033, 0x0039, + /* 2744 */ 0x0034, 0x0030, + /* 2746 */ 0x0034, 0x0031, + /* 2748 */ 0x0034, 0x0032, + /* 2750 */ 0x0034, 0x0033, + /* 2752 */ 0x0034, 0x0034, + /* 2754 */ 0x0034, 0x0035, + /* 2756 */ 0x0034, 0x0036, + /* 2758 */ 0x0034, 0x0037, + /* 2760 */ 0x0034, 0x0038, + /* 2762 */ 0x0034, 0x0039, + /* 2764 */ 0x0035, 0x0030, + /* 2766 */ 0x0031, 0x6708, + /* 2768 */ 0x0032, 0x6708, + /* 2770 */ 0x0033, 0x6708, + /* 2772 */ 0x0034, 0x6708, + /* 2774 */ 0x0035, 0x6708, + /* 2776 */ 0x0036, 0x6708, + /* 2778 */ 0x0037, 0x6708, + /* 2780 */ 0x0038, 0x6708, + /* 2782 */ 0x0039, 0x6708, + /* 2784 */ 0x0031, 0x0030, 0x6708, + /* 2787 */ 0x0031, 0x0031, 0x6708, + /* 2790 */ 0x0031, 0x0032, 0x6708, + /* 2793 */ 0x0048, 0x0067, + /* 2795 */ 0x0065, 0x0072, 0x0067, + /* 2798 */ 0x0065, 0x0056, + /* 2800 */ 0x004C, 0x0054, 0x0044, + /* 2803 */ 0x4EE4, 0x548C, + /* 2805 */ 0x30A2, 0x30D1, 0x30FC, 0x30C8, + /* 2809 */ 0x30A2, 0x30EB, 0x30D5, 0x30A1, + /* 2813 */ 0x30A2, 0x30F3, 0x30DA, 0x30A2, + /* 2817 */ 0x30A2, 0x30FC, 0x30EB, + /* 2820 */ 0x30A4, 0x30CB, 0x30F3, 0x30B0, + /* 2824 */ 0x30A4, 0x30F3, 0x30C1, + /* 2827 */ 0x30A6, 0x30A9, 0x30F3, + /* 2830 */ 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, + /* 2835 */ 0x30A8, 0x30FC, 0x30AB, 0x30FC, + /* 2839 */ 0x30AA, 0x30F3, 0x30B9, + /* 2842 */ 0x30AA, 0x30FC, 0x30E0, + /* 2845 */ 0x30AB, 0x30A4, 0x30EA, + /* 2848 */ 0x30AB, 0x30E9, 0x30C3, 0x30C8, + /* 2852 */ 0x30AB, 0x30ED, 0x30EA, 0x30FC, + /* 2856 */ 0x30AC, 0x30ED, 0x30F3, + /* 2859 */ 0x30AC, 0x30F3, 0x30DE, + /* 2862 */ 0x30AE, 0x30AC, + /* 2864 */ 0x30AE, 0x30CB, 0x30FC, + /* 2867 */ 0x30AD, 0x30E5, 0x30EA, 0x30FC, + /* 2871 */ 0x30AE, 0x30EB, 0x30C0, 0x30FC, + /* 2875 */ 0x30AD, 0x30ED, + /* 2877 */ 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, + /* 2882 */ 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, + /* 2888 */ 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, + /* 2893 */ 0x30B0, 0x30E9, 0x30E0, + /* 2896 */ 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, + /* 2901 */ 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, + /* 2906 */ 0x30AF, 0x30ED, 0x30FC, 0x30CD, + /* 2910 */ 0x30B1, 0x30FC, 0x30B9, + /* 2913 */ 0x30B3, 0x30EB, 0x30CA, + /* 2916 */ 0x30B3, 0x30FC, 0x30DD, + /* 2919 */ 0x30B5, 0x30A4, 0x30AF, 0x30EB, + /* 2923 */ 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, + /* 2928 */ 0x30B7, 0x30EA, 0x30F3, 0x30B0, + /* 2932 */ 0x30BB, 0x30F3, 0x30C1, + /* 2935 */ 0x30BB, 0x30F3, 0x30C8, + /* 2938 */ 0x30C0, 0x30FC, 0x30B9, + /* 2941 */ 0x30C7, 0x30B7, + /* 2943 */ 0x30C9, 0x30EB, + /* 2945 */ 0x30C8, 0x30F3, + /* 2947 */ 0x30CA, 0x30CE, + /* 2949 */ 0x30CE, 0x30C3, 0x30C8, + /* 2952 */ 0x30CF, 0x30A4, 0x30C4, + /* 2955 */ 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, + /* 2960 */ 0x30D1, 0x30FC, 0x30C4, + /* 2963 */ 0x30D0, 0x30FC, 0x30EC, 0x30EB, + /* 2967 */ 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, + /* 2972 */ 0x30D4, 0x30AF, 0x30EB, + /* 2975 */ 0x30D4, 0x30B3, + /* 2977 */ 0x30D3, 0x30EB, + /* 2979 */ 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, + /* 2984 */ 0x30D5, 0x30A3, 0x30FC, 0x30C8, + /* 2988 */ 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, + /* 2993 */ 0x30D5, 0x30E9, 0x30F3, + /* 2996 */ 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, + /* 3001 */ 0x30DA, 0x30BD, + /* 3003 */ 0x30DA, 0x30CB, 0x30D2, + /* 3006 */ 0x30D8, 0x30EB, 0x30C4, + /* 3009 */ 0x30DA, 0x30F3, 0x30B9, + /* 3012 */ 0x30DA, 0x30FC, 0x30B8, + /* 3015 */ 0x30D9, 0x30FC, 0x30BF, + /* 3018 */ 0x30DD, 0x30A4, 0x30F3, 0x30C8, + /* 3022 */ 0x30DC, 0x30EB, 0x30C8, + /* 3025 */ 0x30DB, 0x30F3, + /* 3027 */ 0x30DD, 0x30F3, 0x30C9, + /* 3030 */ 0x30DB, 0x30FC, 0x30EB, + /* 3033 */ 0x30DB, 0x30FC, 0x30F3, + /* 3036 */ 0x30DE, 0x30A4, 0x30AF, 0x30ED, + /* 3040 */ 0x30DE, 0x30A4, 0x30EB, + /* 3043 */ 0x30DE, 0x30C3, 0x30CF, + /* 3046 */ 0x30DE, 0x30EB, 0x30AF, + /* 3049 */ 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, + /* 3054 */ 0x30DF, 0x30AF, 0x30ED, 0x30F3, + /* 3058 */ 0x30DF, 0x30EA, + /* 3060 */ 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, + /* 3065 */ 0x30E1, 0x30AC, + /* 3067 */ 0x30E1, 0x30AC, 0x30C8, 0x30F3, + /* 3071 */ 0x30E1, 0x30FC, 0x30C8, 0x30EB, + /* 3075 */ 0x30E4, 0x30FC, 0x30C9, + /* 3078 */ 0x30E4, 0x30FC, 0x30EB, + /* 3081 */ 0x30E6, 0x30A2, 0x30F3, + /* 3084 */ 0x30EA, 0x30C3, 0x30C8, 0x30EB, + /* 3088 */ 0x30EA, 0x30E9, + /* 3090 */ 0x30EB, 0x30D4, 0x30FC, + /* 3093 */ 0x30EB, 0x30FC, 0x30D6, 0x30EB, + /* 3097 */ 0x30EC, 0x30E0, + /* 3099 */ 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, + /* 3104 */ 0x30EF, 0x30C3, 0x30C8, + /* 3107 */ 0x0030, 0x70B9, + /* 3109 */ 0x0031, 0x70B9, + /* 3111 */ 0x0032, 0x70B9, + /* 3113 */ 0x0033, 0x70B9, + /* 3115 */ 0x0034, 0x70B9, + /* 3117 */ 0x0035, 0x70B9, + /* 3119 */ 0x0036, 0x70B9, + /* 3121 */ 0x0037, 0x70B9, + /* 3123 */ 0x0038, 0x70B9, + /* 3125 */ 0x0039, 0x70B9, + /* 3127 */ 0x0031, 0x0030, 0x70B9, + /* 3130 */ 0x0031, 0x0031, 0x70B9, + /* 3133 */ 0x0031, 0x0032, 0x70B9, + /* 3136 */ 0x0031, 0x0033, 0x70B9, + /* 3139 */ 0x0031, 0x0034, 0x70B9, + /* 3142 */ 0x0031, 0x0035, 0x70B9, + /* 3145 */ 0x0031, 0x0036, 0x70B9, + /* 3148 */ 0x0031, 0x0037, 0x70B9, + /* 3151 */ 0x0031, 0x0038, 0x70B9, + /* 3154 */ 0x0031, 0x0039, 0x70B9, + /* 3157 */ 0x0032, 0x0030, 0x70B9, + /* 3160 */ 0x0032, 0x0031, 0x70B9, + /* 3163 */ 0x0032, 0x0032, 0x70B9, + /* 3166 */ 0x0032, 0x0033, 0x70B9, + /* 3169 */ 0x0032, 0x0034, 0x70B9, + /* 3172 */ 0x0068, 0x0050, 0x0061, + /* 3175 */ 0x0064, 0x0061, + /* 3177 */ 0x0041, 0x0055, + /* 3179 */ 0x0062, 0x0061, 0x0072, + /* 3182 */ 0x006F, 0x0056, + /* 3184 */ 0x0070, 0x0063, + /* 3186 */ 0x0064, 0x006D, + /* 3188 */ 0x0064, 0x006D, 0x00B2, + /* 3191 */ 0x0064, 0x006D, 0x00B3, + /* 3194 */ 0x0049, 0x0055, + /* 3196 */ 0x5E73, 0x6210, + /* 3198 */ 0x662D, 0x548C, + /* 3200 */ 0x5927, 0x6B63, + /* 3202 */ 0x660E, 0x6CBB, + /* 3204 */ 0x682A, 0x5F0F, 0x4F1A, 0x793E, + /* 3208 */ 0x0070, 0x0041, + /* 3210 */ 0x006E, 0x0041, + /* 3212 */ 0x03BC, 0x0041, + /* 3214 */ 0x006D, 0x0041, + /* 3216 */ 0x006B, 0x0041, + /* 3218 */ 0x004B, 0x0042, + /* 3220 */ 0x004D, 0x0042, + /* 3222 */ 0x0047, 0x0042, + /* 3224 */ 0x0063, 0x0061, 0x006C, + /* 3227 */ 0x006B, 0x0063, 0x0061, 0x006C, + /* 3231 */ 0x0070, 0x0046, + /* 3233 */ 0x006E, 0x0046, + /* 3235 */ 0x03BC, 0x0046, + /* 3237 */ 0x03BC, 0x0067, + /* 3239 */ 0x006D, 0x0067, + /* 3241 */ 0x006B, 0x0067, + /* 3243 */ 0x0048, 0x007A, + /* 3245 */ 0x006B, 0x0048, 0x007A, + /* 3248 */ 0x004D, 0x0048, 0x007A, + /* 3251 */ 0x0047, 0x0048, 0x007A, + /* 3254 */ 0x0054, 0x0048, 0x007A, + /* 3257 */ 0x03BC, 0x2113, + /* 3259 */ 0x006D, 0x2113, + /* 3261 */ 0x0064, 0x2113, + /* 3263 */ 0x006B, 0x2113, + /* 3265 */ 0x0066, 0x006D, + /* 3267 */ 0x006E, 0x006D, + /* 3269 */ 0x03BC, 0x006D, + /* 3271 */ 0x006D, 0x006D, + /* 3273 */ 0x0063, 0x006D, + /* 3275 */ 0x006B, 0x006D, + /* 3277 */ 0x006D, 0x006D, 0x00B2, + /* 3280 */ 0x0063, 0x006D, 0x00B2, + /* 3283 */ 0x006D, 0x00B2, + /* 3285 */ 0x006B, 0x006D, 0x00B2, + /* 3288 */ 0x006D, 0x006D, 0x00B3, + /* 3291 */ 0x0063, 0x006D, 0x00B3, + /* 3294 */ 0x006D, 0x00B3, + /* 3296 */ 0x006B, 0x006D, 0x00B3, + /* 3299 */ 0x006D, 0x2215, 0x0073, + /* 3302 */ 0x006D, 0x2215, 0x0073, 0x00B2, + /* 3306 */ 0x0050, 0x0061, + /* 3308 */ 0x006B, 0x0050, 0x0061, + /* 3311 */ 0x004D, 0x0050, 0x0061, + /* 3314 */ 0x0047, 0x0050, 0x0061, + /* 3317 */ 0x0072, 0x0061, 0x0064, + /* 3320 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, + /* 3325 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, + /* 3331 */ 0x0070, 0x0073, + /* 3333 */ 0x006E, 0x0073, + /* 3335 */ 0x03BC, 0x0073, + /* 3337 */ 0x006D, 0x0073, + /* 3339 */ 0x0070, 0x0056, + /* 3341 */ 0x006E, 0x0056, + /* 3343 */ 0x03BC, 0x0056, + /* 3345 */ 0x006D, 0x0056, + /* 3347 */ 0x006B, 0x0056, + /* 3349 */ 0x004D, 0x0056, + /* 3351 */ 0x0070, 0x0057, + /* 3353 */ 0x006E, 0x0057, + /* 3355 */ 0x03BC, 0x0057, + /* 3357 */ 0x006D, 0x0057, + /* 3359 */ 0x006B, 0x0057, + /* 3361 */ 0x004D, 0x0057, + /* 3363 */ 0x006B, 0x03A9, + /* 3365 */ 0x004D, 0x03A9, + /* 3367 */ 0x0061, 0x002E, 0x006D, 0x002E, + /* 3371 */ 0x0042, 0x0071, + /* 3373 */ 0x0063, 0x0063, + /* 3375 */ 0x0063, 0x0064, + /* 3377 */ 0x0043, 0x2215, 0x006B, 0x0067, + /* 3381 */ 0x0043, 0x006F, 0x002E, + /* 3384 */ 0x0064, 0x0042, + /* 3386 */ 0x0047, 0x0079, + /* 3388 */ 0x0068, 0x0061, + /* 3390 */ 0x0048, 0x0050, + /* 3392 */ 0x0069, 0x006E, + /* 3394 */ 0x004B, 0x004B, + /* 3396 */ 0x004B, 0x004D, + /* 3398 */ 0x006B, 0x0074, + /* 3400 */ 0x006C, 0x006D, + /* 3402 */ 0x006C, 0x006E, + /* 3404 */ 0x006C, 0x006F, 0x0067, + /* 3407 */ 0x006C, 0x0078, + /* 3409 */ 0x006D, 0x0062, + /* 3411 */ 0x006D, 0x0069, 0x006C, + /* 3414 */ 0x006D, 0x006F, 0x006C, + /* 3417 */ 0x0050, 0x0048, + /* 3419 */ 0x0070, 0x002E, 0x006D, 0x002E, + /* 3423 */ 0x0050, 0x0050, 0x004D, + /* 3426 */ 0x0050, 0x0052, + /* 3428 */ 0x0073, 0x0072, + /* 3430 */ 0x0053, 0x0076, + /* 3432 */ 0x0057, 0x0062, + /* 3434 */ 0x0056, 0x2215, 0x006D, + /* 3437 */ 0x0041, 0x2215, 0x006D, + /* 3440 */ 0x0031, 0x65E5, + /* 3442 */ 0x0032, 0x65E5, + /* 3444 */ 0x0033, 0x65E5, + /* 3446 */ 0x0034, 0x65E5, + /* 3448 */ 0x0035, 0x65E5, + /* 3450 */ 0x0036, 0x65E5, + /* 3452 */ 0x0037, 0x65E5, + /* 3454 */ 0x0038, 0x65E5, + /* 3456 */ 0x0039, 0x65E5, + /* 3458 */ 0x0031, 0x0030, 0x65E5, + /* 3461 */ 0x0031, 0x0031, 0x65E5, + /* 3464 */ 0x0031, 0x0032, 0x65E5, + /* 3467 */ 0x0031, 0x0033, 0x65E5, + /* 3470 */ 0x0031, 0x0034, 0x65E5, + /* 3473 */ 0x0031, 0x0035, 0x65E5, + /* 3476 */ 0x0031, 0x0036, 0x65E5, + /* 3479 */ 0x0031, 0x0037, 0x65E5, + /* 3482 */ 0x0031, 0x0038, 0x65E5, + /* 3485 */ 0x0031, 0x0039, 0x65E5, + /* 3488 */ 0x0032, 0x0030, 0x65E5, + /* 3491 */ 0x0032, 0x0031, 0x65E5, + /* 3494 */ 0x0032, 0x0032, 0x65E5, + /* 3497 */ 0x0032, 0x0033, 0x65E5, + /* 3500 */ 0x0032, 0x0034, 0x65E5, + /* 3503 */ 0x0032, 0x0035, 0x65E5, + /* 3506 */ 0x0032, 0x0036, 0x65E5, + /* 3509 */ 0x0032, 0x0037, 0x65E5, + /* 3512 */ 0x0032, 0x0038, 0x65E5, + /* 3515 */ 0x0032, 0x0039, 0x65E5, + /* 3518 */ 0x0033, 0x0030, 0x65E5, + /* 3521 */ 0x0033, 0x0031, 0x65E5, + /* 3524 */ 0x0067, 0x0061, 0x006C, + /* 3527 */ 0x242EE, + /* 3528 */ 0x2284A, + /* 3529 */ 0x22844, + /* 3530 */ 0x233D5, + /* 3531 */ 0x25249, + /* 3532 */ 0x25CD0, + /* 3533 */ 0x27ED3, + /* 3534 */ 0x0066, 0x0066, + /* 3536 */ 0x0066, 0x0069, + /* 3538 */ 0x0066, 0x006C, + /* 3540 */ 0x0066, 0x0066, 0x0069, + /* 3543 */ 0x0066, 0x0066, 0x006C, + /* 3546 */ 0x017F, 0x0074, + /* 3548 */ 0x0073, 0x0074, + /* 3550 */ 0x0574, 0x0576, + /* 3552 */ 0x0574, 0x0565, + /* 3554 */ 0x0574, 0x056B, + /* 3556 */ 0x057E, 0x0576, + /* 3558 */ 0x0574, 0x056D, + /* 3560 */ 0x05D9, 0x05B4, + /* 3562 */ 0x05F2, 0x05B7, + /* 3564 */ 0x05E9, 0x05C1, + /* 3566 */ 0x05E9, 0x05C2, + /* 3568 */ 0xFB49, 0x05C1, + /* 3570 */ 0xFB49, 0x05C2, + /* 3572 */ 0x05D0, 0x05B7, + /* 3574 */ 0x05D0, 0x05B8, + /* 3576 */ 0x05D0, 0x05BC, + /* 3578 */ 0x05D1, 0x05BC, + /* 3580 */ 0x05D2, 0x05BC, + /* 3582 */ 0x05D3, 0x05BC, + /* 3584 */ 0x05D4, 0x05BC, + /* 3586 */ 0x05D5, 0x05BC, + /* 3588 */ 0x05D6, 0x05BC, + /* 3590 */ 0x05D8, 0x05BC, + /* 3592 */ 0x05D9, 0x05BC, + /* 3594 */ 0x05DA, 0x05BC, + /* 3596 */ 0x05DB, 0x05BC, + /* 3598 */ 0x05DC, 0x05BC, + /* 3600 */ 0x05DE, 0x05BC, + /* 3602 */ 0x05E0, 0x05BC, + /* 3604 */ 0x05E1, 0x05BC, + /* 3606 */ 0x05E3, 0x05BC, + /* 3608 */ 0x05E4, 0x05BC, + /* 3610 */ 0x05E6, 0x05BC, + /* 3612 */ 0x05E7, 0x05BC, + /* 3614 */ 0x05E8, 0x05BC, + /* 3616 */ 0x05E9, 0x05BC, + /* 3618 */ 0x05EA, 0x05BC, + /* 3620 */ 0x05D5, 0x05B9, + /* 3622 */ 0x05D1, 0x05BF, + /* 3624 */ 0x05DB, 0x05BF, + /* 3626 */ 0x05E4, 0x05BF, + /* 3628 */ 0x05D0, 0x05DC, + /* 3630 */ 0x0626, 0x0627, + /* 3632 */ 0x0626, 0x0627, + /* 3634 */ 0x0626, 0x06D5, + /* 3636 */ 0x0626, 0x06D5, + /* 3638 */ 0x0626, 0x0648, + /* 3640 */ 0x0626, 0x0648, + /* 3642 */ 0x0626, 0x06C7, + /* 3644 */ 0x0626, 0x06C7, + /* 3646 */ 0x0626, 0x06C6, + /* 3648 */ 0x0626, 0x06C6, + /* 3650 */ 0x0626, 0x06C8, + /* 3652 */ 0x0626, 0x06C8, + /* 3654 */ 0x0626, 0x06D0, + /* 3656 */ 0x0626, 0x06D0, + /* 3658 */ 0x0626, 0x06D0, + /* 3660 */ 0x0626, 0x0649, + /* 3662 */ 0x0626, 0x0649, + /* 3664 */ 0x0626, 0x0649, + /* 3666 */ 0x0626, 0x062C, + /* 3668 */ 0x0626, 0x062D, + /* 3670 */ 0x0626, 0x0645, + /* 3672 */ 0x0626, 0x0649, + /* 3674 */ 0x0626, 0x064A, + /* 3676 */ 0x0628, 0x062C, + /* 3678 */ 0x0628, 0x062D, + /* 3680 */ 0x0628, 0x062E, + /* 3682 */ 0x0628, 0x0645, + /* 3684 */ 0x0628, 0x0649, + /* 3686 */ 0x0628, 0x064A, + /* 3688 */ 0x062A, 0x062C, + /* 3690 */ 0x062A, 0x062D, + /* 3692 */ 0x062A, 0x062E, + /* 3694 */ 0x062A, 0x0645, + /* 3696 */ 0x062A, 0x0649, + /* 3698 */ 0x062A, 0x064A, + /* 3700 */ 0x062B, 0x062C, + /* 3702 */ 0x062B, 0x0645, + /* 3704 */ 0x062B, 0x0649, + /* 3706 */ 0x062B, 0x064A, + /* 3708 */ 0x062C, 0x062D, + /* 3710 */ 0x062C, 0x0645, + /* 3712 */ 0x062D, 0x062C, + /* 3714 */ 0x062D, 0x0645, + /* 3716 */ 0x062E, 0x062C, + /* 3718 */ 0x062E, 0x062D, + /* 3720 */ 0x062E, 0x0645, + /* 3722 */ 0x0633, 0x062C, + /* 3724 */ 0x0633, 0x062D, + /* 3726 */ 0x0633, 0x062E, + /* 3728 */ 0x0633, 0x0645, + /* 3730 */ 0x0635, 0x062D, + /* 3732 */ 0x0635, 0x0645, + /* 3734 */ 0x0636, 0x062C, + /* 3736 */ 0x0636, 0x062D, + /* 3738 */ 0x0636, 0x062E, + /* 3740 */ 0x0636, 0x0645, + /* 3742 */ 0x0637, 0x062D, + /* 3744 */ 0x0637, 0x0645, + /* 3746 */ 0x0638, 0x0645, + /* 3748 */ 0x0639, 0x062C, + /* 3750 */ 0x0639, 0x0645, + /* 3752 */ 0x063A, 0x062C, + /* 3754 */ 0x063A, 0x0645, + /* 3756 */ 0x0641, 0x062C, + /* 3758 */ 0x0641, 0x062D, + /* 3760 */ 0x0641, 0x062E, + /* 3762 */ 0x0641, 0x0645, + /* 3764 */ 0x0641, 0x0649, + /* 3766 */ 0x0641, 0x064A, + /* 3768 */ 0x0642, 0x062D, + /* 3770 */ 0x0642, 0x0645, + /* 3772 */ 0x0642, 0x0649, + /* 3774 */ 0x0642, 0x064A, + /* 3776 */ 0x0643, 0x0627, + /* 3778 */ 0x0643, 0x062C, + /* 3780 */ 0x0643, 0x062D, + /* 3782 */ 0x0643, 0x062E, + /* 3784 */ 0x0643, 0x0644, + /* 3786 */ 0x0643, 0x0645, + /* 3788 */ 0x0643, 0x0649, + /* 3790 */ 0x0643, 0x064A, + /* 3792 */ 0x0644, 0x062C, + /* 3794 */ 0x0644, 0x062D, + /* 3796 */ 0x0644, 0x062E, + /* 3798 */ 0x0644, 0x0645, + /* 3800 */ 0x0644, 0x0649, + /* 3802 */ 0x0644, 0x064A, + /* 3804 */ 0x0645, 0x062C, + /* 3806 */ 0x0645, 0x062D, + /* 3808 */ 0x0645, 0x062E, + /* 3810 */ 0x0645, 0x0645, + /* 3812 */ 0x0645, 0x0649, + /* 3814 */ 0x0645, 0x064A, + /* 3816 */ 0x0646, 0x062C, + /* 3818 */ 0x0646, 0x062D, + /* 3820 */ 0x0646, 0x062E, + /* 3822 */ 0x0646, 0x0645, + /* 3824 */ 0x0646, 0x0649, + /* 3826 */ 0x0646, 0x064A, + /* 3828 */ 0x0647, 0x062C, + /* 3830 */ 0x0647, 0x0645, + /* 3832 */ 0x0647, 0x0649, + /* 3834 */ 0x0647, 0x064A, + /* 3836 */ 0x064A, 0x062C, + /* 3838 */ 0x064A, 0x062D, + /* 3840 */ 0x064A, 0x062E, + /* 3842 */ 0x064A, 0x0645, + /* 3844 */ 0x064A, 0x0649, + /* 3846 */ 0x064A, 0x064A, + /* 3848 */ 0x0630, 0x0670, + /* 3850 */ 0x0631, 0x0670, + /* 3852 */ 0x0649, 0x0670, + /* 3854 */ 0x0020, 0x064C, 0x0651, + /* 3857 */ 0x0020, 0x064D, 0x0651, + /* 3860 */ 0x0020, 0x064E, 0x0651, + /* 3863 */ 0x0020, 0x064F, 0x0651, + /* 3866 */ 0x0020, 0x0650, 0x0651, + /* 3869 */ 0x0020, 0x0651, 0x0670, + /* 3872 */ 0x0626, 0x0631, + /* 3874 */ 0x0626, 0x0632, + /* 3876 */ 0x0626, 0x0645, + /* 3878 */ 0x0626, 0x0646, + /* 3880 */ 0x0626, 0x0649, + /* 3882 */ 0x0626, 0x064A, + /* 3884 */ 0x0628, 0x0631, + /* 3886 */ 0x0628, 0x0632, + /* 3888 */ 0x0628, 0x0645, + /* 3890 */ 0x0628, 0x0646, + /* 3892 */ 0x0628, 0x0649, + /* 3894 */ 0x0628, 0x064A, + /* 3896 */ 0x062A, 0x0631, + /* 3898 */ 0x062A, 0x0632, + /* 3900 */ 0x062A, 0x0645, + /* 3902 */ 0x062A, 0x0646, + /* 3904 */ 0x062A, 0x0649, + /* 3906 */ 0x062A, 0x064A, + /* 3908 */ 0x062B, 0x0631, + /* 3910 */ 0x062B, 0x0632, + /* 3912 */ 0x062B, 0x0645, + /* 3914 */ 0x062B, 0x0646, + /* 3916 */ 0x062B, 0x0649, + /* 3918 */ 0x062B, 0x064A, + /* 3920 */ 0x0641, 0x0649, + /* 3922 */ 0x0641, 0x064A, + /* 3924 */ 0x0642, 0x0649, + /* 3926 */ 0x0642, 0x064A, + /* 3928 */ 0x0643, 0x0627, + /* 3930 */ 0x0643, 0x0644, + /* 3932 */ 0x0643, 0x0645, + /* 3934 */ 0x0643, 0x0649, + /* 3936 */ 0x0643, 0x064A, + /* 3938 */ 0x0644, 0x0645, + /* 3940 */ 0x0644, 0x0649, + /* 3942 */ 0x0644, 0x064A, + /* 3944 */ 0x0645, 0x0627, + /* 3946 */ 0x0645, 0x0645, + /* 3948 */ 0x0646, 0x0631, + /* 3950 */ 0x0646, 0x0632, + /* 3952 */ 0x0646, 0x0645, + /* 3954 */ 0x0646, 0x0646, + /* 3956 */ 0x0646, 0x0649, + /* 3958 */ 0x0646, 0x064A, + /* 3960 */ 0x0649, 0x0670, + /* 3962 */ 0x064A, 0x0631, + /* 3964 */ 0x064A, 0x0632, + /* 3966 */ 0x064A, 0x0645, + /* 3968 */ 0x064A, 0x0646, + /* 3970 */ 0x064A, 0x0649, + /* 3972 */ 0x064A, 0x064A, + /* 3974 */ 0x0626, 0x062C, + /* 3976 */ 0x0626, 0x062D, + /* 3978 */ 0x0626, 0x062E, + /* 3980 */ 0x0626, 0x0645, + /* 3982 */ 0x0626, 0x0647, + /* 3984 */ 0x0628, 0x062C, + /* 3986 */ 0x0628, 0x062D, + /* 3988 */ 0x0628, 0x062E, + /* 3990 */ 0x0628, 0x0645, + /* 3992 */ 0x0628, 0x0647, + /* 3994 */ 0x062A, 0x062C, + /* 3996 */ 0x062A, 0x062D, + /* 3998 */ 0x062A, 0x062E, + /* 4000 */ 0x062A, 0x0645, + /* 4002 */ 0x062A, 0x0647, + /* 4004 */ 0x062B, 0x0645, + /* 4006 */ 0x062C, 0x062D, + /* 4008 */ 0x062C, 0x0645, + /* 4010 */ 0x062D, 0x062C, + /* 4012 */ 0x062D, 0x0645, + /* 4014 */ 0x062E, 0x062C, + /* 4016 */ 0x062E, 0x0645, + /* 4018 */ 0x0633, 0x062C, + /* 4020 */ 0x0633, 0x062D, + /* 4022 */ 0x0633, 0x062E, + /* 4024 */ 0x0633, 0x0645, + /* 4026 */ 0x0635, 0x062D, + /* 4028 */ 0x0635, 0x062E, + /* 4030 */ 0x0635, 0x0645, + /* 4032 */ 0x0636, 0x062C, + /* 4034 */ 0x0636, 0x062D, + /* 4036 */ 0x0636, 0x062E, + /* 4038 */ 0x0636, 0x0645, + /* 4040 */ 0x0637, 0x062D, + /* 4042 */ 0x0638, 0x0645, + /* 4044 */ 0x0639, 0x062C, + /* 4046 */ 0x0639, 0x0645, + /* 4048 */ 0x063A, 0x062C, + /* 4050 */ 0x063A, 0x0645, + /* 4052 */ 0x0641, 0x062C, + /* 4054 */ 0x0641, 0x062D, + /* 4056 */ 0x0641, 0x062E, + /* 4058 */ 0x0641, 0x0645, + /* 4060 */ 0x0642, 0x062D, + /* 4062 */ 0x0642, 0x0645, + /* 4064 */ 0x0643, 0x062C, + /* 4066 */ 0x0643, 0x062D, + /* 4068 */ 0x0643, 0x062E, + /* 4070 */ 0x0643, 0x0644, + /* 4072 */ 0x0643, 0x0645, + /* 4074 */ 0x0644, 0x062C, + /* 4076 */ 0x0644, 0x062D, + /* 4078 */ 0x0644, 0x062E, + /* 4080 */ 0x0644, 0x0645, + /* 4082 */ 0x0644, 0x0647, + /* 4084 */ 0x0645, 0x062C, + /* 4086 */ 0x0645, 0x062D, + /* 4088 */ 0x0645, 0x062E, + /* 4090 */ 0x0645, 0x0645, + /* 4092 */ 0x0646, 0x062C, + /* 4094 */ 0x0646, 0x062D, + /* 4096 */ 0x0646, 0x062E, + /* 4098 */ 0x0646, 0x0645, + /* 4100 */ 0x0646, 0x0647, + /* 4102 */ 0x0647, 0x062C, + /* 4104 */ 0x0647, 0x0645, + /* 4106 */ 0x0647, 0x0670, + /* 4108 */ 0x064A, 0x062C, + /* 4110 */ 0x064A, 0x062D, + /* 4112 */ 0x064A, 0x062E, + /* 4114 */ 0x064A, 0x0645, + /* 4116 */ 0x064A, 0x0647, + /* 4118 */ 0x0626, 0x0645, + /* 4120 */ 0x0626, 0x0647, + /* 4122 */ 0x0628, 0x0645, + /* 4124 */ 0x0628, 0x0647, + /* 4126 */ 0x062A, 0x0645, + /* 4128 */ 0x062A, 0x0647, + /* 4130 */ 0x062B, 0x0645, + /* 4132 */ 0x062B, 0x0647, + /* 4134 */ 0x0633, 0x0645, + /* 4136 */ 0x0633, 0x0647, + /* 4138 */ 0x0634, 0x0645, + /* 4140 */ 0x0634, 0x0647, + /* 4142 */ 0x0643, 0x0644, + /* 4144 */ 0x0643, 0x0645, + /* 4146 */ 0x0644, 0x0645, + /* 4148 */ 0x0646, 0x0645, + /* 4150 */ 0x0646, 0x0647, + /* 4152 */ 0x064A, 0x0645, + /* 4154 */ 0x064A, 0x0647, + /* 4156 */ 0x0640, 0x064E, 0x0651, + /* 4159 */ 0x0640, 0x064F, 0x0651, + /* 4162 */ 0x0640, 0x0650, 0x0651, + /* 4165 */ 0x0637, 0x0649, + /* 4167 */ 0x0637, 0x064A, + /* 4169 */ 0x0639, 0x0649, + /* 4171 */ 0x0639, 0x064A, + /* 4173 */ 0x063A, 0x0649, + /* 4175 */ 0x063A, 0x064A, + /* 4177 */ 0x0633, 0x0649, + /* 4179 */ 0x0633, 0x064A, + /* 4181 */ 0x0634, 0x0649, + /* 4183 */ 0x0634, 0x064A, + /* 4185 */ 0x062D, 0x0649, + /* 4187 */ 0x062D, 0x064A, + /* 4189 */ 0x062C, 0x0649, + /* 4191 */ 0x062C, 0x064A, + /* 4193 */ 0x062E, 0x0649, + /* 4195 */ 0x062E, 0x064A, + /* 4197 */ 0x0635, 0x0649, + /* 4199 */ 0x0635, 0x064A, + /* 4201 */ 0x0636, 0x0649, + /* 4203 */ 0x0636, 0x064A, + /* 4205 */ 0x0634, 0x062C, + /* 4207 */ 0x0634, 0x062D, + /* 4209 */ 0x0634, 0x062E, + /* 4211 */ 0x0634, 0x0645, + /* 4213 */ 0x0634, 0x0631, + /* 4215 */ 0x0633, 0x0631, + /* 4217 */ 0x0635, 0x0631, + /* 4219 */ 0x0636, 0x0631, + /* 4221 */ 0x0637, 0x0649, + /* 4223 */ 0x0637, 0x064A, + /* 4225 */ 0x0639, 0x0649, + /* 4227 */ 0x0639, 0x064A, + /* 4229 */ 0x063A, 0x0649, + /* 4231 */ 0x063A, 0x064A, + /* 4233 */ 0x0633, 0x0649, + /* 4235 */ 0x0633, 0x064A, + /* 4237 */ 0x0634, 0x0649, + /* 4239 */ 0x0634, 0x064A, + /* 4241 */ 0x062D, 0x0649, + /* 4243 */ 0x062D, 0x064A, + /* 4245 */ 0x062C, 0x0649, + /* 4247 */ 0x062C, 0x064A, + /* 4249 */ 0x062E, 0x0649, + /* 4251 */ 0x062E, 0x064A, + /* 4253 */ 0x0635, 0x0649, + /* 4255 */ 0x0635, 0x064A, + /* 4257 */ 0x0636, 0x0649, + /* 4259 */ 0x0636, 0x064A, + /* 4261 */ 0x0634, 0x062C, + /* 4263 */ 0x0634, 0x062D, + /* 4265 */ 0x0634, 0x062E, + /* 4267 */ 0x0634, 0x0645, + /* 4269 */ 0x0634, 0x0631, + /* 4271 */ 0x0633, 0x0631, + /* 4273 */ 0x0635, 0x0631, + /* 4275 */ 0x0636, 0x0631, + /* 4277 */ 0x0634, 0x062C, + /* 4279 */ 0x0634, 0x062D, + /* 4281 */ 0x0634, 0x062E, + /* 4283 */ 0x0634, 0x0645, + /* 4285 */ 0x0633, 0x0647, + /* 4287 */ 0x0634, 0x0647, + /* 4289 */ 0x0637, 0x0645, + /* 4291 */ 0x0633, 0x062C, + /* 4293 */ 0x0633, 0x062D, + /* 4295 */ 0x0633, 0x062E, + /* 4297 */ 0x0634, 0x062C, + /* 4299 */ 0x0634, 0x062D, + /* 4301 */ 0x0634, 0x062E, + /* 4303 */ 0x0637, 0x0645, + /* 4305 */ 0x0638, 0x0645, + /* 4307 */ 0x0627, 0x064B, + /* 4309 */ 0x0627, 0x064B, + /* 4311 */ 0x062A, 0x062C, 0x0645, + /* 4314 */ 0x062A, 0x062D, 0x062C, + /* 4317 */ 0x062A, 0x062D, 0x062C, + /* 4320 */ 0x062A, 0x062D, 0x0645, + /* 4323 */ 0x062A, 0x062E, 0x0645, + /* 4326 */ 0x062A, 0x0645, 0x062C, + /* 4329 */ 0x062A, 0x0645, 0x062D, + /* 4332 */ 0x062A, 0x0645, 0x062E, + /* 4335 */ 0x062C, 0x0645, 0x062D, + /* 4338 */ 0x062C, 0x0645, 0x062D, + /* 4341 */ 0x062D, 0x0645, 0x064A, + /* 4344 */ 0x062D, 0x0645, 0x0649, + /* 4347 */ 0x0633, 0x062D, 0x062C, + /* 4350 */ 0x0633, 0x062C, 0x062D, + /* 4353 */ 0x0633, 0x062C, 0x0649, + /* 4356 */ 0x0633, 0x0645, 0x062D, + /* 4359 */ 0x0633, 0x0645, 0x062D, + /* 4362 */ 0x0633, 0x0645, 0x062C, + /* 4365 */ 0x0633, 0x0645, 0x0645, + /* 4368 */ 0x0633, 0x0645, 0x0645, + /* 4371 */ 0x0635, 0x062D, 0x062D, + /* 4374 */ 0x0635, 0x062D, 0x062D, + /* 4377 */ 0x0635, 0x0645, 0x0645, + /* 4380 */ 0x0634, 0x062D, 0x0645, + /* 4383 */ 0x0634, 0x062D, 0x0645, + /* 4386 */ 0x0634, 0x062C, 0x064A, + /* 4389 */ 0x0634, 0x0645, 0x062E, + /* 4392 */ 0x0634, 0x0645, 0x062E, + /* 4395 */ 0x0634, 0x0645, 0x0645, + /* 4398 */ 0x0634, 0x0645, 0x0645, + /* 4401 */ 0x0636, 0x062D, 0x0649, + /* 4404 */ 0x0636, 0x062E, 0x0645, + /* 4407 */ 0x0636, 0x062E, 0x0645, + /* 4410 */ 0x0637, 0x0645, 0x062D, + /* 4413 */ 0x0637, 0x0645, 0x062D, + /* 4416 */ 0x0637, 0x0645, 0x0645, + /* 4419 */ 0x0637, 0x0645, 0x064A, + /* 4422 */ 0x0639, 0x062C, 0x0645, + /* 4425 */ 0x0639, 0x0645, 0x0645, + /* 4428 */ 0x0639, 0x0645, 0x0645, + /* 4431 */ 0x0639, 0x0645, 0x0649, + /* 4434 */ 0x063A, 0x0645, 0x0645, + /* 4437 */ 0x063A, 0x0645, 0x064A, + /* 4440 */ 0x063A, 0x0645, 0x0649, + /* 4443 */ 0x0641, 0x062E, 0x0645, + /* 4446 */ 0x0641, 0x062E, 0x0645, + /* 4449 */ 0x0642, 0x0645, 0x062D, + /* 4452 */ 0x0642, 0x0645, 0x0645, + /* 4455 */ 0x0644, 0x062D, 0x0645, + /* 4458 */ 0x0644, 0x062D, 0x064A, + /* 4461 */ 0x0644, 0x062D, 0x0649, + /* 4464 */ 0x0644, 0x062C, 0x062C, + /* 4467 */ 0x0644, 0x062C, 0x062C, + /* 4470 */ 0x0644, 0x062E, 0x0645, + /* 4473 */ 0x0644, 0x062E, 0x0645, + /* 4476 */ 0x0644, 0x0645, 0x062D, + /* 4479 */ 0x0644, 0x0645, 0x062D, + /* 4482 */ 0x0645, 0x062D, 0x062C, + /* 4485 */ 0x0645, 0x062D, 0x0645, + /* 4488 */ 0x0645, 0x062D, 0x064A, + /* 4491 */ 0x0645, 0x062C, 0x062D, + /* 4494 */ 0x0645, 0x062C, 0x0645, + /* 4497 */ 0x0645, 0x062E, 0x062C, + /* 4500 */ 0x0645, 0x062E, 0x0645, + /* 4503 */ 0x0645, 0x062C, 0x062E, + /* 4506 */ 0x0647, 0x0645, 0x062C, + /* 4509 */ 0x0647, 0x0645, 0x0645, + /* 4512 */ 0x0646, 0x062D, 0x0645, + /* 4515 */ 0x0646, 0x062D, 0x0649, + /* 4518 */ 0x0646, 0x062C, 0x0645, + /* 4521 */ 0x0646, 0x062C, 0x0645, + /* 4524 */ 0x0646, 0x062C, 0x0649, + /* 4527 */ 0x0646, 0x0645, 0x064A, + /* 4530 */ 0x0646, 0x0645, 0x0649, + /* 4533 */ 0x064A, 0x0645, 0x0645, + /* 4536 */ 0x064A, 0x0645, 0x0645, + /* 4539 */ 0x0628, 0x062E, 0x064A, + /* 4542 */ 0x062A, 0x062C, 0x064A, + /* 4545 */ 0x062A, 0x062C, 0x0649, + /* 4548 */ 0x062A, 0x062E, 0x064A, + /* 4551 */ 0x062A, 0x062E, 0x0649, + /* 4554 */ 0x062A, 0x0645, 0x064A, + /* 4557 */ 0x062A, 0x0645, 0x0649, + /* 4560 */ 0x062C, 0x0645, 0x064A, + /* 4563 */ 0x062C, 0x062D, 0x0649, + /* 4566 */ 0x062C, 0x0645, 0x0649, + /* 4569 */ 0x0633, 0x062E, 0x0649, + /* 4572 */ 0x0635, 0x062D, 0x064A, + /* 4575 */ 0x0634, 0x062D, 0x064A, + /* 4578 */ 0x0636, 0x062D, 0x064A, + /* 4581 */ 0x0644, 0x062C, 0x064A, + /* 4584 */ 0x0644, 0x0645, 0x064A, + /* 4587 */ 0x064A, 0x062D, 0x064A, + /* 4590 */ 0x064A, 0x062C, 0x064A, + /* 4593 */ 0x064A, 0x0645, 0x064A, + /* 4596 */ 0x0645, 0x0645, 0x064A, + /* 4599 */ 0x0642, 0x0645, 0x064A, + /* 4602 */ 0x0646, 0x062D, 0x064A, + /* 4605 */ 0x0642, 0x0645, 0x062D, + /* 4608 */ 0x0644, 0x062D, 0x0645, + /* 4611 */ 0x0639, 0x0645, 0x064A, + /* 4614 */ 0x0643, 0x0645, 0x064A, + /* 4617 */ 0x0646, 0x062C, 0x062D, + /* 4620 */ 0x0645, 0x062E, 0x064A, + /* 4623 */ 0x0644, 0x062C, 0x0645, + /* 4626 */ 0x0643, 0x0645, 0x0645, + /* 4629 */ 0x0644, 0x062C, 0x0645, + /* 4632 */ 0x0646, 0x062C, 0x062D, + /* 4635 */ 0x062C, 0x062D, 0x064A, + /* 4638 */ 0x062D, 0x062C, 0x064A, + /* 4641 */ 0x0645, 0x062C, 0x064A, + /* 4644 */ 0x0641, 0x0645, 0x064A, + /* 4647 */ 0x0628, 0x062D, 0x064A, + /* 4650 */ 0x0643, 0x0645, 0x0645, + /* 4653 */ 0x0639, 0x062C, 0x0645, + /* 4656 */ 0x0635, 0x0645, 0x0645, + /* 4659 */ 0x0633, 0x062E, 0x064A, + /* 4662 */ 0x0646, 0x062C, 0x064A, + /* 4665 */ 0x0635, 0x0644, 0x06D2, + /* 4668 */ 0x0642, 0x0644, 0x06D2, + /* 4671 */ 0x0627, 0x0644, 0x0644, 0x0647, + /* 4675 */ 0x0627, 0x0643, 0x0628, 0x0631, + /* 4679 */ 0x0645, 0x062D, 0x0645, 0x062F, + /* 4683 */ 0x0635, 0x0644, 0x0639, 0x0645, + /* 4687 */ 0x0631, 0x0633, 0x0648, 0x0644, + /* 4691 */ 0x0639, 0x0644, 0x064A, 0x0647, + /* 4695 */ 0x0648, 0x0633, 0x0644, 0x0645, + /* 4699 */ 0x0635, 0x0644, 0x0649, + /* 4702 */ 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, + /* 4720 */ 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, + /* 4728 */ 0x0631, 0x06CC, 0x0627, 0x0644, + /* 4732 */ 0x0020, 0x064B, + /* 4734 */ 0x0640, 0x064B, + /* 4736 */ 0x0020, 0x064C, + /* 4738 */ 0x0020, 0x064D, + /* 4740 */ 0x0020, 0x064E, + /* 4742 */ 0x0640, 0x064E, + /* 4744 */ 0x0020, 0x064F, + /* 4746 */ 0x0640, 0x064F, + /* 4748 */ 0x0020, 0x0650, + /* 4750 */ 0x0640, 0x0650, + /* 4752 */ 0x0020, 0x0651, + /* 4754 */ 0x0640, 0x0651, + /* 4756 */ 0x0020, 0x0652, + /* 4758 */ 0x0640, 0x0652, + /* 4760 */ 0x0644, 0x0622, + /* 4762 */ 0x0644, 0x0622, + /* 4764 */ 0x0644, 0x0623, + /* 4766 */ 0x0644, 0x0623, + /* 4768 */ 0x0644, 0x0625, + /* 4770 */ 0x0644, 0x0625, + /* 4772 */ 0x0644, 0x0627, + /* 4774 */ 0x0644, 0x0627, + /* 4776 */ 0x1DF04, + /* 4777 */ 0x1DF05, + /* 4778 */ 0x1DF06, + /* 4779 */ 0x1DF08, + /* 4780 */ 0x1DF0A, + /* 4781 */ 0x1DF1E, + /* 4782 */ 0x11099, 0x110BA, + /* 4784 */ 0x1109B, 0x110BA, + /* 4786 */ 0x110A5, 0x110BA, + /* 4788 */ 0x11131, 0x11127, + /* 4790 */ 0x11132, 0x11127, + /* 4792 */ 0x11347, 0x1133E, + /* 4794 */ 0x11347, 0x11357, + /* 4796 */ 0x114B9, 0x114BA, + /* 4798 */ 0x114B9, 0x114B0, + /* 4800 */ 0x114B9, 0x114BD, + /* 4802 */ 0x115B8, 0x115AF, + /* 4804 */ 0x115B9, 0x115AF, + /* 4806 */ 0x11935, 0x11930, + /* 4808 */ 0x1D157, 0x1D165, + /* 4810 */ 0x1D158, 0x1D165, + /* 4812 */ 0x1D15F, 0x1D16E, + /* 4814 */ 0x1D15F, 0x1D16F, + /* 4816 */ 0x1D15F, 0x1D170, + /* 4818 */ 0x1D15F, 0x1D171, + /* 4820 */ 0x1D15F, 0x1D172, + /* 4822 */ 0x1D1B9, 0x1D165, + /* 4824 */ 0x1D1BA, 0x1D165, + /* 4826 */ 0x1D1BB, 0x1D16E, + /* 4828 */ 0x1D1BC, 0x1D16E, + /* 4830 */ 0x1D1BB, 0x1D16F, + /* 4832 */ 0x1D1BC, 0x1D16F, + /* 4834 */ 0x0030, 0x002E, + /* 4836 */ 0x0030, 0x002C, + /* 4838 */ 0x0031, 0x002C, + /* 4840 */ 0x0032, 0x002C, + /* 4842 */ 0x0033, 0x002C, + /* 4844 */ 0x0034, 0x002C, + /* 4846 */ 0x0035, 0x002C, + /* 4848 */ 0x0036, 0x002C, + /* 4850 */ 0x0037, 0x002C, + /* 4852 */ 0x0038, 0x002C, + /* 4854 */ 0x0039, 0x002C, + /* 4856 */ 0x0028, 0x0041, 0x0029, + /* 4859 */ 0x0028, 0x0042, 0x0029, + /* 4862 */ 0x0028, 0x0043, 0x0029, + /* 4865 */ 0x0028, 0x0044, 0x0029, + /* 4868 */ 0x0028, 0x0045, 0x0029, + /* 4871 */ 0x0028, 0x0046, 0x0029, + /* 4874 */ 0x0028, 0x0047, 0x0029, + /* 4877 */ 0x0028, 0x0048, 0x0029, + /* 4880 */ 0x0028, 0x0049, 0x0029, + /* 4883 */ 0x0028, 0x004A, 0x0029, + /* 4886 */ 0x0028, 0x004B, 0x0029, + /* 4889 */ 0x0028, 0x004C, 0x0029, + /* 4892 */ 0x0028, 0x004D, 0x0029, + /* 4895 */ 0x0028, 0x004E, 0x0029, + /* 4898 */ 0x0028, 0x004F, 0x0029, + /* 4901 */ 0x0028, 0x0050, 0x0029, + /* 4904 */ 0x0028, 0x0051, 0x0029, + /* 4907 */ 0x0028, 0x0052, 0x0029, + /* 4910 */ 0x0028, 0x0053, 0x0029, + /* 4913 */ 0x0028, 0x0054, 0x0029, + /* 4916 */ 0x0028, 0x0055, 0x0029, + /* 4919 */ 0x0028, 0x0056, 0x0029, + /* 4922 */ 0x0028, 0x0057, 0x0029, + /* 4925 */ 0x0028, 0x0058, 0x0029, + /* 4928 */ 0x0028, 0x0059, 0x0029, + /* 4931 */ 0x0028, 0x005A, 0x0029, + /* 4934 */ 0x3014, 0x0053, 0x3015, + /* 4937 */ 0x0043, 0x0044, + /* 4939 */ 0x0057, 0x005A, + /* 4941 */ 0x0048, 0x0056, + /* 4943 */ 0x004D, 0x0056, + /* 4945 */ 0x0053, 0x0044, + /* 4947 */ 0x0053, 0x0053, + /* 4949 */ 0x0050, 0x0050, 0x0056, + /* 4952 */ 0x0057, 0x0043, + /* 4954 */ 0x004D, 0x0043, + /* 4956 */ 0x004D, 0x0044, + /* 4958 */ 0x004D, 0x0052, + /* 4960 */ 0x0044, 0x004A, + /* 4962 */ 0x307B, 0x304B, + /* 4964 */ 0x30B3, 0x30B3, + /* 4966 */ 0x3014, 0x672C, 0x3015, + /* 4969 */ 0x3014, 0x4E09, 0x3015, + /* 4972 */ 0x3014, 0x4E8C, 0x3015, + /* 4975 */ 0x3014, 0x5B89, 0x3015, + /* 4978 */ 0x3014, 0x70B9, 0x3015, + /* 4981 */ 0x3014, 0x6253, 0x3015, + /* 4984 */ 0x3014, 0x76D7, 0x3015, + /* 4987 */ 0x3014, 0x52DD, 0x3015, + /* 4990 */ 0x3014, 0x6557, 0x3015, + /* 4993 */ 0x20122, + /* 4994 */ 0x2063A, + /* 4995 */ 0x2051C, + /* 4996 */ 0x2054B, + /* 4997 */ 0x291DF, + /* 4998 */ 0x20A2C, + /* 4999 */ 0x20B63, + /* 5000 */ 0x214E4, + /* 5001 */ 0x216A8, + /* 5002 */ 0x216EA, + /* 5003 */ 0x219C8, + /* 5004 */ 0x21B18, + /* 5005 */ 0x21DE4, + /* 5006 */ 0x21DE6, + /* 5007 */ 0x22183, + /* 5008 */ 0x2A392, + /* 5009 */ 0x22331, + /* 5010 */ 0x22331, + /* 5011 */ 0x232B8, + /* 5012 */ 0x261DA, + /* 5013 */ 0x226D4, + /* 5014 */ 0x22B0C, + /* 5015 */ 0x22BF1, + /* 5016 */ 0x2300A, + /* 5017 */ 0x233C3, + /* 5018 */ 0x2346D, + /* 5019 */ 0x236A3, + /* 5020 */ 0x238A7, + /* 5021 */ 0x23A8D, + /* 5022 */ 0x21D0B, + /* 5023 */ 0x23AFA, + /* 5024 */ 0x23CBC, + /* 5025 */ 0x23D1E, + /* 5026 */ 0x23ED1, + /* 5027 */ 0x23F5E, + /* 5028 */ 0x23F8E, + /* 5029 */ 0x20525, + /* 5030 */ 0x24263, + /* 5031 */ 0x243AB, + /* 5032 */ 0x24608, + /* 5033 */ 0x24735, + /* 5034 */ 0x24814, + /* 5035 */ 0x24C36, + /* 5036 */ 0x24C92, + /* 5037 */ 0x2219F, + /* 5038 */ 0x24FA1, + /* 5039 */ 0x24FB8, + /* 5040 */ 0x25044, + /* 5041 */ 0x250F3, + /* 5042 */ 0x250F2, + /* 5043 */ 0x25119, + /* 5044 */ 0x25133, + /* 5045 */ 0x2541D, + /* 5046 */ 0x25626, + /* 5047 */ 0x2569A, + /* 5048 */ 0x256C5, + /* 5049 */ 0x2597C, + /* 5050 */ 0x25AA7, + /* 5051 */ 0x25AA7, + /* 5052 */ 0x25BAB, + /* 5053 */ 0x25C80, + /* 5054 */ 0x25F86, + /* 5055 */ 0x26228, + /* 5056 */ 0x26247, + /* 5057 */ 0x262D9, + /* 5058 */ 0x2633E, + /* 5059 */ 0x264DA, + /* 5060 */ 0x26523, + /* 5061 */ 0x265A8, + /* 5062 */ 0x2335F, + /* 5063 */ 0x267A7, + /* 5064 */ 0x267B5, + /* 5065 */ 0x23393, + /* 5066 */ 0x2339C, + /* 5067 */ 0x26B3C, + /* 5068 */ 0x26C36, + /* 5069 */ 0x26D6B, + /* 5070 */ 0x26CD5, + /* 5071 */ 0x273CA, + /* 5072 */ 0x26F2C, + /* 5073 */ 0x26FB1, + /* 5074 */ 0x270D2, + /* 5075 */ 0x27667, + /* 5076 */ 0x278AE, + /* 5077 */ 0x27966, + /* 5078 */ 0x27CA8, + /* 5079 */ 0x27F2F, + /* 5080 */ 0x20804, + /* 5081 */ 0x208DE, + /* 5082 */ 0x285D2, + /* 5083 */ 0x285ED, + /* 5084 */ 0x2872E, + /* 5085 */ 0x28BFA, + /* 5086 */ 0x28D77, + /* 5087 */ 0x29145, + /* 5088 */ 0x2921A, + /* 5089 */ 0x2940A, + /* 5090 */ 0x29496, + /* 5091 */ 0x295B6, + /* 5092 */ 0x29B30, + /* 5093 */ 0x2A0CE, + /* 5094 */ 0x2A105, + /* 5095 */ 0x2A20E, + /* 5096 */ 0x2A291, + /* 5097 */ 0x2A600 +}; diff --git a/install/include/postgresql/server/common/unicode_normprops_table.h b/install/include/postgresql/server/common/unicode_normprops_table.h new file mode 100644 index 00000000000..7a134055252 --- /dev/null +++ b/install/include/postgresql/server/common/unicode_normprops_table.h @@ -0,0 +1,7926 @@ +/* generated by src/common/unicode/generate-unicode_normprops_table.pl, do not edit */ + +#include "common/unicode_norm.h" + +/* + * Normalization quick check entry for codepoint. We use a bit field + * here to save space. + */ +typedef struct +{ + unsigned int codepoint:21; + signed int quickcheck:4; /* really UnicodeNormalizationQC */ +} pg_unicode_normprops; + +/* Typedef for hash function on quick check table */ +typedef int (*qc_hash_func) (const void *key); + +/* Information for quick check lookup with perfect hash function */ +typedef struct +{ + const pg_unicode_normprops *normprops; + qc_hash_func hash; + int num_normprops; +} pg_unicode_norminfo; + +static const pg_unicode_normprops UnicodeNormProps_NFC_QC[] = { + {0x0300, UNICODE_NORM_QC_MAYBE}, + {0x0301, UNICODE_NORM_QC_MAYBE}, + {0x0302, UNICODE_NORM_QC_MAYBE}, + {0x0303, UNICODE_NORM_QC_MAYBE}, + {0x0304, UNICODE_NORM_QC_MAYBE}, + {0x0306, UNICODE_NORM_QC_MAYBE}, + {0x0307, UNICODE_NORM_QC_MAYBE}, + {0x0308, UNICODE_NORM_QC_MAYBE}, + {0x0309, UNICODE_NORM_QC_MAYBE}, + {0x030A, UNICODE_NORM_QC_MAYBE}, + {0x030B, UNICODE_NORM_QC_MAYBE}, + {0x030C, UNICODE_NORM_QC_MAYBE}, + {0x030F, UNICODE_NORM_QC_MAYBE}, + {0x0311, UNICODE_NORM_QC_MAYBE}, + {0x0313, UNICODE_NORM_QC_MAYBE}, + {0x0314, UNICODE_NORM_QC_MAYBE}, + {0x031B, UNICODE_NORM_QC_MAYBE}, + {0x0323, UNICODE_NORM_QC_MAYBE}, + {0x0324, UNICODE_NORM_QC_MAYBE}, + {0x0325, UNICODE_NORM_QC_MAYBE}, + {0x0326, UNICODE_NORM_QC_MAYBE}, + {0x0327, UNICODE_NORM_QC_MAYBE}, + {0x0328, UNICODE_NORM_QC_MAYBE}, + {0x032D, UNICODE_NORM_QC_MAYBE}, + {0x032E, UNICODE_NORM_QC_MAYBE}, + {0x0330, UNICODE_NORM_QC_MAYBE}, + {0x0331, UNICODE_NORM_QC_MAYBE}, + {0x0338, UNICODE_NORM_QC_MAYBE}, + {0x0340, UNICODE_NORM_QC_NO}, + {0x0341, UNICODE_NORM_QC_NO}, + {0x0342, UNICODE_NORM_QC_MAYBE}, + {0x0343, UNICODE_NORM_QC_NO}, + {0x0344, UNICODE_NORM_QC_NO}, + {0x0345, UNICODE_NORM_QC_MAYBE}, + {0x0374, UNICODE_NORM_QC_NO}, + {0x037E, UNICODE_NORM_QC_NO}, + {0x0387, UNICODE_NORM_QC_NO}, + {0x0653, UNICODE_NORM_QC_MAYBE}, + {0x0654, UNICODE_NORM_QC_MAYBE}, + {0x0655, UNICODE_NORM_QC_MAYBE}, + {0x093C, UNICODE_NORM_QC_MAYBE}, + {0x0958, UNICODE_NORM_QC_NO}, + {0x0959, UNICODE_NORM_QC_NO}, + {0x095A, UNICODE_NORM_QC_NO}, + {0x095B, UNICODE_NORM_QC_NO}, + {0x095C, UNICODE_NORM_QC_NO}, + {0x095D, UNICODE_NORM_QC_NO}, + {0x095E, UNICODE_NORM_QC_NO}, + {0x095F, UNICODE_NORM_QC_NO}, + {0x09BE, UNICODE_NORM_QC_MAYBE}, + {0x09D7, UNICODE_NORM_QC_MAYBE}, + {0x09DC, UNICODE_NORM_QC_NO}, + {0x09DD, UNICODE_NORM_QC_NO}, + {0x09DF, UNICODE_NORM_QC_NO}, + {0x0A33, UNICODE_NORM_QC_NO}, + {0x0A36, UNICODE_NORM_QC_NO}, + {0x0A59, UNICODE_NORM_QC_NO}, + {0x0A5A, UNICODE_NORM_QC_NO}, + {0x0A5B, UNICODE_NORM_QC_NO}, + {0x0A5E, UNICODE_NORM_QC_NO}, + {0x0B3E, UNICODE_NORM_QC_MAYBE}, + {0x0B56, UNICODE_NORM_QC_MAYBE}, + {0x0B57, UNICODE_NORM_QC_MAYBE}, + {0x0B5C, UNICODE_NORM_QC_NO}, + {0x0B5D, UNICODE_NORM_QC_NO}, + {0x0BBE, UNICODE_NORM_QC_MAYBE}, + {0x0BD7, UNICODE_NORM_QC_MAYBE}, + {0x0C56, UNICODE_NORM_QC_MAYBE}, + {0x0CC2, UNICODE_NORM_QC_MAYBE}, + {0x0CD5, UNICODE_NORM_QC_MAYBE}, + {0x0CD6, UNICODE_NORM_QC_MAYBE}, + {0x0D3E, UNICODE_NORM_QC_MAYBE}, + {0x0D57, UNICODE_NORM_QC_MAYBE}, + {0x0DCA, UNICODE_NORM_QC_MAYBE}, + {0x0DCF, UNICODE_NORM_QC_MAYBE}, + {0x0DDF, UNICODE_NORM_QC_MAYBE}, + {0x0F43, UNICODE_NORM_QC_NO}, + {0x0F4D, UNICODE_NORM_QC_NO}, + {0x0F52, UNICODE_NORM_QC_NO}, + {0x0F57, UNICODE_NORM_QC_NO}, + {0x0F5C, UNICODE_NORM_QC_NO}, + {0x0F69, UNICODE_NORM_QC_NO}, + {0x0F73, UNICODE_NORM_QC_NO}, + {0x0F75, UNICODE_NORM_QC_NO}, + {0x0F76, UNICODE_NORM_QC_NO}, + {0x0F78, UNICODE_NORM_QC_NO}, + {0x0F81, UNICODE_NORM_QC_NO}, + {0x0F93, UNICODE_NORM_QC_NO}, + {0x0F9D, UNICODE_NORM_QC_NO}, + {0x0FA2, UNICODE_NORM_QC_NO}, + {0x0FA7, UNICODE_NORM_QC_NO}, + {0x0FAC, UNICODE_NORM_QC_NO}, + {0x0FB9, UNICODE_NORM_QC_NO}, + {0x102E, UNICODE_NORM_QC_MAYBE}, + {0x1161, UNICODE_NORM_QC_MAYBE}, + {0x1162, UNICODE_NORM_QC_MAYBE}, + {0x1163, UNICODE_NORM_QC_MAYBE}, + {0x1164, UNICODE_NORM_QC_MAYBE}, + {0x1165, UNICODE_NORM_QC_MAYBE}, + {0x1166, UNICODE_NORM_QC_MAYBE}, + {0x1167, UNICODE_NORM_QC_MAYBE}, + {0x1168, UNICODE_NORM_QC_MAYBE}, + {0x1169, UNICODE_NORM_QC_MAYBE}, + {0x116A, UNICODE_NORM_QC_MAYBE}, + {0x116B, UNICODE_NORM_QC_MAYBE}, + {0x116C, UNICODE_NORM_QC_MAYBE}, + {0x116D, UNICODE_NORM_QC_MAYBE}, + {0x116E, UNICODE_NORM_QC_MAYBE}, + {0x116F, UNICODE_NORM_QC_MAYBE}, + {0x1170, UNICODE_NORM_QC_MAYBE}, + {0x1171, UNICODE_NORM_QC_MAYBE}, + {0x1172, UNICODE_NORM_QC_MAYBE}, + {0x1173, UNICODE_NORM_QC_MAYBE}, + {0x1174, UNICODE_NORM_QC_MAYBE}, + {0x1175, UNICODE_NORM_QC_MAYBE}, + {0x11A8, UNICODE_NORM_QC_MAYBE}, + {0x11A9, UNICODE_NORM_QC_MAYBE}, + {0x11AA, UNICODE_NORM_QC_MAYBE}, + {0x11AB, UNICODE_NORM_QC_MAYBE}, + {0x11AC, UNICODE_NORM_QC_MAYBE}, + {0x11AD, UNICODE_NORM_QC_MAYBE}, + {0x11AE, UNICODE_NORM_QC_MAYBE}, + {0x11AF, UNICODE_NORM_QC_MAYBE}, + {0x11B0, UNICODE_NORM_QC_MAYBE}, + {0x11B1, UNICODE_NORM_QC_MAYBE}, + {0x11B2, UNICODE_NORM_QC_MAYBE}, + {0x11B3, UNICODE_NORM_QC_MAYBE}, + {0x11B4, UNICODE_NORM_QC_MAYBE}, + {0x11B5, UNICODE_NORM_QC_MAYBE}, + {0x11B6, UNICODE_NORM_QC_MAYBE}, + {0x11B7, UNICODE_NORM_QC_MAYBE}, + {0x11B8, UNICODE_NORM_QC_MAYBE}, + {0x11B9, UNICODE_NORM_QC_MAYBE}, + {0x11BA, UNICODE_NORM_QC_MAYBE}, + {0x11BB, UNICODE_NORM_QC_MAYBE}, + {0x11BC, UNICODE_NORM_QC_MAYBE}, + {0x11BD, UNICODE_NORM_QC_MAYBE}, + {0x11BE, UNICODE_NORM_QC_MAYBE}, + {0x11BF, UNICODE_NORM_QC_MAYBE}, + {0x11C0, UNICODE_NORM_QC_MAYBE}, + {0x11C1, UNICODE_NORM_QC_MAYBE}, + {0x11C2, UNICODE_NORM_QC_MAYBE}, + {0x1B35, UNICODE_NORM_QC_MAYBE}, + {0x1F71, UNICODE_NORM_QC_NO}, + {0x1F73, UNICODE_NORM_QC_NO}, + {0x1F75, UNICODE_NORM_QC_NO}, + {0x1F77, UNICODE_NORM_QC_NO}, + {0x1F79, UNICODE_NORM_QC_NO}, + {0x1F7B, UNICODE_NORM_QC_NO}, + {0x1F7D, UNICODE_NORM_QC_NO}, + {0x1FBB, UNICODE_NORM_QC_NO}, + {0x1FBE, UNICODE_NORM_QC_NO}, + {0x1FC9, UNICODE_NORM_QC_NO}, + {0x1FCB, UNICODE_NORM_QC_NO}, + {0x1FD3, UNICODE_NORM_QC_NO}, + {0x1FDB, UNICODE_NORM_QC_NO}, + {0x1FE3, UNICODE_NORM_QC_NO}, + {0x1FEB, UNICODE_NORM_QC_NO}, + {0x1FEE, UNICODE_NORM_QC_NO}, + {0x1FEF, UNICODE_NORM_QC_NO}, + {0x1FF9, UNICODE_NORM_QC_NO}, + {0x1FFB, UNICODE_NORM_QC_NO}, + {0x1FFD, UNICODE_NORM_QC_NO}, + {0x2000, UNICODE_NORM_QC_NO}, + {0x2001, UNICODE_NORM_QC_NO}, + {0x2126, UNICODE_NORM_QC_NO}, + {0x212A, UNICODE_NORM_QC_NO}, + {0x212B, UNICODE_NORM_QC_NO}, + {0x2329, UNICODE_NORM_QC_NO}, + {0x232A, UNICODE_NORM_QC_NO}, + {0x2ADC, UNICODE_NORM_QC_NO}, + {0x3099, UNICODE_NORM_QC_MAYBE}, + {0x309A, UNICODE_NORM_QC_MAYBE}, + {0xF900, UNICODE_NORM_QC_NO}, + {0xF901, UNICODE_NORM_QC_NO}, + {0xF902, UNICODE_NORM_QC_NO}, + {0xF903, UNICODE_NORM_QC_NO}, + {0xF904, UNICODE_NORM_QC_NO}, + {0xF905, UNICODE_NORM_QC_NO}, + {0xF906, UNICODE_NORM_QC_NO}, + {0xF907, UNICODE_NORM_QC_NO}, + {0xF908, UNICODE_NORM_QC_NO}, + {0xF909, UNICODE_NORM_QC_NO}, + {0xF90A, UNICODE_NORM_QC_NO}, + {0xF90B, UNICODE_NORM_QC_NO}, + {0xF90C, UNICODE_NORM_QC_NO}, + {0xF90D, UNICODE_NORM_QC_NO}, + {0xF90E, UNICODE_NORM_QC_NO}, + {0xF90F, UNICODE_NORM_QC_NO}, + {0xF910, UNICODE_NORM_QC_NO}, + {0xF911, UNICODE_NORM_QC_NO}, + {0xF912, UNICODE_NORM_QC_NO}, + {0xF913, UNICODE_NORM_QC_NO}, + {0xF914, UNICODE_NORM_QC_NO}, + {0xF915, UNICODE_NORM_QC_NO}, + {0xF916, UNICODE_NORM_QC_NO}, + {0xF917, UNICODE_NORM_QC_NO}, + {0xF918, UNICODE_NORM_QC_NO}, + {0xF919, UNICODE_NORM_QC_NO}, + {0xF91A, UNICODE_NORM_QC_NO}, + {0xF91B, UNICODE_NORM_QC_NO}, + {0xF91C, UNICODE_NORM_QC_NO}, + {0xF91D, UNICODE_NORM_QC_NO}, + {0xF91E, UNICODE_NORM_QC_NO}, + {0xF91F, UNICODE_NORM_QC_NO}, + {0xF920, UNICODE_NORM_QC_NO}, + {0xF921, UNICODE_NORM_QC_NO}, + {0xF922, UNICODE_NORM_QC_NO}, + {0xF923, UNICODE_NORM_QC_NO}, + {0xF924, UNICODE_NORM_QC_NO}, + {0xF925, UNICODE_NORM_QC_NO}, + {0xF926, UNICODE_NORM_QC_NO}, + {0xF927, UNICODE_NORM_QC_NO}, + {0xF928, UNICODE_NORM_QC_NO}, + {0xF929, UNICODE_NORM_QC_NO}, + {0xF92A, UNICODE_NORM_QC_NO}, + {0xF92B, UNICODE_NORM_QC_NO}, + {0xF92C, UNICODE_NORM_QC_NO}, + {0xF92D, UNICODE_NORM_QC_NO}, + {0xF92E, UNICODE_NORM_QC_NO}, + {0xF92F, UNICODE_NORM_QC_NO}, + {0xF930, UNICODE_NORM_QC_NO}, + {0xF931, UNICODE_NORM_QC_NO}, + {0xF932, UNICODE_NORM_QC_NO}, + {0xF933, UNICODE_NORM_QC_NO}, + {0xF934, UNICODE_NORM_QC_NO}, + {0xF935, UNICODE_NORM_QC_NO}, + {0xF936, UNICODE_NORM_QC_NO}, + {0xF937, UNICODE_NORM_QC_NO}, + {0xF938, UNICODE_NORM_QC_NO}, + {0xF939, UNICODE_NORM_QC_NO}, + {0xF93A, UNICODE_NORM_QC_NO}, + {0xF93B, UNICODE_NORM_QC_NO}, + {0xF93C, UNICODE_NORM_QC_NO}, + {0xF93D, UNICODE_NORM_QC_NO}, + {0xF93E, UNICODE_NORM_QC_NO}, + {0xF93F, UNICODE_NORM_QC_NO}, + {0xF940, UNICODE_NORM_QC_NO}, + {0xF941, UNICODE_NORM_QC_NO}, + {0xF942, UNICODE_NORM_QC_NO}, + {0xF943, UNICODE_NORM_QC_NO}, + {0xF944, UNICODE_NORM_QC_NO}, + {0xF945, UNICODE_NORM_QC_NO}, + {0xF946, UNICODE_NORM_QC_NO}, + {0xF947, UNICODE_NORM_QC_NO}, + {0xF948, UNICODE_NORM_QC_NO}, + {0xF949, UNICODE_NORM_QC_NO}, + {0xF94A, UNICODE_NORM_QC_NO}, + {0xF94B, UNICODE_NORM_QC_NO}, + {0xF94C, UNICODE_NORM_QC_NO}, + {0xF94D, UNICODE_NORM_QC_NO}, + {0xF94E, UNICODE_NORM_QC_NO}, + {0xF94F, UNICODE_NORM_QC_NO}, + {0xF950, UNICODE_NORM_QC_NO}, + {0xF951, UNICODE_NORM_QC_NO}, + {0xF952, UNICODE_NORM_QC_NO}, + {0xF953, UNICODE_NORM_QC_NO}, + {0xF954, UNICODE_NORM_QC_NO}, + {0xF955, UNICODE_NORM_QC_NO}, + {0xF956, UNICODE_NORM_QC_NO}, + {0xF957, UNICODE_NORM_QC_NO}, + {0xF958, UNICODE_NORM_QC_NO}, + {0xF959, UNICODE_NORM_QC_NO}, + {0xF95A, UNICODE_NORM_QC_NO}, + {0xF95B, UNICODE_NORM_QC_NO}, + {0xF95C, UNICODE_NORM_QC_NO}, + {0xF95D, UNICODE_NORM_QC_NO}, + {0xF95E, UNICODE_NORM_QC_NO}, + {0xF95F, UNICODE_NORM_QC_NO}, + {0xF960, UNICODE_NORM_QC_NO}, + {0xF961, UNICODE_NORM_QC_NO}, + {0xF962, UNICODE_NORM_QC_NO}, + {0xF963, UNICODE_NORM_QC_NO}, + {0xF964, UNICODE_NORM_QC_NO}, + {0xF965, UNICODE_NORM_QC_NO}, + {0xF966, UNICODE_NORM_QC_NO}, + {0xF967, UNICODE_NORM_QC_NO}, + {0xF968, UNICODE_NORM_QC_NO}, + {0xF969, UNICODE_NORM_QC_NO}, + {0xF96A, UNICODE_NORM_QC_NO}, + {0xF96B, UNICODE_NORM_QC_NO}, + {0xF96C, UNICODE_NORM_QC_NO}, + {0xF96D, UNICODE_NORM_QC_NO}, + {0xF96E, UNICODE_NORM_QC_NO}, + {0xF96F, UNICODE_NORM_QC_NO}, + {0xF970, UNICODE_NORM_QC_NO}, + {0xF971, UNICODE_NORM_QC_NO}, + {0xF972, UNICODE_NORM_QC_NO}, + {0xF973, UNICODE_NORM_QC_NO}, + {0xF974, UNICODE_NORM_QC_NO}, + {0xF975, UNICODE_NORM_QC_NO}, + {0xF976, UNICODE_NORM_QC_NO}, + {0xF977, UNICODE_NORM_QC_NO}, + {0xF978, UNICODE_NORM_QC_NO}, + {0xF979, UNICODE_NORM_QC_NO}, + {0xF97A, UNICODE_NORM_QC_NO}, + {0xF97B, UNICODE_NORM_QC_NO}, + {0xF97C, UNICODE_NORM_QC_NO}, + {0xF97D, UNICODE_NORM_QC_NO}, + {0xF97E, UNICODE_NORM_QC_NO}, + {0xF97F, UNICODE_NORM_QC_NO}, + {0xF980, UNICODE_NORM_QC_NO}, + {0xF981, UNICODE_NORM_QC_NO}, + {0xF982, UNICODE_NORM_QC_NO}, + {0xF983, UNICODE_NORM_QC_NO}, + {0xF984, UNICODE_NORM_QC_NO}, + {0xF985, UNICODE_NORM_QC_NO}, + {0xF986, UNICODE_NORM_QC_NO}, + {0xF987, UNICODE_NORM_QC_NO}, + {0xF988, UNICODE_NORM_QC_NO}, + {0xF989, UNICODE_NORM_QC_NO}, + {0xF98A, UNICODE_NORM_QC_NO}, + {0xF98B, UNICODE_NORM_QC_NO}, + {0xF98C, UNICODE_NORM_QC_NO}, + {0xF98D, UNICODE_NORM_QC_NO}, + {0xF98E, UNICODE_NORM_QC_NO}, + {0xF98F, UNICODE_NORM_QC_NO}, + {0xF990, UNICODE_NORM_QC_NO}, + {0xF991, UNICODE_NORM_QC_NO}, + {0xF992, UNICODE_NORM_QC_NO}, + {0xF993, UNICODE_NORM_QC_NO}, + {0xF994, UNICODE_NORM_QC_NO}, + {0xF995, UNICODE_NORM_QC_NO}, + {0xF996, UNICODE_NORM_QC_NO}, + {0xF997, UNICODE_NORM_QC_NO}, + {0xF998, UNICODE_NORM_QC_NO}, + {0xF999, UNICODE_NORM_QC_NO}, + {0xF99A, UNICODE_NORM_QC_NO}, + {0xF99B, UNICODE_NORM_QC_NO}, + {0xF99C, UNICODE_NORM_QC_NO}, + {0xF99D, UNICODE_NORM_QC_NO}, + {0xF99E, UNICODE_NORM_QC_NO}, + {0xF99F, UNICODE_NORM_QC_NO}, + {0xF9A0, UNICODE_NORM_QC_NO}, + {0xF9A1, UNICODE_NORM_QC_NO}, + {0xF9A2, UNICODE_NORM_QC_NO}, + {0xF9A3, UNICODE_NORM_QC_NO}, + {0xF9A4, UNICODE_NORM_QC_NO}, + {0xF9A5, UNICODE_NORM_QC_NO}, + {0xF9A6, UNICODE_NORM_QC_NO}, + {0xF9A7, UNICODE_NORM_QC_NO}, + {0xF9A8, UNICODE_NORM_QC_NO}, + {0xF9A9, UNICODE_NORM_QC_NO}, + {0xF9AA, UNICODE_NORM_QC_NO}, + {0xF9AB, UNICODE_NORM_QC_NO}, + {0xF9AC, UNICODE_NORM_QC_NO}, + {0xF9AD, UNICODE_NORM_QC_NO}, + {0xF9AE, UNICODE_NORM_QC_NO}, + {0xF9AF, UNICODE_NORM_QC_NO}, + {0xF9B0, UNICODE_NORM_QC_NO}, + {0xF9B1, UNICODE_NORM_QC_NO}, + {0xF9B2, UNICODE_NORM_QC_NO}, + {0xF9B3, UNICODE_NORM_QC_NO}, + {0xF9B4, UNICODE_NORM_QC_NO}, + {0xF9B5, UNICODE_NORM_QC_NO}, + {0xF9B6, UNICODE_NORM_QC_NO}, + {0xF9B7, UNICODE_NORM_QC_NO}, + {0xF9B8, UNICODE_NORM_QC_NO}, + {0xF9B9, UNICODE_NORM_QC_NO}, + {0xF9BA, UNICODE_NORM_QC_NO}, + {0xF9BB, UNICODE_NORM_QC_NO}, + {0xF9BC, UNICODE_NORM_QC_NO}, + {0xF9BD, UNICODE_NORM_QC_NO}, + {0xF9BE, UNICODE_NORM_QC_NO}, + {0xF9BF, UNICODE_NORM_QC_NO}, + {0xF9C0, UNICODE_NORM_QC_NO}, + {0xF9C1, UNICODE_NORM_QC_NO}, + {0xF9C2, UNICODE_NORM_QC_NO}, + {0xF9C3, UNICODE_NORM_QC_NO}, + {0xF9C4, UNICODE_NORM_QC_NO}, + {0xF9C5, UNICODE_NORM_QC_NO}, + {0xF9C6, UNICODE_NORM_QC_NO}, + {0xF9C7, UNICODE_NORM_QC_NO}, + {0xF9C8, UNICODE_NORM_QC_NO}, + {0xF9C9, UNICODE_NORM_QC_NO}, + {0xF9CA, UNICODE_NORM_QC_NO}, + {0xF9CB, UNICODE_NORM_QC_NO}, + {0xF9CC, UNICODE_NORM_QC_NO}, + {0xF9CD, UNICODE_NORM_QC_NO}, + {0xF9CE, UNICODE_NORM_QC_NO}, + {0xF9CF, UNICODE_NORM_QC_NO}, + {0xF9D0, UNICODE_NORM_QC_NO}, + {0xF9D1, UNICODE_NORM_QC_NO}, + {0xF9D2, UNICODE_NORM_QC_NO}, + {0xF9D3, UNICODE_NORM_QC_NO}, + {0xF9D4, UNICODE_NORM_QC_NO}, + {0xF9D5, UNICODE_NORM_QC_NO}, + {0xF9D6, UNICODE_NORM_QC_NO}, + {0xF9D7, UNICODE_NORM_QC_NO}, + {0xF9D8, UNICODE_NORM_QC_NO}, + {0xF9D9, UNICODE_NORM_QC_NO}, + {0xF9DA, UNICODE_NORM_QC_NO}, + {0xF9DB, UNICODE_NORM_QC_NO}, + {0xF9DC, UNICODE_NORM_QC_NO}, + {0xF9DD, UNICODE_NORM_QC_NO}, + {0xF9DE, UNICODE_NORM_QC_NO}, + {0xF9DF, UNICODE_NORM_QC_NO}, + {0xF9E0, UNICODE_NORM_QC_NO}, + {0xF9E1, UNICODE_NORM_QC_NO}, + {0xF9E2, UNICODE_NORM_QC_NO}, + {0xF9E3, UNICODE_NORM_QC_NO}, + {0xF9E4, UNICODE_NORM_QC_NO}, + {0xF9E5, UNICODE_NORM_QC_NO}, + {0xF9E6, UNICODE_NORM_QC_NO}, + {0xF9E7, UNICODE_NORM_QC_NO}, + {0xF9E8, UNICODE_NORM_QC_NO}, + {0xF9E9, UNICODE_NORM_QC_NO}, + {0xF9EA, UNICODE_NORM_QC_NO}, + {0xF9EB, UNICODE_NORM_QC_NO}, + {0xF9EC, UNICODE_NORM_QC_NO}, + {0xF9ED, UNICODE_NORM_QC_NO}, + {0xF9EE, UNICODE_NORM_QC_NO}, + {0xF9EF, UNICODE_NORM_QC_NO}, + {0xF9F0, UNICODE_NORM_QC_NO}, + {0xF9F1, UNICODE_NORM_QC_NO}, + {0xF9F2, UNICODE_NORM_QC_NO}, + {0xF9F3, UNICODE_NORM_QC_NO}, + {0xF9F4, UNICODE_NORM_QC_NO}, + {0xF9F5, UNICODE_NORM_QC_NO}, + {0xF9F6, UNICODE_NORM_QC_NO}, + {0xF9F7, UNICODE_NORM_QC_NO}, + {0xF9F8, UNICODE_NORM_QC_NO}, + {0xF9F9, UNICODE_NORM_QC_NO}, + {0xF9FA, UNICODE_NORM_QC_NO}, + {0xF9FB, UNICODE_NORM_QC_NO}, + {0xF9FC, UNICODE_NORM_QC_NO}, + {0xF9FD, UNICODE_NORM_QC_NO}, + {0xF9FE, UNICODE_NORM_QC_NO}, + {0xF9FF, UNICODE_NORM_QC_NO}, + {0xFA00, UNICODE_NORM_QC_NO}, + {0xFA01, UNICODE_NORM_QC_NO}, + {0xFA02, UNICODE_NORM_QC_NO}, + {0xFA03, UNICODE_NORM_QC_NO}, + {0xFA04, UNICODE_NORM_QC_NO}, + {0xFA05, UNICODE_NORM_QC_NO}, + {0xFA06, UNICODE_NORM_QC_NO}, + {0xFA07, UNICODE_NORM_QC_NO}, + {0xFA08, UNICODE_NORM_QC_NO}, + {0xFA09, UNICODE_NORM_QC_NO}, + {0xFA0A, UNICODE_NORM_QC_NO}, + {0xFA0B, UNICODE_NORM_QC_NO}, + {0xFA0C, UNICODE_NORM_QC_NO}, + {0xFA0D, UNICODE_NORM_QC_NO}, + {0xFA10, UNICODE_NORM_QC_NO}, + {0xFA12, UNICODE_NORM_QC_NO}, + {0xFA15, UNICODE_NORM_QC_NO}, + {0xFA16, UNICODE_NORM_QC_NO}, + {0xFA17, UNICODE_NORM_QC_NO}, + {0xFA18, UNICODE_NORM_QC_NO}, + {0xFA19, UNICODE_NORM_QC_NO}, + {0xFA1A, UNICODE_NORM_QC_NO}, + {0xFA1B, UNICODE_NORM_QC_NO}, + {0xFA1C, UNICODE_NORM_QC_NO}, + {0xFA1D, UNICODE_NORM_QC_NO}, + {0xFA1E, UNICODE_NORM_QC_NO}, + {0xFA20, UNICODE_NORM_QC_NO}, + {0xFA22, UNICODE_NORM_QC_NO}, + {0xFA25, UNICODE_NORM_QC_NO}, + {0xFA26, UNICODE_NORM_QC_NO}, + {0xFA2A, UNICODE_NORM_QC_NO}, + {0xFA2B, UNICODE_NORM_QC_NO}, + {0xFA2C, UNICODE_NORM_QC_NO}, + {0xFA2D, UNICODE_NORM_QC_NO}, + {0xFA2E, UNICODE_NORM_QC_NO}, + {0xFA2F, UNICODE_NORM_QC_NO}, + {0xFA30, UNICODE_NORM_QC_NO}, + {0xFA31, UNICODE_NORM_QC_NO}, + {0xFA32, UNICODE_NORM_QC_NO}, + {0xFA33, UNICODE_NORM_QC_NO}, + {0xFA34, UNICODE_NORM_QC_NO}, + {0xFA35, UNICODE_NORM_QC_NO}, + {0xFA36, UNICODE_NORM_QC_NO}, + {0xFA37, UNICODE_NORM_QC_NO}, + {0xFA38, UNICODE_NORM_QC_NO}, + {0xFA39, UNICODE_NORM_QC_NO}, + {0xFA3A, UNICODE_NORM_QC_NO}, + {0xFA3B, UNICODE_NORM_QC_NO}, + {0xFA3C, UNICODE_NORM_QC_NO}, + {0xFA3D, UNICODE_NORM_QC_NO}, + {0xFA3E, UNICODE_NORM_QC_NO}, + {0xFA3F, UNICODE_NORM_QC_NO}, + {0xFA40, UNICODE_NORM_QC_NO}, + {0xFA41, UNICODE_NORM_QC_NO}, + {0xFA42, UNICODE_NORM_QC_NO}, + {0xFA43, UNICODE_NORM_QC_NO}, + {0xFA44, UNICODE_NORM_QC_NO}, + {0xFA45, UNICODE_NORM_QC_NO}, + {0xFA46, UNICODE_NORM_QC_NO}, + {0xFA47, UNICODE_NORM_QC_NO}, + {0xFA48, UNICODE_NORM_QC_NO}, + {0xFA49, UNICODE_NORM_QC_NO}, + {0xFA4A, UNICODE_NORM_QC_NO}, + {0xFA4B, UNICODE_NORM_QC_NO}, + {0xFA4C, UNICODE_NORM_QC_NO}, + {0xFA4D, UNICODE_NORM_QC_NO}, + {0xFA4E, UNICODE_NORM_QC_NO}, + {0xFA4F, UNICODE_NORM_QC_NO}, + {0xFA50, UNICODE_NORM_QC_NO}, + {0xFA51, UNICODE_NORM_QC_NO}, + {0xFA52, UNICODE_NORM_QC_NO}, + {0xFA53, UNICODE_NORM_QC_NO}, + {0xFA54, UNICODE_NORM_QC_NO}, + {0xFA55, UNICODE_NORM_QC_NO}, + {0xFA56, UNICODE_NORM_QC_NO}, + {0xFA57, UNICODE_NORM_QC_NO}, + {0xFA58, UNICODE_NORM_QC_NO}, + {0xFA59, UNICODE_NORM_QC_NO}, + {0xFA5A, UNICODE_NORM_QC_NO}, + {0xFA5B, UNICODE_NORM_QC_NO}, + {0xFA5C, UNICODE_NORM_QC_NO}, + {0xFA5D, UNICODE_NORM_QC_NO}, + {0xFA5E, UNICODE_NORM_QC_NO}, + {0xFA5F, UNICODE_NORM_QC_NO}, + {0xFA60, UNICODE_NORM_QC_NO}, + {0xFA61, UNICODE_NORM_QC_NO}, + {0xFA62, UNICODE_NORM_QC_NO}, + {0xFA63, UNICODE_NORM_QC_NO}, + {0xFA64, UNICODE_NORM_QC_NO}, + {0xFA65, UNICODE_NORM_QC_NO}, + {0xFA66, UNICODE_NORM_QC_NO}, + {0xFA67, UNICODE_NORM_QC_NO}, + {0xFA68, UNICODE_NORM_QC_NO}, + {0xFA69, UNICODE_NORM_QC_NO}, + {0xFA6A, UNICODE_NORM_QC_NO}, + {0xFA6B, UNICODE_NORM_QC_NO}, + {0xFA6C, UNICODE_NORM_QC_NO}, + {0xFA6D, UNICODE_NORM_QC_NO}, + {0xFA70, UNICODE_NORM_QC_NO}, + {0xFA71, UNICODE_NORM_QC_NO}, + {0xFA72, UNICODE_NORM_QC_NO}, + {0xFA73, UNICODE_NORM_QC_NO}, + {0xFA74, UNICODE_NORM_QC_NO}, + {0xFA75, UNICODE_NORM_QC_NO}, + {0xFA76, UNICODE_NORM_QC_NO}, + {0xFA77, UNICODE_NORM_QC_NO}, + {0xFA78, UNICODE_NORM_QC_NO}, + {0xFA79, UNICODE_NORM_QC_NO}, + {0xFA7A, UNICODE_NORM_QC_NO}, + {0xFA7B, UNICODE_NORM_QC_NO}, + {0xFA7C, UNICODE_NORM_QC_NO}, + {0xFA7D, UNICODE_NORM_QC_NO}, + {0xFA7E, UNICODE_NORM_QC_NO}, + {0xFA7F, UNICODE_NORM_QC_NO}, + {0xFA80, UNICODE_NORM_QC_NO}, + {0xFA81, UNICODE_NORM_QC_NO}, + {0xFA82, UNICODE_NORM_QC_NO}, + {0xFA83, UNICODE_NORM_QC_NO}, + {0xFA84, UNICODE_NORM_QC_NO}, + {0xFA85, UNICODE_NORM_QC_NO}, + {0xFA86, UNICODE_NORM_QC_NO}, + {0xFA87, UNICODE_NORM_QC_NO}, + {0xFA88, UNICODE_NORM_QC_NO}, + {0xFA89, UNICODE_NORM_QC_NO}, + {0xFA8A, UNICODE_NORM_QC_NO}, + {0xFA8B, UNICODE_NORM_QC_NO}, + {0xFA8C, UNICODE_NORM_QC_NO}, + {0xFA8D, UNICODE_NORM_QC_NO}, + {0xFA8E, UNICODE_NORM_QC_NO}, + {0xFA8F, UNICODE_NORM_QC_NO}, + {0xFA90, UNICODE_NORM_QC_NO}, + {0xFA91, UNICODE_NORM_QC_NO}, + {0xFA92, UNICODE_NORM_QC_NO}, + {0xFA93, UNICODE_NORM_QC_NO}, + {0xFA94, UNICODE_NORM_QC_NO}, + {0xFA95, UNICODE_NORM_QC_NO}, + {0xFA96, UNICODE_NORM_QC_NO}, + {0xFA97, UNICODE_NORM_QC_NO}, + {0xFA98, UNICODE_NORM_QC_NO}, + {0xFA99, UNICODE_NORM_QC_NO}, + {0xFA9A, UNICODE_NORM_QC_NO}, + {0xFA9B, UNICODE_NORM_QC_NO}, + {0xFA9C, UNICODE_NORM_QC_NO}, + {0xFA9D, UNICODE_NORM_QC_NO}, + {0xFA9E, UNICODE_NORM_QC_NO}, + {0xFA9F, UNICODE_NORM_QC_NO}, + {0xFAA0, UNICODE_NORM_QC_NO}, + {0xFAA1, UNICODE_NORM_QC_NO}, + {0xFAA2, UNICODE_NORM_QC_NO}, + {0xFAA3, UNICODE_NORM_QC_NO}, + {0xFAA4, UNICODE_NORM_QC_NO}, + {0xFAA5, UNICODE_NORM_QC_NO}, + {0xFAA6, UNICODE_NORM_QC_NO}, + {0xFAA7, UNICODE_NORM_QC_NO}, + {0xFAA8, UNICODE_NORM_QC_NO}, + {0xFAA9, UNICODE_NORM_QC_NO}, + {0xFAAA, UNICODE_NORM_QC_NO}, + {0xFAAB, UNICODE_NORM_QC_NO}, + {0xFAAC, UNICODE_NORM_QC_NO}, + {0xFAAD, UNICODE_NORM_QC_NO}, + {0xFAAE, UNICODE_NORM_QC_NO}, + {0xFAAF, UNICODE_NORM_QC_NO}, + {0xFAB0, UNICODE_NORM_QC_NO}, + {0xFAB1, UNICODE_NORM_QC_NO}, + {0xFAB2, UNICODE_NORM_QC_NO}, + {0xFAB3, UNICODE_NORM_QC_NO}, + {0xFAB4, UNICODE_NORM_QC_NO}, + {0xFAB5, UNICODE_NORM_QC_NO}, + {0xFAB6, UNICODE_NORM_QC_NO}, + {0xFAB7, UNICODE_NORM_QC_NO}, + {0xFAB8, UNICODE_NORM_QC_NO}, + {0xFAB9, UNICODE_NORM_QC_NO}, + {0xFABA, UNICODE_NORM_QC_NO}, + {0xFABB, UNICODE_NORM_QC_NO}, + {0xFABC, UNICODE_NORM_QC_NO}, + {0xFABD, UNICODE_NORM_QC_NO}, + {0xFABE, UNICODE_NORM_QC_NO}, + {0xFABF, UNICODE_NORM_QC_NO}, + {0xFAC0, UNICODE_NORM_QC_NO}, + {0xFAC1, UNICODE_NORM_QC_NO}, + {0xFAC2, UNICODE_NORM_QC_NO}, + {0xFAC3, UNICODE_NORM_QC_NO}, + {0xFAC4, UNICODE_NORM_QC_NO}, + {0xFAC5, UNICODE_NORM_QC_NO}, + {0xFAC6, UNICODE_NORM_QC_NO}, + {0xFAC7, UNICODE_NORM_QC_NO}, + {0xFAC8, UNICODE_NORM_QC_NO}, + {0xFAC9, UNICODE_NORM_QC_NO}, + {0xFACA, UNICODE_NORM_QC_NO}, + {0xFACB, UNICODE_NORM_QC_NO}, + {0xFACC, UNICODE_NORM_QC_NO}, + {0xFACD, UNICODE_NORM_QC_NO}, + {0xFACE, UNICODE_NORM_QC_NO}, + {0xFACF, UNICODE_NORM_QC_NO}, + {0xFAD0, UNICODE_NORM_QC_NO}, + {0xFAD1, UNICODE_NORM_QC_NO}, + {0xFAD2, UNICODE_NORM_QC_NO}, + {0xFAD3, UNICODE_NORM_QC_NO}, + {0xFAD4, UNICODE_NORM_QC_NO}, + {0xFAD5, UNICODE_NORM_QC_NO}, + {0xFAD6, UNICODE_NORM_QC_NO}, + {0xFAD7, UNICODE_NORM_QC_NO}, + {0xFAD8, UNICODE_NORM_QC_NO}, + {0xFAD9, UNICODE_NORM_QC_NO}, + {0xFB1D, UNICODE_NORM_QC_NO}, + {0xFB1F, UNICODE_NORM_QC_NO}, + {0xFB2A, UNICODE_NORM_QC_NO}, + {0xFB2B, UNICODE_NORM_QC_NO}, + {0xFB2C, UNICODE_NORM_QC_NO}, + {0xFB2D, UNICODE_NORM_QC_NO}, + {0xFB2E, UNICODE_NORM_QC_NO}, + {0xFB2F, UNICODE_NORM_QC_NO}, + {0xFB30, UNICODE_NORM_QC_NO}, + {0xFB31, UNICODE_NORM_QC_NO}, + {0xFB32, UNICODE_NORM_QC_NO}, + {0xFB33, UNICODE_NORM_QC_NO}, + {0xFB34, UNICODE_NORM_QC_NO}, + {0xFB35, UNICODE_NORM_QC_NO}, + {0xFB36, UNICODE_NORM_QC_NO}, + {0xFB38, UNICODE_NORM_QC_NO}, + {0xFB39, UNICODE_NORM_QC_NO}, + {0xFB3A, UNICODE_NORM_QC_NO}, + {0xFB3B, UNICODE_NORM_QC_NO}, + {0xFB3C, UNICODE_NORM_QC_NO}, + {0xFB3E, UNICODE_NORM_QC_NO}, + {0xFB40, UNICODE_NORM_QC_NO}, + {0xFB41, UNICODE_NORM_QC_NO}, + {0xFB43, UNICODE_NORM_QC_NO}, + {0xFB44, UNICODE_NORM_QC_NO}, + {0xFB46, UNICODE_NORM_QC_NO}, + {0xFB47, UNICODE_NORM_QC_NO}, + {0xFB48, UNICODE_NORM_QC_NO}, + {0xFB49, UNICODE_NORM_QC_NO}, + {0xFB4A, UNICODE_NORM_QC_NO}, + {0xFB4B, UNICODE_NORM_QC_NO}, + {0xFB4C, UNICODE_NORM_QC_NO}, + {0xFB4D, UNICODE_NORM_QC_NO}, + {0xFB4E, UNICODE_NORM_QC_NO}, + {0x110BA, UNICODE_NORM_QC_MAYBE}, + {0x11127, UNICODE_NORM_QC_MAYBE}, + {0x1133E, UNICODE_NORM_QC_MAYBE}, + {0x11357, UNICODE_NORM_QC_MAYBE}, + {0x114B0, UNICODE_NORM_QC_MAYBE}, + {0x114BA, UNICODE_NORM_QC_MAYBE}, + {0x114BD, UNICODE_NORM_QC_MAYBE}, + {0x115AF, UNICODE_NORM_QC_MAYBE}, + {0x11930, UNICODE_NORM_QC_MAYBE}, + {0x1D15E, UNICODE_NORM_QC_NO}, + {0x1D15F, UNICODE_NORM_QC_NO}, + {0x1D160, UNICODE_NORM_QC_NO}, + {0x1D161, UNICODE_NORM_QC_NO}, + {0x1D162, UNICODE_NORM_QC_NO}, + {0x1D163, UNICODE_NORM_QC_NO}, + {0x1D164, UNICODE_NORM_QC_NO}, + {0x1D1BB, UNICODE_NORM_QC_NO}, + {0x1D1BC, UNICODE_NORM_QC_NO}, + {0x1D1BD, UNICODE_NORM_QC_NO}, + {0x1D1BE, UNICODE_NORM_QC_NO}, + {0x1D1BF, UNICODE_NORM_QC_NO}, + {0x1D1C0, UNICODE_NORM_QC_NO}, + {0x2F800, UNICODE_NORM_QC_NO}, + {0x2F801, UNICODE_NORM_QC_NO}, + {0x2F802, UNICODE_NORM_QC_NO}, + {0x2F803, UNICODE_NORM_QC_NO}, + {0x2F804, UNICODE_NORM_QC_NO}, + {0x2F805, UNICODE_NORM_QC_NO}, + {0x2F806, UNICODE_NORM_QC_NO}, + {0x2F807, UNICODE_NORM_QC_NO}, + {0x2F808, UNICODE_NORM_QC_NO}, + {0x2F809, UNICODE_NORM_QC_NO}, + {0x2F80A, UNICODE_NORM_QC_NO}, + {0x2F80B, UNICODE_NORM_QC_NO}, + {0x2F80C, UNICODE_NORM_QC_NO}, + {0x2F80D, UNICODE_NORM_QC_NO}, + {0x2F80E, UNICODE_NORM_QC_NO}, + {0x2F80F, UNICODE_NORM_QC_NO}, + {0x2F810, UNICODE_NORM_QC_NO}, + {0x2F811, UNICODE_NORM_QC_NO}, + {0x2F812, UNICODE_NORM_QC_NO}, + {0x2F813, UNICODE_NORM_QC_NO}, + {0x2F814, UNICODE_NORM_QC_NO}, + {0x2F815, UNICODE_NORM_QC_NO}, + {0x2F816, UNICODE_NORM_QC_NO}, + {0x2F817, UNICODE_NORM_QC_NO}, + {0x2F818, UNICODE_NORM_QC_NO}, + {0x2F819, UNICODE_NORM_QC_NO}, + {0x2F81A, UNICODE_NORM_QC_NO}, + {0x2F81B, UNICODE_NORM_QC_NO}, + {0x2F81C, UNICODE_NORM_QC_NO}, + {0x2F81D, UNICODE_NORM_QC_NO}, + {0x2F81E, UNICODE_NORM_QC_NO}, + {0x2F81F, UNICODE_NORM_QC_NO}, + {0x2F820, UNICODE_NORM_QC_NO}, + {0x2F821, UNICODE_NORM_QC_NO}, + {0x2F822, UNICODE_NORM_QC_NO}, + {0x2F823, UNICODE_NORM_QC_NO}, + {0x2F824, UNICODE_NORM_QC_NO}, + {0x2F825, UNICODE_NORM_QC_NO}, + {0x2F826, UNICODE_NORM_QC_NO}, + {0x2F827, UNICODE_NORM_QC_NO}, + {0x2F828, UNICODE_NORM_QC_NO}, + {0x2F829, UNICODE_NORM_QC_NO}, + {0x2F82A, UNICODE_NORM_QC_NO}, + {0x2F82B, UNICODE_NORM_QC_NO}, + {0x2F82C, UNICODE_NORM_QC_NO}, + {0x2F82D, UNICODE_NORM_QC_NO}, + {0x2F82E, UNICODE_NORM_QC_NO}, + {0x2F82F, UNICODE_NORM_QC_NO}, + {0x2F830, UNICODE_NORM_QC_NO}, + {0x2F831, UNICODE_NORM_QC_NO}, + {0x2F832, UNICODE_NORM_QC_NO}, + {0x2F833, UNICODE_NORM_QC_NO}, + {0x2F834, UNICODE_NORM_QC_NO}, + {0x2F835, UNICODE_NORM_QC_NO}, + {0x2F836, UNICODE_NORM_QC_NO}, + {0x2F837, UNICODE_NORM_QC_NO}, + {0x2F838, UNICODE_NORM_QC_NO}, + {0x2F839, UNICODE_NORM_QC_NO}, + {0x2F83A, UNICODE_NORM_QC_NO}, + {0x2F83B, UNICODE_NORM_QC_NO}, + {0x2F83C, UNICODE_NORM_QC_NO}, + {0x2F83D, UNICODE_NORM_QC_NO}, + {0x2F83E, UNICODE_NORM_QC_NO}, + {0x2F83F, UNICODE_NORM_QC_NO}, + {0x2F840, UNICODE_NORM_QC_NO}, + {0x2F841, UNICODE_NORM_QC_NO}, + {0x2F842, UNICODE_NORM_QC_NO}, + {0x2F843, UNICODE_NORM_QC_NO}, + {0x2F844, UNICODE_NORM_QC_NO}, + {0x2F845, UNICODE_NORM_QC_NO}, + {0x2F846, UNICODE_NORM_QC_NO}, + {0x2F847, UNICODE_NORM_QC_NO}, + {0x2F848, UNICODE_NORM_QC_NO}, + {0x2F849, UNICODE_NORM_QC_NO}, + {0x2F84A, UNICODE_NORM_QC_NO}, + {0x2F84B, UNICODE_NORM_QC_NO}, + {0x2F84C, UNICODE_NORM_QC_NO}, + {0x2F84D, UNICODE_NORM_QC_NO}, + {0x2F84E, UNICODE_NORM_QC_NO}, + {0x2F84F, UNICODE_NORM_QC_NO}, + {0x2F850, UNICODE_NORM_QC_NO}, + {0x2F851, UNICODE_NORM_QC_NO}, + {0x2F852, UNICODE_NORM_QC_NO}, + {0x2F853, UNICODE_NORM_QC_NO}, + {0x2F854, UNICODE_NORM_QC_NO}, + {0x2F855, UNICODE_NORM_QC_NO}, + {0x2F856, UNICODE_NORM_QC_NO}, + {0x2F857, UNICODE_NORM_QC_NO}, + {0x2F858, UNICODE_NORM_QC_NO}, + {0x2F859, UNICODE_NORM_QC_NO}, + {0x2F85A, UNICODE_NORM_QC_NO}, + {0x2F85B, UNICODE_NORM_QC_NO}, + {0x2F85C, UNICODE_NORM_QC_NO}, + {0x2F85D, UNICODE_NORM_QC_NO}, + {0x2F85E, UNICODE_NORM_QC_NO}, + {0x2F85F, UNICODE_NORM_QC_NO}, + {0x2F860, UNICODE_NORM_QC_NO}, + {0x2F861, UNICODE_NORM_QC_NO}, + {0x2F862, UNICODE_NORM_QC_NO}, + {0x2F863, UNICODE_NORM_QC_NO}, + {0x2F864, UNICODE_NORM_QC_NO}, + {0x2F865, UNICODE_NORM_QC_NO}, + {0x2F866, UNICODE_NORM_QC_NO}, + {0x2F867, UNICODE_NORM_QC_NO}, + {0x2F868, UNICODE_NORM_QC_NO}, + {0x2F869, UNICODE_NORM_QC_NO}, + {0x2F86A, UNICODE_NORM_QC_NO}, + {0x2F86B, UNICODE_NORM_QC_NO}, + {0x2F86C, UNICODE_NORM_QC_NO}, + {0x2F86D, UNICODE_NORM_QC_NO}, + {0x2F86E, UNICODE_NORM_QC_NO}, + {0x2F86F, UNICODE_NORM_QC_NO}, + {0x2F870, UNICODE_NORM_QC_NO}, + {0x2F871, UNICODE_NORM_QC_NO}, + {0x2F872, UNICODE_NORM_QC_NO}, + {0x2F873, UNICODE_NORM_QC_NO}, + {0x2F874, UNICODE_NORM_QC_NO}, + {0x2F875, UNICODE_NORM_QC_NO}, + {0x2F876, UNICODE_NORM_QC_NO}, + {0x2F877, UNICODE_NORM_QC_NO}, + {0x2F878, UNICODE_NORM_QC_NO}, + {0x2F879, UNICODE_NORM_QC_NO}, + {0x2F87A, UNICODE_NORM_QC_NO}, + {0x2F87B, UNICODE_NORM_QC_NO}, + {0x2F87C, UNICODE_NORM_QC_NO}, + {0x2F87D, UNICODE_NORM_QC_NO}, + {0x2F87E, UNICODE_NORM_QC_NO}, + {0x2F87F, UNICODE_NORM_QC_NO}, + {0x2F880, UNICODE_NORM_QC_NO}, + {0x2F881, UNICODE_NORM_QC_NO}, + {0x2F882, UNICODE_NORM_QC_NO}, + {0x2F883, UNICODE_NORM_QC_NO}, + {0x2F884, UNICODE_NORM_QC_NO}, + {0x2F885, UNICODE_NORM_QC_NO}, + {0x2F886, UNICODE_NORM_QC_NO}, + {0x2F887, UNICODE_NORM_QC_NO}, + {0x2F888, UNICODE_NORM_QC_NO}, + {0x2F889, UNICODE_NORM_QC_NO}, + {0x2F88A, UNICODE_NORM_QC_NO}, + {0x2F88B, UNICODE_NORM_QC_NO}, + {0x2F88C, UNICODE_NORM_QC_NO}, + {0x2F88D, UNICODE_NORM_QC_NO}, + {0x2F88E, UNICODE_NORM_QC_NO}, + {0x2F88F, UNICODE_NORM_QC_NO}, + {0x2F890, UNICODE_NORM_QC_NO}, + {0x2F891, UNICODE_NORM_QC_NO}, + {0x2F892, UNICODE_NORM_QC_NO}, + {0x2F893, UNICODE_NORM_QC_NO}, + {0x2F894, UNICODE_NORM_QC_NO}, + {0x2F895, UNICODE_NORM_QC_NO}, + {0x2F896, UNICODE_NORM_QC_NO}, + {0x2F897, UNICODE_NORM_QC_NO}, + {0x2F898, UNICODE_NORM_QC_NO}, + {0x2F899, UNICODE_NORM_QC_NO}, + {0x2F89A, UNICODE_NORM_QC_NO}, + {0x2F89B, UNICODE_NORM_QC_NO}, + {0x2F89C, UNICODE_NORM_QC_NO}, + {0x2F89D, UNICODE_NORM_QC_NO}, + {0x2F89E, UNICODE_NORM_QC_NO}, + {0x2F89F, UNICODE_NORM_QC_NO}, + {0x2F8A0, UNICODE_NORM_QC_NO}, + {0x2F8A1, UNICODE_NORM_QC_NO}, + {0x2F8A2, UNICODE_NORM_QC_NO}, + {0x2F8A3, UNICODE_NORM_QC_NO}, + {0x2F8A4, UNICODE_NORM_QC_NO}, + {0x2F8A5, UNICODE_NORM_QC_NO}, + {0x2F8A6, UNICODE_NORM_QC_NO}, + {0x2F8A7, UNICODE_NORM_QC_NO}, + {0x2F8A8, UNICODE_NORM_QC_NO}, + {0x2F8A9, UNICODE_NORM_QC_NO}, + {0x2F8AA, UNICODE_NORM_QC_NO}, + {0x2F8AB, UNICODE_NORM_QC_NO}, + {0x2F8AC, UNICODE_NORM_QC_NO}, + {0x2F8AD, UNICODE_NORM_QC_NO}, + {0x2F8AE, UNICODE_NORM_QC_NO}, + {0x2F8AF, UNICODE_NORM_QC_NO}, + {0x2F8B0, UNICODE_NORM_QC_NO}, + {0x2F8B1, UNICODE_NORM_QC_NO}, + {0x2F8B2, UNICODE_NORM_QC_NO}, + {0x2F8B3, UNICODE_NORM_QC_NO}, + {0x2F8B4, UNICODE_NORM_QC_NO}, + {0x2F8B5, UNICODE_NORM_QC_NO}, + {0x2F8B6, UNICODE_NORM_QC_NO}, + {0x2F8B7, UNICODE_NORM_QC_NO}, + {0x2F8B8, UNICODE_NORM_QC_NO}, + {0x2F8B9, UNICODE_NORM_QC_NO}, + {0x2F8BA, UNICODE_NORM_QC_NO}, + {0x2F8BB, UNICODE_NORM_QC_NO}, + {0x2F8BC, UNICODE_NORM_QC_NO}, + {0x2F8BD, UNICODE_NORM_QC_NO}, + {0x2F8BE, UNICODE_NORM_QC_NO}, + {0x2F8BF, UNICODE_NORM_QC_NO}, + {0x2F8C0, UNICODE_NORM_QC_NO}, + {0x2F8C1, UNICODE_NORM_QC_NO}, + {0x2F8C2, UNICODE_NORM_QC_NO}, + {0x2F8C3, UNICODE_NORM_QC_NO}, + {0x2F8C4, UNICODE_NORM_QC_NO}, + {0x2F8C5, UNICODE_NORM_QC_NO}, + {0x2F8C6, UNICODE_NORM_QC_NO}, + {0x2F8C7, UNICODE_NORM_QC_NO}, + {0x2F8C8, UNICODE_NORM_QC_NO}, + {0x2F8C9, UNICODE_NORM_QC_NO}, + {0x2F8CA, UNICODE_NORM_QC_NO}, + {0x2F8CB, UNICODE_NORM_QC_NO}, + {0x2F8CC, UNICODE_NORM_QC_NO}, + {0x2F8CD, UNICODE_NORM_QC_NO}, + {0x2F8CE, UNICODE_NORM_QC_NO}, + {0x2F8CF, UNICODE_NORM_QC_NO}, + {0x2F8D0, UNICODE_NORM_QC_NO}, + {0x2F8D1, UNICODE_NORM_QC_NO}, + {0x2F8D2, UNICODE_NORM_QC_NO}, + {0x2F8D3, UNICODE_NORM_QC_NO}, + {0x2F8D4, UNICODE_NORM_QC_NO}, + {0x2F8D5, UNICODE_NORM_QC_NO}, + {0x2F8D6, UNICODE_NORM_QC_NO}, + {0x2F8D7, UNICODE_NORM_QC_NO}, + {0x2F8D8, UNICODE_NORM_QC_NO}, + {0x2F8D9, UNICODE_NORM_QC_NO}, + {0x2F8DA, UNICODE_NORM_QC_NO}, + {0x2F8DB, UNICODE_NORM_QC_NO}, + {0x2F8DC, UNICODE_NORM_QC_NO}, + {0x2F8DD, UNICODE_NORM_QC_NO}, + {0x2F8DE, UNICODE_NORM_QC_NO}, + {0x2F8DF, UNICODE_NORM_QC_NO}, + {0x2F8E0, UNICODE_NORM_QC_NO}, + {0x2F8E1, UNICODE_NORM_QC_NO}, + {0x2F8E2, UNICODE_NORM_QC_NO}, + {0x2F8E3, UNICODE_NORM_QC_NO}, + {0x2F8E4, UNICODE_NORM_QC_NO}, + {0x2F8E5, UNICODE_NORM_QC_NO}, + {0x2F8E6, UNICODE_NORM_QC_NO}, + {0x2F8E7, UNICODE_NORM_QC_NO}, + {0x2F8E8, UNICODE_NORM_QC_NO}, + {0x2F8E9, UNICODE_NORM_QC_NO}, + {0x2F8EA, UNICODE_NORM_QC_NO}, + {0x2F8EB, UNICODE_NORM_QC_NO}, + {0x2F8EC, UNICODE_NORM_QC_NO}, + {0x2F8ED, UNICODE_NORM_QC_NO}, + {0x2F8EE, UNICODE_NORM_QC_NO}, + {0x2F8EF, UNICODE_NORM_QC_NO}, + {0x2F8F0, UNICODE_NORM_QC_NO}, + {0x2F8F1, UNICODE_NORM_QC_NO}, + {0x2F8F2, UNICODE_NORM_QC_NO}, + {0x2F8F3, UNICODE_NORM_QC_NO}, + {0x2F8F4, UNICODE_NORM_QC_NO}, + {0x2F8F5, UNICODE_NORM_QC_NO}, + {0x2F8F6, UNICODE_NORM_QC_NO}, + {0x2F8F7, UNICODE_NORM_QC_NO}, + {0x2F8F8, UNICODE_NORM_QC_NO}, + {0x2F8F9, UNICODE_NORM_QC_NO}, + {0x2F8FA, UNICODE_NORM_QC_NO}, + {0x2F8FB, UNICODE_NORM_QC_NO}, + {0x2F8FC, UNICODE_NORM_QC_NO}, + {0x2F8FD, UNICODE_NORM_QC_NO}, + {0x2F8FE, UNICODE_NORM_QC_NO}, + {0x2F8FF, UNICODE_NORM_QC_NO}, + {0x2F900, UNICODE_NORM_QC_NO}, + {0x2F901, UNICODE_NORM_QC_NO}, + {0x2F902, UNICODE_NORM_QC_NO}, + {0x2F903, UNICODE_NORM_QC_NO}, + {0x2F904, UNICODE_NORM_QC_NO}, + {0x2F905, UNICODE_NORM_QC_NO}, + {0x2F906, UNICODE_NORM_QC_NO}, + {0x2F907, UNICODE_NORM_QC_NO}, + {0x2F908, UNICODE_NORM_QC_NO}, + {0x2F909, UNICODE_NORM_QC_NO}, + {0x2F90A, UNICODE_NORM_QC_NO}, + {0x2F90B, UNICODE_NORM_QC_NO}, + {0x2F90C, UNICODE_NORM_QC_NO}, + {0x2F90D, UNICODE_NORM_QC_NO}, + {0x2F90E, UNICODE_NORM_QC_NO}, + {0x2F90F, UNICODE_NORM_QC_NO}, + {0x2F910, UNICODE_NORM_QC_NO}, + {0x2F911, UNICODE_NORM_QC_NO}, + {0x2F912, UNICODE_NORM_QC_NO}, + {0x2F913, UNICODE_NORM_QC_NO}, + {0x2F914, UNICODE_NORM_QC_NO}, + {0x2F915, UNICODE_NORM_QC_NO}, + {0x2F916, UNICODE_NORM_QC_NO}, + {0x2F917, UNICODE_NORM_QC_NO}, + {0x2F918, UNICODE_NORM_QC_NO}, + {0x2F919, UNICODE_NORM_QC_NO}, + {0x2F91A, UNICODE_NORM_QC_NO}, + {0x2F91B, UNICODE_NORM_QC_NO}, + {0x2F91C, UNICODE_NORM_QC_NO}, + {0x2F91D, UNICODE_NORM_QC_NO}, + {0x2F91E, UNICODE_NORM_QC_NO}, + {0x2F91F, UNICODE_NORM_QC_NO}, + {0x2F920, UNICODE_NORM_QC_NO}, + {0x2F921, UNICODE_NORM_QC_NO}, + {0x2F922, UNICODE_NORM_QC_NO}, + {0x2F923, UNICODE_NORM_QC_NO}, + {0x2F924, UNICODE_NORM_QC_NO}, + {0x2F925, UNICODE_NORM_QC_NO}, + {0x2F926, UNICODE_NORM_QC_NO}, + {0x2F927, UNICODE_NORM_QC_NO}, + {0x2F928, UNICODE_NORM_QC_NO}, + {0x2F929, UNICODE_NORM_QC_NO}, + {0x2F92A, UNICODE_NORM_QC_NO}, + {0x2F92B, UNICODE_NORM_QC_NO}, + {0x2F92C, UNICODE_NORM_QC_NO}, + {0x2F92D, UNICODE_NORM_QC_NO}, + {0x2F92E, UNICODE_NORM_QC_NO}, + {0x2F92F, UNICODE_NORM_QC_NO}, + {0x2F930, UNICODE_NORM_QC_NO}, + {0x2F931, UNICODE_NORM_QC_NO}, + {0x2F932, UNICODE_NORM_QC_NO}, + {0x2F933, UNICODE_NORM_QC_NO}, + {0x2F934, UNICODE_NORM_QC_NO}, + {0x2F935, UNICODE_NORM_QC_NO}, + {0x2F936, UNICODE_NORM_QC_NO}, + {0x2F937, UNICODE_NORM_QC_NO}, + {0x2F938, UNICODE_NORM_QC_NO}, + {0x2F939, UNICODE_NORM_QC_NO}, + {0x2F93A, UNICODE_NORM_QC_NO}, + {0x2F93B, UNICODE_NORM_QC_NO}, + {0x2F93C, UNICODE_NORM_QC_NO}, + {0x2F93D, UNICODE_NORM_QC_NO}, + {0x2F93E, UNICODE_NORM_QC_NO}, + {0x2F93F, UNICODE_NORM_QC_NO}, + {0x2F940, UNICODE_NORM_QC_NO}, + {0x2F941, UNICODE_NORM_QC_NO}, + {0x2F942, UNICODE_NORM_QC_NO}, + {0x2F943, UNICODE_NORM_QC_NO}, + {0x2F944, UNICODE_NORM_QC_NO}, + {0x2F945, UNICODE_NORM_QC_NO}, + {0x2F946, UNICODE_NORM_QC_NO}, + {0x2F947, UNICODE_NORM_QC_NO}, + {0x2F948, UNICODE_NORM_QC_NO}, + {0x2F949, UNICODE_NORM_QC_NO}, + {0x2F94A, UNICODE_NORM_QC_NO}, + {0x2F94B, UNICODE_NORM_QC_NO}, + {0x2F94C, UNICODE_NORM_QC_NO}, + {0x2F94D, UNICODE_NORM_QC_NO}, + {0x2F94E, UNICODE_NORM_QC_NO}, + {0x2F94F, UNICODE_NORM_QC_NO}, + {0x2F950, UNICODE_NORM_QC_NO}, + {0x2F951, UNICODE_NORM_QC_NO}, + {0x2F952, UNICODE_NORM_QC_NO}, + {0x2F953, UNICODE_NORM_QC_NO}, + {0x2F954, UNICODE_NORM_QC_NO}, + {0x2F955, UNICODE_NORM_QC_NO}, + {0x2F956, UNICODE_NORM_QC_NO}, + {0x2F957, UNICODE_NORM_QC_NO}, + {0x2F958, UNICODE_NORM_QC_NO}, + {0x2F959, UNICODE_NORM_QC_NO}, + {0x2F95A, UNICODE_NORM_QC_NO}, + {0x2F95B, UNICODE_NORM_QC_NO}, + {0x2F95C, UNICODE_NORM_QC_NO}, + {0x2F95D, UNICODE_NORM_QC_NO}, + {0x2F95E, UNICODE_NORM_QC_NO}, + {0x2F95F, UNICODE_NORM_QC_NO}, + {0x2F960, UNICODE_NORM_QC_NO}, + {0x2F961, UNICODE_NORM_QC_NO}, + {0x2F962, UNICODE_NORM_QC_NO}, + {0x2F963, UNICODE_NORM_QC_NO}, + {0x2F964, UNICODE_NORM_QC_NO}, + {0x2F965, UNICODE_NORM_QC_NO}, + {0x2F966, UNICODE_NORM_QC_NO}, + {0x2F967, UNICODE_NORM_QC_NO}, + {0x2F968, UNICODE_NORM_QC_NO}, + {0x2F969, UNICODE_NORM_QC_NO}, + {0x2F96A, UNICODE_NORM_QC_NO}, + {0x2F96B, UNICODE_NORM_QC_NO}, + {0x2F96C, UNICODE_NORM_QC_NO}, + {0x2F96D, UNICODE_NORM_QC_NO}, + {0x2F96E, UNICODE_NORM_QC_NO}, + {0x2F96F, UNICODE_NORM_QC_NO}, + {0x2F970, UNICODE_NORM_QC_NO}, + {0x2F971, UNICODE_NORM_QC_NO}, + {0x2F972, UNICODE_NORM_QC_NO}, + {0x2F973, UNICODE_NORM_QC_NO}, + {0x2F974, UNICODE_NORM_QC_NO}, + {0x2F975, UNICODE_NORM_QC_NO}, + {0x2F976, UNICODE_NORM_QC_NO}, + {0x2F977, UNICODE_NORM_QC_NO}, + {0x2F978, UNICODE_NORM_QC_NO}, + {0x2F979, UNICODE_NORM_QC_NO}, + {0x2F97A, UNICODE_NORM_QC_NO}, + {0x2F97B, UNICODE_NORM_QC_NO}, + {0x2F97C, UNICODE_NORM_QC_NO}, + {0x2F97D, UNICODE_NORM_QC_NO}, + {0x2F97E, UNICODE_NORM_QC_NO}, + {0x2F97F, UNICODE_NORM_QC_NO}, + {0x2F980, UNICODE_NORM_QC_NO}, + {0x2F981, UNICODE_NORM_QC_NO}, + {0x2F982, UNICODE_NORM_QC_NO}, + {0x2F983, UNICODE_NORM_QC_NO}, + {0x2F984, UNICODE_NORM_QC_NO}, + {0x2F985, UNICODE_NORM_QC_NO}, + {0x2F986, UNICODE_NORM_QC_NO}, + {0x2F987, UNICODE_NORM_QC_NO}, + {0x2F988, UNICODE_NORM_QC_NO}, + {0x2F989, UNICODE_NORM_QC_NO}, + {0x2F98A, UNICODE_NORM_QC_NO}, + {0x2F98B, UNICODE_NORM_QC_NO}, + {0x2F98C, UNICODE_NORM_QC_NO}, + {0x2F98D, UNICODE_NORM_QC_NO}, + {0x2F98E, UNICODE_NORM_QC_NO}, + {0x2F98F, UNICODE_NORM_QC_NO}, + {0x2F990, UNICODE_NORM_QC_NO}, + {0x2F991, UNICODE_NORM_QC_NO}, + {0x2F992, UNICODE_NORM_QC_NO}, + {0x2F993, UNICODE_NORM_QC_NO}, + {0x2F994, UNICODE_NORM_QC_NO}, + {0x2F995, UNICODE_NORM_QC_NO}, + {0x2F996, UNICODE_NORM_QC_NO}, + {0x2F997, UNICODE_NORM_QC_NO}, + {0x2F998, UNICODE_NORM_QC_NO}, + {0x2F999, UNICODE_NORM_QC_NO}, + {0x2F99A, UNICODE_NORM_QC_NO}, + {0x2F99B, UNICODE_NORM_QC_NO}, + {0x2F99C, UNICODE_NORM_QC_NO}, + {0x2F99D, UNICODE_NORM_QC_NO}, + {0x2F99E, UNICODE_NORM_QC_NO}, + {0x2F99F, UNICODE_NORM_QC_NO}, + {0x2F9A0, UNICODE_NORM_QC_NO}, + {0x2F9A1, UNICODE_NORM_QC_NO}, + {0x2F9A2, UNICODE_NORM_QC_NO}, + {0x2F9A3, UNICODE_NORM_QC_NO}, + {0x2F9A4, UNICODE_NORM_QC_NO}, + {0x2F9A5, UNICODE_NORM_QC_NO}, + {0x2F9A6, UNICODE_NORM_QC_NO}, + {0x2F9A7, UNICODE_NORM_QC_NO}, + {0x2F9A8, UNICODE_NORM_QC_NO}, + {0x2F9A9, UNICODE_NORM_QC_NO}, + {0x2F9AA, UNICODE_NORM_QC_NO}, + {0x2F9AB, UNICODE_NORM_QC_NO}, + {0x2F9AC, UNICODE_NORM_QC_NO}, + {0x2F9AD, UNICODE_NORM_QC_NO}, + {0x2F9AE, UNICODE_NORM_QC_NO}, + {0x2F9AF, UNICODE_NORM_QC_NO}, + {0x2F9B0, UNICODE_NORM_QC_NO}, + {0x2F9B1, UNICODE_NORM_QC_NO}, + {0x2F9B2, UNICODE_NORM_QC_NO}, + {0x2F9B3, UNICODE_NORM_QC_NO}, + {0x2F9B4, UNICODE_NORM_QC_NO}, + {0x2F9B5, UNICODE_NORM_QC_NO}, + {0x2F9B6, UNICODE_NORM_QC_NO}, + {0x2F9B7, UNICODE_NORM_QC_NO}, + {0x2F9B8, UNICODE_NORM_QC_NO}, + {0x2F9B9, UNICODE_NORM_QC_NO}, + {0x2F9BA, UNICODE_NORM_QC_NO}, + {0x2F9BB, UNICODE_NORM_QC_NO}, + {0x2F9BC, UNICODE_NORM_QC_NO}, + {0x2F9BD, UNICODE_NORM_QC_NO}, + {0x2F9BE, UNICODE_NORM_QC_NO}, + {0x2F9BF, UNICODE_NORM_QC_NO}, + {0x2F9C0, UNICODE_NORM_QC_NO}, + {0x2F9C1, UNICODE_NORM_QC_NO}, + {0x2F9C2, UNICODE_NORM_QC_NO}, + {0x2F9C3, UNICODE_NORM_QC_NO}, + {0x2F9C4, UNICODE_NORM_QC_NO}, + {0x2F9C5, UNICODE_NORM_QC_NO}, + {0x2F9C6, UNICODE_NORM_QC_NO}, + {0x2F9C7, UNICODE_NORM_QC_NO}, + {0x2F9C8, UNICODE_NORM_QC_NO}, + {0x2F9C9, UNICODE_NORM_QC_NO}, + {0x2F9CA, UNICODE_NORM_QC_NO}, + {0x2F9CB, UNICODE_NORM_QC_NO}, + {0x2F9CC, UNICODE_NORM_QC_NO}, + {0x2F9CD, UNICODE_NORM_QC_NO}, + {0x2F9CE, UNICODE_NORM_QC_NO}, + {0x2F9CF, UNICODE_NORM_QC_NO}, + {0x2F9D0, UNICODE_NORM_QC_NO}, + {0x2F9D1, UNICODE_NORM_QC_NO}, + {0x2F9D2, UNICODE_NORM_QC_NO}, + {0x2F9D3, UNICODE_NORM_QC_NO}, + {0x2F9D4, UNICODE_NORM_QC_NO}, + {0x2F9D5, UNICODE_NORM_QC_NO}, + {0x2F9D6, UNICODE_NORM_QC_NO}, + {0x2F9D7, UNICODE_NORM_QC_NO}, + {0x2F9D8, UNICODE_NORM_QC_NO}, + {0x2F9D9, UNICODE_NORM_QC_NO}, + {0x2F9DA, UNICODE_NORM_QC_NO}, + {0x2F9DB, UNICODE_NORM_QC_NO}, + {0x2F9DC, UNICODE_NORM_QC_NO}, + {0x2F9DD, UNICODE_NORM_QC_NO}, + {0x2F9DE, UNICODE_NORM_QC_NO}, + {0x2F9DF, UNICODE_NORM_QC_NO}, + {0x2F9E0, UNICODE_NORM_QC_NO}, + {0x2F9E1, UNICODE_NORM_QC_NO}, + {0x2F9E2, UNICODE_NORM_QC_NO}, + {0x2F9E3, UNICODE_NORM_QC_NO}, + {0x2F9E4, UNICODE_NORM_QC_NO}, + {0x2F9E5, UNICODE_NORM_QC_NO}, + {0x2F9E6, UNICODE_NORM_QC_NO}, + {0x2F9E7, UNICODE_NORM_QC_NO}, + {0x2F9E8, UNICODE_NORM_QC_NO}, + {0x2F9E9, UNICODE_NORM_QC_NO}, + {0x2F9EA, UNICODE_NORM_QC_NO}, + {0x2F9EB, UNICODE_NORM_QC_NO}, + {0x2F9EC, UNICODE_NORM_QC_NO}, + {0x2F9ED, UNICODE_NORM_QC_NO}, + {0x2F9EE, UNICODE_NORM_QC_NO}, + {0x2F9EF, UNICODE_NORM_QC_NO}, + {0x2F9F0, UNICODE_NORM_QC_NO}, + {0x2F9F1, UNICODE_NORM_QC_NO}, + {0x2F9F2, UNICODE_NORM_QC_NO}, + {0x2F9F3, UNICODE_NORM_QC_NO}, + {0x2F9F4, UNICODE_NORM_QC_NO}, + {0x2F9F5, UNICODE_NORM_QC_NO}, + {0x2F9F6, UNICODE_NORM_QC_NO}, + {0x2F9F7, UNICODE_NORM_QC_NO}, + {0x2F9F8, UNICODE_NORM_QC_NO}, + {0x2F9F9, UNICODE_NORM_QC_NO}, + {0x2F9FA, UNICODE_NORM_QC_NO}, + {0x2F9FB, UNICODE_NORM_QC_NO}, + {0x2F9FC, UNICODE_NORM_QC_NO}, + {0x2F9FD, UNICODE_NORM_QC_NO}, + {0x2F9FE, UNICODE_NORM_QC_NO}, + {0x2F9FF, UNICODE_NORM_QC_NO}, + {0x2FA00, UNICODE_NORM_QC_NO}, + {0x2FA01, UNICODE_NORM_QC_NO}, + {0x2FA02, UNICODE_NORM_QC_NO}, + {0x2FA03, UNICODE_NORM_QC_NO}, + {0x2FA04, UNICODE_NORM_QC_NO}, + {0x2FA05, UNICODE_NORM_QC_NO}, + {0x2FA06, UNICODE_NORM_QC_NO}, + {0x2FA07, UNICODE_NORM_QC_NO}, + {0x2FA08, UNICODE_NORM_QC_NO}, + {0x2FA09, UNICODE_NORM_QC_NO}, + {0x2FA0A, UNICODE_NORM_QC_NO}, + {0x2FA0B, UNICODE_NORM_QC_NO}, + {0x2FA0C, UNICODE_NORM_QC_NO}, + {0x2FA0D, UNICODE_NORM_QC_NO}, + {0x2FA0E, UNICODE_NORM_QC_NO}, + {0x2FA0F, UNICODE_NORM_QC_NO}, + {0x2FA10, UNICODE_NORM_QC_NO}, + {0x2FA11, UNICODE_NORM_QC_NO}, + {0x2FA12, UNICODE_NORM_QC_NO}, + {0x2FA13, UNICODE_NORM_QC_NO}, + {0x2FA14, UNICODE_NORM_QC_NO}, + {0x2FA15, UNICODE_NORM_QC_NO}, + {0x2FA16, UNICODE_NORM_QC_NO}, + {0x2FA17, UNICODE_NORM_QC_NO}, + {0x2FA18, UNICODE_NORM_QC_NO}, + {0x2FA19, UNICODE_NORM_QC_NO}, + {0x2FA1A, UNICODE_NORM_QC_NO}, + {0x2FA1B, UNICODE_NORM_QC_NO}, + {0x2FA1C, UNICODE_NORM_QC_NO}, + {0x2FA1D, UNICODE_NORM_QC_NO}, +}; + +/* Perfect hash function for NFC_QC */ +static int +NFC_QC_hash_func(const void *key) +{ + static const int16 h[2463] = { + 0, -2717, 0, 221, 1293, 223, 1295, 225, + 226, 241, 0, 229, 230, 231, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -386, 0, 0, 0, 0, 0, 0, 0, + -163, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -246, -175, 1260, 0, 0, 0, -174, -173, + 0, -172, 0, 0, 0, 0, 0, 0, + 1049, 0, 300, 301, 1071, 0, 1071, 0, + 1071, 1071, 1057, 0, 0, 0, 0, 1061, + 0, -1053, 1664, 0, 2956, 0, 0, -13, + 0, 0, 0, 0, 2156, 0, 0, 0, + 0, 0, 0, 0, 71, 0, 1082, 0, + 1083, 1083, 0, 1084, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 359, 360, 361, + -1091, 363, -762, -130, -129, -128, -127, -126, + 137, -124, -708, -707, -706, -120, -185, -705, + -117, -184, -1307, -114, -113, -112, -111, 0, + 386, 387, 388, 389, -90, 391, 171, 172, + 394, -94, -183, 397, 398, 399, -98, -225, + 402, -1019, -636, -1019, -225, 407, 408, 409, + 410, 411, 674, 413, -171, -170, -169, 417, + 352, -168, 420, 353, -770, 423, 424, 425, + 426, 427, 428, 32767, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 32767, 32767, 237, 32767, 236, 32767, + 32767, 234, 234, 234, 234, 617, 234, 234, + 234, -2483, 234, -1430, 1526, -1430, 1527, 47, + 48, 471, 230, 32767, 32767, 32767, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + -159, 227, 227, 227, 227, 227, 227, 227, + 64, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + -19, 52, 1487, 227, 227, 227, 53, 54, + 227, 55, 227, 227, 227, 227, 227, 227, + 1276, 227, -989, 32767, 1296, 225, 1296, 225, + 1296, 1296, 1282, 225, 225, 225, 225, 1286, + 225, -828, 1889, 225, 3181, 225, 225, 212, + 225, 225, 225, 225, 2381, 225, 225, 225, + 225, 225, 225, 225, 296, 225, 1307, 225, + 1308, 1308, 225, 1309, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 584, 585, 586, + -866, 588, -537, 95, 96, 97, 98, 99, + 362, 101, -483, -482, -481, 105, 40, -480, + 108, 41, -1082, 111, 112, 113, 114, 225, + 611, 612, 613, 614, 135, 616, 396, 397, + 619, 131, 42, 622, 623, 624, 127, 0, + 627, -794, -411, -794, 0, 632, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + -272, 32767, 32767, 32767, 0, 32767, 32767, 32767, + 32767, 32767, -166, -165, 32767, 32767, 32767, 32767, + -164, 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, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 397, 32767, 396, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 386, + 0, 386, 386, 386, 386, 386, 386, 386, + 223, 386, 386, 386, 32767, 385, 385, 385, + 385, 385, 32767, 384, 32767, 383, 383, 32767, + 382, 382, 32767, 381, 381, 381, 381, 381, + 135, 206, 1641, 381, 32767, 32767, 32767, 32767, + 32767, 32767, -160, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 1148, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 32767, 32767, 32767, 0, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, -257, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -910, -910, 32767, 32767, + 0, 32767, 0, 32767, 0, 32767, 0, 32767, + 147, 32767, 0, 32767, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 0, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 143, 32767, 144, 32767, 145, + 32767, 146, 32767, 0, 32767, 148, 32767, 149, + 32767, 32767, 32767, -160, 32767, 32767, 32767, 32767, + 32767, 32767, 15, 32767, 32767, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 145, 32767, 144, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 0, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 0, -148, 32767, 32767, 32767, 32767, + 32767, 32767, 2009, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 0, 32767, 32767, 135, -918, 32767, + 151, 32767, 32767, 0, 1, 2, 3, 4, + 133, 5, 6, 7, 8, 9, 10, 11, + 32767, 32767, -1248, 32767, 13, 154, 188, 188, + 32767, 32767, 32767, 32767, 32767, 155, 16, 32767, + 32767, 32767, 32767, 32767, 32767, -1853, -1054, 18, + -1052, -1051, -1036, 22, 32767, 157, 32767, 28, + 23, 1077, 673, 25, -2930, 0, 32767, 32767, + 32767, 32767, 32767, 27, 32767, 155, 32767, 154, + 32767, 32767, -62, 28, -42, 30, -1051, 32, + -1050, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 34, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 129, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 672, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 0, 32767, + 32767, 32767, 32767, 32767, -156, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -155, 32767, 32767, + 32767, 0, 0, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 73, 32767, 32767, 32767, 32767, 74, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 675, + 32767, 32767, 32767, 32767, 32767, 75, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 165, 32767, 32767, 32767, 166, 167, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 170, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, + 704, 705, 706, 707, 708, 709, 710, 711, + 712, 713, 714, 715, 716, 717, 718, 719, + 720, 721, 722, -304, -303, -302, -301, -300, + -299, -298, -297, 930, -295, -294, -293, -292, + -291, -290, -289, -288, -287, -286, -285, -284, + -283, -282, -281, -280, -279, -278, -277, -276, + -275, 753, 754, 755, 646, 757, -712, -1765, + 952, -712, 2244, -712, 2245, 765, 766, 767, + 768, 125, 770, 771, 772, 773, 774, 775, + 603, 777, 778, 779, 780, 781, 782, 783, + 784, 2011, 786, 787, 788, 789, 790, 791, + 792, 793, 794, 795, 796, 797, 798, 799, + 800, 801, 802, 803, 804, 805, 806, 603, + 603, 809, 603, 811, 603, 603, 814, 815, + 816, 817, 435, 819, 820, 821, 3539, 823, + 603, -468, 603, -468, 603, 603, 589, 831, + 603, 603, 603, 835, 836, 837, 838, 839, + 840, 841, 842, 843, 844, 845, 846, 847, + 848, 849, 850, 851, 852, 1239, 854, 855, + 856, 857, 858, 859, 860, 1024, 862, 863, + 864, 865, 866, 867, 868, 869, 870, 871, + 872, 873, 874, 875, 876, 877, 878, 879, + 880, 881, 882, 883, 884, 1131, 1061, -373, + 888, 889, 890, 1065, 1065, 893, 1066, 895, + 896, 897, 898, 899, 900, -148, 902, 603, + 603, -166, 906, -164, 908, -162, -161, -146, + 912, 913, 914, 915, -145, 917, 1971, -745, + 920, -2035, 922, 923, 937, 925, 926, 927, + 928, -1227, 930, 931, 932, 933, 934, 935, + 936, 866, 938, -143, 940, -142, -141, 943, + -140, 32767, 945, 946, 947, 948, 949, 950, + 951, 952, 953, 954, 955, 956, 957, 958, + 959, 960, 961, -65, -64, -63, -62, -61, + -60, -59, -58, 1169, -56, -55, -54, -53, + -52, -51, -50, -49, -48, -47, -46, -45, + -44, -43, -42, -41, -40, -39, -38, -37, + -36, 992, 993, 994, 885, 996, -473, -1526, + 1191, -473, 2483, -473, 2484, 1004, 1005, 1006, + 1007, 364, 1009, 1010, 1011, 1012, 1013, 1014, + 842, 1016, 1017, 1018, 1019, 1020, 1021, 1022, + 1023, 2250, 1025, 1026, 1027, 1028, 1029, 1030, + 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 842, + 842, 1048, 842, 1050, 842, 842, 1053, 1054, + 1055, 1056, 674, 1058, 1059, 1060, 3778, 1062, + 842, -229, 842, -229, 842, 842, 828, 1070, + 842, 842, 842, 1074, 1075, 1076, 1077, 1078, + 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, + 1087, 1088, 1089, 1090, 1091, 1478, 1093, 1094, + 1095, 1096, 1097, 1098, 1099, 1263, 1101, 1102, + 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, + 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, + 1119, 1120, 1121, 1122, 1123, 1370, 1300, -134, + 1127, 1128, 1129, 1304, 1304, 1132, 1305, 1134, + 1135, 1136, 1137, 1138, 1139, 91, 1141, 842, + 842, 73, 1145, 75, 1147, 77, 78, 93, + 1151, 1152, 1153, 1154, 94, 1156, 2210, -506, + 1159, -1796, 1161, 1162, 1176, 1164, 1165, 1166, + 1167, -988, 1169, 1170, 1171, 1172, 1173, 1174, + 1175, 1105, 1177, 96, 1179, 97, 98, 1182, + 99, 1184, 1185, 1186, 1187, 1188, 1189, 1190, + 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, + 1199, 1200, 0, 174, 175, 176, 177, 178, + 179, 180, 181, 1408, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, + 203, 0, 0, 206, 0, 208, 0, 0, + 211, 212, 213, 214, -168, 216, 217, 218, + 2936, 220, 0, -1071, 0, -1071, 0, 0, + -14, 228, 0, 0, 0, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 636, + 251, 252, 253, 254, 255, 256, 257, 421, + 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 528, + 458, -976, 285, 286, 287, 462, 462, 290, + 463, 292, 293, 294, 295, 296, 297, -751, + 299, 0, 0, -769, 303, -767, 305, -765, + -764, -749, 309, 310, 311, 312, -748, 314, + 1368, -1348, 317, -2638, 319, 320, 334, 322, + 323, 324, 325, -1830, 327, 328, 329, 330, + 331, 332, 333, 263, 335, -746, 337, -745, + -744, 340, -743, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 0, 0, 0, 1453, + 0, 1126, 495, 495, 495, 495, 495, 233, + 495, 1080, 1080, 1080, 495, 561, 1082, 495, + 563, 1687, 495, 495, 495, 495, 385, 0, + 0, 0, 0, 480, 0, 221, 221, 0, + 489, 579, 0, 0, 0, 498, 626, 0, + 1422, 1040, 1424, 631, 0, 0, 0, 0, + 0, -262, 0, 585, 585, 585, 0, 66, + 587, 0, 68, 1192, 0, 0, 0, 0, + 0, 0, 32767, 32767, 32767, 32767, 669, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 670, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 142, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 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, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, -199, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 0, 0, 0, 110, 0, + 1470, 2524, -192, 1473, -1482, 1475, -1481, 0, + 0, 0, 0, 644, 0, 0, 0, 0, + 0, 0, 173, 0, 0, 0, 0, 0, + 0, 0, 0, -1226, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 204, 205, 0, 207, 0, 209, 210, + 0, 0, 0, 0, 383, 0, 0 + }; + + const unsigned char *k = (const unsigned char *) key; + size_t keylen = 4; + uint32 a = 0; + uint32 b = 0; + + while (keylen--) + { + unsigned char c = *k++; + + a = a * 257 + c; + b = b * 17 + c; + } + return h[a % 2463] + h[b % 2463]; +} + +/* Hash lookup information for NFC_QC */ +static const pg_unicode_norminfo UnicodeNormInfo_NFC_QC = { + UnicodeNormProps_NFC_QC, + NFC_QC_hash_func, + 1231 +}; + +static const pg_unicode_normprops UnicodeNormProps_NFKC_QC[] = { + {0x00A0, UNICODE_NORM_QC_NO}, + {0x00A8, UNICODE_NORM_QC_NO}, + {0x00AA, UNICODE_NORM_QC_NO}, + {0x00AF, UNICODE_NORM_QC_NO}, + {0x00B2, UNICODE_NORM_QC_NO}, + {0x00B3, UNICODE_NORM_QC_NO}, + {0x00B4, UNICODE_NORM_QC_NO}, + {0x00B5, UNICODE_NORM_QC_NO}, + {0x00B8, UNICODE_NORM_QC_NO}, + {0x00B9, UNICODE_NORM_QC_NO}, + {0x00BA, UNICODE_NORM_QC_NO}, + {0x00BC, UNICODE_NORM_QC_NO}, + {0x00BD, UNICODE_NORM_QC_NO}, + {0x00BE, UNICODE_NORM_QC_NO}, + {0x0132, UNICODE_NORM_QC_NO}, + {0x0133, UNICODE_NORM_QC_NO}, + {0x013F, UNICODE_NORM_QC_NO}, + {0x0140, UNICODE_NORM_QC_NO}, + {0x0149, UNICODE_NORM_QC_NO}, + {0x017F, UNICODE_NORM_QC_NO}, + {0x01C4, UNICODE_NORM_QC_NO}, + {0x01C5, UNICODE_NORM_QC_NO}, + {0x01C6, UNICODE_NORM_QC_NO}, + {0x01C7, UNICODE_NORM_QC_NO}, + {0x01C8, UNICODE_NORM_QC_NO}, + {0x01C9, UNICODE_NORM_QC_NO}, + {0x01CA, UNICODE_NORM_QC_NO}, + {0x01CB, UNICODE_NORM_QC_NO}, + {0x01CC, UNICODE_NORM_QC_NO}, + {0x01F1, UNICODE_NORM_QC_NO}, + {0x01F2, UNICODE_NORM_QC_NO}, + {0x01F3, UNICODE_NORM_QC_NO}, + {0x02B0, UNICODE_NORM_QC_NO}, + {0x02B1, UNICODE_NORM_QC_NO}, + {0x02B2, UNICODE_NORM_QC_NO}, + {0x02B3, UNICODE_NORM_QC_NO}, + {0x02B4, UNICODE_NORM_QC_NO}, + {0x02B5, UNICODE_NORM_QC_NO}, + {0x02B6, UNICODE_NORM_QC_NO}, + {0x02B7, UNICODE_NORM_QC_NO}, + {0x02B8, UNICODE_NORM_QC_NO}, + {0x02D8, UNICODE_NORM_QC_NO}, + {0x02D9, UNICODE_NORM_QC_NO}, + {0x02DA, UNICODE_NORM_QC_NO}, + {0x02DB, UNICODE_NORM_QC_NO}, + {0x02DC, UNICODE_NORM_QC_NO}, + {0x02DD, UNICODE_NORM_QC_NO}, + {0x02E0, UNICODE_NORM_QC_NO}, + {0x02E1, UNICODE_NORM_QC_NO}, + {0x02E2, UNICODE_NORM_QC_NO}, + {0x02E3, UNICODE_NORM_QC_NO}, + {0x02E4, UNICODE_NORM_QC_NO}, + {0x0300, UNICODE_NORM_QC_MAYBE}, + {0x0301, UNICODE_NORM_QC_MAYBE}, + {0x0302, UNICODE_NORM_QC_MAYBE}, + {0x0303, UNICODE_NORM_QC_MAYBE}, + {0x0304, UNICODE_NORM_QC_MAYBE}, + {0x0306, UNICODE_NORM_QC_MAYBE}, + {0x0307, UNICODE_NORM_QC_MAYBE}, + {0x0308, UNICODE_NORM_QC_MAYBE}, + {0x0309, UNICODE_NORM_QC_MAYBE}, + {0x030A, UNICODE_NORM_QC_MAYBE}, + {0x030B, UNICODE_NORM_QC_MAYBE}, + {0x030C, UNICODE_NORM_QC_MAYBE}, + {0x030F, UNICODE_NORM_QC_MAYBE}, + {0x0311, UNICODE_NORM_QC_MAYBE}, + {0x0313, UNICODE_NORM_QC_MAYBE}, + {0x0314, UNICODE_NORM_QC_MAYBE}, + {0x031B, UNICODE_NORM_QC_MAYBE}, + {0x0323, UNICODE_NORM_QC_MAYBE}, + {0x0324, UNICODE_NORM_QC_MAYBE}, + {0x0325, UNICODE_NORM_QC_MAYBE}, + {0x0326, UNICODE_NORM_QC_MAYBE}, + {0x0327, UNICODE_NORM_QC_MAYBE}, + {0x0328, UNICODE_NORM_QC_MAYBE}, + {0x032D, UNICODE_NORM_QC_MAYBE}, + {0x032E, UNICODE_NORM_QC_MAYBE}, + {0x0330, UNICODE_NORM_QC_MAYBE}, + {0x0331, UNICODE_NORM_QC_MAYBE}, + {0x0338, UNICODE_NORM_QC_MAYBE}, + {0x0340, UNICODE_NORM_QC_NO}, + {0x0341, UNICODE_NORM_QC_NO}, + {0x0342, UNICODE_NORM_QC_MAYBE}, + {0x0343, UNICODE_NORM_QC_NO}, + {0x0344, UNICODE_NORM_QC_NO}, + {0x0345, UNICODE_NORM_QC_MAYBE}, + {0x0374, UNICODE_NORM_QC_NO}, + {0x037A, UNICODE_NORM_QC_NO}, + {0x037E, UNICODE_NORM_QC_NO}, + {0x0384, UNICODE_NORM_QC_NO}, + {0x0385, UNICODE_NORM_QC_NO}, + {0x0387, UNICODE_NORM_QC_NO}, + {0x03D0, UNICODE_NORM_QC_NO}, + {0x03D1, UNICODE_NORM_QC_NO}, + {0x03D2, UNICODE_NORM_QC_NO}, + {0x03D3, UNICODE_NORM_QC_NO}, + {0x03D4, UNICODE_NORM_QC_NO}, + {0x03D5, UNICODE_NORM_QC_NO}, + {0x03D6, UNICODE_NORM_QC_NO}, + {0x03F0, UNICODE_NORM_QC_NO}, + {0x03F1, UNICODE_NORM_QC_NO}, + {0x03F2, UNICODE_NORM_QC_NO}, + {0x03F4, UNICODE_NORM_QC_NO}, + {0x03F5, UNICODE_NORM_QC_NO}, + {0x03F9, UNICODE_NORM_QC_NO}, + {0x0587, UNICODE_NORM_QC_NO}, + {0x0653, UNICODE_NORM_QC_MAYBE}, + {0x0654, UNICODE_NORM_QC_MAYBE}, + {0x0655, UNICODE_NORM_QC_MAYBE}, + {0x0675, UNICODE_NORM_QC_NO}, + {0x0676, UNICODE_NORM_QC_NO}, + {0x0677, UNICODE_NORM_QC_NO}, + {0x0678, UNICODE_NORM_QC_NO}, + {0x093C, UNICODE_NORM_QC_MAYBE}, + {0x0958, UNICODE_NORM_QC_NO}, + {0x0959, UNICODE_NORM_QC_NO}, + {0x095A, UNICODE_NORM_QC_NO}, + {0x095B, UNICODE_NORM_QC_NO}, + {0x095C, UNICODE_NORM_QC_NO}, + {0x095D, UNICODE_NORM_QC_NO}, + {0x095E, UNICODE_NORM_QC_NO}, + {0x095F, UNICODE_NORM_QC_NO}, + {0x09BE, UNICODE_NORM_QC_MAYBE}, + {0x09D7, UNICODE_NORM_QC_MAYBE}, + {0x09DC, UNICODE_NORM_QC_NO}, + {0x09DD, UNICODE_NORM_QC_NO}, + {0x09DF, UNICODE_NORM_QC_NO}, + {0x0A33, UNICODE_NORM_QC_NO}, + {0x0A36, UNICODE_NORM_QC_NO}, + {0x0A59, UNICODE_NORM_QC_NO}, + {0x0A5A, UNICODE_NORM_QC_NO}, + {0x0A5B, UNICODE_NORM_QC_NO}, + {0x0A5E, UNICODE_NORM_QC_NO}, + {0x0B3E, UNICODE_NORM_QC_MAYBE}, + {0x0B56, UNICODE_NORM_QC_MAYBE}, + {0x0B57, UNICODE_NORM_QC_MAYBE}, + {0x0B5C, UNICODE_NORM_QC_NO}, + {0x0B5D, UNICODE_NORM_QC_NO}, + {0x0BBE, UNICODE_NORM_QC_MAYBE}, + {0x0BD7, UNICODE_NORM_QC_MAYBE}, + {0x0C56, UNICODE_NORM_QC_MAYBE}, + {0x0CC2, UNICODE_NORM_QC_MAYBE}, + {0x0CD5, UNICODE_NORM_QC_MAYBE}, + {0x0CD6, UNICODE_NORM_QC_MAYBE}, + {0x0D3E, UNICODE_NORM_QC_MAYBE}, + {0x0D57, UNICODE_NORM_QC_MAYBE}, + {0x0DCA, UNICODE_NORM_QC_MAYBE}, + {0x0DCF, UNICODE_NORM_QC_MAYBE}, + {0x0DDF, UNICODE_NORM_QC_MAYBE}, + {0x0E33, UNICODE_NORM_QC_NO}, + {0x0EB3, UNICODE_NORM_QC_NO}, + {0x0EDC, UNICODE_NORM_QC_NO}, + {0x0EDD, UNICODE_NORM_QC_NO}, + {0x0F0C, UNICODE_NORM_QC_NO}, + {0x0F43, UNICODE_NORM_QC_NO}, + {0x0F4D, UNICODE_NORM_QC_NO}, + {0x0F52, UNICODE_NORM_QC_NO}, + {0x0F57, UNICODE_NORM_QC_NO}, + {0x0F5C, UNICODE_NORM_QC_NO}, + {0x0F69, UNICODE_NORM_QC_NO}, + {0x0F73, UNICODE_NORM_QC_NO}, + {0x0F75, UNICODE_NORM_QC_NO}, + {0x0F76, UNICODE_NORM_QC_NO}, + {0x0F77, UNICODE_NORM_QC_NO}, + {0x0F78, UNICODE_NORM_QC_NO}, + {0x0F79, UNICODE_NORM_QC_NO}, + {0x0F81, UNICODE_NORM_QC_NO}, + {0x0F93, UNICODE_NORM_QC_NO}, + {0x0F9D, UNICODE_NORM_QC_NO}, + {0x0FA2, UNICODE_NORM_QC_NO}, + {0x0FA7, UNICODE_NORM_QC_NO}, + {0x0FAC, UNICODE_NORM_QC_NO}, + {0x0FB9, UNICODE_NORM_QC_NO}, + {0x102E, UNICODE_NORM_QC_MAYBE}, + {0x10FC, UNICODE_NORM_QC_NO}, + {0x1161, UNICODE_NORM_QC_MAYBE}, + {0x1162, UNICODE_NORM_QC_MAYBE}, + {0x1163, UNICODE_NORM_QC_MAYBE}, + {0x1164, UNICODE_NORM_QC_MAYBE}, + {0x1165, UNICODE_NORM_QC_MAYBE}, + {0x1166, UNICODE_NORM_QC_MAYBE}, + {0x1167, UNICODE_NORM_QC_MAYBE}, + {0x1168, UNICODE_NORM_QC_MAYBE}, + {0x1169, UNICODE_NORM_QC_MAYBE}, + {0x116A, UNICODE_NORM_QC_MAYBE}, + {0x116B, UNICODE_NORM_QC_MAYBE}, + {0x116C, UNICODE_NORM_QC_MAYBE}, + {0x116D, UNICODE_NORM_QC_MAYBE}, + {0x116E, UNICODE_NORM_QC_MAYBE}, + {0x116F, UNICODE_NORM_QC_MAYBE}, + {0x1170, UNICODE_NORM_QC_MAYBE}, + {0x1171, UNICODE_NORM_QC_MAYBE}, + {0x1172, UNICODE_NORM_QC_MAYBE}, + {0x1173, UNICODE_NORM_QC_MAYBE}, + {0x1174, UNICODE_NORM_QC_MAYBE}, + {0x1175, UNICODE_NORM_QC_MAYBE}, + {0x11A8, UNICODE_NORM_QC_MAYBE}, + {0x11A9, UNICODE_NORM_QC_MAYBE}, + {0x11AA, UNICODE_NORM_QC_MAYBE}, + {0x11AB, UNICODE_NORM_QC_MAYBE}, + {0x11AC, UNICODE_NORM_QC_MAYBE}, + {0x11AD, UNICODE_NORM_QC_MAYBE}, + {0x11AE, UNICODE_NORM_QC_MAYBE}, + {0x11AF, UNICODE_NORM_QC_MAYBE}, + {0x11B0, UNICODE_NORM_QC_MAYBE}, + {0x11B1, UNICODE_NORM_QC_MAYBE}, + {0x11B2, UNICODE_NORM_QC_MAYBE}, + {0x11B3, UNICODE_NORM_QC_MAYBE}, + {0x11B4, UNICODE_NORM_QC_MAYBE}, + {0x11B5, UNICODE_NORM_QC_MAYBE}, + {0x11B6, UNICODE_NORM_QC_MAYBE}, + {0x11B7, UNICODE_NORM_QC_MAYBE}, + {0x11B8, UNICODE_NORM_QC_MAYBE}, + {0x11B9, UNICODE_NORM_QC_MAYBE}, + {0x11BA, UNICODE_NORM_QC_MAYBE}, + {0x11BB, UNICODE_NORM_QC_MAYBE}, + {0x11BC, UNICODE_NORM_QC_MAYBE}, + {0x11BD, UNICODE_NORM_QC_MAYBE}, + {0x11BE, UNICODE_NORM_QC_MAYBE}, + {0x11BF, UNICODE_NORM_QC_MAYBE}, + {0x11C0, UNICODE_NORM_QC_MAYBE}, + {0x11C1, UNICODE_NORM_QC_MAYBE}, + {0x11C2, UNICODE_NORM_QC_MAYBE}, + {0x1B35, UNICODE_NORM_QC_MAYBE}, + {0x1D2C, UNICODE_NORM_QC_NO}, + {0x1D2D, UNICODE_NORM_QC_NO}, + {0x1D2E, UNICODE_NORM_QC_NO}, + {0x1D30, UNICODE_NORM_QC_NO}, + {0x1D31, UNICODE_NORM_QC_NO}, + {0x1D32, UNICODE_NORM_QC_NO}, + {0x1D33, UNICODE_NORM_QC_NO}, + {0x1D34, UNICODE_NORM_QC_NO}, + {0x1D35, UNICODE_NORM_QC_NO}, + {0x1D36, UNICODE_NORM_QC_NO}, + {0x1D37, UNICODE_NORM_QC_NO}, + {0x1D38, UNICODE_NORM_QC_NO}, + {0x1D39, UNICODE_NORM_QC_NO}, + {0x1D3A, UNICODE_NORM_QC_NO}, + {0x1D3C, UNICODE_NORM_QC_NO}, + {0x1D3D, UNICODE_NORM_QC_NO}, + {0x1D3E, UNICODE_NORM_QC_NO}, + {0x1D3F, UNICODE_NORM_QC_NO}, + {0x1D40, UNICODE_NORM_QC_NO}, + {0x1D41, UNICODE_NORM_QC_NO}, + {0x1D42, UNICODE_NORM_QC_NO}, + {0x1D43, UNICODE_NORM_QC_NO}, + {0x1D44, UNICODE_NORM_QC_NO}, + {0x1D45, UNICODE_NORM_QC_NO}, + {0x1D46, UNICODE_NORM_QC_NO}, + {0x1D47, UNICODE_NORM_QC_NO}, + {0x1D48, UNICODE_NORM_QC_NO}, + {0x1D49, UNICODE_NORM_QC_NO}, + {0x1D4A, UNICODE_NORM_QC_NO}, + {0x1D4B, UNICODE_NORM_QC_NO}, + {0x1D4C, UNICODE_NORM_QC_NO}, + {0x1D4D, UNICODE_NORM_QC_NO}, + {0x1D4F, UNICODE_NORM_QC_NO}, + {0x1D50, UNICODE_NORM_QC_NO}, + {0x1D51, UNICODE_NORM_QC_NO}, + {0x1D52, UNICODE_NORM_QC_NO}, + {0x1D53, UNICODE_NORM_QC_NO}, + {0x1D54, UNICODE_NORM_QC_NO}, + {0x1D55, UNICODE_NORM_QC_NO}, + {0x1D56, UNICODE_NORM_QC_NO}, + {0x1D57, UNICODE_NORM_QC_NO}, + {0x1D58, UNICODE_NORM_QC_NO}, + {0x1D59, UNICODE_NORM_QC_NO}, + {0x1D5A, UNICODE_NORM_QC_NO}, + {0x1D5B, UNICODE_NORM_QC_NO}, + {0x1D5C, UNICODE_NORM_QC_NO}, + {0x1D5D, UNICODE_NORM_QC_NO}, + {0x1D5E, UNICODE_NORM_QC_NO}, + {0x1D5F, UNICODE_NORM_QC_NO}, + {0x1D60, UNICODE_NORM_QC_NO}, + {0x1D61, UNICODE_NORM_QC_NO}, + {0x1D62, UNICODE_NORM_QC_NO}, + {0x1D63, UNICODE_NORM_QC_NO}, + {0x1D64, UNICODE_NORM_QC_NO}, + {0x1D65, UNICODE_NORM_QC_NO}, + {0x1D66, UNICODE_NORM_QC_NO}, + {0x1D67, UNICODE_NORM_QC_NO}, + {0x1D68, UNICODE_NORM_QC_NO}, + {0x1D69, UNICODE_NORM_QC_NO}, + {0x1D6A, UNICODE_NORM_QC_NO}, + {0x1D78, UNICODE_NORM_QC_NO}, + {0x1D9B, UNICODE_NORM_QC_NO}, + {0x1D9C, UNICODE_NORM_QC_NO}, + {0x1D9D, UNICODE_NORM_QC_NO}, + {0x1D9E, UNICODE_NORM_QC_NO}, + {0x1D9F, UNICODE_NORM_QC_NO}, + {0x1DA0, UNICODE_NORM_QC_NO}, + {0x1DA1, UNICODE_NORM_QC_NO}, + {0x1DA2, UNICODE_NORM_QC_NO}, + {0x1DA3, UNICODE_NORM_QC_NO}, + {0x1DA4, UNICODE_NORM_QC_NO}, + {0x1DA5, UNICODE_NORM_QC_NO}, + {0x1DA6, UNICODE_NORM_QC_NO}, + {0x1DA7, UNICODE_NORM_QC_NO}, + {0x1DA8, UNICODE_NORM_QC_NO}, + {0x1DA9, UNICODE_NORM_QC_NO}, + {0x1DAA, UNICODE_NORM_QC_NO}, + {0x1DAB, UNICODE_NORM_QC_NO}, + {0x1DAC, UNICODE_NORM_QC_NO}, + {0x1DAD, UNICODE_NORM_QC_NO}, + {0x1DAE, UNICODE_NORM_QC_NO}, + {0x1DAF, UNICODE_NORM_QC_NO}, + {0x1DB0, UNICODE_NORM_QC_NO}, + {0x1DB1, UNICODE_NORM_QC_NO}, + {0x1DB2, UNICODE_NORM_QC_NO}, + {0x1DB3, UNICODE_NORM_QC_NO}, + {0x1DB4, UNICODE_NORM_QC_NO}, + {0x1DB5, UNICODE_NORM_QC_NO}, + {0x1DB6, UNICODE_NORM_QC_NO}, + {0x1DB7, UNICODE_NORM_QC_NO}, + {0x1DB8, UNICODE_NORM_QC_NO}, + {0x1DB9, UNICODE_NORM_QC_NO}, + {0x1DBA, UNICODE_NORM_QC_NO}, + {0x1DBB, UNICODE_NORM_QC_NO}, + {0x1DBC, UNICODE_NORM_QC_NO}, + {0x1DBD, UNICODE_NORM_QC_NO}, + {0x1DBE, UNICODE_NORM_QC_NO}, + {0x1DBF, UNICODE_NORM_QC_NO}, + {0x1E9A, UNICODE_NORM_QC_NO}, + {0x1E9B, UNICODE_NORM_QC_NO}, + {0x1F71, UNICODE_NORM_QC_NO}, + {0x1F73, UNICODE_NORM_QC_NO}, + {0x1F75, UNICODE_NORM_QC_NO}, + {0x1F77, UNICODE_NORM_QC_NO}, + {0x1F79, UNICODE_NORM_QC_NO}, + {0x1F7B, UNICODE_NORM_QC_NO}, + {0x1F7D, UNICODE_NORM_QC_NO}, + {0x1FBB, UNICODE_NORM_QC_NO}, + {0x1FBD, UNICODE_NORM_QC_NO}, + {0x1FBE, UNICODE_NORM_QC_NO}, + {0x1FBF, UNICODE_NORM_QC_NO}, + {0x1FC0, UNICODE_NORM_QC_NO}, + {0x1FC1, UNICODE_NORM_QC_NO}, + {0x1FC9, UNICODE_NORM_QC_NO}, + {0x1FCB, UNICODE_NORM_QC_NO}, + {0x1FCD, UNICODE_NORM_QC_NO}, + {0x1FCE, UNICODE_NORM_QC_NO}, + {0x1FCF, UNICODE_NORM_QC_NO}, + {0x1FD3, UNICODE_NORM_QC_NO}, + {0x1FDB, UNICODE_NORM_QC_NO}, + {0x1FDD, UNICODE_NORM_QC_NO}, + {0x1FDE, UNICODE_NORM_QC_NO}, + {0x1FDF, UNICODE_NORM_QC_NO}, + {0x1FE3, UNICODE_NORM_QC_NO}, + {0x1FEB, UNICODE_NORM_QC_NO}, + {0x1FED, UNICODE_NORM_QC_NO}, + {0x1FEE, UNICODE_NORM_QC_NO}, + {0x1FEF, UNICODE_NORM_QC_NO}, + {0x1FF9, UNICODE_NORM_QC_NO}, + {0x1FFB, UNICODE_NORM_QC_NO}, + {0x1FFD, UNICODE_NORM_QC_NO}, + {0x1FFE, UNICODE_NORM_QC_NO}, + {0x2000, UNICODE_NORM_QC_NO}, + {0x2001, UNICODE_NORM_QC_NO}, + {0x2002, UNICODE_NORM_QC_NO}, + {0x2003, UNICODE_NORM_QC_NO}, + {0x2004, UNICODE_NORM_QC_NO}, + {0x2005, UNICODE_NORM_QC_NO}, + {0x2006, UNICODE_NORM_QC_NO}, + {0x2007, UNICODE_NORM_QC_NO}, + {0x2008, UNICODE_NORM_QC_NO}, + {0x2009, UNICODE_NORM_QC_NO}, + {0x200A, UNICODE_NORM_QC_NO}, + {0x2011, UNICODE_NORM_QC_NO}, + {0x2017, UNICODE_NORM_QC_NO}, + {0x2024, UNICODE_NORM_QC_NO}, + {0x2025, UNICODE_NORM_QC_NO}, + {0x2026, UNICODE_NORM_QC_NO}, + {0x202F, UNICODE_NORM_QC_NO}, + {0x2033, UNICODE_NORM_QC_NO}, + {0x2034, UNICODE_NORM_QC_NO}, + {0x2036, UNICODE_NORM_QC_NO}, + {0x2037, UNICODE_NORM_QC_NO}, + {0x203C, UNICODE_NORM_QC_NO}, + {0x203E, UNICODE_NORM_QC_NO}, + {0x2047, UNICODE_NORM_QC_NO}, + {0x2048, UNICODE_NORM_QC_NO}, + {0x2049, UNICODE_NORM_QC_NO}, + {0x2057, UNICODE_NORM_QC_NO}, + {0x205F, UNICODE_NORM_QC_NO}, + {0x2070, UNICODE_NORM_QC_NO}, + {0x2071, UNICODE_NORM_QC_NO}, + {0x2074, UNICODE_NORM_QC_NO}, + {0x2075, UNICODE_NORM_QC_NO}, + {0x2076, UNICODE_NORM_QC_NO}, + {0x2077, UNICODE_NORM_QC_NO}, + {0x2078, UNICODE_NORM_QC_NO}, + {0x2079, UNICODE_NORM_QC_NO}, + {0x207A, UNICODE_NORM_QC_NO}, + {0x207B, UNICODE_NORM_QC_NO}, + {0x207C, UNICODE_NORM_QC_NO}, + {0x207D, UNICODE_NORM_QC_NO}, + {0x207E, UNICODE_NORM_QC_NO}, + {0x207F, UNICODE_NORM_QC_NO}, + {0x2080, UNICODE_NORM_QC_NO}, + {0x2081, UNICODE_NORM_QC_NO}, + {0x2082, UNICODE_NORM_QC_NO}, + {0x2083, UNICODE_NORM_QC_NO}, + {0x2084, UNICODE_NORM_QC_NO}, + {0x2085, UNICODE_NORM_QC_NO}, + {0x2086, UNICODE_NORM_QC_NO}, + {0x2087, UNICODE_NORM_QC_NO}, + {0x2088, UNICODE_NORM_QC_NO}, + {0x2089, UNICODE_NORM_QC_NO}, + {0x208A, UNICODE_NORM_QC_NO}, + {0x208B, UNICODE_NORM_QC_NO}, + {0x208C, UNICODE_NORM_QC_NO}, + {0x208D, UNICODE_NORM_QC_NO}, + {0x208E, UNICODE_NORM_QC_NO}, + {0x2090, UNICODE_NORM_QC_NO}, + {0x2091, UNICODE_NORM_QC_NO}, + {0x2092, UNICODE_NORM_QC_NO}, + {0x2093, UNICODE_NORM_QC_NO}, + {0x2094, UNICODE_NORM_QC_NO}, + {0x2095, UNICODE_NORM_QC_NO}, + {0x2096, UNICODE_NORM_QC_NO}, + {0x2097, UNICODE_NORM_QC_NO}, + {0x2098, UNICODE_NORM_QC_NO}, + {0x2099, UNICODE_NORM_QC_NO}, + {0x209A, UNICODE_NORM_QC_NO}, + {0x209B, UNICODE_NORM_QC_NO}, + {0x209C, UNICODE_NORM_QC_NO}, + {0x20A8, UNICODE_NORM_QC_NO}, + {0x2100, UNICODE_NORM_QC_NO}, + {0x2101, UNICODE_NORM_QC_NO}, + {0x2102, UNICODE_NORM_QC_NO}, + {0x2103, UNICODE_NORM_QC_NO}, + {0x2105, UNICODE_NORM_QC_NO}, + {0x2106, UNICODE_NORM_QC_NO}, + {0x2107, UNICODE_NORM_QC_NO}, + {0x2109, UNICODE_NORM_QC_NO}, + {0x210A, UNICODE_NORM_QC_NO}, + {0x210B, UNICODE_NORM_QC_NO}, + {0x210C, UNICODE_NORM_QC_NO}, + {0x210D, UNICODE_NORM_QC_NO}, + {0x210E, UNICODE_NORM_QC_NO}, + {0x210F, UNICODE_NORM_QC_NO}, + {0x2110, UNICODE_NORM_QC_NO}, + {0x2111, UNICODE_NORM_QC_NO}, + {0x2112, UNICODE_NORM_QC_NO}, + {0x2113, UNICODE_NORM_QC_NO}, + {0x2115, UNICODE_NORM_QC_NO}, + {0x2116, UNICODE_NORM_QC_NO}, + {0x2119, UNICODE_NORM_QC_NO}, + {0x211A, UNICODE_NORM_QC_NO}, + {0x211B, UNICODE_NORM_QC_NO}, + {0x211C, UNICODE_NORM_QC_NO}, + {0x211D, UNICODE_NORM_QC_NO}, + {0x2120, UNICODE_NORM_QC_NO}, + {0x2121, UNICODE_NORM_QC_NO}, + {0x2122, UNICODE_NORM_QC_NO}, + {0x2124, UNICODE_NORM_QC_NO}, + {0x2126, UNICODE_NORM_QC_NO}, + {0x2128, UNICODE_NORM_QC_NO}, + {0x212A, UNICODE_NORM_QC_NO}, + {0x212B, UNICODE_NORM_QC_NO}, + {0x212C, UNICODE_NORM_QC_NO}, + {0x212D, UNICODE_NORM_QC_NO}, + {0x212F, UNICODE_NORM_QC_NO}, + {0x2130, UNICODE_NORM_QC_NO}, + {0x2131, UNICODE_NORM_QC_NO}, + {0x2133, UNICODE_NORM_QC_NO}, + {0x2134, UNICODE_NORM_QC_NO}, + {0x2135, UNICODE_NORM_QC_NO}, + {0x2136, UNICODE_NORM_QC_NO}, + {0x2137, UNICODE_NORM_QC_NO}, + {0x2138, UNICODE_NORM_QC_NO}, + {0x2139, UNICODE_NORM_QC_NO}, + {0x213B, UNICODE_NORM_QC_NO}, + {0x213C, UNICODE_NORM_QC_NO}, + {0x213D, UNICODE_NORM_QC_NO}, + {0x213E, UNICODE_NORM_QC_NO}, + {0x213F, UNICODE_NORM_QC_NO}, + {0x2140, UNICODE_NORM_QC_NO}, + {0x2145, UNICODE_NORM_QC_NO}, + {0x2146, UNICODE_NORM_QC_NO}, + {0x2147, UNICODE_NORM_QC_NO}, + {0x2148, UNICODE_NORM_QC_NO}, + {0x2149, UNICODE_NORM_QC_NO}, + {0x2150, UNICODE_NORM_QC_NO}, + {0x2151, UNICODE_NORM_QC_NO}, + {0x2152, UNICODE_NORM_QC_NO}, + {0x2153, UNICODE_NORM_QC_NO}, + {0x2154, UNICODE_NORM_QC_NO}, + {0x2155, UNICODE_NORM_QC_NO}, + {0x2156, UNICODE_NORM_QC_NO}, + {0x2157, UNICODE_NORM_QC_NO}, + {0x2158, UNICODE_NORM_QC_NO}, + {0x2159, UNICODE_NORM_QC_NO}, + {0x215A, UNICODE_NORM_QC_NO}, + {0x215B, UNICODE_NORM_QC_NO}, + {0x215C, UNICODE_NORM_QC_NO}, + {0x215D, UNICODE_NORM_QC_NO}, + {0x215E, UNICODE_NORM_QC_NO}, + {0x215F, UNICODE_NORM_QC_NO}, + {0x2160, UNICODE_NORM_QC_NO}, + {0x2161, UNICODE_NORM_QC_NO}, + {0x2162, UNICODE_NORM_QC_NO}, + {0x2163, UNICODE_NORM_QC_NO}, + {0x2164, UNICODE_NORM_QC_NO}, + {0x2165, UNICODE_NORM_QC_NO}, + {0x2166, UNICODE_NORM_QC_NO}, + {0x2167, UNICODE_NORM_QC_NO}, + {0x2168, UNICODE_NORM_QC_NO}, + {0x2169, UNICODE_NORM_QC_NO}, + {0x216A, UNICODE_NORM_QC_NO}, + {0x216B, UNICODE_NORM_QC_NO}, + {0x216C, UNICODE_NORM_QC_NO}, + {0x216D, UNICODE_NORM_QC_NO}, + {0x216E, UNICODE_NORM_QC_NO}, + {0x216F, UNICODE_NORM_QC_NO}, + {0x2170, UNICODE_NORM_QC_NO}, + {0x2171, UNICODE_NORM_QC_NO}, + {0x2172, UNICODE_NORM_QC_NO}, + {0x2173, UNICODE_NORM_QC_NO}, + {0x2174, UNICODE_NORM_QC_NO}, + {0x2175, UNICODE_NORM_QC_NO}, + {0x2176, UNICODE_NORM_QC_NO}, + {0x2177, UNICODE_NORM_QC_NO}, + {0x2178, UNICODE_NORM_QC_NO}, + {0x2179, UNICODE_NORM_QC_NO}, + {0x217A, UNICODE_NORM_QC_NO}, + {0x217B, UNICODE_NORM_QC_NO}, + {0x217C, UNICODE_NORM_QC_NO}, + {0x217D, UNICODE_NORM_QC_NO}, + {0x217E, UNICODE_NORM_QC_NO}, + {0x217F, UNICODE_NORM_QC_NO}, + {0x2189, UNICODE_NORM_QC_NO}, + {0x222C, UNICODE_NORM_QC_NO}, + {0x222D, UNICODE_NORM_QC_NO}, + {0x222F, UNICODE_NORM_QC_NO}, + {0x2230, UNICODE_NORM_QC_NO}, + {0x2329, UNICODE_NORM_QC_NO}, + {0x232A, UNICODE_NORM_QC_NO}, + {0x2460, UNICODE_NORM_QC_NO}, + {0x2461, UNICODE_NORM_QC_NO}, + {0x2462, UNICODE_NORM_QC_NO}, + {0x2463, UNICODE_NORM_QC_NO}, + {0x2464, UNICODE_NORM_QC_NO}, + {0x2465, UNICODE_NORM_QC_NO}, + {0x2466, UNICODE_NORM_QC_NO}, + {0x2467, UNICODE_NORM_QC_NO}, + {0x2468, UNICODE_NORM_QC_NO}, + {0x2469, UNICODE_NORM_QC_NO}, + {0x246A, UNICODE_NORM_QC_NO}, + {0x246B, UNICODE_NORM_QC_NO}, + {0x246C, UNICODE_NORM_QC_NO}, + {0x246D, UNICODE_NORM_QC_NO}, + {0x246E, UNICODE_NORM_QC_NO}, + {0x246F, UNICODE_NORM_QC_NO}, + {0x2470, UNICODE_NORM_QC_NO}, + {0x2471, UNICODE_NORM_QC_NO}, + {0x2472, UNICODE_NORM_QC_NO}, + {0x2473, UNICODE_NORM_QC_NO}, + {0x2474, UNICODE_NORM_QC_NO}, + {0x2475, UNICODE_NORM_QC_NO}, + {0x2476, UNICODE_NORM_QC_NO}, + {0x2477, UNICODE_NORM_QC_NO}, + {0x2478, UNICODE_NORM_QC_NO}, + {0x2479, UNICODE_NORM_QC_NO}, + {0x247A, UNICODE_NORM_QC_NO}, + {0x247B, UNICODE_NORM_QC_NO}, + {0x247C, UNICODE_NORM_QC_NO}, + {0x247D, UNICODE_NORM_QC_NO}, + {0x247E, UNICODE_NORM_QC_NO}, + {0x247F, UNICODE_NORM_QC_NO}, + {0x2480, UNICODE_NORM_QC_NO}, + {0x2481, UNICODE_NORM_QC_NO}, + {0x2482, UNICODE_NORM_QC_NO}, + {0x2483, UNICODE_NORM_QC_NO}, + {0x2484, UNICODE_NORM_QC_NO}, + {0x2485, UNICODE_NORM_QC_NO}, + {0x2486, UNICODE_NORM_QC_NO}, + {0x2487, UNICODE_NORM_QC_NO}, + {0x2488, UNICODE_NORM_QC_NO}, + {0x2489, UNICODE_NORM_QC_NO}, + {0x248A, UNICODE_NORM_QC_NO}, + {0x248B, UNICODE_NORM_QC_NO}, + {0x248C, UNICODE_NORM_QC_NO}, + {0x248D, UNICODE_NORM_QC_NO}, + {0x248E, UNICODE_NORM_QC_NO}, + {0x248F, UNICODE_NORM_QC_NO}, + {0x2490, UNICODE_NORM_QC_NO}, + {0x2491, UNICODE_NORM_QC_NO}, + {0x2492, UNICODE_NORM_QC_NO}, + {0x2493, UNICODE_NORM_QC_NO}, + {0x2494, UNICODE_NORM_QC_NO}, + {0x2495, UNICODE_NORM_QC_NO}, + {0x2496, UNICODE_NORM_QC_NO}, + {0x2497, UNICODE_NORM_QC_NO}, + {0x2498, UNICODE_NORM_QC_NO}, + {0x2499, UNICODE_NORM_QC_NO}, + {0x249A, UNICODE_NORM_QC_NO}, + {0x249B, UNICODE_NORM_QC_NO}, + {0x249C, UNICODE_NORM_QC_NO}, + {0x249D, UNICODE_NORM_QC_NO}, + {0x249E, UNICODE_NORM_QC_NO}, + {0x249F, UNICODE_NORM_QC_NO}, + {0x24A0, UNICODE_NORM_QC_NO}, + {0x24A1, UNICODE_NORM_QC_NO}, + {0x24A2, UNICODE_NORM_QC_NO}, + {0x24A3, UNICODE_NORM_QC_NO}, + {0x24A4, UNICODE_NORM_QC_NO}, + {0x24A5, UNICODE_NORM_QC_NO}, + {0x24A6, UNICODE_NORM_QC_NO}, + {0x24A7, UNICODE_NORM_QC_NO}, + {0x24A8, UNICODE_NORM_QC_NO}, + {0x24A9, UNICODE_NORM_QC_NO}, + {0x24AA, UNICODE_NORM_QC_NO}, + {0x24AB, UNICODE_NORM_QC_NO}, + {0x24AC, UNICODE_NORM_QC_NO}, + {0x24AD, UNICODE_NORM_QC_NO}, + {0x24AE, UNICODE_NORM_QC_NO}, + {0x24AF, UNICODE_NORM_QC_NO}, + {0x24B0, UNICODE_NORM_QC_NO}, + {0x24B1, UNICODE_NORM_QC_NO}, + {0x24B2, UNICODE_NORM_QC_NO}, + {0x24B3, UNICODE_NORM_QC_NO}, + {0x24B4, UNICODE_NORM_QC_NO}, + {0x24B5, UNICODE_NORM_QC_NO}, + {0x24B6, UNICODE_NORM_QC_NO}, + {0x24B7, UNICODE_NORM_QC_NO}, + {0x24B8, UNICODE_NORM_QC_NO}, + {0x24B9, UNICODE_NORM_QC_NO}, + {0x24BA, UNICODE_NORM_QC_NO}, + {0x24BB, UNICODE_NORM_QC_NO}, + {0x24BC, UNICODE_NORM_QC_NO}, + {0x24BD, UNICODE_NORM_QC_NO}, + {0x24BE, UNICODE_NORM_QC_NO}, + {0x24BF, UNICODE_NORM_QC_NO}, + {0x24C0, UNICODE_NORM_QC_NO}, + {0x24C1, UNICODE_NORM_QC_NO}, + {0x24C2, UNICODE_NORM_QC_NO}, + {0x24C3, UNICODE_NORM_QC_NO}, + {0x24C4, UNICODE_NORM_QC_NO}, + {0x24C5, UNICODE_NORM_QC_NO}, + {0x24C6, UNICODE_NORM_QC_NO}, + {0x24C7, UNICODE_NORM_QC_NO}, + {0x24C8, UNICODE_NORM_QC_NO}, + {0x24C9, UNICODE_NORM_QC_NO}, + {0x24CA, UNICODE_NORM_QC_NO}, + {0x24CB, UNICODE_NORM_QC_NO}, + {0x24CC, UNICODE_NORM_QC_NO}, + {0x24CD, UNICODE_NORM_QC_NO}, + {0x24CE, UNICODE_NORM_QC_NO}, + {0x24CF, UNICODE_NORM_QC_NO}, + {0x24D0, UNICODE_NORM_QC_NO}, + {0x24D1, UNICODE_NORM_QC_NO}, + {0x24D2, UNICODE_NORM_QC_NO}, + {0x24D3, UNICODE_NORM_QC_NO}, + {0x24D4, UNICODE_NORM_QC_NO}, + {0x24D5, UNICODE_NORM_QC_NO}, + {0x24D6, UNICODE_NORM_QC_NO}, + {0x24D7, UNICODE_NORM_QC_NO}, + {0x24D8, UNICODE_NORM_QC_NO}, + {0x24D9, UNICODE_NORM_QC_NO}, + {0x24DA, UNICODE_NORM_QC_NO}, + {0x24DB, UNICODE_NORM_QC_NO}, + {0x24DC, UNICODE_NORM_QC_NO}, + {0x24DD, UNICODE_NORM_QC_NO}, + {0x24DE, UNICODE_NORM_QC_NO}, + {0x24DF, UNICODE_NORM_QC_NO}, + {0x24E0, UNICODE_NORM_QC_NO}, + {0x24E1, UNICODE_NORM_QC_NO}, + {0x24E2, UNICODE_NORM_QC_NO}, + {0x24E3, UNICODE_NORM_QC_NO}, + {0x24E4, UNICODE_NORM_QC_NO}, + {0x24E5, UNICODE_NORM_QC_NO}, + {0x24E6, UNICODE_NORM_QC_NO}, + {0x24E7, UNICODE_NORM_QC_NO}, + {0x24E8, UNICODE_NORM_QC_NO}, + {0x24E9, UNICODE_NORM_QC_NO}, + {0x24EA, UNICODE_NORM_QC_NO}, + {0x2A0C, UNICODE_NORM_QC_NO}, + {0x2A74, UNICODE_NORM_QC_NO}, + {0x2A75, UNICODE_NORM_QC_NO}, + {0x2A76, UNICODE_NORM_QC_NO}, + {0x2ADC, UNICODE_NORM_QC_NO}, + {0x2C7C, UNICODE_NORM_QC_NO}, + {0x2C7D, UNICODE_NORM_QC_NO}, + {0x2D6F, UNICODE_NORM_QC_NO}, + {0x2E9F, UNICODE_NORM_QC_NO}, + {0x2EF3, UNICODE_NORM_QC_NO}, + {0x2F00, UNICODE_NORM_QC_NO}, + {0x2F01, UNICODE_NORM_QC_NO}, + {0x2F02, UNICODE_NORM_QC_NO}, + {0x2F03, UNICODE_NORM_QC_NO}, + {0x2F04, UNICODE_NORM_QC_NO}, + {0x2F05, UNICODE_NORM_QC_NO}, + {0x2F06, UNICODE_NORM_QC_NO}, + {0x2F07, UNICODE_NORM_QC_NO}, + {0x2F08, UNICODE_NORM_QC_NO}, + {0x2F09, UNICODE_NORM_QC_NO}, + {0x2F0A, UNICODE_NORM_QC_NO}, + {0x2F0B, UNICODE_NORM_QC_NO}, + {0x2F0C, UNICODE_NORM_QC_NO}, + {0x2F0D, UNICODE_NORM_QC_NO}, + {0x2F0E, UNICODE_NORM_QC_NO}, + {0x2F0F, UNICODE_NORM_QC_NO}, + {0x2F10, UNICODE_NORM_QC_NO}, + {0x2F11, UNICODE_NORM_QC_NO}, + {0x2F12, UNICODE_NORM_QC_NO}, + {0x2F13, UNICODE_NORM_QC_NO}, + {0x2F14, UNICODE_NORM_QC_NO}, + {0x2F15, UNICODE_NORM_QC_NO}, + {0x2F16, UNICODE_NORM_QC_NO}, + {0x2F17, UNICODE_NORM_QC_NO}, + {0x2F18, UNICODE_NORM_QC_NO}, + {0x2F19, UNICODE_NORM_QC_NO}, + {0x2F1A, UNICODE_NORM_QC_NO}, + {0x2F1B, UNICODE_NORM_QC_NO}, + {0x2F1C, UNICODE_NORM_QC_NO}, + {0x2F1D, UNICODE_NORM_QC_NO}, + {0x2F1E, UNICODE_NORM_QC_NO}, + {0x2F1F, UNICODE_NORM_QC_NO}, + {0x2F20, UNICODE_NORM_QC_NO}, + {0x2F21, UNICODE_NORM_QC_NO}, + {0x2F22, UNICODE_NORM_QC_NO}, + {0x2F23, UNICODE_NORM_QC_NO}, + {0x2F24, UNICODE_NORM_QC_NO}, + {0x2F25, UNICODE_NORM_QC_NO}, + {0x2F26, UNICODE_NORM_QC_NO}, + {0x2F27, UNICODE_NORM_QC_NO}, + {0x2F28, UNICODE_NORM_QC_NO}, + {0x2F29, UNICODE_NORM_QC_NO}, + {0x2F2A, UNICODE_NORM_QC_NO}, + {0x2F2B, UNICODE_NORM_QC_NO}, + {0x2F2C, UNICODE_NORM_QC_NO}, + {0x2F2D, UNICODE_NORM_QC_NO}, + {0x2F2E, UNICODE_NORM_QC_NO}, + {0x2F2F, UNICODE_NORM_QC_NO}, + {0x2F30, UNICODE_NORM_QC_NO}, + {0x2F31, UNICODE_NORM_QC_NO}, + {0x2F32, UNICODE_NORM_QC_NO}, + {0x2F33, UNICODE_NORM_QC_NO}, + {0x2F34, UNICODE_NORM_QC_NO}, + {0x2F35, UNICODE_NORM_QC_NO}, + {0x2F36, UNICODE_NORM_QC_NO}, + {0x2F37, UNICODE_NORM_QC_NO}, + {0x2F38, UNICODE_NORM_QC_NO}, + {0x2F39, UNICODE_NORM_QC_NO}, + {0x2F3A, UNICODE_NORM_QC_NO}, + {0x2F3B, UNICODE_NORM_QC_NO}, + {0x2F3C, UNICODE_NORM_QC_NO}, + {0x2F3D, UNICODE_NORM_QC_NO}, + {0x2F3E, UNICODE_NORM_QC_NO}, + {0x2F3F, UNICODE_NORM_QC_NO}, + {0x2F40, UNICODE_NORM_QC_NO}, + {0x2F41, UNICODE_NORM_QC_NO}, + {0x2F42, UNICODE_NORM_QC_NO}, + {0x2F43, UNICODE_NORM_QC_NO}, + {0x2F44, UNICODE_NORM_QC_NO}, + {0x2F45, UNICODE_NORM_QC_NO}, + {0x2F46, UNICODE_NORM_QC_NO}, + {0x2F47, UNICODE_NORM_QC_NO}, + {0x2F48, UNICODE_NORM_QC_NO}, + {0x2F49, UNICODE_NORM_QC_NO}, + {0x2F4A, UNICODE_NORM_QC_NO}, + {0x2F4B, UNICODE_NORM_QC_NO}, + {0x2F4C, UNICODE_NORM_QC_NO}, + {0x2F4D, UNICODE_NORM_QC_NO}, + {0x2F4E, UNICODE_NORM_QC_NO}, + {0x2F4F, UNICODE_NORM_QC_NO}, + {0x2F50, UNICODE_NORM_QC_NO}, + {0x2F51, UNICODE_NORM_QC_NO}, + {0x2F52, UNICODE_NORM_QC_NO}, + {0x2F53, UNICODE_NORM_QC_NO}, + {0x2F54, UNICODE_NORM_QC_NO}, + {0x2F55, UNICODE_NORM_QC_NO}, + {0x2F56, UNICODE_NORM_QC_NO}, + {0x2F57, UNICODE_NORM_QC_NO}, + {0x2F58, UNICODE_NORM_QC_NO}, + {0x2F59, UNICODE_NORM_QC_NO}, + {0x2F5A, UNICODE_NORM_QC_NO}, + {0x2F5B, UNICODE_NORM_QC_NO}, + {0x2F5C, UNICODE_NORM_QC_NO}, + {0x2F5D, UNICODE_NORM_QC_NO}, + {0x2F5E, UNICODE_NORM_QC_NO}, + {0x2F5F, UNICODE_NORM_QC_NO}, + {0x2F60, UNICODE_NORM_QC_NO}, + {0x2F61, UNICODE_NORM_QC_NO}, + {0x2F62, UNICODE_NORM_QC_NO}, + {0x2F63, UNICODE_NORM_QC_NO}, + {0x2F64, UNICODE_NORM_QC_NO}, + {0x2F65, UNICODE_NORM_QC_NO}, + {0x2F66, UNICODE_NORM_QC_NO}, + {0x2F67, UNICODE_NORM_QC_NO}, + {0x2F68, UNICODE_NORM_QC_NO}, + {0x2F69, UNICODE_NORM_QC_NO}, + {0x2F6A, UNICODE_NORM_QC_NO}, + {0x2F6B, UNICODE_NORM_QC_NO}, + {0x2F6C, UNICODE_NORM_QC_NO}, + {0x2F6D, UNICODE_NORM_QC_NO}, + {0x2F6E, UNICODE_NORM_QC_NO}, + {0x2F6F, UNICODE_NORM_QC_NO}, + {0x2F70, UNICODE_NORM_QC_NO}, + {0x2F71, UNICODE_NORM_QC_NO}, + {0x2F72, UNICODE_NORM_QC_NO}, + {0x2F73, UNICODE_NORM_QC_NO}, + {0x2F74, UNICODE_NORM_QC_NO}, + {0x2F75, UNICODE_NORM_QC_NO}, + {0x2F76, UNICODE_NORM_QC_NO}, + {0x2F77, UNICODE_NORM_QC_NO}, + {0x2F78, UNICODE_NORM_QC_NO}, + {0x2F79, UNICODE_NORM_QC_NO}, + {0x2F7A, UNICODE_NORM_QC_NO}, + {0x2F7B, UNICODE_NORM_QC_NO}, + {0x2F7C, UNICODE_NORM_QC_NO}, + {0x2F7D, UNICODE_NORM_QC_NO}, + {0x2F7E, UNICODE_NORM_QC_NO}, + {0x2F7F, UNICODE_NORM_QC_NO}, + {0x2F80, UNICODE_NORM_QC_NO}, + {0x2F81, UNICODE_NORM_QC_NO}, + {0x2F82, UNICODE_NORM_QC_NO}, + {0x2F83, UNICODE_NORM_QC_NO}, + {0x2F84, UNICODE_NORM_QC_NO}, + {0x2F85, UNICODE_NORM_QC_NO}, + {0x2F86, UNICODE_NORM_QC_NO}, + {0x2F87, UNICODE_NORM_QC_NO}, + {0x2F88, UNICODE_NORM_QC_NO}, + {0x2F89, UNICODE_NORM_QC_NO}, + {0x2F8A, UNICODE_NORM_QC_NO}, + {0x2F8B, UNICODE_NORM_QC_NO}, + {0x2F8C, UNICODE_NORM_QC_NO}, + {0x2F8D, UNICODE_NORM_QC_NO}, + {0x2F8E, UNICODE_NORM_QC_NO}, + {0x2F8F, UNICODE_NORM_QC_NO}, + {0x2F90, UNICODE_NORM_QC_NO}, + {0x2F91, UNICODE_NORM_QC_NO}, + {0x2F92, UNICODE_NORM_QC_NO}, + {0x2F93, UNICODE_NORM_QC_NO}, + {0x2F94, UNICODE_NORM_QC_NO}, + {0x2F95, UNICODE_NORM_QC_NO}, + {0x2F96, UNICODE_NORM_QC_NO}, + {0x2F97, UNICODE_NORM_QC_NO}, + {0x2F98, UNICODE_NORM_QC_NO}, + {0x2F99, UNICODE_NORM_QC_NO}, + {0x2F9A, UNICODE_NORM_QC_NO}, + {0x2F9B, UNICODE_NORM_QC_NO}, + {0x2F9C, UNICODE_NORM_QC_NO}, + {0x2F9D, UNICODE_NORM_QC_NO}, + {0x2F9E, UNICODE_NORM_QC_NO}, + {0x2F9F, UNICODE_NORM_QC_NO}, + {0x2FA0, UNICODE_NORM_QC_NO}, + {0x2FA1, UNICODE_NORM_QC_NO}, + {0x2FA2, UNICODE_NORM_QC_NO}, + {0x2FA3, UNICODE_NORM_QC_NO}, + {0x2FA4, UNICODE_NORM_QC_NO}, + {0x2FA5, UNICODE_NORM_QC_NO}, + {0x2FA6, UNICODE_NORM_QC_NO}, + {0x2FA7, UNICODE_NORM_QC_NO}, + {0x2FA8, UNICODE_NORM_QC_NO}, + {0x2FA9, UNICODE_NORM_QC_NO}, + {0x2FAA, UNICODE_NORM_QC_NO}, + {0x2FAB, UNICODE_NORM_QC_NO}, + {0x2FAC, UNICODE_NORM_QC_NO}, + {0x2FAD, UNICODE_NORM_QC_NO}, + {0x2FAE, UNICODE_NORM_QC_NO}, + {0x2FAF, UNICODE_NORM_QC_NO}, + {0x2FB0, UNICODE_NORM_QC_NO}, + {0x2FB1, UNICODE_NORM_QC_NO}, + {0x2FB2, UNICODE_NORM_QC_NO}, + {0x2FB3, UNICODE_NORM_QC_NO}, + {0x2FB4, UNICODE_NORM_QC_NO}, + {0x2FB5, UNICODE_NORM_QC_NO}, + {0x2FB6, UNICODE_NORM_QC_NO}, + {0x2FB7, UNICODE_NORM_QC_NO}, + {0x2FB8, UNICODE_NORM_QC_NO}, + {0x2FB9, UNICODE_NORM_QC_NO}, + {0x2FBA, UNICODE_NORM_QC_NO}, + {0x2FBB, UNICODE_NORM_QC_NO}, + {0x2FBC, UNICODE_NORM_QC_NO}, + {0x2FBD, UNICODE_NORM_QC_NO}, + {0x2FBE, UNICODE_NORM_QC_NO}, + {0x2FBF, UNICODE_NORM_QC_NO}, + {0x2FC0, UNICODE_NORM_QC_NO}, + {0x2FC1, UNICODE_NORM_QC_NO}, + {0x2FC2, UNICODE_NORM_QC_NO}, + {0x2FC3, UNICODE_NORM_QC_NO}, + {0x2FC4, UNICODE_NORM_QC_NO}, + {0x2FC5, UNICODE_NORM_QC_NO}, + {0x2FC6, UNICODE_NORM_QC_NO}, + {0x2FC7, UNICODE_NORM_QC_NO}, + {0x2FC8, UNICODE_NORM_QC_NO}, + {0x2FC9, UNICODE_NORM_QC_NO}, + {0x2FCA, UNICODE_NORM_QC_NO}, + {0x2FCB, UNICODE_NORM_QC_NO}, + {0x2FCC, UNICODE_NORM_QC_NO}, + {0x2FCD, UNICODE_NORM_QC_NO}, + {0x2FCE, UNICODE_NORM_QC_NO}, + {0x2FCF, UNICODE_NORM_QC_NO}, + {0x2FD0, UNICODE_NORM_QC_NO}, + {0x2FD1, UNICODE_NORM_QC_NO}, + {0x2FD2, UNICODE_NORM_QC_NO}, + {0x2FD3, UNICODE_NORM_QC_NO}, + {0x2FD4, UNICODE_NORM_QC_NO}, + {0x2FD5, UNICODE_NORM_QC_NO}, + {0x3000, UNICODE_NORM_QC_NO}, + {0x3036, UNICODE_NORM_QC_NO}, + {0x3038, UNICODE_NORM_QC_NO}, + {0x3039, UNICODE_NORM_QC_NO}, + {0x303A, UNICODE_NORM_QC_NO}, + {0x3099, UNICODE_NORM_QC_MAYBE}, + {0x309A, UNICODE_NORM_QC_MAYBE}, + {0x309B, UNICODE_NORM_QC_NO}, + {0x309C, UNICODE_NORM_QC_NO}, + {0x309F, UNICODE_NORM_QC_NO}, + {0x30FF, UNICODE_NORM_QC_NO}, + {0x3131, UNICODE_NORM_QC_NO}, + {0x3132, UNICODE_NORM_QC_NO}, + {0x3133, UNICODE_NORM_QC_NO}, + {0x3134, UNICODE_NORM_QC_NO}, + {0x3135, UNICODE_NORM_QC_NO}, + {0x3136, UNICODE_NORM_QC_NO}, + {0x3137, UNICODE_NORM_QC_NO}, + {0x3138, UNICODE_NORM_QC_NO}, + {0x3139, UNICODE_NORM_QC_NO}, + {0x313A, UNICODE_NORM_QC_NO}, + {0x313B, UNICODE_NORM_QC_NO}, + {0x313C, UNICODE_NORM_QC_NO}, + {0x313D, UNICODE_NORM_QC_NO}, + {0x313E, UNICODE_NORM_QC_NO}, + {0x313F, UNICODE_NORM_QC_NO}, + {0x3140, UNICODE_NORM_QC_NO}, + {0x3141, UNICODE_NORM_QC_NO}, + {0x3142, UNICODE_NORM_QC_NO}, + {0x3143, UNICODE_NORM_QC_NO}, + {0x3144, UNICODE_NORM_QC_NO}, + {0x3145, UNICODE_NORM_QC_NO}, + {0x3146, UNICODE_NORM_QC_NO}, + {0x3147, UNICODE_NORM_QC_NO}, + {0x3148, UNICODE_NORM_QC_NO}, + {0x3149, UNICODE_NORM_QC_NO}, + {0x314A, UNICODE_NORM_QC_NO}, + {0x314B, UNICODE_NORM_QC_NO}, + {0x314C, UNICODE_NORM_QC_NO}, + {0x314D, UNICODE_NORM_QC_NO}, + {0x314E, UNICODE_NORM_QC_NO}, + {0x314F, UNICODE_NORM_QC_NO}, + {0x3150, UNICODE_NORM_QC_NO}, + {0x3151, UNICODE_NORM_QC_NO}, + {0x3152, UNICODE_NORM_QC_NO}, + {0x3153, UNICODE_NORM_QC_NO}, + {0x3154, UNICODE_NORM_QC_NO}, + {0x3155, UNICODE_NORM_QC_NO}, + {0x3156, UNICODE_NORM_QC_NO}, + {0x3157, UNICODE_NORM_QC_NO}, + {0x3158, UNICODE_NORM_QC_NO}, + {0x3159, UNICODE_NORM_QC_NO}, + {0x315A, UNICODE_NORM_QC_NO}, + {0x315B, UNICODE_NORM_QC_NO}, + {0x315C, UNICODE_NORM_QC_NO}, + {0x315D, UNICODE_NORM_QC_NO}, + {0x315E, UNICODE_NORM_QC_NO}, + {0x315F, UNICODE_NORM_QC_NO}, + {0x3160, UNICODE_NORM_QC_NO}, + {0x3161, UNICODE_NORM_QC_NO}, + {0x3162, UNICODE_NORM_QC_NO}, + {0x3163, UNICODE_NORM_QC_NO}, + {0x3164, UNICODE_NORM_QC_NO}, + {0x3165, UNICODE_NORM_QC_NO}, + {0x3166, UNICODE_NORM_QC_NO}, + {0x3167, UNICODE_NORM_QC_NO}, + {0x3168, UNICODE_NORM_QC_NO}, + {0x3169, UNICODE_NORM_QC_NO}, + {0x316A, UNICODE_NORM_QC_NO}, + {0x316B, UNICODE_NORM_QC_NO}, + {0x316C, UNICODE_NORM_QC_NO}, + {0x316D, UNICODE_NORM_QC_NO}, + {0x316E, UNICODE_NORM_QC_NO}, + {0x316F, UNICODE_NORM_QC_NO}, + {0x3170, UNICODE_NORM_QC_NO}, + {0x3171, UNICODE_NORM_QC_NO}, + {0x3172, UNICODE_NORM_QC_NO}, + {0x3173, UNICODE_NORM_QC_NO}, + {0x3174, UNICODE_NORM_QC_NO}, + {0x3175, UNICODE_NORM_QC_NO}, + {0x3176, UNICODE_NORM_QC_NO}, + {0x3177, UNICODE_NORM_QC_NO}, + {0x3178, UNICODE_NORM_QC_NO}, + {0x3179, UNICODE_NORM_QC_NO}, + {0x317A, UNICODE_NORM_QC_NO}, + {0x317B, UNICODE_NORM_QC_NO}, + {0x317C, UNICODE_NORM_QC_NO}, + {0x317D, UNICODE_NORM_QC_NO}, + {0x317E, UNICODE_NORM_QC_NO}, + {0x317F, UNICODE_NORM_QC_NO}, + {0x3180, UNICODE_NORM_QC_NO}, + {0x3181, UNICODE_NORM_QC_NO}, + {0x3182, UNICODE_NORM_QC_NO}, + {0x3183, UNICODE_NORM_QC_NO}, + {0x3184, UNICODE_NORM_QC_NO}, + {0x3185, UNICODE_NORM_QC_NO}, + {0x3186, UNICODE_NORM_QC_NO}, + {0x3187, UNICODE_NORM_QC_NO}, + {0x3188, UNICODE_NORM_QC_NO}, + {0x3189, UNICODE_NORM_QC_NO}, + {0x318A, UNICODE_NORM_QC_NO}, + {0x318B, UNICODE_NORM_QC_NO}, + {0x318C, UNICODE_NORM_QC_NO}, + {0x318D, UNICODE_NORM_QC_NO}, + {0x318E, UNICODE_NORM_QC_NO}, + {0x3192, UNICODE_NORM_QC_NO}, + {0x3193, UNICODE_NORM_QC_NO}, + {0x3194, UNICODE_NORM_QC_NO}, + {0x3195, UNICODE_NORM_QC_NO}, + {0x3196, UNICODE_NORM_QC_NO}, + {0x3197, UNICODE_NORM_QC_NO}, + {0x3198, UNICODE_NORM_QC_NO}, + {0x3199, UNICODE_NORM_QC_NO}, + {0x319A, UNICODE_NORM_QC_NO}, + {0x319B, UNICODE_NORM_QC_NO}, + {0x319C, UNICODE_NORM_QC_NO}, + {0x319D, UNICODE_NORM_QC_NO}, + {0x319E, UNICODE_NORM_QC_NO}, + {0x319F, UNICODE_NORM_QC_NO}, + {0x3200, UNICODE_NORM_QC_NO}, + {0x3201, UNICODE_NORM_QC_NO}, + {0x3202, UNICODE_NORM_QC_NO}, + {0x3203, UNICODE_NORM_QC_NO}, + {0x3204, UNICODE_NORM_QC_NO}, + {0x3205, UNICODE_NORM_QC_NO}, + {0x3206, UNICODE_NORM_QC_NO}, + {0x3207, UNICODE_NORM_QC_NO}, + {0x3208, UNICODE_NORM_QC_NO}, + {0x3209, UNICODE_NORM_QC_NO}, + {0x320A, UNICODE_NORM_QC_NO}, + {0x320B, UNICODE_NORM_QC_NO}, + {0x320C, UNICODE_NORM_QC_NO}, + {0x320D, UNICODE_NORM_QC_NO}, + {0x320E, UNICODE_NORM_QC_NO}, + {0x320F, UNICODE_NORM_QC_NO}, + {0x3210, UNICODE_NORM_QC_NO}, + {0x3211, UNICODE_NORM_QC_NO}, + {0x3212, UNICODE_NORM_QC_NO}, + {0x3213, UNICODE_NORM_QC_NO}, + {0x3214, UNICODE_NORM_QC_NO}, + {0x3215, UNICODE_NORM_QC_NO}, + {0x3216, UNICODE_NORM_QC_NO}, + {0x3217, UNICODE_NORM_QC_NO}, + {0x3218, UNICODE_NORM_QC_NO}, + {0x3219, UNICODE_NORM_QC_NO}, + {0x321A, UNICODE_NORM_QC_NO}, + {0x321B, UNICODE_NORM_QC_NO}, + {0x321C, UNICODE_NORM_QC_NO}, + {0x321D, UNICODE_NORM_QC_NO}, + {0x321E, UNICODE_NORM_QC_NO}, + {0x3220, UNICODE_NORM_QC_NO}, + {0x3221, UNICODE_NORM_QC_NO}, + {0x3222, UNICODE_NORM_QC_NO}, + {0x3223, UNICODE_NORM_QC_NO}, + {0x3224, UNICODE_NORM_QC_NO}, + {0x3225, UNICODE_NORM_QC_NO}, + {0x3226, UNICODE_NORM_QC_NO}, + {0x3227, UNICODE_NORM_QC_NO}, + {0x3228, UNICODE_NORM_QC_NO}, + {0x3229, UNICODE_NORM_QC_NO}, + {0x322A, UNICODE_NORM_QC_NO}, + {0x322B, UNICODE_NORM_QC_NO}, + {0x322C, UNICODE_NORM_QC_NO}, + {0x322D, UNICODE_NORM_QC_NO}, + {0x322E, UNICODE_NORM_QC_NO}, + {0x322F, UNICODE_NORM_QC_NO}, + {0x3230, UNICODE_NORM_QC_NO}, + {0x3231, UNICODE_NORM_QC_NO}, + {0x3232, UNICODE_NORM_QC_NO}, + {0x3233, UNICODE_NORM_QC_NO}, + {0x3234, UNICODE_NORM_QC_NO}, + {0x3235, UNICODE_NORM_QC_NO}, + {0x3236, UNICODE_NORM_QC_NO}, + {0x3237, UNICODE_NORM_QC_NO}, + {0x3238, UNICODE_NORM_QC_NO}, + {0x3239, UNICODE_NORM_QC_NO}, + {0x323A, UNICODE_NORM_QC_NO}, + {0x323B, UNICODE_NORM_QC_NO}, + {0x323C, UNICODE_NORM_QC_NO}, + {0x323D, UNICODE_NORM_QC_NO}, + {0x323E, UNICODE_NORM_QC_NO}, + {0x323F, UNICODE_NORM_QC_NO}, + {0x3240, UNICODE_NORM_QC_NO}, + {0x3241, UNICODE_NORM_QC_NO}, + {0x3242, UNICODE_NORM_QC_NO}, + {0x3243, UNICODE_NORM_QC_NO}, + {0x3244, UNICODE_NORM_QC_NO}, + {0x3245, UNICODE_NORM_QC_NO}, + {0x3246, UNICODE_NORM_QC_NO}, + {0x3247, UNICODE_NORM_QC_NO}, + {0x3250, UNICODE_NORM_QC_NO}, + {0x3251, UNICODE_NORM_QC_NO}, + {0x3252, UNICODE_NORM_QC_NO}, + {0x3253, UNICODE_NORM_QC_NO}, + {0x3254, UNICODE_NORM_QC_NO}, + {0x3255, UNICODE_NORM_QC_NO}, + {0x3256, UNICODE_NORM_QC_NO}, + {0x3257, UNICODE_NORM_QC_NO}, + {0x3258, UNICODE_NORM_QC_NO}, + {0x3259, UNICODE_NORM_QC_NO}, + {0x325A, UNICODE_NORM_QC_NO}, + {0x325B, UNICODE_NORM_QC_NO}, + {0x325C, UNICODE_NORM_QC_NO}, + {0x325D, UNICODE_NORM_QC_NO}, + {0x325E, UNICODE_NORM_QC_NO}, + {0x325F, UNICODE_NORM_QC_NO}, + {0x3260, UNICODE_NORM_QC_NO}, + {0x3261, UNICODE_NORM_QC_NO}, + {0x3262, UNICODE_NORM_QC_NO}, + {0x3263, UNICODE_NORM_QC_NO}, + {0x3264, UNICODE_NORM_QC_NO}, + {0x3265, UNICODE_NORM_QC_NO}, + {0x3266, UNICODE_NORM_QC_NO}, + {0x3267, UNICODE_NORM_QC_NO}, + {0x3268, UNICODE_NORM_QC_NO}, + {0x3269, UNICODE_NORM_QC_NO}, + {0x326A, UNICODE_NORM_QC_NO}, + {0x326B, UNICODE_NORM_QC_NO}, + {0x326C, UNICODE_NORM_QC_NO}, + {0x326D, UNICODE_NORM_QC_NO}, + {0x326E, UNICODE_NORM_QC_NO}, + {0x326F, UNICODE_NORM_QC_NO}, + {0x3270, UNICODE_NORM_QC_NO}, + {0x3271, UNICODE_NORM_QC_NO}, + {0x3272, UNICODE_NORM_QC_NO}, + {0x3273, UNICODE_NORM_QC_NO}, + {0x3274, UNICODE_NORM_QC_NO}, + {0x3275, UNICODE_NORM_QC_NO}, + {0x3276, UNICODE_NORM_QC_NO}, + {0x3277, UNICODE_NORM_QC_NO}, + {0x3278, UNICODE_NORM_QC_NO}, + {0x3279, UNICODE_NORM_QC_NO}, + {0x327A, UNICODE_NORM_QC_NO}, + {0x327B, UNICODE_NORM_QC_NO}, + {0x327C, UNICODE_NORM_QC_NO}, + {0x327D, UNICODE_NORM_QC_NO}, + {0x327E, UNICODE_NORM_QC_NO}, + {0x3280, UNICODE_NORM_QC_NO}, + {0x3281, UNICODE_NORM_QC_NO}, + {0x3282, UNICODE_NORM_QC_NO}, + {0x3283, UNICODE_NORM_QC_NO}, + {0x3284, UNICODE_NORM_QC_NO}, + {0x3285, UNICODE_NORM_QC_NO}, + {0x3286, UNICODE_NORM_QC_NO}, + {0x3287, UNICODE_NORM_QC_NO}, + {0x3288, UNICODE_NORM_QC_NO}, + {0x3289, UNICODE_NORM_QC_NO}, + {0x328A, UNICODE_NORM_QC_NO}, + {0x328B, UNICODE_NORM_QC_NO}, + {0x328C, UNICODE_NORM_QC_NO}, + {0x328D, UNICODE_NORM_QC_NO}, + {0x328E, UNICODE_NORM_QC_NO}, + {0x328F, UNICODE_NORM_QC_NO}, + {0x3290, UNICODE_NORM_QC_NO}, + {0x3291, UNICODE_NORM_QC_NO}, + {0x3292, UNICODE_NORM_QC_NO}, + {0x3293, UNICODE_NORM_QC_NO}, + {0x3294, UNICODE_NORM_QC_NO}, + {0x3295, UNICODE_NORM_QC_NO}, + {0x3296, UNICODE_NORM_QC_NO}, + {0x3297, UNICODE_NORM_QC_NO}, + {0x3298, UNICODE_NORM_QC_NO}, + {0x3299, UNICODE_NORM_QC_NO}, + {0x329A, UNICODE_NORM_QC_NO}, + {0x329B, UNICODE_NORM_QC_NO}, + {0x329C, UNICODE_NORM_QC_NO}, + {0x329D, UNICODE_NORM_QC_NO}, + {0x329E, UNICODE_NORM_QC_NO}, + {0x329F, UNICODE_NORM_QC_NO}, + {0x32A0, UNICODE_NORM_QC_NO}, + {0x32A1, UNICODE_NORM_QC_NO}, + {0x32A2, UNICODE_NORM_QC_NO}, + {0x32A3, UNICODE_NORM_QC_NO}, + {0x32A4, UNICODE_NORM_QC_NO}, + {0x32A5, UNICODE_NORM_QC_NO}, + {0x32A6, UNICODE_NORM_QC_NO}, + {0x32A7, UNICODE_NORM_QC_NO}, + {0x32A8, UNICODE_NORM_QC_NO}, + {0x32A9, UNICODE_NORM_QC_NO}, + {0x32AA, UNICODE_NORM_QC_NO}, + {0x32AB, UNICODE_NORM_QC_NO}, + {0x32AC, UNICODE_NORM_QC_NO}, + {0x32AD, UNICODE_NORM_QC_NO}, + {0x32AE, UNICODE_NORM_QC_NO}, + {0x32AF, UNICODE_NORM_QC_NO}, + {0x32B0, UNICODE_NORM_QC_NO}, + {0x32B1, UNICODE_NORM_QC_NO}, + {0x32B2, UNICODE_NORM_QC_NO}, + {0x32B3, UNICODE_NORM_QC_NO}, + {0x32B4, UNICODE_NORM_QC_NO}, + {0x32B5, UNICODE_NORM_QC_NO}, + {0x32B6, UNICODE_NORM_QC_NO}, + {0x32B7, UNICODE_NORM_QC_NO}, + {0x32B8, UNICODE_NORM_QC_NO}, + {0x32B9, UNICODE_NORM_QC_NO}, + {0x32BA, UNICODE_NORM_QC_NO}, + {0x32BB, UNICODE_NORM_QC_NO}, + {0x32BC, UNICODE_NORM_QC_NO}, + {0x32BD, UNICODE_NORM_QC_NO}, + {0x32BE, UNICODE_NORM_QC_NO}, + {0x32BF, UNICODE_NORM_QC_NO}, + {0x32C0, UNICODE_NORM_QC_NO}, + {0x32C1, UNICODE_NORM_QC_NO}, + {0x32C2, UNICODE_NORM_QC_NO}, + {0x32C3, UNICODE_NORM_QC_NO}, + {0x32C4, UNICODE_NORM_QC_NO}, + {0x32C5, UNICODE_NORM_QC_NO}, + {0x32C6, UNICODE_NORM_QC_NO}, + {0x32C7, UNICODE_NORM_QC_NO}, + {0x32C8, UNICODE_NORM_QC_NO}, + {0x32C9, UNICODE_NORM_QC_NO}, + {0x32CA, UNICODE_NORM_QC_NO}, + {0x32CB, UNICODE_NORM_QC_NO}, + {0x32CC, UNICODE_NORM_QC_NO}, + {0x32CD, UNICODE_NORM_QC_NO}, + {0x32CE, UNICODE_NORM_QC_NO}, + {0x32CF, UNICODE_NORM_QC_NO}, + {0x32D0, UNICODE_NORM_QC_NO}, + {0x32D1, UNICODE_NORM_QC_NO}, + {0x32D2, UNICODE_NORM_QC_NO}, + {0x32D3, UNICODE_NORM_QC_NO}, + {0x32D4, UNICODE_NORM_QC_NO}, + {0x32D5, UNICODE_NORM_QC_NO}, + {0x32D6, UNICODE_NORM_QC_NO}, + {0x32D7, UNICODE_NORM_QC_NO}, + {0x32D8, UNICODE_NORM_QC_NO}, + {0x32D9, UNICODE_NORM_QC_NO}, + {0x32DA, UNICODE_NORM_QC_NO}, + {0x32DB, UNICODE_NORM_QC_NO}, + {0x32DC, UNICODE_NORM_QC_NO}, + {0x32DD, UNICODE_NORM_QC_NO}, + {0x32DE, UNICODE_NORM_QC_NO}, + {0x32DF, UNICODE_NORM_QC_NO}, + {0x32E0, UNICODE_NORM_QC_NO}, + {0x32E1, UNICODE_NORM_QC_NO}, + {0x32E2, UNICODE_NORM_QC_NO}, + {0x32E3, UNICODE_NORM_QC_NO}, + {0x32E4, UNICODE_NORM_QC_NO}, + {0x32E5, UNICODE_NORM_QC_NO}, + {0x32E6, UNICODE_NORM_QC_NO}, + {0x32E7, UNICODE_NORM_QC_NO}, + {0x32E8, UNICODE_NORM_QC_NO}, + {0x32E9, UNICODE_NORM_QC_NO}, + {0x32EA, UNICODE_NORM_QC_NO}, + {0x32EB, UNICODE_NORM_QC_NO}, + {0x32EC, UNICODE_NORM_QC_NO}, + {0x32ED, UNICODE_NORM_QC_NO}, + {0x32EE, UNICODE_NORM_QC_NO}, + {0x32EF, UNICODE_NORM_QC_NO}, + {0x32F0, UNICODE_NORM_QC_NO}, + {0x32F1, UNICODE_NORM_QC_NO}, + {0x32F2, UNICODE_NORM_QC_NO}, + {0x32F3, UNICODE_NORM_QC_NO}, + {0x32F4, UNICODE_NORM_QC_NO}, + {0x32F5, UNICODE_NORM_QC_NO}, + {0x32F6, UNICODE_NORM_QC_NO}, + {0x32F7, UNICODE_NORM_QC_NO}, + {0x32F8, UNICODE_NORM_QC_NO}, + {0x32F9, UNICODE_NORM_QC_NO}, + {0x32FA, UNICODE_NORM_QC_NO}, + {0x32FB, UNICODE_NORM_QC_NO}, + {0x32FC, UNICODE_NORM_QC_NO}, + {0x32FD, UNICODE_NORM_QC_NO}, + {0x32FE, UNICODE_NORM_QC_NO}, + {0x32FF, UNICODE_NORM_QC_NO}, + {0x3300, UNICODE_NORM_QC_NO}, + {0x3301, UNICODE_NORM_QC_NO}, + {0x3302, UNICODE_NORM_QC_NO}, + {0x3303, UNICODE_NORM_QC_NO}, + {0x3304, UNICODE_NORM_QC_NO}, + {0x3305, UNICODE_NORM_QC_NO}, + {0x3306, UNICODE_NORM_QC_NO}, + {0x3307, UNICODE_NORM_QC_NO}, + {0x3308, UNICODE_NORM_QC_NO}, + {0x3309, UNICODE_NORM_QC_NO}, + {0x330A, UNICODE_NORM_QC_NO}, + {0x330B, UNICODE_NORM_QC_NO}, + {0x330C, UNICODE_NORM_QC_NO}, + {0x330D, UNICODE_NORM_QC_NO}, + {0x330E, UNICODE_NORM_QC_NO}, + {0x330F, UNICODE_NORM_QC_NO}, + {0x3310, UNICODE_NORM_QC_NO}, + {0x3311, UNICODE_NORM_QC_NO}, + {0x3312, UNICODE_NORM_QC_NO}, + {0x3313, UNICODE_NORM_QC_NO}, + {0x3314, UNICODE_NORM_QC_NO}, + {0x3315, UNICODE_NORM_QC_NO}, + {0x3316, UNICODE_NORM_QC_NO}, + {0x3317, UNICODE_NORM_QC_NO}, + {0x3318, UNICODE_NORM_QC_NO}, + {0x3319, UNICODE_NORM_QC_NO}, + {0x331A, UNICODE_NORM_QC_NO}, + {0x331B, UNICODE_NORM_QC_NO}, + {0x331C, UNICODE_NORM_QC_NO}, + {0x331D, UNICODE_NORM_QC_NO}, + {0x331E, UNICODE_NORM_QC_NO}, + {0x331F, UNICODE_NORM_QC_NO}, + {0x3320, UNICODE_NORM_QC_NO}, + {0x3321, UNICODE_NORM_QC_NO}, + {0x3322, UNICODE_NORM_QC_NO}, + {0x3323, UNICODE_NORM_QC_NO}, + {0x3324, UNICODE_NORM_QC_NO}, + {0x3325, UNICODE_NORM_QC_NO}, + {0x3326, UNICODE_NORM_QC_NO}, + {0x3327, UNICODE_NORM_QC_NO}, + {0x3328, UNICODE_NORM_QC_NO}, + {0x3329, UNICODE_NORM_QC_NO}, + {0x332A, UNICODE_NORM_QC_NO}, + {0x332B, UNICODE_NORM_QC_NO}, + {0x332C, UNICODE_NORM_QC_NO}, + {0x332D, UNICODE_NORM_QC_NO}, + {0x332E, UNICODE_NORM_QC_NO}, + {0x332F, UNICODE_NORM_QC_NO}, + {0x3330, UNICODE_NORM_QC_NO}, + {0x3331, UNICODE_NORM_QC_NO}, + {0x3332, UNICODE_NORM_QC_NO}, + {0x3333, UNICODE_NORM_QC_NO}, + {0x3334, UNICODE_NORM_QC_NO}, + {0x3335, UNICODE_NORM_QC_NO}, + {0x3336, UNICODE_NORM_QC_NO}, + {0x3337, UNICODE_NORM_QC_NO}, + {0x3338, UNICODE_NORM_QC_NO}, + {0x3339, UNICODE_NORM_QC_NO}, + {0x333A, UNICODE_NORM_QC_NO}, + {0x333B, UNICODE_NORM_QC_NO}, + {0x333C, UNICODE_NORM_QC_NO}, + {0x333D, UNICODE_NORM_QC_NO}, + {0x333E, UNICODE_NORM_QC_NO}, + {0x333F, UNICODE_NORM_QC_NO}, + {0x3340, UNICODE_NORM_QC_NO}, + {0x3341, UNICODE_NORM_QC_NO}, + {0x3342, UNICODE_NORM_QC_NO}, + {0x3343, UNICODE_NORM_QC_NO}, + {0x3344, UNICODE_NORM_QC_NO}, + {0x3345, UNICODE_NORM_QC_NO}, + {0x3346, UNICODE_NORM_QC_NO}, + {0x3347, UNICODE_NORM_QC_NO}, + {0x3348, UNICODE_NORM_QC_NO}, + {0x3349, UNICODE_NORM_QC_NO}, + {0x334A, UNICODE_NORM_QC_NO}, + {0x334B, UNICODE_NORM_QC_NO}, + {0x334C, UNICODE_NORM_QC_NO}, + {0x334D, UNICODE_NORM_QC_NO}, + {0x334E, UNICODE_NORM_QC_NO}, + {0x334F, UNICODE_NORM_QC_NO}, + {0x3350, UNICODE_NORM_QC_NO}, + {0x3351, UNICODE_NORM_QC_NO}, + {0x3352, UNICODE_NORM_QC_NO}, + {0x3353, UNICODE_NORM_QC_NO}, + {0x3354, UNICODE_NORM_QC_NO}, + {0x3355, UNICODE_NORM_QC_NO}, + {0x3356, UNICODE_NORM_QC_NO}, + {0x3357, UNICODE_NORM_QC_NO}, + {0x3358, UNICODE_NORM_QC_NO}, + {0x3359, UNICODE_NORM_QC_NO}, + {0x335A, UNICODE_NORM_QC_NO}, + {0x335B, UNICODE_NORM_QC_NO}, + {0x335C, UNICODE_NORM_QC_NO}, + {0x335D, UNICODE_NORM_QC_NO}, + {0x335E, UNICODE_NORM_QC_NO}, + {0x335F, UNICODE_NORM_QC_NO}, + {0x3360, UNICODE_NORM_QC_NO}, + {0x3361, UNICODE_NORM_QC_NO}, + {0x3362, UNICODE_NORM_QC_NO}, + {0x3363, UNICODE_NORM_QC_NO}, + {0x3364, UNICODE_NORM_QC_NO}, + {0x3365, UNICODE_NORM_QC_NO}, + {0x3366, UNICODE_NORM_QC_NO}, + {0x3367, UNICODE_NORM_QC_NO}, + {0x3368, UNICODE_NORM_QC_NO}, + {0x3369, UNICODE_NORM_QC_NO}, + {0x336A, UNICODE_NORM_QC_NO}, + {0x336B, UNICODE_NORM_QC_NO}, + {0x336C, UNICODE_NORM_QC_NO}, + {0x336D, UNICODE_NORM_QC_NO}, + {0x336E, UNICODE_NORM_QC_NO}, + {0x336F, UNICODE_NORM_QC_NO}, + {0x3370, UNICODE_NORM_QC_NO}, + {0x3371, UNICODE_NORM_QC_NO}, + {0x3372, UNICODE_NORM_QC_NO}, + {0x3373, UNICODE_NORM_QC_NO}, + {0x3374, UNICODE_NORM_QC_NO}, + {0x3375, UNICODE_NORM_QC_NO}, + {0x3376, UNICODE_NORM_QC_NO}, + {0x3377, UNICODE_NORM_QC_NO}, + {0x3378, UNICODE_NORM_QC_NO}, + {0x3379, UNICODE_NORM_QC_NO}, + {0x337A, UNICODE_NORM_QC_NO}, + {0x337B, UNICODE_NORM_QC_NO}, + {0x337C, UNICODE_NORM_QC_NO}, + {0x337D, UNICODE_NORM_QC_NO}, + {0x337E, UNICODE_NORM_QC_NO}, + {0x337F, UNICODE_NORM_QC_NO}, + {0x3380, UNICODE_NORM_QC_NO}, + {0x3381, UNICODE_NORM_QC_NO}, + {0x3382, UNICODE_NORM_QC_NO}, + {0x3383, UNICODE_NORM_QC_NO}, + {0x3384, UNICODE_NORM_QC_NO}, + {0x3385, UNICODE_NORM_QC_NO}, + {0x3386, UNICODE_NORM_QC_NO}, + {0x3387, UNICODE_NORM_QC_NO}, + {0x3388, UNICODE_NORM_QC_NO}, + {0x3389, UNICODE_NORM_QC_NO}, + {0x338A, UNICODE_NORM_QC_NO}, + {0x338B, UNICODE_NORM_QC_NO}, + {0x338C, UNICODE_NORM_QC_NO}, + {0x338D, UNICODE_NORM_QC_NO}, + {0x338E, UNICODE_NORM_QC_NO}, + {0x338F, UNICODE_NORM_QC_NO}, + {0x3390, UNICODE_NORM_QC_NO}, + {0x3391, UNICODE_NORM_QC_NO}, + {0x3392, UNICODE_NORM_QC_NO}, + {0x3393, UNICODE_NORM_QC_NO}, + {0x3394, UNICODE_NORM_QC_NO}, + {0x3395, UNICODE_NORM_QC_NO}, + {0x3396, UNICODE_NORM_QC_NO}, + {0x3397, UNICODE_NORM_QC_NO}, + {0x3398, UNICODE_NORM_QC_NO}, + {0x3399, UNICODE_NORM_QC_NO}, + {0x339A, UNICODE_NORM_QC_NO}, + {0x339B, UNICODE_NORM_QC_NO}, + {0x339C, UNICODE_NORM_QC_NO}, + {0x339D, UNICODE_NORM_QC_NO}, + {0x339E, UNICODE_NORM_QC_NO}, + {0x339F, UNICODE_NORM_QC_NO}, + {0x33A0, UNICODE_NORM_QC_NO}, + {0x33A1, UNICODE_NORM_QC_NO}, + {0x33A2, UNICODE_NORM_QC_NO}, + {0x33A3, UNICODE_NORM_QC_NO}, + {0x33A4, UNICODE_NORM_QC_NO}, + {0x33A5, UNICODE_NORM_QC_NO}, + {0x33A6, UNICODE_NORM_QC_NO}, + {0x33A7, UNICODE_NORM_QC_NO}, + {0x33A8, UNICODE_NORM_QC_NO}, + {0x33A9, UNICODE_NORM_QC_NO}, + {0x33AA, UNICODE_NORM_QC_NO}, + {0x33AB, UNICODE_NORM_QC_NO}, + {0x33AC, UNICODE_NORM_QC_NO}, + {0x33AD, UNICODE_NORM_QC_NO}, + {0x33AE, UNICODE_NORM_QC_NO}, + {0x33AF, UNICODE_NORM_QC_NO}, + {0x33B0, UNICODE_NORM_QC_NO}, + {0x33B1, UNICODE_NORM_QC_NO}, + {0x33B2, UNICODE_NORM_QC_NO}, + {0x33B3, UNICODE_NORM_QC_NO}, + {0x33B4, UNICODE_NORM_QC_NO}, + {0x33B5, UNICODE_NORM_QC_NO}, + {0x33B6, UNICODE_NORM_QC_NO}, + {0x33B7, UNICODE_NORM_QC_NO}, + {0x33B8, UNICODE_NORM_QC_NO}, + {0x33B9, UNICODE_NORM_QC_NO}, + {0x33BA, UNICODE_NORM_QC_NO}, + {0x33BB, UNICODE_NORM_QC_NO}, + {0x33BC, UNICODE_NORM_QC_NO}, + {0x33BD, UNICODE_NORM_QC_NO}, + {0x33BE, UNICODE_NORM_QC_NO}, + {0x33BF, UNICODE_NORM_QC_NO}, + {0x33C0, UNICODE_NORM_QC_NO}, + {0x33C1, UNICODE_NORM_QC_NO}, + {0x33C2, UNICODE_NORM_QC_NO}, + {0x33C3, UNICODE_NORM_QC_NO}, + {0x33C4, UNICODE_NORM_QC_NO}, + {0x33C5, UNICODE_NORM_QC_NO}, + {0x33C6, UNICODE_NORM_QC_NO}, + {0x33C7, UNICODE_NORM_QC_NO}, + {0x33C8, UNICODE_NORM_QC_NO}, + {0x33C9, UNICODE_NORM_QC_NO}, + {0x33CA, UNICODE_NORM_QC_NO}, + {0x33CB, UNICODE_NORM_QC_NO}, + {0x33CC, UNICODE_NORM_QC_NO}, + {0x33CD, UNICODE_NORM_QC_NO}, + {0x33CE, UNICODE_NORM_QC_NO}, + {0x33CF, UNICODE_NORM_QC_NO}, + {0x33D0, UNICODE_NORM_QC_NO}, + {0x33D1, UNICODE_NORM_QC_NO}, + {0x33D2, UNICODE_NORM_QC_NO}, + {0x33D3, UNICODE_NORM_QC_NO}, + {0x33D4, UNICODE_NORM_QC_NO}, + {0x33D5, UNICODE_NORM_QC_NO}, + {0x33D6, UNICODE_NORM_QC_NO}, + {0x33D7, UNICODE_NORM_QC_NO}, + {0x33D8, UNICODE_NORM_QC_NO}, + {0x33D9, UNICODE_NORM_QC_NO}, + {0x33DA, UNICODE_NORM_QC_NO}, + {0x33DB, UNICODE_NORM_QC_NO}, + {0x33DC, UNICODE_NORM_QC_NO}, + {0x33DD, UNICODE_NORM_QC_NO}, + {0x33DE, UNICODE_NORM_QC_NO}, + {0x33DF, UNICODE_NORM_QC_NO}, + {0x33E0, UNICODE_NORM_QC_NO}, + {0x33E1, UNICODE_NORM_QC_NO}, + {0x33E2, UNICODE_NORM_QC_NO}, + {0x33E3, UNICODE_NORM_QC_NO}, + {0x33E4, UNICODE_NORM_QC_NO}, + {0x33E5, UNICODE_NORM_QC_NO}, + {0x33E6, UNICODE_NORM_QC_NO}, + {0x33E7, UNICODE_NORM_QC_NO}, + {0x33E8, UNICODE_NORM_QC_NO}, + {0x33E9, UNICODE_NORM_QC_NO}, + {0x33EA, UNICODE_NORM_QC_NO}, + {0x33EB, UNICODE_NORM_QC_NO}, + {0x33EC, UNICODE_NORM_QC_NO}, + {0x33ED, UNICODE_NORM_QC_NO}, + {0x33EE, UNICODE_NORM_QC_NO}, + {0x33EF, UNICODE_NORM_QC_NO}, + {0x33F0, UNICODE_NORM_QC_NO}, + {0x33F1, UNICODE_NORM_QC_NO}, + {0x33F2, UNICODE_NORM_QC_NO}, + {0x33F3, UNICODE_NORM_QC_NO}, + {0x33F4, UNICODE_NORM_QC_NO}, + {0x33F5, UNICODE_NORM_QC_NO}, + {0x33F6, UNICODE_NORM_QC_NO}, + {0x33F7, UNICODE_NORM_QC_NO}, + {0x33F8, UNICODE_NORM_QC_NO}, + {0x33F9, UNICODE_NORM_QC_NO}, + {0x33FA, UNICODE_NORM_QC_NO}, + {0x33FB, UNICODE_NORM_QC_NO}, + {0x33FC, UNICODE_NORM_QC_NO}, + {0x33FD, UNICODE_NORM_QC_NO}, + {0x33FE, UNICODE_NORM_QC_NO}, + {0x33FF, UNICODE_NORM_QC_NO}, + {0xA69C, UNICODE_NORM_QC_NO}, + {0xA69D, UNICODE_NORM_QC_NO}, + {0xA770, UNICODE_NORM_QC_NO}, + {0xA7F2, UNICODE_NORM_QC_NO}, + {0xA7F3, UNICODE_NORM_QC_NO}, + {0xA7F4, UNICODE_NORM_QC_NO}, + {0xA7F8, UNICODE_NORM_QC_NO}, + {0xA7F9, UNICODE_NORM_QC_NO}, + {0xAB5C, UNICODE_NORM_QC_NO}, + {0xAB5D, UNICODE_NORM_QC_NO}, + {0xAB5E, UNICODE_NORM_QC_NO}, + {0xAB5F, UNICODE_NORM_QC_NO}, + {0xAB69, UNICODE_NORM_QC_NO}, + {0xF900, UNICODE_NORM_QC_NO}, + {0xF901, UNICODE_NORM_QC_NO}, + {0xF902, UNICODE_NORM_QC_NO}, + {0xF903, UNICODE_NORM_QC_NO}, + {0xF904, UNICODE_NORM_QC_NO}, + {0xF905, UNICODE_NORM_QC_NO}, + {0xF906, UNICODE_NORM_QC_NO}, + {0xF907, UNICODE_NORM_QC_NO}, + {0xF908, UNICODE_NORM_QC_NO}, + {0xF909, UNICODE_NORM_QC_NO}, + {0xF90A, UNICODE_NORM_QC_NO}, + {0xF90B, UNICODE_NORM_QC_NO}, + {0xF90C, UNICODE_NORM_QC_NO}, + {0xF90D, UNICODE_NORM_QC_NO}, + {0xF90E, UNICODE_NORM_QC_NO}, + {0xF90F, UNICODE_NORM_QC_NO}, + {0xF910, UNICODE_NORM_QC_NO}, + {0xF911, UNICODE_NORM_QC_NO}, + {0xF912, UNICODE_NORM_QC_NO}, + {0xF913, UNICODE_NORM_QC_NO}, + {0xF914, UNICODE_NORM_QC_NO}, + {0xF915, UNICODE_NORM_QC_NO}, + {0xF916, UNICODE_NORM_QC_NO}, + {0xF917, UNICODE_NORM_QC_NO}, + {0xF918, UNICODE_NORM_QC_NO}, + {0xF919, UNICODE_NORM_QC_NO}, + {0xF91A, UNICODE_NORM_QC_NO}, + {0xF91B, UNICODE_NORM_QC_NO}, + {0xF91C, UNICODE_NORM_QC_NO}, + {0xF91D, UNICODE_NORM_QC_NO}, + {0xF91E, UNICODE_NORM_QC_NO}, + {0xF91F, UNICODE_NORM_QC_NO}, + {0xF920, UNICODE_NORM_QC_NO}, + {0xF921, UNICODE_NORM_QC_NO}, + {0xF922, UNICODE_NORM_QC_NO}, + {0xF923, UNICODE_NORM_QC_NO}, + {0xF924, UNICODE_NORM_QC_NO}, + {0xF925, UNICODE_NORM_QC_NO}, + {0xF926, UNICODE_NORM_QC_NO}, + {0xF927, UNICODE_NORM_QC_NO}, + {0xF928, UNICODE_NORM_QC_NO}, + {0xF929, UNICODE_NORM_QC_NO}, + {0xF92A, UNICODE_NORM_QC_NO}, + {0xF92B, UNICODE_NORM_QC_NO}, + {0xF92C, UNICODE_NORM_QC_NO}, + {0xF92D, UNICODE_NORM_QC_NO}, + {0xF92E, UNICODE_NORM_QC_NO}, + {0xF92F, UNICODE_NORM_QC_NO}, + {0xF930, UNICODE_NORM_QC_NO}, + {0xF931, UNICODE_NORM_QC_NO}, + {0xF932, UNICODE_NORM_QC_NO}, + {0xF933, UNICODE_NORM_QC_NO}, + {0xF934, UNICODE_NORM_QC_NO}, + {0xF935, UNICODE_NORM_QC_NO}, + {0xF936, UNICODE_NORM_QC_NO}, + {0xF937, UNICODE_NORM_QC_NO}, + {0xF938, UNICODE_NORM_QC_NO}, + {0xF939, UNICODE_NORM_QC_NO}, + {0xF93A, UNICODE_NORM_QC_NO}, + {0xF93B, UNICODE_NORM_QC_NO}, + {0xF93C, UNICODE_NORM_QC_NO}, + {0xF93D, UNICODE_NORM_QC_NO}, + {0xF93E, UNICODE_NORM_QC_NO}, + {0xF93F, UNICODE_NORM_QC_NO}, + {0xF940, UNICODE_NORM_QC_NO}, + {0xF941, UNICODE_NORM_QC_NO}, + {0xF942, UNICODE_NORM_QC_NO}, + {0xF943, UNICODE_NORM_QC_NO}, + {0xF944, UNICODE_NORM_QC_NO}, + {0xF945, UNICODE_NORM_QC_NO}, + {0xF946, UNICODE_NORM_QC_NO}, + {0xF947, UNICODE_NORM_QC_NO}, + {0xF948, UNICODE_NORM_QC_NO}, + {0xF949, UNICODE_NORM_QC_NO}, + {0xF94A, UNICODE_NORM_QC_NO}, + {0xF94B, UNICODE_NORM_QC_NO}, + {0xF94C, UNICODE_NORM_QC_NO}, + {0xF94D, UNICODE_NORM_QC_NO}, + {0xF94E, UNICODE_NORM_QC_NO}, + {0xF94F, UNICODE_NORM_QC_NO}, + {0xF950, UNICODE_NORM_QC_NO}, + {0xF951, UNICODE_NORM_QC_NO}, + {0xF952, UNICODE_NORM_QC_NO}, + {0xF953, UNICODE_NORM_QC_NO}, + {0xF954, UNICODE_NORM_QC_NO}, + {0xF955, UNICODE_NORM_QC_NO}, + {0xF956, UNICODE_NORM_QC_NO}, + {0xF957, UNICODE_NORM_QC_NO}, + {0xF958, UNICODE_NORM_QC_NO}, + {0xF959, UNICODE_NORM_QC_NO}, + {0xF95A, UNICODE_NORM_QC_NO}, + {0xF95B, UNICODE_NORM_QC_NO}, + {0xF95C, UNICODE_NORM_QC_NO}, + {0xF95D, UNICODE_NORM_QC_NO}, + {0xF95E, UNICODE_NORM_QC_NO}, + {0xF95F, UNICODE_NORM_QC_NO}, + {0xF960, UNICODE_NORM_QC_NO}, + {0xF961, UNICODE_NORM_QC_NO}, + {0xF962, UNICODE_NORM_QC_NO}, + {0xF963, UNICODE_NORM_QC_NO}, + {0xF964, UNICODE_NORM_QC_NO}, + {0xF965, UNICODE_NORM_QC_NO}, + {0xF966, UNICODE_NORM_QC_NO}, + {0xF967, UNICODE_NORM_QC_NO}, + {0xF968, UNICODE_NORM_QC_NO}, + {0xF969, UNICODE_NORM_QC_NO}, + {0xF96A, UNICODE_NORM_QC_NO}, + {0xF96B, UNICODE_NORM_QC_NO}, + {0xF96C, UNICODE_NORM_QC_NO}, + {0xF96D, UNICODE_NORM_QC_NO}, + {0xF96E, UNICODE_NORM_QC_NO}, + {0xF96F, UNICODE_NORM_QC_NO}, + {0xF970, UNICODE_NORM_QC_NO}, + {0xF971, UNICODE_NORM_QC_NO}, + {0xF972, UNICODE_NORM_QC_NO}, + {0xF973, UNICODE_NORM_QC_NO}, + {0xF974, UNICODE_NORM_QC_NO}, + {0xF975, UNICODE_NORM_QC_NO}, + {0xF976, UNICODE_NORM_QC_NO}, + {0xF977, UNICODE_NORM_QC_NO}, + {0xF978, UNICODE_NORM_QC_NO}, + {0xF979, UNICODE_NORM_QC_NO}, + {0xF97A, UNICODE_NORM_QC_NO}, + {0xF97B, UNICODE_NORM_QC_NO}, + {0xF97C, UNICODE_NORM_QC_NO}, + {0xF97D, UNICODE_NORM_QC_NO}, + {0xF97E, UNICODE_NORM_QC_NO}, + {0xF97F, UNICODE_NORM_QC_NO}, + {0xF980, UNICODE_NORM_QC_NO}, + {0xF981, UNICODE_NORM_QC_NO}, + {0xF982, UNICODE_NORM_QC_NO}, + {0xF983, UNICODE_NORM_QC_NO}, + {0xF984, UNICODE_NORM_QC_NO}, + {0xF985, UNICODE_NORM_QC_NO}, + {0xF986, UNICODE_NORM_QC_NO}, + {0xF987, UNICODE_NORM_QC_NO}, + {0xF988, UNICODE_NORM_QC_NO}, + {0xF989, UNICODE_NORM_QC_NO}, + {0xF98A, UNICODE_NORM_QC_NO}, + {0xF98B, UNICODE_NORM_QC_NO}, + {0xF98C, UNICODE_NORM_QC_NO}, + {0xF98D, UNICODE_NORM_QC_NO}, + {0xF98E, UNICODE_NORM_QC_NO}, + {0xF98F, UNICODE_NORM_QC_NO}, + {0xF990, UNICODE_NORM_QC_NO}, + {0xF991, UNICODE_NORM_QC_NO}, + {0xF992, UNICODE_NORM_QC_NO}, + {0xF993, UNICODE_NORM_QC_NO}, + {0xF994, UNICODE_NORM_QC_NO}, + {0xF995, UNICODE_NORM_QC_NO}, + {0xF996, UNICODE_NORM_QC_NO}, + {0xF997, UNICODE_NORM_QC_NO}, + {0xF998, UNICODE_NORM_QC_NO}, + {0xF999, UNICODE_NORM_QC_NO}, + {0xF99A, UNICODE_NORM_QC_NO}, + {0xF99B, UNICODE_NORM_QC_NO}, + {0xF99C, UNICODE_NORM_QC_NO}, + {0xF99D, UNICODE_NORM_QC_NO}, + {0xF99E, UNICODE_NORM_QC_NO}, + {0xF99F, UNICODE_NORM_QC_NO}, + {0xF9A0, UNICODE_NORM_QC_NO}, + {0xF9A1, UNICODE_NORM_QC_NO}, + {0xF9A2, UNICODE_NORM_QC_NO}, + {0xF9A3, UNICODE_NORM_QC_NO}, + {0xF9A4, UNICODE_NORM_QC_NO}, + {0xF9A5, UNICODE_NORM_QC_NO}, + {0xF9A6, UNICODE_NORM_QC_NO}, + {0xF9A7, UNICODE_NORM_QC_NO}, + {0xF9A8, UNICODE_NORM_QC_NO}, + {0xF9A9, UNICODE_NORM_QC_NO}, + {0xF9AA, UNICODE_NORM_QC_NO}, + {0xF9AB, UNICODE_NORM_QC_NO}, + {0xF9AC, UNICODE_NORM_QC_NO}, + {0xF9AD, UNICODE_NORM_QC_NO}, + {0xF9AE, UNICODE_NORM_QC_NO}, + {0xF9AF, UNICODE_NORM_QC_NO}, + {0xF9B0, UNICODE_NORM_QC_NO}, + {0xF9B1, UNICODE_NORM_QC_NO}, + {0xF9B2, UNICODE_NORM_QC_NO}, + {0xF9B3, UNICODE_NORM_QC_NO}, + {0xF9B4, UNICODE_NORM_QC_NO}, + {0xF9B5, UNICODE_NORM_QC_NO}, + {0xF9B6, UNICODE_NORM_QC_NO}, + {0xF9B7, UNICODE_NORM_QC_NO}, + {0xF9B8, UNICODE_NORM_QC_NO}, + {0xF9B9, UNICODE_NORM_QC_NO}, + {0xF9BA, UNICODE_NORM_QC_NO}, + {0xF9BB, UNICODE_NORM_QC_NO}, + {0xF9BC, UNICODE_NORM_QC_NO}, + {0xF9BD, UNICODE_NORM_QC_NO}, + {0xF9BE, UNICODE_NORM_QC_NO}, + {0xF9BF, UNICODE_NORM_QC_NO}, + {0xF9C0, UNICODE_NORM_QC_NO}, + {0xF9C1, UNICODE_NORM_QC_NO}, + {0xF9C2, UNICODE_NORM_QC_NO}, + {0xF9C3, UNICODE_NORM_QC_NO}, + {0xF9C4, UNICODE_NORM_QC_NO}, + {0xF9C5, UNICODE_NORM_QC_NO}, + {0xF9C6, UNICODE_NORM_QC_NO}, + {0xF9C7, UNICODE_NORM_QC_NO}, + {0xF9C8, UNICODE_NORM_QC_NO}, + {0xF9C9, UNICODE_NORM_QC_NO}, + {0xF9CA, UNICODE_NORM_QC_NO}, + {0xF9CB, UNICODE_NORM_QC_NO}, + {0xF9CC, UNICODE_NORM_QC_NO}, + {0xF9CD, UNICODE_NORM_QC_NO}, + {0xF9CE, UNICODE_NORM_QC_NO}, + {0xF9CF, UNICODE_NORM_QC_NO}, + {0xF9D0, UNICODE_NORM_QC_NO}, + {0xF9D1, UNICODE_NORM_QC_NO}, + {0xF9D2, UNICODE_NORM_QC_NO}, + {0xF9D3, UNICODE_NORM_QC_NO}, + {0xF9D4, UNICODE_NORM_QC_NO}, + {0xF9D5, UNICODE_NORM_QC_NO}, + {0xF9D6, UNICODE_NORM_QC_NO}, + {0xF9D7, UNICODE_NORM_QC_NO}, + {0xF9D8, UNICODE_NORM_QC_NO}, + {0xF9D9, UNICODE_NORM_QC_NO}, + {0xF9DA, UNICODE_NORM_QC_NO}, + {0xF9DB, UNICODE_NORM_QC_NO}, + {0xF9DC, UNICODE_NORM_QC_NO}, + {0xF9DD, UNICODE_NORM_QC_NO}, + {0xF9DE, UNICODE_NORM_QC_NO}, + {0xF9DF, UNICODE_NORM_QC_NO}, + {0xF9E0, UNICODE_NORM_QC_NO}, + {0xF9E1, UNICODE_NORM_QC_NO}, + {0xF9E2, UNICODE_NORM_QC_NO}, + {0xF9E3, UNICODE_NORM_QC_NO}, + {0xF9E4, UNICODE_NORM_QC_NO}, + {0xF9E5, UNICODE_NORM_QC_NO}, + {0xF9E6, UNICODE_NORM_QC_NO}, + {0xF9E7, UNICODE_NORM_QC_NO}, + {0xF9E8, UNICODE_NORM_QC_NO}, + {0xF9E9, UNICODE_NORM_QC_NO}, + {0xF9EA, UNICODE_NORM_QC_NO}, + {0xF9EB, UNICODE_NORM_QC_NO}, + {0xF9EC, UNICODE_NORM_QC_NO}, + {0xF9ED, UNICODE_NORM_QC_NO}, + {0xF9EE, UNICODE_NORM_QC_NO}, + {0xF9EF, UNICODE_NORM_QC_NO}, + {0xF9F0, UNICODE_NORM_QC_NO}, + {0xF9F1, UNICODE_NORM_QC_NO}, + {0xF9F2, UNICODE_NORM_QC_NO}, + {0xF9F3, UNICODE_NORM_QC_NO}, + {0xF9F4, UNICODE_NORM_QC_NO}, + {0xF9F5, UNICODE_NORM_QC_NO}, + {0xF9F6, UNICODE_NORM_QC_NO}, + {0xF9F7, UNICODE_NORM_QC_NO}, + {0xF9F8, UNICODE_NORM_QC_NO}, + {0xF9F9, UNICODE_NORM_QC_NO}, + {0xF9FA, UNICODE_NORM_QC_NO}, + {0xF9FB, UNICODE_NORM_QC_NO}, + {0xF9FC, UNICODE_NORM_QC_NO}, + {0xF9FD, UNICODE_NORM_QC_NO}, + {0xF9FE, UNICODE_NORM_QC_NO}, + {0xF9FF, UNICODE_NORM_QC_NO}, + {0xFA00, UNICODE_NORM_QC_NO}, + {0xFA01, UNICODE_NORM_QC_NO}, + {0xFA02, UNICODE_NORM_QC_NO}, + {0xFA03, UNICODE_NORM_QC_NO}, + {0xFA04, UNICODE_NORM_QC_NO}, + {0xFA05, UNICODE_NORM_QC_NO}, + {0xFA06, UNICODE_NORM_QC_NO}, + {0xFA07, UNICODE_NORM_QC_NO}, + {0xFA08, UNICODE_NORM_QC_NO}, + {0xFA09, UNICODE_NORM_QC_NO}, + {0xFA0A, UNICODE_NORM_QC_NO}, + {0xFA0B, UNICODE_NORM_QC_NO}, + {0xFA0C, UNICODE_NORM_QC_NO}, + {0xFA0D, UNICODE_NORM_QC_NO}, + {0xFA10, UNICODE_NORM_QC_NO}, + {0xFA12, UNICODE_NORM_QC_NO}, + {0xFA15, UNICODE_NORM_QC_NO}, + {0xFA16, UNICODE_NORM_QC_NO}, + {0xFA17, UNICODE_NORM_QC_NO}, + {0xFA18, UNICODE_NORM_QC_NO}, + {0xFA19, UNICODE_NORM_QC_NO}, + {0xFA1A, UNICODE_NORM_QC_NO}, + {0xFA1B, UNICODE_NORM_QC_NO}, + {0xFA1C, UNICODE_NORM_QC_NO}, + {0xFA1D, UNICODE_NORM_QC_NO}, + {0xFA1E, UNICODE_NORM_QC_NO}, + {0xFA20, UNICODE_NORM_QC_NO}, + {0xFA22, UNICODE_NORM_QC_NO}, + {0xFA25, UNICODE_NORM_QC_NO}, + {0xFA26, UNICODE_NORM_QC_NO}, + {0xFA2A, UNICODE_NORM_QC_NO}, + {0xFA2B, UNICODE_NORM_QC_NO}, + {0xFA2C, UNICODE_NORM_QC_NO}, + {0xFA2D, UNICODE_NORM_QC_NO}, + {0xFA2E, UNICODE_NORM_QC_NO}, + {0xFA2F, UNICODE_NORM_QC_NO}, + {0xFA30, UNICODE_NORM_QC_NO}, + {0xFA31, UNICODE_NORM_QC_NO}, + {0xFA32, UNICODE_NORM_QC_NO}, + {0xFA33, UNICODE_NORM_QC_NO}, + {0xFA34, UNICODE_NORM_QC_NO}, + {0xFA35, UNICODE_NORM_QC_NO}, + {0xFA36, UNICODE_NORM_QC_NO}, + {0xFA37, UNICODE_NORM_QC_NO}, + {0xFA38, UNICODE_NORM_QC_NO}, + {0xFA39, UNICODE_NORM_QC_NO}, + {0xFA3A, UNICODE_NORM_QC_NO}, + {0xFA3B, UNICODE_NORM_QC_NO}, + {0xFA3C, UNICODE_NORM_QC_NO}, + {0xFA3D, UNICODE_NORM_QC_NO}, + {0xFA3E, UNICODE_NORM_QC_NO}, + {0xFA3F, UNICODE_NORM_QC_NO}, + {0xFA40, UNICODE_NORM_QC_NO}, + {0xFA41, UNICODE_NORM_QC_NO}, + {0xFA42, UNICODE_NORM_QC_NO}, + {0xFA43, UNICODE_NORM_QC_NO}, + {0xFA44, UNICODE_NORM_QC_NO}, + {0xFA45, UNICODE_NORM_QC_NO}, + {0xFA46, UNICODE_NORM_QC_NO}, + {0xFA47, UNICODE_NORM_QC_NO}, + {0xFA48, UNICODE_NORM_QC_NO}, + {0xFA49, UNICODE_NORM_QC_NO}, + {0xFA4A, UNICODE_NORM_QC_NO}, + {0xFA4B, UNICODE_NORM_QC_NO}, + {0xFA4C, UNICODE_NORM_QC_NO}, + {0xFA4D, UNICODE_NORM_QC_NO}, + {0xFA4E, UNICODE_NORM_QC_NO}, + {0xFA4F, UNICODE_NORM_QC_NO}, + {0xFA50, UNICODE_NORM_QC_NO}, + {0xFA51, UNICODE_NORM_QC_NO}, + {0xFA52, UNICODE_NORM_QC_NO}, + {0xFA53, UNICODE_NORM_QC_NO}, + {0xFA54, UNICODE_NORM_QC_NO}, + {0xFA55, UNICODE_NORM_QC_NO}, + {0xFA56, UNICODE_NORM_QC_NO}, + {0xFA57, UNICODE_NORM_QC_NO}, + {0xFA58, UNICODE_NORM_QC_NO}, + {0xFA59, UNICODE_NORM_QC_NO}, + {0xFA5A, UNICODE_NORM_QC_NO}, + {0xFA5B, UNICODE_NORM_QC_NO}, + {0xFA5C, UNICODE_NORM_QC_NO}, + {0xFA5D, UNICODE_NORM_QC_NO}, + {0xFA5E, UNICODE_NORM_QC_NO}, + {0xFA5F, UNICODE_NORM_QC_NO}, + {0xFA60, UNICODE_NORM_QC_NO}, + {0xFA61, UNICODE_NORM_QC_NO}, + {0xFA62, UNICODE_NORM_QC_NO}, + {0xFA63, UNICODE_NORM_QC_NO}, + {0xFA64, UNICODE_NORM_QC_NO}, + {0xFA65, UNICODE_NORM_QC_NO}, + {0xFA66, UNICODE_NORM_QC_NO}, + {0xFA67, UNICODE_NORM_QC_NO}, + {0xFA68, UNICODE_NORM_QC_NO}, + {0xFA69, UNICODE_NORM_QC_NO}, + {0xFA6A, UNICODE_NORM_QC_NO}, + {0xFA6B, UNICODE_NORM_QC_NO}, + {0xFA6C, UNICODE_NORM_QC_NO}, + {0xFA6D, UNICODE_NORM_QC_NO}, + {0xFA70, UNICODE_NORM_QC_NO}, + {0xFA71, UNICODE_NORM_QC_NO}, + {0xFA72, UNICODE_NORM_QC_NO}, + {0xFA73, UNICODE_NORM_QC_NO}, + {0xFA74, UNICODE_NORM_QC_NO}, + {0xFA75, UNICODE_NORM_QC_NO}, + {0xFA76, UNICODE_NORM_QC_NO}, + {0xFA77, UNICODE_NORM_QC_NO}, + {0xFA78, UNICODE_NORM_QC_NO}, + {0xFA79, UNICODE_NORM_QC_NO}, + {0xFA7A, UNICODE_NORM_QC_NO}, + {0xFA7B, UNICODE_NORM_QC_NO}, + {0xFA7C, UNICODE_NORM_QC_NO}, + {0xFA7D, UNICODE_NORM_QC_NO}, + {0xFA7E, UNICODE_NORM_QC_NO}, + {0xFA7F, UNICODE_NORM_QC_NO}, + {0xFA80, UNICODE_NORM_QC_NO}, + {0xFA81, UNICODE_NORM_QC_NO}, + {0xFA82, UNICODE_NORM_QC_NO}, + {0xFA83, UNICODE_NORM_QC_NO}, + {0xFA84, UNICODE_NORM_QC_NO}, + {0xFA85, UNICODE_NORM_QC_NO}, + {0xFA86, UNICODE_NORM_QC_NO}, + {0xFA87, UNICODE_NORM_QC_NO}, + {0xFA88, UNICODE_NORM_QC_NO}, + {0xFA89, UNICODE_NORM_QC_NO}, + {0xFA8A, UNICODE_NORM_QC_NO}, + {0xFA8B, UNICODE_NORM_QC_NO}, + {0xFA8C, UNICODE_NORM_QC_NO}, + {0xFA8D, UNICODE_NORM_QC_NO}, + {0xFA8E, UNICODE_NORM_QC_NO}, + {0xFA8F, UNICODE_NORM_QC_NO}, + {0xFA90, UNICODE_NORM_QC_NO}, + {0xFA91, UNICODE_NORM_QC_NO}, + {0xFA92, UNICODE_NORM_QC_NO}, + {0xFA93, UNICODE_NORM_QC_NO}, + {0xFA94, UNICODE_NORM_QC_NO}, + {0xFA95, UNICODE_NORM_QC_NO}, + {0xFA96, UNICODE_NORM_QC_NO}, + {0xFA97, UNICODE_NORM_QC_NO}, + {0xFA98, UNICODE_NORM_QC_NO}, + {0xFA99, UNICODE_NORM_QC_NO}, + {0xFA9A, UNICODE_NORM_QC_NO}, + {0xFA9B, UNICODE_NORM_QC_NO}, + {0xFA9C, UNICODE_NORM_QC_NO}, + {0xFA9D, UNICODE_NORM_QC_NO}, + {0xFA9E, UNICODE_NORM_QC_NO}, + {0xFA9F, UNICODE_NORM_QC_NO}, + {0xFAA0, UNICODE_NORM_QC_NO}, + {0xFAA1, UNICODE_NORM_QC_NO}, + {0xFAA2, UNICODE_NORM_QC_NO}, + {0xFAA3, UNICODE_NORM_QC_NO}, + {0xFAA4, UNICODE_NORM_QC_NO}, + {0xFAA5, UNICODE_NORM_QC_NO}, + {0xFAA6, UNICODE_NORM_QC_NO}, + {0xFAA7, UNICODE_NORM_QC_NO}, + {0xFAA8, UNICODE_NORM_QC_NO}, + {0xFAA9, UNICODE_NORM_QC_NO}, + {0xFAAA, UNICODE_NORM_QC_NO}, + {0xFAAB, UNICODE_NORM_QC_NO}, + {0xFAAC, UNICODE_NORM_QC_NO}, + {0xFAAD, UNICODE_NORM_QC_NO}, + {0xFAAE, UNICODE_NORM_QC_NO}, + {0xFAAF, UNICODE_NORM_QC_NO}, + {0xFAB0, UNICODE_NORM_QC_NO}, + {0xFAB1, UNICODE_NORM_QC_NO}, + {0xFAB2, UNICODE_NORM_QC_NO}, + {0xFAB3, UNICODE_NORM_QC_NO}, + {0xFAB4, UNICODE_NORM_QC_NO}, + {0xFAB5, UNICODE_NORM_QC_NO}, + {0xFAB6, UNICODE_NORM_QC_NO}, + {0xFAB7, UNICODE_NORM_QC_NO}, + {0xFAB8, UNICODE_NORM_QC_NO}, + {0xFAB9, UNICODE_NORM_QC_NO}, + {0xFABA, UNICODE_NORM_QC_NO}, + {0xFABB, UNICODE_NORM_QC_NO}, + {0xFABC, UNICODE_NORM_QC_NO}, + {0xFABD, UNICODE_NORM_QC_NO}, + {0xFABE, UNICODE_NORM_QC_NO}, + {0xFABF, UNICODE_NORM_QC_NO}, + {0xFAC0, UNICODE_NORM_QC_NO}, + {0xFAC1, UNICODE_NORM_QC_NO}, + {0xFAC2, UNICODE_NORM_QC_NO}, + {0xFAC3, UNICODE_NORM_QC_NO}, + {0xFAC4, UNICODE_NORM_QC_NO}, + {0xFAC5, UNICODE_NORM_QC_NO}, + {0xFAC6, UNICODE_NORM_QC_NO}, + {0xFAC7, UNICODE_NORM_QC_NO}, + {0xFAC8, UNICODE_NORM_QC_NO}, + {0xFAC9, UNICODE_NORM_QC_NO}, + {0xFACA, UNICODE_NORM_QC_NO}, + {0xFACB, UNICODE_NORM_QC_NO}, + {0xFACC, UNICODE_NORM_QC_NO}, + {0xFACD, UNICODE_NORM_QC_NO}, + {0xFACE, UNICODE_NORM_QC_NO}, + {0xFACF, UNICODE_NORM_QC_NO}, + {0xFAD0, UNICODE_NORM_QC_NO}, + {0xFAD1, UNICODE_NORM_QC_NO}, + {0xFAD2, UNICODE_NORM_QC_NO}, + {0xFAD3, UNICODE_NORM_QC_NO}, + {0xFAD4, UNICODE_NORM_QC_NO}, + {0xFAD5, UNICODE_NORM_QC_NO}, + {0xFAD6, UNICODE_NORM_QC_NO}, + {0xFAD7, UNICODE_NORM_QC_NO}, + {0xFAD8, UNICODE_NORM_QC_NO}, + {0xFAD9, UNICODE_NORM_QC_NO}, + {0xFB00, UNICODE_NORM_QC_NO}, + {0xFB01, UNICODE_NORM_QC_NO}, + {0xFB02, UNICODE_NORM_QC_NO}, + {0xFB03, UNICODE_NORM_QC_NO}, + {0xFB04, UNICODE_NORM_QC_NO}, + {0xFB05, UNICODE_NORM_QC_NO}, + {0xFB06, UNICODE_NORM_QC_NO}, + {0xFB13, UNICODE_NORM_QC_NO}, + {0xFB14, UNICODE_NORM_QC_NO}, + {0xFB15, UNICODE_NORM_QC_NO}, + {0xFB16, UNICODE_NORM_QC_NO}, + {0xFB17, UNICODE_NORM_QC_NO}, + {0xFB1D, UNICODE_NORM_QC_NO}, + {0xFB1F, UNICODE_NORM_QC_NO}, + {0xFB20, UNICODE_NORM_QC_NO}, + {0xFB21, UNICODE_NORM_QC_NO}, + {0xFB22, UNICODE_NORM_QC_NO}, + {0xFB23, UNICODE_NORM_QC_NO}, + {0xFB24, UNICODE_NORM_QC_NO}, + {0xFB25, UNICODE_NORM_QC_NO}, + {0xFB26, UNICODE_NORM_QC_NO}, + {0xFB27, UNICODE_NORM_QC_NO}, + {0xFB28, UNICODE_NORM_QC_NO}, + {0xFB29, UNICODE_NORM_QC_NO}, + {0xFB2A, UNICODE_NORM_QC_NO}, + {0xFB2B, UNICODE_NORM_QC_NO}, + {0xFB2C, UNICODE_NORM_QC_NO}, + {0xFB2D, UNICODE_NORM_QC_NO}, + {0xFB2E, UNICODE_NORM_QC_NO}, + {0xFB2F, UNICODE_NORM_QC_NO}, + {0xFB30, UNICODE_NORM_QC_NO}, + {0xFB31, UNICODE_NORM_QC_NO}, + {0xFB32, UNICODE_NORM_QC_NO}, + {0xFB33, UNICODE_NORM_QC_NO}, + {0xFB34, UNICODE_NORM_QC_NO}, + {0xFB35, UNICODE_NORM_QC_NO}, + {0xFB36, UNICODE_NORM_QC_NO}, + {0xFB38, UNICODE_NORM_QC_NO}, + {0xFB39, UNICODE_NORM_QC_NO}, + {0xFB3A, UNICODE_NORM_QC_NO}, + {0xFB3B, UNICODE_NORM_QC_NO}, + {0xFB3C, UNICODE_NORM_QC_NO}, + {0xFB3E, UNICODE_NORM_QC_NO}, + {0xFB40, UNICODE_NORM_QC_NO}, + {0xFB41, UNICODE_NORM_QC_NO}, + {0xFB43, UNICODE_NORM_QC_NO}, + {0xFB44, UNICODE_NORM_QC_NO}, + {0xFB46, UNICODE_NORM_QC_NO}, + {0xFB47, UNICODE_NORM_QC_NO}, + {0xFB48, UNICODE_NORM_QC_NO}, + {0xFB49, UNICODE_NORM_QC_NO}, + {0xFB4A, UNICODE_NORM_QC_NO}, + {0xFB4B, UNICODE_NORM_QC_NO}, + {0xFB4C, UNICODE_NORM_QC_NO}, + {0xFB4D, UNICODE_NORM_QC_NO}, + {0xFB4E, UNICODE_NORM_QC_NO}, + {0xFB4F, UNICODE_NORM_QC_NO}, + {0xFB50, UNICODE_NORM_QC_NO}, + {0xFB51, UNICODE_NORM_QC_NO}, + {0xFB52, UNICODE_NORM_QC_NO}, + {0xFB53, UNICODE_NORM_QC_NO}, + {0xFB54, UNICODE_NORM_QC_NO}, + {0xFB55, UNICODE_NORM_QC_NO}, + {0xFB56, UNICODE_NORM_QC_NO}, + {0xFB57, UNICODE_NORM_QC_NO}, + {0xFB58, UNICODE_NORM_QC_NO}, + {0xFB59, UNICODE_NORM_QC_NO}, + {0xFB5A, UNICODE_NORM_QC_NO}, + {0xFB5B, UNICODE_NORM_QC_NO}, + {0xFB5C, UNICODE_NORM_QC_NO}, + {0xFB5D, UNICODE_NORM_QC_NO}, + {0xFB5E, UNICODE_NORM_QC_NO}, + {0xFB5F, UNICODE_NORM_QC_NO}, + {0xFB60, UNICODE_NORM_QC_NO}, + {0xFB61, UNICODE_NORM_QC_NO}, + {0xFB62, UNICODE_NORM_QC_NO}, + {0xFB63, UNICODE_NORM_QC_NO}, + {0xFB64, UNICODE_NORM_QC_NO}, + {0xFB65, UNICODE_NORM_QC_NO}, + {0xFB66, UNICODE_NORM_QC_NO}, + {0xFB67, UNICODE_NORM_QC_NO}, + {0xFB68, UNICODE_NORM_QC_NO}, + {0xFB69, UNICODE_NORM_QC_NO}, + {0xFB6A, UNICODE_NORM_QC_NO}, + {0xFB6B, UNICODE_NORM_QC_NO}, + {0xFB6C, UNICODE_NORM_QC_NO}, + {0xFB6D, UNICODE_NORM_QC_NO}, + {0xFB6E, UNICODE_NORM_QC_NO}, + {0xFB6F, UNICODE_NORM_QC_NO}, + {0xFB70, UNICODE_NORM_QC_NO}, + {0xFB71, UNICODE_NORM_QC_NO}, + {0xFB72, UNICODE_NORM_QC_NO}, + {0xFB73, UNICODE_NORM_QC_NO}, + {0xFB74, UNICODE_NORM_QC_NO}, + {0xFB75, UNICODE_NORM_QC_NO}, + {0xFB76, UNICODE_NORM_QC_NO}, + {0xFB77, UNICODE_NORM_QC_NO}, + {0xFB78, UNICODE_NORM_QC_NO}, + {0xFB79, UNICODE_NORM_QC_NO}, + {0xFB7A, UNICODE_NORM_QC_NO}, + {0xFB7B, UNICODE_NORM_QC_NO}, + {0xFB7C, UNICODE_NORM_QC_NO}, + {0xFB7D, UNICODE_NORM_QC_NO}, + {0xFB7E, UNICODE_NORM_QC_NO}, + {0xFB7F, UNICODE_NORM_QC_NO}, + {0xFB80, UNICODE_NORM_QC_NO}, + {0xFB81, UNICODE_NORM_QC_NO}, + {0xFB82, UNICODE_NORM_QC_NO}, + {0xFB83, UNICODE_NORM_QC_NO}, + {0xFB84, UNICODE_NORM_QC_NO}, + {0xFB85, UNICODE_NORM_QC_NO}, + {0xFB86, UNICODE_NORM_QC_NO}, + {0xFB87, UNICODE_NORM_QC_NO}, + {0xFB88, UNICODE_NORM_QC_NO}, + {0xFB89, UNICODE_NORM_QC_NO}, + {0xFB8A, UNICODE_NORM_QC_NO}, + {0xFB8B, UNICODE_NORM_QC_NO}, + {0xFB8C, UNICODE_NORM_QC_NO}, + {0xFB8D, UNICODE_NORM_QC_NO}, + {0xFB8E, UNICODE_NORM_QC_NO}, + {0xFB8F, UNICODE_NORM_QC_NO}, + {0xFB90, UNICODE_NORM_QC_NO}, + {0xFB91, UNICODE_NORM_QC_NO}, + {0xFB92, UNICODE_NORM_QC_NO}, + {0xFB93, UNICODE_NORM_QC_NO}, + {0xFB94, UNICODE_NORM_QC_NO}, + {0xFB95, UNICODE_NORM_QC_NO}, + {0xFB96, UNICODE_NORM_QC_NO}, + {0xFB97, UNICODE_NORM_QC_NO}, + {0xFB98, UNICODE_NORM_QC_NO}, + {0xFB99, UNICODE_NORM_QC_NO}, + {0xFB9A, UNICODE_NORM_QC_NO}, + {0xFB9B, UNICODE_NORM_QC_NO}, + {0xFB9C, UNICODE_NORM_QC_NO}, + {0xFB9D, UNICODE_NORM_QC_NO}, + {0xFB9E, UNICODE_NORM_QC_NO}, + {0xFB9F, UNICODE_NORM_QC_NO}, + {0xFBA0, UNICODE_NORM_QC_NO}, + {0xFBA1, UNICODE_NORM_QC_NO}, + {0xFBA2, UNICODE_NORM_QC_NO}, + {0xFBA3, UNICODE_NORM_QC_NO}, + {0xFBA4, UNICODE_NORM_QC_NO}, + {0xFBA5, UNICODE_NORM_QC_NO}, + {0xFBA6, UNICODE_NORM_QC_NO}, + {0xFBA7, UNICODE_NORM_QC_NO}, + {0xFBA8, UNICODE_NORM_QC_NO}, + {0xFBA9, UNICODE_NORM_QC_NO}, + {0xFBAA, UNICODE_NORM_QC_NO}, + {0xFBAB, UNICODE_NORM_QC_NO}, + {0xFBAC, UNICODE_NORM_QC_NO}, + {0xFBAD, UNICODE_NORM_QC_NO}, + {0xFBAE, UNICODE_NORM_QC_NO}, + {0xFBAF, UNICODE_NORM_QC_NO}, + {0xFBB0, UNICODE_NORM_QC_NO}, + {0xFBB1, UNICODE_NORM_QC_NO}, + {0xFBD3, UNICODE_NORM_QC_NO}, + {0xFBD4, UNICODE_NORM_QC_NO}, + {0xFBD5, UNICODE_NORM_QC_NO}, + {0xFBD6, UNICODE_NORM_QC_NO}, + {0xFBD7, UNICODE_NORM_QC_NO}, + {0xFBD8, UNICODE_NORM_QC_NO}, + {0xFBD9, UNICODE_NORM_QC_NO}, + {0xFBDA, UNICODE_NORM_QC_NO}, + {0xFBDB, UNICODE_NORM_QC_NO}, + {0xFBDC, UNICODE_NORM_QC_NO}, + {0xFBDD, UNICODE_NORM_QC_NO}, + {0xFBDE, UNICODE_NORM_QC_NO}, + {0xFBDF, UNICODE_NORM_QC_NO}, + {0xFBE0, UNICODE_NORM_QC_NO}, + {0xFBE1, UNICODE_NORM_QC_NO}, + {0xFBE2, UNICODE_NORM_QC_NO}, + {0xFBE3, UNICODE_NORM_QC_NO}, + {0xFBE4, UNICODE_NORM_QC_NO}, + {0xFBE5, UNICODE_NORM_QC_NO}, + {0xFBE6, UNICODE_NORM_QC_NO}, + {0xFBE7, UNICODE_NORM_QC_NO}, + {0xFBE8, UNICODE_NORM_QC_NO}, + {0xFBE9, UNICODE_NORM_QC_NO}, + {0xFBEA, UNICODE_NORM_QC_NO}, + {0xFBEB, UNICODE_NORM_QC_NO}, + {0xFBEC, UNICODE_NORM_QC_NO}, + {0xFBED, UNICODE_NORM_QC_NO}, + {0xFBEE, UNICODE_NORM_QC_NO}, + {0xFBEF, UNICODE_NORM_QC_NO}, + {0xFBF0, UNICODE_NORM_QC_NO}, + {0xFBF1, UNICODE_NORM_QC_NO}, + {0xFBF2, UNICODE_NORM_QC_NO}, + {0xFBF3, UNICODE_NORM_QC_NO}, + {0xFBF4, UNICODE_NORM_QC_NO}, + {0xFBF5, UNICODE_NORM_QC_NO}, + {0xFBF6, UNICODE_NORM_QC_NO}, + {0xFBF7, UNICODE_NORM_QC_NO}, + {0xFBF8, UNICODE_NORM_QC_NO}, + {0xFBF9, UNICODE_NORM_QC_NO}, + {0xFBFA, UNICODE_NORM_QC_NO}, + {0xFBFB, UNICODE_NORM_QC_NO}, + {0xFBFC, UNICODE_NORM_QC_NO}, + {0xFBFD, UNICODE_NORM_QC_NO}, + {0xFBFE, UNICODE_NORM_QC_NO}, + {0xFBFF, UNICODE_NORM_QC_NO}, + {0xFC00, UNICODE_NORM_QC_NO}, + {0xFC01, UNICODE_NORM_QC_NO}, + {0xFC02, UNICODE_NORM_QC_NO}, + {0xFC03, UNICODE_NORM_QC_NO}, + {0xFC04, UNICODE_NORM_QC_NO}, + {0xFC05, UNICODE_NORM_QC_NO}, + {0xFC06, UNICODE_NORM_QC_NO}, + {0xFC07, UNICODE_NORM_QC_NO}, + {0xFC08, UNICODE_NORM_QC_NO}, + {0xFC09, UNICODE_NORM_QC_NO}, + {0xFC0A, UNICODE_NORM_QC_NO}, + {0xFC0B, UNICODE_NORM_QC_NO}, + {0xFC0C, UNICODE_NORM_QC_NO}, + {0xFC0D, UNICODE_NORM_QC_NO}, + {0xFC0E, UNICODE_NORM_QC_NO}, + {0xFC0F, UNICODE_NORM_QC_NO}, + {0xFC10, UNICODE_NORM_QC_NO}, + {0xFC11, UNICODE_NORM_QC_NO}, + {0xFC12, UNICODE_NORM_QC_NO}, + {0xFC13, UNICODE_NORM_QC_NO}, + {0xFC14, UNICODE_NORM_QC_NO}, + {0xFC15, UNICODE_NORM_QC_NO}, + {0xFC16, UNICODE_NORM_QC_NO}, + {0xFC17, UNICODE_NORM_QC_NO}, + {0xFC18, UNICODE_NORM_QC_NO}, + {0xFC19, UNICODE_NORM_QC_NO}, + {0xFC1A, UNICODE_NORM_QC_NO}, + {0xFC1B, UNICODE_NORM_QC_NO}, + {0xFC1C, UNICODE_NORM_QC_NO}, + {0xFC1D, UNICODE_NORM_QC_NO}, + {0xFC1E, UNICODE_NORM_QC_NO}, + {0xFC1F, UNICODE_NORM_QC_NO}, + {0xFC20, UNICODE_NORM_QC_NO}, + {0xFC21, UNICODE_NORM_QC_NO}, + {0xFC22, UNICODE_NORM_QC_NO}, + {0xFC23, UNICODE_NORM_QC_NO}, + {0xFC24, UNICODE_NORM_QC_NO}, + {0xFC25, UNICODE_NORM_QC_NO}, + {0xFC26, UNICODE_NORM_QC_NO}, + {0xFC27, UNICODE_NORM_QC_NO}, + {0xFC28, UNICODE_NORM_QC_NO}, + {0xFC29, UNICODE_NORM_QC_NO}, + {0xFC2A, UNICODE_NORM_QC_NO}, + {0xFC2B, UNICODE_NORM_QC_NO}, + {0xFC2C, UNICODE_NORM_QC_NO}, + {0xFC2D, UNICODE_NORM_QC_NO}, + {0xFC2E, UNICODE_NORM_QC_NO}, + {0xFC2F, UNICODE_NORM_QC_NO}, + {0xFC30, UNICODE_NORM_QC_NO}, + {0xFC31, UNICODE_NORM_QC_NO}, + {0xFC32, UNICODE_NORM_QC_NO}, + {0xFC33, UNICODE_NORM_QC_NO}, + {0xFC34, UNICODE_NORM_QC_NO}, + {0xFC35, UNICODE_NORM_QC_NO}, + {0xFC36, UNICODE_NORM_QC_NO}, + {0xFC37, UNICODE_NORM_QC_NO}, + {0xFC38, UNICODE_NORM_QC_NO}, + {0xFC39, UNICODE_NORM_QC_NO}, + {0xFC3A, UNICODE_NORM_QC_NO}, + {0xFC3B, UNICODE_NORM_QC_NO}, + {0xFC3C, UNICODE_NORM_QC_NO}, + {0xFC3D, UNICODE_NORM_QC_NO}, + {0xFC3E, UNICODE_NORM_QC_NO}, + {0xFC3F, UNICODE_NORM_QC_NO}, + {0xFC40, UNICODE_NORM_QC_NO}, + {0xFC41, UNICODE_NORM_QC_NO}, + {0xFC42, UNICODE_NORM_QC_NO}, + {0xFC43, UNICODE_NORM_QC_NO}, + {0xFC44, UNICODE_NORM_QC_NO}, + {0xFC45, UNICODE_NORM_QC_NO}, + {0xFC46, UNICODE_NORM_QC_NO}, + {0xFC47, UNICODE_NORM_QC_NO}, + {0xFC48, UNICODE_NORM_QC_NO}, + {0xFC49, UNICODE_NORM_QC_NO}, + {0xFC4A, UNICODE_NORM_QC_NO}, + {0xFC4B, UNICODE_NORM_QC_NO}, + {0xFC4C, UNICODE_NORM_QC_NO}, + {0xFC4D, UNICODE_NORM_QC_NO}, + {0xFC4E, UNICODE_NORM_QC_NO}, + {0xFC4F, UNICODE_NORM_QC_NO}, + {0xFC50, UNICODE_NORM_QC_NO}, + {0xFC51, UNICODE_NORM_QC_NO}, + {0xFC52, UNICODE_NORM_QC_NO}, + {0xFC53, UNICODE_NORM_QC_NO}, + {0xFC54, UNICODE_NORM_QC_NO}, + {0xFC55, UNICODE_NORM_QC_NO}, + {0xFC56, UNICODE_NORM_QC_NO}, + {0xFC57, UNICODE_NORM_QC_NO}, + {0xFC58, UNICODE_NORM_QC_NO}, + {0xFC59, UNICODE_NORM_QC_NO}, + {0xFC5A, UNICODE_NORM_QC_NO}, + {0xFC5B, UNICODE_NORM_QC_NO}, + {0xFC5C, UNICODE_NORM_QC_NO}, + {0xFC5D, UNICODE_NORM_QC_NO}, + {0xFC5E, UNICODE_NORM_QC_NO}, + {0xFC5F, UNICODE_NORM_QC_NO}, + {0xFC60, UNICODE_NORM_QC_NO}, + {0xFC61, UNICODE_NORM_QC_NO}, + {0xFC62, UNICODE_NORM_QC_NO}, + {0xFC63, UNICODE_NORM_QC_NO}, + {0xFC64, UNICODE_NORM_QC_NO}, + {0xFC65, UNICODE_NORM_QC_NO}, + {0xFC66, UNICODE_NORM_QC_NO}, + {0xFC67, UNICODE_NORM_QC_NO}, + {0xFC68, UNICODE_NORM_QC_NO}, + {0xFC69, UNICODE_NORM_QC_NO}, + {0xFC6A, UNICODE_NORM_QC_NO}, + {0xFC6B, UNICODE_NORM_QC_NO}, + {0xFC6C, UNICODE_NORM_QC_NO}, + {0xFC6D, UNICODE_NORM_QC_NO}, + {0xFC6E, UNICODE_NORM_QC_NO}, + {0xFC6F, UNICODE_NORM_QC_NO}, + {0xFC70, UNICODE_NORM_QC_NO}, + {0xFC71, UNICODE_NORM_QC_NO}, + {0xFC72, UNICODE_NORM_QC_NO}, + {0xFC73, UNICODE_NORM_QC_NO}, + {0xFC74, UNICODE_NORM_QC_NO}, + {0xFC75, UNICODE_NORM_QC_NO}, + {0xFC76, UNICODE_NORM_QC_NO}, + {0xFC77, UNICODE_NORM_QC_NO}, + {0xFC78, UNICODE_NORM_QC_NO}, + {0xFC79, UNICODE_NORM_QC_NO}, + {0xFC7A, UNICODE_NORM_QC_NO}, + {0xFC7B, UNICODE_NORM_QC_NO}, + {0xFC7C, UNICODE_NORM_QC_NO}, + {0xFC7D, UNICODE_NORM_QC_NO}, + {0xFC7E, UNICODE_NORM_QC_NO}, + {0xFC7F, UNICODE_NORM_QC_NO}, + {0xFC80, UNICODE_NORM_QC_NO}, + {0xFC81, UNICODE_NORM_QC_NO}, + {0xFC82, UNICODE_NORM_QC_NO}, + {0xFC83, UNICODE_NORM_QC_NO}, + {0xFC84, UNICODE_NORM_QC_NO}, + {0xFC85, UNICODE_NORM_QC_NO}, + {0xFC86, UNICODE_NORM_QC_NO}, + {0xFC87, UNICODE_NORM_QC_NO}, + {0xFC88, UNICODE_NORM_QC_NO}, + {0xFC89, UNICODE_NORM_QC_NO}, + {0xFC8A, UNICODE_NORM_QC_NO}, + {0xFC8B, UNICODE_NORM_QC_NO}, + {0xFC8C, UNICODE_NORM_QC_NO}, + {0xFC8D, UNICODE_NORM_QC_NO}, + {0xFC8E, UNICODE_NORM_QC_NO}, + {0xFC8F, UNICODE_NORM_QC_NO}, + {0xFC90, UNICODE_NORM_QC_NO}, + {0xFC91, UNICODE_NORM_QC_NO}, + {0xFC92, UNICODE_NORM_QC_NO}, + {0xFC93, UNICODE_NORM_QC_NO}, + {0xFC94, UNICODE_NORM_QC_NO}, + {0xFC95, UNICODE_NORM_QC_NO}, + {0xFC96, UNICODE_NORM_QC_NO}, + {0xFC97, UNICODE_NORM_QC_NO}, + {0xFC98, UNICODE_NORM_QC_NO}, + {0xFC99, UNICODE_NORM_QC_NO}, + {0xFC9A, UNICODE_NORM_QC_NO}, + {0xFC9B, UNICODE_NORM_QC_NO}, + {0xFC9C, UNICODE_NORM_QC_NO}, + {0xFC9D, UNICODE_NORM_QC_NO}, + {0xFC9E, UNICODE_NORM_QC_NO}, + {0xFC9F, UNICODE_NORM_QC_NO}, + {0xFCA0, UNICODE_NORM_QC_NO}, + {0xFCA1, UNICODE_NORM_QC_NO}, + {0xFCA2, UNICODE_NORM_QC_NO}, + {0xFCA3, UNICODE_NORM_QC_NO}, + {0xFCA4, UNICODE_NORM_QC_NO}, + {0xFCA5, UNICODE_NORM_QC_NO}, + {0xFCA6, UNICODE_NORM_QC_NO}, + {0xFCA7, UNICODE_NORM_QC_NO}, + {0xFCA8, UNICODE_NORM_QC_NO}, + {0xFCA9, UNICODE_NORM_QC_NO}, + {0xFCAA, UNICODE_NORM_QC_NO}, + {0xFCAB, UNICODE_NORM_QC_NO}, + {0xFCAC, UNICODE_NORM_QC_NO}, + {0xFCAD, UNICODE_NORM_QC_NO}, + {0xFCAE, UNICODE_NORM_QC_NO}, + {0xFCAF, UNICODE_NORM_QC_NO}, + {0xFCB0, UNICODE_NORM_QC_NO}, + {0xFCB1, UNICODE_NORM_QC_NO}, + {0xFCB2, UNICODE_NORM_QC_NO}, + {0xFCB3, UNICODE_NORM_QC_NO}, + {0xFCB4, UNICODE_NORM_QC_NO}, + {0xFCB5, UNICODE_NORM_QC_NO}, + {0xFCB6, UNICODE_NORM_QC_NO}, + {0xFCB7, UNICODE_NORM_QC_NO}, + {0xFCB8, UNICODE_NORM_QC_NO}, + {0xFCB9, UNICODE_NORM_QC_NO}, + {0xFCBA, UNICODE_NORM_QC_NO}, + {0xFCBB, UNICODE_NORM_QC_NO}, + {0xFCBC, UNICODE_NORM_QC_NO}, + {0xFCBD, UNICODE_NORM_QC_NO}, + {0xFCBE, UNICODE_NORM_QC_NO}, + {0xFCBF, UNICODE_NORM_QC_NO}, + {0xFCC0, UNICODE_NORM_QC_NO}, + {0xFCC1, UNICODE_NORM_QC_NO}, + {0xFCC2, UNICODE_NORM_QC_NO}, + {0xFCC3, UNICODE_NORM_QC_NO}, + {0xFCC4, UNICODE_NORM_QC_NO}, + {0xFCC5, UNICODE_NORM_QC_NO}, + {0xFCC6, UNICODE_NORM_QC_NO}, + {0xFCC7, UNICODE_NORM_QC_NO}, + {0xFCC8, UNICODE_NORM_QC_NO}, + {0xFCC9, UNICODE_NORM_QC_NO}, + {0xFCCA, UNICODE_NORM_QC_NO}, + {0xFCCB, UNICODE_NORM_QC_NO}, + {0xFCCC, UNICODE_NORM_QC_NO}, + {0xFCCD, UNICODE_NORM_QC_NO}, + {0xFCCE, UNICODE_NORM_QC_NO}, + {0xFCCF, UNICODE_NORM_QC_NO}, + {0xFCD0, UNICODE_NORM_QC_NO}, + {0xFCD1, UNICODE_NORM_QC_NO}, + {0xFCD2, UNICODE_NORM_QC_NO}, + {0xFCD3, UNICODE_NORM_QC_NO}, + {0xFCD4, UNICODE_NORM_QC_NO}, + {0xFCD5, UNICODE_NORM_QC_NO}, + {0xFCD6, UNICODE_NORM_QC_NO}, + {0xFCD7, UNICODE_NORM_QC_NO}, + {0xFCD8, UNICODE_NORM_QC_NO}, + {0xFCD9, UNICODE_NORM_QC_NO}, + {0xFCDA, UNICODE_NORM_QC_NO}, + {0xFCDB, UNICODE_NORM_QC_NO}, + {0xFCDC, UNICODE_NORM_QC_NO}, + {0xFCDD, UNICODE_NORM_QC_NO}, + {0xFCDE, UNICODE_NORM_QC_NO}, + {0xFCDF, UNICODE_NORM_QC_NO}, + {0xFCE0, UNICODE_NORM_QC_NO}, + {0xFCE1, UNICODE_NORM_QC_NO}, + {0xFCE2, UNICODE_NORM_QC_NO}, + {0xFCE3, UNICODE_NORM_QC_NO}, + {0xFCE4, UNICODE_NORM_QC_NO}, + {0xFCE5, UNICODE_NORM_QC_NO}, + {0xFCE6, UNICODE_NORM_QC_NO}, + {0xFCE7, UNICODE_NORM_QC_NO}, + {0xFCE8, UNICODE_NORM_QC_NO}, + {0xFCE9, UNICODE_NORM_QC_NO}, + {0xFCEA, UNICODE_NORM_QC_NO}, + {0xFCEB, UNICODE_NORM_QC_NO}, + {0xFCEC, UNICODE_NORM_QC_NO}, + {0xFCED, UNICODE_NORM_QC_NO}, + {0xFCEE, UNICODE_NORM_QC_NO}, + {0xFCEF, UNICODE_NORM_QC_NO}, + {0xFCF0, UNICODE_NORM_QC_NO}, + {0xFCF1, UNICODE_NORM_QC_NO}, + {0xFCF2, UNICODE_NORM_QC_NO}, + {0xFCF3, UNICODE_NORM_QC_NO}, + {0xFCF4, UNICODE_NORM_QC_NO}, + {0xFCF5, UNICODE_NORM_QC_NO}, + {0xFCF6, UNICODE_NORM_QC_NO}, + {0xFCF7, UNICODE_NORM_QC_NO}, + {0xFCF8, UNICODE_NORM_QC_NO}, + {0xFCF9, UNICODE_NORM_QC_NO}, + {0xFCFA, UNICODE_NORM_QC_NO}, + {0xFCFB, UNICODE_NORM_QC_NO}, + {0xFCFC, UNICODE_NORM_QC_NO}, + {0xFCFD, UNICODE_NORM_QC_NO}, + {0xFCFE, UNICODE_NORM_QC_NO}, + {0xFCFF, UNICODE_NORM_QC_NO}, + {0xFD00, UNICODE_NORM_QC_NO}, + {0xFD01, UNICODE_NORM_QC_NO}, + {0xFD02, UNICODE_NORM_QC_NO}, + {0xFD03, UNICODE_NORM_QC_NO}, + {0xFD04, UNICODE_NORM_QC_NO}, + {0xFD05, UNICODE_NORM_QC_NO}, + {0xFD06, UNICODE_NORM_QC_NO}, + {0xFD07, UNICODE_NORM_QC_NO}, + {0xFD08, UNICODE_NORM_QC_NO}, + {0xFD09, UNICODE_NORM_QC_NO}, + {0xFD0A, UNICODE_NORM_QC_NO}, + {0xFD0B, UNICODE_NORM_QC_NO}, + {0xFD0C, UNICODE_NORM_QC_NO}, + {0xFD0D, UNICODE_NORM_QC_NO}, + {0xFD0E, UNICODE_NORM_QC_NO}, + {0xFD0F, UNICODE_NORM_QC_NO}, + {0xFD10, UNICODE_NORM_QC_NO}, + {0xFD11, UNICODE_NORM_QC_NO}, + {0xFD12, UNICODE_NORM_QC_NO}, + {0xFD13, UNICODE_NORM_QC_NO}, + {0xFD14, UNICODE_NORM_QC_NO}, + {0xFD15, UNICODE_NORM_QC_NO}, + {0xFD16, UNICODE_NORM_QC_NO}, + {0xFD17, UNICODE_NORM_QC_NO}, + {0xFD18, UNICODE_NORM_QC_NO}, + {0xFD19, UNICODE_NORM_QC_NO}, + {0xFD1A, UNICODE_NORM_QC_NO}, + {0xFD1B, UNICODE_NORM_QC_NO}, + {0xFD1C, UNICODE_NORM_QC_NO}, + {0xFD1D, UNICODE_NORM_QC_NO}, + {0xFD1E, UNICODE_NORM_QC_NO}, + {0xFD1F, UNICODE_NORM_QC_NO}, + {0xFD20, UNICODE_NORM_QC_NO}, + {0xFD21, UNICODE_NORM_QC_NO}, + {0xFD22, UNICODE_NORM_QC_NO}, + {0xFD23, UNICODE_NORM_QC_NO}, + {0xFD24, UNICODE_NORM_QC_NO}, + {0xFD25, UNICODE_NORM_QC_NO}, + {0xFD26, UNICODE_NORM_QC_NO}, + {0xFD27, UNICODE_NORM_QC_NO}, + {0xFD28, UNICODE_NORM_QC_NO}, + {0xFD29, UNICODE_NORM_QC_NO}, + {0xFD2A, UNICODE_NORM_QC_NO}, + {0xFD2B, UNICODE_NORM_QC_NO}, + {0xFD2C, UNICODE_NORM_QC_NO}, + {0xFD2D, UNICODE_NORM_QC_NO}, + {0xFD2E, UNICODE_NORM_QC_NO}, + {0xFD2F, UNICODE_NORM_QC_NO}, + {0xFD30, UNICODE_NORM_QC_NO}, + {0xFD31, UNICODE_NORM_QC_NO}, + {0xFD32, UNICODE_NORM_QC_NO}, + {0xFD33, UNICODE_NORM_QC_NO}, + {0xFD34, UNICODE_NORM_QC_NO}, + {0xFD35, UNICODE_NORM_QC_NO}, + {0xFD36, UNICODE_NORM_QC_NO}, + {0xFD37, UNICODE_NORM_QC_NO}, + {0xFD38, UNICODE_NORM_QC_NO}, + {0xFD39, UNICODE_NORM_QC_NO}, + {0xFD3A, UNICODE_NORM_QC_NO}, + {0xFD3B, UNICODE_NORM_QC_NO}, + {0xFD3C, UNICODE_NORM_QC_NO}, + {0xFD3D, UNICODE_NORM_QC_NO}, + {0xFD50, UNICODE_NORM_QC_NO}, + {0xFD51, UNICODE_NORM_QC_NO}, + {0xFD52, UNICODE_NORM_QC_NO}, + {0xFD53, UNICODE_NORM_QC_NO}, + {0xFD54, UNICODE_NORM_QC_NO}, + {0xFD55, UNICODE_NORM_QC_NO}, + {0xFD56, UNICODE_NORM_QC_NO}, + {0xFD57, UNICODE_NORM_QC_NO}, + {0xFD58, UNICODE_NORM_QC_NO}, + {0xFD59, UNICODE_NORM_QC_NO}, + {0xFD5A, UNICODE_NORM_QC_NO}, + {0xFD5B, UNICODE_NORM_QC_NO}, + {0xFD5C, UNICODE_NORM_QC_NO}, + {0xFD5D, UNICODE_NORM_QC_NO}, + {0xFD5E, UNICODE_NORM_QC_NO}, + {0xFD5F, UNICODE_NORM_QC_NO}, + {0xFD60, UNICODE_NORM_QC_NO}, + {0xFD61, UNICODE_NORM_QC_NO}, + {0xFD62, UNICODE_NORM_QC_NO}, + {0xFD63, UNICODE_NORM_QC_NO}, + {0xFD64, UNICODE_NORM_QC_NO}, + {0xFD65, UNICODE_NORM_QC_NO}, + {0xFD66, UNICODE_NORM_QC_NO}, + {0xFD67, UNICODE_NORM_QC_NO}, + {0xFD68, UNICODE_NORM_QC_NO}, + {0xFD69, UNICODE_NORM_QC_NO}, + {0xFD6A, UNICODE_NORM_QC_NO}, + {0xFD6B, UNICODE_NORM_QC_NO}, + {0xFD6C, UNICODE_NORM_QC_NO}, + {0xFD6D, UNICODE_NORM_QC_NO}, + {0xFD6E, UNICODE_NORM_QC_NO}, + {0xFD6F, UNICODE_NORM_QC_NO}, + {0xFD70, UNICODE_NORM_QC_NO}, + {0xFD71, UNICODE_NORM_QC_NO}, + {0xFD72, UNICODE_NORM_QC_NO}, + {0xFD73, UNICODE_NORM_QC_NO}, + {0xFD74, UNICODE_NORM_QC_NO}, + {0xFD75, UNICODE_NORM_QC_NO}, + {0xFD76, UNICODE_NORM_QC_NO}, + {0xFD77, UNICODE_NORM_QC_NO}, + {0xFD78, UNICODE_NORM_QC_NO}, + {0xFD79, UNICODE_NORM_QC_NO}, + {0xFD7A, UNICODE_NORM_QC_NO}, + {0xFD7B, UNICODE_NORM_QC_NO}, + {0xFD7C, UNICODE_NORM_QC_NO}, + {0xFD7D, UNICODE_NORM_QC_NO}, + {0xFD7E, UNICODE_NORM_QC_NO}, + {0xFD7F, UNICODE_NORM_QC_NO}, + {0xFD80, UNICODE_NORM_QC_NO}, + {0xFD81, UNICODE_NORM_QC_NO}, + {0xFD82, UNICODE_NORM_QC_NO}, + {0xFD83, UNICODE_NORM_QC_NO}, + {0xFD84, UNICODE_NORM_QC_NO}, + {0xFD85, UNICODE_NORM_QC_NO}, + {0xFD86, UNICODE_NORM_QC_NO}, + {0xFD87, UNICODE_NORM_QC_NO}, + {0xFD88, UNICODE_NORM_QC_NO}, + {0xFD89, UNICODE_NORM_QC_NO}, + {0xFD8A, UNICODE_NORM_QC_NO}, + {0xFD8B, UNICODE_NORM_QC_NO}, + {0xFD8C, UNICODE_NORM_QC_NO}, + {0xFD8D, UNICODE_NORM_QC_NO}, + {0xFD8E, UNICODE_NORM_QC_NO}, + {0xFD8F, UNICODE_NORM_QC_NO}, + {0xFD92, UNICODE_NORM_QC_NO}, + {0xFD93, UNICODE_NORM_QC_NO}, + {0xFD94, UNICODE_NORM_QC_NO}, + {0xFD95, UNICODE_NORM_QC_NO}, + {0xFD96, UNICODE_NORM_QC_NO}, + {0xFD97, UNICODE_NORM_QC_NO}, + {0xFD98, UNICODE_NORM_QC_NO}, + {0xFD99, UNICODE_NORM_QC_NO}, + {0xFD9A, UNICODE_NORM_QC_NO}, + {0xFD9B, UNICODE_NORM_QC_NO}, + {0xFD9C, UNICODE_NORM_QC_NO}, + {0xFD9D, UNICODE_NORM_QC_NO}, + {0xFD9E, UNICODE_NORM_QC_NO}, + {0xFD9F, UNICODE_NORM_QC_NO}, + {0xFDA0, UNICODE_NORM_QC_NO}, + {0xFDA1, UNICODE_NORM_QC_NO}, + {0xFDA2, UNICODE_NORM_QC_NO}, + {0xFDA3, UNICODE_NORM_QC_NO}, + {0xFDA4, UNICODE_NORM_QC_NO}, + {0xFDA5, UNICODE_NORM_QC_NO}, + {0xFDA6, UNICODE_NORM_QC_NO}, + {0xFDA7, UNICODE_NORM_QC_NO}, + {0xFDA8, UNICODE_NORM_QC_NO}, + {0xFDA9, UNICODE_NORM_QC_NO}, + {0xFDAA, UNICODE_NORM_QC_NO}, + {0xFDAB, UNICODE_NORM_QC_NO}, + {0xFDAC, UNICODE_NORM_QC_NO}, + {0xFDAD, UNICODE_NORM_QC_NO}, + {0xFDAE, UNICODE_NORM_QC_NO}, + {0xFDAF, UNICODE_NORM_QC_NO}, + {0xFDB0, UNICODE_NORM_QC_NO}, + {0xFDB1, UNICODE_NORM_QC_NO}, + {0xFDB2, UNICODE_NORM_QC_NO}, + {0xFDB3, UNICODE_NORM_QC_NO}, + {0xFDB4, UNICODE_NORM_QC_NO}, + {0xFDB5, UNICODE_NORM_QC_NO}, + {0xFDB6, UNICODE_NORM_QC_NO}, + {0xFDB7, UNICODE_NORM_QC_NO}, + {0xFDB8, UNICODE_NORM_QC_NO}, + {0xFDB9, UNICODE_NORM_QC_NO}, + {0xFDBA, UNICODE_NORM_QC_NO}, + {0xFDBB, UNICODE_NORM_QC_NO}, + {0xFDBC, UNICODE_NORM_QC_NO}, + {0xFDBD, UNICODE_NORM_QC_NO}, + {0xFDBE, UNICODE_NORM_QC_NO}, + {0xFDBF, UNICODE_NORM_QC_NO}, + {0xFDC0, UNICODE_NORM_QC_NO}, + {0xFDC1, UNICODE_NORM_QC_NO}, + {0xFDC2, UNICODE_NORM_QC_NO}, + {0xFDC3, UNICODE_NORM_QC_NO}, + {0xFDC4, UNICODE_NORM_QC_NO}, + {0xFDC5, UNICODE_NORM_QC_NO}, + {0xFDC6, UNICODE_NORM_QC_NO}, + {0xFDC7, UNICODE_NORM_QC_NO}, + {0xFDF0, UNICODE_NORM_QC_NO}, + {0xFDF1, UNICODE_NORM_QC_NO}, + {0xFDF2, UNICODE_NORM_QC_NO}, + {0xFDF3, UNICODE_NORM_QC_NO}, + {0xFDF4, UNICODE_NORM_QC_NO}, + {0xFDF5, UNICODE_NORM_QC_NO}, + {0xFDF6, UNICODE_NORM_QC_NO}, + {0xFDF7, UNICODE_NORM_QC_NO}, + {0xFDF8, UNICODE_NORM_QC_NO}, + {0xFDF9, UNICODE_NORM_QC_NO}, + {0xFDFA, UNICODE_NORM_QC_NO}, + {0xFDFB, UNICODE_NORM_QC_NO}, + {0xFDFC, UNICODE_NORM_QC_NO}, + {0xFE10, UNICODE_NORM_QC_NO}, + {0xFE11, UNICODE_NORM_QC_NO}, + {0xFE12, UNICODE_NORM_QC_NO}, + {0xFE13, UNICODE_NORM_QC_NO}, + {0xFE14, UNICODE_NORM_QC_NO}, + {0xFE15, UNICODE_NORM_QC_NO}, + {0xFE16, UNICODE_NORM_QC_NO}, + {0xFE17, UNICODE_NORM_QC_NO}, + {0xFE18, UNICODE_NORM_QC_NO}, + {0xFE19, UNICODE_NORM_QC_NO}, + {0xFE30, UNICODE_NORM_QC_NO}, + {0xFE31, UNICODE_NORM_QC_NO}, + {0xFE32, UNICODE_NORM_QC_NO}, + {0xFE33, UNICODE_NORM_QC_NO}, + {0xFE34, UNICODE_NORM_QC_NO}, + {0xFE35, UNICODE_NORM_QC_NO}, + {0xFE36, UNICODE_NORM_QC_NO}, + {0xFE37, UNICODE_NORM_QC_NO}, + {0xFE38, UNICODE_NORM_QC_NO}, + {0xFE39, UNICODE_NORM_QC_NO}, + {0xFE3A, UNICODE_NORM_QC_NO}, + {0xFE3B, UNICODE_NORM_QC_NO}, + {0xFE3C, UNICODE_NORM_QC_NO}, + {0xFE3D, UNICODE_NORM_QC_NO}, + {0xFE3E, UNICODE_NORM_QC_NO}, + {0xFE3F, UNICODE_NORM_QC_NO}, + {0xFE40, UNICODE_NORM_QC_NO}, + {0xFE41, UNICODE_NORM_QC_NO}, + {0xFE42, UNICODE_NORM_QC_NO}, + {0xFE43, UNICODE_NORM_QC_NO}, + {0xFE44, UNICODE_NORM_QC_NO}, + {0xFE47, UNICODE_NORM_QC_NO}, + {0xFE48, UNICODE_NORM_QC_NO}, + {0xFE49, UNICODE_NORM_QC_NO}, + {0xFE4A, UNICODE_NORM_QC_NO}, + {0xFE4B, UNICODE_NORM_QC_NO}, + {0xFE4C, UNICODE_NORM_QC_NO}, + {0xFE4D, UNICODE_NORM_QC_NO}, + {0xFE4E, UNICODE_NORM_QC_NO}, + {0xFE4F, UNICODE_NORM_QC_NO}, + {0xFE50, UNICODE_NORM_QC_NO}, + {0xFE51, UNICODE_NORM_QC_NO}, + {0xFE52, UNICODE_NORM_QC_NO}, + {0xFE54, UNICODE_NORM_QC_NO}, + {0xFE55, UNICODE_NORM_QC_NO}, + {0xFE56, UNICODE_NORM_QC_NO}, + {0xFE57, UNICODE_NORM_QC_NO}, + {0xFE58, UNICODE_NORM_QC_NO}, + {0xFE59, UNICODE_NORM_QC_NO}, + {0xFE5A, UNICODE_NORM_QC_NO}, + {0xFE5B, UNICODE_NORM_QC_NO}, + {0xFE5C, UNICODE_NORM_QC_NO}, + {0xFE5D, UNICODE_NORM_QC_NO}, + {0xFE5E, UNICODE_NORM_QC_NO}, + {0xFE5F, UNICODE_NORM_QC_NO}, + {0xFE60, UNICODE_NORM_QC_NO}, + {0xFE61, UNICODE_NORM_QC_NO}, + {0xFE62, UNICODE_NORM_QC_NO}, + {0xFE63, UNICODE_NORM_QC_NO}, + {0xFE64, UNICODE_NORM_QC_NO}, + {0xFE65, UNICODE_NORM_QC_NO}, + {0xFE66, UNICODE_NORM_QC_NO}, + {0xFE68, UNICODE_NORM_QC_NO}, + {0xFE69, UNICODE_NORM_QC_NO}, + {0xFE6A, UNICODE_NORM_QC_NO}, + {0xFE6B, UNICODE_NORM_QC_NO}, + {0xFE70, UNICODE_NORM_QC_NO}, + {0xFE71, UNICODE_NORM_QC_NO}, + {0xFE72, UNICODE_NORM_QC_NO}, + {0xFE74, UNICODE_NORM_QC_NO}, + {0xFE76, UNICODE_NORM_QC_NO}, + {0xFE77, UNICODE_NORM_QC_NO}, + {0xFE78, UNICODE_NORM_QC_NO}, + {0xFE79, UNICODE_NORM_QC_NO}, + {0xFE7A, UNICODE_NORM_QC_NO}, + {0xFE7B, UNICODE_NORM_QC_NO}, + {0xFE7C, UNICODE_NORM_QC_NO}, + {0xFE7D, UNICODE_NORM_QC_NO}, + {0xFE7E, UNICODE_NORM_QC_NO}, + {0xFE7F, UNICODE_NORM_QC_NO}, + {0xFE80, UNICODE_NORM_QC_NO}, + {0xFE81, UNICODE_NORM_QC_NO}, + {0xFE82, UNICODE_NORM_QC_NO}, + {0xFE83, UNICODE_NORM_QC_NO}, + {0xFE84, UNICODE_NORM_QC_NO}, + {0xFE85, UNICODE_NORM_QC_NO}, + {0xFE86, UNICODE_NORM_QC_NO}, + {0xFE87, UNICODE_NORM_QC_NO}, + {0xFE88, UNICODE_NORM_QC_NO}, + {0xFE89, UNICODE_NORM_QC_NO}, + {0xFE8A, UNICODE_NORM_QC_NO}, + {0xFE8B, UNICODE_NORM_QC_NO}, + {0xFE8C, UNICODE_NORM_QC_NO}, + {0xFE8D, UNICODE_NORM_QC_NO}, + {0xFE8E, UNICODE_NORM_QC_NO}, + {0xFE8F, UNICODE_NORM_QC_NO}, + {0xFE90, UNICODE_NORM_QC_NO}, + {0xFE91, UNICODE_NORM_QC_NO}, + {0xFE92, UNICODE_NORM_QC_NO}, + {0xFE93, UNICODE_NORM_QC_NO}, + {0xFE94, UNICODE_NORM_QC_NO}, + {0xFE95, UNICODE_NORM_QC_NO}, + {0xFE96, UNICODE_NORM_QC_NO}, + {0xFE97, UNICODE_NORM_QC_NO}, + {0xFE98, UNICODE_NORM_QC_NO}, + {0xFE99, UNICODE_NORM_QC_NO}, + {0xFE9A, UNICODE_NORM_QC_NO}, + {0xFE9B, UNICODE_NORM_QC_NO}, + {0xFE9C, UNICODE_NORM_QC_NO}, + {0xFE9D, UNICODE_NORM_QC_NO}, + {0xFE9E, UNICODE_NORM_QC_NO}, + {0xFE9F, UNICODE_NORM_QC_NO}, + {0xFEA0, UNICODE_NORM_QC_NO}, + {0xFEA1, UNICODE_NORM_QC_NO}, + {0xFEA2, UNICODE_NORM_QC_NO}, + {0xFEA3, UNICODE_NORM_QC_NO}, + {0xFEA4, UNICODE_NORM_QC_NO}, + {0xFEA5, UNICODE_NORM_QC_NO}, + {0xFEA6, UNICODE_NORM_QC_NO}, + {0xFEA7, UNICODE_NORM_QC_NO}, + {0xFEA8, UNICODE_NORM_QC_NO}, + {0xFEA9, UNICODE_NORM_QC_NO}, + {0xFEAA, UNICODE_NORM_QC_NO}, + {0xFEAB, UNICODE_NORM_QC_NO}, + {0xFEAC, UNICODE_NORM_QC_NO}, + {0xFEAD, UNICODE_NORM_QC_NO}, + {0xFEAE, UNICODE_NORM_QC_NO}, + {0xFEAF, UNICODE_NORM_QC_NO}, + {0xFEB0, UNICODE_NORM_QC_NO}, + {0xFEB1, UNICODE_NORM_QC_NO}, + {0xFEB2, UNICODE_NORM_QC_NO}, + {0xFEB3, UNICODE_NORM_QC_NO}, + {0xFEB4, UNICODE_NORM_QC_NO}, + {0xFEB5, UNICODE_NORM_QC_NO}, + {0xFEB6, UNICODE_NORM_QC_NO}, + {0xFEB7, UNICODE_NORM_QC_NO}, + {0xFEB8, UNICODE_NORM_QC_NO}, + {0xFEB9, UNICODE_NORM_QC_NO}, + {0xFEBA, UNICODE_NORM_QC_NO}, + {0xFEBB, UNICODE_NORM_QC_NO}, + {0xFEBC, UNICODE_NORM_QC_NO}, + {0xFEBD, UNICODE_NORM_QC_NO}, + {0xFEBE, UNICODE_NORM_QC_NO}, + {0xFEBF, UNICODE_NORM_QC_NO}, + {0xFEC0, UNICODE_NORM_QC_NO}, + {0xFEC1, UNICODE_NORM_QC_NO}, + {0xFEC2, UNICODE_NORM_QC_NO}, + {0xFEC3, UNICODE_NORM_QC_NO}, + {0xFEC4, UNICODE_NORM_QC_NO}, + {0xFEC5, UNICODE_NORM_QC_NO}, + {0xFEC6, UNICODE_NORM_QC_NO}, + {0xFEC7, UNICODE_NORM_QC_NO}, + {0xFEC8, UNICODE_NORM_QC_NO}, + {0xFEC9, UNICODE_NORM_QC_NO}, + {0xFECA, UNICODE_NORM_QC_NO}, + {0xFECB, UNICODE_NORM_QC_NO}, + {0xFECC, UNICODE_NORM_QC_NO}, + {0xFECD, UNICODE_NORM_QC_NO}, + {0xFECE, UNICODE_NORM_QC_NO}, + {0xFECF, UNICODE_NORM_QC_NO}, + {0xFED0, UNICODE_NORM_QC_NO}, + {0xFED1, UNICODE_NORM_QC_NO}, + {0xFED2, UNICODE_NORM_QC_NO}, + {0xFED3, UNICODE_NORM_QC_NO}, + {0xFED4, UNICODE_NORM_QC_NO}, + {0xFED5, UNICODE_NORM_QC_NO}, + {0xFED6, UNICODE_NORM_QC_NO}, + {0xFED7, UNICODE_NORM_QC_NO}, + {0xFED8, UNICODE_NORM_QC_NO}, + {0xFED9, UNICODE_NORM_QC_NO}, + {0xFEDA, UNICODE_NORM_QC_NO}, + {0xFEDB, UNICODE_NORM_QC_NO}, + {0xFEDC, UNICODE_NORM_QC_NO}, + {0xFEDD, UNICODE_NORM_QC_NO}, + {0xFEDE, UNICODE_NORM_QC_NO}, + {0xFEDF, UNICODE_NORM_QC_NO}, + {0xFEE0, UNICODE_NORM_QC_NO}, + {0xFEE1, UNICODE_NORM_QC_NO}, + {0xFEE2, UNICODE_NORM_QC_NO}, + {0xFEE3, UNICODE_NORM_QC_NO}, + {0xFEE4, UNICODE_NORM_QC_NO}, + {0xFEE5, UNICODE_NORM_QC_NO}, + {0xFEE6, UNICODE_NORM_QC_NO}, + {0xFEE7, UNICODE_NORM_QC_NO}, + {0xFEE8, UNICODE_NORM_QC_NO}, + {0xFEE9, UNICODE_NORM_QC_NO}, + {0xFEEA, UNICODE_NORM_QC_NO}, + {0xFEEB, UNICODE_NORM_QC_NO}, + {0xFEEC, UNICODE_NORM_QC_NO}, + {0xFEED, UNICODE_NORM_QC_NO}, + {0xFEEE, UNICODE_NORM_QC_NO}, + {0xFEEF, UNICODE_NORM_QC_NO}, + {0xFEF0, UNICODE_NORM_QC_NO}, + {0xFEF1, UNICODE_NORM_QC_NO}, + {0xFEF2, UNICODE_NORM_QC_NO}, + {0xFEF3, UNICODE_NORM_QC_NO}, + {0xFEF4, UNICODE_NORM_QC_NO}, + {0xFEF5, UNICODE_NORM_QC_NO}, + {0xFEF6, UNICODE_NORM_QC_NO}, + {0xFEF7, UNICODE_NORM_QC_NO}, + {0xFEF8, UNICODE_NORM_QC_NO}, + {0xFEF9, UNICODE_NORM_QC_NO}, + {0xFEFA, UNICODE_NORM_QC_NO}, + {0xFEFB, UNICODE_NORM_QC_NO}, + {0xFEFC, UNICODE_NORM_QC_NO}, + {0xFF01, UNICODE_NORM_QC_NO}, + {0xFF02, UNICODE_NORM_QC_NO}, + {0xFF03, UNICODE_NORM_QC_NO}, + {0xFF04, UNICODE_NORM_QC_NO}, + {0xFF05, UNICODE_NORM_QC_NO}, + {0xFF06, UNICODE_NORM_QC_NO}, + {0xFF07, UNICODE_NORM_QC_NO}, + {0xFF08, UNICODE_NORM_QC_NO}, + {0xFF09, UNICODE_NORM_QC_NO}, + {0xFF0A, UNICODE_NORM_QC_NO}, + {0xFF0B, UNICODE_NORM_QC_NO}, + {0xFF0C, UNICODE_NORM_QC_NO}, + {0xFF0D, UNICODE_NORM_QC_NO}, + {0xFF0E, UNICODE_NORM_QC_NO}, + {0xFF0F, UNICODE_NORM_QC_NO}, + {0xFF10, UNICODE_NORM_QC_NO}, + {0xFF11, UNICODE_NORM_QC_NO}, + {0xFF12, UNICODE_NORM_QC_NO}, + {0xFF13, UNICODE_NORM_QC_NO}, + {0xFF14, UNICODE_NORM_QC_NO}, + {0xFF15, UNICODE_NORM_QC_NO}, + {0xFF16, UNICODE_NORM_QC_NO}, + {0xFF17, UNICODE_NORM_QC_NO}, + {0xFF18, UNICODE_NORM_QC_NO}, + {0xFF19, UNICODE_NORM_QC_NO}, + {0xFF1A, UNICODE_NORM_QC_NO}, + {0xFF1B, UNICODE_NORM_QC_NO}, + {0xFF1C, UNICODE_NORM_QC_NO}, + {0xFF1D, UNICODE_NORM_QC_NO}, + {0xFF1E, UNICODE_NORM_QC_NO}, + {0xFF1F, UNICODE_NORM_QC_NO}, + {0xFF20, UNICODE_NORM_QC_NO}, + {0xFF21, UNICODE_NORM_QC_NO}, + {0xFF22, UNICODE_NORM_QC_NO}, + {0xFF23, UNICODE_NORM_QC_NO}, + {0xFF24, UNICODE_NORM_QC_NO}, + {0xFF25, UNICODE_NORM_QC_NO}, + {0xFF26, UNICODE_NORM_QC_NO}, + {0xFF27, UNICODE_NORM_QC_NO}, + {0xFF28, UNICODE_NORM_QC_NO}, + {0xFF29, UNICODE_NORM_QC_NO}, + {0xFF2A, UNICODE_NORM_QC_NO}, + {0xFF2B, UNICODE_NORM_QC_NO}, + {0xFF2C, UNICODE_NORM_QC_NO}, + {0xFF2D, UNICODE_NORM_QC_NO}, + {0xFF2E, UNICODE_NORM_QC_NO}, + {0xFF2F, UNICODE_NORM_QC_NO}, + {0xFF30, UNICODE_NORM_QC_NO}, + {0xFF31, UNICODE_NORM_QC_NO}, + {0xFF32, UNICODE_NORM_QC_NO}, + {0xFF33, UNICODE_NORM_QC_NO}, + {0xFF34, UNICODE_NORM_QC_NO}, + {0xFF35, UNICODE_NORM_QC_NO}, + {0xFF36, UNICODE_NORM_QC_NO}, + {0xFF37, UNICODE_NORM_QC_NO}, + {0xFF38, UNICODE_NORM_QC_NO}, + {0xFF39, UNICODE_NORM_QC_NO}, + {0xFF3A, UNICODE_NORM_QC_NO}, + {0xFF3B, UNICODE_NORM_QC_NO}, + {0xFF3C, UNICODE_NORM_QC_NO}, + {0xFF3D, UNICODE_NORM_QC_NO}, + {0xFF3E, UNICODE_NORM_QC_NO}, + {0xFF3F, UNICODE_NORM_QC_NO}, + {0xFF40, UNICODE_NORM_QC_NO}, + {0xFF41, UNICODE_NORM_QC_NO}, + {0xFF42, UNICODE_NORM_QC_NO}, + {0xFF43, UNICODE_NORM_QC_NO}, + {0xFF44, UNICODE_NORM_QC_NO}, + {0xFF45, UNICODE_NORM_QC_NO}, + {0xFF46, UNICODE_NORM_QC_NO}, + {0xFF47, UNICODE_NORM_QC_NO}, + {0xFF48, UNICODE_NORM_QC_NO}, + {0xFF49, UNICODE_NORM_QC_NO}, + {0xFF4A, UNICODE_NORM_QC_NO}, + {0xFF4B, UNICODE_NORM_QC_NO}, + {0xFF4C, UNICODE_NORM_QC_NO}, + {0xFF4D, UNICODE_NORM_QC_NO}, + {0xFF4E, UNICODE_NORM_QC_NO}, + {0xFF4F, UNICODE_NORM_QC_NO}, + {0xFF50, UNICODE_NORM_QC_NO}, + {0xFF51, UNICODE_NORM_QC_NO}, + {0xFF52, UNICODE_NORM_QC_NO}, + {0xFF53, UNICODE_NORM_QC_NO}, + {0xFF54, UNICODE_NORM_QC_NO}, + {0xFF55, UNICODE_NORM_QC_NO}, + {0xFF56, UNICODE_NORM_QC_NO}, + {0xFF57, UNICODE_NORM_QC_NO}, + {0xFF58, UNICODE_NORM_QC_NO}, + {0xFF59, UNICODE_NORM_QC_NO}, + {0xFF5A, UNICODE_NORM_QC_NO}, + {0xFF5B, UNICODE_NORM_QC_NO}, + {0xFF5C, UNICODE_NORM_QC_NO}, + {0xFF5D, UNICODE_NORM_QC_NO}, + {0xFF5E, UNICODE_NORM_QC_NO}, + {0xFF5F, UNICODE_NORM_QC_NO}, + {0xFF60, UNICODE_NORM_QC_NO}, + {0xFF61, UNICODE_NORM_QC_NO}, + {0xFF62, UNICODE_NORM_QC_NO}, + {0xFF63, UNICODE_NORM_QC_NO}, + {0xFF64, UNICODE_NORM_QC_NO}, + {0xFF65, UNICODE_NORM_QC_NO}, + {0xFF66, UNICODE_NORM_QC_NO}, + {0xFF67, UNICODE_NORM_QC_NO}, + {0xFF68, UNICODE_NORM_QC_NO}, + {0xFF69, UNICODE_NORM_QC_NO}, + {0xFF6A, UNICODE_NORM_QC_NO}, + {0xFF6B, UNICODE_NORM_QC_NO}, + {0xFF6C, UNICODE_NORM_QC_NO}, + {0xFF6D, UNICODE_NORM_QC_NO}, + {0xFF6E, UNICODE_NORM_QC_NO}, + {0xFF6F, UNICODE_NORM_QC_NO}, + {0xFF70, UNICODE_NORM_QC_NO}, + {0xFF71, UNICODE_NORM_QC_NO}, + {0xFF72, UNICODE_NORM_QC_NO}, + {0xFF73, UNICODE_NORM_QC_NO}, + {0xFF74, UNICODE_NORM_QC_NO}, + {0xFF75, UNICODE_NORM_QC_NO}, + {0xFF76, UNICODE_NORM_QC_NO}, + {0xFF77, UNICODE_NORM_QC_NO}, + {0xFF78, UNICODE_NORM_QC_NO}, + {0xFF79, UNICODE_NORM_QC_NO}, + {0xFF7A, UNICODE_NORM_QC_NO}, + {0xFF7B, UNICODE_NORM_QC_NO}, + {0xFF7C, UNICODE_NORM_QC_NO}, + {0xFF7D, UNICODE_NORM_QC_NO}, + {0xFF7E, UNICODE_NORM_QC_NO}, + {0xFF7F, UNICODE_NORM_QC_NO}, + {0xFF80, UNICODE_NORM_QC_NO}, + {0xFF81, UNICODE_NORM_QC_NO}, + {0xFF82, UNICODE_NORM_QC_NO}, + {0xFF83, UNICODE_NORM_QC_NO}, + {0xFF84, UNICODE_NORM_QC_NO}, + {0xFF85, UNICODE_NORM_QC_NO}, + {0xFF86, UNICODE_NORM_QC_NO}, + {0xFF87, UNICODE_NORM_QC_NO}, + {0xFF88, UNICODE_NORM_QC_NO}, + {0xFF89, UNICODE_NORM_QC_NO}, + {0xFF8A, UNICODE_NORM_QC_NO}, + {0xFF8B, UNICODE_NORM_QC_NO}, + {0xFF8C, UNICODE_NORM_QC_NO}, + {0xFF8D, UNICODE_NORM_QC_NO}, + {0xFF8E, UNICODE_NORM_QC_NO}, + {0xFF8F, UNICODE_NORM_QC_NO}, + {0xFF90, UNICODE_NORM_QC_NO}, + {0xFF91, UNICODE_NORM_QC_NO}, + {0xFF92, UNICODE_NORM_QC_NO}, + {0xFF93, UNICODE_NORM_QC_NO}, + {0xFF94, UNICODE_NORM_QC_NO}, + {0xFF95, UNICODE_NORM_QC_NO}, + {0xFF96, UNICODE_NORM_QC_NO}, + {0xFF97, UNICODE_NORM_QC_NO}, + {0xFF98, UNICODE_NORM_QC_NO}, + {0xFF99, UNICODE_NORM_QC_NO}, + {0xFF9A, UNICODE_NORM_QC_NO}, + {0xFF9B, UNICODE_NORM_QC_NO}, + {0xFF9C, UNICODE_NORM_QC_NO}, + {0xFF9D, UNICODE_NORM_QC_NO}, + {0xFF9E, UNICODE_NORM_QC_NO}, + {0xFF9F, UNICODE_NORM_QC_NO}, + {0xFFA0, UNICODE_NORM_QC_NO}, + {0xFFA1, UNICODE_NORM_QC_NO}, + {0xFFA2, UNICODE_NORM_QC_NO}, + {0xFFA3, UNICODE_NORM_QC_NO}, + {0xFFA4, UNICODE_NORM_QC_NO}, + {0xFFA5, UNICODE_NORM_QC_NO}, + {0xFFA6, UNICODE_NORM_QC_NO}, + {0xFFA7, UNICODE_NORM_QC_NO}, + {0xFFA8, UNICODE_NORM_QC_NO}, + {0xFFA9, UNICODE_NORM_QC_NO}, + {0xFFAA, UNICODE_NORM_QC_NO}, + {0xFFAB, UNICODE_NORM_QC_NO}, + {0xFFAC, UNICODE_NORM_QC_NO}, + {0xFFAD, UNICODE_NORM_QC_NO}, + {0xFFAE, UNICODE_NORM_QC_NO}, + {0xFFAF, UNICODE_NORM_QC_NO}, + {0xFFB0, UNICODE_NORM_QC_NO}, + {0xFFB1, UNICODE_NORM_QC_NO}, + {0xFFB2, UNICODE_NORM_QC_NO}, + {0xFFB3, UNICODE_NORM_QC_NO}, + {0xFFB4, UNICODE_NORM_QC_NO}, + {0xFFB5, UNICODE_NORM_QC_NO}, + {0xFFB6, UNICODE_NORM_QC_NO}, + {0xFFB7, UNICODE_NORM_QC_NO}, + {0xFFB8, UNICODE_NORM_QC_NO}, + {0xFFB9, UNICODE_NORM_QC_NO}, + {0xFFBA, UNICODE_NORM_QC_NO}, + {0xFFBB, UNICODE_NORM_QC_NO}, + {0xFFBC, UNICODE_NORM_QC_NO}, + {0xFFBD, UNICODE_NORM_QC_NO}, + {0xFFBE, UNICODE_NORM_QC_NO}, + {0xFFC2, UNICODE_NORM_QC_NO}, + {0xFFC3, UNICODE_NORM_QC_NO}, + {0xFFC4, UNICODE_NORM_QC_NO}, + {0xFFC5, UNICODE_NORM_QC_NO}, + {0xFFC6, UNICODE_NORM_QC_NO}, + {0xFFC7, UNICODE_NORM_QC_NO}, + {0xFFCA, UNICODE_NORM_QC_NO}, + {0xFFCB, UNICODE_NORM_QC_NO}, + {0xFFCC, UNICODE_NORM_QC_NO}, + {0xFFCD, UNICODE_NORM_QC_NO}, + {0xFFCE, UNICODE_NORM_QC_NO}, + {0xFFCF, UNICODE_NORM_QC_NO}, + {0xFFD2, UNICODE_NORM_QC_NO}, + {0xFFD3, UNICODE_NORM_QC_NO}, + {0xFFD4, UNICODE_NORM_QC_NO}, + {0xFFD5, UNICODE_NORM_QC_NO}, + {0xFFD6, UNICODE_NORM_QC_NO}, + {0xFFD7, UNICODE_NORM_QC_NO}, + {0xFFDA, UNICODE_NORM_QC_NO}, + {0xFFDB, UNICODE_NORM_QC_NO}, + {0xFFDC, UNICODE_NORM_QC_NO}, + {0xFFE0, UNICODE_NORM_QC_NO}, + {0xFFE1, UNICODE_NORM_QC_NO}, + {0xFFE2, UNICODE_NORM_QC_NO}, + {0xFFE3, UNICODE_NORM_QC_NO}, + {0xFFE4, UNICODE_NORM_QC_NO}, + {0xFFE5, UNICODE_NORM_QC_NO}, + {0xFFE6, UNICODE_NORM_QC_NO}, + {0xFFE8, UNICODE_NORM_QC_NO}, + {0xFFE9, UNICODE_NORM_QC_NO}, + {0xFFEA, UNICODE_NORM_QC_NO}, + {0xFFEB, UNICODE_NORM_QC_NO}, + {0xFFEC, UNICODE_NORM_QC_NO}, + {0xFFED, UNICODE_NORM_QC_NO}, + {0xFFEE, UNICODE_NORM_QC_NO}, + {0x10781, UNICODE_NORM_QC_NO}, + {0x10782, UNICODE_NORM_QC_NO}, + {0x10783, UNICODE_NORM_QC_NO}, + {0x10784, UNICODE_NORM_QC_NO}, + {0x10785, UNICODE_NORM_QC_NO}, + {0x10787, UNICODE_NORM_QC_NO}, + {0x10788, UNICODE_NORM_QC_NO}, + {0x10789, UNICODE_NORM_QC_NO}, + {0x1078A, UNICODE_NORM_QC_NO}, + {0x1078B, UNICODE_NORM_QC_NO}, + {0x1078C, UNICODE_NORM_QC_NO}, + {0x1078D, UNICODE_NORM_QC_NO}, + {0x1078E, UNICODE_NORM_QC_NO}, + {0x1078F, UNICODE_NORM_QC_NO}, + {0x10790, UNICODE_NORM_QC_NO}, + {0x10791, UNICODE_NORM_QC_NO}, + {0x10792, UNICODE_NORM_QC_NO}, + {0x10793, UNICODE_NORM_QC_NO}, + {0x10794, UNICODE_NORM_QC_NO}, + {0x10795, UNICODE_NORM_QC_NO}, + {0x10796, UNICODE_NORM_QC_NO}, + {0x10797, UNICODE_NORM_QC_NO}, + {0x10798, UNICODE_NORM_QC_NO}, + {0x10799, UNICODE_NORM_QC_NO}, + {0x1079A, UNICODE_NORM_QC_NO}, + {0x1079B, UNICODE_NORM_QC_NO}, + {0x1079C, UNICODE_NORM_QC_NO}, + {0x1079D, UNICODE_NORM_QC_NO}, + {0x1079E, UNICODE_NORM_QC_NO}, + {0x1079F, UNICODE_NORM_QC_NO}, + {0x107A0, UNICODE_NORM_QC_NO}, + {0x107A1, UNICODE_NORM_QC_NO}, + {0x107A2, UNICODE_NORM_QC_NO}, + {0x107A3, UNICODE_NORM_QC_NO}, + {0x107A4, UNICODE_NORM_QC_NO}, + {0x107A5, UNICODE_NORM_QC_NO}, + {0x107A6, UNICODE_NORM_QC_NO}, + {0x107A7, UNICODE_NORM_QC_NO}, + {0x107A8, UNICODE_NORM_QC_NO}, + {0x107A9, UNICODE_NORM_QC_NO}, + {0x107AA, UNICODE_NORM_QC_NO}, + {0x107AB, UNICODE_NORM_QC_NO}, + {0x107AC, UNICODE_NORM_QC_NO}, + {0x107AD, UNICODE_NORM_QC_NO}, + {0x107AE, UNICODE_NORM_QC_NO}, + {0x107AF, UNICODE_NORM_QC_NO}, + {0x107B0, UNICODE_NORM_QC_NO}, + {0x107B2, UNICODE_NORM_QC_NO}, + {0x107B3, UNICODE_NORM_QC_NO}, + {0x107B4, UNICODE_NORM_QC_NO}, + {0x107B5, UNICODE_NORM_QC_NO}, + {0x107B6, UNICODE_NORM_QC_NO}, + {0x107B7, UNICODE_NORM_QC_NO}, + {0x107B8, UNICODE_NORM_QC_NO}, + {0x107B9, UNICODE_NORM_QC_NO}, + {0x107BA, UNICODE_NORM_QC_NO}, + {0x110BA, UNICODE_NORM_QC_MAYBE}, + {0x11127, UNICODE_NORM_QC_MAYBE}, + {0x1133E, UNICODE_NORM_QC_MAYBE}, + {0x11357, UNICODE_NORM_QC_MAYBE}, + {0x114B0, UNICODE_NORM_QC_MAYBE}, + {0x114BA, UNICODE_NORM_QC_MAYBE}, + {0x114BD, UNICODE_NORM_QC_MAYBE}, + {0x115AF, UNICODE_NORM_QC_MAYBE}, + {0x11930, UNICODE_NORM_QC_MAYBE}, + {0x1D15E, UNICODE_NORM_QC_NO}, + {0x1D15F, UNICODE_NORM_QC_NO}, + {0x1D160, UNICODE_NORM_QC_NO}, + {0x1D161, UNICODE_NORM_QC_NO}, + {0x1D162, UNICODE_NORM_QC_NO}, + {0x1D163, UNICODE_NORM_QC_NO}, + {0x1D164, UNICODE_NORM_QC_NO}, + {0x1D1BB, UNICODE_NORM_QC_NO}, + {0x1D1BC, UNICODE_NORM_QC_NO}, + {0x1D1BD, UNICODE_NORM_QC_NO}, + {0x1D1BE, UNICODE_NORM_QC_NO}, + {0x1D1BF, UNICODE_NORM_QC_NO}, + {0x1D1C0, UNICODE_NORM_QC_NO}, + {0x1D400, UNICODE_NORM_QC_NO}, + {0x1D401, UNICODE_NORM_QC_NO}, + {0x1D402, UNICODE_NORM_QC_NO}, + {0x1D403, UNICODE_NORM_QC_NO}, + {0x1D404, UNICODE_NORM_QC_NO}, + {0x1D405, UNICODE_NORM_QC_NO}, + {0x1D406, UNICODE_NORM_QC_NO}, + {0x1D407, UNICODE_NORM_QC_NO}, + {0x1D408, UNICODE_NORM_QC_NO}, + {0x1D409, UNICODE_NORM_QC_NO}, + {0x1D40A, UNICODE_NORM_QC_NO}, + {0x1D40B, UNICODE_NORM_QC_NO}, + {0x1D40C, UNICODE_NORM_QC_NO}, + {0x1D40D, UNICODE_NORM_QC_NO}, + {0x1D40E, UNICODE_NORM_QC_NO}, + {0x1D40F, UNICODE_NORM_QC_NO}, + {0x1D410, UNICODE_NORM_QC_NO}, + {0x1D411, UNICODE_NORM_QC_NO}, + {0x1D412, UNICODE_NORM_QC_NO}, + {0x1D413, UNICODE_NORM_QC_NO}, + {0x1D414, UNICODE_NORM_QC_NO}, + {0x1D415, UNICODE_NORM_QC_NO}, + {0x1D416, UNICODE_NORM_QC_NO}, + {0x1D417, UNICODE_NORM_QC_NO}, + {0x1D418, UNICODE_NORM_QC_NO}, + {0x1D419, UNICODE_NORM_QC_NO}, + {0x1D41A, UNICODE_NORM_QC_NO}, + {0x1D41B, UNICODE_NORM_QC_NO}, + {0x1D41C, UNICODE_NORM_QC_NO}, + {0x1D41D, UNICODE_NORM_QC_NO}, + {0x1D41E, UNICODE_NORM_QC_NO}, + {0x1D41F, UNICODE_NORM_QC_NO}, + {0x1D420, UNICODE_NORM_QC_NO}, + {0x1D421, UNICODE_NORM_QC_NO}, + {0x1D422, UNICODE_NORM_QC_NO}, + {0x1D423, UNICODE_NORM_QC_NO}, + {0x1D424, UNICODE_NORM_QC_NO}, + {0x1D425, UNICODE_NORM_QC_NO}, + {0x1D426, UNICODE_NORM_QC_NO}, + {0x1D427, UNICODE_NORM_QC_NO}, + {0x1D428, UNICODE_NORM_QC_NO}, + {0x1D429, UNICODE_NORM_QC_NO}, + {0x1D42A, UNICODE_NORM_QC_NO}, + {0x1D42B, UNICODE_NORM_QC_NO}, + {0x1D42C, UNICODE_NORM_QC_NO}, + {0x1D42D, UNICODE_NORM_QC_NO}, + {0x1D42E, UNICODE_NORM_QC_NO}, + {0x1D42F, UNICODE_NORM_QC_NO}, + {0x1D430, UNICODE_NORM_QC_NO}, + {0x1D431, UNICODE_NORM_QC_NO}, + {0x1D432, UNICODE_NORM_QC_NO}, + {0x1D433, UNICODE_NORM_QC_NO}, + {0x1D434, UNICODE_NORM_QC_NO}, + {0x1D435, UNICODE_NORM_QC_NO}, + {0x1D436, UNICODE_NORM_QC_NO}, + {0x1D437, UNICODE_NORM_QC_NO}, + {0x1D438, UNICODE_NORM_QC_NO}, + {0x1D439, UNICODE_NORM_QC_NO}, + {0x1D43A, UNICODE_NORM_QC_NO}, + {0x1D43B, UNICODE_NORM_QC_NO}, + {0x1D43C, UNICODE_NORM_QC_NO}, + {0x1D43D, UNICODE_NORM_QC_NO}, + {0x1D43E, UNICODE_NORM_QC_NO}, + {0x1D43F, UNICODE_NORM_QC_NO}, + {0x1D440, UNICODE_NORM_QC_NO}, + {0x1D441, UNICODE_NORM_QC_NO}, + {0x1D442, UNICODE_NORM_QC_NO}, + {0x1D443, UNICODE_NORM_QC_NO}, + {0x1D444, UNICODE_NORM_QC_NO}, + {0x1D445, UNICODE_NORM_QC_NO}, + {0x1D446, UNICODE_NORM_QC_NO}, + {0x1D447, UNICODE_NORM_QC_NO}, + {0x1D448, UNICODE_NORM_QC_NO}, + {0x1D449, UNICODE_NORM_QC_NO}, + {0x1D44A, UNICODE_NORM_QC_NO}, + {0x1D44B, UNICODE_NORM_QC_NO}, + {0x1D44C, UNICODE_NORM_QC_NO}, + {0x1D44D, UNICODE_NORM_QC_NO}, + {0x1D44E, UNICODE_NORM_QC_NO}, + {0x1D44F, UNICODE_NORM_QC_NO}, + {0x1D450, UNICODE_NORM_QC_NO}, + {0x1D451, UNICODE_NORM_QC_NO}, + {0x1D452, UNICODE_NORM_QC_NO}, + {0x1D453, UNICODE_NORM_QC_NO}, + {0x1D454, UNICODE_NORM_QC_NO}, + {0x1D456, UNICODE_NORM_QC_NO}, + {0x1D457, UNICODE_NORM_QC_NO}, + {0x1D458, UNICODE_NORM_QC_NO}, + {0x1D459, UNICODE_NORM_QC_NO}, + {0x1D45A, UNICODE_NORM_QC_NO}, + {0x1D45B, UNICODE_NORM_QC_NO}, + {0x1D45C, UNICODE_NORM_QC_NO}, + {0x1D45D, UNICODE_NORM_QC_NO}, + {0x1D45E, UNICODE_NORM_QC_NO}, + {0x1D45F, UNICODE_NORM_QC_NO}, + {0x1D460, UNICODE_NORM_QC_NO}, + {0x1D461, UNICODE_NORM_QC_NO}, + {0x1D462, UNICODE_NORM_QC_NO}, + {0x1D463, UNICODE_NORM_QC_NO}, + {0x1D464, UNICODE_NORM_QC_NO}, + {0x1D465, UNICODE_NORM_QC_NO}, + {0x1D466, UNICODE_NORM_QC_NO}, + {0x1D467, UNICODE_NORM_QC_NO}, + {0x1D468, UNICODE_NORM_QC_NO}, + {0x1D469, UNICODE_NORM_QC_NO}, + {0x1D46A, UNICODE_NORM_QC_NO}, + {0x1D46B, UNICODE_NORM_QC_NO}, + {0x1D46C, UNICODE_NORM_QC_NO}, + {0x1D46D, UNICODE_NORM_QC_NO}, + {0x1D46E, UNICODE_NORM_QC_NO}, + {0x1D46F, UNICODE_NORM_QC_NO}, + {0x1D470, UNICODE_NORM_QC_NO}, + {0x1D471, UNICODE_NORM_QC_NO}, + {0x1D472, UNICODE_NORM_QC_NO}, + {0x1D473, UNICODE_NORM_QC_NO}, + {0x1D474, UNICODE_NORM_QC_NO}, + {0x1D475, UNICODE_NORM_QC_NO}, + {0x1D476, UNICODE_NORM_QC_NO}, + {0x1D477, UNICODE_NORM_QC_NO}, + {0x1D478, UNICODE_NORM_QC_NO}, + {0x1D479, UNICODE_NORM_QC_NO}, + {0x1D47A, UNICODE_NORM_QC_NO}, + {0x1D47B, UNICODE_NORM_QC_NO}, + {0x1D47C, UNICODE_NORM_QC_NO}, + {0x1D47D, UNICODE_NORM_QC_NO}, + {0x1D47E, UNICODE_NORM_QC_NO}, + {0x1D47F, UNICODE_NORM_QC_NO}, + {0x1D480, UNICODE_NORM_QC_NO}, + {0x1D481, UNICODE_NORM_QC_NO}, + {0x1D482, UNICODE_NORM_QC_NO}, + {0x1D483, UNICODE_NORM_QC_NO}, + {0x1D484, UNICODE_NORM_QC_NO}, + {0x1D485, UNICODE_NORM_QC_NO}, + {0x1D486, UNICODE_NORM_QC_NO}, + {0x1D487, UNICODE_NORM_QC_NO}, + {0x1D488, UNICODE_NORM_QC_NO}, + {0x1D489, UNICODE_NORM_QC_NO}, + {0x1D48A, UNICODE_NORM_QC_NO}, + {0x1D48B, UNICODE_NORM_QC_NO}, + {0x1D48C, UNICODE_NORM_QC_NO}, + {0x1D48D, UNICODE_NORM_QC_NO}, + {0x1D48E, UNICODE_NORM_QC_NO}, + {0x1D48F, UNICODE_NORM_QC_NO}, + {0x1D490, UNICODE_NORM_QC_NO}, + {0x1D491, UNICODE_NORM_QC_NO}, + {0x1D492, UNICODE_NORM_QC_NO}, + {0x1D493, UNICODE_NORM_QC_NO}, + {0x1D494, UNICODE_NORM_QC_NO}, + {0x1D495, UNICODE_NORM_QC_NO}, + {0x1D496, UNICODE_NORM_QC_NO}, + {0x1D497, UNICODE_NORM_QC_NO}, + {0x1D498, UNICODE_NORM_QC_NO}, + {0x1D499, UNICODE_NORM_QC_NO}, + {0x1D49A, UNICODE_NORM_QC_NO}, + {0x1D49B, UNICODE_NORM_QC_NO}, + {0x1D49C, UNICODE_NORM_QC_NO}, + {0x1D49E, UNICODE_NORM_QC_NO}, + {0x1D49F, UNICODE_NORM_QC_NO}, + {0x1D4A2, UNICODE_NORM_QC_NO}, + {0x1D4A5, UNICODE_NORM_QC_NO}, + {0x1D4A6, UNICODE_NORM_QC_NO}, + {0x1D4A9, UNICODE_NORM_QC_NO}, + {0x1D4AA, UNICODE_NORM_QC_NO}, + {0x1D4AB, UNICODE_NORM_QC_NO}, + {0x1D4AC, UNICODE_NORM_QC_NO}, + {0x1D4AE, UNICODE_NORM_QC_NO}, + {0x1D4AF, UNICODE_NORM_QC_NO}, + {0x1D4B0, UNICODE_NORM_QC_NO}, + {0x1D4B1, UNICODE_NORM_QC_NO}, + {0x1D4B2, UNICODE_NORM_QC_NO}, + {0x1D4B3, UNICODE_NORM_QC_NO}, + {0x1D4B4, UNICODE_NORM_QC_NO}, + {0x1D4B5, UNICODE_NORM_QC_NO}, + {0x1D4B6, UNICODE_NORM_QC_NO}, + {0x1D4B7, UNICODE_NORM_QC_NO}, + {0x1D4B8, UNICODE_NORM_QC_NO}, + {0x1D4B9, UNICODE_NORM_QC_NO}, + {0x1D4BB, UNICODE_NORM_QC_NO}, + {0x1D4BD, UNICODE_NORM_QC_NO}, + {0x1D4BE, UNICODE_NORM_QC_NO}, + {0x1D4BF, UNICODE_NORM_QC_NO}, + {0x1D4C0, UNICODE_NORM_QC_NO}, + {0x1D4C1, UNICODE_NORM_QC_NO}, + {0x1D4C2, UNICODE_NORM_QC_NO}, + {0x1D4C3, UNICODE_NORM_QC_NO}, + {0x1D4C5, UNICODE_NORM_QC_NO}, + {0x1D4C6, UNICODE_NORM_QC_NO}, + {0x1D4C7, UNICODE_NORM_QC_NO}, + {0x1D4C8, UNICODE_NORM_QC_NO}, + {0x1D4C9, UNICODE_NORM_QC_NO}, + {0x1D4CA, UNICODE_NORM_QC_NO}, + {0x1D4CB, UNICODE_NORM_QC_NO}, + {0x1D4CC, UNICODE_NORM_QC_NO}, + {0x1D4CD, UNICODE_NORM_QC_NO}, + {0x1D4CE, UNICODE_NORM_QC_NO}, + {0x1D4CF, UNICODE_NORM_QC_NO}, + {0x1D4D0, UNICODE_NORM_QC_NO}, + {0x1D4D1, UNICODE_NORM_QC_NO}, + {0x1D4D2, UNICODE_NORM_QC_NO}, + {0x1D4D3, UNICODE_NORM_QC_NO}, + {0x1D4D4, UNICODE_NORM_QC_NO}, + {0x1D4D5, UNICODE_NORM_QC_NO}, + {0x1D4D6, UNICODE_NORM_QC_NO}, + {0x1D4D7, UNICODE_NORM_QC_NO}, + {0x1D4D8, UNICODE_NORM_QC_NO}, + {0x1D4D9, UNICODE_NORM_QC_NO}, + {0x1D4DA, UNICODE_NORM_QC_NO}, + {0x1D4DB, UNICODE_NORM_QC_NO}, + {0x1D4DC, UNICODE_NORM_QC_NO}, + {0x1D4DD, UNICODE_NORM_QC_NO}, + {0x1D4DE, UNICODE_NORM_QC_NO}, + {0x1D4DF, UNICODE_NORM_QC_NO}, + {0x1D4E0, UNICODE_NORM_QC_NO}, + {0x1D4E1, UNICODE_NORM_QC_NO}, + {0x1D4E2, UNICODE_NORM_QC_NO}, + {0x1D4E3, UNICODE_NORM_QC_NO}, + {0x1D4E4, UNICODE_NORM_QC_NO}, + {0x1D4E5, UNICODE_NORM_QC_NO}, + {0x1D4E6, UNICODE_NORM_QC_NO}, + {0x1D4E7, UNICODE_NORM_QC_NO}, + {0x1D4E8, UNICODE_NORM_QC_NO}, + {0x1D4E9, UNICODE_NORM_QC_NO}, + {0x1D4EA, UNICODE_NORM_QC_NO}, + {0x1D4EB, UNICODE_NORM_QC_NO}, + {0x1D4EC, UNICODE_NORM_QC_NO}, + {0x1D4ED, UNICODE_NORM_QC_NO}, + {0x1D4EE, UNICODE_NORM_QC_NO}, + {0x1D4EF, UNICODE_NORM_QC_NO}, + {0x1D4F0, UNICODE_NORM_QC_NO}, + {0x1D4F1, UNICODE_NORM_QC_NO}, + {0x1D4F2, UNICODE_NORM_QC_NO}, + {0x1D4F3, UNICODE_NORM_QC_NO}, + {0x1D4F4, UNICODE_NORM_QC_NO}, + {0x1D4F5, UNICODE_NORM_QC_NO}, + {0x1D4F6, UNICODE_NORM_QC_NO}, + {0x1D4F7, UNICODE_NORM_QC_NO}, + {0x1D4F8, UNICODE_NORM_QC_NO}, + {0x1D4F9, UNICODE_NORM_QC_NO}, + {0x1D4FA, UNICODE_NORM_QC_NO}, + {0x1D4FB, UNICODE_NORM_QC_NO}, + {0x1D4FC, UNICODE_NORM_QC_NO}, + {0x1D4FD, UNICODE_NORM_QC_NO}, + {0x1D4FE, UNICODE_NORM_QC_NO}, + {0x1D4FF, UNICODE_NORM_QC_NO}, + {0x1D500, UNICODE_NORM_QC_NO}, + {0x1D501, UNICODE_NORM_QC_NO}, + {0x1D502, UNICODE_NORM_QC_NO}, + {0x1D503, UNICODE_NORM_QC_NO}, + {0x1D504, UNICODE_NORM_QC_NO}, + {0x1D505, UNICODE_NORM_QC_NO}, + {0x1D507, UNICODE_NORM_QC_NO}, + {0x1D508, UNICODE_NORM_QC_NO}, + {0x1D509, UNICODE_NORM_QC_NO}, + {0x1D50A, UNICODE_NORM_QC_NO}, + {0x1D50D, UNICODE_NORM_QC_NO}, + {0x1D50E, UNICODE_NORM_QC_NO}, + {0x1D50F, UNICODE_NORM_QC_NO}, + {0x1D510, UNICODE_NORM_QC_NO}, + {0x1D511, UNICODE_NORM_QC_NO}, + {0x1D512, UNICODE_NORM_QC_NO}, + {0x1D513, UNICODE_NORM_QC_NO}, + {0x1D514, UNICODE_NORM_QC_NO}, + {0x1D516, UNICODE_NORM_QC_NO}, + {0x1D517, UNICODE_NORM_QC_NO}, + {0x1D518, UNICODE_NORM_QC_NO}, + {0x1D519, UNICODE_NORM_QC_NO}, + {0x1D51A, UNICODE_NORM_QC_NO}, + {0x1D51B, UNICODE_NORM_QC_NO}, + {0x1D51C, UNICODE_NORM_QC_NO}, + {0x1D51E, UNICODE_NORM_QC_NO}, + {0x1D51F, UNICODE_NORM_QC_NO}, + {0x1D520, UNICODE_NORM_QC_NO}, + {0x1D521, UNICODE_NORM_QC_NO}, + {0x1D522, UNICODE_NORM_QC_NO}, + {0x1D523, UNICODE_NORM_QC_NO}, + {0x1D524, UNICODE_NORM_QC_NO}, + {0x1D525, UNICODE_NORM_QC_NO}, + {0x1D526, UNICODE_NORM_QC_NO}, + {0x1D527, UNICODE_NORM_QC_NO}, + {0x1D528, UNICODE_NORM_QC_NO}, + {0x1D529, UNICODE_NORM_QC_NO}, + {0x1D52A, UNICODE_NORM_QC_NO}, + {0x1D52B, UNICODE_NORM_QC_NO}, + {0x1D52C, UNICODE_NORM_QC_NO}, + {0x1D52D, UNICODE_NORM_QC_NO}, + {0x1D52E, UNICODE_NORM_QC_NO}, + {0x1D52F, UNICODE_NORM_QC_NO}, + {0x1D530, UNICODE_NORM_QC_NO}, + {0x1D531, UNICODE_NORM_QC_NO}, + {0x1D532, UNICODE_NORM_QC_NO}, + {0x1D533, UNICODE_NORM_QC_NO}, + {0x1D534, UNICODE_NORM_QC_NO}, + {0x1D535, UNICODE_NORM_QC_NO}, + {0x1D536, UNICODE_NORM_QC_NO}, + {0x1D537, UNICODE_NORM_QC_NO}, + {0x1D538, UNICODE_NORM_QC_NO}, + {0x1D539, UNICODE_NORM_QC_NO}, + {0x1D53B, UNICODE_NORM_QC_NO}, + {0x1D53C, UNICODE_NORM_QC_NO}, + {0x1D53D, UNICODE_NORM_QC_NO}, + {0x1D53E, UNICODE_NORM_QC_NO}, + {0x1D540, UNICODE_NORM_QC_NO}, + {0x1D541, UNICODE_NORM_QC_NO}, + {0x1D542, UNICODE_NORM_QC_NO}, + {0x1D543, UNICODE_NORM_QC_NO}, + {0x1D544, UNICODE_NORM_QC_NO}, + {0x1D546, UNICODE_NORM_QC_NO}, + {0x1D54A, UNICODE_NORM_QC_NO}, + {0x1D54B, UNICODE_NORM_QC_NO}, + {0x1D54C, UNICODE_NORM_QC_NO}, + {0x1D54D, UNICODE_NORM_QC_NO}, + {0x1D54E, UNICODE_NORM_QC_NO}, + {0x1D54F, UNICODE_NORM_QC_NO}, + {0x1D550, UNICODE_NORM_QC_NO}, + {0x1D552, UNICODE_NORM_QC_NO}, + {0x1D553, UNICODE_NORM_QC_NO}, + {0x1D554, UNICODE_NORM_QC_NO}, + {0x1D555, UNICODE_NORM_QC_NO}, + {0x1D556, UNICODE_NORM_QC_NO}, + {0x1D557, UNICODE_NORM_QC_NO}, + {0x1D558, UNICODE_NORM_QC_NO}, + {0x1D559, UNICODE_NORM_QC_NO}, + {0x1D55A, UNICODE_NORM_QC_NO}, + {0x1D55B, UNICODE_NORM_QC_NO}, + {0x1D55C, UNICODE_NORM_QC_NO}, + {0x1D55D, UNICODE_NORM_QC_NO}, + {0x1D55E, UNICODE_NORM_QC_NO}, + {0x1D55F, UNICODE_NORM_QC_NO}, + {0x1D560, UNICODE_NORM_QC_NO}, + {0x1D561, UNICODE_NORM_QC_NO}, + {0x1D562, UNICODE_NORM_QC_NO}, + {0x1D563, UNICODE_NORM_QC_NO}, + {0x1D564, UNICODE_NORM_QC_NO}, + {0x1D565, UNICODE_NORM_QC_NO}, + {0x1D566, UNICODE_NORM_QC_NO}, + {0x1D567, UNICODE_NORM_QC_NO}, + {0x1D568, UNICODE_NORM_QC_NO}, + {0x1D569, UNICODE_NORM_QC_NO}, + {0x1D56A, UNICODE_NORM_QC_NO}, + {0x1D56B, UNICODE_NORM_QC_NO}, + {0x1D56C, UNICODE_NORM_QC_NO}, + {0x1D56D, UNICODE_NORM_QC_NO}, + {0x1D56E, UNICODE_NORM_QC_NO}, + {0x1D56F, UNICODE_NORM_QC_NO}, + {0x1D570, UNICODE_NORM_QC_NO}, + {0x1D571, UNICODE_NORM_QC_NO}, + {0x1D572, UNICODE_NORM_QC_NO}, + {0x1D573, UNICODE_NORM_QC_NO}, + {0x1D574, UNICODE_NORM_QC_NO}, + {0x1D575, UNICODE_NORM_QC_NO}, + {0x1D576, UNICODE_NORM_QC_NO}, + {0x1D577, UNICODE_NORM_QC_NO}, + {0x1D578, UNICODE_NORM_QC_NO}, + {0x1D579, UNICODE_NORM_QC_NO}, + {0x1D57A, UNICODE_NORM_QC_NO}, + {0x1D57B, UNICODE_NORM_QC_NO}, + {0x1D57C, UNICODE_NORM_QC_NO}, + {0x1D57D, UNICODE_NORM_QC_NO}, + {0x1D57E, UNICODE_NORM_QC_NO}, + {0x1D57F, UNICODE_NORM_QC_NO}, + {0x1D580, UNICODE_NORM_QC_NO}, + {0x1D581, UNICODE_NORM_QC_NO}, + {0x1D582, UNICODE_NORM_QC_NO}, + {0x1D583, UNICODE_NORM_QC_NO}, + {0x1D584, UNICODE_NORM_QC_NO}, + {0x1D585, UNICODE_NORM_QC_NO}, + {0x1D586, UNICODE_NORM_QC_NO}, + {0x1D587, UNICODE_NORM_QC_NO}, + {0x1D588, UNICODE_NORM_QC_NO}, + {0x1D589, UNICODE_NORM_QC_NO}, + {0x1D58A, UNICODE_NORM_QC_NO}, + {0x1D58B, UNICODE_NORM_QC_NO}, + {0x1D58C, UNICODE_NORM_QC_NO}, + {0x1D58D, UNICODE_NORM_QC_NO}, + {0x1D58E, UNICODE_NORM_QC_NO}, + {0x1D58F, UNICODE_NORM_QC_NO}, + {0x1D590, UNICODE_NORM_QC_NO}, + {0x1D591, UNICODE_NORM_QC_NO}, + {0x1D592, UNICODE_NORM_QC_NO}, + {0x1D593, UNICODE_NORM_QC_NO}, + {0x1D594, UNICODE_NORM_QC_NO}, + {0x1D595, UNICODE_NORM_QC_NO}, + {0x1D596, UNICODE_NORM_QC_NO}, + {0x1D597, UNICODE_NORM_QC_NO}, + {0x1D598, UNICODE_NORM_QC_NO}, + {0x1D599, UNICODE_NORM_QC_NO}, + {0x1D59A, UNICODE_NORM_QC_NO}, + {0x1D59B, UNICODE_NORM_QC_NO}, + {0x1D59C, UNICODE_NORM_QC_NO}, + {0x1D59D, UNICODE_NORM_QC_NO}, + {0x1D59E, UNICODE_NORM_QC_NO}, + {0x1D59F, UNICODE_NORM_QC_NO}, + {0x1D5A0, UNICODE_NORM_QC_NO}, + {0x1D5A1, UNICODE_NORM_QC_NO}, + {0x1D5A2, UNICODE_NORM_QC_NO}, + {0x1D5A3, UNICODE_NORM_QC_NO}, + {0x1D5A4, UNICODE_NORM_QC_NO}, + {0x1D5A5, UNICODE_NORM_QC_NO}, + {0x1D5A6, UNICODE_NORM_QC_NO}, + {0x1D5A7, UNICODE_NORM_QC_NO}, + {0x1D5A8, UNICODE_NORM_QC_NO}, + {0x1D5A9, UNICODE_NORM_QC_NO}, + {0x1D5AA, UNICODE_NORM_QC_NO}, + {0x1D5AB, UNICODE_NORM_QC_NO}, + {0x1D5AC, UNICODE_NORM_QC_NO}, + {0x1D5AD, UNICODE_NORM_QC_NO}, + {0x1D5AE, UNICODE_NORM_QC_NO}, + {0x1D5AF, UNICODE_NORM_QC_NO}, + {0x1D5B0, UNICODE_NORM_QC_NO}, + {0x1D5B1, UNICODE_NORM_QC_NO}, + {0x1D5B2, UNICODE_NORM_QC_NO}, + {0x1D5B3, UNICODE_NORM_QC_NO}, + {0x1D5B4, UNICODE_NORM_QC_NO}, + {0x1D5B5, UNICODE_NORM_QC_NO}, + {0x1D5B6, UNICODE_NORM_QC_NO}, + {0x1D5B7, UNICODE_NORM_QC_NO}, + {0x1D5B8, UNICODE_NORM_QC_NO}, + {0x1D5B9, UNICODE_NORM_QC_NO}, + {0x1D5BA, UNICODE_NORM_QC_NO}, + {0x1D5BB, UNICODE_NORM_QC_NO}, + {0x1D5BC, UNICODE_NORM_QC_NO}, + {0x1D5BD, UNICODE_NORM_QC_NO}, + {0x1D5BE, UNICODE_NORM_QC_NO}, + {0x1D5BF, UNICODE_NORM_QC_NO}, + {0x1D5C0, UNICODE_NORM_QC_NO}, + {0x1D5C1, UNICODE_NORM_QC_NO}, + {0x1D5C2, UNICODE_NORM_QC_NO}, + {0x1D5C3, UNICODE_NORM_QC_NO}, + {0x1D5C4, UNICODE_NORM_QC_NO}, + {0x1D5C5, UNICODE_NORM_QC_NO}, + {0x1D5C6, UNICODE_NORM_QC_NO}, + {0x1D5C7, UNICODE_NORM_QC_NO}, + {0x1D5C8, UNICODE_NORM_QC_NO}, + {0x1D5C9, UNICODE_NORM_QC_NO}, + {0x1D5CA, UNICODE_NORM_QC_NO}, + {0x1D5CB, UNICODE_NORM_QC_NO}, + {0x1D5CC, UNICODE_NORM_QC_NO}, + {0x1D5CD, UNICODE_NORM_QC_NO}, + {0x1D5CE, UNICODE_NORM_QC_NO}, + {0x1D5CF, UNICODE_NORM_QC_NO}, + {0x1D5D0, UNICODE_NORM_QC_NO}, + {0x1D5D1, UNICODE_NORM_QC_NO}, + {0x1D5D2, UNICODE_NORM_QC_NO}, + {0x1D5D3, UNICODE_NORM_QC_NO}, + {0x1D5D4, UNICODE_NORM_QC_NO}, + {0x1D5D5, UNICODE_NORM_QC_NO}, + {0x1D5D6, UNICODE_NORM_QC_NO}, + {0x1D5D7, UNICODE_NORM_QC_NO}, + {0x1D5D8, UNICODE_NORM_QC_NO}, + {0x1D5D9, UNICODE_NORM_QC_NO}, + {0x1D5DA, UNICODE_NORM_QC_NO}, + {0x1D5DB, UNICODE_NORM_QC_NO}, + {0x1D5DC, UNICODE_NORM_QC_NO}, + {0x1D5DD, UNICODE_NORM_QC_NO}, + {0x1D5DE, UNICODE_NORM_QC_NO}, + {0x1D5DF, UNICODE_NORM_QC_NO}, + {0x1D5E0, UNICODE_NORM_QC_NO}, + {0x1D5E1, UNICODE_NORM_QC_NO}, + {0x1D5E2, UNICODE_NORM_QC_NO}, + {0x1D5E3, UNICODE_NORM_QC_NO}, + {0x1D5E4, UNICODE_NORM_QC_NO}, + {0x1D5E5, UNICODE_NORM_QC_NO}, + {0x1D5E6, UNICODE_NORM_QC_NO}, + {0x1D5E7, UNICODE_NORM_QC_NO}, + {0x1D5E8, UNICODE_NORM_QC_NO}, + {0x1D5E9, UNICODE_NORM_QC_NO}, + {0x1D5EA, UNICODE_NORM_QC_NO}, + {0x1D5EB, UNICODE_NORM_QC_NO}, + {0x1D5EC, UNICODE_NORM_QC_NO}, + {0x1D5ED, UNICODE_NORM_QC_NO}, + {0x1D5EE, UNICODE_NORM_QC_NO}, + {0x1D5EF, UNICODE_NORM_QC_NO}, + {0x1D5F0, UNICODE_NORM_QC_NO}, + {0x1D5F1, UNICODE_NORM_QC_NO}, + {0x1D5F2, UNICODE_NORM_QC_NO}, + {0x1D5F3, UNICODE_NORM_QC_NO}, + {0x1D5F4, UNICODE_NORM_QC_NO}, + {0x1D5F5, UNICODE_NORM_QC_NO}, + {0x1D5F6, UNICODE_NORM_QC_NO}, + {0x1D5F7, UNICODE_NORM_QC_NO}, + {0x1D5F8, UNICODE_NORM_QC_NO}, + {0x1D5F9, UNICODE_NORM_QC_NO}, + {0x1D5FA, UNICODE_NORM_QC_NO}, + {0x1D5FB, UNICODE_NORM_QC_NO}, + {0x1D5FC, UNICODE_NORM_QC_NO}, + {0x1D5FD, UNICODE_NORM_QC_NO}, + {0x1D5FE, UNICODE_NORM_QC_NO}, + {0x1D5FF, UNICODE_NORM_QC_NO}, + {0x1D600, UNICODE_NORM_QC_NO}, + {0x1D601, UNICODE_NORM_QC_NO}, + {0x1D602, UNICODE_NORM_QC_NO}, + {0x1D603, UNICODE_NORM_QC_NO}, + {0x1D604, UNICODE_NORM_QC_NO}, + {0x1D605, UNICODE_NORM_QC_NO}, + {0x1D606, UNICODE_NORM_QC_NO}, + {0x1D607, UNICODE_NORM_QC_NO}, + {0x1D608, UNICODE_NORM_QC_NO}, + {0x1D609, UNICODE_NORM_QC_NO}, + {0x1D60A, UNICODE_NORM_QC_NO}, + {0x1D60B, UNICODE_NORM_QC_NO}, + {0x1D60C, UNICODE_NORM_QC_NO}, + {0x1D60D, UNICODE_NORM_QC_NO}, + {0x1D60E, UNICODE_NORM_QC_NO}, + {0x1D60F, UNICODE_NORM_QC_NO}, + {0x1D610, UNICODE_NORM_QC_NO}, + {0x1D611, UNICODE_NORM_QC_NO}, + {0x1D612, UNICODE_NORM_QC_NO}, + {0x1D613, UNICODE_NORM_QC_NO}, + {0x1D614, UNICODE_NORM_QC_NO}, + {0x1D615, UNICODE_NORM_QC_NO}, + {0x1D616, UNICODE_NORM_QC_NO}, + {0x1D617, UNICODE_NORM_QC_NO}, + {0x1D618, UNICODE_NORM_QC_NO}, + {0x1D619, UNICODE_NORM_QC_NO}, + {0x1D61A, UNICODE_NORM_QC_NO}, + {0x1D61B, UNICODE_NORM_QC_NO}, + {0x1D61C, UNICODE_NORM_QC_NO}, + {0x1D61D, UNICODE_NORM_QC_NO}, + {0x1D61E, UNICODE_NORM_QC_NO}, + {0x1D61F, UNICODE_NORM_QC_NO}, + {0x1D620, UNICODE_NORM_QC_NO}, + {0x1D621, UNICODE_NORM_QC_NO}, + {0x1D622, UNICODE_NORM_QC_NO}, + {0x1D623, UNICODE_NORM_QC_NO}, + {0x1D624, UNICODE_NORM_QC_NO}, + {0x1D625, UNICODE_NORM_QC_NO}, + {0x1D626, UNICODE_NORM_QC_NO}, + {0x1D627, UNICODE_NORM_QC_NO}, + {0x1D628, UNICODE_NORM_QC_NO}, + {0x1D629, UNICODE_NORM_QC_NO}, + {0x1D62A, UNICODE_NORM_QC_NO}, + {0x1D62B, UNICODE_NORM_QC_NO}, + {0x1D62C, UNICODE_NORM_QC_NO}, + {0x1D62D, UNICODE_NORM_QC_NO}, + {0x1D62E, UNICODE_NORM_QC_NO}, + {0x1D62F, UNICODE_NORM_QC_NO}, + {0x1D630, UNICODE_NORM_QC_NO}, + {0x1D631, UNICODE_NORM_QC_NO}, + {0x1D632, UNICODE_NORM_QC_NO}, + {0x1D633, UNICODE_NORM_QC_NO}, + {0x1D634, UNICODE_NORM_QC_NO}, + {0x1D635, UNICODE_NORM_QC_NO}, + {0x1D636, UNICODE_NORM_QC_NO}, + {0x1D637, UNICODE_NORM_QC_NO}, + {0x1D638, UNICODE_NORM_QC_NO}, + {0x1D639, UNICODE_NORM_QC_NO}, + {0x1D63A, UNICODE_NORM_QC_NO}, + {0x1D63B, UNICODE_NORM_QC_NO}, + {0x1D63C, UNICODE_NORM_QC_NO}, + {0x1D63D, UNICODE_NORM_QC_NO}, + {0x1D63E, UNICODE_NORM_QC_NO}, + {0x1D63F, UNICODE_NORM_QC_NO}, + {0x1D640, UNICODE_NORM_QC_NO}, + {0x1D641, UNICODE_NORM_QC_NO}, + {0x1D642, UNICODE_NORM_QC_NO}, + {0x1D643, UNICODE_NORM_QC_NO}, + {0x1D644, UNICODE_NORM_QC_NO}, + {0x1D645, UNICODE_NORM_QC_NO}, + {0x1D646, UNICODE_NORM_QC_NO}, + {0x1D647, UNICODE_NORM_QC_NO}, + {0x1D648, UNICODE_NORM_QC_NO}, + {0x1D649, UNICODE_NORM_QC_NO}, + {0x1D64A, UNICODE_NORM_QC_NO}, + {0x1D64B, UNICODE_NORM_QC_NO}, + {0x1D64C, UNICODE_NORM_QC_NO}, + {0x1D64D, UNICODE_NORM_QC_NO}, + {0x1D64E, UNICODE_NORM_QC_NO}, + {0x1D64F, UNICODE_NORM_QC_NO}, + {0x1D650, UNICODE_NORM_QC_NO}, + {0x1D651, UNICODE_NORM_QC_NO}, + {0x1D652, UNICODE_NORM_QC_NO}, + {0x1D653, UNICODE_NORM_QC_NO}, + {0x1D654, UNICODE_NORM_QC_NO}, + {0x1D655, UNICODE_NORM_QC_NO}, + {0x1D656, UNICODE_NORM_QC_NO}, + {0x1D657, UNICODE_NORM_QC_NO}, + {0x1D658, UNICODE_NORM_QC_NO}, + {0x1D659, UNICODE_NORM_QC_NO}, + {0x1D65A, UNICODE_NORM_QC_NO}, + {0x1D65B, UNICODE_NORM_QC_NO}, + {0x1D65C, UNICODE_NORM_QC_NO}, + {0x1D65D, UNICODE_NORM_QC_NO}, + {0x1D65E, UNICODE_NORM_QC_NO}, + {0x1D65F, UNICODE_NORM_QC_NO}, + {0x1D660, UNICODE_NORM_QC_NO}, + {0x1D661, UNICODE_NORM_QC_NO}, + {0x1D662, UNICODE_NORM_QC_NO}, + {0x1D663, UNICODE_NORM_QC_NO}, + {0x1D664, UNICODE_NORM_QC_NO}, + {0x1D665, UNICODE_NORM_QC_NO}, + {0x1D666, UNICODE_NORM_QC_NO}, + {0x1D667, UNICODE_NORM_QC_NO}, + {0x1D668, UNICODE_NORM_QC_NO}, + {0x1D669, UNICODE_NORM_QC_NO}, + {0x1D66A, UNICODE_NORM_QC_NO}, + {0x1D66B, UNICODE_NORM_QC_NO}, + {0x1D66C, UNICODE_NORM_QC_NO}, + {0x1D66D, UNICODE_NORM_QC_NO}, + {0x1D66E, UNICODE_NORM_QC_NO}, + {0x1D66F, UNICODE_NORM_QC_NO}, + {0x1D670, UNICODE_NORM_QC_NO}, + {0x1D671, UNICODE_NORM_QC_NO}, + {0x1D672, UNICODE_NORM_QC_NO}, + {0x1D673, UNICODE_NORM_QC_NO}, + {0x1D674, UNICODE_NORM_QC_NO}, + {0x1D675, UNICODE_NORM_QC_NO}, + {0x1D676, UNICODE_NORM_QC_NO}, + {0x1D677, UNICODE_NORM_QC_NO}, + {0x1D678, UNICODE_NORM_QC_NO}, + {0x1D679, UNICODE_NORM_QC_NO}, + {0x1D67A, UNICODE_NORM_QC_NO}, + {0x1D67B, UNICODE_NORM_QC_NO}, + {0x1D67C, UNICODE_NORM_QC_NO}, + {0x1D67D, UNICODE_NORM_QC_NO}, + {0x1D67E, UNICODE_NORM_QC_NO}, + {0x1D67F, UNICODE_NORM_QC_NO}, + {0x1D680, UNICODE_NORM_QC_NO}, + {0x1D681, UNICODE_NORM_QC_NO}, + {0x1D682, UNICODE_NORM_QC_NO}, + {0x1D683, UNICODE_NORM_QC_NO}, + {0x1D684, UNICODE_NORM_QC_NO}, + {0x1D685, UNICODE_NORM_QC_NO}, + {0x1D686, UNICODE_NORM_QC_NO}, + {0x1D687, UNICODE_NORM_QC_NO}, + {0x1D688, UNICODE_NORM_QC_NO}, + {0x1D689, UNICODE_NORM_QC_NO}, + {0x1D68A, UNICODE_NORM_QC_NO}, + {0x1D68B, UNICODE_NORM_QC_NO}, + {0x1D68C, UNICODE_NORM_QC_NO}, + {0x1D68D, UNICODE_NORM_QC_NO}, + {0x1D68E, UNICODE_NORM_QC_NO}, + {0x1D68F, UNICODE_NORM_QC_NO}, + {0x1D690, UNICODE_NORM_QC_NO}, + {0x1D691, UNICODE_NORM_QC_NO}, + {0x1D692, UNICODE_NORM_QC_NO}, + {0x1D693, UNICODE_NORM_QC_NO}, + {0x1D694, UNICODE_NORM_QC_NO}, + {0x1D695, UNICODE_NORM_QC_NO}, + {0x1D696, UNICODE_NORM_QC_NO}, + {0x1D697, UNICODE_NORM_QC_NO}, + {0x1D698, UNICODE_NORM_QC_NO}, + {0x1D699, UNICODE_NORM_QC_NO}, + {0x1D69A, UNICODE_NORM_QC_NO}, + {0x1D69B, UNICODE_NORM_QC_NO}, + {0x1D69C, UNICODE_NORM_QC_NO}, + {0x1D69D, UNICODE_NORM_QC_NO}, + {0x1D69E, UNICODE_NORM_QC_NO}, + {0x1D69F, UNICODE_NORM_QC_NO}, + {0x1D6A0, UNICODE_NORM_QC_NO}, + {0x1D6A1, UNICODE_NORM_QC_NO}, + {0x1D6A2, UNICODE_NORM_QC_NO}, + {0x1D6A3, UNICODE_NORM_QC_NO}, + {0x1D6A4, UNICODE_NORM_QC_NO}, + {0x1D6A5, UNICODE_NORM_QC_NO}, + {0x1D6A8, UNICODE_NORM_QC_NO}, + {0x1D6A9, UNICODE_NORM_QC_NO}, + {0x1D6AA, UNICODE_NORM_QC_NO}, + {0x1D6AB, UNICODE_NORM_QC_NO}, + {0x1D6AC, UNICODE_NORM_QC_NO}, + {0x1D6AD, UNICODE_NORM_QC_NO}, + {0x1D6AE, UNICODE_NORM_QC_NO}, + {0x1D6AF, UNICODE_NORM_QC_NO}, + {0x1D6B0, UNICODE_NORM_QC_NO}, + {0x1D6B1, UNICODE_NORM_QC_NO}, + {0x1D6B2, UNICODE_NORM_QC_NO}, + {0x1D6B3, UNICODE_NORM_QC_NO}, + {0x1D6B4, UNICODE_NORM_QC_NO}, + {0x1D6B5, UNICODE_NORM_QC_NO}, + {0x1D6B6, UNICODE_NORM_QC_NO}, + {0x1D6B7, UNICODE_NORM_QC_NO}, + {0x1D6B8, UNICODE_NORM_QC_NO}, + {0x1D6B9, UNICODE_NORM_QC_NO}, + {0x1D6BA, UNICODE_NORM_QC_NO}, + {0x1D6BB, UNICODE_NORM_QC_NO}, + {0x1D6BC, UNICODE_NORM_QC_NO}, + {0x1D6BD, UNICODE_NORM_QC_NO}, + {0x1D6BE, UNICODE_NORM_QC_NO}, + {0x1D6BF, UNICODE_NORM_QC_NO}, + {0x1D6C0, UNICODE_NORM_QC_NO}, + {0x1D6C1, UNICODE_NORM_QC_NO}, + {0x1D6C2, UNICODE_NORM_QC_NO}, + {0x1D6C3, UNICODE_NORM_QC_NO}, + {0x1D6C4, UNICODE_NORM_QC_NO}, + {0x1D6C5, UNICODE_NORM_QC_NO}, + {0x1D6C6, UNICODE_NORM_QC_NO}, + {0x1D6C7, UNICODE_NORM_QC_NO}, + {0x1D6C8, UNICODE_NORM_QC_NO}, + {0x1D6C9, UNICODE_NORM_QC_NO}, + {0x1D6CA, UNICODE_NORM_QC_NO}, + {0x1D6CB, UNICODE_NORM_QC_NO}, + {0x1D6CC, UNICODE_NORM_QC_NO}, + {0x1D6CD, UNICODE_NORM_QC_NO}, + {0x1D6CE, UNICODE_NORM_QC_NO}, + {0x1D6CF, UNICODE_NORM_QC_NO}, + {0x1D6D0, UNICODE_NORM_QC_NO}, + {0x1D6D1, UNICODE_NORM_QC_NO}, + {0x1D6D2, UNICODE_NORM_QC_NO}, + {0x1D6D3, UNICODE_NORM_QC_NO}, + {0x1D6D4, UNICODE_NORM_QC_NO}, + {0x1D6D5, UNICODE_NORM_QC_NO}, + {0x1D6D6, UNICODE_NORM_QC_NO}, + {0x1D6D7, UNICODE_NORM_QC_NO}, + {0x1D6D8, UNICODE_NORM_QC_NO}, + {0x1D6D9, UNICODE_NORM_QC_NO}, + {0x1D6DA, UNICODE_NORM_QC_NO}, + {0x1D6DB, UNICODE_NORM_QC_NO}, + {0x1D6DC, UNICODE_NORM_QC_NO}, + {0x1D6DD, UNICODE_NORM_QC_NO}, + {0x1D6DE, UNICODE_NORM_QC_NO}, + {0x1D6DF, UNICODE_NORM_QC_NO}, + {0x1D6E0, UNICODE_NORM_QC_NO}, + {0x1D6E1, UNICODE_NORM_QC_NO}, + {0x1D6E2, UNICODE_NORM_QC_NO}, + {0x1D6E3, UNICODE_NORM_QC_NO}, + {0x1D6E4, UNICODE_NORM_QC_NO}, + {0x1D6E5, UNICODE_NORM_QC_NO}, + {0x1D6E6, UNICODE_NORM_QC_NO}, + {0x1D6E7, UNICODE_NORM_QC_NO}, + {0x1D6E8, UNICODE_NORM_QC_NO}, + {0x1D6E9, UNICODE_NORM_QC_NO}, + {0x1D6EA, UNICODE_NORM_QC_NO}, + {0x1D6EB, UNICODE_NORM_QC_NO}, + {0x1D6EC, UNICODE_NORM_QC_NO}, + {0x1D6ED, UNICODE_NORM_QC_NO}, + {0x1D6EE, UNICODE_NORM_QC_NO}, + {0x1D6EF, UNICODE_NORM_QC_NO}, + {0x1D6F0, UNICODE_NORM_QC_NO}, + {0x1D6F1, UNICODE_NORM_QC_NO}, + {0x1D6F2, UNICODE_NORM_QC_NO}, + {0x1D6F3, UNICODE_NORM_QC_NO}, + {0x1D6F4, UNICODE_NORM_QC_NO}, + {0x1D6F5, UNICODE_NORM_QC_NO}, + {0x1D6F6, UNICODE_NORM_QC_NO}, + {0x1D6F7, UNICODE_NORM_QC_NO}, + {0x1D6F8, UNICODE_NORM_QC_NO}, + {0x1D6F9, UNICODE_NORM_QC_NO}, + {0x1D6FA, UNICODE_NORM_QC_NO}, + {0x1D6FB, UNICODE_NORM_QC_NO}, + {0x1D6FC, UNICODE_NORM_QC_NO}, + {0x1D6FD, UNICODE_NORM_QC_NO}, + {0x1D6FE, UNICODE_NORM_QC_NO}, + {0x1D6FF, UNICODE_NORM_QC_NO}, + {0x1D700, UNICODE_NORM_QC_NO}, + {0x1D701, UNICODE_NORM_QC_NO}, + {0x1D702, UNICODE_NORM_QC_NO}, + {0x1D703, UNICODE_NORM_QC_NO}, + {0x1D704, UNICODE_NORM_QC_NO}, + {0x1D705, UNICODE_NORM_QC_NO}, + {0x1D706, UNICODE_NORM_QC_NO}, + {0x1D707, UNICODE_NORM_QC_NO}, + {0x1D708, UNICODE_NORM_QC_NO}, + {0x1D709, UNICODE_NORM_QC_NO}, + {0x1D70A, UNICODE_NORM_QC_NO}, + {0x1D70B, UNICODE_NORM_QC_NO}, + {0x1D70C, UNICODE_NORM_QC_NO}, + {0x1D70D, UNICODE_NORM_QC_NO}, + {0x1D70E, UNICODE_NORM_QC_NO}, + {0x1D70F, UNICODE_NORM_QC_NO}, + {0x1D710, UNICODE_NORM_QC_NO}, + {0x1D711, UNICODE_NORM_QC_NO}, + {0x1D712, UNICODE_NORM_QC_NO}, + {0x1D713, UNICODE_NORM_QC_NO}, + {0x1D714, UNICODE_NORM_QC_NO}, + {0x1D715, UNICODE_NORM_QC_NO}, + {0x1D716, UNICODE_NORM_QC_NO}, + {0x1D717, UNICODE_NORM_QC_NO}, + {0x1D718, UNICODE_NORM_QC_NO}, + {0x1D719, UNICODE_NORM_QC_NO}, + {0x1D71A, UNICODE_NORM_QC_NO}, + {0x1D71B, UNICODE_NORM_QC_NO}, + {0x1D71C, UNICODE_NORM_QC_NO}, + {0x1D71D, UNICODE_NORM_QC_NO}, + {0x1D71E, UNICODE_NORM_QC_NO}, + {0x1D71F, UNICODE_NORM_QC_NO}, + {0x1D720, UNICODE_NORM_QC_NO}, + {0x1D721, UNICODE_NORM_QC_NO}, + {0x1D722, UNICODE_NORM_QC_NO}, + {0x1D723, UNICODE_NORM_QC_NO}, + {0x1D724, UNICODE_NORM_QC_NO}, + {0x1D725, UNICODE_NORM_QC_NO}, + {0x1D726, UNICODE_NORM_QC_NO}, + {0x1D727, UNICODE_NORM_QC_NO}, + {0x1D728, UNICODE_NORM_QC_NO}, + {0x1D729, UNICODE_NORM_QC_NO}, + {0x1D72A, UNICODE_NORM_QC_NO}, + {0x1D72B, UNICODE_NORM_QC_NO}, + {0x1D72C, UNICODE_NORM_QC_NO}, + {0x1D72D, UNICODE_NORM_QC_NO}, + {0x1D72E, UNICODE_NORM_QC_NO}, + {0x1D72F, UNICODE_NORM_QC_NO}, + {0x1D730, UNICODE_NORM_QC_NO}, + {0x1D731, UNICODE_NORM_QC_NO}, + {0x1D732, UNICODE_NORM_QC_NO}, + {0x1D733, UNICODE_NORM_QC_NO}, + {0x1D734, UNICODE_NORM_QC_NO}, + {0x1D735, UNICODE_NORM_QC_NO}, + {0x1D736, UNICODE_NORM_QC_NO}, + {0x1D737, UNICODE_NORM_QC_NO}, + {0x1D738, UNICODE_NORM_QC_NO}, + {0x1D739, UNICODE_NORM_QC_NO}, + {0x1D73A, UNICODE_NORM_QC_NO}, + {0x1D73B, UNICODE_NORM_QC_NO}, + {0x1D73C, UNICODE_NORM_QC_NO}, + {0x1D73D, UNICODE_NORM_QC_NO}, + {0x1D73E, UNICODE_NORM_QC_NO}, + {0x1D73F, UNICODE_NORM_QC_NO}, + {0x1D740, UNICODE_NORM_QC_NO}, + {0x1D741, UNICODE_NORM_QC_NO}, + {0x1D742, UNICODE_NORM_QC_NO}, + {0x1D743, UNICODE_NORM_QC_NO}, + {0x1D744, UNICODE_NORM_QC_NO}, + {0x1D745, UNICODE_NORM_QC_NO}, + {0x1D746, UNICODE_NORM_QC_NO}, + {0x1D747, UNICODE_NORM_QC_NO}, + {0x1D748, UNICODE_NORM_QC_NO}, + {0x1D749, UNICODE_NORM_QC_NO}, + {0x1D74A, UNICODE_NORM_QC_NO}, + {0x1D74B, UNICODE_NORM_QC_NO}, + {0x1D74C, UNICODE_NORM_QC_NO}, + {0x1D74D, UNICODE_NORM_QC_NO}, + {0x1D74E, UNICODE_NORM_QC_NO}, + {0x1D74F, UNICODE_NORM_QC_NO}, + {0x1D750, UNICODE_NORM_QC_NO}, + {0x1D751, UNICODE_NORM_QC_NO}, + {0x1D752, UNICODE_NORM_QC_NO}, + {0x1D753, UNICODE_NORM_QC_NO}, + {0x1D754, UNICODE_NORM_QC_NO}, + {0x1D755, UNICODE_NORM_QC_NO}, + {0x1D756, UNICODE_NORM_QC_NO}, + {0x1D757, UNICODE_NORM_QC_NO}, + {0x1D758, UNICODE_NORM_QC_NO}, + {0x1D759, UNICODE_NORM_QC_NO}, + {0x1D75A, UNICODE_NORM_QC_NO}, + {0x1D75B, UNICODE_NORM_QC_NO}, + {0x1D75C, UNICODE_NORM_QC_NO}, + {0x1D75D, UNICODE_NORM_QC_NO}, + {0x1D75E, UNICODE_NORM_QC_NO}, + {0x1D75F, UNICODE_NORM_QC_NO}, + {0x1D760, UNICODE_NORM_QC_NO}, + {0x1D761, UNICODE_NORM_QC_NO}, + {0x1D762, UNICODE_NORM_QC_NO}, + {0x1D763, UNICODE_NORM_QC_NO}, + {0x1D764, UNICODE_NORM_QC_NO}, + {0x1D765, UNICODE_NORM_QC_NO}, + {0x1D766, UNICODE_NORM_QC_NO}, + {0x1D767, UNICODE_NORM_QC_NO}, + {0x1D768, UNICODE_NORM_QC_NO}, + {0x1D769, UNICODE_NORM_QC_NO}, + {0x1D76A, UNICODE_NORM_QC_NO}, + {0x1D76B, UNICODE_NORM_QC_NO}, + {0x1D76C, UNICODE_NORM_QC_NO}, + {0x1D76D, UNICODE_NORM_QC_NO}, + {0x1D76E, UNICODE_NORM_QC_NO}, + {0x1D76F, UNICODE_NORM_QC_NO}, + {0x1D770, UNICODE_NORM_QC_NO}, + {0x1D771, UNICODE_NORM_QC_NO}, + {0x1D772, UNICODE_NORM_QC_NO}, + {0x1D773, UNICODE_NORM_QC_NO}, + {0x1D774, UNICODE_NORM_QC_NO}, + {0x1D775, UNICODE_NORM_QC_NO}, + {0x1D776, UNICODE_NORM_QC_NO}, + {0x1D777, UNICODE_NORM_QC_NO}, + {0x1D778, UNICODE_NORM_QC_NO}, + {0x1D779, UNICODE_NORM_QC_NO}, + {0x1D77A, UNICODE_NORM_QC_NO}, + {0x1D77B, UNICODE_NORM_QC_NO}, + {0x1D77C, UNICODE_NORM_QC_NO}, + {0x1D77D, UNICODE_NORM_QC_NO}, + {0x1D77E, UNICODE_NORM_QC_NO}, + {0x1D77F, UNICODE_NORM_QC_NO}, + {0x1D780, UNICODE_NORM_QC_NO}, + {0x1D781, UNICODE_NORM_QC_NO}, + {0x1D782, UNICODE_NORM_QC_NO}, + {0x1D783, UNICODE_NORM_QC_NO}, + {0x1D784, UNICODE_NORM_QC_NO}, + {0x1D785, UNICODE_NORM_QC_NO}, + {0x1D786, UNICODE_NORM_QC_NO}, + {0x1D787, UNICODE_NORM_QC_NO}, + {0x1D788, UNICODE_NORM_QC_NO}, + {0x1D789, UNICODE_NORM_QC_NO}, + {0x1D78A, UNICODE_NORM_QC_NO}, + {0x1D78B, UNICODE_NORM_QC_NO}, + {0x1D78C, UNICODE_NORM_QC_NO}, + {0x1D78D, UNICODE_NORM_QC_NO}, + {0x1D78E, UNICODE_NORM_QC_NO}, + {0x1D78F, UNICODE_NORM_QC_NO}, + {0x1D790, UNICODE_NORM_QC_NO}, + {0x1D791, UNICODE_NORM_QC_NO}, + {0x1D792, UNICODE_NORM_QC_NO}, + {0x1D793, UNICODE_NORM_QC_NO}, + {0x1D794, UNICODE_NORM_QC_NO}, + {0x1D795, UNICODE_NORM_QC_NO}, + {0x1D796, UNICODE_NORM_QC_NO}, + {0x1D797, UNICODE_NORM_QC_NO}, + {0x1D798, UNICODE_NORM_QC_NO}, + {0x1D799, UNICODE_NORM_QC_NO}, + {0x1D79A, UNICODE_NORM_QC_NO}, + {0x1D79B, UNICODE_NORM_QC_NO}, + {0x1D79C, UNICODE_NORM_QC_NO}, + {0x1D79D, UNICODE_NORM_QC_NO}, + {0x1D79E, UNICODE_NORM_QC_NO}, + {0x1D79F, UNICODE_NORM_QC_NO}, + {0x1D7A0, UNICODE_NORM_QC_NO}, + {0x1D7A1, UNICODE_NORM_QC_NO}, + {0x1D7A2, UNICODE_NORM_QC_NO}, + {0x1D7A3, UNICODE_NORM_QC_NO}, + {0x1D7A4, UNICODE_NORM_QC_NO}, + {0x1D7A5, UNICODE_NORM_QC_NO}, + {0x1D7A6, UNICODE_NORM_QC_NO}, + {0x1D7A7, UNICODE_NORM_QC_NO}, + {0x1D7A8, UNICODE_NORM_QC_NO}, + {0x1D7A9, UNICODE_NORM_QC_NO}, + {0x1D7AA, UNICODE_NORM_QC_NO}, + {0x1D7AB, UNICODE_NORM_QC_NO}, + {0x1D7AC, UNICODE_NORM_QC_NO}, + {0x1D7AD, UNICODE_NORM_QC_NO}, + {0x1D7AE, UNICODE_NORM_QC_NO}, + {0x1D7AF, UNICODE_NORM_QC_NO}, + {0x1D7B0, UNICODE_NORM_QC_NO}, + {0x1D7B1, UNICODE_NORM_QC_NO}, + {0x1D7B2, UNICODE_NORM_QC_NO}, + {0x1D7B3, UNICODE_NORM_QC_NO}, + {0x1D7B4, UNICODE_NORM_QC_NO}, + {0x1D7B5, UNICODE_NORM_QC_NO}, + {0x1D7B6, UNICODE_NORM_QC_NO}, + {0x1D7B7, UNICODE_NORM_QC_NO}, + {0x1D7B8, UNICODE_NORM_QC_NO}, + {0x1D7B9, UNICODE_NORM_QC_NO}, + {0x1D7BA, UNICODE_NORM_QC_NO}, + {0x1D7BB, UNICODE_NORM_QC_NO}, + {0x1D7BC, UNICODE_NORM_QC_NO}, + {0x1D7BD, UNICODE_NORM_QC_NO}, + {0x1D7BE, UNICODE_NORM_QC_NO}, + {0x1D7BF, UNICODE_NORM_QC_NO}, + {0x1D7C0, UNICODE_NORM_QC_NO}, + {0x1D7C1, UNICODE_NORM_QC_NO}, + {0x1D7C2, UNICODE_NORM_QC_NO}, + {0x1D7C3, UNICODE_NORM_QC_NO}, + {0x1D7C4, UNICODE_NORM_QC_NO}, + {0x1D7C5, UNICODE_NORM_QC_NO}, + {0x1D7C6, UNICODE_NORM_QC_NO}, + {0x1D7C7, UNICODE_NORM_QC_NO}, + {0x1D7C8, UNICODE_NORM_QC_NO}, + {0x1D7C9, UNICODE_NORM_QC_NO}, + {0x1D7CA, UNICODE_NORM_QC_NO}, + {0x1D7CB, UNICODE_NORM_QC_NO}, + {0x1D7CE, UNICODE_NORM_QC_NO}, + {0x1D7CF, UNICODE_NORM_QC_NO}, + {0x1D7D0, UNICODE_NORM_QC_NO}, + {0x1D7D1, UNICODE_NORM_QC_NO}, + {0x1D7D2, UNICODE_NORM_QC_NO}, + {0x1D7D3, UNICODE_NORM_QC_NO}, + {0x1D7D4, UNICODE_NORM_QC_NO}, + {0x1D7D5, UNICODE_NORM_QC_NO}, + {0x1D7D6, UNICODE_NORM_QC_NO}, + {0x1D7D7, UNICODE_NORM_QC_NO}, + {0x1D7D8, UNICODE_NORM_QC_NO}, + {0x1D7D9, UNICODE_NORM_QC_NO}, + {0x1D7DA, UNICODE_NORM_QC_NO}, + {0x1D7DB, UNICODE_NORM_QC_NO}, + {0x1D7DC, UNICODE_NORM_QC_NO}, + {0x1D7DD, UNICODE_NORM_QC_NO}, + {0x1D7DE, UNICODE_NORM_QC_NO}, + {0x1D7DF, UNICODE_NORM_QC_NO}, + {0x1D7E0, UNICODE_NORM_QC_NO}, + {0x1D7E1, UNICODE_NORM_QC_NO}, + {0x1D7E2, UNICODE_NORM_QC_NO}, + {0x1D7E3, UNICODE_NORM_QC_NO}, + {0x1D7E4, UNICODE_NORM_QC_NO}, + {0x1D7E5, UNICODE_NORM_QC_NO}, + {0x1D7E6, UNICODE_NORM_QC_NO}, + {0x1D7E7, UNICODE_NORM_QC_NO}, + {0x1D7E8, UNICODE_NORM_QC_NO}, + {0x1D7E9, UNICODE_NORM_QC_NO}, + {0x1D7EA, UNICODE_NORM_QC_NO}, + {0x1D7EB, UNICODE_NORM_QC_NO}, + {0x1D7EC, UNICODE_NORM_QC_NO}, + {0x1D7ED, UNICODE_NORM_QC_NO}, + {0x1D7EE, UNICODE_NORM_QC_NO}, + {0x1D7EF, UNICODE_NORM_QC_NO}, + {0x1D7F0, UNICODE_NORM_QC_NO}, + {0x1D7F1, UNICODE_NORM_QC_NO}, + {0x1D7F2, UNICODE_NORM_QC_NO}, + {0x1D7F3, UNICODE_NORM_QC_NO}, + {0x1D7F4, UNICODE_NORM_QC_NO}, + {0x1D7F5, UNICODE_NORM_QC_NO}, + {0x1D7F6, UNICODE_NORM_QC_NO}, + {0x1D7F7, UNICODE_NORM_QC_NO}, + {0x1D7F8, UNICODE_NORM_QC_NO}, + {0x1D7F9, UNICODE_NORM_QC_NO}, + {0x1D7FA, UNICODE_NORM_QC_NO}, + {0x1D7FB, UNICODE_NORM_QC_NO}, + {0x1D7FC, UNICODE_NORM_QC_NO}, + {0x1D7FD, UNICODE_NORM_QC_NO}, + {0x1D7FE, UNICODE_NORM_QC_NO}, + {0x1D7FF, UNICODE_NORM_QC_NO}, + {0x1E030, UNICODE_NORM_QC_NO}, + {0x1E031, UNICODE_NORM_QC_NO}, + {0x1E032, UNICODE_NORM_QC_NO}, + {0x1E033, UNICODE_NORM_QC_NO}, + {0x1E034, UNICODE_NORM_QC_NO}, + {0x1E035, UNICODE_NORM_QC_NO}, + {0x1E036, UNICODE_NORM_QC_NO}, + {0x1E037, UNICODE_NORM_QC_NO}, + {0x1E038, UNICODE_NORM_QC_NO}, + {0x1E039, UNICODE_NORM_QC_NO}, + {0x1E03A, UNICODE_NORM_QC_NO}, + {0x1E03B, UNICODE_NORM_QC_NO}, + {0x1E03C, UNICODE_NORM_QC_NO}, + {0x1E03D, UNICODE_NORM_QC_NO}, + {0x1E03E, UNICODE_NORM_QC_NO}, + {0x1E03F, UNICODE_NORM_QC_NO}, + {0x1E040, UNICODE_NORM_QC_NO}, + {0x1E041, UNICODE_NORM_QC_NO}, + {0x1E042, UNICODE_NORM_QC_NO}, + {0x1E043, UNICODE_NORM_QC_NO}, + {0x1E044, UNICODE_NORM_QC_NO}, + {0x1E045, UNICODE_NORM_QC_NO}, + {0x1E046, UNICODE_NORM_QC_NO}, + {0x1E047, UNICODE_NORM_QC_NO}, + {0x1E048, UNICODE_NORM_QC_NO}, + {0x1E049, UNICODE_NORM_QC_NO}, + {0x1E04A, UNICODE_NORM_QC_NO}, + {0x1E04B, UNICODE_NORM_QC_NO}, + {0x1E04C, UNICODE_NORM_QC_NO}, + {0x1E04D, UNICODE_NORM_QC_NO}, + {0x1E04E, UNICODE_NORM_QC_NO}, + {0x1E04F, UNICODE_NORM_QC_NO}, + {0x1E050, UNICODE_NORM_QC_NO}, + {0x1E051, UNICODE_NORM_QC_NO}, + {0x1E052, UNICODE_NORM_QC_NO}, + {0x1E053, UNICODE_NORM_QC_NO}, + {0x1E054, UNICODE_NORM_QC_NO}, + {0x1E055, UNICODE_NORM_QC_NO}, + {0x1E056, UNICODE_NORM_QC_NO}, + {0x1E057, UNICODE_NORM_QC_NO}, + {0x1E058, UNICODE_NORM_QC_NO}, + {0x1E059, UNICODE_NORM_QC_NO}, + {0x1E05A, UNICODE_NORM_QC_NO}, + {0x1E05B, UNICODE_NORM_QC_NO}, + {0x1E05C, UNICODE_NORM_QC_NO}, + {0x1E05D, UNICODE_NORM_QC_NO}, + {0x1E05E, UNICODE_NORM_QC_NO}, + {0x1E05F, UNICODE_NORM_QC_NO}, + {0x1E060, UNICODE_NORM_QC_NO}, + {0x1E061, UNICODE_NORM_QC_NO}, + {0x1E062, UNICODE_NORM_QC_NO}, + {0x1E063, UNICODE_NORM_QC_NO}, + {0x1E064, UNICODE_NORM_QC_NO}, + {0x1E065, UNICODE_NORM_QC_NO}, + {0x1E066, UNICODE_NORM_QC_NO}, + {0x1E067, UNICODE_NORM_QC_NO}, + {0x1E068, UNICODE_NORM_QC_NO}, + {0x1E069, UNICODE_NORM_QC_NO}, + {0x1E06A, UNICODE_NORM_QC_NO}, + {0x1E06B, UNICODE_NORM_QC_NO}, + {0x1E06C, UNICODE_NORM_QC_NO}, + {0x1E06D, UNICODE_NORM_QC_NO}, + {0x1EE00, UNICODE_NORM_QC_NO}, + {0x1EE01, UNICODE_NORM_QC_NO}, + {0x1EE02, UNICODE_NORM_QC_NO}, + {0x1EE03, UNICODE_NORM_QC_NO}, + {0x1EE05, UNICODE_NORM_QC_NO}, + {0x1EE06, UNICODE_NORM_QC_NO}, + {0x1EE07, UNICODE_NORM_QC_NO}, + {0x1EE08, UNICODE_NORM_QC_NO}, + {0x1EE09, UNICODE_NORM_QC_NO}, + {0x1EE0A, UNICODE_NORM_QC_NO}, + {0x1EE0B, UNICODE_NORM_QC_NO}, + {0x1EE0C, UNICODE_NORM_QC_NO}, + {0x1EE0D, UNICODE_NORM_QC_NO}, + {0x1EE0E, UNICODE_NORM_QC_NO}, + {0x1EE0F, UNICODE_NORM_QC_NO}, + {0x1EE10, UNICODE_NORM_QC_NO}, + {0x1EE11, UNICODE_NORM_QC_NO}, + {0x1EE12, UNICODE_NORM_QC_NO}, + {0x1EE13, UNICODE_NORM_QC_NO}, + {0x1EE14, UNICODE_NORM_QC_NO}, + {0x1EE15, UNICODE_NORM_QC_NO}, + {0x1EE16, UNICODE_NORM_QC_NO}, + {0x1EE17, UNICODE_NORM_QC_NO}, + {0x1EE18, UNICODE_NORM_QC_NO}, + {0x1EE19, UNICODE_NORM_QC_NO}, + {0x1EE1A, UNICODE_NORM_QC_NO}, + {0x1EE1B, UNICODE_NORM_QC_NO}, + {0x1EE1C, UNICODE_NORM_QC_NO}, + {0x1EE1D, UNICODE_NORM_QC_NO}, + {0x1EE1E, UNICODE_NORM_QC_NO}, + {0x1EE1F, UNICODE_NORM_QC_NO}, + {0x1EE21, UNICODE_NORM_QC_NO}, + {0x1EE22, UNICODE_NORM_QC_NO}, + {0x1EE24, UNICODE_NORM_QC_NO}, + {0x1EE27, UNICODE_NORM_QC_NO}, + {0x1EE29, UNICODE_NORM_QC_NO}, + {0x1EE2A, UNICODE_NORM_QC_NO}, + {0x1EE2B, UNICODE_NORM_QC_NO}, + {0x1EE2C, UNICODE_NORM_QC_NO}, + {0x1EE2D, UNICODE_NORM_QC_NO}, + {0x1EE2E, UNICODE_NORM_QC_NO}, + {0x1EE2F, UNICODE_NORM_QC_NO}, + {0x1EE30, UNICODE_NORM_QC_NO}, + {0x1EE31, UNICODE_NORM_QC_NO}, + {0x1EE32, UNICODE_NORM_QC_NO}, + {0x1EE34, UNICODE_NORM_QC_NO}, + {0x1EE35, UNICODE_NORM_QC_NO}, + {0x1EE36, UNICODE_NORM_QC_NO}, + {0x1EE37, UNICODE_NORM_QC_NO}, + {0x1EE39, UNICODE_NORM_QC_NO}, + {0x1EE3B, UNICODE_NORM_QC_NO}, + {0x1EE42, UNICODE_NORM_QC_NO}, + {0x1EE47, UNICODE_NORM_QC_NO}, + {0x1EE49, UNICODE_NORM_QC_NO}, + {0x1EE4B, UNICODE_NORM_QC_NO}, + {0x1EE4D, UNICODE_NORM_QC_NO}, + {0x1EE4E, UNICODE_NORM_QC_NO}, + {0x1EE4F, UNICODE_NORM_QC_NO}, + {0x1EE51, UNICODE_NORM_QC_NO}, + {0x1EE52, UNICODE_NORM_QC_NO}, + {0x1EE54, UNICODE_NORM_QC_NO}, + {0x1EE57, UNICODE_NORM_QC_NO}, + {0x1EE59, UNICODE_NORM_QC_NO}, + {0x1EE5B, UNICODE_NORM_QC_NO}, + {0x1EE5D, UNICODE_NORM_QC_NO}, + {0x1EE5F, UNICODE_NORM_QC_NO}, + {0x1EE61, UNICODE_NORM_QC_NO}, + {0x1EE62, UNICODE_NORM_QC_NO}, + {0x1EE64, UNICODE_NORM_QC_NO}, + {0x1EE67, UNICODE_NORM_QC_NO}, + {0x1EE68, UNICODE_NORM_QC_NO}, + {0x1EE69, UNICODE_NORM_QC_NO}, + {0x1EE6A, UNICODE_NORM_QC_NO}, + {0x1EE6C, UNICODE_NORM_QC_NO}, + {0x1EE6D, UNICODE_NORM_QC_NO}, + {0x1EE6E, UNICODE_NORM_QC_NO}, + {0x1EE6F, UNICODE_NORM_QC_NO}, + {0x1EE70, UNICODE_NORM_QC_NO}, + {0x1EE71, UNICODE_NORM_QC_NO}, + {0x1EE72, UNICODE_NORM_QC_NO}, + {0x1EE74, UNICODE_NORM_QC_NO}, + {0x1EE75, UNICODE_NORM_QC_NO}, + {0x1EE76, UNICODE_NORM_QC_NO}, + {0x1EE77, UNICODE_NORM_QC_NO}, + {0x1EE79, UNICODE_NORM_QC_NO}, + {0x1EE7A, UNICODE_NORM_QC_NO}, + {0x1EE7B, UNICODE_NORM_QC_NO}, + {0x1EE7C, UNICODE_NORM_QC_NO}, + {0x1EE7E, UNICODE_NORM_QC_NO}, + {0x1EE80, UNICODE_NORM_QC_NO}, + {0x1EE81, UNICODE_NORM_QC_NO}, + {0x1EE82, UNICODE_NORM_QC_NO}, + {0x1EE83, UNICODE_NORM_QC_NO}, + {0x1EE84, UNICODE_NORM_QC_NO}, + {0x1EE85, UNICODE_NORM_QC_NO}, + {0x1EE86, UNICODE_NORM_QC_NO}, + {0x1EE87, UNICODE_NORM_QC_NO}, + {0x1EE88, UNICODE_NORM_QC_NO}, + {0x1EE89, UNICODE_NORM_QC_NO}, + {0x1EE8B, UNICODE_NORM_QC_NO}, + {0x1EE8C, UNICODE_NORM_QC_NO}, + {0x1EE8D, UNICODE_NORM_QC_NO}, + {0x1EE8E, UNICODE_NORM_QC_NO}, + {0x1EE8F, UNICODE_NORM_QC_NO}, + {0x1EE90, UNICODE_NORM_QC_NO}, + {0x1EE91, UNICODE_NORM_QC_NO}, + {0x1EE92, UNICODE_NORM_QC_NO}, + {0x1EE93, UNICODE_NORM_QC_NO}, + {0x1EE94, UNICODE_NORM_QC_NO}, + {0x1EE95, UNICODE_NORM_QC_NO}, + {0x1EE96, UNICODE_NORM_QC_NO}, + {0x1EE97, UNICODE_NORM_QC_NO}, + {0x1EE98, UNICODE_NORM_QC_NO}, + {0x1EE99, UNICODE_NORM_QC_NO}, + {0x1EE9A, UNICODE_NORM_QC_NO}, + {0x1EE9B, UNICODE_NORM_QC_NO}, + {0x1EEA1, UNICODE_NORM_QC_NO}, + {0x1EEA2, UNICODE_NORM_QC_NO}, + {0x1EEA3, UNICODE_NORM_QC_NO}, + {0x1EEA5, UNICODE_NORM_QC_NO}, + {0x1EEA6, UNICODE_NORM_QC_NO}, + {0x1EEA7, UNICODE_NORM_QC_NO}, + {0x1EEA8, UNICODE_NORM_QC_NO}, + {0x1EEA9, UNICODE_NORM_QC_NO}, + {0x1EEAB, UNICODE_NORM_QC_NO}, + {0x1EEAC, UNICODE_NORM_QC_NO}, + {0x1EEAD, UNICODE_NORM_QC_NO}, + {0x1EEAE, UNICODE_NORM_QC_NO}, + {0x1EEAF, UNICODE_NORM_QC_NO}, + {0x1EEB0, UNICODE_NORM_QC_NO}, + {0x1EEB1, UNICODE_NORM_QC_NO}, + {0x1EEB2, UNICODE_NORM_QC_NO}, + {0x1EEB3, UNICODE_NORM_QC_NO}, + {0x1EEB4, UNICODE_NORM_QC_NO}, + {0x1EEB5, UNICODE_NORM_QC_NO}, + {0x1EEB6, UNICODE_NORM_QC_NO}, + {0x1EEB7, UNICODE_NORM_QC_NO}, + {0x1EEB8, UNICODE_NORM_QC_NO}, + {0x1EEB9, UNICODE_NORM_QC_NO}, + {0x1EEBA, UNICODE_NORM_QC_NO}, + {0x1EEBB, UNICODE_NORM_QC_NO}, + {0x1F100, UNICODE_NORM_QC_NO}, + {0x1F101, UNICODE_NORM_QC_NO}, + {0x1F102, UNICODE_NORM_QC_NO}, + {0x1F103, UNICODE_NORM_QC_NO}, + {0x1F104, UNICODE_NORM_QC_NO}, + {0x1F105, UNICODE_NORM_QC_NO}, + {0x1F106, UNICODE_NORM_QC_NO}, + {0x1F107, UNICODE_NORM_QC_NO}, + {0x1F108, UNICODE_NORM_QC_NO}, + {0x1F109, UNICODE_NORM_QC_NO}, + {0x1F10A, UNICODE_NORM_QC_NO}, + {0x1F110, UNICODE_NORM_QC_NO}, + {0x1F111, UNICODE_NORM_QC_NO}, + {0x1F112, UNICODE_NORM_QC_NO}, + {0x1F113, UNICODE_NORM_QC_NO}, + {0x1F114, UNICODE_NORM_QC_NO}, + {0x1F115, UNICODE_NORM_QC_NO}, + {0x1F116, UNICODE_NORM_QC_NO}, + {0x1F117, UNICODE_NORM_QC_NO}, + {0x1F118, UNICODE_NORM_QC_NO}, + {0x1F119, UNICODE_NORM_QC_NO}, + {0x1F11A, UNICODE_NORM_QC_NO}, + {0x1F11B, UNICODE_NORM_QC_NO}, + {0x1F11C, UNICODE_NORM_QC_NO}, + {0x1F11D, UNICODE_NORM_QC_NO}, + {0x1F11E, UNICODE_NORM_QC_NO}, + {0x1F11F, UNICODE_NORM_QC_NO}, + {0x1F120, UNICODE_NORM_QC_NO}, + {0x1F121, UNICODE_NORM_QC_NO}, + {0x1F122, UNICODE_NORM_QC_NO}, + {0x1F123, UNICODE_NORM_QC_NO}, + {0x1F124, UNICODE_NORM_QC_NO}, + {0x1F125, UNICODE_NORM_QC_NO}, + {0x1F126, UNICODE_NORM_QC_NO}, + {0x1F127, UNICODE_NORM_QC_NO}, + {0x1F128, UNICODE_NORM_QC_NO}, + {0x1F129, UNICODE_NORM_QC_NO}, + {0x1F12A, UNICODE_NORM_QC_NO}, + {0x1F12B, UNICODE_NORM_QC_NO}, + {0x1F12C, UNICODE_NORM_QC_NO}, + {0x1F12D, UNICODE_NORM_QC_NO}, + {0x1F12E, UNICODE_NORM_QC_NO}, + {0x1F130, UNICODE_NORM_QC_NO}, + {0x1F131, UNICODE_NORM_QC_NO}, + {0x1F132, UNICODE_NORM_QC_NO}, + {0x1F133, UNICODE_NORM_QC_NO}, + {0x1F134, UNICODE_NORM_QC_NO}, + {0x1F135, UNICODE_NORM_QC_NO}, + {0x1F136, UNICODE_NORM_QC_NO}, + {0x1F137, UNICODE_NORM_QC_NO}, + {0x1F138, UNICODE_NORM_QC_NO}, + {0x1F139, UNICODE_NORM_QC_NO}, + {0x1F13A, UNICODE_NORM_QC_NO}, + {0x1F13B, UNICODE_NORM_QC_NO}, + {0x1F13C, UNICODE_NORM_QC_NO}, + {0x1F13D, UNICODE_NORM_QC_NO}, + {0x1F13E, UNICODE_NORM_QC_NO}, + {0x1F13F, UNICODE_NORM_QC_NO}, + {0x1F140, UNICODE_NORM_QC_NO}, + {0x1F141, UNICODE_NORM_QC_NO}, + {0x1F142, UNICODE_NORM_QC_NO}, + {0x1F143, UNICODE_NORM_QC_NO}, + {0x1F144, UNICODE_NORM_QC_NO}, + {0x1F145, UNICODE_NORM_QC_NO}, + {0x1F146, UNICODE_NORM_QC_NO}, + {0x1F147, UNICODE_NORM_QC_NO}, + {0x1F148, UNICODE_NORM_QC_NO}, + {0x1F149, UNICODE_NORM_QC_NO}, + {0x1F14A, UNICODE_NORM_QC_NO}, + {0x1F14B, UNICODE_NORM_QC_NO}, + {0x1F14C, UNICODE_NORM_QC_NO}, + {0x1F14D, UNICODE_NORM_QC_NO}, + {0x1F14E, UNICODE_NORM_QC_NO}, + {0x1F14F, UNICODE_NORM_QC_NO}, + {0x1F16A, UNICODE_NORM_QC_NO}, + {0x1F16B, UNICODE_NORM_QC_NO}, + {0x1F16C, UNICODE_NORM_QC_NO}, + {0x1F190, UNICODE_NORM_QC_NO}, + {0x1F200, UNICODE_NORM_QC_NO}, + {0x1F201, UNICODE_NORM_QC_NO}, + {0x1F202, UNICODE_NORM_QC_NO}, + {0x1F210, UNICODE_NORM_QC_NO}, + {0x1F211, UNICODE_NORM_QC_NO}, + {0x1F212, UNICODE_NORM_QC_NO}, + {0x1F213, UNICODE_NORM_QC_NO}, + {0x1F214, UNICODE_NORM_QC_NO}, + {0x1F215, UNICODE_NORM_QC_NO}, + {0x1F216, UNICODE_NORM_QC_NO}, + {0x1F217, UNICODE_NORM_QC_NO}, + {0x1F218, UNICODE_NORM_QC_NO}, + {0x1F219, UNICODE_NORM_QC_NO}, + {0x1F21A, UNICODE_NORM_QC_NO}, + {0x1F21B, UNICODE_NORM_QC_NO}, + {0x1F21C, UNICODE_NORM_QC_NO}, + {0x1F21D, UNICODE_NORM_QC_NO}, + {0x1F21E, UNICODE_NORM_QC_NO}, + {0x1F21F, UNICODE_NORM_QC_NO}, + {0x1F220, UNICODE_NORM_QC_NO}, + {0x1F221, UNICODE_NORM_QC_NO}, + {0x1F222, UNICODE_NORM_QC_NO}, + {0x1F223, UNICODE_NORM_QC_NO}, + {0x1F224, UNICODE_NORM_QC_NO}, + {0x1F225, UNICODE_NORM_QC_NO}, + {0x1F226, UNICODE_NORM_QC_NO}, + {0x1F227, UNICODE_NORM_QC_NO}, + {0x1F228, UNICODE_NORM_QC_NO}, + {0x1F229, UNICODE_NORM_QC_NO}, + {0x1F22A, UNICODE_NORM_QC_NO}, + {0x1F22B, UNICODE_NORM_QC_NO}, + {0x1F22C, UNICODE_NORM_QC_NO}, + {0x1F22D, UNICODE_NORM_QC_NO}, + {0x1F22E, UNICODE_NORM_QC_NO}, + {0x1F22F, UNICODE_NORM_QC_NO}, + {0x1F230, UNICODE_NORM_QC_NO}, + {0x1F231, UNICODE_NORM_QC_NO}, + {0x1F232, UNICODE_NORM_QC_NO}, + {0x1F233, UNICODE_NORM_QC_NO}, + {0x1F234, UNICODE_NORM_QC_NO}, + {0x1F235, UNICODE_NORM_QC_NO}, + {0x1F236, UNICODE_NORM_QC_NO}, + {0x1F237, UNICODE_NORM_QC_NO}, + {0x1F238, UNICODE_NORM_QC_NO}, + {0x1F239, UNICODE_NORM_QC_NO}, + {0x1F23A, UNICODE_NORM_QC_NO}, + {0x1F23B, UNICODE_NORM_QC_NO}, + {0x1F240, UNICODE_NORM_QC_NO}, + {0x1F241, UNICODE_NORM_QC_NO}, + {0x1F242, UNICODE_NORM_QC_NO}, + {0x1F243, UNICODE_NORM_QC_NO}, + {0x1F244, UNICODE_NORM_QC_NO}, + {0x1F245, UNICODE_NORM_QC_NO}, + {0x1F246, UNICODE_NORM_QC_NO}, + {0x1F247, UNICODE_NORM_QC_NO}, + {0x1F248, UNICODE_NORM_QC_NO}, + {0x1F250, UNICODE_NORM_QC_NO}, + {0x1F251, UNICODE_NORM_QC_NO}, + {0x1FBF0, UNICODE_NORM_QC_NO}, + {0x1FBF1, UNICODE_NORM_QC_NO}, + {0x1FBF2, UNICODE_NORM_QC_NO}, + {0x1FBF3, UNICODE_NORM_QC_NO}, + {0x1FBF4, UNICODE_NORM_QC_NO}, + {0x1FBF5, UNICODE_NORM_QC_NO}, + {0x1FBF6, UNICODE_NORM_QC_NO}, + {0x1FBF7, UNICODE_NORM_QC_NO}, + {0x1FBF8, UNICODE_NORM_QC_NO}, + {0x1FBF9, UNICODE_NORM_QC_NO}, + {0x2F800, UNICODE_NORM_QC_NO}, + {0x2F801, UNICODE_NORM_QC_NO}, + {0x2F802, UNICODE_NORM_QC_NO}, + {0x2F803, UNICODE_NORM_QC_NO}, + {0x2F804, UNICODE_NORM_QC_NO}, + {0x2F805, UNICODE_NORM_QC_NO}, + {0x2F806, UNICODE_NORM_QC_NO}, + {0x2F807, UNICODE_NORM_QC_NO}, + {0x2F808, UNICODE_NORM_QC_NO}, + {0x2F809, UNICODE_NORM_QC_NO}, + {0x2F80A, UNICODE_NORM_QC_NO}, + {0x2F80B, UNICODE_NORM_QC_NO}, + {0x2F80C, UNICODE_NORM_QC_NO}, + {0x2F80D, UNICODE_NORM_QC_NO}, + {0x2F80E, UNICODE_NORM_QC_NO}, + {0x2F80F, UNICODE_NORM_QC_NO}, + {0x2F810, UNICODE_NORM_QC_NO}, + {0x2F811, UNICODE_NORM_QC_NO}, + {0x2F812, UNICODE_NORM_QC_NO}, + {0x2F813, UNICODE_NORM_QC_NO}, + {0x2F814, UNICODE_NORM_QC_NO}, + {0x2F815, UNICODE_NORM_QC_NO}, + {0x2F816, UNICODE_NORM_QC_NO}, + {0x2F817, UNICODE_NORM_QC_NO}, + {0x2F818, UNICODE_NORM_QC_NO}, + {0x2F819, UNICODE_NORM_QC_NO}, + {0x2F81A, UNICODE_NORM_QC_NO}, + {0x2F81B, UNICODE_NORM_QC_NO}, + {0x2F81C, UNICODE_NORM_QC_NO}, + {0x2F81D, UNICODE_NORM_QC_NO}, + {0x2F81E, UNICODE_NORM_QC_NO}, + {0x2F81F, UNICODE_NORM_QC_NO}, + {0x2F820, UNICODE_NORM_QC_NO}, + {0x2F821, UNICODE_NORM_QC_NO}, + {0x2F822, UNICODE_NORM_QC_NO}, + {0x2F823, UNICODE_NORM_QC_NO}, + {0x2F824, UNICODE_NORM_QC_NO}, + {0x2F825, UNICODE_NORM_QC_NO}, + {0x2F826, UNICODE_NORM_QC_NO}, + {0x2F827, UNICODE_NORM_QC_NO}, + {0x2F828, UNICODE_NORM_QC_NO}, + {0x2F829, UNICODE_NORM_QC_NO}, + {0x2F82A, UNICODE_NORM_QC_NO}, + {0x2F82B, UNICODE_NORM_QC_NO}, + {0x2F82C, UNICODE_NORM_QC_NO}, + {0x2F82D, UNICODE_NORM_QC_NO}, + {0x2F82E, UNICODE_NORM_QC_NO}, + {0x2F82F, UNICODE_NORM_QC_NO}, + {0x2F830, UNICODE_NORM_QC_NO}, + {0x2F831, UNICODE_NORM_QC_NO}, + {0x2F832, UNICODE_NORM_QC_NO}, + {0x2F833, UNICODE_NORM_QC_NO}, + {0x2F834, UNICODE_NORM_QC_NO}, + {0x2F835, UNICODE_NORM_QC_NO}, + {0x2F836, UNICODE_NORM_QC_NO}, + {0x2F837, UNICODE_NORM_QC_NO}, + {0x2F838, UNICODE_NORM_QC_NO}, + {0x2F839, UNICODE_NORM_QC_NO}, + {0x2F83A, UNICODE_NORM_QC_NO}, + {0x2F83B, UNICODE_NORM_QC_NO}, + {0x2F83C, UNICODE_NORM_QC_NO}, + {0x2F83D, UNICODE_NORM_QC_NO}, + {0x2F83E, UNICODE_NORM_QC_NO}, + {0x2F83F, UNICODE_NORM_QC_NO}, + {0x2F840, UNICODE_NORM_QC_NO}, + {0x2F841, UNICODE_NORM_QC_NO}, + {0x2F842, UNICODE_NORM_QC_NO}, + {0x2F843, UNICODE_NORM_QC_NO}, + {0x2F844, UNICODE_NORM_QC_NO}, + {0x2F845, UNICODE_NORM_QC_NO}, + {0x2F846, UNICODE_NORM_QC_NO}, + {0x2F847, UNICODE_NORM_QC_NO}, + {0x2F848, UNICODE_NORM_QC_NO}, + {0x2F849, UNICODE_NORM_QC_NO}, + {0x2F84A, UNICODE_NORM_QC_NO}, + {0x2F84B, UNICODE_NORM_QC_NO}, + {0x2F84C, UNICODE_NORM_QC_NO}, + {0x2F84D, UNICODE_NORM_QC_NO}, + {0x2F84E, UNICODE_NORM_QC_NO}, + {0x2F84F, UNICODE_NORM_QC_NO}, + {0x2F850, UNICODE_NORM_QC_NO}, + {0x2F851, UNICODE_NORM_QC_NO}, + {0x2F852, UNICODE_NORM_QC_NO}, + {0x2F853, UNICODE_NORM_QC_NO}, + {0x2F854, UNICODE_NORM_QC_NO}, + {0x2F855, UNICODE_NORM_QC_NO}, + {0x2F856, UNICODE_NORM_QC_NO}, + {0x2F857, UNICODE_NORM_QC_NO}, + {0x2F858, UNICODE_NORM_QC_NO}, + {0x2F859, UNICODE_NORM_QC_NO}, + {0x2F85A, UNICODE_NORM_QC_NO}, + {0x2F85B, UNICODE_NORM_QC_NO}, + {0x2F85C, UNICODE_NORM_QC_NO}, + {0x2F85D, UNICODE_NORM_QC_NO}, + {0x2F85E, UNICODE_NORM_QC_NO}, + {0x2F85F, UNICODE_NORM_QC_NO}, + {0x2F860, UNICODE_NORM_QC_NO}, + {0x2F861, UNICODE_NORM_QC_NO}, + {0x2F862, UNICODE_NORM_QC_NO}, + {0x2F863, UNICODE_NORM_QC_NO}, + {0x2F864, UNICODE_NORM_QC_NO}, + {0x2F865, UNICODE_NORM_QC_NO}, + {0x2F866, UNICODE_NORM_QC_NO}, + {0x2F867, UNICODE_NORM_QC_NO}, + {0x2F868, UNICODE_NORM_QC_NO}, + {0x2F869, UNICODE_NORM_QC_NO}, + {0x2F86A, UNICODE_NORM_QC_NO}, + {0x2F86B, UNICODE_NORM_QC_NO}, + {0x2F86C, UNICODE_NORM_QC_NO}, + {0x2F86D, UNICODE_NORM_QC_NO}, + {0x2F86E, UNICODE_NORM_QC_NO}, + {0x2F86F, UNICODE_NORM_QC_NO}, + {0x2F870, UNICODE_NORM_QC_NO}, + {0x2F871, UNICODE_NORM_QC_NO}, + {0x2F872, UNICODE_NORM_QC_NO}, + {0x2F873, UNICODE_NORM_QC_NO}, + {0x2F874, UNICODE_NORM_QC_NO}, + {0x2F875, UNICODE_NORM_QC_NO}, + {0x2F876, UNICODE_NORM_QC_NO}, + {0x2F877, UNICODE_NORM_QC_NO}, + {0x2F878, UNICODE_NORM_QC_NO}, + {0x2F879, UNICODE_NORM_QC_NO}, + {0x2F87A, UNICODE_NORM_QC_NO}, + {0x2F87B, UNICODE_NORM_QC_NO}, + {0x2F87C, UNICODE_NORM_QC_NO}, + {0x2F87D, UNICODE_NORM_QC_NO}, + {0x2F87E, UNICODE_NORM_QC_NO}, + {0x2F87F, UNICODE_NORM_QC_NO}, + {0x2F880, UNICODE_NORM_QC_NO}, + {0x2F881, UNICODE_NORM_QC_NO}, + {0x2F882, UNICODE_NORM_QC_NO}, + {0x2F883, UNICODE_NORM_QC_NO}, + {0x2F884, UNICODE_NORM_QC_NO}, + {0x2F885, UNICODE_NORM_QC_NO}, + {0x2F886, UNICODE_NORM_QC_NO}, + {0x2F887, UNICODE_NORM_QC_NO}, + {0x2F888, UNICODE_NORM_QC_NO}, + {0x2F889, UNICODE_NORM_QC_NO}, + {0x2F88A, UNICODE_NORM_QC_NO}, + {0x2F88B, UNICODE_NORM_QC_NO}, + {0x2F88C, UNICODE_NORM_QC_NO}, + {0x2F88D, UNICODE_NORM_QC_NO}, + {0x2F88E, UNICODE_NORM_QC_NO}, + {0x2F88F, UNICODE_NORM_QC_NO}, + {0x2F890, UNICODE_NORM_QC_NO}, + {0x2F891, UNICODE_NORM_QC_NO}, + {0x2F892, UNICODE_NORM_QC_NO}, + {0x2F893, UNICODE_NORM_QC_NO}, + {0x2F894, UNICODE_NORM_QC_NO}, + {0x2F895, UNICODE_NORM_QC_NO}, + {0x2F896, UNICODE_NORM_QC_NO}, + {0x2F897, UNICODE_NORM_QC_NO}, + {0x2F898, UNICODE_NORM_QC_NO}, + {0x2F899, UNICODE_NORM_QC_NO}, + {0x2F89A, UNICODE_NORM_QC_NO}, + {0x2F89B, UNICODE_NORM_QC_NO}, + {0x2F89C, UNICODE_NORM_QC_NO}, + {0x2F89D, UNICODE_NORM_QC_NO}, + {0x2F89E, UNICODE_NORM_QC_NO}, + {0x2F89F, UNICODE_NORM_QC_NO}, + {0x2F8A0, UNICODE_NORM_QC_NO}, + {0x2F8A1, UNICODE_NORM_QC_NO}, + {0x2F8A2, UNICODE_NORM_QC_NO}, + {0x2F8A3, UNICODE_NORM_QC_NO}, + {0x2F8A4, UNICODE_NORM_QC_NO}, + {0x2F8A5, UNICODE_NORM_QC_NO}, + {0x2F8A6, UNICODE_NORM_QC_NO}, + {0x2F8A7, UNICODE_NORM_QC_NO}, + {0x2F8A8, UNICODE_NORM_QC_NO}, + {0x2F8A9, UNICODE_NORM_QC_NO}, + {0x2F8AA, UNICODE_NORM_QC_NO}, + {0x2F8AB, UNICODE_NORM_QC_NO}, + {0x2F8AC, UNICODE_NORM_QC_NO}, + {0x2F8AD, UNICODE_NORM_QC_NO}, + {0x2F8AE, UNICODE_NORM_QC_NO}, + {0x2F8AF, UNICODE_NORM_QC_NO}, + {0x2F8B0, UNICODE_NORM_QC_NO}, + {0x2F8B1, UNICODE_NORM_QC_NO}, + {0x2F8B2, UNICODE_NORM_QC_NO}, + {0x2F8B3, UNICODE_NORM_QC_NO}, + {0x2F8B4, UNICODE_NORM_QC_NO}, + {0x2F8B5, UNICODE_NORM_QC_NO}, + {0x2F8B6, UNICODE_NORM_QC_NO}, + {0x2F8B7, UNICODE_NORM_QC_NO}, + {0x2F8B8, UNICODE_NORM_QC_NO}, + {0x2F8B9, UNICODE_NORM_QC_NO}, + {0x2F8BA, UNICODE_NORM_QC_NO}, + {0x2F8BB, UNICODE_NORM_QC_NO}, + {0x2F8BC, UNICODE_NORM_QC_NO}, + {0x2F8BD, UNICODE_NORM_QC_NO}, + {0x2F8BE, UNICODE_NORM_QC_NO}, + {0x2F8BF, UNICODE_NORM_QC_NO}, + {0x2F8C0, UNICODE_NORM_QC_NO}, + {0x2F8C1, UNICODE_NORM_QC_NO}, + {0x2F8C2, UNICODE_NORM_QC_NO}, + {0x2F8C3, UNICODE_NORM_QC_NO}, + {0x2F8C4, UNICODE_NORM_QC_NO}, + {0x2F8C5, UNICODE_NORM_QC_NO}, + {0x2F8C6, UNICODE_NORM_QC_NO}, + {0x2F8C7, UNICODE_NORM_QC_NO}, + {0x2F8C8, UNICODE_NORM_QC_NO}, + {0x2F8C9, UNICODE_NORM_QC_NO}, + {0x2F8CA, UNICODE_NORM_QC_NO}, + {0x2F8CB, UNICODE_NORM_QC_NO}, + {0x2F8CC, UNICODE_NORM_QC_NO}, + {0x2F8CD, UNICODE_NORM_QC_NO}, + {0x2F8CE, UNICODE_NORM_QC_NO}, + {0x2F8CF, UNICODE_NORM_QC_NO}, + {0x2F8D0, UNICODE_NORM_QC_NO}, + {0x2F8D1, UNICODE_NORM_QC_NO}, + {0x2F8D2, UNICODE_NORM_QC_NO}, + {0x2F8D3, UNICODE_NORM_QC_NO}, + {0x2F8D4, UNICODE_NORM_QC_NO}, + {0x2F8D5, UNICODE_NORM_QC_NO}, + {0x2F8D6, UNICODE_NORM_QC_NO}, + {0x2F8D7, UNICODE_NORM_QC_NO}, + {0x2F8D8, UNICODE_NORM_QC_NO}, + {0x2F8D9, UNICODE_NORM_QC_NO}, + {0x2F8DA, UNICODE_NORM_QC_NO}, + {0x2F8DB, UNICODE_NORM_QC_NO}, + {0x2F8DC, UNICODE_NORM_QC_NO}, + {0x2F8DD, UNICODE_NORM_QC_NO}, + {0x2F8DE, UNICODE_NORM_QC_NO}, + {0x2F8DF, UNICODE_NORM_QC_NO}, + {0x2F8E0, UNICODE_NORM_QC_NO}, + {0x2F8E1, UNICODE_NORM_QC_NO}, + {0x2F8E2, UNICODE_NORM_QC_NO}, + {0x2F8E3, UNICODE_NORM_QC_NO}, + {0x2F8E4, UNICODE_NORM_QC_NO}, + {0x2F8E5, UNICODE_NORM_QC_NO}, + {0x2F8E6, UNICODE_NORM_QC_NO}, + {0x2F8E7, UNICODE_NORM_QC_NO}, + {0x2F8E8, UNICODE_NORM_QC_NO}, + {0x2F8E9, UNICODE_NORM_QC_NO}, + {0x2F8EA, UNICODE_NORM_QC_NO}, + {0x2F8EB, UNICODE_NORM_QC_NO}, + {0x2F8EC, UNICODE_NORM_QC_NO}, + {0x2F8ED, UNICODE_NORM_QC_NO}, + {0x2F8EE, UNICODE_NORM_QC_NO}, + {0x2F8EF, UNICODE_NORM_QC_NO}, + {0x2F8F0, UNICODE_NORM_QC_NO}, + {0x2F8F1, UNICODE_NORM_QC_NO}, + {0x2F8F2, UNICODE_NORM_QC_NO}, + {0x2F8F3, UNICODE_NORM_QC_NO}, + {0x2F8F4, UNICODE_NORM_QC_NO}, + {0x2F8F5, UNICODE_NORM_QC_NO}, + {0x2F8F6, UNICODE_NORM_QC_NO}, + {0x2F8F7, UNICODE_NORM_QC_NO}, + {0x2F8F8, UNICODE_NORM_QC_NO}, + {0x2F8F9, UNICODE_NORM_QC_NO}, + {0x2F8FA, UNICODE_NORM_QC_NO}, + {0x2F8FB, UNICODE_NORM_QC_NO}, + {0x2F8FC, UNICODE_NORM_QC_NO}, + {0x2F8FD, UNICODE_NORM_QC_NO}, + {0x2F8FE, UNICODE_NORM_QC_NO}, + {0x2F8FF, UNICODE_NORM_QC_NO}, + {0x2F900, UNICODE_NORM_QC_NO}, + {0x2F901, UNICODE_NORM_QC_NO}, + {0x2F902, UNICODE_NORM_QC_NO}, + {0x2F903, UNICODE_NORM_QC_NO}, + {0x2F904, UNICODE_NORM_QC_NO}, + {0x2F905, UNICODE_NORM_QC_NO}, + {0x2F906, UNICODE_NORM_QC_NO}, + {0x2F907, UNICODE_NORM_QC_NO}, + {0x2F908, UNICODE_NORM_QC_NO}, + {0x2F909, UNICODE_NORM_QC_NO}, + {0x2F90A, UNICODE_NORM_QC_NO}, + {0x2F90B, UNICODE_NORM_QC_NO}, + {0x2F90C, UNICODE_NORM_QC_NO}, + {0x2F90D, UNICODE_NORM_QC_NO}, + {0x2F90E, UNICODE_NORM_QC_NO}, + {0x2F90F, UNICODE_NORM_QC_NO}, + {0x2F910, UNICODE_NORM_QC_NO}, + {0x2F911, UNICODE_NORM_QC_NO}, + {0x2F912, UNICODE_NORM_QC_NO}, + {0x2F913, UNICODE_NORM_QC_NO}, + {0x2F914, UNICODE_NORM_QC_NO}, + {0x2F915, UNICODE_NORM_QC_NO}, + {0x2F916, UNICODE_NORM_QC_NO}, + {0x2F917, UNICODE_NORM_QC_NO}, + {0x2F918, UNICODE_NORM_QC_NO}, + {0x2F919, UNICODE_NORM_QC_NO}, + {0x2F91A, UNICODE_NORM_QC_NO}, + {0x2F91B, UNICODE_NORM_QC_NO}, + {0x2F91C, UNICODE_NORM_QC_NO}, + {0x2F91D, UNICODE_NORM_QC_NO}, + {0x2F91E, UNICODE_NORM_QC_NO}, + {0x2F91F, UNICODE_NORM_QC_NO}, + {0x2F920, UNICODE_NORM_QC_NO}, + {0x2F921, UNICODE_NORM_QC_NO}, + {0x2F922, UNICODE_NORM_QC_NO}, + {0x2F923, UNICODE_NORM_QC_NO}, + {0x2F924, UNICODE_NORM_QC_NO}, + {0x2F925, UNICODE_NORM_QC_NO}, + {0x2F926, UNICODE_NORM_QC_NO}, + {0x2F927, UNICODE_NORM_QC_NO}, + {0x2F928, UNICODE_NORM_QC_NO}, + {0x2F929, UNICODE_NORM_QC_NO}, + {0x2F92A, UNICODE_NORM_QC_NO}, + {0x2F92B, UNICODE_NORM_QC_NO}, + {0x2F92C, UNICODE_NORM_QC_NO}, + {0x2F92D, UNICODE_NORM_QC_NO}, + {0x2F92E, UNICODE_NORM_QC_NO}, + {0x2F92F, UNICODE_NORM_QC_NO}, + {0x2F930, UNICODE_NORM_QC_NO}, + {0x2F931, UNICODE_NORM_QC_NO}, + {0x2F932, UNICODE_NORM_QC_NO}, + {0x2F933, UNICODE_NORM_QC_NO}, + {0x2F934, UNICODE_NORM_QC_NO}, + {0x2F935, UNICODE_NORM_QC_NO}, + {0x2F936, UNICODE_NORM_QC_NO}, + {0x2F937, UNICODE_NORM_QC_NO}, + {0x2F938, UNICODE_NORM_QC_NO}, + {0x2F939, UNICODE_NORM_QC_NO}, + {0x2F93A, UNICODE_NORM_QC_NO}, + {0x2F93B, UNICODE_NORM_QC_NO}, + {0x2F93C, UNICODE_NORM_QC_NO}, + {0x2F93D, UNICODE_NORM_QC_NO}, + {0x2F93E, UNICODE_NORM_QC_NO}, + {0x2F93F, UNICODE_NORM_QC_NO}, + {0x2F940, UNICODE_NORM_QC_NO}, + {0x2F941, UNICODE_NORM_QC_NO}, + {0x2F942, UNICODE_NORM_QC_NO}, + {0x2F943, UNICODE_NORM_QC_NO}, + {0x2F944, UNICODE_NORM_QC_NO}, + {0x2F945, UNICODE_NORM_QC_NO}, + {0x2F946, UNICODE_NORM_QC_NO}, + {0x2F947, UNICODE_NORM_QC_NO}, + {0x2F948, UNICODE_NORM_QC_NO}, + {0x2F949, UNICODE_NORM_QC_NO}, + {0x2F94A, UNICODE_NORM_QC_NO}, + {0x2F94B, UNICODE_NORM_QC_NO}, + {0x2F94C, UNICODE_NORM_QC_NO}, + {0x2F94D, UNICODE_NORM_QC_NO}, + {0x2F94E, UNICODE_NORM_QC_NO}, + {0x2F94F, UNICODE_NORM_QC_NO}, + {0x2F950, UNICODE_NORM_QC_NO}, + {0x2F951, UNICODE_NORM_QC_NO}, + {0x2F952, UNICODE_NORM_QC_NO}, + {0x2F953, UNICODE_NORM_QC_NO}, + {0x2F954, UNICODE_NORM_QC_NO}, + {0x2F955, UNICODE_NORM_QC_NO}, + {0x2F956, UNICODE_NORM_QC_NO}, + {0x2F957, UNICODE_NORM_QC_NO}, + {0x2F958, UNICODE_NORM_QC_NO}, + {0x2F959, UNICODE_NORM_QC_NO}, + {0x2F95A, UNICODE_NORM_QC_NO}, + {0x2F95B, UNICODE_NORM_QC_NO}, + {0x2F95C, UNICODE_NORM_QC_NO}, + {0x2F95D, UNICODE_NORM_QC_NO}, + {0x2F95E, UNICODE_NORM_QC_NO}, + {0x2F95F, UNICODE_NORM_QC_NO}, + {0x2F960, UNICODE_NORM_QC_NO}, + {0x2F961, UNICODE_NORM_QC_NO}, + {0x2F962, UNICODE_NORM_QC_NO}, + {0x2F963, UNICODE_NORM_QC_NO}, + {0x2F964, UNICODE_NORM_QC_NO}, + {0x2F965, UNICODE_NORM_QC_NO}, + {0x2F966, UNICODE_NORM_QC_NO}, + {0x2F967, UNICODE_NORM_QC_NO}, + {0x2F968, UNICODE_NORM_QC_NO}, + {0x2F969, UNICODE_NORM_QC_NO}, + {0x2F96A, UNICODE_NORM_QC_NO}, + {0x2F96B, UNICODE_NORM_QC_NO}, + {0x2F96C, UNICODE_NORM_QC_NO}, + {0x2F96D, UNICODE_NORM_QC_NO}, + {0x2F96E, UNICODE_NORM_QC_NO}, + {0x2F96F, UNICODE_NORM_QC_NO}, + {0x2F970, UNICODE_NORM_QC_NO}, + {0x2F971, UNICODE_NORM_QC_NO}, + {0x2F972, UNICODE_NORM_QC_NO}, + {0x2F973, UNICODE_NORM_QC_NO}, + {0x2F974, UNICODE_NORM_QC_NO}, + {0x2F975, UNICODE_NORM_QC_NO}, + {0x2F976, UNICODE_NORM_QC_NO}, + {0x2F977, UNICODE_NORM_QC_NO}, + {0x2F978, UNICODE_NORM_QC_NO}, + {0x2F979, UNICODE_NORM_QC_NO}, + {0x2F97A, UNICODE_NORM_QC_NO}, + {0x2F97B, UNICODE_NORM_QC_NO}, + {0x2F97C, UNICODE_NORM_QC_NO}, + {0x2F97D, UNICODE_NORM_QC_NO}, + {0x2F97E, UNICODE_NORM_QC_NO}, + {0x2F97F, UNICODE_NORM_QC_NO}, + {0x2F980, UNICODE_NORM_QC_NO}, + {0x2F981, UNICODE_NORM_QC_NO}, + {0x2F982, UNICODE_NORM_QC_NO}, + {0x2F983, UNICODE_NORM_QC_NO}, + {0x2F984, UNICODE_NORM_QC_NO}, + {0x2F985, UNICODE_NORM_QC_NO}, + {0x2F986, UNICODE_NORM_QC_NO}, + {0x2F987, UNICODE_NORM_QC_NO}, + {0x2F988, UNICODE_NORM_QC_NO}, + {0x2F989, UNICODE_NORM_QC_NO}, + {0x2F98A, UNICODE_NORM_QC_NO}, + {0x2F98B, UNICODE_NORM_QC_NO}, + {0x2F98C, UNICODE_NORM_QC_NO}, + {0x2F98D, UNICODE_NORM_QC_NO}, + {0x2F98E, UNICODE_NORM_QC_NO}, + {0x2F98F, UNICODE_NORM_QC_NO}, + {0x2F990, UNICODE_NORM_QC_NO}, + {0x2F991, UNICODE_NORM_QC_NO}, + {0x2F992, UNICODE_NORM_QC_NO}, + {0x2F993, UNICODE_NORM_QC_NO}, + {0x2F994, UNICODE_NORM_QC_NO}, + {0x2F995, UNICODE_NORM_QC_NO}, + {0x2F996, UNICODE_NORM_QC_NO}, + {0x2F997, UNICODE_NORM_QC_NO}, + {0x2F998, UNICODE_NORM_QC_NO}, + {0x2F999, UNICODE_NORM_QC_NO}, + {0x2F99A, UNICODE_NORM_QC_NO}, + {0x2F99B, UNICODE_NORM_QC_NO}, + {0x2F99C, UNICODE_NORM_QC_NO}, + {0x2F99D, UNICODE_NORM_QC_NO}, + {0x2F99E, UNICODE_NORM_QC_NO}, + {0x2F99F, UNICODE_NORM_QC_NO}, + {0x2F9A0, UNICODE_NORM_QC_NO}, + {0x2F9A1, UNICODE_NORM_QC_NO}, + {0x2F9A2, UNICODE_NORM_QC_NO}, + {0x2F9A3, UNICODE_NORM_QC_NO}, + {0x2F9A4, UNICODE_NORM_QC_NO}, + {0x2F9A5, UNICODE_NORM_QC_NO}, + {0x2F9A6, UNICODE_NORM_QC_NO}, + {0x2F9A7, UNICODE_NORM_QC_NO}, + {0x2F9A8, UNICODE_NORM_QC_NO}, + {0x2F9A9, UNICODE_NORM_QC_NO}, + {0x2F9AA, UNICODE_NORM_QC_NO}, + {0x2F9AB, UNICODE_NORM_QC_NO}, + {0x2F9AC, UNICODE_NORM_QC_NO}, + {0x2F9AD, UNICODE_NORM_QC_NO}, + {0x2F9AE, UNICODE_NORM_QC_NO}, + {0x2F9AF, UNICODE_NORM_QC_NO}, + {0x2F9B0, UNICODE_NORM_QC_NO}, + {0x2F9B1, UNICODE_NORM_QC_NO}, + {0x2F9B2, UNICODE_NORM_QC_NO}, + {0x2F9B3, UNICODE_NORM_QC_NO}, + {0x2F9B4, UNICODE_NORM_QC_NO}, + {0x2F9B5, UNICODE_NORM_QC_NO}, + {0x2F9B6, UNICODE_NORM_QC_NO}, + {0x2F9B7, UNICODE_NORM_QC_NO}, + {0x2F9B8, UNICODE_NORM_QC_NO}, + {0x2F9B9, UNICODE_NORM_QC_NO}, + {0x2F9BA, UNICODE_NORM_QC_NO}, + {0x2F9BB, UNICODE_NORM_QC_NO}, + {0x2F9BC, UNICODE_NORM_QC_NO}, + {0x2F9BD, UNICODE_NORM_QC_NO}, + {0x2F9BE, UNICODE_NORM_QC_NO}, + {0x2F9BF, UNICODE_NORM_QC_NO}, + {0x2F9C0, UNICODE_NORM_QC_NO}, + {0x2F9C1, UNICODE_NORM_QC_NO}, + {0x2F9C2, UNICODE_NORM_QC_NO}, + {0x2F9C3, UNICODE_NORM_QC_NO}, + {0x2F9C4, UNICODE_NORM_QC_NO}, + {0x2F9C5, UNICODE_NORM_QC_NO}, + {0x2F9C6, UNICODE_NORM_QC_NO}, + {0x2F9C7, UNICODE_NORM_QC_NO}, + {0x2F9C8, UNICODE_NORM_QC_NO}, + {0x2F9C9, UNICODE_NORM_QC_NO}, + {0x2F9CA, UNICODE_NORM_QC_NO}, + {0x2F9CB, UNICODE_NORM_QC_NO}, + {0x2F9CC, UNICODE_NORM_QC_NO}, + {0x2F9CD, UNICODE_NORM_QC_NO}, + {0x2F9CE, UNICODE_NORM_QC_NO}, + {0x2F9CF, UNICODE_NORM_QC_NO}, + {0x2F9D0, UNICODE_NORM_QC_NO}, + {0x2F9D1, UNICODE_NORM_QC_NO}, + {0x2F9D2, UNICODE_NORM_QC_NO}, + {0x2F9D3, UNICODE_NORM_QC_NO}, + {0x2F9D4, UNICODE_NORM_QC_NO}, + {0x2F9D5, UNICODE_NORM_QC_NO}, + {0x2F9D6, UNICODE_NORM_QC_NO}, + {0x2F9D7, UNICODE_NORM_QC_NO}, + {0x2F9D8, UNICODE_NORM_QC_NO}, + {0x2F9D9, UNICODE_NORM_QC_NO}, + {0x2F9DA, UNICODE_NORM_QC_NO}, + {0x2F9DB, UNICODE_NORM_QC_NO}, + {0x2F9DC, UNICODE_NORM_QC_NO}, + {0x2F9DD, UNICODE_NORM_QC_NO}, + {0x2F9DE, UNICODE_NORM_QC_NO}, + {0x2F9DF, UNICODE_NORM_QC_NO}, + {0x2F9E0, UNICODE_NORM_QC_NO}, + {0x2F9E1, UNICODE_NORM_QC_NO}, + {0x2F9E2, UNICODE_NORM_QC_NO}, + {0x2F9E3, UNICODE_NORM_QC_NO}, + {0x2F9E4, UNICODE_NORM_QC_NO}, + {0x2F9E5, UNICODE_NORM_QC_NO}, + {0x2F9E6, UNICODE_NORM_QC_NO}, + {0x2F9E7, UNICODE_NORM_QC_NO}, + {0x2F9E8, UNICODE_NORM_QC_NO}, + {0x2F9E9, UNICODE_NORM_QC_NO}, + {0x2F9EA, UNICODE_NORM_QC_NO}, + {0x2F9EB, UNICODE_NORM_QC_NO}, + {0x2F9EC, UNICODE_NORM_QC_NO}, + {0x2F9ED, UNICODE_NORM_QC_NO}, + {0x2F9EE, UNICODE_NORM_QC_NO}, + {0x2F9EF, UNICODE_NORM_QC_NO}, + {0x2F9F0, UNICODE_NORM_QC_NO}, + {0x2F9F1, UNICODE_NORM_QC_NO}, + {0x2F9F2, UNICODE_NORM_QC_NO}, + {0x2F9F3, UNICODE_NORM_QC_NO}, + {0x2F9F4, UNICODE_NORM_QC_NO}, + {0x2F9F5, UNICODE_NORM_QC_NO}, + {0x2F9F6, UNICODE_NORM_QC_NO}, + {0x2F9F7, UNICODE_NORM_QC_NO}, + {0x2F9F8, UNICODE_NORM_QC_NO}, + {0x2F9F9, UNICODE_NORM_QC_NO}, + {0x2F9FA, UNICODE_NORM_QC_NO}, + {0x2F9FB, UNICODE_NORM_QC_NO}, + {0x2F9FC, UNICODE_NORM_QC_NO}, + {0x2F9FD, UNICODE_NORM_QC_NO}, + {0x2F9FE, UNICODE_NORM_QC_NO}, + {0x2F9FF, UNICODE_NORM_QC_NO}, + {0x2FA00, UNICODE_NORM_QC_NO}, + {0x2FA01, UNICODE_NORM_QC_NO}, + {0x2FA02, UNICODE_NORM_QC_NO}, + {0x2FA03, UNICODE_NORM_QC_NO}, + {0x2FA04, UNICODE_NORM_QC_NO}, + {0x2FA05, UNICODE_NORM_QC_NO}, + {0x2FA06, UNICODE_NORM_QC_NO}, + {0x2FA07, UNICODE_NORM_QC_NO}, + {0x2FA08, UNICODE_NORM_QC_NO}, + {0x2FA09, UNICODE_NORM_QC_NO}, + {0x2FA0A, UNICODE_NORM_QC_NO}, + {0x2FA0B, UNICODE_NORM_QC_NO}, + {0x2FA0C, UNICODE_NORM_QC_NO}, + {0x2FA0D, UNICODE_NORM_QC_NO}, + {0x2FA0E, UNICODE_NORM_QC_NO}, + {0x2FA0F, UNICODE_NORM_QC_NO}, + {0x2FA10, UNICODE_NORM_QC_NO}, + {0x2FA11, UNICODE_NORM_QC_NO}, + {0x2FA12, UNICODE_NORM_QC_NO}, + {0x2FA13, UNICODE_NORM_QC_NO}, + {0x2FA14, UNICODE_NORM_QC_NO}, + {0x2FA15, UNICODE_NORM_QC_NO}, + {0x2FA16, UNICODE_NORM_QC_NO}, + {0x2FA17, UNICODE_NORM_QC_NO}, + {0x2FA18, UNICODE_NORM_QC_NO}, + {0x2FA19, UNICODE_NORM_QC_NO}, + {0x2FA1A, UNICODE_NORM_QC_NO}, + {0x2FA1B, UNICODE_NORM_QC_NO}, + {0x2FA1C, UNICODE_NORM_QC_NO}, + {0x2FA1D, UNICODE_NORM_QC_NO}, +}; + +/* Perfect hash function for NFKC_QC */ +static int +NFKC_QC_hash_func(const void *key) +{ + static const int16 h[10079] = { + 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, + 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, + 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565, + 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, + 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, + 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, + 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, + 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, + 3606, 3607, 3608, 3970, 3488, 3611, 3612, 3613, + 3614, 3615, 3616, 3617, 3618, 7967, 3620, 3621, + 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, + 3630, 3631, 3632, 3633, 3634, 3512, 3636, 3637, + 3638, 3639, 32767, 11118, 11119, 11120, 11121, 11122, + 1470, 11124, 11125, 11126, 11127, 11128, 11129, 11130, + 11131, 11132, -287, 8773, 8774, 8775, 8776, 8777, + 8778, -287, 8781, 8782, -287, 8783, 8784, 8785, + 8786, 8787, 8788, 8789, 8790, 8791, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, 2372, -287, -287, -287, -287, -287, -287, + -287, -287, -287, 2458, 2458, 2458, 2458, 2458, + 2458, 2458, 2458, 2458, -287, -287, -287, -5017, + 5765, -287, -5019, -5019, -5019, -5019, -287, -287, + 4632, -5021, -5021, -287, -5022, -5022, -5022, 3732, + -287, -287, 3735, 3736, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + 4994, 2491, 2491, -287, -287, -287, 6887, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, 32767, 32767, -289, 1778, 629, 3809, 3810, + -3050, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, 3861, 3862, 3863, 3864, 3865, 3866, + 3867, 3868, -1002, 3870, 3871, 3872, 3873, 3874, + 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, + 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, + 3891, 3892, 3893, 32767, 3392, 3392, 3392, -5411, + 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, + 3392, 3392, 224, 225, 226, 3392, 227, 228, + -5998, -5998, 3392, -5998, -5, 0, -5997, -5997, + -7477, 3923, -7478, -7478, -7478, -7478, -7478, -7478, + -7478, -7478, 2175, -7478, -7478, -7478, -7478, -7478, + -7478, -7478, -7478, -7478, 3942, -5117, -5117, -5117, + -5117, -5117, -5117, 3949, -5118, -5118, 3952, -5117, + -5117, -5117, -5117, -5117, -5117, -5117, -5117, -5117, + 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, + 3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, + 3978, 3979, 3980, 1322, 3982, 3983, 3984, 3985, + 3986, 3987, 3988, 3989, 3990, 1246, 1247, 1248, + 1249, 1250, 1251, 1252, 1253, 1254, 4000, 4001, + 4002, 8733, -2048, 4005, 8738, 8739, 8740, 8741, + 4010, 4011, -907, 8747, 8748, 4015, 8751, 8752, + 8753, 0, 4020, 4021, 0, 0, 4024, 4025, + 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, + 4034, 4035, -1245, 1259, 1260, 4039, 4040, 4041, + -3132, 4043, 4044, 4045, 4046, 4047, 4048, 4049, + 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, + 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, + 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, + 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, + 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, + 4090, 4091, 4092, 4093, 4094, 4095, 2029, 3179, + 0, 0, 6861, 4099, 4100, 4101, 4102, 4103, + 4104, 4105, 4106, 4107, 4108, 4109, 4110, 4111, + 4112, 4113, 4114, 4115, 4116, 4117, 4118, 4119, + 4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, + 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, + 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, + 4144, 4145, 4146, 4147, 0, 0, 0, 0, + 0, 0, 0, 0, 4871, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, -1786, -1785, -1784, -1783, -1782, 5982, + -630, -48, -48, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 677, + 32767, 32767, -636, -635, 1019, -3373, 1019, 1019, + 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, + 1019, 1019, 1019, 1019, 1019, -685, -684, -683, + -682, -681, -6170, -679, -678, 2476, 2477, -6912, + 2479, -3513, 3959, 2482, 2483, 3964, 3965, 3966, + 3967, 3968, 3969, 3970, 3971, 3972, 55, 56, + 2495, 57, 58, 59, 60, 61, 62, 63, + 2503, 2504, 64, 2506, 65, 2508, 66, 67, + 2511, 2512, 32767, 32767, 32767, 32767, 68, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 69, 70, + 71, 72, 73, 74, 1140, 2514, 2515, 422, + 75, 2518, -1594, 556, 557, 2522, 2523, 2524, + 2525, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 422, 422, 422, 422, 422, -2277, + -2277, -2277, -2277, -2277, 32767, 32767, -2279, -2279, + -2279, -2279, -2279, -2279, -2279, -2279, -2279, 86, + -2279, -2279, -2279, -2279, -2279, 87, -2279, -2279, + -2279, 88, -2279, -2279, -2279, -2279, -2279, 89, + 453, 453, 453, 453, 453, 453, 2609, 453, + 453, 453, 453, 453, 453, 453, 453, 453, + 453, 453, 453, 1817, 453, 453, 453, 453, + 453, 453, 453, 453, 32767, 32767, 32767, 681, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -2319, 2632, -2319, -2319, + -2319, 2636, 2637, 92, 2639, 2640, 95, 96, + 97, 98, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 3279, 3280, 3281, 3282, 3283, 3284, + 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, + -384, -1535, -385, -385, 0, 3298, 3299, 3300, + 3301, 3302, 3303, 3304, -8646, -1149, -1148, -1147, + -1146, 32767, 3310, 3311, 3312, 3313, 3314, -1140, + -1139, -1138, -1137, -1136, -1135, -1134, -1133, -1132, + 3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, + 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, + 3340, 3341, 3342, 3343, 3344, -1327, -1327, -1327, + -1327, -1327, 32767, 32767, 2346, 32767, 32767, 32767, + 32767, 32767, 3350, 335, 3245, 8185, 1818, 666, + 1818, 795, 795, 1818, 1818, 1818, 1818, 1818, + -5945, 668, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 0, 0, 671, 671, 671, + 671, 671, 0, 0, 673, 673, 673, 0, + 674, 0, 675, 0, 676, 0, 677, 677, + 677, 32767, 0, 677, 677, -976, 3417, -974, + -973, 678, 678, -972, -971, -970, -969, -968, + 1152, 1153, 1154, 1155, 1156, 0, 1022, 1022, + 5615, -6335, 1162, 1163, 1164, 1165, 5621, 5622, + 5623, 5624, 5625, 5626, 1172, 1173, 1174, 1175, + 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, + 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, + 1192, 1193, 9997, 1195, 1196, 1197, 1198, 1199, + 1200, 1201, 1202, 1203, 1204, 4373, 4373, 4373, + 1208, 4374, 4374, 10601, 10602, 1213, 10604, 4612, + 4608, 10606, 10607, 12088, 1220, 1221, 1222, 1223, + 1224, 1225, 1226, 2453, 2454, 2455, 2456, 2457, + 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, + 2466, 2467, 6860, 2469, 2470, 2471, 2472, 2473, + 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, + 2482, 2483, 2484, 258, 2486, 2487, 258, 258, + 0, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 5673, 5674, + 0, 5677, 0, 5680, 5681, 5682, 5683, 5684, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 682, 683, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 105, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 2315, 4754, 2316, 2317, 2318, 2319, 2320, 2321, + 2322, 4762, 4763, 2323, 4765, 2324, 4767, 2325, + 2326, 4770, 4771, 4772, 2377, 4774, 4775, 4776, + 4777, 4778, 4779, 4780, 4781, 4782, 4783, 4784, + 4785, 4786, 4787, 4788, 4789, 3417, 4791, 4792, + 2699, 2352, 4795, 683, 2833, 2834, 4799, 4800, + 4801, 4802, 2699, 2699, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2365, 0, 0, 0, 0, 0, 2366, 0, + 0, 0, 2367, 0, 0, 0, 0, 0, + 2368, 2732, 2732, 2732, 2732, 2732, 2732, 4888, + 2732, 2732, 2732, 2732, 2732, 2732, 2732, 2732, + 2732, 2732, 2732, 2732, 4096, 2732, 2732, 2732, + 2732, 2732, 2732, 2732, 2732, 2732, 2732, 2732, + 2732, 2732, 2732, 2732, 2732, 2732, 2732, 2732, + 2732, 2732, 2732, 2732, 2732, 2732, 4927, 0, + 0, 0, 0, 0, 4933, 0, 0, 0, + 0, -2910, 0, 4940, 4941, 4942, 0, 0, + 0, 0, 0, 0, 0, 0, 4951, 0, + 0, 0, 4955, 4956, 2411, 4958, 4959, 2414, + 2415, 2416, 0, 10954, 0, 3436, 0, 0, + 0, 0, 0, -3170, -3169, -3168, -3167, 3446, + 2865, 0, 0, 0, 0, 0, 2339, 2339, + 2339, 2339, 2339, 2339, 2339, 2339, 2892, 2339, + 0, 0, 0, 0, 0, 0, 2907, 0, + 0, 0, 0, 0, 0, 4719, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 1856, 868, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 1856, + 1856, 1856, 1856, 1856, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 6441, 6442, 6443, + 6444, 6445, 6446, 6447, 6448, 6449, 6450, 6451, + 6452, -1169, 6454, 6455, 6456, 6457, 6458, 6459, + 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, + 6468, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, -3334, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -766, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, -1530, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 686, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 687, 688, 689, 690, 691, 692, 693, 694, + 695, 2465, 697, 698, 699, 700, 701, 702, + 703, 704, 705, 2484, 707, 708, 709, 710, + 2493, 712, 713, 714, 715, 2502, 717, 718, + 719, 720, 2511, 722, 723, 724, 725, 726, + 727, 728, 729, 730, 731, 732, 733, 2536, + 735, 736, 737, 738, 739, 740, 741, 742, + 743, 2555, 745, 2558, 2559, 2560, 2561, 2562, + 751, 752, 753, 754, 755, 756, 757, 2577, + 759, 760, 761, 762, 763, 764, 1224, 1224, + 767, 768, 769, 770, 3787, 772, 773, 774, + 775, 776, 777, 778, 779, 780, 781, 782, + 783, 784, 785, 786, 787, 788, 789, 790, + 791, 792, 793, 794, 795, 796, 797, 798, + 799, 800, 801, 802, 803, 804, 805, 806, + 807, 808, 809, 810, 811, 812, 813, 814, + 815, 816, 817, 818, 819, 820, 821, 822, + 823, 824, 825, 826, 827, 828, 829, 830, + 831, 832, 833, 834, 835, 836, 837, 838, + 839, 840, 841, 842, 843, 844, 845, 846, + 847, 848, 849, 850, 851, 852, 853, 854, + 855, 856, 857, 858, 859, 860, 861, 862, + 863, 864, 865, 866, 867, 868, 869, 870, + 871, 872, 873, 874, 875, 876, 877, 878, + 879, 880, 881, 882, 883, 884, 885, 886, + 887, 888, 889, 890, 891, 892, 893, 894, + 895, 896, 897, 898, 899, 900, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 901, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, -1268, + 32767, 32767, 32767, 32767, 32767, -984, -984, -2101, + -2101, -2101, -2101, 32767, 3402, 3403, -985, -985, + 32767, 32767, 0, -986, -986, -986, -986, -986, + -986, -986, 32767, -987, -987, -987, -987, -987, + -987, -987, 32767, -988, -988, -988, -988, -1746, + -988, -1747, -1747, -1194, -988, -988, -988, -988, + -988, -988, -988, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32767, + 0, 0, 0, 321, 32767, 0, 0, 0, + 0, 0, 32767, 0, 32767, 32767, 32767, -968, + 0, 0, 0, 0, 0, 0, 32767, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 333, 113, 333, 2915, + 333, 333, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -934, 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, 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, -361, 122, + 0, 0, 0, 0, 0, 0, 0, 0, + -4348, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 123, 0, 0, 0, 0, -3819, -3818, 32767, + 126, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 5367, 5368, 914, 915, 916, + 917, 918, 919, 920, 921, 922, 923, 924, + 925, 926, 927, 928, 929, 930, 931, 932, + 933, 934, 935, 9739, 937, 938, 939, 940, + 941, 942, 943, 944, 945, 946, 4115, 4115, + 4115, 950, 4116, 4116, 10343, 10344, 955, 10346, + 4354, 4350, 10348, 10349, 11830, 962, 963, 964, + 965, 966, 967, 968, 2195, 2196, 2197, 2198, + 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, + 2207, 2208, 2209, 6602, 2211, 2212, 2213, 2214, + 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, + 2223, 2224, 2225, 2226, 0, 2228, 2229, 0, + 0, 2232, 0, 129, 2235, 2236, -260, -260, + 2239, 2240, 2241, 2242, -260, 2244, 2245, 2246, + 2247, 2248, 2249, 2250, 2251, 2252, 2253, -2259, + -2259, -2259, -2259, -2259, -2259, -2259, -2259, -2259, + -2259, 2264, 2265, -2259, 2267, 2268, 2269, 2270, + 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, + -2729, 2280, 2281, 2282, 2283, 2284, 2285, 2286, + 2287, 2288, 2289, 2290, 2291, 2292, 3281, 3282, + 3283, 3284, 3285, 3286, 3287, 3288, 3289, 3290, + 3291, 2304, 2305, 2306, 2307, 2308, 3292, 3293, + 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, + 3302, 3303, 3304, 3305, 3306, 3307, 3308, -2259, + -2259, -2259, -2259, -2259, -2259, -2259, -2259, -2259, + -2259, -2259, -2259, 5363, -2259, -2259, -2259, -2259, + -2259, -2259, -2259, -2259, -2259, -2259, -2259, -2259, + -2259, -2259, -2259, -2259, -2259, -2259, -2259, -2259, + -2259, 1418, 2570, 1421, 1422, 1038, -2259, -2259, + -2259, -2259, -2259, -2259, -2259, 9692, 2196, 2196, + 2196, 2196, -2259, -2259, -2259, -2259, -2259, -2259, + 2196, 2196, 2196, 2196, 2196, 2196, 2196, 2196, + 2196, -2259, -2259, -2259, -2259, -2259, -2259, -2259, + -2259, -2259, -2259, -2259, -2259, -2259, -2259, -2259, + -2259, -2259, -2259, -2259, -2259, -2259, 2413, 2414, + 2415, 2416, 2417, 2418, 2419, 301, 302, 760, + -2259, -2259, -2259, -2259, 757, -2152, -7091, -723, + 430, -721, 303, 304, -718, -717, -716, -715, + -714, 7050, 438, 1020, 1020, 1020, 1020, 1020, + 1020, 1020, 1020, 1020, 1116, 1117, 447, 448, + 449, 450, 451, 1123, 1124, 452, 453, 454, + 1128, 455, 1130, 456, 1132, 457, 1134, 458, + 459, 460, 461, 1138, 462, 463, 2117, -2275, + 2117, 2117, 467, 468, 2119, 2119, 2119, 2119, + 2119, 0, 0, 0, 0, 0, 1157, 136, + 137, -4455, 7496, 0, 0, 0, 0, -4455, + -4455, -4455, -4455, -4455, -4455, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -8803, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -3168, -3167, + -3166, 0, -3165, -3164, -9390, -9390, 0, -9390, + -3397, -3392, -9389, -9389, -10869,0, 0, 0, + 0, 0, 0, 0, -1226, -1226, -1226, -1226, + -1226, -1226, -1226, -1226, -1226, -1226, -1226, -1226, + -1226, -1226, -1226, -5618, -1226, -1226, -1226, -1226, + -1226, -1226, -1226, -1226, -1226, -1226, -1226, -1226, + -1226, -1226, -1226, -1226, 1001, -1226, -1226, 1004, + 1005, 1264, 1265, 32767, -1229, -1229, 1268, 1269, + -1229, -1229, -1229, -1229, 1274, -1229, -1229, -1229, + -1229, -1229, 139, 1281, 1282, 1283, 1284, 1285, + 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, + 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, + 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, + 1310, 1311, 1675, 1313, 1676, 1315, 1316, 1317, + 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, + 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, + 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, + 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, + 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, + 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, + 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, + 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, + 1382, 1383, 1384, 1385, 1386, 1387, 3934, 3935, + 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, + 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, + 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, + 1414, 1415, 1416, 1417, 1418, 935, 1320, 4618, + 1422, 4621, 4622, 1425, 1426, 1427, -7322, 5372, + 1430, 1431, 5375, 891, 891, 891, 891, 891, + 891, 891, 5376, 2037, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 141, 891, + 891, 891, 891, 891, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 142, 143, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 1999, 4498, 4499, 4500, 4501, 1999, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4523, 4524, 0, 4526, 4527, 4528, + 4529, 4530, 4531, 4532, 4533, 4534, 4535, 4536, + 4537, -470, 4539, 4540, 4541, 4542, 4543, 4544, + 4545, 4546, 4547, 4548, 4549, 4550, 4551, 5540, + 5541, 5542, 5543, 5544, 5545, 5546, 5547, 5548, + 5549, 5550, 4563, 4564, 4565, 4566, 4567, 5551, + 5552, 5553, 5554, 5555, 5556, 5557, 5558, 5559, + 5560, 5561, 5562, 5563, 5564, 5565, 5566, 5567, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7622, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3677, 4829, 3680, 3681, 3297, 0, + 0, 0, 0, 0, 0, 0, 11951, 4455, + 4455, 4455, 4455, 0, 0, 0, 0, 0, + 0, 4455, 4455, 4455, 4455, 4455, 4455, 4455, + 4455, 4455, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4672, + 4673, 4674, 4675, 4676, 4677, 4678, 2560, 2561, + 3019, 0, 0, 0, 0, 3016, 107, -4832, + 1536, 2689, 1538, 2562, 2563, 1541, 1542, 1543, + 1544, 1545, 9309, 2697, 3279, 3279, 3279, 3279, + 3279, 3279, 3279, 3279, 3279, 3279, 3279, -1113, + 3279, 3279, 3279, 3279, 3279, 3279, 3279, 3279, + 3279, 3279, 3279, 3279, 3279, 3279, 3279, 1575, + 1576, 1577, 1578, 1579, -3910, 1581, 1582, 4736, + 4737, -4652, 4739, -1253, 6219, 4742, 4743, 6224, + 6225, 6226, 6227, 6228, 6229, 6230, 6231, 6232, + 6233, -3419, 6235, 6236, 6237, 6238, 6239, 6240, + 6241, 6242, 6243, 3882, 3883, 3884, 3885, 3886, + 3887, 3888, -5177, 3891, 3892, -5177, 3893, 3894, + 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, + -5176, -5176, -5176, -5176, -5176, -5176, -5176, -5176, + 1640, 1641, 1642, 3924, 1644, 1645, 1646, 1647, + 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, + 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, + 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, + 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, + 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, + 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, + 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, + 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, + 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, + 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, + 1728, 1729, 1730, 1731, -847, -5786, 582, 1735, + 1736, 1609, 1610, 588, 1740, 591, 592, 593, + 8357, 1745, 2327, 2327, 2327, 2327, 2327, 2327, + 1357, 2328, 2328, 1755, 1756, 1757, 1758, 1759, + 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, + 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, + 1776, 1777, 1778, 1779, 1780, 3434, 1782, 3435, + 3435, 1785, 1786, 3437, 3437, 3437, 3306, 32767, + -2509, -2509, -2509, -2509, -2509, -2509, -2509, -2509, + -2509, 1800, -2508, -2508, -2508, -2508, 32767, 32767, + -2510, 32767, -2511, 32767, 32767, -2513, -2513, -2513, + -2513, -2513, -2513, 1813, 1814, 1815, 1816, 32767, + -2509, 32767, -2510, 32767, 32767, -2511, -2511, 32767, + 32767, 32767, -3871, -3871, -2513, -2513, -2513, -2513, + -2513, -2513, -2513, -2513, -2513, -2513, -2513, -2513, + -2513, -2513, -2513, 1838, 1839, 1840, 1841, 1842, + 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, + 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, + 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, + 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, + 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, + 1883, 1401, 1885, 1886, 1887, 1888, 32767, 32767, + 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, + 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, + 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, + 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, + 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, + 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, + 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, + 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, + 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, + 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, + 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, + 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, + 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, + 3710, 1994, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 167, 612, 32767, 32767, 2714, 32767, + 32767, 32767, 32767, 32767, 168, 32767, 32767, 32767, + 32767, 169, 32767, 32767, 32767, 32767, 170, 32767, + 32767, 32767, 32767, 171, 32767, 32767, 32767, 32767, + 32767, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 172, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -1151, -127, -126, -1148, + -1147, 32767, 32767, 32767, 32767, 32767, 585, 32767, + 584, 584, 584, 584, 584, 584, 584, 584, + 584, -3808, 584, 584, 584, 584, 584, 584, + 584, 584, 584, 584, 584, 584, 584, 584, + 32767, -1121, -1120, -1119, -1118, -1117, 32767, -1116, + 32767, 2038, 2039, 32767, 2040, -3952, 32767, 2042, + 2043, 3524, 3525, 3526, 3527, 3528, 3529, 3530, + 3531, 3532, -385, -384, 2055, -383, -382, -381, + -380, -379, -378, -377, 2063, 2064, -376, 2066, + -375, 2068, -374, -373, 2071, 2072, 2073, -322, + 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, + 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, + 718, 2092, 2093, 0, -347, 2096, -2016, 134, + 135, 2100, 2101, 2102, 2103, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2156, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1364, + 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, -4392, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2227, 0, 0, 2230, 2231, 0, + 2233, 2105, 0, 0, 2497, 2498, 0, 0, + 0, 0, 2503, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4513, 4514, 4515, + 4516, 4517, 4518, 4519, 4520, 4521, 4522, 0, + 0, 4525, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5008, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -988, -988, -988, -988, + -988, -988, -988, -988, -988, -988, -988, 0, + 0, 0, 0, 0, -983, -983, -983, -983, + -983, -983, -983, -983, -983, -983, -983, -983, + -983, -983, -983, -983, -983, 4585, 4586, 4587, + 4588, 4589, 4590, 4591, 4592, 4593, 4594, 4595, + 4596, -3025, 4598, 4599, 4600, 4601, 4602, 4603, + 4604, 4605, 4606, 4607, 4608, 4609, 4610, 4611, + 4612, 4613, 4614, 4615, 4616, 4617, 4618, 942, + -209, 941, 941, 1326, 4624, 4625, 4626, 4627, + 4628, 4629, 4630, -7320, 177, 178, 179, 180, + 4636, 4637, 4638, 4639, 4640, 4641, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 4651, + 4652, 4653, 4654, 4655, 4656, 4657, 4658, 4659, + 4660, 4661, 4662, 4663, 4664, 4665, 4666, 4667, + 4668, 4669, 4670, 4671, 0, 0, 0, 0, + 0, 0, 0, 2119, 2119, 1662, 4682, 4683, + 4684, 4685, 1670, 4580, 9520, 3153, 2001, 3153, + 2130, 2130, 3153, 3153, 3153, 3153, 3153, -4610, + 2003, 1422, 1423, 1424, 1425, 1426, 1427, 1428, + 1429, 1430, 1431, 1432, 5825, 1434, 1435, 1436, + 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, + 1445, 1446, 1447, 1448, 3153, 3153, 3153, 3153, + 3153, 8643, 3153, 3153, 0, 0, 9390, 0, + 5993, -1478, 0, 0, -1480, -1480, -1480, -1480, + -1480, -1480, -1480, -1480, -1480, 2438, 2438, 0, + 2439, 2439, 2439, 2439, 2439, 2439, 2439, 0, + 0, 2441, 0, 2442, 0, 2443, 2443, 0, + 0, 0, 2396, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1373, 0, 0, 2094, 2442, + 0, 4113, 1964, 1964, 0, 0, 0, 0, + 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, + 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, + 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, + 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, + 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, + 2144, 2145, 2146, 2147, 2148, 2149, 4849, 4850, + 4851, 4852, 4853, 4854, 4855, 4856, 4857, 4858, + 4859, 4860, 4861, 4862, 4863, 4864, 2500, 4866, + 4867, 4868, 4869, 4870, 2505, 4872, 4873, 4874, + 2508, 4876, 4877, 4878, 4879, 4880, 2513, 2150, + 2151, 2152, 2153, 2154, 2155, 0, 2157, 2158, + 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, + 2167, 2168, 805, 2170, 2171, 2172, 2173, 2174, + 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, + 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, + 2191, 2192, 2193, 2194, 0, 4928, 4929, 4930, + 4931, 4932, 0, 4934, 4935, 4936, 4937, 7848, + 4939, 0, 0, 0, 4943, 4944, 4945, 4946, + 4947, 4948, 4949, 4950, 0, 4952, 4953, 4954, + 0, 0, 2546, 0, 0, 2546, 2546, 2546, + 4963, -5990, 4965, 1530, 4967, 4968, 4969, 4970, + 4971, 8142, 8142, 8142, 8142, 1530, 2112, 4978, + 4979, 4980, 4981, 4982, 2644, 2645, 2646, 2647, + 2648, 2649, 2650, 2651, 2099, 2653, 4993, 4994, + 4995, 4996, 4997, 4998, 2092, 5000, 5001, 5002, + 5003, 5004, 5005, 287, 5007, 5008, 32767, 5009, + 5010, 5011, 5012, -2457, 5014, -2456, 5016, 5017, + 5018, 5019, 5020, 5021, 5022, 5023, 5024, 5025, + 5026, 5027, 5028, -4624, 5030, 5031, 5032, 5033, + 5034, 5035, 5036, 5037, 5038, 2677, 2678, 2679, + 2680, 2681, 2682, 2683, 2684, 2685, 2686, -6383, + 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, + 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, + 2703, 2704, 2705, 32767, 2706, 2707, 2708, 2709, + 32767, 32767, 32767, 32767, 2710, 4682, 4683, 32767, + 2713, 32767, 2714, 906, 907, 908, 909, 2719, + 2720, 910, 2722, 2723, 2724, 2725, 2726, 2727, + 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, + 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, + 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, + 2752, 2753, 2974, 2755, 174, 2757, 2758, 2759, + 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, + 2768, 2769, 2770, 6689, 6690, 6691, 2774, 2775, + 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, + 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, + 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, + 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, + 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, + 2816, 5259, 2818, 3298, 3299, 2821, 2822, 2823, + 2824, 2825, 2826, 3170, 2828, 2829, 2830, 2831, + 2832, 2833, 2834, 3177, 3177, 3177, 3177, 3177, + 3177, 2841, 2842, 2843, 2844, 2845, 2846, 2847, + 2848, 32767, 32767, 32767, 32767, 32767, 2849, 2850, + 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, + 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, + 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, + 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, + 2883, -1495, 2885, 2886, 4004, 4005, 4006, 4007, + 4008, -1495, -1495, 2894, 2895, -1495, -1495, 2898, + 2899, 2900, 2901, 2902, 2903, 2904, 2905, -1494, + 2907, 2908, 2909, 2910, 2911, 2912, 2913, -1494, + 2915, 2916, 2917, 2918, 3677, 2920, 3680, 3681, + 3129, 2924, 2925, 2926, 2927, 2928, 2929, 2930, + 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, + 2939, 2940, 2941, 2942, 2943, 2944, 2945, 2946, + 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, + 2955, 2956, -1468, -1468, 2959, 2960, 2961, 2962, + 2963, 2964, 2965, 2966, 2967, 2968, 2969, 2970, + 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, + 2979, 2980, 2981, 2982, 2983, 2984, 2985, 2986, + 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, + 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, + 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, + 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, + 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, + 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, + 3035, 3036, 3037, 3038, 32767, 32767, 32767, 3039, + 3040, 3041, 3042, 3043, 3044, 32767, 32767, 3045, + 3046, 3047, 3048, 3049, 3050, 32767, 32767, 3051, + 3052, 3053, 3054, 3055, 3056, 32767, 32767, 3057, + 3058, 3059, 32767, 32767, 32767, 3060, 3061, 3062, + 3063, 3064, 3065, 3066, 32767, 3067, 3068, 3069, + 3070, 3071, 3072, 3073, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, 32767, 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, + 32767, 0, 0, 32767, 0, 32767, 32767, 0, + 32767, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 32767, 0, 0, 0, 0, + 32767, 0, 32767, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 0, 32767, 32767, 32767, 32767, 0, + 32767, 0, 32767, 0, 32767, 0, 0, 0, + 32767, 0, 0, 32767, 0, 32767, 32767, 0, + 32767, 0, 32767, 0, 32767, 0, 32767, 0, + 32767, 0, 0, 32767, 0, 32767, 32767, 0, + 0, 0, 0, 32767, 0, 0, 0, 0, + 0, 0, 0, 32767, 0, 0, 0, 0, + 32767, 0, 0, 0, 0, 32767, 0, 32767, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32767, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 32767, 0, 0, 0, 32767, 0, 0, 0, + 0, 0, 32767, -1358, -1358, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, -847, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 5181, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, -2069, 32767, 32767, -2071, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 0, -2105, -2105, 32767, 32767, -2107, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 256, + 257, 258, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 4210, 4211, 4212, 4213, 32767, + 4214, 4215, 4216, 4217, 4218, 4219, 4220, 4221, + 4222, 4223, 4224, 4225, 4226, 4227, 4228, 4229, + 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, + 4238, 4239, 4240, 32767, 4241, 4242, 32767, 4243, + 32767, 32767, 4244, 32767, 4245, 4246, 4247, 4248, + 4249, 4250, 4251, 4252, 4253, 4254, 32767, 4255, + 4256, 4257, 4258, 32767, 4259, 32767, 4260, 32767, + 32767, 32767, 32767, 32767, 32767, 4261, 32767, 32767, + 32767, 32767, 4262, 32767, 4263, 32767, 4264, 32767, + 4265, 4266, 4267, 32767, 4268, 4269, 32767, 4270, + 32767, 32767, 4271, 32767, 4272, 32767, 4273, 32767, + 4274, 32767, 4275, 32767, 4276, 4277, 32767, 4278, + 32767, 32767, 4279, 4280, 4281, 4282, 32767, 4283, + 4284, 4285, 4286, 4287, 4288, 4289, 32767, 4290, + 4291, 4292, 4293, 32767, 4294, 4295, 4296, 4297, + 32767, 4298, 32767, 4299, 4300, 4301, 4302, 4303, + 4304, 4305, 4306, 4307, 4308, 0, 4309, 4310, + 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4318, + 4319, 4320, 4321, 4322, 4323, 4324, 4325, 0, + 0, 0, 0, 32767, 4326, 4327, 4328, 32767, + 4329, 4330, 4331, 4332, 4333, 32767, 5692, 5693, + 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, + 4344, 4345, 4346, 4347, 4348, 4349, 4350, 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, 483, 0, 0, + 0, 0, 32767, 32767, 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, 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, -1717, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1769, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1778, 0, 0, + 0, 0, -1782, 0, 0, 0, 0, -1786, + 0, 0, 0, 0, -1790, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1802, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1811, 0, -1812, -1812, -1812, + -1812, -1812, 0, 0, 0, 0, 0, 0, + 0, -1819, 0, 0, 0, 0, 0, 0, + -459, -458, 0, 0, 0, 0, -3016, 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, 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, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 0, 32767, + 0, 32767, 0, 0, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 223, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 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, 4379, + 0, 0, -1117, -1117, -1117, -1117, -1117, 4387, + 4388, 0, 0, 4391, 4392, 0, 0, 0, + 0, 0, 0, 0, 0, 4400, 0, 0, + 0, 0, 0, 0, 0, 4408, 0, 0, + 0, 0, -758, 0, -759, -759, -206, 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, + 4425, 4426, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32767, 32767, 32767, 0, 0, 0, + 0, 0, 0, 32767, 32767, 0, 0, 0, + 0, 0, 0, 32767, 32767, 0, 0, 0, + 0, 0, 0, 32767, 32767, 0, 0, 0, + 32767, 32767, 32767, 0, 0, 0, 0, 0, + 0, 0, 32767, 0, 0, 0, 0, 0, + 0, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 4429, + 4430, 4431, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 4432, + 4433, 4434, 4435, 4436, 4437, 4438, 4439, 4440, + 4441, 4442, 4443, 4444, 4445, 4446, 4447, 4448, + 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, + 4457, 4458, 4459, 4460, 4461, 4462, 4463, 4464, + 4465, 4466, 4467, 4468, 4469, 4470, 4471, 4472, + 4473, 4474, 4475, 32767, 32767, 32767, 32767, 4476, + 4477, 4478, 4479, 4480, 4481, 539, 540, 4484, + 0, 0, 0, 0, 0, 0, 0, 4485, + 1146, 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -750, 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, 6227, + 6228, -3161, 6230, 238, 234, 6232, 6233, 7714, + 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, + 7723, -1929, 7725, 7726, 7727, 7728, 7729, 7730, + 7731, 7732, 7733, 5372, 5373, 5374, 5375, 5376, + 5377, 5378, -3687, 5381, 5382, -3687, 5383, 5384, + 5385, 5386, 5387, 5388, 5389, 5390, 5391, -3687, + -3687, -3687, -3687, -3687, -3687, -3687, -3687, -3687, + 3129, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, -3700, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 285, -3734, -3734, 288, 289, -3734, -3734, -3734, + -3734, -3734, -3734, -3734, -3734, -3734, -3734, -3734, + -3734, 1547, -956, -956, -3734, -3734, -3734, 3440, + -3734, -3734, -3734, -3734, -3734, -3734, -3734, -3734, + -3734, -3734, -3734, -3734, -3734, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 322, 323, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 0, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 114, 115, 116, 117, 118, 119, 120, + 121, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 0, 0, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 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, 32767, 32767, 32767, 32767, 0, + 0, 0, 0, 0, 0, 3943, 3943, 0, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 3340, 32767, 325, 32767, 326, 32767, 327, 32767, + 328, 32767, 329, 32767, 330, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 331, 32767, 332, 333, 334, 335, + 336, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 337, 32767, 338, 32767, 339, 340, 341, 32767, + 32767, 32767, 342, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 343, 32767, 344, 345, 346, 32767, + 32767, 32767, 347, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 348, 32767, 349, 350, 351, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 352, 32767, 353, 32767, 354, 355, 32767, 32767, + -1816, -1816, -1816, -1816, -1816, -1816, -1816, -1816, + -1816, -1816, -1816, 32767, 32767, 32767, 32767, 32767, + 32767, -1822, 32767, 32767, 32767, 32767, 32767, 368, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 369, 370, 371, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 372, + 32767, 32767, 32767, 373, 374, 32767, 375, 376, + 32767, 32767, 32767, 32767, 6367, 0, -1152, 0, + -1023, -1023, 0, 0, 0, 0, 0, -7763, + -1150, -1731, -1730, -1729, -1728, -1727, -1726, -1725, + -1724, -1723, -1722, -1721, 2672, -1719, -1718, -1717, + -1716, -1715, -1714, -1713, -1712, -1711, -1710, -1709, + -1708, -1707, -1706, -1705, 0, 0, 0, 0, + 0, 5490, 0, 0, -3153, -3153, 6237, -3153, + 2840, -4631, -3153, -3153, -4633, -4633, -4633, -4633, + -4633, -4633, -4633, -4633, -4633, -4633, 5020, -4633, + -4633, -4633, -4633, -4633, -4633, -4633, -4633, -4633, + -2271, -2271, -2271, -2271, -2271, -2271, -2271, 6795, + -2272, -2272, 6798, -2271, -2271, -2271, -2271, -2271, + -2271, -2271, -2271, -2271, -2271, 6808, 6809, 6810, + 6811, 6812, 6813, 6814, 6815, 0, 0, 0, + -2281, 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, + 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, 2579, 7519, 1152, 0, 0, 128, 128, + 1151, 0, 1150, 1150, 1150, -6613, 0, -581, + -580, -579, -578, -577, -576, 395, -575, -574, + 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, -1653, 0, -1652, -1651, 0, 0, + -1650, -1649, -1648, -1516, -1647, 473, 474, 475, + 476, 477, 32767, 32767, 32767, 32767, -7018, 479, + 480, 481, 482, 32767, 32767, 32767, 32767, 32767, + 32767, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 497, + 498, 499, 500, 501, 502, 503, 504, 9308, + 506, 507, 508, 509, 510, 511, 512, 513, + 514, 515, 3684, 3684, 3684, 519, 3685, 3685, + 9912, 9913, 524, 9915, 3923, 3919, 9917, 9918, + 11399, 0, 11402, 11403, 11404, 11405, 11406, 11407, + 11408, 11409, 1757, 11411, 11412, 11413, 11414, 11415, + 11416, 11417, 11418, 11419, 0, 9060, 9061, 9062, + 9063, 9064, 9065, 0, 9068, 9069, 0, 9070, + 9071, 9072, 9073, 9074, 9075, 9076, 9077, 9078, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2659, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2745, 2745, 2745, + 2745, 2745, 2745, 2745, 2745, 2745, 0, 0, + 0, -4730, 6052, 0, -4732, -4732, -4732, -4732, + 0, 0, 4919, -4734, -4734, 0, -4735, -4735, + -4735, 4019, 0, 0, 4022, 4023, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5281, 2778, 2778, 0, 0, 0, + 7174, 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, 2067, 918, + 32767, 534, -2763, 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, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 0, 0, 0, 0, 0, + 0, 0, 0, 553, 0, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, -2360, 5111, -2360, -2360, -2360, + -2360, -2360, -2360, -2360, -2360, -2360, -2360, -2360, + -2360, -2360, 7293, -2360, -2360, -2360, -2360, -2360, + 3144, 3145, -2362, -2362, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32767, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32767, 0, 0, 0, 0, 32767, + 32767, 32767, 32767, 0, -1971, -1971, 32767, 0, + 32767, 0, 1809, 1809, 1809, 1809, 0, 0, + 1811, 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, -220, 0, 2582, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -3918, -3918, -3918, 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, + -2442, 0, -479, -479, 0, 0, 0, 0, + 0, 0, -343, 0, 0, 0, 0, 0, + 0, 0, -342, -341, -340, -339, -338, -337, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 2495, 2496, 0, 0, 2499, 2500, 2501, + 2502, 0, 2504, 2505, 2506, 2507, 2508, 1141, + 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, -363, + 0, -362, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -2546, -2546, 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, 484, 100, -3197, 0, -3198, -3198, + 0, 0, 0, 8750, -3943, 0, 0, -3943, + 542, 543, 544, 545, 546, 547, 548, -3936, + -596, 551, 552, 553, 554, 555, 556, 557, + 558, 559, 560, 561, 562, 563, 564, 565, + 566, 567, 568, 569, 570, 571, 572, 573, + 574, 575, 576, 577, 578, 579, 580, 581, + 582, 583, 584, 585, 586, 587, 588, 589, + 590, 591, 592, 593, 594, 595, 596, 597, + 598, 599, 600, 601, 602, 603, 604, 605, + 606, 607, 608, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 619, 620, 621, + 622, 623, 624, 1375, 626, 627, 628, 629, + 630, 631, 632, 633, 634, 635, 636, 637, + 638, 639, 640, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 659, 660, 661, + 662, 663, 664, 665, 666, 667, 668, 669, + 670, 671, 672, 673, 674, 675, 676, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 0, + 0, 0, 0, 7470, 0, 7471, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9653, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 32767, 32767, 32767, + 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, + 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, + 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, + 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, + 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, + 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, + 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, + 3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215, + 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, + 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, + 3232, 3233, 3234, 3235, 3236, 32767, 3237, 3238, + 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, + 3247, 3248, 1885, 3250, 3251, 3252, 3253, 3254, + 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, + 3263, 3264, 3265, 3266, 3267, 3268, 3269, 3270, + 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278, + 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, + 3287, 3288, 3289, 3290, 7683, 3292, 3293, 3294, + 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, + 3303, 3304, 3305, 3306, 3307, 32767, 3308, 3309, + 32767, 32767, 3310, 32767, 32767, 3311, 3312, 32767, + 32767, 3313, 3314, 3315, 3316, 32767, 3317, 3318, + 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, + -1186, -1186, 4489, -1187, 4491, -1188, -1188, -1188, + -1188, -1188, 3335, 3336, 32767, 3337, 3338, 3339, + 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, + 3348, -1659, 3350, 3351, 3352, 3353, 3354, 3355, + 3356, 3357, 3358, 3359, 3360, 3361, 3362, 4351, + 4352, 4353, 4354, 4355, 4356, 4357, 4358, 4359, + 4360, 4361, 3374, 3375, 3376, 3377, 3378, 4362, + 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, + 4371, 4372, 4373, 4374, 4375, 4376, 4377, 4378, + 0, 4380, 4381, 5499, 5500, 5501, 5502, 5503, + 0, 0, 4389, 4390, 0, 0, 3406, 4393, + 4394, 4395, 4396, 4397, 4398, 4399, 0, 4401, + 4402, 4403, 4404, 4405, 4406, 4407, 0, 4409, + 4410, 4411, 4412, 5171, 4414, 5174, 5175, 4623, + 4418, 4419, 4420, 4421, 4422, 4423, 4424, 3437, + 3438, 3439, 3440, 3441, 3442, 3443, 3444, 3445, + 3446, 3447, 3448, 32767, 3449, 3450, 3451, 3131, + 32767, 3453, 3454, 3455, 3456, 3457, 32767, 3458, + 32767, 0, 0, 4427, 3460, 3461, 3462, 3463, + 3464, 3465, 32767, 3466, 3467, 3468, 3469, 3470, + 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478, + 3146, 3367, 3148, 567, 3150, 3151, 3485, 3486, + 3487, 3488, 3489, 3490, 3491, 3492, 3493, 4428, + 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, + 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, + 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, + 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, + 3527, 3528, 3529, 3530, 3531, 3532, 3533, 3534, + 3535, 3536, 3537, 3538, 3539, 3540, 3541 + }; + + const unsigned char *k = (const unsigned char *) key; + size_t keylen = 4; + uint32 a = 0; + uint32 b = 1; + + while (keylen--) + { + unsigned char c = *k++; + + a = a * 257 + c; + b = b * 8191 + c; + } + return h[a % 10079] + h[b % 10079]; +} + +/* Hash lookup information for NFKC_QC */ +static const pg_unicode_norminfo UnicodeNormInfo_NFKC_QC = { + UnicodeNormProps_NFKC_QC, + NFKC_QC_hash_func, + 5039 +}; diff --git a/install/include/postgresql/server/common/username.h b/install/include/postgresql/server/common/username.h new file mode 100644 index 00000000000..fd07df64c19 --- /dev/null +++ b/install/include/postgresql/server/common/username.h @@ -0,0 +1,15 @@ +/* + * username.h + * lookup effective username + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/common/username.h + */ +#ifndef USERNAME_H +#define USERNAME_H + +extern const char *get_user_name(char **errstr); +extern const char *get_user_name_or_exit(const char *progname); + +#endif /* USERNAME_H */ diff --git a/install/include/postgresql/server/datatype/timestamp.h b/install/include/postgresql/server/datatype/timestamp.h new file mode 100644 index 00000000000..ab04344da0b --- /dev/null +++ b/install/include/postgresql/server/datatype/timestamp.h @@ -0,0 +1,243 @@ +/*------------------------------------------------------------------------- + * + * timestamp.h + * Timestamp and Interval typedefs and related macros. + * + * Note: this file must be includable in both frontend and backend contexts. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/datatype/timestamp.h + * + *------------------------------------------------------------------------- + */ +#ifndef DATATYPE_TIMESTAMP_H +#define DATATYPE_TIMESTAMP_H + +/* + * Timestamp represents absolute time. + * + * Interval represents delta time. Keep track of months (and years), days, + * and hours/minutes/seconds separately since the elapsed time spanned is + * unknown until instantiated relative to an absolute time. + * + * Note that Postgres uses "time interval" to mean a bounded interval, + * consisting of a beginning and ending time, not a time span - thomas 97/03/20 + * + * Timestamps, as well as the h/m/s fields of intervals, are stored as + * int64 values with units of microseconds. (Once upon a time they were + * double values with units of seconds.) + * + * TimeOffset and fsec_t are convenience typedefs for temporary variables. + * Do not use fsec_t in values stored on-disk. + * Also, fsec_t is only meant for *fractional* seconds; beware of overflow + * if the value you need to store could be many seconds. + */ + +typedef int64 Timestamp; +typedef int64 TimestampTz; +typedef int64 TimeOffset; +typedef int32 fsec_t; /* fractional seconds (in microseconds) */ + + +/* + * Storage format for type interval. + */ +typedef struct +{ + TimeOffset time; /* all time units other than days, months and + * years */ + int32 day; /* days, after time for alignment */ + int32 month; /* months and years, after time for alignment */ +} Interval; + +/* + * Data structure representing a broken-down interval. + * + * For historical reasons, this is modeled on struct pg_tm for timestamps. + * Unlike the situation for timestamps, there's no magic interpretation + * needed for months or years: they're just zero or not. Note that fields + * can be negative; however, because of the divisions done while converting + * from struct Interval, only tm_mday could be INT_MIN. This is important + * because we may need to negate the values in some code paths. + */ +struct pg_itm +{ + int tm_usec; + int tm_sec; + int tm_min; + int64 tm_hour; /* needs to be wide */ + int tm_mday; + int tm_mon; + int tm_year; +}; + +/* + * Data structure for decoding intervals. We could just use struct pg_itm, + * but then the requirement for tm_usec to be 64 bits would propagate to + * places where it's not really needed. Also, omitting the fields that + * aren't used during decoding seems like a good error-prevention measure. + */ +struct pg_itm_in +{ + int64 tm_usec; /* needs to be wide */ + int tm_mday; + int tm_mon; + int tm_year; +}; + + +/* Limits on the "precision" option (typmod) for these data types */ +#define MAX_TIMESTAMP_PRECISION 6 +#define MAX_INTERVAL_PRECISION 6 + +/* + * Round off to MAX_TIMESTAMP_PRECISION decimal places. + * Note: this is also used for rounding off intervals. + */ +#define TS_PREC_INV 1000000.0 +#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV) + + +/* + * Assorted constants for datetime-related calculations + */ + +#define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */ +#define MONTHS_PER_YEAR 12 +/* + * DAYS_PER_MONTH is very imprecise. The more accurate value is + * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only + * return an integral number of days, but someday perhaps we should + * also return a 'time' value to be used as well. ISO 8601 suggests + * 30 days. + */ +#define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */ +#define HOURS_PER_DAY 24 /* assume no daylight savings time changes */ + +/* + * This doesn't adjust for uneven daylight savings time intervals or leap + * seconds, and it crudely estimates leap years. A more accurate value + * for days per years is 365.2422. + */ +#define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */ +#define SECS_PER_DAY 86400 +#define SECS_PER_HOUR 3600 +#define SECS_PER_MINUTE 60 +#define MINS_PER_HOUR 60 + +#define USECS_PER_DAY INT64CONST(86400000000) +#define USECS_PER_HOUR INT64CONST(3600000000) +#define USECS_PER_MINUTE INT64CONST(60000000) +#define USECS_PER_SEC INT64CONST(1000000) + +/* + * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich. + * Currently, the record holders for wackiest offsets in actual use are zones + * Asia/Manila, at -15:56:08 until 1844, and America/Metlakatla, at +15:13:42 + * until 1867. If we were to reject such values we would fail to dump and + * restore old timestamptz values with these zone settings. + */ +#define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */ +#define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR) + +/* + * We reserve the minimum and maximum integer values to represent + * timestamp (or timestamptz) -infinity and +infinity. + */ +#define TIMESTAMP_MINUS_INFINITY PG_INT64_MIN +#define TIMESTAMP_INFINITY PG_INT64_MAX + +/* + * Historically these alias for infinity have been used. + */ +#define DT_NOBEGIN TIMESTAMP_MINUS_INFINITY +#define DT_NOEND TIMESTAMP_INFINITY + +#define TIMESTAMP_NOBEGIN(j) \ + do {(j) = DT_NOBEGIN;} while (0) + +#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN) + +#define TIMESTAMP_NOEND(j) \ + do {(j) = DT_NOEND;} while (0) + +#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND) + +#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j)) + + +/* + * Julian date support. + * + * date2j() and j2date() nominally handle the Julian date range 0..INT_MAX, + * or 4714-11-24 BC to 5874898-06-03 AD. In practice, date2j() will work and + * give correct negative Julian dates for dates before 4714-11-24 BC as well. + * We rely on it to do so back to 4714-11-01 BC. Allowing at least one day's + * slop is necessary so that timestamp rotation doesn't produce dates that + * would be rejected on input. For example, '4714-11-24 00:00 GMT BC' is a + * legal timestamptz value, but in zones east of Greenwich it would print as + * sometime in the afternoon of 4714-11-23 BC; if we couldn't process such a + * date we'd have a dump/reload failure. So the idea is for IS_VALID_JULIAN + * to accept a slightly wider range of dates than we really support, and + * then we apply the exact checks in IS_VALID_DATE or IS_VALID_TIMESTAMP, + * after timezone rotation if any. To save a few cycles, we can make + * IS_VALID_JULIAN check only to the month boundary, since its exact cutoffs + * are not very critical in this scheme. + * + * It is correct that JULIAN_MINYEAR is -4713, not -4714; it is defined to + * allow easy comparison to tm_year values, in which we follow the convention + * that tm_year <= 0 represents abs(tm_year)+1 BC. + */ + +#define JULIAN_MINYEAR (-4713) +#define JULIAN_MINMONTH (11) +#define JULIAN_MINDAY (24) +#define JULIAN_MAXYEAR (5874898) +#define JULIAN_MAXMONTH (6) +#define JULIAN_MAXDAY (3) + +#define IS_VALID_JULIAN(y,m,d) \ + (((y) > JULIAN_MINYEAR || \ + ((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \ + ((y) < JULIAN_MAXYEAR || \ + ((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH)))) + +/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */ +#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */ +#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */ + +/* + * Range limits for dates and timestamps. + * + * We have traditionally allowed Julian day zero as a valid datetime value, + * so that is the lower bound for both dates and timestamps. + * + * The upper limit for dates is 5874897-12-31, which is a bit less than what + * the Julian-date code can allow. For timestamps, the upper limit is + * 294276-12-31. The int64 overflow limit would be a few days later; again, + * leaving some slop avoids worries about corner-case overflow, and provides + * a simpler user-visible definition. + */ + +/* First allowed date, and first disallowed date, in Julian-date form */ +#define DATETIME_MIN_JULIAN (0) +#define DATE_END_JULIAN (2147483494) /* == date2j(JULIAN_MAXYEAR, 1, 1) */ +#define TIMESTAMP_END_JULIAN (109203528) /* == date2j(294277, 1, 1) */ + +/* Timestamp limits */ +#define MIN_TIMESTAMP INT64CONST(-211813488000000000) +/* == (DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ +#define END_TIMESTAMP INT64CONST(9223371331200000000) +/* == (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ + +/* Range-check a date (given in Postgres, not Julian, numbering) */ +#define IS_VALID_DATE(d) \ + ((DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) <= (d) && \ + (d) < (DATE_END_JULIAN - POSTGRES_EPOCH_JDATE)) + +/* Range-check a timestamp */ +#define IS_VALID_TIMESTAMP(t) (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP) + +#endif /* DATATYPE_TIMESTAMP_H */ diff --git a/install/include/postgresql/server/executor/execAsync.h b/install/include/postgresql/server/executor/execAsync.h new file mode 100644 index 00000000000..9c48f052fa0 --- /dev/null +++ b/install/include/postgresql/server/executor/execAsync.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * execAsync.h + * Support functions for asynchronous execution + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/executor/execAsync.h + *------------------------------------------------------------------------- + */ + +#ifndef EXECASYNC_H +#define EXECASYNC_H + +#include "nodes/execnodes.h" + +extern void ExecAsyncRequest(AsyncRequest *areq); +extern void ExecAsyncConfigureWait(AsyncRequest *areq); +extern void ExecAsyncNotify(AsyncRequest *areq); +extern void ExecAsyncResponse(AsyncRequest *areq); +extern void ExecAsyncRequestDone(AsyncRequest *areq, TupleTableSlot *result); +extern void ExecAsyncRequestPending(AsyncRequest *areq); + +#endif /* EXECASYNC_H */ diff --git a/install/include/postgresql/server/executor/execExpr.h b/install/include/postgresql/server/executor/execExpr.h new file mode 100644 index 00000000000..0e67484cdd3 --- /dev/null +++ b/install/include/postgresql/server/executor/execExpr.h @@ -0,0 +1,831 @@ +/*------------------------------------------------------------------------- + * + * execExpr.h + * Low level infrastructure related to expression evaluation + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/execExpr.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXEC_EXPR_H +#define EXEC_EXPR_H + +#include "executor/nodeAgg.h" +#include "nodes/execnodes.h" + +/* forward references to avoid circularity */ +struct ExprEvalStep; +struct SubscriptingRefState; +struct ScalarArrayOpExprHashTable; +struct JsonConstructorExprState; + +/* Bits in ExprState->flags (see also execnodes.h for public flag bits): */ +/* expression's interpreter has been initialized */ +#define EEO_FLAG_INTERPRETER_INITIALIZED (1 << 1) +/* jump-threading is in use */ +#define EEO_FLAG_DIRECT_THREADED (1 << 2) + +/* Typical API for out-of-line evaluation subroutines */ +typedef void (*ExecEvalSubroutine) (ExprState *state, + struct ExprEvalStep *op, + ExprContext *econtext); + +/* API for out-of-line evaluation subroutines returning bool */ +typedef bool (*ExecEvalBoolSubroutine) (ExprState *state, + struct ExprEvalStep *op, + ExprContext *econtext); + +/* ExprEvalSteps that cache a composite type's tupdesc need one of these */ +/* (it fits in-line in some step types, otherwise allocate out-of-line) */ +typedef struct ExprEvalRowtypeCache +{ + /* + * cacheptr points to composite type's TypeCacheEntry if tupdesc_id is not + * 0; or for an anonymous RECORD type, it points directly at the cached + * tupdesc for the type, and tupdesc_id is 0. (We'd use separate fields + * if space were not at a premium.) Initial state is cacheptr == NULL. + */ + void *cacheptr; + uint64 tupdesc_id; /* last-seen tupdesc identifier, or 0 */ +} ExprEvalRowtypeCache; + +/* + * Discriminator for ExprEvalSteps. + * + * Identifies the operation to be executed and which member in the + * ExprEvalStep->d union is valid. + * + * The order of entries needs to be kept in sync with the dispatch_table[] + * array in execExprInterp.c:ExecInterpExpr(). + */ +typedef enum ExprEvalOp +{ + /* entire expression has been evaluated completely, return */ + EEOP_DONE, + + /* apply slot_getsomeattrs on corresponding tuple slot */ + EEOP_INNER_FETCHSOME, + EEOP_OUTER_FETCHSOME, + EEOP_SCAN_FETCHSOME, + + /* compute non-system Var value */ + EEOP_INNER_VAR, + EEOP_OUTER_VAR, + EEOP_SCAN_VAR, + + /* compute system Var value */ + EEOP_INNER_SYSVAR, + EEOP_OUTER_SYSVAR, + EEOP_SCAN_SYSVAR, + + /* compute wholerow Var */ + EEOP_WHOLEROW, + + /* + * Compute non-system Var value, assign it into ExprState's resultslot. + * These are not used if a CheckVarSlotCompatibility() check would be + * needed. + */ + EEOP_ASSIGN_INNER_VAR, + EEOP_ASSIGN_OUTER_VAR, + EEOP_ASSIGN_SCAN_VAR, + + /* assign ExprState's resvalue/resnull to a column of its resultslot */ + EEOP_ASSIGN_TMP, + /* ditto, applying MakeExpandedObjectReadOnly() */ + EEOP_ASSIGN_TMP_MAKE_RO, + + /* evaluate Const value */ + EEOP_CONST, + + /* + * Evaluate function call (including OpExprs etc). For speed, we + * distinguish in the opcode whether the function is strict and/or + * requires usage stats tracking. + */ + EEOP_FUNCEXPR, + EEOP_FUNCEXPR_STRICT, + EEOP_FUNCEXPR_FUSAGE, + EEOP_FUNCEXPR_STRICT_FUSAGE, + + /* + * Evaluate boolean AND expression, one step per subexpression. FIRST/LAST + * subexpressions are special-cased for performance. Since AND always has + * at least two subexpressions, FIRST and LAST never apply to the same + * subexpression. + */ + EEOP_BOOL_AND_STEP_FIRST, + EEOP_BOOL_AND_STEP, + EEOP_BOOL_AND_STEP_LAST, + + /* similarly for boolean OR expression */ + EEOP_BOOL_OR_STEP_FIRST, + EEOP_BOOL_OR_STEP, + EEOP_BOOL_OR_STEP_LAST, + + /* evaluate boolean NOT expression */ + EEOP_BOOL_NOT_STEP, + + /* simplified version of BOOL_AND_STEP for use by ExecQual() */ + EEOP_QUAL, + + /* unconditional jump to another step */ + EEOP_JUMP, + + /* conditional jumps based on current result value */ + EEOP_JUMP_IF_NULL, + EEOP_JUMP_IF_NOT_NULL, + EEOP_JUMP_IF_NOT_TRUE, + + /* perform NULL tests for scalar values */ + EEOP_NULLTEST_ISNULL, + EEOP_NULLTEST_ISNOTNULL, + + /* perform NULL tests for row values */ + EEOP_NULLTEST_ROWISNULL, + EEOP_NULLTEST_ROWISNOTNULL, + + /* evaluate a BooleanTest expression */ + EEOP_BOOLTEST_IS_TRUE, + EEOP_BOOLTEST_IS_NOT_TRUE, + EEOP_BOOLTEST_IS_FALSE, + EEOP_BOOLTEST_IS_NOT_FALSE, + + /* evaluate PARAM_EXEC/EXTERN parameters */ + EEOP_PARAM_EXEC, + EEOP_PARAM_EXTERN, + EEOP_PARAM_CALLBACK, + + /* return CaseTestExpr value */ + EEOP_CASE_TESTVAL, + + /* apply MakeExpandedObjectReadOnly() to target value */ + EEOP_MAKE_READONLY, + + /* evaluate assorted special-purpose expression types */ + EEOP_IOCOERCE, + EEOP_DISTINCT, + EEOP_NOT_DISTINCT, + EEOP_NULLIF, + EEOP_SQLVALUEFUNCTION, + EEOP_CURRENTOFEXPR, + EEOP_NEXTVALUEEXPR, + EEOP_ARRAYEXPR, + EEOP_ARRAYCOERCE, + EEOP_ROW, + + /* + * Compare two individual elements of each of two compared ROW() + * expressions. Skip to ROWCOMPARE_FINAL if elements are not equal. + */ + EEOP_ROWCOMPARE_STEP, + + /* evaluate boolean value based on previous ROWCOMPARE_STEP operations */ + EEOP_ROWCOMPARE_FINAL, + + /* evaluate GREATEST() or LEAST() */ + EEOP_MINMAX, + + /* evaluate FieldSelect expression */ + EEOP_FIELDSELECT, + + /* + * Deform tuple before evaluating new values for individual fields in a + * FieldStore expression. + */ + EEOP_FIELDSTORE_DEFORM, + + /* + * Form the new tuple for a FieldStore expression. Individual fields will + * have been evaluated into columns of the tuple deformed by the preceding + * DEFORM step. + */ + EEOP_FIELDSTORE_FORM, + + /* Process container subscripts; possibly short-circuit result to NULL */ + EEOP_SBSREF_SUBSCRIPTS, + + /* + * Compute old container element/slice when a SubscriptingRef assignment + * expression contains SubscriptingRef/FieldStore subexpressions. Value is + * accessed using the CaseTest mechanism. + */ + EEOP_SBSREF_OLD, + + /* compute new value for SubscriptingRef assignment expression */ + EEOP_SBSREF_ASSIGN, + + /* compute element/slice for SubscriptingRef fetch expression */ + EEOP_SBSREF_FETCH, + + /* evaluate value for CoerceToDomainValue */ + EEOP_DOMAIN_TESTVAL, + + /* evaluate a domain's NOT NULL constraint */ + EEOP_DOMAIN_NOTNULL, + + /* evaluate a single domain CHECK constraint */ + EEOP_DOMAIN_CHECK, + + /* evaluate assorted special-purpose expression types */ + EEOP_CONVERT_ROWTYPE, + EEOP_SCALARARRAYOP, + EEOP_HASHED_SCALARARRAYOP, + EEOP_XMLEXPR, + EEOP_JSON_CONSTRUCTOR, + EEOP_IS_JSON, + EEOP_AGGREF, + EEOP_GROUPING_FUNC, + EEOP_WINDOW_FUNC, + EEOP_SUBPLAN, + + /* aggregation related nodes */ + EEOP_AGG_STRICT_DESERIALIZE, + EEOP_AGG_DESERIALIZE, + EEOP_AGG_STRICT_INPUT_CHECK_ARGS, + EEOP_AGG_STRICT_INPUT_CHECK_NULLS, + EEOP_AGG_PLAIN_PERGROUP_NULLCHECK, + EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL, + EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL, + EEOP_AGG_PLAIN_TRANS_BYVAL, + EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF, + EEOP_AGG_PLAIN_TRANS_STRICT_BYREF, + EEOP_AGG_PLAIN_TRANS_BYREF, + EEOP_AGG_PRESORTED_DISTINCT_SINGLE, + EEOP_AGG_PRESORTED_DISTINCT_MULTI, + EEOP_AGG_ORDERED_TRANS_DATUM, + EEOP_AGG_ORDERED_TRANS_TUPLE, + + /* non-existent operation, used e.g. to check array lengths */ + EEOP_LAST +} ExprEvalOp; + + +typedef struct ExprEvalStep +{ + /* + * Instruction to be executed. During instruction preparation this is an + * enum ExprEvalOp, but later it can be changed to some other type, e.g. a + * pointer for computed goto (that's why it's an intptr_t). + */ + intptr_t opcode; + + /* where to store the result of this step */ + Datum *resvalue; + bool *resnull; + + /* + * Inline data for the operation. Inline data is faster to access, but + * also bloats the size of all instructions. The union should be kept to + * no more than 40 bytes on 64-bit systems (so that the entire struct is + * no more than 64 bytes, a single cacheline on common systems). + */ + union + { + /* for EEOP_INNER/OUTER/SCAN_FETCHSOME */ + struct + { + /* attribute number up to which to fetch (inclusive) */ + int last_var; + /* will the type of slot be the same for every invocation */ + bool fixed; + /* tuple descriptor, if known */ + TupleDesc known_desc; + /* type of slot, can only be relied upon if fixed is set */ + const TupleTableSlotOps *kind; + } fetch; + + /* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */ + struct + { + /* attnum is attr number - 1 for regular VAR ... */ + /* but it's just the normal (negative) attr number for SYSVAR */ + int attnum; + Oid vartype; /* type OID of variable */ + } var; + + /* for EEOP_WHOLEROW */ + struct + { + Var *var; /* original Var node in plan tree */ + bool first; /* first time through, need to initialize? */ + bool slow; /* need runtime check for nulls? */ + TupleDesc tupdesc; /* descriptor for resulting tuples */ + JunkFilter *junkFilter; /* JunkFilter to remove resjunk cols */ + } wholerow; + + /* for EEOP_ASSIGN_*_VAR */ + struct + { + /* target index in ExprState->resultslot->tts_values/nulls */ + int resultnum; + /* source attribute number - 1 */ + int attnum; + } assign_var; + + /* for EEOP_ASSIGN_TMP[_MAKE_RO] */ + struct + { + /* target index in ExprState->resultslot->tts_values/nulls */ + int resultnum; + } assign_tmp; + + /* for EEOP_CONST */ + struct + { + /* constant's value */ + Datum value; + bool isnull; + } constval; + + /* for EEOP_FUNCEXPR_* / NULLIF / DISTINCT */ + struct + { + FmgrInfo *finfo; /* function's lookup data */ + FunctionCallInfo fcinfo_data; /* arguments etc */ + /* faster to access without additional indirection: */ + PGFunction fn_addr; /* actual call address */ + int nargs; /* number of arguments */ + bool make_ro; /* make arg0 R/O (used only for NULLIF) */ + } func; + + /* for EEOP_BOOL_*_STEP */ + struct + { + bool *anynull; /* track if any input was NULL */ + int jumpdone; /* jump here if result determined */ + } boolexpr; + + /* for EEOP_QUAL */ + struct + { + int jumpdone; /* jump here on false or null */ + } qualexpr; + + /* for EEOP_JUMP[_CONDITION] */ + struct + { + int jumpdone; /* target instruction's index */ + } jump; + + /* for EEOP_NULLTEST_ROWIS[NOT]NULL */ + struct + { + /* cached descriptor for composite type - filled at runtime */ + ExprEvalRowtypeCache rowcache; + } nulltest_row; + + /* for EEOP_PARAM_EXEC/EXTERN */ + struct + { + int paramid; /* numeric ID for parameter */ + Oid paramtype; /* OID of parameter's datatype */ + } param; + + /* for EEOP_PARAM_CALLBACK */ + struct + { + ExecEvalSubroutine paramfunc; /* add-on evaluation subroutine */ + void *paramarg; /* private data for same */ + int paramid; /* numeric ID for parameter */ + Oid paramtype; /* OID of parameter's datatype */ + } cparam; + + /* for EEOP_CASE_TESTVAL/DOMAIN_TESTVAL */ + struct + { + Datum *value; /* value to return */ + bool *isnull; + } casetest; + + /* for EEOP_MAKE_READONLY */ + struct + { + Datum *value; /* value to coerce to read-only */ + bool *isnull; + } make_readonly; + + /* for EEOP_IOCOERCE */ + struct + { + /* lookup and call info for source type's output function */ + FmgrInfo *finfo_out; + FunctionCallInfo fcinfo_data_out; + /* lookup and call info for result type's input function */ + FmgrInfo *finfo_in; + FunctionCallInfo fcinfo_data_in; + } iocoerce; + + /* for EEOP_SQLVALUEFUNCTION */ + struct + { + SQLValueFunction *svf; + } sqlvaluefunction; + + /* for EEOP_NEXTVALUEEXPR */ + struct + { + Oid seqid; + Oid seqtypid; + } nextvalueexpr; + + /* for EEOP_ARRAYEXPR */ + struct + { + Datum *elemvalues; /* element values get stored here */ + bool *elemnulls; + int nelems; /* length of the above arrays */ + Oid elemtype; /* array element type */ + int16 elemlength; /* typlen of the array element type */ + bool elembyval; /* is the element type pass-by-value? */ + char elemalign; /* typalign of the element type */ + bool multidims; /* is array expression multi-D? */ + } arrayexpr; + + /* for EEOP_ARRAYCOERCE */ + struct + { + ExprState *elemexprstate; /* null if no per-element work */ + Oid resultelemtype; /* element type of result array */ + struct ArrayMapState *amstate; /* workspace for array_map */ + } arraycoerce; + + /* for EEOP_ROW */ + struct + { + TupleDesc tupdesc; /* descriptor for result tuples */ + /* workspace for the values constituting the row: */ + Datum *elemvalues; + bool *elemnulls; + } row; + + /* for EEOP_ROWCOMPARE_STEP */ + struct + { + /* lookup and call data for column comparison function */ + FmgrInfo *finfo; + FunctionCallInfo fcinfo_data; + PGFunction fn_addr; + /* target for comparison resulting in NULL */ + int jumpnull; + /* target for comparison yielding inequality */ + int jumpdone; + } rowcompare_step; + + /* for EEOP_ROWCOMPARE_FINAL */ + struct + { + RowCompareType rctype; + } rowcompare_final; + + /* for EEOP_MINMAX */ + struct + { + /* workspace for argument values */ + Datum *values; + bool *nulls; + int nelems; + /* is it GREATEST or LEAST? */ + MinMaxOp op; + /* lookup and call data for comparison function */ + FmgrInfo *finfo; + FunctionCallInfo fcinfo_data; + } minmax; + + /* for EEOP_FIELDSELECT */ + struct + { + AttrNumber fieldnum; /* field number to extract */ + Oid resulttype; /* field's type */ + /* cached descriptor for composite type - filled at runtime */ + ExprEvalRowtypeCache rowcache; + } fieldselect; + + /* for EEOP_FIELDSTORE_DEFORM / FIELDSTORE_FORM */ + struct + { + /* original expression node */ + FieldStore *fstore; + + /* cached descriptor for composite type - filled at runtime */ + /* note that a DEFORM and FORM pair share the same cache */ + ExprEvalRowtypeCache *rowcache; + + /* workspace for column values */ + Datum *values; + bool *nulls; + int ncolumns; + } fieldstore; + + /* for EEOP_SBSREF_SUBSCRIPTS */ + struct + { + ExecEvalBoolSubroutine subscriptfunc; /* evaluation subroutine */ + /* too big to have inline */ + struct SubscriptingRefState *state; + int jumpdone; /* jump here on null */ + } sbsref_subscript; + + /* for EEOP_SBSREF_OLD / ASSIGN / FETCH */ + struct + { + ExecEvalSubroutine subscriptfunc; /* evaluation subroutine */ + /* too big to have inline */ + struct SubscriptingRefState *state; + } sbsref; + + /* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */ + struct + { + /* name of constraint */ + char *constraintname; + /* where the result of a CHECK constraint will be stored */ + Datum *checkvalue; + bool *checknull; + /* OID of domain type */ + Oid resulttype; + } domaincheck; + + /* for EEOP_CONVERT_ROWTYPE */ + struct + { + Oid inputtype; /* input composite type */ + Oid outputtype; /* output composite type */ + /* these three fields are filled at runtime: */ + ExprEvalRowtypeCache *incache; /* cache for input type */ + ExprEvalRowtypeCache *outcache; /* cache for output type */ + TupleConversionMap *map; /* column mapping */ + } convert_rowtype; + + /* for EEOP_SCALARARRAYOP */ + struct + { + /* element_type/typlen/typbyval/typalign are filled at runtime */ + Oid element_type; /* InvalidOid if not yet filled */ + bool useOr; /* use OR or AND semantics? */ + int16 typlen; /* array element type storage info */ + bool typbyval; + char typalign; + FmgrInfo *finfo; /* function's lookup data */ + FunctionCallInfo fcinfo_data; /* arguments etc */ + /* faster to access without additional indirection: */ + PGFunction fn_addr; /* actual call address */ + } scalararrayop; + + /* for EEOP_HASHED_SCALARARRAYOP */ + struct + { + bool has_nulls; + bool inclause; /* true for IN and false for NOT IN */ + struct ScalarArrayOpExprHashTable *elements_tab; + FmgrInfo *finfo; /* function's lookup data */ + FunctionCallInfo fcinfo_data; /* arguments etc */ + ScalarArrayOpExpr *saop; + } hashedscalararrayop; + + /* for EEOP_XMLEXPR */ + struct + { + XmlExpr *xexpr; /* original expression node */ + /* workspace for evaluating named args, if any */ + Datum *named_argvalue; + bool *named_argnull; + /* workspace for evaluating unnamed args, if any */ + Datum *argvalue; + bool *argnull; + } xmlexpr; + + /* for EEOP_JSON_CONSTRUCTOR */ + struct + { + struct JsonConstructorExprState *jcstate; + } json_constructor; + + /* for EEOP_AGGREF */ + struct + { + int aggno; + } aggref; + + /* for EEOP_GROUPING_FUNC */ + struct + { + List *clauses; /* integer list of column numbers */ + } grouping_func; + + /* for EEOP_WINDOW_FUNC */ + struct + { + /* out-of-line state, modified by nodeWindowAgg.c */ + WindowFuncExprState *wfstate; + } window_func; + + /* for EEOP_SUBPLAN */ + struct + { + /* out-of-line state, created by nodeSubplan.c */ + SubPlanState *sstate; + } subplan; + + /* for EEOP_AGG_*DESERIALIZE */ + struct + { + FunctionCallInfo fcinfo_data; + int jumpnull; + } agg_deserialize; + + /* for EEOP_AGG_STRICT_INPUT_CHECK_NULLS / STRICT_INPUT_CHECK_ARGS */ + struct + { + /* + * For EEOP_AGG_STRICT_INPUT_CHECK_ARGS args contains pointers to + * the NullableDatums that need to be checked for NULLs. + * + * For EEOP_AGG_STRICT_INPUT_CHECK_NULLS nulls contains pointers + * to booleans that need to be checked for NULLs. + * + * Both cases currently need to exist because sometimes the + * to-be-checked nulls are in TupleTableSlot.isnull array, and + * sometimes in FunctionCallInfoBaseData.args[i].isnull. + */ + NullableDatum *args; + bool *nulls; + int nargs; + int jumpnull; + } agg_strict_input_check; + + /* for EEOP_AGG_PLAIN_PERGROUP_NULLCHECK */ + struct + { + int setoff; + int jumpnull; + } agg_plain_pergroup_nullcheck; + + /* for EEOP_AGG_PRESORTED_DISTINCT_{SINGLE,MULTI} */ + struct + { + AggStatePerTrans pertrans; + ExprContext *aggcontext; + int jumpdistinct; + } agg_presorted_distinctcheck; + + /* for EEOP_AGG_PLAIN_TRANS_[INIT_][STRICT_]{BYVAL,BYREF} */ + /* for EEOP_AGG_ORDERED_TRANS_{DATUM,TUPLE} */ + struct + { + AggStatePerTrans pertrans; + ExprContext *aggcontext; + int setno; + int transno; + int setoff; + } agg_trans; + + /* for EEOP_IS_JSON */ + struct + { + JsonIsPredicate *pred; /* original expression node */ + } is_json; + + } d; +} ExprEvalStep; + +/* Enforce the size rule given in the comment above */ +StaticAssertDecl(sizeof(ExprEvalStep) <= 64, + "size of ExprEvalStep exceeds 64 bytes"); + + +/* Non-inline data for container operations */ +typedef struct SubscriptingRefState +{ + bool isassignment; /* is it assignment, or just fetch? */ + + /* workspace for type-specific subscripting code */ + void *workspace; + + /* numupper and upperprovided[] are filled at expression compile time */ + /* at runtime, subscripts are computed in upperindex[]/upperindexnull[] */ + int numupper; + bool *upperprovided; /* indicates if this position is supplied */ + Datum *upperindex; + bool *upperindexnull; + + /* similarly for lower indexes, if any */ + int numlower; + bool *lowerprovided; + Datum *lowerindex; + bool *lowerindexnull; + + /* for assignment, new value to assign is evaluated into here */ + Datum replacevalue; + bool replacenull; + + /* if we have a nested assignment, sbs_fetch_old puts old value here */ + Datum prevvalue; + bool prevnull; +} SubscriptingRefState; + +/* Execution step methods used for SubscriptingRef */ +typedef struct SubscriptExecSteps +{ + /* See nodes/subscripting.h for more detail about these */ + ExecEvalBoolSubroutine sbs_check_subscripts; /* process subscripts */ + ExecEvalSubroutine sbs_fetch; /* fetch an element */ + ExecEvalSubroutine sbs_assign; /* assign to an element */ + ExecEvalSubroutine sbs_fetch_old; /* fetch old value for assignment */ +} SubscriptExecSteps; + +/* EEOP_JSON_CONSTRUCTOR state, too big to inline */ +typedef struct JsonConstructorExprState +{ + JsonConstructorExpr *constructor; + Datum *arg_values; + bool *arg_nulls; + Oid *arg_types; + struct + { + int category; + Oid outfuncid; + } *arg_type_cache; /* cache for datum_to_json[b]() */ + int nargs; +} JsonConstructorExprState; + + +/* functions in execExpr.c */ +extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s); + +/* functions in execExprInterp.c */ +extern void ExecReadyInterpretedExpr(ExprState *state); +extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op); + +extern Datum ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull); +extern void CheckExprStillValid(ExprState *state, ExprContext *econtext); + +/* + * Non fast-path execution functions. These are externs instead of statics in + * execExprInterp.c, because that allows them to be used by other methods of + * expression evaluation, reducing code duplication. + */ +extern void ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op); +extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op); +extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op); +extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); +extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); +extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); +extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op); +extern void ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op); +extern void ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op); +extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op); +extern void ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalJsonIsPredicate(ExprState *state, ExprEvalStep *op); +extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op); +extern void ExecEvalSubPlan(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op, + ExprContext *econtext, TupleTableSlot *slot); + +extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup, + ExprContext *aggcontext); +extern Datum ExecAggCopyTransValue(AggState *aggstate, AggStatePerTrans pertrans, + Datum newValue, bool newValueIsNull, + Datum oldValue, bool oldValueIsNull); +extern bool ExecEvalPreOrderedDistinctSingle(AggState *aggstate, + AggStatePerTrans pertrans); +extern bool ExecEvalPreOrderedDistinctMulti(AggState *aggstate, + AggStatePerTrans pertrans); +extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); +extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); + +#endif /* EXEC_EXPR_H */ diff --git a/install/include/postgresql/server/executor/execParallel.h b/install/include/postgresql/server/executor/execParallel.h new file mode 100644 index 00000000000..39a8792a319 --- /dev/null +++ b/install/include/postgresql/server/executor/execParallel.h @@ -0,0 +1,51 @@ +/*-------------------------------------------------------------------- + * execParallel.h + * POSTGRES parallel execution interface + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/executor/execParallel.h + *-------------------------------------------------------------------- + */ + +#ifndef EXECPARALLEL_H +#define EXECPARALLEL_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" +#include "nodes/parsenodes.h" +#include "nodes/plannodes.h" +#include "utils/dsa.h" + +typedef struct SharedExecutorInstrumentation SharedExecutorInstrumentation; + +typedef struct ParallelExecutorInfo +{ + PlanState *planstate; /* plan subtree we're running in parallel */ + ParallelContext *pcxt; /* parallel context we're using */ + BufferUsage *buffer_usage; /* points to bufusage area in DSM */ + WalUsage *wal_usage; /* walusage area in DSM */ + SharedExecutorInstrumentation *instrumentation; /* optional */ + struct SharedJitInstrumentation *jit_instrumentation; /* optional */ + dsa_area *area; /* points to DSA area in DSM */ + dsa_pointer param_exec; /* serialized PARAM_EXEC parameters */ + bool finished; /* set true by ExecParallelFinish */ + /* These two arrays have pcxt->nworkers_launched entries: */ + shm_mq_handle **tqueue; /* tuple queues for worker output */ + struct TupleQueueReader **reader; /* tuple reader/writer support */ +} ParallelExecutorInfo; + +extern ParallelExecutorInfo *ExecInitParallelPlan(PlanState *planstate, + EState *estate, Bitmapset *sendParams, int nworkers, + int64 tuples_needed); +extern void ExecParallelCreateReaders(ParallelExecutorInfo *pei); +extern void ExecParallelFinish(ParallelExecutorInfo *pei); +extern void ExecParallelCleanup(ParallelExecutorInfo *pei); +extern void ExecParallelReinitialize(PlanState *planstate, + ParallelExecutorInfo *pei, Bitmapset *sendParams); + +extern void ParallelQueryMain(dsm_segment *seg, shm_toc *toc); + +#endif /* EXECPARALLEL_H */ diff --git a/install/include/postgresql/server/executor/execPartition.h b/install/include/postgresql/server/executor/execPartition.h new file mode 100644 index 00000000000..15ec869ac81 --- /dev/null +++ b/install/include/postgresql/server/executor/execPartition.h @@ -0,0 +1,131 @@ +/*-------------------------------------------------------------------- + * execPartition.h + * POSTGRES partitioning executor interface + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/executor/execPartition.h + *-------------------------------------------------------------------- + */ + +#ifndef EXECPARTITION_H +#define EXECPARTITION_H + +#include "nodes/execnodes.h" +#include "nodes/parsenodes.h" +#include "nodes/plannodes.h" +#include "partitioning/partprune.h" + +/* See execPartition.c for the definitions. */ +typedef struct PartitionDispatchData *PartitionDispatch; +typedef struct PartitionTupleRouting PartitionTupleRouting; + +extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(EState *estate, + Relation rel); +extern ResultRelInfo *ExecFindPartition(ModifyTableState *mtstate, + ResultRelInfo *rootResultRelInfo, + PartitionTupleRouting *proute, + TupleTableSlot *slot, + EState *estate); +extern void ExecCleanupTupleRouting(ModifyTableState *mtstate, + PartitionTupleRouting *proute); + + +/* + * PartitionedRelPruningData - Per-partitioned-table data for run-time pruning + * of partitions. For a multilevel partitioned table, we have one of these + * for the topmost partition plus one for each non-leaf child partition. + * + * subplan_map[] and subpart_map[] have the same definitions as in + * PartitionedRelPruneInfo (see plannodes.h); though note that here, + * subpart_map contains indexes into PartitionPruningData.partrelprunedata[]. + * + * nparts Length of subplan_map[] and subpart_map[]. + * subplan_map Subplan index by partition index, or -1. + * subpart_map Subpart index by partition index, or -1. + * present_parts A Bitmapset of the partition indexes that we + * have subplans or subparts for. + * initial_pruning_steps List of PartitionPruneSteps used to + * perform executor startup pruning. + * exec_pruning_steps List of PartitionPruneSteps used to + * perform per-scan pruning. + * initial_context If initial_pruning_steps isn't NIL, contains + * the details needed to execute those steps. + * exec_context If exec_pruning_steps isn't NIL, contains + * the details needed to execute those steps. + */ +typedef struct PartitionedRelPruningData +{ + int nparts; + int *subplan_map; + int *subpart_map; + Bitmapset *present_parts; + List *initial_pruning_steps; + List *exec_pruning_steps; + PartitionPruneContext initial_context; + PartitionPruneContext exec_context; +} PartitionedRelPruningData; + +/* + * PartitionPruningData - Holds all the run-time pruning information for + * a single partitioning hierarchy containing one or more partitions. + * partrelprunedata[] is an array ordered such that parents appear before + * their children; in particular, the first entry is the topmost partition, + * which was actually named in the SQL query. + */ +typedef struct PartitionPruningData +{ + int num_partrelprunedata; /* number of array entries */ + PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER]; +} PartitionPruningData; + +/* + * PartitionPruneState - State object required for plan nodes to perform + * run-time partition pruning. + * + * This struct can be attached to plan types which support arbitrary Lists of + * subplans containing partitions, to allow subplans to be eliminated due to + * the clauses being unable to match to any tuple that the subplan could + * possibly produce. + * + * execparamids Contains paramids of PARAM_EXEC Params found within + * any of the partprunedata structs. Pruning must be + * done again each time the value of one of these + * parameters changes. + * other_subplans Contains indexes of subplans that don't belong to any + * "partprunedata", e.g UNION ALL children that are not + * partitioned tables, or a partitioned table that the + * planner deemed run-time pruning to be useless for. + * These must not be pruned. + * prune_context A short-lived memory context in which to execute the + * partition pruning functions. + * do_initial_prune true if pruning should be performed during executor + * startup (at any hierarchy level). + * do_exec_prune true if pruning should be performed during + * executor run (at any hierarchy level). + * num_partprunedata Number of items in "partprunedata" array. + * partprunedata Array of PartitionPruningData pointers for the plan's + * partitioned relation(s), one for each partitioning + * hierarchy that requires run-time pruning. + */ +typedef struct PartitionPruneState +{ + Bitmapset *execparamids; + Bitmapset *other_subplans; + MemoryContext prune_context; + bool do_initial_prune; + bool do_exec_prune; + int num_partprunedata; + PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER]; +} PartitionPruneState; + +extern PartitionPruneState *ExecInitPartitionPruning(PlanState *planstate, + int n_total_subplans, + PartitionPruneInfo *pruneinfo, + Bitmapset **initially_valid_subplans); +extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate, + bool initial_prune); + +#endif /* EXECPARTITION_H */ diff --git a/install/include/postgresql/server/executor/execdebug.h b/install/include/postgresql/server/executor/execdebug.h new file mode 100644 index 00000000000..5a8e5e290c9 --- /dev/null +++ b/install/include/postgresql/server/executor/execdebug.h @@ -0,0 +1,130 @@ +/*------------------------------------------------------------------------- + * + * execdebug.h + * #defines governing debugging behaviour in the executor + * + * XXX this is all pretty old and crufty. Newer code tends to use elog() + * for debug printouts, because that's more flexible than printf(). + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/execdebug.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXECDEBUG_H +#define EXECDEBUG_H + +#include "executor/executor.h" +#include "nodes/print.h" + +/* ---------------------------------------------------------------- + * debugging defines. + * + * If you want certain debugging behaviour, then #define + * the variable to 1. No need to explicitly #undef by default, + * since we can use -D compiler options to enable features. + * - thomas 1999-02-20 + * ---------------------------------------------------------------- + */ + +/* ---------------- + * EXEC_NESTLOOPDEBUG is a flag which turns on debugging of the + * nest loop node by NL_printf() and ENL_printf() in nodeNestloop.c + * ---------------- +#undef EXEC_NESTLOOPDEBUG + */ + +/* ---------------- + * EXEC_SORTDEBUG is a flag which turns on debugging of + * the ExecSort() stuff by SO_printf() in nodeSort.c + * ---------------- +#undef EXEC_SORTDEBUG + */ + +/* ---------------- + * EXEC_MERGEJOINDEBUG is a flag which turns on debugging of + * the ExecMergeJoin() stuff by MJ_printf() in nodeMergejoin.c + * ---------------- +#undef EXEC_MERGEJOINDEBUG + */ + +/* ---------------------------------------------------------------- + * #defines controlled by above definitions + * + * Note: most of these are "incomplete" because I didn't + * need the ones not defined. More should be added + * only as necessary -cim 10/26/89 + * ---------------------------------------------------------------- + */ +#define T_OR_F(b) ((b) ? "true" : "false") +#define NULL_OR_TUPLE(slot) (TupIsNull(slot) ? "null" : "a tuple") + +/* ---------------- + * nest loop debugging defines + * ---------------- + */ +#ifdef EXEC_NESTLOOPDEBUG +#define NL_nodeDisplay(l) nodeDisplay(l) +#define NL_printf(s) printf(s) +#define NL1_printf(s, a) printf(s, a) +#define ENL1_printf(message) printf("ExecNestLoop: %s\n", message) +#else +#define NL_nodeDisplay(l) +#define NL_printf(s) +#define NL1_printf(s, a) +#define ENL1_printf(message) +#endif /* EXEC_NESTLOOPDEBUG */ + +/* ---------------- + * sort node debugging defines + * ---------------- + */ +#ifdef EXEC_SORTDEBUG +#define SO_nodeDisplay(l) nodeDisplay(l) +#define SO_printf(s) printf(s) +#define SO1_printf(s, p) printf(s, p) +#define SO2_printf(s, p1, p2) printf(s, p1, p2) +#else +#define SO_nodeDisplay(l) +#define SO_printf(s) +#define SO1_printf(s, p) +#define SO2_printf(s, p1, p2) +#endif /* EXEC_SORTDEBUG */ + +/* ---------------- + * merge join debugging defines + * ---------------- + */ +#ifdef EXEC_MERGEJOINDEBUG + +#define MJ_nodeDisplay(l) nodeDisplay(l) +#define MJ_printf(s) printf(s) +#define MJ1_printf(s, p) printf(s, p) +#define MJ2_printf(s, p1, p2) printf(s, p1, p2) +#define MJ_debugtup(slot) debugtup(slot, NULL) +#define MJ_dump(state) ExecMergeTupleDump(state) +#define MJ_DEBUG_COMPARE(res) \ + MJ1_printf(" MJCompare() returns %d\n", (res)) +#define MJ_DEBUG_QUAL(clause, res) \ + MJ2_printf(" ExecQual(%s, econtext) returns %s\n", \ + CppAsString(clause), T_OR_F(res)) +#define MJ_DEBUG_PROC_NODE(slot) \ + MJ2_printf(" %s = ExecProcNode(...) returns %s\n", \ + CppAsString(slot), NULL_OR_TUPLE(slot)) +#else + +#define MJ_nodeDisplay(l) +#define MJ_printf(s) +#define MJ1_printf(s, p) +#define MJ2_printf(s, p1, p2) +#define MJ_debugtup(slot) +#define MJ_dump(state) +#define MJ_DEBUG_COMPARE(res) +#define MJ_DEBUG_QUAL(clause, res) +#define MJ_DEBUG_PROC_NODE(slot) +#endif /* EXEC_MERGEJOINDEBUG */ + +#endif /* EXECDEBUG_H */ diff --git a/install/include/postgresql/server/executor/execdesc.h b/install/include/postgresql/server/executor/execdesc.h new file mode 100644 index 00000000000..10320c66b0c --- /dev/null +++ b/install/include/postgresql/server/executor/execdesc.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------- + * + * execdesc.h + * plan and query descriptor accessor macros used by the executor + * and related modules. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/execdesc.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXECDESC_H +#define EXECDESC_H + +#include "nodes/execnodes.h" +#include "tcop/dest.h" + + +/* ---------------- + * query descriptor: + * + * a QueryDesc encapsulates everything that the executor + * needs to execute the query. + * + * For the convenience of SQL-language functions, we also support QueryDescs + * containing utility statements; these must not be passed to the executor + * however. + * --------------------- + */ +typedef struct QueryDesc +{ + /* These fields are provided by CreateQueryDesc */ + CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */ + PlannedStmt *plannedstmt; /* planner's output (could be utility, too) */ + const char *sourceText; /* source text of the query */ + Snapshot snapshot; /* snapshot to use for query */ + Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */ + DestReceiver *dest; /* the destination for tuple output */ + ParamListInfo params; /* param values being passed in */ + QueryEnvironment *queryEnv; /* query environment passed in */ + int instrument_options; /* OR of InstrumentOption flags */ + + /* These fields are set by ExecutorStart */ + TupleDesc tupDesc; /* descriptor for result tuples */ + EState *estate; /* executor's query-wide state */ + PlanState *planstate; /* tree of per-plan-node state */ + + /* This field is set by ExecutePlan */ + bool already_executed; /* true if previously executed */ + + /* This is always set NULL by the core system, but plugins can change it */ + struct Instrumentation *totaltime; /* total time spent in ExecutorRun */ +} QueryDesc; + +/* in pquery.c */ +extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, + const char *sourceText, + Snapshot snapshot, + Snapshot crosscheck_snapshot, + DestReceiver *dest, + ParamListInfo params, + QueryEnvironment *queryEnv, + int instrument_options); + +extern void FreeQueryDesc(QueryDesc *qdesc); + +#endif /* EXECDESC_H */ diff --git a/install/include/postgresql/server/executor/executor.h b/install/include/postgresql/server/executor/executor.h new file mode 100644 index 00000000000..baef7e031ee --- /dev/null +++ b/install/include/postgresql/server/executor/executor.h @@ -0,0 +1,684 @@ +/*------------------------------------------------------------------------- + * + * executor.h + * support for the POSTGRES executor module + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/executor.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXECUTOR_H +#define EXECUTOR_H + +#include "executor/execdesc.h" +#include "fmgr.h" +#include "nodes/lockoptions.h" +#include "nodes/parsenodes.h" +#include "utils/memutils.h" + + +/* + * The "eflags" argument to ExecutorStart and the various ExecInitNode + * routines is a bitwise OR of the following flag bits, which tell the + * called plan node what to expect. Note that the flags will get modified + * as they are passed down the plan tree, since an upper node may require + * functionality in its subnode not demanded of the plan as a whole + * (example: MergeJoin requires mark/restore capability in its inner input), + * or an upper node may shield its input from some functionality requirement + * (example: Materialize shields its input from needing to do backward scan). + * + * EXPLAIN_ONLY indicates that the plan tree is being initialized just so + * EXPLAIN can print it out; it will not be run. Hence, no side-effects + * of startup should occur. However, error checks (such as permission checks) + * should be performed. + * + * EXPLAIN_GENERIC can only be used together with EXPLAIN_ONLY. It indicates + * that a generic plan is being shown using EXPLAIN (GENERIC_PLAN), which + * means that missing parameter values must be tolerated. Currently, the only + * effect is to suppress execution-time partition pruning. + * + * REWIND indicates that the plan node should try to efficiently support + * rescans without parameter changes. (Nodes must support ExecReScan calls + * in any case, but if this flag was not given, they are at liberty to do it + * through complete recalculation. Note that a parameter change forces a + * full recalculation in any case.) + * + * BACKWARD indicates that the plan node must respect the es_direction flag. + * When this is not passed, the plan node will only be run forwards. + * + * MARK indicates that the plan node must support Mark/Restore calls. + * When this is not passed, no Mark/Restore will occur. + * + * SKIP_TRIGGERS tells ExecutorStart/ExecutorFinish to skip calling + * AfterTriggerBeginQuery/AfterTriggerEndQuery. This does not necessarily + * mean that the plan can't queue any AFTER triggers; just that the caller + * is responsible for there being a trigger context for them to be queued in. + * + * WITH_NO_DATA indicates that we are performing REFRESH MATERIALIZED VIEW + * ... WITH NO DATA. Currently, the only effect is to suppress errors about + * scanning unpopulated materialized views. + */ +#define EXEC_FLAG_EXPLAIN_ONLY 0x0001 /* EXPLAIN, no ANALYZE */ +#define EXEC_FLAG_EXPLAIN_GENERIC 0x0002 /* EXPLAIN (GENERIC_PLAN) */ +#define EXEC_FLAG_REWIND 0x0004 /* need efficient rescan */ +#define EXEC_FLAG_BACKWARD 0x0008 /* need backward scan */ +#define EXEC_FLAG_MARK 0x0010 /* need mark/restore */ +#define EXEC_FLAG_SKIP_TRIGGERS 0x0020 /* skip AfterTrigger setup */ +#define EXEC_FLAG_WITH_NO_DATA 0x0040 /* REFRESH ... WITH NO DATA */ + + +/* Hook for plugins to get control in ExecutorStart() */ +typedef void (*ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags); +extern PGDLLIMPORT ExecutorStart_hook_type ExecutorStart_hook; + +/* Hook for plugins to get control in ExecutorRun() */ +typedef void (*ExecutorRun_hook_type) (QueryDesc *queryDesc, + ScanDirection direction, + uint64 count, + bool execute_once); +extern PGDLLIMPORT ExecutorRun_hook_type ExecutorRun_hook; + +/* Hook for plugins to get control in ExecutorFinish() */ +typedef void (*ExecutorFinish_hook_type) (QueryDesc *queryDesc); +extern PGDLLIMPORT ExecutorFinish_hook_type ExecutorFinish_hook; + +/* Hook for plugins to get control in ExecutorEnd() */ +typedef void (*ExecutorEnd_hook_type) (QueryDesc *queryDesc); +extern PGDLLIMPORT ExecutorEnd_hook_type ExecutorEnd_hook; + +/* Hook for plugins to get control in ExecCheckPermissions() */ +typedef bool (*ExecutorCheckPerms_hook_type) (List *rangeTable, + List *rtePermInfos, + bool ereport_on_violation); +extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook; + + +/* + * prototypes from functions in execAmi.c + */ +struct Path; /* avoid including pathnodes.h here */ + +extern void ExecReScan(PlanState *node); +extern void ExecMarkPos(PlanState *node); +extern void ExecRestrPos(PlanState *node); +extern bool ExecSupportsMarkRestore(struct Path *pathnode); +extern bool ExecSupportsBackwardScan(Plan *node); +extern bool ExecMaterializesOutput(NodeTag plantype); + +/* + * prototypes from functions in execCurrent.c + */ +extern bool execCurrentOf(CurrentOfExpr *cexpr, + ExprContext *econtext, + Oid table_oid, + ItemPointer current_tid); + +/* + * prototypes from functions in execGrouping.c + */ +extern ExprState *execTuplesMatchPrepare(TupleDesc desc, + int numCols, + const AttrNumber *keyColIdx, + const Oid *eqOperators, + const Oid *collations, + PlanState *parent); +extern void execTuplesHashPrepare(int numCols, + const Oid *eqOperators, + Oid **eqFuncOids, + FmgrInfo **hashFunctions); +extern TupleHashTable BuildTupleHashTable(PlanState *parent, + TupleDesc inputDesc, + int numCols, AttrNumber *keyColIdx, + const Oid *eqfuncoids, + FmgrInfo *hashfunctions, + Oid *collations, + long nbuckets, Size additionalsize, + MemoryContext tablecxt, + MemoryContext tempcxt, bool use_variable_hash_iv); +extern TupleHashTable BuildTupleHashTableExt(PlanState *parent, + TupleDesc inputDesc, + int numCols, AttrNumber *keyColIdx, + const Oid *eqfuncoids, + FmgrInfo *hashfunctions, + Oid *collations, + long nbuckets, Size additionalsize, + MemoryContext metacxt, + MemoryContext tablecxt, + MemoryContext tempcxt, bool use_variable_hash_iv); +extern TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable, + TupleTableSlot *slot, + bool *isnew, uint32 *hash); +extern uint32 TupleHashTableHash(TupleHashTable hashtable, + TupleTableSlot *slot); +extern TupleHashEntry LookupTupleHashEntryHash(TupleHashTable hashtable, + TupleTableSlot *slot, + bool *isnew, uint32 hash); +extern TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable, + TupleTableSlot *slot, + ExprState *eqcomp, + FmgrInfo *hashfunctions); +extern void ResetTupleHashTable(TupleHashTable hashtable); + +/* + * prototypes from functions in execJunk.c + */ +extern JunkFilter *ExecInitJunkFilter(List *targetList, + TupleTableSlot *slot); +extern JunkFilter *ExecInitJunkFilterConversion(List *targetList, + TupleDesc cleanTupType, + TupleTableSlot *slot); +extern AttrNumber ExecFindJunkAttribute(JunkFilter *junkfilter, + const char *attrName); +extern AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, + const char *attrName); +extern TupleTableSlot *ExecFilterJunk(JunkFilter *junkfilter, + TupleTableSlot *slot); + +/* + * 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. + */ +#ifndef FRONTEND +static inline Datum +ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull) +{ + Assert(attno > 0); + return slot_getattr(slot, attno, isNull); +} +#endif + +/* + * prototypes from functions in execMain.c + */ +extern void ExecutorStart(QueryDesc *queryDesc, int eflags); +extern void standard_ExecutorStart(QueryDesc *queryDesc, int eflags); +extern void ExecutorRun(QueryDesc *queryDesc, + ScanDirection direction, uint64 count, bool execute_once); +extern void standard_ExecutorRun(QueryDesc *queryDesc, + ScanDirection direction, uint64 count, bool execute_once); +extern void ExecutorFinish(QueryDesc *queryDesc); +extern void standard_ExecutorFinish(QueryDesc *queryDesc); +extern void ExecutorEnd(QueryDesc *queryDesc); +extern void standard_ExecutorEnd(QueryDesc *queryDesc); +extern void ExecutorRewind(QueryDesc *queryDesc); +extern bool ExecCheckPermissions(List *rangeTable, + List *rteperminfos, bool ereport_on_violation); +extern bool ExecCheckOneRelPerms(RTEPermissionInfo *perminfo); +extern void CheckValidResultRelNew(ResultRelInfo *resultRelInfo, CmdType operation, + OnConflictAction onConflictAction, + List *mergeActions); +extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation); +extern void InitResultRelInfo(ResultRelInfo *resultRelInfo, + Relation resultRelationDesc, + Index resultRelationIndex, + ResultRelInfo *partition_root_rri, + int instrument_options); +extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid, + ResultRelInfo *rootRelInfo); +extern List *ExecGetAncestorResultRels(EState *estate, ResultRelInfo *resultRelInfo); +extern void ExecConstraints(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate); +extern bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate, bool emitError); +extern void ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate); +extern void ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate); +extern LockTupleMode ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo); +extern ExecRowMark *ExecFindRowMark(EState *estate, Index rti, bool missing_ok); +extern ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist); +extern TupleTableSlot *EvalPlanQual(EPQState *epqstate, Relation relation, + Index rti, TupleTableSlot *inputslot); +extern void EvalPlanQualInit(EPQState *epqstate, EState *parentestate, + Plan *subplan, List *auxrowmarks, + int epqParam, List *resultRelations); +extern void EvalPlanQualSetPlan(EPQState *epqstate, + Plan *subplan, List *auxrowmarks); +extern TupleTableSlot *EvalPlanQualSlot(EPQState *epqstate, + Relation relation, Index rti); + +#define EvalPlanQualSetSlot(epqstate, slot) ((epqstate)->origslot = (slot)) +extern bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot); +extern TupleTableSlot *EvalPlanQualNext(EPQState *epqstate); +extern void EvalPlanQualBegin(EPQState *epqstate); +extern void EvalPlanQualEnd(EPQState *epqstate); + +/* + * functions in execProcnode.c + */ +extern PlanState *ExecInitNode(Plan *node, EState *estate, int eflags); +extern void ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function); +extern Node *MultiExecProcNode(PlanState *node); +extern void ExecEndNode(PlanState *node); +extern void ExecShutdownNode(PlanState *node); +extern void ExecSetTupleBound(int64 tuples_needed, PlanState *child_node); + + +/* ---------------------------------------------------------------- + * ExecProcNode + * + * Execute the given node to return a(nother) tuple. + * ---------------------------------------------------------------- + */ +#ifndef FRONTEND +static inline TupleTableSlot * +ExecProcNode(PlanState *node) +{ + if (node->chgParam != NULL) /* something changed? */ + ExecReScan(node); /* let ReScan handle this */ + + return node->ExecProcNode(node); +} +#endif + +/* + * prototypes from functions in execExpr.c + */ +extern ExprState *ExecInitExpr(Expr *node, PlanState *parent); +extern ExprState *ExecInitExprWithParams(Expr *node, ParamListInfo ext_params); +extern ExprState *ExecInitQual(List *qual, PlanState *parent); +extern ExprState *ExecInitCheck(List *qual, PlanState *parent); +extern List *ExecInitExprList(List *nodes, PlanState *parent); +extern ExprState *ExecBuildAggTrans(AggState *aggstate, struct AggStatePerPhaseData *phase, + bool doSort, bool doHash, bool nullcheck); +extern ExprState *ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, + const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, + int numCols, + const AttrNumber *keyColIdx, + const Oid *eqfunctions, + const Oid *collations, + PlanState *parent); +extern ExprState *ExecBuildParamSetEqual(TupleDesc desc, + const TupleTableSlotOps *lops, + const TupleTableSlotOps *rops, + const Oid *eqfunctions, + const Oid *collations, + const List *param_exprs, + PlanState *parent); +extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList, + ExprContext *econtext, + TupleTableSlot *slot, + PlanState *parent, + TupleDesc inputDesc); +extern ProjectionInfo *ExecBuildUpdateProjection(List *targetList, + bool evalTargetList, + List *targetColnos, + TupleDesc relDesc, + ExprContext *econtext, + TupleTableSlot *slot, + PlanState *parent); +extern ExprState *ExecPrepareExpr(Expr *node, EState *estate); +extern ExprState *ExecPrepareQual(List *qual, EState *estate); +extern ExprState *ExecPrepareCheck(List *qual, EState *estate); +extern List *ExecPrepareExprList(List *nodes, EState *estate); + +/* + * ExecEvalExpr + * + * Evaluate expression identified by "state" in the execution context + * given by "econtext". *isNull is set to the is-null flag for the result, + * and the Datum value is the function result. + * + * The caller should already have switched into the temporary memory + * context econtext->ecxt_per_tuple_memory. The convenience entry point + * ExecEvalExprSwitchContext() is provided for callers who don't prefer to + * do the switch in an outer loop. + */ +#ifndef FRONTEND +static inline Datum +ExecEvalExpr(ExprState *state, + ExprContext *econtext, + bool *isNull) +{ + return state->evalfunc(state, econtext, isNull); +} +#endif + +/* + * ExecEvalExprSwitchContext + * + * Same as ExecEvalExpr, but get into the right allocation context explicitly. + */ +#ifndef FRONTEND +static inline Datum +ExecEvalExprSwitchContext(ExprState *state, + ExprContext *econtext, + bool *isNull) +{ + Datum retDatum; + MemoryContext oldContext; + + oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); + retDatum = state->evalfunc(state, econtext, isNull); + MemoryContextSwitchTo(oldContext); + return retDatum; +} +#endif + +/* + * ExecProject + * + * Projects a tuple based on projection info and stores it in the slot passed + * to ExecBuildProjectionInfo(). + * + * Note: the result is always a virtual tuple; therefore it may reference + * the contents of the exprContext's scan tuples and/or temporary results + * constructed in the exprContext. If the caller wishes the result to be + * valid longer than that data will be valid, he must call ExecMaterializeSlot + * on the result slot. + */ +#ifndef FRONTEND +static inline TupleTableSlot * +ExecProject(ProjectionInfo *projInfo) +{ + ExprContext *econtext = projInfo->pi_exprContext; + ExprState *state = &projInfo->pi_state; + TupleTableSlot *slot = state->resultslot; + bool isnull; + + /* + * Clear any former contents of the result slot. This makes it safe for + * us to use the slot's Datum/isnull arrays as workspace. + */ + ExecClearTuple(slot); + + /* Run the expression, discarding scalar result from the last column. */ + (void) ExecEvalExprSwitchContext(state, econtext, &isnull); + + /* + * Successfully formed a result row. Mark the result slot as containing a + * valid virtual tuple (inlined version of ExecStoreVirtualTuple()). + */ + slot->tts_flags &= ~TTS_FLAG_EMPTY; + slot->tts_nvalid = slot->tts_tupleDescriptor->natts; + + return slot; +} +#endif + +/* + * ExecQual - evaluate a qual prepared with ExecInitQual (possibly via + * ExecPrepareQual). Returns true if qual is satisfied, else false. + * + * Note: ExecQual used to have a third argument "resultForNull". The + * behavior of this function now corresponds to resultForNull == false. + * If you want the resultForNull == true behavior, see ExecCheck. + */ +#ifndef FRONTEND +static inline bool +ExecQual(ExprState *state, ExprContext *econtext) +{ + Datum ret; + bool isnull; + + /* short-circuit (here and in ExecInitQual) for empty restriction list */ + if (state == NULL) + return true; + + /* verify that expression was compiled using ExecInitQual */ + Assert(state->flags & EEO_FLAG_IS_QUAL); + + ret = ExecEvalExprSwitchContext(state, econtext, &isnull); + + /* EEOP_QUAL should never return NULL */ + Assert(!isnull); + + return DatumGetBool(ret); +} +#endif + +/* + * ExecQualAndReset() - evaluate qual with ExecQual() and reset expression + * context. + */ +#ifndef FRONTEND +static inline bool +ExecQualAndReset(ExprState *state, ExprContext *econtext) +{ + bool ret = ExecQual(state, econtext); + + /* inline ResetExprContext, to avoid ordering issue in this file */ + MemoryContextReset(econtext->ecxt_per_tuple_memory); + return ret; +} +#endif + +extern bool ExecCheck(ExprState *state, ExprContext *econtext); + +/* + * prototypes from functions in execSRF.c + */ +extern SetExprState *ExecInitTableFunctionResult(Expr *expr, + ExprContext *econtext, PlanState *parent); +extern Tuplestorestate *ExecMakeTableFunctionResult(SetExprState *setexpr, + ExprContext *econtext, + MemoryContext argContext, + TupleDesc expectedDesc, + bool randomAccess); +extern SetExprState *ExecInitFunctionResultSet(Expr *expr, + ExprContext *econtext, PlanState *parent); +extern Datum ExecMakeFunctionResultSet(SetExprState *fcache, + ExprContext *econtext, + MemoryContext argContext, + bool *isNull, + ExprDoneCond *isDone); + +/* + * prototypes from functions in execScan.c + */ +typedef TupleTableSlot *(*ExecScanAccessMtd) (ScanState *node); +typedef bool (*ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot); + +extern TupleTableSlot *ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, + ExecScanRecheckMtd recheckMtd); +extern void ExecAssignScanProjectionInfo(ScanState *node); +extern void ExecAssignScanProjectionInfoWithVarno(ScanState *node, int varno); +extern void ExecScanReScan(ScanState *node); + +/* + * prototypes from functions in execTuples.c + */ +extern void ExecInitResultTypeTL(PlanState *planstate); +extern void ExecInitResultSlot(PlanState *planstate, + const TupleTableSlotOps *tts_ops); +extern void ExecInitResultTupleSlotTL(PlanState *planstate, + const TupleTableSlotOps *tts_ops); +extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, + TupleDesc tupledesc, + const TupleTableSlotOps *tts_ops); +extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate, + TupleDesc tupledesc, + const TupleTableSlotOps *tts_ops); +extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate, TupleDesc tupType, + const TupleTableSlotOps *tts_ops); +extern TupleDesc ExecTypeFromTL(List *targetList); +extern TupleDesc ExecCleanTypeFromTL(List *targetList); +extern TupleDesc ExecTypeFromExprList(List *exprList); +extern void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList); +extern void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg); + +typedef struct TupOutputState +{ + TupleTableSlot *slot; + DestReceiver *dest; +} TupOutputState; + +extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest, + TupleDesc tupdesc, + const TupleTableSlotOps *tts_ops); +extern void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull); +extern void do_text_output_multiline(TupOutputState *tstate, const char *txt); +extern void end_tup_output(TupOutputState *tstate); + +/* + * Write a single line of text given as a C string. + * + * Should only be used with a single-TEXT-attribute tupdesc. + */ +#define do_text_output_oneline(tstate, str_to_emit) \ + do { \ + Datum values_[1]; \ + bool isnull_[1]; \ + values_[0] = PointerGetDatum(cstring_to_text(str_to_emit)); \ + isnull_[0] = false; \ + do_tup_output(tstate, values_, isnull_); \ + pfree(DatumGetPointer(values_[0])); \ + } while (0) + + +/* + * prototypes from functions in execUtils.c + */ +extern EState *CreateExecutorState(void); +extern void FreeExecutorState(EState *estate); +extern ExprContext *CreateExprContext(EState *estate); +extern ExprContext *CreateWorkExprContext(EState *estate); +extern ExprContext *CreateStandaloneExprContext(void); +extern void FreeExprContext(ExprContext *econtext, bool isCommit); +extern void ReScanExprContext(ExprContext *econtext); + +#define ResetExprContext(econtext) \ + MemoryContextReset((econtext)->ecxt_per_tuple_memory) + +extern ExprContext *MakePerTupleExprContext(EState *estate); + +/* Get an EState's per-output-tuple exprcontext, making it if first use */ +#define GetPerTupleExprContext(estate) \ + ((estate)->es_per_tuple_exprcontext ? \ + (estate)->es_per_tuple_exprcontext : \ + MakePerTupleExprContext(estate)) + +#define GetPerTupleMemoryContext(estate) \ + (GetPerTupleExprContext(estate)->ecxt_per_tuple_memory) + +/* Reset an EState's per-output-tuple exprcontext, if one's been created */ +#define ResetPerTupleExprContext(estate) \ + do { \ + if ((estate)->es_per_tuple_exprcontext) \ + ResetExprContext((estate)->es_per_tuple_exprcontext); \ + } while (0) + +extern void ExecAssignExprContext(EState *estate, PlanState *planstate); +extern TupleDesc ExecGetResultType(PlanState *planstate); +extern const TupleTableSlotOps *ExecGetResultSlotOps(PlanState *planstate, + bool *isfixed); +extern void ExecAssignProjectionInfo(PlanState *planstate, + TupleDesc inputDesc); +extern void ExecConditionalAssignProjectionInfo(PlanState *planstate, + TupleDesc inputDesc, int varno); +extern void ExecFreeExprContext(PlanState *planstate); +extern void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc); +extern void ExecCreateScanSlotFromOuterPlan(EState *estate, + ScanState *scanstate, + const TupleTableSlotOps *tts_ops); + +extern bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid); + +extern Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags); + +extern void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos); +extern void ExecCloseRangeTableRelations(EState *estate); +extern void ExecCloseResultRelations(EState *estate); + +static inline RangeTblEntry * +exec_rt_fetch(Index rti, EState *estate) +{ + return (RangeTblEntry *) list_nth(estate->es_range_table, rti - 1); +} + +extern Relation ExecGetRangeTableRelation(EState *estate, Index rti); +extern void ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, + Index rti); + +extern int executor_errposition(EState *estate, int location); + +extern void RegisterExprContextCallback(ExprContext *econtext, + ExprContextCallbackFunction function, + Datum arg); +extern void UnregisterExprContextCallback(ExprContext *econtext, + ExprContextCallbackFunction function, + Datum arg); + +extern Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname, + bool *isNull); +extern Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno, + bool *isNull); + +extern int ExecTargetListLength(List *targetlist); +extern int ExecCleanTargetListLength(List *targetlist); + +extern TupleTableSlot *ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo); +extern TupleTableSlot *ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo); +extern TupleTableSlot *ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo); +extern TupleConversionMap *ExecGetChildToRootMap(ResultRelInfo *resultRelInfo); +extern TupleConversionMap *ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate); + +extern Oid ExecGetResultRelCheckAsUser(ResultRelInfo *relInfo, EState *estate); +extern Bitmapset *ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate); +extern Bitmapset *ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate); +extern Bitmapset *ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate); +extern Bitmapset *ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate); + +/* + * prototypes from functions in execIndexing.c + */ +extern void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative); +extern void ExecCloseIndices(ResultRelInfo *resultRelInfo); +extern List *ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate, + bool update, + bool noDupErr, + bool *specConflict, List *arbiterIndexes, + bool onlySummarizing); +extern bool ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, + EState *estate, ItemPointer conflictTid, + List *arbiterIndexes); +extern void check_exclusion_constraint(Relation heap, Relation index, + IndexInfo *indexInfo, + ItemPointer tupleid, + Datum *values, bool *isnull, + EState *estate, bool newIndex); + +/* + * prototypes from functions in execReplication.c + */ +extern bool RelationFindReplTupleByIndex(Relation rel, Oid idxoid, + LockTupleMode lockmode, + TupleTableSlot *searchslot, + TupleTableSlot *outslot); +extern bool RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, + TupleTableSlot *searchslot, TupleTableSlot *outslot); + +extern void ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo, + EState *estate, TupleTableSlot *slot); +extern void ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo, + EState *estate, EPQState *epqstate, + TupleTableSlot *searchslot, TupleTableSlot *slot); +extern void ExecSimpleRelationDelete(ResultRelInfo *resultRelInfo, + EState *estate, EPQState *epqstate, + TupleTableSlot *searchslot); +extern void CheckCmdReplicaIdentity(Relation rel, CmdType cmd); + +extern void CheckSubscriptionRelkind(char relkind, const char *nspname, + const char *relname); + +/* + * prototypes from functions in nodeModifyTable.c + */ +extern TupleTableSlot *ExecGetUpdateNewTuple(ResultRelInfo *relinfo, + TupleTableSlot *planSlot, + TupleTableSlot *oldSlot); +extern ResultRelInfo *ExecLookupResultRelByOid(ModifyTableState *node, + Oid resultoid, + bool missing_ok, + bool update_cache); + +#endif /* EXECUTOR_H */ diff --git a/install/include/postgresql/server/executor/functions.h b/install/include/postgresql/server/executor/functions.h new file mode 100644 index 00000000000..53702430b2d --- /dev/null +++ b/install/include/postgresql/server/executor/functions.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * functions.h + * Declarations for execution of SQL-language functions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/functions.h + * + *------------------------------------------------------------------------- + */ +#ifndef FUNCTIONS_H +#define FUNCTIONS_H + +#include "nodes/execnodes.h" +#include "tcop/dest.h" + +/* + * 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; + +typedef SQLFunctionParseInfo *SQLFunctionParseInfoPtr; + +extern Datum fmgr_sql(PG_FUNCTION_ARGS); + +extern SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, + Node *call_expr, + Oid inputCollation); + +extern void sql_fn_parser_setup(struct ParseState *pstate, + SQLFunctionParseInfoPtr pinfo); + +extern void check_sql_fn_statements(List *queryTreeLists); + +extern bool check_sql_fn_retval(List *queryTreeLists, + Oid rettype, TupleDesc rettupdesc, + bool insertDroppedCols, + List **resultTargetList); + +extern bool check_sql_fn_retval_ext(List *queryTreeLists, + Oid rettype, TupleDesc rettupdesc, + char prokind, + bool insertDroppedCols, + List **resultTargetList); + +extern DestReceiver *CreateSQLFunctionDestReceiver(void); + +#endif /* FUNCTIONS_H */ diff --git a/install/include/postgresql/server/executor/hashjoin.h b/install/include/postgresql/server/executor/hashjoin.h new file mode 100644 index 00000000000..cb2a2cde8a8 --- /dev/null +++ b/install/include/postgresql/server/executor/hashjoin.h @@ -0,0 +1,377 @@ +/*------------------------------------------------------------------------- + * + * hashjoin.h + * internal structures for hash joins + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/hashjoin.h + * + *------------------------------------------------------------------------- + */ +#ifndef HASHJOIN_H +#define HASHJOIN_H + +#include "nodes/execnodes.h" +#include "port/atomics.h" +#include "storage/barrier.h" +#include "storage/buffile.h" +#include "storage/lwlock.h" + +/* ---------------------------------------------------------------- + * hash-join hash table structures + * + * Each active hashjoin has a HashJoinTable structure, which is + * palloc'd in the executor's per-query context. Other storage needed for + * each hashjoin is kept in child contexts, three for each hashjoin: + * - HashTableContext (hashCxt): the parent hash table storage context + * - HashSpillContext (spillCxt): storage for temp files buffers + * - HashBatchContext (batchCxt): storage for a batch in serial hash join + * + * The hashtable contexts are made children of the per-query context, ensuring + * that they will be discarded at end of statement even if the join is + * aborted early by an error. (Likewise, any temporary files we make will + * be cleaned up by the virtual file manager in event of an error.) + * + * Storage that should live through the entire join is allocated from the + * "hashCxt" (mainly the hashtable's metadata). Also, the "hashCxt" context is + * the parent of "spillCxt" and "batchCxt". It makes it easy and fast to + * release the storage when we don't need it anymore. + * + * Data associated with temp files is allocated in the "spillCxt" context + * which lives for the duration of the entire join as batch files' + * creation and usage may span batch execution. These files are + * explicitly destroyed by calling BufFileClose() when the code is done + * with them. The aim of this context is to help accounting for the + * memory allocated for temp files and their buffers. + * + * Finally, data used only during a single batch's execution is allocated + * in the "batchCxt". By resetting the batchCxt at the end of each batch, + * we free all the per-batch storage reliably and without tedium. + * + * During first scan of inner relation, we get its tuples from executor. + * If nbatch > 1 then tuples that don't belong in first batch get saved + * into inner-batch temp files. The same statements apply for the + * first scan of the outer relation, except we write tuples to outer-batch + * temp files. After finishing the first scan, we do the following for + * each remaining batch: + * 1. Read tuples from inner batch file, load into hash buckets. + * 2. Read tuples from outer batch file, match to hash buckets and output. + * + * It is possible to increase nbatch on the fly if the in-memory hash table + * gets too big. The hash-value-to-batch computation is arranged so that this + * can only cause a tuple to go into a later batch than previously thought, + * never into an earlier batch. When we increase nbatch, we rescan the hash + * table and dump out any tuples that are now of a later batch to the correct + * inner batch file. Subsequently, while reading either inner or outer batch + * files, we might find tuples that no longer belong to the current batch; + * if so, we just dump them out to the correct batch file. + * ---------------------------------------------------------------- + */ + +/* these are in nodes/execnodes.h: */ +/* typedef struct HashJoinTupleData *HashJoinTuple; */ +/* typedef struct HashJoinTableData *HashJoinTable; */ + +typedef struct HashJoinTupleData +{ + /* link to next tuple in same bucket */ + union + { + struct HashJoinTupleData *unshared; + dsa_pointer shared; + } next; + uint32 hashvalue; /* tuple's hash code */ + /* Tuple data, in MinimalTuple format, follows on a MAXALIGN boundary */ +} HashJoinTupleData; + +#define HJTUPLE_OVERHEAD MAXALIGN(sizeof(HashJoinTupleData)) +#define HJTUPLE_MINTUPLE(hjtup) \ + ((MinimalTuple) ((char *) (hjtup) + HJTUPLE_OVERHEAD)) + +/* + * If the outer relation's distribution is sufficiently nonuniform, we attempt + * to optimize the join by treating the hash values corresponding to the outer + * relation's MCVs specially. Inner relation tuples matching these hash + * values go into the "skew" hashtable instead of the main hashtable, and + * outer relation tuples with these hash values are matched against that + * table instead of the main one. Thus, tuples with these hash values are + * effectively handled as part of the first batch and will never go to disk. + * The skew hashtable is limited to SKEW_HASH_MEM_PERCENT of the total memory + * allowed for the join; while building the hashtables, we decrease the number + * of MCVs being specially treated if needed to stay under this limit. + * + * Note: you might wonder why we look at the outer relation stats for this, + * rather than the inner. One reason is that the outer relation is typically + * bigger, so we get more I/O savings by optimizing for its most common values. + * Also, for similarly-sized relations, the planner prefers to put the more + * uniformly distributed relation on the inside, so we're more likely to find + * interesting skew in the outer relation. + */ +typedef struct HashSkewBucket +{ + uint32 hashvalue; /* common hash value */ + HashJoinTuple tuples; /* linked list of inner-relation tuples */ +} HashSkewBucket; + +#define SKEW_BUCKET_OVERHEAD MAXALIGN(sizeof(HashSkewBucket)) +#define INVALID_SKEW_BUCKET_NO (-1) +#define SKEW_HASH_MEM_PERCENT 2 +#define SKEW_MIN_OUTER_FRACTION 0.01 + +/* + * To reduce palloc overhead, the HashJoinTuples for the current batch are + * packed in 32kB buffers instead of pallocing each tuple individually. + */ +typedef struct HashMemoryChunkData +{ + int ntuples; /* number of tuples stored in this chunk */ + size_t maxlen; /* size of the chunk's tuple buffer */ + size_t used; /* number of buffer bytes already used */ + + /* pointer to the next chunk (linked list) */ + union + { + struct HashMemoryChunkData *unshared; + dsa_pointer shared; + } next; + + /* + * The chunk's tuple buffer starts after the HashMemoryChunkData struct, + * at offset HASH_CHUNK_HEADER_SIZE (which must be maxaligned). Note that + * that offset is not included in "maxlen" or "used". + */ +} HashMemoryChunkData; + +typedef struct HashMemoryChunkData *HashMemoryChunk; + +#define HASH_CHUNK_SIZE (32 * 1024L) +#define HASH_CHUNK_HEADER_SIZE MAXALIGN(sizeof(HashMemoryChunkData)) +#define HASH_CHUNK_DATA(hc) (((char *) (hc)) + HASH_CHUNK_HEADER_SIZE) +/* tuples exceeding HASH_CHUNK_THRESHOLD bytes are put in their own chunk */ +#define HASH_CHUNK_THRESHOLD (HASH_CHUNK_SIZE / 4) + +/* + * For each batch of a Parallel Hash Join, we have a ParallelHashJoinBatch + * object in shared memory to coordinate access to it. Since they are + * followed by variable-sized objects, they are arranged in contiguous memory + * but not accessed directly as an array. + */ +typedef struct ParallelHashJoinBatch +{ + dsa_pointer buckets; /* array of hash table buckets */ + Barrier batch_barrier; /* synchronization for joining this batch */ + + dsa_pointer chunks; /* chunks of tuples loaded */ + size_t size; /* size of buckets + chunks in memory */ + size_t estimated_size; /* size of buckets + chunks while writing */ + size_t ntuples; /* number of tuples loaded */ + size_t old_ntuples; /* number of tuples before repartitioning */ + bool space_exhausted; + bool skip_unmatched; /* whether to abandon unmatched scan */ + + /* + * Variable-sized SharedTuplestore objects follow this struct in memory. + * See the accessor macros below. + */ +} ParallelHashJoinBatch; + +/* Accessor for inner batch tuplestore following a ParallelHashJoinBatch. */ +#define ParallelHashJoinBatchInner(batch) \ + ((SharedTuplestore *) \ + ((char *) (batch) + MAXALIGN(sizeof(ParallelHashJoinBatch)))) + +/* Accessor for outer batch tuplestore following a ParallelHashJoinBatch. */ +#define ParallelHashJoinBatchOuter(batch, nparticipants) \ + ((SharedTuplestore *) \ + ((char *) ParallelHashJoinBatchInner(batch) + \ + MAXALIGN(sts_estimate(nparticipants)))) + +/* Total size of a ParallelHashJoinBatch and tuplestores. */ +#define EstimateParallelHashJoinBatch(hashtable) \ + (MAXALIGN(sizeof(ParallelHashJoinBatch)) + \ + MAXALIGN(sts_estimate((hashtable)->parallel_state->nparticipants)) * 2) + +/* Accessor for the nth ParallelHashJoinBatch given the base. */ +#define NthParallelHashJoinBatch(base, n) \ + ((ParallelHashJoinBatch *) \ + ((char *) (base) + \ + EstimateParallelHashJoinBatch(hashtable) * (n))) + +/* + * Each backend requires a small amount of per-batch state to interact with + * each ParallelHashJoinBatch. + */ +typedef struct ParallelHashJoinBatchAccessor +{ + ParallelHashJoinBatch *shared; /* pointer to shared state */ + + /* Per-backend partial counters to reduce contention. */ + size_t preallocated; /* pre-allocated space for this backend */ + size_t ntuples; /* number of tuples */ + size_t size; /* size of partition in memory */ + size_t estimated_size; /* size of partition on disk */ + size_t old_ntuples; /* how many tuples before repartitioning? */ + bool at_least_one_chunk; /* has this backend allocated a chunk? */ + bool outer_eof; /* has this process hit end of batch? */ + bool done; /* flag to remember that a batch is done */ + SharedTuplestoreAccessor *inner_tuples; + SharedTuplestoreAccessor *outer_tuples; +} ParallelHashJoinBatchAccessor; + +/* + * While hashing the inner relation, any participant might determine that it's + * time to increase the number of buckets to reduce the load factor or batches + * to reduce the memory size. This is indicated by setting the growth flag to + * these values. + */ +typedef enum ParallelHashGrowth +{ + /* The current dimensions are sufficient. */ + PHJ_GROWTH_OK, + /* The load factor is too high, so we need to add buckets. */ + PHJ_GROWTH_NEED_MORE_BUCKETS, + /* The memory budget would be exhausted, so we need to repartition. */ + PHJ_GROWTH_NEED_MORE_BATCHES, + /* Repartitioning didn't help last time, so don't try to do that again. */ + PHJ_GROWTH_DISABLED +} ParallelHashGrowth; + +/* + * The shared state used to coordinate a Parallel Hash Join. This is stored + * in the DSM segment. + */ +typedef struct ParallelHashJoinState +{ + dsa_pointer batches; /* array of ParallelHashJoinBatch */ + dsa_pointer old_batches; /* previous generation during repartition */ + int nbatch; /* number of batches now */ + int old_nbatch; /* previous number of batches */ + int nbuckets; /* number of buckets */ + ParallelHashGrowth growth; /* control batch/bucket growth */ + dsa_pointer chunk_work_queue; /* chunk work queue */ + int nparticipants; + size_t space_allowed; + size_t total_tuples; /* total number of inner tuples */ + LWLock lock; /* lock protecting the above */ + + Barrier build_barrier; /* synchronization for the build phases */ + Barrier grow_batches_barrier; + Barrier grow_buckets_barrier; + pg_atomic_uint32 distributor; /* counter for load balancing */ + + SharedFileSet fileset; /* space for shared temporary files */ +} ParallelHashJoinState; + +/* The phases for building batches, used by build_barrier. */ +#define PHJ_BUILD_ELECT 0 +#define PHJ_BUILD_ALLOCATE 1 +#define PHJ_BUILD_HASH_INNER 2 +#define PHJ_BUILD_HASH_OUTER 3 +#define PHJ_BUILD_RUN 4 +#define PHJ_BUILD_FREE 5 + +/* The phases for probing each batch, used by for batch_barrier. */ +#define PHJ_BATCH_ELECT 0 +#define PHJ_BATCH_ALLOCATE 1 +#define PHJ_BATCH_LOAD 2 +#define PHJ_BATCH_PROBE 3 +#define PHJ_BATCH_SCAN 4 +#define PHJ_BATCH_FREE 5 + +/* The phases of batch growth while hashing, for grow_batches_barrier. */ +#define PHJ_GROW_BATCHES_ELECT 0 +#define PHJ_GROW_BATCHES_REALLOCATE 1 +#define PHJ_GROW_BATCHES_REPARTITION 2 +#define PHJ_GROW_BATCHES_DECIDE 3 +#define PHJ_GROW_BATCHES_FINISH 4 +#define PHJ_GROW_BATCHES_PHASE(n) ((n) % 5) /* circular phases */ + +/* The phases of bucket growth while hashing, for grow_buckets_barrier. */ +#define PHJ_GROW_BUCKETS_ELECT 0 +#define PHJ_GROW_BUCKETS_REALLOCATE 1 +#define PHJ_GROW_BUCKETS_REINSERT 2 +#define PHJ_GROW_BUCKETS_PHASE(n) ((n) % 3) /* circular phases */ + +typedef struct HashJoinTableData +{ + int nbuckets; /* # buckets in the in-memory hash table */ + int log2_nbuckets; /* its log2 (nbuckets must be a power of 2) */ + + int nbuckets_original; /* # buckets when starting the first hash */ + int nbuckets_optimal; /* optimal # buckets (per batch) */ + int log2_nbuckets_optimal; /* log2(nbuckets_optimal) */ + + /* buckets[i] is head of list of tuples in i'th in-memory bucket */ + union + { + /* unshared array is per-batch storage, as are all the tuples */ + struct HashJoinTupleData **unshared; + /* shared array is per-query DSA area, as are all the tuples */ + dsa_pointer_atomic *shared; + } buckets; + + bool keepNulls; /* true to store unmatchable NULL tuples */ + + bool skewEnabled; /* are we using skew optimization? */ + HashSkewBucket **skewBucket; /* hashtable of skew buckets */ + int skewBucketLen; /* size of skewBucket array (a power of 2!) */ + int nSkewBuckets; /* number of active skew buckets */ + int *skewBucketNums; /* array indexes of active skew buckets */ + + int nbatch; /* number of batches */ + int curbatch; /* current batch #; 0 during 1st pass */ + + int nbatch_original; /* nbatch when we started inner scan */ + int nbatch_outstart; /* nbatch when we started outer scan */ + + bool growEnabled; /* flag to shut off nbatch increases */ + + double totalTuples; /* # tuples obtained from inner plan */ + double partialTuples; /* # tuples obtained from inner plan by me */ + double skewTuples; /* # tuples inserted into skew tuples */ + + /* + * These arrays are allocated for the life of the hash join, but only if + * nbatch > 1. A file is opened only when we first write a tuple into it + * (otherwise its pointer remains NULL). Note that the zero'th array + * elements never get used, since we will process rather than dump out any + * tuples of batch zero. + */ + BufFile **innerBatchFile; /* buffered virtual temp file per batch */ + BufFile **outerBatchFile; /* buffered virtual temp file per batch */ + + /* + * Info about the datatype-specific hash functions for the datatypes being + * hashed. These are arrays of the same length as the number of hash join + * clauses (hash keys). + */ + FmgrInfo *outer_hashfunctions; /* lookup data for hash functions */ + FmgrInfo *inner_hashfunctions; /* lookup data for hash functions */ + bool *hashStrict; /* is each hash join operator strict? */ + Oid *collations; + + Size spaceUsed; /* memory space currently used by tuples */ + Size spaceAllowed; /* upper limit for space used */ + Size spacePeak; /* peak space used */ + Size spaceUsedSkew; /* skew hash table's current space usage */ + Size spaceAllowedSkew; /* upper limit for skew hashtable */ + + MemoryContext hashCxt; /* context for whole-hash-join storage */ + MemoryContext batchCxt; /* context for this-batch-only storage */ + MemoryContext spillCxt; /* context for spilling to temp files */ + + /* used for dense allocation of tuples (into linked chunks) */ + HashMemoryChunk chunks; /* one list for the whole batch */ + + /* Shared and private state for Parallel Hash. */ + HashMemoryChunk current_chunk; /* this backend's current chunk */ + dsa_area *area; /* DSA area to allocate memory from */ + ParallelHashJoinState *parallel_state; + ParallelHashJoinBatchAccessor *batches; + dsa_pointer current_chunk_shared; +} HashJoinTableData; + +#endif /* HASHJOIN_H */ diff --git a/install/include/postgresql/server/executor/instrument.h b/install/include/postgresql/server/executor/instrument.h new file mode 100644 index 00000000000..87e5e2183bd --- /dev/null +++ b/install/include/postgresql/server/executor/instrument.h @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------------- + * + * instrument.h + * definitions for run-time statistics collection + * + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/executor/instrument.h + * + *------------------------------------------------------------------------- + */ +#ifndef INSTRUMENT_H +#define INSTRUMENT_H + +#include "portability/instr_time.h" + + +/* + * BufferUsage and WalUsage counters keep being incremented infinitely, + * i.e., must never be reset to zero, so that we can calculate how much + * the counters are incremented in an arbitrary period. + */ +typedef struct BufferUsage +{ + int64 shared_blks_hit; /* # of shared buffer hits */ + int64 shared_blks_read; /* # of shared disk blocks read */ + int64 shared_blks_dirtied; /* # of shared blocks dirtied */ + int64 shared_blks_written; /* # of shared disk blocks written */ + int64 local_blks_hit; /* # of local buffer hits */ + int64 local_blks_read; /* # of local disk blocks read */ + int64 local_blks_dirtied; /* # of local blocks dirtied */ + int64 local_blks_written; /* # of local disk blocks written */ + int64 temp_blks_read; /* # of temp blocks read */ + int64 temp_blks_written; /* # of temp blocks written */ + instr_time blk_read_time; /* time spent reading blocks */ + instr_time blk_write_time; /* time spent writing blocks */ + instr_time temp_blk_read_time; /* time spent reading temp blocks */ + instr_time temp_blk_write_time; /* time spent writing temp blocks */ +} BufferUsage; + +/* + * WalUsage tracks only WAL activity like WAL records generation that + * can be measured per query and is displayed by EXPLAIN command, + * pg_stat_statements extension, etc. It does not track other WAL activity + * like WAL writes that it's not worth measuring per query. That's tracked + * by WAL global statistics counters in WalStats, instead. + */ +typedef struct WalUsage +{ + int64 wal_records; /* # of WAL records produced */ + int64 wal_fpi; /* # of WAL full page images produced */ + uint64 wal_bytes; /* size of WAL records produced */ +} WalUsage; + +/* Flag bits included in InstrAlloc's instrument_options bitmask */ +typedef enum InstrumentOption +{ + INSTRUMENT_TIMER = 1 << 0, /* needs timer (and row counts) */ + INSTRUMENT_BUFFERS = 1 << 1, /* needs buffer usage */ + INSTRUMENT_ROWS = 1 << 2, /* needs row count */ + INSTRUMENT_WAL = 1 << 3, /* needs WAL usage */ + INSTRUMENT_ALL = PG_INT32_MAX +} InstrumentOption; + +typedef struct Instrumentation +{ + /* Parameters set at node creation: */ + bool need_timer; /* true if we need timer data */ + bool need_bufusage; /* true if we need buffer usage data */ + bool need_walusage; /* true if we need WAL usage data */ + bool async_mode; /* true if node is in async mode */ + /* Info about current plan cycle: */ + bool running; /* true if we've completed first tuple */ + instr_time starttime; /* start time of current iteration of node */ + instr_time counter; /* accumulated runtime for this node */ + double firsttuple; /* time for first tuple of this cycle */ + double tuplecount; /* # of tuples emitted so far this cycle */ + BufferUsage bufusage_start; /* buffer usage at start */ + WalUsage walusage_start; /* WAL usage at start */ + /* Accumulated statistics across all completed cycles: */ + double startup; /* total startup time (in seconds) */ + double total; /* total time (in seconds) */ + double ntuples; /* total tuples produced */ + double ntuples2; /* secondary node-specific tuple counter */ + double nloops; /* # of run cycles for this node */ + double nfiltered1; /* # of tuples removed by scanqual or joinqual */ + double nfiltered2; /* # of tuples removed by "other" quals */ + BufferUsage bufusage; /* total buffer usage */ + WalUsage walusage; /* total WAL usage */ +} Instrumentation; + +typedef struct WorkerInstrumentation +{ + int num_workers; /* # of structures that follow */ + Instrumentation instrument[FLEXIBLE_ARRAY_MEMBER]; +} WorkerInstrumentation; + +extern PGDLLIMPORT BufferUsage pgBufferUsage; +extern PGDLLIMPORT WalUsage pgWalUsage; + +extern Instrumentation *InstrAlloc(int n, int instrument_options, + bool async_mode); +extern void InstrInit(Instrumentation *instr, int instrument_options); +extern void InstrStartNode(Instrumentation *instr); +extern void InstrStopNode(Instrumentation *instr, double nTuples); +extern void InstrUpdateTupleCount(Instrumentation *instr, double nTuples); +extern void InstrEndLoop(Instrumentation *instr); +extern void InstrAggNode(Instrumentation *dst, Instrumentation *add); +extern void InstrStartParallelQuery(void); +extern void InstrEndParallelQuery(BufferUsage *bufusage, WalUsage *walusage); +extern void InstrAccumParallelQuery(BufferUsage *bufusage, WalUsage *walusage); +extern void BufferUsageAccumDiff(BufferUsage *dst, + const BufferUsage *add, const BufferUsage *sub); +extern void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, + const WalUsage *sub); + +#endif /* INSTRUMENT_H */ diff --git a/install/include/postgresql/server/executor/nodeAgg.h b/install/include/postgresql/server/executor/nodeAgg.h new file mode 100644 index 00000000000..4e43b86d31a --- /dev/null +++ b/install/include/postgresql/server/executor/nodeAgg.h @@ -0,0 +1,341 @@ +/*------------------------------------------------------------------------- + * + * nodeAgg.h + * prototypes for nodeAgg.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeAgg.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEAGG_H +#define NODEAGG_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + + +/* + * AggStatePerTransData - per aggregate state value information + * + * Working state for updating the aggregate's state value, by calling the + * transition function with an input row. This struct does not store the + * information needed to produce the final aggregate result from the transition + * state, that's stored in AggStatePerAggData instead. This separation allows + * multiple aggregate results to be produced from a single state value. + */ +typedef struct AggStatePerTransData +{ + /* + * These values are set up during ExecInitAgg() and do not change + * thereafter: + */ + + /* + * Link to an Aggref expr this state value is for. + * + * There can be multiple Aggref's sharing the same state value, so long as + * the inputs and transition functions are identical and the final + * functions are not read-write. This points to the first one of them. + */ + Aggref *aggref; + + /* + * Is this state value actually being shared by more than one Aggref? + */ + bool aggshared; + + /* + * True for ORDER BY and DISTINCT Aggrefs that are not aggpresorted. + */ + bool aggsortrequired; + + /* + * Number of aggregated input columns. This includes ORDER BY expressions + * in both the plain-agg and ordered-set cases. Ordered-set direct args + * are not counted, though. + */ + int numInputs; + + /* + * Number of aggregated input columns to pass to the transfn. This + * includes the ORDER BY columns for ordered-set aggs, but not for plain + * aggs. (This doesn't count the transition state value!) + */ + int numTransInputs; + + /* Oid of the state transition or combine function */ + Oid transfn_oid; + + /* Oid of the serialization function or InvalidOid */ + Oid serialfn_oid; + + /* Oid of the deserialization function or InvalidOid */ + Oid deserialfn_oid; + + /* Oid of state value's datatype */ + Oid aggtranstype; + + /* + * fmgr lookup data for transition function or combine function. Note in + * particular that the fn_strict flag is kept here. + */ + FmgrInfo transfn; + + /* fmgr lookup data for serialization function */ + FmgrInfo serialfn; + + /* fmgr lookup data for deserialization function */ + FmgrInfo deserialfn; + + /* Input collation derived for aggregate */ + Oid aggCollation; + + /* number of sorting columns */ + int numSortCols; + + /* number of sorting columns to consider in DISTINCT comparisons */ + /* (this is either zero or the same as numSortCols) */ + int numDistinctCols; + + /* deconstructed sorting information (arrays of length numSortCols) */ + AttrNumber *sortColIdx; + Oid *sortOperators; + Oid *sortCollations; + bool *sortNullsFirst; + + /* + * Comparators for input columns --- only set/used when aggregate has + * DISTINCT flag. equalfnOne version is used for single-column + * comparisons, equalfnMulti for the case of multiple columns. + */ + FmgrInfo equalfnOne; + ExprState *equalfnMulti; + + /* + * initial value from pg_aggregate entry + */ + Datum initValue; + bool initValueIsNull; + + /* + * We need the len and byval info for the agg's input and transition data + * types in order to know how to copy/delete values. + * + * Note that the info for the input type is used only when handling + * DISTINCT aggs with just one argument, so there is only one input type. + */ + int16 inputtypeLen, + transtypeLen; + bool inputtypeByVal, + transtypeByVal; + + /* + * Slots for holding the evaluated input arguments. These are set up + * during ExecInitAgg() and then used for each input row requiring either + * FILTER or ORDER BY/DISTINCT processing. + */ + TupleTableSlot *sortslot; /* current input tuple */ + TupleTableSlot *uniqslot; /* used for multi-column DISTINCT */ + TupleDesc sortdesc; /* descriptor of input tuples */ + Datum lastdatum; /* used for single-column DISTINCT */ + bool lastisnull; /* used for single-column DISTINCT */ + bool haslast; /* got a last value for DISTINCT check */ + + /* + * These values are working state that is initialized at the start of an + * input tuple group and updated for each input tuple. + * + * For a simple (non DISTINCT/ORDER BY) aggregate, we just feed the input + * values straight to the transition function. If it's DISTINCT or + * requires ORDER BY, we pass the input values into a Tuplesort object; + * then at completion of the input tuple group, we scan the sorted values, + * eliminate duplicates if needed, and run the transition function on the + * rest. + * + * We need a separate tuplesort for each grouping set. + */ + + Tuplesortstate **sortstates; /* sort objects, if DISTINCT or ORDER BY */ + + /* + * This field is a pre-initialized FunctionCallInfo struct used for + * calling this aggregate's transfn. We save a few cycles per row by not + * re-initializing the unchanging fields; which isn't much, but it seems + * worth the extra space consumption. + */ + FunctionCallInfo transfn_fcinfo; + + /* Likewise for serialization and deserialization functions */ + FunctionCallInfo serialfn_fcinfo; + + FunctionCallInfo deserialfn_fcinfo; +} AggStatePerTransData; + +/* + * AggStatePerAggData - per-aggregate information + * + * This contains the information needed to call the final function, to produce + * a final aggregate result from the state value. If there are multiple + * identical Aggrefs in the query, they can all share the same per-agg data. + * + * These values are set up during ExecInitAgg() and do not change thereafter. + */ +typedef struct AggStatePerAggData +{ + /* + * Link to an Aggref expr this state value is for. + * + * There can be multiple identical Aggref's sharing the same per-agg. This + * points to the first one of them. + */ + Aggref *aggref; + + /* index to the state value which this agg should use */ + int transno; + + /* Optional Oid of final function (may be InvalidOid) */ + Oid finalfn_oid; + + /* + * fmgr lookup data for final function --- only valid when finalfn_oid is + * not InvalidOid. + */ + FmgrInfo finalfn; + + /* + * Number of arguments to pass to the finalfn. This is always at least 1 + * (the transition state value) plus any ordered-set direct args. If the + * finalfn wants extra args then we pass nulls corresponding to the + * aggregated input columns. + */ + int numFinalArgs; + + /* ExprStates for any direct-argument expressions */ + List *aggdirectargs; + + /* + * We need the len and byval info for the agg's result data type in order + * to know how to copy/delete values. + */ + int16 resulttypeLen; + bool resulttypeByVal; + + /* + * "shareable" is false if this agg cannot share state values with other + * aggregates because the final function is read-write. + */ + bool shareable; +} AggStatePerAggData; + +/* + * AggStatePerGroupData - per-aggregate-per-group working state + * + * These values are working state that is initialized at the start of + * an input tuple group and updated for each input tuple. + * + * In AGG_PLAIN and AGG_SORTED modes, we have a single array of these + * structs (pointed to by aggstate->pergroup); we re-use the array for + * each input group, if it's AGG_SORTED mode. In AGG_HASHED mode, the + * hash table contains an array of these structs for each tuple group. + * + * Logically, the sortstate field belongs in this struct, but we do not + * keep it here for space reasons: we don't support DISTINCT aggregates + * in AGG_HASHED mode, so there's no reason to use up a pointer field + * in every entry of the hashtable. + */ +typedef struct AggStatePerGroupData +{ +#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE 0 + Datum transValue; /* current transition value */ +#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL 1 + bool transValueIsNull; + +#define FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE 2 + bool noTransValue; /* true if transValue not set yet */ + + /* + * Note: noTransValue initially has the same value as transValueIsNull, + * and if true both are cleared to false at the same time. They are not + * the same though: if transfn later returns a NULL, we want to keep that + * NULL and not auto-replace it with a later input value. Only the first + * non-NULL input will be auto-substituted. + */ +} AggStatePerGroupData; + +/* + * AggStatePerPhaseData - per-grouping-set-phase state + * + * Grouping sets are divided into "phases", where a single phase can be + * processed in one pass over the input. If there is more than one phase, then + * at the end of input from the current phase, state is reset and another pass + * taken over the data which has been re-sorted in the mean time. + * + * Accordingly, each phase specifies a list of grouping sets and group clause + * information, plus each phase after the first also has a sort order. + */ +typedef struct AggStatePerPhaseData +{ + AggStrategy aggstrategy; /* strategy for this phase */ + int numsets; /* number of grouping sets (or 0) */ + int *gset_lengths; /* lengths of grouping sets */ + Bitmapset **grouped_cols; /* column groupings for rollup */ + ExprState **eqfunctions; /* expression returning equality, indexed by + * nr of cols to compare */ + Agg *aggnode; /* Agg node for phase data */ + Sort *sortnode; /* Sort node for input ordering for phase */ + + ExprState *evaltrans; /* evaluation of transition functions */ + + /*---------- + * Cached variants of the compiled expression. + * first subscript: 0: outerops; 1: TTSOpsMinimalTuple + * second subscript: 0: no NULL check; 1: with NULL check + *---------- + */ + ExprState *evaltrans_cache[2][2]; +} AggStatePerPhaseData; + +/* + * AggStatePerHashData - per-hashtable state + * + * When doing grouping sets with hashing, we have one of these for each + * grouping set. (When doing hashing without grouping sets, we have just one of + * them.) + */ +typedef struct AggStatePerHashData +{ + TupleHashTable hashtable; /* hash table with one entry per group */ + TupleHashIterator hashiter; /* for iterating through hash table */ + TupleTableSlot *hashslot; /* slot for loading hash table */ + FmgrInfo *hashfunctions; /* per-grouping-field hash fns */ + Oid *eqfuncoids; /* per-grouping-field equality fns */ + int numCols; /* number of hash key columns */ + int numhashGrpCols; /* number of columns in hash table */ + int largestGrpColIdx; /* largest col required for hashing */ + AttrNumber *hashGrpColIdxInput; /* hash col indices in input slot */ + AttrNumber *hashGrpColIdxHash; /* indices in hash table tuples */ + Agg *aggnode; /* original Agg node, for numGroups etc. */ +} AggStatePerHashData; + + +extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags); +extern void ExecEndAgg(AggState *node); +extern void ExecReScanAgg(AggState *node); + +extern Size hash_agg_entry_size(int numTrans, Size tupleWidth, + Size transitionSpace); +extern void hash_agg_set_limits(double hashentrysize, double input_groups, + int used_bits, Size *mem_limit, + uint64 *ngroups_limit, int *num_partitions); + +/* parallel instrumentation support */ +extern void ExecAggEstimate(AggState *node, ParallelContext *pcxt); +extern void ExecAggInitializeDSM(AggState *node, ParallelContext *pcxt); +extern void ExecAggInitializeWorker(AggState *node, ParallelWorkerContext *pwcxt); +extern void ExecAggRetrieveInstrumentation(AggState *node); + +#endif /* NODEAGG_H */ diff --git a/install/include/postgresql/server/executor/nodeAppend.h b/install/include/postgresql/server/executor/nodeAppend.h new file mode 100644 index 00000000000..4427ef371d2 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeAppend.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * nodeAppend.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeAppend.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEAPPEND_H +#define NODEAPPEND_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern AppendState *ExecInitAppend(Append *node, EState *estate, int eflags); +extern void ExecEndAppend(AppendState *node); +extern void ExecReScanAppend(AppendState *node); +extern void ExecAppendEstimate(AppendState *node, ParallelContext *pcxt); +extern void ExecAppendInitializeDSM(AppendState *node, ParallelContext *pcxt); +extern void ExecAppendReInitializeDSM(AppendState *node, ParallelContext *pcxt); +extern void ExecAppendInitializeWorker(AppendState *node, ParallelWorkerContext *pwcxt); + +extern void ExecAsyncAppendResponse(AsyncRequest *areq); + +#endif /* NODEAPPEND_H */ diff --git a/install/include/postgresql/server/executor/nodeBitmapAnd.h b/install/include/postgresql/server/executor/nodeBitmapAnd.h new file mode 100644 index 00000000000..4833fd0df7e --- /dev/null +++ b/install/include/postgresql/server/executor/nodeBitmapAnd.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * nodeBitmapAnd.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeBitmapAnd.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEBITMAPAND_H +#define NODEBITMAPAND_H + +#include "nodes/execnodes.h" + +extern BitmapAndState *ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags); +extern Node *MultiExecBitmapAnd(BitmapAndState *node); +extern void ExecEndBitmapAnd(BitmapAndState *node); +extern void ExecReScanBitmapAnd(BitmapAndState *node); + +#endif /* NODEBITMAPAND_H */ diff --git a/install/include/postgresql/server/executor/nodeBitmapHeapscan.h b/install/include/postgresql/server/executor/nodeBitmapHeapscan.h new file mode 100644 index 00000000000..3a267a7fbd7 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeBitmapHeapscan.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * nodeBitmapHeapscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeBitmapHeapscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEBITMAPHEAPSCAN_H +#define NODEBITMAPHEAPSCAN_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern BitmapHeapScanState *ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags); +extern void ExecEndBitmapHeapScan(BitmapHeapScanState *node); +extern void ExecReScanBitmapHeapScan(BitmapHeapScanState *node); +extern void ExecBitmapHeapEstimate(BitmapHeapScanState *node, + ParallelContext *pcxt); +extern void ExecBitmapHeapInitializeDSM(BitmapHeapScanState *node, + ParallelContext *pcxt); +extern void ExecBitmapHeapReInitializeDSM(BitmapHeapScanState *node, + ParallelContext *pcxt); +extern void ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node, + ParallelWorkerContext *pwcxt); + +#endif /* NODEBITMAPHEAPSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeBitmapIndexscan.h b/install/include/postgresql/server/executor/nodeBitmapIndexscan.h new file mode 100644 index 00000000000..454aa434425 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeBitmapIndexscan.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * nodeBitmapIndexscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeBitmapIndexscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEBITMAPINDEXSCAN_H +#define NODEBITMAPINDEXSCAN_H + +#include "nodes/execnodes.h" + +extern BitmapIndexScanState *ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags); +extern Node *MultiExecBitmapIndexScan(BitmapIndexScanState *node); +extern void ExecEndBitmapIndexScan(BitmapIndexScanState *node); +extern void ExecReScanBitmapIndexScan(BitmapIndexScanState *node); + +#endif /* NODEBITMAPINDEXSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeBitmapOr.h b/install/include/postgresql/server/executor/nodeBitmapOr.h new file mode 100644 index 00000000000..2c2e112840f --- /dev/null +++ b/install/include/postgresql/server/executor/nodeBitmapOr.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * nodeBitmapOr.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeBitmapOr.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEBITMAPOR_H +#define NODEBITMAPOR_H + +#include "nodes/execnodes.h" + +extern BitmapOrState *ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags); +extern Node *MultiExecBitmapOr(BitmapOrState *node); +extern void ExecEndBitmapOr(BitmapOrState *node); +extern void ExecReScanBitmapOr(BitmapOrState *node); + +#endif /* NODEBITMAPOR_H */ diff --git a/install/include/postgresql/server/executor/nodeCtescan.h b/install/include/postgresql/server/executor/nodeCtescan.h new file mode 100644 index 00000000000..d28e2eb5d5b --- /dev/null +++ b/install/include/postgresql/server/executor/nodeCtescan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeCtescan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeCtescan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODECTESCAN_H +#define NODECTESCAN_H + +#include "nodes/execnodes.h" + +extern CteScanState *ExecInitCteScan(CteScan *node, EState *estate, int eflags); +extern void ExecEndCteScan(CteScanState *node); +extern void ExecReScanCteScan(CteScanState *node); + +#endif /* NODECTESCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeCustom.h b/install/include/postgresql/server/executor/nodeCustom.h new file mode 100644 index 00000000000..05f63eb6a29 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeCustom.h @@ -0,0 +1,42 @@ +/* ------------------------------------------------------------------------ + * + * nodeCustom.h + * + * prototypes for CustomScan nodes + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * ------------------------------------------------------------------------ + */ +#ifndef NODECUSTOM_H +#define NODECUSTOM_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +/* + * General executor code + */ +extern CustomScanState *ExecInitCustomScan(CustomScan *cscan, + EState *estate, int eflags); +extern void ExecEndCustomScan(CustomScanState *node); + +extern void ExecReScanCustomScan(CustomScanState *node); +extern void ExecCustomMarkPos(CustomScanState *node); +extern void ExecCustomRestrPos(CustomScanState *node); + +/* + * Parallel execution support + */ +extern void ExecCustomScanEstimate(CustomScanState *node, + ParallelContext *pcxt); +extern void ExecCustomScanInitializeDSM(CustomScanState *node, + ParallelContext *pcxt); +extern void ExecCustomScanReInitializeDSM(CustomScanState *node, + ParallelContext *pcxt); +extern void ExecCustomScanInitializeWorker(CustomScanState *node, + ParallelWorkerContext *pwcxt); +extern void ExecShutdownCustomScan(CustomScanState *node); + +#endif /* NODECUSTOM_H */ diff --git a/install/include/postgresql/server/executor/nodeForeignscan.h b/install/include/postgresql/server/executor/nodeForeignscan.h new file mode 100644 index 00000000000..4016c767a87 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeForeignscan.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * nodeForeignscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeForeignscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEFOREIGNSCAN_H +#define NODEFOREIGNSCAN_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern ForeignScanState *ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags); +extern void ExecEndForeignScan(ForeignScanState *node); +extern void ExecReScanForeignScan(ForeignScanState *node); + +extern void ExecForeignScanEstimate(ForeignScanState *node, + ParallelContext *pcxt); +extern void ExecForeignScanInitializeDSM(ForeignScanState *node, + ParallelContext *pcxt); +extern void ExecForeignScanReInitializeDSM(ForeignScanState *node, + ParallelContext *pcxt); +extern void ExecForeignScanInitializeWorker(ForeignScanState *node, + ParallelWorkerContext *pwcxt); +extern void ExecShutdownForeignScan(ForeignScanState *node); + +extern void ExecAsyncForeignScanRequest(AsyncRequest *areq); +extern void ExecAsyncForeignScanConfigureWait(AsyncRequest *areq); +extern void ExecAsyncForeignScanNotify(AsyncRequest *areq); + +#endif /* NODEFOREIGNSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeFunctionscan.h b/install/include/postgresql/server/executor/nodeFunctionscan.h new file mode 100644 index 00000000000..da71fb84635 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeFunctionscan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeFunctionscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeFunctionscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEFUNCTIONSCAN_H +#define NODEFUNCTIONSCAN_H + +#include "nodes/execnodes.h" + +extern FunctionScanState *ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags); +extern void ExecEndFunctionScan(FunctionScanState *node); +extern void ExecReScanFunctionScan(FunctionScanState *node); + +#endif /* NODEFUNCTIONSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeGather.h b/install/include/postgresql/server/executor/nodeGather.h new file mode 100644 index 00000000000..a3915617400 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeGather.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * nodeGather.h + * prototypes for nodeGather.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeGather.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEGATHER_H +#define NODEGATHER_H + +#include "nodes/execnodes.h" + +extern GatherState *ExecInitGather(Gather *node, EState *estate, int eflags); +extern void ExecEndGather(GatherState *node); +extern void ExecShutdownGather(GatherState *node); +extern void ExecReScanGather(GatherState *node); + +#endif /* NODEGATHER_H */ diff --git a/install/include/postgresql/server/executor/nodeGatherMerge.h b/install/include/postgresql/server/executor/nodeGatherMerge.h new file mode 100644 index 00000000000..06ef0f44efd --- /dev/null +++ b/install/include/postgresql/server/executor/nodeGatherMerge.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * nodeGatherMerge.h + * prototypes for nodeGatherMerge.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeGatherMerge.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEGATHERMERGE_H +#define NODEGATHERMERGE_H + +#include "nodes/execnodes.h" + +extern GatherMergeState *ExecInitGatherMerge(GatherMerge *node, + EState *estate, + int eflags); +extern void ExecEndGatherMerge(GatherMergeState *node); +extern void ExecReScanGatherMerge(GatherMergeState *node); +extern void ExecShutdownGatherMerge(GatherMergeState *node); + +#endif /* NODEGATHERMERGE_H */ diff --git a/install/include/postgresql/server/executor/nodeGroup.h b/install/include/postgresql/server/executor/nodeGroup.h new file mode 100644 index 00000000000..79215147e55 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeGroup.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeGroup.h + * prototypes for nodeGroup.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeGroup.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEGROUP_H +#define NODEGROUP_H + +#include "nodes/execnodes.h" + +extern GroupState *ExecInitGroup(Group *node, EState *estate, int eflags); +extern void ExecEndGroup(GroupState *node); +extern void ExecReScanGroup(GroupState *node); + +#endif /* NODEGROUP_H */ diff --git a/install/include/postgresql/server/executor/nodeHash.h b/install/include/postgresql/server/executor/nodeHash.h new file mode 100644 index 00000000000..56d5350c615 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeHash.h @@ -0,0 +1,82 @@ +/*------------------------------------------------------------------------- + * + * nodeHash.h + * prototypes for nodeHash.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeHash.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEHASH_H +#define NODEHASH_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +struct SharedHashJoinBatch; + +extern HashState *ExecInitHash(Hash *node, EState *estate, int eflags); +extern Node *MultiExecHash(HashState *node); +extern void ExecEndHash(HashState *node); +extern void ExecReScanHash(HashState *node); + +extern HashJoinTable ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations, + bool keepNulls); +extern void ExecParallelHashTableAlloc(HashJoinTable hashtable, + int batchno); +extern void ExecHashTableDestroy(HashJoinTable hashtable); +extern void ExecHashTableDetach(HashJoinTable hashtable); +extern void ExecHashTableDetachBatch(HashJoinTable hashtable); +extern void ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, + int batchno); + +extern void ExecHashTableInsert(HashJoinTable hashtable, + TupleTableSlot *slot, + uint32 hashvalue); +extern void ExecParallelHashTableInsert(HashJoinTable hashtable, + TupleTableSlot *slot, + uint32 hashvalue); +extern void ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable, + TupleTableSlot *slot, + uint32 hashvalue); +extern bool ExecHashGetHashValue(HashJoinTable hashtable, + ExprContext *econtext, + List *hashkeys, + bool outer_tuple, + bool keep_nulls, + uint32 *hashvalue); +extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable, + uint32 hashvalue, + int *bucketno, + int *batchno); +extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext); +extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext); +extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate); +extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate); +extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate, + ExprContext *econtext); +extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate, + ExprContext *econtext); +extern void ExecHashTableReset(HashJoinTable hashtable); +extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable); +extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew, + bool try_combined_hash_mem, + int parallel_workers, + size_t *space_allowed, + int *numbuckets, + int *numbatches, + int *num_skew_mcvs); +extern int ExecHashGetSkewBucket(HashJoinTable hashtable, uint32 hashvalue); +extern void ExecHashEstimate(HashState *node, ParallelContext *pcxt); +extern void ExecHashInitializeDSM(HashState *node, ParallelContext *pcxt); +extern void ExecHashInitializeWorker(HashState *node, ParallelWorkerContext *pwcxt); +extern void ExecHashRetrieveInstrumentation(HashState *node); +extern void ExecShutdownHash(HashState *node); +extern void ExecHashAccumInstrumentation(HashInstrumentation *instrument, + HashJoinTable hashtable); + +#endif /* NODEHASH_H */ diff --git a/install/include/postgresql/server/executor/nodeHashjoin.h b/install/include/postgresql/server/executor/nodeHashjoin.h new file mode 100644 index 00000000000..ccb704ede1d --- /dev/null +++ b/install/include/postgresql/server/executor/nodeHashjoin.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * nodeHashjoin.h + * prototypes for nodeHashjoin.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeHashjoin.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEHASHJOIN_H +#define NODEHASHJOIN_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" +#include "storage/buffile.h" + +extern HashJoinState *ExecInitHashJoin(HashJoin *node, EState *estate, int eflags); +extern void ExecEndHashJoin(HashJoinState *node); +extern void ExecReScanHashJoin(HashJoinState *node); +extern void ExecShutdownHashJoin(HashJoinState *node); +extern void ExecHashJoinEstimate(HashJoinState *state, ParallelContext *pcxt); +extern void ExecHashJoinInitializeDSM(HashJoinState *state, ParallelContext *pcxt); +extern void ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *pcxt); +extern void ExecHashJoinInitializeWorker(HashJoinState *state, + ParallelWorkerContext *pwcxt); + +extern void ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue, + BufFile **fileptr, HashJoinTable hashtable); + +#endif /* NODEHASHJOIN_H */ diff --git a/install/include/postgresql/server/executor/nodeIncrementalSort.h b/install/include/postgresql/server/executor/nodeIncrementalSort.h new file mode 100644 index 00000000000..4e190092129 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeIncrementalSort.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * nodeIncrementalSort.h + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeIncrementalSort.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEINCREMENTALSORT_H +#define NODEINCREMENTALSORT_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern IncrementalSortState *ExecInitIncrementalSort(IncrementalSort *node, EState *estate, int eflags); +extern void ExecEndIncrementalSort(IncrementalSortState *node); +extern void ExecReScanIncrementalSort(IncrementalSortState *node); + +/* parallel instrumentation support */ +extern void ExecIncrementalSortEstimate(IncrementalSortState *node, ParallelContext *pcxt); +extern void ExecIncrementalSortInitializeDSM(IncrementalSortState *node, ParallelContext *pcxt); +extern void ExecIncrementalSortInitializeWorker(IncrementalSortState *node, ParallelWorkerContext *pwcxt); +extern void ExecIncrementalSortRetrieveInstrumentation(IncrementalSortState *node); + +#endif /* NODEINCREMENTALSORT_H */ diff --git a/install/include/postgresql/server/executor/nodeIndexonlyscan.h b/install/include/postgresql/server/executor/nodeIndexonlyscan.h new file mode 100644 index 00000000000..e5260f87779 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeIndexonlyscan.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * nodeIndexonlyscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeIndexonlyscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEINDEXONLYSCAN_H +#define NODEINDEXONLYSCAN_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern IndexOnlyScanState *ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags); +extern void ExecEndIndexOnlyScan(IndexOnlyScanState *node); +extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node); +extern void ExecIndexOnlyRestrPos(IndexOnlyScanState *node); +extern void ExecReScanIndexOnlyScan(IndexOnlyScanState *node); + +/* Support functions for parallel index-only scans */ +extern void ExecIndexOnlyScanEstimate(IndexOnlyScanState *node, + ParallelContext *pcxt); +extern void ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node, + ParallelContext *pcxt); +extern void ExecIndexOnlyScanReInitializeDSM(IndexOnlyScanState *node, + ParallelContext *pcxt); +extern void ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node, + ParallelWorkerContext *pwcxt); + +#endif /* NODEINDEXONLYSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeIndexscan.h b/install/include/postgresql/server/executor/nodeIndexscan.h new file mode 100644 index 00000000000..8ee7969792b --- /dev/null +++ b/install/include/postgresql/server/executor/nodeIndexscan.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * nodeIndexscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeIndexscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEINDEXSCAN_H +#define NODEINDEXSCAN_H + +#include "access/genam.h" +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern IndexScanState *ExecInitIndexScan(IndexScan *node, EState *estate, int eflags); +extern void ExecEndIndexScan(IndexScanState *node); +extern void ExecIndexMarkPos(IndexScanState *node); +extern void ExecIndexRestrPos(IndexScanState *node); +extern void ExecReScanIndexScan(IndexScanState *node); +extern void ExecIndexScanEstimate(IndexScanState *node, ParallelContext *pcxt); +extern void ExecIndexScanInitializeDSM(IndexScanState *node, ParallelContext *pcxt); +extern void ExecIndexScanReInitializeDSM(IndexScanState *node, ParallelContext *pcxt); +extern void ExecIndexScanInitializeWorker(IndexScanState *node, + ParallelWorkerContext *pwcxt); + +/* + * These routines are exported to share code with nodeIndexonlyscan.c and + * nodeBitmapIndexscan.c + */ +extern void ExecIndexBuildScanKeys(PlanState *planstate, Relation index, + List *quals, bool isorderby, + ScanKey *scanKeys, int *numScanKeys, + IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys, + IndexArrayKeyInfo **arrayKeys, int *numArrayKeys); +extern void ExecIndexEvalRuntimeKeys(ExprContext *econtext, + IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys); +extern bool ExecIndexEvalArrayKeys(ExprContext *econtext, + IndexArrayKeyInfo *arrayKeys, int numArrayKeys); +extern bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys); + +#endif /* NODEINDEXSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeLimit.h b/install/include/postgresql/server/executor/nodeLimit.h new file mode 100644 index 00000000000..7ff465c0f0a --- /dev/null +++ b/install/include/postgresql/server/executor/nodeLimit.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeLimit.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeLimit.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODELIMIT_H +#define NODELIMIT_H + +#include "nodes/execnodes.h" + +extern LimitState *ExecInitLimit(Limit *node, EState *estate, int eflags); +extern void ExecEndLimit(LimitState *node); +extern void ExecReScanLimit(LimitState *node); + +#endif /* NODELIMIT_H */ diff --git a/install/include/postgresql/server/executor/nodeLockRows.h b/install/include/postgresql/server/executor/nodeLockRows.h new file mode 100644 index 00000000000..27cb169ccfd --- /dev/null +++ b/install/include/postgresql/server/executor/nodeLockRows.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeLockRows.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeLockRows.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODELOCKROWS_H +#define NODELOCKROWS_H + +#include "nodes/execnodes.h" + +extern LockRowsState *ExecInitLockRows(LockRows *node, EState *estate, int eflags); +extern void ExecEndLockRows(LockRowsState *node); +extern void ExecReScanLockRows(LockRowsState *node); + +#endif /* NODELOCKROWS_H */ diff --git a/install/include/postgresql/server/executor/nodeMaterial.h b/install/include/postgresql/server/executor/nodeMaterial.h new file mode 100644 index 00000000000..4af2e8a6ce6 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeMaterial.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * + * nodeMaterial.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeMaterial.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEMATERIAL_H +#define NODEMATERIAL_H + +#include "nodes/execnodes.h" + +extern MaterialState *ExecInitMaterial(Material *node, EState *estate, int eflags); +extern void ExecEndMaterial(MaterialState *node); +extern void ExecMaterialMarkPos(MaterialState *node); +extern void ExecMaterialRestrPos(MaterialState *node); +extern void ExecReScanMaterial(MaterialState *node); + +#endif /* NODEMATERIAL_H */ diff --git a/install/include/postgresql/server/executor/nodeMemoize.h b/install/include/postgresql/server/executor/nodeMemoize.h new file mode 100644 index 00000000000..2089900a236 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeMemoize.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * nodeMemoize.h + * + * + * + * Portions Copyright (c) 2021-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeMemoize.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEMEMOIZE_H +#define NODEMEMOIZE_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern MemoizeState *ExecInitMemoize(Memoize *node, EState *estate, int eflags); +extern void ExecEndMemoize(MemoizeState *node); +extern void ExecReScanMemoize(MemoizeState *node); +extern double ExecEstimateCacheEntryOverheadBytes(double ntuples); +extern void ExecMemoizeEstimate(MemoizeState *node, + ParallelContext *pcxt); +extern void ExecMemoizeInitializeDSM(MemoizeState *node, + ParallelContext *pcxt); +extern void ExecMemoizeInitializeWorker(MemoizeState *node, + ParallelWorkerContext *pwcxt); +extern void ExecMemoizeRetrieveInstrumentation(MemoizeState *node); + +#endif /* NODEMEMOIZE_H */ diff --git a/install/include/postgresql/server/executor/nodeMergeAppend.h b/install/include/postgresql/server/executor/nodeMergeAppend.h new file mode 100644 index 00000000000..ed24a3529d5 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeMergeAppend.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeMergeAppend.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeMergeAppend.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEMERGEAPPEND_H +#define NODEMERGEAPPEND_H + +#include "nodes/execnodes.h" + +extern MergeAppendState *ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags); +extern void ExecEndMergeAppend(MergeAppendState *node); +extern void ExecReScanMergeAppend(MergeAppendState *node); + +#endif /* NODEMERGEAPPEND_H */ diff --git a/install/include/postgresql/server/executor/nodeMergejoin.h b/install/include/postgresql/server/executor/nodeMergejoin.h new file mode 100644 index 00000000000..344d9cad825 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeMergejoin.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeMergejoin.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeMergejoin.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEMERGEJOIN_H +#define NODEMERGEJOIN_H + +#include "nodes/execnodes.h" + +extern MergeJoinState *ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags); +extern void ExecEndMergeJoin(MergeJoinState *node); +extern void ExecReScanMergeJoin(MergeJoinState *node); + +#endif /* NODEMERGEJOIN_H */ diff --git a/install/include/postgresql/server/executor/nodeModifyTable.h b/install/include/postgresql/server/executor/nodeModifyTable.h new file mode 100644 index 00000000000..e7eeb307d0f --- /dev/null +++ b/install/include/postgresql/server/executor/nodeModifyTable.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * nodeModifyTable.h + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeModifyTable.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEMODIFYTABLE_H +#define NODEMODIFYTABLE_H + +#include "nodes/execnodes.h" + +extern void ExecInitStoredGenerated(ResultRelInfo *resultRelInfo, + EState *estate, + CmdType cmdtype); + +extern void ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo, + EState *estate, TupleTableSlot *slot, + CmdType cmdtype); + +extern ModifyTableState *ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags); +extern void ExecEndModifyTable(ModifyTableState *node); +extern void ExecReScanModifyTable(ModifyTableState *node); + +extern void ExecInitMergeTupleSlots(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo); + +#endif /* NODEMODIFYTABLE_H */ diff --git a/install/include/postgresql/server/executor/nodeNamedtuplestorescan.h b/install/include/postgresql/server/executor/nodeNamedtuplestorescan.h new file mode 100644 index 00000000000..3ff687023af --- /dev/null +++ b/install/include/postgresql/server/executor/nodeNamedtuplestorescan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeNamedtuplestorescan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeNamedtuplestorescan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODENAMEDTUPLESTORESCAN_H +#define NODENAMEDTUPLESTORESCAN_H + +#include "nodes/execnodes.h" + +extern NamedTuplestoreScanState *ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags); +extern void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node); +extern void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node); + +#endif /* NODENAMEDTUPLESTORESCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeNestloop.h b/install/include/postgresql/server/executor/nodeNestloop.h new file mode 100644 index 00000000000..c9a339e6a75 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeNestloop.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeNestloop.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeNestloop.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODENESTLOOP_H +#define NODENESTLOOP_H + +#include "nodes/execnodes.h" + +extern NestLoopState *ExecInitNestLoop(NestLoop *node, EState *estate, int eflags); +extern void ExecEndNestLoop(NestLoopState *node); +extern void ExecReScanNestLoop(NestLoopState *node); + +#endif /* NODENESTLOOP_H */ diff --git a/install/include/postgresql/server/executor/nodeProjectSet.h b/install/include/postgresql/server/executor/nodeProjectSet.h new file mode 100644 index 00000000000..9369443bdb0 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeProjectSet.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeProjectSet.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeProjectSet.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEPROJECTSET_H +#define NODEPROJECTSET_H + +#include "nodes/execnodes.h" + +extern ProjectSetState *ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags); +extern void ExecEndProjectSet(ProjectSetState *node); +extern void ExecReScanProjectSet(ProjectSetState *node); + +#endif /* NODEPROJECTSET_H */ diff --git a/install/include/postgresql/server/executor/nodeRecursiveunion.h b/install/include/postgresql/server/executor/nodeRecursiveunion.h new file mode 100644 index 00000000000..0053605dcaf --- /dev/null +++ b/install/include/postgresql/server/executor/nodeRecursiveunion.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeRecursiveunion.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeRecursiveunion.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODERECURSIVEUNION_H +#define NODERECURSIVEUNION_H + +#include "nodes/execnodes.h" + +extern RecursiveUnionState *ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags); +extern void ExecEndRecursiveUnion(RecursiveUnionState *node); +extern void ExecReScanRecursiveUnion(RecursiveUnionState *node); + +#endif /* NODERECURSIVEUNION_H */ diff --git a/install/include/postgresql/server/executor/nodeResult.h b/install/include/postgresql/server/executor/nodeResult.h new file mode 100644 index 00000000000..86ff91a6236 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeResult.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * + * nodeResult.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeResult.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODERESULT_H +#define NODERESULT_H + +#include "nodes/execnodes.h" + +extern ResultState *ExecInitResult(Result *node, EState *estate, int eflags); +extern void ExecEndResult(ResultState *node); +extern void ExecResultMarkPos(ResultState *node); +extern void ExecResultRestrPos(ResultState *node); +extern void ExecReScanResult(ResultState *node); + +#endif /* NODERESULT_H */ diff --git a/install/include/postgresql/server/executor/nodeSamplescan.h b/install/include/postgresql/server/executor/nodeSamplescan.h new file mode 100644 index 00000000000..888170a59ae --- /dev/null +++ b/install/include/postgresql/server/executor/nodeSamplescan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeSamplescan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeSamplescan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODESAMPLESCAN_H +#define NODESAMPLESCAN_H + +#include "nodes/execnodes.h" + +extern SampleScanState *ExecInitSampleScan(SampleScan *node, EState *estate, int eflags); +extern void ExecEndSampleScan(SampleScanState *node); +extern void ExecReScanSampleScan(SampleScanState *node); + +#endif /* NODESAMPLESCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeSeqscan.h b/install/include/postgresql/server/executor/nodeSeqscan.h new file mode 100644 index 00000000000..a5cab9355b5 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeSeqscan.h @@ -0,0 +1,31 @@ +/*------------------------------------------------------------------------- + * + * nodeSeqscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeSeqscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODESEQSCAN_H +#define NODESEQSCAN_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern SeqScanState *ExecInitSeqScan(SeqScan *node, EState *estate, int eflags); +extern void ExecEndSeqScan(SeqScanState *node); +extern void ExecReScanSeqScan(SeqScanState *node); + +/* parallel scan support */ +extern void ExecSeqScanEstimate(SeqScanState *node, ParallelContext *pcxt); +extern void ExecSeqScanInitializeDSM(SeqScanState *node, ParallelContext *pcxt); +extern void ExecSeqScanReInitializeDSM(SeqScanState *node, ParallelContext *pcxt); +extern void ExecSeqScanInitializeWorker(SeqScanState *node, + ParallelWorkerContext *pwcxt); + +#endif /* NODESEQSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeSetOp.h b/install/include/postgresql/server/executor/nodeSetOp.h new file mode 100644 index 00000000000..1fdaafa31c2 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeSetOp.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeSetOp.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeSetOp.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODESETOP_H +#define NODESETOP_H + +#include "nodes/execnodes.h" + +extern SetOpState *ExecInitSetOp(SetOp *node, EState *estate, int eflags); +extern void ExecEndSetOp(SetOpState *node); +extern void ExecReScanSetOp(SetOpState *node); + +#endif /* NODESETOP_H */ diff --git a/install/include/postgresql/server/executor/nodeSort.h b/install/include/postgresql/server/executor/nodeSort.h new file mode 100644 index 00000000000..88e84798905 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeSort.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * nodeSort.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeSort.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODESORT_H +#define NODESORT_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" + +extern SortState *ExecInitSort(Sort *node, EState *estate, int eflags); +extern void ExecEndSort(SortState *node); +extern void ExecSortMarkPos(SortState *node); +extern void ExecSortRestrPos(SortState *node); +extern void ExecReScanSort(SortState *node); + +/* parallel instrumentation support */ +extern void ExecSortEstimate(SortState *node, ParallelContext *pcxt); +extern void ExecSortInitializeDSM(SortState *node, ParallelContext *pcxt); +extern void ExecSortInitializeWorker(SortState *node, ParallelWorkerContext *pwcxt); +extern void ExecSortRetrieveInstrumentation(SortState *node); + +#endif /* NODESORT_H */ diff --git a/install/include/postgresql/server/executor/nodeSubplan.h b/install/include/postgresql/server/executor/nodeSubplan.h new file mode 100644 index 00000000000..3f0e2bba2b7 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeSubplan.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * nodeSubplan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeSubplan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODESUBPLAN_H +#define NODESUBPLAN_H + +#include "nodes/execnodes.h" + +extern SubPlanState *ExecInitSubPlan(SubPlan *subplan, PlanState *parent); + +extern Datum ExecSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull); + +extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent); + +extern void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext); + +extern void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext); + +#endif /* NODESUBPLAN_H */ diff --git a/install/include/postgresql/server/executor/nodeSubqueryscan.h b/install/include/postgresql/server/executor/nodeSubqueryscan.h new file mode 100644 index 00000000000..cc6a9078830 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeSubqueryscan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeSubqueryscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeSubqueryscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODESUBQUERYSCAN_H +#define NODESUBQUERYSCAN_H + +#include "nodes/execnodes.h" + +extern SubqueryScanState *ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags); +extern void ExecEndSubqueryScan(SubqueryScanState *node); +extern void ExecReScanSubqueryScan(SubqueryScanState *node); + +#endif /* NODESUBQUERYSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeTableFuncscan.h b/install/include/postgresql/server/executor/nodeTableFuncscan.h new file mode 100644 index 00000000000..6c002abbc57 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeTableFuncscan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeTableFuncscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeTableFuncscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODETABLEFUNCSCAN_H +#define NODETABLEFUNCSCAN_H + +#include "nodes/execnodes.h" + +extern TableFuncScanState *ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags); +extern void ExecEndTableFuncScan(TableFuncScanState *node); +extern void ExecReScanTableFuncScan(TableFuncScanState *node); + +#endif /* NODETABLEFUNCSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeTidrangescan.h b/install/include/postgresql/server/executor/nodeTidrangescan.h new file mode 100644 index 00000000000..2f46bb53c27 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeTidrangescan.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * nodeTidrangescan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeTidrangescan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODETIDRANGESCAN_H +#define NODETIDRANGESCAN_H + +#include "nodes/execnodes.h" + +extern TidRangeScanState *ExecInitTidRangeScan(TidRangeScan *node, + EState *estate, int eflags); +extern void ExecEndTidRangeScan(TidRangeScanState *node); +extern void ExecReScanTidRangeScan(TidRangeScanState *node); + +#endif /* NODETIDRANGESCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeTidscan.h b/install/include/postgresql/server/executor/nodeTidscan.h new file mode 100644 index 00000000000..ca822064435 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeTidscan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeTidscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeTidscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODETIDSCAN_H +#define NODETIDSCAN_H + +#include "nodes/execnodes.h" + +extern TidScanState *ExecInitTidScan(TidScan *node, EState *estate, int eflags); +extern void ExecEndTidScan(TidScanState *node); +extern void ExecReScanTidScan(TidScanState *node); + +#endif /* NODETIDSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeUnique.h b/install/include/postgresql/server/executor/nodeUnique.h new file mode 100644 index 00000000000..671e10aff06 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeUnique.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeUnique.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeUnique.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEUNIQUE_H +#define NODEUNIQUE_H + +#include "nodes/execnodes.h" + +extern UniqueState *ExecInitUnique(Unique *node, EState *estate, int eflags); +extern void ExecEndUnique(UniqueState *node); +extern void ExecReScanUnique(UniqueState *node); + +#endif /* NODEUNIQUE_H */ diff --git a/install/include/postgresql/server/executor/nodeValuesscan.h b/install/include/postgresql/server/executor/nodeValuesscan.h new file mode 100644 index 00000000000..a52fa678dfe --- /dev/null +++ b/install/include/postgresql/server/executor/nodeValuesscan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeValuesscan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeValuesscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEVALUESSCAN_H +#define NODEVALUESSCAN_H + +#include "nodes/execnodes.h" + +extern ValuesScanState *ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags); +extern void ExecEndValuesScan(ValuesScanState *node); +extern void ExecReScanValuesScan(ValuesScanState *node); + +#endif /* NODEVALUESSCAN_H */ diff --git a/install/include/postgresql/server/executor/nodeWindowAgg.h b/install/include/postgresql/server/executor/nodeWindowAgg.h new file mode 100644 index 00000000000..4a60ab28b9c --- /dev/null +++ b/install/include/postgresql/server/executor/nodeWindowAgg.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeWindowAgg.h + * prototypes for nodeWindowAgg.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeWindowAgg.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEWINDOWAGG_H +#define NODEWINDOWAGG_H + +#include "nodes/execnodes.h" + +extern WindowAggState *ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags); +extern void ExecEndWindowAgg(WindowAggState *node); +extern void ExecReScanWindowAgg(WindowAggState *node); + +#endif /* NODEWINDOWAGG_H */ diff --git a/install/include/postgresql/server/executor/nodeWorktablescan.h b/install/include/postgresql/server/executor/nodeWorktablescan.h new file mode 100644 index 00000000000..e553a453f34 --- /dev/null +++ b/install/include/postgresql/server/executor/nodeWorktablescan.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * nodeWorktablescan.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/nodeWorktablescan.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEWORKTABLESCAN_H +#define NODEWORKTABLESCAN_H + +#include "nodes/execnodes.h" + +extern WorkTableScanState *ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags); +extern void ExecEndWorkTableScan(WorkTableScanState *node); +extern void ExecReScanWorkTableScan(WorkTableScanState *node); + +#endif /* NODEWORKTABLESCAN_H */ diff --git a/install/include/postgresql/server/executor/spi.h b/install/include/postgresql/server/executor/spi.h new file mode 100644 index 00000000000..d1de139a3b5 --- /dev/null +++ b/install/include/postgresql/server/executor/spi.h @@ -0,0 +1,213 @@ +/*------------------------------------------------------------------------- + * + * spi.h + * Server Programming Interface public declarations + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/spi.h + * + *------------------------------------------------------------------------- + */ +#ifndef SPI_H +#define SPI_H + +#include "commands/trigger.h" +#include "lib/ilist.h" +#include "parser/parser.h" +#include "utils/portal.h" + + +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; + +/* Optional arguments for SPI_prepare_extended */ +typedef struct SPIPrepareOptions +{ + ParserSetupHook parserSetup; + void *parserSetupArg; + RawParseMode parseMode; + int cursorOptions; +} SPIPrepareOptions; + +/* Optional arguments for SPI_execute[_plan]_extended */ +typedef struct SPIExecuteOptions +{ + ParamListInfo params; + bool read_only; + bool allow_nonatomic; + bool must_return_tuples; + uint64 tcount; + DestReceiver *dest; + ResourceOwner owner; +} SPIExecuteOptions; + +/* Optional arguments for SPI_cursor_parse_open */ +typedef struct SPIParseOpenOptions +{ + ParamListInfo params; + int cursorOptions; + bool read_only; +} SPIParseOpenOptions; + +/* Plans are opaque structs for standard users of SPI */ +typedef struct _SPI_plan *SPIPlanPtr; + +#define SPI_ERROR_CONNECT (-1) +#define SPI_ERROR_COPY (-2) +#define SPI_ERROR_OPUNKNOWN (-3) +#define SPI_ERROR_UNCONNECTED (-4) +#define SPI_ERROR_CURSOR (-5) /* not used anymore */ +#define SPI_ERROR_ARGUMENT (-6) +#define SPI_ERROR_PARAM (-7) +#define SPI_ERROR_TRANSACTION (-8) +#define SPI_ERROR_NOATTRIBUTE (-9) +#define SPI_ERROR_NOOUTFUNC (-10) +#define SPI_ERROR_TYPUNKNOWN (-11) +#define SPI_ERROR_REL_DUPLICATE (-12) +#define SPI_ERROR_REL_NOT_FOUND (-13) + +#define SPI_OK_CONNECT 1 +#define SPI_OK_FINISH 2 +#define SPI_OK_FETCH 3 +#define SPI_OK_UTILITY 4 +#define SPI_OK_SELECT 5 +#define SPI_OK_SELINTO 6 +#define SPI_OK_INSERT 7 +#define SPI_OK_DELETE 8 +#define SPI_OK_UPDATE 9 +#define SPI_OK_CURSOR 10 +#define SPI_OK_INSERT_RETURNING 11 +#define SPI_OK_DELETE_RETURNING 12 +#define SPI_OK_UPDATE_RETURNING 13 +#define SPI_OK_REWRITTEN 14 +#define SPI_OK_REL_REGISTER 15 +#define SPI_OK_REL_UNREGISTER 16 +#define SPI_OK_TD_REGISTER 17 +#define SPI_OK_MERGE 18 + +#define SPI_OPT_NONATOMIC (1 << 0) + +/* These used to be functions, now just no-ops for backwards compatibility */ +#define SPI_push() ((void) 0) +#define SPI_pop() ((void) 0) +#define SPI_push_conditional() false +#define SPI_pop_conditional(pushed) ((void) 0) +#define SPI_restore_connection() ((void) 0) + +extern PGDLLIMPORT uint64 SPI_processed; +extern PGDLLIMPORT SPITupleTable *SPI_tuptable; +extern PGDLLIMPORT int SPI_result; + +extern int SPI_connect(void); +extern int SPI_connect_ext(int options); +extern int SPI_finish(void); +extern int SPI_execute(const char *src, bool read_only, long tcount); +extern int SPI_execute_extended(const char *src, + const SPIExecuteOptions *options); +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, + bool read_only, long tcount); +extern int SPI_execute_plan_extended(SPIPlanPtr plan, + const SPIExecuteOptions *options); +extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, + ParamListInfo params, + bool read_only, long tcount); +extern int SPI_exec(const char *src, long tcount); +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, + long tcount); +extern int SPI_execute_snapshot(SPIPlanPtr plan, + Datum *Values, const char *Nulls, + Snapshot snapshot, + Snapshot crosscheck_snapshot, + bool read_only, bool fire_triggers, long tcount); +extern int SPI_execute_with_args(const char *src, + int nargs, Oid *argtypes, + Datum *Values, const char *Nulls, + bool read_only, long tcount); +extern SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes); +extern SPIPlanPtr SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes, + int cursorOptions); +extern SPIPlanPtr SPI_prepare_extended(const char *src, + const SPIPrepareOptions *options); +extern SPIPlanPtr SPI_prepare_params(const char *src, + ParserSetupHook parserSetup, + void *parserSetupArg, + int cursorOptions); +extern int SPI_keepplan(SPIPlanPtr plan); +extern SPIPlanPtr SPI_saveplan(SPIPlanPtr plan); +extern int SPI_freeplan(SPIPlanPtr plan); + +extern Oid SPI_getargtypeid(SPIPlanPtr plan, int argIndex); +extern int SPI_getargcount(SPIPlanPtr plan); +extern bool SPI_is_cursor_plan(SPIPlanPtr plan); +extern bool SPI_plan_is_valid(SPIPlanPtr plan); +extern const char *SPI_result_code_string(int code); + +extern List *SPI_plan_get_plan_sources(SPIPlanPtr plan); +extern CachedPlan *SPI_plan_get_cached_plan(SPIPlanPtr plan); + +extern HeapTuple SPI_copytuple(HeapTuple tuple); +extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc); +extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, + int *attnum, Datum *Values, const char *Nulls); +extern int SPI_fnumber(TupleDesc tupdesc, const char *fname); +extern char *SPI_fname(TupleDesc tupdesc, int fnumber); +extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber); +extern Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull); +extern char *SPI_gettype(TupleDesc tupdesc, int fnumber); +extern Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber); +extern char *SPI_getrelname(Relation rel); +extern char *SPI_getnspname(Relation rel); +extern void *SPI_palloc(Size size); +extern void *SPI_repalloc(void *pointer, Size size); +extern void SPI_pfree(void *pointer); +extern Datum SPI_datumTransfer(Datum value, bool typByVal, int typLen); +extern void SPI_freetuple(HeapTuple tuple); +extern void SPI_freetuptable(SPITupleTable *tuptable); + +extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, + Datum *Values, const char *Nulls, bool read_only); +extern Portal SPI_cursor_open_with_args(const char *name, + const char *src, + int nargs, Oid *argtypes, + Datum *Values, const char *Nulls, + bool read_only, int cursorOptions); +extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, + ParamListInfo params, bool read_only); +extern Portal SPI_cursor_parse_open(const char *name, + const char *src, + const SPIParseOpenOptions *options); +extern Portal SPI_cursor_find(const char *name); +extern void SPI_cursor_fetch(Portal portal, bool forward, long count); +extern void SPI_cursor_move(Portal portal, bool forward, long count); +extern void SPI_scroll_cursor_fetch(Portal, FetchDirection direction, long count); +extern void SPI_scroll_cursor_move(Portal, FetchDirection direction, long count); +extern void SPI_cursor_close(Portal portal); + +extern int SPI_register_relation(EphemeralNamedRelation enr); +extern int SPI_unregister_relation(const char *name); +extern int SPI_register_trigger_data(TriggerData *tdata); + +extern void SPI_start_transaction(void); +extern void SPI_commit(void); +extern void SPI_commit_and_chain(void); +extern void SPI_rollback(void); +extern void SPI_rollback_and_chain(void); + +extern void AtEOXact_SPI(bool isCommit); +extern void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid); +extern bool SPI_inside_nonatomic_context(void); + +#endif /* SPI_H */ diff --git a/install/include/postgresql/server/executor/spi_priv.h b/install/include/postgresql/server/executor/spi_priv.h new file mode 100644 index 00000000000..92d1bcef782 --- /dev/null +++ b/install/include/postgresql/server/executor/spi_priv.h @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------- + * + * spi_priv.h + * Server Programming Interface private declarations + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/spi_priv.h + * + *------------------------------------------------------------------------- + */ +#ifndef SPI_PRIV_H +#define SPI_PRIV_H + +#include "executor/spi.h" +#include "utils/queryenvironment.h" + + +#define _SPI_PLAN_MAGIC 569278163 + +typedef struct +{ + /* current results */ + uint64 processed; /* by Executor */ + SPITupleTable *tuptable; /* tuptable currently being built */ + + /* subtransaction in which current Executor call was started */ + SubTransactionId execSubid; + + /* resources of this execution context */ + slist_head tuptables; /* list of all live SPITupleTables */ + MemoryContext procCxt; /* procedure context */ + MemoryContext execCxt; /* executor context */ + MemoryContext savedcxt; /* context of SPI_connect's caller */ + SubTransactionId connectSubid; /* ID of connecting subtransaction */ + QueryEnvironment *queryEnv; /* query environment setup for SPI level */ + + /* transaction management support */ + bool atomic; /* atomic execution context, does not allow + * transactions */ + bool internal_xact; /* SPI-managed transaction boundary, skip + * cleanup */ + + /* saved values of API global variables for previous nesting level */ + uint64 outer_processed; + SPITupleTable *outer_tuptable; + int outer_result; +} _SPI_connection; + +/* + * SPI plans have three states: saved, unsaved, or temporary. + * + * Ordinarily, the _SPI_plan struct itself as well as the argtypes array + * are in a dedicated memory context identified by plancxt (which can be + * really small). All the other subsidiary state is in plancache entries + * identified by plancache_list (note: the list cells themselves are in + * plancxt). + * + * In an unsaved plan, the plancxt as well as the plancache entries' contexts + * are children of the SPI procedure context, so they'll all disappear at + * function exit. plancache.c also knows that the plancache entries are + * "unsaved", so it doesn't link them into its global list; hence they do + * not respond to inval events. This is OK since we are presumably holding + * adequate locks to prevent other backends from messing with the tables. + * + * For a saved plan, the plancxt is made a child of CacheMemoryContext + * since it should persist until explicitly destroyed. Likewise, the + * plancache entries will be under CacheMemoryContext since we tell + * plancache.c to save them. We rely on plancache.c to keep the cache + * entries up-to-date as needed in the face of invalidation events. + * + * There are also "temporary" SPI plans, in which the _SPI_plan struct is + * not even palloc'd but just exists in some function's local variable. + * The plancache entries are unsaved and exist under the SPI executor context, + * while additional data such as argtypes and list cells is loose in the SPI + * executor context. Such plans can be identified by having plancxt == NULL. + * + * We can also have "one-shot" SPI plans (which are typically temporary, + * as described above). These are meant to be executed once and discarded, + * and various optimizations are made on the assumption of single use. + * Note in particular that the CachedPlanSources within such an SPI plan + * are not "complete" until execution. + * + * Note: if the original query string contained only whitespace and comments, + * the plancache_list will be NIL and so there is no place to store the + * query string. We don't care about that, but we do care about the + * argument type array, which is why it's seemingly-redundantly stored. + */ +typedef struct _SPI_plan +{ + int magic; /* should equal _SPI_PLAN_MAGIC */ + bool saved; /* saved or unsaved plan? */ + bool oneshot; /* one-shot plan? */ + List *plancache_list; /* one CachedPlanSource per parsetree */ + MemoryContext plancxt; /* Context containing _SPI_plan and data */ + RawParseMode parse_mode; /* raw_parser() mode */ + int cursor_options; /* Cursor options used for planning */ + int nargs; /* number of plan arguments */ + Oid *argtypes; /* Argument types (NULL if nargs is 0) */ + ParserSetupHook parserSetup; /* alternative parameter spec method */ + void *parserSetupArg; +} _SPI_plan; + +#endif /* SPI_PRIV_H */ diff --git a/install/include/postgresql/server/executor/tablefunc.h b/install/include/postgresql/server/executor/tablefunc.h new file mode 100644 index 00000000000..ca235ae1fb9 --- /dev/null +++ b/install/include/postgresql/server/executor/tablefunc.h @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------- + * + * tablefunc.h + * interface for TableFunc executor node + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/tablefunc.h + * + *------------------------------------------------------------------------- + */ +#ifndef _TABLEFUNC_H +#define _TABLEFUNC_H + +/* Forward-declare this to avoid including execnodes.h here */ +struct TableFuncScanState; + +/* + * TableFuncRoutine holds function pointers used for generating content of + * table-producer functions, such as XMLTABLE. + * + * InitOpaque initializes table builder private objects. The output tuple + * descriptor, input functions for the columns, and typioparams are passed + * from executor state. + * + * SetDocument is called to define the input document. The table builder may + * apply additional transformations not exposed outside the table builder + * context. + * + * SetNamespace is called to pass namespace declarations from the table + * expression. This function may be NULL if namespaces are not supported by + * the table builder. Namespaces must be given before setting the row and + * column filters. If the name is given as NULL, the entry shall be for the + * default namespace. + * + * SetRowFilter is called do define the row-generating filter, which shall be + * used to extract each row from the input document. + * + * SetColumnFilter is called once for each column, to define the column- + * generating filter for the given column. + * + * FetchRow shall be called repeatedly until it returns that no more rows are + * found in the document. On each invocation it shall set state in the table + * builder context such that each subsequent GetValue call returns the values + * for the indicated column for the row being processed. + * + * DestroyOpaque shall release all resources associated with a table builder + * context. It may be called either because all rows have been consumed, or + * because an error occurred while processing the table expression. + */ +typedef struct TableFuncRoutine +{ + void (*InitOpaque) (struct TableFuncScanState *state, int natts); + void (*SetDocument) (struct TableFuncScanState *state, Datum value); + void (*SetNamespace) (struct TableFuncScanState *state, const char *name, + const char *uri); + void (*SetRowFilter) (struct TableFuncScanState *state, const char *path); + void (*SetColumnFilter) (struct TableFuncScanState *state, + const char *path, int colnum); + bool (*FetchRow) (struct TableFuncScanState *state); + Datum (*GetValue) (struct TableFuncScanState *state, int colnum, + Oid typid, int32 typmod, bool *isnull); + void (*DestroyOpaque) (struct TableFuncScanState *state); +} TableFuncRoutine; + +#endif /* _TABLEFUNC_H */ diff --git a/install/include/postgresql/server/executor/tqueue.h b/install/include/postgresql/server/executor/tqueue.h new file mode 100644 index 00000000000..440178bc7c2 --- /dev/null +++ b/install/include/postgresql/server/executor/tqueue.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * tqueue.h + * Use shm_mq to send & receive tuples between parallel backends + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/tqueue.h + * + *------------------------------------------------------------------------- + */ + +#ifndef TQUEUE_H +#define TQUEUE_H + +#include "storage/shm_mq.h" +#include "tcop/dest.h" + +/* Opaque struct, only known inside tqueue.c. */ +typedef struct TupleQueueReader TupleQueueReader; + +/* Use this to send tuples to a shm_mq. */ +extern DestReceiver *CreateTupleQueueDestReceiver(shm_mq_handle *handle); + +/* Use these to receive tuples from a shm_mq. */ +extern TupleQueueReader *CreateTupleQueueReader(shm_mq_handle *handle); +extern void DestroyTupleQueueReader(TupleQueueReader *reader); +extern MinimalTuple TupleQueueReaderNext(TupleQueueReader *reader, + bool nowait, bool *done); + +#endif /* TQUEUE_H */ diff --git a/install/include/postgresql/server/executor/tstoreReceiver.h b/install/include/postgresql/server/executor/tstoreReceiver.h new file mode 100644 index 00000000000..bbdc9ee7950 --- /dev/null +++ b/install/include/postgresql/server/executor/tstoreReceiver.h @@ -0,0 +1,31 @@ +/*------------------------------------------------------------------------- + * + * tstoreReceiver.h + * prototypes for tstoreReceiver.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/tstoreReceiver.h + * + *------------------------------------------------------------------------- + */ + +#ifndef TSTORE_RECEIVER_H +#define TSTORE_RECEIVER_H + +#include "tcop/dest.h" +#include "utils/tuplestore.h" + + +extern DestReceiver *CreateTuplestoreDestReceiver(void); + +extern void SetTuplestoreDestReceiverParams(DestReceiver *self, + Tuplestorestate *tStore, + MemoryContext tContext, + bool detoast, + TupleDesc target_tupdesc, + const char *map_failure_msg); + +#endif /* TSTORE_RECEIVER_H */ diff --git a/install/include/postgresql/server/executor/tuptable.h b/install/include/postgresql/server/executor/tuptable.h new file mode 100644 index 00000000000..4210d6d838f --- /dev/null +++ b/install/include/postgresql/server/executor/tuptable.h @@ -0,0 +1,494 @@ +/*------------------------------------------------------------------------- + * + * tuptable.h + * tuple table support stuff + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/executor/tuptable.h + * + *------------------------------------------------------------------------- + */ +#ifndef TUPTABLE_H +#define TUPTABLE_H + +#include "access/htup.h" +#include "access/htup_details.h" +#include "access/sysattr.h" +#include "access/tupdesc.h" +#include "storage/buf.h" + +/*---------- + * The executor stores tuples in a "tuple table" which is a List of + * independent TupleTableSlots. + * + * There's various different types of tuple table slots, each being able to + * store different types of tuples. Additional types of slots can be added + * without modifying core code. The type of a slot is determined by the + * TupleTableSlotOps* passed to the slot creation routine. The builtin types + * of slots are + * + * 1. physical tuple in a disk buffer page (TTSOpsBufferHeapTuple) + * 2. physical tuple constructed in palloc'ed memory (TTSOpsHeapTuple) + * 3. "minimal" physical tuple constructed in palloc'ed memory + * (TTSOpsMinimalTuple) + * 4. "virtual" tuple consisting of Datum/isnull arrays (TTSOpsVirtual) + * + * + * The first two cases are similar in that they both deal with "materialized" + * tuples, but resource management is different. For a tuple in a disk page + * we need to hold a pin on the buffer until the TupleTableSlot's reference + * to the tuple is dropped; while for a palloc'd tuple we usually want the + * tuple pfree'd when the TupleTableSlot's reference is dropped. + * + * A "minimal" tuple is handled similarly to a palloc'd regular tuple. + * At present, minimal tuples never are stored in buffers, so there is no + * parallel to case 1. Note that a minimal tuple has no "system columns". + * + * A "virtual" tuple is an optimization used to minimize physical data copying + * in a nest of plan nodes. Until materialized pass-by-reference Datums in + * the slot point to storage that is not directly associated with the + * TupleTableSlot; generally they will point to part of a tuple stored in a + * lower plan node's output TupleTableSlot, or to a function result + * constructed in a plan node's per-tuple econtext. It is the responsibility + * of the generating plan node to be sure these resources are not released for + * as long as the virtual tuple needs to be valid or is materialized. Note + * also that a virtual tuple does not have any "system columns". + * + * The Datum/isnull arrays of a TupleTableSlot serve double duty. For virtual + * slots they are the authoritative data. For the other builtin slots, + * the arrays contain data extracted from the tuple. (In this state, any + * pass-by-reference Datums point into the physical tuple.) The extracted + * information is built "lazily", ie, only as needed. This serves to avoid + * repeated extraction of data from the physical tuple. + * + * A TupleTableSlot can also be "empty", indicated by flag TTS_FLAG_EMPTY set + * in tts_flags, holding no valid data. This is the only valid state for a + * freshly-created slot that has not yet had a tuple descriptor assigned to + * it. In this state, TTS_FLAG_SHOULDFREE should not be set in tts_flags and + * tts_nvalid should be set to zero. + * + * The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot + * code. The caller of ExecSetSlotDescriptor() is responsible for providing + * a descriptor that will live as long as the slot does. (Typically, both + * slots and descriptors are in per-query memory and are freed by memory + * context deallocation at query end; so it's not worth providing any extra + * mechanism to do more. However, the slot will increment the tupdesc + * reference count if a reference-counted tupdesc is supplied.) + * + * When TTS_FLAG_SHOULDFREE is set in tts_flags, the physical tuple is "owned" + * by the slot and should be freed when the slot's reference to the tuple is + * dropped. + * + * tts_values/tts_isnull are allocated either when the slot is created (when + * the descriptor is provided), or when a descriptor is assigned to the slot; + * they are of length equal to the descriptor's natts. + * + * The TTS_FLAG_SLOW flag is saved state for + * slot_deform_heap_tuple, and should not be touched by any other code. + *---------- + */ + +/* true = slot is empty */ +#define TTS_FLAG_EMPTY (1 << 1) +#define TTS_EMPTY(slot) (((slot)->tts_flags & TTS_FLAG_EMPTY) != 0) + +/* should pfree tuple "owned" by the slot? */ +#define TTS_FLAG_SHOULDFREE (1 << 2) +#define TTS_SHOULDFREE(slot) (((slot)->tts_flags & TTS_FLAG_SHOULDFREE) != 0) + +/* saved state for slot_deform_heap_tuple */ +#define TTS_FLAG_SLOW (1 << 3) +#define TTS_SLOW(slot) (((slot)->tts_flags & TTS_FLAG_SLOW) != 0) + +/* fixed tuple descriptor */ +#define TTS_FLAG_FIXED (1 << 4) +#define TTS_FIXED(slot) (((slot)->tts_flags & TTS_FLAG_FIXED) != 0) + +struct TupleTableSlotOps; +typedef struct TupleTableSlotOps TupleTableSlotOps; + +/* base tuple table slot type */ +typedef struct TupleTableSlot +{ + NodeTag type; +#define FIELDNO_TUPLETABLESLOT_FLAGS 1 + uint16 tts_flags; /* Boolean states */ +#define FIELDNO_TUPLETABLESLOT_NVALID 2 + AttrNumber tts_nvalid; /* # of valid values in tts_values */ + const TupleTableSlotOps *const tts_ops; /* implementation of slot */ +#define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 4 + TupleDesc tts_tupleDescriptor; /* slot's tuple descriptor */ +#define FIELDNO_TUPLETABLESLOT_VALUES 5 + Datum *tts_values; /* current per-attribute values */ +#define FIELDNO_TUPLETABLESLOT_ISNULL 6 + bool *tts_isnull; /* current per-attribute isnull flags */ + MemoryContext tts_mcxt; /* slot itself is in this context */ + ItemPointerData tts_tid; /* stored tuple's tid */ + Oid tts_tableOid; /* table oid of tuple */ +} TupleTableSlot; + +/* routines for a TupleTableSlot implementation */ +struct TupleTableSlotOps +{ + /* Minimum size of the slot */ + size_t base_slot_size; + + /* Initialization. */ + void (*init) (TupleTableSlot *slot); + + /* Destruction. */ + void (*release) (TupleTableSlot *slot); + + /* + * Clear the contents of the slot. Only the contents are expected to be + * cleared and not the tuple descriptor. Typically an implementation of + * this callback should free the memory allocated for the tuple contained + * in the slot. + */ + void (*clear) (TupleTableSlot *slot); + + /* + * Fill up first natts entries of tts_values and tts_isnull arrays with + * values from the tuple contained in the slot. The function may be called + * with natts more than the number of attributes available in the tuple, + * in which case it should set tts_nvalid to the number of returned + * columns. + */ + void (*getsomeattrs) (TupleTableSlot *slot, int natts); + + /* + * Returns value of the given system attribute as a datum and sets isnull + * to false, if it's not NULL. Throws an error if the slot type does not + * support system attributes. + */ + Datum (*getsysattr) (TupleTableSlot *slot, int attnum, bool *isnull); + + /* + * Make the contents of the slot solely depend on the slot, and not on + * underlying resources (like another memory context, buffers, etc). + */ + void (*materialize) (TupleTableSlot *slot); + + /* + * Copy the contents of the source slot into the destination slot's own + * context. Invoked using callback of the destination slot. + */ + void (*copyslot) (TupleTableSlot *dstslot, TupleTableSlot *srcslot); + + /* + * Return a heap tuple "owned" by the slot. It is slot's responsibility to + * free the memory consumed by the heap tuple. If the slot can not "own" a + * heap tuple, it should not implement this callback and should set it as + * NULL. + */ + HeapTuple (*get_heap_tuple) (TupleTableSlot *slot); + + /* + * Return a minimal tuple "owned" by the slot. It is slot's responsibility + * to free the memory consumed by the minimal tuple. If the slot can not + * "own" a minimal tuple, it should not implement this callback and should + * set it as NULL. + */ + MinimalTuple (*get_minimal_tuple) (TupleTableSlot *slot); + + /* + * Return a copy of heap tuple representing the contents of the slot. The + * copy needs to be palloc'd in the current memory context. The slot + * itself is expected to remain unaffected. It is *not* expected to have + * meaningful "system columns" in the copy. The copy is not be "owned" by + * the slot i.e. the caller has to take responsibility to free memory + * consumed by the slot. + */ + HeapTuple (*copy_heap_tuple) (TupleTableSlot *slot); + + /* + * Return a copy of minimal tuple representing the contents of the slot. + * The copy needs to be palloc'd in the current memory context. The slot + * itself is expected to remain unaffected. It is *not* expected to have + * meaningful "system columns" in the copy. The copy is not be "owned" by + * the slot i.e. the caller has to take responsibility to free memory + * consumed by the slot. + */ + MinimalTuple (*copy_minimal_tuple) (TupleTableSlot *slot); +}; + +/* + * Predefined TupleTableSlotOps for various types of TupleTableSlotOps. The + * same are used to identify the type of a given slot. + */ +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsVirtual; +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsHeapTuple; +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsMinimalTuple; +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsBufferHeapTuple; + +#define TTS_IS_VIRTUAL(slot) ((slot)->tts_ops == &TTSOpsVirtual) +#define TTS_IS_HEAPTUPLE(slot) ((slot)->tts_ops == &TTSOpsHeapTuple) +#define TTS_IS_MINIMALTUPLE(slot) ((slot)->tts_ops == &TTSOpsMinimalTuple) +#define TTS_IS_BUFFERTUPLE(slot) ((slot)->tts_ops == &TTSOpsBufferHeapTuple) + + +/* + * Tuple table slot implementations. + */ + +typedef struct VirtualTupleTableSlot +{ + pg_node_attr(abstract) + + TupleTableSlot base; + + char *data; /* data for materialized slots */ +} VirtualTupleTableSlot; + +typedef struct HeapTupleTableSlot +{ + pg_node_attr(abstract) + + TupleTableSlot base; + +#define FIELDNO_HEAPTUPLETABLESLOT_TUPLE 1 + HeapTuple tuple; /* physical tuple */ +#define FIELDNO_HEAPTUPLETABLESLOT_OFF 2 + uint32 off; /* saved state for slot_deform_heap_tuple */ + HeapTupleData tupdata; /* optional workspace for storing tuple */ +} HeapTupleTableSlot; + +/* heap tuple residing in a buffer */ +typedef struct BufferHeapTupleTableSlot +{ + pg_node_attr(abstract) + + HeapTupleTableSlot base; + + /* + * If buffer is not InvalidBuffer, then the slot is holding a pin on the + * indicated buffer page; drop the pin when we release the slot's + * reference to that buffer. (TTS_FLAG_SHOULDFREE should not be set in + * such a case, since presumably base.tuple is pointing into the buffer.) + */ + Buffer buffer; /* tuple's buffer, or InvalidBuffer */ +} BufferHeapTupleTableSlot; + +typedef struct MinimalTupleTableSlot +{ + pg_node_attr(abstract) + + TupleTableSlot base; + + /* + * In a minimal slot tuple points at minhdr and the fields of that struct + * are set correctly for access to the minimal tuple; in particular, + * minhdr.t_data points MINIMAL_TUPLE_OFFSET bytes before mintuple. This + * allows column extraction to treat the case identically to regular + * physical tuples. + */ +#define FIELDNO_MINIMALTUPLETABLESLOT_TUPLE 1 + HeapTuple tuple; /* tuple wrapper */ + MinimalTuple mintuple; /* minimal tuple, or NULL if none */ + HeapTupleData minhdr; /* workspace for minimal-tuple-only case */ +#define FIELDNO_MINIMALTUPLETABLESLOT_OFF 4 + uint32 off; /* saved state for slot_deform_heap_tuple */ +} MinimalTupleTableSlot; + +/* + * TupIsNull -- is a TupleTableSlot empty? + */ +#define TupIsNull(slot) \ + ((slot) == NULL || TTS_EMPTY(slot)) + +/* in executor/execTuples.c */ +extern TupleTableSlot *MakeTupleTableSlot(TupleDesc tupleDesc, + const TupleTableSlotOps *tts_ops); +extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc, + const TupleTableSlotOps *tts_ops); +extern void ExecResetTupleTable(List *tupleTable, bool shouldFree); +extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc, + const TupleTableSlotOps *tts_ops); +extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot); +extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc); +extern TupleTableSlot *ExecStoreHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + bool shouldFree); +extern void ExecForceStoreHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + bool shouldFree); +extern TupleTableSlot *ExecStoreBufferHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + Buffer buffer); +extern TupleTableSlot *ExecStorePinnedBufferHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + Buffer buffer); +extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup, + TupleTableSlot *slot, + bool shouldFree); +extern void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, + bool shouldFree); +extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot); +extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot); +extern void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot); +extern HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree); +extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot, + bool *shouldFree); +extern Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot); +extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, + int lastAttNum); +extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum); + + +#ifndef FRONTEND + +/* + * This function forces the entries of the slot's Datum/isnull arrays to be + * valid at least up through the attnum'th entry. + */ +static inline void +slot_getsomeattrs(TupleTableSlot *slot, int attnum) +{ + if (slot->tts_nvalid < attnum) + slot_getsomeattrs_int(slot, attnum); +} + +/* + * slot_getallattrs + * This function forces all the entries of the slot's Datum/isnull + * arrays to be valid. The caller may then extract data directly + * from those arrays instead of using slot_getattr. + */ +static inline void +slot_getallattrs(TupleTableSlot *slot) +{ + slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts); +} + + +/* + * slot_attisnull + * + * Detect whether an attribute of the slot is null, without actually fetching + * it. + */ +static inline bool +slot_attisnull(TupleTableSlot *slot, int attnum) +{ + Assert(attnum > 0); + + if (attnum > slot->tts_nvalid) + slot_getsomeattrs(slot, attnum); + + return slot->tts_isnull[attnum - 1]; +} + +/* + * slot_getattr - fetch one attribute of the slot's contents. + */ +static inline Datum +slot_getattr(TupleTableSlot *slot, int attnum, + bool *isnull) +{ + Assert(attnum > 0); + + if (attnum > slot->tts_nvalid) + slot_getsomeattrs(slot, attnum); + + *isnull = slot->tts_isnull[attnum - 1]; + + return slot->tts_values[attnum - 1]; +} + +/* + * slot_getsysattr - fetch a system attribute of the slot's current tuple. + * + * If the slot type does not contain system attributes, this will throw an + * error. Hence before calling this function, callers should make sure that + * the slot type is the one that supports system attributes. + */ +static inline Datum +slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) +{ + Assert(attnum < 0); /* caller error */ + + if (attnum == TableOidAttributeNumber) + { + *isnull = false; + return ObjectIdGetDatum(slot->tts_tableOid); + } + else if (attnum == SelfItemPointerAttributeNumber) + { + *isnull = false; + return PointerGetDatum(&slot->tts_tid); + } + + /* Fetch the system attribute from the underlying tuple. */ + return slot->tts_ops->getsysattr(slot, attnum, isnull); +} + +/* + * ExecClearTuple - clear the slot's contents + */ +static inline TupleTableSlot * +ExecClearTuple(TupleTableSlot *slot) +{ + slot->tts_ops->clear(slot); + + return slot; +} + +/* ExecMaterializeSlot - force a slot into the "materialized" state. + * + * This causes the slot's tuple to be a local copy not dependent on any + * external storage (i.e. pointing into a Buffer, or having allocations in + * another memory context). + * + * A typical use for this operation is to prepare a computed tuple for being + * stored on disk. The original data may or may not be virtual, but in any + * case we need a private copy for heap_insert to scribble on. + */ +static inline void +ExecMaterializeSlot(TupleTableSlot *slot) +{ + slot->tts_ops->materialize(slot); +} + +/* + * ExecCopySlotHeapTuple - return HeapTuple allocated in caller's context + */ +static inline HeapTuple +ExecCopySlotHeapTuple(TupleTableSlot *slot) +{ + Assert(!TTS_EMPTY(slot)); + + return slot->tts_ops->copy_heap_tuple(slot); +} + +/* + * ExecCopySlotMinimalTuple - return MinimalTuple allocated in caller's context + */ +static inline MinimalTuple +ExecCopySlotMinimalTuple(TupleTableSlot *slot) +{ + return slot->tts_ops->copy_minimal_tuple(slot); +} + +/* + * ExecCopySlot - copy one slot's contents into another. + * + * If a source's system attributes are supposed to be accessed in the target + * slot, the target slot and source slot types need to match. + */ +static inline TupleTableSlot * +ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) +{ + Assert(!TTS_EMPTY(srcslot)); + Assert(srcslot != dstslot); + + dstslot->tts_ops->copyslot(dstslot, srcslot); + + return dstslot; +} + +#endif /* FRONTEND */ + +#endif /* TUPTABLE_H */ diff --git a/install/include/postgresql/server/fe_utils/archive.h b/install/include/postgresql/server/fe_utils/archive.h new file mode 100644 index 00000000000..8f05ccc0608 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/archive.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * archive.h + * Routines to access WAL archives from frontend + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/archive.h + * + *------------------------------------------------------------------------- + */ +#ifndef FE_ARCHIVE_H +#define FE_ARCHIVE_H + +extern int RestoreArchivedFile(const char *path, + const char *xlogfname, + off_t expectedSize, + const char *restoreCommand); + +#endif /* FE_ARCHIVE_H */ diff --git a/install/include/postgresql/server/fe_utils/cancel.h b/install/include/postgresql/server/fe_utils/cancel.h new file mode 100644 index 00000000000..6e8b9ddfc43 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/cancel.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * Query cancellation support for frontend code + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/cancel.h + * + *------------------------------------------------------------------------- + */ + +#ifndef CANCEL_H +#define CANCEL_H + +#include + +#include "libpq-fe.h" + +extern PGDLLIMPORT volatile sig_atomic_t CancelRequested; + +extern void SetCancelConn(PGconn *conn); +extern void ResetCancelConn(void); + +/* + * A callback can be optionally set up to be called at cancellation + * time. + */ +extern void setup_cancel_handler(void (*query_cancel_callback) (void)); + +#endif /* CANCEL_H */ diff --git a/install/include/postgresql/server/fe_utils/conditional.h b/install/include/postgresql/server/fe_utils/conditional.h new file mode 100644 index 00000000000..36e72c977ce --- /dev/null +++ b/install/include/postgresql/server/fe_utils/conditional.h @@ -0,0 +1,102 @@ +/*------------------------------------------------------------------------- + * A stack of automaton states to handle nested conditionals. + * + * This file describes a stack of automaton states which + * allow a manage nested conditionals. + * + * It is used by: + * - "psql" interpreter for handling \if ... \endif + * - "pgbench" interpreter for handling \if ... \endif + * - "pgbench" syntax checker to test for proper nesting + * + * The stack holds the state of enclosing conditionals (are we in + * a true branch? in a false branch? have we already encountered + * a true branch?) so that the interpreter knows whether to execute + * code and whether to evaluate conditions. + * + * Copyright (c) 2000-2023, PostgreSQL Global Development Group + * + * src/include/fe_utils/conditional.h + * + *------------------------------------------------------------------------- + */ +#ifndef CONDITIONAL_H +#define CONDITIONAL_H + +/* + * Possible states of a single level of \if block. + */ +typedef enum ifState +{ + IFSTATE_NONE = 0, /* not currently in an \if block */ + IFSTATE_TRUE, /* currently in an \if or \elif that is true + * and all parent branches (if any) are true */ + IFSTATE_FALSE, /* currently in an \if or \elif that is false + * but no true branch has yet been seen, and + * all parent branches (if any) are true */ + IFSTATE_IGNORED, /* currently in an \elif that follows a true + * branch, or the whole \if is a child of a + * false parent branch */ + IFSTATE_ELSE_TRUE, /* currently in an \else that is true and all + * parent branches (if any) are true */ + IFSTATE_ELSE_FALSE /* currently in an \else that is false or + * ignored */ +} ifState; + +/* + * The state of nested \ifs is stored in a stack. + * + * query_len is used to determine what accumulated text to throw away at the + * end of an inactive branch. (We could, perhaps, teach the lexer to not add + * stuff to the query buffer in the first place when inside an inactive branch; + * but that would be very invasive.) We also need to save and restore the + * lexer's parenthesis nesting depth when throwing away text. (We don't need + * to save and restore any of its other state, such as comment nesting depth, + * because a backslash command could never appear inside a comment or SQL + * literal.) + */ +typedef struct IfStackElem +{ + ifState if_state; /* current state, see enum above */ + int query_len; /* length of query_buf at last branch start */ + int paren_depth; /* parenthesis depth at last branch start */ + struct IfStackElem *next; /* next surrounding \if, if any */ +} IfStackElem; + +typedef struct ConditionalStackData +{ + IfStackElem *head; +} ConditionalStackData; + +typedef struct ConditionalStackData *ConditionalStack; + + +extern ConditionalStack conditional_stack_create(void); + +extern void conditional_stack_reset(ConditionalStack cstack); + +extern void conditional_stack_destroy(ConditionalStack cstack); + +extern int conditional_stack_depth(ConditionalStack cstack); + +extern void conditional_stack_push(ConditionalStack cstack, ifState new_state); + +extern bool conditional_stack_pop(ConditionalStack cstack); + +extern ifState conditional_stack_peek(ConditionalStack cstack); + +extern bool conditional_stack_poke(ConditionalStack cstack, ifState new_state); + +extern bool conditional_stack_empty(ConditionalStack cstack); + +extern bool conditional_active(ConditionalStack cstack); + +extern void conditional_stack_set_query_len(ConditionalStack cstack, int len); + +extern int conditional_stack_get_query_len(ConditionalStack cstack); + +extern void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth); + +extern int conditional_stack_get_paren_depth(ConditionalStack cstack); + +#endif /* CONDITIONAL_H */ diff --git a/install/include/postgresql/server/fe_utils/connect_utils.h b/install/include/postgresql/server/fe_utils/connect_utils.h new file mode 100644 index 00000000000..ddcd8b32c16 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/connect_utils.h @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------- + * + * Facilities for frontend code to connect to and disconnect from databases. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/connect_utils.h + * + *------------------------------------------------------------------------- + */ +#ifndef CONNECT_UTILS_H +#define CONNECT_UTILS_H + +#include "libpq-fe.h" + +enum trivalue +{ + TRI_DEFAULT, + TRI_NO, + TRI_YES +}; + +/* Parameters needed by connectDatabase/connectMaintenanceDatabase */ +typedef struct _connParams +{ + /* These fields record the actual command line parameters */ + const char *dbname; /* this may be a connstring! */ + const char *pghost; + const char *pgport; + const char *pguser; + enum trivalue prompt_password; + /* If not NULL, this overrides the dbname obtained from command line */ + /* (but *only* the DB name, not anything else in the connstring) */ + const char *override_dbname; +} ConnParams; + +extern PGconn *connectDatabase(const ConnParams *cparams, + const char *progname, + bool echo, bool fail_ok, + bool allow_password_reuse); + +extern PGconn *connectMaintenanceDatabase(ConnParams *cparams, + const char *progname, bool echo); + +extern void disconnectDatabase(PGconn *conn); + +#endif /* CONNECT_UTILS_H */ diff --git a/install/include/postgresql/server/fe_utils/mbprint.h b/install/include/postgresql/server/fe_utils/mbprint.h new file mode 100644 index 00000000000..fd24c5e193d --- /dev/null +++ b/install/include/postgresql/server/fe_utils/mbprint.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * Multibyte character printing support for frontend code + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/mbprint.h + * + *------------------------------------------------------------------------- + */ +#ifndef MBPRINT_H +#define MBPRINT_H + +struct lineptr +{ + unsigned char *ptr; + int width; +}; + +extern unsigned char *mbvalidate(unsigned char *pwcs, int encoding); +extern int pg_wcswidth(const char *pwcs, size_t len, int encoding); +extern void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, + struct lineptr *lines, int count); +extern void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, + int *result_width, int *result_height, + int *result_format_size); + +#endif /* MBPRINT_H */ diff --git a/install/include/postgresql/server/fe_utils/option_utils.h b/install/include/postgresql/server/fe_utils/option_utils.h new file mode 100644 index 00000000000..b7b0654cee7 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/option_utils.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * Command line option processing facilities for frontend code + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/option_utils.h + * + *------------------------------------------------------------------------- + */ +#ifndef OPTION_UTILS_H +#define OPTION_UTILS_H + +#include "postgres_fe.h" + +typedef void (*help_handler) (const char *progname); + +extern void handle_help_version_opts(int argc, char *argv[], + const char *fixed_progname, + help_handler hlp); +extern bool option_parse_int(const char *optarg, const char *optname, + int min_range, int max_range, + int *result); + +#endif /* OPTION_UTILS_H */ diff --git a/install/include/postgresql/server/fe_utils/parallel_slot.h b/install/include/postgresql/server/fe_utils/parallel_slot.h new file mode 100644 index 00000000000..0eb8c149e96 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/parallel_slot.h @@ -0,0 +1,77 @@ +/*------------------------------------------------------------------------- + * + * parallel_slot.h + * Parallel support for bin/scripts/ + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/fe_utils/parallel_slot.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARALLEL_SLOT_H +#define PARALLEL_SLOT_H + +#include "fe_utils/connect_utils.h" +#include "libpq-fe.h" + +typedef bool (*ParallelSlotResultHandler) (PGresult *res, PGconn *conn, + void *context); + +typedef struct ParallelSlot +{ + PGconn *connection; /* One connection */ + bool inUse; /* Is the slot being used? */ + + /* + * Prior to issuing a command or query on 'connection', a handler callback + * function may optionally be registered to be invoked to process the + * results, and context information may optionally be registered for use + * by the handler. If unset, these fields should be NULL. + */ + ParallelSlotResultHandler handler; + void *handler_context; +} ParallelSlot; + +typedef struct ParallelSlotArray +{ + int numslots; + ConnParams *cparams; + const char *progname; + bool echo; + const char *initcmd; + ParallelSlot slots[FLEXIBLE_ARRAY_MEMBER]; +} ParallelSlotArray; + +static inline void +ParallelSlotSetHandler(ParallelSlot *slot, ParallelSlotResultHandler handler, + void *context) +{ + slot->handler = handler; + slot->handler_context = context; +} + +static inline void +ParallelSlotClearHandler(ParallelSlot *slot) +{ + slot->handler = NULL; + slot->handler_context = NULL; +} + +extern ParallelSlot *ParallelSlotsGetIdle(ParallelSlotArray *sa, + const char *dbname); + +extern ParallelSlotArray *ParallelSlotsSetup(int numslots, ConnParams *cparams, + const char *progname, bool echo, + const char *initcmd); + +extern void ParallelSlotsAdoptConn(ParallelSlotArray *sa, PGconn *conn); + +extern void ParallelSlotsTerminate(ParallelSlotArray *sa); + +extern bool ParallelSlotsWaitCompletion(ParallelSlotArray *sa); + +extern bool TableCommandResultHandler(PGresult *res, PGconn *conn, + void *context); + +#endif /* PARALLEL_SLOT_H */ diff --git a/install/include/postgresql/server/fe_utils/print.h b/install/include/postgresql/server/fe_utils/print.h new file mode 100644 index 00000000000..cc6652def9e --- /dev/null +++ b/install/include/postgresql/server/fe_utils/print.h @@ -0,0 +1,236 @@ +/*------------------------------------------------------------------------- + * + * Query-result printing support for frontend code + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/print.h + * + *------------------------------------------------------------------------- + */ +#ifndef PRINT_H +#define PRINT_H + +#include + +#include "libpq-fe.h" + + +/* This is not a particularly great place for this ... */ +#ifndef __CYGWIN__ +#define DEFAULT_PAGER "more" +#else +#define DEFAULT_PAGER "less" +#endif + +enum printFormat +{ + PRINT_NOTHING = 0, /* to make sure someone initializes this */ + PRINT_ALIGNED, + PRINT_ASCIIDOC, + PRINT_CSV, + PRINT_HTML, + PRINT_LATEX, + PRINT_LATEX_LONGTABLE, + PRINT_TROFF_MS, + PRINT_UNALIGNED, + PRINT_WRAPPED + /* add your favourite output format here ... */ +}; + +typedef struct printTextLineFormat +{ + /* Line drawing characters to be used in various contexts */ + const char *hrule; /* horizontal line character */ + const char *leftvrule; /* left vertical line (+horizontal) */ + const char *midvrule; /* intra-column vertical line (+horizontal) */ + const char *rightvrule; /* right vertical line (+horizontal) */ +} printTextLineFormat; + +typedef enum printTextRule +{ + /* Additional context for selecting line drawing characters */ + PRINT_RULE_TOP, /* top horizontal line */ + PRINT_RULE_MIDDLE, /* intra-data horizontal line */ + PRINT_RULE_BOTTOM, /* bottom horizontal line */ + PRINT_RULE_DATA /* data line (hrule is unused here) */ +} printTextRule; + +typedef enum printTextLineWrap +{ + /* Line wrapping conditions */ + PRINT_LINE_WRAP_NONE, /* No wrapping */ + PRINT_LINE_WRAP_WRAP, /* Wraparound due to overlength line */ + PRINT_LINE_WRAP_NEWLINE /* Newline in data */ +} printTextLineWrap; + +typedef enum printXheaderWidthType +{ + /* Expanded header line width variants */ + PRINT_XHEADER_FULL, /* do not truncate header line (this is the + * default) */ + PRINT_XHEADER_COLUMN, /* only print header line above the first + * column */ + PRINT_XHEADER_PAGE, /* header line must not be longer than + * terminal width */ + PRINT_XHEADER_EXACT_WIDTH, /* explicitly specified width */ +} printXheaderWidthType; + +typedef struct printTextFormat +{ + /* A complete line style */ + const char *name; /* for display purposes */ + printTextLineFormat lrule[4]; /* indexed by enum printTextRule */ + const char *midvrule_nl; /* vertical line for continue after newline */ + const char *midvrule_wrap; /* vertical line for wrapped data */ + const char *midvrule_blank; /* vertical line for blank data */ + const char *header_nl_left; /* left mark after newline */ + const char *header_nl_right; /* right mark for newline */ + const char *nl_left; /* left mark after newline */ + const char *nl_right; /* right mark for newline */ + const char *wrap_left; /* left mark after wrapped data */ + const char *wrap_right; /* right mark for wrapped data */ + bool wrap_right_border; /* use right-hand border for wrap marks + * when border=0? */ +} printTextFormat; + +typedef enum unicode_linestyle +{ + UNICODE_LINESTYLE_SINGLE = 0, + UNICODE_LINESTYLE_DOUBLE +} unicode_linestyle; + +struct separator +{ + char *separator; + bool separator_zero; +}; + +typedef struct printTableOpt +{ + enum printFormat format; /* see enum above */ + unsigned short int expanded; /* expanded/vertical output (if supported + * by output format); 0=no, 1=yes, 2=auto */ + printXheaderWidthType expanded_header_width_type; /* width type for header + * line in expanded mode */ + int expanded_header_exact_width; /* explicit width for header + * line in expanded mode */ + unsigned short int border; /* Print a border around the table. 0=none, + * 1=dividing lines, 2=full */ + unsigned short int pager; /* use pager for output (if to stdout and + * stdout is a tty) 0=off 1=on 2=always */ + int pager_min_lines; /* don't use pager unless there are at + * least this many lines */ + bool tuples_only; /* don't output headers, row counts, etc. */ + bool start_table; /* print start decoration, eg */ + bool stop_table; /* print stop decoration, eg
*/ + bool default_footer; /* allow "(xx rows)" default footer */ + unsigned long prior_records; /* start offset for record counters */ + const printTextFormat *line_style; /* line style (NULL for default) */ + struct separator fieldSep; /* field separator for unaligned text mode */ + struct separator recordSep; /* record separator for unaligned text mode */ + char csvFieldSep[2]; /* field separator for csv format */ + bool numericLocale; /* locale-aware numeric units separator and + * decimal marker */ + char *tableAttr; /* attributes for HTML */ + int encoding; /* character encoding */ + int env_columns; /* $COLUMNS on psql start, 0 is unset */ + int columns; /* target width for wrapped format */ + unicode_linestyle unicode_border_linestyle; + unicode_linestyle unicode_column_linestyle; + unicode_linestyle unicode_header_linestyle; +} printTableOpt; + +/* + * Table footers are implemented as a singly-linked list. + * + * This is so that you don't need to know the number of footers in order to + * initialise the printTableContent struct, which is very convenient when + * preparing complex footers (as in describeOneTableDetails). + */ +typedef struct printTableFooter +{ + char *data; + struct printTableFooter *next; +} printTableFooter; + +/* + * The table content struct holds all the information which will be displayed + * by printTable(). + */ +typedef struct printTableContent +{ + const printTableOpt *opt; + const char *title; /* May be NULL */ + int ncolumns; /* Specified in Init() */ + int nrows; /* Specified in Init() */ + const char **headers; /* NULL-terminated array of header strings */ + const char **header; /* Pointer to the last added header */ + const char **cells; /* NULL-terminated array of cell content + * strings */ + const char **cell; /* Pointer to the last added cell */ + long cellsadded; /* Number of cells added this far */ + bool *cellmustfree; /* true for cells that need to be free()d */ + printTableFooter *footers; /* Pointer to the first footer */ + printTableFooter *footer; /* Pointer to the last added footer */ + char *aligns; /* Array of alignment specifiers; 'l' or 'r', + * one per column */ + char *align; /* Pointer to the last added alignment */ +} printTableContent; + +typedef struct printQueryOpt +{ + printTableOpt topt; /* the options above */ + char *nullPrint; /* how to print null entities */ + char *title; /* override title */ + char **footers; /* override footer (default is "(xx rows)") */ + bool translate_header; /* do gettext on column headers */ + const bool *translate_columns; /* translate_columns[i-1] => do gettext on + * col i */ + int n_translate_columns; /* length of translate_columns[] */ +} printQueryOpt; + + +extern PGDLLIMPORT volatile sig_atomic_t cancel_pressed; + +extern PGDLLIMPORT const printTextFormat pg_asciiformat; +extern PGDLLIMPORT const printTextFormat pg_asciiformat_old; +extern PGDLLIMPORT printTextFormat pg_utf8format; /* ideally would be const, + * but... */ + + +extern void disable_sigpipe_trap(void); +extern void restore_sigpipe_trap(void); +extern void set_sigpipe_trap_state(bool ignore); + +extern FILE *PageOutput(int lines, const printTableOpt *topt); +extern void ClosePager(FILE *pagerpipe); + +extern void html_escaped_print(const char *in, FILE *fout); + +extern void printTableInit(printTableContent *const content, + const printTableOpt *opt, const char *title, + const int ncolumns, const int nrows); +extern void printTableAddHeader(printTableContent *const content, + char *header, const bool translate, const char align); +extern void printTableAddCell(printTableContent *const content, + char *cell, const bool translate, const bool mustfree); +extern void printTableAddFooter(printTableContent *const content, + const char *footer); +extern void printTableSetFooter(printTableContent *const content, + const char *footer); +extern void printTableCleanup(printTableContent *const content); +extern void printTable(const printTableContent *cont, + FILE *fout, bool is_pager, FILE *flog); +extern void printQuery(const PGresult *result, const printQueryOpt *opt, + FILE *fout, bool is_pager, FILE *flog); + +extern char column_type_alignment(Oid); + +extern void setDecimalLocale(void); +extern const printTextFormat *get_line_style(const printTableOpt *opt); +extern void refresh_utf8format(const printTableOpt *opt); + +#endif /* PRINT_H */ diff --git a/install/include/postgresql/server/fe_utils/psqlscan.h b/install/include/postgresql/server/fe_utils/psqlscan.h new file mode 100644 index 00000000000..6a90fcab9eb --- /dev/null +++ b/install/include/postgresql/server/fe_utils/psqlscan.h @@ -0,0 +1,90 @@ +/*------------------------------------------------------------------------- + * + * psqlscan.h + * lexical scanner for SQL commands + * + * This lexer used to be part of psql, and that heritage is reflected in + * the file name as well as function and typedef names, though it can now + * be used by other frontend programs as well. It's also possible to extend + * this lexer with a compatible add-on lexer to handle program-specific + * backslash commands. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/psqlscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef PSQLSCAN_H +#define PSQLSCAN_H + +#include "pqexpbuffer.h" + + +/* Abstract type for lexer's internal state */ +typedef struct PsqlScanStateData *PsqlScanState; + +/* Termination states for psql_scan() */ +typedef enum +{ + PSCAN_SEMICOLON, /* found command-ending semicolon */ + PSCAN_BACKSLASH, /* found backslash command */ + PSCAN_INCOMPLETE, /* end of line, SQL statement incomplete */ + PSCAN_EOL /* end of line, SQL possibly complete */ +} PsqlScanResult; + +/* Prompt type returned by psql_scan() */ +typedef enum _promptStatus +{ + PROMPT_READY, + PROMPT_CONTINUE, + PROMPT_COMMENT, + PROMPT_SINGLEQUOTE, + PROMPT_DOUBLEQUOTE, + PROMPT_DOLLARQUOTE, + PROMPT_PAREN, + PROMPT_COPY +} promptStatus_t; + +/* Quoting request types for get_variable() callback */ +typedef enum +{ + PQUOTE_PLAIN, /* just return the actual value */ + PQUOTE_SQL_LITERAL, /* add quotes to make a valid SQL literal */ + PQUOTE_SQL_IDENT, /* quote if needed to make a SQL identifier */ + PQUOTE_SHELL_ARG /* quote if needed to be safe in a shell cmd */ +} PsqlScanQuoteType; + +/* Callback functions to be used by the lexer */ +typedef struct PsqlScanCallbacks +{ + /* Fetch value of a variable, as a free'able string; NULL if unknown */ + /* This pointer can be NULL if no variable substitution is wanted */ + char *(*get_variable) (const char *varname, PsqlScanQuoteType quote, + void *passthrough); +} PsqlScanCallbacks; + + +extern PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks); +extern void psql_scan_destroy(PsqlScanState state); + +extern void psql_scan_set_passthrough(PsqlScanState state, void *passthrough); + +extern void psql_scan_setup(PsqlScanState state, + const char *line, int line_len, + int encoding, bool std_strings); +extern void psql_scan_finish(PsqlScanState state); + +extern PsqlScanResult psql_scan(PsqlScanState state, + PQExpBuffer query_buf, + promptStatus_t *prompt); + +extern void psql_scan_reset(PsqlScanState state); + +extern void psql_scan_reselect_sql_lexer(PsqlScanState state); + +extern bool psql_scan_in_quote(PsqlScanState state); + +#endif /* PSQLSCAN_H */ diff --git a/install/include/postgresql/server/fe_utils/psqlscan_int.h b/install/include/postgresql/server/fe_utils/psqlscan_int.h new file mode 100644 index 00000000000..373e7e14763 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/psqlscan_int.h @@ -0,0 +1,157 @@ +/*------------------------------------------------------------------------- + * + * psqlscan_int.h + * lexical scanner internal declarations + * + * This file declares the PsqlScanStateData structure used by psqlscan.l + * and shared by other lexers compatible with it, such as psqlscanslash.l. + * + * One difficult aspect of this code is that we need to work in multibyte + * encodings that are not ASCII-safe. A "safe" encoding is one in which each + * byte of a multibyte character has the high bit set (it's >= 0x80). Since + * all our lexing rules treat all high-bit-set characters alike, we don't + * really need to care whether such a byte is part of a sequence or not. + * In an "unsafe" encoding, we still expect the first byte of a multibyte + * sequence to be >= 0x80, but later bytes might not be. If we scan such + * a sequence as-is, the lexing rules could easily be fooled into matching + * such bytes to ordinary ASCII characters. Our solution for this is to + * substitute 0xFF for each non-first byte within the data presented to flex. + * The flex rules will then pass the FF's through unmolested. The + * psqlscan_emit() subroutine is responsible for looking back to the original + * string and replacing FF's with the corresponding original bytes. + * + * Another interesting thing we do here is scan different parts of the same + * input with physically separate flex lexers (ie, lexers written in separate + * .l files). We can get away with this because the only part of the + * persistent state of a flex lexer that depends on its parsing rule tables + * is the start state number, which is easy enough to manage --- usually, + * in fact, we just need to set it to INITIAL when changing lexers. But to + * make that work at all, we must use re-entrant lexers, so that all the + * relevant state is in the yyscan_t attached to the PsqlScanState; + * if we were using lexers with separate static state we would soon end up + * with dangling buffer pointers in one or the other. Also note that this + * is unlikely to work very nicely if the lexers aren't all built with the + * same flex version, or if they don't use the same flex options. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/psqlscan_int.h + * + *------------------------------------------------------------------------- + */ +#ifndef PSQLSCAN_INT_H +#define PSQLSCAN_INT_H + +#include "fe_utils/psqlscan.h" + +/* + * These are just to allow this file to be compilable standalone for header + * validity checking; in actual use, this file should always be included + * from the body of a flex file, where these symbols are already defined. + */ +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void *yyscan_t; +#endif + +/* + * We use a stack of flex buffers to handle substitution of psql variables. + * Each stacked buffer contains the as-yet-unread text from one psql variable. + * When we pop the stack all the way, we resume reading from the outer buffer + * identified by scanbufhandle. + */ +typedef struct StackElem +{ + YY_BUFFER_STATE buf; /* flex input control structure */ + char *bufstring; /* data actually being scanned by flex */ + char *origstring; /* copy of original data, if needed */ + char *varname; /* name of variable providing data, or NULL */ + struct StackElem *next; +} StackElem; + +/* + * All working state of the lexer must be stored in PsqlScanStateData + * between calls. This allows us to have multiple open lexer operations, + * which is needed for nested include files. The lexer itself is not + * recursive, but it must be re-entrant. + */ +typedef struct PsqlScanStateData +{ + yyscan_t scanner; /* Flex's state for this PsqlScanState */ + + PQExpBuffer output_buf; /* current output buffer */ + + StackElem *buffer_stack; /* stack of variable expansion buffers */ + + /* + * These variables always refer to the outer buffer, never to any stacked + * variable-expansion buffer. + */ + YY_BUFFER_STATE scanbufhandle; + char *scanbuf; /* start of outer-level input buffer */ + const char *scanline; /* current input line at outer level */ + + /* safe_encoding, curline, refline are used by emit() to replace FFs */ + int encoding; /* encoding being used now */ + bool safe_encoding; /* is current encoding "safe"? */ + bool std_strings; /* are string literals standard? */ + const char *curline; /* actual flex input string for cur buf */ + const char *refline; /* original data for cur buffer */ + + /* + * All this state lives across successive input lines, until explicitly + * reset by psql_scan_reset. start_state is adopted by yylex() on entry, + * and updated with its finishing state on exit. + */ + int start_state; /* yylex's starting/finishing state */ + int state_before_str_stop; /* start cond. before end quote */ + int paren_depth; /* depth of nesting in parentheses */ + int xcdepth; /* depth of nesting in slash-star comments */ + char *dolqstart; /* current $foo$ quote start string */ + + /* + * State to track boundaries of BEGIN ... END blocks in function + * definitions, so that semicolons do not send query too early. + */ + int identifier_count; /* identifiers since start of statement */ + char identifiers[4]; /* records the first few identifiers */ + int begin_depth; /* depth of begin/end pairs */ + + /* + * Callback functions provided by the program making use of the lexer, + * plus a void* callback passthrough argument. + */ + const PsqlScanCallbacks *callbacks; + void *cb_passthrough; +} PsqlScanStateData; + + +/* + * Functions exported by psqlscan.l, but only meant for use within + * compatible lexers. + */ +extern void psqlscan_push_new_buffer(PsqlScanState state, + const char *newstr, const char *varname); +extern void psqlscan_pop_buffer_stack(PsqlScanState state); +extern void psqlscan_select_top_buffer(PsqlScanState state); +extern bool psqlscan_var_is_current_source(PsqlScanState state, + const char *varname); +extern YY_BUFFER_STATE psqlscan_prepare_buffer(PsqlScanState state, + const char *txt, int len, + char **txtcopy); +extern void psqlscan_emit(PsqlScanState state, const char *txt, int len); +extern char *psqlscan_extract_substring(PsqlScanState state, + const char *txt, int len); +extern void psqlscan_escape_variable(PsqlScanState state, + const char *txt, int len, + PsqlScanQuoteType quote); +extern void psqlscan_test_variable(PsqlScanState state, + const char *txt, int len); + +#endif /* PSQLSCAN_INT_H */ diff --git a/install/include/postgresql/server/fe_utils/query_utils.h b/install/include/postgresql/server/fe_utils/query_utils.h new file mode 100644 index 00000000000..e461df9e5c5 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/query_utils.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * Facilities for frontend code to query a databases. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/query_utils.h + * + *------------------------------------------------------------------------- + */ +#ifndef QUERY_UTILS_H +#define QUERY_UTILS_H + +#include "postgres_fe.h" + +#include "libpq-fe.h" + +extern PGresult *executeQuery(PGconn *conn, const char *query, bool echo); + +extern void executeCommand(PGconn *conn, const char *query, bool echo); + +extern bool executeMaintenanceCommand(PGconn *conn, const char *query, + bool echo); + +#endif /* QUERY_UTILS_H */ diff --git a/install/include/postgresql/server/fe_utils/recovery_gen.h b/install/include/postgresql/server/fe_utils/recovery_gen.h new file mode 100644 index 00000000000..8fe56756356 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/recovery_gen.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * Generator for recovery configuration + * + * Portions Copyright (c) 2011-2023, PostgreSQL Global Development Group + * + * src/include/fe_utils/recovery_gen.h + * + *------------------------------------------------------------------------- + */ +#ifndef RECOVERY_GEN_H +#define RECOVERY_GEN_H + +#include "libpq-fe.h" +#include "pqexpbuffer.h" + +/* + * recovery configuration is part of postgresql.conf in version 12 and up, and + * in recovery.conf before that. + */ +#define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000 + +extern PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, + char *replication_slot); +extern void WriteRecoveryConfig(PGconn *pgconn, char *target_dir, + PQExpBuffer contents); + +#endif /* RECOVERY_GEN_H */ diff --git a/install/include/postgresql/server/fe_utils/simple_list.h b/install/include/postgresql/server/fe_utils/simple_list.h new file mode 100644 index 00000000000..9f87138654b --- /dev/null +++ b/install/include/postgresql/server/fe_utils/simple_list.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------- + * + * Simple list facilities for frontend code + * + * Data structures for simple lists of OIDs, strings, and pointers. The + * support for these is very primitive compared to the backend's List + * facilities, but it's all we need in, eg, pg_dump. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/simple_list.h + * + *------------------------------------------------------------------------- + */ +#ifndef SIMPLE_LIST_H +#define SIMPLE_LIST_H + +typedef struct SimpleOidListCell +{ + struct SimpleOidListCell *next; + Oid val; +} SimpleOidListCell; + +typedef struct SimpleOidList +{ + SimpleOidListCell *head; + SimpleOidListCell *tail; +} SimpleOidList; + +typedef struct SimpleStringListCell +{ + struct SimpleStringListCell *next; + bool touched; /* true, when this string was searched and + * touched */ + char val[FLEXIBLE_ARRAY_MEMBER]; /* null-terminated string here */ +} SimpleStringListCell; + +typedef struct SimpleStringList +{ + SimpleStringListCell *head; + SimpleStringListCell *tail; +} SimpleStringList; + +typedef struct SimplePtrListCell +{ + struct SimplePtrListCell *next; + void *ptr; +} SimplePtrListCell; + +typedef struct SimplePtrList +{ + SimplePtrListCell *head; + SimplePtrListCell *tail; +} SimplePtrList; + +extern void simple_oid_list_append(SimpleOidList *list, Oid val); +extern bool simple_oid_list_member(SimpleOidList *list, Oid val); +extern void simple_oid_list_destroy(SimpleOidList *list); + +extern void simple_string_list_append(SimpleStringList *list, const char *val); +extern bool simple_string_list_member(SimpleStringList *list, const char *val); +extern void simple_string_list_destroy(SimpleStringList *list); + +extern const char *simple_string_list_not_touched(SimpleStringList *list); + +extern void simple_ptr_list_append(SimplePtrList *list, void *ptr); + +#endif /* SIMPLE_LIST_H */ diff --git a/install/include/postgresql/server/fe_utils/string_utils.h b/install/include/postgresql/server/fe_utils/string_utils.h new file mode 100644 index 00000000000..9980f193161 --- /dev/null +++ b/install/include/postgresql/server/fe_utils/string_utils.h @@ -0,0 +1,69 @@ +/*------------------------------------------------------------------------- + * + * String-processing utility routines for frontend code + * + * Utility functions that interpret backend output or quote strings for + * assorted contexts. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/string_utils.h + * + *------------------------------------------------------------------------- + */ +#ifndef STRING_UTILS_H +#define STRING_UTILS_H + +#include "libpq-fe.h" +#include "pqexpbuffer.h" + +/* Global variables controlling behavior of fmtId() and fmtQualifiedId() */ +extern PGDLLIMPORT int quote_all_identifiers; +extern PQExpBuffer (*getLocalPQExpBuffer) (void); + +/* Functions */ +extern const char *fmtId(const char *rawid); +extern const char *fmtIdEnc(const char *rawid, int encoding); +extern const char *fmtQualifiedId(const char *schema, const char *id); +extern const char *fmtQualifiedIdEnc(const char *schema, const char *id, int encoding); +extern void setFmtEncoding(int encoding); + +extern char *formatPGVersionNumber(int version_number, bool include_minor, + char *buf, size_t buflen); + +extern void appendStringLiteral(PQExpBuffer buf, const char *str, + int encoding, bool std_strings); +extern void appendStringLiteralConn(PQExpBuffer buf, const char *str, + PGconn *conn); +extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str, + const char *dqprefix); +extern void appendByteaLiteral(PQExpBuffer buf, + const unsigned char *str, size_t length, + bool std_strings); + +extern void appendShellString(PQExpBuffer buf, const char *str); +extern bool appendShellStringNoError(PQExpBuffer buf, const char *str); +extern void appendConnStrVal(PQExpBuffer buf, const char *str); +extern void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname); + +extern bool parsePGArray(const char *atext, char ***itemarray, int *nitems); +extern void appendPGArray(PQExpBuffer buffer, const char *value); + +extern bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, + const char *prefix, int encoding, bool std_strings); + +extern bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, + const char *pattern, + bool have_where, bool force_escape, + const char *schemavar, const char *namevar, + const char *altnamevar, const char *visibilityrule, + PQExpBuffer dbnamebuf, int *dotcnt); + +extern void patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, + PQExpBuffer schemabuf, PQExpBuffer namebuf, + const char *pattern, bool force_escape, + bool want_literal_dbname, int *dotcnt); + +#endif /* STRING_UTILS_H */ diff --git a/install/include/postgresql/server/fmgr.h b/install/include/postgresql/server/fmgr.h new file mode 100644 index 00000000000..b120f5e7fef --- /dev/null +++ b/install/include/postgresql/server/fmgr.h @@ -0,0 +1,800 @@ +/*------------------------------------------------------------------------- + * + * fmgr.h + * Definitions for the Postgres function manager and function-call + * interface. + * + * This file must be included by all Postgres modules that either define + * or call fmgr-callable functions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fmgr.h + * + *------------------------------------------------------------------------- + */ +#ifndef FMGR_H +#define FMGR_H + +/* We don't want to include primnodes.h here, so make some stub references */ +typedef struct Node *fmNodePtr; +typedef struct Aggref *fmAggrefPtr; + +/* Likewise, avoid including execnodes.h here */ +typedef void (*fmExprContextCallbackFunction) (Datum arg); + +/* Likewise, avoid including stringinfo.h here */ +typedef struct StringInfoData *fmStringInfo; + + +/* + * All functions that can be called directly by fmgr must have this signature. + * (Other functions can be called by using a handler that does have this + * signature.) + */ + +typedef struct FunctionCallInfoBaseData *FunctionCallInfo; + +typedef Datum (*PGFunction) (FunctionCallInfo fcinfo); + +/* + * This struct holds the system-catalog information that must be looked up + * before a function can be called through fmgr. If the same function is + * to be called multiple times, the lookup need be done only once and the + * info struct saved for re-use. + * + * Note that fn_expr really is parse-time-determined information about the + * arguments, rather than about the function itself. But it's convenient to + * store it here rather than in FunctionCallInfoBaseData, where it might more + * logically belong. + * + * fn_extra is available for use by the called function; all other fields + * should be treated as read-only after the struct is created. + */ +typedef struct FmgrInfo +{ + PGFunction fn_addr; /* pointer to function or handler to be called */ + Oid fn_oid; /* OID of function (NOT of handler, if any) */ + short fn_nargs; /* number of input args (0..FUNC_MAX_ARGS) */ + bool fn_strict; /* function is "strict" (NULL in => NULL out) */ + bool fn_retset; /* function returns a set */ + unsigned char fn_stats; /* collect stats if track_functions > this */ + void *fn_extra; /* extra space for use by handler */ + MemoryContext fn_mcxt; /* memory context to store fn_extra in */ + fmNodePtr fn_expr; /* expression parse tree for call, or NULL */ +} FmgrInfo; + +/* + * This struct is the data actually passed to an fmgr-called function. + * + * The called function is expected to set isnull, and possibly resultinfo or + * fields in whatever resultinfo points to. It should not change any other + * fields. (In particular, scribbling on the argument arrays is a bad idea, + * since some callers assume they can re-call with the same arguments.) + * + * Note that enough space for arguments needs to be provided, either by using + * SizeForFunctionCallInfo() in dynamic allocations, or by using + * LOCAL_FCINFO() for on-stack allocations. + * + * This struct is named *BaseData, rather than *Data, to break pre v12 code + * that allocated FunctionCallInfoData itself, as it'd often silently break + * old code due to no space for arguments being provided. + */ +typedef struct FunctionCallInfoBaseData +{ + FmgrInfo *flinfo; /* ptr to lookup info used for this call */ + fmNodePtr context; /* pass info about context of call */ + fmNodePtr resultinfo; /* pass or return extra info about result */ + Oid fncollation; /* collation for function to use */ +#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4 + bool isnull; /* function must set true if result is NULL */ + short nargs; /* # arguments actually passed */ +#define FIELDNO_FUNCTIONCALLINFODATA_ARGS 6 + NullableDatum args[FLEXIBLE_ARRAY_MEMBER]; +} FunctionCallInfoBaseData; + +/* + * Space needed for a FunctionCallInfoBaseData struct with sufficient space + * for `nargs` arguments. + */ +#define SizeForFunctionCallInfo(nargs) \ + (offsetof(FunctionCallInfoBaseData, args) + \ + sizeof(NullableDatum) * (nargs)) + +/* + * This macro ensures that `name` points to a stack-allocated + * FunctionCallInfoBaseData struct with sufficient space for `nargs` arguments. + */ +#define LOCAL_FCINFO(name, nargs) \ + /* use union with FunctionCallInfoBaseData to guarantee alignment */ \ + union \ + { \ + FunctionCallInfoBaseData fcinfo; \ + /* ensure enough space for nargs args is available */ \ + char fcinfo_data[SizeForFunctionCallInfo(nargs)]; \ + } name##data; \ + FunctionCallInfo name = &name##data.fcinfo + +/* + * This routine fills a FmgrInfo struct, given the OID + * of the function to be called. + */ +extern void fmgr_info(Oid functionId, FmgrInfo *finfo); + +/* + * Same, when the FmgrInfo struct is in a memory context longer-lived than + * CurrentMemoryContext. The specified context will be set as fn_mcxt + * and used to hold all subsidiary data of finfo. + */ +extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, + MemoryContext mcxt); + +/* Convenience macro for setting the fn_expr field */ +#define fmgr_info_set_expr(expr, finfo) \ + ((finfo)->fn_expr = (expr)) + +/* + * Copy an FmgrInfo struct + */ +extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, + MemoryContext destcxt); + +extern void fmgr_symbol(Oid functionId, char **mod, char **fn); + +/* + * This macro initializes all the fields of a FunctionCallInfoBaseData except + * for the args[] array. + */ +#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo) \ + do { \ + (Fcinfo).flinfo = (Flinfo); \ + (Fcinfo).context = (Context); \ + (Fcinfo).resultinfo = (Resultinfo); \ + (Fcinfo).fncollation = (Collation); \ + (Fcinfo).isnull = false; \ + (Fcinfo).nargs = (Nargs); \ + } while (0) + +/* + * This macro invokes a function given a filled-in FunctionCallInfoBaseData + * struct. The macro result is the returned Datum --- but note that + * caller must still check fcinfo->isnull! Also, if function is strict, + * it is caller's responsibility to verify that no null arguments are present + * before calling. + * + * Some code performs multiple calls without redoing InitFunctionCallInfoData, + * possibly altering the argument values. This is okay, but be sure to reset + * the fcinfo->isnull flag before each call, since callees are permitted to + * assume that starts out false. + */ +#define FunctionCallInvoke(fcinfo) ((* (fcinfo)->flinfo->fn_addr) (fcinfo)) + + +/*------------------------------------------------------------------------- + * Support macros to ease writing fmgr-compatible functions + * + * A C-coded fmgr-compatible function should be declared as + * + * Datum + * function_name(PG_FUNCTION_ARGS) + * { + * ... + * } + * + * It should access its arguments using appropriate PG_GETARG_xxx macros + * and should return its result using PG_RETURN_xxx. + * + *------------------------------------------------------------------------- + */ + +/* Standard parameter list for fmgr-compatible functions */ +#define PG_FUNCTION_ARGS FunctionCallInfo fcinfo + +/* + * Get collation function should use. + */ +#define PG_GET_COLLATION() (fcinfo->fncollation) + +/* + * Get number of arguments passed to function. + */ +#define PG_NARGS() (fcinfo->nargs) + +/* + * If function is not marked "proisstrict" in pg_proc, it must check for + * null arguments using this macro. Do not try to GETARG a null argument! + */ +#define PG_ARGISNULL(n) (fcinfo->args[n].isnull) + +/* + * Support for fetching detoasted copies of toastable datatypes (all of + * which are varlena types). pg_detoast_datum() gives you either the input + * datum (if not toasted) or a detoasted copy allocated with palloc(). + * pg_detoast_datum_copy() always gives you a palloc'd copy --- use it + * if you need a modifiable copy of the input. Caller is expected to have + * checked for null inputs first, if necessary. + * + * pg_detoast_datum_packed() will return packed (1-byte header) datums + * unmodified. It will still expand an externally toasted or compressed datum. + * The resulting datum can be accessed using VARSIZE_ANY() and VARDATA_ANY() + * (beware of multiple evaluations in those macros!) + * + * In consumers oblivious to data alignment, call PG_DETOAST_DATUM_PACKED(), + * VARDATA_ANY(), VARSIZE_ANY() and VARSIZE_ANY_EXHDR(). Elsewhere, call + * PG_DETOAST_DATUM(), VARDATA() and VARSIZE(). Directly fetching an int16, + * int32 or wider field in the struct representing the datum layout requires + * aligned data. memcpy() is alignment-oblivious, as are most operations on + * datatypes, such as text, whose layout struct contains only char fields. + * + * Note: it'd be nice if these could be macros, but I see no way to do that + * without evaluating the arguments multiple times, which is NOT acceptable. + */ +extern struct varlena *pg_detoast_datum(struct varlena *datum); +extern struct varlena *pg_detoast_datum_copy(struct varlena *datum); +extern struct varlena *pg_detoast_datum_slice(struct varlena *datum, + int32 first, int32 count); +extern struct varlena *pg_detoast_datum_packed(struct varlena *datum); + +#define PG_DETOAST_DATUM(datum) \ + pg_detoast_datum((struct varlena *) DatumGetPointer(datum)) +#define PG_DETOAST_DATUM_COPY(datum) \ + pg_detoast_datum_copy((struct varlena *) DatumGetPointer(datum)) +#define PG_DETOAST_DATUM_SLICE(datum,f,c) \ + pg_detoast_datum_slice((struct varlena *) DatumGetPointer(datum), \ + (int32) (f), (int32) (c)) +/* WARNING -- unaligned pointer */ +#define PG_DETOAST_DATUM_PACKED(datum) \ + pg_detoast_datum_packed((struct varlena *) DatumGetPointer(datum)) + +/* + * Support for cleaning up detoasted copies of inputs. This must only + * be used for pass-by-ref datatypes, and normally would only be used + * for toastable types. If the given pointer is different from the + * original argument, assume it's a palloc'd detoasted copy, and pfree it. + * NOTE: most functions on toastable types do not have to worry about this, + * but we currently require that support functions for indexes not leak + * memory. + */ +#define PG_FREE_IF_COPY(ptr,n) \ + do { \ + if ((Pointer) (ptr) != PG_GETARG_POINTER(n)) \ + pfree(ptr); \ + } while (0) + +/* Macros for fetching arguments of standard types */ + +#define PG_GETARG_DATUM(n) (fcinfo->args[n].value) +#define PG_GETARG_INT32(n) DatumGetInt32(PG_GETARG_DATUM(n)) +#define PG_GETARG_UINT32(n) DatumGetUInt32(PG_GETARG_DATUM(n)) +#define PG_GETARG_INT16(n) DatumGetInt16(PG_GETARG_DATUM(n)) +#define PG_GETARG_UINT16(n) DatumGetUInt16(PG_GETARG_DATUM(n)) +#define PG_GETARG_CHAR(n) DatumGetChar(PG_GETARG_DATUM(n)) +#define PG_GETARG_BOOL(n) DatumGetBool(PG_GETARG_DATUM(n)) +#define PG_GETARG_OID(n) DatumGetObjectId(PG_GETARG_DATUM(n)) +#define PG_GETARG_POINTER(n) DatumGetPointer(PG_GETARG_DATUM(n)) +#define PG_GETARG_CSTRING(n) DatumGetCString(PG_GETARG_DATUM(n)) +#define PG_GETARG_NAME(n) DatumGetName(PG_GETARG_DATUM(n)) +#define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n)) +/* these macros hide the pass-by-reference-ness of the datatype: */ +#define PG_GETARG_FLOAT4(n) DatumGetFloat4(PG_GETARG_DATUM(n)) +#define PG_GETARG_FLOAT8(n) DatumGetFloat8(PG_GETARG_DATUM(n)) +#define PG_GETARG_INT64(n) DatumGetInt64(PG_GETARG_DATUM(n)) +/* use this if you want the raw, possibly-toasted input datum: */ +#define PG_GETARG_RAW_VARLENA_P(n) ((struct varlena *) PG_GETARG_POINTER(n)) +/* use this if you want the input datum de-toasted: */ +#define PG_GETARG_VARLENA_P(n) PG_DETOAST_DATUM(PG_GETARG_DATUM(n)) +/* and this if you can handle 1-byte-header datums: */ +#define PG_GETARG_VARLENA_PP(n) PG_DETOAST_DATUM_PACKED(PG_GETARG_DATUM(n)) +/* DatumGetFoo macros for varlena types will typically look like this: */ +#define DatumGetByteaPP(X) ((bytea *) PG_DETOAST_DATUM_PACKED(X)) +#define DatumGetTextPP(X) ((text *) PG_DETOAST_DATUM_PACKED(X)) +#define DatumGetBpCharPP(X) ((BpChar *) PG_DETOAST_DATUM_PACKED(X)) +#define DatumGetVarCharPP(X) ((VarChar *) PG_DETOAST_DATUM_PACKED(X)) +#define DatumGetHeapTupleHeader(X) ((HeapTupleHeader) PG_DETOAST_DATUM(X)) +/* And we also offer variants that return an OK-to-write copy */ +#define DatumGetByteaPCopy(X) ((bytea *) PG_DETOAST_DATUM_COPY(X)) +#define DatumGetTextPCopy(X) ((text *) PG_DETOAST_DATUM_COPY(X)) +#define DatumGetBpCharPCopy(X) ((BpChar *) PG_DETOAST_DATUM_COPY(X)) +#define DatumGetVarCharPCopy(X) ((VarChar *) PG_DETOAST_DATUM_COPY(X)) +#define DatumGetHeapTupleHeaderCopy(X) ((HeapTupleHeader) PG_DETOAST_DATUM_COPY(X)) +/* Variants which return n bytes starting at pos. m */ +#define DatumGetByteaPSlice(X,m,n) ((bytea *) PG_DETOAST_DATUM_SLICE(X,m,n)) +#define DatumGetTextPSlice(X,m,n) ((text *) PG_DETOAST_DATUM_SLICE(X,m,n)) +#define DatumGetBpCharPSlice(X,m,n) ((BpChar *) PG_DETOAST_DATUM_SLICE(X,m,n)) +#define DatumGetVarCharPSlice(X,m,n) ((VarChar *) PG_DETOAST_DATUM_SLICE(X,m,n)) +/* GETARG macros for varlena types will typically look like this: */ +#define PG_GETARG_BYTEA_PP(n) DatumGetByteaPP(PG_GETARG_DATUM(n)) +#define PG_GETARG_TEXT_PP(n) DatumGetTextPP(PG_GETARG_DATUM(n)) +#define PG_GETARG_BPCHAR_PP(n) DatumGetBpCharPP(PG_GETARG_DATUM(n)) +#define PG_GETARG_VARCHAR_PP(n) DatumGetVarCharPP(PG_GETARG_DATUM(n)) +#define PG_GETARG_HEAPTUPLEHEADER(n) DatumGetHeapTupleHeader(PG_GETARG_DATUM(n)) +/* And we also offer variants that return an OK-to-write copy */ +#define PG_GETARG_BYTEA_P_COPY(n) DatumGetByteaPCopy(PG_GETARG_DATUM(n)) +#define PG_GETARG_TEXT_P_COPY(n) DatumGetTextPCopy(PG_GETARG_DATUM(n)) +#define PG_GETARG_BPCHAR_P_COPY(n) DatumGetBpCharPCopy(PG_GETARG_DATUM(n)) +#define PG_GETARG_VARCHAR_P_COPY(n) DatumGetVarCharPCopy(PG_GETARG_DATUM(n)) +#define PG_GETARG_HEAPTUPLEHEADER_COPY(n) DatumGetHeapTupleHeaderCopy(PG_GETARG_DATUM(n)) +/* And a b-byte slice from position a -also OK to write */ +#define PG_GETARG_BYTEA_P_SLICE(n,a,b) DatumGetByteaPSlice(PG_GETARG_DATUM(n),a,b) +#define PG_GETARG_TEXT_P_SLICE(n,a,b) DatumGetTextPSlice(PG_GETARG_DATUM(n),a,b) +#define PG_GETARG_BPCHAR_P_SLICE(n,a,b) DatumGetBpCharPSlice(PG_GETARG_DATUM(n),a,b) +#define PG_GETARG_VARCHAR_P_SLICE(n,a,b) DatumGetVarCharPSlice(PG_GETARG_DATUM(n),a,b) +/* + * Obsolescent variants that guarantee INT alignment for the return value. + * Few operations on these particular types need alignment, mainly operations + * that cast the VARDATA pointer to a type like int16[]. Most code should use + * the ...PP(X) counterpart. Nonetheless, these appear frequently in code + * predating the PostgreSQL 8.3 introduction of the ...PP(X) variants. + */ +#define DatumGetByteaP(X) ((bytea *) PG_DETOAST_DATUM(X)) +#define DatumGetTextP(X) ((text *) PG_DETOAST_DATUM(X)) +#define DatumGetBpCharP(X) ((BpChar *) PG_DETOAST_DATUM(X)) +#define DatumGetVarCharP(X) ((VarChar *) PG_DETOAST_DATUM(X)) +#define PG_GETARG_BYTEA_P(n) DatumGetByteaP(PG_GETARG_DATUM(n)) +#define PG_GETARG_TEXT_P(n) DatumGetTextP(PG_GETARG_DATUM(n)) +#define PG_GETARG_BPCHAR_P(n) DatumGetBpCharP(PG_GETARG_DATUM(n)) +#define PG_GETARG_VARCHAR_P(n) DatumGetVarCharP(PG_GETARG_DATUM(n)) + +/* To access options from opclass support functions use this: */ +#define PG_HAS_OPCLASS_OPTIONS() has_fn_opclass_options(fcinfo->flinfo) +#define PG_GET_OPCLASS_OPTIONS() get_fn_opclass_options(fcinfo->flinfo) + +/* To return a NULL do this: */ +#define PG_RETURN_NULL() \ + do { fcinfo->isnull = true; return (Datum) 0; } while (0) + +/* A few internal functions return void (which is not the same as NULL!) */ +#define PG_RETURN_VOID() return (Datum) 0 + +/* Macros for returning results of standard types */ + +#define PG_RETURN_DATUM(x) return (x) +#define PG_RETURN_INT32(x) return Int32GetDatum(x) +#define PG_RETURN_UINT32(x) return UInt32GetDatum(x) +#define PG_RETURN_INT16(x) return Int16GetDatum(x) +#define PG_RETURN_UINT16(x) return UInt16GetDatum(x) +#define PG_RETURN_CHAR(x) return CharGetDatum(x) +#define PG_RETURN_BOOL(x) return BoolGetDatum(x) +#define PG_RETURN_OID(x) return ObjectIdGetDatum(x) +#define PG_RETURN_POINTER(x) return PointerGetDatum(x) +#define PG_RETURN_CSTRING(x) return CStringGetDatum(x) +#define PG_RETURN_NAME(x) return NameGetDatum(x) +#define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x) +/* these macros hide the pass-by-reference-ness of the datatype: */ +#define PG_RETURN_FLOAT4(x) return Float4GetDatum(x) +#define PG_RETURN_FLOAT8(x) return Float8GetDatum(x) +#define PG_RETURN_INT64(x) return Int64GetDatum(x) +#define PG_RETURN_UINT64(x) return UInt64GetDatum(x) +/* RETURN macros for other pass-by-ref types will typically look like this: */ +#define PG_RETURN_BYTEA_P(x) PG_RETURN_POINTER(x) +#define PG_RETURN_TEXT_P(x) PG_RETURN_POINTER(x) +#define PG_RETURN_BPCHAR_P(x) PG_RETURN_POINTER(x) +#define PG_RETURN_VARCHAR_P(x) PG_RETURN_POINTER(x) +#define PG_RETURN_HEAPTUPLEHEADER(x) return HeapTupleHeaderGetDatum(x) + + +/*------------------------------------------------------------------------- + * Support for detecting call convention of dynamically-loaded functions + * + * Dynamically loaded functions currently can only use the version-1 ("new + * style") calling convention. Version-0 ("old style") is not supported + * anymore. Version 1 is the call convention defined in this header file, and + * must be accompanied by the macro call + * + * PG_FUNCTION_INFO_V1(function_name); + * + * Note that internal functions do not need this decoration since they are + * assumed to be version-1. + * + *------------------------------------------------------------------------- + */ + +typedef struct +{ + int api_version; /* specifies call convention version number */ + /* More fields may be added later, for version numbers > 1. */ +} Pg_finfo_record; + +/* Expected signature of an info function */ +typedef const Pg_finfo_record *(*PGFInfoFunction) (void); + +/* + * Macro to build an info function associated with the given function name. + * + * As a convenience, also provide an "extern" declaration for the given + * function name, so that writers of C functions need not write that too. + * + * On Windows, the function and info function must be exported. Our normal + * build processes take care of that via .DEF files or --export-all-symbols. + * Module authors using a different build process might need to manually + * declare the function PGDLLEXPORT. We do that automatically here for the + * info function, since authors shouldn't need to be explicitly aware of it. + */ +#define PG_FUNCTION_INFO_V1(funcname) \ +extern PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS); \ +extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \ +const Pg_finfo_record * \ +CppConcat(pg_finfo_,funcname) (void) \ +{ \ + static const Pg_finfo_record my_finfo = { 1 }; \ + return &my_finfo; \ +} \ +extern int no_such_variable + + +/* + * Declare _PG_init/_PG_fini centrally. Historically each shared library had + * its own declaration; but now that we want to mark these PGDLLEXPORT, using + * central declarations avoids each extension having to add that. Any + * existing declarations in extensions will continue to work if fmgr.h is + * included before them, otherwise compilation for Windows will fail. + */ +extern PGDLLEXPORT void _PG_init(void); +extern PGDLLEXPORT void _PG_fini(void); + + +/*------------------------------------------------------------------------- + * Support for verifying backend compatibility of loaded modules + * + * We require dynamically-loaded modules to include the macro call + * PG_MODULE_MAGIC; + * so that we can check for obvious incompatibility, such as being compiled + * for a different major PostgreSQL version. + * + * To compile with versions of PostgreSQL that do not support this, + * you may put an #ifdef/#endif test around it. Note that in a multiple- + * source-file module, the macro call should only appear once. + * + * The specific items included in the magic block are intended to be ones that + * are custom-configurable and especially likely to break dynamically loaded + * modules if they were compiled with other values. Also, the length field + * can be used to detect definition changes. + * + * Note: we compare magic blocks with memcmp(), so there had better not be + * any alignment pad bytes in them. + * + * Note: when changing the contents of magic blocks, be sure to adjust the + * incompatible_module_error() function in dfmgr.c. + *------------------------------------------------------------------------- + */ + +/* Definition of the magic block structure */ +typedef struct +{ + int len; /* sizeof(this struct) */ + int version; /* PostgreSQL major version */ + int funcmaxargs; /* FUNC_MAX_ARGS */ + int indexmaxkeys; /* INDEX_MAX_KEYS */ + int namedatalen; /* NAMEDATALEN */ + int float8byval; /* FLOAT8PASSBYVAL */ + char abi_extra[32]; /* see pg_config_manual.h */ +} Pg_magic_struct; + +/* The actual data block contents */ +#define PG_MODULE_MAGIC_DATA \ +{ \ + sizeof(Pg_magic_struct), \ + PG_VERSION_NUM / 100, \ + FUNC_MAX_ARGS, \ + INDEX_MAX_KEYS, \ + NAMEDATALEN, \ + FLOAT8PASSBYVAL, \ + FMGR_ABI_EXTRA, \ +} + +StaticAssertDecl(sizeof(FMGR_ABI_EXTRA) <= sizeof(((Pg_magic_struct *) 0)->abi_extra), + "FMGR_ABI_EXTRA too long"); + +/* + * Declare the module magic function. It needs to be a function as the dlsym + * in the backend is only guaranteed to work on functions, not data + */ +typedef const Pg_magic_struct *(*PGModuleMagicFunction) (void); + +#define PG_MAGIC_FUNCTION_NAME Pg_magic_func +#define PG_MAGIC_FUNCTION_NAME_STRING "Pg_magic_func" + +#define PG_MODULE_MAGIC \ +extern PGDLLEXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \ +const Pg_magic_struct * \ +PG_MAGIC_FUNCTION_NAME(void) \ +{ \ + static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \ + return &Pg_magic_data; \ +} \ +extern int no_such_variable + + +/*------------------------------------------------------------------------- + * Support routines and macros for callers of fmgr-compatible functions + *------------------------------------------------------------------------- + */ + +/* These are for invocation of a specifically named function with a + * directly-computed parameter list. Note that neither arguments nor result + * are allowed to be NULL. Also, the function cannot be one that needs to + * look at FmgrInfo, since there won't be any. + */ +extern Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, + Datum arg1); +extern Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2); +extern Datum DirectFunctionCall3Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2, + Datum arg3); +extern Datum DirectFunctionCall4Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4); +extern Datum DirectFunctionCall5Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5); +extern Datum DirectFunctionCall6Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6); +extern Datum DirectFunctionCall7Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7); +extern Datum DirectFunctionCall8Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8); +extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8, + Datum arg9); + +/* + * These functions work like the DirectFunctionCall functions except that + * they use the flinfo parameter to initialise the fcinfo for the call. + * It's recommended that the callee only use the fn_extra and fn_mcxt + * fields, as other fields will typically describe the calling function + * not the callee. Conversely, the calling function should not have + * used fn_extra, unless its use is known to be compatible with the callee's. + */ +extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, + Oid collation, Datum arg1); +extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, + Oid collation, Datum arg1, Datum arg2); + +/* These are for invocation of a previously-looked-up function with a + * directly-computed parameter list. Note that neither arguments nor result + * are allowed to be NULL. + */ +extern Datum FunctionCall0Coll(FmgrInfo *flinfo, Oid collation); +extern Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1); +extern Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2); +extern Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2, + Datum arg3); +extern Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4); +extern Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5); +extern Datum FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6); +extern Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7); +extern Datum FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8); +extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8, + Datum arg9); + +/* These are for invocation of a function identified by OID with a + * directly-computed parameter list. Note that neither arguments nor result + * are allowed to be NULL. These are essentially fmgr_info() followed by + * FunctionCallN(). If the same function is to be invoked repeatedly, do the + * fmgr_info() once and then use FunctionCallN(). + */ +extern Datum OidFunctionCall0Coll(Oid functionId, Oid collation); +extern Datum OidFunctionCall1Coll(Oid functionId, Oid collation, + Datum arg1); +extern Datum OidFunctionCall2Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2); +extern Datum OidFunctionCall3Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2, + Datum arg3); +extern Datum OidFunctionCall4Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4); +extern Datum OidFunctionCall5Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5); +extern Datum OidFunctionCall6Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6); +extern Datum OidFunctionCall7Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7); +extern Datum OidFunctionCall8Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8); +extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation, + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8, + Datum arg9); + +/* These macros allow the collation argument to be omitted (with a default of + * InvalidOid, ie, no collation). They exist mostly for backwards + * compatibility of source code. + */ +#define DirectFunctionCall1(func, arg1) \ + DirectFunctionCall1Coll(func, InvalidOid, arg1) +#define DirectFunctionCall2(func, arg1, arg2) \ + DirectFunctionCall2Coll(func, InvalidOid, arg1, arg2) +#define DirectFunctionCall3(func, arg1, arg2, arg3) \ + DirectFunctionCall3Coll(func, InvalidOid, arg1, arg2, arg3) +#define DirectFunctionCall4(func, arg1, arg2, arg3, arg4) \ + DirectFunctionCall4Coll(func, InvalidOid, arg1, arg2, arg3, arg4) +#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5) \ + DirectFunctionCall5Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5) +#define DirectFunctionCall6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ + DirectFunctionCall6Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6) +#define DirectFunctionCall7(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DirectFunctionCall7Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define DirectFunctionCall8(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ + DirectFunctionCall8Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) +#define DirectFunctionCall9(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ + DirectFunctionCall9Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) +#define FunctionCall1(flinfo, arg1) \ + FunctionCall1Coll(flinfo, InvalidOid, arg1) +#define FunctionCall2(flinfo, arg1, arg2) \ + FunctionCall2Coll(flinfo, InvalidOid, arg1, arg2) +#define FunctionCall3(flinfo, arg1, arg2, arg3) \ + FunctionCall3Coll(flinfo, InvalidOid, arg1, arg2, arg3) +#define FunctionCall4(flinfo, arg1, arg2, arg3, arg4) \ + FunctionCall4Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4) +#define FunctionCall5(flinfo, arg1, arg2, arg3, arg4, arg5) \ + FunctionCall5Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5) +#define FunctionCall6(flinfo, arg1, arg2, arg3, arg4, arg5, arg6) \ + FunctionCall6Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6) +#define FunctionCall7(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + FunctionCall7Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define FunctionCall8(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ + FunctionCall8Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) +#define FunctionCall9(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ + FunctionCall9Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) +#define OidFunctionCall0(functionId) \ + OidFunctionCall0Coll(functionId, InvalidOid) +#define OidFunctionCall1(functionId, arg1) \ + OidFunctionCall1Coll(functionId, InvalidOid, arg1) +#define OidFunctionCall2(functionId, arg1, arg2) \ + OidFunctionCall2Coll(functionId, InvalidOid, arg1, arg2) +#define OidFunctionCall3(functionId, arg1, arg2, arg3) \ + OidFunctionCall3Coll(functionId, InvalidOid, arg1, arg2, arg3) +#define OidFunctionCall4(functionId, arg1, arg2, arg3, arg4) \ + OidFunctionCall4Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4) +#define OidFunctionCall5(functionId, arg1, arg2, arg3, arg4, arg5) \ + OidFunctionCall5Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5) +#define OidFunctionCall6(functionId, arg1, arg2, arg3, arg4, arg5, arg6) \ + OidFunctionCall6Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6) +#define OidFunctionCall7(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + OidFunctionCall7Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define OidFunctionCall8(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ + OidFunctionCall8Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) +#define OidFunctionCall9(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ + OidFunctionCall9Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) + + +/* Special cases for convenient invocation of datatype I/O functions. */ +extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str, + Oid typioparam, int32 typmod); +extern bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, + Oid typioparam, int32 typmod, + fmNodePtr escontext, + Datum *result); +extern bool DirectInputFunctionCallSafe(PGFunction func, char *str, + Oid typioparam, int32 typmod, + fmNodePtr escontext, + Datum *result); +extern Datum OidInputFunctionCall(Oid functionId, char *str, + Oid typioparam, int32 typmod); +extern char *OutputFunctionCall(FmgrInfo *flinfo, Datum val); +extern char *OidOutputFunctionCall(Oid functionId, Datum val); +extern Datum ReceiveFunctionCall(FmgrInfo *flinfo, fmStringInfo buf, + Oid typioparam, int32 typmod); +extern Datum OidReceiveFunctionCall(Oid functionId, fmStringInfo buf, + Oid typioparam, int32 typmod); +extern bytea *SendFunctionCall(FmgrInfo *flinfo, Datum val); +extern bytea *OidSendFunctionCall(Oid functionId, Datum val); + + +/* + * Routines in fmgr.c + */ +extern const Pg_finfo_record *fetch_finfo_record(void *filehandle, const char *funcname); +extern Oid fmgr_internal_function(const char *proname); +extern Oid get_fn_expr_rettype(FmgrInfo *flinfo); +extern Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum); +extern Oid get_call_expr_argtype(fmNodePtr expr, int argnum); +extern bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum); +extern bool get_call_expr_arg_stable(fmNodePtr expr, int argnum); +extern bool get_fn_expr_variadic(FmgrInfo *flinfo); +extern bytea *get_fn_opclass_options(FmgrInfo *flinfo); +extern bool has_fn_opclass_options(FmgrInfo *flinfo); +extern void set_fn_opclass_options(FmgrInfo *flinfo, bytea *options); +extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid); + +/* + * Routines in dfmgr.c + */ +extern PGDLLIMPORT char *Dynamic_library_path; + +extern void *load_external_function(const char *filename, const char *funcname, + bool signalNotFound, void **filehandle); +extern void *lookup_external_function(void *filehandle, const char *funcname); +extern void load_file(const char *filename, bool restricted); +extern void **find_rendezvous_variable(const char *varName); +extern Size EstimateLibraryStateSpace(void); +extern void SerializeLibraryState(Size maxsize, char *start_address); +extern void RestoreLibraryState(char *start_address); + +/* + * Support for aggregate functions + * + * These are actually in executor/nodeAgg.c, but we declare them here since + * the whole point is for callers to not be overly friendly with nodeAgg. + */ + +/* AggCheckCallContext can return one of the following codes, or 0: */ +#define AGG_CONTEXT_AGGREGATE 1 /* regular aggregate */ +#define AGG_CONTEXT_WINDOW 2 /* window function */ + +extern int AggCheckCallContext(FunctionCallInfo fcinfo, + MemoryContext *aggcontext); +extern fmAggrefPtr AggGetAggref(FunctionCallInfo fcinfo); +extern MemoryContext AggGetTempMemoryContext(FunctionCallInfo fcinfo); +extern bool AggStateIsShared(FunctionCallInfo fcinfo); +extern void AggRegisterCallback(FunctionCallInfo fcinfo, + fmExprContextCallbackFunction func, + Datum arg); + +/* + * We allow plugin modules to hook function entry/exit. This is intended + * as support for loadable security policy modules, which may want to + * perform additional privilege checks on function entry or exit, or to do + * other internal bookkeeping. To make this possible, such modules must be + * able not only to support normal function entry and exit, but also to trap + * the case where we bail out due to an error; and they must also be able to + * prevent inlining. + */ +typedef enum FmgrHookEventType +{ + FHET_START, + FHET_END, + FHET_ABORT +} FmgrHookEventType; + +typedef bool (*needs_fmgr_hook_type) (Oid fn_oid); + +typedef void (*fmgr_hook_type) (FmgrHookEventType event, + FmgrInfo *flinfo, Datum *arg); + +extern PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook; +extern PGDLLIMPORT fmgr_hook_type fmgr_hook; + +#define FmgrHookIsNeeded(fn_oid) \ + (!needs_fmgr_hook ? false : (*needs_fmgr_hook)(fn_oid)) + +#endif /* FMGR_H */ diff --git a/install/include/postgresql/server/foreign/fdwapi.h b/install/include/postgresql/server/foreign/fdwapi.h new file mode 100644 index 00000000000..996c62e3055 --- /dev/null +++ b/install/include/postgresql/server/foreign/fdwapi.h @@ -0,0 +1,294 @@ +/*------------------------------------------------------------------------- + * + * fdwapi.h + * API for foreign-data wrappers + * + * Copyright (c) 2010-2023, PostgreSQL Global Development Group + * + * src/include/foreign/fdwapi.h + * + *------------------------------------------------------------------------- + */ +#ifndef FDWAPI_H +#define FDWAPI_H + +#include "access/parallel.h" +#include "nodes/execnodes.h" +#include "nodes/pathnodes.h" + +/* To avoid including explain.h here, reference ExplainState thus: */ +struct ExplainState; + + +/* + * Callback function signatures --- see fdwhandler.sgml for more info. + */ + +typedef void (*GetForeignRelSize_function) (PlannerInfo *root, + RelOptInfo *baserel, + Oid foreigntableid); + +typedef void (*GetForeignPaths_function) (PlannerInfo *root, + RelOptInfo *baserel, + Oid foreigntableid); + +typedef ForeignScan *(*GetForeignPlan_function) (PlannerInfo *root, + RelOptInfo *baserel, + Oid foreigntableid, + ForeignPath *best_path, + List *tlist, + List *scan_clauses, + Plan *outer_plan); + +typedef void (*BeginForeignScan_function) (ForeignScanState *node, + int eflags); + +typedef TupleTableSlot *(*IterateForeignScan_function) (ForeignScanState *node); + +typedef bool (*RecheckForeignScan_function) (ForeignScanState *node, + TupleTableSlot *slot); + +typedef void (*ReScanForeignScan_function) (ForeignScanState *node); + +typedef void (*EndForeignScan_function) (ForeignScanState *node); + +typedef void (*GetForeignJoinPaths_function) (PlannerInfo *root, + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + JoinPathExtraData *extra); + +typedef void (*GetForeignUpperPaths_function) (PlannerInfo *root, + UpperRelationKind stage, + RelOptInfo *input_rel, + RelOptInfo *output_rel, + void *extra); + +typedef void (*AddForeignUpdateTargets_function) (PlannerInfo *root, + Index rtindex, + RangeTblEntry *target_rte, + Relation target_relation); + +typedef List *(*PlanForeignModify_function) (PlannerInfo *root, + ModifyTable *plan, + Index resultRelation, + int subplan_index); + +typedef void (*BeginForeignModify_function) (ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + int eflags); + +typedef TupleTableSlot *(*ExecForeignInsert_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef TupleTableSlot **(*ExecForeignBatchInsert_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int *numSlots); + +typedef int (*GetForeignModifyBatchSize_function) (ResultRelInfo *rinfo); + +typedef TupleTableSlot *(*ExecForeignUpdate_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef TupleTableSlot *(*ExecForeignDelete_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef void (*EndForeignModify_function) (EState *estate, + ResultRelInfo *rinfo); + +typedef void (*BeginForeignInsert_function) (ModifyTableState *mtstate, + ResultRelInfo *rinfo); + +typedef void (*EndForeignInsert_function) (EState *estate, + ResultRelInfo *rinfo); + +typedef int (*IsForeignRelUpdatable_function) (Relation rel); + +typedef bool (*PlanDirectModify_function) (PlannerInfo *root, + ModifyTable *plan, + Index resultRelation, + int subplan_index); + +typedef void (*BeginDirectModify_function) (ForeignScanState *node, + int eflags); + +typedef TupleTableSlot *(*IterateDirectModify_function) (ForeignScanState *node); + +typedef void (*EndDirectModify_function) (ForeignScanState *node); + +typedef RowMarkType (*GetForeignRowMarkType_function) (RangeTblEntry *rte, + LockClauseStrength strength); + +typedef void (*RefetchForeignRow_function) (EState *estate, + ExecRowMark *erm, + Datum rowid, + TupleTableSlot *slot, + bool *updated); + +typedef void (*ExplainForeignScan_function) (ForeignScanState *node, + struct ExplainState *es); + +typedef void (*ExplainForeignModify_function) (ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + struct ExplainState *es); + +typedef void (*ExplainDirectModify_function) (ForeignScanState *node, + struct ExplainState *es); + +typedef int (*AcquireSampleRowsFunc) (Relation relation, int elevel, + HeapTuple *rows, int targrows, + double *totalrows, + double *totaldeadrows); + +typedef bool (*AnalyzeForeignTable_function) (Relation relation, + AcquireSampleRowsFunc *func, + BlockNumber *totalpages); + +typedef List *(*ImportForeignSchema_function) (ImportForeignSchemaStmt *stmt, + Oid serverOid); + +typedef void (*ExecForeignTruncate_function) (List *rels, + DropBehavior behavior, + bool restart_seqs); + +typedef Size (*EstimateDSMForeignScan_function) (ForeignScanState *node, + ParallelContext *pcxt); +typedef void (*InitializeDSMForeignScan_function) (ForeignScanState *node, + ParallelContext *pcxt, + void *coordinate); +typedef void (*ReInitializeDSMForeignScan_function) (ForeignScanState *node, + ParallelContext *pcxt, + void *coordinate); +typedef void (*InitializeWorkerForeignScan_function) (ForeignScanState *node, + shm_toc *toc, + void *coordinate); +typedef void (*ShutdownForeignScan_function) (ForeignScanState *node); +typedef bool (*IsForeignScanParallelSafe_function) (PlannerInfo *root, + RelOptInfo *rel, + RangeTblEntry *rte); +typedef List *(*ReparameterizeForeignPathByChild_function) (PlannerInfo *root, + List *fdw_private, + RelOptInfo *child_rel); + +typedef bool (*IsForeignPathAsyncCapable_function) (ForeignPath *path); + +typedef void (*ForeignAsyncRequest_function) (AsyncRequest *areq); + +typedef void (*ForeignAsyncConfigureWait_function) (AsyncRequest *areq); + +typedef void (*ForeignAsyncNotify_function) (AsyncRequest *areq); + +/* + * FdwRoutine is the struct returned by a foreign-data wrapper's handler + * function. It provides pointers to the callback functions needed by the + * planner and executor. + * + * More function pointers are likely to be added in the future. Therefore + * it's recommended that the handler initialize the struct with + * makeNode(FdwRoutine) so that all fields are set to NULL. This will + * ensure that no fields are accidentally left undefined. + */ +typedef struct FdwRoutine +{ + NodeTag type; + + /* Functions for scanning foreign tables */ + GetForeignRelSize_function GetForeignRelSize; + GetForeignPaths_function GetForeignPaths; + GetForeignPlan_function GetForeignPlan; + BeginForeignScan_function BeginForeignScan; + IterateForeignScan_function IterateForeignScan; + ReScanForeignScan_function ReScanForeignScan; + EndForeignScan_function EndForeignScan; + + /* + * Remaining functions are optional. Set the pointer to NULL for any that + * are not provided. + */ + + /* Functions for remote-join planning */ + GetForeignJoinPaths_function GetForeignJoinPaths; + + /* Functions for remote upper-relation (post scan/join) planning */ + GetForeignUpperPaths_function GetForeignUpperPaths; + + /* Functions for updating foreign tables */ + AddForeignUpdateTargets_function AddForeignUpdateTargets; + PlanForeignModify_function PlanForeignModify; + BeginForeignModify_function BeginForeignModify; + ExecForeignInsert_function ExecForeignInsert; + ExecForeignBatchInsert_function ExecForeignBatchInsert; + GetForeignModifyBatchSize_function GetForeignModifyBatchSize; + ExecForeignUpdate_function ExecForeignUpdate; + ExecForeignDelete_function ExecForeignDelete; + EndForeignModify_function EndForeignModify; + BeginForeignInsert_function BeginForeignInsert; + EndForeignInsert_function EndForeignInsert; + IsForeignRelUpdatable_function IsForeignRelUpdatable; + PlanDirectModify_function PlanDirectModify; + BeginDirectModify_function BeginDirectModify; + IterateDirectModify_function IterateDirectModify; + EndDirectModify_function EndDirectModify; + + /* Functions for SELECT FOR UPDATE/SHARE row locking */ + GetForeignRowMarkType_function GetForeignRowMarkType; + RefetchForeignRow_function RefetchForeignRow; + RecheckForeignScan_function RecheckForeignScan; + + /* Support functions for EXPLAIN */ + ExplainForeignScan_function ExplainForeignScan; + ExplainForeignModify_function ExplainForeignModify; + ExplainDirectModify_function ExplainDirectModify; + + /* Support functions for ANALYZE */ + AnalyzeForeignTable_function AnalyzeForeignTable; + + /* Support functions for IMPORT FOREIGN SCHEMA */ + ImportForeignSchema_function ImportForeignSchema; + + /* Support functions for TRUNCATE */ + ExecForeignTruncate_function ExecForeignTruncate; + + /* Support functions for parallelism under Gather node */ + IsForeignScanParallelSafe_function IsForeignScanParallelSafe; + EstimateDSMForeignScan_function EstimateDSMForeignScan; + InitializeDSMForeignScan_function InitializeDSMForeignScan; + ReInitializeDSMForeignScan_function ReInitializeDSMForeignScan; + InitializeWorkerForeignScan_function InitializeWorkerForeignScan; + ShutdownForeignScan_function ShutdownForeignScan; + + /* Support functions for path reparameterization. */ + ReparameterizeForeignPathByChild_function ReparameterizeForeignPathByChild; + + /* Support functions for asynchronous execution */ + IsForeignPathAsyncCapable_function IsForeignPathAsyncCapable; + ForeignAsyncRequest_function ForeignAsyncRequest; + ForeignAsyncConfigureWait_function ForeignAsyncConfigureWait; + ForeignAsyncNotify_function ForeignAsyncNotify; +} FdwRoutine; + + +/* Functions in foreign/foreign.c */ +extern FdwRoutine *GetFdwRoutine(Oid fdwhandler); +extern Oid GetForeignServerIdByRelId(Oid relid); +extern FdwRoutine *GetFdwRoutineByServerId(Oid serverid); +extern FdwRoutine *GetFdwRoutineByRelId(Oid relid); +extern FdwRoutine *GetFdwRoutineForRelation(Relation relation, bool makecopy); +extern bool IsImportableForeignTable(const char *tablename, + ImportForeignSchemaStmt *stmt); +extern Path *GetExistingLocalJoinPath(RelOptInfo *joinrel); + +#endif /* FDWAPI_H */ diff --git a/install/include/postgresql/server/foreign/foreign.h b/install/include/postgresql/server/foreign/foreign.h new file mode 100644 index 00000000000..5256d4d91f5 --- /dev/null +++ b/install/include/postgresql/server/foreign/foreign.h @@ -0,0 +1,85 @@ +/*------------------------------------------------------------------------- + * + * foreign.h + * support for foreign-data wrappers, servers and user mappings. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/foreign/foreign.h + * + *------------------------------------------------------------------------- + */ +#ifndef FOREIGN_H +#define FOREIGN_H + +#include "nodes/parsenodes.h" + + +/* Helper for obtaining username for user mapping */ +#define MappingUserName(userid) \ + (OidIsValid(userid) ? GetUserNameFromId(userid, false) : "public") + + +typedef struct ForeignDataWrapper +{ + Oid fdwid; /* FDW Oid */ + Oid owner; /* FDW owner user Oid */ + char *fdwname; /* Name of the FDW */ + Oid fdwhandler; /* Oid of handler function, or 0 */ + Oid fdwvalidator; /* Oid of validator function, or 0 */ + List *options; /* fdwoptions as DefElem list */ +} ForeignDataWrapper; + +typedef struct ForeignServer +{ + Oid serverid; /* server Oid */ + Oid fdwid; /* foreign-data wrapper */ + Oid owner; /* server owner user Oid */ + char *servername; /* name of the server */ + char *servertype; /* server type, optional */ + char *serverversion; /* server version, optional */ + List *options; /* srvoptions as DefElem list */ +} ForeignServer; + +typedef struct UserMapping +{ + Oid umid; /* Oid of user mapping */ + Oid userid; /* local user Oid */ + Oid serverid; /* server Oid */ + List *options; /* useoptions as DefElem list */ +} UserMapping; + +typedef struct ForeignTable +{ + Oid relid; /* relation Oid */ + Oid serverid; /* server Oid */ + List *options; /* ftoptions as DefElem list */ +} ForeignTable; + +/* Flags for GetForeignServerExtended */ +#define FSV_MISSING_OK 0x01 + +/* Flags for GetForeignDataWrapperExtended */ +#define FDW_MISSING_OK 0x01 + + +extern ForeignServer *GetForeignServer(Oid serverid); +extern ForeignServer *GetForeignServerExtended(Oid serverid, + bits16 flags); +extern ForeignServer *GetForeignServerByName(const char *srvname, + bool missing_ok); +extern UserMapping *GetUserMapping(Oid userid, Oid serverid); +extern ForeignDataWrapper *GetForeignDataWrapper(Oid fdwid); +extern ForeignDataWrapper *GetForeignDataWrapperExtended(Oid fdwid, + bits16 flags); +extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *fdwname, + bool missing_ok); +extern ForeignTable *GetForeignTable(Oid relid); + +extern List *GetForeignColumnOptions(Oid relid, AttrNumber attnum); + +extern Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok); +extern Oid get_foreign_server_oid(const char *servername, bool missing_ok); + +#endif /* FOREIGN_H */ diff --git a/install/include/postgresql/server/funcapi.h b/install/include/postgresql/server/funcapi.h new file mode 100644 index 00000000000..cc0cca32725 --- /dev/null +++ b/install/include/postgresql/server/funcapi.h @@ -0,0 +1,360 @@ +/*------------------------------------------------------------------------- + * + * funcapi.h + * Definitions for functions which return composite type and/or sets + * or work on VARIADIC inputs. + * + * This file must be included by all Postgres modules that either define + * or call FUNCAPI-callable functions or macros. + * + * + * Copyright (c) 2002-2023, PostgreSQL Global Development Group + * + * src/include/funcapi.h + * + *------------------------------------------------------------------------- + */ +#ifndef FUNCAPI_H +#define FUNCAPI_H + +#include "access/tupdesc.h" +#include "executor/executor.h" +#include "executor/tuptable.h" +#include "fmgr.h" + +/*------------------------------------------------------------------------- + * Support to ease writing Functions returning composite types + *------------------------------------------------------------------------- + * + * This struct holds arrays of individual attribute information + * needed to create a tuple from raw C strings. It also requires + * a copy of the TupleDesc. The information carried here + * is derived from the TupleDesc, but it is stored here to + * avoid redundant cpu cycles on each call to an SRF. + */ +typedef struct AttInMetadata +{ + /* full TupleDesc */ + TupleDesc tupdesc; + + /* array of attribute type input function finfo */ + FmgrInfo *attinfuncs; + + /* array of attribute type i/o parameter OIDs */ + Oid *attioparams; + + /* array of attribute typmod */ + int32 *atttypmods; +} AttInMetadata; + +/*------------------------------------------------------------------------- + * Support struct to ease writing Set Returning Functions (SRFs) + *------------------------------------------------------------------------- + * + * This struct holds function context for Set Returning Functions. + * Use fn_extra to hold a pointer to it across calls + */ +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 struct 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; + +/*---------- + * Support to ease writing functions returning composite types + * + * External declarations: + * get_call_result_type: + * Given a function's call info record, determine the kind of datatype + * it is supposed to return. If resultTypeId isn't NULL, *resultTypeId + * receives the actual datatype OID (this is mainly useful for scalar + * result types). If resultTupleDesc isn't NULL, *resultTupleDesc + * receives a pointer to a TupleDesc when the result is of a composite + * type, or NULL when it's a scalar result or the rowtype could not be + * determined. NB: the tupledesc should be copied if it is to be + * accessed over a long period. + * get_expr_result_type: + * Given an expression node, return the same info as for + * get_call_result_type. Note: the cases in which rowtypes cannot be + * determined are different from the cases for get_call_result_type. + * get_func_result_type: + * Given only a function's OID, return the same info as for + * get_call_result_type. Note: the cases in which rowtypes cannot be + * determined are different from the cases for get_call_result_type. + * Do *not* use this if you can use one of the others. + * + * See also get_expr_result_tupdesc(), which is a convenient wrapper around + * get_expr_result_type() for use when the caller only cares about + * determinable-rowtype cases. + *---------- + */ + +/* Type categories for get_call_result_type and siblings */ +typedef enum TypeFuncClass +{ + TYPEFUNC_SCALAR, /* scalar result type */ + TYPEFUNC_COMPOSITE, /* determinable rowtype result */ + TYPEFUNC_COMPOSITE_DOMAIN, /* domain over determinable rowtype result */ + TYPEFUNC_RECORD, /* indeterminate rowtype result */ + TYPEFUNC_OTHER /* bogus type, eg pseudotype */ +} TypeFuncClass; + +extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, + Oid *resultTypeId, + TupleDesc *resultTupleDesc); +extern TypeFuncClass get_expr_result_type(Node *expr, + Oid *resultTypeId, + TupleDesc *resultTupleDesc); +extern TypeFuncClass get_func_result_type(Oid functionId, + Oid *resultTypeId, + TupleDesc *resultTupleDesc); + +extern TupleDesc get_expr_result_tupdesc(Node *expr, bool noError); + +extern bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, + char *argmodes, + Node *call_expr); + +extern int get_func_arg_info(HeapTuple procTup, + Oid **p_argtypes, char ***p_argnames, + char **p_argmodes); + +extern int get_func_input_arg_names(Datum proargnames, Datum proargmodes, + char ***arg_names); + +extern int get_func_trftypes(HeapTuple procTup, Oid **p_trftypes); +extern char *get_func_result_name(Oid functionId); + +extern TupleDesc build_function_result_tupdesc_d(char prokind, + Datum proallargtypes, + Datum proargmodes, + Datum proargnames); +extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple); + + +/*---------- + * Support to ease writing functions returning composite types + * + * External declarations: + * TupleDesc BlessTupleDesc(TupleDesc tupdesc) - "Bless" a completed tuple + * descriptor so that it can be used to return properly labeled tuples. + * You need to call this if you are going to use heap_form_tuple directly. + * TupleDescGetAttInMetadata does it for you, however, so no need to call + * it if you call TupleDescGetAttInMetadata. + * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Build an + * AttInMetadata struct based on the given TupleDesc. AttInMetadata can + * be used in conjunction with C strings to produce a properly formed + * tuple. + * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) - + * build a HeapTuple given user data in C string form. values is an array + * of C strings, one for each attribute of the return tuple. + * Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple) - convert a + * HeapTupleHeader to a Datum. + * + * Inline declarations: + * HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum. + * + * Obsolete routines and macros: + * TupleDesc RelationNameGetTupleDesc(const char *relname) - Use to get a + * TupleDesc based on a named relation. + * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a + * TupleDesc based on a type OID. + * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum + * given a tuple and a slot. + *---------- + */ + +extern TupleDesc RelationNameGetTupleDesc(const char *relname); +extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases); + +/* from execTuples.c */ +extern TupleDesc BlessTupleDesc(TupleDesc tupdesc); +extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc); +extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values); +extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple); + +static inline Datum +HeapTupleGetDatum(const HeapTupleData *tuple) +{ + return HeapTupleHeaderGetDatum(tuple->t_data); +} + +/* obsolete version of above */ +#define TupleGetDatum(_slot, _tuple) HeapTupleGetDatum(_tuple) + + +/*---------- + * Support for Set Returning Functions (SRFs) + * + * The basic API for SRFs using ValuePerCall mode looks something like this: + * + * Datum + * my_Set_Returning_Function(PG_FUNCTION_ARGS) + * { + * FuncCallContext *funcctx; + * Datum result; + * MemoryContext oldcontext; + * + * + * if (SRF_IS_FIRSTCALL()) + * { + * funcctx = SRF_FIRSTCALL_INIT(); + * // switch context when allocating stuff to be used in later calls + * oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + * + * + * + * + * + * // return to original context when allocating transient memory + * MemoryContextSwitchTo(oldcontext); + * } + * + * funcctx = SRF_PERCALL_SETUP(); + * + * + * if (funcctx->call_cntr < funcctx->max_calls) + * { + * + * + * SRF_RETURN_NEXT(funcctx, result); + * } + * else + * SRF_RETURN_DONE(funcctx); + * } + * + * NOTE: there is no guarantee that a SRF using ValuePerCall mode will be + * run to completion; for example, a query with LIMIT might stop short of + * fetching all the rows. Therefore, do not expect that you can do resource + * cleanup just before SRF_RETURN_DONE(). You need not worry about releasing + * memory allocated in multi_call_memory_ctx, but holding file descriptors or + * other non-memory resources open across calls is a bug. SRFs that need + * such resources should not use these macros, but instead populate a + * tuplestore during a single call, as set up by InitMaterializedSRF() (see + * fmgr/README). Alternatively, set up a callback to release resources + * at query shutdown, using RegisterExprContextCallback(). + * + *---------- + */ + +/* from funcapi.c */ + +/* flag bits for InitMaterializedSRF() */ +#define MAT_SRF_USE_EXPECTED_DESC 0x01 /* use expectedDesc as tupdesc. */ +#define MAT_SRF_BLESS 0x02 /* "Bless" a tuple descriptor with + * BlessTupleDesc(). */ +extern void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags); + +extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS); +extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS); +extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx); + +#define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL) + +#define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo) + +#define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo) + +#define SRF_RETURN_NEXT(_funcctx, _result) \ + do { \ + ReturnSetInfo *rsi; \ + (_funcctx)->call_cntr++; \ + rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ + rsi->isDone = ExprMultipleResult; \ + PG_RETURN_DATUM(_result); \ + } while (0) + +#define SRF_RETURN_NEXT_NULL(_funcctx) \ + do { \ + ReturnSetInfo *rsi; \ + (_funcctx)->call_cntr++; \ + rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ + rsi->isDone = ExprMultipleResult; \ + PG_RETURN_NULL(); \ + } while (0) + +#define SRF_RETURN_DONE(_funcctx) \ + do { \ + ReturnSetInfo *rsi; \ + end_MultiFuncCall(fcinfo, _funcctx); \ + rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ + rsi->isDone = ExprEndResult; \ + PG_RETURN_NULL(); \ + } while (0) + +/*---------- + * Support to ease writing of functions dealing with VARIADIC inputs + *---------- + * + * This function extracts a set of argument values, types and NULL markers + * for a given input function. This returns a set of data: + * - **values includes the set of Datum values extracted. + * - **types the data type OID for each element. + * - **nulls tracks if an element is NULL. + * + * variadic_start indicates the argument number where the VARIADIC argument + * starts. + * convert_unknown set to true will enforce the conversion of arguments + * with unknown data type to text. + * + * The return result is the number of elements stored, or -1 in the case of + * "VARIADIC NULL". + */ +extern int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, + bool convert_unknown, Datum **args, + Oid **types, bool **nulls); + +#endif /* FUNCAPI_H */ diff --git a/install/include/postgresql/server/getopt_long.h b/install/include/postgresql/server/getopt_long.h new file mode 100644 index 00000000000..62b4a416eda --- /dev/null +++ b/install/include/postgresql/server/getopt_long.h @@ -0,0 +1,36 @@ +/* + * Portions Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Portions Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/getopt_long.h + */ +#ifndef GETOPT_LONG_H +#define GETOPT_LONG_H + +#include "pg_getopt.h" + +#ifndef HAVE_STRUCT_OPTION + +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 +#endif + +#ifndef HAVE_GETOPT_LONG + +extern int getopt_long(int argc, char *const argv[], + const char *optstring, + const struct option *longopts, int *longindex); +#endif + +#endif /* GETOPT_LONG_H */ diff --git a/install/include/postgresql/server/jit/SectionMemoryManager.h b/install/include/postgresql/server/jit/SectionMemoryManager.h new file mode 100644 index 00000000000..93cf9771570 --- /dev/null +++ b/install/include/postgresql/server/jit/SectionMemoryManager.h @@ -0,0 +1,226 @@ +/* + * This is a copy LLVM source code modified by the PostgreSQL project. + * See SectionMemoryManager.cpp for notes on provenance and license. + */ + +//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of a section-based memory manager used by +// the MCJIT execution engine and RuntimeDyld. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_BACKPORT_SECTIONMEMORYMANAGER_H +#define LLVM_EXECUTIONENGINE_BACKPORT_SECTIONMEMORYMANAGER_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#include "llvm/Support/Alignment.h" +#include "llvm/Support/Memory.h" +#include +#include +#include + +namespace llvm { +namespace backport { + +/// This is a simple memory manager which implements the methods called by +/// the RuntimeDyld class to allocate memory for section-based loading of +/// objects, usually those generated by the MCJIT execution engine. +/// +/// This memory manager allocates all section memory as read-write. The +/// RuntimeDyld will copy JITed section memory into these allocated blocks +/// and perform any necessary linking and relocations. +/// +/// Any client using this memory manager MUST ensure that section-specific +/// page permissions have been applied before attempting to execute functions +/// in the JITed object. Permissions can be applied either by calling +/// MCJIT::finalizeObject or by calling SectionMemoryManager::finalizeMemory +/// directly. Clients of MCJIT should call MCJIT::finalizeObject. +class SectionMemoryManager : public RTDyldMemoryManager { +public: + /// This enum describes the various reasons to allocate pages from + /// allocateMappedMemory. + enum class AllocationPurpose { + Code, + ROData, + RWData, + }; + + /// Implementations of this interface are used by SectionMemoryManager to + /// request pages from the operating system. + class MemoryMapper { + public: + /// This method attempts to allocate \p NumBytes bytes of virtual memory for + /// \p Purpose. \p NearBlock may point to an existing allocation, in which + /// case an attempt is made to allocate more memory near the existing block. + /// The actual allocated address is not guaranteed to be near the requested + /// address. \p Flags is used to set the initial protection flags for the + /// block of the memory. \p EC [out] returns an object describing any error + /// that occurs. + /// + /// This method may allocate more than the number of bytes requested. The + /// actual number of bytes allocated is indicated in the returned + /// MemoryBlock. + /// + /// The start of the allocated block must be aligned with the system + /// allocation granularity (64K on Windows, page size on Linux). If the + /// address following \p NearBlock is not so aligned, it will be rounded up + /// to the next allocation granularity boundary. + /// + /// \r a non-null MemoryBlock if the function was successful, otherwise a + /// null MemoryBlock with \p EC describing the error. + virtual sys::MemoryBlock + allocateMappedMemory(AllocationPurpose Purpose, size_t NumBytes, + const sys::MemoryBlock *const NearBlock, + unsigned Flags, std::error_code &EC) = 0; + + /// This method sets the protection flags for a block of memory to the state + /// specified by \p Flags. The behavior is not specified if the memory was + /// not allocated using the allocateMappedMemory method. + /// \p Block describes the memory block to be protected. + /// \p Flags specifies the new protection state to be assigned to the block. + /// + /// If \p Flags is MF_WRITE, the actual behavior varies with the operating + /// system (i.e. MF_READ | MF_WRITE on Windows) and the target architecture + /// (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386). + /// + /// \r error_success if the function was successful, or an error_code + /// describing the failure if an error occurred. + virtual std::error_code protectMappedMemory(const sys::MemoryBlock &Block, + unsigned Flags) = 0; + + /// This method releases a block of memory that was allocated with the + /// allocateMappedMemory method. It should not be used to release any memory + /// block allocated any other way. + /// \p Block describes the memory to be released. + /// + /// \r error_success if the function was successful, or an error_code + /// describing the failure if an error occurred. + virtual std::error_code releaseMappedMemory(sys::MemoryBlock &M) = 0; + + virtual ~MemoryMapper(); + }; + + /// Creates a SectionMemoryManager instance with \p MM as the associated + /// memory mapper. If \p MM is nullptr then a default memory mapper is used + /// that directly calls into the operating system. + /// + /// If \p ReserveAlloc is true all memory will be pre-allocated, and any + /// attempts to allocate beyond pre-allocated memory will fail. + SectionMemoryManager(MemoryMapper *MM = nullptr, bool ReserveAlloc = false); + SectionMemoryManager(const SectionMemoryManager &) = delete; + void operator=(const SectionMemoryManager &) = delete; + ~SectionMemoryManager() override; + + /// Enable reserveAllocationSpace when requested. + bool needsToReserveAllocationSpace() override { return ReserveAllocation; } + + /// Implements allocating all memory in a single block. This is required to + /// limit memory offsets to fit the ARM ABI; large memory systems may + /// otherwise allocate separate sections too far apart. +#if LLVM_VERSION_MAJOR < 16 + virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, + uintptr_t RODataSize, + uint32_t RODataAlign, + uintptr_t RWDataSize, + uint32_t RWDataAlign) override; +#else + void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign, + uintptr_t RODataSize, Align RODataAlign, + uintptr_t RWDataSize, Align RWDataAlign) override; +#endif + + /// Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + StringRef SectionName) override; + + /// Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName, + bool isReadOnly) override; + + /// Update section-specific memory permissions and other attributes. + /// + /// This method is called when object loading is complete and section page + /// permissions can be applied. It is up to the memory manager implementation + /// to decide whether or not to act on this method. The memory manager will + /// typically allocate all sections as read-write and then apply specific + /// permissions when this method is called. Code sections cannot be executed + /// until this function has been called. In addition, any cache coherency + /// operations needed to reliably use the memory are also performed. + /// + /// \returns true if an error occurred, false otherwise. + bool finalizeMemory(std::string *ErrMsg = nullptr) override; + + /// Invalidate instruction cache for code sections. + /// + /// Some platforms with separate data cache and instruction cache require + /// explicit cache flush, otherwise JIT code manipulations (like resolved + /// relocations) will get to the data cache but not to the instruction cache. + /// + /// This method is called from finalizeMemory. + virtual void invalidateInstructionCache(); + +private: + struct FreeMemBlock { + // The actual block of free memory + sys::MemoryBlock Free; + // If there is a pending allocation from the same reservation right before + // this block, store it's index in PendingMem, to be able to update the + // pending region if part of this block is allocated, rather than having to + // create a new one + unsigned PendingPrefixIndex; + }; + + struct MemoryGroup { + // PendingMem contains all blocks of memory (subblocks of AllocatedMem) + // which have not yet had their permissions applied, but have been given + // out to the user. FreeMem contains all block of memory, which have + // neither had their permissions applied, nor been given out to the user. + SmallVector PendingMem; + SmallVector FreeMem; + + // All memory blocks that have been requested from the system + SmallVector AllocatedMem; + + sys::MemoryBlock Near; + }; + + uint8_t *allocateSection(AllocationPurpose Purpose, uintptr_t Size, + unsigned Alignment); + + std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions); + + bool hasSpace(const MemoryGroup &MemGroup, uintptr_t Size) const; + + void anchor() override; + + MemoryGroup CodeMem; + MemoryGroup RWDataMem; + MemoryGroup RODataMem; + MemoryMapper *MMapper; + std::unique_ptr OwnedMMapper; + bool ReserveAllocation; +}; + +} // end namespace backport +} // end namespace llvm + +#endif // LLVM_EXECUTIONENGINE_BACKPORT_SECTIONMEMORYMANAGER_H diff --git a/install/include/postgresql/server/jit/jit.h b/install/include/postgresql/server/jit/jit.h new file mode 100644 index 00000000000..14f2e36b371 --- /dev/null +++ b/install/include/postgresql/server/jit/jit.h @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------- + * jit.h + * Provider independent JIT infrastructure. + * + * Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/jit/jit.h + * + *------------------------------------------------------------------------- + */ +#ifndef JIT_H +#define JIT_H + +#include "executor/instrument.h" +#include "utils/resowner.h" + + +/* Flags determining what kind of JIT operations to perform */ +#define PGJIT_NONE 0 +#define PGJIT_PERFORM (1 << 0) +#define PGJIT_OPT3 (1 << 1) +#define PGJIT_INLINE (1 << 2) +#define PGJIT_EXPR (1 << 3) +#define PGJIT_DEFORM (1 << 4) + + +typedef struct JitInstrumentation +{ + /* number of emitted functions */ + size_t created_functions; + + /* accumulated time to generate code */ + instr_time generation_counter; + + /* accumulated time for inlining */ + instr_time inlining_counter; + + /* accumulated time for optimization */ + instr_time optimization_counter; + + /* accumulated time for code emission */ + instr_time emission_counter; +} JitInstrumentation; + +/* + * DSM structure for accumulating jit instrumentation of all workers. + */ +typedef struct SharedJitInstrumentation +{ + int num_workers; + JitInstrumentation jit_instr[FLEXIBLE_ARRAY_MEMBER]; +} SharedJitInstrumentation; + +typedef struct JitContext +{ + /* see PGJIT_* above */ + int flags; + + ResourceOwner resowner; + + JitInstrumentation instr; +} JitContext; + +typedef struct JitProviderCallbacks JitProviderCallbacks; + +extern PGDLLEXPORT void _PG_jit_provider_init(JitProviderCallbacks *cb); +typedef void (*JitProviderInit) (JitProviderCallbacks *cb); +typedef void (*JitProviderResetAfterErrorCB) (void); +typedef void (*JitProviderReleaseContextCB) (JitContext *context); +struct ExprState; +typedef bool (*JitProviderCompileExprCB) (struct ExprState *state); + +struct JitProviderCallbacks +{ + JitProviderResetAfterErrorCB reset_after_error; + JitProviderReleaseContextCB release_context; + JitProviderCompileExprCB compile_expr; +}; + + +/* GUCs */ +extern PGDLLIMPORT bool jit_enabled; +extern PGDLLIMPORT char *jit_provider; +extern PGDLLIMPORT bool jit_debugging_support; +extern PGDLLIMPORT bool jit_dump_bitcode; +extern PGDLLIMPORT bool jit_expressions; +extern PGDLLIMPORT bool jit_profiling_support; +extern PGDLLIMPORT bool jit_tuple_deforming; +extern PGDLLIMPORT double jit_above_cost; +extern PGDLLIMPORT double jit_inline_above_cost; +extern PGDLLIMPORT double jit_optimize_above_cost; + + +extern void jit_reset_after_error(void); +extern void jit_release_context(JitContext *context); + +/* + * Functions for attempting to JIT code. Callers must accept that these might + * not be able to perform JIT (i.e. return false). + */ +extern bool jit_compile_expr(struct ExprState *state); +extern void InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add); + + +#endif /* JIT_H */ diff --git a/install/include/postgresql/server/jit/llvmjit.h b/install/include/postgresql/server/jit/llvmjit.h new file mode 100644 index 00000000000..d079685fb10 --- /dev/null +++ b/install/include/postgresql/server/jit/llvmjit.h @@ -0,0 +1,169 @@ +/*------------------------------------------------------------------------- + * llvmjit.h + * LLVM JIT provider. + * + * Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/jit/llvmjit.h + * + *------------------------------------------------------------------------- + */ +#ifndef LLVMJIT_H +#define LLVMJIT_H + +/* + * To avoid breaking cpluspluscheck, allow including the file even when LLVM + * is not available. + */ +#ifdef USE_LLVM + +#include "jit/llvmjit_backport.h" + +#include +#ifdef USE_LLVM_BACKPORT_SECTION_MEMORY_MANAGER +#include +#endif + + +/* + * File needs to be includable by both C and C++ code, and include other + * headers doing the same. Therefore wrap C portion in our own extern "C" if + * in C++ mode. + */ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "access/tupdesc.h" +#include "fmgr.h" +#include "jit/jit.h" +#include "nodes/pg_list.h" + +typedef struct LLVMJitContext +{ + JitContext base; + + /* number of modules created */ + size_t module_generation; + + /* + * The LLVM Context used by this JIT context. An LLVM context is reused + * across many compilations, but occasionally reset to prevent it using + * too much memory due to more and more types accumulating. + */ + LLVMContextRef llvm_context; + + /* current, "open for write", module */ + LLVMModuleRef module; + + /* is there any pending code that needs to be emitted */ + bool compiled; + + /* # of objects emitted, used to generate non-conflicting names */ + int counter; + + /* list of handles for code emitted via Orc */ + List *handles; +} LLVMJitContext; + +/* llvm module containing information about types */ +extern PGDLLIMPORT LLVMModuleRef llvm_types_module; + +/* type and struct definitions */ +extern PGDLLIMPORT LLVMTypeRef TypeParamBool; +extern PGDLLIMPORT LLVMTypeRef TypePGFunction; +extern PGDLLIMPORT LLVMTypeRef TypeSizeT; +extern PGDLLIMPORT LLVMTypeRef TypeStorageBool; + +extern PGDLLIMPORT LLVMTypeRef StructNullableDatum; +extern PGDLLIMPORT LLVMTypeRef StructTupleDescData; +extern PGDLLIMPORT LLVMTypeRef StructHeapTupleData; +extern PGDLLIMPORT LLVMTypeRef StructHeapTupleHeaderData; +extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleData; +extern PGDLLIMPORT LLVMTypeRef StructTupleTableSlot; +extern PGDLLIMPORT LLVMTypeRef StructHeapTupleTableSlot; +extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleTableSlot; +extern PGDLLIMPORT LLVMTypeRef StructMemoryContextData; +extern PGDLLIMPORT LLVMTypeRef StructFunctionCallInfoData; +extern PGDLLIMPORT LLVMTypeRef StructExprContext; +extern PGDLLIMPORT LLVMTypeRef StructExprEvalStep; +extern PGDLLIMPORT LLVMTypeRef StructExprState; +extern PGDLLIMPORT LLVMTypeRef StructAggState; +extern PGDLLIMPORT LLVMTypeRef StructAggStatePerTransData; +extern PGDLLIMPORT LLVMTypeRef StructAggStatePerGroupData; +extern PGDLLIMPORT LLVMTypeRef StructPlanState; + +extern PGDLLIMPORT LLVMValueRef AttributeTemplate; +extern PGDLLIMPORT LLVMValueRef ExecEvalBoolSubroutineTemplate; +extern PGDLLIMPORT LLVMValueRef ExecEvalSubroutineTemplate; + + +extern void llvm_enter_fatal_on_oom(void); +extern void llvm_leave_fatal_on_oom(void); +extern bool llvm_in_fatal_on_oom(void); +extern void llvm_reset_after_error(void); +extern void llvm_assert_in_fatal_section(void); + +extern LLVMJitContext *llvm_create_context(int jitFlags); +extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context); +extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename); +extern void *llvm_get_function(LLVMJitContext *context, const char *funcname); +extern void llvm_split_symbol_name(const char *name, char **modname, char **funcname); +extern LLVMTypeRef llvm_pg_var_type(const char *varname); +extern LLVMTypeRef llvm_pg_var_func_type(const char *varname); +extern LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname); +extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to); +extern LLVMValueRef llvm_function_reference(LLVMJitContext *context, + LLVMBuilderRef builder, + LLVMModuleRef mod, + FunctionCallInfo fcinfo); + +extern void llvm_inline_reset_caches(void); +extern void llvm_inline(LLVMModuleRef mod); + +/* + **************************************************************************** + * Code generation functions. + **************************************************************************** + */ +extern bool llvm_compile_expr(struct ExprState *state); +struct TupleTableSlotOps; +extern LLVMValueRef slot_compile_deform(struct LLVMJitContext *context, TupleDesc desc, + const struct TupleTableSlotOps *ops, int natts); + +/* + **************************************************************************** + * Extensions / Backward compatibility section of the LLVM C API + * Error handling related functions. + **************************************************************************** + */ +#if defined(HAVE_DECL_LLVMGETHOSTCPUNAME) && !HAVE_DECL_LLVMGETHOSTCPUNAME +/** Get the host CPU as a string. The result needs to be disposed with + LLVMDisposeMessage. */ +extern char *LLVMGetHostCPUName(void); +#endif + +#if defined(HAVE_DECL_LLVMGETHOSTCPUFEATURES) && !HAVE_DECL_LLVMGETHOSTCPUFEATURES +/** Get the host CPU features as a string. The result needs to be disposed + with LLVMDisposeMessage. */ +extern char *LLVMGetHostCPUFeatures(void); +#endif + +extern unsigned LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx); +extern LLVMTypeRef LLVMGetFunctionReturnType(LLVMValueRef r); +extern LLVMTypeRef LLVMGetFunctionType(LLVMValueRef r); +#ifdef USE_LLVM_BACKPORT_SECTION_MEMORY_MANAGER +extern LLVMOrcObjectLayerRef LLVMOrcCreateRTDyldObjectLinkingLayerWithSafeSectionMemoryManager(LLVMOrcExecutionSessionRef ES); +#endif + +#if LLVM_MAJOR_VERSION < 8 +extern LLVMTypeRef LLVMGlobalGetValueType(LLVMValueRef g); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* USE_LLVM */ +#endif /* LLVMJIT_H */ diff --git a/install/include/postgresql/server/jit/llvmjit_backport.h b/install/include/postgresql/server/jit/llvmjit_backport.h new file mode 100644 index 00000000000..92874f7998c --- /dev/null +++ b/install/include/postgresql/server/jit/llvmjit_backport.h @@ -0,0 +1,25 @@ +/* + * A small header than can be included by backported LLVM code or PostgreSQL + * code, to control conditional compilation. + */ +#ifndef LLVMJIT_BACKPORT_H +#define LLVMJIT_BACKPORT_H + +#include + +/* + * LLVM's RuntimeDyld can produce code that crashes on larger memory ARM + * systems, because llvm::SectionMemoryManager allocates multiple pieces of + * memory that can be placed too far apart for the generated code. See + * src/backend/jit/llvm/SectionMemoryManager.cpp for the patched replacement + * class llvm::backport::SectionMemoryManager that we use as a workaround. + * This header controls whether we use it. + * + * We have adjusted it to compile against a range of LLVM versions, but not + * further back than 12 for now. + */ +#if defined(__aarch64__) && LLVM_VERSION_MAJOR > 11 +#define USE_LLVM_BACKPORT_SECTION_MEMORY_MANAGER +#endif + +#endif diff --git a/install/include/postgresql/server/jit/llvmjit_emit.h b/install/include/postgresql/server/jit/llvmjit_emit.h new file mode 100644 index 00000000000..b1f0ea56c08 --- /dev/null +++ b/install/include/postgresql/server/jit/llvmjit_emit.h @@ -0,0 +1,336 @@ +/* + * llvmjit_emit.h + * Helpers to make emitting LLVM IR a bit more concise and pgindent proof. + * + * Copyright (c) 2018-2023, PostgreSQL Global Development Group + * + * src/include/jit/llvmjit_emit.h + */ +#ifndef LLVMJIT_EMIT_H +#define LLVMJIT_EMIT_H + +/* + * To avoid breaking cpluspluscheck, allow including the file even when LLVM + * is not available. + */ +#ifdef USE_LLVM + +#include +#include + +#include "jit/llvmjit.h" + + +/* + * Emit a non-LLVM pointer as an LLVM constant. + */ +static inline LLVMValueRef +l_ptr_const(void *ptr, LLVMTypeRef type) +{ + LLVMValueRef c = LLVMConstInt(TypeSizeT, (uintptr_t) ptr, false); + + return LLVMConstIntToPtr(c, type); +} + +/* + * Emit pointer. + */ +static inline LLVMTypeRef +l_ptr(LLVMTypeRef t) +{ + return LLVMPointerType(t, 0); +} + +/* + * Emit constant integer. + */ +static inline LLVMValueRef +l_int8_const(LLVMContextRef lc, int8 i) +{ + return LLVMConstInt(LLVMInt8TypeInContext(lc), i, false); +} + +/* + * Emit constant integer. + */ +static inline LLVMValueRef +l_int16_const(LLVMContextRef lc, int16 i) +{ + return LLVMConstInt(LLVMInt16TypeInContext(lc), i, false); +} + +/* + * Emit constant integer. + */ +static inline LLVMValueRef +l_int32_const(LLVMContextRef lc, int32 i) +{ + return LLVMConstInt(LLVMInt32TypeInContext(lc), i, false); +} + +/* + * Emit constant integer. + */ +static inline LLVMValueRef +l_int64_const(LLVMContextRef lc, int64 i) +{ + return LLVMConstInt(LLVMInt64TypeInContext(lc), i, false); +} + +/* + * Emit constant integer. + */ +static inline LLVMValueRef +l_sizet_const(size_t i) +{ + return LLVMConstInt(TypeSizeT, i, false); +} + +/* + * Emit constant boolean, as used for storage (e.g. global vars, structs). + */ +static inline LLVMValueRef +l_sbool_const(bool i) +{ + return LLVMConstInt(TypeStorageBool, (int) i, false); +} + +/* + * Emit constant boolean, as used for parameters (e.g. function parameters). + */ +static inline LLVMValueRef +l_pbool_const(bool i) +{ + return LLVMConstInt(TypeParamBool, (int) i, false); +} + +static inline LLVMValueRef +l_struct_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, int32 idx, const char *name) +{ +#if LLVM_VERSION_MAJOR < 16 + return LLVMBuildStructGEP(b, v, idx, ""); +#else + return LLVMBuildStructGEP2(b, t, v, idx, ""); +#endif +} + +static inline LLVMValueRef +l_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef *indices, int32 nindices, const char *name) +{ +#if LLVM_VERSION_MAJOR < 16 + return LLVMBuildGEP(b, v, indices, nindices, name); +#else + return LLVMBuildGEP2(b, t, v, indices, nindices, name); +#endif +} + +static inline LLVMValueRef +l_load(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, const char *name) +{ +#if LLVM_VERSION_MAJOR < 16 + return LLVMBuildLoad(b, v, name); +#else + return LLVMBuildLoad2(b, t, v, name); +#endif +} + +static inline LLVMValueRef +l_call(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef fn, LLVMValueRef *args, int32 nargs, const char *name) +{ +#if LLVM_VERSION_MAJOR < 16 + return LLVMBuildCall(b, fn, args, nargs, name); +#else + return LLVMBuildCall2(b, t, fn, args, nargs, name); +#endif +} + +/* + * Load a pointer member idx from a struct. + */ +static inline LLVMValueRef +l_load_struct_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, int32 idx, const char *name) +{ + return l_load(b, + LLVMStructGetTypeAtIndex(t, idx), + l_struct_gep(b, t, v, idx, ""), + name); +} + +/* + * Load value of a pointer, after applying one index operation. + */ +static inline LLVMValueRef +l_load_gep1(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef idx, const char *name) +{ + return l_load(b, t, l_gep(b, t, v, &idx, 1, ""), name); +} + +/* separate, because pg_attribute_printf(2, 3) can't appear in definition */ +static inline LLVMBasicBlockRef l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...) pg_attribute_printf(2, 3); + +/* + * Insert a new basic block, just before r, the name being determined by fmt + * and arguments. + */ +static inline LLVMBasicBlockRef +l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...) +{ + char buf[512]; + va_list args; + LLVMContextRef lc; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + lc = LLVMGetTypeContext(LLVMTypeOf(LLVMGetBasicBlockParent(r))); + + return LLVMInsertBasicBlockInContext(lc, r, buf); +} + +/* separate, because pg_attribute_printf(2, 3) can't appear in definition */ +static inline LLVMBasicBlockRef l_bb_append_v(LLVMValueRef f, const char *fmt,...) pg_attribute_printf(2, 3); + +/* + * Insert a new basic block after previous basic blocks, the name being + * determined by fmt and arguments. + */ +static inline LLVMBasicBlockRef +l_bb_append_v(LLVMValueRef f, const char *fmt,...) +{ + char buf[512]; + va_list args; + LLVMContextRef lc; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + lc = LLVMGetTypeContext(LLVMTypeOf(f)); + + return LLVMAppendBasicBlockInContext(lc, f, buf); +} + +/* + * Mark a callsite as readonly. + */ +static inline void +l_callsite_ro(LLVMValueRef f) +{ + const char argname[] = "readonly"; + LLVMAttributeRef ref; + + ref = LLVMCreateStringAttribute(LLVMGetTypeContext(LLVMTypeOf(f)), + argname, + sizeof(argname) - 1, + NULL, 0); + + LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, ref); +} + +/* + * Mark a callsite as alwaysinline. + */ +static inline void +l_callsite_alwaysinline(LLVMValueRef f) +{ + const char argname[] = "alwaysinline"; + int id; + LLVMAttributeRef attr; + + id = LLVMGetEnumAttributeKindForName(argname, + sizeof(argname) - 1); + attr = LLVMCreateEnumAttribute(LLVMGetTypeContext(LLVMTypeOf(f)), id, 0); + LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr); +} + +/* + * Emit code to switch memory context. + */ +static inline LLVMValueRef +l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc) +{ + const char *cmc = "CurrentMemoryContext"; + LLVMValueRef cur; + LLVMValueRef ret; + + if (!(cur = LLVMGetNamedGlobal(mod, cmc))) + cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc); + ret = l_load(b, l_ptr(StructMemoryContextData), cur, cmc); + LLVMBuildStore(b, nc, cur); + + return ret; +} + +/* + * Return pointer to the argno'th argument nullness. + */ +static inline LLVMValueRef +l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + LLVMValueRef v_args; + LLVMValueRef v_argn; + + v_args = l_struct_gep(b, + StructFunctionCallInfoData, + v_fcinfo, + FIELDNO_FUNCTIONCALLINFODATA_ARGS, + ""); + v_argn = l_struct_gep(b, + LLVMArrayType(StructNullableDatum, 0), + v_args, + argno, + ""); + return l_struct_gep(b, + StructNullableDatum, + v_argn, + FIELDNO_NULLABLE_DATUM_ISNULL, + ""); +} + +/* + * Return pointer to the argno'th argument datum. + */ +static inline LLVMValueRef +l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + LLVMValueRef v_args; + LLVMValueRef v_argn; + + v_args = l_struct_gep(b, + StructFunctionCallInfoData, + v_fcinfo, + FIELDNO_FUNCTIONCALLINFODATA_ARGS, + ""); + v_argn = l_struct_gep(b, + LLVMArrayType(StructNullableDatum, 0), + v_args, + argno, + ""); + return l_struct_gep(b, + StructNullableDatum, + v_argn, + FIELDNO_NULLABLE_DATUM_DATUM, + ""); +} + +/* + * Return argno'th argument nullness. + */ +static inline LLVMValueRef +l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + return l_load(b, TypeStorageBool, l_funcnullp(b, v_fcinfo, argno), ""); +} + +/* + * Return argno'th argument datum. + */ +static inline LLVMValueRef +l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + return l_load(b, TypeSizeT, l_funcvaluep(b, v_fcinfo, argno), ""); +} + +#endif /* USE_LLVM */ +#endif diff --git a/install/include/postgresql/server/lib/binaryheap.h b/install/include/postgresql/server/lib/binaryheap.h new file mode 100644 index 00000000000..52f7b06b253 --- /dev/null +++ b/install/include/postgresql/server/lib/binaryheap.h @@ -0,0 +1,54 @@ +/* + * binaryheap.h + * + * A simple binary heap implementation + * + * Portions Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + * src/include/lib/binaryheap.h + */ + +#ifndef BINARYHEAP_H +#define BINARYHEAP_H + +/* + * For a max-heap, the comparator must return <0 iff a < b, 0 iff a == b, + * and >0 iff a > b. For a min-heap, the conditions are reversed. + */ +typedef int (*binaryheap_comparator) (Datum a, Datum b, void *arg); + +/* + * binaryheap + * + * bh_size how many nodes are currently in "nodes" + * bh_space how many nodes can be stored in "nodes" + * bh_has_heap_property no unordered operations since last heap build + * bh_compare comparison function to define the heap property + * bh_arg user data for comparison function + * bh_nodes variable-length array of "space" nodes + */ +typedef struct binaryheap +{ + int bh_size; + int bh_space; + bool bh_has_heap_property; /* debugging cross-check */ + binaryheap_comparator bh_compare; + void *bh_arg; + Datum bh_nodes[FLEXIBLE_ARRAY_MEMBER]; +} binaryheap; + +extern binaryheap *binaryheap_allocate(int capacity, + binaryheap_comparator compare, + void *arg); +extern void binaryheap_reset(binaryheap *heap); +extern void binaryheap_free(binaryheap *heap); +extern void binaryheap_add_unordered(binaryheap *heap, Datum d); +extern void binaryheap_build(binaryheap *heap); +extern void binaryheap_add(binaryheap *heap, Datum d); +extern Datum binaryheap_first(binaryheap *heap); +extern Datum binaryheap_remove_first(binaryheap *heap); +extern void binaryheap_replace_first(binaryheap *heap, Datum d); + +#define binaryheap_empty(h) ((h)->bh_size == 0) + +#endif /* BINARYHEAP_H */ diff --git a/install/include/postgresql/server/lib/bipartite_match.h b/install/include/postgresql/server/lib/bipartite_match.h new file mode 100644 index 00000000000..8fbbcaeb500 --- /dev/null +++ b/install/include/postgresql/server/lib/bipartite_match.h @@ -0,0 +1,46 @@ +/* + * bipartite_match.h + * + * Copyright (c) 2015-2023, PostgreSQL Global Development Group + * + * src/include/lib/bipartite_match.h + */ +#ifndef BIPARTITE_MATCH_H +#define BIPARTITE_MATCH_H + +/* + * Given a bipartite graph consisting of nodes U numbered 1..nU, nodes V + * numbered 1..nV, and an adjacency map of undirected edges in the form + * adjacency[u] = [k, v1, v2, v3, ... vk], we wish to find a "maximum + * cardinality matching", which is defined as follows: a matching is a subset + * of the original edges such that no node has more than one edge, and a + * matching has maximum cardinality if there exists no other matching with a + * greater number of edges. + * + * This matching has various applications in graph theory, but the motivating + * example here is Dilworth's theorem: a partially-ordered set can be divided + * into the minimum number of chains (i.e. subsets X where x1 < x2 < x3 ...) by + * a bipartite graph construction. This gives us a polynomial-time solution to + * the problem of planning a collection of grouping sets with the provably + * minimal number of sort operations. + */ +typedef struct BipartiteMatchState +{ + /* inputs: */ + int u_size; /* size of U */ + int v_size; /* size of V */ + short **adjacency; /* adjacency[u] = [k, v1,v2,v3,...,vk] */ + /* outputs: */ + int matching; /* number of edges in matching */ + short *pair_uv; /* pair_uv[u] -> v */ + short *pair_vu; /* pair_vu[v] -> u */ + /* private state for matching algorithm: */ + short *distance; /* distance[u] */ + short *queue; /* queue storage for breadth search */ +} BipartiteMatchState; + +extern BipartiteMatchState *BipartiteMatch(int u_size, int v_size, short **adjacency); + +extern void BipartiteMatchFree(BipartiteMatchState *state); + +#endif /* BIPARTITE_MATCH_H */ diff --git a/install/include/postgresql/server/lib/bloomfilter.h b/install/include/postgresql/server/lib/bloomfilter.h new file mode 100644 index 00000000000..5a98c09ab8a --- /dev/null +++ b/install/include/postgresql/server/lib/bloomfilter.h @@ -0,0 +1,27 @@ +/*------------------------------------------------------------------------- + * + * bloomfilter.h + * Space-efficient set membership testing + * + * Copyright (c) 2018-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/lib/bloomfilter.h + * + *------------------------------------------------------------------------- + */ +#ifndef BLOOMFILTER_H +#define BLOOMFILTER_H + +typedef struct bloom_filter bloom_filter; + +extern bloom_filter *bloom_create(int64 total_elems, int bloom_work_mem, + uint64 seed); +extern void bloom_free(bloom_filter *filter); +extern void bloom_add_element(bloom_filter *filter, unsigned char *elem, + size_t len); +extern bool bloom_lacks_element(bloom_filter *filter, unsigned char *elem, + size_t len); +extern double bloom_prop_bits_set(bloom_filter *filter); + +#endif /* BLOOMFILTER_H */ diff --git a/install/include/postgresql/server/lib/dshash.h b/install/include/postgresql/server/lib/dshash.h new file mode 100644 index 00000000000..ece55521226 --- /dev/null +++ b/install/include/postgresql/server/lib/dshash.h @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------------- + * + * dshash.h + * Concurrent hash tables backed by dynamic shared memory areas. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/lib/dshash.h + * + *------------------------------------------------------------------------- + */ +#ifndef DSHASH_H +#define DSHASH_H + +#include "utils/dsa.h" + +/* The opaque type representing a hash table. */ +struct dshash_table; +typedef struct dshash_table dshash_table; + +/* A handle for a dshash_table which can be shared with other processes. */ +typedef dsa_pointer dshash_table_handle; + +/* Sentinel value to use for invalid dshash_table handles. */ +#define DSHASH_HANDLE_INVALID ((dshash_table_handle) InvalidDsaPointer) + +/* The type for hash values. */ +typedef uint32 dshash_hash; + +/* A function type for comparing keys. */ +typedef int (*dshash_compare_function) (const void *a, const void *b, + size_t size, void *arg); + +/* A function type for computing hash values for keys. */ +typedef dshash_hash (*dshash_hash_function) (const void *v, size_t size, + void *arg); + +/* + * The set of parameters needed to create or attach to a hash table. The + * members tranche_id and tranche_name do not need to be initialized when + * attaching to an existing hash table. + * + * Compare and hash functions must be supplied even when attaching, because we + * can't safely share function pointers between backends in general. Either + * the arg variants or the non-arg variants should be supplied; the other + * function pointers should be NULL. If the arg variants are supplied then the + * user data pointer supplied to the create and attach functions will be + * passed to the hash and compare functions. + */ +typedef struct dshash_parameters +{ + size_t key_size; /* Size of the key (initial bytes of entry) */ + size_t entry_size; /* Total size of entry */ + dshash_compare_function compare_function; /* Compare function */ + dshash_hash_function hash_function; /* Hash function */ + int tranche_id; /* The tranche ID to use for locks */ +} dshash_parameters; + +/* Forward declaration of private types for use only by dshash.c. */ +struct dshash_table_item; +typedef struct dshash_table_item dshash_table_item; + +/* + * Sequential scan state. The detail is exposed to let users know the storage + * size but it should be considered as an opaque type by callers. + */ +typedef struct dshash_seq_status +{ + dshash_table *hash_table; /* dshash table working on */ + int curbucket; /* bucket number we are at */ + int nbuckets; /* total number of buckets in the dshash */ + dshash_table_item *curitem; /* item we are currently at */ + dsa_pointer pnextitem; /* dsa-pointer to the next item */ + int curpartition; /* partition number we are at */ + bool exclusive; /* locking mode */ +} dshash_seq_status; + +/* Creating, sharing and destroying from hash tables. */ +extern dshash_table *dshash_create(dsa_area *area, + const dshash_parameters *params, + void *arg); +extern dshash_table *dshash_attach(dsa_area *area, + const dshash_parameters *params, + dshash_table_handle handle, + void *arg); +extern void dshash_detach(dshash_table *hash_table); +extern dshash_table_handle dshash_get_hash_table_handle(dshash_table *hash_table); +extern void dshash_destroy(dshash_table *hash_table); + +/* Finding, creating, deleting entries. */ +extern void *dshash_find(dshash_table *hash_table, + const void *key, bool exclusive); +extern void *dshash_find_or_insert(dshash_table *hash_table, + const void *key, bool *found); +extern bool dshash_delete_key(dshash_table *hash_table, const void *key); +extern void dshash_delete_entry(dshash_table *hash_table, void *entry); +extern void dshash_release_lock(dshash_table *hash_table, void *entry); + +/* seq scan support */ +extern void dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table, + bool exclusive); +extern void *dshash_seq_next(dshash_seq_status *status); +extern void dshash_seq_term(dshash_seq_status *status); +extern void dshash_delete_current(dshash_seq_status *status); + +/* Convenience hash and compare functions wrapping memcmp and tag_hash. */ +extern int dshash_memcmp(const void *a, const void *b, size_t size, void *arg); +extern dshash_hash dshash_memhash(const void *v, size_t size, void *arg); + +/* Debugging support. */ +extern void dshash_dump(dshash_table *hash_table); + +#endif /* DSHASH_H */ diff --git a/install/include/postgresql/server/lib/hyperloglog.h b/install/include/postgresql/server/lib/hyperloglog.h new file mode 100644 index 00000000000..f4150f0e85a --- /dev/null +++ b/install/include/postgresql/server/lib/hyperloglog.h @@ -0,0 +1,68 @@ +/* + * hyperloglog.h + * + * A simple HyperLogLog cardinality estimator implementation + * + * Portions Copyright (c) 2014-2023, PostgreSQL Global Development Group + * + * Based on Hideaki Ohno's C++ implementation. The copyright terms of Ohno's + * original version (the MIT license) follow. + * + * src/include/lib/hyperloglog.h + */ + +/* + * Copyright (c) 2013 Hideaki Ohno + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the 'Software'), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef HYPERLOGLOG_H +#define HYPERLOGLOG_H + +/* + * HyperLogLog is an approximate technique for computing the number of distinct + * entries in a set. Importantly, it does this by using a fixed amount of + * memory. See the 2007 paper "HyperLogLog: the analysis of a near-optimal + * cardinality estimation algorithm" for more. + * + * hyperLogLogState + * + * registerWidth register width, in bits ("k") + * nRegisters number of registers + * alphaMM alpha * m ^ 2 (see initHyperLogLog()) + * hashesArr array of hashes + * arrSize size of hashesArr + */ +typedef struct hyperLogLogState +{ + uint8 registerWidth; + Size nRegisters; + double alphaMM; + uint8 *hashesArr; + Size arrSize; +} hyperLogLogState; + +extern void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth); +extern void initHyperLogLogError(hyperLogLogState *cState, double error); +extern void addHyperLogLog(hyperLogLogState *cState, uint32 hash); +extern double estimateHyperLogLog(hyperLogLogState *cState); +extern void freeHyperLogLog(hyperLogLogState *cState); + +#endif /* HYPERLOGLOG_H */ diff --git a/install/include/postgresql/server/lib/ilist.h b/install/include/postgresql/server/lib/ilist.h new file mode 100644 index 00000000000..095107a99c4 --- /dev/null +++ b/install/include/postgresql/server/lib/ilist.h @@ -0,0 +1,1159 @@ +/*------------------------------------------------------------------------- + * + * ilist.h + * integrated/inline doubly- and singly-linked lists + * + * These list types are useful when there are only a predetermined set of + * lists that an object could be in. List links are embedded directly into + * the objects, and thus no extra memory management overhead is required. + * (Of course, if only a small proportion of existing objects are in a list, + * the link fields in the remainder would be wasted space. But usually, + * it saves space to not have separately-allocated list nodes.) + * + * The doubly-linked list comes in 2 forms. dlist_head defines a head of a + * doubly-linked list of dlist_nodes, whereas dclist_head defines the head of + * a doubly-linked list of dlist_nodes with an additional 'count' field to + * keep track of how many items are contained within the given list. For + * simplicity, dlist_head and dclist_head share the same node and iterator + * types. The functions to manipulate a dlist_head always have a name + * starting with "dlist", whereas functions to manipulate a dclist_head have a + * name starting with "dclist". dclist_head comes with an additional function + * (dclist_count) to return the number of entries in the list. dclists are + * able to store a maximum of PG_UINT32_MAX elements. It is up to the caller + * to ensure no more than this many items are added to a dclist. + * + * None of the functions here allocate any memory; they just manipulate + * externally managed memory. With the exception doubly-linked count lists + * providing the ability to obtain the number of items in the list, the APIs + * for singly and both doubly linked lists are identical as far as + * capabilities of both allow. + * + * Each list has a list header, which exists even when the list is empty. + * An empty singly-linked list has a NULL pointer in its header. + * + * For both doubly-linked list types, there are two valid ways to represent an + * empty list. The head's 'next' pointer can either be NULL or the head's + * 'next' and 'prev' links can both point back to the list head (circular). + * (If a dlist is modified and then all its elements are deleted, it will be + * in the circular state.). We prefer circular dlists because there are some + * operations that can be done without branches (and thus faster) on lists + * that use circular representation. However, it is often convenient to + * initialize list headers to zeroes rather than setting them up with an + * explicit initialization function, so we also allow the NULL initialization. + * + * EXAMPLES + * + * Here's a simple example demonstrating how this can be used. Let's assume + * we want to store information about the tables contained in a database. + * + * #include "lib/ilist.h" + * + * // Define struct for the databases including a list header that will be + * // used to access the nodes in the table list later on. + * typedef struct my_database + * { + * char *datname; + * dlist_head tables; + * // ... + * } my_database; + * + * // Define struct for the tables. Note the list_node element which stores + * // prev/next list links. The list_node element need not be first. + * typedef struct my_table + * { + * char *tablename; + * dlist_node list_node; + * perm_t permissions; + * // ... + * } my_table; + * + * // create a database + * my_database *db = create_database(); + * + * // and add a few tables to its table list + * dlist_push_head(&db->tables, &create_table(db, "a")->list_node); + * ... + * dlist_push_head(&db->tables, &create_table(db, "b")->list_node); + * + * + * To iterate over the table list, we allocate an iterator variable and use + * a specialized looping construct. Inside a dlist_foreach, the iterator's + * 'cur' field can be used to access the current element. iter.cur points to + * a 'dlist_node', but most of the time what we want is the actual table + * information; dlist_container() gives us that, like so: + * + * dlist_iter iter; + * dlist_foreach(iter, &db->tables) + * { + * my_table *tbl = dlist_container(my_table, list_node, iter.cur); + * printf("we have a table: %s in database %s\n", + * tbl->tablename, db->datname); + * } + * + * + * While a simple iteration is useful, we sometimes also want to manipulate + * the list while iterating. There is a different iterator element and looping + * construct for that. Suppose we want to delete tables that meet a certain + * criterion: + * + * dlist_mutable_iter miter; + * dlist_foreach_modify(miter, &db->tables) + * { + * my_table *tbl = dlist_container(my_table, list_node, miter.cur); + * + * if (!tbl->to_be_deleted) + * continue; // don't touch this one + * + * // unlink the current table from the linked list + * dlist_delete(miter.cur); + * // as these lists never manage memory, we can still access the table + * // after it's been unlinked + * drop_table(db, tbl); + * } + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/lib/ilist.h + *------------------------------------------------------------------------- + */ +#ifndef ILIST_H +#define ILIST_H + +/* + * Enable for extra debugging. This is rather expensive, so it's not enabled by + * default even when USE_ASSERT_CHECKING. + */ +/* #define ILIST_DEBUG */ + +/* + * Node of a doubly linked list. + * + * Embed this in structs that need to be part of a doubly linked list. + */ +typedef struct dlist_node dlist_node; +struct dlist_node +{ + dlist_node *prev; + dlist_node *next; +}; + +/* + * Head of a doubly linked list. + * + * Non-empty lists are internally circularly linked. Circular lists have the + * advantage of not needing any branches in the most common list manipulations. + * An empty list can also be represented as a pair of NULL pointers, making + * initialization easier. + */ +typedef struct dlist_head +{ + /* + * head.next either points to the first element of the list; to &head if + * it's a circular empty list; or to NULL if empty and not circular. + * + * head.prev either points to the last element of the list; to &head if + * it's a circular empty list; or to NULL if empty and not circular. + */ + dlist_node head; +} dlist_head; + + +/* + * Doubly linked list iterator type for dlist_head and dclist_head types. + * + * Used as state in dlist_foreach() and dlist_reverse_foreach() (and the + * dclist variant thereof). + * + * To get the current element of the iteration use the 'cur' member. + * + * Iterations using this are *not* allowed to change the list while iterating! + * + * NB: We use an extra "end" field here to avoid multiple evaluations of + * arguments in the dlist_foreach() and dclist_foreach() macros. + */ +typedef struct dlist_iter +{ + dlist_node *cur; /* current element */ + dlist_node *end; /* last node we'll iterate to */ +} dlist_iter; + +/* + * Doubly linked list iterator for both dlist_head and dclist_head types. + * This iterator type allows some modifications while iterating. + * + * Used as state in dlist_foreach_modify() and dclist_foreach_modify(). + * + * To get the current element of the iteration use the 'cur' member. + * + * Iterations using this are only allowed to change the list at the current + * point of iteration. It is fine to delete the current node, but it is *not* + * fine to insert or delete adjacent nodes. + * + * NB: We need a separate type for mutable iterations so that we can store + * the 'next' node of the current node in case it gets deleted or modified. + */ +typedef struct dlist_mutable_iter +{ + dlist_node *cur; /* current element */ + dlist_node *next; /* next node we'll iterate to */ + dlist_node *end; /* last node we'll iterate to */ +} dlist_mutable_iter; + +/* + * Head of a doubly linked list with a count of the number of items + * + * This internally makes use of a dlist to implement the actual list. When + * items are added or removed from the list the count is updated to reflect + * the current number of items in the list. + */ +typedef struct dclist_head +{ + dlist_head dlist; /* the actual list header */ + uint32 count; /* the number of items in the list */ +} dclist_head; + +/* + * Node of a singly linked list. + * + * Embed this in structs that need to be part of a singly linked list. + */ +typedef struct slist_node slist_node; +struct slist_node +{ + slist_node *next; +}; + +/* + * Head of a singly linked list. + * + * Singly linked lists are not circularly linked, in contrast to doubly linked + * lists; we just set head.next to NULL if empty. This doesn't incur any + * additional branches in the usual manipulations. + */ +typedef struct slist_head +{ + slist_node head; +} slist_head; + +/* + * Singly linked list iterator. + * + * Used as state in slist_foreach(). To get the current element of the + * iteration use the 'cur' member. + * + * It's allowed to modify the list while iterating, with the exception of + * deleting the iterator's current node; deletion of that node requires + * care if the iteration is to be continued afterward. (Doing so and also + * deleting or inserting adjacent list elements might misbehave; also, if + * the user frees the current node's storage, continuing the iteration is + * not safe.) + * + * NB: this wouldn't really need to be an extra struct, we could use an + * slist_node * directly. We prefer a separate type for consistency. + */ +typedef struct slist_iter +{ + slist_node *cur; +} slist_iter; + +/* + * Singly linked list iterator allowing some modifications while iterating. + * + * Used as state in slist_foreach_modify(). To get the current element of the + * iteration use the 'cur' member. + * + * The only list modification allowed while iterating is to remove the current + * node via slist_delete_current() (*not* slist_delete()). Insertion or + * deletion of nodes adjacent to the current node would misbehave. + */ +typedef struct slist_mutable_iter +{ + slist_node *cur; /* current element */ + slist_node *next; /* next node we'll iterate to */ + slist_node *prev; /* prev node, for deletions */ +} slist_mutable_iter; + + +/* Static initializers */ +#define DLIST_STATIC_INIT(name) {{&(name).head, &(name).head}} +#define DCLIST_STATIC_INIT(name) {{{&(name).dlist.head, &(name).dlist.head}}, 0} +#define SLIST_STATIC_INIT(name) {{NULL}} + + +/* Prototypes for functions too big to be inline */ + +/* Caution: this is O(n); consider using slist_delete_current() instead */ +extern void slist_delete(slist_head *head, const slist_node *node); + +#ifdef ILIST_DEBUG +extern void dlist_member_check(const dlist_head *head, const dlist_node *node); +extern void dlist_check(const dlist_head *head); +extern void slist_check(const slist_head *head); +#else +/* + * These seemingly useless casts to void are here to keep the compiler quiet + * about the argument being unused in many functions in a non-debug compile, + * in which functions the only point of passing the list head pointer is to be + * able to run these checks. + */ +#define dlist_member_check(head, node) ((void) (head)) +#define dlist_check(head) ((void) (head)) +#define slist_check(head) ((void) (head)) +#endif /* ILIST_DEBUG */ + +/* doubly linked list implementation */ + +/* + * Initialize a doubly linked list. + * Previous state will be thrown away without any cleanup. + */ +static inline void +dlist_init(dlist_head *head) +{ + head->head.next = head->head.prev = &head->head; +} + +/* + * Initialize a doubly linked list element. + * + * This is only needed when dlist_node_is_detached() may be needed. + */ +static inline void +dlist_node_init(dlist_node *node) +{ + node->next = node->prev = NULL; +} + +/* + * Is the list empty? + * + * An empty list has either its first 'next' pointer set to NULL, or to itself. + */ +static inline bool +dlist_is_empty(const dlist_head *head) +{ + dlist_check(head); + + return head->head.next == NULL || head->head.next == &(head->head); +} + +/* + * Insert a node at the beginning of the list. + */ +static inline void +dlist_push_head(dlist_head *head, dlist_node *node) +{ + if (head->head.next == NULL) /* convert NULL header to circular */ + dlist_init(head); + + node->next = head->head.next; + node->prev = &head->head; + node->next->prev = node; + head->head.next = node; + + dlist_check(head); +} + +/* + * Insert a node at the end of the list. + */ +static inline void +dlist_push_tail(dlist_head *head, dlist_node *node) +{ + if (head->head.next == NULL) /* convert NULL header to circular */ + dlist_init(head); + + node->next = &head->head; + node->prev = head->head.prev; + node->prev->next = node; + head->head.prev = node; + + dlist_check(head); +} + +/* + * Insert a node after another *in the same list* + */ +static inline void +dlist_insert_after(dlist_node *after, dlist_node *node) +{ + node->prev = after; + node->next = after->next; + after->next = node; + node->next->prev = node; +} + +/* + * Insert a node before another *in the same list* + */ +static inline void +dlist_insert_before(dlist_node *before, dlist_node *node) +{ + node->prev = before->prev; + node->next = before; + before->prev = node; + node->prev->next = node; +} + +/* + * Delete 'node' from its list (it must be in one). + */ +static inline void +dlist_delete(dlist_node *node) +{ + node->prev->next = node->next; + node->next->prev = node->prev; +} + +/* + * Like dlist_delete(), but also sets next/prev to NULL to signal not being in + * a list. + */ +static inline void +dlist_delete_thoroughly(dlist_node *node) +{ + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = NULL; + node->prev = NULL; +} + +/* + * Same as dlist_delete, but performs checks in ILIST_DEBUG builds to ensure + * that 'node' belongs to 'head'. + */ +static inline void +dlist_delete_from(dlist_head *head, dlist_node *node) +{ + dlist_member_check(head, node); + dlist_delete(node); +} + +/* + * Like dlist_delete_from, but also sets next/prev to NULL to signal not + * being in a list. + */ +static inline void +dlist_delete_from_thoroughly(dlist_head *head, dlist_node *node) +{ + dlist_member_check(head, node); + dlist_delete_thoroughly(node); +} + +/* + * Remove and return the first node from a list (there must be one). + */ +static inline dlist_node * +dlist_pop_head_node(dlist_head *head) +{ + dlist_node *node; + + Assert(!dlist_is_empty(head)); + node = head->head.next; + dlist_delete(node); + return node; +} + +/* + * Move element from its current position in the list to the head position in + * the same list. + * + * Undefined behaviour if 'node' is not already part of the list. + */ +static inline void +dlist_move_head(dlist_head *head, dlist_node *node) +{ + /* fast path if it's already at the head */ + if (head->head.next == node) + return; + + dlist_delete(node); + dlist_push_head(head, node); + + dlist_check(head); +} + +/* + * Move element from its current position in the list to the tail position in + * the same list. + * + * Undefined behaviour if 'node' is not already part of the list. + */ +static inline void +dlist_move_tail(dlist_head *head, dlist_node *node) +{ + /* fast path if it's already at the tail */ + if (head->head.prev == node) + return; + + dlist_delete(node); + dlist_push_tail(head, node); + + dlist_check(head); +} + +/* + * Check whether 'node' has a following node. + * Caution: unreliable if 'node' is not in the list. + */ +static inline bool +dlist_has_next(const dlist_head *head, const dlist_node *node) +{ + return node->next != &head->head; +} + +/* + * Check whether 'node' has a preceding node. + * Caution: unreliable if 'node' is not in the list. + */ +static inline bool +dlist_has_prev(const dlist_head *head, const dlist_node *node) +{ + return node->prev != &head->head; +} + +/* + * Check if node is detached. A node is only detached if it either has been + * initialized with dlist_init_node(), or deleted with + * dlist_delete_thoroughly() / dlist_delete_from_thoroughly() / + * dclist_delete_from_thoroughly(). + */ +static inline bool +dlist_node_is_detached(const dlist_node *node) +{ + Assert((node->next == NULL && node->prev == NULL) || + (node->next != NULL && node->prev != NULL)); + + return node->next == NULL; +} + +/* + * Return the next node in the list (there must be one). + */ +static inline dlist_node * +dlist_next_node(dlist_head *head, dlist_node *node) +{ + Assert(dlist_has_next(head, node)); + return node->next; +} + +/* + * Return previous node in the list (there must be one). + */ +static inline dlist_node * +dlist_prev_node(dlist_head *head, dlist_node *node) +{ + Assert(dlist_has_prev(head, node)); + return node->prev; +} + +/* internal support function to get address of head element's struct */ +static inline void * +dlist_head_element_off(dlist_head *head, size_t off) +{ + Assert(!dlist_is_empty(head)); + return (char *) head->head.next - off; +} + +/* + * Return the first node in the list (there must be one). + */ +static inline dlist_node * +dlist_head_node(dlist_head *head) +{ + return (dlist_node *) dlist_head_element_off(head, 0); +} + +/* internal support function to get address of tail element's struct */ +static inline void * +dlist_tail_element_off(dlist_head *head, size_t off) +{ + Assert(!dlist_is_empty(head)); + return (char *) head->head.prev - off; +} + +/* + * Return the last node in the list (there must be one). + */ +static inline dlist_node * +dlist_tail_node(dlist_head *head) +{ + return (dlist_node *) dlist_tail_element_off(head, 0); +} + +/* + * Return the containing struct of 'type' where 'membername' is the dlist_node + * pointed at by 'ptr'. + * + * This is used to convert a dlist_node * back to its containing struct. + */ +#define dlist_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, dlist_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + ((type *) ((char *) (ptr) - offsetof(type, membername)))) + +/* + * Return the address of the first element in the list. + * + * The list must not be empty. + */ +#define dlist_head_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + (type *) dlist_head_element_off(lhead, offsetof(type, membername))) + +/* + * Return the address of the last element in the list. + * + * The list must not be empty. + */ +#define dlist_tail_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + ((type *) dlist_tail_element_off(lhead, offsetof(type, membername)))) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * It is *not* allowed to manipulate the list during iteration. + */ +#define dlist_foreach(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, dlist_iter), \ + AssertVariableIsOfTypeMacro(lhead, dlist_head *), \ + (iter).end = &(lhead)->head, \ + (iter).cur = (iter).end->next ? (iter).end->next : (iter).end; \ + (iter).cur != (iter).end; \ + (iter).cur = (iter).cur->next) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * Iterations using this are only allowed to change the list at the current + * point of iteration. It is fine to delete the current node, but it is *not* + * fine to insert or delete adjacent nodes. + */ +#define dlist_foreach_modify(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, dlist_mutable_iter), \ + AssertVariableIsOfTypeMacro(lhead, dlist_head *), \ + (iter).end = &(lhead)->head, \ + (iter).cur = (iter).end->next ? (iter).end->next : (iter).end, \ + (iter).next = (iter).cur->next; \ + (iter).cur != (iter).end; \ + (iter).cur = (iter).next, (iter).next = (iter).cur->next) + +/* + * Iterate through the list in reverse order. + * + * It is *not* allowed to manipulate the list during iteration. + */ +#define dlist_reverse_foreach(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, dlist_iter), \ + AssertVariableIsOfTypeMacro(lhead, dlist_head *), \ + (iter).end = &(lhead)->head, \ + (iter).cur = (iter).end->prev ? (iter).end->prev : (iter).end; \ + (iter).cur != (iter).end; \ + (iter).cur = (iter).cur->prev) + +/* doubly-linked count list implementation */ + +/* + * dclist_init + * Initialize a doubly linked count list. + * + * Previous state will be thrown away without any cleanup. + */ +static inline void +dclist_init(dclist_head *head) +{ + dlist_init(&head->dlist); + head->count = 0; +} + +/* + * dclist_is_empty + * Returns true if the list is empty, otherwise false. + */ +static inline bool +dclist_is_empty(const dclist_head *head) +{ + Assert(dlist_is_empty(&head->dlist) == (head->count == 0)); + return (head->count == 0); +} + +/* + * dclist_push_head + * Insert a node at the beginning of the list. + */ +static inline void +dclist_push_head(dclist_head *head, dlist_node *node) +{ + if (head->dlist.head.next == NULL) /* convert NULL header to circular */ + dclist_init(head); + + dlist_push_head(&head->dlist, node); + head->count++; + + Assert(head->count > 0); /* count overflow check */ +} + +/* + * dclist_push_tail + * Insert a node at the end of the list. + */ +static inline void +dclist_push_tail(dclist_head *head, dlist_node *node) +{ + if (head->dlist.head.next == NULL) /* convert NULL header to circular */ + dclist_init(head); + + dlist_push_tail(&head->dlist, node); + head->count++; + + Assert(head->count > 0); /* count overflow check */ +} + +/* + * dclist_insert_after + * Insert a node after another *in the same list* + * + * Caution: 'after' must be a member of 'head'. + */ +static inline void +dclist_insert_after(dclist_head *head, dlist_node *after, dlist_node *node) +{ + dlist_member_check(&head->dlist, after); + Assert(head->count > 0); /* must be at least 1 already */ + + dlist_insert_after(after, node); + head->count++; + + Assert(head->count > 0); /* count overflow check */ +} + +/* + * dclist_insert_before + * Insert a node before another *in the same list* + * + * Caution: 'before' must be a member of 'head'. + */ +static inline void +dclist_insert_before(dclist_head *head, dlist_node *before, dlist_node *node) +{ + dlist_member_check(&head->dlist, before); + Assert(head->count > 0); /* must be at least 1 already */ + + dlist_insert_before(before, node); + head->count++; + + Assert(head->count > 0); /* count overflow check */ +} + +/* + * dclist_delete_from + * Deletes 'node' from 'head'. + * + * Caution: 'node' must be a member of 'head'. + */ +static inline void +dclist_delete_from(dclist_head *head, dlist_node *node) +{ + Assert(head->count > 0); + + dlist_delete_from(&head->dlist, node); + head->count--; +} + +/* + * Like dclist_delete_from(), but also sets next/prev to NULL to signal not + * being in a list. + */ +static inline void +dclist_delete_from_thoroughly(dclist_head *head, dlist_node *node) +{ + Assert(head->count > 0); + + dlist_delete_from_thoroughly(&head->dlist, node); + head->count--; +} + +/* + * dclist_pop_head_node + * Remove and return the first node from a list (there must be one). + */ +static inline dlist_node * +dclist_pop_head_node(dclist_head *head) +{ + dlist_node *node; + + Assert(head->count > 0); + + node = dlist_pop_head_node(&head->dlist); + head->count--; + return node; +} + +/* + * dclist_move_head + * Move 'node' from its current position in the list to the head position + * in 'head'. + * + * Caution: 'node' must be a member of 'head'. + */ +static inline void +dclist_move_head(dclist_head *head, dlist_node *node) +{ + dlist_member_check(&head->dlist, node); + Assert(head->count > 0); + + dlist_move_head(&head->dlist, node); +} + +/* + * dclist_move_tail + * Move 'node' from its current position in the list to the tail position + * in 'head'. + * + * Caution: 'node' must be a member of 'head'. + */ +static inline void +dclist_move_tail(dclist_head *head, dlist_node *node) +{ + dlist_member_check(&head->dlist, node); + Assert(head->count > 0); + + dlist_move_tail(&head->dlist, node); +} + +/* + * dclist_has_next + * Check whether 'node' has a following node. + * + * Caution: 'node' must be a member of 'head'. + */ +static inline bool +dclist_has_next(const dclist_head *head, const dlist_node *node) +{ + dlist_member_check(&head->dlist, node); + Assert(head->count > 0); + + return dlist_has_next(&head->dlist, node); +} + +/* + * dclist_has_prev + * Check whether 'node' has a preceding node. + * + * Caution: 'node' must be a member of 'head'. + */ +static inline bool +dclist_has_prev(const dclist_head *head, const dlist_node *node) +{ + dlist_member_check(&head->dlist, node); + Assert(head->count > 0); + + return dlist_has_prev(&head->dlist, node); +} + +/* + * dclist_next_node + * Return the next node in the list (there must be one). + */ +static inline dlist_node * +dclist_next_node(dclist_head *head, dlist_node *node) +{ + Assert(head->count > 0); + + return dlist_next_node(&head->dlist, node); +} + +/* + * dclist_prev_node + * Return the prev node in the list (there must be one). + */ +static inline dlist_node * +dclist_prev_node(dclist_head *head, dlist_node *node) +{ + Assert(head->count > 0); + + return dlist_prev_node(&head->dlist, node); +} + +/* internal support function to get address of head element's struct */ +static inline void * +dclist_head_element_off(dclist_head *head, size_t off) +{ + Assert(!dclist_is_empty(head)); + + return (char *) head->dlist.head.next - off; +} + +/* + * dclist_head_node + * Return the first node in the list (there must be one). + */ +static inline dlist_node * +dclist_head_node(dclist_head *head) +{ + Assert(head->count > 0); + + return (dlist_node *) dlist_head_element_off(&head->dlist, 0); +} + +/* internal support function to get address of tail element's struct */ +static inline void * +dclist_tail_element_off(dclist_head *head, size_t off) +{ + Assert(!dclist_is_empty(head)); + + return (char *) head->dlist.head.prev - off; +} + +/* + * Return the last node in the list (there must be one). + */ +static inline dlist_node * +dclist_tail_node(dclist_head *head) +{ + Assert(head->count > 0); + + return (dlist_node *) dlist_tail_element_off(&head->dlist, 0); +} + +/* + * dclist_count + * Returns the stored number of entries in 'head' + */ +static inline uint32 +dclist_count(const dclist_head *head) +{ + Assert(dlist_is_empty(&head->dlist) == (head->count == 0)); + + return head->count; +} + +/* + * Return the containing struct of 'type' where 'membername' is the dlist_node + * pointed at by 'ptr'. + * + * This is used to convert a dlist_node * back to its containing struct. + * + * Note: This is effectively just the same as dlist_container, so reuse that. + */ +#define dclist_container(type, membername, ptr) \ + dlist_container(type, membername, ptr) + + /* + * Return the address of the first element in the list. + * + * The list must not be empty. + */ +#define dclist_head_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + (type *) dclist_head_element_off(lhead, offsetof(type, membername))) + + /* + * Return the address of the last element in the list. + * + * The list must not be empty. + */ +#define dclist_tail_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + ((type *) dclist_tail_element_off(lhead, offsetof(type, membername)))) + + +/* Iterators for dclists */ +#define dclist_foreach(iter, lhead) \ + dlist_foreach(iter, &((lhead)->dlist)) + +#define dclist_foreach_modify(iter, lhead) \ + dlist_foreach_modify(iter, &((lhead)->dlist)) + +#define dclist_reverse_foreach(iter, lhead) \ + dlist_reverse_foreach(iter, &((lhead)->dlist)) + +/* singly linked list implementation */ + +/* + * Initialize a singly linked list. + * Previous state will be thrown away without any cleanup. + */ +static inline void +slist_init(slist_head *head) +{ + head->head.next = NULL; +} + +/* + * Is the list empty? + */ +static inline bool +slist_is_empty(const slist_head *head) +{ + slist_check(head); + + return head->head.next == NULL; +} + +/* + * Insert a node at the beginning of the list. + */ +static inline void +slist_push_head(slist_head *head, slist_node *node) +{ + node->next = head->head.next; + head->head.next = node; + + slist_check(head); +} + +/* + * Insert a node after another *in the same list* + */ +static inline void +slist_insert_after(slist_node *after, slist_node *node) +{ + node->next = after->next; + after->next = node; +} + +/* + * Remove and return the first node from a list (there must be one). + */ +static inline slist_node * +slist_pop_head_node(slist_head *head) +{ + slist_node *node; + + Assert(!slist_is_empty(head)); + node = head->head.next; + head->head.next = node->next; + slist_check(head); + return node; +} + +/* + * Check whether 'node' has a following node. + */ +static inline bool +slist_has_next(const slist_head *head, const slist_node *node) +{ + slist_check(head); + + return node->next != NULL; +} + +/* + * Return the next node in the list (there must be one). + */ +static inline slist_node * +slist_next_node(slist_head *head, slist_node *node) +{ + Assert(slist_has_next(head, node)); + return node->next; +} + +/* internal support function to get address of head element's struct */ +static inline void * +slist_head_element_off(slist_head *head, size_t off) +{ + Assert(!slist_is_empty(head)); + return (char *) head->head.next - off; +} + +/* + * Return the first node in the list (there must be one). + */ +static inline slist_node * +slist_head_node(slist_head *head) +{ + return (slist_node *) slist_head_element_off(head, 0); +} + +/* + * Delete the list element the iterator currently points to. + * + * Caution: this modifies iter->cur, so don't use that again in the current + * loop iteration. + */ +static inline void +slist_delete_current(slist_mutable_iter *iter) +{ + /* + * Update previous element's forward link. If the iteration is at the + * first list element, iter->prev will point to the list header's "head" + * field, so we don't need a special case for that. + */ + iter->prev->next = iter->next; + + /* + * Reset cur to prev, so that prev will continue to point to the prior + * valid list element after slist_foreach_modify() advances to the next. + */ + iter->cur = iter->prev; +} + +/* + * Return the containing struct of 'type' where 'membername' is the slist_node + * pointed at by 'ptr'. + * + * This is used to convert a slist_node * back to its containing struct. + */ +#define slist_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, slist_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node), \ + ((type *) ((char *) (ptr) - offsetof(type, membername)))) + +/* + * Return the address of the first element in the list. + * + * The list must not be empty. + */ +#define slist_head_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node), \ + (type *) slist_head_element_off(lhead, offsetof(type, membername))) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * It's allowed to modify the list while iterating, with the exception of + * deleting the iterator's current node; deletion of that node requires + * care if the iteration is to be continued afterward. (Doing so and also + * deleting or inserting adjacent list elements might misbehave; also, if + * the user frees the current node's storage, continuing the iteration is + * not safe.) + */ +#define slist_foreach(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, slist_iter), \ + AssertVariableIsOfTypeMacro(lhead, slist_head *), \ + (iter).cur = (lhead)->head.next; \ + (iter).cur != NULL; \ + (iter).cur = (iter).cur->next) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * The only list modification allowed while iterating is to remove the current + * node via slist_delete_current() (*not* slist_delete()). Insertion or + * deletion of nodes adjacent to the current node would misbehave. + */ +#define slist_foreach_modify(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, slist_mutable_iter), \ + AssertVariableIsOfTypeMacro(lhead, slist_head *), \ + (iter).prev = &(lhead)->head, \ + (iter).cur = (iter).prev->next, \ + (iter).next = (iter).cur ? (iter).cur->next : NULL; \ + (iter).cur != NULL; \ + (iter).prev = (iter).cur, \ + (iter).cur = (iter).next, \ + (iter).next = (iter).next ? (iter).next->next : NULL) + +#endif /* ILIST_H */ diff --git a/install/include/postgresql/server/lib/integerset.h b/install/include/postgresql/server/lib/integerset.h new file mode 100644 index 00000000000..d7f711ee8b6 --- /dev/null +++ b/install/include/postgresql/server/lib/integerset.h @@ -0,0 +1,24 @@ +/* + * integerset.h + * In-memory data structure to hold a large set of integers efficiently + * + * Portions Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + * src/include/lib/integerset.h + */ +#ifndef INTEGERSET_H +#define INTEGERSET_H + +typedef struct IntegerSet IntegerSet; + +extern IntegerSet *intset_create(void); +extern void intset_add_member(IntegerSet *intset, uint64 x); +extern bool intset_is_member(IntegerSet *intset, uint64 x); + +extern uint64 intset_num_entries(IntegerSet *intset); +extern uint64 intset_memory_usage(IntegerSet *intset); + +extern void intset_begin_iterate(IntegerSet *intset); +extern bool intset_iterate_next(IntegerSet *intset, uint64 *next); + +#endif /* INTEGERSET_H */ diff --git a/install/include/postgresql/server/lib/knapsack.h b/install/include/postgresql/server/lib/knapsack.h new file mode 100644 index 00000000000..04427ba7b5c --- /dev/null +++ b/install/include/postgresql/server/lib/knapsack.h @@ -0,0 +1,16 @@ +/* + * knapsack.h + * + * Copyright (c) 2017-2023, PostgreSQL Global Development Group + * + * src/include/lib/knapsack.h + */ +#ifndef KNAPSACK_H +#define KNAPSACK_H + +#include "nodes/bitmapset.h" + +extern Bitmapset *DiscreteKnapsack(int max_weight, int num_items, + int *item_weights, double *item_values); + +#endif /* KNAPSACK_H */ diff --git a/install/include/postgresql/server/lib/pairingheap.h b/install/include/postgresql/server/lib/pairingheap.h new file mode 100644 index 00000000000..5691e10342d --- /dev/null +++ b/install/include/postgresql/server/lib/pairingheap.h @@ -0,0 +1,102 @@ +/* + * pairingheap.h + * + * A Pairing Heap implementation + * + * Portions Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + * src/include/lib/pairingheap.h + */ + +#ifndef PAIRINGHEAP_H +#define PAIRINGHEAP_H + +#include "lib/stringinfo.h" + +/* Enable if you need the pairingheap_dump() debug function */ +/* #define PAIRINGHEAP_DEBUG */ + +/* + * This represents an element stored in the heap. Embed this in a larger + * struct containing the actual data you're storing. + * + * A node can have multiple children, which form a double-linked list. + * first_child points to the node's first child, and the subsequent children + * can be found by following the next_sibling pointers. The last child has + * next_sibling == NULL. The prev_or_parent pointer points to the node's + * previous sibling, or if the node is its parent's first child, to the + * parent. + */ +typedef struct pairingheap_node +{ + struct pairingheap_node *first_child; + struct pairingheap_node *next_sibling; + struct pairingheap_node *prev_or_parent; +} pairingheap_node; + +/* + * Return the containing struct of 'type' where 'membername' is the + * pairingheap_node pointed at by 'ptr'. + * + * This is used to convert a pairingheap_node * back to its containing struct. + */ +#define pairingheap_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, pairingheap_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, pairingheap_node), \ + ((type *) ((char *) (ptr) - offsetof(type, membername)))) + +/* + * Like pairingheap_container, but used when the pointer is 'const ptr' + */ +#define pairingheap_const_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, const pairingheap_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, pairingheap_node), \ + ((const type *) ((const char *) (ptr) - offsetof(type, membername)))) + +/* + * For a max-heap, the comparator must return <0 iff a < b, 0 iff a == b, + * and >0 iff a > b. For a min-heap, the conditions are reversed. + */ +typedef int (*pairingheap_comparator) (const pairingheap_node *a, + const pairingheap_node *b, + void *arg); + +/* + * A pairing heap. + * + * You can use pairingheap_allocate() to create a new palloc'd heap, or embed + * this in a larger struct, set ph_compare and ph_arg directly and initialize + * ph_root to NULL. + */ +typedef struct pairingheap +{ + pairingheap_comparator ph_compare; /* comparison function */ + void *ph_arg; /* opaque argument to ph_compare */ + pairingheap_node *ph_root; /* current root of the heap */ +} pairingheap; + +extern pairingheap *pairingheap_allocate(pairingheap_comparator compare, + void *arg); +extern void pairingheap_free(pairingheap *heap); +extern void pairingheap_add(pairingheap *heap, pairingheap_node *node); +extern pairingheap_node *pairingheap_first(pairingheap *heap); +extern pairingheap_node *pairingheap_remove_first(pairingheap *heap); +extern void pairingheap_remove(pairingheap *heap, pairingheap_node *node); + +#ifdef PAIRINGHEAP_DEBUG +extern char *pairingheap_dump(pairingheap *heap, + void (*dumpfunc) (pairingheap_node *node, StringInfo buf, void *opaque), + void *opaque); +#endif + +/* Resets the heap to be empty. */ +#define pairingheap_reset(h) ((h)->ph_root = NULL) + +/* Is the heap empty? */ +#define pairingheap_is_empty(h) ((h)->ph_root == NULL) + +/* Is there exactly one node in the heap? */ +#define pairingheap_is_singular(h) \ + ((h)->ph_root && (h)->ph_root->first_child == NULL) + +#endif /* PAIRINGHEAP_H */ diff --git a/install/include/postgresql/server/lib/qunique.h b/install/include/postgresql/server/lib/qunique.h new file mode 100644 index 00000000000..30b67c794f6 --- /dev/null +++ b/install/include/postgresql/server/lib/qunique.h @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------- + * + * qunique.h + * inline array unique functions + * Portions Copyright (c) 2019-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/lib/qunique.h + *------------------------------------------------------------------------- + */ + +#ifndef QUNIQUE_H +#define QUNIQUE_H + +/* + * Remove duplicates from a pre-sorted array, according to a user-supplied + * comparator. Usually the array should have been sorted with qsort() using + * the same arguments. Return the new size. + */ +static inline size_t +qunique(void *array, size_t elements, size_t width, + int (*compare) (const void *, const void *)) +{ + char *bytes = (char *) array; + size_t i, + j; + + if (elements <= 1) + return elements; + + for (i = 1, j = 0; i < elements; ++i) + { + if (compare(bytes + i * width, bytes + j * width) != 0 && + ++j != i) + memcpy(bytes + j * width, bytes + i * width, width); + } + + return j + 1; +} + +/* + * Like qunique(), but takes a comparator with an extra user data argument + * which is passed through, for compatibility with qsort_arg(). + */ +static inline size_t +qunique_arg(void *array, size_t elements, size_t width, + int (*compare) (const void *, const void *, void *), + void *arg) +{ + char *bytes = (char *) array; + size_t i, + j; + + if (elements <= 1) + return elements; + + for (i = 1, j = 0; i < elements; ++i) + { + if (compare(bytes + i * width, bytes + j * width, arg) != 0 && + ++j != i) + memcpy(bytes + j * width, bytes + i * width, width); + } + + return j + 1; +} + +#endif /* QUNIQUE_H */ diff --git a/install/include/postgresql/server/lib/rbtree.h b/install/include/postgresql/server/lib/rbtree.h new file mode 100644 index 00000000000..b339d6ea6fe --- /dev/null +++ b/install/include/postgresql/server/lib/rbtree.h @@ -0,0 +1,81 @@ +/*------------------------------------------------------------------------- + * + * rbtree.h + * interface for PostgreSQL generic Red-Black binary tree package + * + * Copyright (c) 2009-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/lib/rbtree.h + * + *------------------------------------------------------------------------- + */ +#ifndef RBTREE_H +#define RBTREE_H + +/* + * RBTNode is intended to be used as the first field of a larger struct, + * whose additional fields carry whatever payload data the caller needs + * for a tree entry. (The total size of that larger struct is passed to + * rbt_create.) RBTNode is declared here to support this usage, but + * callers must treat it as an opaque struct. + */ +typedef struct RBTNode +{ + char color; /* node's current color, red or black */ + struct RBTNode *left; /* left child, or RBTNIL if none */ + struct RBTNode *right; /* right child, or RBTNIL if none */ + struct RBTNode *parent; /* parent, or NULL (not RBTNIL!) if none */ +} RBTNode; + +/* Opaque struct representing a whole tree */ +typedef struct RBTree RBTree; + +/* Available tree iteration orderings */ +typedef enum RBTOrderControl +{ + LeftRightWalk, /* inorder: left child, node, right child */ + RightLeftWalk /* reverse inorder: right, node, left */ +} RBTOrderControl; + +/* + * RBTreeIterator holds state while traversing a tree. This is declared + * here so that callers can stack-allocate this, but must otherwise be + * treated as an opaque struct. + */ +typedef struct RBTreeIterator RBTreeIterator; + +struct RBTreeIterator +{ + RBTree *rbt; + RBTNode *(*iterate) (RBTreeIterator *iter); + RBTNode *last_visited; + bool is_over; +}; + +/* Support functions to be provided by caller */ +typedef int (*rbt_comparator) (const RBTNode *a, const RBTNode *b, void *arg); +typedef void (*rbt_combiner) (RBTNode *existing, const RBTNode *newdata, void *arg); +typedef RBTNode *(*rbt_allocfunc) (void *arg); +typedef void (*rbt_freefunc) (RBTNode *x, void *arg); + +extern RBTree *rbt_create(Size node_size, + rbt_comparator comparator, + rbt_combiner combiner, + rbt_allocfunc allocfunc, + rbt_freefunc freefunc, + void *arg); + +extern RBTNode *rbt_find(RBTree *rbt, const RBTNode *data); +extern RBTNode *rbt_find_great(RBTree *rbt, const RBTNode *data, bool equal_match); +extern RBTNode *rbt_find_less(RBTree *rbt, const RBTNode *data, bool equal_match); +extern RBTNode *rbt_leftmost(RBTree *rbt); + +extern RBTNode *rbt_insert(RBTree *rbt, const RBTNode *data, bool *isNew); +extern void rbt_delete(RBTree *rbt, RBTNode *node); + +extern void rbt_begin_iterate(RBTree *rbt, RBTOrderControl ctrl, + RBTreeIterator *iter); +extern RBTNode *rbt_iterate(RBTreeIterator *iter); + +#endif /* RBTREE_H */ diff --git a/install/include/postgresql/server/lib/simplehash.h b/install/include/postgresql/server/lib/simplehash.h new file mode 100644 index 00000000000..1dc817ac8d9 --- /dev/null +++ b/install/include/postgresql/server/lib/simplehash.h @@ -0,0 +1,1187 @@ +/* + * simplehash.h + * + * When included this file generates a "templated" (by way of macros) + * open-addressing hash table implementation specialized to user-defined + * types. + * + * It's probably not worthwhile to generate such a specialized implementation + * for hash tables that aren't performance or space sensitive. + * + * Compared to dynahash, simplehash has the following benefits: + * + * - Due to the "templated" code generation has known structure sizes and no + * indirect function calls (which show up substantially in dynahash + * profiles). These features considerably increase speed for small + * entries. + * - Open addressing has better CPU cache behavior than dynahash's chained + * hashtables. + * - The generated interface is type-safe and easier to use than dynahash, + * though at the cost of more complex setup. + * - Allocates memory in a MemoryContext or another allocator with a + * malloc/free style interface (which isn't easily usable in a shared + * memory context) + * - Does not require the overhead of a separate memory context. + * + * Usage notes: + * + * To generate a hash-table and associated functions for a use case several + * macros have to be #define'ed before this file is included. Including + * the file #undef's all those, so a new hash table can be generated + * afterwards. + * The relevant parameters are: + * - SH_PREFIX - prefix for all symbol names generated. A prefix of 'foo' + * will result in hash table type 'foo_hash' and functions like + * 'foo_insert'/'foo_lookup' and so forth. + * - SH_ELEMENT_TYPE - type of the contained elements + * - SH_KEY_TYPE - type of the hashtable's key + * - SH_DECLARE - if defined function prototypes and type declarations are + * generated + * - SH_DEFINE - if defined function definitions are generated + * - SH_SCOPE - in which scope (e.g. extern, static inline) do function + * declarations reside + * - SH_RAW_ALLOCATOR - if defined, memory contexts are not used; instead, + * use this to allocate bytes. The allocator must zero the returned space. + * - SH_USE_NONDEFAULT_ALLOCATOR - if defined no element allocator functions + * are defined, so you can supply your own + * The following parameters are only relevant when SH_DEFINE is defined: + * - SH_KEY - name of the element in SH_ELEMENT_TYPE containing the hash key + * - SH_EQUAL(table, a, b) - compare two table keys + * - SH_HASH_KEY(table, key) - generate hash for the key + * - SH_STORE_HASH - if defined the hash is stored in the elements + * - SH_GET_HASH(tb, a) - return the field to store the hash in + * + * The element type is required to contain a "status" member that can store + * the range of values defined in the SH_STATUS enum. + * + * While SH_STORE_HASH (and subsequently SH_GET_HASH) are optional, because + * the hash table implementation needs to compare hashes to move elements + * (particularly when growing the hash), it's preferable, if possible, to + * store the element's hash in the element's data type. If the hash is so + * stored, the hash table will also compare hashes before calling SH_EQUAL + * when comparing two keys. + * + * For convenience the hash table create functions accept a void pointer + * that will be stored in the hash table type's member private_data. This + * allows callbacks to reference caller provided data. + * + * For examples of usage look at tidbitmap.c (file local definition) and + * execnodes.h/execGrouping.c (exposed declaration, file local + * implementation). + * + * Hash table design: + * + * The hash table design chosen is a variant of linear open-addressing. The + * reason for doing so is that linear addressing is CPU cache & pipeline + * friendly. The biggest disadvantage of simple linear addressing schemes + * are highly variable lookup times due to clustering, and deletions + * leaving a lot of tombstones around. To address these issues a variant + * of "robin hood" hashing is employed. Robin hood hashing optimizes + * chaining lengths by moving elements close to their optimal bucket + * ("rich" elements), out of the way if a to-be-inserted element is further + * away from its optimal position (i.e. it's "poor"). While that can make + * insertions slower, the average lookup performance is a lot better, and + * higher fill factors can be used in a still performant manner. To avoid + * tombstones - which normally solve the issue that a deleted node's + * presence is relevant to determine whether a lookup needs to continue + * looking or is done - buckets following a deleted element are shifted + * backwards, unless they're empty or already at their optimal position. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/lib/simplehash.h + */ + +#include "port/pg_bitutils.h" + +/* helpers */ +#define SH_MAKE_PREFIX(a) CppConcat(a,_) +#define SH_MAKE_NAME(name) SH_MAKE_NAME_(SH_MAKE_PREFIX(SH_PREFIX),name) +#define SH_MAKE_NAME_(a,b) CppConcat(a,b) + +/* name macros for: */ + +/* type declarations */ +#define SH_TYPE SH_MAKE_NAME(hash) +#define SH_STATUS SH_MAKE_NAME(status) +#define SH_STATUS_EMPTY SH_MAKE_NAME(SH_EMPTY) +#define SH_STATUS_IN_USE SH_MAKE_NAME(SH_IN_USE) +#define SH_ITERATOR SH_MAKE_NAME(iterator) + +/* function declarations */ +#define SH_CREATE SH_MAKE_NAME(create) +#define SH_DESTROY SH_MAKE_NAME(destroy) +#define SH_RESET SH_MAKE_NAME(reset) +#define SH_INSERT SH_MAKE_NAME(insert) +#define SH_INSERT_HASH SH_MAKE_NAME(insert_hash) +#define SH_DELETE_ITEM SH_MAKE_NAME(delete_item) +#define SH_DELETE SH_MAKE_NAME(delete) +#define SH_LOOKUP SH_MAKE_NAME(lookup) +#define SH_LOOKUP_HASH SH_MAKE_NAME(lookup_hash) +#define SH_GROW SH_MAKE_NAME(grow) +#define SH_START_ITERATE SH_MAKE_NAME(start_iterate) +#define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at) +#define SH_ITERATE SH_MAKE_NAME(iterate) +#define SH_ALLOCATE SH_MAKE_NAME(allocate) +#define SH_FREE SH_MAKE_NAME(free) +#define SH_STAT SH_MAKE_NAME(stat) + +/* internal helper functions (no externally visible prototypes) */ +#define SH_COMPUTE_PARAMETERS SH_MAKE_NAME(compute_parameters) +#define SH_NEXT SH_MAKE_NAME(next) +#define SH_PREV SH_MAKE_NAME(prev) +#define SH_DISTANCE_FROM_OPTIMAL SH_MAKE_NAME(distance) +#define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket) +#define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash) +#define SH_INSERT_HASH_INTERNAL SH_MAKE_NAME(insert_hash_internal) +#define SH_LOOKUP_HASH_INTERNAL SH_MAKE_NAME(lookup_hash_internal) + +/* generate forward declarations necessary to use the hash table */ +#ifdef SH_DECLARE + +/* type definitions */ +typedef struct SH_TYPE +{ + /* + * Size of data / bucket array, 64 bits to handle UINT32_MAX sized hash + * tables. Note that the maximum number of elements is lower + * (SH_MAX_FILLFACTOR) + */ + uint64 size; + + /* how many elements have valid contents */ + uint32 members; + + /* mask for bucket and size calculations, based on size */ + uint32 sizemask; + + /* boundary after which to grow hashtable */ + uint32 grow_threshold; + + /* hash buckets */ + SH_ELEMENT_TYPE *data; + +#ifndef SH_RAW_ALLOCATOR + /* memory context to use for allocations */ + MemoryContext ctx; +#endif + + /* user defined data, useful for callbacks */ + void *private_data; +} SH_TYPE; + +typedef enum SH_STATUS +{ + SH_STATUS_EMPTY = 0x00, + SH_STATUS_IN_USE = 0x01 +} SH_STATUS; + +typedef struct SH_ITERATOR +{ + uint32 cur; /* current element */ + uint32 end; + bool done; /* iterator exhausted? */ +} SH_ITERATOR; + +/* externally visible function prototypes */ +#ifdef SH_RAW_ALLOCATOR +/* _hash _create(uint32 nelements, void *private_data) */ +SH_SCOPE SH_TYPE *SH_CREATE(uint32 nelements, void *private_data); +#else +/* + * _hash _create(MemoryContext ctx, uint32 nelements, + * void *private_data) + */ +SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements, + void *private_data); +#endif + +/* void _destroy(_hash *tb) */ +SH_SCOPE void SH_DESTROY(SH_TYPE * tb); + +/* void _reset(_hash *tb) */ +SH_SCOPE void SH_RESET(SH_TYPE * tb); + +/* void _grow(_hash *tb, uint64 newsize) */ +SH_SCOPE void SH_GROW(SH_TYPE * tb, uint64 newsize); + +/* *_insert(_hash *tb, key, bool *found) */ +SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found); + +/* + * *_insert_hash(_hash *tb, key, uint32 hash, + * bool *found) + */ +SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT_HASH(SH_TYPE * tb, SH_KEY_TYPE key, + uint32 hash, bool *found); + +/* *_lookup(_hash *tb, key) */ +SH_SCOPE SH_ELEMENT_TYPE *SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key); + +/* *_lookup_hash(_hash *tb, key, uint32 hash) */ +SH_SCOPE SH_ELEMENT_TYPE *SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key, + uint32 hash); + +/* void _delete_item(_hash *tb, *entry) */ +SH_SCOPE void SH_DELETE_ITEM(SH_TYPE * tb, SH_ELEMENT_TYPE * entry); + +/* bool _delete(_hash *tb, key) */ +SH_SCOPE bool SH_DELETE(SH_TYPE * tb, SH_KEY_TYPE key); + +/* void _start_iterate(_hash *tb, _iterator *iter) */ +SH_SCOPE void SH_START_ITERATE(SH_TYPE * tb, SH_ITERATOR * iter); + +/* + * void _start_iterate_at(_hash *tb, _iterator *iter, + * uint32 at) + */ +SH_SCOPE void SH_START_ITERATE_AT(SH_TYPE * tb, SH_ITERATOR * iter, uint32 at); + +/* *_iterate(_hash *tb, _iterator *iter) */ +SH_SCOPE SH_ELEMENT_TYPE *SH_ITERATE(SH_TYPE * tb, SH_ITERATOR * iter); + +/* void _stat(_hash *tb */ +SH_SCOPE void SH_STAT(SH_TYPE * tb); + +#endif /* SH_DECLARE */ + + +/* generate implementation of the hash table */ +#ifdef SH_DEFINE + +#ifndef SH_RAW_ALLOCATOR +#include "utils/memutils.h" +#endif + +/* max data array size,we allow up to PG_UINT32_MAX buckets, including 0 */ +#define SH_MAX_SIZE (((uint64) PG_UINT32_MAX) + 1) + +/* normal fillfactor, unless already close to maximum */ +#ifndef SH_FILLFACTOR +#define SH_FILLFACTOR (0.9) +#endif +/* increase fillfactor if we otherwise would error out */ +#define SH_MAX_FILLFACTOR (0.98) +/* grow if actual and optimal location bigger than */ +#ifndef SH_GROW_MAX_DIB +#define SH_GROW_MAX_DIB 25 +#endif +/* grow if more than elements to move when inserting */ +#ifndef SH_GROW_MAX_MOVE +#define SH_GROW_MAX_MOVE 150 +#endif +#ifndef SH_GROW_MIN_FILLFACTOR +/* but do not grow due to SH_GROW_MAX_* if below */ +#define SH_GROW_MIN_FILLFACTOR 0.1 +#endif + +#ifdef SH_STORE_HASH +#define SH_COMPARE_KEYS(tb, ahash, akey, b) (ahash == SH_GET_HASH(tb, b) && SH_EQUAL(tb, b->SH_KEY, akey)) +#else +#define SH_COMPARE_KEYS(tb, ahash, akey, b) (SH_EQUAL(tb, b->SH_KEY, akey)) +#endif + +/* + * Wrap the following definitions in include guards, to avoid multiple + * definition errors if this header is included more than once. The rest of + * the file deliberately has no include guards, because it can be included + * with different parameters to define functions and types with non-colliding + * names. + */ +#ifndef SIMPLEHASH_H +#define SIMPLEHASH_H + +#ifdef FRONTEND +#define sh_error(...) pg_fatal(__VA_ARGS__) +#define sh_log(...) pg_log_info(__VA_ARGS__) +#else +#define sh_error(...) elog(ERROR, __VA_ARGS__) +#define sh_log(...) elog(LOG, __VA_ARGS__) +#endif + +#endif + +/* + * Compute sizing parameters for hashtable. Called when creating and growing + * the hashtable. + */ +static inline void +SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint64 newsize) +{ + uint64 size; + + /* supporting zero sized hashes would complicate matters */ + size = Max(newsize, 2); + + /* round up size to the next power of 2, that's how bucketing works */ + size = pg_nextpower2_64(size); + Assert(size <= SH_MAX_SIZE); + + /* + * Verify that allocation of ->data is possible on this platform, without + * overflowing Size. + */ + if (unlikely((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2)) + sh_error("hash table too large"); + + /* now set size */ + tb->size = size; + tb->sizemask = (uint32) (size - 1); + + /* + * Compute the next threshold at which we need to grow the hash table + * again. + */ + if (tb->size == SH_MAX_SIZE) + tb->grow_threshold = ((double) tb->size) * SH_MAX_FILLFACTOR; + else + tb->grow_threshold = ((double) tb->size) * SH_FILLFACTOR; +} + +/* return the optimal bucket for the hash */ +static inline uint32 +SH_INITIAL_BUCKET(SH_TYPE * tb, uint32 hash) +{ + return hash & tb->sizemask; +} + +/* return next bucket after the current, handling wraparound */ +static inline uint32 +SH_NEXT(SH_TYPE * tb, uint32 curelem, uint32 startelem) +{ + curelem = (curelem + 1) & tb->sizemask; + + Assert(curelem != startelem); + + return curelem; +} + +/* return bucket before the current, handling wraparound */ +static inline uint32 +SH_PREV(SH_TYPE * tb, uint32 curelem, uint32 startelem) +{ + curelem = (curelem - 1) & tb->sizemask; + + Assert(curelem != startelem); + + return curelem; +} + +/* return distance between bucket and its optimal position */ +static inline uint32 +SH_DISTANCE_FROM_OPTIMAL(SH_TYPE * tb, uint32 optimal, uint32 bucket) +{ + if (optimal <= bucket) + return bucket - optimal; + else + return (tb->size + bucket) - optimal; +} + +static inline uint32 +SH_ENTRY_HASH(SH_TYPE * tb, SH_ELEMENT_TYPE * entry) +{ +#ifdef SH_STORE_HASH + return SH_GET_HASH(tb, entry); +#else + return SH_HASH_KEY(tb, entry->SH_KEY); +#endif +} + +/* default memory allocator function */ +static inline void *SH_ALLOCATE(SH_TYPE * type, Size size); +static inline void SH_FREE(SH_TYPE * type, void *pointer); + +#ifndef SH_USE_NONDEFAULT_ALLOCATOR + +/* default memory allocator function */ +static inline void * +SH_ALLOCATE(SH_TYPE * type, Size size) +{ +#ifdef SH_RAW_ALLOCATOR + return SH_RAW_ALLOCATOR(size); +#else + return MemoryContextAllocExtended(type->ctx, size, + MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO); +#endif +} + +/* default memory free function */ +static inline void +SH_FREE(SH_TYPE * type, void *pointer) +{ + pfree(pointer); +} + +#endif + +/* + * Create a hash table with enough space for `nelements` distinct members. + * Memory for the hash table is allocated from the passed-in context. If + * desired, the array of elements can be allocated using a passed-in allocator; + * this could be useful in order to place the array of elements in a shared + * memory, or in a context that will outlive the rest of the hash table. + * Memory other than for the array of elements will still be allocated from + * the passed-in context. + */ +#ifdef SH_RAW_ALLOCATOR +SH_SCOPE SH_TYPE * +SH_CREATE(uint32 nelements, void *private_data) +#else +SH_SCOPE SH_TYPE * +SH_CREATE(MemoryContext ctx, uint32 nelements, void *private_data) +#endif +{ + SH_TYPE *tb; + uint64 size; + +#ifdef SH_RAW_ALLOCATOR + tb = (SH_TYPE *) SH_RAW_ALLOCATOR(sizeof(SH_TYPE)); +#else + tb = (SH_TYPE *) MemoryContextAllocZero(ctx, sizeof(SH_TYPE)); + tb->ctx = ctx; +#endif + tb->private_data = private_data; + + /* increase nelements by fillfactor, want to store nelements elements */ + size = Min((double) SH_MAX_SIZE, ((double) nelements) / SH_FILLFACTOR); + + SH_COMPUTE_PARAMETERS(tb, size); + + tb->data = (SH_ELEMENT_TYPE *) SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size); + + return tb; +} + +/* destroy a previously created hash table */ +SH_SCOPE void +SH_DESTROY(SH_TYPE * tb) +{ + SH_FREE(tb, tb->data); + pfree(tb); +} + +/* reset the contents of a previously created hash table */ +SH_SCOPE void +SH_RESET(SH_TYPE * tb) +{ + memset(tb->data, 0, sizeof(SH_ELEMENT_TYPE) * tb->size); + tb->members = 0; +} + +/* + * Grow a hash table to at least `newsize` buckets. + * + * Usually this will automatically be called by insertions/deletions, when + * necessary. But resizing to the exact input size can be advantageous + * performance-wise, when known at some point. + */ +SH_SCOPE void +SH_GROW(SH_TYPE * tb, uint64 newsize) +{ + uint64 oldsize = tb->size; + SH_ELEMENT_TYPE *olddata = tb->data; + SH_ELEMENT_TYPE *newdata; + uint32 i; + uint32 startelem = 0; + uint32 copyelem; + + Assert(oldsize == pg_nextpower2_64(oldsize)); + Assert(oldsize != SH_MAX_SIZE); + Assert(oldsize < newsize); + + /* compute parameters for new table */ + SH_COMPUTE_PARAMETERS(tb, newsize); + + tb->data = (SH_ELEMENT_TYPE *) SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size); + + newdata = tb->data; + + /* + * Copy entries from the old data to newdata. We theoretically could use + * SH_INSERT here, to avoid code duplication, but that's more general than + * we need. We neither want tb->members increased, nor do we need to do + * deal with deleted elements, nor do we need to compare keys. So a + * special-cased implementation is lot faster. As resizing can be time + * consuming and frequent, that's worthwhile to optimize. + * + * To be able to simply move entries over, we have to start not at the + * first bucket (i.e olddata[0]), but find the first bucket that's either + * empty, or is occupied by an entry at its optimal position. Such a + * bucket has to exist in any table with a load factor under 1, as not all + * buckets are occupied, i.e. there always has to be an empty bucket. By + * starting at such a bucket we can move the entries to the larger table, + * without having to deal with conflicts. + */ + + /* search for the first element in the hash that's not wrapped around */ + for (i = 0; i < oldsize; i++) + { + SH_ELEMENT_TYPE *oldentry = &olddata[i]; + uint32 hash; + uint32 optimal; + + if (oldentry->status != SH_STATUS_IN_USE) + { + startelem = i; + break; + } + + hash = SH_ENTRY_HASH(tb, oldentry); + optimal = SH_INITIAL_BUCKET(tb, hash); + + if (optimal == i) + { + startelem = i; + break; + } + } + + /* and copy all elements in the old table */ + copyelem = startelem; + for (i = 0; i < oldsize; i++) + { + SH_ELEMENT_TYPE *oldentry = &olddata[copyelem]; + + if (oldentry->status == SH_STATUS_IN_USE) + { + uint32 hash; + uint32 startelem2; + uint32 curelem; + SH_ELEMENT_TYPE *newentry; + + hash = SH_ENTRY_HASH(tb, oldentry); + startelem2 = SH_INITIAL_BUCKET(tb, hash); + curelem = startelem2; + + /* find empty element to put data into */ + while (true) + { + newentry = &newdata[curelem]; + + if (newentry->status == SH_STATUS_EMPTY) + { + break; + } + + curelem = SH_NEXT(tb, curelem, startelem2); + } + + /* copy entry to new slot */ + memcpy(newentry, oldentry, sizeof(SH_ELEMENT_TYPE)); + } + + /* can't use SH_NEXT here, would use new size */ + copyelem++; + if (copyelem >= oldsize) + { + copyelem = 0; + } + } + + SH_FREE(tb, olddata); +} + +/* + * This is a separate static inline function, so it can be reliably be inlined + * into its wrapper functions even if SH_SCOPE is extern. + */ +static inline SH_ELEMENT_TYPE * +SH_INSERT_HASH_INTERNAL(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found) +{ + uint32 startelem; + uint32 curelem; + SH_ELEMENT_TYPE *data; + uint32 insertdist; + +restart: + insertdist = 0; + + /* + * We do the grow check even if the key is actually present, to avoid + * doing the check inside the loop. This also lets us avoid having to + * re-find our position in the hashtable after resizing. + * + * Note that this also reached when resizing the table due to + * SH_GROW_MAX_DIB / SH_GROW_MAX_MOVE. + */ + if (unlikely(tb->members >= tb->grow_threshold)) + { + if (unlikely(tb->size == SH_MAX_SIZE)) + sh_error("hash table size exceeded"); + + /* + * When optimizing, it can be very useful to print these out. + */ + /* SH_STAT(tb); */ + SH_GROW(tb, tb->size * 2); + /* SH_STAT(tb); */ + } + + /* perform insert, start bucket search at optimal location */ + data = tb->data; + startelem = SH_INITIAL_BUCKET(tb, hash); + curelem = startelem; + while (true) + { + uint32 curdist; + uint32 curhash; + uint32 curoptimal; + SH_ELEMENT_TYPE *entry = &data[curelem]; + + /* any empty bucket can directly be used */ + if (entry->status == SH_STATUS_EMPTY) + { + tb->members++; + entry->SH_KEY = key; +#ifdef SH_STORE_HASH + SH_GET_HASH(tb, entry) = hash; +#endif + entry->status = SH_STATUS_IN_USE; + *found = false; + return entry; + } + + /* + * If the bucket is not empty, we either found a match (in which case + * we're done), or we have to decide whether to skip over or move the + * colliding entry. When the colliding element's distance to its + * optimal position is smaller than the to-be-inserted entry's, we + * shift the colliding entry (and its followers) forward by one. + */ + + if (SH_COMPARE_KEYS(tb, hash, key, entry)) + { + Assert(entry->status == SH_STATUS_IN_USE); + *found = true; + return entry; + } + + curhash = SH_ENTRY_HASH(tb, entry); + curoptimal = SH_INITIAL_BUCKET(tb, curhash); + curdist = SH_DISTANCE_FROM_OPTIMAL(tb, curoptimal, curelem); + + if (insertdist > curdist) + { + SH_ELEMENT_TYPE *lastentry = entry; + uint32 emptyelem = curelem; + uint32 moveelem; + int32 emptydist = 0; + + /* find next empty bucket */ + while (true) + { + SH_ELEMENT_TYPE *emptyentry; + + emptyelem = SH_NEXT(tb, emptyelem, startelem); + emptyentry = &data[emptyelem]; + + if (emptyentry->status == SH_STATUS_EMPTY) + { + lastentry = emptyentry; + break; + } + + /* + * To avoid negative consequences from overly imbalanced + * hashtables, grow the hashtable if collisions would require + * us to move a lot of entries. The most likely cause of such + * imbalance is filling a (currently) small table, from a + * currently big one, in hash-table order. Don't grow if the + * hashtable would be too empty, to prevent quick space + * explosion for some weird edge cases. + */ + if (unlikely(++emptydist > SH_GROW_MAX_MOVE) && + ((double) tb->members / tb->size) >= SH_GROW_MIN_FILLFACTOR) + { + tb->grow_threshold = 0; + goto restart; + } + } + + /* shift forward, starting at last occupied element */ + + /* + * TODO: This could be optimized to be one memcpy in many cases, + * excepting wrapping around at the end of ->data. Hasn't shown up + * in profiles so far though. + */ + moveelem = emptyelem; + while (moveelem != curelem) + { + SH_ELEMENT_TYPE *moveentry; + + moveelem = SH_PREV(tb, moveelem, startelem); + moveentry = &data[moveelem]; + + memcpy(lastentry, moveentry, sizeof(SH_ELEMENT_TYPE)); + lastentry = moveentry; + } + + /* and fill the now empty spot */ + tb->members++; + + entry->SH_KEY = key; +#ifdef SH_STORE_HASH + SH_GET_HASH(tb, entry) = hash; +#endif + entry->status = SH_STATUS_IN_USE; + *found = false; + return entry; + } + + curelem = SH_NEXT(tb, curelem, startelem); + insertdist++; + + /* + * To avoid negative consequences from overly imbalanced hashtables, + * grow the hashtable if collisions lead to large runs. The most + * likely cause of such imbalance is filling a (currently) small + * table, from a currently big one, in hash-table order. Don't grow + * if the hashtable would be too empty, to prevent quick space + * explosion for some weird edge cases. + */ + if (unlikely(insertdist > SH_GROW_MAX_DIB) && + ((double) tb->members / tb->size) >= SH_GROW_MIN_FILLFACTOR) + { + tb->grow_threshold = 0; + goto restart; + } + } +} + +/* + * Insert the key key into the hash-table, set *found to true if the key + * already exists, false otherwise. Returns the hash-table entry in either + * case. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found) +{ + uint32 hash = SH_HASH_KEY(tb, key); + + return SH_INSERT_HASH_INTERNAL(tb, key, hash, found); +} + +/* + * Insert the key key into the hash-table using an already-calculated + * hash. Set *found to true if the key already exists, false + * otherwise. Returns the hash-table entry in either case. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_INSERT_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found) +{ + return SH_INSERT_HASH_INTERNAL(tb, key, hash, found); +} + +/* + * This is a separate static inline function, so it can be reliably be inlined + * into its wrapper functions even if SH_SCOPE is extern. + */ +static inline SH_ELEMENT_TYPE * +SH_LOOKUP_HASH_INTERNAL(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash) +{ + const uint32 startelem = SH_INITIAL_BUCKET(tb, hash); + uint32 curelem = startelem; + + while (true) + { + SH_ELEMENT_TYPE *entry = &tb->data[curelem]; + + if (entry->status == SH_STATUS_EMPTY) + { + return NULL; + } + + Assert(entry->status == SH_STATUS_IN_USE); + + if (SH_COMPARE_KEYS(tb, hash, key, entry)) + return entry; + + /* + * TODO: we could stop search based on distance. If the current + * buckets's distance-from-optimal is smaller than what we've skipped + * already, the entry doesn't exist. Probably only do so if + * SH_STORE_HASH is defined, to avoid re-computing hashes? + */ + + curelem = SH_NEXT(tb, curelem, startelem); + } +} + +/* + * Lookup entry in hash table. Returns NULL if key not present. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key) +{ + uint32 hash = SH_HASH_KEY(tb, key); + + return SH_LOOKUP_HASH_INTERNAL(tb, key, hash); +} + +/* + * Lookup entry in hash table using an already-calculated hash. + * + * Returns NULL if key not present. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash) +{ + return SH_LOOKUP_HASH_INTERNAL(tb, key, hash); +} + +/* + * Delete entry from hash table by key. Returns whether to-be-deleted key was + * present. + */ +SH_SCOPE bool +SH_DELETE(SH_TYPE * tb, SH_KEY_TYPE key) +{ + uint32 hash = SH_HASH_KEY(tb, key); + uint32 startelem = SH_INITIAL_BUCKET(tb, hash); + uint32 curelem = startelem; + + while (true) + { + SH_ELEMENT_TYPE *entry = &tb->data[curelem]; + + if (entry->status == SH_STATUS_EMPTY) + return false; + + if (entry->status == SH_STATUS_IN_USE && + SH_COMPARE_KEYS(tb, hash, key, entry)) + { + SH_ELEMENT_TYPE *lastentry = entry; + + tb->members--; + + /* + * Backward shift following elements till either an empty element + * or an element at its optimal position is encountered. + * + * While that sounds expensive, the average chain length is short, + * and deletions would otherwise require tombstones. + */ + while (true) + { + SH_ELEMENT_TYPE *curentry; + uint32 curhash; + uint32 curoptimal; + + curelem = SH_NEXT(tb, curelem, startelem); + curentry = &tb->data[curelem]; + + if (curentry->status != SH_STATUS_IN_USE) + { + lastentry->status = SH_STATUS_EMPTY; + break; + } + + curhash = SH_ENTRY_HASH(tb, curentry); + curoptimal = SH_INITIAL_BUCKET(tb, curhash); + + /* current is at optimal position, done */ + if (curoptimal == curelem) + { + lastentry->status = SH_STATUS_EMPTY; + break; + } + + /* shift */ + memcpy(lastentry, curentry, sizeof(SH_ELEMENT_TYPE)); + + lastentry = curentry; + } + + return true; + } + + /* TODO: return false; if distance too big */ + + curelem = SH_NEXT(tb, curelem, startelem); + } +} + +/* + * Delete entry from hash table by entry pointer + */ +SH_SCOPE void +SH_DELETE_ITEM(SH_TYPE * tb, SH_ELEMENT_TYPE * entry) +{ + SH_ELEMENT_TYPE *lastentry = entry; + uint32 hash = SH_ENTRY_HASH(tb, entry); + uint32 startelem = SH_INITIAL_BUCKET(tb, hash); + uint32 curelem; + + /* Calculate the index of 'entry' */ + curelem = entry - &tb->data[0]; + + tb->members--; + + /* + * Backward shift following elements till either an empty element or an + * element at its optimal position is encountered. + * + * While that sounds expensive, the average chain length is short, and + * deletions would otherwise require tombstones. + */ + while (true) + { + SH_ELEMENT_TYPE *curentry; + uint32 curhash; + uint32 curoptimal; + + curelem = SH_NEXT(tb, curelem, startelem); + curentry = &tb->data[curelem]; + + if (curentry->status != SH_STATUS_IN_USE) + { + lastentry->status = SH_STATUS_EMPTY; + break; + } + + curhash = SH_ENTRY_HASH(tb, curentry); + curoptimal = SH_INITIAL_BUCKET(tb, curhash); + + /* current is at optimal position, done */ + if (curoptimal == curelem) + { + lastentry->status = SH_STATUS_EMPTY; + break; + } + + /* shift */ + memcpy(lastentry, curentry, sizeof(SH_ELEMENT_TYPE)); + + lastentry = curentry; + } +} + +/* + * Initialize iterator. + */ +SH_SCOPE void +SH_START_ITERATE(SH_TYPE * tb, SH_ITERATOR * iter) +{ + uint64 startelem = PG_UINT64_MAX; + + /* + * Search for the first empty element. As deletions during iterations are + * supported, we want to start/end at an element that cannot be affected + * by elements being shifted. + */ + for (uint32 i = 0; i < tb->size; i++) + { + SH_ELEMENT_TYPE *entry = &tb->data[i]; + + if (entry->status != SH_STATUS_IN_USE) + { + startelem = i; + break; + } + } + + /* we should have found an empty element */ + Assert(startelem < SH_MAX_SIZE); + + /* + * Iterate backwards, that allows the current element to be deleted, even + * if there are backward shifts + */ + iter->cur = startelem; + iter->end = iter->cur; + iter->done = false; +} + +/* + * Initialize iterator to a specific bucket. That's really only useful for + * cases where callers are partially iterating over the hashspace, and that + * iteration deletes and inserts elements based on visited entries. Doing that + * repeatedly could lead to an unbalanced keyspace when always starting at the + * same position. + */ +SH_SCOPE void +SH_START_ITERATE_AT(SH_TYPE * tb, SH_ITERATOR * iter, uint32 at) +{ + /* + * Iterate backwards, that allows the current element to be deleted, even + * if there are backward shifts. + */ + iter->cur = at & tb->sizemask; /* ensure at is within a valid range */ + iter->end = iter->cur; + iter->done = false; +} + +/* + * Iterate over all entries in the hash-table. Return the next occupied entry, + * or NULL if done. + * + * During iteration the current entry in the hash table may be deleted, + * without leading to elements being skipped or returned twice. Additionally + * the rest of the table may be modified (i.e. there can be insertions or + * deletions), but if so, there's neither a guarantee that all nodes are + * visited at least once, nor a guarantee that a node is visited at most once. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_ITERATE(SH_TYPE * tb, SH_ITERATOR * iter) +{ + while (!iter->done) + { + SH_ELEMENT_TYPE *elem; + + elem = &tb->data[iter->cur]; + + /* next element in backward direction */ + iter->cur = (iter->cur - 1) & tb->sizemask; + + if ((iter->cur & tb->sizemask) == (iter->end & tb->sizemask)) + iter->done = true; + if (elem->status == SH_STATUS_IN_USE) + { + return elem; + } + } + + return NULL; +} + +/* + * Report some statistics about the state of the hashtable. For + * debugging/profiling purposes only. + */ +SH_SCOPE void +SH_STAT(SH_TYPE * tb) +{ + uint32 max_chain_length = 0; + uint32 total_chain_length = 0; + double avg_chain_length; + double fillfactor; + uint32 i; + + uint32 *collisions = (uint32 *) palloc0(tb->size * sizeof(uint32)); + uint32 total_collisions = 0; + uint32 max_collisions = 0; + double avg_collisions; + + for (i = 0; i < tb->size; i++) + { + uint32 hash; + uint32 optimal; + uint32 dist; + SH_ELEMENT_TYPE *elem; + + elem = &tb->data[i]; + + if (elem->status != SH_STATUS_IN_USE) + continue; + + hash = SH_ENTRY_HASH(tb, elem); + optimal = SH_INITIAL_BUCKET(tb, hash); + dist = SH_DISTANCE_FROM_OPTIMAL(tb, optimal, i); + + if (dist > max_chain_length) + max_chain_length = dist; + total_chain_length += dist; + + collisions[optimal]++; + } + + for (i = 0; i < tb->size; i++) + { + uint32 curcoll = collisions[i]; + + if (curcoll == 0) + continue; + + /* single contained element is not a collision */ + curcoll--; + total_collisions += curcoll; + if (curcoll > max_collisions) + max_collisions = curcoll; + } + + /* large enough to be worth freeing, even if just used for debugging */ + pfree(collisions); + + if (tb->members > 0) + { + fillfactor = tb->members / ((double) tb->size); + avg_chain_length = ((double) total_chain_length) / tb->members; + avg_collisions = ((double) total_collisions) / tb->members; + } + else + { + fillfactor = 0; + avg_chain_length = 0; + avg_collisions = 0; + } + + sh_log("size: " UINT64_FORMAT ", members: %u, filled: %f, total chain: %u, max chain: %u, avg chain: %f, total_collisions: %u, max_collisions: %u, avg_collisions: %f", + tb->size, tb->members, fillfactor, total_chain_length, max_chain_length, avg_chain_length, + total_collisions, max_collisions, avg_collisions); +} + +#endif /* SH_DEFINE */ + + +/* undefine external parameters, so next hash table can be defined */ +#undef SH_PREFIX +#undef SH_KEY_TYPE +#undef SH_KEY +#undef SH_ELEMENT_TYPE +#undef SH_HASH_KEY +#undef SH_SCOPE +#undef SH_DECLARE +#undef SH_DEFINE +#undef SH_GET_HASH +#undef SH_STORE_HASH +#undef SH_USE_NONDEFAULT_ALLOCATOR +#undef SH_EQUAL + +/* undefine locally declared macros */ +#undef SH_MAKE_PREFIX +#undef SH_MAKE_NAME +#undef SH_MAKE_NAME_ +#undef SH_FILLFACTOR +#undef SH_MAX_FILLFACTOR +#undef SH_GROW_MAX_DIB +#undef SH_GROW_MAX_MOVE +#undef SH_GROW_MIN_FILLFACTOR +#undef SH_MAX_SIZE + +/* types */ +#undef SH_TYPE +#undef SH_STATUS +#undef SH_STATUS_EMPTY +#undef SH_STATUS_IN_USE +#undef SH_ITERATOR + +/* external function names */ +#undef SH_CREATE +#undef SH_DESTROY +#undef SH_RESET +#undef SH_INSERT +#undef SH_INSERT_HASH +#undef SH_DELETE_ITEM +#undef SH_DELETE +#undef SH_LOOKUP +#undef SH_LOOKUP_HASH +#undef SH_GROW +#undef SH_START_ITERATE +#undef SH_START_ITERATE_AT +#undef SH_ITERATE +#undef SH_ALLOCATE +#undef SH_FREE +#undef SH_STAT + +/* internal function names */ +#undef SH_COMPUTE_PARAMETERS +#undef SH_COMPARE_KEYS +#undef SH_INITIAL_BUCKET +#undef SH_NEXT +#undef SH_PREV +#undef SH_DISTANCE_FROM_OPTIMAL +#undef SH_ENTRY_HASH +#undef SH_INSERT_HASH_INTERNAL +#undef SH_LOOKUP_HASH_INTERNAL diff --git a/install/include/postgresql/server/lib/sort_template.h b/install/include/postgresql/server/lib/sort_template.h new file mode 100644 index 00000000000..1edd05c7d36 --- /dev/null +++ b/install/include/postgresql/server/lib/sort_template.h @@ -0,0 +1,432 @@ +/*------------------------------------------------------------------------- + * + * sort_template.h + * + * A template for a sort algorithm that supports varying degrees of + * specialization. + * + * Copyright (c) 2021-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1992-1994, Regents of the University of California + * + * Usage notes: + * + * To generate functions specialized for a type, the following parameter + * macros should be #define'd before this file is included. + * + * - ST_SORT - the name of a sort function to be generated + * - ST_ELEMENT_TYPE - type of the referenced elements + * - ST_DECLARE - if defined the functions and types are declared + * - ST_DEFINE - if defined the functions and types are defined + * - ST_SCOPE - scope (e.g. extern, static inline) for functions + * - ST_CHECK_FOR_INTERRUPTS - if defined the sort is interruptible + * + * Instead of ST_ELEMENT_TYPE, ST_ELEMENT_TYPE_VOID can be defined. Then + * the generated functions will automatically gain an "element_size" + * parameter. This allows us to generate a traditional qsort function. + * + * One of the following macros must be defined, to show how to compare + * elements. The first two options are arbitrary expressions depending + * on whether an extra pass-through argument is desired, and the third + * option should be defined if the sort function should receive a + * function pointer at runtime. + * + * - ST_COMPARE(a, b) - a simple comparison expression + * - ST_COMPARE(a, b, arg) - variant that takes an extra argument + * - ST_COMPARE_RUNTIME_POINTER - sort function takes a function pointer + * + * To say that the comparator and therefore also sort function should + * receive an extra pass-through argument, specify the type of the + * argument. + * + * - ST_COMPARE_ARG_TYPE - type of extra argument + * + * The prototype of the generated sort function is: + * + * void ST_SORT(ST_ELEMENT_TYPE *data, size_t n, + * [size_t element_size,] + * [ST_SORT_compare_function compare,] + * [ST_COMPARE_ARG_TYPE *arg]); + * + * ST_SORT_compare_function is a function pointer of the following type: + * + * int (*)(const ST_ELEMENT_TYPE *a, const ST_ELEMENT_TYPE *b, + * [ST_COMPARE_ARG_TYPE *arg]) + * + * HISTORY + * + * 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 + * - Convert into a header that can generate specialized functions + * + * IDENTIFICATION + * src/include/lib/sort_template.h + * + *------------------------------------------------------------------------- + */ + +/* $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. + */ + +#define ST_MAKE_PREFIX(a) CppConcat(a,_) +#define ST_MAKE_NAME(a,b) ST_MAKE_NAME_(ST_MAKE_PREFIX(a),b) +#define ST_MAKE_NAME_(a,b) CppConcat(a,b) + +/* + * If the element type is void, we'll also need an element_size argument + * because we don't know the size. + */ +#ifdef ST_ELEMENT_TYPE_VOID +#define ST_ELEMENT_TYPE void +#define ST_SORT_PROTO_ELEMENT_SIZE , size_t element_size +#define ST_SORT_INVOKE_ELEMENT_SIZE , element_size +#else +#define ST_SORT_PROTO_ELEMENT_SIZE +#define ST_SORT_INVOKE_ELEMENT_SIZE +#endif + +/* + * If the user wants to be able to pass in compare functions at runtime, + * we'll need to make that an argument of the sort and med3 functions. + */ +#ifdef ST_COMPARE_RUNTIME_POINTER +/* + * The type of the comparator function pointer that ST_SORT will take, unless + * you've already declared a type name manually and want to use that instead of + * having a new one defined. + */ +#ifndef ST_COMPARATOR_TYPE_NAME +#define ST_COMPARATOR_TYPE_NAME ST_MAKE_NAME(ST_SORT, compare_function) +#endif +#define ST_COMPARE compare +#ifndef ST_COMPARE_ARG_TYPE +#define ST_SORT_PROTO_COMPARE , ST_COMPARATOR_TYPE_NAME compare +#define ST_SORT_INVOKE_COMPARE , compare +#else +#define ST_SORT_PROTO_COMPARE , ST_COMPARATOR_TYPE_NAME compare +#define ST_SORT_INVOKE_COMPARE , compare +#endif +#else +#define ST_SORT_PROTO_COMPARE +#define ST_SORT_INVOKE_COMPARE +#endif + +/* + * If the user wants to use a compare function or expression that takes an + * extra argument, we'll need to make that an argument of the sort, compare and + * med3 functions. + */ +#ifdef ST_COMPARE_ARG_TYPE +#define ST_SORT_PROTO_ARG , ST_COMPARE_ARG_TYPE *arg +#define ST_SORT_INVOKE_ARG , arg +#else +#define ST_SORT_PROTO_ARG +#define ST_SORT_INVOKE_ARG +#endif + +#ifdef ST_DECLARE + +#ifdef ST_COMPARE_RUNTIME_POINTER +typedef int (*ST_COMPARATOR_TYPE_NAME) (const ST_ELEMENT_TYPE *, + const ST_ELEMENT_TYPE * ST_SORT_PROTO_ARG); +#endif + +/* Declare the sort function. Note optional arguments at end. */ +ST_SCOPE void ST_SORT(ST_ELEMENT_TYPE * first, size_t n + ST_SORT_PROTO_ELEMENT_SIZE + ST_SORT_PROTO_COMPARE + ST_SORT_PROTO_ARG); + +#endif + +#ifdef ST_DEFINE + +/* sort private helper functions */ +#define ST_MED3 ST_MAKE_NAME(ST_SORT, med3) +#define ST_SWAP ST_MAKE_NAME(ST_SORT, swap) +#define ST_SWAPN ST_MAKE_NAME(ST_SORT, swapn) + +/* Users expecting to run very large sorts may need them to be interruptible. */ +#ifdef ST_CHECK_FOR_INTERRUPTS +#define DO_CHECK_FOR_INTERRUPTS() CHECK_FOR_INTERRUPTS() +#else +#define DO_CHECK_FOR_INTERRUPTS() +#endif + +/* + * Create wrapper macros that know how to invoke compare, med3 and sort with + * the right arguments. + */ +#ifdef ST_COMPARE_RUNTIME_POINTER +#define DO_COMPARE(a_, b_) ST_COMPARE((a_), (b_) ST_SORT_INVOKE_ARG) +#elif defined(ST_COMPARE_ARG_TYPE) +#define DO_COMPARE(a_, b_) ST_COMPARE((a_), (b_), arg) +#else +#define DO_COMPARE(a_, b_) ST_COMPARE((a_), (b_)) +#endif +#define DO_MED3(a_, b_, c_) \ + ST_MED3((a_), (b_), (c_) \ + ST_SORT_INVOKE_COMPARE \ + ST_SORT_INVOKE_ARG) +#define DO_SORT(a_, n_) \ + ST_SORT((a_), (n_) \ + ST_SORT_INVOKE_ELEMENT_SIZE \ + ST_SORT_INVOKE_COMPARE \ + ST_SORT_INVOKE_ARG) + +/* + * If we're working with void pointers, we'll use pointer arithmetic based on + * uint8, and use the runtime element_size to step through the array and swap + * elements. Otherwise we'll work with ST_ELEMENT_TYPE. + */ +#ifndef ST_ELEMENT_TYPE_VOID +#define ST_POINTER_TYPE ST_ELEMENT_TYPE +#define ST_POINTER_STEP 1 +#define DO_SWAPN(a_, b_, n_) ST_SWAPN((a_), (b_), (n_)) +#define DO_SWAP(a_, b_) ST_SWAP((a_), (b_)) +#else +#define ST_POINTER_TYPE uint8 +#define ST_POINTER_STEP element_size +#define DO_SWAPN(a_, b_, n_) ST_SWAPN((a_), (b_), (n_)) +#define DO_SWAP(a_, b_) DO_SWAPN((a_), (b_), element_size) +#endif + +/* + * Find the median of three values. Currently, performance seems to be best + * if the comparator is inlined here, but the med3 function is not inlined + * in the qsort function. + */ +static pg_noinline ST_ELEMENT_TYPE * +ST_MED3(ST_ELEMENT_TYPE * a, + ST_ELEMENT_TYPE * b, + ST_ELEMENT_TYPE * c + ST_SORT_PROTO_COMPARE + ST_SORT_PROTO_ARG) +{ + return DO_COMPARE(a, b) < 0 ? + (DO_COMPARE(b, c) < 0 ? b : (DO_COMPARE(a, c) < 0 ? c : a)) + : (DO_COMPARE(b, c) > 0 ? b : (DO_COMPARE(a, c) < 0 ? a : c)); +} + +static inline void +ST_SWAP(ST_POINTER_TYPE * a, ST_POINTER_TYPE * b) +{ + ST_POINTER_TYPE tmp = *a; + + *a = *b; + *b = tmp; +} + +static inline void +ST_SWAPN(ST_POINTER_TYPE * a, ST_POINTER_TYPE * b, size_t n) +{ + for (size_t i = 0; i < n; ++i) + ST_SWAP(&a[i], &b[i]); +} + +/* + * Sort an array. + */ +ST_SCOPE void +ST_SORT(ST_ELEMENT_TYPE * data, size_t n + ST_SORT_PROTO_ELEMENT_SIZE + ST_SORT_PROTO_COMPARE + ST_SORT_PROTO_ARG) +{ + ST_POINTER_TYPE *a = (ST_POINTER_TYPE *) data, + *pa, + *pb, + *pc, + *pd, + *pl, + *pm, + *pn; + size_t d1, + d2; + int r, + presorted; + +loop: + DO_CHECK_FOR_INTERRUPTS(); + if (n < 7) + { + for (pm = a + ST_POINTER_STEP; pm < a + n * ST_POINTER_STEP; + pm += ST_POINTER_STEP) + for (pl = pm; pl > a && DO_COMPARE(pl - ST_POINTER_STEP, pl) > 0; + pl -= ST_POINTER_STEP) + DO_SWAP(pl, pl - ST_POINTER_STEP); + return; + } + presorted = 1; + for (pm = a + ST_POINTER_STEP; pm < a + n * ST_POINTER_STEP; + pm += ST_POINTER_STEP) + { + DO_CHECK_FOR_INTERRUPTS(); + if (DO_COMPARE(pm - ST_POINTER_STEP, pm) > 0) + { + presorted = 0; + break; + } + } + if (presorted) + return; + pm = a + (n / 2) * ST_POINTER_STEP; + if (n > 7) + { + pl = a; + pn = a + (n - 1) * ST_POINTER_STEP; + if (n > 40) + { + size_t d = (n / 8) * ST_POINTER_STEP; + + pl = DO_MED3(pl, pl + d, pl + 2 * d); + pm = DO_MED3(pm - d, pm, pm + d); + pn = DO_MED3(pn - 2 * d, pn - d, pn); + } + pm = DO_MED3(pl, pm, pn); + } + DO_SWAP(a, pm); + pa = pb = a + ST_POINTER_STEP; + pc = pd = a + (n - 1) * ST_POINTER_STEP; + for (;;) + { + while (pb <= pc && (r = DO_COMPARE(pb, a)) <= 0) + { + if (r == 0) + { + DO_SWAP(pa, pb); + pa += ST_POINTER_STEP; + } + pb += ST_POINTER_STEP; + DO_CHECK_FOR_INTERRUPTS(); + } + while (pb <= pc && (r = DO_COMPARE(pc, a)) >= 0) + { + if (r == 0) + { + DO_SWAP(pc, pd); + pd -= ST_POINTER_STEP; + } + pc -= ST_POINTER_STEP; + DO_CHECK_FOR_INTERRUPTS(); + } + if (pb > pc) + break; + DO_SWAP(pb, pc); + pb += ST_POINTER_STEP; + pc -= ST_POINTER_STEP; + } + pn = a + n * ST_POINTER_STEP; + d1 = Min(pa - a, pb - pa); + DO_SWAPN(a, pb - d1, d1); + d1 = Min(pd - pc, pn - pd - ST_POINTER_STEP); + DO_SWAPN(pb, pn - d1, d1); + d1 = pb - pa; + d2 = pd - pc; + if (d1 <= d2) + { + /* Recurse on left partition, then iterate on right partition */ + if (d1 > ST_POINTER_STEP) + DO_SORT(a, d1 / ST_POINTER_STEP); + if (d2 > ST_POINTER_STEP) + { + /* Iterate rather than recurse to save stack space */ + /* DO_SORT(pn - d2, d2 / ST_POINTER_STEP) */ + a = pn - d2; + n = d2 / ST_POINTER_STEP; + goto loop; + } + } + else + { + /* Recurse on right partition, then iterate on left partition */ + if (d2 > ST_POINTER_STEP) + DO_SORT(pn - d2, d2 / ST_POINTER_STEP); + if (d1 > ST_POINTER_STEP) + { + /* Iterate rather than recurse to save stack space */ + /* DO_SORT(a, d1 / ST_POINTER_STEP) */ + n = d1 / ST_POINTER_STEP; + goto loop; + } + } +} +#endif + +#undef DO_CHECK_FOR_INTERRUPTS +#undef DO_COMPARE +#undef DO_MED3 +#undef DO_SORT +#undef DO_SWAP +#undef DO_SWAPN +#undef ST_CHECK_FOR_INTERRUPTS +#undef ST_COMPARATOR_TYPE_NAME +#undef ST_COMPARE +#undef ST_COMPARE_ARG_TYPE +#undef ST_COMPARE_RUNTIME_POINTER +#undef ST_ELEMENT_TYPE +#undef ST_ELEMENT_TYPE_VOID +#undef ST_MAKE_NAME +#undef ST_MAKE_NAME_ +#undef ST_MAKE_PREFIX +#undef ST_MED3 +#undef ST_POINTER_STEP +#undef ST_POINTER_TYPE +#undef ST_SCOPE +#undef ST_SORT +#undef ST_SORT_INVOKE_ARG +#undef ST_SORT_INVOKE_COMPARE +#undef ST_SORT_INVOKE_ELEMENT_SIZE +#undef ST_SORT_PROTO_ARG +#undef ST_SORT_PROTO_COMPARE +#undef ST_SORT_PROTO_ELEMENT_SIZE +#undef ST_SWAP +#undef ST_SWAPN diff --git a/install/include/postgresql/server/lib/stringinfo.h b/install/include/postgresql/server/lib/stringinfo.h new file mode 100644 index 00000000000..36a416f8e0a --- /dev/null +++ b/install/include/postgresql/server/lib/stringinfo.h @@ -0,0 +1,161 @@ +/*------------------------------------------------------------------------- + * + * stringinfo.h + * Declarations/definitions for "StringInfo" functions. + * + * StringInfo provides an extensible string data type (currently limited to a + * length of 1GB). It can be used to buffer either ordinary C strings + * (null-terminated text) or arbitrary binary data. All storage is allocated + * with palloc() (falling back to malloc in frontend code). + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/lib/stringinfo.h + * + *------------------------------------------------------------------------- + */ +#ifndef STRINGINFO_H +#define STRINGINFO_H + +/*------------------------- + * StringInfoData holds information about an extensible string. + * data is the current buffer for the string (allocated with palloc). + * len is the current string length. There is guaranteed to be + * a terminating '\0' at data[len], although this is not very + * useful when the string holds binary data rather than text. + * maxlen is the allocated size in bytes of 'data', i.e. the maximum + * string size (including the terminating '\0' char) that we can + * currently store in 'data' without having to reallocate + * more space. We must always have maxlen > len. + * cursor is initialized to zero by makeStringInfo or initStringInfo, + * but is not otherwise touched by the stringinfo.c routines. + * Some routines use it to scan through a StringInfo. + *------------------------- + */ +typedef struct StringInfoData +{ + char *data; + int len; + int maxlen; + int cursor; +} StringInfoData; + +typedef StringInfoData *StringInfo; + + +/*------------------------ + * There are two ways to create a StringInfo object initially: + * + * StringInfo stringptr = makeStringInfo(); + * Both the StringInfoData and the data buffer are palloc'd. + * + * StringInfoData string; + * initStringInfo(&string); + * The data buffer is palloc'd but the StringInfoData is just local. + * This is the easiest approach for a StringInfo object that will + * only live as long as the current routine. + * + * To destroy a StringInfo, pfree() the data buffer, and then pfree() the + * StringInfoData if it was palloc'd. There's no special support for this. + * + * NOTE: some routines build up a string using StringInfo, and then + * release the StringInfoData but return the data string itself to their + * caller. At that point the data string looks like a plain palloc'd + * string. + *------------------------- + */ + +/*------------------------ + * makeStringInfo + * Create an empty 'StringInfoData' & return a pointer to it. + */ +extern StringInfo makeStringInfo(void); + +/*------------------------ + * initStringInfo + * Initialize a StringInfoData struct (with previously undefined contents) + * to describe an empty string. + */ +extern void initStringInfo(StringInfo str); + +/*------------------------ + * resetStringInfo + * Clears the current content of the StringInfo, if any. The + * StringInfo remains valid. + */ +extern void resetStringInfo(StringInfo str); + +/*------------------------ + * appendStringInfo + * Format text data under the control of fmt (an sprintf-style format string) + * and append it to whatever is already in str. More space is allocated + * to str if necessary. This is sort of like a combination of sprintf and + * strcat. + */ +extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3); + +/*------------------------ + * appendStringInfoVA + * Attempt to format text data under the control of fmt (an sprintf-style + * format string) and append it to whatever is already in str. If successful + * return zero; if not (because there's not enough space), return an estimate + * of the space needed, without modifying str. Typically the caller should + * pass the return value to enlargeStringInfo() before trying again; see + * appendStringInfo for standard usage pattern. + */ +extern int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2, 0); + +/*------------------------ + * appendStringInfoString + * Append a null-terminated string to str. + * Like appendStringInfo(str, "%s", s) but faster. + */ +extern void appendStringInfoString(StringInfo str, const char *s); + +/*------------------------ + * appendStringInfoChar + * Append a single byte to str. + * Like appendStringInfo(str, "%c", ch) but much faster. + */ +extern void appendStringInfoChar(StringInfo str, char ch); + +/*------------------------ + * appendStringInfoCharMacro + * As above, but a macro for even more speed where it matters. + * Caution: str argument will be evaluated multiple times. + */ +#define appendStringInfoCharMacro(str,ch) \ + (((str)->len + 1 >= (str)->maxlen) ? \ + appendStringInfoChar(str, ch) : \ + (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0')) + +/*------------------------ + * appendStringInfoSpaces + * Append a given number of spaces to str. + */ +extern void appendStringInfoSpaces(StringInfo str, int count); + +/*------------------------ + * appendBinaryStringInfo + * Append arbitrary binary data to a StringInfo, allocating more space + * if necessary. + */ +extern void appendBinaryStringInfo(StringInfo str, + const void *data, int datalen); + +/*------------------------ + * appendBinaryStringInfoNT + * Append arbitrary binary data to a StringInfo, allocating more space + * if necessary. Does not ensure a trailing null-byte exists. + */ +extern void appendBinaryStringInfoNT(StringInfo str, + const void *data, int datalen); + +/*------------------------ + * enlargeStringInfo + * Make sure a StringInfo's buffer can hold at least 'needed' more bytes. + */ +extern void enlargeStringInfo(StringInfo str, int needed); + +#endif /* STRINGINFO_H */ diff --git a/install/include/postgresql/server/libpq/auth.h b/install/include/postgresql/server/libpq/auth.h new file mode 100644 index 00000000000..7fac05b813f --- /dev/null +++ b/install/include/postgresql/server/libpq/auth.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * auth.h + * Definitions for network authentication routines + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/auth.h + * + *------------------------------------------------------------------------- + */ +#ifndef AUTH_H +#define AUTH_H + +#include "libpq/libpq-be.h" + +extern PGDLLIMPORT char *pg_krb_server_keyfile; +extern PGDLLIMPORT bool pg_krb_caseins_users; +extern PGDLLIMPORT bool pg_gss_accept_delegation; + +extern void ClientAuthentication(Port *port); +extern void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, + int extralen); + +/* Hook for plugins to get control in ClientAuthentication() */ +typedef void (*ClientAuthentication_hook_type) (Port *, int); +extern PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook; + +/* hook type for password manglers */ +typedef char *(*auth_password_hook_typ) (char *input); + +/* Default LDAP password mutator hook, can be overridden by a shared library */ +extern PGDLLIMPORT auth_password_hook_typ ldap_password_hook; + +#endif /* AUTH_H */ diff --git a/install/include/postgresql/server/libpq/be-fsstubs.h b/install/include/postgresql/server/libpq/be-fsstubs.h new file mode 100644 index 00000000000..e70a6cb56cc --- /dev/null +++ b/install/include/postgresql/server/libpq/be-fsstubs.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * be-fsstubs.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/be-fsstubs.h + * + *------------------------------------------------------------------------- + */ +#ifndef BE_FSSTUBS_H +#define BE_FSSTUBS_H + +/* + * These are not fmgr-callable, but are available to C code. + * Probably these should have had the underscore-free names, + * but too late now... + */ +extern int lo_read(int fd, char *buf, int len); +extern int lo_write(int fd, const char *buf, int len); + +/* + * Cleanup LOs at xact commit/abort + */ +extern void AtEOXact_LargeObject(bool isCommit); +extern void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, + SubTransactionId parentSubid); + +#endif /* BE_FSSTUBS_H */ diff --git a/install/include/postgresql/server/libpq/be-gssapi-common.h b/install/include/postgresql/server/libpq/be-gssapi-common.h new file mode 100644 index 00000000000..0381f0ce771 --- /dev/null +++ b/install/include/postgresql/server/libpq/be-gssapi-common.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * be-gssapi-common.h + * Definitions for GSSAPI authentication and encryption handling + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/be-gssapi-common.h + * + *------------------------------------------------------------------------- + */ + +#ifndef BE_GSSAPI_COMMON_H +#define BE_GSSAPI_COMMON_H + +#ifdef ENABLE_GSS + +#if defined(HAVE_GSSAPI_H) +#include +#include +#else +#include +#include +#endif + +extern void pg_GSS_error(const char *errmsg, + OM_uint32 maj_stat, OM_uint32 min_stat); + +extern void pg_store_delegated_credential(gss_cred_id_t cred); +#endif /* ENABLE_GSS */ + +#endif /* BE_GSSAPI_COMMON_H */ diff --git a/install/include/postgresql/server/libpq/crypt.h b/install/include/postgresql/server/libpq/crypt.h new file mode 100644 index 00000000000..ddcd27469ac --- /dev/null +++ b/install/include/postgresql/server/libpq/crypt.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * crypt.h + * Interface to libpq/crypt.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/crypt.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CRYPT_H +#define PG_CRYPT_H + +#include "datatype/timestamp.h" + +/* + * Types of password hashes or secrets. + * + * Plaintext passwords can be passed in by the user, in a CREATE/ALTER USER + * command. They will be encrypted to MD5 or SCRAM-SHA-256 format, before + * storing on-disk, so only MD5 and SCRAM-SHA-256 passwords should appear + * in pg_authid.rolpassword. They are also the allowed values for the + * password_encryption GUC. + */ +typedef enum PasswordType +{ + PASSWORD_TYPE_PLAINTEXT = 0, + PASSWORD_TYPE_MD5, + PASSWORD_TYPE_SCRAM_SHA_256 +} PasswordType; + +extern PasswordType get_password_type(const char *shadow_pass); +extern char *encrypt_password(PasswordType target_type, const char *role, + const char *password); + +extern char *get_role_password(const char *role, const char **logdetail); + +extern int md5_crypt_verify(const char *role, const char *shadow_pass, + const char *client_pass, const char *md5_salt, + int md5_salt_len, const char **logdetail); +extern int plain_crypt_verify(const char *role, const char *shadow_pass, + const char *client_pass, + const char **logdetail); + +#endif diff --git a/install/include/postgresql/server/libpq/hba.h b/install/include/postgresql/server/libpq/hba.h new file mode 100644 index 00000000000..189f6d0df24 --- /dev/null +++ b/install/include/postgresql/server/libpq/hba.h @@ -0,0 +1,186 @@ +/*------------------------------------------------------------------------- + * + * hba.h + * Interface to hba.c + * + * + * src/include/libpq/hba.h + * + *------------------------------------------------------------------------- + */ +#ifndef HBA_H +#define HBA_H + +#include "libpq/pqcomm.h" /* pgrminclude ignore */ /* needed for NetBSD */ +#include "nodes/pg_list.h" +#include "regex/regex.h" + + +/* + * The following enum represents the authentication methods that + * are supported by PostgreSQL. + * + * Note: keep this in sync with the UserAuthName array in hba.c. + */ +typedef enum UserAuth +{ + uaReject, + uaImplicitReject, /* Not a user-visible option */ + uaTrust, + uaIdent, + uaPassword, + uaMD5, + uaSCRAM, + uaGSS, + uaSSPI, + uaPAM, + uaBSD, + uaLDAP, + uaCert, + uaRADIUS, + uaPeer +#define USER_AUTH_LAST uaPeer /* Must be last value of this enum */ +} UserAuth; + +/* + * Data structures representing pg_hba.conf entries + */ + +typedef enum IPCompareMethod +{ + ipCmpMask, + ipCmpSameHost, + ipCmpSameNet, + ipCmpAll +} IPCompareMethod; + +typedef enum ConnType +{ + ctLocal, + ctHost, + ctHostSSL, + ctHostNoSSL, + ctHostGSS, + ctHostNoGSS, +} ConnType; + +typedef enum ClientCertMode +{ + clientCertOff, + clientCertCA, + clientCertFull +} ClientCertMode; + +typedef enum ClientCertName +{ + clientCertCN, + clientCertDN +} ClientCertName; + +/* + * A single string token lexed from an authentication configuration file + * (pg_ident.conf or pg_hba.conf), together with whether the token has + * been quoted. If "string" begins with a slash, it may optionally + * contain a regular expression (currently used for pg_ident.conf when + * building IdentLines and for pg_hba.conf when building HbaLines). + */ +typedef struct AuthToken +{ + char *string; + bool quoted; + regex_t *regex; +} AuthToken; + +typedef struct HbaLine +{ + char *sourcefile; + int linenumber; + char *rawline; + ConnType conntype; + List *databases; + List *roles; + struct sockaddr_storage addr; + int addrlen; /* zero if we don't have a valid addr */ + struct sockaddr_storage mask; + int masklen; /* zero if we don't have a valid mask */ + IPCompareMethod ip_cmp_method; + char *hostname; + UserAuth auth_method; + char *usermap; + char *pamservice; + bool pam_use_hostname; + bool ldaptls; + char *ldapscheme; + char *ldapserver; + int ldapport; + char *ldapbinddn; + char *ldapbindpasswd; + char *ldapsearchattribute; + char *ldapsearchfilter; + char *ldapbasedn; + int ldapscope; + char *ldapprefix; + char *ldapsuffix; + ClientCertMode clientcert; + ClientCertName clientcertname; + char *krb_realm; + bool include_realm; + bool compat_realm; + bool upn_username; + List *radiusservers; + char *radiusservers_s; + List *radiussecrets; + char *radiussecrets_s; + List *radiusidentifiers; + char *radiusidentifiers_s; + List *radiusports; + char *radiusports_s; +} HbaLine; + +typedef struct IdentLine +{ + int linenumber; + + char *usermap; + AuthToken *system_user; + AuthToken *pg_user; +} IdentLine; + +/* + * TokenizedAuthLine represents one line lexed from an authentication + * configuration file. Each item in the "fields" list is a sub-list of + * AuthTokens. We don't emit a TokenizedAuthLine for empty or all-comment + * lines, so "fields" is never NIL (nor are any of its sub-lists). + * + * Exception: if an error occurs during tokenization, we might have + * fields == NIL, in which case err_msg != NULL. + */ +typedef struct TokenizedAuthLine +{ + List *fields; /* List of lists of AuthTokens */ + char *file_name; /* File name of origin */ + int line_num; /* Line number */ + char *raw_line; /* Raw line text */ + char *err_msg; /* Error message if any */ +} TokenizedAuthLine; + +/* kluge to avoid including libpq/libpq-be.h here */ +typedef struct Port hbaPort; + +extern bool load_hba(void); +extern bool load_ident(void); +extern const char *hba_authname(UserAuth auth_method); +extern void hba_getauthmethod(hbaPort *port); +extern int check_usermap(const char *usermap_name, + const char *pg_user, const char *system_user, + bool case_insensitive); +extern HbaLine *parse_hba_line(TokenizedAuthLine *tok_line, int elevel); +extern IdentLine *parse_ident_line(TokenizedAuthLine *tok_line, int elevel); +extern bool pg_isblank(const char c); +extern FILE *open_auth_file(const char *filename, int elevel, int depth, + char **err_msg); +extern void free_auth_file(FILE *file, int depth); +extern void tokenize_auth_file(const char *filename, FILE *file, + List **tok_lines, int elevel, int depth); + +#endif /* HBA_H */ diff --git a/install/include/postgresql/server/libpq/ifaddr.h b/install/include/postgresql/server/libpq/ifaddr.h new file mode 100644 index 00000000000..fb50efe6ae7 --- /dev/null +++ b/install/include/postgresql/server/libpq/ifaddr.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * ifaddr.h + * IP netmask calculations, and enumerating network interfaces. + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/libpq/ifaddr.h + * + *------------------------------------------------------------------------- + */ +#ifndef IFADDR_H +#define IFADDR_H + +#include "libpq/pqcomm.h" /* pgrminclude ignore */ + +typedef void (*PgIfAddrCallback) (struct sockaddr *addr, + struct sockaddr *netmask, + void *cb_data); + +extern int pg_range_sockaddr(const struct sockaddr_storage *addr, + const struct sockaddr_storage *netaddr, + const struct sockaddr_storage *netmask); + +extern int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, + char *numbits, int family); + +extern int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data); + +#endif /* IFADDR_H */ diff --git a/install/include/postgresql/server/libpq/libpq-be-fe-helpers.h b/install/include/postgresql/server/libpq/libpq-be-fe-helpers.h new file mode 100644 index 00000000000..a4b3e805b9d --- /dev/null +++ b/install/include/postgresql/server/libpq/libpq-be-fe-helpers.h @@ -0,0 +1,369 @@ +/*------------------------------------------------------------------------- + * + * libpq-be-fe-helpers.h + * Helper functions for using libpq in extensions + * + * Code built directly into the backend is not allowed to link to libpq + * directly. Extension code is allowed to use libpq however. However, libpq + * used in extensions has to be careful to block inside libpq, otherwise + * interrupts will not be processed, leading to issues like unresolvable + * deadlocks. Backend code also needs to take care to acquire/release an + * external fd for the connection, otherwise fd.c's accounting of fd's is + * broken. + * + * This file provides helper functions to make it easier to comply with these + * rules. It is a header only library as it needs to be linked into each + * extension using libpq, and it seems too small to be worth adding a + * dedicated static library for. + * + * TODO: For historical reasons the connections established here are not put + * into non-blocking mode. That can lead to blocking even when only the async + * libpq functions are used. This should be fixed. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/libpq-be-fe-helpers.h + * + *------------------------------------------------------------------------- + */ +#ifndef LIBPQ_BE_FE_HELPERS_H +#define LIBPQ_BE_FE_HELPERS_H + +/* + * Despite the name, BUILDING_DLL is set only when building code directly part + * of the backend. Which also is where libpq isn't allowed to be + * used. Obviously this doesn't protect against libpq-fe.h getting included + * otherwise, but perhaps still protects against a few mistakes... + */ +#ifdef BUILDING_DLL +#error "libpq may not be used code directly built into the backend" +#endif + +#include "libpq-fe.h" +#include "miscadmin.h" +#include "storage/fd.h" +#include "storage/latch.h" +#include "utils/wait_event.h" + + +static inline void libpqsrv_connect_prepare(void); +static inline void libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info); +static inline PGresult *libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info); +static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info); + + +/* + * PQconnectdb() wrapper that reserves a file descriptor and processes + * interrupts during connection establishment. + * + * Throws an error if AcquireExternalFD() fails, but does not throw if + * connection establishment itself fails. Callers need to use PQstatus() to + * check if connection establishment succeeded. + */ +static inline PGconn * +libpqsrv_connect(const char *conninfo, uint32 wait_event_info) +{ + PGconn *conn = NULL; + + libpqsrv_connect_prepare(); + + conn = PQconnectStart(conninfo); + + libpqsrv_connect_internal(conn, wait_event_info); + + return conn; +} + +/* + * Like libpqsrv_connect(), except that this is a wrapper for + * PQconnectdbParams(). + */ +static inline PGconn * +libpqsrv_connect_params(const char *const *keywords, + const char *const *values, + int expand_dbname, + uint32 wait_event_info) +{ + PGconn *conn = NULL; + + libpqsrv_connect_prepare(); + + conn = PQconnectStartParams(keywords, values, expand_dbname); + + libpqsrv_connect_internal(conn, wait_event_info); + + return conn; +} + +/* + * PQfinish() wrapper that additionally releases the reserved file descriptor. + * + * It is allowed to call this with a NULL pgconn iff NULL was returned by + * libpqsrv_connect*. + */ +static inline void +libpqsrv_disconnect(PGconn *conn) +{ + /* + * If no connection was established, we haven't reserved an FD for it (or + * already released it). This rule makes it easier to write PG_CATCH() + * handlers for this facility's users. + * + * See also libpqsrv_connect_internal(). + */ + if (conn == NULL) + return; + + ReleaseExternalFD(); + PQfinish(conn); +} + + +/* internal helper functions follow */ + + +/* + * Helper function for all connection establishment functions. + */ +static inline void +libpqsrv_connect_prepare(void) +{ + /* + * We must obey fd.c's limit on non-virtual file descriptors. Assume that + * a PGconn represents one long-lived FD. (Doing this here also ensures + * that VFDs are closed if needed to make room.) + */ + if (!AcquireExternalFD()) + { +#ifndef WIN32 /* can't write #if within ereport() macro */ + ereport(ERROR, + (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION), + errmsg("could not establish connection"), + errdetail("There are too many open files on the local server."), + errhint("Raise the server's max_files_per_process and/or \"ulimit -n\" limits."))); +#else + ereport(ERROR, + (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION), + errmsg("could not establish connection"), + errdetail("There are too many open files on the local server."), + errhint("Raise the server's max_files_per_process setting."))); +#endif + } +} + +/* + * Helper function for all connection establishment functions. + */ +static inline void +libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info) +{ + /* + * With conn == NULL libpqsrv_disconnect() wouldn't release the FD. So do + * that here. + */ + if (conn == NULL) + { + ReleaseExternalFD(); + return; + } + + /* + * Can't wait without a socket. Note that we don't want to close the libpq + * connection yet, so callers can emit a useful error. + */ + if (PQstatus(conn) == CONNECTION_BAD) + return; + + /* + * WaitLatchOrSocket() can conceivably fail, handle that case here instead + * of requiring all callers to do so. + */ + PG_TRY(); + { + PostgresPollingStatusType status; + + /* + * Poll connection until we have OK or FAILED status. + * + * Per spec for PQconnectPoll, first wait till socket is write-ready. + */ + status = PGRES_POLLING_WRITING; + while (status != PGRES_POLLING_OK && status != PGRES_POLLING_FAILED) + { + int io_flag; + int rc; + + if (status == PGRES_POLLING_READING) + io_flag = WL_SOCKET_READABLE; +#ifdef WIN32 + + /* + * Windows needs a different test while waiting for + * connection-made + */ + else if (PQstatus(conn) == CONNECTION_STARTED) + io_flag = WL_SOCKET_CONNECTED; +#endif + else + io_flag = WL_SOCKET_WRITEABLE; + + rc = WaitLatchOrSocket(MyLatch, + WL_EXIT_ON_PM_DEATH | WL_LATCH_SET | io_flag, + PQsocket(conn), + 0, + wait_event_info); + + /* Interrupted? */ + if (rc & WL_LATCH_SET) + { + ResetLatch(MyLatch); + CHECK_FOR_INTERRUPTS(); + } + + /* If socket is ready, advance the libpq state machine */ + if (rc & io_flag) + status = PQconnectPoll(conn); + } + } + PG_CATCH(); + { + /* + * If an error is thrown here, the callers won't call + * libpqsrv_disconnect() with a conn, so release resources + * immediately. + */ + ReleaseExternalFD(); + PQfinish(conn); + + PG_RE_THROW(); + } + PG_END_TRY(); +} + +/* + * PQexec() wrapper that processes interrupts. + * + * Unless PQsetnonblocking(conn, 1) is in effect, this can't process + * interrupts while pushing the query text to the server. Consider that + * setting if query strings can be long relative to TCP buffer size. + * + * This has the preconditions of PQsendQuery(), not those of PQexec(). Most + * notably, PQexec() would silently discard any prior query results. + */ +static inline PGresult * +libpqsrv_exec(PGconn *conn, const char *query, uint32 wait_event_info) +{ + if (!PQsendQuery(conn, query)) + return NULL; + return libpqsrv_get_result_last(conn, wait_event_info); +} + +/* + * PQexecParams() wrapper that processes interrupts. + * + * See notes at libpqsrv_exec(). + */ +static inline PGresult * +libpqsrv_exec_params(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat, + uint32 wait_event_info) +{ + if (!PQsendQueryParams(conn, command, nParams, paramTypes, paramValues, + paramLengths, paramFormats, resultFormat)) + return NULL; + return libpqsrv_get_result_last(conn, wait_event_info); +} + +/* + * Like PQexec(), loop over PQgetResult() until it returns NULL or another + * terminal state. Return the last non-NULL result or the terminal state. + */ +static inline PGresult * +libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info) +{ + PGresult *volatile lastResult = NULL; + + /* In what follows, do not leak any PGresults on an error. */ + PG_TRY(); + { + for (;;) + { + /* Wait for, and collect, the next PGresult. */ + PGresult *result; + + result = libpqsrv_get_result(conn, wait_event_info); + if (result == NULL) + break; /* query is complete, or failure */ + + /* + * Emulate PQexec()'s behavior of returning the last result when + * there are many. + */ + PQclear(lastResult); + lastResult = result; + + if (PQresultStatus(lastResult) == PGRES_COPY_IN || + PQresultStatus(lastResult) == PGRES_COPY_OUT || + PQresultStatus(lastResult) == PGRES_COPY_BOTH || + PQstatus(conn) == CONNECTION_BAD) + break; + } + } + PG_CATCH(); + { + PQclear(lastResult); + PG_RE_THROW(); + } + PG_END_TRY(); + + return lastResult; +} + +/* + * Perform the equivalent of PQgetResult(), but watch for interrupts. + */ +static inline PGresult * +libpqsrv_get_result(PGconn *conn, uint32 wait_event_info) +{ + /* + * Collect data until PQgetResult is ready to get the result without + * blocking. + */ + while (PQisBusy(conn)) + { + int rc; + + rc = WaitLatchOrSocket(MyLatch, + WL_EXIT_ON_PM_DEATH | WL_LATCH_SET | + WL_SOCKET_READABLE, + PQsocket(conn), + 0, + wait_event_info); + + /* Interrupted? */ + if (rc & WL_LATCH_SET) + { + ResetLatch(MyLatch); + CHECK_FOR_INTERRUPTS(); + } + + /* Consume whatever data is available from the socket */ + if (PQconsumeInput(conn) == 0) + { + /* trouble; expect PQgetResult() to return NULL */ + break; + } + } + + /* Now we can collect and return the next PGresult */ + return PQgetResult(conn); +} + +#endif /* LIBPQ_BE_FE_HELPERS_H */ diff --git a/install/include/postgresql/server/libpq/libpq-be.h b/install/include/postgresql/server/libpq/libpq-be.h new file mode 100644 index 00000000000..3b2ce9908f8 --- /dev/null +++ b/install/include/postgresql/server/libpq/libpq-be.h @@ -0,0 +1,354 @@ +/*------------------------------------------------------------------------- + * + * libpq-be.h + * This file contains definitions for structures and externs used + * by the postmaster during client authentication. + * + * Note that this is backend-internal and is NOT exported to clients. + * Structs that need to be client-visible are in pqcomm.h. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/libpq-be.h + * + *------------------------------------------------------------------------- + */ +#ifndef LIBPQ_BE_H +#define LIBPQ_BE_H + +#include +#ifdef USE_OPENSSL +#include +#include +#endif +#include + +#ifdef ENABLE_GSS +#if defined(HAVE_GSSAPI_H) +#include +#else +#include +#endif /* HAVE_GSSAPI_H */ +#endif /* ENABLE_GSS */ + +#ifdef ENABLE_SSPI +#define SECURITY_WIN32 +#if defined(WIN32) && !defined(_MSC_VER) +#include +#endif +#include +#undef SECURITY_WIN32 + +#ifndef ENABLE_GSS +/* + * Define a fake structure compatible with GSSAPI on Unix. + */ +typedef struct +{ + void *value; + int length; +} gss_buffer_desc; +#endif +#endif /* ENABLE_SSPI */ + +#include "datatype/timestamp.h" +#include "libpq/hba.h" +#include "libpq/pqcomm.h" + + +typedef enum CAC_state +{ + CAC_OK, + CAC_STARTUP, + CAC_SHUTDOWN, + CAC_RECOVERY, + CAC_NOTCONSISTENT, + CAC_TOOMANY +} CAC_state; + + +/* + * GSSAPI specific state information + */ +#if defined(ENABLE_GSS) | defined(ENABLE_SSPI) +typedef struct +{ + gss_buffer_desc outbuf; /* GSSAPI output token buffer */ +#ifdef ENABLE_GSS + gss_cred_id_t cred; /* GSSAPI connection cred's */ + gss_ctx_id_t ctx; /* GSSAPI connection context */ + gss_name_t name; /* GSSAPI client name */ + char *princ; /* GSSAPI Principal used for auth, NULL if + * GSSAPI auth was not used */ + bool auth; /* GSSAPI Authentication used */ + bool enc; /* GSSAPI encryption in use */ + bool delegated_creds; /* GSSAPI Delegated credentials */ +#endif +} pg_gssinfo; +#endif + +/* + * ClientConnectionInfo includes the fields describing the client connection + * that are copied over to parallel workers as nothing from Port does that. + * The same rules apply for allocations here as for Port (everything must be + * malloc'd or palloc'd in TopMemoryContext). + * + * If you add a struct member here, remember to also handle serialization in + * SerializeClientConnectionInfo() and co. + */ +typedef struct ClientConnectionInfo +{ + /* + * Authenticated identity. The meaning of this identifier is dependent on + * auth_method; it is the identity (if any) that the user presented during + * the authentication cycle, before they were assigned a database role. + * (It is effectively the "SYSTEM-USERNAME" of a pg_ident usermap -- + * though the exact string in use may be different, depending on pg_hba + * options.) + * + * authn_id is NULL if the user has not actually been authenticated, for + * example if the "trust" auth method is in use. + */ + const char *authn_id; + + /* + * The HBA method that determined the above authn_id. This only has + * meaning if authn_id is not NULL; otherwise it's undefined. + */ + UserAuth auth_method; +} ClientConnectionInfo; + +/* + * This is used by the postmaster in its communication with frontends. It + * contains all state information needed during this communication before the + * backend is run. The Port structure is kept in malloc'd memory and is + * still available when a backend is running (see MyProcPort). The data + * it points to must also be malloc'd, or else palloc'd in TopMemoryContext, + * so that it survives into PostgresMain execution! + * + * remote_hostname is set if we did a successful reverse lookup of the + * client's IP address during connection setup. + * remote_hostname_resolv tracks the state of hostname verification: + * +1 = remote_hostname is known to resolve to client's IP address + * -1 = remote_hostname is known NOT to resolve to client's IP address + * 0 = we have not done the forward DNS lookup yet + * -2 = there was an error in name resolution + * If reverse lookup of the client IP address fails, remote_hostname will be + * left NULL while remote_hostname_resolv is set to -2. If reverse lookup + * succeeds but forward lookup fails, remote_hostname_resolv is also set to -2 + * (the case is distinguishable because remote_hostname isn't NULL). In + * either of the -2 cases, remote_hostname_errcode saves the lookup return + * code for possible later use with gai_strerror. + */ + +typedef struct Port +{ + pgsocket sock; /* File descriptor */ + bool noblock; /* is the socket in non-blocking mode? */ + ProtocolVersion proto; /* FE/BE protocol version */ + SockAddr laddr; /* local addr (postmaster) */ + SockAddr raddr; /* remote addr (client) */ + char *remote_host; /* name (or ip addr) of remote host */ + char *remote_hostname; /* name (not ip addr) of remote host, if + * available */ + int remote_hostname_resolv; /* see above */ + int remote_hostname_errcode; /* see above */ + char *remote_port; /* text rep of remote port */ + CAC_state canAcceptConnections; /* postmaster connection status */ + + /* + * Information that needs to be saved from the startup packet and passed + * into backend execution. "char *" fields are NULL if not set. + * guc_options points to a List of alternating option names and values. + */ + char *database_name; + char *user_name; + char *cmdline_options; + List *guc_options; + + /* + * The startup packet application name, only used here for the "connection + * authorized" log message. We shouldn't use this post-startup, instead + * the GUC should be used as application can change it afterward. + */ + char *application_name; + + /* + * Information that needs to be held during the authentication cycle. + */ + HbaLine *hba; + + /* + * TCP keepalive and user timeout settings. + * + * default values are 0 if AF_UNIX or not yet known; current values are 0 + * if AF_UNIX or using the default. Also, -1 in a default value means we + * were unable to find out the default (getsockopt failed). + */ + int default_keepalives_idle; + int default_keepalives_interval; + int default_keepalives_count; + int default_tcp_user_timeout; + int keepalives_idle; + int keepalives_interval; + int keepalives_count; + int tcp_user_timeout; + + /* + * GSSAPI structures. + */ +#if defined(ENABLE_GSS) || defined(ENABLE_SSPI) + + /* + * If GSSAPI is supported and used on this connection, store GSSAPI + * information. Even when GSSAPI is not compiled in, store a NULL pointer + * to keep struct offsets the same (for extension ABI compatibility). + */ + pg_gssinfo *gss; +#else + void *gss; +#endif + + /* + * SSL structures. + */ + bool ssl_in_use; + char *peer_cn; + char *peer_dn; + bool peer_cert_valid; + + /* + * OpenSSL structures. (Keep these last so that the locations of other + * fields are the same whether or not you build with SSL enabled.) + */ +#ifdef USE_OPENSSL + SSL *ssl; + X509 *peer; +#endif +} Port; + +#ifdef USE_SSL +/* + * Hardcoded DH parameters, used in ephemeral DH keying. (See also + * README.SSL for more details on EDH.) + * + * This is the 2048-bit DH parameter from RFC 3526. The generation of the + * prime is specified in RFC 2412 Appendix E, which also discusses the + * design choice of the generator. Note that when loaded with OpenSSL + * this causes DH_check() to fail on DH_NOT_SUITABLE_GENERATOR, where + * leaking a bit is preferred. + */ +#define FILE_DH2048 \ +"-----BEGIN DH PARAMETERS-----\n\ +MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n\ +IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n\ +awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n\ +mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n\ +fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n\ +5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n\ +-----END DH PARAMETERS-----\n" + +/* + * These functions are implemented by the glue code specific to each + * SSL implementation (e.g. be-secure-openssl.c) + */ + +/* + * Initialize global SSL context. + * + * If isServerStart is true, report any errors as FATAL (so we don't return). + * Otherwise, log errors at LOG level and return -1 to indicate trouble, + * preserving the old SSL state if any. Returns 0 if OK. + */ +extern int be_tls_init(bool isServerStart); + +/* + * Destroy global SSL context, if any. + */ +extern void be_tls_destroy(void); + +/* + * Attempt to negotiate SSL connection. + */ +extern int be_tls_open_server(Port *port); + +/* + * Close SSL connection. + */ +extern void be_tls_close(Port *port); + +/* + * Read data from a secure connection. + */ +extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor); + +/* + * Write data to a secure connection. + */ +extern ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor); + +/* + * Return information about the SSL connection. + */ +extern int be_tls_get_cipher_bits(Port *port); +extern const char *be_tls_get_version(Port *port); +extern const char *be_tls_get_cipher(Port *port); +extern void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len); +extern void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len); +extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len); + +/* + * Get the server certificate hash for SCRAM channel binding type + * tls-server-end-point. + * + * The result is a palloc'd hash of the server certificate with its + * size, and NULL if there is no certificate available. + * + * This is not supported with old versions of OpenSSL that don't have + * the X509_get_signature_nid() function. + */ +#if defined(USE_OPENSSL) && (defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO)) +#define HAVE_BE_TLS_GET_CERTIFICATE_HASH +extern char *be_tls_get_certificate_hash(Port *port, size_t *len); +#endif + +/* init hook for SSL, the default sets the password callback if appropriate */ +#ifdef USE_OPENSSL +typedef void (*openssl_tls_init_hook_typ) (SSL_CTX *context, bool isServerStart); +extern PGDLLIMPORT openssl_tls_init_hook_typ openssl_tls_init_hook; +#endif + +#endif /* USE_SSL */ + +#ifdef ENABLE_GSS +/* + * Return information about the GSSAPI authenticated connection + */ +extern bool be_gssapi_get_auth(Port *port); +extern bool be_gssapi_get_enc(Port *port); +extern const char *be_gssapi_get_princ(Port *port); +extern bool be_gssapi_get_delegation(Port *port); + +/* Read and write to a GSSAPI-encrypted connection. */ +extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len); +extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len); +#endif /* ENABLE_GSS */ + +extern PGDLLIMPORT ProtocolVersion FrontendProtocol; +extern PGDLLIMPORT ClientConnectionInfo MyClientConnectionInfo; + +/* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */ + +extern int pq_getkeepalivesidle(Port *port); +extern int pq_getkeepalivesinterval(Port *port); +extern int pq_getkeepalivescount(Port *port); +extern int pq_gettcpusertimeout(Port *port); + +extern int pq_setkeepalivesidle(int idle, Port *port); +extern int pq_setkeepalivesinterval(int interval, Port *port); +extern int pq_setkeepalivescount(int count, Port *port); +extern int pq_settcpusertimeout(int timeout, Port *port); + +#endif /* LIBPQ_BE_H */ diff --git a/install/include/postgresql/server/libpq/libpq-fs.h b/install/include/postgresql/server/libpq/libpq-fs.h new file mode 100644 index 00000000000..f89e0f9e3fb --- /dev/null +++ b/install/include/postgresql/server/libpq/libpq-fs.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * libpq-fs.h + * definitions for using Inversion file system routines (ie, large objects) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/libpq-fs.h + * + *------------------------------------------------------------------------- + */ +#ifndef LIBPQ_FS_H +#define LIBPQ_FS_H + +/* + * Read/write mode flags for inversion (large object) calls + */ + +#define INV_WRITE 0x00020000 +#define INV_READ 0x00040000 + +#endif /* LIBPQ_FS_H */ diff --git a/install/include/postgresql/server/libpq/libpq.h b/install/include/postgresql/server/libpq/libpq.h new file mode 100644 index 00000000000..50fc781f471 --- /dev/null +++ b/install/include/postgresql/server/libpq/libpq.h @@ -0,0 +1,144 @@ +/*------------------------------------------------------------------------- + * + * libpq.h + * POSTGRES LIBPQ buffer structure definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/libpq.h + * + *------------------------------------------------------------------------- + */ +#ifndef LIBPQ_H +#define LIBPQ_H + +#include + +#include "lib/stringinfo.h" +#include "libpq/libpq-be.h" +#include "storage/latch.h" + + +/* + * Callers of pq_getmessage() must supply a maximum expected message size. + * By convention, if there's not any specific reason to use another value, + * use PQ_SMALL_MESSAGE_LIMIT for messages that shouldn't be too long, and + * PQ_LARGE_MESSAGE_LIMIT for messages that can be long. + */ +#define PQ_SMALL_MESSAGE_LIMIT 10000 +#define PQ_LARGE_MESSAGE_LIMIT (MaxAllocSize - 1) + +typedef struct +{ + void (*comm_reset) (void); + int (*flush) (void); + int (*flush_if_writable) (void); + bool (*is_send_pending) (void); + int (*putmessage) (char msgtype, const char *s, size_t len); + void (*putmessage_noblock) (char msgtype, const char *s, size_t len); +} PQcommMethods; + +extern const PGDLLIMPORT PQcommMethods *PqCommMethods; + +#define pq_comm_reset() (PqCommMethods->comm_reset()) +#define pq_flush() (PqCommMethods->flush()) +#define pq_flush_if_writable() (PqCommMethods->flush_if_writable()) +#define pq_is_send_pending() (PqCommMethods->is_send_pending()) +#define pq_putmessage(msgtype, s, len) \ + (PqCommMethods->putmessage(msgtype, s, len)) +#define pq_putmessage_noblock(msgtype, s, len) \ + (PqCommMethods->putmessage_noblock(msgtype, s, len)) + +/* + * External functions. + */ + +/* + * prototypes for functions in pqcomm.c + */ +extern PGDLLIMPORT WaitEventSet *FeBeWaitSet; + +#define FeBeWaitSetSocketPos 0 +#define FeBeWaitSetLatchPos 1 +#define FeBeWaitSetNEvents 3 + +extern int StreamServerPort(int family, const char *hostName, + unsigned short portNumber, const char *unixSocketDir, + pgsocket ListenSocket[], int MaxListen); +extern int StreamConnection(pgsocket server_fd, Port *port); +extern void StreamClose(pgsocket sock); +extern void TouchSocketFiles(void); +extern void RemoveSocketFiles(void); +extern void pq_init(void); +extern int pq_getbytes(char *s, size_t len); +extern void pq_startmsgread(void); +extern void pq_endmsgread(void); +extern bool pq_is_reading_msg(void); +extern int pq_getmessage(StringInfo s, int maxlen); +extern int pq_getbyte(void); +extern int pq_peekbyte(void); +extern int pq_getbyte_if_available(unsigned char *c); +extern bool pq_buffer_has_data(void); +extern int pq_putmessage_v2(char msgtype, const char *s, size_t len); +extern bool pq_check_connection(void); + +/* + * prototypes for functions in be-secure.c + */ +extern PGDLLIMPORT char *ssl_library; +extern PGDLLIMPORT char *ssl_cert_file; +extern PGDLLIMPORT char *ssl_key_file; +extern PGDLLIMPORT char *ssl_ca_file; +extern PGDLLIMPORT char *ssl_crl_file; +extern PGDLLIMPORT char *ssl_crl_dir; +extern PGDLLIMPORT char *ssl_dh_params_file; +extern PGDLLIMPORT char *ssl_passphrase_command; +extern PGDLLIMPORT bool ssl_passphrase_command_supports_reload; +#ifdef USE_SSL +extern PGDLLIMPORT bool ssl_loaded_verify_locations; +#endif + +extern int secure_initialize(bool isServerStart); +extern bool secure_loaded_verify_locations(void); +extern void secure_destroy(void); +extern int secure_open_server(Port *port); +extern void secure_close(Port *port); +extern ssize_t secure_read(Port *port, void *ptr, size_t len); +extern ssize_t secure_write(Port *port, void *ptr, size_t len); +extern ssize_t secure_raw_read(Port *port, void *ptr, size_t len); +extern ssize_t secure_raw_write(Port *port, const void *ptr, size_t len); + +/* + * prototypes for functions in be-secure-gssapi.c + */ +#ifdef ENABLE_GSS +extern ssize_t secure_open_gssapi(Port *port); +#endif + +/* GUCs */ +extern PGDLLIMPORT char *SSLCipherSuites; +extern PGDLLIMPORT char *SSLECDHCurve; +extern PGDLLIMPORT bool SSLPreferServerCiphers; +extern PGDLLIMPORT int ssl_min_protocol_version; +extern PGDLLIMPORT int ssl_max_protocol_version; + +enum ssl_protocol_versions +{ + PG_TLS_ANY = 0, + PG_TLS1_VERSION, + PG_TLS1_1_VERSION, + PG_TLS1_2_VERSION, + PG_TLS1_3_VERSION, +}; + +/* + * prototypes for functions in be-secure-common.c + */ +extern int run_ssl_passphrase_command(const char *prompt, bool is_server_start, + char *buf, int size); +extern bool check_ssl_key_file_permissions(const char *ssl_key_file, + bool isServerStart); + +#endif /* LIBPQ_H */ diff --git a/install/include/postgresql/server/libpq/pqcomm.h b/install/include/postgresql/server/libpq/pqcomm.h new file mode 100644 index 00000000000..c85090259d9 --- /dev/null +++ b/install/include/postgresql/server/libpq/pqcomm.h @@ -0,0 +1,163 @@ +/*------------------------------------------------------------------------- + * + * pqcomm.h + * Definitions common to frontends and backends. + * + * NOTE: for historical reasons, this does not correspond to pqcomm.c. + * pqcomm.c's routines are declared in libpq.h. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/pqcomm.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQCOMM_H +#define PQCOMM_H + +#include +#include +#include +#include + +typedef struct +{ + struct sockaddr_storage addr; + socklen_t salen; +} SockAddr; + +typedef struct +{ + int family; + SockAddr addr; +} AddrInfo; + +/* Configure the UNIX socket location for the well known port. */ + +#define UNIXSOCK_PATH(path, port, sockdir) \ + (AssertMacro(sockdir), \ + AssertMacro(*(sockdir) != '\0'), \ + snprintf(path, sizeof(path), "%s/.s.PGSQL.%d", \ + (sockdir), (port))) + +/* + * The maximum workable length of a socket path is what will fit into + * struct sockaddr_un. This is usually only 100 or so bytes :-(. + * + * For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(), + * then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes. + * (Because the standard API for getaddrinfo doesn't allow it to complain in + * a useful way when the socket pathname is too long, we have to test for + * this explicitly, instead of just letting the subroutine return an error.) + */ +#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path) + +/* + * A host that looks either like an absolute path or starts with @ is + * interpreted as a Unix-domain socket address. + */ +static inline bool +is_unixsock_path(const char *path) +{ + return is_absolute_path(path) || path[0] == '@'; +} + +/* + * These manipulate the frontend/backend protocol version number. + * + * The major number should be incremented for incompatible changes. The minor + * number should be incremented for compatible changes (eg. additional + * functionality). + * + * If a backend supports version m.n of the protocol it must actually support + * versions m.[0..n]. Backend support for version m-1 can be dropped after a + * `reasonable' length of time. + * + * A frontend isn't required to support anything other than the current + * version. + */ + +#define PG_PROTOCOL_MAJOR(v) ((v) >> 16) +#define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff) +#define PG_PROTOCOL(m,n) (((m) << 16) | (n)) + +/* + * The earliest and latest frontend/backend protocol version supported. + * (Only protocol version 3 is currently supported) + */ + +#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(3,0) +#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,0) + +typedef uint32 ProtocolVersion; /* FE/BE protocol version number */ + +typedef ProtocolVersion MsgType; + + +/* + * Packet lengths are 4 bytes in network byte order. + * + * The initial length is omitted from the packet layouts appearing below. + */ + +typedef uint32 PacketLen; + +extern PGDLLIMPORT bool Db_user_namespace; + +/* + * In protocol 3.0 and later, the startup packet length is not fixed, but + * we set an arbitrary limit on it anyway. This is just to prevent simple + * denial-of-service attacks via sending enough data to run the server + * out of memory. + */ +#define MAX_STARTUP_PACKET_LENGTH 10000 + + +/* These are the authentication request codes sent by the backend. */ + +#define AUTH_REQ_OK 0 /* User is authenticated */ +#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ +#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ +#define AUTH_REQ_PASSWORD 3 /* Password */ +#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ +#define AUTH_REQ_MD5 5 /* md5 password */ +/* 6 is available. It was used for SCM creds, not supported any more. */ +#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */ +#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */ +#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */ +#define AUTH_REQ_SASL 10 /* Begin SASL authentication */ +#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */ +#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */ +#define AUTH_REQ_MAX AUTH_REQ_SASL_FIN /* maximum AUTH_REQ_* value */ + +typedef uint32 AuthRequest; + + +/* + * A client can also send a cancel-current-operation request to the postmaster. + * This is uglier than sending it directly to the client's backend, but it + * avoids depending on out-of-band communication facilities. + * + * The cancel request code must not match any protocol version number + * we're ever likely to use. This random choice should do. + */ +#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678) + +typedef struct CancelRequestPacket +{ + /* Note that each field is stored in network byte order! */ + MsgType cancelRequestCode; /* code to identify a cancel request */ + uint32 backendPID; /* PID of client's backend */ + uint32 cancelAuthCode; /* secret key to authorize cancel */ +} CancelRequestPacket; + + +/* + * A client can also start by sending a SSL or GSSAPI negotiation request to + * get a secure channel. + */ +#define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679) +#define NEGOTIATE_GSS_CODE PG_PROTOCOL(1234,5680) + +#endif /* PQCOMM_H */ diff --git a/install/include/postgresql/server/libpq/pqformat.h b/install/include/postgresql/server/libpq/pqformat.h new file mode 100644 index 00000000000..0d2f958af33 --- /dev/null +++ b/install/include/postgresql/server/libpq/pqformat.h @@ -0,0 +1,210 @@ +/*------------------------------------------------------------------------- + * + * pqformat.h + * Definitions for formatting and parsing frontend/backend messages + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/pqformat.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQFORMAT_H +#define PQFORMAT_H + +#include "lib/stringinfo.h" +#include "mb/pg_wchar.h" +#include "port/pg_bswap.h" + +extern void pq_beginmessage(StringInfo buf, char msgtype); +extern void pq_beginmessage_reuse(StringInfo buf, char msgtype); +extern void pq_endmessage(StringInfo buf); +extern void pq_endmessage_reuse(StringInfo buf); + +extern void pq_sendbytes(StringInfo buf, const void *data, int datalen); +extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen, + bool countincludesself); +extern void pq_sendtext(StringInfo buf, const char *str, int slen); +extern void pq_sendstring(StringInfo buf, const char *str); +extern void pq_send_ascii_string(StringInfo buf, const char *str); +extern void pq_sendfloat4(StringInfo buf, float4 f); +extern void pq_sendfloat8(StringInfo buf, float8 f); + +/* + * Append a [u]int8 to a StringInfo buffer, which already has enough space + * preallocated. + * + * The use of pg_restrict allows the compiler to optimize the code based on + * the assumption that buf, buf->len, buf->data and *buf->data don't + * overlap. Without the annotation buf->len etc cannot be kept in a register + * over subsequent pq_writeintN calls. + * + * The use of StringInfoData * rather than StringInfo is due to MSVC being + * overly picky and demanding a * before a restrict. + */ +static inline void +pq_writeint8(StringInfoData *pg_restrict buf, uint8 i) +{ + uint8 ni = i; + + Assert(buf->len + (int) sizeof(uint8) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint8)); + buf->len += sizeof(uint8); +} + +/* + * Append a [u]int16 to a StringInfo buffer, which already has enough space + * preallocated. + */ +static inline void +pq_writeint16(StringInfoData *pg_restrict buf, uint16 i) +{ + uint16 ni = pg_hton16(i); + + Assert(buf->len + (int) sizeof(uint16) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint16)); + buf->len += sizeof(uint16); +} + +/* + * Append a [u]int32 to a StringInfo buffer, which already has enough space + * preallocated. + */ +static inline void +pq_writeint32(StringInfoData *pg_restrict buf, uint32 i) +{ + uint32 ni = pg_hton32(i); + + Assert(buf->len + (int) sizeof(uint32) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint32)); + buf->len += sizeof(uint32); +} + +/* + * Append a [u]int64 to a StringInfo buffer, which already has enough space + * preallocated. + */ +static inline void +pq_writeint64(StringInfoData *pg_restrict buf, uint64 i) +{ + uint64 ni = pg_hton64(i); + + Assert(buf->len + (int) sizeof(uint64) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint64)); + buf->len += sizeof(uint64); +} + +/* + * Append a null-terminated text string (with conversion) to a buffer with + * preallocated space. + * + * NB: The pre-allocated space needs to be sufficient for the string after + * converting to client encoding. + * + * NB: passed text string must be null-terminated, and so is the data + * sent to the frontend. + */ +static inline void +pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str) +{ + int slen = strlen(str); + char *p; + + p = pg_server_to_client(str, slen); + if (p != str) /* actual conversion has been done? */ + slen = strlen(p); + + Assert(buf->len + slen + 1 <= buf->maxlen); + + memcpy(((char *pg_restrict) buf->data + buf->len), p, slen + 1); + buf->len += slen + 1; + + if (p != str) + pfree(p); +} + +/* append a binary [u]int8 to a StringInfo buffer */ +static inline void +pq_sendint8(StringInfo buf, uint8 i) +{ + enlargeStringInfo(buf, sizeof(uint8)); + pq_writeint8(buf, i); +} + +/* append a binary [u]int16 to a StringInfo buffer */ +static inline void +pq_sendint16(StringInfo buf, uint16 i) +{ + enlargeStringInfo(buf, sizeof(uint16)); + pq_writeint16(buf, i); +} + +/* append a binary [u]int32 to a StringInfo buffer */ +static inline void +pq_sendint32(StringInfo buf, uint32 i) +{ + enlargeStringInfo(buf, sizeof(uint32)); + pq_writeint32(buf, i); +} + +/* append a binary [u]int64 to a StringInfo buffer */ +static inline void +pq_sendint64(StringInfo buf, uint64 i) +{ + enlargeStringInfo(buf, sizeof(uint64)); + pq_writeint64(buf, i); +} + +/* append a binary byte to a StringInfo buffer */ +static inline void +pq_sendbyte(StringInfo buf, uint8 byt) +{ + pq_sendint8(buf, byt); +} + +/* + * Append a binary integer to a StringInfo buffer + * + * This function is deprecated; prefer use of the functions above. + */ +static inline void +pq_sendint(StringInfo buf, uint32 i, int b) +{ + switch (b) + { + case 1: + pq_sendint8(buf, (uint8) i); + break; + case 2: + pq_sendint16(buf, (uint16) i); + break; + case 4: + pq_sendint32(buf, (uint32) i); + break; + default: + elog(ERROR, "unsupported integer size %d", b); + break; + } +} + + +extern void pq_begintypsend(StringInfo buf); +extern bytea *pq_endtypsend(StringInfo buf); + +extern void pq_puttextmessage(char msgtype, const char *str); +extern void pq_putemptymessage(char msgtype); + +extern int pq_getmsgbyte(StringInfo msg); +extern unsigned int pq_getmsgint(StringInfo msg, int b); +extern int64 pq_getmsgint64(StringInfo msg); +extern float4 pq_getmsgfloat4(StringInfo msg); +extern float8 pq_getmsgfloat8(StringInfo msg); +extern const char *pq_getmsgbytes(StringInfo msg, int datalen); +extern void pq_copymsgbytes(StringInfo msg, char *buf, int datalen); +extern char *pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes); +extern const char *pq_getmsgstring(StringInfo msg); +extern const char *pq_getmsgrawstring(StringInfo msg); +extern void pq_getmsgend(StringInfo msg); + +#endif /* PQFORMAT_H */ diff --git a/install/include/postgresql/server/libpq/pqmq.h b/install/include/postgresql/server/libpq/pqmq.h new file mode 100644 index 00000000000..af607edf4cb --- /dev/null +++ b/install/include/postgresql/server/libpq/pqmq.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * pqmq.h + * Use the frontend/backend protocol for communication over a shm_mq + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/pqmq.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQMQ_H +#define PQMQ_H + +#include "lib/stringinfo.h" +#include "storage/shm_mq.h" + +extern void pq_redirect_to_shm_mq(dsm_segment *seg, shm_mq_handle *mqh); +extern void pq_set_parallel_leader(pid_t pid, BackendId backend_id); + +extern void pq_parse_errornotice(StringInfo msg, ErrorData *edata); + +#endif /* PQMQ_H */ diff --git a/install/include/postgresql/server/libpq/pqsignal.h b/install/include/postgresql/server/libpq/pqsignal.h new file mode 100644 index 00000000000..023bcd13bd4 --- /dev/null +++ b/install/include/postgresql/server/libpq/pqsignal.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * pqsignal.h + * Backend signal(2) support (see also src/port/pqsignal.c) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/pqsignal.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQSIGNAL_H +#define PQSIGNAL_H + +#include + +#ifdef WIN32 +/* Emulate POSIX sigset_t APIs on Windows */ +typedef int sigset_t; + +#define SA_RESTART 1 +#define SA_NODEFER 2 + +struct sigaction +{ + void (*sa_handler) (int); + /* sa_sigaction not yet implemented */ + sigset_t sa_mask; + int sa_flags; +}; + +extern int pqsigprocmask(int how, const sigset_t *set, sigset_t *oset); +extern int pqsigaction(int signum, const struct sigaction *act, + struct sigaction *oldact); + +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 +#define sigprocmask(how, set, oset) pqsigprocmask((how), (set), (oset)) +#define sigaction(signum, act, oldact) pqsigaction((signum), (act), (oldact)) +#define sigemptyset(set) (*(set) = 0) +#define sigfillset(set) (*(set) = ~0) +#define sigaddset(set, signum) (*(set) |= (sigmask(signum))) +#define sigdelset(set, signum) (*(set) &= ~(sigmask(signum))) +#endif /* WIN32 */ + +extern PGDLLIMPORT sigset_t UnBlockSig; +extern PGDLLIMPORT sigset_t BlockSig; +extern PGDLLIMPORT sigset_t StartupBlockSig; + +extern void pqinitmask(void); + +#endif /* PQSIGNAL_H */ diff --git a/install/include/postgresql/server/libpq/sasl.h b/install/include/postgresql/server/libpq/sasl.h new file mode 100644 index 00000000000..7a1b1ed0a00 --- /dev/null +++ b/install/include/postgresql/server/libpq/sasl.h @@ -0,0 +1,136 @@ +/*------------------------------------------------------------------------- + * + * sasl.h + * Defines the SASL mechanism interface for the backend. + * + * Each SASL mechanism defines a frontend and a backend callback structure. + * + * See src/interfaces/libpq/fe-auth-sasl.h for the frontend counterpart. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/sasl.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PG_SASL_H +#define PG_SASL_H + +#include "lib/stringinfo.h" +#include "libpq/libpq-be.h" + +/* Status codes for message exchange */ +#define PG_SASL_EXCHANGE_CONTINUE 0 +#define PG_SASL_EXCHANGE_SUCCESS 1 +#define PG_SASL_EXCHANGE_FAILURE 2 + +/* + * Backend SASL mechanism callbacks. + * + * To implement a backend mechanism, declare a pg_be_sasl_mech struct with + * appropriate callback implementations. Then pass the mechanism to + * CheckSASLAuth() during ClientAuthentication(), once the server has decided + * which authentication method to use. + */ +typedef struct pg_be_sasl_mech +{ + /*--------- + * get_mechanisms() + * + * Retrieves the list of SASL mechanism names supported by this + * implementation. + * + * Input parameters: + * + * port: The client Port + * + * Output parameters: + * + * buf: A StringInfo buffer that the callback should populate with + * supported mechanism names. The names are appended into this + * StringInfo, each one ending with '\0' bytes. + *--------- + */ + void (*get_mechanisms) (Port *port, StringInfo buf); + + /*--------- + * init() + * + * Initializes mechanism-specific state for a connection. This callback + * must return a pointer to its allocated state, which will be passed + * as-is as the first argument to the other callbacks. + * + * Input parameters: + * + * port: The client Port. + * + * mech: The actual mechanism name in use by the client. + * + * shadow_pass: The stored secret for the role being authenticated, or + * NULL if one does not exist. Mechanisms that do not use + * shadow entries may ignore this parameter. If a + * mechanism uses shadow entries but shadow_pass is NULL, + * the implementation must continue the exchange as if the + * user existed and the password did not match, to avoid + * disclosing valid user names. + *--------- + */ + void *(*init) (Port *port, const char *mech, const char *shadow_pass); + + /*--------- + * exchange() + * + * Produces a server challenge to be sent to the client. The callback + * must return one of the PG_SASL_EXCHANGE_* values, depending on + * whether the exchange continues, has finished successfully, or has + * failed. + * + * Input parameters: + * + * state: The opaque mechanism state returned by init() + * + * input: The response data sent by the client, or NULL if the + * mechanism is client-first but the client did not send an + * initial response. (This can only happen during the first + * message from the client.) This is guaranteed to be + * null-terminated for safety, but SASL allows embedded + * nulls in responses, so mechanisms must be careful to + * check inputlen. + * + * inputlen: The length of the challenge data sent by the server, or + * -1 if the client did not send an initial response + * + * Output parameters, to be set by the callback function: + * + * output: A palloc'd buffer containing either the server's next + * challenge (if PG_SASL_EXCHANGE_CONTINUE is returned) or + * the server's outcome data (if PG_SASL_EXCHANGE_SUCCESS is + * returned and the mechanism requires data to be sent during + * a successful outcome). The callback should set this to + * NULL if the exchange is over and no output should be sent, + * which should correspond to either PG_SASL_EXCHANGE_FAILURE + * or a PG_SASL_EXCHANGE_SUCCESS with no outcome data. + * + * outputlen: The length of the challenge data. Ignored if *output is + * NULL. + * + * logdetail: Set to an optional DETAIL message to be printed to the + * server log, to disambiguate failure modes. (The client + * will only ever see the same generic authentication + * failure message.) Ignored if the exchange is completed + * with PG_SASL_EXCHANGE_SUCCESS. + *--------- + */ + int (*exchange) (void *state, + const char *input, int inputlen, + char **output, int *outputlen, + const char **logdetail); +} pg_be_sasl_mech; + +/* Common implementation for auth.c */ +extern int CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, + char *shadow_pass, const char **logdetail); + +#endif /* PG_SASL_H */ diff --git a/install/include/postgresql/server/libpq/scram.h b/install/include/postgresql/server/libpq/scram.h new file mode 100644 index 00000000000..310bc365177 --- /dev/null +++ b/install/include/postgresql/server/libpq/scram.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * scram.h + * Interface to libpq/scram.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/scram.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SCRAM_H +#define PG_SCRAM_H + +#include "common/cryptohash.h" +#include "lib/stringinfo.h" +#include "libpq/libpq-be.h" +#include "libpq/sasl.h" + +/* Number of iterations when generating new secrets */ +extern PGDLLIMPORT int scram_sha_256_iterations; + +/* SASL implementation callbacks */ +extern PGDLLIMPORT const pg_be_sasl_mech pg_be_scram_mech; + +/* Routines to handle and check SCRAM-SHA-256 secret */ +extern char *pg_be_scram_build_secret(const char *password); +extern bool parse_scram_secret(const char *secret, + int *iterations, + pg_cryptohash_type *hash_type, + int *key_length, char **salt, + uint8 *stored_key, uint8 *server_key); +extern bool scram_verify_plain_password(const char *username, + const char *password, const char *secret); + +#endif /* PG_SCRAM_H */ diff --git a/install/include/postgresql/server/mb/pg_wchar.h b/install/include/postgresql/server/mb/pg_wchar.h new file mode 100644 index 00000000000..448ceb0458f --- /dev/null +++ b/install/include/postgresql/server/mb/pg_wchar.h @@ -0,0 +1,713 @@ +/*------------------------------------------------------------------------- + * + * pg_wchar.h + * multibyte-character support + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/mb/pg_wchar.h + * + * NOTES + * This is used both by the backend and by frontends, but should not be + * included by libpq client programs. In particular, a libpq client + * should not assume that the encoding IDs used by the version of libpq + * it's linked to match up with the IDs declared here. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_WCHAR_H +#define PG_WCHAR_H + +/* + * The pg_wchar type + */ +typedef unsigned int pg_wchar; + +/* + * Maximum byte length of multibyte characters in any backend encoding + */ +#define MAX_MULTIBYTE_CHAR_LEN 4 + +/* + * various definitions for EUC + */ +#define SS2 0x8e /* single shift 2 (JIS0201) */ +#define SS3 0x8f /* single shift 3 (JIS0212) */ + +/* + * SJIS validation macros + */ +#define ISSJISHEAD(c) (((c) >= 0x81 && (c) <= 0x9f) || ((c) >= 0xe0 && (c) <= 0xfc)) +#define ISSJISTAIL(c) (((c) >= 0x40 && (c) <= 0x7e) || ((c) >= 0x80 && (c) <= 0xfc)) + +/*---------------------------------------------------- + * MULE Internal Encoding (MIC) + * + * This encoding follows the design used within XEmacs; it is meant to + * subsume many externally-defined character sets. Each character includes + * identification of the character set it belongs to, so the encoding is + * general but somewhat bulky. + * + * Currently PostgreSQL supports 5 types of MULE character sets: + * + * 1) 1-byte ASCII characters. Each byte is below 0x80. + * + * 2) "Official" single byte charsets such as ISO-8859-1 (Latin1). + * Each MULE character consists of 2 bytes: LC1 + C1, where LC1 is + * an identifier for the charset (in the range 0x81 to 0x8d) and C1 + * is the character code (in the range 0xa0 to 0xff). + * + * 3) "Private" single byte charsets such as SISHENG. Each MULE + * character consists of 3 bytes: LCPRV1 + LC12 + C1, where LCPRV1 + * is a private-charset flag, LC12 is an identifier for the charset, + * and C1 is the character code (in the range 0xa0 to 0xff). + * LCPRV1 is either 0x9a (if LC12 is in the range 0xa0 to 0xdf) + * or 0x9b (if LC12 is in the range 0xe0 to 0xef). + * + * 4) "Official" multibyte charsets such as JIS X0208. Each MULE + * character consists of 3 bytes: LC2 + C1 + C2, where LC2 is + * an identifier for the charset (in the range 0x90 to 0x99) and C1 + * and C2 form the character code (each in the range 0xa0 to 0xff). + * + * 5) "Private" multibyte charsets such as CNS 11643-1992 Plane 3. + * Each MULE character consists of 4 bytes: LCPRV2 + LC22 + C1 + C2, + * where LCPRV2 is a private-charset flag, LC22 is an identifier for + * the charset, and C1 and C2 form the character code (each in the range + * 0xa0 to 0xff). LCPRV2 is either 0x9c (if LC22 is in the range 0xf0 + * to 0xf4) or 0x9d (if LC22 is in the range 0xf5 to 0xfe). + * + * "Official" encodings are those that have been assigned code numbers by + * the XEmacs project; "private" encodings have Postgres-specific charset + * identifiers. + * + * See the "XEmacs Internals Manual", available at http://www.xemacs.org, + * for more details. Note that for historical reasons, Postgres' + * private-charset flag values do not match what XEmacs says they should be, + * so this isn't really exactly MULE (not that private charsets would be + * interoperable anyway). + * + * Note that XEmacs's implementation is different from what emacs does. + * We follow emacs's implementation, rather than XEmacs's. + *---------------------------------------------------- + */ + +/* + * Charset identifiers (also called "leading bytes" in the MULE documentation) + */ + +/* + * Charset IDs for official single byte encodings (0x81-0x8e) + */ +#define LC_ISO8859_1 0x81 /* ISO8859 Latin 1 */ +#define LC_ISO8859_2 0x82 /* ISO8859 Latin 2 */ +#define LC_ISO8859_3 0x83 /* ISO8859 Latin 3 */ +#define LC_ISO8859_4 0x84 /* ISO8859 Latin 4 */ +#define LC_TIS620 0x85 /* Thai (not supported yet) */ +#define LC_ISO8859_7 0x86 /* Greek (not supported yet) */ +#define LC_ISO8859_6 0x87 /* Arabic (not supported yet) */ +#define LC_ISO8859_8 0x88 /* Hebrew (not supported yet) */ +#define LC_JISX0201K 0x89 /* Japanese 1 byte kana */ +#define LC_JISX0201R 0x8a /* Japanese 1 byte Roman */ +/* Note that 0x8b seems to be unused as of Emacs 20.7. + * However, there might be a chance that 0x8b could be used + * in later versions of Emacs. + */ +#define LC_KOI8_R 0x8b /* Cyrillic KOI8-R */ +#define LC_ISO8859_5 0x8c /* ISO8859 Cyrillic */ +#define LC_ISO8859_9 0x8d /* ISO8859 Latin 5 (not supported yet) */ +#define LC_ISO8859_15 0x8e /* ISO8859 Latin 15 (not supported yet) */ +/* #define CONTROL_1 0x8f control characters (unused) */ + +/* Is a leading byte for "official" single byte encodings? */ +#define IS_LC1(c) ((unsigned char)(c) >= 0x81 && (unsigned char)(c) <= 0x8d) + +/* + * Charset IDs for official multibyte encodings (0x90-0x99) + * 0x9a-0x9d are free. 0x9e and 0x9f are reserved. + */ +#define LC_JISX0208_1978 0x90 /* Japanese Kanji, old JIS (not supported) */ +#define LC_GB2312_80 0x91 /* Chinese */ +#define LC_JISX0208 0x92 /* Japanese Kanji (JIS X 0208) */ +#define LC_KS5601 0x93 /* Korean */ +#define LC_JISX0212 0x94 /* Japanese Kanji (JIS X 0212) */ +#define LC_CNS11643_1 0x95 /* CNS 11643-1992 Plane 1 */ +#define LC_CNS11643_2 0x96 /* CNS 11643-1992 Plane 2 */ +#define LC_JISX0213_1 0x97 /* Japanese Kanji (JIS X 0213 Plane 1) + * (not supported) */ +#define LC_BIG5_1 0x98 /* Plane 1 Chinese traditional (not + * supported) */ +#define LC_BIG5_2 0x99 /* Plane 1 Chinese traditional (not + * supported) */ + +/* Is a leading byte for "official" multibyte encodings? */ +#define IS_LC2(c) ((unsigned char)(c) >= 0x90 && (unsigned char)(c) <= 0x99) + +/* + * Postgres-specific prefix bytes for "private" single byte encodings + * (According to the MULE docs, we should be using 0x9e for this) + */ +#define LCPRV1_A 0x9a +#define LCPRV1_B 0x9b +#define IS_LCPRV1(c) ((unsigned char)(c) == LCPRV1_A || (unsigned char)(c) == LCPRV1_B) +#define IS_LCPRV1_A_RANGE(c) \ + ((unsigned char)(c) >= 0xa0 && (unsigned char)(c) <= 0xdf) +#define IS_LCPRV1_B_RANGE(c) \ + ((unsigned char)(c) >= 0xe0 && (unsigned char)(c) <= 0xef) + +/* + * Postgres-specific prefix bytes for "private" multibyte encodings + * (According to the MULE docs, we should be using 0x9f for this) + */ +#define LCPRV2_A 0x9c +#define LCPRV2_B 0x9d +#define IS_LCPRV2(c) ((unsigned char)(c) == LCPRV2_A || (unsigned char)(c) == LCPRV2_B) +#define IS_LCPRV2_A_RANGE(c) \ + ((unsigned char)(c) >= 0xf0 && (unsigned char)(c) <= 0xf4) +#define IS_LCPRV2_B_RANGE(c) \ + ((unsigned char)(c) >= 0xf5 && (unsigned char)(c) <= 0xfe) + +/* + * Charset IDs for private single byte encodings (0xa0-0xef) + */ +#define LC_SISHENG 0xa0 /* Chinese SiSheng characters for + * PinYin/ZhuYin (not supported) */ +#define LC_IPA 0xa1 /* IPA (International Phonetic + * Association) (not supported) */ +#define LC_VISCII_LOWER 0xa2 /* Vietnamese VISCII1.1 lower-case (not + * supported) */ +#define LC_VISCII_UPPER 0xa3 /* Vietnamese VISCII1.1 upper-case (not + * supported) */ +#define LC_ARABIC_DIGIT 0xa4 /* Arabic digit (not supported) */ +#define LC_ARABIC_1_COLUMN 0xa5 /* Arabic 1-column (not supported) */ +#define LC_ASCII_RIGHT_TO_LEFT 0xa6 /* ASCII (left half of ISO8859-1) with + * right-to-left direction (not + * supported) */ +#define LC_LAO 0xa7 /* Lao characters (ISO10646 0E80..0EDF) + * (not supported) */ +#define LC_ARABIC_2_COLUMN 0xa8 /* Arabic 1-column (not supported) */ + +/* + * Charset IDs for private multibyte encodings (0xf0-0xff) + */ +#define LC_INDIAN_1_COLUMN 0xf0 /* Indian charset for 1-column width + * glyphs (not supported) */ +#define LC_TIBETAN_1_COLUMN 0xf1 /* Tibetan 1-column width glyphs (not + * supported) */ +#define LC_UNICODE_SUBSET_2 0xf2 /* Unicode characters of the range + * U+2500..U+33FF. (not supported) */ +#define LC_UNICODE_SUBSET_3 0xf3 /* Unicode characters of the range + * U+E000..U+FFFF. (not supported) */ +#define LC_UNICODE_SUBSET 0xf4 /* Unicode characters of the range + * U+0100..U+24FF. (not supported) */ +#define LC_ETHIOPIC 0xf5 /* Ethiopic characters (not supported) */ +#define LC_CNS11643_3 0xf6 /* CNS 11643-1992 Plane 3 */ +#define LC_CNS11643_4 0xf7 /* CNS 11643-1992 Plane 4 */ +#define LC_CNS11643_5 0xf8 /* CNS 11643-1992 Plane 5 */ +#define LC_CNS11643_6 0xf9 /* CNS 11643-1992 Plane 6 */ +#define LC_CNS11643_7 0xfa /* CNS 11643-1992 Plane 7 */ +#define LC_INDIAN_2_COLUMN 0xfb /* Indian charset for 2-column width + * glyphs (not supported) */ +#define LC_TIBETAN 0xfc /* Tibetan (not supported) */ +/* #define FREE 0xfd free (unused) */ +/* #define FREE 0xfe free (unused) */ +/* #define FREE 0xff free (unused) */ + +/*---------------------------------------------------- + * end of MULE stuff + *---------------------------------------------------- + */ + +/* + * PostgreSQL encoding identifiers + * + * WARNING: the order of this enum must be same as order of entries + * in the pg_enc2name_tbl[] array (in src/common/encnames.c), and + * in the pg_wchar_table[] array (in src/common/wchar.c)! + * + * If you add some encoding don't forget to check + * PG_ENCODING_BE_LAST macro. + * + * PG_SQL_ASCII is default encoding and must be = 0. + * + * XXX We must avoid renumbering any backend encoding until libpq's major + * version number is increased beyond 5; it turns out that the backend + * encoding IDs are effectively part of libpq's ABI as far as 8.2 initdb and + * psql are concerned. + */ +typedef enum pg_enc +{ + PG_SQL_ASCII = 0, /* SQL/ASCII */ + PG_EUC_JP, /* EUC for Japanese */ + PG_EUC_CN, /* EUC for Chinese */ + PG_EUC_KR, /* EUC for Korean */ + PG_EUC_TW, /* EUC for Taiwan */ + PG_EUC_JIS_2004, /* EUC-JIS-2004 */ + PG_UTF8, /* Unicode UTF8 */ + PG_MULE_INTERNAL, /* Mule internal code */ + PG_LATIN1, /* ISO-8859-1 Latin 1 */ + PG_LATIN2, /* ISO-8859-2 Latin 2 */ + PG_LATIN3, /* ISO-8859-3 Latin 3 */ + PG_LATIN4, /* ISO-8859-4 Latin 4 */ + PG_LATIN5, /* ISO-8859-9 Latin 5 */ + PG_LATIN6, /* ISO-8859-10 Latin6 */ + PG_LATIN7, /* ISO-8859-13 Latin7 */ + PG_LATIN8, /* ISO-8859-14 Latin8 */ + PG_LATIN9, /* ISO-8859-15 Latin9 */ + PG_LATIN10, /* ISO-8859-16 Latin10 */ + PG_WIN1256, /* windows-1256 */ + PG_WIN1258, /* Windows-1258 */ + PG_WIN866, /* (MS-DOS CP866) */ + PG_WIN874, /* windows-874 */ + PG_KOI8R, /* KOI8-R */ + PG_WIN1251, /* windows-1251 */ + PG_WIN1252, /* windows-1252 */ + PG_ISO_8859_5, /* ISO-8859-5 */ + PG_ISO_8859_6, /* ISO-8859-6 */ + PG_ISO_8859_7, /* ISO-8859-7 */ + PG_ISO_8859_8, /* ISO-8859-8 */ + PG_WIN1250, /* windows-1250 */ + PG_WIN1253, /* windows-1253 */ + PG_WIN1254, /* windows-1254 */ + PG_WIN1255, /* windows-1255 */ + PG_WIN1257, /* windows-1257 */ + PG_KOI8U, /* KOI8-U */ + /* PG_ENCODING_BE_LAST points to the above entry */ + + /* followings are for client encoding only */ + PG_SJIS, /* Shift JIS (Windows-932) */ + PG_BIG5, /* Big5 (Windows-950) */ + PG_GBK, /* GBK (Windows-936) */ + PG_UHC, /* UHC (Windows-949) */ + PG_GB18030, /* GB18030 */ + PG_JOHAB, /* EUC for Korean JOHAB */ + PG_SHIFT_JIS_2004, /* Shift-JIS-2004 */ + _PG_LAST_ENCODING_ /* mark only */ + +} pg_enc; + +#define PG_ENCODING_BE_LAST PG_KOI8U + +/* + * Please use these tests before access to pg_enc2name_tbl[] + * or to other places... + */ +#define PG_VALID_BE_ENCODING(_enc) \ + ((_enc) >= 0 && (_enc) <= PG_ENCODING_BE_LAST) + +#define PG_ENCODING_IS_CLIENT_ONLY(_enc) \ + ((_enc) > PG_ENCODING_BE_LAST && (_enc) < _PG_LAST_ENCODING_) + +#define PG_VALID_ENCODING(_enc) \ + ((_enc) >= 0 && (_enc) < _PG_LAST_ENCODING_) + +/* On FE are possible all encodings */ +#define PG_VALID_FE_ENCODING(_enc) PG_VALID_ENCODING(_enc) + +/* + * When converting strings between different encodings, we assume that space + * for converted result is 4-to-1 growth in the worst case. The rate for + * currently supported encoding pairs are within 3 (SJIS JIS X0201 half width + * kana -> UTF8 is the worst case). So "4" should be enough for the moment. + * + * Note that this is not the same as the maximum character width in any + * particular encoding. + */ +#define MAX_CONVERSION_GROWTH 4 + +/* + * Maximum byte length of a string that's required in any encoding to convert + * at least one character to any other encoding. In other words, if you feed + * MAX_CONVERSION_INPUT_LENGTH bytes to any encoding conversion function, it + * is guaranteed to be able to convert something without needing more input + * (assuming the input is valid). + * + * Currently, the maximum case is the conversion UTF8 -> SJIS JIS X0201 half + * width kana, where a pair of UTF-8 characters is converted into a single + * SHIFT_JIS_2004 character (the reverse of the worst case for + * MAX_CONVERSION_GROWTH). It needs 6 bytes of input. In theory, a + * user-defined conversion function might have more complicated cases, although + * for the reverse mapping you would probably also need to bump up + * MAX_CONVERSION_GROWTH. But there is no need to be stingy here, so make it + * generous. + */ +#define MAX_CONVERSION_INPUT_LENGTH 16 + +/* + * Maximum byte length of the string equivalent to any one Unicode code point, + * in any backend encoding. The current value assumes that a 4-byte UTF-8 + * character might expand by MAX_CONVERSION_GROWTH, which is a huge + * overestimate. But in current usage we don't allocate large multiples of + * this, so there's little point in being stingy. + */ +#define MAX_UNICODE_EQUIVALENT_STRING 16 + +/* + * Table for mapping an encoding number to official encoding name and + * possibly other subsidiary data. Be careful to check encoding number + * before accessing a table entry! + * + * if (PG_VALID_ENCODING(encoding)) + * pg_enc2name_tbl[ encoding ]; + */ +typedef struct pg_enc2name +{ + const char *name; + pg_enc encoding; +#ifdef WIN32 + unsigned codepage; /* codepage for WIN32 */ +#endif +} pg_enc2name; + +extern PGDLLIMPORT const pg_enc2name pg_enc2name_tbl[]; + +/* + * Encoding names for gettext + */ +typedef struct pg_enc2gettext +{ + pg_enc encoding; + const char *name; +} pg_enc2gettext; + +extern PGDLLIMPORT const pg_enc2gettext pg_enc2gettext_tbl[]; + +/* + * pg_wchar stuff + */ +typedef int (*mb2wchar_with_len_converter) (const unsigned char *from, + pg_wchar *to, + int len); + +typedef int (*wchar2mb_with_len_converter) (const pg_wchar *from, + unsigned char *to, + int len); + +typedef int (*mblen_converter) (const unsigned char *mbstr); + +typedef int (*mbdisplaylen_converter) (const unsigned char *mbstr); + +typedef bool (*mbcharacter_incrementer) (unsigned char *mbstr, int len); + +typedef int (*mbchar_verifier) (const unsigned char *mbstr, int len); + +typedef int (*mbstr_verifier) (const unsigned char *mbstr, int len); + +typedef struct +{ + mb2wchar_with_len_converter mb2wchar_with_len; /* convert a multibyte + * string to a wchar */ + wchar2mb_with_len_converter wchar2mb_with_len; /* convert a wchar string + * to a multibyte */ + mblen_converter mblen; /* get byte length of a char */ + mbdisplaylen_converter dsplen; /* get display width of a char */ + mbchar_verifier mbverifychar; /* verify multibyte character */ + mbstr_verifier mbverifystr; /* verify multibyte string */ + int maxmblen; /* max bytes for a char in this encoding */ +} pg_wchar_tbl; + +extern PGDLLIMPORT const pg_wchar_tbl pg_wchar_table[]; + +/* + * Data structures for conversions between UTF-8 and other encodings + * (UtfToLocal() and LocalToUtf()). In these data structures, characters of + * either encoding are represented by uint32 words; hence we can only support + * characters up to 4 bytes long. For example, the byte sequence 0xC2 0x89 + * would be represented by 0x0000C289, and 0xE8 0xA2 0xB4 by 0x00E8A2B4. + * + * There are three possible ways a character can be mapped: + * + * 1. Using a radix tree, from source to destination code. + * 2. Using a sorted array of source -> destination code pairs. This + * method is used for "combining" characters. There are so few of + * them that building a radix tree would be wasteful. + * 3. Using a conversion function. + */ + +/* + * Radix tree for character conversion. + * + * Logically, this is actually four different radix trees, for 1-byte, + * 2-byte, 3-byte and 4-byte inputs. The 1-byte tree is a simple lookup + * table from source to target code. The 2-byte tree consists of two levels: + * one lookup table for the first byte, where the value in the lookup table + * points to a lookup table for the second byte. And so on. + * + * Physically, all the trees are stored in one big array, in 'chars16' or + * 'chars32', depending on the maximum value that needs to be represented. For + * each level in each tree, we also store lower and upper bound of allowed + * values - values outside those bounds are considered invalid, and are left + * out of the tables. + * + * In the intermediate levels of the trees, the values stored are offsets + * into the chars[16|32] array. + * + * In the beginning of the chars[16|32] array, there is always a number of + * zeros, so that you safely follow an index from an intermediate table + * without explicitly checking for a zero. Following a zero any number of + * times will always bring you to the dummy, all-zeros table in the + * beginning. This helps to shave some cycles when looking up values. + */ +typedef struct +{ + /* + * Array containing all the values. Only one of chars16 or chars32 is + * used, depending on how wide the values we need to represent are. + */ + const uint16 *chars16; + const uint32 *chars32; + + /* Radix tree for 1-byte inputs */ + uint32 b1root; /* offset of table in the chars[16|32] array */ + uint8 b1_lower; /* min allowed value for a single byte input */ + uint8 b1_upper; /* max allowed value for a single byte input */ + + /* Radix tree for 2-byte inputs */ + uint32 b2root; /* offset of 1st byte's table */ + uint8 b2_1_lower; /* min/max allowed value for 1st input byte */ + uint8 b2_1_upper; + uint8 b2_2_lower; /* min/max allowed value for 2nd input byte */ + uint8 b2_2_upper; + + /* Radix tree for 3-byte inputs */ + uint32 b3root; /* offset of 1st byte's table */ + uint8 b3_1_lower; /* min/max allowed value for 1st input byte */ + uint8 b3_1_upper; + uint8 b3_2_lower; /* min/max allowed value for 2nd input byte */ + uint8 b3_2_upper; + uint8 b3_3_lower; /* min/max allowed value for 3rd input byte */ + uint8 b3_3_upper; + + /* Radix tree for 4-byte inputs */ + uint32 b4root; /* offset of 1st byte's table */ + uint8 b4_1_lower; /* min/max allowed value for 1st input byte */ + uint8 b4_1_upper; + uint8 b4_2_lower; /* min/max allowed value for 2nd input byte */ + uint8 b4_2_upper; + uint8 b4_3_lower; /* min/max allowed value for 3rd input byte */ + uint8 b4_3_upper; + uint8 b4_4_lower; /* min/max allowed value for 4th input byte */ + uint8 b4_4_upper; + +} pg_mb_radix_tree; + +/* + * UTF-8 to local code conversion map (for combined characters) + */ +typedef struct +{ + uint32 utf1; /* UTF-8 code 1 */ + uint32 utf2; /* UTF-8 code 2 */ + uint32 code; /* local code */ +} pg_utf_to_local_combined; + +/* + * local code to UTF-8 conversion map (for combined characters) + */ +typedef struct +{ + uint32 code; /* local code */ + uint32 utf1; /* UTF-8 code 1 */ + uint32 utf2; /* UTF-8 code 2 */ +} pg_local_to_utf_combined; + +/* + * callback function for algorithmic encoding conversions (in either direction) + * + * if function returns zero, it does not know how to convert the code + */ +typedef uint32 (*utf_local_conversion_func) (uint32 code); + +/* + * Support macro for encoding conversion functions to validate their + * arguments. (This could be made more compact if we included fmgr.h + * here, but we don't want to do that because this header file is also + * used by frontends.) + */ +#define CHECK_ENCODING_CONVERSION_ARGS(srcencoding,destencoding) \ + check_encoding_conversion_args(PG_GETARG_INT32(0), \ + PG_GETARG_INT32(1), \ + PG_GETARG_INT32(4), \ + (srcencoding), \ + (destencoding)) + + +/* + * Some handy functions for Unicode-specific tests. + */ +static inline bool +is_valid_unicode_codepoint(pg_wchar c) +{ + return (c > 0 && c <= 0x10FFFF); +} + +static inline bool +is_utf16_surrogate_first(pg_wchar c) +{ + return (c >= 0xD800 && c <= 0xDBFF); +} + +static inline bool +is_utf16_surrogate_second(pg_wchar c) +{ + return (c >= 0xDC00 && c <= 0xDFFF); +} + +static inline pg_wchar +surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second) +{ + return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF); +} + + +/* + * These functions are considered part of libpq's exported API and + * are also declared in libpq-fe.h. + */ +extern int pg_char_to_encoding(const char *name); +extern const char *pg_encoding_to_char(int encoding); +extern int pg_valid_server_encoding_id(int encoding); + +/* + * These functions are available to frontend code that links with libpgcommon + * (in addition to the ones just above). The constant tables declared + * earlier in this file are also available from libpgcommon. + */ +extern void pg_encoding_set_invalid(int encoding, char *dst); +extern int pg_encoding_mblen(int encoding, const char *mbstr); +extern int pg_encoding_mblen_or_incomplete(int encoding, const char *mbstr, + size_t remaining); +extern int pg_encoding_mblen_bounded(int encoding, const char *mbstr); +extern int pg_encoding_dsplen(int encoding, const char *mbstr); +extern int pg_encoding_verifymbchar(int encoding, const char *mbstr, int len); +extern int pg_encoding_verifymbstr(int encoding, const char *mbstr, int len); +extern int pg_encoding_max_length(int encoding); +extern int pg_valid_client_encoding(const char *name); +extern int pg_valid_server_encoding(const char *name); +extern bool is_encoding_supported_by_icu(int encoding); +extern const char *get_encoding_name_for_icu(int encoding); + +extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string); +extern pg_wchar utf8_to_unicode(const unsigned char *c); +extern bool pg_utf8_islegal(const unsigned char *source, int length); +extern int pg_utf_mblen(const unsigned char *s); +extern int pg_mule_mblen(const unsigned char *s); + +/* + * The remaining functions are backend-only. + */ +extern int pg_mb2wchar(const char *from, pg_wchar *to); +extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len); +extern int pg_encoding_mb2wchar_with_len(int encoding, + const char *from, pg_wchar *to, int len); +extern int pg_wchar2mb(const pg_wchar *from, char *to); +extern int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len); +extern int pg_encoding_wchar2mb_with_len(int encoding, + const pg_wchar *from, char *to, int len); +extern int pg_char_and_wchar_strcmp(const char *s1, const pg_wchar *s2); +extern int pg_wchar_strncmp(const pg_wchar *s1, const pg_wchar *s2, size_t n); +extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t n); +extern size_t pg_wchar_strlen(const pg_wchar *str); +extern int pg_mblen_cstr(const char *mbstr); +extern int pg_mblen_range(const char *mbstr, const char *end); +extern int pg_mblen_with_len(const char *mbstr, int limit); +extern int pg_mblen_unbounded(const char *mbstr); + +/* deprecated */ +extern int pg_mblen(const char *mbstr); + +extern int pg_dsplen(const char *mbstr); +extern int pg_mbstrlen(const char *mbstr); +extern int pg_mbstrlen_with_len(const char *mbstr, int limit); +extern int pg_mbcliplen(const char *mbstr, int len, int limit); +extern int pg_encoding_mbcliplen(int encoding, const char *mbstr, + int len, int limit); +extern int pg_mbcharcliplen(const char *mbstr, int len, int limit); +extern int pg_database_encoding_max_length(void); +extern mbcharacter_incrementer pg_database_encoding_character_incrementer(void); + +extern int PrepareClientEncoding(int encoding); +extern int SetClientEncoding(int encoding); +extern void InitializeClientEncoding(void); +extern int pg_get_client_encoding(void); +extern const char *pg_get_client_encoding_name(void); + +extern void SetDatabaseEncoding(int encoding); +extern int GetDatabaseEncoding(void); +extern const char *GetDatabaseEncodingName(void); +extern void SetMessageEncoding(int encoding); +extern int GetMessageEncoding(void); + +#ifdef ENABLE_NLS +extern int pg_bind_textdomain_codeset(const char *domainname); +#endif + +extern unsigned char *pg_do_encoding_conversion(unsigned char *src, int len, + int src_encoding, + int dest_encoding); +extern 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); + +extern char *pg_client_to_server(const char *s, int len); +extern char *pg_server_to_client(const char *s, int len); +extern char *pg_any_to_server(const char *s, int len, int encoding); +extern char *pg_server_to_any(const char *s, int len, int encoding); + +extern void pg_unicode_to_server(pg_wchar c, unsigned char *s); +extern bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s); + +extern unsigned short BIG5toCNS(unsigned short big5, unsigned char *lc); +extern unsigned short CNStoBIG5(unsigned short cns, unsigned char lc); + +extern 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, bool noError); +extern 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, bool noError); + +extern bool pg_verifymbstr(const char *mbstr, int len, bool noError); +extern bool pg_verify_mbstr(int encoding, const char *mbstr, int len, + bool noError); +extern int pg_verify_mbstr_len(int encoding, const char *mbstr, int len, + bool noError); + +extern void check_encoding_conversion_args(int src_encoding, + int dest_encoding, + int len, + int expected_src_encoding, + int expected_dest_encoding); + +extern void report_invalid_encoding(int encoding, const char *mbstr, int len) pg_attribute_noreturn(); +extern void report_untranslatable_char(int src_encoding, int dest_encoding, + const char *mbstr, int len) pg_attribute_noreturn(); + +extern int local2local(const unsigned char *l, unsigned char *p, int len, + int src_encoding, int dest_encoding, + const unsigned char *tab, bool noError); +extern int latin2mic(const unsigned char *l, unsigned char *p, int len, + int lc, int encoding, bool noError); +extern int mic2latin(const unsigned char *mic, unsigned char *p, int len, + int lc, int encoding, bool noError); +extern int latin2mic_with_table(const unsigned char *l, unsigned char *p, + int len, int lc, int encoding, + const unsigned char *tab, bool noError); +extern int mic2latin_with_table(const unsigned char *mic, unsigned char *p, + int len, int lc, int encoding, + const unsigned char *tab, bool noError); + +#ifdef WIN32 +extern WCHAR *pgwin32_message_to_UTF16(const char *str, int len, int *utf16len); +#endif + +#endif /* PG_WCHAR_H */ diff --git a/install/include/postgresql/server/mb/stringinfo_mb.h b/install/include/postgresql/server/mb/stringinfo_mb.h new file mode 100644 index 00000000000..9c533f3e76e --- /dev/null +++ b/install/include/postgresql/server/mb/stringinfo_mb.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * stringinfo_mb.h + * multibyte support for StringInfo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/mb/stringinfo_mb.h + *------------------------------------------------------------------------- + */ +#ifndef STRINGINFO_MB_H +#define STRINGINFO_MB_H + + +#include "lib/stringinfo.h" + +/* + * Multibyte-aware StringInfo support function. + */ +extern void appendStringInfoStringQuoted(StringInfo str, + const char *s, int maxlen); + +#endif /* STRINGINFO_MB_H */ diff --git a/install/include/postgresql/server/miscadmin.h b/install/include/postgresql/server/miscadmin.h new file mode 100644 index 00000000000..75144605795 --- /dev/null +++ b/install/include/postgresql/server/miscadmin.h @@ -0,0 +1,679 @@ +/*------------------------------------------------------------------------- + * + * miscadmin.h + * This file contains general postgres administration and initialization + * stuff that used to be spread out between the following files: + * globals.h global variables + * pdir.h directory path crud + * pinit.h postgres initialization + * pmod.h processing modes + * Over time, this has also become the preferred place for widely known + * resource-limitation stuff, such as work_mem and check_stack_depth(). + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/miscadmin.h + * + * NOTES + * some of the information in this file should be moved to other files. + * + *------------------------------------------------------------------------- + * + * PGRAC MODIFICATIONS + * Modified by: SqlRush + * Stage: 0.10 + * + * Extended BackendType enum with 14 pgrac cluster background process + * types (B_CLUSTER_STATS .. B_UNDO_CLEANER), appended after the 13 + * PG-native values to preserve PG ABI for the original numeric + * positions. BACKEND_NUM_TYPES updated to 28 (14 PG + 14 pgrac). + * + * Stage 0.10 only registers the enum identifiers; postmaster fork + * paths for these processes land in stage 0.13+ (ProcessAux + GUC). + * No #ifdef USE_PGRAC_CLUSTER guard around the new values: keeping the + * identifiers always defined avoids #ifdef sprawl across every site + * that references BackendType (matching PG's treatment of + * B_AUTOVAC_LAUNCHER even when autovacuum is off). + * + * Related design: + * docs/background-process-design.md §8.2 (the 14-process roster) + * docs/background-process-design.md §8.3 (ps display names) + * specs/spec-0.10-backend-type-extension.md + * + *------------------------------------------------------------------------- + */ +#ifndef MISCADMIN_H +#define MISCADMIN_H + +#include + +#include "datatype/timestamp.h" /* for TimestampTz */ +#include "pgtime.h" /* for pg_time_t */ + + +#define InvalidPid (-1) + + +/***************************************************************************** + * System interrupt and critical section handling + * + * There are two types of interrupts that a running backend needs to accept + * without messing up its state: QueryCancel (SIGINT) and ProcDie (SIGTERM). + * In both cases, we need to be able to clean up the current transaction + * gracefully, so we can't respond to the interrupt instantaneously --- + * there's no guarantee that internal data structures would be self-consistent + * if the code is interrupted at an arbitrary instant. Instead, the signal + * handlers set flags that are checked periodically during execution. + * + * The CHECK_FOR_INTERRUPTS() macro is called at strategically located spots + * where it is normally safe to accept a cancel or die interrupt. In some + * cases, we invoke CHECK_FOR_INTERRUPTS() inside low-level subroutines that + * might sometimes be called in contexts that do *not* want to allow a cancel + * or die interrupt. The HOLD_INTERRUPTS() and RESUME_INTERRUPTS() macros + * allow code to ensure that no cancel or die interrupt will be accepted, + * even if CHECK_FOR_INTERRUPTS() gets called in a subroutine. The interrupt + * will be held off until CHECK_FOR_INTERRUPTS() is done outside any + * HOLD_INTERRUPTS() ... RESUME_INTERRUPTS() section. + * + * There is also a mechanism to prevent query cancel interrupts, while still + * allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and + * RESUME_CANCEL_INTERRUPTS(). + * + * Note that ProcessInterrupts() has also acquired a number of tasks that + * do not necessarily cause a query-cancel-or-die response. Hence, it's + * possible that it will just clear InterruptPending and return. + * + * INTERRUPTS_PENDING_CONDITION() can be checked to see whether an + * interrupt needs to be serviced, without trying to do so immediately. + * Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(), + * which tells whether ProcessInterrupts is sure to clear the interrupt. + * + * Special mechanisms are used to let an interrupt be accepted when we are + * waiting for a lock or when we are waiting for command input (but, of + * course, only if the interrupt holdoff counter is zero). See the + * related code for details. + * + * A lost connection is handled similarly, although the loss of connection + * does not raise a signal, but is detected when we fail to write to the + * socket. If there was a signal for a broken connection, we could make use of + * it by setting ClientConnectionLost in the signal handler. + * + * A related, but conceptually distinct, mechanism is the "critical section" + * mechanism. A critical section not only holds off cancel/die interrupts, + * but causes any ereport(ERROR) or ereport(FATAL) to become ereport(PANIC) + * --- that is, a system-wide reset is forced. Needless to say, only really + * *critical* code should be marked as a critical section! Currently, this + * mechanism is only used for XLOG-related code. + * + *****************************************************************************/ + +/* in globals.c */ +/* these are marked volatile because they are set by signal handlers: */ +extern PGDLLIMPORT volatile sig_atomic_t InterruptPending; +extern PGDLLIMPORT volatile sig_atomic_t QueryCancelPending; +extern PGDLLIMPORT volatile sig_atomic_t ProcDiePending; +extern PGDLLIMPORT volatile sig_atomic_t IdleInTransactionSessionTimeoutPending; +extern PGDLLIMPORT volatile sig_atomic_t IdleSessionTimeoutPending; +extern PGDLLIMPORT volatile sig_atomic_t ProcSignalBarrierPending; +extern PGDLLIMPORT volatile sig_atomic_t LogMemoryContextPending; +extern PGDLLIMPORT volatile sig_atomic_t IdleStatsUpdateTimeoutPending; + +extern PGDLLIMPORT volatile sig_atomic_t CheckClientConnectionPending; +extern PGDLLIMPORT volatile sig_atomic_t ClientConnectionLost; + +/* these are marked volatile because they are examined by signal handlers: */ +extern PGDLLIMPORT volatile uint32 InterruptHoldoffCount; +extern PGDLLIMPORT volatile uint32 QueryCancelHoldoffCount; +extern PGDLLIMPORT volatile uint32 CritSectionCount; + +/* in tcop/postgres.c */ +extern void ProcessInterrupts(void); + +/* Test whether an interrupt is pending */ +#ifndef WIN32 +#define INTERRUPTS_PENDING_CONDITION() (unlikely(InterruptPending)) +#else +#define INTERRUPTS_PENDING_CONDITION() \ + (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : (void)0, \ + unlikely(InterruptPending)) +#endif + +/* Service interrupt, if one is pending and it's safe to service it now */ +#define CHECK_FOR_INTERRUPTS() \ + do { \ + if (INTERRUPTS_PENDING_CONDITION()) \ + ProcessInterrupts(); \ + } while (0) + +/* Is ProcessInterrupts() guaranteed to clear InterruptPending? */ +#define INTERRUPTS_CAN_BE_PROCESSED() \ + (InterruptHoldoffCount == 0 && CritSectionCount == 0 && QueryCancelHoldoffCount == 0) + +#define HOLD_INTERRUPTS() (InterruptHoldoffCount++) + +#define RESUME_INTERRUPTS() \ + do { \ + Assert(InterruptHoldoffCount > 0); \ + InterruptHoldoffCount--; \ + } while (0) + +#define HOLD_CANCEL_INTERRUPTS() (QueryCancelHoldoffCount++) + +#define RESUME_CANCEL_INTERRUPTS() \ + do { \ + Assert(QueryCancelHoldoffCount > 0); \ + QueryCancelHoldoffCount--; \ + } while (0) + +#define START_CRIT_SECTION() (CritSectionCount++) + +#define END_CRIT_SECTION() \ + do { \ + Assert(CritSectionCount > 0); \ + CritSectionCount--; \ + } while (0) + + +/***************************************************************************** + * globals.h -- * + *****************************************************************************/ + +/* + * from utils/init/globals.c + */ +extern PGDLLIMPORT pid_t PostmasterPid; +extern PGDLLIMPORT bool IsPostmasterEnvironment; +extern PGDLLIMPORT bool IsUnderPostmaster; +extern PGDLLIMPORT bool IsBackgroundWorker; +extern PGDLLIMPORT bool IsBinaryUpgrade; + +extern PGDLLIMPORT bool ExitOnAnyError; + +extern PGDLLIMPORT char *DataDir; +extern PGDLLIMPORT int data_directory_mode; + +extern PGDLLIMPORT int NBuffers; +extern PGDLLIMPORT int MaxBackends; +extern PGDLLIMPORT int MaxConnections; +extern PGDLLIMPORT int max_worker_processes; +extern PGDLLIMPORT int max_parallel_workers; + +extern PGDLLIMPORT int MyProcPid; +extern PGDLLIMPORT pg_time_t MyStartTime; +extern PGDLLIMPORT TimestampTz MyStartTimestamp; +extern PGDLLIMPORT struct Port *MyProcPort; +extern PGDLLIMPORT struct Latch *MyLatch; +extern PGDLLIMPORT int32 MyCancelKey; +extern PGDLLIMPORT int MyPMChildSlot; + +extern PGDLLIMPORT char OutputFileName[]; +extern PGDLLIMPORT char my_exec_path[]; +extern PGDLLIMPORT char pkglib_path[]; + +#ifdef EXEC_BACKEND +extern PGDLLIMPORT char postgres_exec_path[]; +#endif + +/* + * done in storage/backendid.h for now. + * + * extern BackendId MyBackendId; + */ +extern PGDLLIMPORT Oid MyDatabaseId; + +extern PGDLLIMPORT Oid MyDatabaseTableSpace; + +/* + * Date/Time Configuration + * + * DateStyle defines the output formatting choice for date/time types: + * USE_POSTGRES_DATES specifies traditional Postgres format + * USE_ISO_DATES specifies ISO-compliant format + * USE_SQL_DATES specifies Oracle/Ingres-compliant format + * USE_GERMAN_DATES specifies German-style dd.mm/yyyy + * + * DateOrder defines the field order to be assumed when reading an + * ambiguous date (anything not in YYYY-MM-DD format, with a four-digit + * year field first, is taken to be ambiguous): + * DATEORDER_YMD specifies field order yy-mm-dd + * DATEORDER_DMY specifies field order dd-mm-yy ("European" convention) + * DATEORDER_MDY specifies field order mm-dd-yy ("US" convention) + * + * In the Postgres and SQL DateStyles, DateOrder also selects output field + * order: day comes before month in DMY style, else month comes before day. + * + * The user-visible "DateStyle" run-time parameter subsumes both of these. + */ + +/* valid DateStyle values */ +#define USE_POSTGRES_DATES 0 +#define USE_ISO_DATES 1 +#define USE_SQL_DATES 2 +#define USE_GERMAN_DATES 3 +#define USE_XSD_DATES 4 + +/* valid DateOrder values */ +#define DATEORDER_YMD 0 +#define DATEORDER_DMY 1 +#define DATEORDER_MDY 2 + +extern PGDLLIMPORT int DateStyle; +extern PGDLLIMPORT int DateOrder; + +/* + * IntervalStyles + * INTSTYLE_POSTGRES Like Postgres < 8.4 when DateStyle = 'iso' + * INTSTYLE_POSTGRES_VERBOSE Like Postgres < 8.4 when DateStyle != 'iso' + * INTSTYLE_SQL_STANDARD SQL standard interval literals + * INTSTYLE_ISO_8601 ISO-8601-basic formatted intervals + */ +#define INTSTYLE_POSTGRES 0 +#define INTSTYLE_POSTGRES_VERBOSE 1 +#define INTSTYLE_SQL_STANDARD 2 +#define INTSTYLE_ISO_8601 3 + +extern PGDLLIMPORT int IntervalStyle; + +#define MAXTZLEN 10 /* max TZ name len, not counting tr. null */ + +extern PGDLLIMPORT bool enableFsync; +extern PGDLLIMPORT bool allowSystemTableMods; +extern PGDLLIMPORT int work_mem; +extern PGDLLIMPORT double hash_mem_multiplier; +extern PGDLLIMPORT int maintenance_work_mem; +extern PGDLLIMPORT int max_parallel_maintenance_workers; + +/* + * Upper and lower hard limits for the buffer access strategy ring size + * specified by the VacuumBufferUsageLimit GUC and BUFFER_USAGE_LIMIT option + * to VACUUM and ANALYZE. + */ +#define MIN_BAS_VAC_RING_SIZE_KB 128 +#define MAX_BAS_VAC_RING_SIZE_KB (16 * 1024 * 1024) + +extern PGDLLIMPORT int VacuumBufferUsageLimit; +extern PGDLLIMPORT int VacuumCostPageHit; +extern PGDLLIMPORT int VacuumCostPageMiss; +extern PGDLLIMPORT int VacuumCostPageDirty; +extern PGDLLIMPORT int VacuumCostLimit; +extern PGDLLIMPORT double VacuumCostDelay; + +extern PGDLLIMPORT int64 VacuumPageHit; +extern PGDLLIMPORT int64 VacuumPageMiss; +extern PGDLLIMPORT int64 VacuumPageDirty; + +extern PGDLLIMPORT int VacuumCostBalance; +extern PGDLLIMPORT bool VacuumCostActive; + + +/* in tcop/postgres.c */ + +typedef char *pg_stack_base_t; + +extern pg_stack_base_t set_stack_base(void); +extern void restore_stack_base(pg_stack_base_t base); +extern void check_stack_depth(void); +extern bool stack_is_too_deep(void); + +/* in tcop/utility.c */ +extern void PreventCommandIfReadOnly(const char *cmdname); +extern void PreventCommandIfParallelMode(const char *cmdname); +extern void PreventCommandDuringRecovery(const char *cmdname); + +/* in utils/misc/guc_tables.c */ +extern PGDLLIMPORT int trace_recovery_messages; +extern int trace_recovery(int trace_level); + +/***************************************************************************** + * pdir.h -- * + * POSTGRES directory path definitions. * + *****************************************************************************/ + +/* flags to be OR'd to form sec_context */ +#define SECURITY_LOCAL_USERID_CHANGE 0x0001 +#define SECURITY_RESTRICTED_OPERATION 0x0002 +#define SECURITY_NOFORCE_RLS 0x0004 + +extern PGDLLIMPORT char *DatabasePath; + +/* now in utils/init/miscinit.c */ +extern void InitPostmasterChild(void); +extern void InitStandaloneProcess(const char *argv0); +extern void InitProcessLocalLatch(void); +extern void SwitchToSharedLatch(void); +extern void SwitchBackToLocalLatch(void); + +typedef enum BackendType { + B_INVALID = 0, + B_ARCHIVER, + B_AUTOVAC_LAUNCHER, + B_AUTOVAC_WORKER, + B_BACKEND, + B_BG_WORKER, + B_BG_WRITER, + B_CHECKPOINTER, + B_LOGGER, + B_STANDALONE_BACKEND, + B_STARTUP, + B_WAL_RECEIVER, + B_WAL_SENDER, + B_WAL_WRITER, + + /* + * PGRAC: pgrac cluster background process types (stage 0.10). + * Appended in alphabetic order; see docs/background-process-design.md + * §8.2. Stage 0.10 registers identifiers only -- spawning paths + * land in stage 0.13+. + */ + B_CLUSTER_STATS, + B_CSSD, + B_DIAG, + B_HEARTBEAT, + B_INTERCONNECT, + B_LCK, + B_LMD, + B_LMON, + B_LMS, + B_LMS_WORKER, + B_MRP, + B_QVOTEC, + B_RECOVERY_COORD, + B_RECOVERY_WORKER, + B_SINVAL_BCAST, + B_TT_GC, + B_UNDO_CLEANER, +} BackendType; + +/* PGRAC: anchored on the last pgrac value so additions stay correct. */ +#define BACKEND_NUM_TYPES (B_UNDO_CLEANER + 1) + +extern PGDLLIMPORT BackendType MyBackendType; + +#define AmRegularBackendProcess() (MyBackendType == B_BACKEND) + +extern const char *GetBackendTypeDesc(BackendType backendType); + +extern void SetDatabasePath(const char *path); +extern void checkDataDir(void); +extern void SetDataDir(const char *dir); +extern void ChangeToDataDir(void); + +extern char *GetUserNameFromId(Oid roleid, bool noerr); +extern Oid GetUserId(void); +extern Oid GetOuterUserId(void); +extern Oid GetSessionUserId(void); +extern bool GetSessionUserIsSuperuser(void); +extern Oid GetAuthenticatedUserId(void); +extern bool GetAuthenticatedUserIsSuperuser(void); +extern void SetAuthenticatedUserId(Oid userid, bool is_superuser); +extern void GetUserIdAndSecContext(Oid *userid, int *sec_context); +extern void SetUserIdAndSecContext(Oid userid, int sec_context); +extern bool InLocalUserIdChange(void); +extern bool InSecurityRestrictedOperation(void); +extern bool InNoForceRLSOperation(void); +extern void GetUserIdAndContext(Oid *userid, bool *sec_def_context); +extern void SetUserIdAndContext(Oid userid, bool sec_def_context); +extern void InitializeSessionUserId(const char *rolename, Oid roleid); +extern void InitializeSessionUserIdStandalone(void); +extern void SetSessionAuthorization(Oid userid, bool is_superuser); +extern Oid GetCurrentRoleId(void); +extern void SetCurrentRoleId(Oid roleid, bool is_superuser); +extern void InitializeSystemUser(const char *authn_id, const char *auth_method); +extern const char *GetSystemUser(void); + +/* in utils/misc/superuser.c */ +extern bool superuser(void); /* current user is superuser */ +extern bool superuser_arg(Oid roleid); /* given user is superuser */ + + +/***************************************************************************** + * pmod.h -- * + * POSTGRES processing mode definitions. * + *****************************************************************************/ + +/* + * Description: + * There are three processing modes in POSTGRES. They are + * BootstrapProcessing or "bootstrap," InitProcessing or + * "initialization," and NormalProcessing or "normal." + * + * The first two processing modes are used during special times. When the + * system state indicates bootstrap processing, transactions are all given + * transaction id "one" and are consequently guaranteed to commit. This mode + * is used during the initial generation of template databases. + * + * Initialization mode: used while starting a backend, until all normal + * initialization is complete. Some code behaves differently when executed + * in this mode to enable system bootstrapping. + * + * If a POSTGRES backend process is in normal mode, then all code may be + * executed normally. + */ + +typedef enum ProcessingMode { + BootstrapProcessing, /* bootstrap creation of template database */ + InitProcessing, /* initializing system */ + NormalProcessing /* normal processing */ +} ProcessingMode; + +extern PGDLLIMPORT ProcessingMode Mode; + +#define IsBootstrapProcessingMode() (Mode == BootstrapProcessing) +#define IsInitProcessingMode() (Mode == InitProcessing) +#define IsNormalProcessingMode() (Mode == NormalProcessing) + +#define GetProcessingMode() Mode + +#define SetProcessingMode(mode) \ + do { \ + Assert((mode) == BootstrapProcessing || (mode) == InitProcessing \ + || (mode) == NormalProcessing); \ + Mode = (mode); \ + } while (0) + + +/* + * Auxiliary-process type identifiers. These used to be in bootstrap.h + * but it seems saner to have them here, with the ProcessingMode stuff. + * The MyAuxProcType global is defined and set in auxprocess.c. + * + * Make sure to list in the glossary any items you add here. + */ + +typedef enum { + NotAnAuxProcess = -1, + StartupProcess = 0, + BgWriterProcess, + ArchiverProcess, + CheckpointerProcess, + WalWriterProcess, + WalReceiverProcess, +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC (stage 1.11 Sprint A): LMON aux process — first cluster + * background process spawned by postmaster. Appended to preserve + * existing AuxProcType numeric values; this slot only exists in + * --enable-cluster builds so non-cluster postgres binaries are + * ABI-compatible at the AuxProcType level. Lifecycle skeleton + * only at 1.11 Sprint A; real reconfig / fence / GRD / heartbeat + * consumption land in Stage 2-6. See cluster_lmon.h. + */ + LmonProcess, + /* + * PGRAC (stage 1.12 Sprint A): LCK aux process — second cluster + * background process; instance-level lock placeholder. Appended + * after LmonProcess to preserve numeric values. Lifecycle + * skeleton only; real dictionary/catalog lock protocol lands in + * Stage 2+ GES feature. See cluster_lck.h. + */ + LckProcess, + /* + * DIAG (Diagnostic Process) is stage 1.13 Sprint A's third real + * cluster background process; cross-node diagnostic placeholder. + * Appended after LckProcess to preserve numeric values. Lifecycle + * skeleton only; real diagnostic snapshot / hang dump / cross-node + * DIAG request protocol lands in Stage 2+ when interconnect is + * fully wired. See cluster_diag.h. + */ + DiagProcess, + /* + * Cluster Stats (Cluster Statistics process) is stage 1.14 Sprint + * A's fourth real cluster background process; pg_stat_cluster_* + * view filling / cross-node aggregation / wait event tracking / + * history retention placeholder. Appended after DiagProcess to + * preserve numeric values. Lifecycle skeleton only; real protocols + * land in Stage 2+ when interconnect is fully wired. See + * cluster_stats.h. + */ + ClusterStatsProcess, + /* + * CSSD (Cluster Synchronization Service Daemon) is the 5th cluster + * background process — spec-2.5 Sprint A. Appended after + * ClusterStatsProcess to preserve numeric values. Application-level + * peer dead detection via heartbeat broadcast (paired with spec-2.4 + * D8 socket-level TCP KeepAlive for two-layer dead detection). + * Lifecycle skeleton + heartbeat broadcast + per-peer state machine; + * does NOT trigger reconfig (spec-2.29 separate sub-spec). See + * cluster_cssd.h. + */ + CssdProcess, + /* + * QVOTEC (Quorum Voting Coordinator) is the 6th cluster background + * process — spec-2.6 Sprint A Step 3 D7. Appended after CssdProcess + * to preserve numeric values. Polls voting disks on shared storage + * to derive cluster-wide quorum view;broadcasts cluster_freeze_writes + * / cluster_thaw_writes via PG ProcSignal multiplexer when + * quorum_state transitions. Implements spec-2.0 §3 Invariant 1 + * (no-quorum no dual-write fail-closed) + Invariant 3 (uncertainty + * → fail-closed). Lease-based in_quorum semantics (Q4 v0.2) + * defends against qvotec hung > 2 × poll interval. See + * cluster_qvotec.h. + */ + QvotecProcess, + /* + * LMS (Lock Master / Grant Service) is the 7th cluster background + * process — spec-2.18 Sprint A. Appended after QvotecProcess to + * preserve numeric values. Spec-2.18 ships the LMS skeleton + + * grant-decision ownership migration from LMON to LMS with + * single ownership path + fail-closed semantics (no runtime + * LMON fallback grant; cluster.lms_enabled=off is PGC_POSTMASTER + * startup-only fallback). Real grant state machine activation, + * BAST send, deadlock detection, cleanup_on_backend_exit, lock + * class expansion all defer to spec-2.19+ Phase 2.C. See + * cluster_lms.h. + */ + LmsProcess, + /* + * LMD (Lock Manager Daemon — deadlock detection actor) is the 8th + * cluster background process — spec-2.19 Sprint A. Appended after + * LmsProcess to preserve numeric values. Spec-2.19 ships the LMD + * skeleton + deadlock-detection ownership migration from spec-2.17 + * caller-side 4-node placeholder to LMD with single ownership path + + * fail-closed semantics (no runtime caller-side fallback grant; + * cluster.lmd_enabled=off is PGC_POSTMASTER startup-only fallback). + * Real Tarjan cycle detection, wait-for graph maintenance, victim + * selection, cancellation all defer to spec-2.20+ Phase 2.C + spec-5.9 + * Stage 5. See cluster_lmd.h. B_LMD BackendType already exists + * (spec-1.10 backend types extension) — spec-2.19 D3 reuses existing + * surface without duplicate definition. + */ + LmdProcess, + /* + * SI Broadcaster (Shared Invalidation Broadcaster) is the 9th cluster + * background process — spec-2.38 Sprint A D4. Appended after + * LmdProcess to preserve numeric values. Cross-node sinval message + * propagation: LMON drains ClusterSinvalOutbound and fanouts + * PGRAC_IC_MSG_SINVAL wire envelopes because tier1 TCP descriptors + * are LMON-local; this aux process drains ClusterSinvalInbound and + * applies SendSharedInvalidMessages (PG-native sinval API); executes + * fail-safe SIResetAll() on inbound overflow (HC134). The IC inbound + * handler nonblocking 约束 (HC133) forbids LWLockAcquire inside handler + * context, so all real apply work is deferred to this aux process main + * loop. Producer mask CLUSTER_IC_PRODUCER_SINVAL_FANOUT means only + * LMON may directly send SINVAL wire envelopes (HC139); backends must + * enqueue via cluster_sinval_enqueue_batch(). See cluster_sinval_bcast.h. + */ + SinvalBcastProcess, + + /* + * Undo Cleaner is the Stage 3.13 cluster background process — + * proactive undo/TT-slot retention GC (spec-3.13). Appended after + * SinvalBcastProcess to preserve numeric values. Consumes the + * B_UNDO_CLEANER BackendType reserved at Stage 1. ServerLoop- + * managed (NOT phase-4 gated): absence degrades to spec-3.12 + * lazy-only recycling. See cluster_undo_cleaner.h. + */ + UndoCleanerProcess, + +#endif + NUM_AUXPROCTYPES /* Must be last! */ +} AuxProcType; + +extern PGDLLIMPORT AuxProcType MyAuxProcType; + +#define AmStartupProcess() (MyAuxProcType == StartupProcess) +#define AmBackgroundWriterProcess() (MyAuxProcType == BgWriterProcess) +#define AmArchiverProcess() (MyAuxProcType == ArchiverProcess) +#define AmCheckpointerProcess() (MyAuxProcType == CheckpointerProcess) +#define AmWalWriterProcess() (MyAuxProcType == WalWriterProcess) +#define AmWalReceiverProcess() (MyAuxProcType == WalReceiverProcess) +#ifdef USE_PGRAC_CLUSTER +#define AmLmonProcess() (MyAuxProcType == LmonProcess) +#define AmLckProcess() (MyAuxProcType == LckProcess) +#define AmDiagProcess() (MyAuxProcType == DiagProcess) +#define AmClusterStatsProcess() (MyAuxProcType == ClusterStatsProcess) +#define AmCssdProcess() (MyAuxProcType == CssdProcess) +#define AmQvotecProcess() (MyAuxProcType == QvotecProcess) +#define AmLmsProcess() (MyAuxProcType == LmsProcess) +#define AmLmdProcess() (MyAuxProcType == LmdProcess) +#define AmSinvalBcastProcess() (MyAuxProcType == SinvalBcastProcess) +#define AmUndoCleanerProcess() (MyAuxProcType == UndoCleanerProcess) +#endif + + +/***************************************************************************** + * pinit.h -- * + * POSTGRES initialization and cleanup definitions. * + *****************************************************************************/ + +/* in utils/init/postinit.c */ +extern void pg_split_opts(char **argv, int *argcp, const char *optstr); +extern void InitializeMaxBackends(void); +extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username, Oid useroid, + bool load_session_libraries, bool override_allow_connections, + char *out_dbname); +extern void BaseInit(void); + +/* in utils/init/miscinit.c */ +extern PGDLLIMPORT bool IgnoreSystemIndexes; +extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress; +extern PGDLLIMPORT bool process_shared_preload_libraries_done; +extern PGDLLIMPORT bool process_shmem_requests_in_progress; +extern PGDLLIMPORT char *session_preload_libraries_string; +extern PGDLLIMPORT char *shared_preload_libraries_string; +extern PGDLLIMPORT char *local_preload_libraries_string; + +extern void CreateDataDirLockFile(bool amPostmaster); +extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster, const char *socketDir); +extern void TouchSocketLockFiles(void); +extern void AddToDataDirLockFile(int target_line, const char *str); +extern bool RecheckDataDirLockFile(void); +extern void ValidatePgVersion(const char *path); +extern void process_shared_preload_libraries(void); +extern void process_session_preload_libraries(void); +extern void process_shmem_requests(void); +extern void pg_bindtextdomain(const char *domain); +extern bool has_rolreplication(Oid roleid); + +typedef void (*shmem_request_hook_type)(void); +extern PGDLLIMPORT shmem_request_hook_type shmem_request_hook; + +extern Size EstimateClientConnectionInfoSpace(void); +extern void SerializeClientConnectionInfo(Size maxsize, char *start_address); +extern void RestoreClientConnectionInfo(char *conninfo); + +/* in executor/nodeHash.c */ +extern size_t get_hash_memory_limit(void); + +#endif /* MISCADMIN_H */ diff --git a/install/include/postgresql/server/nodes/bitmapset.h b/install/include/postgresql/server/nodes/bitmapset.h new file mode 100644 index 00000000000..14de6a9ff1e --- /dev/null +++ b/install/include/postgresql/server/nodes/bitmapset.h @@ -0,0 +1,126 @@ +/*------------------------------------------------------------------------- + * + * bitmapset.h + * PostgreSQL generic bitmap set package + * + * A bitmap set can represent any set of nonnegative integers, although + * it is mainly intended for sets where the maximum value is not large, + * say at most a few hundred. By convention, we always represent the + * empty set by a NULL pointer. + * + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/nodes/bitmapset.h + * + *------------------------------------------------------------------------- + */ +#ifndef BITMAPSET_H +#define BITMAPSET_H + +#include "nodes/nodes.h" + +/* + * Forward decl to save including pg_list.h + */ +struct List; + +/* + * Data representation + * + * Larger bitmap word sizes generally give better performance, so long as + * they're not wider than the processor can handle efficiently. We use + * 64-bit words if pointers are that large, else 32-bit words. + */ +#if SIZEOF_VOID_P >= 8 + +#define BITS_PER_BITMAPWORD 64 +typedef uint64 bitmapword; /* must be an unsigned type */ +typedef int64 signedbitmapword; /* must be the matching signed type */ + +#else + +#define BITS_PER_BITMAPWORD 32 +typedef uint32 bitmapword; /* must be an unsigned type */ +typedef int32 signedbitmapword; /* must be the matching signed type */ + +#endif + +typedef struct Bitmapset +{ + pg_node_attr(custom_copy_equal, special_read_write, no_query_jumble) + + NodeTag type; + int nwords; /* number of words in array */ + bitmapword words[FLEXIBLE_ARRAY_MEMBER]; /* really [nwords] */ +} Bitmapset; + + +/* result of bms_subset_compare */ +typedef enum +{ + BMS_EQUAL, /* sets are equal */ + BMS_SUBSET1, /* first set is a subset of the second */ + BMS_SUBSET2, /* second set is a subset of the first */ + BMS_DIFFERENT /* neither set is a subset of the other */ +} BMS_Comparison; + +/* result of bms_membership */ +typedef enum +{ + BMS_EMPTY_SET, /* 0 members */ + BMS_SINGLETON, /* 1 member */ + BMS_MULTIPLE /* >1 member */ +} BMS_Membership; + + +/* + * function prototypes in nodes/bitmapset.c + */ + +extern Bitmapset *bms_copy(const Bitmapset *a); +extern bool bms_equal(const Bitmapset *a, const Bitmapset *b); +extern int bms_compare(const Bitmapset *a, const Bitmapset *b); +extern Bitmapset *bms_make_singleton(int x); +extern void bms_free(Bitmapset *a); + +extern Bitmapset *bms_union(const Bitmapset *a, const Bitmapset *b); +extern Bitmapset *bms_intersect(const Bitmapset *a, const Bitmapset *b); +extern Bitmapset *bms_difference(const Bitmapset *a, const Bitmapset *b); +extern bool bms_is_subset(const Bitmapset *a, const Bitmapset *b); +extern BMS_Comparison bms_subset_compare(const Bitmapset *a, const Bitmapset *b); +extern bool bms_is_member(int x, const Bitmapset *a); +extern int bms_member_index(Bitmapset *a, int x); +extern bool bms_overlap(const Bitmapset *a, const Bitmapset *b); +extern bool bms_overlap_list(const Bitmapset *a, const struct List *b); +extern bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b); +extern int bms_singleton_member(const Bitmapset *a); +extern bool bms_get_singleton_member(const Bitmapset *a, int *member); +extern int bms_num_members(const Bitmapset *a); + +/* optimized tests when we don't need to know exact membership count: */ +extern BMS_Membership bms_membership(const Bitmapset *a); + +/* NULL is now the only allowed representation of an empty bitmapset */ +#define bms_is_empty(a) ((a) == NULL) + +/* these routines recycle (modify or free) their non-const inputs: */ + +extern Bitmapset *bms_add_member(Bitmapset *a, int x); +extern Bitmapset *bms_del_member(Bitmapset *a, int x); +extern Bitmapset *bms_add_members(Bitmapset *a, const Bitmapset *b); +extern Bitmapset *bms_add_range(Bitmapset *a, int lower, int upper); +extern Bitmapset *bms_int_members(Bitmapset *a, const Bitmapset *b); +extern Bitmapset *bms_del_members(Bitmapset *a, const Bitmapset *b); +extern Bitmapset *bms_join(Bitmapset *a, Bitmapset *b); + +/* support for iterating through the integer elements of a set: */ +extern int bms_next_member(const Bitmapset *a, int prevbit); +extern int bms_prev_member(const Bitmapset *a, int prevbit); + +/* support for hashtables using Bitmapsets as keys: */ +extern uint32 bms_hash_value(const Bitmapset *a); +extern uint32 bitmap_hash(const void *key, Size keysize); +extern int bitmap_match(const void *key1, const void *key2, Size keysize); + +#endif /* BITMAPSET_H */ diff --git a/install/include/postgresql/server/nodes/execnodes.h b/install/include/postgresql/server/nodes/execnodes.h new file mode 100644 index 00000000000..74718fa256d --- /dev/null +++ b/install/include/postgresql/server/nodes/execnodes.h @@ -0,0 +1,2774 @@ +/*------------------------------------------------------------------------- + * + * execnodes.h + * definitions for executor state nodes + * + * Most plan node types declared in plannodes.h have a corresponding + * execution-state node type declared here. An exception is that + * expression nodes (subtypes of Expr) are usually represented by steps + * of an ExprState, and fully handled within execExpr* - but sometimes + * their state needs to be shared with other parts of the executor, as + * for example with SubPlanState, which nodeSubplan.c has to modify. + * + * Node types declared in this file do not have any copy/equal/out/read + * support. (That is currently hard-wired in gen_node_support.pl, rather + * than being explicitly represented by pg_node_attr decorations here.) + * There is no need for copy, equal, or read support for executor trees. + * Output support could be useful for debugging; but there are a lot of + * specialized fields that would require custom code, so for now it's + * not provided. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/execnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXECNODES_H +#define EXECNODES_H + +#include "access/tupconvert.h" +#include "executor/instrument.h" +#include "fmgr.h" +#include "lib/ilist.h" +#include "lib/pairingheap.h" +#include "nodes/params.h" +#include "nodes/plannodes.h" +#include "nodes/tidbitmap.h" +#include "partitioning/partdefs.h" +#include "storage/condition_variable.h" +#include "utils/hsearch.h" +#include "utils/queryenvironment.h" +#include "utils/reltrigger.h" +#include "utils/sharedtuplestore.h" +#include "utils/snapshot.h" +#include "utils/sortsupport.h" +#include "utils/tuplesort.h" +#include "utils/tuplestore.h" + +struct PlanState; /* forward references in this file */ +struct ParallelHashJoinState; +struct ExecRowMark; +struct ExprState; +struct ExprContext; +struct RangeTblEntry; /* avoid including parsenodes.h here */ +struct ExprEvalStep; /* avoid including execExpr.h everywhere */ +struct CopyMultiInsertBuffer; +struct LogicalTapeSet; + + +/* ---------------- + * ExprState node + * + * ExprState represents the evaluation state for a whole expression tree. + * It contains instructions (in ->steps) to evaluate the expression. + * ---------------- + */ +typedef Datum (*ExprStateEvalFunc) (struct ExprState *expression, + struct ExprContext *econtext, + bool *isNull); + +/* Bits in ExprState->flags (see also execExpr.h for private flag bits): */ +/* expression is for use with ExecQual() */ +#define EEO_FLAG_IS_QUAL (1 << 0) + +typedef struct ExprState +{ + NodeTag type; + + uint8 flags; /* bitmask of EEO_FLAG_* bits, see above */ + + /* + * Storage for result value of a scalar expression, or for individual + * column results within expressions built by ExecBuildProjectionInfo(). + */ +#define FIELDNO_EXPRSTATE_RESNULL 2 + bool resnull; +#define FIELDNO_EXPRSTATE_RESVALUE 3 + Datum resvalue; + + /* + * If projecting a tuple result, this slot holds the result; else NULL. + */ +#define FIELDNO_EXPRSTATE_RESULTSLOT 4 + TupleTableSlot *resultslot; + + /* + * Instructions to compute expression's return value. + */ + struct ExprEvalStep *steps; + + /* + * Function that actually evaluates the expression. This can be set to + * different values depending on the complexity of the expression. + */ + ExprStateEvalFunc evalfunc; + + /* original expression tree, for debugging only */ + Expr *expr; + + /* private state for an evalfunc */ + void *evalfunc_private; + + /* + * XXX: following fields only needed during "compilation" (ExecInitExpr); + * could be thrown away afterwards. + */ + + int steps_len; /* number of steps currently */ + int steps_alloc; /* allocated length of steps array */ + +#define FIELDNO_EXPRSTATE_PARENT 11 + struct PlanState *parent; /* parent PlanState node, if any */ + ParamListInfo ext_params; /* for compiling PARAM_EXTERN nodes */ + + Datum *innermost_caseval; + bool *innermost_casenull; + + Datum *innermost_domainval; + bool *innermost_domainnull; +} ExprState; + + +/* ---------------- + * IndexInfo information + * + * this struct holds the information needed to construct new index + * entries for a particular index. Used for both index_build and + * retail creation of index entries. + * + * NumIndexAttrs total number of columns in this index + * NumIndexKeyAttrs number of key columns in index + * IndexAttrNumbers underlying-rel attribute numbers used as keys + * (zeroes indicate expressions). It also contains + * info about included columns. + * Expressions expr trees for expression entries, or NIL if none + * ExpressionsState exec state for expressions, or NIL if none + * Predicate partial-index predicate, or NIL if none + * PredicateState exec state for predicate, or NIL if none + * ExclusionOps Per-column exclusion operators, or NULL if none + * ExclusionProcs Underlying function OIDs for ExclusionOps + * ExclusionStrats Opclass strategy numbers for ExclusionOps + * UniqueOps These are like Exclusion*, but for unique indexes + * UniqueProcs + * UniqueStrats + * OpclassOptions opclass-specific options, or NULL if none + * Unique is it a unique index? + * NullsNotDistinct is NULLS NOT DISTINCT? + * ReadyForInserts is it valid for inserts? + * CheckedUnchanged IndexUnchanged status determined yet? + * IndexUnchanged aminsert hint, cached for retail inserts + * Concurrent are we doing a concurrent index build? + * BrokenHotChain did we detect any broken HOT chains? + * Summarizing is it a summarizing index? + * ParallelWorkers # of workers requested (excludes leader) + * Am Oid of index AM + * AmCache private cache area for index AM + * Context memory context holding this IndexInfo + * + * ii_Concurrent, ii_BrokenHotChain, and ii_ParallelWorkers are used only + * during index build; they're conventionally zeroed otherwise. + * ---------------- + */ +typedef struct IndexInfo +{ + NodeTag type; + int ii_NumIndexAttrs; /* total number of columns in index */ + int ii_NumIndexKeyAttrs; /* number of key columns in index */ + AttrNumber ii_IndexAttrNumbers[INDEX_MAX_KEYS]; + List *ii_Expressions; /* list of Expr */ + List *ii_ExpressionsState; /* list of ExprState */ + List *ii_Predicate; /* list of Expr */ + ExprState *ii_PredicateState; + Oid *ii_ExclusionOps; /* array with one entry per column */ + Oid *ii_ExclusionProcs; /* array with one entry per column */ + uint16 *ii_ExclusionStrats; /* array with one entry per column */ + Oid *ii_UniqueOps; /* array with one entry per column */ + Oid *ii_UniqueProcs; /* array with one entry per column */ + uint16 *ii_UniqueStrats; /* array with one entry per column */ + Datum *ii_OpclassOptions; /* array with one entry per column */ + bool ii_Unique; + bool ii_NullsNotDistinct; + bool ii_ReadyForInserts; + bool ii_CheckedUnchanged; + bool ii_IndexUnchanged; + bool ii_Concurrent; + bool ii_BrokenHotChain; + bool ii_Summarizing; + int ii_ParallelWorkers; + Oid ii_Am; + void *ii_AmCache; + MemoryContext ii_Context; +} IndexInfo; + +/* ---------------- + * ExprContext_CB + * + * List of callbacks to be called at ExprContext shutdown. + * ---------------- + */ +typedef void (*ExprContextCallbackFunction) (Datum arg); + +typedef struct ExprContext_CB +{ + struct ExprContext_CB *next; + ExprContextCallbackFunction function; + Datum arg; +} ExprContext_CB; + +/* ---------------- + * ExprContext + * + * This class holds the "current context" information + * needed to evaluate expressions for doing tuple qualifications + * and tuple projections. For example, if an expression refers + * to an attribute in the current inner tuple then we need to know + * what the current inner tuple is and so we look at the expression + * context. + * + * There are two memory contexts associated with an ExprContext: + * * ecxt_per_query_memory is a query-lifespan context, typically the same + * context the ExprContext node itself is allocated in. This context + * can be used for purposes such as storing function call cache info. + * * ecxt_per_tuple_memory is a short-term context for expression results. + * As the name suggests, it will typically be reset once per tuple, + * before we begin to evaluate expressions for that tuple. Each + * ExprContext normally has its very own per-tuple memory context. + * + * CurrentMemoryContext should be set to ecxt_per_tuple_memory before + * calling ExecEvalExpr() --- see ExecEvalExprSwitchContext(). + * ---------------- + */ +typedef struct ExprContext +{ + NodeTag type; + + /* Tuples that Var nodes in expression may refer to */ +#define FIELDNO_EXPRCONTEXT_SCANTUPLE 1 + TupleTableSlot *ecxt_scantuple; +#define FIELDNO_EXPRCONTEXT_INNERTUPLE 2 + TupleTableSlot *ecxt_innertuple; +#define FIELDNO_EXPRCONTEXT_OUTERTUPLE 3 + TupleTableSlot *ecxt_outertuple; + + /* Memory contexts for expression evaluation --- see notes above */ + MemoryContext ecxt_per_query_memory; + MemoryContext ecxt_per_tuple_memory; + + /* Values to substitute for Param nodes in expression */ + ParamExecData *ecxt_param_exec_vals; /* for PARAM_EXEC params */ + ParamListInfo ecxt_param_list_info; /* for other param types */ + + /* + * Values to substitute for Aggref nodes in the expressions of an Agg + * node, or for WindowFunc nodes within a WindowAgg node. + */ +#define FIELDNO_EXPRCONTEXT_AGGVALUES 8 + Datum *ecxt_aggvalues; /* precomputed values for aggs/windowfuncs */ +#define FIELDNO_EXPRCONTEXT_AGGNULLS 9 + bool *ecxt_aggnulls; /* null flags for aggs/windowfuncs */ + + /* Value to substitute for CaseTestExpr nodes in expression */ +#define FIELDNO_EXPRCONTEXT_CASEDATUM 10 + Datum caseValue_datum; +#define FIELDNO_EXPRCONTEXT_CASENULL 11 + bool caseValue_isNull; + + /* Value to substitute for CoerceToDomainValue nodes in expression */ +#define FIELDNO_EXPRCONTEXT_DOMAINDATUM 12 + Datum domainValue_datum; +#define FIELDNO_EXPRCONTEXT_DOMAINNULL 13 + bool domainValue_isNull; + + /* Link to containing EState (NULL if a standalone ExprContext) */ + struct EState *ecxt_estate; + + /* Functions to call back when ExprContext is shut down or rescanned */ + ExprContext_CB *ecxt_callbacks; +} ExprContext; + +/* + * Set-result status used when evaluating functions potentially returning a + * set. + */ +typedef enum +{ + ExprSingleResult, /* expression does not return a set */ + ExprMultipleResult, /* this result is an element of a set */ + ExprEndResult /* there are no more elements in the set */ +} ExprDoneCond; + +/* + * Return modes for functions returning sets. Note values must be chosen + * as separate bits so that a bitmask can be formed to indicate supported + * modes. SFRM_Materialize_Random and SFRM_Materialize_Preferred are + * auxiliary flags about SFRM_Materialize mode, rather than separate modes. + */ +typedef enum +{ + SFRM_ValuePerCall = 0x01, /* one value returned per call */ + SFRM_Materialize = 0x02, /* result set instantiated in Tuplestore */ + SFRM_Materialize_Random = 0x04, /* Tuplestore needs randomAccess */ + SFRM_Materialize_Preferred = 0x08 /* caller prefers Tuplestore */ +} SetFunctionReturnMode; + +/* + * When calling a function that might return a set (multiple rows), + * a node of this type is passed as fcinfo->resultinfo to allow + * return status to be passed back. A function returning set should + * raise an error if no such resultinfo is provided. + */ +typedef struct ReturnSetInfo +{ + NodeTag type; + /* values set by caller: */ + ExprContext *econtext; /* context function is being called in */ + TupleDesc expectedDesc; /* tuple descriptor expected by caller */ + int allowedModes; /* bitmask: return modes caller can handle */ + /* result status from function (but pre-initialized by caller): */ + SetFunctionReturnMode returnMode; /* actual return mode */ + ExprDoneCond isDone; /* status for ValuePerCall mode */ + /* fields filled by function in Materialize return mode: */ + Tuplestorestate *setResult; /* holds the complete returned tuple set */ + TupleDesc setDesc; /* actual descriptor for returned tuples */ +} ReturnSetInfo; + +/* ---------------- + * ProjectionInfo node information + * + * This is all the information needed to perform projections --- + * that is, form new tuples by evaluation of targetlist expressions. + * Nodes which need to do projections create one of these. + * + * The target tuple slot is kept in ProjectionInfo->pi_state.resultslot. + * ExecProject() evaluates the tlist, forms a tuple, and stores it + * in the given slot. Note that the result will be a "virtual" tuple + * unless ExecMaterializeSlot() is then called to force it to be + * converted to a physical tuple. The slot must have a tupledesc + * that matches the output of the tlist! + * ---------------- + */ +typedef struct ProjectionInfo +{ + NodeTag type; + /* instructions to evaluate projection */ + ExprState pi_state; + /* expression context in which to evaluate expression */ + ExprContext *pi_exprContext; +} ProjectionInfo; + +/* ---------------- + * JunkFilter + * + * This class is used to store information regarding junk attributes. + * A junk attribute is an attribute in a tuple that is needed only for + * storing intermediate information in the executor, and does not belong + * in emitted tuples. For example, when we do an UPDATE query, + * the planner adds a "junk" entry to the targetlist so that the tuples + * returned to ExecutePlan() contain an extra attribute: the ctid of + * the tuple to be updated. This is needed to do the update, but we + * don't want the ctid to be part of the stored new tuple! So, we + * apply a "junk filter" to remove the junk attributes and form the + * real output tuple. The junkfilter code also provides routines to + * extract the values of the junk attribute(s) from the input tuple. + * + * targetList: the original target list (including junk attributes). + * cleanTupType: the tuple descriptor for the "clean" tuple (with + * junk attributes removed). + * cleanMap: A map with the correspondence between the non-junk + * attribute numbers of the "original" tuple and the + * attribute numbers of the "clean" tuple. + * resultSlot: tuple slot used to hold cleaned tuple. + * ---------------- + */ +typedef struct JunkFilter +{ + NodeTag type; + List *jf_targetList; + TupleDesc jf_cleanTupType; + AttrNumber *jf_cleanMap; + TupleTableSlot *jf_resultSlot; +} JunkFilter; + +/* + * OnConflictSetState + * + * Executor state of an ON CONFLICT DO UPDATE operation. + */ +typedef struct OnConflictSetState +{ + NodeTag type; + + TupleTableSlot *oc_Existing; /* slot to store existing target tuple in */ + TupleTableSlot *oc_ProjSlot; /* CONFLICT ... SET ... projection target */ + ProjectionInfo *oc_ProjInfo; /* for ON CONFLICT DO UPDATE SET */ + ExprState *oc_WhereClause; /* state for the WHERE clause */ +} OnConflictSetState; + +/* ---------------- + * MergeActionState information + * + * Executor state for a MERGE action. + * ---------------- + */ +typedef struct MergeActionState +{ + NodeTag type; + + MergeAction *mas_action; /* associated MergeAction node */ + ProjectionInfo *mas_proj; /* projection of the action's targetlist for + * this rel */ + ExprState *mas_whenqual; /* WHEN [NOT] MATCHED AND conditions */ +} MergeActionState; + +/* + * ResultRelInfo + * + * Whenever we update an existing relation, we have to update indexes on the + * relation, and perhaps also fire triggers. ResultRelInfo holds all the + * information needed about a result relation, including indexes. + * + * Normally, a ResultRelInfo refers to a table that is in the query's range + * table; then ri_RangeTableIndex is the RT index and ri_RelationDesc is + * just a copy of the relevant es_relations[] entry. However, in some + * situations we create ResultRelInfos for relations that are not in the + * range table, namely for targets of tuple routing in a partitioned table, + * and when firing triggers in tables other than the target tables (See + * ExecGetTriggerResultRel). In these situations, ri_RangeTableIndex is 0 + * and ri_RelationDesc is a separately-opened relcache pointer that needs to + * be separately closed. + */ +typedef struct ResultRelInfo +{ + NodeTag type; + + /* result relation's range table index, or 0 if not in range table */ + Index ri_RangeTableIndex; + + /* relation descriptor for result relation */ + Relation ri_RelationDesc; + + /* # of indices existing on result relation */ + int ri_NumIndices; + + /* array of relation descriptors for indices */ + RelationPtr ri_IndexRelationDescs; + + /* array of key/attr info for indices */ + IndexInfo **ri_IndexRelationInfo; + + /* + * For UPDATE/DELETE result relations, the attribute number of the row + * identity junk attribute in the source plan's output tuples + */ + AttrNumber ri_RowIdAttNo; + + /* For UPDATE, attnums of generated columns to be computed */ + Bitmapset *ri_extraUpdatedCols; + + /* Projection to generate new tuple in an INSERT/UPDATE */ + ProjectionInfo *ri_projectNew; + /* Slot to hold that tuple */ + TupleTableSlot *ri_newTupleSlot; + /* Slot to hold the old tuple being updated */ + TupleTableSlot *ri_oldTupleSlot; + /* Have the projection and the slots above been initialized? */ + bool ri_projectNewInfoValid; + + /* updates do LockTuple() before oldtup read; see README.tuplock */ + bool ri_needLockTagTuple; + + /* triggers to be fired, if any */ + TriggerDesc *ri_TrigDesc; + + /* cached lookup info for trigger functions */ + FmgrInfo *ri_TrigFunctions; + + /* array of trigger WHEN expr states */ + ExprState **ri_TrigWhenExprs; + + /* optional runtime measurements for triggers */ + Instrumentation *ri_TrigInstrument; + + /* On-demand created slots for triggers / returning processing */ + TupleTableSlot *ri_ReturningSlot; /* for trigger output tuples */ + TupleTableSlot *ri_TrigOldSlot; /* for a trigger's old tuple */ + TupleTableSlot *ri_TrigNewSlot; /* for a trigger's new tuple */ + + /* FDW callback functions, if foreign table */ + struct FdwRoutine *ri_FdwRoutine; + + /* available to save private state of FDW */ + void *ri_FdwState; + + /* true when modifying foreign table directly */ + bool ri_usesFdwDirectModify; + + /* batch insert stuff */ + int ri_NumSlots; /* number of slots in the array */ + int ri_NumSlotsInitialized; /* number of initialized slots */ + int ri_BatchSize; /* max slots inserted in a single batch */ + TupleTableSlot **ri_Slots; /* input tuples for batch insert */ + TupleTableSlot **ri_PlanSlots; + + /* list of WithCheckOption's to be checked */ + List *ri_WithCheckOptions; + + /* list of WithCheckOption expr states */ + List *ri_WithCheckOptionExprs; + + /* array of constraint-checking expr states */ + ExprState **ri_ConstraintExprs; + + /* arrays of stored generated columns expr states, for INSERT and UPDATE */ + ExprState **ri_GeneratedExprsI; + ExprState **ri_GeneratedExprsU; + + /* number of stored generated columns we need to compute */ + int ri_NumGeneratedNeededI; + int ri_NumGeneratedNeededU; + + /* list of RETURNING expressions */ + List *ri_returningList; + + /* for computing a RETURNING list */ + ProjectionInfo *ri_projectReturning; + + /* list of arbiter indexes to use to check conflicts */ + List *ri_onConflictArbiterIndexes; + + /* ON CONFLICT evaluation state */ + OnConflictSetState *ri_onConflict; + + /* for MERGE, lists of MergeActionState */ + List *ri_matchedMergeAction; + List *ri_notMatchedMergeAction; + + /* partition check expression state (NULL if not set up yet) */ + ExprState *ri_PartitionCheckExpr; + + /* + * Map to convert child result relation tuples to the format of the table + * actually mentioned in the query (called "root"). Computed only if + * needed. A NULL map value indicates that no conversion is needed, so we + * must have a separate flag to show if the map has been computed. + */ + TupleConversionMap *ri_ChildToRootMap; + bool ri_ChildToRootMapValid; + + /* + * As above, but in the other direction. + */ + TupleConversionMap *ri_RootToChildMap; + bool ri_RootToChildMapValid; + + /* + * Other information needed by child result relations + * + * ri_RootResultRelInfo gives the target relation mentioned in the query. + * Used as the root for tuple routing and/or transition capture. + * + * ri_PartitionTupleSlot is non-NULL if the relation is a partition to + * route tuples into and ri_RootToChildMap conversion is needed. + */ + struct ResultRelInfo *ri_RootResultRelInfo; + TupleTableSlot *ri_PartitionTupleSlot; + + /* for use by copyfrom.c when performing multi-inserts */ + struct CopyMultiInsertBuffer *ri_CopyMultiInsertBuffer; + + /* + * Used when a leaf partition is involved in a cross-partition update of + * one of its ancestors; see ExecCrossPartitionUpdateForeignKey(). + */ + List *ri_ancestorResultRels; +} ResultRelInfo; + +/* ---------------- + * AsyncRequest + * + * State for an asynchronous tuple request. + * ---------------- + */ +typedef struct AsyncRequest +{ + struct PlanState *requestor; /* Node that wants a tuple */ + struct PlanState *requestee; /* Node from which a tuple is wanted */ + int request_index; /* Scratch space for requestor */ + bool callback_pending; /* Callback is needed */ + bool request_complete; /* Request complete, result valid */ + TupleTableSlot *result; /* Result (NULL or an empty slot if no more + * tuples) */ +} AsyncRequest; + +/* ---------------- + * EState information + * + * Working state for an Executor invocation + * ---------------- + */ +typedef struct EState +{ + NodeTag type; + + /* Basic state for all query types: */ + ScanDirection es_direction; /* current scan direction */ + Snapshot es_snapshot; /* time qual to use */ + Snapshot es_crosscheck_snapshot; /* crosscheck time qual for RI */ + List *es_range_table; /* List of RangeTblEntry */ + Index es_range_table_size; /* size of the range table arrays */ + Relation *es_relations; /* Array of per-range-table-entry Relation + * pointers, or NULL if not yet opened */ + struct ExecRowMark **es_rowmarks; /* Array of per-range-table-entry + * ExecRowMarks, or NULL if none */ + List *es_rteperminfos; /* List of RTEPermissionInfo */ + PlannedStmt *es_plannedstmt; /* link to top of plan tree */ + const char *es_sourceText; /* Source text from QueryDesc */ + + JunkFilter *es_junkFilter; /* top-level junk filter, if any */ + + /* If query can insert/delete tuples, the command ID to mark them with */ + CommandId es_output_cid; + + /* Info about target table(s) for insert/update/delete queries: */ + ResultRelInfo **es_result_relations; /* Array of per-range-table-entry + * ResultRelInfo pointers, or NULL + * if not a target table */ + List *es_opened_result_relations; /* List of non-NULL entries in + * es_result_relations in no + * specific order */ + + PartitionDirectory es_partition_directory; /* for PartitionDesc lookup */ + + /* + * The following list contains ResultRelInfos created by the tuple routing + * code for partitions that aren't found in the es_result_relations array. + */ + List *es_tuple_routing_result_relations; + + /* Stuff used for firing triggers: */ + List *es_trig_target_relations; /* trigger-only ResultRelInfos */ + + /* Parameter info: */ + ParamListInfo es_param_list_info; /* values of external params */ + ParamExecData *es_param_exec_vals; /* values of internal params */ + + QueryEnvironment *es_queryEnv; /* query environment */ + + /* Other working state: */ + MemoryContext es_query_cxt; /* per-query context in which EState lives */ + + List *es_tupleTable; /* List of TupleTableSlots */ + + uint64 es_processed; /* # of tuples processed during one + * ExecutorRun() call. */ + uint64 es_total_processed; /* total # of tuples aggregated across all + * ExecutorRun() calls. */ + + int es_top_eflags; /* eflags passed to ExecutorStart */ + int es_instrument; /* OR of InstrumentOption flags */ + bool es_finished; /* true when ExecutorFinish is done */ + + List *es_exprcontexts; /* List of ExprContexts within EState */ + + List *es_subplanstates; /* List of PlanState for SubPlans */ + + List *es_auxmodifytables; /* List of secondary ModifyTableStates */ + + /* + * this ExprContext is for per-output-tuple operations, such as constraint + * checks and index-value computations. It will be reset for each output + * tuple. Note that it will be created only if needed. + */ + ExprContext *es_per_tuple_exprcontext; + + /* + * If not NULL, this is an EPQState's EState. This is a field in EState + * both to allow EvalPlanQual aware executor nodes to detect that they + * need to perform EPQ related work, and to provide necessary information + * to do so. + */ + struct EPQState *es_epq_active; + + bool es_use_parallel_mode; /* can we use parallel workers? */ + + /* The per-query shared memory area to use for parallel execution. */ + struct dsa_area *es_query_dsa; + + /* + * JIT information. es_jit_flags indicates whether JIT should be performed + * and with which options. es_jit is created on-demand when JITing is + * performed. + * + * es_jit_worker_instr is the combined, on demand allocated, + * instrumentation from all workers. The leader's instrumentation is kept + * separate, and is combined on demand by ExplainPrintJITSummary(). + */ + int es_jit_flags; + struct JitContext *es_jit; + struct JitInstrumentation *es_jit_worker_instr; + + /* + * Lists of ResultRelInfos for foreign tables on which batch-inserts are + * to be executed and owning ModifyTableStates, stored in the same order. + */ + List *es_insert_pending_result_relations; + List *es_insert_pending_modifytables; +} EState; + + +/* + * ExecRowMark - + * runtime representation of FOR [KEY] UPDATE/SHARE clauses + * + * When doing UPDATE/DELETE/MERGE/SELECT FOR [KEY] UPDATE/SHARE, we will have + * an ExecRowMark for each non-target relation in the query (except inheritance + * parent RTEs, which can be ignored at runtime). Virtual relations such as + * subqueries-in-FROM will have an ExecRowMark with relation == NULL. See + * PlanRowMark for details about most of the fields. In addition to fields + * directly derived from PlanRowMark, we store an activity flag (to denote + * inactive children of inheritance trees), curCtid, which is used by the + * WHERE CURRENT OF code, and ermExtra, which is available for use by the plan + * node that sources the relation (e.g., for a foreign table the FDW can use + * ermExtra to hold information). + * + * EState->es_rowmarks is an array of these structs, indexed by RT index, + * with NULLs for irrelevant RT indexes. es_rowmarks itself is NULL if + * there are no rowmarks. + */ +typedef struct ExecRowMark +{ + Relation relation; /* opened and suitably locked relation */ + Oid relid; /* its OID (or InvalidOid, if subquery) */ + Index rti; /* its range table index */ + Index prti; /* parent range table index, if child */ + Index rowmarkId; /* unique identifier for resjunk columns */ + RowMarkType markType; /* see enum in nodes/plannodes.h */ + LockClauseStrength strength; /* LockingClause's strength, or LCS_NONE */ + LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED */ + bool ermActive; /* is this mark relevant for current tuple? */ + ItemPointerData curCtid; /* ctid of currently locked tuple, if any */ + void *ermExtra; /* available for use by relation source node */ +} ExecRowMark; + +/* + * ExecAuxRowMark - + * additional runtime representation of FOR [KEY] UPDATE/SHARE clauses + * + * Each LockRows and ModifyTable node keeps a list of the rowmarks it needs to + * deal with. In addition to a pointer to the related entry in es_rowmarks, + * this struct carries the column number(s) of the resjunk columns associated + * with the rowmark (see comments for PlanRowMark for more detail). + */ +typedef struct ExecAuxRowMark +{ + ExecRowMark *rowmark; /* related entry in es_rowmarks */ + AttrNumber ctidAttNo; /* resno of ctid junk attribute, if any */ + AttrNumber toidAttNo; /* resno of tableoid junk attribute, if any */ + AttrNumber wholeAttNo; /* resno of whole-row junk attribute, if any */ +} ExecAuxRowMark; + + +/* ---------------------------------------------------------------- + * Tuple Hash Tables + * + * All-in-memory tuple hash tables are used for a number of purposes. + * + * Note: tab_hash_funcs are for the key datatype(s) stored in the table, + * and tab_eq_funcs are non-cross-type equality operators for those types. + * Normally these are the only functions used, but FindTupleHashEntry() + * supports searching a hashtable using cross-data-type hashing. For that, + * the caller must supply hash functions for the LHS datatype as well as + * the cross-type equality operators to use. in_hash_funcs and cur_eq_func + * are set to point to the caller's function arrays while doing such a search. + * During LookupTupleHashEntry(), they point to tab_hash_funcs and + * tab_eq_func respectively. + * ---------------------------------------------------------------- + */ +typedef struct TupleHashEntryData *TupleHashEntry; +typedef struct TupleHashTableData *TupleHashTable; + +typedef struct TupleHashEntryData +{ + MinimalTuple firstTuple; /* copy of first tuple in this group */ + void *additional; /* user data */ + uint32 status; /* hash status */ + uint32 hash; /* hash value (cached) */ +} TupleHashEntryData; + +/* define parameters necessary to generate the tuple hash table interface */ +#define SH_PREFIX tuplehash +#define SH_ELEMENT_TYPE TupleHashEntryData +#define SH_KEY_TYPE MinimalTuple +#define SH_SCOPE extern +#define SH_DECLARE +#include "lib/simplehash.h" + +typedef struct TupleHashTableData +{ + tuplehash_hash *hashtab; /* underlying hash table */ + int numCols; /* number of columns in lookup key */ + AttrNumber *keyColIdx; /* attr numbers of key columns */ + FmgrInfo *tab_hash_funcs; /* hash functions for table datatype(s) */ + ExprState *tab_eq_func; /* comparator for table datatype(s) */ + Oid *tab_collations; /* collations for hash and comparison */ + MemoryContext tablecxt; /* memory context containing table */ + MemoryContext tempcxt; /* context for function evaluations */ + Size entrysize; /* actual size to make each hash entry */ + TupleTableSlot *tableslot; /* slot for referencing table entries */ + /* The following fields are set transiently for each table search: */ + TupleTableSlot *inputslot; /* current input tuple's slot */ + FmgrInfo *in_hash_funcs; /* hash functions for input datatype(s) */ + ExprState *cur_eq_func; /* comparator for input vs. table */ + uint32 hash_iv; /* hash-function IV */ + ExprContext *exprcontext; /* expression context */ +} TupleHashTableData; + +typedef tuplehash_iterator TupleHashIterator; + +/* + * Use InitTupleHashIterator/TermTupleHashIterator for a read/write scan. + * Use ResetTupleHashIterator if the table can be frozen (in this case no + * explicit scan termination is needed). + */ +#define InitTupleHashIterator(htable, iter) \ + tuplehash_start_iterate(htable->hashtab, iter) +#define TermTupleHashIterator(iter) \ + ((void) 0) +#define ResetTupleHashIterator(htable, iter) \ + InitTupleHashIterator(htable, iter) +#define ScanTupleHashTable(htable, iter) \ + tuplehash_iterate(htable->hashtab, iter) + + +/* ---------------------------------------------------------------- + * Expression State Nodes + * + * Formerly, there was a separate executor expression state node corresponding + * to each node in a planned expression tree. That's no longer the case; for + * common expression node types, all the execution info is embedded into + * step(s) in a single ExprState node. But we still have a few executor state + * node types for selected expression node types, mostly those in which info + * has to be shared with other parts of the execution state tree. + * ---------------------------------------------------------------- + */ + +/* ---------------- + * WindowFuncExprState node + * ---------------- + */ +typedef struct WindowFuncExprState +{ + NodeTag type; + WindowFunc *wfunc; /* expression plan node */ + List *args; /* ExprStates for argument expressions */ + ExprState *aggfilter; /* FILTER expression */ + int wfuncno; /* ID number for wfunc within its plan node */ +} WindowFuncExprState; + + +/* ---------------- + * SetExprState node + * + * State for evaluating a potentially set-returning expression (like FuncExpr + * or OpExpr). In some cases, like some of the expressions in ROWS FROM(...) + * the expression might not be a SRF, but nonetheless it uses the same + * machinery as SRFs; it will be treated as a SRF returning a single row. + * ---------------- + */ +typedef struct SetExprState +{ + NodeTag type; + Expr *expr; /* expression plan node */ + List *args; /* ExprStates for argument expressions */ + + /* + * In ROWS FROM, functions can be inlined, removing the FuncExpr normally + * inside. In such a case this is the compiled expression (which cannot + * return a set), which'll be evaluated using regular ExecEvalExpr(). + */ + ExprState *elidedFuncState; + + /* + * Function manager's lookup info for the target function. If func.fn_oid + * is InvalidOid, we haven't initialized it yet (nor any of the following + * fields, except funcReturnsSet). + */ + FmgrInfo func; + + /* + * For a set-returning function (SRF) that returns a tuplestore, we keep + * the tuplestore here and dole out the result rows one at a time. The + * slot holds the row currently being returned. + */ + Tuplestorestate *funcResultStore; + TupleTableSlot *funcResultSlot; + + /* + * In some cases we need to compute a tuple descriptor for the function's + * output. If so, it's stored here. + */ + TupleDesc funcResultDesc; + bool funcReturnsTuple; /* valid when funcResultDesc isn't NULL */ + + /* + * Remember whether the function is declared to return a set. This is set + * by ExecInitExpr, and is valid even before the FmgrInfo is set up. + */ + bool funcReturnsSet; + + /* + * setArgsValid is true when we are evaluating a set-returning function + * that uses value-per-call mode and we are in the middle of a call + * series; we want to pass the same argument values to the function again + * (and again, until it returns ExprEndResult). This indicates that + * fcinfo_data already contains valid argument data. + */ + bool setArgsValid; + + /* + * Flag to remember whether we have registered a shutdown callback for + * this SetExprState. We do so only if funcResultStore or setArgsValid + * has been set at least once (since all the callback is for is to release + * the tuplestore or clear setArgsValid). + */ + bool shutdown_reg; /* a shutdown callback is registered */ + + /* + * Call parameter structure for the function. This has been initialized + * (by InitFunctionCallInfoData) if func.fn_oid is valid. It also saves + * argument values between calls, when setArgsValid is true. + */ + FunctionCallInfo fcinfo; +} SetExprState; + +/* ---------------- + * SubPlanState node + * ---------------- + */ +typedef struct SubPlanState +{ + NodeTag type; + SubPlan *subplan; /* expression plan node */ + struct PlanState *planstate; /* subselect plan's state tree */ + struct PlanState *parent; /* parent plan node's state tree */ + ExprState *testexpr; /* state of combining expression */ + List *args; /* states of argument expression(s) */ + HeapTuple curTuple; /* copy of most recent tuple from subplan */ + Datum curArray; /* most recent array from ARRAY() subplan */ + /* these are used when hashing the subselect's output: */ + TupleDesc descRight; /* subselect desc after projection */ + ProjectionInfo *projLeft; /* for projecting lefthand exprs */ + ProjectionInfo *projRight; /* for projecting subselect output */ + TupleHashTable hashtable; /* hash table for no-nulls subselect rows */ + TupleHashTable hashnulls; /* hash table for rows with null(s) */ + bool havehashrows; /* true if hashtable is not empty */ + bool havenullrows; /* true if hashnulls is not empty */ + MemoryContext hashtablecxt; /* memory context containing hash tables */ + MemoryContext hashtempcxt; /* temp memory context for hash tables */ + ExprContext *innerecontext; /* econtext for computing inner tuples */ + int numCols; /* number of columns being hashed */ + /* each of the remaining fields is an array of length numCols: */ + AttrNumber *keyColIdx; /* control data for hash tables */ + Oid *tab_eq_funcoids; /* equality func oids for table + * datatype(s) */ + Oid *tab_collations; /* collations for hash and comparison */ + FmgrInfo *tab_hash_funcs; /* hash functions for table datatype(s) */ + FmgrInfo *tab_eq_funcs; /* equality functions for table datatype(s) */ + FmgrInfo *lhs_hash_funcs; /* hash functions for lefthand datatype(s) */ + FmgrInfo *cur_eq_funcs; /* equality functions for LHS vs. table */ + ExprState *cur_eq_comp; /* equality comparator for LHS vs. table */ +} SubPlanState; + +/* + * DomainConstraintState - one item to check during CoerceToDomain + * + * Note: we consider this to be part of an ExprState tree, so we give it + * a name following the xxxState convention. But there's no directly + * associated plan-tree node. + */ +typedef enum DomainConstraintType +{ + DOM_CONSTRAINT_NOTNULL, + DOM_CONSTRAINT_CHECK +} DomainConstraintType; + +typedef struct DomainConstraintState +{ + NodeTag type; + DomainConstraintType constrainttype; /* constraint type */ + char *name; /* name of constraint (for error msgs) */ + Expr *check_expr; /* for CHECK, a boolean expression */ + ExprState *check_exprstate; /* check_expr's eval state, or NULL */ +} DomainConstraintState; + + +/* ---------------------------------------------------------------- + * Executor State Trees + * + * An executing query has a PlanState tree paralleling the Plan tree + * that describes the plan. + * ---------------------------------------------------------------- + */ + +/* ---------------- + * ExecProcNodeMtd + * + * This is the method called by ExecProcNode to return the next tuple + * from an executor node. It returns NULL, or an empty TupleTableSlot, + * if no more tuples are available. + * ---------------- + */ +typedef TupleTableSlot *(*ExecProcNodeMtd) (struct PlanState *pstate); + +/* ---------------- + * PlanState node + * + * We never actually instantiate any PlanState nodes; this is just the common + * abstract superclass for all PlanState-type nodes. + * ---------------- + */ +typedef struct PlanState +{ + pg_node_attr(abstract) + + NodeTag type; + + Plan *plan; /* associated Plan node */ + + EState *state; /* at execution time, states of individual + * nodes point to one EState for the whole + * top-level plan */ + + ExecProcNodeMtd ExecProcNode; /* function to return next tuple */ + ExecProcNodeMtd ExecProcNodeReal; /* actual function, if above is a + * wrapper */ + + Instrumentation *instrument; /* Optional runtime stats for this node */ + WorkerInstrumentation *worker_instrument; /* per-worker instrumentation */ + + /* Per-worker JIT instrumentation */ + struct SharedJitInstrumentation *worker_jit_instrument; + + /* + * Common structural data for all Plan types. These links to subsidiary + * state trees parallel links in the associated plan tree (except for the + * subPlan list, which does not exist in the plan tree). + */ + ExprState *qual; /* boolean qual condition */ + struct PlanState *lefttree; /* input plan tree(s) */ + struct PlanState *righttree; + + List *initPlan; /* Init SubPlanState nodes (un-correlated expr + * subselects) */ + List *subPlan; /* SubPlanState nodes in my expressions */ + + /* + * State for management of parameter-change-driven rescanning + */ + Bitmapset *chgParam; /* set of IDs of changed Params */ + + /* + * Other run-time state needed by most if not all node types. + */ + TupleDesc ps_ResultTupleDesc; /* node's return type */ + TupleTableSlot *ps_ResultTupleSlot; /* slot for my result tuples */ + ExprContext *ps_ExprContext; /* node's expression-evaluation context */ + ProjectionInfo *ps_ProjInfo; /* info for doing tuple projection */ + + bool async_capable; /* true if node is async-capable */ + + /* + * Scanslot's descriptor if known. This is a bit of a hack, but otherwise + * it's hard for expression compilation to optimize based on the + * descriptor, without encoding knowledge about all executor nodes. + */ + TupleDesc scandesc; + + /* + * Define the slot types for inner, outer and scanslots for expression + * contexts with this state as a parent. If *opsset is set, then + * *opsfixed indicates whether *ops is guaranteed to be the type of slot + * used. That means that every slot in the corresponding + * ExprContext.ecxt_*tuple will point to a slot of that type, while + * evaluating the expression. If *opsfixed is false, but *ops is set, + * that indicates the most likely type of slot. + * + * The scan* fields are set by ExecInitScanTupleSlot(). If that's not + * called, nodes can initialize the fields themselves. + * + * If outer/inneropsset is false, the information is inferred on-demand + * using ExecGetResultSlotOps() on ->righttree/lefttree, using the + * corresponding node's resultops* fields. + * + * The result* fields are automatically set when ExecInitResultSlot is + * used (be it directly or when the slot is created by + * ExecAssignScanProjectionInfo() / + * ExecConditionalAssignProjectionInfo()). If no projection is necessary + * ExecConditionalAssignProjectionInfo() defaults those fields to the scan + * operations. + */ + const TupleTableSlotOps *scanops; + const TupleTableSlotOps *outerops; + const TupleTableSlotOps *innerops; + const TupleTableSlotOps *resultops; + bool scanopsfixed; + bool outeropsfixed; + bool inneropsfixed; + bool resultopsfixed; + bool scanopsset; + bool outeropsset; + bool inneropsset; + bool resultopsset; +} PlanState; + +/* ---------------- + * these are defined to avoid confusion problems with "left" + * and "right" and "inner" and "outer". The convention is that + * the "left" plan is the "outer" plan and the "right" plan is + * the inner plan, but these make the code more readable. + * ---------------- + */ +#define innerPlanState(node) (((PlanState *)(node))->righttree) +#define outerPlanState(node) (((PlanState *)(node))->lefttree) + +/* Macros for inline access to certain instrumentation counters */ +#define InstrCountTuples2(node, delta) \ + do { \ + if (((PlanState *)(node))->instrument) \ + ((PlanState *)(node))->instrument->ntuples2 += (delta); \ + } while (0) +#define InstrCountFiltered1(node, delta) \ + do { \ + if (((PlanState *)(node))->instrument) \ + ((PlanState *)(node))->instrument->nfiltered1 += (delta); \ + } while(0) +#define InstrCountFiltered2(node, delta) \ + do { \ + if (((PlanState *)(node))->instrument) \ + ((PlanState *)(node))->instrument->nfiltered2 += (delta); \ + } while(0) + +/* + * EPQState is state for executing an EvalPlanQual recheck on a candidate + * tuples e.g. in ModifyTable or LockRows. + * + * To execute EPQ a separate EState is created (stored in ->recheckestate), + * which shares some resources, like the rangetable, with the main query's + * EState (stored in ->parentestate). The (sub-)tree of the plan that needs to + * be rechecked (in ->plan), is separately initialized (into + * ->recheckplanstate), but shares plan nodes with the corresponding nodes in + * the main query. The scan nodes in that separate executor tree are changed + * to return only the current tuple of interest for the respective + * table. Those tuples are either provided by the caller (using + * EvalPlanQualSlot), and/or found using the rowmark mechanism (non-locking + * rowmarks by the EPQ machinery itself, locking ones by the caller). + * + * While the plan to be checked may be changed using EvalPlanQualSetPlan(), + * all such plans need to share the same EState. + */ +typedef struct EPQState +{ + /* These are initialized by EvalPlanQualInit() and do not change later: */ + EState *parentestate; /* main query's EState */ + int epqParam; /* ID of Param to force scan node re-eval */ + List *resultRelations; /* integer list of RT indexes, or NIL */ + + /* + * relsubs_slot[scanrelid - 1] holds the EPQ test tuple to be returned by + * the scan node for the scanrelid'th RT index, in place of performing an + * actual table scan. Callers should use EvalPlanQualSlot() to fetch + * these slots. + */ + List *tuple_table; /* tuple table for relsubs_slot */ + TupleTableSlot **relsubs_slot; + + /* + * Initialized by EvalPlanQualInit(), may be changed later with + * EvalPlanQualSetPlan(): + */ + + Plan *plan; /* plan tree to be executed */ + List *arowMarks; /* ExecAuxRowMarks (non-locking only) */ + + + /* + * The original output tuple to be rechecked. Set by + * EvalPlanQualSetSlot(), before EvalPlanQualNext() or EvalPlanQual() may + * be called. + */ + TupleTableSlot *origslot; + + + /* Initialized or reset by EvalPlanQualBegin(): */ + + EState *recheckestate; /* EState for EPQ execution, see above */ + + /* + * Rowmarks that can be fetched on-demand using + * EvalPlanQualFetchRowMark(), indexed by scanrelid - 1. Only non-locking + * rowmarks. + */ + ExecAuxRowMark **relsubs_rowmark; + + /* + * relsubs_done[scanrelid - 1] is true if there is no EPQ tuple for this + * target relation or it has already been fetched in the current scan of + * this target relation within the current EvalPlanQual test. + */ + bool *relsubs_done; + + /* + * relsubs_blocked[scanrelid - 1] is true if there is no EPQ tuple for + * this target relation during the current EvalPlanQual test. We keep + * these flags set for all relids listed in resultRelations, but + * transiently clear the one for the relation whose tuple is actually + * passed to EvalPlanQual(). + */ + bool *relsubs_blocked; + + PlanState *recheckplanstate; /* EPQ specific exec nodes, for ->plan */ +} EPQState; + + +/* ---------------- + * ResultState information + * ---------------- + */ +typedef struct ResultState +{ + PlanState ps; /* its first field is NodeTag */ + ExprState *resconstantqual; + bool rs_done; /* are we done? */ + bool rs_checkqual; /* do we need to check the qual? */ +} ResultState; + +/* ---------------- + * ProjectSetState information + * + * Note: at least one of the "elems" will be a SetExprState; the rest are + * regular ExprStates. + * ---------------- + */ +typedef struct ProjectSetState +{ + PlanState ps; /* its first field is NodeTag */ + Node **elems; /* array of expression states */ + ExprDoneCond *elemdone; /* array of per-SRF is-done states */ + int nelems; /* length of elemdone[] array */ + bool pending_srf_tuples; /* still evaluating srfs in tlist? */ + MemoryContext argcontext; /* context for SRF arguments */ +} ProjectSetState; + + +/* flags for mt_merge_subcommands */ +#define MERGE_INSERT 0x01 +#define MERGE_UPDATE 0x02 +#define MERGE_DELETE 0x04 + +/* ---------------- + * ModifyTableState information + * ---------------- + */ +typedef struct ModifyTableState +{ + PlanState ps; /* its first field is NodeTag */ + CmdType operation; /* INSERT, UPDATE, DELETE, or MERGE */ + bool canSetTag; /* do we set the command tag/es_processed? */ + bool mt_done; /* are we done? */ + int mt_nrels; /* number of entries in resultRelInfo[] */ + ResultRelInfo *resultRelInfo; /* info about target relation(s) */ + + /* + * Target relation mentioned in the original statement, used to fire + * statement-level triggers and as the root for tuple routing. (This + * might point to one of the resultRelInfo[] entries, but it can also be a + * distinct struct.) + */ + ResultRelInfo *rootResultRelInfo; + + EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */ + bool fireBSTriggers; /* do we need to fire stmt triggers? */ + + /* + * These fields are used for inherited UPDATE and DELETE, to track which + * target relation a given tuple is from. If there are a lot of target + * relations, we use a hash table to translate table OIDs to + * resultRelInfo[] indexes; otherwise mt_resultOidHash is NULL. + */ + int mt_resultOidAttno; /* resno of "tableoid" junk attr */ + Oid mt_lastResultOid; /* last-seen value of tableoid */ + int mt_lastResultIndex; /* corresponding index in resultRelInfo[] */ + HTAB *mt_resultOidHash; /* optional hash table to speed lookups */ + + /* + * Slot for storing tuples in the root partitioned table's rowtype during + * an UPDATE of a partitioned table. + */ + TupleTableSlot *mt_root_tuple_slot; + + /* Tuple-routing support info */ + struct PartitionTupleRouting *mt_partition_tuple_routing; + + /* controls transition table population for specified operation */ + struct TransitionCaptureState *mt_transition_capture; + + /* controls transition table population for INSERT...ON CONFLICT UPDATE */ + struct TransitionCaptureState *mt_oc_transition_capture; + + /* Flags showing which subcommands are present INS/UPD/DEL/DO NOTHING */ + int mt_merge_subcommands; + + /* tuple counters for MERGE */ + double mt_merge_inserted; + double mt_merge_updated; + double mt_merge_deleted; +} ModifyTableState; + +/* ---------------- + * AppendState information + * + * nplans how many plans are in the array + * whichplan which synchronous plan is being executed (0 .. n-1) + * or a special negative value. See nodeAppend.c. + * prune_state details required to allow partitions to be + * eliminated from the scan, or NULL if not possible. + * valid_subplans for runtime pruning, valid synchronous appendplans + * indexes to scan. + * ---------------- + */ + +struct AppendState; +typedef struct AppendState AppendState; +struct ParallelAppendState; +typedef struct ParallelAppendState ParallelAppendState; +struct PartitionPruneState; + +struct AppendState +{ + PlanState ps; /* its first field is NodeTag */ + PlanState **appendplans; /* array of PlanStates for my inputs */ + int as_nplans; + int as_whichplan; + bool as_begun; /* false means need to initialize */ + Bitmapset *as_asyncplans; /* asynchronous plans indexes */ + int as_nasyncplans; /* # of asynchronous plans */ + AsyncRequest **as_asyncrequests; /* array of AsyncRequests */ + TupleTableSlot **as_asyncresults; /* unreturned results of async plans */ + int as_nasyncresults; /* # of valid entries in as_asyncresults */ + bool as_syncdone; /* true if all synchronous plans done in + * asynchronous mode, else false */ + int as_nasyncremain; /* # of remaining asynchronous plans */ + Bitmapset *as_needrequest; /* asynchronous plans needing a new request */ + struct WaitEventSet *as_eventset; /* WaitEventSet used to configure file + * descriptor wait events */ + int as_first_partial_plan; /* Index of 'appendplans' containing + * the first partial plan */ + ParallelAppendState *as_pstate; /* parallel coordination info */ + Size pstate_len; /* size of parallel coordination info */ + struct PartitionPruneState *as_prune_state; + bool as_valid_subplans_identified; /* is as_valid_subplans valid? */ + Bitmapset *as_valid_subplans; + Bitmapset *as_valid_asyncplans; /* valid asynchronous plans indexes */ + bool (*choose_next_subplan) (AppendState *); +}; + +/* ---------------- + * MergeAppendState information + * + * nplans how many plans are in the array + * nkeys number of sort key columns + * sortkeys sort keys in SortSupport representation + * slots current output tuple of each subplan + * heap heap of active tuples + * initialized true if we have fetched first tuple from each subplan + * prune_state details required to allow partitions to be + * eliminated from the scan, or NULL if not possible. + * valid_subplans for runtime pruning, valid mergeplans indexes to + * scan. + * ---------------- + */ +typedef struct MergeAppendState +{ + PlanState ps; /* its first field is NodeTag */ + PlanState **mergeplans; /* array of PlanStates for my inputs */ + int ms_nplans; + int ms_nkeys; + SortSupport ms_sortkeys; /* array of length ms_nkeys */ + TupleTableSlot **ms_slots; /* array of length ms_nplans */ + struct binaryheap *ms_heap; /* binary heap of slot indices */ + bool ms_initialized; /* are subplans started? */ + struct PartitionPruneState *ms_prune_state; + Bitmapset *ms_valid_subplans; +} MergeAppendState; + +/* ---------------- + * RecursiveUnionState information + * + * RecursiveUnionState is used for performing a recursive union. + * + * recursing T when we're done scanning the non-recursive term + * intermediate_empty T if intermediate_table is currently empty + * working_table working table (to be scanned by recursive term) + * intermediate_table current recursive output (next generation of WT) + * ---------------- + */ +typedef struct RecursiveUnionState +{ + PlanState ps; /* its first field is NodeTag */ + bool recursing; + bool intermediate_empty; + Tuplestorestate *working_table; + Tuplestorestate *intermediate_table; + /* Remaining fields are unused in UNION ALL case */ + Oid *eqfuncoids; /* per-grouping-field equality fns */ + FmgrInfo *hashfunctions; /* per-grouping-field hash fns */ + MemoryContext tempContext; /* short-term context for comparisons */ + TupleHashTable hashtable; /* hash table for tuples already seen */ + MemoryContext tableContext; /* memory context containing hash table */ +} RecursiveUnionState; + +/* ---------------- + * BitmapAndState information + * ---------------- + */ +typedef struct BitmapAndState +{ + PlanState ps; /* its first field is NodeTag */ + PlanState **bitmapplans; /* array of PlanStates for my inputs */ + int nplans; /* number of input plans */ +} BitmapAndState; + +/* ---------------- + * BitmapOrState information + * ---------------- + */ +typedef struct BitmapOrState +{ + PlanState ps; /* its first field is NodeTag */ + PlanState **bitmapplans; /* array of PlanStates for my inputs */ + int nplans; /* number of input plans */ +} BitmapOrState; + +/* ---------------------------------------------------------------- + * Scan State Information + * ---------------------------------------------------------------- + */ + +/* ---------------- + * ScanState information + * + * ScanState extends PlanState for node types that represent + * scans of an underlying relation. It can also be used for nodes + * that scan the output of an underlying plan node --- in that case, + * only ScanTupleSlot is actually useful, and it refers to the tuple + * retrieved from the subplan. + * + * currentRelation relation being scanned (NULL if none) + * currentScanDesc current scan descriptor for scan (NULL if none) + * ScanTupleSlot pointer to slot in tuple table holding scan tuple + * ---------------- + */ +typedef struct ScanState +{ + PlanState ps; /* its first field is NodeTag */ + Relation ss_currentRelation; + struct TableScanDescData *ss_currentScanDesc; + TupleTableSlot *ss_ScanTupleSlot; +} ScanState; + +/* ---------------- + * SeqScanState information + * ---------------- + */ +typedef struct SeqScanState +{ + ScanState ss; /* its first field is NodeTag */ + Size pscan_len; /* size of parallel heap scan descriptor */ +} SeqScanState; + +/* ---------------- + * SampleScanState information + * ---------------- + */ +typedef struct SampleScanState +{ + ScanState ss; + List *args; /* expr states for TABLESAMPLE params */ + ExprState *repeatable; /* expr state for REPEATABLE expr */ + /* use struct pointer to avoid including tsmapi.h here */ + struct TsmRoutine *tsmroutine; /* descriptor for tablesample method */ + void *tsm_state; /* tablesample method can keep state here */ + bool use_bulkread; /* use bulkread buffer access strategy? */ + bool use_pagemode; /* use page-at-a-time visibility checking? */ + bool begun; /* false means need to call BeginSampleScan */ + uint32 seed; /* random seed */ + int64 donetuples; /* number of tuples already returned */ + bool haveblock; /* has a block for sampling been determined */ + bool done; /* exhausted all tuples? */ +} SampleScanState; + +/* + * These structs store information about index quals that don't have simple + * constant right-hand sides. See comments for ExecIndexBuildScanKeys() + * for discussion. + */ +typedef struct +{ + struct ScanKeyData *scan_key; /* scankey to put value into */ + ExprState *key_expr; /* expr to evaluate to get value */ + bool key_toastable; /* is expr's result a toastable datatype? */ +} IndexRuntimeKeyInfo; + +typedef struct +{ + struct ScanKeyData *scan_key; /* scankey to put value into */ + ExprState *array_expr; /* expr to evaluate to get array value */ + int next_elem; /* next array element to use */ + int num_elems; /* number of elems in current array value */ + Datum *elem_values; /* array of num_elems Datums */ + bool *elem_nulls; /* array of num_elems is-null flags */ +} IndexArrayKeyInfo; + +/* ---------------- + * IndexScanState information + * + * indexqualorig execution state for indexqualorig expressions + * indexorderbyorig execution state for indexorderbyorig expressions + * ScanKeys Skey structures for index quals + * NumScanKeys number of ScanKeys + * OrderByKeys Skey structures for index ordering operators + * NumOrderByKeys number of OrderByKeys + * RuntimeKeys info about Skeys that must be evaluated at runtime + * NumRuntimeKeys number of RuntimeKeys + * RuntimeKeysReady true if runtime Skeys have been computed + * RuntimeContext expr context for evaling runtime Skeys + * RelationDesc index relation descriptor + * ScanDesc index scan descriptor + * + * ReorderQueue tuples that need reordering due to re-check + * ReachedEnd have we fetched all tuples from index already? + * OrderByValues values of ORDER BY exprs of last fetched tuple + * OrderByNulls null flags for OrderByValues + * SortSupport for reordering ORDER BY exprs + * OrderByTypByVals is the datatype of order by expression pass-by-value? + * OrderByTypLens typlens of the datatypes of order by expressions + * PscanLen size of parallel index scan descriptor + * ---------------- + */ +typedef struct IndexScanState +{ + ScanState ss; /* its first field is NodeTag */ + ExprState *indexqualorig; + List *indexorderbyorig; + struct ScanKeyData *iss_ScanKeys; + int iss_NumScanKeys; + struct ScanKeyData *iss_OrderByKeys; + int iss_NumOrderByKeys; + IndexRuntimeKeyInfo *iss_RuntimeKeys; + int iss_NumRuntimeKeys; + bool iss_RuntimeKeysReady; + ExprContext *iss_RuntimeContext; + Relation iss_RelationDesc; + struct IndexScanDescData *iss_ScanDesc; + + /* These are needed for re-checking ORDER BY expr ordering */ + pairingheap *iss_ReorderQueue; + bool iss_ReachedEnd; + Datum *iss_OrderByValues; + bool *iss_OrderByNulls; + SortSupport iss_SortSupport; + bool *iss_OrderByTypByVals; + int16 *iss_OrderByTypLens; + Size iss_PscanLen; +} IndexScanState; + +/* ---------------- + * IndexOnlyScanState information + * + * recheckqual execution state for recheckqual expressions + * ScanKeys Skey structures for index quals + * NumScanKeys number of ScanKeys + * OrderByKeys Skey structures for index ordering operators + * NumOrderByKeys number of OrderByKeys + * RuntimeKeys info about Skeys that must be evaluated at runtime + * NumRuntimeKeys number of RuntimeKeys + * RuntimeKeysReady true if runtime Skeys have been computed + * RuntimeContext expr context for evaling runtime Skeys + * RelationDesc index relation descriptor + * ScanDesc index scan descriptor + * TableSlot slot for holding tuples fetched from the table + * VMBuffer buffer in use for visibility map testing, if any + * PscanLen size of parallel index-only scan descriptor + * NameCStringAttNums attnums of name typed columns to pad to NAMEDATALEN + * NameCStringCount number of elements in the NameCStringAttNums array + * ---------------- + */ +typedef struct IndexOnlyScanState +{ + ScanState ss; /* its first field is NodeTag */ + ExprState *recheckqual; + struct ScanKeyData *ioss_ScanKeys; + int ioss_NumScanKeys; + struct ScanKeyData *ioss_OrderByKeys; + int ioss_NumOrderByKeys; + IndexRuntimeKeyInfo *ioss_RuntimeKeys; + int ioss_NumRuntimeKeys; + bool ioss_RuntimeKeysReady; + ExprContext *ioss_RuntimeContext; + Relation ioss_RelationDesc; + struct IndexScanDescData *ioss_ScanDesc; + TupleTableSlot *ioss_TableSlot; + Buffer ioss_VMBuffer; + Size ioss_PscanLen; + AttrNumber *ioss_NameCStringAttNums; + int ioss_NameCStringCount; +} IndexOnlyScanState; + +/* ---------------- + * BitmapIndexScanState information + * + * result bitmap to return output into, or NULL + * ScanKeys Skey structures for index quals + * NumScanKeys number of ScanKeys + * RuntimeKeys info about Skeys that must be evaluated at runtime + * NumRuntimeKeys number of RuntimeKeys + * ArrayKeys info about Skeys that come from ScalarArrayOpExprs + * NumArrayKeys number of ArrayKeys + * RuntimeKeysReady true if runtime Skeys have been computed + * RuntimeContext expr context for evaling runtime Skeys + * RelationDesc index relation descriptor + * ScanDesc index scan descriptor + * ---------------- + */ +typedef struct BitmapIndexScanState +{ + ScanState ss; /* its first field is NodeTag */ + TIDBitmap *biss_result; + struct ScanKeyData *biss_ScanKeys; + int biss_NumScanKeys; + IndexRuntimeKeyInfo *biss_RuntimeKeys; + int biss_NumRuntimeKeys; + IndexArrayKeyInfo *biss_ArrayKeys; + int biss_NumArrayKeys; + bool biss_RuntimeKeysReady; + ExprContext *biss_RuntimeContext; + Relation biss_RelationDesc; + struct IndexScanDescData *biss_ScanDesc; +} BitmapIndexScanState; + +/* ---------------- + * SharedBitmapState information + * + * BM_INITIAL TIDBitmap creation is not yet started, so first worker + * to see this state will set the state to BM_INPROGRESS + * and that process will be responsible for creating + * TIDBitmap. + * BM_INPROGRESS TIDBitmap creation is in progress; workers need to + * sleep until it's finished. + * BM_FINISHED TIDBitmap creation is done, so now all workers can + * proceed to iterate over TIDBitmap. + * ---------------- + */ +typedef enum +{ + BM_INITIAL, + BM_INPROGRESS, + BM_FINISHED +} SharedBitmapState; + +/* ---------------- + * ParallelBitmapHeapState information + * tbmiterator iterator for scanning current pages + * prefetch_iterator iterator for prefetching ahead of current page + * mutex mutual exclusion for the prefetching variable + * and state + * prefetch_pages # pages prefetch iterator is ahead of current + * prefetch_target current target prefetch distance + * state current state of the TIDBitmap + * cv conditional wait variable + * phs_snapshot_data snapshot data shared to workers + * ---------------- + */ +typedef struct ParallelBitmapHeapState +{ + dsa_pointer tbmiterator; + dsa_pointer prefetch_iterator; + slock_t mutex; + int prefetch_pages; + int prefetch_target; + SharedBitmapState state; + ConditionVariable cv; + char phs_snapshot_data[FLEXIBLE_ARRAY_MEMBER]; +} ParallelBitmapHeapState; + +/* ---------------- + * BitmapHeapScanState information + * + * bitmapqualorig execution state for bitmapqualorig expressions + * tbm bitmap obtained from child index scan(s) + * tbmiterator iterator for scanning current pages + * tbmres current-page data + * can_skip_fetch can we potentially skip tuple fetches in this scan? + * return_empty_tuples number of empty tuples to return + * vmbuffer buffer for visibility-map lookups + * pvmbuffer ditto, for prefetched pages + * exact_pages total number of exact pages retrieved + * lossy_pages total number of lossy pages retrieved + * prefetch_iterator iterator for prefetching ahead of current page + * prefetch_pages # pages prefetch iterator is ahead of current + * prefetch_target current target prefetch distance + * prefetch_maximum maximum value for prefetch_target + * pscan_len size of the shared memory for parallel bitmap + * initialized is node is ready to iterate + * shared_tbmiterator shared iterator + * shared_prefetch_iterator shared iterator for prefetching + * pstate shared state for parallel bitmap scan + * ---------------- + */ +typedef struct BitmapHeapScanState +{ + ScanState ss; /* its first field is NodeTag */ + ExprState *bitmapqualorig; + TIDBitmap *tbm; + TBMIterator *tbmiterator; + TBMIterateResult *tbmres; + bool can_skip_fetch; + int return_empty_tuples; + Buffer vmbuffer; + Buffer pvmbuffer; + long exact_pages; + long lossy_pages; + TBMIterator *prefetch_iterator; + int prefetch_pages; + int prefetch_target; + int prefetch_maximum; + Size pscan_len; + bool initialized; + TBMSharedIterator *shared_tbmiterator; + TBMSharedIterator *shared_prefetch_iterator; + ParallelBitmapHeapState *pstate; +} BitmapHeapScanState; + +/* ---------------- + * TidScanState information + * + * tidexprs list of TidExpr structs (see nodeTidscan.c) + * isCurrentOf scan has a CurrentOfExpr qual + * NumTids number of tids in this scan + * TidPtr index of currently fetched tid + * TidList evaluated item pointers (array of size NumTids) + * htup currently-fetched tuple, if any + * ---------------- + */ +typedef struct TidScanState +{ + ScanState ss; /* its first field is NodeTag */ + List *tss_tidexprs; + bool tss_isCurrentOf; + int tss_NumTids; + int tss_TidPtr; + ItemPointerData *tss_TidList; + HeapTupleData tss_htup; +} TidScanState; + +/* ---------------- + * TidRangeScanState information + * + * trss_tidexprs list of TidOpExpr structs (see nodeTidrangescan.c) + * trss_mintid the lowest TID in the scan range + * trss_maxtid the highest TID in the scan range + * trss_inScan is a scan currently in progress? + * ---------------- + */ +typedef struct TidRangeScanState +{ + ScanState ss; /* its first field is NodeTag */ + List *trss_tidexprs; + ItemPointerData trss_mintid; + ItemPointerData trss_maxtid; + bool trss_inScan; +} TidRangeScanState; + +/* ---------------- + * SubqueryScanState information + * + * SubqueryScanState is used for scanning a sub-query in the range table. + * ScanTupleSlot references the current output tuple of the sub-query. + * ---------------- + */ +typedef struct SubqueryScanState +{ + ScanState ss; /* its first field is NodeTag */ + PlanState *subplan; +} SubqueryScanState; + +/* ---------------- + * FunctionScanState information + * + * Function nodes are used to scan the results of a + * function appearing in FROM (typically a function returning set). + * + * eflags node's capability flags + * ordinality is this scan WITH ORDINALITY? + * simple true if we have 1 function and no ordinality + * ordinal current ordinal column value + * nfuncs number of functions being executed + * funcstates per-function execution states (private in + * nodeFunctionscan.c) + * argcontext memory context to evaluate function arguments in + * ---------------- + */ +struct FunctionScanPerFuncState; + +typedef struct FunctionScanState +{ + ScanState ss; /* its first field is NodeTag */ + int eflags; + bool ordinality; + bool simple; + int64 ordinal; + int nfuncs; + struct FunctionScanPerFuncState *funcstates; /* array of length nfuncs */ + MemoryContext argcontext; +} FunctionScanState; + +/* ---------------- + * ValuesScanState information + * + * ValuesScan nodes are used to scan the results of a VALUES list + * + * rowcontext per-expression-list context + * exprlists array of expression lists being evaluated + * exprstatelists array of expression state lists, for SubPlans only + * array_len size of above arrays + * curr_idx current array index (0-based) + * + * Note: ss.ps.ps_ExprContext is used to evaluate any qual or projection + * expressions attached to the node. We create a second ExprContext, + * rowcontext, in which to build the executor expression state for each + * Values sublist. Resetting this context lets us get rid of expression + * state for each row, avoiding major memory leakage over a long values list. + * However, that doesn't work for sublists containing SubPlans, because a + * SubPlan has to be connected up to the outer plan tree to work properly. + * Therefore, for only those sublists containing SubPlans, we do expression + * state construction at executor start, and store those pointers in + * exprstatelists[]. NULL entries in that array correspond to simple + * subexpressions that are handled as described above. + * ---------------- + */ +typedef struct ValuesScanState +{ + ScanState ss; /* its first field is NodeTag */ + ExprContext *rowcontext; + List **exprlists; + List **exprstatelists; + int array_len; + int curr_idx; +} ValuesScanState; + +/* ---------------- + * TableFuncScanState node + * + * Used in table-expression functions like XMLTABLE. + * ---------------- + */ +typedef struct TableFuncScanState +{ + ScanState ss; /* its first field is NodeTag */ + ExprState *docexpr; /* state for document expression */ + ExprState *rowexpr; /* state for row-generating expression */ + List *colexprs; /* state for column-generating expression */ + List *coldefexprs; /* state for column default expressions */ + List *ns_names; /* same as TableFunc.ns_names */ + List *ns_uris; /* list of states of namespace URI exprs */ + Bitmapset *notnulls; /* nullability flag for each output column */ + void *opaque; /* table builder private space */ + const struct TableFuncRoutine *routine; /* table builder methods */ + FmgrInfo *in_functions; /* input function for each column */ + Oid *typioparams; /* typioparam for each column */ + int64 ordinal; /* row number to be output next */ + MemoryContext perTableCxt; /* per-table context */ + Tuplestorestate *tupstore; /* output tuple store */ +} TableFuncScanState; + +/* ---------------- + * CteScanState information + * + * CteScan nodes are used to scan a CommonTableExpr query. + * + * Multiple CteScan nodes can read out from the same CTE query. We use + * a tuplestore to hold rows that have been read from the CTE query but + * not yet consumed by all readers. + * ---------------- + */ +typedef struct CteScanState +{ + ScanState ss; /* its first field is NodeTag */ + int eflags; /* capability flags to pass to tuplestore */ + int readptr; /* index of my tuplestore read pointer */ + PlanState *cteplanstate; /* PlanState for the CTE query itself */ + /* Link to the "leader" CteScanState (possibly this same node) */ + struct CteScanState *leader; + /* The remaining fields are only valid in the "leader" CteScanState */ + Tuplestorestate *cte_table; /* rows already read from the CTE query */ + bool eof_cte; /* reached end of CTE query? */ +} CteScanState; + +/* ---------------- + * NamedTuplestoreScanState information + * + * NamedTuplestoreScan nodes are used to scan a Tuplestore created and + * named prior to execution of the query. An example is a transition + * table for an AFTER trigger. + * + * Multiple NamedTuplestoreScan nodes can read out from the same Tuplestore. + * ---------------- + */ +typedef struct NamedTuplestoreScanState +{ + ScanState ss; /* its first field is NodeTag */ + int readptr; /* index of my tuplestore read pointer */ + TupleDesc tupdesc; /* format of the tuples in the tuplestore */ + Tuplestorestate *relation; /* the rows */ +} NamedTuplestoreScanState; + +/* ---------------- + * WorkTableScanState information + * + * WorkTableScan nodes are used to scan the work table created by + * a RecursiveUnion node. We locate the RecursiveUnion node + * during executor startup. + * ---------------- + */ +typedef struct WorkTableScanState +{ + ScanState ss; /* its first field is NodeTag */ + RecursiveUnionState *rustate; +} WorkTableScanState; + +/* ---------------- + * ForeignScanState information + * + * ForeignScan nodes are used to scan foreign-data tables. + * ---------------- + */ +typedef struct ForeignScanState +{ + ScanState ss; /* its first field is NodeTag */ + ExprState *fdw_recheck_quals; /* original quals not in ss.ps.qual */ + Size pscan_len; /* size of parallel coordination information */ + ResultRelInfo *resultRelInfo; /* result rel info, if UPDATE or DELETE */ + /* use struct pointer to avoid including fdwapi.h here */ + struct FdwRoutine *fdwroutine; + void *fdw_state; /* foreign-data wrapper can keep state here */ +} ForeignScanState; + +/* ---------------- + * CustomScanState information + * + * CustomScan nodes are used to execute custom code within executor. + * + * Core code must avoid assuming that the CustomScanState is only as large as + * the structure declared here; providers are allowed to make it the first + * element in a larger structure, and typically would need to do so. The + * struct is actually allocated by the CreateCustomScanState method associated + * with the plan node. Any additional fields can be initialized there, or in + * the BeginCustomScan method. + * ---------------- + */ +struct CustomExecMethods; + +typedef struct CustomScanState +{ + ScanState ss; + uint32 flags; /* mask of CUSTOMPATH_* flags, see + * nodes/extensible.h */ + List *custom_ps; /* list of child PlanState nodes, if any */ + Size pscan_len; /* size of parallel coordination information */ + const struct CustomExecMethods *methods; + const struct TupleTableSlotOps *slotOps; +} CustomScanState; + +/* ---------------------------------------------------------------- + * Join State Information + * ---------------------------------------------------------------- + */ + +/* ---------------- + * JoinState information + * + * Superclass for state nodes of join plans. + * ---------------- + */ +typedef struct JoinState +{ + PlanState ps; + JoinType jointype; + bool single_match; /* True if we should skip to next outer tuple + * after finding one inner match */ + ExprState *joinqual; /* JOIN quals (in addition to ps.qual) */ +} JoinState; + +/* ---------------- + * NestLoopState information + * + * NeedNewOuter true if need new outer tuple on next call + * MatchedOuter true if found a join match for current outer tuple + * NullInnerTupleSlot prepared null tuple for left outer joins + * ---------------- + */ +typedef struct NestLoopState +{ + JoinState js; /* its first field is NodeTag */ + bool nl_NeedNewOuter; + bool nl_MatchedOuter; + TupleTableSlot *nl_NullInnerTupleSlot; +} NestLoopState; + +/* ---------------- + * MergeJoinState information + * + * NumClauses number of mergejoinable join clauses + * Clauses info for each mergejoinable clause + * JoinState current state of ExecMergeJoin state machine + * SkipMarkRestore true if we may skip Mark and Restore operations + * ExtraMarks true to issue extra Mark operations on inner scan + * ConstFalseJoin true if we have a constant-false joinqual + * FillOuter true if should emit unjoined outer tuples anyway + * FillInner true if should emit unjoined inner tuples anyway + * MatchedOuter true if found a join match for current outer tuple + * MatchedInner true if found a join match for current inner tuple + * OuterTupleSlot slot in tuple table for cur outer tuple + * InnerTupleSlot slot in tuple table for cur inner tuple + * MarkedTupleSlot slot in tuple table for marked tuple + * NullOuterTupleSlot prepared null tuple for right outer joins + * NullInnerTupleSlot prepared null tuple for left outer joins + * OuterEContext workspace for computing outer tuple's join values + * InnerEContext workspace for computing inner tuple's join values + * ---------------- + */ +/* private in nodeMergejoin.c: */ +typedef struct MergeJoinClauseData *MergeJoinClause; + +typedef struct MergeJoinState +{ + JoinState js; /* its first field is NodeTag */ + int mj_NumClauses; + MergeJoinClause mj_Clauses; /* array of length mj_NumClauses */ + int mj_JoinState; + bool mj_SkipMarkRestore; + bool mj_ExtraMarks; + bool mj_ConstFalseJoin; + bool mj_FillOuter; + bool mj_FillInner; + bool mj_MatchedOuter; + bool mj_MatchedInner; + TupleTableSlot *mj_OuterTupleSlot; + TupleTableSlot *mj_InnerTupleSlot; + TupleTableSlot *mj_MarkedTupleSlot; + TupleTableSlot *mj_NullOuterTupleSlot; + TupleTableSlot *mj_NullInnerTupleSlot; + ExprContext *mj_OuterEContext; + ExprContext *mj_InnerEContext; +} MergeJoinState; + +/* ---------------- + * HashJoinState information + * + * hashclauses original form of the hashjoin condition + * hj_OuterHashKeys the outer hash keys in the hashjoin condition + * hj_HashOperators the join operators in the hashjoin condition + * hj_HashTable hash table for the hashjoin + * (NULL if table not built yet) + * hj_CurHashValue hash value for current outer tuple + * hj_CurBucketNo regular bucket# for current outer tuple + * hj_CurSkewBucketNo skew bucket# for current outer tuple + * hj_CurTuple last inner tuple matched to current outer + * tuple, or NULL if starting search + * (hj_CurXXX variables are undefined if + * OuterTupleSlot is empty!) + * hj_OuterTupleSlot tuple slot for outer tuples + * hj_HashTupleSlot tuple slot for inner (hashed) tuples + * hj_NullOuterTupleSlot prepared null tuple for right/right-anti/full + * outer joins + * hj_NullInnerTupleSlot prepared null tuple for left/full outer joins + * hj_FirstOuterTupleSlot first tuple retrieved from outer plan + * hj_JoinState current state of ExecHashJoin state machine + * hj_MatchedOuter true if found a join match for current outer + * hj_OuterNotEmpty true if outer relation known not empty + * ---------------- + */ + +/* these structs are defined in executor/hashjoin.h: */ +typedef struct HashJoinTupleData *HashJoinTuple; +typedef struct HashJoinTableData *HashJoinTable; + +typedef struct HashJoinState +{ + JoinState js; /* its first field is NodeTag */ + ExprState *hashclauses; + List *hj_OuterHashKeys; /* list of ExprState nodes */ + List *hj_HashOperators; /* list of operator OIDs */ + List *hj_Collations; + HashJoinTable hj_HashTable; + uint32 hj_CurHashValue; + int hj_CurBucketNo; + int hj_CurSkewBucketNo; + HashJoinTuple hj_CurTuple; + TupleTableSlot *hj_OuterTupleSlot; + TupleTableSlot *hj_HashTupleSlot; + TupleTableSlot *hj_NullOuterTupleSlot; + TupleTableSlot *hj_NullInnerTupleSlot; + TupleTableSlot *hj_FirstOuterTupleSlot; + int hj_JoinState; + bool hj_MatchedOuter; + bool hj_OuterNotEmpty; +} HashJoinState; + + +/* ---------------------------------------------------------------- + * Materialization State Information + * ---------------------------------------------------------------- + */ + +/* ---------------- + * MaterialState information + * + * materialize nodes are used to materialize the results + * of a subplan into a temporary file. + * + * ss.ss_ScanTupleSlot refers to output of underlying plan. + * ---------------- + */ +typedef struct MaterialState +{ + ScanState ss; /* its first field is NodeTag */ + int eflags; /* capability flags to pass to tuplestore */ + bool eof_underlying; /* reached end of underlying plan? */ + Tuplestorestate *tuplestorestate; +} MaterialState; + +struct MemoizeEntry; +struct MemoizeTuple; +struct MemoizeKey; + +typedef struct MemoizeInstrumentation +{ + uint64 cache_hits; /* number of rescans where we've found the + * scan parameter values to be cached */ + uint64 cache_misses; /* number of rescans where we've not found the + * scan parameter values to be cached. */ + uint64 cache_evictions; /* number of cache entries removed due to + * the need to free memory */ + uint64 cache_overflows; /* number of times we've had to bypass the + * cache when filling it due to not being + * able to free enough space to store the + * current scan's tuples. */ + uint64 mem_peak; /* peak memory usage in bytes */ +} MemoizeInstrumentation; + +/* ---------------- + * Shared memory container for per-worker memoize information + * ---------------- + */ +typedef struct SharedMemoizeInfo +{ + int num_workers; + MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedMemoizeInfo; + +/* ---------------- + * MemoizeState information + * + * memoize nodes are used to cache recent and commonly seen results from + * a parameterized scan. + * ---------------- + */ +typedef struct MemoizeState +{ + ScanState ss; /* its first field is NodeTag */ + int mstatus; /* value of ExecMemoize state machine */ + int nkeys; /* number of cache keys */ + struct memoize_hash *hashtable; /* hash table for cache entries */ + TupleDesc hashkeydesc; /* tuple descriptor for cache keys */ + TupleTableSlot *tableslot; /* min tuple slot for existing cache entries */ + TupleTableSlot *probeslot; /* virtual slot used for hash lookups */ + ExprState *cache_eq_expr; /* Compare exec params to hash key */ + ExprState **param_exprs; /* exprs containing the parameters to this + * node */ + FmgrInfo *hashfunctions; /* lookup data for hash funcs nkeys in size */ + Oid *collations; /* collation for comparisons nkeys in size */ + uint64 mem_used; /* bytes of memory used by cache */ + uint64 mem_limit; /* memory limit in bytes for the cache */ + MemoryContext tableContext; /* memory context to store cache data */ + dlist_head lru_list; /* least recently used entry list */ + struct MemoizeTuple *last_tuple; /* Used to point to the last tuple + * returned during a cache hit and the + * tuple we last stored when + * populating the cache. */ + struct MemoizeEntry *entry; /* the entry that 'last_tuple' belongs to or + * NULL if 'last_tuple' is NULL. */ + bool singlerow; /* true if the cache entry is to be marked as + * complete after caching the first tuple. */ + bool binary_mode; /* true when cache key should be compared bit + * by bit, false when using hash equality ops */ + MemoizeInstrumentation stats; /* execution statistics */ + SharedMemoizeInfo *shared_info; /* statistics for parallel workers */ + Bitmapset *keyparamids; /* Param->paramids of expressions belonging to + * param_exprs */ +} MemoizeState; + +/* ---------------- + * When performing sorting by multiple keys, it's possible that the input + * dataset is already sorted on a prefix of those keys. We call these + * "presorted keys". + * PresortedKeyData represents information about one such key. + * ---------------- + */ +typedef struct PresortedKeyData +{ + FmgrInfo flinfo; /* comparison function info */ + FunctionCallInfo fcinfo; /* comparison function call info */ + OffsetNumber attno; /* attribute number in tuple */ +} PresortedKeyData; + +/* ---------------- + * Shared memory container for per-worker sort information + * ---------------- + */ +typedef struct SharedSortInfo +{ + int num_workers; + TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedSortInfo; + +/* ---------------- + * SortState information + * ---------------- + */ +typedef struct SortState +{ + ScanState ss; /* its first field is NodeTag */ + bool randomAccess; /* need random access to sort output? */ + bool bounded; /* is the result set bounded? */ + int64 bound; /* if bounded, how many tuples are needed */ + bool sort_Done; /* sort completed yet? */ + bool bounded_Done; /* value of bounded we did the sort with */ + int64 bound_Done; /* value of bound we did the sort with */ + void *tuplesortstate; /* private state of tuplesort.c */ + bool am_worker; /* are we a worker? */ + bool datumSort; /* Datum sort instead of tuple sort? */ + SharedSortInfo *shared_info; /* one entry per worker */ +} SortState; + +/* ---------------- + * Instrumentation information for IncrementalSort + * ---------------- + */ +typedef struct IncrementalSortGroupInfo +{ + int64 groupCount; + int64 maxDiskSpaceUsed; + int64 totalDiskSpaceUsed; + int64 maxMemorySpaceUsed; + int64 totalMemorySpaceUsed; + bits32 sortMethods; /* bitmask of TuplesortMethod */ +} IncrementalSortGroupInfo; + +typedef struct IncrementalSortInfo +{ + IncrementalSortGroupInfo fullsortGroupInfo; + IncrementalSortGroupInfo prefixsortGroupInfo; +} IncrementalSortInfo; + +/* ---------------- + * Shared memory container for per-worker incremental sort information + * ---------------- + */ +typedef struct SharedIncrementalSortInfo +{ + int num_workers; + IncrementalSortInfo sinfo[FLEXIBLE_ARRAY_MEMBER]; +} SharedIncrementalSortInfo; + +/* ---------------- + * IncrementalSortState information + * ---------------- + */ +typedef enum +{ + INCSORT_LOADFULLSORT, + INCSORT_LOADPREFIXSORT, + INCSORT_READFULLSORT, + INCSORT_READPREFIXSORT, +} IncrementalSortExecutionStatus; + +typedef struct IncrementalSortState +{ + ScanState ss; /* its first field is NodeTag */ + bool bounded; /* is the result set bounded? */ + int64 bound; /* if bounded, how many tuples are needed */ + bool outerNodeDone; /* finished fetching tuples from outer node */ + int64 bound_Done; /* value of bound we did the sort with */ + IncrementalSortExecutionStatus execution_status; + int64 n_fullsort_remaining; + Tuplesortstate *fullsort_state; /* private state of tuplesort.c */ + Tuplesortstate *prefixsort_state; /* private state of tuplesort.c */ + /* the keys by which the input path is already sorted */ + PresortedKeyData *presorted_keys; + + IncrementalSortInfo incsort_info; + + /* slot for pivot tuple defining values of presorted keys within group */ + TupleTableSlot *group_pivot; + TupleTableSlot *transfer_tuple; + bool am_worker; /* are we a worker? */ + SharedIncrementalSortInfo *shared_info; /* one entry per worker */ +} IncrementalSortState; + +/* --------------------- + * GroupState information + * --------------------- + */ +typedef struct GroupState +{ + ScanState ss; /* its first field is NodeTag */ + ExprState *eqfunction; /* equality function */ + bool grp_done; /* indicates completion of Group scan */ +} GroupState; + +/* --------------------- + * per-worker aggregate information + * --------------------- + */ +typedef struct AggregateInstrumentation +{ + Size hash_mem_peak; /* peak hash table memory usage */ + uint64 hash_disk_used; /* kB of disk space used */ + int hash_batches_used; /* batches used during entire execution */ +} AggregateInstrumentation; + +/* ---------------- + * Shared memory container for per-worker aggregate information + * ---------------- + */ +typedef struct SharedAggInfo +{ + int num_workers; + AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedAggInfo; + +/* --------------------- + * AggState information + * + * ss.ss_ScanTupleSlot refers to output of underlying plan. + * + * Note: ss.ps.ps_ExprContext contains ecxt_aggvalues and + * ecxt_aggnulls arrays, which hold the computed agg values for the current + * input group during evaluation of an Agg node's output tuple(s). We + * create a second ExprContext, tmpcontext, in which to evaluate input + * expressions and run the aggregate transition functions. + * --------------------- + */ +/* these structs are private in nodeAgg.c: */ +typedef struct AggStatePerAggData *AggStatePerAgg; +typedef struct AggStatePerTransData *AggStatePerTrans; +typedef struct AggStatePerGroupData *AggStatePerGroup; +typedef struct AggStatePerPhaseData *AggStatePerPhase; +typedef struct AggStatePerHashData *AggStatePerHash; + +typedef struct AggState +{ + ScanState ss; /* its first field is NodeTag */ + List *aggs; /* all Aggref nodes in targetlist & quals */ + int numaggs; /* length of list (could be zero!) */ + int numtrans; /* number of pertrans items */ + AggStrategy aggstrategy; /* strategy mode */ + AggSplit aggsplit; /* agg-splitting mode, see nodes.h */ + AggStatePerPhase phase; /* pointer to current phase data */ + int numphases; /* number of phases (including phase 0) */ + int current_phase; /* current phase number */ + AggStatePerAgg peragg; /* per-Aggref information */ + AggStatePerTrans pertrans; /* per-Trans state information */ + ExprContext *hashcontext; /* econtexts for long-lived data (hashtable) */ + ExprContext **aggcontexts; /* econtexts for long-lived data (per GS) */ + ExprContext *tmpcontext; /* econtext for input expressions */ +#define FIELDNO_AGGSTATE_CURAGGCONTEXT 14 + ExprContext *curaggcontext; /* currently active aggcontext */ + AggStatePerAgg curperagg; /* currently active aggregate, if any */ +#define FIELDNO_AGGSTATE_CURPERTRANS 16 + AggStatePerTrans curpertrans; /* currently active trans state, if any */ + bool input_done; /* indicates end of input */ + bool agg_done; /* indicates completion of Agg scan */ + int projected_set; /* The last projected grouping set */ +#define FIELDNO_AGGSTATE_CURRENT_SET 20 + int current_set; /* The current grouping set being evaluated */ + Bitmapset *grouped_cols; /* grouped cols in current projection */ + List *all_grouped_cols; /* list of all grouped cols in DESC order */ + Bitmapset *colnos_needed; /* all columns needed from the outer plan */ + int max_colno_needed; /* highest colno needed from outer plan */ + bool all_cols_needed; /* are all cols from outer plan needed? */ + /* These fields are for grouping set phase data */ + int maxsets; /* The max number of sets in any phase */ + AggStatePerPhase phases; /* array of all phases */ + Tuplesortstate *sort_in; /* sorted input to phases > 1 */ + Tuplesortstate *sort_out; /* input is copied here for next phase */ + TupleTableSlot *sort_slot; /* slot for sort results */ + /* these fields are used in AGG_PLAIN and AGG_SORTED modes: */ + AggStatePerGroup *pergroups; /* grouping set indexed array of per-group + * pointers */ + HeapTuple grp_firstTuple; /* copy of first tuple of current group */ + /* these fields are used in AGG_HASHED and AGG_MIXED modes: */ + bool table_filled; /* hash table filled yet? */ + int num_hashes; + MemoryContext hash_metacxt; /* memory for hash table itself */ + struct LogicalTapeSet *hash_tapeset; /* tape set for hash spill tapes */ + struct HashAggSpill *hash_spills; /* HashAggSpill for each grouping set, + * exists only during first pass */ + TupleTableSlot *hash_spill_rslot; /* for reading spill files */ + TupleTableSlot *hash_spill_wslot; /* for writing spill files */ + List *hash_batches; /* hash batches remaining to be processed */ + bool hash_ever_spilled; /* ever spilled during this execution? */ + bool hash_spill_mode; /* we hit a limit during the current batch + * and we must not create new groups */ + Size hash_mem_limit; /* limit before spilling hash table */ + uint64 hash_ngroups_limit; /* limit before spilling hash table */ + int hash_planned_partitions; /* number of partitions planned + * for first pass */ + double hashentrysize; /* estimate revised during execution */ + Size hash_mem_peak; /* peak hash table memory usage */ + uint64 hash_ngroups_current; /* number of groups currently in + * memory in all hash tables */ + uint64 hash_disk_used; /* kB of disk space used */ + int hash_batches_used; /* batches used during entire execution */ + + AggStatePerHash perhash; /* array of per-hashtable data */ + AggStatePerGroup *hash_pergroup; /* grouping set indexed array of + * per-group pointers */ + + /* support for evaluation of agg input expressions: */ +#define FIELDNO_AGGSTATE_ALL_PERGROUPS 53 + AggStatePerGroup *all_pergroups; /* array of first ->pergroups, than + * ->hash_pergroup */ + ProjectionInfo *combinedproj; /* projection machinery */ + SharedAggInfo *shared_info; /* one entry per worker */ +} AggState; + +/* ---------------- + * WindowAggState information + * ---------------- + */ +/* these structs are private in nodeWindowAgg.c: */ +typedef struct WindowStatePerFuncData *WindowStatePerFunc; +typedef struct WindowStatePerAggData *WindowStatePerAgg; + +/* + * WindowAggStatus -- Used to track the status of WindowAggState + */ +typedef enum WindowAggStatus +{ + WINDOWAGG_DONE, /* No more processing to do */ + WINDOWAGG_RUN, /* Normal processing of window funcs */ + WINDOWAGG_PASSTHROUGH, /* Don't eval window funcs */ + WINDOWAGG_PASSTHROUGH_STRICT /* Pass-through plus don't store new + * tuples during spool */ +} WindowAggStatus; + +typedef struct WindowAggState +{ + ScanState ss; /* its first field is NodeTag */ + + /* these fields are filled in by ExecInitExpr: */ + List *funcs; /* all WindowFunc nodes in targetlist */ + int numfuncs; /* total number of window functions */ + int numaggs; /* number that are plain aggregates */ + + WindowStatePerFunc perfunc; /* per-window-function information */ + WindowStatePerAgg peragg; /* per-plain-aggregate information */ + ExprState *partEqfunction; /* equality funcs for partition columns */ + ExprState *ordEqfunction; /* equality funcs for ordering columns */ + Tuplestorestate *buffer; /* stores rows of current partition */ + int current_ptr; /* read pointer # for current row */ + int framehead_ptr; /* read pointer # for frame head, if used */ + int frametail_ptr; /* read pointer # for frame tail, if used */ + int grouptail_ptr; /* read pointer # for group tail, if used */ + int64 spooled_rows; /* total # of rows in buffer */ + int64 currentpos; /* position of current row in partition */ + int64 frameheadpos; /* current frame head position */ + int64 frametailpos; /* current frame tail position (frame end+1) */ + /* use struct pointer to avoid including windowapi.h here */ + struct WindowObjectData *agg_winobj; /* winobj for aggregate fetches */ + int64 aggregatedbase; /* start row for current aggregates */ + int64 aggregatedupto; /* rows before this one are aggregated */ + WindowAggStatus status; /* run status of WindowAggState */ + + int frameOptions; /* frame_clause options, see WindowDef */ + ExprState *startOffset; /* expression for starting bound offset */ + ExprState *endOffset; /* expression for ending bound offset */ + Datum startOffsetValue; /* result of startOffset evaluation */ + Datum endOffsetValue; /* result of endOffset evaluation */ + + /* these fields are used with RANGE offset PRECEDING/FOLLOWING: */ + FmgrInfo startInRangeFunc; /* in_range function for startOffset */ + FmgrInfo endInRangeFunc; /* in_range function for endOffset */ + Oid inRangeColl; /* collation for in_range tests */ + bool inRangeAsc; /* use ASC sort order for in_range tests? */ + bool inRangeNullsFirst; /* nulls sort first for in_range tests? */ + + /* these fields are used in GROUPS mode: */ + int64 currentgroup; /* peer group # of current row in partition */ + int64 frameheadgroup; /* peer group # of frame head row */ + int64 frametailgroup; /* peer group # of frame tail row */ + int64 groupheadpos; /* current row's peer group head position */ + int64 grouptailpos; /* " " " " tail position (group end+1) */ + + MemoryContext partcontext; /* context for partition-lifespan data */ + MemoryContext aggcontext; /* shared context for aggregate working data */ + MemoryContext curaggcontext; /* current aggregate's working data */ + ExprContext *tmpcontext; /* short-term evaluation context */ + + ExprState *runcondition; /* Condition which must remain true otherwise + * execution of the WindowAgg will finish or + * go into pass-through mode. NULL when there + * is no such condition. */ + + bool use_pass_through; /* When false, stop execution when + * runcondition is no longer true. Else + * just stop evaluating window funcs. */ + bool top_window; /* true if this is the top-most WindowAgg or + * the only WindowAgg in this query level */ + bool all_first; /* true if the scan is starting */ + bool partition_spooled; /* true if all tuples in current partition + * have been spooled into tuplestore */ + bool more_partitions; /* true if there's more partitions after + * this one */ + bool framehead_valid; /* true if frameheadpos is known up to + * date for current row */ + bool frametail_valid; /* true if frametailpos is known up to + * date for current row */ + bool grouptail_valid; /* true if grouptailpos is known up to + * date for current row */ + + TupleTableSlot *first_part_slot; /* first tuple of current or next + * partition */ + TupleTableSlot *framehead_slot; /* first tuple of current frame */ + TupleTableSlot *frametail_slot; /* first tuple after current frame */ + + /* temporary slots for tuples fetched back from tuplestore */ + TupleTableSlot *agg_row_slot; + TupleTableSlot *temp_slot_1; + TupleTableSlot *temp_slot_2; +} WindowAggState; + +/* ---------------- + * UniqueState information + * + * Unique nodes are used "on top of" sort nodes to discard + * duplicate tuples returned from the sort phase. Basically + * all it does is compare the current tuple from the subplan + * with the previously fetched tuple (stored in its result slot). + * If the two are identical in all interesting fields, then + * we just fetch another tuple from the sort and try again. + * ---------------- + */ +typedef struct UniqueState +{ + PlanState ps; /* its first field is NodeTag */ + ExprState *eqfunction; /* tuple equality qual */ +} UniqueState; + +/* ---------------- + * GatherState information + * + * Gather nodes launch 1 or more parallel workers, run a subplan + * in those workers, and collect the results. + * ---------------- + */ +typedef struct GatherState +{ + PlanState ps; /* its first field is NodeTag */ + bool initialized; /* workers launched? */ + bool need_to_scan_locally; /* need to read from local plan? */ + int64 tuples_needed; /* tuple bound, see ExecSetTupleBound */ + /* these fields are set up once: */ + TupleTableSlot *funnel_slot; + struct ParallelExecutorInfo *pei; + /* all remaining fields are reinitialized during a rescan: */ + int nworkers_launched; /* original number of workers */ + int nreaders; /* number of still-active workers */ + int nextreader; /* next one to try to read from */ + struct TupleQueueReader **reader; /* array with nreaders active entries */ +} GatherState; + +/* ---------------- + * GatherMergeState information + * + * Gather merge nodes launch 1 or more parallel workers, run a + * subplan which produces sorted output in each worker, and then + * merge the results into a single sorted stream. + * ---------------- + */ +struct GMReaderTupleBuffer; /* private in nodeGatherMerge.c */ + +typedef struct GatherMergeState +{ + PlanState ps; /* its first field is NodeTag */ + bool initialized; /* workers launched? */ + bool gm_initialized; /* gather_merge_init() done? */ + bool need_to_scan_locally; /* need to read from local plan? */ + int64 tuples_needed; /* tuple bound, see ExecSetTupleBound */ + /* these fields are set up once: */ + TupleDesc tupDesc; /* descriptor for subplan result tuples */ + int gm_nkeys; /* number of sort columns */ + SortSupport gm_sortkeys; /* array of length gm_nkeys */ + struct ParallelExecutorInfo *pei; + /* all remaining fields are reinitialized during a rescan */ + /* (but the arrays are not reallocated, just cleared) */ + int nworkers_launched; /* original number of workers */ + int nreaders; /* number of active workers */ + TupleTableSlot **gm_slots; /* array with nreaders+1 entries */ + struct TupleQueueReader **reader; /* array with nreaders active entries */ + struct GMReaderTupleBuffer *gm_tuple_buffers; /* nreaders tuple buffers */ + struct binaryheap *gm_heap; /* binary heap of slot indices */ +} GatherMergeState; + +/* ---------------- + * Values displayed by EXPLAIN ANALYZE + * ---------------- + */ +typedef struct HashInstrumentation +{ + int nbuckets; /* number of buckets at end of execution */ + int nbuckets_original; /* planned number of buckets */ + int nbatch; /* number of batches at end of execution */ + int nbatch_original; /* planned number of batches */ + Size space_peak; /* peak memory usage in bytes */ +} HashInstrumentation; + +/* ---------------- + * Shared memory container for per-worker hash information + * ---------------- + */ +typedef struct SharedHashInfo +{ + int num_workers; + HashInstrumentation hinstrument[FLEXIBLE_ARRAY_MEMBER]; +} SharedHashInfo; + +/* ---------------- + * HashState information + * ---------------- + */ +typedef struct HashState +{ + PlanState ps; /* its first field is NodeTag */ + HashJoinTable hashtable; /* hash table for the hashjoin */ + List *hashkeys; /* list of ExprState nodes */ + + /* + * In a parallelized hash join, the leader retains a pointer to the + * shared-memory stats area in its shared_info field, and then copies the + * shared-memory info back to local storage before DSM shutdown. The + * shared_info field remains NULL in workers, or in non-parallel joins. + */ + SharedHashInfo *shared_info; + + /* + * If we are collecting hash stats, this points to an initially-zeroed + * collection area, which could be either local storage or in shared + * memory; either way it's for just one process. + */ + HashInstrumentation *hinstrument; + + /* Parallel hash state. */ + struct ParallelHashJoinState *parallel_state; +} HashState; + +/* ---------------- + * SetOpState information + * + * Even in "sorted" mode, SetOp nodes are more complex than a simple + * Unique, since we have to count how many duplicates to return. But + * we also support hashing, so this is really more like a cut-down + * form of Agg. + * ---------------- + */ +/* this struct is private in nodeSetOp.c: */ +typedef struct SetOpStatePerGroupData *SetOpStatePerGroup; + +typedef struct SetOpState +{ + PlanState ps; /* its first field is NodeTag */ + ExprState *eqfunction; /* equality comparator */ + Oid *eqfuncoids; /* per-grouping-field equality fns */ + FmgrInfo *hashfunctions; /* per-grouping-field hash fns */ + bool setop_done; /* indicates completion of output scan */ + long numOutput; /* number of dups left to output */ + /* these fields are used in SETOP_SORTED mode: */ + SetOpStatePerGroup pergroup; /* per-group working state */ + HeapTuple grp_firstTuple; /* copy of first tuple of current group */ + /* these fields are used in SETOP_HASHED mode: */ + TupleHashTable hashtable; /* hash table with one entry per group */ + MemoryContext tableContext; /* memory context containing hash table */ + bool table_filled; /* hash table filled yet? */ + TupleHashIterator hashiter; /* for iterating through hash table */ +} SetOpState; + +/* ---------------- + * LockRowsState information + * + * LockRows nodes are used to enforce FOR [KEY] UPDATE/SHARE locking. + * ---------------- + */ +typedef struct LockRowsState +{ + PlanState ps; /* its first field is NodeTag */ + List *lr_arowMarks; /* List of ExecAuxRowMarks */ + EPQState lr_epqstate; /* for evaluating EvalPlanQual rechecks */ +} LockRowsState; + +/* ---------------- + * LimitState information + * + * Limit nodes are used to enforce LIMIT/OFFSET clauses. + * They just select the desired subrange of their subplan's output. + * + * offset is the number of initial tuples to skip (0 does nothing). + * count is the number of tuples to return after skipping the offset tuples. + * If no limit count was specified, count is undefined and noCount is true. + * When lstate == LIMIT_INITIAL, offset/count/noCount haven't been set yet. + * ---------------- + */ +typedef enum +{ + LIMIT_INITIAL, /* initial state for LIMIT node */ + LIMIT_RESCAN, /* rescan after recomputing parameters */ + LIMIT_EMPTY, /* there are no returnable rows */ + LIMIT_INWINDOW, /* have returned a row in the window */ + LIMIT_WINDOWEND_TIES, /* have returned a tied row */ + LIMIT_SUBPLANEOF, /* at EOF of subplan (within window) */ + LIMIT_WINDOWEND, /* stepped off end of window */ + LIMIT_WINDOWSTART /* stepped off beginning of window */ +} LimitStateCond; + +typedef struct LimitState +{ + PlanState ps; /* its first field is NodeTag */ + ExprState *limitOffset; /* OFFSET parameter, or NULL if none */ + ExprState *limitCount; /* COUNT parameter, or NULL if none */ + LimitOption limitOption; /* limit specification type */ + int64 offset; /* current OFFSET value */ + int64 count; /* current COUNT, if any */ + bool noCount; /* if true, ignore count */ + LimitStateCond lstate; /* state machine status, as above */ + int64 position; /* 1-based index of last tuple returned */ + TupleTableSlot *subSlot; /* tuple last obtained from subplan */ + ExprState *eqfunction; /* tuple equality qual in case of WITH TIES + * option */ + TupleTableSlot *last_slot; /* slot for evaluation of ties */ +} LimitState; + +#endif /* EXECNODES_H */ diff --git a/install/include/postgresql/server/nodes/extensible.h b/install/include/postgresql/server/nodes/extensible.h new file mode 100644 index 00000000000..7d51c6033e7 --- /dev/null +++ b/install/include/postgresql/server/nodes/extensible.h @@ -0,0 +1,164 @@ +/*------------------------------------------------------------------------- + * + * extensible.h + * Definitions for extensible nodes and custom scans + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/extensible.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXTENSIBLE_H +#define EXTENSIBLE_H + +#include "access/parallel.h" +#include "commands/explain.h" +#include "nodes/execnodes.h" +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" + +/* maximum length of an extensible node identifier */ +#define EXTNODENAME_MAX_LEN 64 + +/* + * An extensible node is a new type of node defined by an extension. The + * type is always T_ExtensibleNode, while the extnodename identifies the + * specific type of node. extnodename can be looked up to find the + * ExtensibleNodeMethods for this node type. + */ +typedef struct ExtensibleNode +{ + pg_node_attr(custom_copy_equal, custom_read_write) + + NodeTag type; + const char *extnodename; /* identifier of ExtensibleNodeMethods */ +} ExtensibleNode; + +/* + * node_size is the size of an extensible node of this type in bytes. + * + * nodeCopy is a function which performs a deep copy from oldnode to newnode. + * It does not need to copy type or extnodename, which are copied by the + * core system. + * + * nodeEqual is a function which performs a deep equality comparison between + * a and b and returns true or false accordingly. It does not need to compare + * type or extnodename, which are compared by the core system. + * + * nodeOut is a serialization function for the node type. It should use the + * output conventions typical for outfuncs.c. It does not need to output + * type or extnodename; the core system handles those. + * + * nodeRead is a deserialization function for the node type. It does not need + * to read type or extnodename; the core system handles those. It should fetch + * the next token using pg_strtok() from the current input stream, and then + * reconstruct the private fields according to the manner in readfuncs.c. + * + * All callbacks are mandatory. + */ +typedef struct ExtensibleNodeMethods +{ + const char *extnodename; + Size node_size; + void (*nodeCopy) (struct ExtensibleNode *newnode, + const struct ExtensibleNode *oldnode); + bool (*nodeEqual) (const struct ExtensibleNode *a, + const struct ExtensibleNode *b); + void (*nodeOut) (struct StringInfoData *str, + const struct ExtensibleNode *node); + void (*nodeRead) (struct ExtensibleNode *node); +} ExtensibleNodeMethods; + +extern void RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *methods); +extern const ExtensibleNodeMethods *GetExtensibleNodeMethods(const char *extnodename, + bool missing_ok); + +/* + * Flags for custom paths, indicating what capabilities the resulting scan + * will have. The flags fields of CustomPath and CustomScan nodes are + * bitmasks of these flags. + */ +#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN 0x0001 +#define CUSTOMPATH_SUPPORT_MARK_RESTORE 0x0002 +#define CUSTOMPATH_SUPPORT_PROJECTION 0x0004 + +/* + * Custom path methods. Mostly, we just need to know how to convert a + * CustomPath to a plan. + */ +typedef struct CustomPathMethods +{ + const char *CustomName; + + /* Convert Path to a Plan */ + struct Plan *(*PlanCustomPath) (PlannerInfo *root, + RelOptInfo *rel, + struct CustomPath *best_path, + List *tlist, + List *clauses, + List *custom_plans); + struct List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root, + List *custom_private, + RelOptInfo *child_rel); +} CustomPathMethods; + +/* + * Custom scan. Here again, there's not much to do: we need to be able to + * generate a ScanState corresponding to the scan. + */ +typedef struct CustomScanMethods +{ + const char *CustomName; + + /* Create execution state (CustomScanState) from a CustomScan plan node */ + Node *(*CreateCustomScanState) (CustomScan *cscan); +} CustomScanMethods; + +/* + * Execution-time methods for a CustomScanState. This is more complex than + * what we need for a custom path or scan. + */ +typedef struct CustomExecMethods +{ + const char *CustomName; + + /* Required executor methods */ + void (*BeginCustomScan) (CustomScanState *node, + EState *estate, + int eflags); + TupleTableSlot *(*ExecCustomScan) (CustomScanState *node); + void (*EndCustomScan) (CustomScanState *node); + void (*ReScanCustomScan) (CustomScanState *node); + + /* Optional methods: needed if mark/restore is supported */ + void (*MarkPosCustomScan) (CustomScanState *node); + void (*RestrPosCustomScan) (CustomScanState *node); + + /* Optional methods: needed if parallel execution is supported */ + Size (*EstimateDSMCustomScan) (CustomScanState *node, + ParallelContext *pcxt); + void (*InitializeDSMCustomScan) (CustomScanState *node, + ParallelContext *pcxt, + void *coordinate); + void (*ReInitializeDSMCustomScan) (CustomScanState *node, + ParallelContext *pcxt, + void *coordinate); + void (*InitializeWorkerCustomScan) (CustomScanState *node, + shm_toc *toc, + void *coordinate); + void (*ShutdownCustomScan) (CustomScanState *node); + + /* Optional: print additional information in EXPLAIN */ + void (*ExplainCustomScan) (CustomScanState *node, + List *ancestors, + ExplainState *es); +} CustomExecMethods; + +extern void RegisterCustomScanMethods(const CustomScanMethods *methods); +extern const CustomScanMethods *GetCustomScanMethods(const char *CustomName, + bool missing_ok); + +#endif /* EXTENSIBLE_H */ diff --git a/install/include/postgresql/server/nodes/lockoptions.h b/install/include/postgresql/server/nodes/lockoptions.h new file mode 100644 index 00000000000..bc5e98336f1 --- /dev/null +++ b/install/include/postgresql/server/nodes/lockoptions.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * lockoptions.h + * Common header for some locking-related declarations. + * + * + * Copyright (c) 2014-2023, PostgreSQL Global Development Group + * + * src/include/nodes/lockoptions.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOCKOPTIONS_H +#define LOCKOPTIONS_H + +/* + * This enum represents the different strengths of FOR UPDATE/SHARE clauses. + * The ordering here is important, because the highest numerical value takes + * precedence when a RTE is specified multiple ways. See applyLockingClause. + */ +typedef enum LockClauseStrength +{ + LCS_NONE, /* no such clause - only used in PlanRowMark */ + LCS_FORKEYSHARE, /* FOR KEY SHARE */ + LCS_FORSHARE, /* FOR SHARE */ + LCS_FORNOKEYUPDATE, /* FOR NO KEY UPDATE */ + LCS_FORUPDATE /* FOR UPDATE */ +} LockClauseStrength; + +/* + * This enum controls how to deal with rows being locked by FOR UPDATE/SHARE + * clauses (i.e., it represents the NOWAIT and SKIP LOCKED options). + * The ordering here is important, because the highest numerical value takes + * precedence when a RTE is specified multiple ways. See applyLockingClause. + */ +typedef enum LockWaitPolicy +{ + /* Wait for the lock to become available (default behavior) */ + LockWaitBlock, + /* Skip rows that can't be locked (SKIP LOCKED) */ + LockWaitSkip, + /* Raise an error if a row cannot be locked (NOWAIT) */ + LockWaitError +} LockWaitPolicy; + +/* + * Possible lock modes for a tuple. + */ +typedef enum LockTupleMode +{ + /* SELECT FOR KEY SHARE */ + LockTupleKeyShare, + /* SELECT FOR SHARE */ + LockTupleShare, + /* SELECT FOR NO KEY UPDATE, and UPDATEs that don't modify key columns */ + LockTupleNoKeyExclusive, + /* SELECT FOR UPDATE, UPDATEs that modify key columns, and DELETE */ + LockTupleExclusive +} LockTupleMode; + +#endif /* LOCKOPTIONS_H */ diff --git a/install/include/postgresql/server/nodes/makefuncs.h b/install/include/postgresql/server/nodes/makefuncs.h new file mode 100644 index 00000000000..31807030055 --- /dev/null +++ b/install/include/postgresql/server/nodes/makefuncs.h @@ -0,0 +1,121 @@ +/*------------------------------------------------------------------------- + * + * makefuncs.h + * prototypes for the creator functions of various nodes + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/makefuncs.h + * + *------------------------------------------------------------------------- + */ +#ifndef MAKEFUNC_H +#define MAKEFUNC_H + +#include "nodes/execnodes.h" +#include "nodes/parsenodes.h" + + +extern A_Expr *makeA_Expr(A_Expr_Kind kind, List *name, + Node *lexpr, Node *rexpr, int location); + +extern A_Expr *makeSimpleA_Expr(A_Expr_Kind kind, char *name, + Node *lexpr, Node *rexpr, int location); + +extern Var *makeVar(int varno, + AttrNumber varattno, + Oid vartype, + int32 vartypmod, + Oid varcollid, + Index varlevelsup); + +extern Var *makeVarFromTargetEntry(int varno, + TargetEntry *tle); + +extern Var *makeWholeRowVar(RangeTblEntry *rte, + int varno, + Index varlevelsup, + bool allowScalar); + +extern TargetEntry *makeTargetEntry(Expr *expr, + AttrNumber resno, + char *resname, + bool resjunk); + +extern TargetEntry *flatCopyTargetEntry(TargetEntry *src_tle); + +extern FromExpr *makeFromExpr(List *fromlist, Node *quals); + +extern Const *makeConst(Oid consttype, + int32 consttypmod, + Oid constcollid, + int constlen, + Datum constvalue, + bool constisnull, + bool constbyval); + +extern Const *makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid); + +extern Node *makeBoolConst(bool value, bool isnull); + +extern Expr *makeBoolExpr(BoolExprType boolop, List *args, int location); + +extern Alias *makeAlias(const char *aliasname, List *colnames); + +extern RelabelType *makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, + Oid rcollid, CoercionForm rformat); + +extern RangeVar *makeRangeVar(char *schemaname, char *relname, int location); + +extern TypeName *makeTypeName(char *typnam); +extern TypeName *makeTypeNameFromNameList(List *names); +extern TypeName *makeTypeNameFromOid(Oid typeOid, int32 typmod); + +extern ColumnDef *makeColumnDef(const char *colname, + Oid typeOid, int32 typmod, Oid collOid); + +extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args, + Oid funccollid, Oid inputcollid, CoercionForm fformat); + +extern FuncCall *makeFuncCall(List *name, List *args, + CoercionForm funcformat, int location); + +extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset, + Expr *leftop, Expr *rightop, + Oid opcollid, Oid inputcollid); + +extern Expr *make_andclause(List *andclauses); +extern Expr *make_orclause(List *orclauses); +extern Expr *make_notclause(Expr *notclause); + +extern Node *make_and_qual(Node *qual1, Node *qual2); +extern Expr *make_ands_explicit(List *andclauses); +extern List *make_ands_implicit(Expr *clause); + +extern IndexInfo *makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, + List *expressions, List *predicates, + bool unique, bool nulls_not_distinct, + bool isready, bool concurrent, + bool summarizing); + +extern DefElem *makeDefElem(char *name, Node *arg, int location); +extern DefElem *makeDefElemExtended(char *nameSpace, char *name, Node *arg, + DefElemAction defaction, int location); + +extern GroupingSet *makeGroupingSet(GroupingSetKind kind, List *content, int location); + +extern VacuumRelation *makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols); + +extern JsonFormat *makeJsonFormat(JsonFormatType type, JsonEncoding encoding, + int location); +extern JsonValueExpr *makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr, + JsonFormat *format); +extern Node *makeJsonKeyValue(Node *key, Node *value); +extern Node *makeJsonIsPredicate(Node *expr, JsonFormat *format, + JsonValueType item_type, bool unique_keys, + int location); +extern JsonEncoding makeJsonEncoding(char *name); + +#endif /* MAKEFUNC_H */ diff --git a/install/include/postgresql/server/nodes/memnodes.h b/install/include/postgresql/server/nodes/memnodes.h new file mode 100644 index 00000000000..ff6453bb7ac --- /dev/null +++ b/install/include/postgresql/server/nodes/memnodes.h @@ -0,0 +1,113 @@ +/*------------------------------------------------------------------------- + * + * memnodes.h + * POSTGRES memory context node definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/memnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef MEMNODES_H +#define MEMNODES_H + +#include "nodes/nodes.h" + +/* + * MemoryContextCounters + * Summarization state for MemoryContextStats collection. + * + * The set of counters in this struct is biased towards AllocSet; if we ever + * add any context types that are based on fundamentally different approaches, + * we might need more or different counters here. A possible API spec then + * would be to print only nonzero counters, but for now we just summarize in + * the format historically used by AllocSet. + */ +typedef struct MemoryContextCounters +{ + Size nblocks; /* Total number of malloc blocks */ + Size freechunks; /* Total number of free chunks */ + Size totalspace; /* Total bytes requested from malloc */ + Size freespace; /* The unused portion of totalspace */ +} MemoryContextCounters; + +/* + * MemoryContext + * A logical context in which memory allocations occur. + * + * MemoryContext itself is an abstract type that can have multiple + * implementations. + * The function pointers in MemoryContextMethods define one specific + * implementation of MemoryContext --- they are a virtual function table + * in C++ terms. + * + * Node types that are actual implementations of memory contexts must + * begin with the same fields as MemoryContextData. + * + * Note: for largely historical reasons, typedef MemoryContext is a pointer + * to the context struct rather than the struct type itself. + */ + +typedef void (*MemoryStatsPrintFunc) (MemoryContext context, void *passthru, + const char *stats_string, + bool print_to_stderr); + +typedef struct MemoryContextMethods +{ + void *(*alloc) (MemoryContext context, Size size); + /* call this free_p in case someone #define's free() */ + void (*free_p) (void *pointer); + void *(*realloc) (void *pointer, Size size); + void (*reset) (MemoryContext context); + void (*delete_context) (MemoryContext context); + MemoryContext (*get_chunk_context) (void *pointer); + Size (*get_chunk_space) (void *pointer); + bool (*is_empty) (MemoryContext context); + void (*stats) (MemoryContext context, + MemoryStatsPrintFunc printfunc, void *passthru, + MemoryContextCounters *totals, + bool print_to_stderr); +#ifdef MEMORY_CONTEXT_CHECKING + void (*check) (MemoryContext context); +#endif +} MemoryContextMethods; + + +typedef struct MemoryContextData +{ + pg_node_attr(abstract) /* there are no nodes of this type */ + + NodeTag type; /* identifies exact kind of context */ + /* these two fields are placed here to minimize alignment wastage: */ + bool isReset; /* T = no space alloced since last reset */ + bool allowInCritSection; /* allow palloc in critical section */ + Size mem_allocated; /* track memory allocated for this context */ + const MemoryContextMethods *methods; /* virtual function table */ + MemoryContext parent; /* NULL if no parent (toplevel context) */ + MemoryContext firstchild; /* head of linked list of children */ + MemoryContext prevchild; /* previous child of same parent */ + MemoryContext nextchild; /* next child of same parent */ + const char *name; /* context name (just for debugging) */ + const char *ident; /* context ID if any (just for debugging) */ + MemoryContextCallback *reset_cbs; /* list of reset/delete callbacks */ +} MemoryContextData; + +/* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */ + + +/* + * MemoryContextIsValid + * True iff memory context is valid. + * + * Add new context types to the set accepted by this macro. + */ +#define MemoryContextIsValid(context) \ + ((context) != NULL && \ + (IsA((context), AllocSetContext) || \ + IsA((context), SlabContext) || \ + IsA((context), GenerationContext))) + +#endif /* MEMNODES_H */ diff --git a/install/include/postgresql/server/nodes/miscnodes.h b/install/include/postgresql/server/nodes/miscnodes.h new file mode 100644 index 00000000000..79cc0db4754 --- /dev/null +++ b/install/include/postgresql/server/nodes/miscnodes.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * miscnodes.h + * Definitions for hard-to-classify node types. + * + * Node types declared here are not part of parse trees, plan trees, + * or execution state trees. We only assign them NodeTag values because + * IsA() tests provide a convenient way to disambiguate what kind of + * structure is being passed through assorted APIs, such as function + * "context" pointers. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/miscnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef MISCNODES_H +#define MISCNODES_H + +#include "nodes/nodes.h" + +/* + * ErrorSaveContext - + * function call context node for handling of "soft" errors + * + * A caller wishing to trap soft errors must initialize a struct like this + * with all fields zero/NULL except for the NodeTag. Optionally, set + * details_wanted = true if more than the bare knowledge that a soft error + * occurred is required. The struct is then passed to a SQL-callable function + * via the FunctionCallInfo.context field; or below the level of SQL calls, + * it could be passed to a subroutine directly. + * + * After calling code that might report an error this way, check + * error_occurred to see if an error happened. If so, and if details_wanted + * is true, error_data has been filled with error details (stored in the + * callee's memory context!). FreeErrorData() can be called to release + * error_data, although that step is typically not necessary if the called + * code was run in a short-lived context. + */ +typedef struct ErrorSaveContext +{ + NodeTag type; + bool error_occurred; /* set to true if we detect a soft error */ + bool details_wanted; /* does caller want more info than that? */ + ErrorData *error_data; /* details of error, if so */ +} ErrorSaveContext; + +/* Often-useful macro for checking if a soft error was reported */ +#define SOFT_ERROR_OCCURRED(escontext) \ + ((escontext) != NULL && IsA(escontext, ErrorSaveContext) && \ + ((ErrorSaveContext *) (escontext))->error_occurred) + +#endif /* MISCNODES_H */ diff --git a/install/include/postgresql/server/nodes/multibitmapset.h b/install/include/postgresql/server/nodes/multibitmapset.h new file mode 100644 index 00000000000..505f017d688 --- /dev/null +++ b/install/include/postgresql/server/nodes/multibitmapset.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * multibitmapset.h + * Lists of Bitmapsets + * + * A multibitmapset is useful in situations where members of a set can + * be identified by two small integers; for example, varno and varattno + * of a group of Vars within a query. The implementation is a List of + * Bitmapsets, so that the empty set can be represented by NIL. (But, + * as with Bitmapsets, that's not the only allowed representation.) + * The zero-based index of a List element is the first identifying value, + * and the (also zero-based) index of a bit within that Bitmapset is + * the second identifying value. There is no expectation that the + * Bitmapsets should all be the same size. + * + * The available operations on multibitmapsets are intended to parallel + * those on bitmapsets, for example union and intersection. So far only + * a small fraction of that has been built out; we'll add more as needed. + * + * + * Copyright (c) 2022-2023, PostgreSQL Global Development Group + * + * src/include/nodes/multibitmapset.h + * + *------------------------------------------------------------------------- + */ +#ifndef MULTIBITMAPSET_H +#define MULTIBITMAPSET_H + +#include "nodes/bitmapset.h" +#include "nodes/pg_list.h" + +extern List *mbms_add_member(List *a, int listidx, int bitidx); +extern List *mbms_add_members(List *a, const List *b); +extern List *mbms_int_members(List *a, const List *b); +extern bool mbms_is_member(int listidx, int bitidx, const List *a); +extern Bitmapset *mbms_overlap_sets(const List *a, const List *b); + +#endif /* MULTIBITMAPSET_H */ diff --git a/install/include/postgresql/server/nodes/nodeFuncs.h b/install/include/postgresql/server/nodes/nodeFuncs.h new file mode 100644 index 00000000000..20921b45b9e --- /dev/null +++ b/install/include/postgresql/server/nodes/nodeFuncs.h @@ -0,0 +1,222 @@ +/*------------------------------------------------------------------------- + * + * nodeFuncs.h + * Various general-purpose manipulations of Node trees + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/nodeFuncs.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODEFUNCS_H +#define NODEFUNCS_H + +#include "nodes/parsenodes.h" + +struct PlanState; /* avoid including execnodes.h too */ + + +/* flags bits for query_tree_walker and query_tree_mutator */ +#define QTW_IGNORE_RT_SUBQUERIES 0x01 /* subqueries in rtable */ +#define QTW_IGNORE_CTE_SUBQUERIES 0x02 /* subqueries in cteList */ +#define QTW_IGNORE_RC_SUBQUERIES 0x03 /* both of above */ +#define QTW_IGNORE_JOINALIASES 0x04 /* JOIN alias var lists */ +#define QTW_IGNORE_RANGE_TABLE 0x08 /* skip rangetable entirely */ +#define QTW_EXAMINE_RTES_BEFORE 0x10 /* examine RTE nodes before their + * contents */ +#define QTW_EXAMINE_RTES_AFTER 0x20 /* examine RTE nodes after their + * contents */ +#define QTW_DONT_COPY_QUERY 0x40 /* do not copy top Query */ +#define QTW_EXAMINE_SORTGROUP 0x80 /* include SortGroupClause lists */ + +/* callback function for check_functions_in_node */ +typedef bool (*check_function_callback) (Oid func_id, void *context); + +/* callback functions for tree walkers */ +typedef bool (*tree_walker_callback) (Node *node, void *context); +typedef bool (*planstate_tree_walker_callback) (struct PlanState *planstate, + void *context); + +/* callback functions for tree mutators */ +typedef Node *(*tree_mutator_callback) (Node *node, void *context); + + +extern Oid exprType(const Node *expr); +extern int32 exprTypmod(const Node *expr); +extern bool exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod); +extern Node *applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, + CoercionForm rformat, int rlocation, + bool overwrite_ok); +extern Node *relabel_to_typmod(Node *expr, int32 typmod); +extern Node *strip_implicit_coercions(Node *node); +extern bool expression_returns_set(Node *clause); + +extern Oid exprCollation(const Node *expr); +extern Oid exprInputCollation(const Node *expr); +extern void exprSetCollation(Node *expr, Oid collation); +extern void exprSetInputCollation(Node *expr, Oid inputcollation); + +extern int exprLocation(const Node *expr); + +extern void fix_opfuncids(Node *node); +extern void set_opfuncid(OpExpr *opexpr); +extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr); + +/* Is clause a FuncExpr clause? */ +static inline bool +is_funcclause(const void *clause) +{ + return clause != NULL && IsA(clause, FuncExpr); +} + +/* Is clause an OpExpr clause? */ +static inline bool +is_opclause(const void *clause) +{ + return clause != NULL && IsA(clause, OpExpr); +} + +/* Extract left arg of a binary opclause, or only arg of a unary opclause */ +static inline Node * +get_leftop(const void *clause) +{ + const OpExpr *expr = (const OpExpr *) clause; + + if (expr->args != NIL) + return (Node *) linitial(expr->args); + else + return NULL; +} + +/* Extract right arg of a binary opclause (NULL if it's a unary opclause) */ +static inline Node * +get_rightop(const void *clause) +{ + const OpExpr *expr = (const OpExpr *) clause; + + if (list_length(expr->args) >= 2) + return (Node *) lsecond(expr->args); + else + return NULL; +} + +/* Is clause an AND clause? */ +static inline bool +is_andclause(const void *clause) +{ + return (clause != NULL && + IsA(clause, BoolExpr) && + ((const BoolExpr *) clause)->boolop == AND_EXPR); +} + +/* Is clause an OR clause? */ +static inline bool +is_orclause(const void *clause) +{ + return (clause != NULL && + IsA(clause, BoolExpr) && + ((const BoolExpr *) clause)->boolop == OR_EXPR); +} + +/* Is clause a NOT clause? */ +static inline bool +is_notclause(const void *clause) +{ + return (clause != NULL && + IsA(clause, BoolExpr) && + ((const BoolExpr *) clause)->boolop == NOT_EXPR); +} + +/* Extract argument from a clause known to be a NOT clause */ +static inline Expr * +get_notclausearg(const void *notclause) +{ + return (Expr *) linitial(((const BoolExpr *) notclause)->args); +} + +extern bool check_functions_in_node(Node *node, check_function_callback checker, + void *context); + +/* + * The following functions are usually passed walker or mutator callbacks + * that are declared like "bool walker(Node *node, my_struct *context)" + * rather than "bool walker(Node *node, void *context)" as a strict reading + * of the C standard would require. Changing the callbacks' declarations + * to "void *" would create serious hazards of passing them the wrong context + * struct type, so we respectfully decline to support the standard's position + * that a pointer to struct is incompatible with "void *". Instead, silence + * related compiler warnings by inserting casts into these macro wrappers. + */ + +#define expression_tree_walker(n, w, c) \ + expression_tree_walker_impl(n, (tree_walker_callback) (w), c) +#define expression_tree_mutator(n, m, c) \ + expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c) + +#define query_tree_walker(q, w, c, f) \ + query_tree_walker_impl(q, (tree_walker_callback) (w), c, f) +#define query_tree_mutator(q, m, c, f) \ + query_tree_mutator_impl(q, (tree_mutator_callback) (m), c, f) + +#define range_table_walker(rt, w, c, f) \ + range_table_walker_impl(rt, (tree_walker_callback) (w), c, f) +#define range_table_mutator(rt, m, c, f) \ + range_table_mutator_impl(rt, (tree_mutator_callback) (m), c, f) + +#define range_table_entry_walker(r, w, c, f) \ + range_table_entry_walker_impl(r, (tree_walker_callback) (w), c, f) + +#define query_or_expression_tree_walker(n, w, c, f) \ + query_or_expression_tree_walker_impl(n, (tree_walker_callback) (w), c, f) +#define query_or_expression_tree_mutator(n, m, c, f) \ + query_or_expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c, f) + +#define raw_expression_tree_walker(n, w, c) \ + raw_expression_tree_walker_impl(n, (tree_walker_callback) (w), c) + +#define planstate_tree_walker(ps, w, c) \ + planstate_tree_walker_impl(ps, (planstate_tree_walker_callback) (w), c) + +extern bool expression_tree_walker_impl(Node *node, + tree_walker_callback walker, + void *context); +extern Node *expression_tree_mutator_impl(Node *node, + tree_mutator_callback mutator, + void *context); + +extern bool query_tree_walker_impl(Query *query, + tree_walker_callback walker, + void *context, int flags); +extern Query *query_tree_mutator_impl(Query *query, + tree_mutator_callback mutator, + void *context, int flags); + +extern bool range_table_walker_impl(List *rtable, + tree_walker_callback walker, + void *context, int flags); +extern List *range_table_mutator_impl(List *rtable, + tree_mutator_callback mutator, + void *context, int flags); + +extern bool range_table_entry_walker_impl(RangeTblEntry *rte, + tree_walker_callback walker, + void *context, int flags); + +extern bool query_or_expression_tree_walker_impl(Node *node, + tree_walker_callback walker, + void *context, int flags); +extern Node *query_or_expression_tree_mutator_impl(Node *node, + tree_mutator_callback mutator, + void *context, int flags); + +extern bool raw_expression_tree_walker_impl(Node *node, + tree_walker_callback walker, + void *context); + +extern bool planstate_tree_walker_impl(struct PlanState *planstate, + planstate_tree_walker_callback walker, + void *context); + +#endif /* NODEFUNCS_H */ diff --git a/install/include/postgresql/server/nodes/nodes.h b/install/include/postgresql/server/nodes/nodes.h new file mode 100644 index 00000000000..f8e8fe699ab --- /dev/null +++ b/install/include/postgresql/server/nodes/nodes.h @@ -0,0 +1,446 @@ +/*------------------------------------------------------------------------- + * + * nodes.h + * Definitions for tagged nodes. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/nodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef NODES_H +#define NODES_H + +/* + * The first field of every node is NodeTag. Each node created (with makeNode) + * will have one of the following tags as the value of its first field. + * + * Note that inserting or deleting node types changes the numbers of other + * node types later in the list. This is no problem during development, since + * the node numbers are never stored on disk. But don't do it in a released + * branch, because that would represent an ABI break for extensions. + */ +typedef enum NodeTag +{ + T_Invalid = 0, + +#include "nodes/nodetags.h" +} NodeTag; + +/* + * pg_node_attr() - Used in node definitions to set extra information for + * gen_node_support.pl + * + * Attributes can be attached to a node as a whole (place the attribute + * specification on the first line after the struct's opening brace) + * or to a specific field (place it at the end of that field's line). The + * argument is a comma-separated list of attributes. Unrecognized attributes + * cause an error. + * + * Valid node attributes: + * + * - abstract: Abstract types are types that cannot be instantiated but that + * can be supertypes of other types. We track their fields, so that + * subtypes can use them, but we don't emit a node tag, so you can't + * instantiate them. + * + * - custom_copy_equal: Has custom implementations in copyfuncs.c and + * equalfuncs.c. + * + * - custom_read_write: Has custom implementations in outfuncs.c and + * readfuncs.c. + * + * - custom_query_jumble: Has custom implementation in queryjumblefuncs.c. + * + * - no_copy: Does not support copyObject() at all. + * + * - no_equal: Does not support equal() at all. + * + * - no_copy_equal: Shorthand for both no_copy and no_equal. + * + * - no_query_jumble: Does not support JumbleQuery() at all. + * + * - no_read: Does not support nodeRead() at all. + * + * - nodetag_only: Does not support copyObject(), equal(), jumbleQuery() + * outNode() or nodeRead(). + * + * - special_read_write: Has special treatment in outNode() and nodeRead(). + * + * - nodetag_number(VALUE): assign the specified nodetag number instead of + * an auto-generated number. Typically this would only be used in stable + * branches, to give a newly-added node type a number without breaking ABI + * by changing the numbers of existing node types. + * + * Node types can be supertypes of other types whether or not they are marked + * abstract: if a node struct appears as the first field of another struct + * type, then it is the supertype of that type. The no_copy, no_equal, + * no_query_jumble and no_read node attributes are automatically inherited + * from the supertype. (Notice that nodetag_only does not inherit, so it's + * not quite equivalent to a combination of other attributes.) + * + * Valid node field attributes: + * + * - array_size(OTHERFIELD): This field is a dynamically allocated array with + * size indicated by the mentioned other field. The other field is either a + * scalar or a list, in which case the length of the list is used. + * + * - copy_as(VALUE): In copyObject(), replace the field's value with VALUE. + * + * - copy_as_scalar: In copyObject(), copy the field as a scalar value + * (e.g. a pointer) even if it is a node-type pointer. + * + * - equal_as_scalar: In equal(), compare the field as a scalar value + * even if it is a node-type pointer. + * + * - equal_ignore: Ignore the field for equality. + * + * - equal_ignore_if_zero: Ignore the field for equality if it is zero. + * (Otherwise, compare normally.) + * + * - query_jumble_ignore: Ignore the field for the query jumbling. Note + * that typmod and collation information are usually irrelevant for the + * query jumbling. + * + * - query_jumble_location: Mark the field as a location to track. This is + * only allowed for integer fields that include "location" in their name. + * + * - read_as(VALUE): In nodeRead(), replace the field's value with VALUE. + * + * - read_write_ignore: Ignore the field for read/write. This is only allowed + * if the node type is marked no_read or read_as() is also specified. + * + * - write_only_relids, write_only_nondefault_pathtarget, write_only_req_outer: + * Special handling for Path struct; see there. + * + */ +#define pg_node_attr(...) + +/* + * The first field of a node of any type is guaranteed to be the NodeTag. + * Hence the type of any node can be gotten by casting it to Node. Declaring + * a variable to be of Node * (instead of void *) can also facilitate + * debugging. + */ +typedef struct Node +{ + NodeTag type; +} Node; + +#define nodeTag(nodeptr) (((const Node*)(nodeptr))->type) + +/* + * newNode - + * create a new node of the specified size and tag the node with the + * specified tag. + * + * !WARNING!: Avoid using newNode directly. You should be using the + * macro makeNode. eg. to create a Query node, use makeNode(Query) + * + * Note: the size argument should always be a compile-time constant, so the + * apparent risk of multiple evaluation doesn't matter in practice. + */ +#ifdef __GNUC__ + +/* With GCC, we can use a compound statement within an expression */ +#define newNode(size, tag) \ +({ Node *_result; \ + AssertMacro((size) >= sizeof(Node)); /* need the tag, at least */ \ + _result = (Node *) palloc0fast(size); \ + _result->type = (tag); \ + _result; \ +}) +#else + +/* + * There is no way to dereference the palloc'ed pointer to assign the + * tag, and also return the pointer itself, so we need a holder variable. + * Fortunately, this macro isn't recursive so we just define + * a global variable for this purpose. + */ +extern PGDLLIMPORT Node *newNodeMacroHolder; + +#define newNode(size, tag) \ +( \ + AssertMacro((size) >= sizeof(Node)), /* need the tag, at least */ \ + newNodeMacroHolder = (Node *) palloc0fast(size), \ + newNodeMacroHolder->type = (tag), \ + newNodeMacroHolder \ +) +#endif /* __GNUC__ */ + + +#define makeNode(_type_) ((_type_ *) newNode(sizeof(_type_),T_##_type_)) +#define NodeSetTag(nodeptr,t) (((Node*)(nodeptr))->type = (t)) + +#define IsA(nodeptr,_type_) (nodeTag(nodeptr) == T_##_type_) + +/* + * castNode(type, ptr) casts ptr to "type *", and if assertions are enabled, + * verifies that the node has the appropriate type (using its nodeTag()). + * + * Use an inline function when assertions are enabled, to avoid multiple + * evaluations of the ptr argument (which could e.g. be a function call). + */ +#ifdef USE_ASSERT_CHECKING +static inline Node * +castNodeImpl(NodeTag type, void *ptr) +{ + Assert(ptr == NULL || nodeTag(ptr) == type); + return (Node *) ptr; +} +#define castNode(_type_, nodeptr) ((_type_ *) castNodeImpl(T_##_type_, nodeptr)) +#else +#define castNode(_type_, nodeptr) ((_type_ *) (nodeptr)) +#endif /* USE_ASSERT_CHECKING */ + + +/* ---------------------------------------------------------------- + * extern declarations follow + * ---------------------------------------------------------------- + */ + +/* + * nodes/{outfuncs.c,print.c} + */ +struct Bitmapset; /* not to include bitmapset.h here */ +struct StringInfoData; /* not to include stringinfo.h here */ + +extern void outNode(struct StringInfoData *str, const void *obj); +extern void outToken(struct StringInfoData *str, const char *s); +extern void outBitmapset(struct StringInfoData *str, + const struct Bitmapset *bms); +extern void outDatum(struct StringInfoData *str, uintptr_t value, + int typlen, bool typbyval); +extern char *nodeToString(const void *obj); +extern char *bmsToString(const struct Bitmapset *bms); + +/* + * nodes/{readfuncs.c,read.c} + */ +extern void *stringToNode(const char *str); +#ifdef WRITE_READ_PARSE_PLAN_TREES +extern void *stringToNodeWithLocations(const char *str); +#endif +extern struct Bitmapset *readBitmapset(void); +extern uintptr_t readDatum(bool typbyval); +extern bool *readBoolCols(int numCols); +extern int *readIntCols(int numCols); +extern Oid *readOidCols(int numCols); +extern int16 *readAttrNumberCols(int numCols); + +/* + * nodes/copyfuncs.c + */ +extern void *copyObjectImpl(const void *from); + +/* cast result back to argument type, if supported by compiler */ +#ifdef HAVE_TYPEOF +#define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj)) +#else +#define copyObject(obj) copyObjectImpl(obj) +#endif + +/* + * nodes/equalfuncs.c + */ +extern bool equal(const void *a, const void *b); + + +/* + * Typedefs for identifying qualifier selectivities and plan costs as such. + * These are just plain "double"s, but declaring a variable as Selectivity + * or Cost makes the intent more obvious. + * + * These could have gone into plannodes.h or some such, but many files + * depend on them... + */ +typedef double Selectivity; /* fraction of tuples a qualifier will pass */ +typedef double Cost; /* execution cost (in page-access units) */ +typedef double Cardinality; /* (estimated) number of rows or other integer + * count */ + + +/* + * CmdType - + * enums for type of operation represented by a Query or PlannedStmt + * + * This is needed in both parsenodes.h and plannodes.h, so put it here... + */ +typedef enum CmdType +{ + CMD_UNKNOWN, + CMD_SELECT, /* select stmt */ + CMD_UPDATE, /* update stmt */ + CMD_INSERT, /* insert stmt */ + CMD_DELETE, /* delete stmt */ + CMD_MERGE, /* merge stmt */ + CMD_UTILITY, /* cmds like create, destroy, copy, vacuum, + * etc. */ + CMD_NOTHING /* dummy command for instead nothing rules + * with qual */ +} CmdType; + + +/* + * JoinType - + * enums for types of relation joins + * + * JoinType determines the exact semantics of joining two relations using + * a matching qualification. For example, it tells what to do with a tuple + * that has no match in the other relation. + * + * This is needed in both parsenodes.h and plannodes.h, so put it here... + */ +typedef enum JoinType +{ + /* + * The canonical kinds of joins according to the SQL JOIN syntax. Only + * these codes can appear in parser output (e.g., JoinExpr nodes). + */ + JOIN_INNER, /* matching tuple pairs only */ + JOIN_LEFT, /* pairs + unmatched LHS tuples */ + JOIN_FULL, /* pairs + unmatched LHS + unmatched RHS */ + JOIN_RIGHT, /* pairs + unmatched RHS tuples */ + + /* + * Semijoins and anti-semijoins (as defined in relational theory) do not + * appear in the SQL JOIN syntax, but there are standard idioms for + * representing them (e.g., using EXISTS). The planner recognizes these + * cases and converts them to joins. So the planner and executor must + * support these codes. NOTE: in JOIN_SEMI output, it is unspecified + * which matching RHS row is joined to. In JOIN_ANTI output, the row is + * guaranteed to be null-extended. + */ + JOIN_SEMI, /* 1 copy of each LHS row that has match(es) */ + JOIN_ANTI, /* 1 copy of each LHS row that has no match */ + JOIN_RIGHT_ANTI, /* 1 copy of each RHS row that has no match */ + + /* + * These codes are used internally in the planner, but are not supported + * by the executor (nor, indeed, by most of the planner). + */ + JOIN_UNIQUE_OUTER, /* LHS path must be made unique */ + JOIN_UNIQUE_INNER /* RHS path must be made unique */ + + /* + * We might need additional join types someday. + */ +} JoinType; + +/* + * OUTER joins are those for which pushed-down quals must behave differently + * from the join's own quals. This is in fact everything except INNER and + * SEMI joins. However, this macro must also exclude the JOIN_UNIQUE symbols + * since those are temporary proxies for what will eventually be an INNER + * join. + * + * Note: semijoins are a hybrid case, but we choose to treat them as not + * being outer joins. This is okay principally because the SQL syntax makes + * it impossible to have a pushed-down qual that refers to the inner relation + * of a semijoin; so there is no strong need to distinguish join quals from + * pushed-down quals. This is convenient because for almost all purposes, + * quals attached to a semijoin can be treated the same as innerjoin quals. + */ +#define IS_OUTER_JOIN(jointype) \ + (((1 << (jointype)) & \ + ((1 << JOIN_LEFT) | \ + (1 << JOIN_FULL) | \ + (1 << JOIN_RIGHT) | \ + (1 << JOIN_ANTI) | \ + (1 << JOIN_RIGHT_ANTI))) != 0) + +/* + * AggStrategy - + * overall execution strategies for Agg plan nodes + * + * This is needed in both pathnodes.h and plannodes.h, so put it here... + */ +typedef enum AggStrategy +{ + AGG_PLAIN, /* simple agg across all input rows */ + AGG_SORTED, /* grouped agg, input must be sorted */ + AGG_HASHED, /* grouped agg, use internal hashtable */ + AGG_MIXED /* grouped agg, hash and sort both used */ +} AggStrategy; + +/* + * AggSplit - + * splitting (partial aggregation) modes for Agg plan nodes + * + * This is needed in both pathnodes.h and plannodes.h, so put it here... + */ + +/* Primitive options supported by nodeAgg.c: */ +#define AGGSPLITOP_COMBINE 0x01 /* substitute combinefn for transfn */ +#define AGGSPLITOP_SKIPFINAL 0x02 /* skip finalfn, return state as-is */ +#define AGGSPLITOP_SERIALIZE 0x04 /* apply serialfn to output */ +#define AGGSPLITOP_DESERIALIZE 0x08 /* apply deserialfn to input */ + +/* Supported operating modes (i.e., useful combinations of these options): */ +typedef enum AggSplit +{ + /* Basic, non-split aggregation: */ + AGGSPLIT_SIMPLE = 0, + /* Initial phase of partial aggregation, with serialization: */ + AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE, + /* Final phase of partial aggregation, with deserialization: */ + AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE +} AggSplit; + +/* Test whether an AggSplit value selects each primitive option: */ +#define DO_AGGSPLIT_COMBINE(as) (((as) & AGGSPLITOP_COMBINE) != 0) +#define DO_AGGSPLIT_SKIPFINAL(as) (((as) & AGGSPLITOP_SKIPFINAL) != 0) +#define DO_AGGSPLIT_SERIALIZE(as) (((as) & AGGSPLITOP_SERIALIZE) != 0) +#define DO_AGGSPLIT_DESERIALIZE(as) (((as) & AGGSPLITOP_DESERIALIZE) != 0) + +/* + * SetOpCmd and SetOpStrategy - + * overall semantics and execution strategies for SetOp plan nodes + * + * This is needed in both pathnodes.h and plannodes.h, so put it here... + */ +typedef enum SetOpCmd +{ + SETOPCMD_INTERSECT, + SETOPCMD_INTERSECT_ALL, + SETOPCMD_EXCEPT, + SETOPCMD_EXCEPT_ALL +} SetOpCmd; + +typedef enum SetOpStrategy +{ + SETOP_SORTED, /* input must be sorted */ + SETOP_HASHED /* use internal hashtable */ +} SetOpStrategy; + +/* + * OnConflictAction - + * "ON CONFLICT" clause type of query + * + * This is needed in both parsenodes.h and plannodes.h, so put it here... + */ +typedef enum OnConflictAction +{ + ONCONFLICT_NONE, /* No "ON CONFLICT" clause */ + ONCONFLICT_NOTHING, /* ON CONFLICT ... DO NOTHING */ + ONCONFLICT_UPDATE /* ON CONFLICT ... DO UPDATE */ +} OnConflictAction; + +/* + * LimitOption - + * LIMIT option of query + * + * This is needed in both parsenodes.h and plannodes.h, so put it here... + */ +typedef enum LimitOption +{ + LIMIT_OPTION_COUNT, /* FETCH FIRST... ONLY */ + LIMIT_OPTION_WITH_TIES, /* FETCH FIRST... WITH TIES */ + LIMIT_OPTION_DEFAULT, /* No limit present */ +} LimitOption; + +#endif /* NODES_H */ diff --git a/install/include/postgresql/server/nodes/nodetags.h b/install/include/postgresql/server/nodes/nodetags.h new file mode 100644 index 00000000000..f75ac7a05ee --- /dev/null +++ b/install/include/postgresql/server/nodes/nodetags.h @@ -0,0 +1,471 @@ +/*------------------------------------------------------------------------- + * + * nodetags.h + * Generated node infrastructure code + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/nodes/gen_node_support.pl + * + *------------------------------------------------------------------------- + */ + T_List = 1, + T_Alias = 2, + T_RangeVar = 3, + T_TableFunc = 4, + T_IntoClause = 5, + T_Var = 6, + T_Const = 7, + T_Param = 8, + T_Aggref = 9, + T_GroupingFunc = 10, + T_WindowFunc = 11, + T_SubscriptingRef = 12, + T_FuncExpr = 13, + T_NamedArgExpr = 14, + T_OpExpr = 15, + T_DistinctExpr = 16, + T_NullIfExpr = 17, + T_ScalarArrayOpExpr = 18, + T_BoolExpr = 19, + T_SubLink = 20, + T_SubPlan = 21, + T_AlternativeSubPlan = 22, + T_FieldSelect = 23, + T_FieldStore = 24, + T_RelabelType = 25, + T_CoerceViaIO = 26, + T_ArrayCoerceExpr = 27, + T_ConvertRowtypeExpr = 28, + T_CollateExpr = 29, + T_CaseExpr = 30, + T_CaseWhen = 31, + T_CaseTestExpr = 32, + T_ArrayExpr = 33, + T_RowExpr = 34, + T_RowCompareExpr = 35, + T_CoalesceExpr = 36, + T_MinMaxExpr = 37, + T_SQLValueFunction = 38, + T_XmlExpr = 39, + T_JsonFormat = 40, + T_JsonReturning = 41, + T_JsonValueExpr = 42, + T_JsonConstructorExpr = 43, + T_JsonIsPredicate = 44, + T_NullTest = 45, + T_BooleanTest = 46, + T_CoerceToDomain = 47, + T_CoerceToDomainValue = 48, + T_SetToDefault = 49, + T_CurrentOfExpr = 50, + T_NextValueExpr = 51, + T_InferenceElem = 52, + T_TargetEntry = 53, + T_RangeTblRef = 54, + T_JoinExpr = 55, + T_FromExpr = 56, + T_OnConflictExpr = 57, + T_Query = 58, + T_TypeName = 59, + T_ColumnRef = 60, + T_ParamRef = 61, + T_A_Expr = 62, + T_A_Const = 63, + T_TypeCast = 64, + T_CollateClause = 65, + T_RoleSpec = 66, + T_FuncCall = 67, + T_A_Star = 68, + T_A_Indices = 69, + T_A_Indirection = 70, + T_A_ArrayExpr = 71, + T_ResTarget = 72, + T_MultiAssignRef = 73, + T_SortBy = 74, + T_WindowDef = 75, + T_RangeSubselect = 76, + T_RangeFunction = 77, + T_RangeTableFunc = 78, + T_RangeTableFuncCol = 79, + T_RangeTableSample = 80, + T_ColumnDef = 81, + T_TableLikeClause = 82, + T_IndexElem = 83, + T_DefElem = 84, + T_LockingClause = 85, + T_XmlSerialize = 86, + T_PartitionElem = 87, + T_PartitionSpec = 88, + T_PartitionBoundSpec = 89, + T_PartitionRangeDatum = 90, + T_PartitionCmd = 91, + T_RangeTblEntry = 92, + T_RTEPermissionInfo = 93, + T_RangeTblFunction = 94, + T_TableSampleClause = 95, + T_WithCheckOption = 96, + T_SortGroupClause = 97, + T_GroupingSet = 98, + T_WindowClause = 99, + T_RowMarkClause = 100, + T_WithClause = 101, + T_InferClause = 102, + T_OnConflictClause = 103, + T_CTESearchClause = 104, + T_CTECycleClause = 105, + T_CommonTableExpr = 106, + T_MergeWhenClause = 107, + T_MergeAction = 108, + T_TriggerTransition = 109, + T_JsonOutput = 110, + T_JsonKeyValue = 111, + T_JsonObjectConstructor = 112, + T_JsonArrayConstructor = 113, + T_JsonArrayQueryConstructor = 114, + T_JsonAggConstructor = 115, + T_JsonObjectAgg = 116, + T_JsonArrayAgg = 117, + T_RawStmt = 118, + T_InsertStmt = 119, + T_DeleteStmt = 120, + T_UpdateStmt = 121, + T_MergeStmt = 122, + T_SelectStmt = 123, + T_SetOperationStmt = 124, + T_ReturnStmt = 125, + T_PLAssignStmt = 126, + T_CreateSchemaStmt = 127, + T_AlterTableStmt = 128, + T_ReplicaIdentityStmt = 129, + T_AlterTableCmd = 130, + T_AlterCollationStmt = 131, + T_AlterDomainStmt = 132, + T_GrantStmt = 133, + T_ObjectWithArgs = 134, + T_AccessPriv = 135, + T_GrantRoleStmt = 136, + T_AlterDefaultPrivilegesStmt = 137, + T_CopyStmt = 138, + T_VariableSetStmt = 139, + T_VariableShowStmt = 140, + T_CreateStmt = 141, + T_Constraint = 142, + T_CreateTableSpaceStmt = 143, + T_DropTableSpaceStmt = 144, + T_AlterTableSpaceOptionsStmt = 145, + T_AlterTableMoveAllStmt = 146, + T_CreateExtensionStmt = 147, + T_AlterExtensionStmt = 148, + T_AlterExtensionContentsStmt = 149, + T_CreateFdwStmt = 150, + T_AlterFdwStmt = 151, + T_CreateForeignServerStmt = 152, + T_AlterForeignServerStmt = 153, + T_CreateForeignTableStmt = 154, + T_CreateUserMappingStmt = 155, + T_AlterUserMappingStmt = 156, + T_DropUserMappingStmt = 157, + T_ImportForeignSchemaStmt = 158, + T_CreatePolicyStmt = 159, + T_AlterPolicyStmt = 160, + T_CreateAmStmt = 161, + T_CreateTrigStmt = 162, + T_CreateEventTrigStmt = 163, + T_AlterEventTrigStmt = 164, + T_CreatePLangStmt = 165, + T_CreateRoleStmt = 166, + T_AlterRoleStmt = 167, + T_AlterRoleSetStmt = 168, + T_DropRoleStmt = 169, + T_CreateSeqStmt = 170, + T_AlterSeqStmt = 171, + T_DefineStmt = 172, + T_CreateDomainStmt = 173, + T_CreateOpClassStmt = 174, + T_CreateOpClassItem = 175, + T_CreateOpFamilyStmt = 176, + T_AlterOpFamilyStmt = 177, + T_DropStmt = 178, + T_TruncateStmt = 179, + T_CommentStmt = 180, + T_SecLabelStmt = 181, + T_DeclareCursorStmt = 182, + T_ClosePortalStmt = 183, + T_FetchStmt = 184, + T_IndexStmt = 185, + T_CreateStatsStmt = 186, + T_StatsElem = 187, + T_AlterStatsStmt = 188, + T_CreateFunctionStmt = 189, + T_FunctionParameter = 190, + T_AlterFunctionStmt = 191, + T_DoStmt = 192, + T_InlineCodeBlock = 193, + T_CallStmt = 194, + T_CallContext = 195, + T_RenameStmt = 196, + T_AlterObjectDependsStmt = 197, + T_AlterObjectSchemaStmt = 198, + T_AlterOwnerStmt = 199, + T_AlterOperatorStmt = 200, + T_AlterTypeStmt = 201, + T_RuleStmt = 202, + T_NotifyStmt = 203, + T_ListenStmt = 204, + T_UnlistenStmt = 205, + T_TransactionStmt = 206, + T_CompositeTypeStmt = 207, + T_CreateEnumStmt = 208, + T_CreateRangeStmt = 209, + T_AlterEnumStmt = 210, + T_ViewStmt = 211, + T_LoadStmt = 212, + T_CreatedbStmt = 213, + T_AlterDatabaseStmt = 214, + T_AlterDatabaseRefreshCollStmt = 215, + T_AlterDatabaseSetStmt = 216, + T_DropdbStmt = 217, + T_AlterSystemStmt = 218, + T_ClusterStmt = 219, + T_VacuumStmt = 220, + T_VacuumRelation = 221, + T_ExplainStmt = 222, + T_CreateTableAsStmt = 223, + T_RefreshMatViewStmt = 224, + T_CheckPointStmt = 225, + T_DiscardStmt = 226, + T_LockStmt = 227, + T_ConstraintsSetStmt = 228, + T_ReindexStmt = 229, + T_CreateConversionStmt = 230, + T_CreateCastStmt = 231, + T_CreateTransformStmt = 232, + T_PrepareStmt = 233, + T_ExecuteStmt = 234, + T_DeallocateStmt = 235, + T_DropOwnedStmt = 236, + T_ReassignOwnedStmt = 237, + T_AlterTSDictionaryStmt = 238, + T_AlterTSConfigurationStmt = 239, + T_PublicationTable = 240, + T_PublicationObjSpec = 241, + T_CreatePublicationStmt = 242, + T_AlterPublicationStmt = 243, + T_CreateSubscriptionStmt = 244, + T_AlterSubscriptionStmt = 245, + T_DropSubscriptionStmt = 246, + T_PlannerGlobal = 247, + T_PlannerInfo = 248, + T_RelOptInfo = 249, + T_IndexOptInfo = 250, + T_ForeignKeyOptInfo = 251, + T_StatisticExtInfo = 252, + T_JoinDomain = 253, + T_EquivalenceClass = 254, + T_EquivalenceMember = 255, + T_PathKey = 256, + T_PathTarget = 257, + T_ParamPathInfo = 258, + T_Path = 259, + T_IndexPath = 260, + T_IndexClause = 261, + T_BitmapHeapPath = 262, + T_BitmapAndPath = 263, + T_BitmapOrPath = 264, + T_TidPath = 265, + T_TidRangePath = 266, + T_SubqueryScanPath = 267, + T_ForeignPath = 268, + T_CustomPath = 269, + T_AppendPath = 270, + T_MergeAppendPath = 271, + T_GroupResultPath = 272, + T_MaterialPath = 273, + T_MemoizePath = 274, + T_UniquePath = 275, + T_GatherPath = 276, + T_GatherMergePath = 277, + T_NestPath = 278, + T_MergePath = 279, + T_HashPath = 280, + T_ProjectionPath = 281, + T_ProjectSetPath = 282, + T_SortPath = 283, + T_IncrementalSortPath = 284, + T_GroupPath = 285, + T_UpperUniquePath = 286, + T_AggPath = 287, + T_GroupingSetData = 288, + T_RollupData = 289, + T_GroupingSetsPath = 290, + T_MinMaxAggPath = 291, + T_WindowAggPath = 292, + T_SetOpPath = 293, + T_RecursiveUnionPath = 294, + T_LockRowsPath = 295, + T_ModifyTablePath = 296, + T_LimitPath = 297, + T_RestrictInfo = 298, + T_PlaceHolderVar = 299, + T_SpecialJoinInfo = 300, + T_OuterJoinClauseInfo = 301, + T_AppendRelInfo = 302, + T_RowIdentityVarInfo = 303, + T_PlaceHolderInfo = 304, + T_MinMaxAggInfo = 305, + T_PlannerParamItem = 306, + T_AggInfo = 307, + T_AggTransInfo = 308, + T_PlannedStmt = 309, + T_Result = 310, + T_ProjectSet = 311, + T_ModifyTable = 312, + T_Append = 313, + T_MergeAppend = 314, + T_RecursiveUnion = 315, + T_BitmapAnd = 316, + T_BitmapOr = 317, + T_SeqScan = 318, + T_SampleScan = 319, + T_IndexScan = 320, + T_IndexOnlyScan = 321, + T_BitmapIndexScan = 322, + T_BitmapHeapScan = 323, + T_TidScan = 324, + T_TidRangeScan = 325, + T_SubqueryScan = 326, + T_FunctionScan = 327, + T_ValuesScan = 328, + T_TableFuncScan = 329, + T_CteScan = 330, + T_NamedTuplestoreScan = 331, + T_WorkTableScan = 332, + T_ForeignScan = 333, + T_CustomScan = 334, + T_NestLoop = 335, + T_NestLoopParam = 336, + T_MergeJoin = 337, + T_HashJoin = 338, + T_Material = 339, + T_Memoize = 340, + T_Sort = 341, + T_IncrementalSort = 342, + T_Group = 343, + T_Agg = 344, + T_WindowAgg = 345, + T_Unique = 346, + T_Gather = 347, + T_GatherMerge = 348, + T_Hash = 349, + T_SetOp = 350, + T_LockRows = 351, + T_Limit = 352, + T_PlanRowMark = 353, + T_PartitionPruneInfo = 354, + T_PartitionedRelPruneInfo = 355, + T_PartitionPruneStepOp = 356, + T_PartitionPruneStepCombine = 357, + T_PlanInvalItem = 358, + T_ExprState = 359, + T_IndexInfo = 360, + T_ExprContext = 361, + T_ReturnSetInfo = 362, + T_ProjectionInfo = 363, + T_JunkFilter = 364, + T_OnConflictSetState = 365, + T_MergeActionState = 366, + T_ResultRelInfo = 367, + T_EState = 368, + T_WindowFuncExprState = 369, + T_SetExprState = 370, + T_SubPlanState = 371, + T_DomainConstraintState = 372, + T_ResultState = 373, + T_ProjectSetState = 374, + T_ModifyTableState = 375, + T_AppendState = 376, + T_MergeAppendState = 377, + T_RecursiveUnionState = 378, + T_BitmapAndState = 379, + T_BitmapOrState = 380, + T_ScanState = 381, + T_SeqScanState = 382, + T_SampleScanState = 383, + T_IndexScanState = 384, + T_IndexOnlyScanState = 385, + T_BitmapIndexScanState = 386, + T_BitmapHeapScanState = 387, + T_TidScanState = 388, + T_TidRangeScanState = 389, + T_SubqueryScanState = 390, + T_FunctionScanState = 391, + T_ValuesScanState = 392, + T_TableFuncScanState = 393, + T_CteScanState = 394, + T_NamedTuplestoreScanState = 395, + T_WorkTableScanState = 396, + T_ForeignScanState = 397, + T_CustomScanState = 398, + T_JoinState = 399, + T_NestLoopState = 400, + T_MergeJoinState = 401, + T_HashJoinState = 402, + T_MaterialState = 403, + T_MemoizeState = 404, + T_SortState = 405, + T_IncrementalSortState = 406, + T_GroupState = 407, + T_AggState = 408, + T_WindowAggState = 409, + T_UniqueState = 410, + T_GatherState = 411, + T_GatherMergeState = 412, + T_HashState = 413, + T_SetOpState = 414, + T_LockRowsState = 415, + T_LimitState = 416, + T_IndexAmRoutine = 417, + T_TableAmRoutine = 418, + T_TsmRoutine = 419, + T_EventTriggerData = 420, + T_TriggerData = 421, + T_TupleTableSlot = 422, + T_FdwRoutine = 423, + T_Bitmapset = 424, + T_ExtensibleNode = 425, + T_ErrorSaveContext = 426, + T_IdentifySystemCmd = 427, + T_BaseBackupCmd = 428, + T_CreateReplicationSlotCmd = 429, + T_DropReplicationSlotCmd = 430, + T_StartReplicationCmd = 431, + T_ReadReplicationSlotCmd = 432, + T_TimeLineHistoryCmd = 433, + T_SupportRequestSimplify = 434, + T_SupportRequestSelectivity = 435, + T_SupportRequestCost = 436, + T_SupportRequestRows = 437, + T_SupportRequestIndexCondition = 438, + T_SupportRequestWFuncMonotonic = 439, + T_SupportRequestOptimizeWindowClause = 440, + T_Integer = 441, + T_Float = 442, + T_Boolean = 443, + T_String = 444, + T_BitString = 445, + T_ForeignKeyCacheInfo = 446, + T_IntList = 447, + T_OidList = 448, + T_XidList = 449, + T_AllocSetContext = 450, + T_GenerationContext = 451, + T_SlabContext = 452, + T_TIDBitmap = 453, + T_WindowObjectData = 454, diff --git a/install/include/postgresql/server/nodes/params.h b/install/include/postgresql/server/nodes/params.h new file mode 100644 index 00000000000..ad23113a61c --- /dev/null +++ b/install/include/postgresql/server/nodes/params.h @@ -0,0 +1,170 @@ +/*------------------------------------------------------------------------- + * + * params.h + * Support for finding the values associated with Param nodes. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/params.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARAMS_H +#define PARAMS_H + +/* Forward declarations, to avoid including other headers */ +struct Bitmapset; +struct ExprState; +struct Param; +struct ParseState; + + +/* + * ParamListInfo + * + * ParamListInfo structures are used to pass parameters into the executor + * for parameterized plans. We support two basic approaches to supplying + * parameter values, the "static" way and the "dynamic" way. + * + * In the static approach, per-parameter data is stored in an array of + * ParamExternData structs appended to the ParamListInfo struct. + * Each entry in the array defines the value to be substituted for a + * PARAM_EXTERN parameter. The "paramid" of a PARAM_EXTERN Param + * can range from 1 to numParams. + * + * Although parameter numbers are normally consecutive, we allow + * ptype == InvalidOid to signal an unused array entry. + * + * pflags is a flags field. Currently the only used bit is: + * PARAM_FLAG_CONST signals the planner that it may treat this parameter + * as a constant (i.e., generate a plan that works only for this value + * of the parameter). + * + * In the dynamic approach, all access to parameter values is done through + * hook functions found in the ParamListInfo struct. In this case, + * the ParamExternData array is typically unused and not allocated; + * but the legal range of paramid is still 1 to numParams. + * + * Although the data structure is really an array, not a list, we keep + * the old typedef name to avoid unnecessary code changes. + * + * There are 3 hook functions that can be associated with a ParamListInfo + * structure: + * + * If paramFetch isn't null, it is called to fetch the ParamExternData + * for a particular param ID, rather than accessing the relevant element + * of the ParamExternData array. This supports the case where the array + * isn't there at all, as well as cases where the data in the array + * might be obsolete or lazily evaluated. paramFetch must return the + * address of a ParamExternData struct describing the specified param ID; + * the convention above about ptype == InvalidOid signaling an invalid + * param ID still applies. The returned struct can either be placed in + * the "workspace" supplied by the caller, or it can be in storage + * controlled by the paramFetch hook if that's more convenient. + * (In either case, the struct is not expected to be long-lived.) + * If "speculative" is true, the paramFetch hook should not risk errors + * in trying to fetch the parameter value, and should report an invalid + * parameter instead. + * + * If paramCompile isn't null, then it controls what execExpr.c compiles + * for PARAM_EXTERN Param nodes --- typically, this hook would emit a + * EEOP_PARAM_CALLBACK step. This allows unnecessary work to be + * optimized away in compiled expressions. + * + * If parserSetup isn't null, then it is called to re-instantiate the + * original parsing hooks when a query needs to be re-parsed/planned. + * This is especially useful if the types of parameters might change + * from time to time, since it can replace the need to supply a fixed + * list of parameter types to the parser. + * + * Notice that the paramFetch and paramCompile hooks are actually passed + * the ParamListInfo struct's address; they can therefore access all + * three of the "arg" fields, and the distinction between paramFetchArg + * and paramCompileArg is rather arbitrary. + */ + +#define PARAM_FLAG_CONST 0x0001 /* parameter is constant */ + +typedef struct ParamExternData +{ + Datum value; /* parameter value */ + bool isnull; /* is it NULL? */ + uint16 pflags; /* flag bits, see above */ + Oid ptype; /* parameter's datatype, or 0 */ +} ParamExternData; + +typedef struct ParamListInfoData *ParamListInfo; + +typedef ParamExternData *(*ParamFetchHook) (ParamListInfo params, + int paramid, bool speculative, + ParamExternData *workspace); + +typedef void (*ParamCompileHook) (ParamListInfo params, struct Param *param, + struct ExprState *state, + Datum *resv, bool *resnull); + +typedef void (*ParserSetupHook) (struct ParseState *pstate, void *arg); + +typedef struct ParamListInfoData +{ + ParamFetchHook paramFetch; /* parameter fetch hook */ + void *paramFetchArg; + ParamCompileHook paramCompile; /* parameter compile hook */ + void *paramCompileArg; + ParserSetupHook parserSetup; /* parser setup hook */ + void *parserSetupArg; + char *paramValuesStr; /* params as a single string for errors */ + int numParams; /* nominal/maximum # of Params represented */ + + /* + * params[] may be of length zero if paramFetch is supplied; otherwise it + * must be of length numParams. + */ + ParamExternData params[FLEXIBLE_ARRAY_MEMBER]; +} ParamListInfoData; + + +/* ---------------- + * ParamExecData + * + * ParamExecData entries are used for executor internal parameters + * (that is, values being passed into or out of a sub-query). The + * paramid of a PARAM_EXEC Param is a (zero-based) index into an + * array of ParamExecData records, which is referenced through + * es_param_exec_vals or ecxt_param_exec_vals. + * + * If execPlan is not NULL, it points to a SubPlanState node that needs + * to be executed to produce the value. (This is done so that we can have + * lazy evaluation of InitPlans: they aren't executed until/unless a + * result value is needed.) Otherwise the value is assumed to be valid + * when needed. + * ---------------- + */ + +typedef struct ParamExecData +{ + void *execPlan; /* should be "SubPlanState *" */ + Datum value; + bool isnull; +} ParamExecData; + +/* type of argument for ParamsErrorCallback */ +typedef struct ParamsErrorCbData +{ + const char *portalName; + ParamListInfo params; +} ParamsErrorCbData; + +/* Functions found in src/backend/nodes/params.c */ +extern ParamListInfo makeParamList(int numParams); +extern ParamListInfo copyParamList(ParamListInfo from); +extern Size EstimateParamListSpace(ParamListInfo paramLI); +extern void SerializeParamList(ParamListInfo paramLI, char **start_address); +extern ParamListInfo RestoreParamList(char **start_address); +extern char *BuildParamLogString(ParamListInfo params, char **knownTextValues, + int maxlen); +extern void ParamsErrorCallback(void *arg); + +#endif /* PARAMS_H */ diff --git a/install/include/postgresql/server/nodes/parsenodes.h b/install/include/postgresql/server/nodes/parsenodes.h new file mode 100644 index 00000000000..9dca3b65287 --- /dev/null +++ b/install/include/postgresql/server/nodes/parsenodes.h @@ -0,0 +1,4050 @@ +/*------------------------------------------------------------------------- + * + * parsenodes.h + * definitions for parse tree nodes + * + * Many of the node types used in parsetrees include a "location" field. + * This is a byte (not character) offset in the original source text, to be + * used for positioning an error cursor when there is an error related to + * the node. Access to the original source text is needed to make use of + * the location. At the topmost (statement) level, we also provide a + * statement length, likewise measured in bytes, for convenience in + * identifying statement boundaries in multi-statement source strings. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/parsenodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSENODES_H +#define PARSENODES_H + +#include "common/relpath.h" +#include "nodes/bitmapset.h" +#include "nodes/lockoptions.h" +#include "nodes/primnodes.h" +#include "nodes/value.h" +#include "partitioning/partdefs.h" + + +typedef enum OverridingKind +{ + OVERRIDING_NOT_SET = 0, + OVERRIDING_USER_VALUE, + OVERRIDING_SYSTEM_VALUE +} OverridingKind; + +/* Possible sources of a Query */ +typedef enum QuerySource +{ + QSRC_ORIGINAL, /* original parsetree (explicit query) */ + QSRC_PARSER, /* added by parse analysis (now unused) */ + QSRC_INSTEAD_RULE, /* added by unconditional INSTEAD rule */ + QSRC_QUAL_INSTEAD_RULE, /* added by conditional INSTEAD rule */ + QSRC_NON_INSTEAD_RULE /* added by non-INSTEAD rule */ +} QuerySource; + +/* Sort ordering options for ORDER BY and CREATE INDEX */ +typedef enum SortByDir +{ + SORTBY_DEFAULT, + SORTBY_ASC, + SORTBY_DESC, + SORTBY_USING /* not allowed in CREATE INDEX ... */ +} SortByDir; + +typedef enum SortByNulls +{ + SORTBY_NULLS_DEFAULT, + SORTBY_NULLS_FIRST, + SORTBY_NULLS_LAST +} SortByNulls; + +/* Options for [ ALL | DISTINCT ] */ +typedef enum SetQuantifier +{ + SET_QUANTIFIER_DEFAULT, + SET_QUANTIFIER_ALL, + SET_QUANTIFIER_DISTINCT +} SetQuantifier; + +/* + * Grantable rights are encoded so that we can OR them together in a bitmask. + * The present representation of AclItem limits us to 32 distinct rights, + * even though AclMode is defined as uint64. See utils/acl.h. + * + * Caution: changing these codes breaks stored ACLs, hence forces initdb. + */ +typedef uint64 AclMode; /* a bitmask of privilege bits */ + +#define ACL_INSERT (1<<0) /* for relations */ +#define ACL_SELECT (1<<1) +#define ACL_UPDATE (1<<2) +#define ACL_DELETE (1<<3) +#define ACL_TRUNCATE (1<<4) +#define ACL_REFERENCES (1<<5) +#define ACL_TRIGGER (1<<6) +#define ACL_EXECUTE (1<<7) /* for functions */ +#define ACL_USAGE (1<<8) /* for various object types */ +#define ACL_CREATE (1<<9) /* for namespaces and databases */ +#define ACL_CREATE_TEMP (1<<10) /* for databases */ +#define ACL_CONNECT (1<<11) /* for databases */ +#define ACL_SET (1<<12) /* for configuration parameters */ +#define ACL_ALTER_SYSTEM (1<<13) /* for configuration parameters */ +#define N_ACL_RIGHTS 14 /* 1 plus the last 1< 0 + */ + List *rteperminfos pg_node_attr(query_jumble_ignore); + FromExpr *jointree; /* table join tree (FROM and WHERE clauses); + * also USING clause for MERGE */ + + List *mergeActionList; /* list of actions for MERGE (only) */ + /* whether to use outer join */ + bool mergeUseOuterJoin pg_node_attr(query_jumble_ignore); + + List *targetList; /* target list (of TargetEntry) */ + + /* OVERRIDING clause */ + OverridingKind override pg_node_attr(query_jumble_ignore); + + OnConflictExpr *onConflict; /* ON CONFLICT DO [NOTHING | UPDATE] */ + + List *returningList; /* return-values list (of TargetEntry) */ + + List *groupClause; /* a list of SortGroupClause's */ + bool groupDistinct; /* is the group by clause distinct? */ + + List *groupingSets; /* a list of GroupingSet's if present */ + + Node *havingQual; /* qualifications applied to groups */ + + List *windowClause; /* a list of WindowClause's */ + + List *distinctClause; /* a list of SortGroupClause's */ + + List *sortClause; /* a list of SortGroupClause's */ + + Node *limitOffset; /* # of result tuples to skip (int8 expr) */ + Node *limitCount; /* # of result tuples to return (int8 expr) */ + LimitOption limitOption; /* limit type */ + + List *rowMarks; /* a list of RowMarkClause's */ + + Node *setOperations; /* set-operation tree if this is top level of + * a UNION/INTERSECT/EXCEPT query */ + + /* + * A list of pg_constraint OIDs that the query depends on to be + * semantically valid + */ + List *constraintDeps pg_node_attr(query_jumble_ignore); + + /* a list of WithCheckOption's (added during rewrite) */ + List *withCheckOptions pg_node_attr(query_jumble_ignore); + + /* + * The following two fields identify the portion of the source text string + * containing this query. They are typically only populated in top-level + * Queries, not in sub-queries. When not set, they might both be zero, or + * both be -1 meaning "unknown". + */ + /* start location, or -1 if unknown */ + int stmt_location; + /* length in bytes; 0 means "rest of string" */ + int stmt_len pg_node_attr(query_jumble_ignore); +} Query; + + +/**************************************************************************** + * Supporting data structures for Parse Trees + * + * Most of these node types appear in raw parsetrees output by the grammar, + * and get transformed to something else by the analyzer. A few of them + * are used as-is in transformed querytrees. + ****************************************************************************/ + +/* + * TypeName - specifies a type in definitions + * + * For TypeName structures generated internally, it is often easier to + * specify the type by OID than by name. If "names" is NIL then the + * actual type OID is given by typeOid, otherwise typeOid is unused. + * Similarly, if "typmods" is NIL then the actual typmod is expected to + * be prespecified in typemod, otherwise typemod is unused. + * + * If pct_type is true, then names is actually a field name and we look up + * the type of that field. Otherwise (the normal case), names is a type + * name possibly qualified with schema and database name. + */ +typedef struct TypeName +{ + NodeTag type; + List *names; /* qualified name (list of String nodes) */ + Oid typeOid; /* type identified by OID */ + bool setof; /* is a set? */ + bool pct_type; /* %TYPE specified? */ + List *typmods; /* type modifier expression(s) */ + int32 typemod; /* prespecified type modifier */ + List *arrayBounds; /* array bounds */ + int location; /* token location, or -1 if unknown */ +} TypeName; + +/* + * ColumnRef - specifies a reference to a column, or possibly a whole tuple + * + * The "fields" list must be nonempty. It can contain String nodes + * (representing names) and A_Star nodes (representing occurrence of a '*'). + * Currently, A_Star must appear only as the last list element --- the grammar + * is responsible for enforcing this! + * + * Note: any container subscripting or selection of fields from composite columns + * is represented by an A_Indirection node above the ColumnRef. However, + * for simplicity in the normal case, initial field selection from a table + * name is represented within ColumnRef and not by adding A_Indirection. + */ +typedef struct ColumnRef +{ + NodeTag type; + List *fields; /* field names (String nodes) or A_Star */ + int location; /* token location, or -1 if unknown */ +} ColumnRef; + +/* + * ParamRef - specifies a $n parameter reference + */ +typedef struct ParamRef +{ + NodeTag type; + int number; /* the number of the parameter */ + int location; /* token location, or -1 if unknown */ +} ParamRef; + +/* + * A_Expr - infix, prefix, and postfix expressions + */ +typedef enum A_Expr_Kind +{ + AEXPR_OP, /* normal operator */ + AEXPR_OP_ANY, /* scalar op ANY (array) */ + AEXPR_OP_ALL, /* scalar op ALL (array) */ + AEXPR_DISTINCT, /* IS DISTINCT FROM - name must be "=" */ + AEXPR_NOT_DISTINCT, /* IS NOT DISTINCT FROM - name must be "=" */ + AEXPR_NULLIF, /* NULLIF - name must be "=" */ + AEXPR_IN, /* [NOT] IN - name must be "=" or "<>" */ + AEXPR_LIKE, /* [NOT] LIKE - name must be "~~" or "!~~" */ + AEXPR_ILIKE, /* [NOT] ILIKE - name must be "~~*" or "!~~*" */ + AEXPR_SIMILAR, /* [NOT] SIMILAR - name must be "~" or "!~" */ + AEXPR_BETWEEN, /* name must be "BETWEEN" */ + AEXPR_NOT_BETWEEN, /* name must be "NOT BETWEEN" */ + AEXPR_BETWEEN_SYM, /* name must be "BETWEEN SYMMETRIC" */ + AEXPR_NOT_BETWEEN_SYM /* name must be "NOT BETWEEN SYMMETRIC" */ +} A_Expr_Kind; + +typedef struct A_Expr +{ + pg_node_attr(custom_read_write) + + NodeTag type; + A_Expr_Kind kind; /* see above */ + List *name; /* possibly-qualified name of operator */ + Node *lexpr; /* left argument, or NULL if none */ + Node *rexpr; /* right argument, or NULL if none */ + int location; /* token location, or -1 if unknown */ +} A_Expr; + +/* + * A_Const - a literal constant + * + * Value nodes are inline for performance. You can treat 'val' as a node, + * as in IsA(&val, Integer). 'val' is not valid if isnull is true. + */ +union ValUnion +{ + Node node; + Integer ival; + Float fval; + Boolean boolval; + String sval; + BitString bsval; +}; + +typedef struct A_Const +{ + pg_node_attr(custom_copy_equal, custom_read_write, custom_query_jumble) + + NodeTag type; + union ValUnion val; + bool isnull; /* SQL NULL constant */ + int location; /* token location, or -1 if unknown */ +} A_Const; + +/* + * TypeCast - a CAST expression + */ +typedef struct TypeCast +{ + NodeTag type; + Node *arg; /* the expression being casted */ + TypeName *typeName; /* the target type */ + int location; /* token location, or -1 if unknown */ +} TypeCast; + +/* + * CollateClause - a COLLATE expression + */ +typedef struct CollateClause +{ + NodeTag type; + Node *arg; /* input expression */ + List *collname; /* possibly-qualified collation name */ + int location; /* token location, or -1 if unknown */ +} CollateClause; + +/* + * RoleSpec - a role name or one of a few special values. + */ +typedef enum RoleSpecType +{ + ROLESPEC_CSTRING, /* role name is stored as a C string */ + ROLESPEC_CURRENT_ROLE, /* role spec is CURRENT_ROLE */ + ROLESPEC_CURRENT_USER, /* role spec is CURRENT_USER */ + ROLESPEC_SESSION_USER, /* role spec is SESSION_USER */ + ROLESPEC_PUBLIC /* role name is "public" */ +} RoleSpecType; + +typedef struct RoleSpec +{ + NodeTag type; + RoleSpecType roletype; /* Type of this rolespec */ + char *rolename; /* filled only for ROLESPEC_CSTRING */ + int location; /* token location, or -1 if unknown */ +} RoleSpec; + +/* + * FuncCall - a function or aggregate invocation + * + * agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)', or if + * agg_within_group is true, it was 'foo(...) WITHIN GROUP (ORDER BY ...)'. + * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct + * indicates we saw 'foo(DISTINCT ...)'. In any of these cases, the + * construct *must* be an aggregate call. Otherwise, it might be either an + * aggregate or some other kind of function. However, if FILTER or OVER is + * present it had better be an aggregate or window function. + * + * Normally, you'd initialize this via makeFuncCall() and then only change the + * parts of the struct its defaults don't match afterwards, as needed. + */ +typedef struct FuncCall +{ + NodeTag type; + List *funcname; /* qualified name of function */ + List *args; /* the arguments (list of exprs) */ + List *agg_order; /* ORDER BY (list of SortBy) */ + Node *agg_filter; /* FILTER clause, if any */ + struct WindowDef *over; /* OVER clause, if any */ + bool agg_within_group; /* ORDER BY appeared in WITHIN GROUP */ + bool agg_star; /* argument was really '*' */ + bool agg_distinct; /* arguments were labeled DISTINCT */ + bool func_variadic; /* last argument was labeled VARIADIC */ + CoercionForm funcformat; /* how to display this node */ + int location; /* token location, or -1 if unknown */ +} FuncCall; + +/* + * A_Star - '*' representing all columns of a table or compound field + * + * This can appear within ColumnRef.fields, A_Indirection.indirection, and + * ResTarget.indirection lists. + */ +typedef struct A_Star +{ + NodeTag type; +} A_Star; + +/* + * A_Indices - array subscript or slice bounds ([idx] or [lidx:uidx]) + * + * In slice case, either or both of lidx and uidx can be NULL (omitted). + * In non-slice case, uidx holds the single subscript and lidx is always NULL. + */ +typedef struct A_Indices +{ + NodeTag type; + bool is_slice; /* true if slice (i.e., colon present) */ + Node *lidx; /* slice lower bound, if any */ + Node *uidx; /* subscript, or slice upper bound if any */ +} A_Indices; + +/* + * A_Indirection - select a field and/or array element from an expression + * + * The indirection list can contain A_Indices nodes (representing + * subscripting), String nodes (representing field selection --- the + * string value is the name of the field to select), and A_Star nodes + * (representing selection of all fields of a composite type). + * For example, a complex selection operation like + * (foo).field1[42][7].field2 + * would be represented with a single A_Indirection node having a 4-element + * indirection list. + * + * Currently, A_Star must appear only as the last list element --- the grammar + * is responsible for enforcing this! + */ +typedef struct A_Indirection +{ + NodeTag type; + Node *arg; /* the thing being selected from */ + List *indirection; /* subscripts and/or field names and/or * */ +} A_Indirection; + +/* + * A_ArrayExpr - an ARRAY[] construct + */ +typedef struct A_ArrayExpr +{ + NodeTag type; + List *elements; /* array element expressions */ + int location; /* token location, or -1 if unknown */ +} A_ArrayExpr; + +/* + * ResTarget - + * result target (used in target list of pre-transformed parse trees) + * + * In a SELECT target list, 'name' is the column label from an + * 'AS ColumnLabel' clause, or NULL if there was none, and 'val' is the + * value expression itself. The 'indirection' field is not used. + * + * INSERT uses ResTarget in its target-column-names list. Here, 'name' is + * the name of the destination column, 'indirection' stores any subscripts + * attached to the destination, and 'val' is not used. + * + * In an UPDATE target list, 'name' is the name of the destination column, + * 'indirection' stores any subscripts attached to the destination, and + * 'val' is the expression to assign. + * + * See A_Indirection for more info about what can appear in 'indirection'. + */ +typedef struct ResTarget +{ + NodeTag type; + char *name; /* column name or NULL */ + List *indirection; /* subscripts, field names, and '*', or NIL */ + Node *val; /* the value expression to compute or assign */ + int location; /* token location, or -1 if unknown */ +} ResTarget; + +/* + * MultiAssignRef - element of a row source expression for UPDATE + * + * In an UPDATE target list, when we have SET (a,b,c) = row-valued-expression, + * we generate separate ResTarget items for each of a,b,c. Their "val" trees + * are MultiAssignRef nodes numbered 1..n, linking to a common copy of the + * row-valued-expression (which parse analysis will process only once, when + * handling the MultiAssignRef with colno=1). + */ +typedef struct MultiAssignRef +{ + NodeTag type; + Node *source; /* the row-valued expression */ + int colno; /* column number for this target (1..n) */ + int ncolumns; /* number of targets in the construct */ +} MultiAssignRef; + +/* + * SortBy - for ORDER BY clause + */ +typedef struct SortBy +{ + NodeTag type; + Node *node; /* expression to sort on */ + SortByDir sortby_dir; /* ASC/DESC/USING/default */ + SortByNulls sortby_nulls; /* NULLS FIRST/LAST */ + List *useOp; /* name of op to use, if SORTBY_USING */ + int location; /* operator location, or -1 if none/unknown */ +} SortBy; + +/* + * WindowDef - raw representation of WINDOW and OVER clauses + * + * For entries in a WINDOW list, "name" is the window name being defined. + * For OVER clauses, we use "name" for the "OVER window" syntax, or "refname" + * for the "OVER (window)" syntax, which is subtly different --- the latter + * implies overriding the window frame clause. + */ +typedef struct WindowDef +{ + NodeTag type; + char *name; /* window's own name */ + char *refname; /* referenced window name, if any */ + List *partitionClause; /* PARTITION BY expression list */ + List *orderClause; /* ORDER BY (list of SortBy) */ + int frameOptions; /* frame_clause options, see below */ + Node *startOffset; /* expression for starting bound, if any */ + Node *endOffset; /* expression for ending bound, if any */ + int location; /* parse location, or -1 if none/unknown */ +} WindowDef; + +/* + * frameOptions is an OR of these bits. The NONDEFAULT and BETWEEN bits are + * used so that ruleutils.c can tell which properties were specified and + * which were defaulted; the correct behavioral bits must be set either way. + * The START_foo and END_foo options must come in pairs of adjacent bits for + * the convenience of gram.y, even though some of them are useless/invalid. + */ +#define FRAMEOPTION_NONDEFAULT 0x00001 /* any specified? */ +#define FRAMEOPTION_RANGE 0x00002 /* RANGE behavior */ +#define FRAMEOPTION_ROWS 0x00004 /* ROWS behavior */ +#define FRAMEOPTION_GROUPS 0x00008 /* GROUPS behavior */ +#define FRAMEOPTION_BETWEEN 0x00010 /* BETWEEN given? */ +#define FRAMEOPTION_START_UNBOUNDED_PRECEDING 0x00020 /* start is U. P. */ +#define FRAMEOPTION_END_UNBOUNDED_PRECEDING 0x00040 /* (disallowed) */ +#define FRAMEOPTION_START_UNBOUNDED_FOLLOWING 0x00080 /* (disallowed) */ +#define FRAMEOPTION_END_UNBOUNDED_FOLLOWING 0x00100 /* end is U. F. */ +#define FRAMEOPTION_START_CURRENT_ROW 0x00200 /* start is C. R. */ +#define FRAMEOPTION_END_CURRENT_ROW 0x00400 /* end is C. R. */ +#define FRAMEOPTION_START_OFFSET_PRECEDING 0x00800 /* start is O. P. */ +#define FRAMEOPTION_END_OFFSET_PRECEDING 0x01000 /* end is O. P. */ +#define FRAMEOPTION_START_OFFSET_FOLLOWING 0x02000 /* start is O. F. */ +#define FRAMEOPTION_END_OFFSET_FOLLOWING 0x04000 /* end is O. F. */ +#define FRAMEOPTION_EXCLUDE_CURRENT_ROW 0x08000 /* omit C.R. */ +#define FRAMEOPTION_EXCLUDE_GROUP 0x10000 /* omit C.R. & peers */ +#define FRAMEOPTION_EXCLUDE_TIES 0x20000 /* omit C.R.'s peers */ + +#define FRAMEOPTION_START_OFFSET \ + (FRAMEOPTION_START_OFFSET_PRECEDING | FRAMEOPTION_START_OFFSET_FOLLOWING) +#define FRAMEOPTION_END_OFFSET \ + (FRAMEOPTION_END_OFFSET_PRECEDING | FRAMEOPTION_END_OFFSET_FOLLOWING) +#define FRAMEOPTION_EXCLUSION \ + (FRAMEOPTION_EXCLUDE_CURRENT_ROW | FRAMEOPTION_EXCLUDE_GROUP | \ + FRAMEOPTION_EXCLUDE_TIES) + +#define FRAMEOPTION_DEFAULTS \ + (FRAMEOPTION_RANGE | FRAMEOPTION_START_UNBOUNDED_PRECEDING | \ + FRAMEOPTION_END_CURRENT_ROW) + +/* + * RangeSubselect - subquery appearing in a FROM clause + */ +typedef struct RangeSubselect +{ + NodeTag type; + bool lateral; /* does it have LATERAL prefix? */ + Node *subquery; /* the untransformed sub-select clause */ + Alias *alias; /* table alias & optional column aliases */ +} RangeSubselect; + +/* + * RangeFunction - function call appearing in a FROM clause + * + * functions is a List because we use this to represent the construct + * ROWS FROM(func1(...), func2(...), ...). Each element of this list is a + * two-element sublist, the first element being the untransformed function + * call tree, and the second element being a possibly-empty list of ColumnDef + * nodes representing any columndef list attached to that function within the + * ROWS FROM() syntax. + * + * alias and coldeflist represent any alias and/or columndef list attached + * at the top level. (We disallow coldeflist appearing both here and + * per-function, but that's checked in parse analysis, not by the grammar.) + */ +typedef struct RangeFunction +{ + NodeTag type; + bool lateral; /* does it have LATERAL prefix? */ + bool ordinality; /* does it have WITH ORDINALITY suffix? */ + bool is_rowsfrom; /* is result of ROWS FROM() syntax? */ + List *functions; /* per-function information, see above */ + Alias *alias; /* table alias & optional column aliases */ + List *coldeflist; /* list of ColumnDef nodes to describe result + * of function returning RECORD */ +} RangeFunction; + +/* + * RangeTableFunc - raw form of "table functions" such as XMLTABLE + */ +typedef struct RangeTableFunc +{ + NodeTag type; + bool lateral; /* does it have LATERAL prefix? */ + Node *docexpr; /* document expression */ + Node *rowexpr; /* row generator expression */ + List *namespaces; /* list of namespaces as ResTarget */ + List *columns; /* list of RangeTableFuncCol */ + Alias *alias; /* table alias & optional column aliases */ + int location; /* token location, or -1 if unknown */ +} RangeTableFunc; + +/* + * RangeTableFuncCol - one column in a RangeTableFunc->columns + * + * If for_ordinality is true (FOR ORDINALITY), then the column is an int4 + * column and the rest of the fields are ignored. + */ +typedef struct RangeTableFuncCol +{ + NodeTag type; + char *colname; /* name of generated column */ + TypeName *typeName; /* type of generated column */ + bool for_ordinality; /* does it have FOR ORDINALITY? */ + bool is_not_null; /* does it have NOT NULL? */ + Node *colexpr; /* column filter expression */ + Node *coldefexpr; /* column default value expression */ + int location; /* token location, or -1 if unknown */ +} RangeTableFuncCol; + +/* + * RangeTableSample - TABLESAMPLE appearing in a raw FROM clause + * + * This node, appearing only in raw parse trees, represents + * TABLESAMPLE () REPEATABLE () + * Currently, the can only be a RangeVar, but we might in future + * allow RangeSubselect and other options. Note that the RangeTableSample + * is wrapped around the node representing the , rather than being + * a subfield of it. + */ +typedef struct RangeTableSample +{ + NodeTag type; + Node *relation; /* relation to be sampled */ + List *method; /* sampling method name (possibly qualified) */ + List *args; /* argument(s) for sampling method */ + Node *repeatable; /* REPEATABLE expression, or NULL if none */ + int location; /* method name location, or -1 if unknown */ +} RangeTableSample; + +/* + * ColumnDef - column definition (used in various creates) + * + * If the column has a default value, we may have the value expression + * in either "raw" form (an untransformed parse tree) or "cooked" form + * (a post-parse-analysis, executable expression tree), depending on + * how this ColumnDef node was created (by parsing, or by inheritance + * from an existing relation). We should never have both in the same node! + * + * Similarly, we may have a COLLATE specification in either raw form + * (represented as a CollateClause with arg==NULL) or cooked form + * (the collation's OID). + * + * The constraints list may contain a CONSTR_DEFAULT item in a raw + * parsetree produced by gram.y, but transformCreateStmt will remove + * the item and set raw_default instead. CONSTR_DEFAULT items + * should not appear in any subsequent processing. + */ +typedef struct ColumnDef +{ + NodeTag type; + char *colname; /* name of column */ + TypeName *typeName; /* type of column */ + char *compression; /* compression method for column */ + int inhcount; /* number of times column is inherited */ + bool is_local; /* column has local (non-inherited) def'n */ + bool is_not_null; /* NOT NULL constraint specified? */ + bool is_from_type; /* column definition came from table type */ + char storage; /* attstorage setting, or 0 for default */ + char *storage_name; /* attstorage setting name or NULL for default */ + Node *raw_default; /* default value (untransformed parse tree) */ + Node *cooked_default; /* default value (transformed expr tree) */ + char identity; /* attidentity setting */ + RangeVar *identitySequence; /* to store identity sequence name for + * ALTER TABLE ... ADD COLUMN */ + char generated; /* attgenerated setting */ + CollateClause *collClause; /* untransformed COLLATE spec, if any */ + Oid collOid; /* collation OID (InvalidOid if not set) */ + List *constraints; /* other constraints on column */ + List *fdwoptions; /* per-column FDW options */ + int location; /* parse location, or -1 if none/unknown */ +} ColumnDef; + +/* + * TableLikeClause - CREATE TABLE ( ... LIKE ... ) clause + */ +typedef struct TableLikeClause +{ + NodeTag type; + RangeVar *relation; + bits32 options; /* OR of TableLikeOption flags */ + Oid relationOid; /* If table has been looked up, its OID */ +} TableLikeClause; + +typedef enum TableLikeOption +{ + CREATE_TABLE_LIKE_COMMENTS = 1 << 0, + CREATE_TABLE_LIKE_COMPRESSION = 1 << 1, + CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 2, + CREATE_TABLE_LIKE_DEFAULTS = 1 << 3, + CREATE_TABLE_LIKE_GENERATED = 1 << 4, + CREATE_TABLE_LIKE_IDENTITY = 1 << 5, + CREATE_TABLE_LIKE_INDEXES = 1 << 6, + CREATE_TABLE_LIKE_STATISTICS = 1 << 7, + CREATE_TABLE_LIKE_STORAGE = 1 << 8, + CREATE_TABLE_LIKE_ALL = PG_INT32_MAX +} TableLikeOption; + +/* + * IndexElem - index parameters (used in CREATE INDEX, and in ON CONFLICT) + * + * For a plain index attribute, 'name' is the name of the table column to + * index, and 'expr' is NULL. For an index expression, 'name' is NULL and + * 'expr' is the expression tree. + */ +typedef struct IndexElem +{ + NodeTag type; + char *name; /* name of attribute to index, or NULL */ + Node *expr; /* expression to index, or NULL */ + char *indexcolname; /* name for index column; NULL = default */ + List *collation; /* name of collation; NIL = default */ + List *opclass; /* name of desired opclass; NIL = default */ + List *opclassopts; /* opclass-specific options, or NIL */ + SortByDir ordering; /* ASC/DESC/default */ + SortByNulls nulls_ordering; /* FIRST/LAST/default */ +} IndexElem; + +/* + * DefElem - a generic "name = value" option definition + * + * In some contexts the name can be qualified. Also, certain SQL commands + * allow a SET/ADD/DROP action to be attached to option settings, so it's + * convenient to carry a field for that too. (Note: currently, it is our + * practice that the grammar allows namespace and action only in statements + * where they are relevant; C code can just ignore those fields in other + * statements.) + */ +typedef enum DefElemAction +{ + DEFELEM_UNSPEC, /* no action given */ + DEFELEM_SET, + DEFELEM_ADD, + DEFELEM_DROP +} DefElemAction; + +typedef struct DefElem +{ + NodeTag type; + char *defnamespace; /* NULL if unqualified name */ + char *defname; + Node *arg; /* typically Integer, Float, String, or + * TypeName */ + DefElemAction defaction; /* unspecified action, or SET/ADD/DROP */ + int location; /* token location, or -1 if unknown */ +} DefElem; + +/* + * LockingClause - raw representation of FOR [NO KEY] UPDATE/[KEY] SHARE + * options + * + * Note: lockedRels == NIL means "all relations in query". Otherwise it + * is a list of RangeVar nodes. (We use RangeVar mainly because it carries + * a location field --- currently, parse analysis insists on unqualified + * names in LockingClause.) + */ +typedef struct LockingClause +{ + NodeTag type; + List *lockedRels; /* FOR [KEY] UPDATE/SHARE relations */ + LockClauseStrength strength; + LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED */ +} LockingClause; + +/* + * XMLSERIALIZE (in raw parse tree only) + */ +typedef struct XmlSerialize +{ + NodeTag type; + XmlOptionType xmloption; /* DOCUMENT or CONTENT */ + Node *expr; + TypeName *typeName; + bool indent; /* [NO] INDENT */ + int location; /* token location, or -1 if unknown */ +} XmlSerialize; + +/* Partitioning related definitions */ + +/* + * PartitionElem - parse-time representation of a single partition key + * + * expr can be either a raw expression tree or a parse-analyzed expression. + * We don't store these on-disk, though. + */ +typedef struct PartitionElem +{ + NodeTag type; + char *name; /* name of column to partition on, or NULL */ + Node *expr; /* expression to partition on, or NULL */ + List *collation; /* name of collation; NIL = default */ + List *opclass; /* name of desired opclass; NIL = default */ + int location; /* token location, or -1 if unknown */ +} PartitionElem; + +typedef enum PartitionStrategy +{ + PARTITION_STRATEGY_LIST = 'l', + PARTITION_STRATEGY_RANGE = 'r', + PARTITION_STRATEGY_HASH = 'h' +} PartitionStrategy; + +/* + * PartitionSpec - parse-time representation of a partition key specification + * + * This represents the key space we will be partitioning on. + */ +typedef struct PartitionSpec +{ + NodeTag type; + PartitionStrategy strategy; + List *partParams; /* List of PartitionElems */ + int location; /* token location, or -1 if unknown */ +} PartitionSpec; + +/* + * PartitionBoundSpec - a partition bound specification + * + * This represents the portion of the partition key space assigned to a + * particular partition. These are stored on disk in pg_class.relpartbound. + */ +struct PartitionBoundSpec +{ + NodeTag type; + + char strategy; /* see PARTITION_STRATEGY codes above */ + bool is_default; /* is it a default partition bound? */ + + /* Partitioning info for HASH strategy: */ + int modulus; + int remainder; + + /* Partitioning info for LIST strategy: */ + List *listdatums; /* List of Consts (or A_Consts in raw tree) */ + + /* Partitioning info for RANGE strategy: */ + List *lowerdatums; /* List of PartitionRangeDatums */ + List *upperdatums; /* List of PartitionRangeDatums */ + + int location; /* token location, or -1 if unknown */ +}; + +/* + * PartitionRangeDatum - one of the values in a range partition bound + * + * This can be MINVALUE, MAXVALUE or a specific bounded value. + */ +typedef enum PartitionRangeDatumKind +{ + PARTITION_RANGE_DATUM_MINVALUE = -1, /* less than any other value */ + PARTITION_RANGE_DATUM_VALUE = 0, /* a specific (bounded) value */ + PARTITION_RANGE_DATUM_MAXVALUE = 1 /* greater than any other value */ +} PartitionRangeDatumKind; + +typedef struct PartitionRangeDatum +{ + NodeTag type; + + PartitionRangeDatumKind kind; + Node *value; /* Const (or A_Const in raw tree), if kind is + * PARTITION_RANGE_DATUM_VALUE, else NULL */ + + int location; /* token location, or -1 if unknown */ +} PartitionRangeDatum; + +/* + * PartitionCmd - info for ALTER TABLE/INDEX ATTACH/DETACH PARTITION commands + */ +typedef struct PartitionCmd +{ + NodeTag type; + RangeVar *name; /* name of partition to attach/detach */ + PartitionBoundSpec *bound; /* FOR VALUES, if attaching */ + bool concurrent; +} PartitionCmd; + +/**************************************************************************** + * Nodes for a Query tree + ****************************************************************************/ + +/*-------------------- + * RangeTblEntry - + * A range table is a List of RangeTblEntry nodes. + * + * A range table entry may represent a plain relation, a sub-select in + * FROM, or the result of a JOIN clause. (Only explicit JOIN syntax + * produces an RTE, not the implicit join resulting from multiple FROM + * items. This is because we only need the RTE to deal with SQL features + * like outer joins and join-output-column aliasing.) Other special + * RTE types also exist, as indicated by RTEKind. + * + * Note that we consider RTE_RELATION to cover anything that has a pg_class + * entry. relkind distinguishes the sub-cases. + * + * alias is an Alias node representing the AS alias-clause attached to the + * FROM expression, or NULL if no clause. + * + * eref is the table reference name and column reference names (either + * real or aliases). Note that system columns (OID etc) are not included + * in the column list. + * eref->aliasname is required to be present, and should generally be used + * to identify the RTE for error messages etc. + * + * In RELATION RTEs, the colnames in both alias and eref are indexed by + * physical attribute number; this means there must be colname entries for + * dropped columns. When building an RTE we insert empty strings ("") for + * dropped columns. Note however that a stored rule may have nonempty + * colnames for columns dropped since the rule was created (and for that + * matter the colnames might be out of date due to column renamings). + * The same comments apply to FUNCTION RTEs when a function's return type + * is a named composite type. + * + * In JOIN RTEs, the colnames in both alias and eref are one-to-one with + * joinaliasvars entries. A JOIN RTE will omit columns of its inputs when + * those columns are known to be dropped at parse time. Again, however, + * a stored rule might contain entries for columns dropped since the rule + * was created. (This is only possible for columns not actually referenced + * in the rule.) When loading a stored rule, we replace the joinaliasvars + * items for any such columns with null pointers. (We can't simply delete + * them from the joinaliasvars list, because that would affect the attnums + * of Vars referencing the rest of the list.) + * + * inh is true for relation references that should be expanded to include + * inheritance children, if the rel has any. This *must* be false for + * RTEs other than RTE_RELATION entries. + * + * inFromCl marks those range variables that are listed in the FROM clause. + * It's false for RTEs that are added to a query behind the scenes, such + * as the NEW and OLD variables for a rule, or the subqueries of a UNION. + * This flag is not used during parsing (except in transformLockingClause, + * q.v.); the parser now uses a separate "namespace" data structure to + * control visibility. But it is needed by ruleutils.c to determine + * whether RTEs should be shown in decompiled queries. + * + * securityQuals is a list of security barrier quals (boolean expressions), + * to be tested in the listed order before returning a row from the + * relation. It is always NIL in parser output. Entries are added by the + * rewriter to implement security-barrier views and/or row-level security. + * Note that the planner turns each boolean expression into an implicitly + * AND'ed sublist, as is its usual habit with qualification expressions. + *-------------------- + */ +typedef enum RTEKind +{ + RTE_RELATION, /* ordinary relation reference */ + RTE_SUBQUERY, /* subquery in FROM */ + RTE_JOIN, /* join */ + RTE_FUNCTION, /* function in FROM */ + RTE_TABLEFUNC, /* TableFunc(.., column list) */ + RTE_VALUES, /* VALUES (), (), ... */ + RTE_CTE, /* common table expr (WITH list element) */ + RTE_NAMEDTUPLESTORE, /* tuplestore, e.g. for AFTER triggers */ + RTE_RESULT /* RTE represents an empty FROM clause; such + * RTEs are added by the planner, they're not + * present during parsing or rewriting */ +} RTEKind; + +typedef struct RangeTblEntry +{ + pg_node_attr(custom_read_write, custom_query_jumble) + + NodeTag type; + + RTEKind rtekind; /* see above */ + + /* + * XXX the fields applicable to only some rte kinds should be merged into + * a union. I didn't do this yet because the diffs would impact a lot of + * code that is being actively worked on. FIXME someday. + */ + + /* + * Fields valid for a plain relation RTE (else zero): + * + * rellockmode is really LOCKMODE, but it's declared int to avoid having + * to include lock-related headers here. It must be RowExclusiveLock if + * the RTE is an INSERT/UPDATE/DELETE/MERGE target, else RowShareLock if + * the RTE is a SELECT FOR UPDATE/FOR SHARE target, else AccessShareLock. + * + * Note: in some cases, rule expansion may result in RTEs that are marked + * with RowExclusiveLock even though they are not the target of the + * current query; this happens if a DO ALSO rule simply scans the original + * target table. We leave such RTEs with their original lockmode so as to + * avoid getting an additional, lesser lock. + * + * perminfoindex is 1-based index of the RTEPermissionInfo belonging to + * this RTE in the containing struct's list of same; 0 if permissions need + * not be checked for this RTE. + * + * As a special case, relid, relkind, rellockmode, and perminfoindex can + * also be set (nonzero) in an RTE_SUBQUERY RTE. This occurs when we + * convert an RTE_RELATION RTE naming a view into an RTE_SUBQUERY + * containing the view's query. We still need to perform run-time locking + * and permission checks on the view, even though it's not directly used + * in the query anymore, and the most expedient way to do that is to + * retain these fields from the old state of the RTE. + * + * As a special case, RTE_NAMEDTUPLESTORE can also set relid to indicate + * that the tuple format of the tuplestore is the same as the referenced + * relation. This allows plans referencing AFTER trigger transition + * tables to be invalidated if the underlying table is altered. + */ + Oid relid; /* OID of the relation */ + char relkind; /* relation kind (see pg_class.relkind) */ + int rellockmode; /* lock level that query requires on the rel */ + struct TableSampleClause *tablesample; /* sampling info, or NULL */ + Index perminfoindex; + + /* + * Fields valid for a subquery RTE (else NULL): + */ + Query *subquery; /* the sub-query */ + bool security_barrier; /* is from security_barrier view? */ + + /* + * Fields valid for a join RTE (else NULL/zero): + * + * joinaliasvars is a list of (usually) Vars corresponding to the columns + * of the join result. An alias Var referencing column K of the join + * result can be replaced by the K'th element of joinaliasvars --- but to + * simplify the task of reverse-listing aliases correctly, we do not do + * that until planning time. In detail: an element of joinaliasvars can + * be a Var of one of the join's input relations, or such a Var with an + * implicit coercion to the join's output column type, or a COALESCE + * expression containing the two input column Vars (possibly coerced). + * Elements beyond the first joinmergedcols entries are always just Vars, + * and are never referenced from elsewhere in the query (that is, join + * alias Vars are generated only for merged columns). We keep these + * entries only because they're needed in expandRTE() and similar code. + * + * Vars appearing within joinaliasvars are marked with varnullingrels sets + * that describe the nulling effects of this join and lower ones. This is + * essential for FULL JOIN cases, because the COALESCE expression only + * describes the semantics correctly if its inputs have been nulled by the + * join. For other cases, it allows expandRTE() to generate a valid + * representation of the join's output without consulting additional + * parser state. + * + * Within a Query loaded from a stored rule, it is possible for non-merged + * joinaliasvars items to be null pointers, which are placeholders for + * (necessarily unreferenced) columns dropped since the rule was made. + * Also, once planning begins, joinaliasvars items can be almost anything, + * as a result of subquery-flattening substitutions. + * + * joinleftcols is an integer list of physical column numbers of the left + * join input rel that are included in the join; likewise joinrighttcols + * for the right join input rel. (Which rels those are can be determined + * from the associated JoinExpr.) If the join is USING/NATURAL, then the + * first joinmergedcols entries in each list identify the merged columns. + * The merged columns come first in the join output, then remaining + * columns of the left input, then remaining columns of the right. + * + * Note that input columns could have been dropped after creation of a + * stored rule, if they are not referenced in the query (in particular, + * merged columns could not be dropped); this is not accounted for in + * joinleftcols/joinrighttcols. + */ + JoinType jointype; /* type of join */ + int joinmergedcols; /* number of merged (JOIN USING) columns */ + List *joinaliasvars; /* list of alias-var expansions */ + List *joinleftcols; /* left-side input column numbers */ + List *joinrightcols; /* right-side input column numbers */ + + /* + * join_using_alias is an alias clause attached directly to JOIN/USING. It + * is different from the alias field (below) in that it does not hide the + * range variables of the tables being joined. + */ + Alias *join_using_alias; + + /* + * Fields valid for a function RTE (else NIL/zero): + * + * When funcordinality is true, the eref->colnames list includes an alias + * for the ordinality column. The ordinality column is otherwise + * implicit, and must be accounted for "by hand" in places such as + * expandRTE(). + */ + List *functions; /* list of RangeTblFunction nodes */ + bool funcordinality; /* is this called WITH ORDINALITY? */ + + /* + * Fields valid for a TableFunc RTE (else NULL): + */ + TableFunc *tablefunc; + + /* + * Fields valid for a values RTE (else NIL): + */ + List *values_lists; /* list of expression lists */ + + /* + * Fields valid for a CTE RTE (else NULL/zero): + */ + char *ctename; /* name of the WITH list item */ + Index ctelevelsup; /* number of query levels up */ + bool self_reference; /* is this a recursive self-reference? */ + + /* + * Fields valid for CTE, VALUES, ENR, and TableFunc RTEs (else NIL): + * + * We need these for CTE RTEs so that the types of self-referential + * columns are well-defined. For VALUES RTEs, storing these explicitly + * saves having to re-determine the info by scanning the values_lists. For + * ENRs, we store the types explicitly here (we could get the information + * from the catalogs if 'relid' was supplied, but we'd still need these + * for TupleDesc-based ENRs, so we might as well always store the type + * info here). For TableFuncs, these fields are redundant with data in + * the TableFunc node, but keeping them here allows some code sharing with + * the other cases. + * + * For ENRs only, we have to consider the possibility of dropped columns. + * A dropped column is included in these lists, but it will have zeroes in + * all three lists (as well as an empty-string entry in eref). Testing + * for zero coltype is the standard way to detect a dropped column. + */ + List *coltypes; /* OID list of column type OIDs */ + List *coltypmods; /* integer list of column typmods */ + List *colcollations; /* OID list of column collation OIDs */ + + /* + * Fields valid for ENR RTEs (else NULL/zero): + */ + char *enrname; /* name of ephemeral named relation */ + Cardinality enrtuples; /* estimated or actual from caller */ + + /* + * Fields valid in all RTEs: + */ + Alias *alias; /* user-written alias clause, if any */ + Alias *eref; /* expanded reference names */ + bool lateral; /* subquery, function, or values is LATERAL? */ + bool inh; /* inheritance requested? */ + bool inFromCl; /* present in FROM clause? */ + List *securityQuals; /* security barrier quals to apply, if any */ +} RangeTblEntry; + +/* + * RTEPermissionInfo + * Per-relation information for permission checking. Added to the Query + * node by the parser when adding the corresponding RTE to the query + * range table and subsequently editorialized on by the rewriter if + * needed after rule expansion. + * + * Only the relations directly mentioned in the query are checked for + * access permissions by the core executor, so only their RTEPermissionInfos + * are present in the Query. However, extensions may want to check inheritance + * children too, depending on the value of rte->inh, so it's copied in 'inh' + * for their perusal. + * + * requiredPerms and checkAsUser specify run-time access permissions checks + * to be performed at query startup. The user must have *all* of the + * permissions that are OR'd together in requiredPerms (never 0!). If + * checkAsUser is not zero, then do the permissions checks using the access + * rights of that user, not the current effective user ID. (This allows rules + * to act as setuid gateways.) + * + * For SELECT/INSERT/UPDATE permissions, if the user doesn't have table-wide + * permissions then it is sufficient to have the permissions on all columns + * identified in selectedCols (for SELECT) and/or insertedCols and/or + * updatedCols (INSERT with ON CONFLICT DO UPDATE may have all 3). + * selectedCols, insertedCols and updatedCols are bitmapsets, which cannot have + * negative integer members, so we subtract FirstLowInvalidHeapAttributeNumber + * from column numbers before storing them in these fields. A whole-row Var + * reference is represented by setting the bit for InvalidAttrNumber. + * + * updatedCols is also used in some other places, for example, to determine + * which triggers to fire and in FDWs to know which changed columns they need + * to ship off. + */ +typedef struct RTEPermissionInfo +{ + NodeTag type; + + Oid relid; /* relation OID */ + bool inh; /* separately check inheritance children? */ + AclMode requiredPerms; /* bitmask of required access permissions */ + Oid checkAsUser; /* if valid, check access as this role */ + Bitmapset *selectedCols; /* columns needing SELECT permission */ + Bitmapset *insertedCols; /* columns needing INSERT permission */ + Bitmapset *updatedCols; /* columns needing UPDATE permission */ +} RTEPermissionInfo; + +/* + * RangeTblFunction - + * RangeTblEntry subsidiary data for one function in a FUNCTION RTE. + * + * If the function had a column definition list (required for an + * otherwise-unspecified RECORD result), funccolnames lists the names given + * in the definition list, funccoltypes lists their declared column types, + * funccoltypmods lists their typmods, funccolcollations their collations. + * Otherwise, those fields are NIL. + * + * Notice we don't attempt to store info about the results of functions + * returning named composite types, because those can change from time to + * time. We do however remember how many columns we thought the type had + * (including dropped columns!), so that we can successfully ignore any + * columns added after the query was parsed. + * + * The query jumbling only needs to track the function expression. + */ +typedef struct RangeTblFunction +{ + NodeTag type; + + Node *funcexpr; /* expression tree for func call */ + /* number of columns it contributes to RTE */ + int funccolcount pg_node_attr(query_jumble_ignore); + /* These fields record the contents of a column definition list, if any: */ + /* column names (list of String) */ + List *funccolnames pg_node_attr(query_jumble_ignore); + /* OID list of column type OIDs */ + List *funccoltypes pg_node_attr(query_jumble_ignore); + /* integer list of column typmods */ + List *funccoltypmods pg_node_attr(query_jumble_ignore); + /* OID list of column collation OIDs */ + List *funccolcollations pg_node_attr(query_jumble_ignore); + + /* This is set during planning for use by the executor: */ + /* PARAM_EXEC Param IDs affecting this func */ + Bitmapset *funcparams pg_node_attr(query_jumble_ignore); +} RangeTblFunction; + +/* + * TableSampleClause - TABLESAMPLE appearing in a transformed FROM clause + * + * Unlike RangeTableSample, this is a subnode of the relevant RangeTblEntry. + */ +typedef struct TableSampleClause +{ + NodeTag type; + Oid tsmhandler; /* OID of the tablesample handler function */ + List *args; /* tablesample argument expression(s) */ + Expr *repeatable; /* REPEATABLE expression, or NULL if none */ +} TableSampleClause; + +/* + * WithCheckOption - + * representation of WITH CHECK OPTION checks to be applied to new tuples + * when inserting/updating an auto-updatable view, or RLS WITH CHECK + * policies to be applied when inserting/updating a relation with RLS. + */ +typedef enum WCOKind +{ + WCO_VIEW_CHECK, /* WCO on an auto-updatable view */ + WCO_RLS_INSERT_CHECK, /* RLS INSERT WITH CHECK policy */ + WCO_RLS_UPDATE_CHECK, /* RLS UPDATE WITH CHECK policy */ + WCO_RLS_CONFLICT_CHECK, /* RLS ON CONFLICT DO UPDATE USING policy */ + WCO_RLS_MERGE_UPDATE_CHECK, /* RLS MERGE UPDATE USING policy */ + WCO_RLS_MERGE_DELETE_CHECK /* RLS MERGE DELETE USING policy */ +} WCOKind; + +typedef struct WithCheckOption +{ + NodeTag type; + WCOKind kind; /* kind of WCO */ + char *relname; /* name of relation that specified the WCO */ + char *polname; /* name of RLS policy being checked */ + Node *qual; /* constraint qual to check */ + bool cascaded; /* true for a cascaded WCO on a view */ +} WithCheckOption; + +/* + * SortGroupClause - + * representation of ORDER BY, GROUP BY, PARTITION BY, + * DISTINCT, DISTINCT ON items + * + * You might think that ORDER BY is only interested in defining ordering, + * and GROUP/DISTINCT are only interested in defining equality. However, + * one way to implement grouping is to sort and then apply a "uniq"-like + * filter. So it's also interesting to keep track of possible sort operators + * for GROUP/DISTINCT, and in particular to try to sort for the grouping + * in a way that will also yield a requested ORDER BY ordering. So we need + * to be able to compare ORDER BY and GROUP/DISTINCT lists, which motivates + * the decision to give them the same representation. + * + * tleSortGroupRef must match ressortgroupref of exactly one entry of the + * query's targetlist; that is the expression to be sorted or grouped by. + * eqop is the OID of the equality operator. + * sortop is the OID of the ordering operator (a "<" or ">" operator), + * or InvalidOid if not available. + * nulls_first means about what you'd expect. If sortop is InvalidOid + * then nulls_first is meaningless and should be set to false. + * hashable is true if eqop is hashable (note this condition also depends + * on the datatype of the input expression). + * + * In an ORDER BY item, all fields must be valid. (The eqop isn't essential + * here, but it's cheap to get it along with the sortop, and requiring it + * to be valid eases comparisons to grouping items.) Note that this isn't + * actually enough information to determine an ordering: if the sortop is + * collation-sensitive, a collation OID is needed too. We don't store the + * collation in SortGroupClause because it's not available at the time the + * parser builds the SortGroupClause; instead, consult the exposed collation + * of the referenced targetlist expression to find out what it is. + * + * In a grouping item, eqop must be valid. If the eqop is a btree equality + * operator, then sortop should be set to a compatible ordering operator. + * We prefer to set eqop/sortop/nulls_first to match any ORDER BY item that + * the query presents for the same tlist item. If there is none, we just + * use the default ordering op for the datatype. + * + * If the tlist item's type has a hash opclass but no btree opclass, then + * we will set eqop to the hash equality operator, sortop to InvalidOid, + * and nulls_first to false. A grouping item of this kind can only be + * implemented by hashing, and of course it'll never match an ORDER BY item. + * + * The hashable flag is provided since we generally have the requisite + * information readily available when the SortGroupClause is constructed, + * and it's relatively expensive to get it again later. Note there is no + * need for a "sortable" flag since OidIsValid(sortop) serves the purpose. + * + * A query might have both ORDER BY and DISTINCT (or DISTINCT ON) clauses. + * In SELECT DISTINCT, the distinctClause list is as long or longer than the + * sortClause list, while in SELECT DISTINCT ON it's typically shorter. + * The two lists must match up to the end of the shorter one --- the parser + * rearranges the distinctClause if necessary to make this true. (This + * restriction ensures that only one sort step is needed to both satisfy the + * ORDER BY and set up for the Unique step. This is semantically necessary + * for DISTINCT ON, and presents no real drawback for DISTINCT.) + */ +typedef struct SortGroupClause +{ + NodeTag type; + Index tleSortGroupRef; /* reference into targetlist */ + Oid eqop; /* the equality operator ('=' op) */ + Oid sortop; /* the ordering operator ('<' op), or 0 */ + bool nulls_first; /* do NULLs come before normal values? */ + /* can eqop be implemented by hashing? */ + bool hashable pg_node_attr(query_jumble_ignore); +} SortGroupClause; + +/* + * GroupingSet - + * representation of CUBE, ROLLUP and GROUPING SETS clauses + * + * In a Query with grouping sets, the groupClause contains a flat list of + * SortGroupClause nodes for each distinct expression used. The actual + * structure of the GROUP BY clause is given by the groupingSets tree. + * + * In the raw parser output, GroupingSet nodes (of all types except SIMPLE + * which is not used) are potentially mixed in with the expressions in the + * groupClause of the SelectStmt. (An expression can't contain a GroupingSet, + * but a list may mix GroupingSet and expression nodes.) At this stage, the + * content of each node is a list of expressions, some of which may be RowExprs + * which represent sublists rather than actual row constructors, and nested + * GroupingSet nodes where legal in the grammar. The structure directly + * reflects the query syntax. + * + * In parse analysis, the transformed expressions are used to build the tlist + * and groupClause list (of SortGroupClause nodes), and the groupingSets tree + * is eventually reduced to a fixed format: + * + * EMPTY nodes represent (), and obviously have no content + * + * SIMPLE nodes represent a list of one or more expressions to be treated as an + * atom by the enclosing structure; the content is an integer list of + * ressortgroupref values (see SortGroupClause) + * + * CUBE and ROLLUP nodes contain a list of one or more SIMPLE nodes. + * + * SETS nodes contain a list of EMPTY, SIMPLE, CUBE or ROLLUP nodes, but after + * parse analysis they cannot contain more SETS nodes; enough of the syntactic + * transforms of the spec have been applied that we no longer have arbitrarily + * deep nesting (though we still preserve the use of cube/rollup). + * + * Note that if the groupingSets tree contains no SIMPLE nodes (only EMPTY + * nodes at the leaves), then the groupClause will be empty, but this is still + * an aggregation query (similar to using aggs or HAVING without GROUP BY). + * + * As an example, the following clause: + * + * GROUP BY GROUPING SETS ((a,b), CUBE(c,(d,e))) + * + * looks like this after raw parsing: + * + * SETS( RowExpr(a,b) , CUBE( c, RowExpr(d,e) ) ) + * + * and parse analysis converts it to: + * + * SETS( SIMPLE(1,2), CUBE( SIMPLE(3), SIMPLE(4,5) ) ) + */ +typedef enum GroupingSetKind +{ + GROUPING_SET_EMPTY, + GROUPING_SET_SIMPLE, + GROUPING_SET_ROLLUP, + GROUPING_SET_CUBE, + GROUPING_SET_SETS +} GroupingSetKind; + +typedef struct GroupingSet +{ + NodeTag type; + GroupingSetKind kind pg_node_attr(query_jumble_ignore); + List *content; + int location; +} GroupingSet; + +/* + * WindowClause - + * transformed representation of WINDOW and OVER clauses + * + * A parsed Query's windowClause list contains these structs. "name" is set + * if the clause originally came from WINDOW, and is NULL if it originally + * was an OVER clause (but note that we collapse out duplicate OVERs). + * partitionClause and orderClause are lists of SortGroupClause structs. + * If we have RANGE with offset PRECEDING/FOLLOWING, the semantics of that are + * specified by startInRangeFunc/inRangeColl/inRangeAsc/inRangeNullsFirst + * for the start offset, or endInRangeFunc/inRange* for the end offset. + * winref is an ID number referenced by WindowFunc nodes; it must be unique + * among the members of a Query's windowClause list. + * When refname isn't null, the partitionClause is always copied from there; + * the orderClause might or might not be copied (see copiedOrder); the framing + * options are never copied, per spec. + * + * The information relevant for the query jumbling is the partition clause + * type and its bounds. + */ +typedef struct WindowClause +{ + NodeTag type; + /* window name (NULL in an OVER clause) */ + char *name pg_node_attr(query_jumble_ignore); + /* referenced window name, if any */ + char *refname pg_node_attr(query_jumble_ignore); + List *partitionClause; /* PARTITION BY list */ + /* ORDER BY list */ + List *orderClause; + int frameOptions; /* frame_clause options, see WindowDef */ + Node *startOffset; /* expression for starting bound, if any */ + Node *endOffset; /* expression for ending bound, if any */ + /* qual to help short-circuit execution */ + List *runCondition pg_node_attr(query_jumble_ignore); + /* in_range function for startOffset */ + Oid startInRangeFunc pg_node_attr(query_jumble_ignore); + /* in_range function for endOffset */ + Oid endInRangeFunc pg_node_attr(query_jumble_ignore); + /* collation for in_range tests */ + Oid inRangeColl pg_node_attr(query_jumble_ignore); + /* use ASC sort order for in_range tests? */ + bool inRangeAsc pg_node_attr(query_jumble_ignore); + /* nulls sort first for in_range tests? */ + bool inRangeNullsFirst pg_node_attr(query_jumble_ignore); + Index winref; /* ID referenced by window functions */ + /* did we copy orderClause from refname? */ + bool copiedOrder pg_node_attr(query_jumble_ignore); +} WindowClause; + +/* + * RowMarkClause - + * parser output representation of FOR [KEY] UPDATE/SHARE clauses + * + * Query.rowMarks contains a separate RowMarkClause node for each relation + * identified as a FOR [KEY] UPDATE/SHARE target. If one of these clauses + * is applied to a subquery, we generate RowMarkClauses for all normal and + * subquery rels in the subquery, but they are marked pushedDown = true to + * distinguish them from clauses that were explicitly written at this query + * level. Also, Query.hasForUpdate tells whether there were explicit FOR + * UPDATE/SHARE/KEY SHARE clauses in the current query level. + */ +typedef struct RowMarkClause +{ + NodeTag type; + Index rti; /* range table index of target relation */ + LockClauseStrength strength; + LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED */ + bool pushedDown; /* pushed down from higher query level? */ +} RowMarkClause; + +/* + * WithClause - + * representation of WITH clause + * + * Note: WithClause does not propagate into the Query representation; + * but CommonTableExpr does. + */ +typedef struct WithClause +{ + NodeTag type; + List *ctes; /* list of CommonTableExprs */ + bool recursive; /* true = WITH RECURSIVE */ + int location; /* token location, or -1 if unknown */ +} WithClause; + +/* + * InferClause - + * ON CONFLICT unique index inference clause + * + * Note: InferClause does not propagate into the Query representation. + */ +typedef struct InferClause +{ + NodeTag type; + List *indexElems; /* IndexElems to infer unique index */ + Node *whereClause; /* qualification (partial-index predicate) */ + char *conname; /* Constraint name, or NULL if unnamed */ + int location; /* token location, or -1 if unknown */ +} InferClause; + +/* + * OnConflictClause - + * representation of ON CONFLICT clause + * + * Note: OnConflictClause does not propagate into the Query representation. + */ +typedef struct OnConflictClause +{ + NodeTag type; + OnConflictAction action; /* DO NOTHING or UPDATE? */ + InferClause *infer; /* Optional index inference clause */ + List *targetList; /* the target list (of ResTarget) */ + Node *whereClause; /* qualifications */ + int location; /* token location, or -1 if unknown */ +} OnConflictClause; + +/* + * CommonTableExpr - + * representation of WITH list element + */ + +typedef enum CTEMaterialize +{ + CTEMaterializeDefault, /* no option specified */ + CTEMaterializeAlways, /* MATERIALIZED */ + CTEMaterializeNever /* NOT MATERIALIZED */ +} CTEMaterialize; + +typedef struct CTESearchClause +{ + NodeTag type; + List *search_col_list; + bool search_breadth_first; + char *search_seq_column; + int location; +} CTESearchClause; + +typedef struct CTECycleClause +{ + NodeTag type; + List *cycle_col_list; + char *cycle_mark_column; + Node *cycle_mark_value; + Node *cycle_mark_default; + char *cycle_path_column; + int location; + /* These fields are set during parse analysis: */ + Oid cycle_mark_type; /* common type of _value and _default */ + int cycle_mark_typmod; + Oid cycle_mark_collation; + Oid cycle_mark_neop; /* <> operator for type */ +} CTECycleClause; + +typedef struct CommonTableExpr +{ + NodeTag type; + + /* + * Query name (never qualified). The string name is included in the query + * jumbling because RTE_CTE RTEs need it. + */ + char *ctename; + /* optional list of column names */ + List *aliascolnames pg_node_attr(query_jumble_ignore); + CTEMaterialize ctematerialized; /* is this an optimization fence? */ + /* SelectStmt/InsertStmt/etc before parse analysis, Query afterwards: */ + Node *ctequery; /* the CTE's subquery */ + CTESearchClause *search_clause pg_node_attr(query_jumble_ignore); + CTECycleClause *cycle_clause pg_node_attr(query_jumble_ignore); + int location; /* token location, or -1 if unknown */ + /* These fields are set during parse analysis: */ + /* is this CTE actually recursive? */ + bool cterecursive pg_node_attr(query_jumble_ignore); + + /* + * Number of RTEs referencing this CTE (excluding internal + * self-references), irrelevant for query jumbling. + */ + int cterefcount pg_node_attr(query_jumble_ignore); + /* list of output column names */ + List *ctecolnames pg_node_attr(query_jumble_ignore); + /* OID list of output column type OIDs */ + List *ctecoltypes pg_node_attr(query_jumble_ignore); + /* integer list of output column typmods */ + List *ctecoltypmods pg_node_attr(query_jumble_ignore); + /* OID list of column collation OIDs */ + List *ctecolcollations pg_node_attr(query_jumble_ignore); +} CommonTableExpr; + +/* Convenience macro to get the output tlist of a CTE's query */ +#define GetCTETargetList(cte) \ + (AssertMacro(IsA((cte)->ctequery, Query)), \ + ((Query *) (cte)->ctequery)->commandType == CMD_SELECT ? \ + ((Query *) (cte)->ctequery)->targetList : \ + ((Query *) (cte)->ctequery)->returningList) + +/* + * MergeWhenClause - + * raw parser representation of a WHEN clause in a MERGE statement + * + * This is transformed into MergeAction by parse analysis + */ +typedef struct MergeWhenClause +{ + NodeTag type; + bool matched; /* true=MATCHED, false=NOT MATCHED */ + CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ + OverridingKind override; /* OVERRIDING clause */ + Node *condition; /* WHEN conditions (raw parser) */ + List *targetList; /* INSERT/UPDATE targetlist */ + /* the following members are only used in INSERT actions */ + List *values; /* VALUES to INSERT, or NULL */ +} MergeWhenClause; + +/* + * MergeAction - + * Transformed representation of a WHEN clause in a MERGE statement + */ +typedef struct MergeAction +{ + NodeTag type; + bool matched; /* true=MATCHED, false=NOT MATCHED */ + CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ + /* OVERRIDING clause */ + OverridingKind override pg_node_attr(query_jumble_ignore); + Node *qual; /* transformed WHEN conditions */ + List *targetList; /* the target list (of TargetEntry) */ + /* target attribute numbers of an UPDATE */ + List *updateColnos pg_node_attr(query_jumble_ignore); +} MergeAction; + +/* + * TriggerTransition - + * representation of transition row or table naming clause + * + * Only transition tables are initially supported in the syntax, and only for + * AFTER triggers, but other permutations are accepted by the parser so we can + * give a meaningful message from C code. + */ +typedef struct TriggerTransition +{ + NodeTag type; + char *name; + bool isNew; + bool isTable; +} TriggerTransition; + +/* Nodes for SQL/JSON support */ + +/* + * JsonOutput - + * representation of JSON output clause (RETURNING type [FORMAT format]) + */ +typedef struct JsonOutput +{ + NodeTag type; + TypeName *typeName; /* RETURNING type name, if specified */ + JsonReturning *returning; /* RETURNING FORMAT clause and type Oids */ +} JsonOutput; + +/* + * JsonKeyValue - + * untransformed representation of JSON object key-value pair for + * JSON_OBJECT() and JSON_OBJECTAGG() + */ +typedef struct JsonKeyValue +{ + NodeTag type; + Expr *key; /* key expression */ + JsonValueExpr *value; /* JSON value expression */ +} JsonKeyValue; + +/* + * JsonObjectConstructor - + * untransformed representation of JSON_OBJECT() constructor + */ +typedef struct JsonObjectConstructor +{ + NodeTag type; + List *exprs; /* list of JsonKeyValue pairs */ + JsonOutput *output; /* RETURNING clause, if specified */ + bool absent_on_null; /* skip NULL values? */ + bool unique; /* check key uniqueness? */ + int location; /* token location, or -1 if unknown */ +} JsonObjectConstructor; + +/* + * JsonArrayConstructor - + * untransformed representation of JSON_ARRAY(element,...) constructor + */ +typedef struct JsonArrayConstructor +{ + NodeTag type; + List *exprs; /* list of JsonValueExpr elements */ + JsonOutput *output; /* RETURNING clause, if specified */ + bool absent_on_null; /* skip NULL elements? */ + int location; /* token location, or -1 if unknown */ +} JsonArrayConstructor; + +/* + * JsonArrayQueryConstructor - + * untransformed representation of JSON_ARRAY(subquery) constructor + */ +typedef struct JsonArrayQueryConstructor +{ + NodeTag type; + Node *query; /* subquery */ + JsonOutput *output; /* RETURNING clause, if specified */ + JsonFormat *format; /* FORMAT clause for subquery, if specified */ + bool absent_on_null; /* skip NULL elements? */ + int location; /* token location, or -1 if unknown */ +} JsonArrayQueryConstructor; + +/* + * JsonAggConstructor - + * common fields of untransformed representation of + * JSON_ARRAYAGG() and JSON_OBJECTAGG() + */ +typedef struct JsonAggConstructor +{ + NodeTag type; + JsonOutput *output; /* RETURNING clause, if any */ + Node *agg_filter; /* FILTER clause, if any */ + List *agg_order; /* ORDER BY clause, if any */ + struct WindowDef *over; /* OVER clause, if any */ + int location; /* token location, or -1 if unknown */ +} JsonAggConstructor; + +/* + * JsonObjectAgg - + * untransformed representation of JSON_OBJECTAGG() + */ +typedef struct JsonObjectAgg +{ + NodeTag type; + JsonAggConstructor *constructor; /* common fields */ + JsonKeyValue *arg; /* object key-value pair */ + bool absent_on_null; /* skip NULL values? */ + bool unique; /* check key uniqueness? */ +} JsonObjectAgg; + +/* + * JsonArrayAgg - + * untransformed representation of JSON_ARRAYAGG() + */ +typedef struct JsonArrayAgg +{ + NodeTag type; + JsonAggConstructor *constructor; /* common fields */ + JsonValueExpr *arg; /* array element expression */ + bool absent_on_null; /* skip NULL elements? */ +} JsonArrayAgg; + + +/***************************************************************************** + * Raw Grammar Output Statements + *****************************************************************************/ + +/* + * RawStmt --- container for any one statement's raw parse tree + * + * Parse analysis converts a raw parse tree headed by a RawStmt node into + * an analyzed statement headed by a Query node. For optimizable statements, + * the conversion is complex. For utility statements, the parser usually just + * transfers the raw parse tree (sans RawStmt) into the utilityStmt field of + * the Query node, and all the useful work happens at execution time. + * + * stmt_location/stmt_len identify the portion of the source text string + * containing this raw statement (useful for multi-statement strings). + * + * This is irrelevant for query jumbling, as this is not used in parsed + * queries. + */ +typedef struct RawStmt +{ + pg_node_attr(no_query_jumble) + + NodeTag type; + Node *stmt; /* raw parse tree */ + int stmt_location; /* start location, or -1 if unknown */ + int stmt_len; /* length in bytes; 0 means "rest of string" */ +} RawStmt; + +/***************************************************************************** + * Optimizable Statements + *****************************************************************************/ + +/* ---------------------- + * Insert Statement + * + * The source expression is represented by SelectStmt for both the + * SELECT and VALUES cases. If selectStmt is NULL, then the query + * is INSERT ... DEFAULT VALUES. + * ---------------------- + */ +typedef struct InsertStmt +{ + NodeTag type; + RangeVar *relation; /* relation to insert into */ + List *cols; /* optional: names of the target columns */ + Node *selectStmt; /* the source SELECT/VALUES, or NULL */ + OnConflictClause *onConflictClause; /* ON CONFLICT clause */ + List *returningList; /* list of expressions to return */ + WithClause *withClause; /* WITH clause */ + OverridingKind override; /* OVERRIDING clause */ +} InsertStmt; + +/* ---------------------- + * Delete Statement + * ---------------------- + */ +typedef struct DeleteStmt +{ + NodeTag type; + RangeVar *relation; /* relation to delete from */ + List *usingClause; /* optional using clause for more tables */ + Node *whereClause; /* qualifications */ + List *returningList; /* list of expressions to return */ + WithClause *withClause; /* WITH clause */ +} DeleteStmt; + +/* ---------------------- + * Update Statement + * ---------------------- + */ +typedef struct UpdateStmt +{ + NodeTag type; + RangeVar *relation; /* relation to update */ + List *targetList; /* the target list (of ResTarget) */ + Node *whereClause; /* qualifications */ + List *fromClause; /* optional from clause for more tables */ + List *returningList; /* list of expressions to return */ + WithClause *withClause; /* WITH clause */ +} UpdateStmt; + +/* ---------------------- + * Merge Statement + * ---------------------- + */ +typedef struct MergeStmt +{ + NodeTag type; + RangeVar *relation; /* target relation to merge into */ + Node *sourceRelation; /* source relation */ + Node *joinCondition; /* join condition between source and target */ + List *mergeWhenClauses; /* list of MergeWhenClause(es) */ + WithClause *withClause; /* WITH clause */ +} MergeStmt; + +/* ---------------------- + * Select Statement + * + * A "simple" SELECT is represented in the output of gram.y by a single + * SelectStmt node; so is a VALUES construct. A query containing set + * operators (UNION, INTERSECT, EXCEPT) is represented by a tree of SelectStmt + * nodes, in which the leaf nodes are component SELECTs and the internal nodes + * represent UNION, INTERSECT, or EXCEPT operators. Using the same node + * type for both leaf and internal nodes allows gram.y to stick ORDER BY, + * LIMIT, etc, clause values into a SELECT statement without worrying + * whether it is a simple or compound SELECT. + * ---------------------- + */ +typedef enum SetOperation +{ + SETOP_NONE = 0, + SETOP_UNION, + SETOP_INTERSECT, + SETOP_EXCEPT +} SetOperation; + +typedef struct SelectStmt +{ + NodeTag type; + + /* + * These fields are used only in "leaf" SelectStmts. + */ + List *distinctClause; /* NULL, list of DISTINCT ON exprs, or + * lcons(NIL,NIL) for all (SELECT DISTINCT) */ + IntoClause *intoClause; /* target for SELECT INTO */ + List *targetList; /* the target list (of ResTarget) */ + List *fromClause; /* the FROM clause */ + Node *whereClause; /* WHERE qualification */ + List *groupClause; /* GROUP BY clauses */ + bool groupDistinct; /* Is this GROUP BY DISTINCT? */ + Node *havingClause; /* HAVING conditional-expression */ + List *windowClause; /* WINDOW window_name AS (...), ... */ + + /* + * In a "leaf" node representing a VALUES list, the above fields are all + * null, and instead this field is set. Note that the elements of the + * sublists are just expressions, without ResTarget decoration. Also note + * that a list element can be DEFAULT (represented as a SetToDefault + * node), regardless of the context of the VALUES list. It's up to parse + * analysis to reject that where not valid. + */ + List *valuesLists; /* untransformed list of expression lists */ + + /* + * These fields are used in both "leaf" SelectStmts and upper-level + * SelectStmts. + */ + List *sortClause; /* sort clause (a list of SortBy's) */ + Node *limitOffset; /* # of result tuples to skip */ + Node *limitCount; /* # of result tuples to return */ + LimitOption limitOption; /* limit type */ + List *lockingClause; /* FOR UPDATE (list of LockingClause's) */ + WithClause *withClause; /* WITH clause */ + + /* + * These fields are used only in upper-level SelectStmts. + */ + SetOperation op; /* type of set op */ + bool all; /* ALL specified? */ + struct SelectStmt *larg; /* left child */ + struct SelectStmt *rarg; /* right child */ + /* Eventually add fields for CORRESPONDING spec here */ +} SelectStmt; + + +/* ---------------------- + * Set Operation node for post-analysis query trees + * + * After parse analysis, a SELECT with set operations is represented by a + * top-level Query node containing the leaf SELECTs as subqueries in its + * range table. Its setOperations field shows the tree of set operations, + * with leaf SelectStmt nodes replaced by RangeTblRef nodes, and internal + * nodes replaced by SetOperationStmt nodes. Information about the output + * column types is added, too. (Note that the child nodes do not necessarily + * produce these types directly, but we've checked that their output types + * can be coerced to the output column type.) Also, if it's not UNION ALL, + * information about the types' sort/group semantics is provided in the form + * of a SortGroupClause list (same representation as, eg, DISTINCT). + * The resolved common column collations are provided too; but note that if + * it's not UNION ALL, it's okay for a column to not have a common collation, + * so a member of the colCollations list could be InvalidOid even though the + * column has a collatable type. + * ---------------------- + */ +typedef struct SetOperationStmt +{ + NodeTag type; + SetOperation op; /* type of set op */ + bool all; /* ALL specified? */ + Node *larg; /* left child */ + Node *rarg; /* right child */ + /* Eventually add fields for CORRESPONDING spec here */ + + /* Fields derived during parse analysis (irrelevant for query jumbling): */ + /* OID list of output column type OIDs */ + List *colTypes pg_node_attr(query_jumble_ignore); + /* integer list of output column typmods */ + List *colTypmods pg_node_attr(query_jumble_ignore); + /* OID list of output column collation OIDs */ + List *colCollations pg_node_attr(query_jumble_ignore); + /* a list of SortGroupClause's */ + List *groupClauses pg_node_attr(query_jumble_ignore); + /* groupClauses is NIL if UNION ALL, but must be set otherwise */ +} SetOperationStmt; + + +/* + * RETURN statement (inside SQL function body) + */ +typedef struct ReturnStmt +{ + NodeTag type; + Node *returnval; +} ReturnStmt; + + +/* ---------------------- + * PL/pgSQL Assignment Statement + * + * Like SelectStmt, this is transformed into a SELECT Query. + * However, the targetlist of the result looks more like an UPDATE. + * ---------------------- + */ +typedef struct PLAssignStmt +{ + NodeTag type; + + char *name; /* initial column name */ + List *indirection; /* subscripts and field names, if any */ + int nnames; /* number of names to use in ColumnRef */ + SelectStmt *val; /* the PL/pgSQL expression to assign */ + int location; /* name's token location, or -1 if unknown */ +} PLAssignStmt; + + +/***************************************************************************** + * Other Statements (no optimizations required) + * + * These are not touched by parser/analyze.c except to put them into + * the utilityStmt field of a Query. This is eventually passed to + * ProcessUtility (by-passing rewriting and planning). Some of the + * statements do need attention from parse analysis, and this is + * done by routines in parser/parse_utilcmd.c after ProcessUtility + * receives the command for execution. + * DECLARE CURSOR, EXPLAIN, and CREATE TABLE AS are special cases: + * they contain optimizable statements, which get processed normally + * by parser/analyze.c. + *****************************************************************************/ + +/* + * When a command can act on several kinds of objects with only one + * parse structure required, use these constants to designate the + * object type. Note that commands typically don't support all the types. + */ + +typedef enum ObjectType +{ + OBJECT_ACCESS_METHOD, + OBJECT_AGGREGATE, + OBJECT_AMOP, + OBJECT_AMPROC, + OBJECT_ATTRIBUTE, /* type's attribute, when distinct from column */ + OBJECT_CAST, + OBJECT_COLUMN, + OBJECT_COLLATION, + OBJECT_CONVERSION, + OBJECT_DATABASE, + OBJECT_DEFAULT, + OBJECT_DEFACL, + OBJECT_DOMAIN, + OBJECT_DOMCONSTRAINT, + OBJECT_EVENT_TRIGGER, + OBJECT_EXTENSION, + OBJECT_FDW, + OBJECT_FOREIGN_SERVER, + OBJECT_FOREIGN_TABLE, + OBJECT_FUNCTION, + OBJECT_INDEX, + OBJECT_LANGUAGE, + OBJECT_LARGEOBJECT, + OBJECT_MATVIEW, + OBJECT_OPCLASS, + OBJECT_OPERATOR, + OBJECT_OPFAMILY, + OBJECT_PARAMETER_ACL, + OBJECT_POLICY, + OBJECT_PROCEDURE, + OBJECT_PUBLICATION, + OBJECT_PUBLICATION_NAMESPACE, + OBJECT_PUBLICATION_REL, + OBJECT_ROLE, + OBJECT_ROUTINE, + OBJECT_RULE, + OBJECT_SCHEMA, + OBJECT_SEQUENCE, + OBJECT_SUBSCRIPTION, + OBJECT_STATISTIC_EXT, + OBJECT_TABCONSTRAINT, + OBJECT_TABLE, + OBJECT_TABLESPACE, + OBJECT_TRANSFORM, + OBJECT_TRIGGER, + OBJECT_TSCONFIGURATION, + OBJECT_TSDICTIONARY, + OBJECT_TSPARSER, + OBJECT_TSTEMPLATE, + OBJECT_TYPE, + OBJECT_USER_MAPPING, + OBJECT_VIEW +} ObjectType; + +/* ---------------------- + * Create Schema Statement + * + * NOTE: the schemaElts list contains raw parsetrees for component statements + * of the schema, such as CREATE TABLE, GRANT, etc. These are analyzed and + * executed after the schema itself is created. + * ---------------------- + */ +typedef struct CreateSchemaStmt +{ + NodeTag type; + char *schemaname; /* the name of the schema to create */ + RoleSpec *authrole; /* the owner of the created schema */ + List *schemaElts; /* schema components (list of parsenodes) */ + bool if_not_exists; /* just do nothing if schema already exists? */ +} CreateSchemaStmt; + +typedef enum DropBehavior +{ + DROP_RESTRICT, /* drop fails if any dependent objects */ + DROP_CASCADE /* remove dependent objects too */ +} DropBehavior; + +/* ---------------------- + * Alter Table + * ---------------------- + */ +typedef struct AlterTableStmt +{ + NodeTag type; + RangeVar *relation; /* table to work on */ + List *cmds; /* list of subcommands */ + ObjectType objtype; /* type of object */ + bool missing_ok; /* skip error if table missing */ +} AlterTableStmt; + +typedef enum AlterTableType +{ + AT_AddColumn, /* add column */ + AT_AddColumnToView, /* implicitly via CREATE OR REPLACE VIEW */ + AT_ColumnDefault, /* alter column default */ + AT_CookedColumnDefault, /* add a pre-cooked column default */ + AT_DropNotNull, /* alter column drop not null */ + AT_SetNotNull, /* alter column set not null */ + AT_DropExpression, /* alter column drop expression */ + AT_CheckNotNull, /* check column is already marked not null */ + AT_SetStatistics, /* alter column set statistics */ + AT_SetOptions, /* alter column set ( options ) */ + AT_ResetOptions, /* alter column reset ( options ) */ + AT_SetStorage, /* alter column set storage */ + AT_SetCompression, /* alter column set compression */ + AT_DropColumn, /* drop column */ + AT_AddIndex, /* add index */ + AT_ReAddIndex, /* internal to commands/tablecmds.c */ + AT_AddConstraint, /* add constraint */ + AT_ReAddConstraint, /* internal to commands/tablecmds.c */ + AT_ReAddDomainConstraint, /* internal to commands/tablecmds.c */ + AT_AlterConstraint, /* alter constraint */ + AT_ValidateConstraint, /* validate constraint */ + AT_AddIndexConstraint, /* add constraint using existing index */ + AT_DropConstraint, /* drop constraint */ + AT_ReAddComment, /* internal to commands/tablecmds.c */ + AT_AlterColumnType, /* alter column type */ + AT_AlterColumnGenericOptions, /* alter column OPTIONS (...) */ + AT_ChangeOwner, /* change owner */ + AT_ClusterOn, /* CLUSTER ON */ + AT_DropCluster, /* SET WITHOUT CLUSTER */ + AT_SetLogged, /* SET LOGGED */ + AT_SetUnLogged, /* SET UNLOGGED */ + AT_DropOids, /* SET WITHOUT OIDS */ + AT_SetAccessMethod, /* SET ACCESS METHOD */ + AT_SetTableSpace, /* SET TABLESPACE */ + AT_SetRelOptions, /* SET (...) -- AM specific parameters */ + AT_ResetRelOptions, /* RESET (...) -- AM specific parameters */ + AT_ReplaceRelOptions, /* replace reloption list in its entirety */ + AT_EnableTrig, /* ENABLE TRIGGER name */ + AT_EnableAlwaysTrig, /* ENABLE ALWAYS TRIGGER name */ + AT_EnableReplicaTrig, /* ENABLE REPLICA TRIGGER name */ + AT_DisableTrig, /* DISABLE TRIGGER name */ + AT_EnableTrigAll, /* ENABLE TRIGGER ALL */ + AT_DisableTrigAll, /* DISABLE TRIGGER ALL */ + AT_EnableTrigUser, /* ENABLE TRIGGER USER */ + AT_DisableTrigUser, /* DISABLE TRIGGER USER */ + AT_EnableRule, /* ENABLE RULE name */ + AT_EnableAlwaysRule, /* ENABLE ALWAYS RULE name */ + AT_EnableReplicaRule, /* ENABLE REPLICA RULE name */ + AT_DisableRule, /* DISABLE RULE name */ + AT_AddInherit, /* INHERIT parent */ + AT_DropInherit, /* NO INHERIT parent */ + AT_AddOf, /* OF */ + AT_DropOf, /* NOT OF */ + AT_ReplicaIdentity, /* REPLICA IDENTITY */ + AT_EnableRowSecurity, /* ENABLE ROW SECURITY */ + AT_DisableRowSecurity, /* DISABLE ROW SECURITY */ + AT_ForceRowSecurity, /* FORCE ROW SECURITY */ + AT_NoForceRowSecurity, /* NO FORCE ROW SECURITY */ + AT_GenericOptions, /* OPTIONS (...) */ + AT_AttachPartition, /* ATTACH PARTITION */ + AT_DetachPartition, /* DETACH PARTITION */ + AT_DetachPartitionFinalize, /* DETACH PARTITION FINALIZE */ + AT_AddIdentity, /* ADD IDENTITY */ + AT_SetIdentity, /* SET identity column options */ + AT_DropIdentity, /* DROP IDENTITY */ + AT_ReAddStatistics /* internal to commands/tablecmds.c */ +} AlterTableType; + +typedef struct ReplicaIdentityStmt +{ + NodeTag type; + char identity_type; + char *name; +} ReplicaIdentityStmt; + +typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ +{ + NodeTag type; + AlterTableType subtype; /* Type of table alteration to apply */ + char *name; /* column, constraint, or trigger to act on, + * or tablespace */ + int16 num; /* attribute number for columns referenced by + * number */ + RoleSpec *newowner; + Node *def; /* definition of new column, index, + * constraint, or parent table */ + DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ + bool missing_ok; /* skip error if missing? */ + bool recurse; /* exec-time recursion */ +} AlterTableCmd; + + +/* ---------------------- + * Alter Collation + * ---------------------- + */ +typedef struct AlterCollationStmt +{ + NodeTag type; + List *collname; +} AlterCollationStmt; + + +/* ---------------------- + * Alter Domain + * + * The fields are used in different ways by the different variants of + * this command. + * ---------------------- + */ +typedef struct AlterDomainStmt +{ + NodeTag type; + char subtype; /*------------ + * T = alter column default + * N = alter column drop not null + * O = alter column set not null + * C = add constraint + * X = drop constraint + *------------ + */ + List *typeName; /* domain to work on */ + char *name; /* column or constraint name to act on */ + Node *def; /* definition of default or constraint */ + DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ + bool missing_ok; /* skip error if missing? */ +} AlterDomainStmt; + + +/* ---------------------- + * Grant|Revoke Statement + * ---------------------- + */ +typedef enum GrantTargetType +{ + ACL_TARGET_OBJECT, /* grant on specific named object(s) */ + ACL_TARGET_ALL_IN_SCHEMA, /* grant on all objects in given schema(s) */ + ACL_TARGET_DEFAULTS /* ALTER DEFAULT PRIVILEGES */ +} GrantTargetType; + +typedef struct GrantStmt +{ + NodeTag type; + bool is_grant; /* true = GRANT, false = REVOKE */ + GrantTargetType targtype; /* type of the grant target */ + ObjectType objtype; /* kind of object being operated on */ + List *objects; /* list of RangeVar nodes, ObjectWithArgs + * nodes, or plain names (as String values) */ + List *privileges; /* list of AccessPriv nodes */ + /* privileges == NIL denotes ALL PRIVILEGES */ + List *grantees; /* list of RoleSpec nodes */ + bool grant_option; /* grant or revoke grant option */ + RoleSpec *grantor; + DropBehavior behavior; /* drop behavior (for REVOKE) */ +} GrantStmt; + +/* + * ObjectWithArgs represents a function/procedure/operator name plus parameter + * identification. + * + * objargs includes only the types of the input parameters of the object. + * In some contexts, that will be all we have, and it's enough to look up + * objects according to the traditional Postgres rules (i.e., when only input + * arguments matter). + * + * objfuncargs, if not NIL, carries the full specification of the parameter + * list, including parameter mode annotations. + * + * Some grammar productions can set args_unspecified = true instead of + * providing parameter info. In this case, lookup will succeed only if + * the object name is unique. Note that otherwise, NIL parameter lists + * mean zero arguments. + */ +typedef struct ObjectWithArgs +{ + NodeTag type; + List *objname; /* qualified name of function/operator */ + List *objargs; /* list of Typename nodes (input args only) */ + List *objfuncargs; /* list of FunctionParameter nodes */ + bool args_unspecified; /* argument list was omitted? */ +} ObjectWithArgs; + +/* + * An access privilege, with optional list of column names + * priv_name == NULL denotes ALL PRIVILEGES (only used with a column list) + * cols == NIL denotes "all columns" + * Note that simple "ALL PRIVILEGES" is represented as a NIL list, not + * an AccessPriv with both fields null. + */ +typedef struct AccessPriv +{ + NodeTag type; + char *priv_name; /* string name of privilege */ + List *cols; /* list of String */ +} AccessPriv; + +/* ---------------------- + * Grant/Revoke Role Statement + * + * Note: because of the parsing ambiguity with the GRANT + * statement, granted_roles is a list of AccessPriv; the execution code + * should complain if any column lists appear. grantee_roles is a list + * of role names, as String values. + * ---------------------- + */ +typedef struct GrantRoleStmt +{ + NodeTag type; + List *granted_roles; /* list of roles to be granted/revoked */ + List *grantee_roles; /* list of member roles to add/delete */ + bool is_grant; /* true = GRANT, false = REVOKE */ + List *opt; /* options e.g. WITH GRANT OPTION */ + RoleSpec *grantor; /* set grantor to other than current role */ + DropBehavior behavior; /* drop behavior (for REVOKE) */ +} GrantRoleStmt; + +/* ---------------------- + * Alter Default Privileges Statement + * ---------------------- + */ +typedef struct AlterDefaultPrivilegesStmt +{ + NodeTag type; + List *options; /* list of DefElem */ + GrantStmt *action; /* GRANT/REVOKE action (with objects=NIL) */ +} AlterDefaultPrivilegesStmt; + +/* ---------------------- + * Copy Statement + * + * We support "COPY relation FROM file", "COPY relation TO file", and + * "COPY (query) TO file". In any given CopyStmt, exactly one of "relation" + * and "query" must be non-NULL. + * ---------------------- + */ +typedef struct CopyStmt +{ + NodeTag type; + RangeVar *relation; /* the relation to copy */ + Node *query; /* the query (SELECT or DML statement with + * RETURNING) to copy, as a raw parse tree */ + List *attlist; /* List of column names (as Strings), or NIL + * for all columns */ + bool is_from; /* TO or FROM */ + bool is_program; /* is 'filename' a program to popen? */ + char *filename; /* filename, or NULL for STDIN/STDOUT */ + List *options; /* List of DefElem nodes */ + Node *whereClause; /* WHERE condition (or NULL) */ +} CopyStmt; + +/* ---------------------- + * SET Statement (includes RESET) + * + * "SET var TO DEFAULT" and "RESET var" are semantically equivalent, but we + * preserve the distinction in VariableSetKind for CreateCommandTag(). + * ---------------------- + */ +typedef enum VariableSetKind +{ + VAR_SET_VALUE, /* SET var = value */ + VAR_SET_DEFAULT, /* SET var TO DEFAULT */ + VAR_SET_CURRENT, /* SET var FROM CURRENT */ + VAR_SET_MULTI, /* special case for SET TRANSACTION ... */ + VAR_RESET, /* RESET var */ + VAR_RESET_ALL /* RESET ALL */ +} VariableSetKind; + +typedef struct VariableSetStmt +{ + NodeTag type; + VariableSetKind kind; + char *name; /* variable to be set */ + List *args; /* List of A_Const nodes */ + bool is_local; /* SET LOCAL? */ +} VariableSetStmt; + +/* ---------------------- + * Show Statement + * ---------------------- + */ +typedef struct VariableShowStmt +{ + NodeTag type; + char *name; +} VariableShowStmt; + +/* ---------------------- + * Create Table Statement + * + * NOTE: in the raw gram.y output, ColumnDef and Constraint nodes are + * intermixed in tableElts, and constraints is NIL. After parse analysis, + * tableElts contains just ColumnDefs, and constraints contains just + * Constraint nodes (in fact, only CONSTR_CHECK nodes, in the present + * implementation). + * ---------------------- + */ + +typedef struct CreateStmt +{ + NodeTag type; + RangeVar *relation; /* relation to create */ + List *tableElts; /* column definitions (list of ColumnDef) */ + List *inhRelations; /* relations to inherit from (list of + * RangeVar) */ + PartitionBoundSpec *partbound; /* FOR VALUES clause */ + PartitionSpec *partspec; /* PARTITION BY clause */ + TypeName *ofTypename; /* OF typename */ + List *constraints; /* constraints (list of Constraint nodes) */ + List *options; /* options from WITH clause */ + OnCommitAction oncommit; /* what do we do at COMMIT? */ + char *tablespacename; /* table space to use, or NULL */ + char *accessMethod; /* table access method */ + bool if_not_exists; /* just do nothing if it already exists? */ +} CreateStmt; + +/* ---------- + * Definitions for constraints in CreateStmt + * + * Note that column defaults are treated as a type of constraint, + * even though that's a bit odd semantically. + * + * For constraints that use expressions (CONSTR_CHECK, CONSTR_DEFAULT) + * we may have the expression in either "raw" form (an untransformed + * parse tree) or "cooked" form (the nodeToString representation of + * an executable expression tree), depending on how this Constraint + * node was created (by parsing, or by inheritance from an existing + * relation). We should never have both in the same node! + * + * FKCONSTR_ACTION_xxx values are stored into pg_constraint.confupdtype + * and pg_constraint.confdeltype columns; FKCONSTR_MATCH_xxx values are + * stored into pg_constraint.confmatchtype. Changing the code values may + * require an initdb! + * + * If skip_validation is true then we skip checking that the existing rows + * in the table satisfy the constraint, and just install the catalog entries + * for the constraint. A new FK constraint is marked as valid iff + * initially_valid is true. (Usually skip_validation and initially_valid + * are inverses, but we can set both true if the table is known empty.) + * + * Constraint attributes (DEFERRABLE etc) are initially represented as + * separate Constraint nodes for simplicity of parsing. parse_utilcmd.c makes + * a pass through the constraints list to insert the info into the appropriate + * Constraint node. + * ---------- + */ + +typedef enum ConstrType /* types of constraints */ +{ + CONSTR_NULL, /* not standard SQL, but a lot of people + * expect it */ + CONSTR_NOTNULL, + CONSTR_DEFAULT, + CONSTR_IDENTITY, + CONSTR_GENERATED, + CONSTR_CHECK, + CONSTR_PRIMARY, + CONSTR_UNIQUE, + CONSTR_EXCLUSION, + CONSTR_FOREIGN, + CONSTR_ATTR_DEFERRABLE, /* attributes for previous constraint node */ + CONSTR_ATTR_NOT_DEFERRABLE, + CONSTR_ATTR_DEFERRED, + CONSTR_ATTR_IMMEDIATE +} ConstrType; + +/* Foreign key action codes */ +#define FKCONSTR_ACTION_NOACTION 'a' +#define FKCONSTR_ACTION_RESTRICT 'r' +#define FKCONSTR_ACTION_CASCADE 'c' +#define FKCONSTR_ACTION_SETNULL 'n' +#define FKCONSTR_ACTION_SETDEFAULT 'd' + +/* Foreign key matchtype codes */ +#define FKCONSTR_MATCH_FULL 'f' +#define FKCONSTR_MATCH_PARTIAL 'p' +#define FKCONSTR_MATCH_SIMPLE 's' + +typedef struct Constraint +{ + pg_node_attr(custom_read_write) + + NodeTag type; + ConstrType contype; /* see above */ + + /* Fields used for most/all constraint types: */ + char *conname; /* Constraint name, or NULL if unnamed */ + bool deferrable; /* DEFERRABLE? */ + bool initdeferred; /* INITIALLY DEFERRED? */ + int location; /* token location, or -1 if unknown */ + + /* Fields used for constraints with expressions (CHECK and DEFAULT): */ + bool is_no_inherit; /* is constraint non-inheritable? */ + Node *raw_expr; /* expr, as untransformed parse tree */ + char *cooked_expr; /* expr, as nodeToString representation */ + char generated_when; /* ALWAYS or BY DEFAULT */ + + /* Fields used for unique constraints (UNIQUE and PRIMARY KEY): */ + bool nulls_not_distinct; /* null treatment for UNIQUE constraints */ + List *keys; /* String nodes naming referenced key + * column(s) */ + List *including; /* String nodes naming referenced nonkey + * column(s) */ + + /* Fields used for EXCLUSION constraints: */ + List *exclusions; /* list of (IndexElem, operator name) pairs */ + + /* Fields used for index constraints (UNIQUE, PRIMARY KEY, EXCLUSION): */ + List *options; /* options from WITH clause */ + char *indexname; /* existing index to use; otherwise NULL */ + char *indexspace; /* index tablespace; NULL for default */ + bool reset_default_tblspc; /* reset default_tablespace prior to + * creating the index */ + /* These could be, but currently are not, used for UNIQUE/PKEY: */ + char *access_method; /* index access method; NULL for default */ + Node *where_clause; /* partial index predicate */ + + /* Fields used for FOREIGN KEY constraints: */ + RangeVar *pktable; /* Primary key table */ + List *fk_attrs; /* Attributes of foreign key */ + List *pk_attrs; /* Corresponding attrs in PK table */ + char fk_matchtype; /* FULL, PARTIAL, SIMPLE */ + char fk_upd_action; /* ON UPDATE action */ + char fk_del_action; /* ON DELETE action */ + List *fk_del_set_cols; /* ON DELETE SET NULL/DEFAULT (col1, col2) */ + List *old_conpfeqop; /* pg_constraint.conpfeqop of my former self */ + Oid old_pktable_oid; /* pg_constraint.confrelid of my former + * self */ + + /* Fields used for constraints that allow a NOT VALID specification */ + bool skip_validation; /* skip validation of existing rows? */ + bool initially_valid; /* mark the new constraint as valid? */ +} Constraint; + +/* ---------------------- + * Create/Drop Table Space Statements + * ---------------------- + */ + +typedef struct CreateTableSpaceStmt +{ + NodeTag type; + char *tablespacename; + RoleSpec *owner; + char *location; + List *options; +} CreateTableSpaceStmt; + +typedef struct DropTableSpaceStmt +{ + NodeTag type; + char *tablespacename; + bool missing_ok; /* skip error if missing? */ +} DropTableSpaceStmt; + +typedef struct AlterTableSpaceOptionsStmt +{ + NodeTag type; + char *tablespacename; + List *options; + bool isReset; +} AlterTableSpaceOptionsStmt; + +typedef struct AlterTableMoveAllStmt +{ + NodeTag type; + char *orig_tablespacename; + ObjectType objtype; /* Object type to move */ + List *roles; /* List of roles to move objects of */ + char *new_tablespacename; + bool nowait; +} AlterTableMoveAllStmt; + +/* ---------------------- + * Create/Alter Extension Statements + * ---------------------- + */ + +typedef struct CreateExtensionStmt +{ + NodeTag type; + char *extname; + bool if_not_exists; /* just do nothing if it already exists? */ + List *options; /* List of DefElem nodes */ +} CreateExtensionStmt; + +/* Only used for ALTER EXTENSION UPDATE; later might need an action field */ +typedef struct AlterExtensionStmt +{ + NodeTag type; + char *extname; + List *options; /* List of DefElem nodes */ +} AlterExtensionStmt; + +typedef struct AlterExtensionContentsStmt +{ + NodeTag type; + char *extname; /* Extension's name */ + int action; /* +1 = add object, -1 = drop object */ + ObjectType objtype; /* Object's type */ + Node *object; /* Qualified name of the object */ +} AlterExtensionContentsStmt; + +/* ---------------------- + * Create/Alter FOREIGN DATA WRAPPER Statements + * ---------------------- + */ + +typedef struct CreateFdwStmt +{ + NodeTag type; + char *fdwname; /* foreign-data wrapper name */ + List *func_options; /* HANDLER/VALIDATOR options */ + List *options; /* generic options to FDW */ +} CreateFdwStmt; + +typedef struct AlterFdwStmt +{ + NodeTag type; + char *fdwname; /* foreign-data wrapper name */ + List *func_options; /* HANDLER/VALIDATOR options */ + List *options; /* generic options to FDW */ +} AlterFdwStmt; + +/* ---------------------- + * Create/Alter FOREIGN SERVER Statements + * ---------------------- + */ + +typedef struct CreateForeignServerStmt +{ + NodeTag type; + char *servername; /* server name */ + char *servertype; /* optional server type */ + char *version; /* optional server version */ + char *fdwname; /* FDW name */ + bool if_not_exists; /* just do nothing if it already exists? */ + List *options; /* generic options to server */ +} CreateForeignServerStmt; + +typedef struct AlterForeignServerStmt +{ + NodeTag type; + char *servername; /* server name */ + char *version; /* optional server version */ + List *options; /* generic options to server */ + bool has_version; /* version specified */ +} AlterForeignServerStmt; + +/* ---------------------- + * Create FOREIGN TABLE Statement + * ---------------------- + */ + +typedef struct CreateForeignTableStmt +{ + CreateStmt base; + char *servername; + List *options; +} CreateForeignTableStmt; + +/* ---------------------- + * Create/Drop USER MAPPING Statements + * ---------------------- + */ + +typedef struct CreateUserMappingStmt +{ + NodeTag type; + RoleSpec *user; /* user role */ + char *servername; /* server name */ + bool if_not_exists; /* just do nothing if it already exists? */ + List *options; /* generic options to server */ +} CreateUserMappingStmt; + +typedef struct AlterUserMappingStmt +{ + NodeTag type; + RoleSpec *user; /* user role */ + char *servername; /* server name */ + List *options; /* generic options to server */ +} AlterUserMappingStmt; + +typedef struct DropUserMappingStmt +{ + NodeTag type; + RoleSpec *user; /* user role */ + char *servername; /* server name */ + bool missing_ok; /* ignore missing mappings */ +} DropUserMappingStmt; + +/* ---------------------- + * Import Foreign Schema Statement + * ---------------------- + */ + +typedef enum ImportForeignSchemaType +{ + FDW_IMPORT_SCHEMA_ALL, /* all relations wanted */ + FDW_IMPORT_SCHEMA_LIMIT_TO, /* include only listed tables in import */ + FDW_IMPORT_SCHEMA_EXCEPT /* exclude listed tables from import */ +} ImportForeignSchemaType; + +typedef struct ImportForeignSchemaStmt +{ + NodeTag type; + char *server_name; /* FDW server name */ + char *remote_schema; /* remote schema name to query */ + char *local_schema; /* local schema to create objects in */ + ImportForeignSchemaType list_type; /* type of table list */ + List *table_list; /* List of RangeVar */ + List *options; /* list of options to pass to FDW */ +} ImportForeignSchemaStmt; + +/*---------------------- + * Create POLICY Statement + *---------------------- + */ +typedef struct CreatePolicyStmt +{ + NodeTag type; + char *policy_name; /* Policy's name */ + RangeVar *table; /* the table name the policy applies to */ + char *cmd_name; /* the command name the policy applies to */ + bool permissive; /* restrictive or permissive policy */ + List *roles; /* the roles associated with the policy */ + Node *qual; /* the policy's condition */ + Node *with_check; /* the policy's WITH CHECK condition. */ +} CreatePolicyStmt; + +/*---------------------- + * Alter POLICY Statement + *---------------------- + */ +typedef struct AlterPolicyStmt +{ + NodeTag type; + char *policy_name; /* Policy's name */ + RangeVar *table; /* the table name the policy applies to */ + List *roles; /* the roles associated with the policy */ + Node *qual; /* the policy's condition */ + Node *with_check; /* the policy's WITH CHECK condition. */ +} AlterPolicyStmt; + +/*---------------------- + * Create ACCESS METHOD Statement + *---------------------- + */ +typedef struct CreateAmStmt +{ + NodeTag type; + char *amname; /* access method name */ + List *handler_name; /* handler function name */ + char amtype; /* type of access method */ +} CreateAmStmt; + +/* ---------------------- + * Create TRIGGER Statement + * ---------------------- + */ +typedef struct CreateTrigStmt +{ + NodeTag type; + bool replace; /* replace trigger if already exists */ + bool isconstraint; /* This is a constraint trigger */ + char *trigname; /* TRIGGER's name */ + RangeVar *relation; /* relation trigger is on */ + List *funcname; /* qual. name of function to call */ + List *args; /* list of String or NIL */ + bool row; /* ROW/STATEMENT */ + /* timing uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ + int16 timing; /* BEFORE, AFTER, or INSTEAD */ + /* events uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ + int16 events; /* "OR" of INSERT/UPDATE/DELETE/TRUNCATE */ + List *columns; /* column names, or NIL for all columns */ + Node *whenClause; /* qual expression, or NULL if none */ + /* explicitly named transition data */ + List *transitionRels; /* TriggerTransition nodes, or NIL if none */ + /* The remaining fields are only used for constraint triggers */ + bool deferrable; /* [NOT] DEFERRABLE */ + bool initdeferred; /* INITIALLY {DEFERRED|IMMEDIATE} */ + RangeVar *constrrel; /* opposite relation, if RI trigger */ +} CreateTrigStmt; + +/* ---------------------- + * Create EVENT TRIGGER Statement + * ---------------------- + */ +typedef struct CreateEventTrigStmt +{ + NodeTag type; + char *trigname; /* TRIGGER's name */ + char *eventname; /* event's identifier */ + List *whenclause; /* list of DefElems indicating filtering */ + List *funcname; /* qual. name of function to call */ +} CreateEventTrigStmt; + +/* ---------------------- + * Alter EVENT TRIGGER Statement + * ---------------------- + */ +typedef struct AlterEventTrigStmt +{ + NodeTag type; + char *trigname; /* TRIGGER's name */ + char tgenabled; /* trigger's firing configuration WRT + * session_replication_role */ +} AlterEventTrigStmt; + +/* ---------------------- + * Create LANGUAGE Statements + * ---------------------- + */ +typedef struct CreatePLangStmt +{ + NodeTag type; + bool replace; /* T => replace if already exists */ + char *plname; /* PL name */ + List *plhandler; /* PL call handler function (qual. name) */ + List *plinline; /* optional inline function (qual. name) */ + List *plvalidator; /* optional validator function (qual. name) */ + bool pltrusted; /* PL is trusted */ +} CreatePLangStmt; + +/* ---------------------- + * Create/Alter/Drop Role Statements + * + * Note: these node types are also used for the backwards-compatible + * Create/Alter/Drop User/Group statements. In the ALTER and DROP cases + * there's really no need to distinguish what the original spelling was, + * but for CREATE we mark the type because the defaults vary. + * ---------------------- + */ +typedef enum RoleStmtType +{ + ROLESTMT_ROLE, + ROLESTMT_USER, + ROLESTMT_GROUP +} RoleStmtType; + +typedef struct CreateRoleStmt +{ + NodeTag type; + RoleStmtType stmt_type; /* ROLE/USER/GROUP */ + char *role; /* role name */ + List *options; /* List of DefElem nodes */ +} CreateRoleStmt; + +typedef struct AlterRoleStmt +{ + NodeTag type; + RoleSpec *role; /* role */ + List *options; /* List of DefElem nodes */ + int action; /* +1 = add members, -1 = drop members */ +} AlterRoleStmt; + +typedef struct AlterRoleSetStmt +{ + NodeTag type; + RoleSpec *role; /* role */ + char *database; /* database name, or NULL */ + VariableSetStmt *setstmt; /* SET or RESET subcommand */ +} AlterRoleSetStmt; + +typedef struct DropRoleStmt +{ + NodeTag type; + List *roles; /* List of roles to remove */ + bool missing_ok; /* skip error if a role is missing? */ +} DropRoleStmt; + +/* ---------------------- + * {Create|Alter} SEQUENCE Statement + * ---------------------- + */ + +typedef struct CreateSeqStmt +{ + NodeTag type; + RangeVar *sequence; /* the sequence to create */ + List *options; + Oid ownerId; /* ID of owner, or InvalidOid for default */ + bool for_identity; + bool if_not_exists; /* just do nothing if it already exists? */ +} CreateSeqStmt; + +typedef struct AlterSeqStmt +{ + NodeTag type; + RangeVar *sequence; /* the sequence to alter */ + List *options; + bool for_identity; + bool missing_ok; /* skip error if a role is missing? */ +} AlterSeqStmt; + +/* ---------------------- + * Create {Aggregate|Operator|Type} Statement + * ---------------------- + */ +typedef struct DefineStmt +{ + NodeTag type; + ObjectType kind; /* aggregate, operator, type */ + bool oldstyle; /* hack to signal old CREATE AGG syntax */ + List *defnames; /* qualified name (list of String) */ + List *args; /* a list of TypeName (if needed) */ + List *definition; /* a list of DefElem */ + bool if_not_exists; /* just do nothing if it already exists? */ + bool replace; /* replace if already exists? */ +} DefineStmt; + +/* ---------------------- + * Create Domain Statement + * ---------------------- + */ +typedef struct CreateDomainStmt +{ + NodeTag type; + List *domainname; /* qualified name (list of String) */ + TypeName *typeName; /* the base type */ + CollateClause *collClause; /* untransformed COLLATE spec, if any */ + List *constraints; /* constraints (list of Constraint nodes) */ +} CreateDomainStmt; + +/* ---------------------- + * Create Operator Class Statement + * ---------------------- + */ +typedef struct CreateOpClassStmt +{ + NodeTag type; + List *opclassname; /* qualified name (list of String) */ + List *opfamilyname; /* qualified name (ditto); NIL if omitted */ + char *amname; /* name of index AM opclass is for */ + TypeName *datatype; /* datatype of indexed column */ + List *items; /* List of CreateOpClassItem nodes */ + bool isDefault; /* Should be marked as default for type? */ +} CreateOpClassStmt; + +#define OPCLASS_ITEM_OPERATOR 1 +#define OPCLASS_ITEM_FUNCTION 2 +#define OPCLASS_ITEM_STORAGETYPE 3 + +typedef struct CreateOpClassItem +{ + NodeTag type; + int itemtype; /* see codes above */ + ObjectWithArgs *name; /* operator or function name and args */ + int number; /* strategy num or support proc num */ + List *order_family; /* only used for ordering operators */ + List *class_args; /* amproclefttype/amprocrighttype or + * amoplefttype/amoprighttype */ + /* fields used for a storagetype item: */ + TypeName *storedtype; /* datatype stored in index */ +} CreateOpClassItem; + +/* ---------------------- + * Create Operator Family Statement + * ---------------------- + */ +typedef struct CreateOpFamilyStmt +{ + NodeTag type; + List *opfamilyname; /* qualified name (list of String) */ + char *amname; /* name of index AM opfamily is for */ +} CreateOpFamilyStmt; + +/* ---------------------- + * Alter Operator Family Statement + * ---------------------- + */ +typedef struct AlterOpFamilyStmt +{ + NodeTag type; + List *opfamilyname; /* qualified name (list of String) */ + char *amname; /* name of index AM opfamily is for */ + bool isDrop; /* ADD or DROP the items? */ + List *items; /* List of CreateOpClassItem nodes */ +} AlterOpFamilyStmt; + +/* ---------------------- + * Drop Table|Sequence|View|Index|Type|Domain|Conversion|Schema Statement + * ---------------------- + */ + +typedef struct DropStmt +{ + NodeTag type; + List *objects; /* list of names */ + ObjectType removeType; /* object type */ + DropBehavior behavior; /* RESTRICT or CASCADE behavior */ + bool missing_ok; /* skip error if object is missing? */ + bool concurrent; /* drop index concurrently? */ +} DropStmt; + +/* ---------------------- + * Truncate Table Statement + * ---------------------- + */ +typedef struct TruncateStmt +{ + NodeTag type; + List *relations; /* relations (RangeVars) to be truncated */ + bool restart_seqs; /* restart owned sequences? */ + DropBehavior behavior; /* RESTRICT or CASCADE behavior */ +} TruncateStmt; + +/* ---------------------- + * Comment On Statement + * ---------------------- + */ +typedef struct CommentStmt +{ + NodeTag type; + ObjectType objtype; /* Object's type */ + Node *object; /* Qualified name of the object */ + char *comment; /* Comment to insert, or NULL to remove */ +} CommentStmt; + +/* ---------------------- + * SECURITY LABEL Statement + * ---------------------- + */ +typedef struct SecLabelStmt +{ + NodeTag type; + ObjectType objtype; /* Object's type */ + Node *object; /* Qualified name of the object */ + char *provider; /* Label provider (or NULL) */ + char *label; /* New security label to be assigned */ +} SecLabelStmt; + +/* ---------------------- + * Declare Cursor Statement + * + * The "query" field is initially a raw parse tree, and is converted to a + * Query node during parse analysis. Note that rewriting and planning + * of the query are always postponed until execution. + * ---------------------- + */ +#define CURSOR_OPT_BINARY 0x0001 /* BINARY */ +#define CURSOR_OPT_SCROLL 0x0002 /* SCROLL explicitly given */ +#define CURSOR_OPT_NO_SCROLL 0x0004 /* NO SCROLL explicitly given */ +#define CURSOR_OPT_INSENSITIVE 0x0008 /* INSENSITIVE */ +#define CURSOR_OPT_ASENSITIVE 0x0010 /* ASENSITIVE */ +#define CURSOR_OPT_HOLD 0x0020 /* WITH HOLD */ +/* these planner-control flags do not correspond to any SQL grammar: */ +#define CURSOR_OPT_FAST_PLAN 0x0100 /* prefer fast-start plan */ +#define CURSOR_OPT_GENERIC_PLAN 0x0200 /* force use of generic plan */ +#define CURSOR_OPT_CUSTOM_PLAN 0x0400 /* force use of custom plan */ +#define CURSOR_OPT_PARALLEL_OK 0x0800 /* parallel mode OK */ + +typedef struct DeclareCursorStmt +{ + NodeTag type; + char *portalname; /* name of the portal (cursor) */ + int options; /* bitmask of options (see above) */ + Node *query; /* the query (see comments above) */ +} DeclareCursorStmt; + +/* ---------------------- + * Close Portal Statement + * ---------------------- + */ +typedef struct ClosePortalStmt +{ + NodeTag type; + char *portalname; /* name of the portal (cursor) */ + /* NULL means CLOSE ALL */ +} ClosePortalStmt; + +/* ---------------------- + * Fetch Statement (also Move) + * ---------------------- + */ +typedef enum FetchDirection +{ + /* for these, howMany is how many rows to fetch; FETCH_ALL means ALL */ + FETCH_FORWARD, + FETCH_BACKWARD, + /* for these, howMany indicates a position; only one row is fetched */ + FETCH_ABSOLUTE, + FETCH_RELATIVE +} FetchDirection; + +#define FETCH_ALL LONG_MAX + +typedef struct FetchStmt +{ + NodeTag type; + FetchDirection direction; /* see above */ + long howMany; /* number of rows, or position argument */ + char *portalname; /* name of portal (cursor) */ + bool ismove; /* true if MOVE */ +} FetchStmt; + +/* ---------------------- + * Create Index Statement + * + * This represents creation of an index and/or an associated constraint. + * If isconstraint is true, we should create a pg_constraint entry along + * with the index. But if indexOid isn't InvalidOid, we are not creating an + * index, just a UNIQUE/PKEY constraint using an existing index. isconstraint + * must always be true in this case, and the fields describing the index + * properties are empty. + * ---------------------- + */ +typedef struct IndexStmt +{ + NodeTag type; + char *idxname; /* name of new index, or NULL for default */ + RangeVar *relation; /* relation to build index on */ + char *accessMethod; /* name of access method (eg. btree) */ + char *tableSpace; /* tablespace, or NULL for default */ + List *indexParams; /* columns to index: a list of IndexElem */ + List *indexIncludingParams; /* additional columns to index: a list + * of IndexElem */ + List *options; /* WITH clause options: a list of DefElem */ + Node *whereClause; /* qualification (partial-index predicate) */ + List *excludeOpNames; /* exclusion operator names, or NIL if none */ + char *idxcomment; /* comment to apply to index, or NULL */ + Oid indexOid; /* OID of an existing index, if any */ + RelFileNumber oldNumber; /* relfilenumber of existing storage, if any */ + SubTransactionId oldCreateSubid; /* rd_createSubid of oldNumber */ + SubTransactionId oldFirstRelfilelocatorSubid; /* rd_firstRelfilelocatorSubid + * of oldNumber */ + bool unique; /* is index unique? */ + bool nulls_not_distinct; /* null treatment for UNIQUE constraints */ + bool primary; /* is index a primary key? */ + bool isconstraint; /* is it for a pkey/unique constraint? */ + bool deferrable; /* is the constraint DEFERRABLE? */ + bool initdeferred; /* is the constraint INITIALLY DEFERRED? */ + bool transformed; /* true when transformIndexStmt is finished */ + bool concurrent; /* should this be a concurrent index build? */ + bool if_not_exists; /* just do nothing if index already exists? */ + bool reset_default_tblspc; /* reset default_tablespace prior to + * executing */ +} IndexStmt; + +/* ---------------------- + * Create Statistics Statement + * ---------------------- + */ +typedef struct CreateStatsStmt +{ + NodeTag type; + List *defnames; /* qualified name (list of String) */ + List *stat_types; /* stat types (list of String) */ + List *exprs; /* expressions to build statistics on */ + List *relations; /* rels to build stats on (list of RangeVar) */ + char *stxcomment; /* comment to apply to stats, or NULL */ + bool transformed; /* true when transformStatsStmt is finished */ + bool if_not_exists; /* do nothing if stats name already exists */ +} CreateStatsStmt; + +/* + * StatsElem - statistics parameters (used in CREATE STATISTICS) + * + * For a plain attribute, 'name' is the name of the referenced table column + * and 'expr' is NULL. For an expression, 'name' is NULL and 'expr' is the + * expression tree. + */ +typedef struct StatsElem +{ + NodeTag type; + char *name; /* name of attribute to index, or NULL */ + Node *expr; /* expression to index, or NULL */ +} StatsElem; + + +/* ---------------------- + * Alter Statistics Statement + * ---------------------- + */ +typedef struct AlterStatsStmt +{ + NodeTag type; + List *defnames; /* qualified name (list of String) */ + int stxstattarget; /* statistics target */ + bool missing_ok; /* skip error if statistics object is missing */ +} AlterStatsStmt; + +/* ---------------------- + * Create Function Statement + * ---------------------- + */ +typedef struct CreateFunctionStmt +{ + NodeTag type; + bool is_procedure; /* it's really CREATE PROCEDURE */ + bool replace; /* T => replace if already exists */ + List *funcname; /* qualified name of function to create */ + List *parameters; /* a list of FunctionParameter */ + TypeName *returnType; /* the return type */ + List *options; /* a list of DefElem */ + Node *sql_body; +} CreateFunctionStmt; + +typedef enum FunctionParameterMode +{ + /* the assigned enum values appear in pg_proc, don't change 'em! */ + FUNC_PARAM_IN = 'i', /* input only */ + FUNC_PARAM_OUT = 'o', /* output only */ + FUNC_PARAM_INOUT = 'b', /* both */ + FUNC_PARAM_VARIADIC = 'v', /* variadic (always input) */ + FUNC_PARAM_TABLE = 't', /* table function output column */ + /* this is not used in pg_proc: */ + FUNC_PARAM_DEFAULT = 'd' /* default; effectively same as IN */ +} FunctionParameterMode; + +typedef struct FunctionParameter +{ + NodeTag type; + char *name; /* parameter name, or NULL if not given */ + TypeName *argType; /* TypeName for parameter type */ + FunctionParameterMode mode; /* IN/OUT/etc */ + Node *defexpr; /* raw default expr, or NULL if not given */ +} FunctionParameter; + +typedef struct AlterFunctionStmt +{ + NodeTag type; + ObjectType objtype; + ObjectWithArgs *func; /* name and args of function */ + List *actions; /* list of DefElem */ +} AlterFunctionStmt; + +/* ---------------------- + * DO Statement + * + * DoStmt is the raw parser output, InlineCodeBlock is the execution-time API + * ---------------------- + */ +typedef struct DoStmt +{ + NodeTag type; + List *args; /* List of DefElem nodes */ +} DoStmt; + +typedef struct InlineCodeBlock +{ + pg_node_attr(nodetag_only) /* this is not a member of parse trees */ + + NodeTag type; + char *source_text; /* source text of anonymous code block */ + Oid langOid; /* OID of selected language */ + bool langIsTrusted; /* trusted property of the language */ + bool atomic; /* atomic execution context */ +} InlineCodeBlock; + +/* ---------------------- + * CALL statement + * + * OUT-mode arguments are removed from the transformed funcexpr. The outargs + * list contains copies of the expressions for all output arguments, in the + * order of the procedure's declared arguments. (outargs is never evaluated, + * but is useful to the caller as a reference for what to assign to.) + * The transformed call state is not relevant in the query jumbling, only the + * function call is. + * ---------------------- + */ +typedef struct CallStmt +{ + NodeTag type; + FuncCall *funccall; /* from the parser */ + /* transformed call, with only input args */ + FuncExpr *funcexpr pg_node_attr(query_jumble_ignore); + /* transformed output-argument expressions */ + List *outargs pg_node_attr(query_jumble_ignore); +} CallStmt; + +typedef struct CallContext +{ + pg_node_attr(nodetag_only) /* this is not a member of parse trees */ + + NodeTag type; + bool atomic; +} CallContext; + +/* ---------------------- + * Alter Object Rename Statement + * ---------------------- + */ +typedef struct RenameStmt +{ + NodeTag type; + ObjectType renameType; /* OBJECT_TABLE, OBJECT_COLUMN, etc */ + ObjectType relationType; /* if column name, associated relation type */ + RangeVar *relation; /* in case it's a table */ + Node *object; /* in case it's some other object */ + char *subname; /* name of contained object (column, rule, + * trigger, etc) */ + char *newname; /* the new name */ + DropBehavior behavior; /* RESTRICT or CASCADE behavior */ + bool missing_ok; /* skip error if missing? */ +} RenameStmt; + +/* ---------------------- + * ALTER object DEPENDS ON EXTENSION extname + * ---------------------- + */ +typedef struct AlterObjectDependsStmt +{ + NodeTag type; + ObjectType objectType; /* OBJECT_FUNCTION, OBJECT_TRIGGER, etc */ + RangeVar *relation; /* in case a table is involved */ + Node *object; /* name of the object */ + String *extname; /* extension name */ + bool remove; /* set true to remove dep rather than add */ +} AlterObjectDependsStmt; + +/* ---------------------- + * ALTER object SET SCHEMA Statement + * ---------------------- + */ +typedef struct AlterObjectSchemaStmt +{ + NodeTag type; + ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */ + RangeVar *relation; /* in case it's a table */ + Node *object; /* in case it's some other object */ + char *newschema; /* the new schema */ + bool missing_ok; /* skip error if missing? */ +} AlterObjectSchemaStmt; + +/* ---------------------- + * Alter Object Owner Statement + * ---------------------- + */ +typedef struct AlterOwnerStmt +{ + NodeTag type; + ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */ + RangeVar *relation; /* in case it's a table */ + Node *object; /* in case it's some other object */ + RoleSpec *newowner; /* the new owner */ +} AlterOwnerStmt; + +/* ---------------------- + * Alter Operator Set ( this-n-that ) + * ---------------------- + */ +typedef struct AlterOperatorStmt +{ + NodeTag type; + ObjectWithArgs *opername; /* operator name and argument types */ + List *options; /* List of DefElem nodes */ +} AlterOperatorStmt; + +/* ------------------------ + * Alter Type Set ( this-n-that ) + * ------------------------ + */ +typedef struct AlterTypeStmt +{ + NodeTag type; + List *typeName; /* type name (possibly qualified) */ + List *options; /* List of DefElem nodes */ +} AlterTypeStmt; + +/* ---------------------- + * Create Rule Statement + * ---------------------- + */ +typedef struct RuleStmt +{ + NodeTag type; + RangeVar *relation; /* relation the rule is for */ + char *rulename; /* name of the rule */ + Node *whereClause; /* qualifications */ + CmdType event; /* SELECT, INSERT, etc */ + bool instead; /* is a 'do instead'? */ + List *actions; /* the action statements */ + bool replace; /* OR REPLACE */ +} RuleStmt; + +/* ---------------------- + * Notify Statement + * ---------------------- + */ +typedef struct NotifyStmt +{ + NodeTag type; + char *conditionname; /* condition name to notify */ + char *payload; /* the payload string, or NULL if none */ +} NotifyStmt; + +/* ---------------------- + * Listen Statement + * ---------------------- + */ +typedef struct ListenStmt +{ + NodeTag type; + char *conditionname; /* condition name to listen on */ +} ListenStmt; + +/* ---------------------- + * Unlisten Statement + * ---------------------- + */ +typedef struct UnlistenStmt +{ + NodeTag type; + char *conditionname; /* name to unlisten on, or NULL for all */ +} UnlistenStmt; + +/* ---------------------- + * {Begin|Commit|Rollback} Transaction Statement + * ---------------------- + */ +typedef enum TransactionStmtKind +{ + TRANS_STMT_BEGIN, + TRANS_STMT_START, /* semantically identical to BEGIN */ + TRANS_STMT_COMMIT, + TRANS_STMT_ROLLBACK, + TRANS_STMT_SAVEPOINT, + TRANS_STMT_RELEASE, + TRANS_STMT_ROLLBACK_TO, + TRANS_STMT_PREPARE, + TRANS_STMT_COMMIT_PREPARED, + TRANS_STMT_ROLLBACK_PREPARED +} TransactionStmtKind; + +typedef struct TransactionStmt +{ + NodeTag type; + TransactionStmtKind kind; /* see above */ + List *options; /* for BEGIN/START commands */ + char *savepoint_name; /* for savepoint commands */ + char *gid; /* for two-phase-commit related commands */ + bool chain; /* AND CHAIN option */ +} TransactionStmt; + +/* ---------------------- + * Create Type Statement, composite types + * ---------------------- + */ +typedef struct CompositeTypeStmt +{ + NodeTag type; + RangeVar *typevar; /* the composite type to be created */ + List *coldeflist; /* list of ColumnDef nodes */ +} CompositeTypeStmt; + +/* ---------------------- + * Create Type Statement, enum types + * ---------------------- + */ +typedef struct CreateEnumStmt +{ + NodeTag type; + List *typeName; /* qualified name (list of String) */ + List *vals; /* enum values (list of String) */ +} CreateEnumStmt; + +/* ---------------------- + * Create Type Statement, range types + * ---------------------- + */ +typedef struct CreateRangeStmt +{ + NodeTag type; + List *typeName; /* qualified name (list of String) */ + List *params; /* range parameters (list of DefElem) */ +} CreateRangeStmt; + +/* ---------------------- + * Alter Type Statement, enum types + * ---------------------- + */ +typedef struct AlterEnumStmt +{ + NodeTag type; + List *typeName; /* qualified name (list of String) */ + char *oldVal; /* old enum value's name, if renaming */ + char *newVal; /* new enum value's name */ + char *newValNeighbor; /* neighboring enum value, if specified */ + bool newValIsAfter; /* place new enum value after neighbor? */ + bool skipIfNewValExists; /* no error if new already exists? */ +} AlterEnumStmt; + +/* ---------------------- + * Create View Statement + * ---------------------- + */ +typedef enum ViewCheckOption +{ + NO_CHECK_OPTION, + LOCAL_CHECK_OPTION, + CASCADED_CHECK_OPTION +} ViewCheckOption; + +typedef struct ViewStmt +{ + NodeTag type; + RangeVar *view; /* the view to be created */ + List *aliases; /* target column names */ + Node *query; /* the SELECT query (as a raw parse tree) */ + bool replace; /* replace an existing view? */ + List *options; /* options from WITH clause */ + ViewCheckOption withCheckOption; /* WITH CHECK OPTION */ +} ViewStmt; + +/* ---------------------- + * Load Statement + * ---------------------- + */ +typedef struct LoadStmt +{ + NodeTag type; + char *filename; /* file to load */ +} LoadStmt; + +/* ---------------------- + * Createdb Statement + * ---------------------- + */ +typedef struct CreatedbStmt +{ + NodeTag type; + char *dbname; /* name of database to create */ + List *options; /* List of DefElem nodes */ +} CreatedbStmt; + +/* ---------------------- + * Alter Database + * ---------------------- + */ +typedef struct AlterDatabaseStmt +{ + NodeTag type; + char *dbname; /* name of database to alter */ + List *options; /* List of DefElem nodes */ +} AlterDatabaseStmt; + +typedef struct AlterDatabaseRefreshCollStmt +{ + NodeTag type; + char *dbname; +} AlterDatabaseRefreshCollStmt; + +typedef struct AlterDatabaseSetStmt +{ + NodeTag type; + char *dbname; /* database name */ + VariableSetStmt *setstmt; /* SET or RESET subcommand */ +} AlterDatabaseSetStmt; + +/* ---------------------- + * Dropdb Statement + * ---------------------- + */ +typedef struct DropdbStmt +{ + NodeTag type; + char *dbname; /* database to drop */ + bool missing_ok; /* skip error if db is missing? */ + List *options; /* currently only FORCE is supported */ +} DropdbStmt; + +/* ---------------------- + * Alter System Statement + * ---------------------- + */ +typedef struct AlterSystemStmt +{ + NodeTag type; + VariableSetStmt *setstmt; /* SET subcommand */ +} AlterSystemStmt; + +/* ---------------------- + * Cluster Statement (support pbrown's cluster index implementation) + * ---------------------- + */ +typedef struct ClusterStmt +{ + NodeTag type; + RangeVar *relation; /* relation being indexed, or NULL if all */ + char *indexname; /* original index defined */ + List *params; /* list of DefElem nodes */ +} ClusterStmt; + +/* ---------------------- + * Vacuum and Analyze Statements + * + * Even though these are nominally two statements, it's convenient to use + * just one node type for both. + * ---------------------- + */ +typedef struct VacuumStmt +{ + NodeTag type; + List *options; /* list of DefElem nodes */ + List *rels; /* list of VacuumRelation, or NIL for all */ + bool is_vacuumcmd; /* true for VACUUM, false for ANALYZE */ +} VacuumStmt; + +/* + * Info about a single target table of VACUUM/ANALYZE. + * + * If the OID field is set, it always identifies the table to process. + * Then the relation field can be NULL; if it isn't, it's used only to report + * failure to open/lock the relation. + */ +typedef struct VacuumRelation +{ + NodeTag type; + RangeVar *relation; /* table name to process, or NULL */ + Oid oid; /* table's OID; InvalidOid if not looked up */ + List *va_cols; /* list of column names, or NIL for all */ +} VacuumRelation; + +/* ---------------------- + * Explain Statement + * + * The "query" field is initially a raw parse tree, and is converted to a + * Query node during parse analysis. Note that rewriting and planning + * of the query are always postponed until execution. + * ---------------------- + */ +typedef struct ExplainStmt +{ + NodeTag type; + Node *query; /* the query (see comments above) */ + List *options; /* list of DefElem nodes */ +} ExplainStmt; + +/* ---------------------- + * CREATE TABLE AS Statement (a/k/a SELECT INTO) + * + * A query written as CREATE TABLE AS will produce this node type natively. + * A query written as SELECT ... INTO will be transformed to this form during + * parse analysis. + * A query written as CREATE MATERIALIZED view will produce this node type, + * during parse analysis, since it needs all the same data. + * + * The "query" field is handled similarly to EXPLAIN, though note that it + * can be a SELECT or an EXECUTE, but not other DML statements. + * ---------------------- + */ +typedef struct CreateTableAsStmt +{ + NodeTag type; + Node *query; /* the query (see comments above) */ + IntoClause *into; /* destination table */ + ObjectType objtype; /* OBJECT_TABLE or OBJECT_MATVIEW */ + bool is_select_into; /* it was written as SELECT INTO */ + bool if_not_exists; /* just do nothing if it already exists? */ +} CreateTableAsStmt; + +/* ---------------------- + * REFRESH MATERIALIZED VIEW Statement + * ---------------------- + */ +typedef struct RefreshMatViewStmt +{ + NodeTag type; + bool concurrent; /* allow concurrent access? */ + bool skipData; /* true for WITH NO DATA */ + RangeVar *relation; /* relation to insert into */ +} RefreshMatViewStmt; + +/* ---------------------- + * Checkpoint Statement + * ---------------------- + */ +typedef struct CheckPointStmt +{ + NodeTag type; +} CheckPointStmt; + +/* ---------------------- + * Discard Statement + * ---------------------- + */ + +typedef enum DiscardMode +{ + DISCARD_ALL, + DISCARD_PLANS, + DISCARD_SEQUENCES, + DISCARD_TEMP +} DiscardMode; + +typedef struct DiscardStmt +{ + NodeTag type; + DiscardMode target; +} DiscardStmt; + +/* ---------------------- + * LOCK Statement + * ---------------------- + */ +typedef struct LockStmt +{ + NodeTag type; + List *relations; /* relations to lock */ + int mode; /* lock mode */ + bool nowait; /* no wait mode */ +} LockStmt; + +/* ---------------------- + * SET CONSTRAINTS Statement + * ---------------------- + */ +typedef struct ConstraintsSetStmt +{ + NodeTag type; + List *constraints; /* List of names as RangeVars */ + bool deferred; +} ConstraintsSetStmt; + +/* ---------------------- + * REINDEX Statement + * ---------------------- + */ +typedef enum ReindexObjectType +{ + REINDEX_OBJECT_INDEX, /* index */ + REINDEX_OBJECT_TABLE, /* table or materialized view */ + REINDEX_OBJECT_SCHEMA, /* schema */ + REINDEX_OBJECT_SYSTEM, /* system catalogs */ + REINDEX_OBJECT_DATABASE /* database */ +} ReindexObjectType; + +typedef struct ReindexStmt +{ + NodeTag type; + ReindexObjectType kind; /* REINDEX_OBJECT_INDEX, REINDEX_OBJECT_TABLE, + * etc. */ + RangeVar *relation; /* Table or index to reindex */ + const char *name; /* name of database to reindex */ + List *params; /* list of DefElem nodes */ +} ReindexStmt; + +/* ---------------------- + * CREATE CONVERSION Statement + * ---------------------- + */ +typedef struct CreateConversionStmt +{ + NodeTag type; + List *conversion_name; /* Name of the conversion */ + char *for_encoding_name; /* source encoding name */ + char *to_encoding_name; /* destination encoding name */ + List *func_name; /* qualified conversion function name */ + bool def; /* is this a default conversion? */ +} CreateConversionStmt; + +/* ---------------------- + * CREATE CAST Statement + * ---------------------- + */ +typedef struct CreateCastStmt +{ + NodeTag type; + TypeName *sourcetype; + TypeName *targettype; + ObjectWithArgs *func; + CoercionContext context; + bool inout; +} CreateCastStmt; + +/* ---------------------- + * CREATE TRANSFORM Statement + * ---------------------- + */ +typedef struct CreateTransformStmt +{ + NodeTag type; + bool replace; + TypeName *type_name; + char *lang; + ObjectWithArgs *fromsql; + ObjectWithArgs *tosql; +} CreateTransformStmt; + +/* ---------------------- + * PREPARE Statement + * ---------------------- + */ +typedef struct PrepareStmt +{ + NodeTag type; + char *name; /* Name of plan, arbitrary */ + List *argtypes; /* Types of parameters (List of TypeName) */ + Node *query; /* The query itself (as a raw parsetree) */ +} PrepareStmt; + + +/* ---------------------- + * EXECUTE Statement + * ---------------------- + */ + +typedef struct ExecuteStmt +{ + NodeTag type; + char *name; /* The name of the plan to execute */ + List *params; /* Values to assign to parameters */ +} ExecuteStmt; + + +/* ---------------------- + * DEALLOCATE Statement + * ---------------------- + */ +typedef struct DeallocateStmt +{ + NodeTag type; + char *name; /* The name of the plan to remove */ + /* NULL means DEALLOCATE ALL */ +} DeallocateStmt; + +/* + * DROP OWNED statement + */ +typedef struct DropOwnedStmt +{ + NodeTag type; + List *roles; + DropBehavior behavior; +} DropOwnedStmt; + +/* + * REASSIGN OWNED statement + */ +typedef struct ReassignOwnedStmt +{ + NodeTag type; + List *roles; + RoleSpec *newrole; +} ReassignOwnedStmt; + +/* + * TS Dictionary stmts: DefineStmt, RenameStmt and DropStmt are default + */ +typedef struct AlterTSDictionaryStmt +{ + NodeTag type; + List *dictname; /* qualified name (list of String) */ + List *options; /* List of DefElem nodes */ +} AlterTSDictionaryStmt; + +/* + * TS Configuration stmts: DefineStmt, RenameStmt and DropStmt are default + */ +typedef enum AlterTSConfigType +{ + ALTER_TSCONFIG_ADD_MAPPING, + ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN, + ALTER_TSCONFIG_REPLACE_DICT, + ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN, + ALTER_TSCONFIG_DROP_MAPPING +} AlterTSConfigType; + +typedef struct AlterTSConfigurationStmt +{ + NodeTag type; + AlterTSConfigType kind; /* ALTER_TSCONFIG_ADD_MAPPING, etc */ + List *cfgname; /* qualified name (list of String) */ + + /* + * dicts will be non-NIL if ADD/ALTER MAPPING was specified. If dicts is + * NIL, but tokentype isn't, DROP MAPPING was specified. + */ + List *tokentype; /* list of String */ + List *dicts; /* list of list of String */ + bool override; /* if true - remove old variant */ + bool replace; /* if true - replace dictionary by another */ + bool missing_ok; /* for DROP - skip error if missing? */ +} AlterTSConfigurationStmt; + +typedef struct PublicationTable +{ + NodeTag type; + RangeVar *relation; /* relation to be published */ + Node *whereClause; /* qualifications */ + List *columns; /* List of columns in a publication table */ +} PublicationTable; + +/* + * Publication object type + */ +typedef enum PublicationObjSpecType +{ + PUBLICATIONOBJ_TABLE, /* A table */ + PUBLICATIONOBJ_TABLES_IN_SCHEMA, /* All tables in schema */ + PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA, /* All tables in first element of + * search_path */ + PUBLICATIONOBJ_CONTINUATION /* Continuation of previous type */ +} PublicationObjSpecType; + +typedef struct PublicationObjSpec +{ + NodeTag type; + PublicationObjSpecType pubobjtype; /* type of this publication object */ + char *name; + PublicationTable *pubtable; + int location; /* token location, or -1 if unknown */ +} PublicationObjSpec; + +typedef struct CreatePublicationStmt +{ + NodeTag type; + char *pubname; /* Name of the publication */ + List *options; /* List of DefElem nodes */ + List *pubobjects; /* Optional list of publication objects */ + bool for_all_tables; /* Special publication for all tables in db */ +} CreatePublicationStmt; + +typedef enum AlterPublicationAction +{ + AP_AddObjects, /* add objects to publication */ + AP_DropObjects, /* remove objects from publication */ + AP_SetObjects /* set list of objects */ +} AlterPublicationAction; + +typedef struct AlterPublicationStmt +{ + NodeTag type; + char *pubname; /* Name of the publication */ + + /* parameters used for ALTER PUBLICATION ... WITH */ + List *options; /* List of DefElem nodes */ + + /* + * Parameters used for ALTER PUBLICATION ... ADD/DROP/SET publication + * objects. + */ + List *pubobjects; /* Optional list of publication objects */ + bool for_all_tables; /* Special publication for all tables in db */ + AlterPublicationAction action; /* What action to perform with the given + * objects */ +} AlterPublicationStmt; + +typedef struct CreateSubscriptionStmt +{ + NodeTag type; + char *subname; /* Name of the subscription */ + char *conninfo; /* Connection string to publisher */ + List *publication; /* One or more publication to subscribe to */ + List *options; /* List of DefElem nodes */ +} CreateSubscriptionStmt; + +typedef enum AlterSubscriptionType +{ + ALTER_SUBSCRIPTION_OPTIONS, + ALTER_SUBSCRIPTION_CONNECTION, + ALTER_SUBSCRIPTION_SET_PUBLICATION, + ALTER_SUBSCRIPTION_ADD_PUBLICATION, + ALTER_SUBSCRIPTION_DROP_PUBLICATION, + ALTER_SUBSCRIPTION_REFRESH, + ALTER_SUBSCRIPTION_ENABLED, + ALTER_SUBSCRIPTION_SKIP +} AlterSubscriptionType; + +typedef struct AlterSubscriptionStmt +{ + NodeTag type; + AlterSubscriptionType kind; /* ALTER_SUBSCRIPTION_OPTIONS, etc */ + char *subname; /* Name of the subscription */ + char *conninfo; /* Connection string to publisher */ + List *publication; /* One or more publication to subscribe to */ + List *options; /* List of DefElem nodes */ +} AlterSubscriptionStmt; + +typedef struct DropSubscriptionStmt +{ + NodeTag type; + char *subname; /* Name of the subscription */ + bool missing_ok; /* Skip error if missing? */ + DropBehavior behavior; /* RESTRICT or CASCADE behavior */ +} DropSubscriptionStmt; + +#endif /* PARSENODES_H */ diff --git a/install/include/postgresql/server/nodes/pathnodes.h b/install/include/postgresql/server/nodes/pathnodes.h new file mode 100644 index 00000000000..0162d59e079 --- /dev/null +++ b/install/include/postgresql/server/nodes/pathnodes.h @@ -0,0 +1,3387 @@ +/*------------------------------------------------------------------------- + * + * pathnodes.h + * Definitions for planner's internal data structures, especially Paths. + * + * We don't support copying RelOptInfo, IndexOptInfo, or Path nodes. + * There are some subsidiary structs that are useful to copy, though. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/pathnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef PATHNODES_H +#define PATHNODES_H + +#include "access/sdir.h" +#include "lib/stringinfo.h" +#include "nodes/params.h" +#include "nodes/parsenodes.h" +#include "storage/block.h" + + +/* + * Relids + * Set of relation identifiers (indexes into the rangetable). + */ +typedef Bitmapset *Relids; + +/* + * When looking for a "cheapest path", this enum specifies whether we want + * cheapest startup cost or cheapest total cost. + */ +typedef enum CostSelector +{ + STARTUP_COST, TOTAL_COST +} CostSelector; + +/* + * The cost estimate produced by cost_qual_eval() includes both a one-time + * (startup) cost, and a per-tuple cost. + */ +typedef struct QualCost +{ + Cost startup; /* one-time cost */ + Cost per_tuple; /* per-evaluation cost */ +} QualCost; + +/* + * Costing aggregate function execution requires these statistics about + * the aggregates to be executed by a given Agg node. Note that the costs + * include the execution costs of the aggregates' argument expressions as + * well as the aggregate functions themselves. Also, the fields must be + * defined so that initializing the struct to zeroes with memset is correct. + */ +typedef struct AggClauseCosts +{ + QualCost transCost; /* total per-input-row execution costs */ + QualCost finalCost; /* total per-aggregated-row costs */ + Size transitionSpace; /* space for pass-by-ref transition data */ +} AggClauseCosts; + +/* + * This enum identifies the different types of "upper" (post-scan/join) + * relations that we might deal with during planning. + */ +typedef enum UpperRelationKind +{ + UPPERREL_SETOP, /* result of UNION/INTERSECT/EXCEPT, if any */ + UPPERREL_PARTIAL_GROUP_AGG, /* result of partial grouping/aggregation, if + * any */ + UPPERREL_GROUP_AGG, /* result of grouping/aggregation, if any */ + UPPERREL_WINDOW, /* result of window functions, if any */ + UPPERREL_PARTIAL_DISTINCT, /* result of partial "SELECT DISTINCT", if any */ + UPPERREL_DISTINCT, /* result of "SELECT DISTINCT", if any */ + UPPERREL_ORDERED, /* result of ORDER BY, if any */ + UPPERREL_FINAL /* result of any remaining top-level actions */ + /* NB: UPPERREL_FINAL must be last enum entry; it's used to size arrays */ +} UpperRelationKind; + +/*---------- + * PlannerGlobal + * Global information for planning/optimization + * + * PlannerGlobal holds state for an entire planner invocation; this state + * is shared across all levels of sub-Queries that exist in the command being + * planned. + * + * Not all fields are printed. (In some cases, there is no print support for + * the field type; in others, doing so would lead to infinite recursion.) + *---------- + */ +typedef struct PlannerGlobal +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* Param values provided to planner() */ + ParamListInfo boundParams pg_node_attr(read_write_ignore); + + /* Plans for SubPlan nodes */ + List *subplans; + + /* PlannerInfos for SubPlan nodes */ + List *subroots pg_node_attr(read_write_ignore); + + /* indices of subplans that require REWIND */ + Bitmapset *rewindPlanIDs; + + /* "flat" rangetable for executor */ + List *finalrtable; + + /* "flat" list of RTEPermissionInfos */ + List *finalrteperminfos; + + /* "flat" list of PlanRowMarks */ + List *finalrowmarks; + + /* "flat" list of integer RT indexes */ + List *resultRelations; + + /* "flat" list of AppendRelInfos */ + List *appendRelations; + + /* OIDs of relations the plan depends on */ + List *relationOids; + + /* other dependencies, as PlanInvalItems */ + List *invalItems; + + /* type OIDs for PARAM_EXEC Params */ + List *paramExecTypes; + + /* highest PlaceHolderVar ID assigned */ + Index lastPHId; + + /* highest PlanRowMark ID assigned */ + Index lastRowMarkId; + + /* highest plan node ID assigned */ + int lastPlanNodeId; + + /* redo plan when TransactionXmin changes? */ + bool transientPlan; + + /* is plan specific to current role? */ + bool dependsOnRole; + + /* parallel mode potentially OK? */ + bool parallelModeOK; + + /* parallel mode actually required? */ + bool parallelModeNeeded; + + /* worst PROPARALLEL hazard level */ + char maxParallelHazard; + + /* partition descriptors */ + PartitionDirectory partition_directory pg_node_attr(read_write_ignore); +} PlannerGlobal; + +/* macro for fetching the Plan associated with a SubPlan node */ +#define planner_subplan_get_plan(root, subplan) \ + ((Plan *) list_nth((root)->glob->subplans, (subplan)->plan_id - 1)) + + +/*---------- + * PlannerInfo + * Per-query information for planning/optimization + * + * This struct is conventionally called "root" in all the planner routines. + * It holds links to all of the planner's working state, in addition to the + * original Query. Note that at present the planner extensively modifies + * the passed-in Query data structure; someday that should stop. + * + * For reasons explained in optimizer/optimizer.h, we define the typedef + * either here or in that header, whichever is read first. + * + * Not all fields are printed. (In some cases, there is no print support for + * the field type; in others, doing so would lead to infinite recursion or + * bloat dump output more than seems useful.) + *---------- + */ +#ifndef HAVE_PLANNERINFO_TYPEDEF +typedef struct PlannerInfo PlannerInfo; +#define HAVE_PLANNERINFO_TYPEDEF 1 +#endif + +struct PlannerInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* the Query being planned */ + Query *parse; + + /* global info for current planner run */ + PlannerGlobal *glob; + + /* 1 at the outermost Query */ + Index query_level; + + /* NULL at outermost Query */ + PlannerInfo *parent_root pg_node_attr(read_write_ignore); + + /* + * plan_params contains the expressions that this query level needs to + * make available to a lower query level that is currently being planned. + * outer_params contains the paramIds of PARAM_EXEC Params that outer + * query levels will make available to this query level. + */ + /* list of PlannerParamItems, see below */ + List *plan_params; + Bitmapset *outer_params; + + /* + * simple_rel_array holds pointers to "base rels" and "other rels" (see + * comments for RelOptInfo for more info). It is indexed by rangetable + * index (so entry 0 is always wasted). Entries can be NULL when an RTE + * does not correspond to a base relation, such as a join RTE or an + * unreferenced view RTE; or if the RelOptInfo hasn't been made yet. + */ + struct RelOptInfo **simple_rel_array pg_node_attr(array_size(simple_rel_array_size)); + /* allocated size of array */ + int simple_rel_array_size; + + /* + * simple_rte_array is the same length as simple_rel_array and holds + * pointers to the associated rangetable entries. Using this is a shade + * faster than using rt_fetch(), mostly due to fewer indirections. (Not + * printed because it'd be redundant with parse->rtable.) + */ + RangeTblEntry **simple_rte_array pg_node_attr(read_write_ignore); + + /* + * append_rel_array is the same length as the above arrays, and holds + * pointers to the corresponding AppendRelInfo entry indexed by + * child_relid, or NULL if the rel is not an appendrel child. The array + * itself is not allocated if append_rel_list is empty. (Not printed + * because it'd be redundant with append_rel_list.) + */ + struct AppendRelInfo **append_rel_array pg_node_attr(read_write_ignore); + + /* + * all_baserels is a Relids set of all base relids (but not joins or + * "other" rels) in the query. This is computed in deconstruct_jointree. + */ + Relids all_baserels; + + /* + * outer_join_rels is a Relids set of all outer-join relids in the query. + * This is computed in deconstruct_jointree. + */ + Relids outer_join_rels; + + /* + * all_query_rels is a Relids set of all base relids and outer join relids + * (but not "other" relids) in the query. This is the Relids identifier + * of the final join we need to form. This is computed in + * deconstruct_jointree. + */ + Relids all_query_rels; + + /* + * join_rel_list is a list of all join-relation RelOptInfos we have + * considered in this planning run. For small problems we just scan the + * list to do lookups, but when there are many join relations we build a + * hash table for faster lookups. The hash table is present and valid + * when join_rel_hash is not NULL. Note that we still maintain the list + * even when using the hash table for lookups; this simplifies life for + * GEQO. + */ + List *join_rel_list; + struct HTAB *join_rel_hash pg_node_attr(read_write_ignore); + + /* + * When doing a dynamic-programming-style join search, join_rel_level[k] + * is a list of all join-relation RelOptInfos of level k, and + * join_cur_level is the current level. New join-relation RelOptInfos are + * automatically added to the join_rel_level[join_cur_level] list. + * join_rel_level is NULL if not in use. + * + * Note: we've already printed all baserel and joinrel RelOptInfos above, + * so we don't dump join_rel_level or other lists of RelOptInfos. + */ + /* lists of join-relation RelOptInfos */ + List **join_rel_level pg_node_attr(read_write_ignore); + /* index of list being extended */ + int join_cur_level; + + /* init SubPlans for query */ + List *init_plans; + + /* + * per-CTE-item list of subplan IDs (or -1 if no subplan was made for that + * CTE) + */ + List *cte_plan_ids; + + /* List of Lists of Params for MULTIEXPR subquery outputs */ + List *multiexpr_params; + + /* list of JoinDomains used in the query (higher ones first) */ + List *join_domains; + + /* list of active EquivalenceClasses */ + List *eq_classes; + + /* set true once ECs are canonical */ + bool ec_merging_done; + + /* list of "canonical" PathKeys */ + List *canon_pathkeys; + + /* + * list of OuterJoinClauseInfos for mergejoinable outer join clauses + * w/nonnullable var on left + */ + List *left_join_clauses; + + /* + * list of OuterJoinClauseInfos for mergejoinable outer join clauses + * w/nonnullable var on right + */ + List *right_join_clauses; + + /* + * list of OuterJoinClauseInfos for mergejoinable full join clauses + */ + List *full_join_clauses; + + /* list of SpecialJoinInfos */ + List *join_info_list; + + /* counter for assigning RestrictInfo serial numbers */ + int last_rinfo_serial; + + /* + * all_result_relids is empty for SELECT, otherwise it contains at least + * parse->resultRelation. For UPDATE/DELETE/MERGE across an inheritance + * or partitioning tree, the result rel's child relids are added. When + * using multi-level partitioning, intermediate partitioned rels are + * included. leaf_result_relids is similar except that only actual result + * tables, not partitioned tables, are included in it. + */ + /* set of all result relids */ + Relids all_result_relids; + /* set of all leaf relids */ + Relids leaf_result_relids; + + /* + * list of AppendRelInfos + * + * Note: for AppendRelInfos describing partitions of a partitioned table, + * we guarantee that partitions that come earlier in the partitioned + * table's PartitionDesc will appear earlier in append_rel_list. + */ + List *append_rel_list; + + /* list of RowIdentityVarInfos */ + List *row_identity_vars; + + /* list of PlanRowMarks */ + List *rowMarks; + + /* list of PlaceHolderInfos */ + List *placeholder_list; + + /* array of PlaceHolderInfos indexed by phid */ + struct PlaceHolderInfo **placeholder_array pg_node_attr(read_write_ignore, array_size(placeholder_array_size)); + /* allocated size of array */ + int placeholder_array_size pg_node_attr(read_write_ignore); + + /* list of ForeignKeyOptInfos */ + List *fkey_list; + + /* desired pathkeys for query_planner() */ + List *query_pathkeys; + + /* groupClause pathkeys, if any */ + List *group_pathkeys; + + /* + * The number of elements in the group_pathkeys list which belong to the + * GROUP BY clause. Additional ones belong to ORDER BY / DISTINCT + * aggregates. + */ + int num_groupby_pathkeys; + + /* pathkeys of bottom window, if any */ + List *window_pathkeys; + /* distinctClause pathkeys, if any */ + List *distinct_pathkeys; + /* sortClause pathkeys, if any */ + List *sort_pathkeys; + + /* Canonicalised partition schemes used in the query. */ + List *part_schemes pg_node_attr(read_write_ignore); + + /* RelOptInfos we are now trying to join */ + List *initial_rels pg_node_attr(read_write_ignore); + + /* + * Upper-rel RelOptInfos. Use fetch_upper_rel() to get any particular + * upper rel. + */ + List *upper_rels[UPPERREL_FINAL + 1] pg_node_attr(read_write_ignore); + + /* Result tlists chosen by grouping_planner for upper-stage processing */ + struct PathTarget *upper_targets[UPPERREL_FINAL + 1] pg_node_attr(read_write_ignore); + + /* + * The fully-processed groupClause is kept here. It differs from + * parse->groupClause in that we remove any items that we can prove + * redundant, so that only the columns named here actually need to be + * compared to determine grouping. Note that it's possible for *all* the + * items to be proven redundant, implying that there is only one group + * containing all the query's rows. Hence, if you want to check whether + * GROUP BY was specified, test for nonempty parse->groupClause, not for + * nonempty processed_groupClause. + * + * Currently, when grouping sets are specified we do not attempt to + * optimize the groupClause, so that processed_groupClause will be + * identical to parse->groupClause. + */ + List *processed_groupClause; + + /* + * The fully-processed distinctClause is kept here. It differs from + * parse->distinctClause in that we remove any items that we can prove + * redundant, so that only the columns named here actually need to be + * compared to determine uniqueness. Note that it's possible for *all* + * the items to be proven redundant, implying that there should be only + * one output row. Hence, if you want to check whether DISTINCT was + * specified, test for nonempty parse->distinctClause, not for nonempty + * processed_distinctClause. + */ + List *processed_distinctClause; + + /* + * The fully-processed targetlist is kept here. It differs from + * parse->targetList in that (for INSERT) it's been reordered to match the + * target table, and defaults have been filled in. Also, additional + * resjunk targets may be present. preprocess_targetlist() does most of + * that work, but note that more resjunk targets can get added during + * appendrel expansion. (Hence, upper_targets mustn't get set up till + * after that.) + */ + List *processed_tlist; + + /* + * For UPDATE, this list contains the target table's attribute numbers to + * which the first N entries of processed_tlist are to be assigned. (Any + * additional entries in processed_tlist must be resjunk.) DO NOT use the + * resnos in processed_tlist to identify the UPDATE target columns. + */ + List *update_colnos; + + /* + * Fields filled during create_plan() for use in setrefs.c + */ + /* for GroupingFunc fixup (can't print: array length not known here) */ + AttrNumber *grouping_map pg_node_attr(read_write_ignore); + /* List of MinMaxAggInfos */ + List *minmax_aggs; + + /* context holding PlannerInfo */ + MemoryContext planner_cxt pg_node_attr(read_write_ignore); + + /* # of pages in all non-dummy tables of query */ + Cardinality total_table_pages; + + /* tuple_fraction passed to query_planner */ + Selectivity tuple_fraction; + /* limit_tuples passed to query_planner */ + Cardinality limit_tuples; + + /* + * Minimum security_level for quals. Note: qual_security_level is zero if + * there are no securityQuals. + */ + Index qual_security_level; + + /* true if any RTEs are RTE_JOIN kind */ + bool hasJoinRTEs; + /* true if any RTEs are marked LATERAL */ + bool hasLateralRTEs; + /* true if havingQual was non-null */ + bool hasHavingQual; + /* true if any RestrictInfo has pseudoconstant = true */ + bool hasPseudoConstantQuals; + /* true if we've made any of those */ + bool hasAlternativeSubPlans; + /* true once we're no longer allowed to add PlaceHolderInfos */ + bool placeholdersFrozen; + /* true if planning a recursive WITH item */ + bool hasRecursion; + + /* + * Information about aggregates. Filled by preprocess_aggrefs(). + */ + /* AggInfo structs */ + List *agginfos; + /* AggTransInfo structs */ + List *aggtransinfos; + /* number of aggs with DISTINCT/ORDER BY/WITHIN GROUP */ + int numOrderedAggs; + /* does any agg not support partial mode? */ + bool hasNonPartialAggs; + /* is any partial agg non-serializable? */ + bool hasNonSerialAggs; + + /* + * These fields are used only when hasRecursion is true: + */ + /* PARAM_EXEC ID for the work table */ + int wt_param_id; + /* a path for non-recursive term */ + struct Path *non_recursive_path; + + /* + * These fields are workspace for createplan.c + */ + /* outer rels above current node */ + Relids curOuterRels; + /* not-yet-assigned NestLoopParams */ + List *curOuterParams; + + /* + * These fields are workspace for setrefs.c. Each is an array + * corresponding to glob->subplans. (We could probably teach + * gen_node_support.pl how to determine the array length, but it doesn't + * seem worth the trouble, so just mark them read_write_ignore.) + */ + bool *isAltSubplan pg_node_attr(read_write_ignore); + bool *isUsedSubplan pg_node_attr(read_write_ignore); + + /* optional private data for join_search_hook, e.g., GEQO */ + void *join_search_private pg_node_attr(read_write_ignore); + + /* Does this query modify any partition key columns? */ + bool partColsUpdated; +}; + + +/* + * In places where it's known that simple_rte_array[] must have been prepared + * already, we just index into it to fetch RTEs. In code that might be + * executed before or after entering query_planner(), use this macro. + */ +#define planner_rt_fetch(rti, root) \ + ((root)->simple_rte_array ? (root)->simple_rte_array[rti] : \ + rt_fetch(rti, (root)->parse->rtable)) + +/* + * If multiple relations are partitioned the same way, all such partitions + * will have a pointer to the same PartitionScheme. A list of PartitionScheme + * objects is attached to the PlannerInfo. By design, the partition scheme + * incorporates only the general properties of the partition method (LIST vs. + * RANGE, number of partitioning columns and the type information for each) + * and not the specific bounds. + * + * We store the opclass-declared input data types instead of the partition key + * datatypes since the former rather than the latter are used to compare + * partition bounds. Since partition key data types and the opclass declared + * input data types are expected to be binary compatible (per ResolveOpClass), + * both of those should have same byval and length properties. + */ +typedef struct PartitionSchemeData +{ + char strategy; /* partition strategy */ + int16 partnatts; /* number of partition attributes */ + Oid *partopfamily; /* OIDs of operator families */ + Oid *partopcintype; /* OIDs of opclass declared input data types */ + Oid *partcollation; /* OIDs of partitioning collations */ + + /* Cached information about partition key data types. */ + int16 *parttyplen; + bool *parttypbyval; + + /* Cached information about partition comparison functions. */ + struct FmgrInfo *partsupfunc; +} PartitionSchemeData; + +typedef struct PartitionSchemeData *PartitionScheme; + +/*---------- + * RelOptInfo + * Per-relation information for planning/optimization + * + * For planning purposes, a "base rel" is either a plain relation (a table) + * or the output of a sub-SELECT or function that appears in the range table. + * In either case it is uniquely identified by an RT index. A "joinrel" + * is the joining of two or more base rels. A joinrel is identified by + * the set of RT indexes for its component baserels, along with RT indexes + * for any outer joins it has computed. We create RelOptInfo nodes for each + * baserel and joinrel, and store them in the PlannerInfo's simple_rel_array + * and join_rel_list respectively. + * + * Note that there is only one joinrel for any given set of component + * baserels, no matter what order we assemble them in; so an unordered + * set is the right datatype to identify it with. + * + * We also have "other rels", which are like base rels in that they refer to + * single RT indexes; but they are not part of the join tree, and are given + * a different RelOptKind to identify them. + * Currently the only kind of otherrels are those made for member relations + * of an "append relation", that is an inheritance set or UNION ALL subquery. + * An append relation has a parent RTE that is a base rel, which represents + * the entire append relation. The member RTEs are otherrels. The parent + * is present in the query join tree but the members are not. The member + * RTEs and otherrels are used to plan the scans of the individual tables or + * subqueries of the append set; then the parent baserel is given Append + * and/or MergeAppend paths comprising the best paths for the individual + * member rels. (See comments for AppendRelInfo for more information.) + * + * At one time we also made otherrels to represent join RTEs, for use in + * handling join alias Vars. Currently this is not needed because all join + * alias Vars are expanded to non-aliased form during preprocess_expression. + * + * We also have relations representing joins between child relations of + * different partitioned tables. These relations are not added to + * join_rel_level lists as they are not joined directly by the dynamic + * programming algorithm. + * + * There is also a RelOptKind for "upper" relations, which are RelOptInfos + * that describe post-scan/join processing steps, such as aggregation. + * Many of the fields in these RelOptInfos are meaningless, but their Path + * fields always hold Paths showing ways to do that processing step. + * + * Parts of this data structure are specific to various scan and join + * mechanisms. It didn't seem worth creating new node types for them. + * + * relids - Set of relation identifiers (RT indexes). This is a base + * relation if there is just one, a join relation if more; + * in the join case, RT indexes of any outer joins formed + * at or below this join are included along with baserels + * rows - estimated number of tuples in the relation after restriction + * clauses have been applied (ie, output rows of a plan for it) + * consider_startup - true if there is any value in keeping plain paths for + * this rel on the basis of having cheap startup cost + * consider_param_startup - the same for parameterized paths + * reltarget - Default Path output tlist for this rel; normally contains + * Var and PlaceHolderVar nodes for the values we need to + * output from this relation. + * List is in no particular order, but all rels of an + * appendrel set must use corresponding orders. + * NOTE: in an appendrel child relation, may contain + * arbitrary expressions pulled up from a subquery! + * pathlist - List of Path nodes, one for each potentially useful + * method of generating the relation + * ppilist - ParamPathInfo nodes for parameterized Paths, if any + * cheapest_startup_path - the pathlist member with lowest startup cost + * (regardless of ordering) among the unparameterized paths; + * or NULL if there is no unparameterized path + * cheapest_total_path - the pathlist member with lowest total cost + * (regardless of ordering) among the unparameterized paths; + * or if there is no unparameterized path, the path with lowest + * total cost among the paths with minimum parameterization + * cheapest_unique_path - for caching cheapest path to produce unique + * (no duplicates) output from relation; NULL if not yet requested + * cheapest_parameterized_paths - best paths for their parameterizations; + * always includes cheapest_total_path, even if that's unparameterized + * direct_lateral_relids - rels this rel has direct LATERAL references to + * lateral_relids - required outer rels for LATERAL, as a Relids set + * (includes both direct and indirect lateral references) + * + * If the relation is a base relation it will have these fields set: + * + * relid - RTE index (this is redundant with the relids field, but + * is provided for convenience of access) + * rtekind - copy of RTE's rtekind field + * min_attr, max_attr - range of valid AttrNumbers for rel + * attr_needed - array of bitmapsets indicating the highest joinrel + * in which each attribute is needed; if bit 0 is set then + * the attribute is needed as part of final targetlist + * attr_widths - cache space for per-attribute width estimates; + * zero means not computed yet + * nulling_relids - relids of outer joins that can null this rel + * lateral_vars - lateral cross-references of rel, if any (list of + * Vars and PlaceHolderVars) + * lateral_referencers - relids of rels that reference this one laterally + * (includes both direct and indirect lateral references) + * indexlist - list of IndexOptInfo nodes for relation's indexes + * (always NIL if it's not a table or partitioned table) + * pages - number of disk pages in relation (zero if not a table) + * tuples - number of tuples in relation (not considering restrictions) + * allvisfrac - fraction of disk pages that are marked all-visible + * eclass_indexes - EquivalenceClasses that mention this rel (filled + * only after EC merging is complete) + * subroot - PlannerInfo for subquery (NULL if it's not a subquery) + * subplan_params - list of PlannerParamItems to be passed to subquery + * + * Note: for a subquery, tuples and subroot are not set immediately + * upon creation of the RelOptInfo object; they are filled in when + * set_subquery_pathlist processes the object. + * + * For otherrels that are appendrel members, these fields are filled + * in just as for a baserel, except we don't bother with lateral_vars. + * + * If the relation is either a foreign table or a join of foreign tables that + * all belong to the same foreign server and are assigned to the same user to + * check access permissions as (cf checkAsUser), these fields will be set: + * + * serverid - OID of foreign server, if foreign table (else InvalidOid) + * userid - OID of user to check access as (InvalidOid means current user) + * useridiscurrent - we've assumed that userid equals current user + * fdwroutine - function hooks for FDW, if foreign table (else NULL) + * fdw_private - private state for FDW, if foreign table (else NULL) + * + * Two fields are used to cache knowledge acquired during the join search + * about whether this rel is provably unique when being joined to given other + * relation(s), ie, it can have at most one row matching any given row from + * that join relation. Currently we only attempt such proofs, and thus only + * populate these fields, for base rels; but someday they might be used for + * join rels too: + * + * unique_for_rels - list of Relid sets, each one being a set of other + * rels for which this one has been proven unique + * non_unique_for_rels - list of Relid sets, each one being a set of + * other rels for which we have tried and failed to prove + * this one unique + * + * The presence of the following fields depends on the restrictions + * and joins that the relation participates in: + * + * baserestrictinfo - List of RestrictInfo nodes, containing info about + * each non-join qualification clause in which this relation + * participates (only used for base rels) + * baserestrictcost - Estimated cost of evaluating the baserestrictinfo + * clauses at a single tuple (only used for base rels) + * baserestrict_min_security - Smallest security_level found among + * clauses in baserestrictinfo + * joininfo - List of RestrictInfo nodes, containing info about each + * join clause in which this relation participates (but + * note this excludes clauses that might be derivable from + * EquivalenceClasses) + * has_eclass_joins - flag that EquivalenceClass joins are possible + * + * Note: Keeping a restrictinfo list in the RelOptInfo is useful only for + * base rels, because for a join rel the set of clauses that are treated as + * restrict clauses varies depending on which sub-relations we choose to join. + * (For example, in a 3-base-rel join, a clause relating rels 1 and 2 must be + * treated as a restrictclause if we join {1} and {2 3} to make {1 2 3}; but + * if we join {1 2} and {3} then that clause will be a restrictclause in {1 2} + * and should not be processed again at the level of {1 2 3}.) Therefore, + * the restrictinfo list in the join case appears in individual JoinPaths + * (field joinrestrictinfo), not in the parent relation. But it's OK for + * the RelOptInfo to store the joininfo list, because that is the same + * for a given rel no matter how we form it. + * + * We store baserestrictcost in the RelOptInfo (for base relations) because + * we know we will need it at least once (to price the sequential scan) + * and may need it multiple times to price index scans. + * + * A join relation is considered to be partitioned if it is formed from a + * join of two relations that are partitioned, have matching partitioning + * schemes, and are joined on an equijoin of the partitioning columns. + * Under those conditions we can consider the join relation to be partitioned + * by either relation's partitioning keys, though some care is needed if + * either relation can be forced to null by outer-joining. For example, an + * outer join like (A LEFT JOIN B ON A.a = B.b) may produce rows with B.b + * NULL. These rows may not fit the partitioning conditions imposed on B. + * Hence, strictly speaking, the join is not partitioned by B.b and thus + * partition keys of an outer join should include partition key expressions + * from the non-nullable side only. However, if a subsequent join uses + * strict comparison operators (and all commonly-used equijoin operators are + * strict), the presence of nulls doesn't cause a problem: such rows couldn't + * match anything on the other side and thus they don't create a need to do + * any cross-partition sub-joins. Hence we can treat such values as still + * partitioning the join output for the purpose of additional partitionwise + * joining, so long as a strict join operator is used by the next join. + * + * If the relation is partitioned, these fields will be set: + * + * part_scheme - Partitioning scheme of the relation + * nparts - Number of partitions + * boundinfo - Partition bounds + * partbounds_merged - true if partition bounds are merged ones + * partition_qual - Partition constraint if not the root + * part_rels - RelOptInfos for each partition + * all_partrels - Relids set of all partition relids + * partexprs, nullable_partexprs - Partition key expressions + * + * The partexprs and nullable_partexprs arrays each contain + * part_scheme->partnatts elements. Each of the elements is a list of + * partition key expressions. For partitioned base relations, there is one + * expression in each partexprs element, and nullable_partexprs is empty. + * For partitioned join relations, each base relation within the join + * contributes one partition key expression per partitioning column; + * that expression goes in the partexprs[i] list if the base relation + * is not nullable by this join or any lower outer join, or in the + * nullable_partexprs[i] list if the base relation is nullable. + * Furthermore, FULL JOINs add extra nullable_partexprs expressions + * corresponding to COALESCE expressions of the left and right join columns, + * to simplify matching join clauses to those lists. + * + * Not all fields are printed. (In some cases, there is no print support for + * the field type.) + *---------- + */ + +/* Bitmask of flags supported by table AMs */ +#define AMFLAG_HAS_TID_RANGE (1 << 0) + +typedef enum RelOptKind +{ + RELOPT_BASEREL, + RELOPT_JOINREL, + RELOPT_OTHER_MEMBER_REL, + RELOPT_OTHER_JOINREL, + RELOPT_UPPER_REL, + RELOPT_OTHER_UPPER_REL +} RelOptKind; + +/* + * Is the given relation a simple relation i.e a base or "other" member + * relation? + */ +#define IS_SIMPLE_REL(rel) \ + ((rel)->reloptkind == RELOPT_BASEREL || \ + (rel)->reloptkind == RELOPT_OTHER_MEMBER_REL) + +/* Is the given relation a join relation? */ +#define IS_JOIN_REL(rel) \ + ((rel)->reloptkind == RELOPT_JOINREL || \ + (rel)->reloptkind == RELOPT_OTHER_JOINREL) + +/* Is the given relation an upper relation? */ +#define IS_UPPER_REL(rel) \ + ((rel)->reloptkind == RELOPT_UPPER_REL || \ + (rel)->reloptkind == RELOPT_OTHER_UPPER_REL) + +/* Is the given relation an "other" relation? */ +#define IS_OTHER_REL(rel) \ + ((rel)->reloptkind == RELOPT_OTHER_MEMBER_REL || \ + (rel)->reloptkind == RELOPT_OTHER_JOINREL || \ + (rel)->reloptkind == RELOPT_OTHER_UPPER_REL) + +typedef struct RelOptInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + RelOptKind reloptkind; + + /* + * all relations included in this RelOptInfo; set of base + OJ relids + * (rangetable indexes) + */ + Relids relids; + + /* + * size estimates generated by planner + */ + /* estimated number of result tuples */ + Cardinality rows; + + /* + * per-relation planner control flags + */ + /* keep cheap-startup-cost paths? */ + bool consider_startup; + /* ditto, for parameterized paths? */ + bool consider_param_startup; + /* consider parallel paths? */ + bool consider_parallel; + + /* + * default result targetlist for Paths scanning this relation; list of + * Vars/Exprs, cost, width + */ + struct PathTarget *reltarget; + + /* + * materialization information + */ + List *pathlist; /* Path structures */ + List *ppilist; /* ParamPathInfos used in pathlist */ + List *partial_pathlist; /* partial Paths */ + struct Path *cheapest_startup_path; + struct Path *cheapest_total_path; + struct Path *cheapest_unique_path; + List *cheapest_parameterized_paths; + + /* + * parameterization information needed for both base rels and join rels + * (see also lateral_vars and lateral_referencers) + */ + /* rels directly laterally referenced */ + Relids direct_lateral_relids; + /* minimum parameterization of rel */ + Relids lateral_relids; + + /* + * information about a base rel (not set for join rels!) + */ + Index relid; + /* containing tablespace */ + Oid reltablespace; + /* RELATION, SUBQUERY, FUNCTION, etc */ + RTEKind rtekind; + /* smallest attrno of rel (often <0) */ + AttrNumber min_attr; + /* largest attrno of rel */ + AttrNumber max_attr; + /* array indexed [min_attr .. max_attr] */ + Relids *attr_needed pg_node_attr(read_write_ignore); + /* array indexed [min_attr .. max_attr] */ + int32 *attr_widths pg_node_attr(read_write_ignore); + /* relids of outer joins that can null this baserel */ + Relids nulling_relids; + /* LATERAL Vars and PHVs referenced by rel */ + List *lateral_vars; + /* rels that reference this baserel laterally */ + Relids lateral_referencers; + /* list of IndexOptInfo */ + List *indexlist; + /* list of StatisticExtInfo */ + List *statlist; + /* size estimates derived from pg_class */ + BlockNumber pages; + Cardinality tuples; + double allvisfrac; + /* indexes in PlannerInfo's eq_classes list of ECs that mention this rel */ + Bitmapset *eclass_indexes; + PlannerInfo *subroot; /* if subquery */ + List *subplan_params; /* if subquery */ + /* wanted number of parallel workers */ + int rel_parallel_workers; + /* Bitmask of optional features supported by the table AM */ + uint32 amflags; + + /* + * Information about foreign tables and foreign joins + */ + /* identifies server for the table or join */ + Oid serverid; + /* identifies user to check access as; 0 means to check as current user */ + Oid userid; + /* join is only valid for current user */ + bool useridiscurrent; + /* use "struct FdwRoutine" to avoid including fdwapi.h here */ + struct FdwRoutine *fdwroutine pg_node_attr(read_write_ignore); + void *fdw_private pg_node_attr(read_write_ignore); + + /* + * cache space for remembering if we have proven this relation unique + */ + /* known unique for these other relid set(s) */ + List *unique_for_rels; + /* known not unique for these set(s) */ + List *non_unique_for_rels; + + /* + * used by various scans and joins: + */ + /* RestrictInfo structures (if base rel) */ + List *baserestrictinfo; + /* cost of evaluating the above */ + QualCost baserestrictcost; + /* min security_level found in baserestrictinfo */ + Index baserestrict_min_security; + /* RestrictInfo structures for join clauses involving this rel */ + List *joininfo; + /* T means joininfo is incomplete */ + bool has_eclass_joins; + + /* + * used by partitionwise joins: + */ + /* consider partitionwise join paths? (if partitioned rel) */ + bool consider_partitionwise_join; + + /* + * inheritance links, if this is an otherrel (otherwise NULL): + */ + /* Immediate parent relation (dumping it would be too verbose) */ + struct RelOptInfo *parent pg_node_attr(read_write_ignore); + /* Topmost parent relation (dumping it would be too verbose) */ + struct RelOptInfo *top_parent pg_node_attr(read_write_ignore); + /* Relids of topmost parent (redundant, but handy) */ + Relids top_parent_relids; + + /* + * used for partitioned relations: + */ + /* Partitioning scheme */ + PartitionScheme part_scheme pg_node_attr(read_write_ignore); + + /* + * Number of partitions; -1 if not yet set; in case of a join relation 0 + * means it's considered unpartitioned + */ + int nparts; + /* Partition bounds */ + struct PartitionBoundInfoData *boundinfo pg_node_attr(read_write_ignore); + /* True if partition bounds were created by partition_bounds_merge() */ + bool partbounds_merged; + /* Partition constraint, if not the root */ + List *partition_qual; + + /* + * Array of RelOptInfos of partitions, stored in the same order as bounds + * (don't print, too bulky and duplicative) + */ + struct RelOptInfo **part_rels pg_node_attr(read_write_ignore); + + /* + * Bitmap with members acting as indexes into the part_rels[] array to + * indicate which partitions survived partition pruning. + */ + Bitmapset *live_parts; + /* Relids set of all partition relids */ + Relids all_partrels; + + /* + * These arrays are of length partkey->partnatts, which we don't have at + * hand, so don't try to print + */ + + /* Non-nullable partition key expressions */ + List **partexprs pg_node_attr(read_write_ignore); + /* Nullable partition key expressions */ + List **nullable_partexprs pg_node_attr(read_write_ignore); +} RelOptInfo; + +/* + * Is given relation partitioned? + * + * It's not enough to test whether rel->part_scheme is set, because it might + * be that the basic partitioning properties of the input relations matched + * but the partition bounds did not. Also, if we are able to prove a rel + * dummy (empty), we should henceforth treat it as unpartitioned. + */ +#define IS_PARTITIONED_REL(rel) \ + ((rel)->part_scheme && (rel)->boundinfo && (rel)->nparts > 0 && \ + (rel)->part_rels && !IS_DUMMY_REL(rel)) + +/* + * Convenience macro to make sure that a partitioned relation has all the + * required members set. + */ +#define REL_HAS_ALL_PART_PROPS(rel) \ + ((rel)->part_scheme && (rel)->boundinfo && (rel)->nparts > 0 && \ + (rel)->part_rels && (rel)->partexprs && (rel)->nullable_partexprs) + +/* + * IndexOptInfo + * Per-index information for planning/optimization + * + * indexkeys[] and canreturn[] each have ncolumns entries. + * + * indexcollations[], opfamily[], and opcintype[] each have nkeycolumns + * entries. These don't contain any information about INCLUDE columns. + * + * sortopfamily[], reverse_sort[], and nulls_first[] have + * nkeycolumns entries, if the index is ordered; but if it is unordered, + * those pointers are NULL. + * + * Zeroes in the indexkeys[] array indicate index columns that are + * expressions; there is one element in indexprs for each such column. + * + * For an ordered index, reverse_sort[] and nulls_first[] describe the + * sort ordering of a forward indexscan; we can also consider a backward + * indexscan, which will generate the reverse ordering. + * + * The indexprs and indpred expressions have been run through + * prepqual.c and eval_const_expressions() for ease of matching to + * WHERE clauses. indpred is in implicit-AND form. + * + * indextlist is a TargetEntry list representing the index columns. + * It provides an equivalent base-relation Var for each simple column, + * and links to the matching indexprs element for each expression column. + * + * While most of these fields are filled when the IndexOptInfo is created + * (by plancat.c), indrestrictinfo and predOK are set later, in + * check_index_predicates(). + */ +#ifndef HAVE_INDEXOPTINFO_TYPEDEF +typedef struct IndexOptInfo IndexOptInfo; +#define HAVE_INDEXOPTINFO_TYPEDEF 1 +#endif + +struct IndexPath; /* forward declaration */ + +struct IndexOptInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* OID of the index relation */ + Oid indexoid; + /* tablespace of index (not table) */ + Oid reltablespace; + /* back-link to index's table; don't print, else infinite recursion */ + RelOptInfo *rel pg_node_attr(read_write_ignore); + + /* + * index-size statistics (from pg_class and elsewhere) + */ + /* number of disk pages in index */ + BlockNumber pages; + /* number of index tuples in index */ + Cardinality tuples; + /* index tree height, or -1 if unknown */ + int tree_height; + + /* + * index descriptor information + */ + /* number of columns in index */ + int ncolumns; + /* number of key columns in index */ + int nkeycolumns; + + /* + * table column numbers of index's columns (both key and included + * columns), or 0 for expression columns + */ + int *indexkeys pg_node_attr(array_size(ncolumns)); + /* OIDs of collations of index columns */ + Oid *indexcollations pg_node_attr(array_size(nkeycolumns)); + /* OIDs of operator families for columns */ + Oid *opfamily pg_node_attr(array_size(nkeycolumns)); + /* OIDs of opclass declared input data types */ + Oid *opcintype pg_node_attr(array_size(nkeycolumns)); + /* OIDs of btree opfamilies, if orderable. NULL if partitioned index */ + Oid *sortopfamily pg_node_attr(array_size(nkeycolumns)); + /* is sort order descending? or NULL if partitioned index */ + bool *reverse_sort pg_node_attr(array_size(nkeycolumns)); + /* do NULLs come first in the sort order? or NULL if partitioned index */ + bool *nulls_first pg_node_attr(array_size(nkeycolumns)); + /* opclass-specific options for columns */ + bytea **opclassoptions pg_node_attr(read_write_ignore); + /* which index cols can be returned in an index-only scan? */ + bool *canreturn pg_node_attr(array_size(ncolumns)); + /* OID of the access method (in pg_am) */ + Oid relam; + + /* + * expressions for non-simple index columns; redundant to print since we + * print indextlist + */ + List *indexprs pg_node_attr(read_write_ignore); + /* predicate if a partial index, else NIL */ + List *indpred; + + /* targetlist representing index columns */ + List *indextlist; + + /* + * parent relation's baserestrictinfo list, less any conditions implied by + * the index's predicate (unless it's a target rel, see comments in + * check_index_predicates()) + */ + List *indrestrictinfo; + + /* true if index predicate matches query */ + bool predOK; + /* true if a unique index */ + bool unique; + /* is uniqueness enforced immediately? */ + bool immediate; + /* true if index doesn't really exist */ + bool hypothetical; + + /* + * Remaining fields are copied from the index AM's API struct + * (IndexAmRoutine). These fields are not set for partitioned indexes. + */ + bool amcanorderbyop; + bool amoptionalkey; + bool amsearcharray; + bool amsearchnulls; + /* does AM have amgettuple interface? */ + bool amhasgettuple; + /* does AM have amgetbitmap interface? */ + bool amhasgetbitmap; + bool amcanparallel; + /* does AM have ammarkpos interface? */ + bool amcanmarkpos; + /* AM's cost estimator */ + /* Rather than include amapi.h here, we declare amcostestimate like this */ + void (*amcostestimate) (struct PlannerInfo *, struct IndexPath *, double, Cost *, Cost *, Selectivity *, double *, double *) pg_node_attr(read_write_ignore); +}; + +/* + * ForeignKeyOptInfo + * Per-foreign-key information for planning/optimization + * + * The per-FK-column arrays can be fixed-size because we allow at most + * INDEX_MAX_KEYS columns in a foreign key constraint. Each array has + * nkeys valid entries. + */ +typedef struct ForeignKeyOptInfo +{ + pg_node_attr(custom_read_write, no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* + * Basic data about the foreign key (fetched from catalogs): + */ + + /* RT index of the referencing table */ + Index con_relid; + /* RT index of the referenced table */ + Index ref_relid; + /* number of columns in the foreign key */ + int nkeys; + /* cols in referencing table */ + AttrNumber conkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys)); + /* cols in referenced table */ + AttrNumber confkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys)); + /* PK = FK operator OIDs */ + Oid conpfeqop[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys)); + + /* + * Derived info about whether FK's equality conditions match the query: + */ + + /* # of FK cols matched by ECs */ + int nmatched_ec; + /* # of these ECs that are ec_has_const */ + int nconst_ec; + /* # of FK cols matched by non-EC rinfos */ + int nmatched_rcols; + /* total # of non-EC rinfos matched to FK */ + int nmatched_ri; + /* Pointer to eclass matching each column's condition, if there is one */ + struct EquivalenceClass *eclass[INDEX_MAX_KEYS]; + /* Pointer to eclass member for the referencing Var, if there is one */ + struct EquivalenceMember *fk_eclass_member[INDEX_MAX_KEYS]; + /* List of non-EC RestrictInfos matching each column's condition */ + List *rinfos[INDEX_MAX_KEYS]; +} ForeignKeyOptInfo; + +/* + * StatisticExtInfo + * Information about extended statistics for planning/optimization + * + * Each pg_statistic_ext row is represented by one or more nodes of this + * type, or even zero if ANALYZE has not computed them. + */ +typedef struct StatisticExtInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* OID of the statistics row */ + Oid statOid; + + /* includes child relations */ + bool inherit; + + /* back-link to statistic's table; don't print, else infinite recursion */ + RelOptInfo *rel pg_node_attr(read_write_ignore); + + /* statistics kind of this entry */ + char kind; + + /* attnums of the columns covered */ + Bitmapset *keys; + + /* expressions */ + List *exprs; +} StatisticExtInfo; + +/* + * JoinDomains + * + * A "join domain" defines the scope of applicability of deductions made via + * the EquivalenceClass mechanism. Roughly speaking, a join domain is a set + * of base+OJ relations that are inner-joined together. More precisely, it is + * the set of relations at which equalities deduced from an EquivalenceClass + * can be enforced or should be expected to hold. The topmost JoinDomain + * covers the whole query (so its jd_relids should equal all_query_rels). + * An outer join creates a new JoinDomain that includes all base+OJ relids + * within its nullable side, but (by convention) not the OJ's own relid. + * A FULL join creates two new JoinDomains, one for each side. + * + * Notice that a rel that is below outer join(s) will thus appear to belong + * to multiple join domains. However, any of its Vars that appear in + * EquivalenceClasses belonging to higher join domains will have nullingrel + * bits preventing them from being evaluated at the rel's scan level, so that + * we will not be able to derive enforceable-at-the-rel-scan-level clauses + * from such ECs. We define the join domain relid sets this way so that + * domains can be said to be "higher" or "lower" when one domain relid set + * includes another. + * + * The JoinDomains for a query are computed in deconstruct_jointree. + * We do not copy JoinDomain structs once made, so they can be compared + * for equality by simple pointer equality. + */ +typedef struct JoinDomain +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + Relids jd_relids; /* all relids contained within the domain */ +} JoinDomain; + +/* + * EquivalenceClasses + * + * Whenever we identify a mergejoinable equality clause A = B that is + * not an outer-join clause, we create an EquivalenceClass containing + * the expressions A and B to record this knowledge. If we later find another + * equivalence B = C, we add C to the existing EquivalenceClass; this may + * require merging two existing EquivalenceClasses. At the end of the qual + * distribution process, we have sets of values that are known all transitively + * equal to each other, where "equal" is according to the rules of the btree + * operator family(s) shown in ec_opfamilies, as well as the collation shown + * by ec_collation. (We restrict an EC to contain only equalities whose + * operators belong to the same set of opfamilies. This could probably be + * relaxed, but for now it's not worth the trouble, since nearly all equality + * operators belong to only one btree opclass anyway. Similarly, we suppose + * that all or none of the input datatypes are collatable, so that a single + * collation value is sufficient.) + * + * Strictly speaking, deductions from an EquivalenceClass hold only within + * a "join domain", that is a set of relations that are innerjoined together + * (see JoinDomain above). For the most part we don't need to account for + * this explicitly, because equality clauses from different join domains + * will contain Vars that are not equal() because they have different + * nullingrel sets, and thus we will never falsely merge ECs from different + * join domains. But Var-free (pseudoconstant) expressions lack that safety + * feature. We handle that by marking "const" EC members with the JoinDomain + * of the clause they came from; two nominally-equal const members will be + * considered different if they came from different JoinDomains. This ensures + * no false EquivalenceClass merges will occur. + * + * We also use EquivalenceClasses as the base structure for PathKeys, letting + * us represent knowledge about different sort orderings being equivalent. + * Since every PathKey must reference an EquivalenceClass, we will end up + * with single-member EquivalenceClasses whenever a sort key expression has + * not been equivalenced to anything else. It is also possible that such an + * EquivalenceClass will contain a volatile expression ("ORDER BY random()"), + * which is a case that can't arise otherwise since clauses containing + * volatile functions are never considered mergejoinable. We mark such + * EquivalenceClasses specially to prevent them from being merged with + * ordinary EquivalenceClasses. Also, for volatile expressions we have + * to be careful to match the EquivalenceClass to the correct targetlist + * entry: consider SELECT random() AS a, random() AS b ... ORDER BY b,a. + * So we record the SortGroupRef of the originating sort clause. + * + * NB: if ec_merged isn't NULL, this class has been merged into another, and + * should be ignored in favor of using the pointed-to class. + * + * NB: EquivalenceClasses are never copied after creation. Therefore, + * copyObject() copies pointers to them as pointers, and equal() compares + * pointers to EquivalenceClasses via pointer equality. This is implemented + * by putting copy_as_scalar and equal_as_scalar attributes on fields that + * are pointers to EquivalenceClasses. The same goes for EquivalenceMembers. + */ +typedef struct EquivalenceClass +{ + pg_node_attr(custom_read_write, no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + List *ec_opfamilies; /* btree operator family OIDs */ + Oid ec_collation; /* collation, if datatypes are collatable */ + List *ec_members; /* list of EquivalenceMembers */ + List *ec_sources; /* list of generating RestrictInfos */ + List *ec_derives; /* list of derived RestrictInfos */ + Relids ec_relids; /* all relids appearing in ec_members, except + * for child members (see below) */ + bool ec_has_const; /* any pseudoconstants in ec_members? */ + bool ec_has_volatile; /* the (sole) member is a volatile expr */ + bool ec_broken; /* failed to generate needed clauses? */ + Index ec_sortref; /* originating sortclause label, or 0 */ + Index ec_min_security; /* minimum security_level in ec_sources */ + Index ec_max_security; /* maximum security_level in ec_sources */ + struct EquivalenceClass *ec_merged; /* set if merged into another EC */ +} EquivalenceClass; + +/* + * If an EC contains a constant, any PathKey depending on it must be + * redundant, since there's only one possible value of the key. + */ +#define EC_MUST_BE_REDUNDANT(eclass) \ + ((eclass)->ec_has_const) + +/* + * EquivalenceMember - one member expression of an EquivalenceClass + * + * em_is_child signifies that this element was built by transposing a member + * for an appendrel parent relation to represent the corresponding expression + * for an appendrel child. These members are used for determining the + * pathkeys of scans on the child relation and for explicitly sorting the + * child when necessary to build a MergeAppend path for the whole appendrel + * tree. An em_is_child member has no impact on the properties of the EC as a + * whole; in particular the EC's ec_relids field does NOT include the child + * relation. An em_is_child member should never be marked em_is_const nor + * cause ec_has_const or ec_has_volatile to be set, either. Thus, em_is_child + * members are not really full-fledged members of the EC, but just reflections + * or doppelgangers of real members. Most operations on EquivalenceClasses + * should ignore em_is_child members, and those that don't should test + * em_relids to make sure they only consider relevant members. + * + * em_datatype is usually the same as exprType(em_expr), but can be + * different when dealing with a binary-compatible opfamily; in particular + * anyarray_ops would never work without this. Use em_datatype when + * looking up a specific btree operator to work with this expression. + */ +typedef struct EquivalenceMember +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + Expr *em_expr; /* the expression represented */ + Relids em_relids; /* all relids appearing in em_expr */ + bool em_is_const; /* expression is pseudoconstant? */ + bool em_is_child; /* derived version for a child relation? */ + Oid em_datatype; /* the "nominal type" used by the opfamily */ + JoinDomain *em_jdomain; /* join domain containing the source clause */ + /* if em_is_child is true, this links to corresponding EM for top parent */ + struct EquivalenceMember *em_parent pg_node_attr(read_write_ignore); +} EquivalenceMember; + +/* + * PathKeys + * + * The sort ordering of a path is represented by a list of PathKey nodes. + * An empty list implies no known ordering. Otherwise the first item + * represents the primary sort key, the second the first secondary sort key, + * etc. The value being sorted is represented by linking to an + * EquivalenceClass containing that value and including pk_opfamily among its + * ec_opfamilies. The EquivalenceClass tells which collation to use, too. + * This is a convenient method because it makes it trivial to detect + * equivalent and closely-related orderings. (See optimizer/README for more + * information.) + * + * Note: pk_strategy is either BTLessStrategyNumber (for ASC) or + * BTGreaterStrategyNumber (for DESC). We assume that all ordering-capable + * index types will use btree-compatible strategy numbers. + */ +typedef struct PathKey +{ + pg_node_attr(no_read, no_query_jumble) + + NodeTag type; + + /* the value that is ordered */ + EquivalenceClass *pk_eclass pg_node_attr(copy_as_scalar, equal_as_scalar); + Oid pk_opfamily; /* btree opfamily defining the ordering */ + int pk_strategy; /* sort direction (ASC or DESC) */ + bool pk_nulls_first; /* do NULLs come before normal values? */ +} PathKey; + +/* + * VolatileFunctionStatus -- allows nodes to cache their + * contain_volatile_functions properties. VOLATILITY_UNKNOWN means not yet + * determined. + */ +typedef enum VolatileFunctionStatus +{ + VOLATILITY_UNKNOWN = 0, + VOLATILITY_VOLATILE, + VOLATILITY_NOVOLATILE +} VolatileFunctionStatus; + +/* + * PathTarget + * + * This struct contains what we need to know during planning about the + * targetlist (output columns) that a Path will compute. Each RelOptInfo + * includes a default PathTarget, which its individual Paths may simply + * reference. However, in some cases a Path may compute outputs different + * from other Paths, and in that case we make a custom PathTarget for it. + * For example, an indexscan might return index expressions that would + * otherwise need to be explicitly calculated. (Note also that "upper" + * relations generally don't have useful default PathTargets.) + * + * exprs contains bare expressions; they do not have TargetEntry nodes on top, + * though those will appear in finished Plans. + * + * sortgrouprefs[] is an array of the same length as exprs, containing the + * corresponding sort/group refnos, or zeroes for expressions not referenced + * by sort/group clauses. If sortgrouprefs is NULL (which it generally is in + * RelOptInfo.reltarget targets; only upper-level Paths contain this info), + * we have not identified sort/group columns in this tlist. This allows us to + * deal with sort/group refnos when needed with less expense than including + * TargetEntry nodes in the exprs list. + */ +typedef struct PathTarget +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* list of expressions to be computed */ + List *exprs; + + /* corresponding sort/group refnos, or 0 */ + Index *sortgrouprefs pg_node_attr(array_size(exprs)); + + /* cost of evaluating the expressions */ + QualCost cost; + + /* estimated avg width of result tuples */ + int width; + + /* indicates if exprs contain any volatile functions */ + VolatileFunctionStatus has_volatile_expr; +} PathTarget; + +/* Convenience macro to get a sort/group refno from a PathTarget */ +#define get_pathtarget_sortgroupref(target, colno) \ + ((target)->sortgrouprefs ? (target)->sortgrouprefs[colno] : (Index) 0) + + +/* + * ParamPathInfo + * + * All parameterized paths for a given relation with given required outer rels + * link to a single ParamPathInfo, which stores common information such as + * the estimated rowcount for this parameterization. We do this partly to + * avoid recalculations, but mostly to ensure that the estimated rowcount + * is in fact the same for every such path. + * + * Note: ppi_clauses is only used in ParamPathInfos for base relation paths; + * in join cases it's NIL because the set of relevant clauses varies depending + * on how the join is formed. The relevant clauses will appear in each + * parameterized join path's joinrestrictinfo list, instead. ParamPathInfos + * for append relations don't bother with this, either. + * + * ppi_serials is the set of rinfo_serial numbers for quals that are enforced + * by this path. As with ppi_clauses, it's only maintained for baserels. + * (We could construct it on-the-fly from ppi_clauses, but it seems better + * to materialize a copy.) + */ +typedef struct ParamPathInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + Relids ppi_req_outer; /* rels supplying parameters used by path */ + Cardinality ppi_rows; /* estimated number of result tuples */ + List *ppi_clauses; /* join clauses available from outer rels */ + Bitmapset *ppi_serials; /* set of rinfo_serial for enforced quals */ +} ParamPathInfo; + + +/* + * Type "Path" is used as-is for sequential-scan paths, as well as some other + * simple plan types that we don't need any extra information in the path for. + * For other path types it is the first component of a larger struct. + * + * "pathtype" is the NodeTag of the Plan node we could build from this Path. + * It is partially redundant with the Path's NodeTag, but allows us to use + * the same Path type for multiple Plan types when there is no need to + * distinguish the Plan type during path processing. + * + * "parent" identifies the relation this Path scans, and "pathtarget" + * describes the precise set of output columns the Path would compute. + * In simple cases all Paths for a given rel share the same targetlist, + * which we represent by having path->pathtarget equal to parent->reltarget. + * + * "param_info", if not NULL, links to a ParamPathInfo that identifies outer + * relation(s) that provide parameter values to each scan of this path. + * That means this path can only be joined to those rels by means of nestloop + * joins with this path on the inside. Also note that a parameterized path + * is responsible for testing all "movable" joinclauses involving this rel + * and the specified outer rel(s). + * + * "rows" is the same as parent->rows in simple paths, but in parameterized + * paths and UniquePaths it can be less than parent->rows, reflecting the + * fact that we've filtered by extra join conditions or removed duplicates. + * + * "pathkeys" is a List of PathKey nodes (see above), describing the sort + * ordering of the path's output rows. + * + * We do not support copying Path trees, mainly because the circular linkages + * between RelOptInfo and Path nodes can't be handled easily in a simple + * depth-first traversal. We also don't have read support at the moment. + */ +typedef struct Path +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* tag identifying scan/join method */ + NodeTag pathtype; + + /* + * the relation this path can build + * + * We do NOT print the parent, else we'd be in infinite recursion. We can + * print the parent's relids for identification purposes, though. + */ + RelOptInfo *parent pg_node_attr(write_only_relids); + + /* + * list of Vars/Exprs, cost, width + * + * We print the pathtarget only if it's not the default one for the rel. + */ + PathTarget *pathtarget pg_node_attr(write_only_nondefault_pathtarget); + + /* + * parameterization info, or NULL if none + * + * We do not print the whole of param_info, since it's printed via + * RelOptInfo; it's sufficient and less cluttering to print just the + * required outer relids. + */ + ParamPathInfo *param_info pg_node_attr(write_only_req_outer); + + /* engage parallel-aware logic? */ + bool parallel_aware; + /* OK to use as part of parallel plan? */ + bool parallel_safe; + /* desired # of workers; 0 = not parallel */ + int parallel_workers; + + /* estimated size/costs for path (see costsize.c for more info) */ + Cardinality rows; /* estimated number of result tuples */ + Cost startup_cost; /* cost expended before fetching any tuples */ + Cost total_cost; /* total cost (assuming all tuples fetched) */ + + /* sort ordering of path's output; a List of PathKey nodes; see above */ + List *pathkeys; +} Path; + +/* Macro for extracting a path's parameterization relids; beware double eval */ +#define PATH_REQ_OUTER(path) \ + ((path)->param_info ? (path)->param_info->ppi_req_outer : (Relids) NULL) + +/*---------- + * IndexPath represents an index scan over a single index. + * + * This struct is used for both regular indexscans and index-only scans; + * path.pathtype is T_IndexScan or T_IndexOnlyScan to show which is meant. + * + * 'indexinfo' is the index to be scanned. + * + * 'indexclauses' is a list of IndexClause nodes, each representing one + * index-checkable restriction, with implicit AND semantics across the list. + * An empty list implies a full index scan. + * + * 'indexorderbys', if not NIL, is a list of ORDER BY expressions that have + * been found to be usable as ordering operators for an amcanorderbyop index. + * The list must match the path's pathkeys, ie, one expression per pathkey + * in the same order. These are not RestrictInfos, just bare expressions, + * since they generally won't yield booleans. It's guaranteed that each + * expression has the index key on the left side of the operator. + * + * 'indexorderbycols' is an integer list of index column numbers (zero-based) + * of the same length as 'indexorderbys', showing which index column each + * ORDER BY expression is meant to be used with. (There is no restriction + * on which index column each ORDER BY can be used with.) + * + * 'indexscandir' is one of: + * ForwardScanDirection: forward scan of an index + * BackwardScanDirection: backward scan of an ordered index + * Unordered indexes will always have an indexscandir of ForwardScanDirection. + * + * 'indextotalcost' and 'indexselectivity' are saved in the IndexPath so that + * we need not recompute them when considering using the same index in a + * bitmap index/heap scan (see BitmapHeapPath). The costs of the IndexPath + * itself represent the costs of an IndexScan or IndexOnlyScan plan type. + *---------- + */ +typedef struct IndexPath +{ + Path path; + IndexOptInfo *indexinfo; + List *indexclauses; + List *indexorderbys; + List *indexorderbycols; + ScanDirection indexscandir; + Cost indextotalcost; + Selectivity indexselectivity; +} IndexPath; + +/* + * Each IndexClause references a RestrictInfo node from the query's WHERE + * or JOIN conditions, and shows how that restriction can be applied to + * the particular index. We support both indexclauses that are directly + * usable by the index machinery, which are typically of the form + * "indexcol OP pseudoconstant", and those from which an indexable qual + * can be derived. The simplest such transformation is that a clause + * of the form "pseudoconstant OP indexcol" can be commuted to produce an + * indexable qual (the index machinery expects the indexcol to be on the + * left always). Another example is that we might be able to extract an + * indexable range condition from a LIKE condition, as in "x LIKE 'foo%bar'" + * giving rise to "x >= 'foo' AND x < 'fop'". Derivation of such lossy + * conditions is done by a planner support function attached to the + * indexclause's top-level function or operator. + * + * indexquals is a list of RestrictInfos for the directly-usable index + * conditions associated with this IndexClause. In the simplest case + * it's a one-element list whose member is iclause->rinfo. Otherwise, + * it contains one or more directly-usable indexqual conditions extracted + * from the given clause. The 'lossy' flag indicates whether the + * indexquals are semantically equivalent to the original clause, or + * represent a weaker condition. + * + * Normally, indexcol is the index of the single index column the clause + * works on, and indexcols is NIL. But if the clause is a RowCompareExpr, + * indexcol is the index of the leading column, and indexcols is a list of + * all the affected columns. (Note that indexcols matches up with the + * columns of the actual indexable RowCompareExpr in indexquals, which + * might be different from the original in rinfo.) + * + * An IndexPath's IndexClause list is required to be ordered by index + * column, i.e. the indexcol values must form a nondecreasing sequence. + * (The order of multiple clauses for the same index column is unspecified.) + */ +typedef struct IndexClause +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + struct RestrictInfo *rinfo; /* original restriction or join clause */ + List *indexquals; /* indexqual(s) derived from it */ + bool lossy; /* are indexquals a lossy version of clause? */ + AttrNumber indexcol; /* index column the clause uses (zero-based) */ + List *indexcols; /* multiple index columns, if RowCompare */ +} IndexClause; + +/* + * BitmapHeapPath represents one or more indexscans that generate TID bitmaps + * instead of directly accessing the heap, followed by AND/OR combinations + * to produce a single bitmap, followed by a heap scan that uses the bitmap. + * Note that the output is always considered unordered, since it will come + * out in physical heap order no matter what the underlying indexes did. + * + * The individual indexscans are represented by IndexPath nodes, and any + * logic on top of them is represented by a tree of BitmapAndPath and + * BitmapOrPath nodes. Notice that we can use the same IndexPath node both + * to represent a regular (or index-only) index scan plan, and as the child + * of a BitmapHeapPath that represents scanning the same index using a + * BitmapIndexScan. The startup_cost and total_cost figures of an IndexPath + * always represent the costs to use it as a regular (or index-only) + * IndexScan. The costs of a BitmapIndexScan can be computed using the + * IndexPath's indextotalcost and indexselectivity. + */ +typedef struct BitmapHeapPath +{ + Path path; + Path *bitmapqual; /* IndexPath, BitmapAndPath, BitmapOrPath */ +} BitmapHeapPath; + +/* + * BitmapAndPath represents a BitmapAnd plan node; it can only appear as + * part of the substructure of a BitmapHeapPath. The Path structure is + * a bit more heavyweight than we really need for this, but for simplicity + * we make it a derivative of Path anyway. + */ +typedef struct BitmapAndPath +{ + Path path; + List *bitmapquals; /* IndexPaths and BitmapOrPaths */ + Selectivity bitmapselectivity; +} BitmapAndPath; + +/* + * BitmapOrPath represents a BitmapOr plan node; it can only appear as + * part of the substructure of a BitmapHeapPath. The Path structure is + * a bit more heavyweight than we really need for this, but for simplicity + * we make it a derivative of Path anyway. + */ +typedef struct BitmapOrPath +{ + Path path; + List *bitmapquals; /* IndexPaths and BitmapAndPaths */ + Selectivity bitmapselectivity; +} BitmapOrPath; + +/* + * TidPath represents a scan by TID + * + * tidquals is an implicitly OR'ed list of qual expressions of the form + * "CTID = pseudoconstant", or "CTID = ANY(pseudoconstant_array)", + * or a CurrentOfExpr for the relation. + */ +typedef struct TidPath +{ + Path path; + List *tidquals; /* qual(s) involving CTID = something */ +} TidPath; + +/* + * TidRangePath represents a scan by a contiguous range of TIDs + * + * tidrangequals is an implicitly AND'ed list of qual expressions of the form + * "CTID relop pseudoconstant", where relop is one of >,>=,<,<=. + */ +typedef struct TidRangePath +{ + Path path; + List *tidrangequals; +} TidRangePath; + +/* + * SubqueryScanPath represents a scan of an unflattened subquery-in-FROM + * + * Note that the subpath comes from a different planning domain; for example + * RTE indexes within it mean something different from those known to the + * SubqueryScanPath. path.parent->subroot is the planning context needed to + * interpret the subpath. + */ +typedef struct SubqueryScanPath +{ + Path path; + Path *subpath; /* path representing subquery execution */ +} SubqueryScanPath; + +/* + * ForeignPath represents a potential scan of a foreign table, foreign join + * or foreign upper-relation. + * + * fdw_private stores FDW private data about the scan. While fdw_private is + * not actually touched by the core code during normal operations, it's + * generally a good idea to use a representation that can be dumped by + * nodeToString(), so that you can examine the structure during debugging + * with tools like pprint(). + */ +typedef struct ForeignPath +{ + Path path; + Path *fdw_outerpath; + List *fdw_private; +} ForeignPath; + +/* + * CustomPath represents a table scan or a table join done by some out-of-core + * extension. + * + * We provide a set of hooks here - which the provider must take care to set + * up correctly - to allow extensions to supply their own methods of scanning + * a relation or joing relations. For example, a provider might provide GPU + * acceleration, a cache-based scan, or some other kind of logic we haven't + * dreamed up yet. + * + * CustomPaths can be injected into the planning process for a base or join + * relation by set_rel_pathlist_hook or set_join_pathlist_hook functions, + * respectively. + * + * Core code must avoid assuming that the CustomPath is only as large as + * the structure declared here; providers are allowed to make it the first + * element in a larger structure. (Since the planner never copies Paths, + * this doesn't add any complication.) However, for consistency with the + * FDW case, we provide a "custom_private" field in CustomPath; providers + * may prefer to use that rather than define another struct type. + */ + +struct CustomPathMethods; + +typedef struct CustomPath +{ + Path path; + uint32 flags; /* mask of CUSTOMPATH_* flags, see + * nodes/extensible.h */ + List *custom_paths; /* list of child Path nodes, if any */ + List *custom_private; + const struct CustomPathMethods *methods; +} CustomPath; + +/* + * AppendPath represents an Append plan, ie, successive execution of + * several member plans. + * + * For partial Append, 'subpaths' contains non-partial subpaths followed by + * partial subpaths. + * + * Note: it is possible for "subpaths" to contain only one, or even no, + * elements. These cases are optimized during create_append_plan. + * In particular, an AppendPath with no subpaths is a "dummy" path that + * is created to represent the case that a relation is provably empty. + * (This is a convenient representation because it means that when we build + * an appendrel and find that all its children have been excluded, no extra + * action is needed to recognize the relation as dummy.) + */ +typedef struct AppendPath +{ + Path path; + List *subpaths; /* list of component Paths */ + /* Index of first partial path in subpaths; list_length(subpaths) if none */ + int first_partial_path; + Cardinality limit_tuples; /* hard limit on output tuples, or -1 */ +} AppendPath; + +#define IS_DUMMY_APPEND(p) \ + (IsA((p), AppendPath) && ((AppendPath *) (p))->subpaths == NIL) + +/* + * A relation that's been proven empty will have one path that is dummy + * (but might have projection paths on top). For historical reasons, + * this is provided as a macro that wraps is_dummy_rel(). + */ +#define IS_DUMMY_REL(r) is_dummy_rel(r) +extern bool is_dummy_rel(RelOptInfo *rel); + +/* + * MergeAppendPath represents a MergeAppend plan, ie, the merging of sorted + * results from several member plans to produce similarly-sorted output. + */ +typedef struct MergeAppendPath +{ + Path path; + List *subpaths; /* list of component Paths */ + Cardinality limit_tuples; /* hard limit on output tuples, or -1 */ +} MergeAppendPath; + +/* + * GroupResultPath represents use of a Result plan node to compute the + * output of a degenerate GROUP BY case, wherein we know we should produce + * exactly one row, which might then be filtered by a HAVING qual. + * + * Note that quals is a list of bare clauses, not RestrictInfos. + */ +typedef struct GroupResultPath +{ + Path path; + List *quals; +} GroupResultPath; + +/* + * MaterialPath represents use of a Material plan node, i.e., caching of + * the output of its subpath. This is used when the subpath is expensive + * and needs to be scanned repeatedly, or when we need mark/restore ability + * and the subpath doesn't have it. + */ +typedef struct MaterialPath +{ + Path path; + Path *subpath; +} MaterialPath; + +/* + * MemoizePath represents a Memoize plan node, i.e., a cache that caches + * tuples from parameterized paths to save the underlying node from having to + * be rescanned for parameter values which are already cached. + */ +typedef struct MemoizePath +{ + Path path; + Path *subpath; /* outerpath to cache tuples from */ + List *hash_operators; /* OIDs of hash equality ops for cache keys */ + List *param_exprs; /* expressions that are cache keys */ + bool singlerow; /* true if the cache entry is to be marked as + * complete after caching the first record. */ + bool binary_mode; /* true when cache key should be compared bit + * by bit, false when using hash equality ops */ + Cardinality calls; /* expected number of rescans */ + uint32 est_entries; /* The maximum number of entries that the + * planner expects will fit in the cache, or 0 + * if unknown */ +} MemoizePath; + +/* + * UniquePath represents elimination of distinct rows from the output of + * its subpath. + * + * This can represent significantly different plans: either hash-based or + * sort-based implementation, or a no-op if the input path can be proven + * distinct already. The decision is sufficiently localized that it's not + * worth having separate Path node types. (Note: in the no-op case, we could + * eliminate the UniquePath node entirely and just return the subpath; but + * it's convenient to have a UniquePath in the path tree to signal upper-level + * routines that the input is known distinct.) + */ +typedef enum UniquePathMethod +{ + UNIQUE_PATH_NOOP, /* input is known unique already */ + UNIQUE_PATH_HASH, /* use hashing */ + UNIQUE_PATH_SORT /* use sorting */ +} UniquePathMethod; + +typedef struct UniquePath +{ + Path path; + Path *subpath; + UniquePathMethod umethod; + List *in_operators; /* equality operators of the IN clause */ + List *uniq_exprs; /* expressions to be made unique */ +} UniquePath; + +/* + * GatherPath runs several copies of a plan in parallel and collects the + * results. The parallel leader may also execute the plan, unless the + * single_copy flag is set. + */ +typedef struct GatherPath +{ + Path path; + Path *subpath; /* path for each worker */ + bool single_copy; /* don't execute path more than once */ + int num_workers; /* number of workers sought to help */ +} GatherPath; + +/* + * GatherMergePath runs several copies of a plan in parallel and collects + * the results, preserving their common sort order. + */ +typedef struct GatherMergePath +{ + Path path; + Path *subpath; /* path for each worker */ + int num_workers; /* number of workers sought to help */ +} GatherMergePath; + + +/* + * All join-type paths share these fields. + */ + +typedef struct JoinPath +{ + pg_node_attr(abstract) + + Path path; + + JoinType jointype; + + bool inner_unique; /* each outer tuple provably matches no more + * than one inner tuple */ + + Path *outerjoinpath; /* path for the outer side of the join */ + Path *innerjoinpath; /* path for the inner side of the join */ + + List *joinrestrictinfo; /* RestrictInfos to apply to join */ + + /* + * See the notes for RelOptInfo and ParamPathInfo to understand why + * joinrestrictinfo is needed in JoinPath, and can't be merged into the + * parent RelOptInfo. + */ +} JoinPath; + +/* + * A nested-loop path needs no special fields. + */ + +typedef struct NestPath +{ + JoinPath jpath; +} NestPath; + +/* + * A mergejoin path has these fields. + * + * Unlike other path types, a MergePath node doesn't represent just a single + * run-time plan node: it can represent up to four. Aside from the MergeJoin + * node itself, there can be a Sort node for the outer input, a Sort node + * for the inner input, and/or a Material node for the inner input. We could + * represent these nodes by separate path nodes, but considering how many + * different merge paths are investigated during a complex join problem, + * it seems better to avoid unnecessary palloc overhead. + * + * path_mergeclauses lists the clauses (in the form of RestrictInfos) + * that will be used in the merge. + * + * Note that the mergeclauses are a subset of the parent relation's + * restriction-clause list. Any join clauses that are not mergejoinable + * appear only in the parent's restrict list, and must be checked by a + * qpqual at execution time. + * + * outersortkeys (resp. innersortkeys) is NIL if the outer path + * (resp. inner path) is already ordered appropriately for the + * mergejoin. If it is not NIL then it is a PathKeys list describing + * the ordering that must be created by an explicit Sort node. + * + * skip_mark_restore is true if the executor need not do mark/restore calls. + * Mark/restore overhead is usually required, but can be skipped if we know + * that the executor need find only one match per outer tuple, and that the + * mergeclauses are sufficient to identify a match. In such cases the + * executor can immediately advance the outer relation after processing a + * match, and therefore it need never back up the inner relation. + * + * materialize_inner is true if a Material node should be placed atop the + * inner input. This may appear with or without an inner Sort step. + */ + +typedef struct MergePath +{ + JoinPath jpath; + List *path_mergeclauses; /* join clauses to be used for merge */ + List *outersortkeys; /* keys for explicit sort, if any */ + List *innersortkeys; /* keys for explicit sort, if any */ + bool skip_mark_restore; /* can executor skip mark/restore? */ + bool materialize_inner; /* add Materialize to inner? */ +} MergePath; + +/* + * A hashjoin path has these fields. + * + * The remarks above for mergeclauses apply for hashclauses as well. + * + * Hashjoin does not care what order its inputs appear in, so we have + * no need for sortkeys. + */ + +typedef struct HashPath +{ + JoinPath jpath; + List *path_hashclauses; /* join clauses used for hashing */ + int num_batches; /* number of batches expected */ + Cardinality inner_rows_total; /* total inner rows expected */ +} HashPath; + +/* + * ProjectionPath represents a projection (that is, targetlist computation) + * + * Nominally, this path node represents using a Result plan node to do a + * projection step. However, if the input plan node supports projection, + * we can just modify its output targetlist to do the required calculations + * directly, and not need a Result. In some places in the planner we can just + * jam the desired PathTarget into the input path node (and adjust its cost + * accordingly), so we don't need a ProjectionPath. But in other places + * it's necessary to not modify the input path node, so we need a separate + * ProjectionPath node, which is marked dummy to indicate that we intend to + * assign the work to the input plan node. The estimated cost for the + * ProjectionPath node will account for whether a Result will be used or not. + */ +typedef struct ProjectionPath +{ + Path path; + Path *subpath; /* path representing input source */ + bool dummypp; /* true if no separate Result is needed */ +} ProjectionPath; + +/* + * ProjectSetPath represents evaluation of a targetlist that includes + * set-returning function(s), which will need to be implemented by a + * ProjectSet plan node. + */ +typedef struct ProjectSetPath +{ + Path path; + Path *subpath; /* path representing input source */ +} ProjectSetPath; + +/* + * SortPath represents an explicit sort step + * + * The sort keys are, by definition, the same as path.pathkeys. + * + * Note: the Sort plan node cannot project, so path.pathtarget must be the + * same as the input's pathtarget. + */ +typedef struct SortPath +{ + Path path; + Path *subpath; /* path representing input source */ +} SortPath; + +/* + * IncrementalSortPath represents an incremental sort step + * + * This is like a regular sort, except some leading key columns are assumed + * to be ordered already. + */ +typedef struct IncrementalSortPath +{ + SortPath spath; + int nPresortedCols; /* number of presorted columns */ +} IncrementalSortPath; + +/* + * GroupPath represents grouping (of presorted input) + * + * groupClause represents the columns to be grouped on; the input path + * must be at least that well sorted. + * + * We can also apply a qual to the grouped rows (equivalent of HAVING) + */ +typedef struct GroupPath +{ + Path path; + Path *subpath; /* path representing input source */ + List *groupClause; /* a list of SortGroupClause's */ + List *qual; /* quals (HAVING quals), if any */ +} GroupPath; + +/* + * UpperUniquePath represents adjacent-duplicate removal (in presorted input) + * + * The columns to be compared are the first numkeys columns of the path's + * pathkeys. The input is presumed already sorted that way. + */ +typedef struct UpperUniquePath +{ + Path path; + Path *subpath; /* path representing input source */ + int numkeys; /* number of pathkey columns to compare */ +} UpperUniquePath; + +/* + * AggPath represents generic computation of aggregate functions + * + * This may involve plain grouping (but not grouping sets), using either + * sorted or hashed grouping; for the AGG_SORTED case, the input must be + * appropriately presorted. + */ +typedef struct AggPath +{ + Path path; + Path *subpath; /* path representing input source */ + AggStrategy aggstrategy; /* basic strategy, see nodes.h */ + AggSplit aggsplit; /* agg-splitting mode, see nodes.h */ + Cardinality numGroups; /* estimated number of groups in input */ + uint64 transitionSpace; /* for pass-by-ref transition data */ + List *groupClause; /* a list of SortGroupClause's */ + List *qual; /* quals (HAVING quals), if any */ +} AggPath; + +/* + * Various annotations used for grouping sets in the planner. + */ + +typedef struct GroupingSetData +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + List *set; /* grouping set as list of sortgrouprefs */ + Cardinality numGroups; /* est. number of result groups */ +} GroupingSetData; + +typedef struct RollupData +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + List *groupClause; /* applicable subset of parse->groupClause */ + List *gsets; /* lists of integer indexes into groupClause */ + List *gsets_data; /* list of GroupingSetData */ + Cardinality numGroups; /* est. number of result groups */ + bool hashable; /* can be hashed */ + bool is_hashed; /* to be implemented as a hashagg */ +} RollupData; + +/* + * GroupingSetsPath represents a GROUPING SETS aggregation + */ + +typedef struct GroupingSetsPath +{ + Path path; + Path *subpath; /* path representing input source */ + AggStrategy aggstrategy; /* basic strategy */ + List *rollups; /* list of RollupData */ + List *qual; /* quals (HAVING quals), if any */ + uint64 transitionSpace; /* for pass-by-ref transition data */ +} GroupingSetsPath; + +/* + * MinMaxAggPath represents computation of MIN/MAX aggregates from indexes + */ +typedef struct MinMaxAggPath +{ + Path path; + List *mmaggregates; /* list of MinMaxAggInfo */ + List *quals; /* HAVING quals, if any */ +} MinMaxAggPath; + +/* + * WindowAggPath represents generic computation of window functions + */ +typedef struct WindowAggPath +{ + Path path; + Path *subpath; /* path representing input source */ + WindowClause *winclause; /* WindowClause we'll be using */ + List *qual; /* lower-level WindowAgg runconditions */ + bool topwindow; /* false for all apart from the WindowAgg + * that's closest to the root of the plan */ +} WindowAggPath; + +/* + * SetOpPath represents a set-operation, that is INTERSECT or EXCEPT + */ +typedef struct SetOpPath +{ + Path path; + Path *subpath; /* path representing input source */ + SetOpCmd cmd; /* what to do, see nodes.h */ + SetOpStrategy strategy; /* how to do it, see nodes.h */ + List *distinctList; /* SortGroupClauses identifying target cols */ + AttrNumber flagColIdx; /* where is the flag column, if any */ + int firstFlag; /* flag value for first input relation */ + Cardinality numGroups; /* estimated number of groups in input */ +} SetOpPath; + +/* + * RecursiveUnionPath represents a recursive UNION node + */ +typedef struct RecursiveUnionPath +{ + Path path; + Path *leftpath; /* paths representing input sources */ + Path *rightpath; + List *distinctList; /* SortGroupClauses identifying target cols */ + int wtParam; /* ID of Param representing work table */ + Cardinality numGroups; /* estimated number of groups in input */ +} RecursiveUnionPath; + +/* + * LockRowsPath represents acquiring row locks for SELECT FOR UPDATE/SHARE + */ +typedef struct LockRowsPath +{ + Path path; + Path *subpath; /* path representing input source */ + List *rowMarks; /* a list of PlanRowMark's */ + int epqParam; /* ID of Param for EvalPlanQual re-eval */ +} LockRowsPath; + +/* + * ModifyTablePath represents performing INSERT/UPDATE/DELETE/MERGE + * + * We represent most things that will be in the ModifyTable plan node + * literally, except we have a child Path not Plan. But analysis of the + * OnConflictExpr is deferred to createplan.c, as is collection of FDW data. + */ +typedef struct ModifyTablePath +{ + Path path; + Path *subpath; /* Path producing source data */ + CmdType operation; /* INSERT, UPDATE, DELETE, or MERGE */ + bool canSetTag; /* do we set the command tag/es_processed? */ + Index nominalRelation; /* Parent RT index for use of EXPLAIN */ + Index rootRelation; /* Root RT index, if partitioned/inherited */ + bool partColsUpdated; /* some part key in hierarchy updated? */ + List *resultRelations; /* integer list of RT indexes */ + List *updateColnosLists; /* per-target-table update_colnos lists */ + List *withCheckOptionLists; /* per-target-table WCO lists */ + List *returningLists; /* per-target-table RETURNING tlists */ + List *rowMarks; /* PlanRowMarks (non-locking only) */ + OnConflictExpr *onconflict; /* ON CONFLICT clause, or NULL */ + int epqParam; /* ID of Param for EvalPlanQual re-eval */ + List *mergeActionLists; /* per-target-table lists of actions for + * MERGE */ +} ModifyTablePath; + +/* + * LimitPath represents applying LIMIT/OFFSET restrictions + */ +typedef struct LimitPath +{ + Path path; + Path *subpath; /* path representing input source */ + Node *limitOffset; /* OFFSET parameter, or NULL if none */ + Node *limitCount; /* COUNT parameter, or NULL if none */ + LimitOption limitOption; /* FETCH FIRST with ties or exact number */ +} LimitPath; + + +/* + * Restriction clause info. + * + * We create one of these for each AND sub-clause of a restriction condition + * (WHERE or JOIN/ON clause). Since the restriction clauses are logically + * ANDed, we can use any one of them or any subset of them to filter out + * tuples, without having to evaluate the rest. The RestrictInfo node itself + * stores data used by the optimizer while choosing the best query plan. + * + * If a restriction clause references a single base relation, it will appear + * in the baserestrictinfo list of the RelOptInfo for that base rel. + * + * If a restriction clause references more than one base+OJ relation, it will + * appear in the joininfo list of every RelOptInfo that describes a strict + * subset of the relations mentioned in the clause. The joininfo lists are + * used to drive join tree building by selecting plausible join candidates. + * The clause cannot actually be applied until we have built a join rel + * containing all the relations it references, however. + * + * When we construct a join rel that includes all the relations referenced + * in a multi-relation restriction clause, we place that clause into the + * joinrestrictinfo lists of paths for the join rel, if neither left nor + * right sub-path includes all relations referenced in the clause. The clause + * will be applied at that join level, and will not propagate any further up + * the join tree. (Note: the "predicate migration" code was once intended to + * push restriction clauses up and down the plan tree based on evaluation + * costs, but it's dead code and is unlikely to be resurrected in the + * foreseeable future.) + * + * Note that in the presence of more than two rels, a multi-rel restriction + * might reach different heights in the join tree depending on the join + * sequence we use. So, these clauses cannot be associated directly with + * the join RelOptInfo, but must be kept track of on a per-join-path basis. + * + * RestrictInfos that represent equivalence conditions (i.e., mergejoinable + * equalities that are not outerjoin-delayed) are handled a bit differently. + * Initially we attach them to the EquivalenceClasses that are derived from + * them. When we construct a scan or join path, we look through all the + * EquivalenceClasses and generate derived RestrictInfos representing the + * minimal set of conditions that need to be checked for this particular scan + * or join to enforce that all members of each EquivalenceClass are in fact + * equal in all rows emitted by the scan or join. + * + * The clause_relids field lists the base plus outer-join RT indexes that + * actually appear in the clause. required_relids lists the minimum set of + * relids needed to evaluate the clause; while this is often equal to + * clause_relids, it can be more. We will add relids to required_relids when + * we need to force an outer join ON clause to be evaluated exactly at the + * level of the outer join, which is true except when it is a "degenerate" + * condition that references only Vars from the nullable side of the join. + * + * RestrictInfo nodes contain a flag to indicate whether a qual has been + * pushed down to a lower level than its original syntactic placement in the + * join tree would suggest. If an outer join prevents us from pushing a qual + * down to its "natural" semantic level (the level associated with just the + * base rels used in the qual) then we mark the qual with a "required_relids" + * value including more than just the base rels it actually uses. By + * pretending that the qual references all the rels required to form the outer + * join, we prevent it from being evaluated below the outer join's joinrel. + * When we do form the outer join's joinrel, we still need to distinguish + * those quals that are actually in that join's JOIN/ON condition from those + * that appeared elsewhere in the tree and were pushed down to the join rel + * because they used no other rels. That's what the is_pushed_down flag is + * for; it tells us that a qual is not an OUTER JOIN qual for the set of base + * rels listed in required_relids. A clause that originally came from WHERE + * or an INNER JOIN condition will *always* have its is_pushed_down flag set. + * It's possible for an OUTER JOIN clause to be marked is_pushed_down too, + * if we decide that it can be pushed down into the nullable side of the join. + * In that case it acts as a plain filter qual for wherever it gets evaluated. + * (In short, is_pushed_down is only false for non-degenerate outer join + * conditions. Possibly we should rename it to reflect that meaning? But + * see also the comments for RINFO_IS_PUSHED_DOWN, below.) + * + * There is also an incompatible_relids field, which is a set of outer-join + * relids above which we cannot evaluate the clause (because they might null + * Vars it uses that should not be nulled yet). In principle this could be + * filled in any RestrictInfo as the set of OJ relids that appear above the + * clause and null Vars that it uses. In practice we only bother to populate + * it for "clone" clauses, as it's currently only needed to prevent multiple + * clones of the same clause from being accepted for evaluation at the same + * join level. + * + * There is also an outer_relids field, which is NULL except for outer join + * clauses; for those, it is the set of relids on the outer side of the + * clause's outer join. (These are rels that the clause cannot be applied to + * in parameterized scans, since pushing it into the join's outer side would + * lead to wrong answers.) + * + * To handle security-barrier conditions efficiently, we mark RestrictInfo + * nodes with a security_level field, in which higher values identify clauses + * coming from less-trusted sources. The exact semantics are that a clause + * cannot be evaluated before another clause with a lower security_level value + * unless the first clause is leakproof. As with outer-join clauses, this + * creates a reason for clauses to sometimes need to be evaluated higher in + * the join tree than their contents would suggest; and even at a single plan + * node, this rule constrains the order of application of clauses. + * + * In general, the referenced clause might be arbitrarily complex. The + * kinds of clauses we can handle as indexscan quals, mergejoin clauses, + * or hashjoin clauses are limited (e.g., no volatile functions). The code + * for each kind of path is responsible for identifying the restrict clauses + * it can use and ignoring the rest. Clauses not implemented by an indexscan, + * mergejoin, or hashjoin will be placed in the plan qual or joinqual field + * of the finished Plan node, where they will be enforced by general-purpose + * qual-expression-evaluation code. (But we are still entitled to count + * their selectivity when estimating the result tuple count, if we + * can guess what it is...) + * + * When the referenced clause is an OR clause, we generate a modified copy + * in which additional RestrictInfo nodes are inserted below the top-level + * OR/AND structure. This is a convenience for OR indexscan processing: + * indexquals taken from either the top level or an OR subclause will have + * associated RestrictInfo nodes. + * + * The can_join flag is set true if the clause looks potentially useful as + * a merge or hash join clause, that is if it is a binary opclause with + * nonoverlapping sets of relids referenced in the left and right sides. + * (Whether the operator is actually merge or hash joinable isn't checked, + * however.) + * + * The pseudoconstant flag is set true if the clause contains no Vars of + * the current query level and no volatile functions. Such a clause can be + * pulled out and used as a one-time qual in a gating Result node. We keep + * pseudoconstant clauses in the same lists as other RestrictInfos so that + * the regular clause-pushing machinery can assign them to the correct join + * level, but they need to be treated specially for cost and selectivity + * estimates. Note that a pseudoconstant clause can never be an indexqual + * or merge or hash join clause, so it's of no interest to large parts of + * the planner. + * + * When we generate multiple versions of a clause so as to have versions + * that will work after commuting some left joins per outer join identity 3, + * we mark the one with the fewest nullingrels bits with has_clone = true, + * and the rest with is_clone = true. This allows proper filtering of + * these redundant clauses, so that we apply only one version of them. + * + * When join clauses are generated from EquivalenceClasses, there may be + * several equally valid ways to enforce join equivalence, of which we need + * apply only one. We mark clauses of this kind by setting parent_ec to + * point to the generating EquivalenceClass. Multiple clauses with the same + * parent_ec in the same join are redundant. + * + * Most fields are ignored for equality, since they may not be set yet, and + * should be derivable from the clause anyway. + * + * parent_ec, left_ec, right_ec are not printed, lest it lead to infinite + * recursion in plan tree dump. + */ + +typedef struct RestrictInfo +{ + pg_node_attr(no_read, no_query_jumble) + + NodeTag type; + + /* the represented clause of WHERE or JOIN */ + Expr *clause; + + /* true if clause was pushed down in level */ + bool is_pushed_down; + + /* see comment above */ + bool can_join pg_node_attr(equal_ignore); + + /* see comment above */ + bool pseudoconstant pg_node_attr(equal_ignore); + + /* see comment above */ + bool has_clone; + bool is_clone; + + /* true if known to contain no leaked Vars */ + bool leakproof pg_node_attr(equal_ignore); + + /* indicates if clause contains any volatile functions */ + VolatileFunctionStatus has_volatile pg_node_attr(equal_ignore); + + /* see comment above */ + Index security_level; + + /* number of base rels in clause_relids */ + int num_base_rels pg_node_attr(equal_ignore); + + /* The relids (varnos+varnullingrels) actually referenced in the clause: */ + Relids clause_relids pg_node_attr(equal_ignore); + + /* The set of relids required to evaluate the clause: */ + Relids required_relids; + + /* Relids above which we cannot evaluate the clause (see comment above) */ + Relids incompatible_relids; + + /* If an outer-join clause, the outer-side relations, else NULL: */ + Relids outer_relids; + + /* + * Relids in the left/right side of the clause. These fields are set for + * any binary opclause. + */ + Relids left_relids pg_node_attr(equal_ignore); + Relids right_relids pg_node_attr(equal_ignore); + + /* + * Modified clause with RestrictInfos. This field is NULL unless clause + * is an OR clause. + */ + Expr *orclause pg_node_attr(equal_ignore); + + /*---------- + * Serial number of this RestrictInfo. This is unique within the current + * PlannerInfo context, with a few critical exceptions: + * 1. When we generate multiple clones of the same qual condition to + * cope with outer join identity 3, all the clones get the same serial + * number. This reflects that we only want to apply one of them in any + * given plan. + * 2. If we manufacture a commuted version of a qual to use as an index + * condition, it copies the original's rinfo_serial, since it is in + * practice the same condition. + * 3. RestrictInfos made for a child relation copy their parent's + * rinfo_serial. Likewise, when an EquivalenceClass makes a derived + * equality clause for a child relation, it copies the rinfo_serial of + * the matching equality clause for the parent. This allows detection + * of redundant pushed-down equality clauses. + *---------- + */ + int rinfo_serial; + + /* + * Generating EquivalenceClass. This field is NULL unless clause is + * potentially redundant. + */ + EquivalenceClass *parent_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore); + + /* + * cache space for cost and selectivity + */ + + /* eval cost of clause; -1 if not yet set */ + QualCost eval_cost pg_node_attr(equal_ignore); + + /* selectivity for "normal" (JOIN_INNER) semantics; -1 if not yet set */ + Selectivity norm_selec pg_node_attr(equal_ignore); + /* selectivity for outer join semantics; -1 if not yet set */ + Selectivity outer_selec pg_node_attr(equal_ignore); + + /* + * opfamilies containing clause operator; valid if clause is + * mergejoinable, else NIL + */ + List *mergeopfamilies pg_node_attr(equal_ignore); + + /* + * cache space for mergeclause processing; NULL if not yet set + */ + + /* EquivalenceClass containing lefthand */ + EquivalenceClass *left_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore); + /* EquivalenceClass containing righthand */ + EquivalenceClass *right_ec pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore); + /* EquivalenceMember for lefthand */ + EquivalenceMember *left_em pg_node_attr(copy_as_scalar, equal_ignore); + /* EquivalenceMember for righthand */ + EquivalenceMember *right_em pg_node_attr(copy_as_scalar, equal_ignore); + + /* + * List of MergeScanSelCache structs. Those aren't Nodes, so hard to + * copy; instead replace with NIL. That has the effect that copying will + * just reset the cache. Likewise, can't compare or print them. + */ + List *scansel_cache pg_node_attr(copy_as(NIL), equal_ignore, read_write_ignore); + + /* + * transient workspace for use while considering a specific join path; T = + * outer var on left, F = on right + */ + bool outer_is_left pg_node_attr(equal_ignore); + + /* + * copy of clause operator; valid if clause is hashjoinable, else + * InvalidOid + */ + Oid hashjoinoperator pg_node_attr(equal_ignore); + + /* + * cache space for hashclause processing; -1 if not yet set + */ + /* avg bucketsize of left side */ + Selectivity left_bucketsize pg_node_attr(equal_ignore); + /* avg bucketsize of right side */ + Selectivity right_bucketsize pg_node_attr(equal_ignore); + /* left side's most common val's freq */ + Selectivity left_mcvfreq pg_node_attr(equal_ignore); + /* right side's most common val's freq */ + Selectivity right_mcvfreq pg_node_attr(equal_ignore); + + /* hash equality operators used for memoize nodes, else InvalidOid */ + Oid left_hasheqoperator pg_node_attr(equal_ignore); + Oid right_hasheqoperator pg_node_attr(equal_ignore); +} RestrictInfo; + +/* + * This macro embodies the correct way to test whether a RestrictInfo is + * "pushed down" to a given outer join, that is, should be treated as a filter + * clause rather than a join clause at that outer join. This is certainly so + * if is_pushed_down is true; but examining that is not sufficient anymore, + * because outer-join clauses will get pushed down to lower outer joins when + * we generate a path for the lower outer join that is parameterized by the + * LHS of the upper one. We can detect such a clause by noting that its + * required_relids exceed the scope of the join. + */ +#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids) \ + ((rinfo)->is_pushed_down || \ + !bms_is_subset((rinfo)->required_relids, joinrelids)) + +/* + * Since mergejoinscansel() is a relatively expensive function, and would + * otherwise be invoked many times while planning a large join tree, + * we go out of our way to cache its results. Each mergejoinable + * RestrictInfo carries a list of the specific sort orderings that have + * been considered for use with it, and the resulting selectivities. + */ +typedef struct MergeScanSelCache +{ + /* Ordering details (cache lookup key) */ + Oid opfamily; /* btree opfamily defining the ordering */ + Oid collation; /* collation for the ordering */ + int strategy; /* sort direction (ASC or DESC) */ + bool nulls_first; /* do NULLs come before normal values? */ + /* Results */ + Selectivity leftstartsel; /* first-join fraction for clause left side */ + Selectivity leftendsel; /* last-join fraction for clause left side */ + Selectivity rightstartsel; /* first-join fraction for clause right side */ + Selectivity rightendsel; /* last-join fraction for clause right side */ +} MergeScanSelCache; + +/* + * Placeholder node for an expression to be evaluated below the top level + * of a plan tree. This is used during planning to represent the contained + * expression. At the end of the planning process it is replaced by either + * the contained expression or a Var referring to a lower-level evaluation of + * the contained expression. Generally the evaluation occurs below an outer + * join, and Var references above the outer join might thereby yield NULL + * instead of the expression value. + * + * phrels and phlevelsup correspond to the varno/varlevelsup fields of a + * plain Var, except that phrels has to be a relid set since the evaluation + * level of a PlaceHolderVar might be a join rather than a base relation. + * Likewise, phnullingrels corresponds to varnullingrels. + * + * Although the planner treats this as an expression node type, it is not + * recognized by the parser or executor, so we declare it here rather than + * in primnodes.h. + * + * We intentionally do not compare phexpr. Two PlaceHolderVars with the + * same ID and levelsup should be considered equal even if the contained + * expressions have managed to mutate to different states. This will + * happen during final plan construction when there are nested PHVs, since + * the inner PHV will get replaced by a Param in some copies of the outer + * PHV. Another way in which it can happen is that initplan sublinks + * could get replaced by differently-numbered Params when sublink folding + * is done. (The end result of such a situation would be some + * unreferenced initplans, which is annoying but not really a problem.) + * On the same reasoning, there is no need to examine phrels. But we do + * need to compare phnullingrels, as that represents effects that are + * external to the original value of the PHV. + */ + +typedef struct PlaceHolderVar +{ + pg_node_attr(no_query_jumble) + + Expr xpr; + + /* the represented expression */ + Expr *phexpr pg_node_attr(equal_ignore); + + /* base+OJ relids syntactically within expr src */ + Relids phrels pg_node_attr(equal_ignore); + + /* RT indexes of outer joins that can null PHV's value */ + Relids phnullingrels; + + /* ID for PHV (unique within planner run) */ + Index phid; + + /* > 0 if PHV belongs to outer query */ + Index phlevelsup; +} PlaceHolderVar; + +/* + * "Special join" info. + * + * One-sided outer joins constrain the order of joining partially but not + * completely. We flatten such joins into the planner's top-level list of + * relations to join, but record information about each outer join in a + * SpecialJoinInfo struct. These structs are kept in the PlannerInfo node's + * join_info_list. + * + * Similarly, semijoins and antijoins created by flattening IN (subselect) + * and EXISTS(subselect) clauses create partial constraints on join order. + * These are likewise recorded in SpecialJoinInfo structs. + * + * We make SpecialJoinInfos for FULL JOINs even though there is no flexibility + * of planning for them, because this simplifies make_join_rel()'s API. + * + * min_lefthand and min_righthand are the sets of base+OJ relids that must be + * available on each side when performing the special join. + * It is not valid for either min_lefthand or min_righthand to be empty sets; + * if they were, this would break the logic that enforces join order. + * + * syn_lefthand and syn_righthand are the sets of base+OJ relids that are + * syntactically below this special join. (These are needed to help compute + * min_lefthand and min_righthand for higher joins.) + * + * jointype is never JOIN_RIGHT; a RIGHT JOIN is handled by switching + * the inputs to make it a LEFT JOIN. It's never JOIN_RIGHT_ANTI either. + * So the allowed values of jointype in a join_info_list member are only + * LEFT, FULL, SEMI, or ANTI. + * + * ojrelid is the RT index of the join RTE representing this outer join, + * if there is one. It is zero when jointype is INNER or SEMI, and can be + * zero for jointype ANTI (if the join was transformed from a SEMI join). + * One use for this field is that when constructing the output targetlist of a + * join relation that implements this OJ, we add ojrelid to the varnullingrels + * and phnullingrels fields of nullable (RHS) output columns, so that the + * output Vars and PlaceHolderVars correctly reflect the nulling that has + * potentially happened to them. + * + * commute_above_l is filled with the relids of syntactically-higher outer + * joins that have been found to commute with this one per outer join identity + * 3 (see optimizer/README), when this join is in the LHS of the upper join + * (so, this is the lower join in the first form of the identity). + * + * commute_above_r is filled with the relids of syntactically-higher outer + * joins that have been found to commute with this one per outer join identity + * 3, when this join is in the RHS of the upper join (so, this is the lower + * join in the second form of the identity). + * + * commute_below_l is filled with the relids of syntactically-lower outer + * joins that have been found to commute with this one per outer join identity + * 3 and are in the LHS of this join (so, this is the upper join in the first + * form of the identity). + * + * commute_below_r is filled with the relids of syntactically-lower outer + * joins that have been found to commute with this one per outer join identity + * 3 and are in the RHS of this join (so, this is the upper join in the second + * form of the identity). + * + * lhs_strict is true if the special join's condition cannot succeed when the + * LHS variables are all NULL (this means that an outer join can commute with + * upper-level outer joins even if it appears in their RHS). We don't bother + * to set lhs_strict for FULL JOINs, however. + * + * For a semijoin, we also extract the join operators and their RHS arguments + * and set semi_operators, semi_rhs_exprs, semi_can_btree, and semi_can_hash. + * This is done in support of possibly unique-ifying the RHS, so we don't + * bother unless at least one of semi_can_btree and semi_can_hash can be set + * true. (You might expect that this information would be computed during + * join planning; but it's helpful to have it available during planning of + * parameterized table scans, so we store it in the SpecialJoinInfo structs.) + * + * For purposes of join selectivity estimation, we create transient + * SpecialJoinInfo structures for regular inner joins; so it is possible + * to have jointype == JOIN_INNER in such a structure, even though this is + * not allowed within join_info_list. We also create transient + * SpecialJoinInfos with jointype == JOIN_INNER for outer joins, since for + * cost estimation purposes it is sometimes useful to know the join size under + * plain innerjoin semantics. Note that lhs_strict and the semi_xxx fields + * are not set meaningfully within such structs. + */ +#ifndef HAVE_SPECIALJOININFO_TYPEDEF +typedef struct SpecialJoinInfo SpecialJoinInfo; +#define HAVE_SPECIALJOININFO_TYPEDEF 1 +#endif + +struct SpecialJoinInfo +{ + pg_node_attr(no_read, no_query_jumble) + + NodeTag type; + Relids min_lefthand; /* base+OJ relids in minimum LHS for join */ + Relids min_righthand; /* base+OJ relids in minimum RHS for join */ + Relids syn_lefthand; /* base+OJ relids syntactically within LHS */ + Relids syn_righthand; /* base+OJ relids syntactically within RHS */ + JoinType jointype; /* always INNER, LEFT, FULL, SEMI, or ANTI */ + Index ojrelid; /* outer join's RT index; 0 if none */ + Relids commute_above_l; /* commuting OJs above this one, if LHS */ + Relids commute_above_r; /* commuting OJs above this one, if RHS */ + Relids commute_below_l; /* commuting OJs in this one's LHS */ + Relids commute_below_r; /* commuting OJs in this one's RHS */ + bool lhs_strict; /* joinclause is strict for some LHS rel */ + /* Remaining fields are set only for JOIN_SEMI jointype: */ + bool semi_can_btree; /* true if semi_operators are all btree */ + bool semi_can_hash; /* true if semi_operators are all hash */ + List *semi_operators; /* OIDs of equality join operators */ + List *semi_rhs_exprs; /* righthand-side expressions of these ops */ +}; + +/* + * Transient outer-join clause info. + * + * We set aside every outer join ON clause that looks mergejoinable, + * and process it specially at the end of qual distribution. + */ +typedef struct OuterJoinClauseInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + RestrictInfo *rinfo; /* a mergejoinable outer-join clause */ + SpecialJoinInfo *sjinfo; /* the outer join's SpecialJoinInfo */ +} OuterJoinClauseInfo; + +/* + * Append-relation info. + * + * When we expand an inheritable table or a UNION-ALL subselect into an + * "append relation" (essentially, a list of child RTEs), we build an + * AppendRelInfo for each child RTE. The list of AppendRelInfos indicates + * which child RTEs must be included when expanding the parent, and each node + * carries information needed to translate between columns of the parent and + * columns of the child. + * + * These structs are kept in the PlannerInfo node's append_rel_list, with + * append_rel_array[] providing a convenient lookup method for the struct + * associated with a particular child relid (there can be only one, though + * parent rels may have many entries in append_rel_list). + * + * Note: after completion of the planner prep phase, any given RTE is an + * append parent having entries in append_rel_list if and only if its + * "inh" flag is set. We clear "inh" for plain tables that turn out not + * to have inheritance children, and (in an abuse of the original meaning + * of the flag) we set "inh" for subquery RTEs that turn out to be + * flattenable UNION ALL queries. This lets us avoid useless searches + * of append_rel_list. + * + * Note: the data structure assumes that append-rel members are single + * baserels. This is OK for inheritance, but it prevents us from pulling + * up a UNION ALL member subquery if it contains a join. While that could + * be fixed with a more complex data structure, at present there's not much + * point because no improvement in the plan could result. + */ + +typedef struct AppendRelInfo +{ + pg_node_attr(no_query_jumble) + + NodeTag type; + + /* + * These fields uniquely identify this append relationship. There can be + * (in fact, always should be) multiple AppendRelInfos for the same + * parent_relid, but never more than one per child_relid, since a given + * RTE cannot be a child of more than one append parent. + */ + Index parent_relid; /* RT index of append parent rel */ + Index child_relid; /* RT index of append child rel */ + + /* + * For an inheritance appendrel, the parent and child are both regular + * relations, and we store their rowtype OIDs here for use in translating + * whole-row Vars. For a UNION-ALL appendrel, the parent and child are + * both subqueries with no named rowtype, and we store InvalidOid here. + */ + Oid parent_reltype; /* OID of parent's composite type */ + Oid child_reltype; /* OID of child's composite type */ + + /* + * The N'th element of this list is a Var or expression representing the + * child column corresponding to the N'th column of the parent. This is + * used to translate Vars referencing the parent rel into references to + * the child. A list element is NULL if it corresponds to a dropped + * column of the parent (this is only possible for inheritance cases, not + * UNION ALL). The list elements are always simple Vars for inheritance + * cases, but can be arbitrary expressions in UNION ALL cases. + * + * Notice we only store entries for user columns (attno > 0). Whole-row + * Vars are special-cased, and system columns (attno < 0) need no special + * translation since their attnos are the same for all tables. + * + * Caution: the Vars have varlevelsup = 0. Be careful to adjust as needed + * when copying into a subquery. + */ + List *translated_vars; /* Expressions in the child's Vars */ + + /* + * This array simplifies translations in the reverse direction, from + * child's column numbers to parent's. The entry at [ccolno - 1] is the + * 1-based parent column number for child column ccolno, or zero if that + * child column is dropped or doesn't exist in the parent. + */ + int num_child_cols; /* length of array */ + AttrNumber *parent_colnos pg_node_attr(array_size(num_child_cols)); + + /* + * We store the parent table's OID here for inheritance, or InvalidOid for + * UNION ALL. This is only needed to help in generating error messages if + * an attempt is made to reference a dropped parent column. + */ + Oid parent_reloid; /* OID of parent relation */ +} AppendRelInfo; + +/* + * Information about a row-identity "resjunk" column in UPDATE/DELETE/MERGE. + * + * In partitioned UPDATE/DELETE/MERGE it's important for child partitions to + * share row-identity columns whenever possible, so as not to chew up too many + * targetlist columns. We use these structs to track which identity columns + * have been requested. In the finished plan, each of these will give rise + * to one resjunk entry in the targetlist of the ModifyTable's subplan node. + * + * All the Vars stored in RowIdentityVarInfos must have varno ROWID_VAR, for + * convenience of detecting duplicate requests. We'll replace that, in the + * final plan, with the varno of the generating rel. + * + * Outside this list, a Var with varno ROWID_VAR and varattno k is a reference + * to the k-th element of the row_identity_vars list (k counting from 1). + * We add such a reference to root->processed_tlist when creating the entry, + * and it propagates into the plan tree from there. + */ +typedef struct RowIdentityVarInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + Var *rowidvar; /* Var to be evaluated (but varno=ROWID_VAR) */ + int32 rowidwidth; /* estimated average width */ + char *rowidname; /* name of the resjunk column */ + Relids rowidrels; /* RTE indexes of target rels using this */ +} RowIdentityVarInfo; + +/* + * For each distinct placeholder expression generated during planning, we + * store a PlaceHolderInfo node in the PlannerInfo node's placeholder_list. + * This stores info that is needed centrally rather than in each copy of the + * PlaceHolderVar. The phid fields identify which PlaceHolderInfo goes with + * each PlaceHolderVar. Note that phid is unique throughout a planner run, + * not just within a query level --- this is so that we need not reassign ID's + * when pulling a subquery into its parent. + * + * The idea is to evaluate the expression at (only) the ph_eval_at join level, + * then allow it to bubble up like a Var until the ph_needed join level. + * ph_needed has the same definition as attr_needed for a regular Var. + * + * The PlaceHolderVar's expression might contain LATERAL references to vars + * coming from outside its syntactic scope. If so, those rels are *not* + * included in ph_eval_at, but they are recorded in ph_lateral. + * + * Notice that when ph_eval_at is a join rather than a single baserel, the + * PlaceHolderInfo may create constraints on join order: the ph_eval_at join + * has to be formed below any outer joins that should null the PlaceHolderVar. + * + * We create a PlaceHolderInfo only after determining that the PlaceHolderVar + * is actually referenced in the plan tree, so that unreferenced placeholders + * don't result in unnecessary constraints on join order. + */ + +typedef struct PlaceHolderInfo +{ + pg_node_attr(no_read, no_query_jumble) + + NodeTag type; + + /* ID for PH (unique within planner run) */ + Index phid; + + /* + * copy of PlaceHolderVar tree (should be redundant for comparison, could + * be ignored) + */ + PlaceHolderVar *ph_var; + + /* lowest level we can evaluate value at */ + Relids ph_eval_at; + + /* relids of contained lateral refs, if any */ + Relids ph_lateral; + + /* highest level the value is needed at */ + Relids ph_needed; + + /* estimated attribute width */ + int32 ph_width; +} PlaceHolderInfo; + +/* + * This struct describes one potentially index-optimizable MIN/MAX aggregate + * function. MinMaxAggPath contains a list of these, and if we accept that + * path, the list is stored into root->minmax_aggs for use during setrefs.c. + */ +typedef struct MinMaxAggInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* pg_proc Oid of the aggregate */ + Oid aggfnoid; + + /* Oid of its sort operator */ + Oid aggsortop; + + /* expression we are aggregating on */ + Expr *target; + + /* + * modified "root" for planning the subquery; not printed, too large, not + * interesting enough + */ + PlannerInfo *subroot pg_node_attr(read_write_ignore); + + /* access path for subquery */ + Path *path; + + /* estimated cost to fetch first row */ + Cost pathcost; + + /* param for subplan's output */ + Param *param; +} MinMaxAggInfo; + +/* + * At runtime, PARAM_EXEC slots are used to pass values around from one plan + * node to another. They can be used to pass values down into subqueries (for + * outer references in subqueries), or up out of subqueries (for the results + * of a subplan), or from a NestLoop plan node into its inner relation (when + * the inner scan is parameterized with values from the outer relation). + * The planner is responsible for assigning nonconflicting PARAM_EXEC IDs to + * the PARAM_EXEC Params it generates. + * + * Outer references are managed via root->plan_params, which is a list of + * PlannerParamItems. While planning a subquery, each parent query level's + * plan_params contains the values required from it by the current subquery. + * During create_plan(), we use plan_params to track values that must be + * passed from outer to inner sides of NestLoop plan nodes. + * + * The item a PlannerParamItem represents can be one of three kinds: + * + * A Var: the slot represents a variable of this level that must be passed + * down because subqueries have outer references to it, or must be passed + * from a NestLoop node to its inner scan. The varlevelsup value in the Var + * will always be zero. + * + * A PlaceHolderVar: this works much like the Var case, except that the + * entry is a PlaceHolderVar node with a contained expression. The PHV + * will have phlevelsup = 0, and the contained expression is adjusted + * to match in level. + * + * An Aggref (with an expression tree representing its argument): the slot + * represents an aggregate expression that is an outer reference for some + * subquery. The Aggref itself has agglevelsup = 0, and its argument tree + * is adjusted to match in level. + * + * Note: we detect duplicate Var and PlaceHolderVar parameters and coalesce + * them into one slot, but we do not bother to do that for Aggrefs. + * The scope of duplicate-elimination only extends across the set of + * parameters passed from one query level into a single subquery, or for + * nestloop parameters across the set of nestloop parameters used in a single + * query level. So there is no possibility of a PARAM_EXEC slot being used + * for conflicting purposes. + * + * In addition, PARAM_EXEC slots are assigned for Params representing outputs + * from subplans (values that are setParam items for those subplans). These + * IDs need not be tracked via PlannerParamItems, since we do not need any + * duplicate-elimination nor later processing of the represented expressions. + * Instead, we just record the assignment of the slot number by appending to + * root->glob->paramExecTypes. + */ +typedef struct PlannerParamItem +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + Node *item; /* the Var, PlaceHolderVar, or Aggref */ + int paramId; /* its assigned PARAM_EXEC slot number */ +} PlannerParamItem; + +/* + * When making cost estimates for a SEMI/ANTI/inner_unique join, there are + * some correction factors that are needed in both nestloop and hash joins + * to account for the fact that the executor can stop scanning inner rows + * as soon as it finds a match to the current outer row. These numbers + * depend only on the selected outer and inner join relations, not on the + * particular paths used for them, so it's worthwhile to calculate them + * just once per relation pair not once per considered path. This struct + * is filled by compute_semi_anti_join_factors and must be passed along + * to the join cost estimation functions. + * + * outer_match_frac is the fraction of the outer tuples that are + * expected to have at least one match. + * match_count is the average number of matches expected for + * outer tuples that have at least one match. + */ +typedef struct SemiAntiJoinFactors +{ + Selectivity outer_match_frac; + Selectivity match_count; +} SemiAntiJoinFactors; + +/* + * Struct for extra information passed to subroutines of add_paths_to_joinrel + * + * restrictlist contains all of the RestrictInfo nodes for restriction + * clauses that apply to this join + * mergeclause_list is a list of RestrictInfo nodes for available + * mergejoin clauses in this join + * inner_unique is true if each outer tuple provably matches no more + * than one inner tuple + * sjinfo is extra info about special joins for selectivity estimation + * semifactors is as shown above (only valid for SEMI/ANTI/inner_unique joins) + * param_source_rels are OK targets for parameterization of result paths + */ +typedef struct JoinPathExtraData +{ + List *restrictlist; + List *mergeclause_list; + bool inner_unique; + SpecialJoinInfo *sjinfo; + SemiAntiJoinFactors semifactors; + Relids param_source_rels; +} JoinPathExtraData; + +/* + * Various flags indicating what kinds of grouping are possible. + * + * GROUPING_CAN_USE_SORT should be set if it's possible to perform + * sort-based implementations of grouping. When grouping sets are in use, + * this will be true if sorting is potentially usable for any of the grouping + * sets, even if it's not usable for all of them. + * + * GROUPING_CAN_USE_HASH should be set if it's possible to perform + * hash-based implementations of grouping. + * + * GROUPING_CAN_PARTIAL_AGG should be set if the aggregation is of a type + * for which we support partial aggregation (not, for example, grouping sets). + * It says nothing about parallel-safety or the availability of suitable paths. + */ +#define GROUPING_CAN_USE_SORT 0x0001 +#define GROUPING_CAN_USE_HASH 0x0002 +#define GROUPING_CAN_PARTIAL_AGG 0x0004 + +/* + * What kind of partitionwise aggregation is in use? + * + * PARTITIONWISE_AGGREGATE_NONE: Not used. + * + * PARTITIONWISE_AGGREGATE_FULL: Aggregate each partition separately, and + * append the results. + * + * PARTITIONWISE_AGGREGATE_PARTIAL: Partially aggregate each partition + * separately, append the results, and then finalize aggregation. + */ +typedef enum +{ + PARTITIONWISE_AGGREGATE_NONE, + PARTITIONWISE_AGGREGATE_FULL, + PARTITIONWISE_AGGREGATE_PARTIAL +} PartitionwiseAggregateType; + +/* + * Struct for extra information passed to subroutines of create_grouping_paths + * + * flags indicating what kinds of grouping are possible. + * partial_costs_set is true if the agg_partial_costs and agg_final_costs + * have been initialized. + * agg_partial_costs gives partial aggregation costs. + * agg_final_costs gives finalization costs. + * target_parallel_safe is true if target is parallel safe. + * havingQual gives list of quals to be applied after aggregation. + * targetList gives list of columns to be projected. + * patype is the type of partitionwise aggregation that is being performed. + */ +typedef struct +{ + /* Data which remains constant once set. */ + int flags; + bool partial_costs_set; + AggClauseCosts agg_partial_costs; + AggClauseCosts agg_final_costs; + + /* Data which may differ across partitions. */ + bool target_parallel_safe; + Node *havingQual; + List *targetList; + PartitionwiseAggregateType patype; +} GroupPathExtraData; + +/* + * Struct for extra information passed to subroutines of grouping_planner + * + * limit_needed is true if we actually need a Limit plan node. + * limit_tuples is an estimated bound on the number of output tuples, + * or -1 if no LIMIT or couldn't estimate. + * count_est and offset_est are the estimated values of the LIMIT and OFFSET + * expressions computed by preprocess_limit() (see comments for + * preprocess_limit() for more information). + */ +typedef struct +{ + bool limit_needed; + Cardinality limit_tuples; + int64 count_est; + int64 offset_est; +} FinalPathExtraData; + +/* + * For speed reasons, cost estimation for join paths is performed in two + * phases: the first phase tries to quickly derive a lower bound for the + * join cost, and then we check if that's sufficient to reject the path. + * If not, we come back for a more refined cost estimate. The first phase + * fills a JoinCostWorkspace struct with its preliminary cost estimates + * and possibly additional intermediate values. The second phase takes + * these values as inputs to avoid repeating work. + * + * (Ideally we'd declare this in cost.h, but it's also needed in pathnode.h, + * so seems best to put it here.) + */ +typedef struct JoinCostWorkspace +{ + /* Preliminary cost estimates --- must not be larger than final ones! */ + Cost startup_cost; /* cost expended before fetching any tuples */ + Cost total_cost; /* total cost (assuming all tuples fetched) */ + + /* Fields below here should be treated as private to costsize.c */ + Cost run_cost; /* non-startup cost components */ + + /* private for cost_nestloop code */ + Cost inner_run_cost; /* also used by cost_mergejoin code */ + Cost inner_rescan_run_cost; + + /* private for cost_mergejoin code */ + Cardinality outer_rows; + Cardinality inner_rows; + Cardinality outer_skip_rows; + Cardinality inner_skip_rows; + + /* private for cost_hashjoin code */ + int numbuckets; + int numbatches; + Cardinality inner_rows_total; +} JoinCostWorkspace; + +/* + * AggInfo holds information about an aggregate that needs to be computed. + * Multiple Aggrefs in a query can refer to the same AggInfo by having the + * same 'aggno' value, so that the aggregate is computed only once. + */ +typedef struct AggInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* + * List of Aggref exprs that this state value is for. + * + * There will always be at least one, but there can be multiple identical + * Aggref's sharing the same per-agg. + */ + List *aggrefs; + + /* Transition state number for this aggregate */ + int transno; + + /* + * "shareable" is false if this agg cannot share state values with other + * aggregates because the final function is read-write. + */ + bool shareable; + + /* Oid of the final function, or InvalidOid if none */ + Oid finalfn_oid; +} AggInfo; + +/* + * AggTransInfo holds information about transition state that is used by one + * or more aggregates in the query. Multiple aggregates can share the same + * transition state, if they have the same inputs and the same transition + * function. Aggrefs that share the same transition info have the same + * 'aggtransno' value. + */ +typedef struct AggTransInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* Inputs for this transition state */ + List *args; + Expr *aggfilter; + + /* Oid of the state transition function */ + Oid transfn_oid; + + /* Oid of the serialization function, or InvalidOid if none */ + Oid serialfn_oid; + + /* Oid of the deserialization function, or InvalidOid if none */ + Oid deserialfn_oid; + + /* Oid of the combine function, or InvalidOid if none */ + Oid combinefn_oid; + + /* Oid of state value's datatype */ + Oid aggtranstype; + + /* Additional data about transtype */ + int32 aggtranstypmod; + int transtypeLen; + bool transtypeByVal; + + /* Space-consumption estimate */ + int32 aggtransspace; + + /* Initial value from pg_aggregate entry */ + Datum initValue pg_node_attr(read_write_ignore); + bool initValueIsNull; +} AggTransInfo; + +#endif /* PATHNODES_H */ diff --git a/install/include/postgresql/server/nodes/pg_list.h b/install/include/postgresql/server/nodes/pg_list.h new file mode 100644 index 00000000000..529a382d284 --- /dev/null +++ b/install/include/postgresql/server/nodes/pg_list.h @@ -0,0 +1,635 @@ +/*------------------------------------------------------------------------- + * + * pg_list.h + * interface for PostgreSQL generic list package + * + * Once upon a time, parts of Postgres were written in Lisp and used real + * cons-cell lists for major data structures. When that code was rewritten + * in C, we initially had a faithful emulation of cons-cell lists, which + * unsurprisingly was a performance bottleneck. A couple of major rewrites + * later, these data structures are actually simple expansible arrays; + * but the "List" name and a lot of the notation survives. + * + * One important concession to the original implementation is that an empty + * list is always represented by a null pointer (preferentially written NIL). + * Non-empty lists have a header, which will not be relocated as long as the + * list remains non-empty, and an expansible data array. + * + * We support four types of lists: + * + * T_List: lists of pointers + * (in practice usually pointers to Nodes, but not always; + * declared as "void *" to minimize casting annoyances) + * T_IntList: lists of integers + * T_OidList: lists of Oids + * T_XidList: lists of TransactionIds + * (the XidList infrastructure is less complete than the other cases) + * + * (At the moment, ints, Oids, and XIDs are the same size, but they may not + * always be so; be careful to use the appropriate list type for your data.) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/pg_list.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LIST_H +#define PG_LIST_H + +#include "nodes/nodes.h" + + +typedef union ListCell +{ + void *ptr_value; + int int_value; + Oid oid_value; + TransactionId xid_value; +} ListCell; + +typedef struct List +{ + NodeTag type; /* T_List, T_IntList, T_OidList, or T_XidList */ + int length; /* number of elements currently present */ + int max_length; /* allocated length of elements[] */ + ListCell *elements; /* re-allocatable array of cells */ + /* We may allocate some cells along with the List header: */ + ListCell initial_elements[FLEXIBLE_ARRAY_MEMBER]; + /* If elements == initial_elements, it's not a separate allocation */ +} List; + +/* + * The *only* valid representation of an empty list is NIL; in other + * words, a non-NIL list is guaranteed to have length >= 1. + */ +#define NIL ((List *) NULL) + +/* + * State structs for various looping macros below. + */ +typedef struct ForEachState +{ + const List *l; /* list we're looping through */ + int i; /* current element index */ +} ForEachState; + +typedef struct ForBothState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + int i; /* common element index */ +} ForBothState; + +typedef struct ForBothCellState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + int i1; /* current element indexes */ + int i2; +} ForBothCellState; + +typedef struct ForThreeState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + const List *l3; + int i; /* common element index */ +} ForThreeState; + +typedef struct ForFourState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + const List *l3; + const List *l4; + int i; /* common element index */ +} ForFourState; + +typedef struct ForFiveState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + const List *l3; + const List *l4; + const List *l5; + int i; /* common element index */ +} ForFiveState; + +/* + * These routines are small enough, and used often enough, to justify being + * inline. + */ + +/* Fetch address of list's first cell; NULL if empty list */ +static inline ListCell * +list_head(const List *l) +{ + return l ? &l->elements[0] : NULL; +} + +/* Fetch address of list's last cell; NULL if empty list */ +static inline ListCell * +list_tail(const List *l) +{ + return l ? &l->elements[l->length - 1] : NULL; +} + +/* Fetch address of list's second cell, if it has one, else NULL */ +static inline ListCell * +list_second_cell(const List *l) +{ + if (l && l->length >= 2) + return &l->elements[1]; + else + return NULL; +} + +/* Fetch list's length */ +static inline int +list_length(const List *l) +{ + return l ? l->length : 0; +} + +/* + * Macros to access the data values within List cells. + * + * Note that with the exception of the "xxx_node" macros, these are + * lvalues and can be assigned to. + * + * NB: There is an unfortunate legacy from a previous incarnation of + * the List API: the macro lfirst() was used to mean "the data in this + * cons cell". To avoid changing every usage of lfirst(), that meaning + * has been kept. As a result, lfirst() takes a ListCell and returns + * the data it contains; to get the data in the first cell of a + * List, use linitial(). Worse, lsecond() is more closely related to + * linitial() than lfirst(): given a List, lsecond() returns the data + * in the second list cell. + */ +#define lfirst(lc) ((lc)->ptr_value) +#define lfirst_int(lc) ((lc)->int_value) +#define lfirst_oid(lc) ((lc)->oid_value) +#define lfirst_xid(lc) ((lc)->xid_value) +#define lfirst_node(type,lc) castNode(type, lfirst(lc)) + +#define linitial(l) lfirst(list_nth_cell(l, 0)) +#define linitial_int(l) lfirst_int(list_nth_cell(l, 0)) +#define linitial_oid(l) lfirst_oid(list_nth_cell(l, 0)) +#define linitial_node(type,l) castNode(type, linitial(l)) + +#define lsecond(l) lfirst(list_nth_cell(l, 1)) +#define lsecond_int(l) lfirst_int(list_nth_cell(l, 1)) +#define lsecond_oid(l) lfirst_oid(list_nth_cell(l, 1)) +#define lsecond_node(type,l) castNode(type, lsecond(l)) + +#define lthird(l) lfirst(list_nth_cell(l, 2)) +#define lthird_int(l) lfirst_int(list_nth_cell(l, 2)) +#define lthird_oid(l) lfirst_oid(list_nth_cell(l, 2)) +#define lthird_node(type,l) castNode(type, lthird(l)) + +#define lfourth(l) lfirst(list_nth_cell(l, 3)) +#define lfourth_int(l) lfirst_int(list_nth_cell(l, 3)) +#define lfourth_oid(l) lfirst_oid(list_nth_cell(l, 3)) +#define lfourth_node(type,l) castNode(type, lfourth(l)) + +#define llast(l) lfirst(list_last_cell(l)) +#define llast_int(l) lfirst_int(list_last_cell(l)) +#define llast_oid(l) lfirst_oid(list_last_cell(l)) +#define llast_xid(l) lfirst_xid(list_last_cell(l)) +#define llast_node(type,l) castNode(type, llast(l)) + +/* + * Convenience macros for building fixed-length lists + */ +#define list_make_ptr_cell(v) ((ListCell) {.ptr_value = (v)}) +#define list_make_int_cell(v) ((ListCell) {.int_value = (v)}) +#define list_make_oid_cell(v) ((ListCell) {.oid_value = (v)}) +#define list_make_xid_cell(v) ((ListCell) {.xid_value = (v)}) + +#define list_make1(x1) \ + list_make1_impl(T_List, list_make_ptr_cell(x1)) +#define list_make2(x1,x2) \ + list_make2_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2)) +#define list_make3(x1,x2,x3) \ + list_make3_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \ + list_make_ptr_cell(x3)) +#define list_make4(x1,x2,x3,x4) \ + list_make4_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \ + list_make_ptr_cell(x3), list_make_ptr_cell(x4)) +#define list_make5(x1,x2,x3,x4,x5) \ + list_make5_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \ + list_make_ptr_cell(x3), list_make_ptr_cell(x4), \ + list_make_ptr_cell(x5)) + +#define list_make1_int(x1) \ + list_make1_impl(T_IntList, list_make_int_cell(x1)) +#define list_make2_int(x1,x2) \ + list_make2_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2)) +#define list_make3_int(x1,x2,x3) \ + list_make3_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \ + list_make_int_cell(x3)) +#define list_make4_int(x1,x2,x3,x4) \ + list_make4_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \ + list_make_int_cell(x3), list_make_int_cell(x4)) +#define list_make5_int(x1,x2,x3,x4,x5) \ + list_make5_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \ + list_make_int_cell(x3), list_make_int_cell(x4), \ + list_make_int_cell(x5)) + +#define list_make1_oid(x1) \ + list_make1_impl(T_OidList, list_make_oid_cell(x1)) +#define list_make2_oid(x1,x2) \ + list_make2_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2)) +#define list_make3_oid(x1,x2,x3) \ + list_make3_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \ + list_make_oid_cell(x3)) +#define list_make4_oid(x1,x2,x3,x4) \ + list_make4_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \ + list_make_oid_cell(x3), list_make_oid_cell(x4)) +#define list_make5_oid(x1,x2,x3,x4,x5) \ + list_make5_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \ + list_make_oid_cell(x3), list_make_oid_cell(x4), \ + list_make_oid_cell(x5)) + +#define list_make1_xid(x1) \ + list_make1_impl(T_XidList, list_make_xid_cell(x1)) +#define list_make2_xid(x1,x2) \ + list_make2_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2)) +#define list_make3_xid(x1,x2,x3) \ + list_make3_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \ + list_make_xid_cell(x3)) +#define list_make4_xid(x1,x2,x3,x4) \ + list_make4_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \ + list_make_xid_cell(x3), list_make_xid_cell(x4)) +#define list_make5_xid(x1,x2,x3,x4,x5) \ + list_make5_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \ + list_make_xid_cell(x3), list_make_xid_cell(x4), \ + list_make_xid_cell(x5)) + +/* + * Locate the n'th cell (counting from 0) of the list. + * It is an assertion failure if there is no such cell. + */ +static inline ListCell * +list_nth_cell(const List *list, int n) +{ + Assert(list != NIL); + Assert(n >= 0 && n < list->length); + return &list->elements[n]; +} + +/* + * Return the last cell in a non-NIL List. + */ +static inline ListCell * +list_last_cell(const List *list) +{ + Assert(list != NIL); + return &list->elements[list->length - 1]; +} + +/* + * Return the pointer value contained in the n'th element of the + * specified list. (List elements begin at 0.) + */ +static inline void * +list_nth(const List *list, int n) +{ + Assert(IsA(list, List)); + return lfirst(list_nth_cell(list, n)); +} + +/* + * Return the integer value contained in the n'th element of the + * specified list. + */ +static inline int +list_nth_int(const List *list, int n) +{ + Assert(IsA(list, IntList)); + return lfirst_int(list_nth_cell(list, n)); +} + +/* + * Return the OID value contained in the n'th element of the specified + * list. + */ +static inline Oid +list_nth_oid(const List *list, int n) +{ + Assert(IsA(list, OidList)); + return lfirst_oid(list_nth_cell(list, n)); +} + +#define list_nth_node(type,list,n) castNode(type, list_nth(list, n)) + +/* + * Get the given ListCell's index (from 0) in the given List. + */ +static inline int +list_cell_number(const List *l, const ListCell *c) +{ + Assert(c >= &l->elements[0] && c < &l->elements[l->length]); + return c - l->elements; +} + +/* + * Get the address of the next cell after "c" within list "l", or NULL if none. + */ +static inline ListCell * +lnext(const List *l, const ListCell *c) +{ + Assert(c >= &l->elements[0] && c < &l->elements[l->length]); + c++; + if (c < &l->elements[l->length]) + return (ListCell *) c; + else + return NULL; +} + +/* + * foreach - + * a convenience macro for looping through a list + * + * "cell" must be the name of a "ListCell *" variable; it's made to point + * to each List element in turn. "cell" will be NULL after normal exit from + * the loop, but an early "break" will leave it pointing at the current + * List element. + * + * Beware of changing the List object while the loop is iterating. + * The current semantics are that we examine successive list indices in + * each iteration, so that insertion or deletion of list elements could + * cause elements to be re-visited or skipped unexpectedly. Previous + * implementations of foreach() behaved differently. However, it's safe + * to append elements to the List (or in general, insert them after the + * current element); such new elements are guaranteed to be visited. + * Also, the current element of the List can be deleted, if you use + * foreach_delete_current() to do so. BUT: either of these actions will + * invalidate the "cell" pointer for the remainder of the current iteration. + */ +#define foreach(cell, lst) \ + for (ForEachState cell##__state = {(lst), 0}; \ + (cell##__state.l != NIL && \ + cell##__state.i < cell##__state.l->length) ? \ + (cell = &cell##__state.l->elements[cell##__state.i], true) : \ + (cell = NULL, false); \ + cell##__state.i++) + +/* + * foreach_delete_current - + * delete the current list element from the List associated with a + * surrounding foreach() loop, returning the new List pointer. + * + * This is equivalent to list_delete_cell(), but it also adjusts the foreach + * loop's state so that no list elements will be missed. Do not delete + * elements from an active foreach loop's list in any other way! + */ +#define foreach_delete_current(lst, cell) \ + (cell##__state.i--, \ + (List *) (cell##__state.l = list_delete_cell(lst, cell))) + +/* + * foreach_current_index - + * get the zero-based list index of a surrounding foreach() loop's + * current element; pass the name of the "ListCell *" iterator variable. + * + * Beware of using this after foreach_delete_current(); the value will be + * out of sync for the rest of the current loop iteration. Anyway, since + * you just deleted the current element, the value is pretty meaningless. + */ +#define foreach_current_index(cell) (cell##__state.i) + +/* + * for_each_from - + * Like foreach(), but start from the N'th (zero-based) list element, + * not necessarily the first one. + * + * It's okay for N to exceed the list length, but not for it to be negative. + * + * The caveats for foreach() apply equally here. + */ +#define for_each_from(cell, lst, N) \ + for (ForEachState cell##__state = for_each_from_setup(lst, N); \ + (cell##__state.l != NIL && \ + cell##__state.i < cell##__state.l->length) ? \ + (cell = &cell##__state.l->elements[cell##__state.i], true) : \ + (cell = NULL, false); \ + cell##__state.i++) + +static inline ForEachState +for_each_from_setup(const List *lst, int N) +{ + ForEachState r = {lst, N}; + + Assert(N >= 0); + return r; +} + +/* + * for_each_cell - + * a convenience macro which loops through a list starting from a + * specified cell + * + * The caveats for foreach() apply equally here. + */ +#define for_each_cell(cell, lst, initcell) \ + for (ForEachState cell##__state = for_each_cell_setup(lst, initcell); \ + (cell##__state.l != NIL && \ + cell##__state.i < cell##__state.l->length) ? \ + (cell = &cell##__state.l->elements[cell##__state.i], true) : \ + (cell = NULL, false); \ + cell##__state.i++) + +static inline ForEachState +for_each_cell_setup(const List *lst, const ListCell *initcell) +{ + ForEachState r = {lst, + initcell ? list_cell_number(lst, initcell) : list_length(lst)}; + + return r; +} + +/* + * forboth - + * a convenience macro for advancing through two linked lists + * simultaneously. This macro loops through both lists at the same + * time, stopping when either list runs out of elements. Depending + * on the requirements of the call site, it may also be wise to + * assert that the lengths of the two lists are equal. (But, if they + * are not, some callers rely on the ending cell values being separately + * NULL or non-NULL as defined here; don't try to optimize that.) + * + * The caveats for foreach() apply equally here. + */ +#define forboth(cell1, list1, cell2, list2) \ + for (ForBothState cell1##__state = {(list1), (list2), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + (cell1 != NULL && cell2 != NULL); \ + cell1##__state.i++) + +#define multi_for_advance_cell(cell, state, l, i) \ + (cell = (state.l != NIL && state.i < state.l->length) ? \ + &state.l->elements[state.i] : NULL) + +/* + * for_both_cell - + * a convenience macro which loops through two lists starting from the + * specified cells of each. This macro loops through both lists at the same + * time, stopping when either list runs out of elements. Depending on the + * requirements of the call site, it may also be wise to assert that the + * lengths of the two lists are equal, and initcell1 and initcell2 are at + * the same position in the respective lists. + * + * The caveats for foreach() apply equally here. + */ +#define for_both_cell(cell1, list1, initcell1, cell2, list2, initcell2) \ + for (ForBothCellState cell1##__state = \ + for_both_cell_setup(list1, initcell1, list2, initcell2); \ + multi_for_advance_cell(cell1, cell1##__state, l1, i1), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i2), \ + (cell1 != NULL && cell2 != NULL); \ + cell1##__state.i1++, cell1##__state.i2++) + +static inline ForBothCellState +for_both_cell_setup(const List *list1, const ListCell *initcell1, + const List *list2, const ListCell *initcell2) +{ + ForBothCellState r = {list1, list2, + initcell1 ? list_cell_number(list1, initcell1) : list_length(list1), + initcell2 ? list_cell_number(list2, initcell2) : list_length(list2)}; + + return r; +} + +/* + * forthree - + * the same for three lists + */ +#define forthree(cell1, list1, cell2, list2, cell3, list3) \ + for (ForThreeState cell1##__state = {(list1), (list2), (list3), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + multi_for_advance_cell(cell3, cell1##__state, l3, i), \ + (cell1 != NULL && cell2 != NULL && cell3 != NULL); \ + cell1##__state.i++) + +/* + * forfour - + * the same for four lists + */ +#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4) \ + for (ForFourState cell1##__state = {(list1), (list2), (list3), (list4), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + multi_for_advance_cell(cell3, cell1##__state, l3, i), \ + multi_for_advance_cell(cell4, cell1##__state, l4, i), \ + (cell1 != NULL && cell2 != NULL && cell3 != NULL && cell4 != NULL); \ + cell1##__state.i++) + +/* + * forfive - + * the same for five lists + */ +#define forfive(cell1, list1, cell2, list2, cell3, list3, cell4, list4, cell5, list5) \ + for (ForFiveState cell1##__state = {(list1), (list2), (list3), (list4), (list5), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + multi_for_advance_cell(cell3, cell1##__state, l3, i), \ + multi_for_advance_cell(cell4, cell1##__state, l4, i), \ + multi_for_advance_cell(cell5, cell1##__state, l5, i), \ + (cell1 != NULL && cell2 != NULL && cell3 != NULL && \ + cell4 != NULL && cell5 != NULL); \ + cell1##__state.i++) + +/* Functions in src/backend/nodes/list.c */ + +extern List *list_make1_impl(NodeTag t, ListCell datum1); +extern List *list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2); +extern List *list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3); +extern List *list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3, ListCell datum4); +extern List *list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3, ListCell datum4, + ListCell datum5); + +extern pg_nodiscard List *lappend(List *list, void *datum); +extern pg_nodiscard List *lappend_int(List *list, int datum); +extern pg_nodiscard List *lappend_oid(List *list, Oid datum); +extern pg_nodiscard List *lappend_xid(List *list, TransactionId datum); + +extern pg_nodiscard List *list_insert_nth(List *list, int pos, void *datum); +extern pg_nodiscard List *list_insert_nth_int(List *list, int pos, int datum); +extern pg_nodiscard List *list_insert_nth_oid(List *list, int pos, Oid datum); + +extern pg_nodiscard List *lcons(void *datum, List *list); +extern pg_nodiscard List *lcons_int(int datum, List *list); +extern pg_nodiscard List *lcons_oid(Oid datum, List *list); + +extern pg_nodiscard List *list_concat(List *list1, const List *list2); +extern pg_nodiscard List *list_concat_copy(const List *list1, const List *list2); + +extern pg_nodiscard List *list_truncate(List *list, int new_size); + +extern bool list_member(const List *list, const void *datum); +extern bool list_member_ptr(const List *list, const void *datum); +extern bool list_member_int(const List *list, int datum); +extern bool list_member_oid(const List *list, Oid datum); +extern bool list_member_xid(const List *list, TransactionId datum); + +extern pg_nodiscard List *list_delete(List *list, void *datum); +extern pg_nodiscard List *list_delete_ptr(List *list, void *datum); +extern pg_nodiscard List *list_delete_int(List *list, int datum); +extern pg_nodiscard List *list_delete_oid(List *list, Oid datum); +extern pg_nodiscard List *list_delete_first(List *list); +extern pg_nodiscard List *list_delete_last(List *list); +extern pg_nodiscard List *list_delete_first_n(List *list, int n); +extern pg_nodiscard List *list_delete_nth_cell(List *list, int n); +extern pg_nodiscard List *list_delete_cell(List *list, ListCell *cell); + +extern List *list_union(const List *list1, const List *list2); +extern List *list_union_ptr(const List *list1, const List *list2); +extern List *list_union_int(const List *list1, const List *list2); +extern List *list_union_oid(const List *list1, const List *list2); + +extern List *list_intersection(const List *list1, const List *list2); +extern List *list_intersection_int(const List *list1, const List *list2); + +/* currently, there's no need for list_intersection_ptr etc */ + +extern List *list_difference(const List *list1, const List *list2); +extern List *list_difference_ptr(const List *list1, const List *list2); +extern List *list_difference_int(const List *list1, const List *list2); +extern List *list_difference_oid(const List *list1, const List *list2); + +extern pg_nodiscard List *list_append_unique(List *list, void *datum); +extern pg_nodiscard List *list_append_unique_ptr(List *list, void *datum); +extern pg_nodiscard List *list_append_unique_int(List *list, int datum); +extern pg_nodiscard List *list_append_unique_oid(List *list, Oid datum); + +extern pg_nodiscard List *list_concat_unique(List *list1, const List *list2); +extern pg_nodiscard List *list_concat_unique_ptr(List *list1, const List *list2); +extern pg_nodiscard List *list_concat_unique_int(List *list1, const List *list2); +extern pg_nodiscard List *list_concat_unique_oid(List *list1, const List *list2); + +extern void list_deduplicate_oid(List *list); + +extern void list_free(List *list); +extern void list_free_deep(List *list); + +extern pg_nodiscard List *list_copy(const List *oldlist); +extern pg_nodiscard List *list_copy_head(const List *oldlist, int len); +extern pg_nodiscard List *list_copy_tail(const List *oldlist, int nskip); +extern pg_nodiscard List *list_copy_deep(const List *oldlist); + +typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b); +extern void list_sort(List *list, list_sort_comparator cmp); + +extern int list_int_cmp(const ListCell *p1, const ListCell *p2); +extern int list_oid_cmp(const ListCell *p1, const ListCell *p2); + +#endif /* PG_LIST_H */ diff --git a/install/include/postgresql/server/nodes/plannodes.h b/install/include/postgresql/server/nodes/plannodes.h new file mode 100644 index 00000000000..d64fe6a328b --- /dev/null +++ b/install/include/postgresql/server/nodes/plannodes.h @@ -0,0 +1,1592 @@ +/*------------------------------------------------------------------------- + * + * plannodes.h + * definitions for query plan nodes + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/plannodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLANNODES_H +#define PLANNODES_H + +#include "access/sdir.h" +#include "access/stratnum.h" +#include "common/relpath.h" +#include "lib/stringinfo.h" +#include "nodes/bitmapset.h" +#include "nodes/lockoptions.h" +#include "nodes/parsenodes.h" +#include "nodes/primnodes.h" + + +/* ---------------------------------------------------------------- + * node definitions + * ---------------------------------------------------------------- + */ + +/* ---------------- + * PlannedStmt node + * + * The output of the planner is a Plan tree headed by a PlannedStmt node. + * PlannedStmt holds the "one time" information needed by the executor. + * + * For simplicity in APIs, we also wrap utility statements in PlannedStmt + * nodes; in such cases, commandType == CMD_UTILITY, the statement itself + * is in the utilityStmt field, and the rest of the struct is mostly dummy. + * (We do use canSetTag, stmt_location, stmt_len, and possibly queryId.) + * + * PlannedStmt, as well as all varieties of Plan, do not support equal(), + * not because it's not sensible but because we currently have no need. + * ---------------- + */ +typedef struct PlannedStmt +{ + pg_node_attr(no_equal, no_query_jumble) + + NodeTag type; + + CmdType commandType; /* select|insert|update|delete|merge|utility */ + + uint64 queryId; /* query identifier (copied from Query) */ + + bool hasReturning; /* is it insert|update|delete RETURNING? */ + + bool hasModifyingCTE; /* has insert|update|delete in WITH? */ + + bool canSetTag; /* do I set the command result tag? */ + + bool transientPlan; /* redo plan when TransactionXmin changes? */ + + bool dependsOnRole; /* is plan specific to current role? */ + + bool parallelModeNeeded; /* parallel mode required to execute? */ + + int jitFlags; /* which forms of JIT should be performed */ + + struct Plan *planTree; /* tree of Plan nodes */ + + List *rtable; /* list of RangeTblEntry nodes */ + + List *permInfos; /* list of RTEPermissionInfo nodes for rtable + * entries needing one */ + + /* rtable indexes of target relations for INSERT/UPDATE/DELETE/MERGE */ + List *resultRelations; /* integer list of RT indexes, or NIL */ + + List *appendRelations; /* list of AppendRelInfo nodes */ + + List *subplans; /* Plan trees for SubPlan expressions; note + * that some could be NULL */ + + Bitmapset *rewindPlanIDs; /* indices of subplans that require REWIND */ + + List *rowMarks; /* a list of PlanRowMark's */ + + List *relationOids; /* OIDs of relations the plan depends on */ + + List *invalItems; /* other dependencies, as PlanInvalItems */ + + List *paramExecTypes; /* type OIDs for PARAM_EXEC Params */ + + Node *utilityStmt; /* non-null if this is utility stmt */ + + /* statement location in source string (copied from Query) */ + int stmt_location; /* start location, or -1 if unknown */ + int stmt_len; /* length in bytes; 0 means "rest of string" */ +} PlannedStmt; + +/* macro for fetching the Plan associated with a SubPlan node */ +#define exec_subplan_get_plan(plannedstmt, subplan) \ + ((Plan *) list_nth((plannedstmt)->subplans, (subplan)->plan_id - 1)) + + +/* ---------------- + * Plan node + * + * All plan nodes "derive" from the Plan structure by having the + * Plan structure as the first field. This ensures that everything works + * when nodes are cast to Plan's. (node pointers are frequently cast to Plan* + * when passed around generically in the executor) + * + * We never actually instantiate any Plan nodes; this is just the common + * abstract superclass for all Plan-type nodes. + * ---------------- + */ +typedef struct Plan +{ + pg_node_attr(abstract, no_equal, no_query_jumble) + + NodeTag type; + + /* + * estimated execution costs for plan (see costsize.c for more info) + */ + Cost startup_cost; /* cost expended before fetching any tuples */ + Cost total_cost; /* total cost (assuming all tuples fetched) */ + + /* + * planner's estimate of result size of this plan step + */ + Cardinality plan_rows; /* number of rows plan is expected to emit */ + int plan_width; /* average row width in bytes */ + + /* + * information needed for parallel query + */ + bool parallel_aware; /* engage parallel-aware logic? */ + bool parallel_safe; /* OK to use as part of parallel plan? */ + + /* + * information needed for asynchronous execution + */ + bool async_capable; /* engage asynchronous-capable logic? */ + + /* + * Common structural data for all Plan types. + */ + int plan_node_id; /* unique across entire final plan tree */ + List *targetlist; /* target list to be computed at this node */ + List *qual; /* implicitly-ANDed qual conditions */ + struct Plan *lefttree; /* input plan tree(s) */ + struct Plan *righttree; + List *initPlan; /* Init Plan nodes (un-correlated expr + * subselects) */ + + /* + * Information for management of parameter-change-driven rescanning + * + * extParam includes the paramIDs of all external PARAM_EXEC params + * affecting this plan node or its children. setParam params from the + * node's initPlans are not included, but their extParams are. + * + * allParam includes all the extParam paramIDs, plus the IDs of local + * params that affect the node (i.e., the setParams of its initplans). + * These are _all_ the PARAM_EXEC params that affect this node. + */ + Bitmapset *extParam; + Bitmapset *allParam; +} Plan; + +/* ---------------- + * these are defined to avoid confusion problems with "left" + * and "right" and "inner" and "outer". The convention is that + * the "left" plan is the "outer" plan and the "right" plan is + * the inner plan, but these make the code more readable. + * ---------------- + */ +#define innerPlan(node) (((Plan *)(node))->righttree) +#define outerPlan(node) (((Plan *)(node))->lefttree) + + +/* ---------------- + * Result node - + * If no outer plan, evaluate a variable-free targetlist. + * If outer plan, return tuples from outer plan (after a level of + * projection as shown by targetlist). + * + * If resconstantqual isn't NULL, it represents a one-time qualification + * test (i.e., one that doesn't depend on any variables from the outer plan, + * so needs to be evaluated only once). + * ---------------- + */ +typedef struct Result +{ + Plan plan; + Node *resconstantqual; +} Result; + +/* ---------------- + * ProjectSet node - + * Apply a projection that includes set-returning functions to the + * output tuples of the outer plan. + * ---------------- + */ +typedef struct ProjectSet +{ + Plan plan; +} ProjectSet; + +/* ---------------- + * ModifyTable node - + * Apply rows produced by outer plan to result table(s), + * by inserting, updating, or deleting. + * + * If the originally named target table is a partitioned table or inheritance + * tree, both nominalRelation and rootRelation contain the RT index of the + * partition root or appendrel RTE, which is not otherwise mentioned in the + * plan. Otherwise rootRelation is zero. However, nominalRelation will + * always be set, as it's the rel that EXPLAIN should claim is the + * INSERT/UPDATE/DELETE/MERGE target. + * + * Note that rowMarks and epqParam are presumed to be valid for all the + * table(s); they can't contain any info that varies across tables. + * ---------------- + */ +typedef struct ModifyTable +{ + Plan plan; + CmdType operation; /* INSERT, UPDATE, DELETE, or MERGE */ + bool canSetTag; /* do we set the command tag/es_processed? */ + Index nominalRelation; /* Parent RT index for use of EXPLAIN */ + Index rootRelation; /* Root RT index, if partitioned/inherited */ + bool partColsUpdated; /* some part key in hierarchy updated? */ + List *resultRelations; /* integer list of RT indexes */ + List *updateColnosLists; /* per-target-table update_colnos lists */ + List *withCheckOptionLists; /* per-target-table WCO lists */ + List *returningLists; /* per-target-table RETURNING tlists */ + List *fdwPrivLists; /* per-target-table FDW private data lists */ + Bitmapset *fdwDirectModifyPlans; /* indices of FDW DM plans */ + List *rowMarks; /* PlanRowMarks (non-locking only) */ + int epqParam; /* ID of Param for EvalPlanQual re-eval */ + OnConflictAction onConflictAction; /* ON CONFLICT action */ + List *arbiterIndexes; /* List of ON CONFLICT arbiter index OIDs */ + List *onConflictSet; /* INSERT ON CONFLICT DO UPDATE targetlist */ + List *onConflictCols; /* target column numbers for onConflictSet */ + Node *onConflictWhere; /* WHERE for ON CONFLICT UPDATE */ + Index exclRelRTI; /* RTI of the EXCLUDED pseudo relation */ + List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */ + List *mergeActionLists; /* per-target-table lists of actions for + * MERGE */ +} ModifyTable; + +struct PartitionPruneInfo; /* forward reference to struct below */ + +/* ---------------- + * Append node - + * Generate the concatenation of the results of sub-plans. + * ---------------- + */ +typedef struct Append +{ + Plan plan; + Bitmapset *apprelids; /* RTIs of appendrel(s) formed by this node */ + List *appendplans; + int nasyncplans; /* # of asynchronous plans */ + + /* + * All 'appendplans' preceding this index are non-partial plans. All + * 'appendplans' from this index onwards are partial plans. + */ + int first_partial_plan; + + /* Info for run-time subplan pruning; NULL if we're not doing that */ + struct PartitionPruneInfo *part_prune_info; +} Append; + +/* ---------------- + * MergeAppend node - + * Merge the results of pre-sorted sub-plans to preserve the ordering. + * ---------------- + */ +typedef struct MergeAppend +{ + Plan plan; + + /* RTIs of appendrel(s) formed by this node */ + Bitmapset *apprelids; + + List *mergeplans; + + /* these fields are just like the sort-key info in struct Sort: */ + + /* number of sort-key columns */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *sortColIdx pg_node_attr(array_size(numCols)); + + /* OIDs of operators to sort them by */ + Oid *sortOperators pg_node_attr(array_size(numCols)); + + /* OIDs of collations */ + Oid *collations pg_node_attr(array_size(numCols)); + + /* NULLS FIRST/LAST directions */ + bool *nullsFirst pg_node_attr(array_size(numCols)); + + /* Info for run-time subplan pruning; NULL if we're not doing that */ + struct PartitionPruneInfo *part_prune_info; +} MergeAppend; + +/* ---------------- + * RecursiveUnion node - + * Generate a recursive union of two subplans. + * + * The "outer" subplan is always the non-recursive term, and the "inner" + * subplan is the recursive term. + * ---------------- + */ +typedef struct RecursiveUnion +{ + Plan plan; + + /* ID of Param representing work table */ + int wtParam; + + /* Remaining fields are zero/null in UNION ALL case */ + + /* number of columns to check for duplicate-ness */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *dupColIdx pg_node_attr(array_size(numCols)); + + /* equality operators to compare with */ + Oid *dupOperators pg_node_attr(array_size(numCols)); + Oid *dupCollations pg_node_attr(array_size(numCols)); + + /* estimated number of groups in input */ + long numGroups; +} RecursiveUnion; + +/* ---------------- + * BitmapAnd node - + * Generate the intersection of the results of sub-plans. + * + * The subplans must be of types that yield tuple bitmaps. The targetlist + * and qual fields of the plan are unused and are always NIL. + * ---------------- + */ +typedef struct BitmapAnd +{ + Plan plan; + List *bitmapplans; +} BitmapAnd; + +/* ---------------- + * BitmapOr node - + * Generate the union of the results of sub-plans. + * + * The subplans must be of types that yield tuple bitmaps. The targetlist + * and qual fields of the plan are unused and are always NIL. + * ---------------- + */ +typedef struct BitmapOr +{ + Plan plan; + bool isshared; + List *bitmapplans; +} BitmapOr; + +/* + * ========== + * Scan nodes + * + * Scan is an abstract type that all relation scan plan types inherit from. + * ========== + */ +typedef struct Scan +{ + pg_node_attr(abstract) + + Plan plan; + Index scanrelid; /* relid is index into the range table */ +} Scan; + +/* ---------------- + * sequential scan node + * ---------------- + */ +typedef struct SeqScan +{ + Scan scan; +} SeqScan; + +/* ---------------- + * table sample scan node + * ---------------- + */ +typedef struct SampleScan +{ + Scan scan; + /* use struct pointer to avoid including parsenodes.h here */ + struct TableSampleClause *tablesample; +} SampleScan; + +/* ---------------- + * index scan node + * + * indexqualorig is an implicitly-ANDed list of index qual expressions, each + * in the same form it appeared in the query WHERE condition. Each should + * be of the form (indexkey OP comparisonval) or (comparisonval OP indexkey). + * The indexkey is a Var or expression referencing column(s) of the index's + * base table. The comparisonval might be any expression, but it won't use + * any columns of the base table. The expressions are ordered by index + * column position (but items referencing the same index column can appear + * in any order). indexqualorig is used at runtime only if we have to recheck + * a lossy indexqual. + * + * indexqual has the same form, but the expressions have been commuted if + * necessary to put the indexkeys on the left, and the indexkeys are replaced + * by Var nodes identifying the index columns (their varno is INDEX_VAR and + * their varattno is the index column number). + * + * indexorderbyorig is similarly the original form of any ORDER BY expressions + * that are being implemented by the index, while indexorderby is modified to + * have index column Vars on the left-hand side. Here, multiple expressions + * must appear in exactly the ORDER BY order, and this is not necessarily the + * index column order. Only the expressions are provided, not the auxiliary + * sort-order information from the ORDER BY SortGroupClauses; it's assumed + * that the sort ordering is fully determinable from the top-level operators. + * indexorderbyorig is used at runtime to recheck the ordering, if the index + * cannot calculate an accurate ordering. It is also needed for EXPLAIN. + * + * indexorderbyops is a list of the OIDs of the operators used to sort the + * ORDER BY expressions. This is used together with indexorderbyorig to + * recheck ordering at run time. (Note that indexorderby, indexorderbyorig, + * and indexorderbyops are used for amcanorderbyop cases, not amcanorder.) + * + * indexorderdir specifies the scan ordering, for indexscans on amcanorder + * indexes (for other indexes it should be "don't care"). + * ---------------- + */ +typedef struct IndexScan +{ + Scan scan; + Oid indexid; /* OID of index to scan */ + List *indexqual; /* list of index quals (usually OpExprs) */ + List *indexqualorig; /* the same in original form */ + List *indexorderby; /* list of index ORDER BY exprs */ + List *indexorderbyorig; /* the same in original form */ + List *indexorderbyops; /* OIDs of sort ops for ORDER BY exprs */ + ScanDirection indexorderdir; /* forward or backward or don't care */ +} IndexScan; + +/* ---------------- + * index-only scan node + * + * IndexOnlyScan is very similar to IndexScan, but it specifies an + * index-only scan, in which the data comes from the index not the heap. + * Because of this, *all* Vars in the plan node's targetlist, qual, and + * index expressions reference index columns and have varno = INDEX_VAR. + * + * We could almost use indexqual directly against the index's output tuple + * when rechecking lossy index operators, but that won't work for quals on + * index columns that are not retrievable. Hence, recheckqual is needed + * for rechecks: it expresses the same condition as indexqual, but using + * only index columns that are retrievable. (We will not generate an + * index-only scan if this is not possible. An example is that if an + * index has table column "x" in a retrievable index column "ind1", plus + * an expression f(x) in a non-retrievable column "ind2", an indexable + * query on f(x) will use "ind2" in indexqual and f(ind1) in recheckqual. + * Without the "ind1" column, an index-only scan would be disallowed.) + * + * We don't currently need a recheckable equivalent of indexorderby, + * because we don't support lossy operators in index ORDER BY. + * + * To help EXPLAIN interpret the index Vars for display, we provide + * indextlist, which represents the contents of the index as a targetlist + * with one TLE per index column. Vars appearing in this list reference + * the base table, and this is the only field in the plan node that may + * contain such Vars. Also, for the convenience of setrefs.c, TLEs in + * indextlist are marked as resjunk if they correspond to columns that + * the index AM cannot reconstruct. + * ---------------- + */ +typedef struct IndexOnlyScan +{ + Scan scan; + Oid indexid; /* OID of index to scan */ + List *indexqual; /* list of index quals (usually OpExprs) */ + List *recheckqual; /* index quals in recheckable form */ + List *indexorderby; /* list of index ORDER BY exprs */ + List *indextlist; /* TargetEntry list describing index's cols */ + ScanDirection indexorderdir; /* forward or backward or don't care */ +} IndexOnlyScan; + +/* ---------------- + * bitmap index scan node + * + * BitmapIndexScan delivers a bitmap of potential tuple locations; + * it does not access the heap itself. The bitmap is used by an + * ancestor BitmapHeapScan node, possibly after passing through + * intermediate BitmapAnd and/or BitmapOr nodes to combine it with + * the results of other BitmapIndexScans. + * + * The fields have the same meanings as for IndexScan, except we don't + * store a direction flag because direction is uninteresting. + * + * In a BitmapIndexScan plan node, the targetlist and qual fields are + * not used and are always NIL. The indexqualorig field is unused at + * run time too, but is saved for the benefit of EXPLAIN. + * ---------------- + */ +typedef struct BitmapIndexScan +{ + Scan scan; + Oid indexid; /* OID of index to scan */ + bool isshared; /* Create shared bitmap if set */ + List *indexqual; /* list of index quals (OpExprs) */ + List *indexqualorig; /* the same in original form */ +} BitmapIndexScan; + +/* ---------------- + * bitmap sequential scan node + * + * This needs a copy of the qual conditions being used by the input index + * scans because there are various cases where we need to recheck the quals; + * for example, when the bitmap is lossy about the specific rows on a page + * that meet the index condition. + * ---------------- + */ +typedef struct BitmapHeapScan +{ + Scan scan; + List *bitmapqualorig; /* index quals, in standard expr form */ +} BitmapHeapScan; + +/* ---------------- + * tid scan node + * + * tidquals is an implicitly OR'ed list of qual expressions of the form + * "CTID = pseudoconstant", or "CTID = ANY(pseudoconstant_array)", + * or a CurrentOfExpr for the relation. + * ---------------- + */ +typedef struct TidScan +{ + Scan scan; + List *tidquals; /* qual(s) involving CTID = something */ +} TidScan; + +/* ---------------- + * tid range scan node + * + * tidrangequals is an implicitly AND'ed list of qual expressions of the form + * "CTID relop pseudoconstant", where relop is one of >,>=,<,<=. + * ---------------- + */ +typedef struct TidRangeScan +{ + Scan scan; + List *tidrangequals; /* qual(s) involving CTID op something */ +} TidRangeScan; + +/* ---------------- + * subquery scan node + * + * SubqueryScan is for scanning the output of a sub-query in the range table. + * We often need an extra plan node above the sub-query's plan to perform + * expression evaluations (which we can't push into the sub-query without + * risking changing its semantics). Although we are not scanning a physical + * relation, we make this a descendant of Scan anyway for code-sharing + * purposes. + * + * SubqueryScanStatus caches the trivial_subqueryscan property of the node. + * SUBQUERY_SCAN_UNKNOWN means not yet determined. This is only used during + * planning. + * + * Note: we store the sub-plan in the type-specific subplan field, not in + * the generic lefttree field as you might expect. This is because we do + * not want plan-tree-traversal routines to recurse into the subplan without + * knowing that they are changing Query contexts. + * ---------------- + */ +typedef enum SubqueryScanStatus +{ + SUBQUERY_SCAN_UNKNOWN, + SUBQUERY_SCAN_TRIVIAL, + SUBQUERY_SCAN_NONTRIVIAL +} SubqueryScanStatus; + +typedef struct SubqueryScan +{ + Scan scan; + Plan *subplan; + SubqueryScanStatus scanstatus; +} SubqueryScan; + +/* ---------------- + * FunctionScan node + * ---------------- + */ +typedef struct FunctionScan +{ + Scan scan; + List *functions; /* list of RangeTblFunction nodes */ + bool funcordinality; /* WITH ORDINALITY */ +} FunctionScan; + +/* ---------------- + * ValuesScan node + * ---------------- + */ +typedef struct ValuesScan +{ + Scan scan; + List *values_lists; /* list of expression lists */ +} ValuesScan; + +/* ---------------- + * TableFunc scan node + * ---------------- + */ +typedef struct TableFuncScan +{ + Scan scan; + TableFunc *tablefunc; /* table function node */ +} TableFuncScan; + +/* ---------------- + * CteScan node + * ---------------- + */ +typedef struct CteScan +{ + Scan scan; + int ctePlanId; /* ID of init SubPlan for CTE */ + int cteParam; /* ID of Param representing CTE output */ +} CteScan; + +/* ---------------- + * NamedTuplestoreScan node + * ---------------- + */ +typedef struct NamedTuplestoreScan +{ + Scan scan; + char *enrname; /* Name given to Ephemeral Named Relation */ +} NamedTuplestoreScan; + +/* ---------------- + * WorkTableScan node + * ---------------- + */ +typedef struct WorkTableScan +{ + Scan scan; + int wtParam; /* ID of Param representing work table */ +} WorkTableScan; + +/* ---------------- + * ForeignScan node + * + * fdw_exprs and fdw_private are both under the control of the foreign-data + * wrapper, but fdw_exprs is presumed to contain expression trees and will + * be post-processed accordingly by the planner; fdw_private won't be. + * Note that everything in both lists must be copiable by copyObject(). + * One way to store an arbitrary blob of bytes is to represent it as a bytea + * Const. Usually, though, you'll be better off choosing a representation + * that can be dumped usefully by nodeToString(). + * + * fdw_scan_tlist is a targetlist describing the contents of the scan tuple + * returned by the FDW; it can be NIL if the scan tuple matches the declared + * rowtype of the foreign table, which is the normal case for a simple foreign + * table scan. (If the plan node represents a foreign join, fdw_scan_tlist + * is required since there is no rowtype available from the system catalogs.) + * When fdw_scan_tlist is provided, Vars in the node's tlist and quals must + * have varno INDEX_VAR, and their varattnos correspond to resnos in the + * fdw_scan_tlist (which are also column numbers in the actual scan tuple). + * fdw_scan_tlist is never actually executed; it just holds expression trees + * describing what is in the scan tuple's columns. + * + * fdw_recheck_quals should contain any quals which the core system passed to + * the FDW but which were not added to scan.plan.qual; that is, it should + * contain the quals being checked remotely. This is needed for correct + * behavior during EvalPlanQual rechecks. + * + * When the plan node represents a foreign join, scan.scanrelid is zero and + * fs_relids must be consulted to identify the join relation. (fs_relids + * is valid for simple scans as well, but will always match scan.scanrelid.) + * fs_relids includes outer joins; fs_base_relids does not. + * + * If the FDW's PlanDirectModify() callback decides to repurpose a ForeignScan + * node to perform the UPDATE or DELETE operation directly in the remote + * server, it sets 'operation' and 'resultRelation' to identify the operation + * type and target relation. Note that these fields are only set if the + * modification is performed *fully* remotely; otherwise, the modification is + * driven by a local ModifyTable node and 'operation' is left to CMD_SELECT. + * ---------------- + */ +typedef struct ForeignScan +{ + Scan scan; + CmdType operation; /* SELECT/INSERT/UPDATE/DELETE */ + Index resultRelation; /* direct modification target's RT index */ + Oid checkAsUser; /* user to perform the scan as; 0 means to + * check as current user */ + Oid fs_server; /* OID of foreign server */ + List *fdw_exprs; /* expressions that FDW may evaluate */ + List *fdw_private; /* private data for FDW */ + List *fdw_scan_tlist; /* optional tlist describing scan tuple */ + List *fdw_recheck_quals; /* original quals not in scan.plan.qual */ + Bitmapset *fs_relids; /* base+OJ RTIs generated by this scan */ + Bitmapset *fs_base_relids; /* base RTIs generated by this scan */ + bool fsSystemCol; /* true if any "system column" is needed */ +} ForeignScan; + +/* ---------------- + * CustomScan node + * + * The comments for ForeignScan's fdw_exprs, fdw_private, fdw_scan_tlist, + * and fs_relids fields apply equally to CustomScan's custom_exprs, + * custom_private, custom_scan_tlist, and custom_relids fields. The + * convention of setting scan.scanrelid to zero for joins applies as well. + * + * Note that since Plan trees can be copied, custom scan providers *must* + * fit all plan data they need into those fields; embedding CustomScan in + * a larger struct will not work. + * ---------------- + */ +struct CustomScanMethods; + +typedef struct CustomScan +{ + Scan scan; + uint32 flags; /* mask of CUSTOMPATH_* flags, see + * nodes/extensible.h */ + List *custom_plans; /* list of Plan nodes, if any */ + List *custom_exprs; /* expressions that custom code may evaluate */ + List *custom_private; /* private data for custom code */ + List *custom_scan_tlist; /* optional tlist describing scan tuple */ + Bitmapset *custom_relids; /* RTIs generated by this scan */ + + /* + * NOTE: The method field of CustomScan is required to be a pointer to a + * static table of callback functions. So we don't copy the table itself, + * just reference the original one. + */ + const struct CustomScanMethods *methods; +} CustomScan; + +/* + * ========== + * Join nodes + * ========== + */ + +/* ---------------- + * Join node + * + * jointype: rule for joining tuples from left and right subtrees + * inner_unique each outer tuple can match to no more than one inner tuple + * joinqual: qual conditions that came from JOIN/ON or JOIN/USING + * (plan.qual contains conditions that came from WHERE) + * + * When jointype is INNER, joinqual and plan.qual are semantically + * interchangeable. For OUTER jointypes, the two are *not* interchangeable; + * only joinqual is used to determine whether a match has been found for + * the purpose of deciding whether to generate null-extended tuples. + * (But plan.qual is still applied before actually returning a tuple.) + * For an outer join, only joinquals are allowed to be used as the merge + * or hash condition of a merge or hash join. + * + * inner_unique is set if the joinquals are such that no more than one inner + * tuple could match any given outer tuple. This allows the executor to + * skip searching for additional matches. (This must be provable from just + * the joinquals, ignoring plan.qual, due to where the executor tests it.) + * ---------------- + */ +typedef struct Join +{ + pg_node_attr(abstract) + + Plan plan; + JoinType jointype; + bool inner_unique; + List *joinqual; /* JOIN quals (in addition to plan.qual) */ +} Join; + +/* ---------------- + * nest loop join node + * + * The nestParams list identifies any executor Params that must be passed + * into execution of the inner subplan carrying values from the current row + * of the outer subplan. Currently we restrict these values to be simple + * Vars, but perhaps someday that'd be worth relaxing. (Note: during plan + * creation, the paramval can actually be a PlaceHolderVar expression; but it + * must be a Var with varno OUTER_VAR by the time it gets to the executor.) + * ---------------- + */ +typedef struct NestLoop +{ + Join join; + List *nestParams; /* list of NestLoopParam nodes */ +} NestLoop; + +typedef struct NestLoopParam +{ + pg_node_attr(no_equal, no_query_jumble) + + NodeTag type; + int paramno; /* number of the PARAM_EXEC Param to set */ + Var *paramval; /* outer-relation Var to assign to Param */ +} NestLoopParam; + +/* ---------------- + * merge join node + * + * The expected ordering of each mergeable column is described by a btree + * opfamily OID, a collation OID, a direction (BTLessStrategyNumber or + * BTGreaterStrategyNumber) and a nulls-first flag. Note that the two sides + * of each mergeclause may be of different datatypes, but they are ordered the + * same way according to the common opfamily and collation. The operator in + * each mergeclause must be an equality operator of the indicated opfamily. + * ---------------- + */ +typedef struct MergeJoin +{ + Join join; + + /* Can we skip mark/restore calls? */ + bool skip_mark_restore; + + /* mergeclauses as expression trees */ + List *mergeclauses; + + /* these are arrays, but have the same length as the mergeclauses list: */ + + /* per-clause OIDs of btree opfamilies */ + Oid *mergeFamilies pg_node_attr(array_size(mergeclauses)); + + /* per-clause OIDs of collations */ + Oid *mergeCollations pg_node_attr(array_size(mergeclauses)); + + /* per-clause ordering (ASC or DESC) */ + int *mergeStrategies pg_node_attr(array_size(mergeclauses)); + + /* per-clause nulls ordering */ + bool *mergeNullsFirst pg_node_attr(array_size(mergeclauses)); +} MergeJoin; + +/* ---------------- + * hash join node + * ---------------- + */ +typedef struct HashJoin +{ + Join join; + List *hashclauses; + List *hashoperators; + List *hashcollations; + + /* + * List of expressions to be hashed for tuples from the outer plan, to + * perform lookups in the hashtable over the inner plan. + */ + List *hashkeys; +} HashJoin; + +/* ---------------- + * materialization node + * ---------------- + */ +typedef struct Material +{ + Plan plan; +} Material; + +/* ---------------- + * memoize node + * ---------------- + */ +typedef struct Memoize +{ + Plan plan; + + /* size of the two arrays below */ + int numKeys; + + /* hash operators for each key */ + Oid *hashOperators pg_node_attr(array_size(numKeys)); + + /* collations for each key */ + Oid *collations pg_node_attr(array_size(numKeys)); + + /* cache keys in the form of exprs containing parameters */ + List *param_exprs; + + /* + * true if the cache entry should be marked as complete after we store the + * first tuple in it. + */ + bool singlerow; + + /* + * true when cache key should be compared bit by bit, false when using + * hash equality ops + */ + bool binary_mode; + + /* + * The maximum number of entries that the planner expects will fit in the + * cache, or 0 if unknown + */ + uint32 est_entries; + + /* paramids from param_exprs */ + Bitmapset *keyparamids; +} Memoize; + +/* ---------------- + * sort node + * ---------------- + */ +typedef struct Sort +{ + Plan plan; + + /* number of sort-key columns */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *sortColIdx pg_node_attr(array_size(numCols)); + + /* OIDs of operators to sort them by */ + Oid *sortOperators pg_node_attr(array_size(numCols)); + + /* OIDs of collations */ + Oid *collations pg_node_attr(array_size(numCols)); + + /* NULLS FIRST/LAST directions */ + bool *nullsFirst pg_node_attr(array_size(numCols)); +} Sort; + +/* ---------------- + * incremental sort node + * ---------------- + */ +typedef struct IncrementalSort +{ + Sort sort; + int nPresortedCols; /* number of presorted columns */ +} IncrementalSort; + +/* --------------- + * group node - + * Used for queries with GROUP BY (but no aggregates) specified. + * The input must be presorted according to the grouping columns. + * --------------- + */ +typedef struct Group +{ + Plan plan; + + /* number of grouping columns */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *grpColIdx pg_node_attr(array_size(numCols)); + + /* equality operators to compare with */ + Oid *grpOperators pg_node_attr(array_size(numCols)); + Oid *grpCollations pg_node_attr(array_size(numCols)); +} Group; + +/* --------------- + * aggregate node + * + * An Agg node implements plain or grouped aggregation. For grouped + * aggregation, we can work with presorted input or unsorted input; + * the latter strategy uses an internal hashtable. + * + * Notice the lack of any direct info about the aggregate functions to be + * computed. They are found by scanning the node's tlist and quals during + * executor startup. (It is possible that there are no aggregate functions; + * this could happen if they get optimized away by constant-folding, or if + * we are using the Agg node to implement hash-based grouping.) + * --------------- + */ +typedef struct Agg +{ + Plan plan; + + /* basic strategy, see nodes.h */ + AggStrategy aggstrategy; + + /* agg-splitting mode, see nodes.h */ + AggSplit aggsplit; + + /* number of grouping columns */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *grpColIdx pg_node_attr(array_size(numCols)); + + /* equality operators to compare with */ + Oid *grpOperators pg_node_attr(array_size(numCols)); + Oid *grpCollations pg_node_attr(array_size(numCols)); + + /* estimated number of groups in input */ + long numGroups; + + /* for pass-by-ref transition data */ + uint64 transitionSpace; + + /* IDs of Params used in Aggref inputs */ + Bitmapset *aggParams; + + /* Note: planner provides numGroups & aggParams only in HASHED/MIXED case */ + + /* grouping sets to use */ + List *groupingSets; + + /* chained Agg/Sort nodes */ + List *chain; +} Agg; + +/* ---------------- + * window aggregate node + * ---------------- + */ +typedef struct WindowAgg +{ + Plan plan; + + /* ID referenced by window functions */ + Index winref; + + /* number of columns in partition clause */ + int partNumCols; + + /* their indexes in the target list */ + AttrNumber *partColIdx pg_node_attr(array_size(partNumCols)); + + /* equality operators for partition columns */ + Oid *partOperators pg_node_attr(array_size(partNumCols)); + + /* collations for partition columns */ + Oid *partCollations pg_node_attr(array_size(partNumCols)); + + /* number of columns in ordering clause */ + int ordNumCols; + + /* their indexes in the target list */ + AttrNumber *ordColIdx pg_node_attr(array_size(ordNumCols)); + + /* equality operators for ordering columns */ + Oid *ordOperators pg_node_attr(array_size(ordNumCols)); + + /* collations for ordering columns */ + Oid *ordCollations pg_node_attr(array_size(ordNumCols)); + + /* frame_clause options, see WindowDef */ + int frameOptions; + + /* expression for starting bound, if any */ + Node *startOffset; + + /* expression for ending bound, if any */ + Node *endOffset; + + /* qual to help short-circuit execution */ + List *runCondition; + + /* runCondition for display in EXPLAIN */ + List *runConditionOrig; + + /* these fields are used with RANGE offset PRECEDING/FOLLOWING: */ + + /* in_range function for startOffset */ + Oid startInRangeFunc; + + /* in_range function for endOffset */ + Oid endInRangeFunc; + + /* collation for in_range tests */ + Oid inRangeColl; + + /* use ASC sort order for in_range tests? */ + bool inRangeAsc; + + /* nulls sort first for in_range tests? */ + bool inRangeNullsFirst; + + /* + * false for all apart from the WindowAgg that's closest to the root of + * the plan + */ + bool topWindow; +} WindowAgg; + +/* ---------------- + * unique node + * ---------------- + */ +typedef struct Unique +{ + Plan plan; + + /* number of columns to check for uniqueness */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *uniqColIdx pg_node_attr(array_size(numCols)); + + /* equality operators to compare with */ + Oid *uniqOperators pg_node_attr(array_size(numCols)); + + /* collations for equality comparisons */ + Oid *uniqCollations pg_node_attr(array_size(numCols)); +} Unique; + +/* ------------ + * gather node + * + * Note: rescan_param is the ID of a PARAM_EXEC parameter slot. That slot + * will never actually contain a value, but the Gather node must flag it as + * having changed whenever it is rescanned. The child parallel-aware scan + * nodes are marked as depending on that parameter, so that the rescan + * machinery is aware that their output is likely to change across rescans. + * In some cases we don't need a rescan Param, so rescan_param is set to -1. + * ------------ + */ +typedef struct Gather +{ + Plan plan; + int num_workers; /* planned number of worker processes */ + int rescan_param; /* ID of Param that signals a rescan, or -1 */ + bool single_copy; /* don't execute plan more than once */ + bool invisible; /* suppress EXPLAIN display (for testing)? */ + Bitmapset *initParam; /* param id's of initplans which are referred + * at gather or one of it's child node */ +} Gather; + +/* ------------ + * gather merge node + * ------------ + */ +typedef struct GatherMerge +{ + Plan plan; + + /* planned number of worker processes */ + int num_workers; + + /* ID of Param that signals a rescan, or -1 */ + int rescan_param; + + /* remaining fields are just like the sort-key info in struct Sort */ + + /* number of sort-key columns */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *sortColIdx pg_node_attr(array_size(numCols)); + + /* OIDs of operators to sort them by */ + Oid *sortOperators pg_node_attr(array_size(numCols)); + + /* OIDs of collations */ + Oid *collations pg_node_attr(array_size(numCols)); + + /* NULLS FIRST/LAST directions */ + bool *nullsFirst pg_node_attr(array_size(numCols)); + + /* + * param id's of initplans which are referred at gather merge or one of + * it's child node + */ + Bitmapset *initParam; +} GatherMerge; + +/* ---------------- + * hash build node + * + * If the executor is supposed to try to apply skew join optimization, then + * skewTable/skewColumn/skewInherit identify the outer relation's join key + * column, from which the relevant MCV statistics can be fetched. + * ---------------- + */ +typedef struct Hash +{ + Plan plan; + + /* + * List of expressions to be hashed for tuples from Hash's outer plan, + * needed to put them into the hashtable. + */ + List *hashkeys; /* hash keys for the hashjoin condition */ + Oid skewTable; /* outer join key's table OID, or InvalidOid */ + AttrNumber skewColumn; /* outer join key's column #, or zero */ + bool skewInherit; /* is outer join rel an inheritance tree? */ + /* all other info is in the parent HashJoin node */ + Cardinality rows_total; /* estimate total rows if parallel_aware */ +} Hash; + +/* ---------------- + * setop node + * ---------------- + */ +typedef struct SetOp +{ + Plan plan; + + /* what to do, see nodes.h */ + SetOpCmd cmd; + + /* how to do it, see nodes.h */ + SetOpStrategy strategy; + + /* number of columns to check for duplicate-ness */ + int numCols; + + /* their indexes in the target list */ + AttrNumber *dupColIdx pg_node_attr(array_size(numCols)); + + /* equality operators to compare with */ + Oid *dupOperators pg_node_attr(array_size(numCols)); + Oid *dupCollations pg_node_attr(array_size(numCols)); + + /* where is the flag column, if any */ + AttrNumber flagColIdx; + + /* flag value for first input relation */ + int firstFlag; + + /* estimated number of groups in input */ + long numGroups; +} SetOp; + +/* ---------------- + * lock-rows node + * + * rowMarks identifies the rels to be locked by this node; it should be + * a subset of the rowMarks listed in the top-level PlannedStmt. + * epqParam is a Param that all scan nodes below this one must depend on. + * It is used to force re-evaluation of the plan during EvalPlanQual. + * ---------------- + */ +typedef struct LockRows +{ + Plan plan; + List *rowMarks; /* a list of PlanRowMark's */ + int epqParam; /* ID of Param for EvalPlanQual re-eval */ +} LockRows; + +/* ---------------- + * limit node + * + * Note: as of Postgres 8.2, the offset and count expressions are expected + * to yield int8, rather than int4 as before. + * ---------------- + */ +typedef struct Limit +{ + Plan plan; + + /* OFFSET parameter, or NULL if none */ + Node *limitOffset; + + /* COUNT parameter, or NULL if none */ + Node *limitCount; + + /* limit type */ + LimitOption limitOption; + + /* number of columns to check for similarity */ + int uniqNumCols; + + /* their indexes in the target list */ + AttrNumber *uniqColIdx pg_node_attr(array_size(uniqNumCols)); + + /* equality operators to compare with */ + Oid *uniqOperators pg_node_attr(array_size(uniqNumCols)); + + /* collations for equality comparisons */ + Oid *uniqCollations pg_node_attr(array_size(uniqNumCols)); +} Limit; + + +/* + * RowMarkType - + * enums for types of row-marking operations + * + * The first four of these values represent different lock strengths that + * we can take on tuples according to SELECT FOR [KEY] UPDATE/SHARE requests. + * We support these on regular tables, as well as on foreign tables whose FDWs + * report support for late locking. For other foreign tables, any locking + * that might be done for such requests must happen during the initial row + * fetch; their FDWs provide no mechanism for going back to lock a row later. + * This means that the semantics will be a bit different than for a local + * table; in particular we are likely to lock more rows than would be locked + * locally, since remote rows will be locked even if they then fail + * locally-checked restriction or join quals. However, the prospect of + * doing a separate remote query to lock each selected row is usually pretty + * unappealing, so early locking remains a credible design choice for FDWs. + * + * When doing UPDATE/DELETE/MERGE/SELECT FOR UPDATE/SHARE, we have to uniquely + * identify all the source rows, not only those from the target relations, so + * that we can perform EvalPlanQual rechecking at need. For plain tables we + * can just fetch the TID, much as for a target relation; this case is + * represented by ROW_MARK_REFERENCE. Otherwise (for example for VALUES or + * FUNCTION scans) we have to copy the whole row value. ROW_MARK_COPY is + * pretty inefficient, since most of the time we'll never need the data; but + * fortunately the overhead is usually not performance-critical in practice. + * By default we use ROW_MARK_COPY for foreign tables, but if the FDW has + * a concept of rowid it can request to use ROW_MARK_REFERENCE instead. + * (Again, this probably doesn't make sense if a physical remote fetch is + * needed, but for FDWs that map to local storage it might be credible.) + */ +typedef enum RowMarkType +{ + ROW_MARK_EXCLUSIVE, /* obtain exclusive tuple lock */ + ROW_MARK_NOKEYEXCLUSIVE, /* obtain no-key exclusive tuple lock */ + ROW_MARK_SHARE, /* obtain shared tuple lock */ + ROW_MARK_KEYSHARE, /* obtain keyshare tuple lock */ + ROW_MARK_REFERENCE, /* just fetch the TID, don't lock it */ + ROW_MARK_COPY /* physically copy the row value */ +} RowMarkType; + +#define RowMarkRequiresRowShareLock(marktype) ((marktype) <= ROW_MARK_KEYSHARE) + +/* + * PlanRowMark - + * plan-time representation of FOR [KEY] UPDATE/SHARE clauses + * + * When doing UPDATE/DELETE/MERGE/SELECT FOR UPDATE/SHARE, we create a separate + * PlanRowMark node for each non-target relation in the query. Relations that + * are not specified as FOR UPDATE/SHARE are marked ROW_MARK_REFERENCE (if + * regular tables or supported foreign tables) or ROW_MARK_COPY (if not). + * + * Initially all PlanRowMarks have rti == prti and isParent == false. + * When the planner discovers that a relation is the root of an inheritance + * tree, it sets isParent true, and adds an additional PlanRowMark to the + * list for each child relation (including the target rel itself in its role + * as a child, if it is not a partitioned table). Any non-leaf partitioned + * child relations will also have entries with isParent = true. The child + * entries have rti == child rel's RT index and prti == top parent's RT index, + * and can therefore be recognized as children by the fact that prti != rti. + * The parent's allMarkTypes field gets the OR of (1<0 means N levels up + */ + Index varlevelsup; + + /* + * varnosyn/varattnosyn are ignored for equality, because Vars with + * different syntactic identifiers are semantically the same as long as + * their varno/varattno match. + */ + /* syntactic relation index (0 if unknown) */ + Index varnosyn pg_node_attr(equal_ignore, query_jumble_ignore); + /* syntactic attribute number */ + AttrNumber varattnosyn pg_node_attr(equal_ignore, query_jumble_ignore); + + /* token location, or -1 if unknown */ + int location; +} Var; + +/* + * Const + * + * Note: for varlena data types, we make a rule that a Const node's value + * must be in non-extended form (4-byte header, no compression or external + * references). This ensures that the Const node is self-contained and makes + * it more likely that equal() will see logically identical values as equal. + * + * Only the constant type OID is relevant for the query jumbling. + */ +typedef struct Const +{ + pg_node_attr(custom_copy_equal, custom_read_write) + + Expr xpr; + /* pg_type OID of the constant's datatype */ + Oid consttype; + /* typmod value, if any */ + int32 consttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid constcollid pg_node_attr(query_jumble_ignore); + /* typlen of the constant's datatype */ + int constlen pg_node_attr(query_jumble_ignore); + /* the constant's value */ + Datum constvalue pg_node_attr(query_jumble_ignore); + /* whether the constant is null (if true, constvalue is undefined) */ + bool constisnull pg_node_attr(query_jumble_ignore); + + /* + * Whether this datatype is passed by value. If true, then all the + * information is stored in the Datum. If false, then the Datum contains + * a pointer to the information. + */ + bool constbyval pg_node_attr(query_jumble_ignore); + + /* + * token location, or -1 if unknown. All constants are tracked as + * locations in query jumbling, to be marked as parameters. + */ + int location pg_node_attr(query_jumble_location); +} Const; + +/* + * Param + * + * paramkind specifies the kind of parameter. The possible values + * for this field are: + * + * PARAM_EXTERN: The parameter value is supplied from outside the plan. + * Such parameters are numbered from 1 to n. + * + * PARAM_EXEC: The parameter is an internal executor parameter, used + * for passing values into and out of sub-queries or from + * nestloop joins to their inner scans. + * For historical reasons, such parameters are numbered from 0. + * These numbers are independent of PARAM_EXTERN numbers. + * + * PARAM_SUBLINK: The parameter represents an output column of a SubLink + * node's sub-select. The column number is contained in the + * `paramid' field. (This type of Param is converted to + * PARAM_EXEC during planning.) + * + * PARAM_MULTIEXPR: Like PARAM_SUBLINK, the parameter represents an + * output column of a SubLink node's sub-select, but here, the + * SubLink is always a MULTIEXPR SubLink. The high-order 16 bits + * of the `paramid' field contain the SubLink's subLinkId, and + * the low-order 16 bits contain the column number. (This type + * of Param is also converted to PARAM_EXEC during planning.) + */ +typedef enum ParamKind +{ + PARAM_EXTERN, + PARAM_EXEC, + PARAM_SUBLINK, + PARAM_MULTIEXPR +} ParamKind; + +typedef struct Param +{ + Expr xpr; + ParamKind paramkind; /* kind of parameter. See above */ + int paramid; /* numeric ID for parameter */ + Oid paramtype; /* pg_type OID of parameter's datatype */ + /* typmod value, if known */ + int32 paramtypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid paramcollid pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location; +} Param; + +/* + * Aggref + * + * The aggregate's args list is a targetlist, ie, a list of TargetEntry nodes. + * + * For a normal (non-ordered-set) aggregate, the non-resjunk TargetEntries + * represent the aggregate's regular arguments (if any) and resjunk TLEs can + * be added at the end to represent ORDER BY expressions that are not also + * arguments. As in a top-level Query, the TLEs can be marked with + * ressortgroupref indexes to let them be referenced by SortGroupClause + * entries in the aggorder and/or aggdistinct lists. This represents ORDER BY + * and DISTINCT operations to be applied to the aggregate input rows before + * they are passed to the transition function. The grammar only allows a + * simple "DISTINCT" specifier for the arguments, but we use the full + * query-level representation to allow more code sharing. + * + * For an ordered-set aggregate, the args list represents the WITHIN GROUP + * (aggregated) arguments, all of which will be listed in the aggorder list. + * DISTINCT is not supported in this case, so aggdistinct will be NIL. + * The direct arguments appear in aggdirectargs (as a list of plain + * expressions, not TargetEntry nodes). + * + * aggtranstype is the data type of the state transition values for this + * aggregate (resolved to an actual type, if agg's transtype is polymorphic). + * This is determined during planning and is InvalidOid before that. + * + * aggargtypes is an OID list of the data types of the direct and regular + * arguments. Normally it's redundant with the aggdirectargs and args lists, + * but in a combining aggregate, it's not because the args list has been + * replaced with a single argument representing the partial-aggregate + * transition values. + * + * aggpresorted is set by the query planner for ORDER BY and DISTINCT + * aggregates where the chosen plan provides presorted input for this + * aggregate during execution. + * + * aggsplit indicates the expected partial-aggregation mode for the Aggref's + * parent plan node. It's always set to AGGSPLIT_SIMPLE in the parser, but + * the planner might change it to something else. We use this mainly as + * a crosscheck that the Aggrefs match the plan; but note that when aggsplit + * indicates a non-final mode, aggtype reflects the transition data type + * not the SQL-level output type of the aggregate. + * + * aggno and aggtransno are -1 in the parse stage, and are set in planning. + * Aggregates with the same 'aggno' represent the same aggregate expression, + * and can share the result. Aggregates with same 'transno' but different + * 'aggno' can share the same transition state, only the final function needs + * to be called separately. + * + * Information related to collations, transition types and internal states + * are irrelevant for the query jumbling. + */ +typedef struct Aggref +{ + Expr xpr; + + /* pg_proc Oid of the aggregate */ + Oid aggfnoid; + + /* type Oid of result of the aggregate */ + Oid aggtype pg_node_attr(query_jumble_ignore); + + /* OID of collation of result */ + Oid aggcollid pg_node_attr(query_jumble_ignore); + + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + + /* + * type Oid of aggregate's transition value; ignored for equal since it + * might not be set yet + */ + Oid aggtranstype pg_node_attr(equal_ignore, query_jumble_ignore); + + /* type Oids of direct and aggregated args */ + List *aggargtypes pg_node_attr(query_jumble_ignore); + + /* direct arguments, if an ordered-set agg */ + List *aggdirectargs; + + /* aggregated arguments and sort expressions */ + List *args; + + /* ORDER BY (list of SortGroupClause) */ + List *aggorder; + + /* DISTINCT (list of SortGroupClause) */ + List *aggdistinct; + + /* FILTER expression, if any */ + Expr *aggfilter; + + /* true if argument list was really '*' */ + bool aggstar pg_node_attr(query_jumble_ignore); + + /* + * true if variadic arguments have been combined into an array last + * argument + */ + bool aggvariadic pg_node_attr(query_jumble_ignore); + + /* aggregate kind (see pg_aggregate.h) */ + char aggkind pg_node_attr(query_jumble_ignore); + + /* aggregate input already sorted */ + bool aggpresorted pg_node_attr(equal_ignore, query_jumble_ignore); + + /* > 0 if agg belongs to outer query */ + Index agglevelsup pg_node_attr(query_jumble_ignore); + + /* expected agg-splitting mode of parent Agg */ + AggSplit aggsplit pg_node_attr(query_jumble_ignore); + + /* unique ID within the Agg node */ + int aggno pg_node_attr(query_jumble_ignore); + + /* unique ID of transition state in the Agg */ + int aggtransno pg_node_attr(query_jumble_ignore); + + /* token location, or -1 if unknown */ + int location; +} Aggref; + +/* + * GroupingFunc + * + * A GroupingFunc is a GROUPING(...) expression, which behaves in many ways + * like an aggregate function (e.g. it "belongs" to a specific query level, + * which might not be the one immediately containing it), but also differs in + * an important respect: it never evaluates its arguments, they merely + * designate expressions from the GROUP BY clause of the query level to which + * it belongs. + * + * The spec defines the evaluation of GROUPING() purely by syntactic + * replacement, but we make it a real expression for optimization purposes so + * that one Agg node can handle multiple grouping sets at once. Evaluating the + * result only needs the column positions to check against the grouping set + * being projected. However, for EXPLAIN to produce meaningful output, we have + * to keep the original expressions around, since expression deparse does not + * give us any feasible way to get at the GROUP BY clause. + * + * Also, we treat two GroupingFunc nodes as equal if they have equal arguments + * lists and agglevelsup, without comparing the refs and cols annotations. + * + * In raw parse output we have only the args list; parse analysis fills in the + * refs list, and the planner fills in the cols list. + * + * All the fields used as information for an internal state are irrelevant + * for the query jumbling. + */ +typedef struct GroupingFunc +{ + Expr xpr; + + /* arguments, not evaluated but kept for benefit of EXPLAIN etc. */ + List *args pg_node_attr(query_jumble_ignore); + + /* ressortgrouprefs of arguments */ + List *refs pg_node_attr(equal_ignore); + + /* actual column positions set by planner */ + List *cols pg_node_attr(equal_ignore, query_jumble_ignore); + + /* same as Aggref.agglevelsup */ + Index agglevelsup; + + /* token location */ + int location; +} GroupingFunc; + +/* + * WindowFunc + * + * Collation information is irrelevant for the query jumbling, as is the + * internal state information of the node like "winstar" and "winagg". + */ +typedef struct WindowFunc +{ + Expr xpr; + /* pg_proc Oid of the function */ + Oid winfnoid; + /* type Oid of result of the window function */ + Oid wintype pg_node_attr(query_jumble_ignore); + /* OID of collation of result */ + Oid wincollid pg_node_attr(query_jumble_ignore); + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + /* arguments to the window function */ + List *args; + /* FILTER expression, if any */ + Expr *aggfilter; + /* index of associated WindowClause */ + Index winref; + /* true if argument list was really '*' */ + bool winstar pg_node_attr(query_jumble_ignore); + /* is function a simple aggregate? */ + bool winagg pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location; +} WindowFunc; + +/* + * SubscriptingRef: describes a subscripting operation over a container + * (array, etc). + * + * A SubscriptingRef can describe fetching a single element from a container, + * fetching a part of a container (e.g. an array slice), storing a single + * element into a container, or storing a slice. The "store" cases work with + * an initial container value and a source value that is inserted into the + * appropriate part of the container; the result of the operation is an + * entire new modified container value. + * + * If reflowerindexpr = NIL, then we are fetching or storing a single container + * element at the subscripts given by refupperindexpr. Otherwise we are + * fetching or storing a container slice, that is a rectangular subcontainer + * with lower and upper bounds given by the index expressions. + * reflowerindexpr must be the same length as refupperindexpr when it + * is not NIL. + * + * In the slice case, individual expressions in the subscript lists can be + * NULL, meaning "substitute the array's current lower or upper bound". + * (Non-array containers may or may not support this.) + * + * refcontainertype is the actual container type that determines the + * subscripting semantics. (This will generally be either the exposed type of + * refexpr, or the base type if that is a domain.) refelemtype is the type of + * the container's elements; this is saved for the use of the subscripting + * functions, but is not used by the core code. refrestype, reftypmod, and + * refcollid describe the type of the SubscriptingRef's result. In a store + * expression, refrestype will always match refcontainertype; in a fetch, + * it could be refelemtype for an element fetch, or refcontainertype for a + * slice fetch, or possibly something else as determined by type-specific + * subscripting logic. Likewise, reftypmod and refcollid will match the + * container's properties in a store, but could be different in a fetch. + * + * Any internal state data is ignored for the query jumbling. + * + * Note: for the cases where a container is returned, if refexpr yields a R/W + * expanded container, then the implementation is allowed to modify that + * object in-place and return the same object. + */ +typedef struct SubscriptingRef +{ + Expr xpr; + /* type of the container proper */ + Oid refcontainertype pg_node_attr(query_jumble_ignore); + /* the container type's pg_type.typelem */ + Oid refelemtype pg_node_attr(query_jumble_ignore); + /* type of the SubscriptingRef's result */ + Oid refrestype pg_node_attr(query_jumble_ignore); + /* typmod of the result */ + int32 reftypmod pg_node_attr(query_jumble_ignore); + /* collation of result, or InvalidOid if none */ + Oid refcollid pg_node_attr(query_jumble_ignore); + /* expressions that evaluate to upper container indexes */ + List *refupperindexpr; + + /* + * expressions that evaluate to lower container indexes, or NIL for single + * container element. + */ + List *reflowerindexpr; + /* the expression that evaluates to a container value */ + Expr *refexpr; + /* expression for the source value, or NULL if fetch */ + Expr *refassgnexpr; +} SubscriptingRef; + +/* + * CoercionContext - distinguishes the allowed set of type casts + * + * NB: ordering of the alternatives is significant; later (larger) values + * allow more casts than earlier ones. + */ +typedef enum CoercionContext +{ + COERCION_IMPLICIT, /* coercion in context of expression */ + COERCION_ASSIGNMENT, /* coercion in context of assignment */ + COERCION_PLPGSQL, /* if no assignment cast, use CoerceViaIO */ + COERCION_EXPLICIT /* explicit cast operation */ +} CoercionContext; + +/* + * CoercionForm - how to display a FuncExpr or related node + * + * "Coercion" is a bit of a misnomer, since this value records other + * special syntaxes besides casts, but for now we'll keep this naming. + * + * NB: equal() ignores CoercionForm fields, therefore this *must* not carry + * any semantically significant information. We need that behavior so that + * the planner will consider equivalent implicit and explicit casts to be + * equivalent. In cases where those actually behave differently, the coercion + * function's arguments will be different. + */ +typedef enum CoercionForm +{ + COERCE_EXPLICIT_CALL, /* display as a function call */ + COERCE_EXPLICIT_CAST, /* display as an explicit cast */ + COERCE_IMPLICIT_CAST, /* implicit cast, so hide it */ + COERCE_SQL_SYNTAX /* display with SQL-mandated special syntax */ +} CoercionForm; + +/* + * FuncExpr - expression node for a function call + * + * Collation information is irrelevant for the query jumbling, only the + * arguments and the function OID matter. + */ +typedef struct FuncExpr +{ + Expr xpr; + /* PG_PROC OID of the function */ + Oid funcid; + /* PG_TYPE OID of result value */ + Oid funcresulttype pg_node_attr(query_jumble_ignore); + /* true if function returns set */ + bool funcretset pg_node_attr(query_jumble_ignore); + + /* + * true if variadic arguments have been combined into an array last + * argument + */ + bool funcvariadic pg_node_attr(query_jumble_ignore); + /* how to display this function call */ + CoercionForm funcformat pg_node_attr(query_jumble_ignore); + /* OID of collation of result */ + Oid funccollid pg_node_attr(query_jumble_ignore); + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + /* arguments to the function */ + List *args; + /* token location, or -1 if unknown */ + int location; +} FuncExpr; + +/* + * NamedArgExpr - a named argument of a function + * + * This node type can only appear in the args list of a FuncCall or FuncExpr + * node. We support pure positional call notation (no named arguments), + * named notation (all arguments are named), and mixed notation (unnamed + * arguments followed by named ones). + * + * Parse analysis sets argnumber to the positional index of the argument, + * but doesn't rearrange the argument list. + * + * The planner will convert argument lists to pure positional notation + * during expression preprocessing, so execution never sees a NamedArgExpr. + */ +typedef struct NamedArgExpr +{ + Expr xpr; + /* the argument expression */ + Expr *arg; + /* the name */ + char *name pg_node_attr(query_jumble_ignore); + /* argument's number in positional notation */ + int argnumber; + /* argument name location, or -1 if unknown */ + int location; +} NamedArgExpr; + +/* + * OpExpr - expression node for an operator invocation + * + * Semantically, this is essentially the same as a function call. + * + * Note that opfuncid is not necessarily filled in immediately on creation + * of the node. The planner makes sure it is valid before passing the node + * tree to the executor, but during parsing/planning opfuncid can be 0. + * Therefore, equal() will accept a zero value as being equal to other values. + * + * Internal state information and collation data is irrelevant for the query + * jumbling. + */ +typedef struct OpExpr +{ + Expr xpr; + + /* PG_OPERATOR OID of the operator */ + Oid opno; + + /* PG_PROC OID of underlying function */ + Oid opfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* PG_TYPE OID of result value */ + Oid opresulttype pg_node_attr(query_jumble_ignore); + + /* true if operator returns set */ + bool opretset pg_node_attr(query_jumble_ignore); + + /* OID of collation of result */ + Oid opcollid pg_node_attr(query_jumble_ignore); + + /* OID of collation that operator should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + + /* arguments to the operator (1 or 2) */ + List *args; + + /* token location, or -1 if unknown */ + int location; +} OpExpr; + +/* + * DistinctExpr - expression node for "x IS DISTINCT FROM y" + * + * Except for the nodetag, this is represented identically to an OpExpr + * referencing the "=" operator for x and y. + * We use "=", not the more obvious "<>", because more datatypes have "=" + * than "<>". This means the executor must invert the operator result. + * Note that the operator function won't be called at all if either input + * is NULL, since then the result can be determined directly. + */ +typedef OpExpr DistinctExpr; + +/* + * NullIfExpr - a NULLIF expression + * + * Like DistinctExpr, this is represented the same as an OpExpr referencing + * the "=" operator for x and y. + */ +typedef OpExpr NullIfExpr; + +/* + * ScalarArrayOpExpr - expression node for "scalar op ANY/ALL (array)" + * + * The operator must yield boolean. It is applied to the left operand + * and each element of the righthand array, and the results are combined + * with OR or AND (for ANY or ALL respectively). The node representation + * is almost the same as for the underlying operator, but we need a useOr + * flag to remember whether it's ANY or ALL, and we don't have to store + * the result type (or the collation) because it must be boolean. + * + * A ScalarArrayOpExpr with a valid hashfuncid is evaluated during execution + * by building a hash table containing the Const values from the RHS arg. + * This table is probed during expression evaluation. The planner will set + * hashfuncid to the hash function which must be used to build and probe the + * hash table. The executor determines if it should use hash-based checks or + * the more traditional means based on if the hashfuncid is set or not. + * + * When performing hashed NOT IN, the negfuncid will also be set to the + * equality function which the hash table must use to build and probe the hash + * table. opno and opfuncid will remain set to the <> operator and its + * corresponding function and won't be used during execution. For + * non-hashtable based NOT INs, negfuncid will be set to InvalidOid. See + * convert_saop_to_hashed_saop(). + * + * Similar to OpExpr, opfuncid, hashfuncid, and negfuncid are not necessarily + * filled in right away, so will be ignored for equality if they are not set + * yet. + * + * OID entries of the internal function types are irrelevant for the query + * jumbling, but the operator OID and the arguments are. + */ +typedef struct ScalarArrayOpExpr +{ + Expr xpr; + + /* PG_OPERATOR OID of the operator */ + Oid opno; + + /* PG_PROC OID of comparison function */ + Oid opfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* PG_PROC OID of hash func or InvalidOid */ + Oid hashfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* PG_PROC OID of negator of opfuncid function or InvalidOid. See above */ + Oid negfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* true for ANY, false for ALL */ + bool useOr; + + /* OID of collation that operator should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + + /* the scalar and array operands */ + List *args; + + /* token location, or -1 if unknown */ + int location; +} ScalarArrayOpExpr; + +/* + * BoolExpr - expression node for the basic Boolean operators AND, OR, NOT + * + * Notice the arguments are given as a List. For NOT, of course the list + * must always have exactly one element. For AND and OR, there can be two + * or more arguments. + */ +typedef enum BoolExprType +{ + AND_EXPR, OR_EXPR, NOT_EXPR +} BoolExprType; + +typedef struct BoolExpr +{ + pg_node_attr(custom_read_write) + + Expr xpr; + BoolExprType boolop; + List *args; /* arguments to this expression */ + int location; /* token location, or -1 if unknown */ +} BoolExpr; + +/* + * SubLink + * + * A SubLink represents a subselect appearing in an expression, and in some + * cases also the combining operator(s) just above it. The subLinkType + * indicates the form of the expression represented: + * EXISTS_SUBLINK EXISTS(SELECT ...) + * ALL_SUBLINK (lefthand) op ALL (SELECT ...) + * ANY_SUBLINK (lefthand) op ANY (SELECT ...) + * ROWCOMPARE_SUBLINK (lefthand) op (SELECT ...) + * EXPR_SUBLINK (SELECT with single targetlist item ...) + * MULTIEXPR_SUBLINK (SELECT with multiple targetlist items ...) + * ARRAY_SUBLINK ARRAY(SELECT with single targetlist item ...) + * CTE_SUBLINK WITH query (never actually part of an expression) + * For ALL, ANY, and ROWCOMPARE, the lefthand is a list of expressions of the + * same length as the subselect's targetlist. ROWCOMPARE will *always* have + * a list with more than one entry; if the subselect has just one target + * then the parser will create an EXPR_SUBLINK instead (and any operator + * above the subselect will be represented separately). + * ROWCOMPARE, EXPR, and MULTIEXPR require the subselect to deliver at most + * one row (if it returns no rows, the result is NULL). + * ALL, ANY, and ROWCOMPARE require the combining operators to deliver boolean + * results. ALL and ANY combine the per-row results using AND and OR + * semantics respectively. + * ARRAY requires just one target column, and creates an array of the target + * column's type using any number of rows resulting from the subselect. + * + * SubLink is classed as an Expr node, but it is not actually executable; + * it must be replaced in the expression tree by a SubPlan node during + * planning. + * + * NOTE: in the raw output of gram.y, testexpr contains just the raw form + * of the lefthand expression (if any), and operName is the String name of + * the combining operator. Also, subselect is a raw parsetree. During parse + * analysis, the parser transforms testexpr into a complete boolean expression + * that compares the lefthand value(s) to PARAM_SUBLINK nodes representing the + * output columns of the subselect. And subselect is transformed to a Query. + * This is the representation seen in saved rules and in the rewriter. + * + * In EXISTS, EXPR, MULTIEXPR, and ARRAY SubLinks, testexpr and operName + * are unused and are always null. + * + * subLinkId is currently used only for MULTIEXPR SubLinks, and is zero in + * other SubLinks. This number identifies different multiple-assignment + * subqueries within an UPDATE statement's SET list. It is unique only + * within a particular targetlist. The output column(s) of the MULTIEXPR + * are referenced by PARAM_MULTIEXPR Params appearing elsewhere in the tlist. + * + * The CTE_SUBLINK case never occurs in actual SubLink nodes, but it is used + * in SubPlans generated for WITH subqueries. + */ +typedef enum SubLinkType +{ + EXISTS_SUBLINK, + ALL_SUBLINK, + ANY_SUBLINK, + ROWCOMPARE_SUBLINK, + EXPR_SUBLINK, + MULTIEXPR_SUBLINK, + ARRAY_SUBLINK, + CTE_SUBLINK /* for SubPlans only */ +} SubLinkType; + + +typedef struct SubLink +{ + Expr xpr; + SubLinkType subLinkType; /* see above */ + int subLinkId; /* ID (1..n); 0 if not MULTIEXPR */ + Node *testexpr; /* outer-query test for ALL/ANY/ROWCOMPARE */ + /* originally specified operator name */ + List *operName pg_node_attr(query_jumble_ignore); + /* subselect as Query* or raw parsetree */ + Node *subselect; + int location; /* token location, or -1 if unknown */ +} SubLink; + +/* + * SubPlan - executable expression node for a subplan (sub-SELECT) + * + * The planner replaces SubLink nodes in expression trees with SubPlan + * nodes after it has finished planning the subquery. SubPlan references + * a sub-plantree stored in the subplans list of the toplevel PlannedStmt. + * (We avoid a direct link to make it easier to copy expression trees + * without causing multiple processing of the subplan.) + * + * In an ordinary subplan, testexpr points to an executable expression + * (OpExpr, an AND/OR tree of OpExprs, or RowCompareExpr) for the combining + * operator(s); the left-hand arguments are the original lefthand expressions, + * and the right-hand arguments are PARAM_EXEC Param nodes representing the + * outputs of the sub-select. (NOTE: runtime coercion functions may be + * inserted as well.) This is just the same expression tree as testexpr in + * the original SubLink node, but the PARAM_SUBLINK nodes are replaced by + * suitably numbered PARAM_EXEC nodes. + * + * If the sub-select becomes an initplan rather than a subplan, the executable + * expression is part of the outer plan's expression tree (and the SubPlan + * node itself is not, but rather is found in the outer plan's initPlan + * list). In this case testexpr is NULL to avoid duplication. + * + * The planner also derives lists of the values that need to be passed into + * and out of the subplan. Input values are represented as a list "args" of + * expressions to be evaluated in the outer-query context (currently these + * args are always just Vars, but in principle they could be any expression). + * The values are assigned to the global PARAM_EXEC params indexed by parParam + * (the parParam and args lists must have the same ordering). setParam is a + * list of the PARAM_EXEC params that are computed by the sub-select, if it + * is an initplan or MULTIEXPR plan; they are listed in order by sub-select + * output column position. (parParam and setParam are integer Lists, not + * Bitmapsets, because their ordering is significant.) + * + * Also, the planner computes startup and per-call costs for use of the + * SubPlan. Note that these include the cost of the subquery proper, + * evaluation of the testexpr if any, and any hashtable management overhead. + */ +typedef struct SubPlan +{ + pg_node_attr(no_query_jumble) + + Expr xpr; + /* Fields copied from original SubLink: */ + SubLinkType subLinkType; /* see above */ + /* The combining operators, transformed to an executable expression: */ + Node *testexpr; /* OpExpr or RowCompareExpr expression tree */ + List *paramIds; /* IDs of Params embedded in the above */ + /* Identification of the Plan tree to use: */ + int plan_id; /* Index (from 1) in PlannedStmt.subplans */ + /* Identification of the SubPlan for EXPLAIN and debugging purposes: */ + char *plan_name; /* A name assigned during planning */ + /* Extra data useful for determining subplan's output type: */ + Oid firstColType; /* Type of first column of subplan result */ + int32 firstColTypmod; /* Typmod of first column of subplan result */ + Oid firstColCollation; /* Collation of first column of subplan + * result */ + /* Information about execution strategy: */ + bool useHashTable; /* true to store subselect output in a hash + * table (implies we are doing "IN") */ + bool unknownEqFalse; /* true if it's okay to return FALSE when the + * spec result is UNKNOWN; this allows much + * simpler handling of null values */ + bool parallel_safe; /* is the subplan parallel-safe? */ + /* Note: parallel_safe does not consider contents of testexpr or args */ + /* Information for passing params into and out of the subselect: */ + /* setParam and parParam are lists of integers (param IDs) */ + List *setParam; /* initplan and MULTIEXPR subqueries have to + * set these Params for parent plan */ + List *parParam; /* indices of input Params from parent plan */ + List *args; /* exprs to pass as parParam values */ + /* Estimated execution costs: */ + Cost startup_cost; /* one-time setup cost */ + Cost per_call_cost; /* cost for each subplan evaluation */ +} SubPlan; + +/* + * AlternativeSubPlan - expression node for a choice among SubPlans + * + * This is used only transiently during planning: by the time the plan + * reaches the executor, all AlternativeSubPlan nodes have been removed. + * + * The subplans are given as a List so that the node definition need not + * change if there's ever more than two alternatives. For the moment, + * though, there are always exactly two; and the first one is the fast-start + * plan. + */ +typedef struct AlternativeSubPlan +{ + pg_node_attr(no_query_jumble) + + Expr xpr; + List *subplans; /* SubPlan(s) with equivalent results */ +} AlternativeSubPlan; + +/* ---------------- + * FieldSelect + * + * FieldSelect represents the operation of extracting one field from a tuple + * value. At runtime, the input expression is expected to yield a rowtype + * Datum. The specified field number is extracted and returned as a Datum. + * ---------------- + */ + +typedef struct FieldSelect +{ + Expr xpr; + Expr *arg; /* input expression */ + AttrNumber fieldnum; /* attribute number of field to extract */ + /* type of the field (result type of this node) */ + Oid resulttype pg_node_attr(query_jumble_ignore); + /* output typmod (usually -1) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation of the field */ + Oid resultcollid pg_node_attr(query_jumble_ignore); +} FieldSelect; + +/* ---------------- + * FieldStore + * + * FieldStore represents the operation of modifying one field in a tuple + * value, yielding a new tuple value (the input is not touched!). Like + * the assign case of SubscriptingRef, this is used to implement UPDATE of a + * portion of a column. + * + * resulttype is always a named composite type (not a domain). To update + * a composite domain value, apply CoerceToDomain to the FieldStore. + * + * A single FieldStore can actually represent updates of several different + * fields. The parser only generates FieldStores with single-element lists, + * but the planner will collapse multiple updates of the same base column + * into one FieldStore. + * ---------------- + */ + +typedef struct FieldStore +{ + Expr xpr; + Expr *arg; /* input tuple value */ + List *newvals; /* new value(s) for field(s) */ + /* integer list of field attnums */ + List *fieldnums pg_node_attr(query_jumble_ignore); + /* type of result (same as type of arg) */ + Oid resulttype pg_node_attr(query_jumble_ignore); + /* Like RowExpr, we deliberately omit a typmod and collation here */ +} FieldStore; + +/* ---------------- + * RelabelType + * + * RelabelType represents a "dummy" type coercion between two binary- + * compatible datatypes, such as reinterpreting the result of an OID + * expression as an int4. It is a no-op at runtime; we only need it + * to provide a place to store the correct type to be attributed to + * the expression result during type resolution. (We can't get away + * with just overwriting the type field of the input expression node, + * so we need a separate node to show the coercion's result type.) + * ---------------- + */ + +typedef struct RelabelType +{ + Expr xpr; + Expr *arg; /* input expression */ + Oid resulttype; /* output type of coercion expression */ + /* output typmod (usually -1) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm relabelformat pg_node_attr(query_jumble_ignore); + int location; /* token location, or -1 if unknown */ +} RelabelType; + +/* ---------------- + * CoerceViaIO + * + * CoerceViaIO represents a type coercion between two types whose textual + * representations are compatible, implemented by invoking the source type's + * typoutput function then the destination type's typinput function. + * ---------------- + */ + +typedef struct CoerceViaIO +{ + Expr xpr; + Expr *arg; /* input expression */ + Oid resulttype; /* output type of coercion */ + /* output typmod is not stored, but is presumed -1 */ + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm coerceformat pg_node_attr(query_jumble_ignore); + int location; /* token location, or -1 if unknown */ +} CoerceViaIO; + +/* ---------------- + * ArrayCoerceExpr + * + * ArrayCoerceExpr represents a type coercion from one array type to another, + * which is implemented by applying the per-element coercion expression + * "elemexpr" to each element of the source array. Within elemexpr, the + * source element is represented by a CaseTestExpr node. Note that even if + * elemexpr is a no-op (that is, just CaseTestExpr + RelabelType), the + * coercion still requires some effort: we have to fix the element type OID + * stored in the array header. + * ---------------- + */ + +typedef struct ArrayCoerceExpr +{ + Expr xpr; + Expr *arg; /* input expression (yields an array) */ + Expr *elemexpr; /* expression representing per-element work */ + Oid resulttype; /* output type of coercion (an array type) */ + /* output typmod (also element typmod) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm coerceformat pg_node_attr(query_jumble_ignore); + int location; /* token location, or -1 if unknown */ +} ArrayCoerceExpr; + +/* ---------------- + * ConvertRowtypeExpr + * + * ConvertRowtypeExpr represents a type coercion from one composite type + * to another, where the source type is guaranteed to contain all the columns + * needed for the destination type plus possibly others; the columns need not + * be in the same positions, but are matched up by name. This is primarily + * used to convert a whole-row value of an inheritance child table into a + * valid whole-row value of its parent table's rowtype. Both resulttype + * and the exposed type of "arg" must be named composite types (not domains). + * ---------------- + */ + +typedef struct ConvertRowtypeExpr +{ + Expr xpr; + Expr *arg; /* input expression */ + Oid resulttype; /* output type (always a composite type) */ + /* Like RowExpr, we deliberately omit a typmod and collation here */ + /* how to display this node */ + CoercionForm convertformat pg_node_attr(query_jumble_ignore); + int location; /* token location, or -1 if unknown */ +} ConvertRowtypeExpr; + +/*---------- + * CollateExpr - COLLATE + * + * The planner replaces CollateExpr with RelabelType during expression + * preprocessing, so execution never sees a CollateExpr. + *---------- + */ +typedef struct CollateExpr +{ + Expr xpr; + Expr *arg; /* input expression */ + Oid collOid; /* collation's OID */ + int location; /* token location, or -1 if unknown */ +} CollateExpr; + +/*---------- + * CaseExpr - a CASE expression + * + * We support two distinct forms of CASE expression: + * CASE WHEN boolexpr THEN expr [ WHEN boolexpr THEN expr ... ] + * CASE testexpr WHEN compexpr THEN expr [ WHEN compexpr THEN expr ... ] + * These are distinguishable by the "arg" field being NULL in the first case + * and the testexpr in the second case. + * + * In the raw grammar output for the second form, the condition expressions + * of the WHEN clauses are just the comparison values. Parse analysis + * converts these to valid boolean expressions of the form + * CaseTestExpr '=' compexpr + * where the CaseTestExpr node is a placeholder that emits the correct + * value at runtime. This structure is used so that the testexpr need be + * evaluated only once. Note that after parse analysis, the condition + * expressions always yield boolean. + * + * Note: we can test whether a CaseExpr has been through parse analysis + * yet by checking whether casetype is InvalidOid or not. + *---------- + */ +typedef struct CaseExpr +{ + Expr xpr; + /* type of expression result */ + Oid casetype pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid casecollid pg_node_attr(query_jumble_ignore); + Expr *arg; /* implicit equality comparison argument */ + List *args; /* the arguments (list of WHEN clauses) */ + Expr *defresult; /* the default result (ELSE clause) */ + int location; /* token location, or -1 if unknown */ +} CaseExpr; + +/* + * CaseWhen - one arm of a CASE expression + */ +typedef struct CaseWhen +{ + Expr xpr; + Expr *expr; /* condition expression */ + Expr *result; /* substitution result */ + int location; /* token location, or -1 if unknown */ +} CaseWhen; + +/* + * Placeholder node for the test value to be processed by a CASE expression. + * This is effectively like a Param, but can be implemented more simply + * since we need only one replacement value at a time. + * + * We also abuse this node type for some other purposes, including: + * * Placeholder for the current array element value in ArrayCoerceExpr; + * see build_coercion_expression(). + * * Nested FieldStore/SubscriptingRef assignment expressions in INSERT/UPDATE; + * see transformAssignmentIndirection(). + * * Placeholder for intermediate results in some SQL/JSON expression nodes, + * such as JsonConstructorExpr. + * + * The uses in CaseExpr and ArrayCoerceExpr are safe only to the extent that + * there is not any other CaseExpr or ArrayCoerceExpr between the value source + * node and its child CaseTestExpr(s). This is true in the parse analysis + * output, but the planner's function-inlining logic has to be careful not to + * break it. + * + * The nested-assignment-expression case is safe because the only node types + * that can be above such CaseTestExprs are FieldStore and SubscriptingRef. + */ +typedef struct CaseTestExpr +{ + Expr xpr; + Oid typeId; /* type for substituted value */ + /* typemod for substituted value */ + int32 typeMod pg_node_attr(query_jumble_ignore); + /* collation for the substituted value */ + Oid collation pg_node_attr(query_jumble_ignore); +} CaseTestExpr; + +/* + * ArrayExpr - an ARRAY[] expression + * + * Note: if multidims is false, the constituent expressions all yield the + * scalar type identified by element_typeid. If multidims is true, the + * constituent expressions all yield arrays of element_typeid (ie, the same + * type as array_typeid); at runtime we must check for compatible subscripts. + */ +typedef struct ArrayExpr +{ + Expr xpr; + /* type of expression result */ + Oid array_typeid pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid array_collid pg_node_attr(query_jumble_ignore); + /* common type of array elements */ + Oid element_typeid pg_node_attr(query_jumble_ignore); + /* the array elements or sub-arrays */ + List *elements; + /* true if elements are sub-arrays */ + bool multidims pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location; +} ArrayExpr; + +/* + * RowExpr - a ROW() expression + * + * Note: the list of fields must have a one-for-one correspondence with + * physical fields of the associated rowtype, although it is okay for it + * to be shorter than the rowtype. That is, the N'th list element must + * match up with the N'th physical field. When the N'th physical field + * is a dropped column (attisdropped) then the N'th list element can just + * be a NULL constant. (This case can only occur for named composite types, + * not RECORD types, since those are built from the RowExpr itself rather + * than vice versa.) It is important not to assume that length(args) is + * the same as the number of columns logically present in the rowtype. + * + * colnames provides field names if the ROW() result is of type RECORD. + * Names *must* be provided if row_typeid is RECORDOID; but if it is a + * named composite type, colnames will be ignored in favor of using the + * type's cataloged field names, so colnames should be NIL. Like the + * args list, colnames is defined to be one-for-one with physical fields + * of the rowtype (although dropped columns shouldn't appear in the + * RECORD case, so this fine point is currently moot). + */ +typedef struct RowExpr +{ + Expr xpr; + List *args; /* the fields */ + + /* RECORDOID or a composite type's ID */ + Oid row_typeid pg_node_attr(query_jumble_ignore); + + /* + * row_typeid cannot be a domain over composite, only plain composite. To + * create a composite domain value, apply CoerceToDomain to the RowExpr. + * + * Note: we deliberately do NOT store a typmod. Although a typmod will be + * associated with specific RECORD types at runtime, it will differ for + * different backends, and so cannot safely be stored in stored + * parsetrees. We must assume typmod -1 for a RowExpr node. + * + * We don't need to store a collation either. The result type is + * necessarily composite, and composite types never have a collation. + */ + + /* how to display this node */ + CoercionForm row_format pg_node_attr(query_jumble_ignore); + + /* list of String, or NIL */ + List *colnames pg_node_attr(query_jumble_ignore); + + int location; /* token location, or -1 if unknown */ +} RowExpr; + +/* + * RowCompareExpr - row-wise comparison, such as (a, b) <= (1, 2) + * + * We support row comparison for any operator that can be determined to + * act like =, <>, <, <=, >, or >= (we determine this by looking for the + * operator in btree opfamilies). Note that the same operator name might + * map to a different operator for each pair of row elements, since the + * element datatypes can vary. + * + * A RowCompareExpr node is only generated for the < <= > >= cases; + * the = and <> cases are translated to simple AND or OR combinations + * of the pairwise comparisons. However, we include = and <> in the + * RowCompareType enum for the convenience of parser logic. + */ +typedef enum RowCompareType +{ + /* Values of this enum are chosen to match btree strategy numbers */ + ROWCOMPARE_LT = 1, /* BTLessStrategyNumber */ + ROWCOMPARE_LE = 2, /* BTLessEqualStrategyNumber */ + ROWCOMPARE_EQ = 3, /* BTEqualStrategyNumber */ + ROWCOMPARE_GE = 4, /* BTGreaterEqualStrategyNumber */ + ROWCOMPARE_GT = 5, /* BTGreaterStrategyNumber */ + ROWCOMPARE_NE = 6 /* no such btree strategy */ +} RowCompareType; + +typedef struct RowCompareExpr +{ + Expr xpr; + + /* LT LE GE or GT, never EQ or NE */ + RowCompareType rctype; + /* OID list of pairwise comparison ops */ + List *opnos pg_node_attr(query_jumble_ignore); + /* OID list of containing operator families */ + List *opfamilies pg_node_attr(query_jumble_ignore); + /* OID list of collations for comparisons */ + List *inputcollids pg_node_attr(query_jumble_ignore); + /* the left-hand input arguments */ + List *largs; + /* the right-hand input arguments */ + List *rargs; +} RowCompareExpr; + +/* + * CoalesceExpr - a COALESCE expression + */ +typedef struct CoalesceExpr +{ + Expr xpr; + /* type of expression result */ + Oid coalescetype pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid coalescecollid pg_node_attr(query_jumble_ignore); + /* the arguments */ + List *args; + /* token location, or -1 if unknown */ + int location; +} CoalesceExpr; + +/* + * MinMaxExpr - a GREATEST or LEAST function + */ +typedef enum MinMaxOp +{ + IS_GREATEST, + IS_LEAST +} MinMaxOp; + +typedef struct MinMaxExpr +{ + Expr xpr; + /* common type of arguments and result */ + Oid minmaxtype pg_node_attr(query_jumble_ignore); + /* OID of collation of result */ + Oid minmaxcollid pg_node_attr(query_jumble_ignore); + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + /* function to execute */ + MinMaxOp op; + /* the arguments */ + List *args; + /* token location, or -1 if unknown */ + int location; +} MinMaxExpr; + +/* + * SQLValueFunction - parameterless functions with special grammar productions + * + * The SQL standard categorizes some of these as + * and others as . We call 'em SQLValueFunctions + * for lack of a better term. We store type and typmod of the result so that + * some code doesn't need to know each function individually, and because + * we would need to store typmod anyway for some of the datetime functions. + * Note that currently, all variants return non-collating datatypes, so we do + * not need a collation field; also, all these functions are stable. + */ +typedef enum SQLValueFunctionOp +{ + SVFOP_CURRENT_DATE, + SVFOP_CURRENT_TIME, + SVFOP_CURRENT_TIME_N, + SVFOP_CURRENT_TIMESTAMP, + SVFOP_CURRENT_TIMESTAMP_N, + SVFOP_LOCALTIME, + SVFOP_LOCALTIME_N, + SVFOP_LOCALTIMESTAMP, + SVFOP_LOCALTIMESTAMP_N, + SVFOP_CURRENT_ROLE, + SVFOP_CURRENT_USER, + SVFOP_USER, + SVFOP_SESSION_USER, + SVFOP_CURRENT_CATALOG, + SVFOP_CURRENT_SCHEMA +} SQLValueFunctionOp; + +typedef struct SQLValueFunction +{ + Expr xpr; + SQLValueFunctionOp op; /* which function this is */ + + /* + * Result type/typmod. Type is fully determined by "op", so no need to + * include this Oid in the query jumbling. + */ + Oid type pg_node_attr(query_jumble_ignore); + int32 typmod; + int location; /* token location, or -1 if unknown */ +} SQLValueFunction; + +/* + * XmlExpr - various SQL/XML functions requiring special grammar productions + * + * 'name' carries the "NAME foo" argument (already XML-escaped). + * 'named_args' and 'arg_names' represent an xml_attribute list. + * 'args' carries all other arguments. + * + * Note: result type/typmod/collation are not stored, but can be deduced + * from the XmlExprOp. The type/typmod fields are just used for display + * purposes, and are NOT necessarily the true result type of the node. + */ +typedef enum XmlExprOp +{ + IS_XMLCONCAT, /* XMLCONCAT(args) */ + IS_XMLELEMENT, /* XMLELEMENT(name, xml_attributes, args) */ + IS_XMLFOREST, /* XMLFOREST(xml_attributes) */ + IS_XMLPARSE, /* XMLPARSE(text, is_doc, preserve_ws) */ + IS_XMLPI, /* XMLPI(name [, args]) */ + IS_XMLROOT, /* XMLROOT(xml, version, standalone) */ + IS_XMLSERIALIZE, /* XMLSERIALIZE(is_document, xmlval, indent) */ + IS_DOCUMENT /* xmlval IS DOCUMENT */ +} XmlExprOp; + +typedef enum XmlOptionType +{ + XMLOPTION_DOCUMENT, + XMLOPTION_CONTENT +} XmlOptionType; + +typedef struct XmlExpr +{ + Expr xpr; + /* xml function ID */ + XmlExprOp op; + /* name in xml(NAME foo ...) syntaxes */ + char *name pg_node_attr(query_jumble_ignore); + /* non-XML expressions for xml_attributes */ + List *named_args; + /* parallel list of String values */ + List *arg_names pg_node_attr(query_jumble_ignore); + /* list of expressions */ + List *args; + /* DOCUMENT or CONTENT */ + XmlOptionType xmloption pg_node_attr(query_jumble_ignore); + /* INDENT option for XMLSERIALIZE */ + bool indent; + /* target type/typmod for XMLSERIALIZE */ + Oid type pg_node_attr(query_jumble_ignore); + int32 typmod pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location; +} XmlExpr; + +/* + * JsonEncoding - + * representation of JSON ENCODING clause + */ +typedef enum JsonEncoding +{ + JS_ENC_DEFAULT, /* unspecified */ + JS_ENC_UTF8, + JS_ENC_UTF16, + JS_ENC_UTF32, +} JsonEncoding; + +/* + * JsonFormatType - + * enumeration of JSON formats used in JSON FORMAT clause + */ +typedef enum JsonFormatType +{ + JS_FORMAT_DEFAULT, /* unspecified */ + JS_FORMAT_JSON, /* FORMAT JSON [ENCODING ...] */ + JS_FORMAT_JSONB /* implicit internal format for RETURNING + * jsonb */ +} JsonFormatType; + +/* + * JsonFormat - + * representation of JSON FORMAT clause + */ +typedef struct JsonFormat +{ + NodeTag type; + JsonFormatType format_type; /* format type */ + JsonEncoding encoding; /* JSON encoding */ + int location; /* token location, or -1 if unknown */ +} JsonFormat; + +/* + * JsonReturning - + * transformed representation of JSON RETURNING clause + */ +typedef struct JsonReturning +{ + NodeTag type; + JsonFormat *format; /* output JSON format */ + Oid typid; /* target type Oid */ + int32 typmod; /* target type modifier */ +} JsonReturning; + +/* + * JsonValueExpr - + * representation of JSON value expression (expr [FORMAT JsonFormat]) + * + * raw_expr is the user-specified value, while formatted_expr is the value + * obtained by coercing raw_expr to the type required by either the FORMAT + * clause or an enclosing node's RETURNING clause. + * + * When deparsing a JsonValueExpr, get_rule_expr() prints raw_expr. However, + * during the evaluation of a JsonValueExpr, the value of formatted_expr + * takes precedence over that of raw_expr. + */ +typedef struct JsonValueExpr +{ + NodeTag type; + Expr *raw_expr; /* user-specified expression */ + Expr *formatted_expr; /* coerced formatted expression */ + JsonFormat *format; /* FORMAT clause, if specified */ +} JsonValueExpr; + +typedef enum JsonConstructorType +{ + JSCTOR_JSON_OBJECT = 1, + JSCTOR_JSON_ARRAY = 2, + JSCTOR_JSON_OBJECTAGG = 3, + JSCTOR_JSON_ARRAYAGG = 4 +} JsonConstructorType; + +/* + * JsonConstructorExpr - + * wrapper over FuncExpr/Aggref/WindowFunc for SQL/JSON constructors + */ +typedef struct JsonConstructorExpr +{ + Expr xpr; + JsonConstructorType type; /* constructor type */ + List *args; + Expr *func; /* underlying json[b]_xxx() function call */ + Expr *coercion; /* coercion to RETURNING type */ + JsonReturning *returning; /* RETURNING clause */ + bool absent_on_null; /* ABSENT ON NULL? */ + bool unique; /* WITH UNIQUE KEYS? (JSON_OBJECT[AGG] only) */ + int location; +} JsonConstructorExpr; + +/* + * JsonValueType - + * representation of JSON item type in IS JSON predicate + */ +typedef enum JsonValueType +{ + JS_TYPE_ANY, /* IS JSON [VALUE] */ + JS_TYPE_OBJECT, /* IS JSON OBJECT */ + JS_TYPE_ARRAY, /* IS JSON ARRAY */ + JS_TYPE_SCALAR /* IS JSON SCALAR */ +} JsonValueType; + +/* + * JsonIsPredicate - + * representation of IS JSON predicate + */ +typedef struct JsonIsPredicate +{ + NodeTag type; + Node *expr; /* subject expression */ + JsonFormat *format; /* FORMAT clause, if specified */ + JsonValueType item_type; /* JSON item type */ + bool unique_keys; /* check key uniqueness? */ + int location; /* token location, or -1 if unknown */ +} JsonIsPredicate; + +/* ---------------- + * NullTest + * + * NullTest represents the operation of testing a value for NULLness. + * The appropriate test is performed and returned as a boolean Datum. + * + * When argisrow is false, this simply represents a test for the null value. + * + * When argisrow is true, the input expression must yield a rowtype, and + * the node implements "row IS [NOT] NULL" per the SQL standard. This + * includes checking individual fields for NULLness when the row datum + * itself isn't NULL. + * + * NOTE: the combination of a rowtype input and argisrow==false does NOT + * correspond to the SQL notation "row IS [NOT] NULL"; instead, this case + * represents the SQL notation "row IS [NOT] DISTINCT FROM NULL". + * ---------------- + */ + +typedef enum NullTestType +{ + IS_NULL, IS_NOT_NULL +} NullTestType; + +typedef struct NullTest +{ + Expr xpr; + Expr *arg; /* input expression */ + NullTestType nulltesttype; /* IS NULL, IS NOT NULL */ + /* T to perform field-by-field null checks */ + bool argisrow pg_node_attr(query_jumble_ignore); + int location; /* token location, or -1 if unknown */ +} NullTest; + +/* + * BooleanTest + * + * BooleanTest represents the operation of determining whether a boolean + * is TRUE, FALSE, or UNKNOWN (ie, NULL). All six meaningful combinations + * are supported. Note that a NULL input does *not* cause a NULL result. + * The appropriate test is performed and returned as a boolean Datum. + */ + +typedef enum BoolTestType +{ + IS_TRUE, IS_NOT_TRUE, IS_FALSE, IS_NOT_FALSE, IS_UNKNOWN, IS_NOT_UNKNOWN +} BoolTestType; + +typedef struct BooleanTest +{ + Expr xpr; + Expr *arg; /* input expression */ + BoolTestType booltesttype; /* test type */ + int location; /* token location, or -1 if unknown */ +} BooleanTest; + +/* + * CoerceToDomain + * + * CoerceToDomain represents the operation of coercing a value to a domain + * type. At runtime (and not before) the precise set of constraints to be + * checked will be determined. If the value passes, it is returned as the + * result; if not, an error is raised. Note that this is equivalent to + * RelabelType in the scenario where no constraints are applied. + */ +typedef struct CoerceToDomain +{ + Expr xpr; + Expr *arg; /* input expression */ + Oid resulttype; /* domain type ID (result type) */ + /* output typmod (currently always -1) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm coercionformat pg_node_attr(query_jumble_ignore); + int location; /* token location, or -1 if unknown */ +} CoerceToDomain; + +/* + * Placeholder node for the value to be processed by a domain's check + * constraint. This is effectively like a Param, but can be implemented more + * simply since we need only one replacement value at a time. + * + * Note: the typeId/typeMod/collation will be set from the domain's base type, + * not the domain itself. This is because we shouldn't consider the value + * to be a member of the domain if we haven't yet checked its constraints. + */ +typedef struct CoerceToDomainValue +{ + Expr xpr; + /* type for substituted value */ + Oid typeId; + /* typemod for substituted value */ + int32 typeMod pg_node_attr(query_jumble_ignore); + /* collation for the substituted value */ + Oid collation pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location; +} CoerceToDomainValue; + +/* + * Placeholder node for a DEFAULT marker in an INSERT or UPDATE command. + * + * This is not an executable expression: it must be replaced by the actual + * column default expression during rewriting. But it is convenient to + * treat it as an expression node during parsing and rewriting. + */ +typedef struct SetToDefault +{ + Expr xpr; + /* type for substituted value */ + Oid typeId; + /* typemod for substituted value */ + int32 typeMod pg_node_attr(query_jumble_ignore); + /* collation for the substituted value */ + Oid collation pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location; +} SetToDefault; + +/* + * Node representing [WHERE] CURRENT OF cursor_name + * + * CURRENT OF is a bit like a Var, in that it carries the rangetable index + * of the target relation being constrained; this aids placing the expression + * correctly during planning. We can assume however that its "levelsup" is + * always zero, due to the syntactic constraints on where it can appear. + * Also, cvarno will always be a true RT index, never INNER_VAR etc. + * + * The referenced cursor can be represented either as a hardwired string + * or as a reference to a run-time parameter of type REFCURSOR. The latter + * case is for the convenience of plpgsql. + */ +typedef struct CurrentOfExpr +{ + Expr xpr; + Index cvarno; /* RT index of target relation */ + char *cursor_name; /* name of referenced cursor, or NULL */ + int cursor_param; /* refcursor parameter number, or 0 */ +} CurrentOfExpr; + +/* + * NextValueExpr - get next value from sequence + * + * This has the same effect as calling the nextval() function, but it does not + * check permissions on the sequence. This is used for identity columns, + * where the sequence is an implicit dependency without its own permissions. + */ +typedef struct NextValueExpr +{ + Expr xpr; + Oid seqid; + Oid typeId; +} NextValueExpr; + +/* + * InferenceElem - an element of a unique index inference specification + * + * This mostly matches the structure of IndexElems, but having a dedicated + * primnode allows for a clean separation between the use of index parameters + * by utility commands, and this node. + */ +typedef struct InferenceElem +{ + Expr xpr; + Node *expr; /* expression to infer from, or NULL */ + Oid infercollid; /* OID of collation, or InvalidOid */ + Oid inferopclass; /* OID of att opclass, or InvalidOid */ +} InferenceElem; + +/*-------------------- + * TargetEntry - + * a target entry (used in query target lists) + * + * Strictly speaking, a TargetEntry isn't an expression node (since it can't + * be evaluated by ExecEvalExpr). But we treat it as one anyway, since in + * very many places it's convenient to process a whole query targetlist as a + * single expression tree. + * + * In a SELECT's targetlist, resno should always be equal to the item's + * ordinal position (counting from 1). However, in an INSERT or UPDATE + * targetlist, resno represents the attribute number of the destination + * column for the item; so there may be missing or out-of-order resnos. + * It is even legal to have duplicated resnos; consider + * UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ... + * In an INSERT, the rewriter and planner will normalize the tlist by + * reordering it into physical column order and filling in default values + * for any columns not assigned values by the original query. In an UPDATE, + * after the rewriter merges multiple assignments for the same column, the + * planner extracts the target-column numbers into a separate "update_colnos" + * list, and then renumbers the tlist elements serially. Thus, tlist resnos + * match ordinal position in all tlists seen by the executor; but it is wrong + * to assume that before planning has happened. + * + * resname is required to represent the correct column name in non-resjunk + * entries of top-level SELECT targetlists, since it will be used as the + * column title sent to the frontend. In most other contexts it is only + * a debugging aid, and may be wrong or even NULL. (In particular, it may + * be wrong in a tlist from a stored rule, if the referenced column has been + * renamed by ALTER TABLE since the rule was made. Also, the planner tends + * to store NULL rather than look up a valid name for tlist entries in + * non-toplevel plan nodes.) In resjunk entries, resname should be either + * a specific system-generated name (such as "ctid") or NULL; anything else + * risks confusing ExecGetJunkAttribute! + * + * ressortgroupref is used in the representation of ORDER BY, GROUP BY, and + * DISTINCT items. Targetlist entries with ressortgroupref=0 are not + * sort/group items. If ressortgroupref>0, then this item is an ORDER BY, + * GROUP BY, and/or DISTINCT target value. No two entries in a targetlist + * may have the same nonzero ressortgroupref --- but there is no particular + * meaning to the nonzero values, except as tags. (For example, one must + * not assume that lower ressortgroupref means a more significant sort key.) + * The order of the associated SortGroupClause lists determine the semantics. + * + * resorigtbl/resorigcol identify the source of the column, if it is a + * simple reference to a column of a base table (or view). If it is not + * a simple reference, these fields are zeroes. + * + * If resjunk is true then the column is a working column (such as a sort key) + * that should be removed from the final output of the query. Resjunk columns + * must have resnos that cannot duplicate any regular column's resno. Also + * note that there are places that assume resjunk columns come after non-junk + * columns. + *-------------------- + */ +typedef struct TargetEntry +{ + Expr xpr; + /* expression to evaluate */ + Expr *expr; + /* attribute number (see notes above) */ + AttrNumber resno; + /* name of the column (could be NULL) */ + char *resname pg_node_attr(query_jumble_ignore); + /* nonzero if referenced by a sort/group clause */ + Index ressortgroupref; + /* OID of column's source table */ + Oid resorigtbl pg_node_attr(query_jumble_ignore); + /* column's number in source table */ + AttrNumber resorigcol pg_node_attr(query_jumble_ignore); + /* set to true to eliminate the attribute from final target list */ + bool resjunk pg_node_attr(query_jumble_ignore); +} TargetEntry; + + +/* ---------------------------------------------------------------- + * node types for join trees + * + * The leaves of a join tree structure are RangeTblRef nodes. Above + * these, JoinExpr nodes can appear to denote a specific kind of join + * or qualified join. Also, FromExpr nodes can appear to denote an + * ordinary cross-product join ("FROM foo, bar, baz WHERE ..."). + * FromExpr is like a JoinExpr of jointype JOIN_INNER, except that it + * may have any number of child nodes, not just two. + * + * NOTE: the top level of a Query's jointree is always a FromExpr. + * Even if the jointree contains no rels, there will be a FromExpr. + * + * NOTE: the qualification expressions present in JoinExpr nodes are + * *in addition to* the query's main WHERE clause, which appears as the + * qual of the top-level FromExpr. The reason for associating quals with + * specific nodes in the jointree is that the position of a qual is critical + * when outer joins are present. (If we enforce a qual too soon or too late, + * that may cause the outer join to produce the wrong set of NULL-extended + * rows.) If all joins are inner joins then all the qual positions are + * semantically interchangeable. + * + * NOTE: in the raw output of gram.y, a join tree contains RangeVar, + * RangeSubselect, and RangeFunction nodes, which are all replaced by + * RangeTblRef nodes during the parse analysis phase. Also, the top-level + * FromExpr is added during parse analysis; the grammar regards FROM and + * WHERE as separate. + * ---------------------------------------------------------------- + */ + +/* + * RangeTblRef - reference to an entry in the query's rangetable + * + * We could use direct pointers to the RT entries and skip having these + * nodes, but multiple pointers to the same node in a querytree cause + * lots of headaches, so it seems better to store an index into the RT. + */ +typedef struct RangeTblRef +{ + NodeTag type; + int rtindex; +} RangeTblRef; + +/*---------- + * JoinExpr - for SQL JOIN expressions + * + * isNatural, usingClause, and quals are interdependent. The user can write + * only one of NATURAL, USING(), or ON() (this is enforced by the grammar). + * If he writes NATURAL then parse analysis generates the equivalent USING() + * list, and from that fills in "quals" with the right equality comparisons. + * If he writes USING() then "quals" is filled with equality comparisons. + * If he writes ON() then only "quals" is set. Note that NATURAL/USING + * are not equivalent to ON() since they also affect the output column list. + * + * alias is an Alias node representing the AS alias-clause attached to the + * join expression, or NULL if no clause. NB: presence or absence of the + * alias has a critical impact on semantics, because a join with an alias + * restricts visibility of the tables/columns inside it. + * + * join_using_alias is an Alias node representing the join correlation + * name that SQL:2016 and later allow to be attached to JOIN/USING. + * Its column alias list includes only the common column names from USING, + * and it does not restrict visibility of the join's input tables. + * + * During parse analysis, an RTE is created for the Join, and its index + * is filled into rtindex. This RTE is present mainly so that Vars can + * be created that refer to the outputs of the join. The planner sometimes + * generates JoinExprs internally; these can have rtindex = 0 if there are + * no join alias variables referencing such joins. + *---------- + */ +typedef struct JoinExpr +{ + NodeTag type; + JoinType jointype; /* type of join */ + bool isNatural; /* Natural join? Will need to shape table */ + Node *larg; /* left subtree */ + Node *rarg; /* right subtree */ + /* USING clause, if any (list of String) */ + List *usingClause pg_node_attr(query_jumble_ignore); + /* alias attached to USING clause, if any */ + Alias *join_using_alias pg_node_attr(query_jumble_ignore); + /* qualifiers on join, if any */ + Node *quals; + /* user-written alias clause, if any */ + Alias *alias pg_node_attr(query_jumble_ignore); + /* RT index assigned for join, or 0 */ + int rtindex; +} JoinExpr; + +/*---------- + * FromExpr - represents a FROM ... WHERE ... construct + * + * This is both more flexible than a JoinExpr (it can have any number of + * children, including zero) and less so --- we don't need to deal with + * aliases and so on. The output column set is implicitly just the union + * of the outputs of the children. + *---------- + */ +typedef struct FromExpr +{ + NodeTag type; + List *fromlist; /* List of join subtrees */ + Node *quals; /* qualifiers on join, if any */ +} FromExpr; + +/*---------- + * OnConflictExpr - represents an ON CONFLICT DO ... expression + * + * The optimizer requires a list of inference elements, and optionally a WHERE + * clause to infer a unique index. The unique index (or, occasionally, + * indexes) inferred are used to arbitrate whether or not the alternative ON + * CONFLICT path is taken. + *---------- + */ +typedef struct OnConflictExpr +{ + NodeTag type; + OnConflictAction action; /* DO NOTHING or UPDATE? */ + + /* Arbiter */ + List *arbiterElems; /* unique index arbiter list (of + * InferenceElem's) */ + Node *arbiterWhere; /* unique index arbiter WHERE clause */ + Oid constraint; /* pg_constraint OID for arbiter */ + + /* ON CONFLICT UPDATE */ + List *onConflictSet; /* List of ON CONFLICT SET TargetEntrys */ + Node *onConflictWhere; /* qualifiers to restrict UPDATE to */ + int exclRelIndex; /* RT index of 'excluded' relation */ + List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */ +} OnConflictExpr; + +#endif /* PRIMNODES_H */ diff --git a/install/include/postgresql/server/nodes/print.h b/install/include/postgresql/server/nodes/print.h new file mode 100644 index 00000000000..3c0473fd4c2 --- /dev/null +++ b/install/include/postgresql/server/nodes/print.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * print.h + * definitions for nodes/print.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/print.h + * + *------------------------------------------------------------------------- + */ +#ifndef PRINT_H +#define PRINT_H + +#include "executor/tuptable.h" + + +#define nodeDisplay(x) pprint(x) + +extern void print(const void *obj); +extern void pprint(const void *obj); +extern void elog_node_display(int lev, const char *title, + const void *obj, bool pretty); +extern char *format_node_dump(const char *dump); +extern char *pretty_format_node_dump(const char *dump); +extern void print_rt(const List *rtable); +extern void print_expr(const Node *expr, const List *rtable); +extern void print_pathkeys(const List *pathkeys, const List *rtable); +extern void print_tl(const List *tlist, const List *rtable); +extern void print_slot(TupleTableSlot *slot); + +#endif /* PRINT_H */ diff --git a/install/include/postgresql/server/nodes/queryjumble.h b/install/include/postgresql/server/nodes/queryjumble.h new file mode 100644 index 00000000000..7649e095aa5 --- /dev/null +++ b/install/include/postgresql/server/nodes/queryjumble.h @@ -0,0 +1,86 @@ +/*------------------------------------------------------------------------- + * + * queryjumble.h + * Query normalization and fingerprinting. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/nodes/queryjumble.h + * + *------------------------------------------------------------------------- + */ +#ifndef QUERYJUMBLE_H +#define QUERYJUMBLE_H + +#include "nodes/parsenodes.h" + +/* + * Struct for tracking locations/lengths of constants during normalization + */ +typedef struct LocationLen +{ + int location; /* start offset in query text */ + int length; /* length in bytes, or -1 to ignore */ +} LocationLen; + +/* + * Working state for computing a query jumble and producing a normalized + * query string + */ +typedef struct JumbleState +{ + /* 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 */ + LocationLen *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; +} JumbleState; + +/* Values for the compute_query_id GUC */ +enum ComputeQueryIdType +{ + COMPUTE_QUERY_ID_OFF, + COMPUTE_QUERY_ID_ON, + COMPUTE_QUERY_ID_AUTO, + COMPUTE_QUERY_ID_REGRESS +}; + +/* GUC parameters */ +extern PGDLLIMPORT int compute_query_id; + + +extern const char *CleanQuerytext(const char *query, int *location, int *len); +extern JumbleState *JumbleQuery(Query *query); +extern void EnableQueryId(void); + +extern PGDLLIMPORT bool query_id_enabled; + +/* + * Returns whether query identifier computation has been enabled, either + * directly in the GUC or by a module when the setting is 'auto'. + */ +static inline bool +IsQueryIdEnabled(void) +{ + if (compute_query_id == COMPUTE_QUERY_ID_OFF) + return false; + if (compute_query_id == COMPUTE_QUERY_ID_ON) + return true; + return query_id_enabled; +} + +#endif /* QUERYJUMBLE_H */ diff --git a/install/include/postgresql/server/nodes/readfuncs.h b/install/include/postgresql/server/nodes/readfuncs.h new file mode 100644 index 00000000000..cba6f0be75a --- /dev/null +++ b/install/include/postgresql/server/nodes/readfuncs.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * readfuncs.h + * header file for read.c and readfuncs.c. These functions are internal + * to the stringToNode interface and should not be used by anyone else. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/readfuncs.h + * + *------------------------------------------------------------------------- + */ +#ifndef READFUNCS_H +#define READFUNCS_H + +#include "nodes/nodes.h" + +/* + * variable in read.c that needs to be accessible to readfuncs.c + */ +#ifdef WRITE_READ_PARSE_PLAN_TREES +extern PGDLLIMPORT bool restore_location_fields; +#endif + +/* + * prototypes for functions in read.c (the lisp token parser) + */ +extern const char *pg_strtok(int *length); +extern char *debackslash(const char *token, int length); +extern void *nodeRead(const char *token, int tok_len); + +/* + * prototypes for functions in readfuncs.c + */ +extern Node *parseNodeString(void); + +#endif /* READFUNCS_H */ diff --git a/install/include/postgresql/server/nodes/replnodes.h b/install/include/postgresql/server/nodes/replnodes.h new file mode 100644 index 00000000000..4321ba8f866 --- /dev/null +++ b/install/include/postgresql/server/nodes/replnodes.h @@ -0,0 +1,111 @@ +/*------------------------------------------------------------------------- + * + * replnodes.h + * definitions for replication grammar parse nodes + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/replnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef REPLNODES_H +#define REPLNODES_H + +#include "access/xlogdefs.h" +#include "nodes/pg_list.h" + +typedef enum ReplicationKind +{ + REPLICATION_KIND_PHYSICAL, + REPLICATION_KIND_LOGICAL +} ReplicationKind; + + +/* ---------------------- + * IDENTIFY_SYSTEM command + * ---------------------- + */ +typedef struct IdentifySystemCmd +{ + NodeTag type; +} IdentifySystemCmd; + + +/* ---------------------- + * BASE_BACKUP command + * ---------------------- + */ +typedef struct BaseBackupCmd +{ + NodeTag type; + List *options; +} BaseBackupCmd; + + +/* ---------------------- + * CREATE_REPLICATION_SLOT command + * ---------------------- + */ +typedef struct CreateReplicationSlotCmd +{ + NodeTag type; + char *slotname; + ReplicationKind kind; + char *plugin; + bool temporary; + List *options; +} CreateReplicationSlotCmd; + + +/* ---------------------- + * DROP_REPLICATION_SLOT command + * ---------------------- + */ +typedef struct DropReplicationSlotCmd +{ + NodeTag type; + char *slotname; + bool wait; +} DropReplicationSlotCmd; + + +/* ---------------------- + * START_REPLICATION command + * ---------------------- + */ +typedef struct StartReplicationCmd +{ + NodeTag type; + ReplicationKind kind; + char *slotname; + TimeLineID timeline; + XLogRecPtr startpoint; + List *options; +} StartReplicationCmd; + + +/* ---------------------- + * READ_REPLICATION_SLOT command + * ---------------------- + */ +typedef struct ReadReplicationSlotCmd +{ + NodeTag type; + char *slotname; +} ReadReplicationSlotCmd; + + +/* ---------------------- + * TIMELINE_HISTORY command + * ---------------------- + */ +typedef struct TimeLineHistoryCmd +{ + NodeTag type; + TimeLineID timeline; +} TimeLineHistoryCmd; + +#endif /* REPLNODES_H */ diff --git a/install/include/postgresql/server/nodes/subscripting.h b/install/include/postgresql/server/nodes/subscripting.h new file mode 100644 index 00000000000..02d98f2e47f --- /dev/null +++ b/install/include/postgresql/server/nodes/subscripting.h @@ -0,0 +1,167 @@ +/*------------------------------------------------------------------------- + * + * subscripting.h + * API for generic type subscripting + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/subscripting.h + * + *------------------------------------------------------------------------- + */ +#ifndef SUBSCRIPTING_H +#define SUBSCRIPTING_H + +#include "nodes/primnodes.h" + +/* Forward declarations, to avoid including other headers */ +struct ParseState; +struct SubscriptingRefState; +struct SubscriptExecSteps; + +/* + * The SQL-visible function that defines a subscripting method is declared + * subscripting_function(internal) returns internal + * but it actually is not passed any parameter. It must return a pointer + * to a "struct SubscriptRoutines" that provides pointers to the individual + * subscript parsing and execution methods. Typically the pointer will point + * to a "static const" variable, but at need it can point to palloc'd space. + * The type (after domain-flattening) of the head variable or expression + * of a subscripting construct determines which subscripting function is + * called for that construct. + * + * In addition to the method pointers, struct SubscriptRoutines includes + * several bool flags that specify properties of the subscripting actions + * this data type can perform: + * + * fetch_strict indicates that a fetch SubscriptRef is strict, i.e., returns + * NULL if any input (either the container or any subscript) is NULL. + * + * fetch_leakproof indicates that a fetch SubscriptRef is leakproof, i.e., + * will not throw any data-value-dependent errors. Typically this requires + * silently returning NULL for invalid subscripts. + * + * store_leakproof similarly indicates whether an assignment SubscriptRef is + * leakproof. (It is common to prefer throwing errors for invalid subscripts + * in assignments; that's fine, but it makes the operation not leakproof. + * In current usage there is no advantage in making assignments leakproof.) + * + * There is no store_strict flag. Such behavior would generally be + * undesirable, since for example a null subscript in an assignment would + * cause the entire container to become NULL. + * + * Regardless of these flags, all SubscriptRefs are expected to be immutable, + * that is they must always give the same results for the same inputs. + * They are expected to always be parallel-safe, as well. + */ + +/* + * The transform method is called during parse analysis of a subscripting + * construct. The SubscriptingRef node has been constructed, but some of + * its fields still need to be filled in, and the subscript expression(s) + * are still in raw form. The transform method is responsible for doing + * parse analysis of each subscript expression (using transformExpr), + * coercing the subscripts to whatever type it needs, and building the + * refupperindexpr and reflowerindexpr lists from those results. The + * reflowerindexpr list must be empty for an element operation, or the + * same length as refupperindexpr for a slice operation. Insert NULLs + * (that is, an empty parse tree, not a null Const node) for any omitted + * subscripts in a slice operation. (Of course, if the transform method + * does not care to support slicing, it can just throw an error if isSlice.) + * See array_subscript_transform() for sample code. + * + * The transform method is also responsible for identifying the result type + * of the subscripting operation. At call, refcontainertype and reftypmod + * describe the container type (this will be a base type not a domain), and + * refelemtype is set to the container type's pg_type.typelem value. The + * transform method must set refrestype and reftypmod to describe the result + * of subscripting. For arrays, refrestype is set to refelemtype for an + * element operation or refcontainertype for a slice, while reftypmod stays + * the same in either case; but other types might use other rules. The + * transform method should ignore refcollid, as that's determined later on + * during parsing. + * + * At call, refassgnexpr has not been filled in, so the SubscriptingRef node + * always looks like a fetch; refrestype should be set as though for a + * fetch, too. (The isAssignment parameter is typically only useful if the + * transform method wishes to throw an error for not supporting assignment.) + * To complete processing of an assignment, the core parser will coerce the + * element/slice source expression to the returned refrestype and reftypmod + * before putting it into refassgnexpr. It will then set refrestype and + * reftypmod to again describe the container type, since that's what an + * assignment must return. + */ +typedef void (*SubscriptTransform) (SubscriptingRef *sbsref, + List *indirection, + struct ParseState *pstate, + bool isSlice, + bool isAssignment); + +/* + * The exec_setup method is called during executor-startup compilation of a + * SubscriptingRef node in an expression. It must fill *methods with pointers + * to functions that can be called for execution of the node. Optionally, + * exec_setup can initialize sbsrefstate->workspace to point to some palloc'd + * workspace for execution. (Typically, such workspace is used to hold + * looked-up catalog data and/or provide space for the check_subscripts step + * to pass data forward to the other step functions.) See executor/execExpr.h + * for the definitions of these structs and other ones used in expression + * execution. + * + * The methods to be provided are: + * + * sbs_check_subscripts: examine the just-computed subscript values available + * in sbsrefstate's arrays, and possibly convert them into another form + * (stored in sbsrefstate->workspace). Return TRUE to continue with + * evaluation of the subscripting construct, or FALSE to skip it and return an + * overall NULL result. If this is a fetch and the data type's fetch_strict + * flag is true, then sbs_check_subscripts must return FALSE if there are any + * NULL subscripts. Otherwise it can choose to throw an error, or return + * FALSE, or let sbs_fetch or sbs_assign deal with the null subscripts. + * + * sbs_fetch: perform a subscripting fetch, using the container value in + * *op->resvalue and the subscripts from sbs_check_subscripts. If + * fetch_strict is true then all these inputs can be assumed non-NULL, + * otherwise sbs_fetch must check for null inputs. Place the result in + * *op->resvalue / *op->resnull. + * + * sbs_assign: perform a subscripting assignment, using the original + * container value in *op->resvalue / *op->resnull, the subscripts from + * sbs_check_subscripts, and the new element/slice value in + * sbsrefstate->replacevalue/replacenull. Any of these inputs might be NULL + * (unless sbs_check_subscripts rejected null subscripts). Place the result + * (an entire new container value) in *op->resvalue / *op->resnull. + * + * sbs_fetch_old: this is only used in cases where an element or slice + * assignment involves an assignment to a sub-field or sub-element + * (i.e., nested containers are involved). It must fetch the existing + * value of the target element or slice. This is exactly the same as + * sbs_fetch except that (a) it must cope with a NULL container, and + * with NULL subscripts if sbs_check_subscripts allows them (typically, + * returning NULL is good enough); and (b) the result must be placed in + * sbsrefstate->prevvalue/prevnull, without overwriting *op->resvalue. + * + * Subscripting implementations that do not support assignment need not + * provide sbs_assign or sbs_fetch_old methods. It might be reasonable + * to also omit sbs_check_subscripts, in which case the sbs_fetch method must + * combine the functionality of sbs_check_subscripts and sbs_fetch. (The + * main reason to have a separate sbs_check_subscripts method is so that + * sbs_fetch_old and sbs_assign need not duplicate subscript processing.) + * Set the relevant pointers to NULL for any omitted methods. + */ +typedef void (*SubscriptExecSetup) (const SubscriptingRef *sbsref, + struct SubscriptingRefState *sbsrefstate, + struct SubscriptExecSteps *methods); + +/* Struct returned by the SQL-visible subscript handler function */ +typedef struct SubscriptRoutines +{ + SubscriptTransform transform; /* parse analysis function */ + SubscriptExecSetup exec_setup; /* expression compilation function */ + bool fetch_strict; /* is fetch SubscriptRef strict? */ + bool fetch_leakproof; /* is fetch SubscriptRef leakproof? */ + bool store_leakproof; /* is assignment SubscriptRef leakproof? */ +} SubscriptRoutines; + +#endif /* SUBSCRIPTING_H */ diff --git a/install/include/postgresql/server/nodes/supportnodes.h b/install/include/postgresql/server/nodes/supportnodes.h new file mode 100644 index 00000000000..4cfa661d882 --- /dev/null +++ b/install/include/postgresql/server/nodes/supportnodes.h @@ -0,0 +1,346 @@ +/*------------------------------------------------------------------------- + * + * supportnodes.h + * Definitions for planner support functions. + * + * This file defines the API for "planner support functions", which + * are SQL functions (normally written in C) that can be attached to + * another "target" function to give the system additional knowledge + * about the target function. All the current capabilities have to do + * with planning queries that use the target function, though it is + * possible that future extensions will add functionality to be invoked + * by the parser or executor. + * + * A support function must have the SQL signature + * supportfn(internal) returns internal + * The argument is a pointer to one of the Node types defined in this file. + * The result is usually also a Node pointer, though its type depends on + * which capability is being invoked. In all cases, a NULL pointer result + * (that's PG_RETURN_POINTER(NULL), not PG_RETURN_NULL()) indicates that + * the support function cannot do anything useful for the given request. + * Support functions must return a NULL pointer, not fail, if they do not + * recognize the request node type or cannot handle the given case; this + * allows for future extensions of the set of request cases. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/supportnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef SUPPORTNODES_H +#define SUPPORTNODES_H + +#include "nodes/plannodes.h" + +struct PlannerInfo; /* avoid including pathnodes.h here */ +struct IndexOptInfo; +struct SpecialJoinInfo; +struct WindowClause; + +/* + * The Simplify request allows the support function to perform plan-time + * simplification of a call to its target function. For example, a varchar + * length coercion that does not decrease the allowed length of its argument + * could be replaced by a RelabelType node, or "x + 0" could be replaced by + * "x". This is invoked during the planner's constant-folding pass, so the + * function's arguments can be presumed already simplified. + * + * The planner's PlannerInfo "root" is typically not needed, but can be + * consulted if it's necessary to obtain info about Vars present in + * the given node tree. Beware that root could be NULL in some usages. + * + * "fcall" will be a FuncExpr invoking the support function's target + * function. (This is true even if the original parsetree node was an + * operator call; a FuncExpr is synthesized for this purpose.) + * + * The result should be a semantically-equivalent transformed node tree, + * or NULL if no simplification could be performed. Do *not* return or + * modify *fcall, as it isn't really a separately allocated Node. But + * it's okay to use fcall->args, or parts of it, in the result tree. + */ +typedef struct SupportRequestSimplify +{ + NodeTag type; + + struct PlannerInfo *root; /* Planner's infrastructure */ + FuncExpr *fcall; /* Function call to be simplified */ +} SupportRequestSimplify; + +/* + * The Selectivity request allows the support function to provide a + * selectivity estimate for a function appearing at top level of a WHERE + * clause (so it applies only to functions returning boolean). + * + * The input arguments are the same as are supplied to operator restriction + * and join estimators, except that we unify those two APIs into just one + * request type. See clause_selectivity() for the details. + * + * If an estimate can be made, store it into the "selectivity" field and + * return the address of the SupportRequestSelectivity node; the estimate + * must be between 0 and 1 inclusive. Return NULL if no estimate can be + * made (in which case the planner will fall back to a default estimate, + * traditionally 1/3). + * + * If the target function is being used as the implementation of an operator, + * the support function will not be used for this purpose; the operator's + * restriction or join estimator is consulted instead. + */ +typedef struct SupportRequestSelectivity +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure */ + Oid funcid; /* function we are inquiring about */ + List *args; /* pre-simplified arguments to function */ + Oid inputcollid; /* function's input collation */ + bool is_join; /* is this a join or restriction case? */ + int varRelid; /* if restriction, RTI of target relation */ + JoinType jointype; /* if join, outer join type */ + struct SpecialJoinInfo *sjinfo; /* if outer join, info about join */ + + /* Output fields: */ + Selectivity selectivity; /* returned selectivity estimate */ +} SupportRequestSelectivity; + +/* + * The Cost request allows the support function to provide an execution + * cost estimate for its target function. The cost estimate can include + * both a one-time (query startup) component and a per-execution component. + * The estimate should *not* include the costs of evaluating the target + * function's arguments, only the target function itself. + * + * The "node" argument is normally the parse node that is invoking the + * target function. This is a FuncExpr in the simplest case, but it could + * also be an OpExpr, DistinctExpr, NullIfExpr, or WindowFunc, or possibly + * other cases in future. NULL is passed if the function cannot presume + * its arguments to be equivalent to what the calling node presents as + * arguments; that happens for, e.g., aggregate support functions and + * per-column comparison operators used by RowExprs. + * + * If an estimate can be made, store it into the cost fields and return the + * address of the SupportRequestCost node. Return NULL if no estimate can be + * made, in which case the planner will rely on the target function's procost + * field. (Note: while procost is automatically scaled by cpu_operator_cost, + * this is not the case for the outputs of the Cost request; the support + * function must scale its results appropriately on its own.) + */ +typedef struct SupportRequestCost +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure (could be NULL) */ + Oid funcid; /* function we are inquiring about */ + Node *node; /* parse node invoking function, or NULL */ + + /* Output fields: */ + Cost startup; /* one-time cost */ + Cost per_tuple; /* per-evaluation cost */ +} SupportRequestCost; + +/* + * The Rows request allows the support function to provide an output rowcount + * estimate for its target function (so it applies only to set-returning + * functions). + * + * The "node" argument is the parse node that is invoking the target function; + * currently this will always be a FuncExpr or OpExpr. + * + * If an estimate can be made, store it into the rows field and return the + * address of the SupportRequestRows node. Return NULL if no estimate can be + * made, in which case the planner will rely on the target function's prorows + * field. + */ +typedef struct SupportRequestRows +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure (could be NULL) */ + Oid funcid; /* function we are inquiring about */ + Node *node; /* parse node invoking function */ + + /* Output fields: */ + double rows; /* number of rows expected to be returned */ +} SupportRequestRows; + +/* + * The IndexCondition request allows the support function to generate + * a directly-indexable condition based on a target function call that is + * not itself indexable. The target function call must appear at the top + * level of WHERE or JOIN/ON, so this applies only to functions returning + * boolean. + * + * The "node" argument is the parse node that is invoking the target function; + * currently this will always be a FuncExpr or OpExpr. The call is made + * only if at least one function argument matches an index column's variable + * or expression. "indexarg" identifies the matching argument (it's the + * argument's zero-based index in the node's args list). + * + * If the transformation is possible, return a List of directly-indexable + * condition expressions, else return NULL. (A List is used because it's + * sometimes useful to generate more than one indexable condition, such as + * when a LIKE with constant prefix gives rise to both >= and < conditions.) + * + * "Directly indexable" means that the condition must be directly executable + * by the index machinery. Typically this means that it is a binary OpExpr + * with the index column value on the left, a pseudo-constant on the right, + * and an operator that is in the index column's operator family. Other + * possibilities include RowCompareExpr, ScalarArrayOpExpr, and NullTest, + * depending on the index type; but those seem less likely to be useful for + * derived index conditions. "Pseudo-constant" means that the right-hand + * expression must not contain any volatile functions, nor any Vars of the + * table the index is for; use is_pseudo_constant_for_index() to check this. + * (Note: if the passed "node" is an OpExpr, the core planner already verified + * that the non-indexkey operand is pseudo-constant; but when the "node" + * is a FuncExpr, it does not check, since it doesn't know which of the + * function's arguments you might need to use in an index comparison value.) + * + * In many cases, an index condition can be generated but it is weaker than + * the function condition itself; for example, a LIKE with a constant prefix + * can produce an index range check based on the prefix, but we still need + * to execute the LIKE operator to verify the rest of the pattern. We say + * that such an index condition is "lossy". When returning an index condition, + * you should set the "lossy" request field to true if the condition is lossy, + * or false if it is an exact equivalent of the function's result. The core + * code will initialize that field to true, which is the common case. + * + * It is important to verify that the index operator family is the correct + * one for the condition you want to generate. Core support functions tend + * to use the known OID of a built-in opfamily for this, but extensions need + * to work harder, since their OIDs aren't fixed. A possibly workable + * answer for an index on an extension datatype is to verify the index AM's + * OID instead, and then assume that there's only one relevant opclass for + * your datatype so the opfamily must be the right one. Generating OpExpr + * nodes may also require knowing extension datatype OIDs (often you can + * find these out by applying exprType() to a function argument) and + * operator OIDs (which you can look up using get_opfamily_member). + */ +typedef struct SupportRequestIndexCondition +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure */ + Oid funcid; /* function we are inquiring about */ + Node *node; /* parse node invoking function */ + int indexarg; /* index of function arg matching indexcol */ + struct IndexOptInfo *index; /* planner's info about target index */ + int indexcol; /* index of target index column (0-based) */ + Oid opfamily; /* index column's operator family */ + Oid indexcollation; /* index column's collation */ + + /* Output fields: */ + bool lossy; /* set to false if index condition is an exact + * equivalent of the function call */ +} SupportRequestIndexCondition; + +/* ---------- + * To support more efficient query execution of any monotonically increasing + * and/or monotonically decreasing window functions, we support calling the + * window function's prosupport function passing along this struct whenever + * the planner sees an OpExpr qual directly reference a window function in a + * subquery. When the planner encounters this, we populate this struct and + * pass it along to the window function's prosupport function so that it can + * evaluate if the given WindowFunc is; + * + * a) monotonically increasing, or + * b) monotonically decreasing, or + * c) both monotonically increasing and decreasing, or + * d) none of the above. + * + * A function that is monotonically increasing can never return a value that + * is lower than a value returned in a "previous call". A monotonically + * decreasing function can never return a value higher than a value returned + * in a previous call. A function that is both must return the same value + * each time. + * + * We define "previous call" to mean a previous call to the same WindowFunc + * struct in the same window partition. + * + * row_number() is an example of a monotonically increasing function. The + * return value will be reset back to 1 in each new partition. An example of + * a monotonically increasing and decreasing function is COUNT(*) OVER (). + * Since there is no ORDER BY clause in this example, all rows in the + * partition are peers and all rows within the partition will be within the + * frame bound. Likewise for COUNT(*) OVER(ORDER BY a ROWS BETWEEN UNBOUNDED + * PRECEDING AND UNBOUNDED FOLLOWING). + * + * COUNT(*) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + * is an example of a monotonically decreasing function. + * + * Implementations must only concern themselves with the given WindowFunc + * being monotonic in a single partition. + * + * Inputs: + * 'window_func' is the pointer to the window function being called. + * + * 'window_clause' pointer to the WindowClause data. Support functions can + * use this to check frame bounds, etc. + * + * Outputs: + * 'monotonic' the resulting MonotonicFunction value for the given input + * window function and window clause. + * ---------- + */ +typedef struct SupportRequestWFuncMonotonic +{ + NodeTag type; + + /* Input fields: */ + WindowFunc *window_func; /* Pointer to the window function data */ + struct WindowClause *window_clause; /* Pointer to the window clause data */ + + /* Output fields: */ + MonotonicFunction monotonic; +} SupportRequestWFuncMonotonic; + +/* + * Some WindowFunc behavior might not be affected by certain variations in + * the WindowClause's frameOptions. For example, row_number() is coded in + * such a way that the frame options don't change the returned row number. + * nodeWindowAgg.c will have less work to do if the ROWS option is used + * instead of the RANGE option as no check needs to be done for peer rows. + * Since RANGE is included in the default frame options, window functions + * such as row_number() might want to change that to ROW. + * + * Here we allow a WindowFunc's support function to determine which, if + * anything, can be changed about the WindowClause which the WindowFunc + * belongs to. Currently only the frameOptions can be modified. However, + * we may want to allow more optimizations in the future. + * + * The support function is responsible for ensuring the optimized version of + * the frameOptions doesn't affect the result of the window function. The + * planner is responsible for only changing the frame options when all + * WindowFuncs using this particular WindowClause agree on what the optimized + * version of the frameOptions are. If a particular WindowFunc being used + * does not have a support function then the planner will not make any changes + * to the WindowClause's frameOptions. + * + * 'window_func' and 'window_clause' are set by the planner before calling the + * support function so that the support function has these fields available. + * These may be required in order to determine which optimizations are + * possible. + * + * 'frameOptions' is set by the planner to WindowClause.frameOptions. The + * support function must only adjust this if optimizations are possible for + * the given WindowFunc. + */ +typedef struct SupportRequestOptimizeWindowClause +{ + NodeTag type; + + /* Input fields: */ + WindowFunc *window_func; /* Pointer to the window function data */ + struct WindowClause *window_clause; /* Pointer to the window clause data */ + + /* Input/Output fields: */ + int frameOptions; /* New frameOptions, or left untouched if no + * optimizations are possible. */ +} SupportRequestOptimizeWindowClause; + +#endif /* SUPPORTNODES_H */ diff --git a/install/include/postgresql/server/nodes/tidbitmap.h b/install/include/postgresql/server/nodes/tidbitmap.h new file mode 100644 index 00000000000..b64e36437a0 --- /dev/null +++ b/install/include/postgresql/server/nodes/tidbitmap.h @@ -0,0 +1,75 @@ +/*------------------------------------------------------------------------- + * + * tidbitmap.h + * PostgreSQL tuple-id (TID) bitmap package + * + * This module provides bitmap data structures that are spiritually + * similar to Bitmapsets, but are specially adapted to store sets of + * tuple identifiers (TIDs), or ItemPointers. In particular, the division + * of an ItemPointer into BlockNumber and OffsetNumber is catered for. + * Also, since we wish to be able to store very large tuple sets in + * memory with this data structure, we support "lossy" storage, in which + * we no longer remember individual tuple offsets on a page but only the + * fact that a particular page needs to be visited. + * + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/nodes/tidbitmap.h + * + *------------------------------------------------------------------------- + */ +#ifndef TIDBITMAP_H +#define TIDBITMAP_H + +#include "storage/itemptr.h" +#include "utils/dsa.h" + + +/* + * Actual bitmap representation is private to tidbitmap.c. Callers can + * do IsA(x, TIDBitmap) on it, but nothing else. + */ +typedef struct TIDBitmap TIDBitmap; + +/* Likewise, TBMIterator is private */ +typedef struct TBMIterator TBMIterator; +typedef struct TBMSharedIterator TBMSharedIterator; + +/* Result structure for tbm_iterate */ +typedef struct TBMIterateResult +{ + BlockNumber blockno; /* page number containing tuples */ + int ntuples; /* -1 indicates lossy result */ + bool recheck; /* should the tuples be rechecked? */ + /* Note: recheck is always true if ntuples < 0 */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; +} TBMIterateResult; + +/* function prototypes in nodes/tidbitmap.c */ + +extern TIDBitmap *tbm_create(long maxbytes, dsa_area *dsa); +extern void tbm_free(TIDBitmap *tbm); +extern void tbm_free_shared_area(dsa_area *dsa, dsa_pointer dp); + +extern void tbm_add_tuples(TIDBitmap *tbm, + const ItemPointer tids, int ntids, + bool recheck); +extern void tbm_add_page(TIDBitmap *tbm, BlockNumber pageno); + +extern void tbm_union(TIDBitmap *a, const TIDBitmap *b); +extern void tbm_intersect(TIDBitmap *a, const TIDBitmap *b); + +extern bool tbm_is_empty(const TIDBitmap *tbm); + +extern TBMIterator *tbm_begin_iterate(TIDBitmap *tbm); +extern dsa_pointer tbm_prepare_shared_iterate(TIDBitmap *tbm); +extern TBMIterateResult *tbm_iterate(TBMIterator *iterator); +extern TBMIterateResult *tbm_shared_iterate(TBMSharedIterator *iterator); +extern void tbm_end_iterate(TBMIterator *iterator); +extern void tbm_end_shared_iterate(TBMSharedIterator *iterator); +extern TBMSharedIterator *tbm_attach_shared_iterate(dsa_area *dsa, + dsa_pointer dp); +extern long tbm_calculate_entries(double maxbytes); + +#endif /* TIDBITMAP_H */ diff --git a/install/include/postgresql/server/nodes/value.h b/install/include/postgresql/server/nodes/value.h new file mode 100644 index 00000000000..b24c4c1afef --- /dev/null +++ b/install/include/postgresql/server/nodes/value.h @@ -0,0 +1,90 @@ +/*------------------------------------------------------------------------- + * + * value.h + * interface for value nodes + * + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/nodes/value.h + * + *------------------------------------------------------------------------- + */ + +#ifndef VALUE_H +#define VALUE_H + +#include "nodes/nodes.h" + +/* + * The node types Integer, Float, String, and BitString are used to represent + * literals in the lexer and are also used to pass constants around in the + * parser. One difference between these node types and, say, a plain int or + * char * is that the nodes can be put into a List. + * + * (There used to be a Value node, which encompassed all these different node types. Hence the name of this file.) + */ + +typedef struct Integer +{ + pg_node_attr(special_read_write) + + NodeTag type; + int ival; +} Integer; + +/* + * Float is internally represented as string. Using T_Float as the node type + * simply indicates that the contents of the string look like a valid numeric + * literal. The value might end up being converted to NUMERIC, so we can't + * store it internally as a C double, since that could lose precision. Since + * these nodes are generally only used in the parsing process, not for runtime + * data, it's better to use the more general representation. + * + * Note that an integer-looking string will get lexed as T_Float if the value + * is too large to fit in an 'int'. + */ +typedef struct Float +{ + pg_node_attr(special_read_write) + + NodeTag type; + char *fval; +} Float; + +typedef struct Boolean +{ + pg_node_attr(special_read_write) + + NodeTag type; + bool boolval; +} Boolean; + +typedef struct String +{ + pg_node_attr(special_read_write) + + NodeTag type; + char *sval; +} String; + +typedef struct BitString +{ + pg_node_attr(special_read_write) + + NodeTag type; + char *bsval; +} BitString; + +#define intVal(v) (castNode(Integer, v)->ival) +#define floatVal(v) atof(castNode(Float, v)->fval) +#define boolVal(v) (castNode(Boolean, v)->boolval) +#define strVal(v) (castNode(String, v)->sval) + +extern Integer *makeInteger(int i); +extern Float *makeFloat(char *numericStr); +extern Boolean *makeBoolean(bool val); +extern String *makeString(char *str); +extern BitString *makeBitString(char *str); + +#endif /* VALUE_H */ diff --git a/install/include/postgresql/server/optimizer/appendinfo.h b/install/include/postgresql/server/optimizer/appendinfo.h new file mode 100644 index 00000000000..a05f91f77d0 --- /dev/null +++ b/install/include/postgresql/server/optimizer/appendinfo.h @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------- + * + * appendinfo.h + * Routines for mapping expressions between append rel parent(s) and + * children + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/appendinfo.h + * + *------------------------------------------------------------------------- + */ +#ifndef APPENDINFO_H +#define APPENDINFO_H + +#include "nodes/pathnodes.h" +#include "utils/relcache.h" + +extern AppendRelInfo *make_append_rel_info(Relation parentrel, + Relation childrel, + Index parentRTindex, Index childRTindex); +extern Node *adjust_appendrel_attrs(PlannerInfo *root, Node *node, + int nappinfos, AppendRelInfo **appinfos); +extern Node *adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, + RelOptInfo *childrel, + RelOptInfo *parentrel); +extern Relids adjust_child_relids(Relids relids, int nappinfos, + AppendRelInfo **appinfos); +extern Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, + RelOptInfo *childrel, + RelOptInfo *parentrel); +extern List *adjust_inherited_attnums(List *attnums, AppendRelInfo *context); +extern List *adjust_inherited_attnums_multilevel(PlannerInfo *root, + List *attnums, + Index child_relid, + Index top_parent_relid); +extern void get_translated_update_targetlist(PlannerInfo *root, Index relid, + List **processed_tlist, + List **update_colnos); +extern AppendRelInfo **find_appinfos_by_relids(PlannerInfo *root, + Relids relids, int *nappinfos); +extern void add_row_identity_var(PlannerInfo *root, Var *orig_var, + Index rtindex, const char *rowid_name); +extern void add_row_identity_columns(PlannerInfo *root, Index rtindex, + RangeTblEntry *target_rte, + Relation target_relation); +extern void distribute_row_identity_vars(PlannerInfo *root); + +#endif /* APPENDINFO_H */ diff --git a/install/include/postgresql/server/optimizer/clauses.h b/install/include/postgresql/server/optimizer/clauses.h new file mode 100644 index 00000000000..cbe0607e85a --- /dev/null +++ b/install/include/postgresql/server/optimizer/clauses.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * clauses.h + * prototypes for clauses.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/clauses.h + * + *------------------------------------------------------------------------- + */ +#ifndef CLAUSES_H +#define CLAUSES_H + +#include "nodes/pathnodes.h" + +typedef struct +{ + int numWindowFuncs; /* total number of WindowFuncs found */ + Index maxWinRef; /* windowFuncs[] is indexed 0 .. maxWinRef */ + List **windowFuncs; /* lists of WindowFuncs for each winref */ +} WindowFuncLists; + +extern bool contain_agg_clause(Node *clause); + +extern bool contain_window_function(Node *clause); +extern WindowFuncLists *find_window_functions(Node *clause, Index maxWinRef); + +extern double expression_returns_set_rows(PlannerInfo *root, Node *clause); + +extern bool contain_subplans(Node *clause); + +extern char max_parallel_hazard(Query *parse); +extern bool is_parallel_safe(PlannerInfo *root, Node *node); +extern bool contain_nonstrict_functions(Node *clause); +extern bool contain_exec_param(Node *clause, List *param_ids); +extern bool contain_leaked_vars(Node *clause); + +extern Relids find_nonnullable_rels(Node *clause); +extern List *find_nonnullable_vars(Node *clause); +extern List *find_forced_null_vars(Node *node); +extern Var *find_forced_null_var(Node *node); + +extern bool is_pseudo_constant_clause(Node *clause); +extern bool is_pseudo_constant_clause_relids(Node *clause, Relids relids); + +extern int NumRelids(PlannerInfo *root, Node *clause); + +extern void CommuteOpExpr(OpExpr *clause); + +extern Query *inline_set_returning_function(PlannerInfo *root, + RangeTblEntry *rte); + +extern Bitmapset *pull_paramids(Expr *expr); + +#endif /* CLAUSES_H */ diff --git a/install/include/postgresql/server/optimizer/cost.h b/install/include/postgresql/server/optimizer/cost.h new file mode 100644 index 00000000000..6cf49705d3a --- /dev/null +++ b/install/include/postgresql/server/optimizer/cost.h @@ -0,0 +1,215 @@ +/*------------------------------------------------------------------------- + * + * cost.h + * prototypes for costsize.c and clausesel.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/cost.h + * + *------------------------------------------------------------------------- + */ +#ifndef COST_H +#define COST_H + +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" + + +/* defaults for costsize.c's Cost parameters */ +/* NB: cost-estimation code should use the variables, not these constants! */ +/* If you change these, update backend/utils/misc/postgresql.conf.sample */ +#define DEFAULT_SEQ_PAGE_COST 1.0 +#define DEFAULT_RANDOM_PAGE_COST 4.0 +#define DEFAULT_CPU_TUPLE_COST 0.01 +#define DEFAULT_CPU_INDEX_TUPLE_COST 0.005 +#define DEFAULT_CPU_OPERATOR_COST 0.0025 +#define DEFAULT_PARALLEL_TUPLE_COST 0.1 +#define DEFAULT_PARALLEL_SETUP_COST 1000.0 + +/* defaults for non-Cost parameters */ +#define DEFAULT_RECURSIVE_WORKTABLE_FACTOR 10.0 +#define DEFAULT_EFFECTIVE_CACHE_SIZE 524288 /* measured in pages */ + +typedef enum +{ + CONSTRAINT_EXCLUSION_OFF, /* do not use c_e */ + CONSTRAINT_EXCLUSION_ON, /* apply c_e to all rels */ + CONSTRAINT_EXCLUSION_PARTITION /* apply c_e to otherrels only */ +} ConstraintExclusionType; + + +/* + * prototypes for costsize.c + * routines to compute costs and sizes + */ + +/* parameter variables and flags (see also optimizer.h) */ +extern PGDLLIMPORT Cost disable_cost; +extern PGDLLIMPORT int max_parallel_workers_per_gather; +extern PGDLLIMPORT bool enable_seqscan; +extern PGDLLIMPORT bool enable_indexscan; +extern PGDLLIMPORT bool enable_indexonlyscan; +extern PGDLLIMPORT bool enable_bitmapscan; +extern PGDLLIMPORT bool enable_tidscan; +extern PGDLLIMPORT bool enable_sort; +extern PGDLLIMPORT bool enable_incremental_sort; +extern PGDLLIMPORT bool enable_hashagg; +extern PGDLLIMPORT bool enable_nestloop; +extern PGDLLIMPORT bool enable_material; +extern PGDLLIMPORT bool enable_memoize; +extern PGDLLIMPORT bool enable_mergejoin; +extern PGDLLIMPORT bool enable_hashjoin; +extern PGDLLIMPORT bool enable_gathermerge; +extern PGDLLIMPORT bool enable_partitionwise_join; +extern PGDLLIMPORT bool enable_partitionwise_aggregate; +extern PGDLLIMPORT bool enable_parallel_append; +extern PGDLLIMPORT bool enable_parallel_hash; +extern PGDLLIMPORT bool enable_partition_pruning; +extern PGDLLIMPORT bool enable_presorted_aggregate; +extern PGDLLIMPORT bool enable_async_append; +extern PGDLLIMPORT int constraint_exclusion; + +extern double index_pages_fetched(double tuples_fetched, BlockNumber pages, + double index_pages, PlannerInfo *root); +extern void cost_seqscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, + ParamPathInfo *param_info); +extern void cost_samplescan(Path *path, PlannerInfo *root, RelOptInfo *baserel, + ParamPathInfo *param_info); +extern void cost_index(IndexPath *path, PlannerInfo *root, + double loop_count, bool partial_path); +extern void cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, + ParamPathInfo *param_info, + Path *bitmapqual, double loop_count); +extern void cost_bitmap_and_node(BitmapAndPath *path, PlannerInfo *root); +extern void cost_bitmap_or_node(BitmapOrPath *path, PlannerInfo *root); +extern void cost_bitmap_tree_node(Path *path, Cost *cost, Selectivity *selec); +extern void cost_tidscan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, List *tidquals, ParamPathInfo *param_info); +extern void cost_tidrangescan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, List *tidrangequals, + ParamPathInfo *param_info); +extern void cost_subqueryscan(SubqueryScanPath *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info, + bool trivial_pathtarget); +extern void cost_functionscan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_valuesscan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_tablefuncscan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_ctescan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_namedtuplestorescan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_resultscan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_recursive_union(Path *runion, Path *nrterm, Path *rterm); +extern void cost_sort(Path *path, PlannerInfo *root, + List *pathkeys, Cost input_cost, double tuples, int width, + Cost comparison_cost, int sort_mem, + double limit_tuples); +extern void cost_incremental_sort(Path *path, + PlannerInfo *root, List *pathkeys, int presorted_keys, + Cost input_startup_cost, Cost input_total_cost, + double input_tuples, int width, Cost comparison_cost, int sort_mem, + double limit_tuples); +extern void cost_append(AppendPath *apath); +extern void cost_merge_append(Path *path, PlannerInfo *root, + List *pathkeys, int n_streams, + Cost input_startup_cost, Cost input_total_cost, + double tuples); +extern void cost_material(Path *path, + Cost input_startup_cost, Cost input_total_cost, + double tuples, int width); +extern void cost_agg(Path *path, PlannerInfo *root, + AggStrategy aggstrategy, const AggClauseCosts *aggcosts, + int numGroupCols, double numGroups, + List *quals, + Cost input_startup_cost, Cost input_total_cost, + double input_tuples, double input_width); +extern void cost_windowagg(Path *path, PlannerInfo *root, + List *windowFuncs, int numPartCols, int numOrderCols, + Cost input_startup_cost, Cost input_total_cost, + double input_tuples); +extern void cost_group(Path *path, PlannerInfo *root, + int numGroupCols, double numGroups, + List *quals, + Cost input_startup_cost, Cost input_total_cost, + double input_tuples); +extern void initial_cost_nestloop(PlannerInfo *root, + JoinCostWorkspace *workspace, + JoinType jointype, + Path *outer_path, Path *inner_path, + JoinPathExtraData *extra); +extern void final_cost_nestloop(PlannerInfo *root, NestPath *path, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra); +extern void initial_cost_mergejoin(PlannerInfo *root, + JoinCostWorkspace *workspace, + JoinType jointype, + List *mergeclauses, + Path *outer_path, Path *inner_path, + List *outersortkeys, List *innersortkeys, + JoinPathExtraData *extra); +extern void final_cost_mergejoin(PlannerInfo *root, MergePath *path, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra); +extern void initial_cost_hashjoin(PlannerInfo *root, + JoinCostWorkspace *workspace, + JoinType jointype, + List *hashclauses, + Path *outer_path, Path *inner_path, + JoinPathExtraData *extra, + bool parallel_hash); +extern void final_cost_hashjoin(PlannerInfo *root, HashPath *path, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra); +extern void cost_gather(GatherPath *path, PlannerInfo *root, + RelOptInfo *rel, ParamPathInfo *param_info, double *rows); +extern void cost_gather_merge(GatherMergePath *path, PlannerInfo *root, + RelOptInfo *rel, ParamPathInfo *param_info, + Cost input_startup_cost, Cost input_total_cost, + double *rows); +extern void cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan); +extern void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root); +extern void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root); +extern void compute_semi_anti_join_factors(PlannerInfo *root, + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + SpecialJoinInfo *sjinfo, + List *restrictlist, + SemiAntiJoinFactors *semifactors); +extern void set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern double get_parameterized_baserel_size(PlannerInfo *root, + RelOptInfo *rel, + List *param_clauses); +extern double get_parameterized_joinrel_size(PlannerInfo *root, + RelOptInfo *rel, + Path *outer_path, + Path *inner_path, + SpecialJoinInfo *sjinfo, + List *restrict_clauses); +extern void set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel, + RelOptInfo *outer_rel, + RelOptInfo *inner_rel, + SpecialJoinInfo *sjinfo, + List *restrictlist); +extern void set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern void set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern void set_values_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern void set_cte_size_estimates(PlannerInfo *root, RelOptInfo *rel, + double cte_rows); +extern void set_tablefunc_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern void set_namedtuplestore_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern void set_result_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern PathTarget *set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target); +extern double compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel, + Path *bitmapqual, int loop_count, Cost *cost, double *tuple); + +#endif /* COST_H */ diff --git a/install/include/postgresql/server/optimizer/geqo.h b/install/include/postgresql/server/optimizer/geqo.h new file mode 100644 index 00000000000..c7981973bc7 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo.h @@ -0,0 +1,90 @@ +/*------------------------------------------------------------------------- + * + * geqo.h + * prototypes for various files in optimizer/geqo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo.h + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +#ifndef GEQO_H +#define GEQO_H + +#include "common/pg_prng.h" +#include "nodes/pathnodes.h" +#include "optimizer/geqo_gene.h" + + +/* GEQO debug flag */ +/* + #define GEQO_DEBUG + */ + +/* choose one recombination mechanism here */ +/* + #define ERX + #define PMX + #define CX + #define PX + #define OX1 + #define OX2 + */ +#define ERX + + +/* + * Configuration options + * + * If you change these, update backend/utils/misc/postgresql.conf.sample + */ +extern PGDLLIMPORT int Geqo_effort; /* 1 .. 10, knob for adjustment of + * defaults */ + +#define DEFAULT_GEQO_EFFORT 5 +#define MIN_GEQO_EFFORT 1 +#define MAX_GEQO_EFFORT 10 + +extern PGDLLIMPORT int Geqo_pool_size; /* 2 .. inf, or 0 to use default */ + +extern PGDLLIMPORT int Geqo_generations; /* 1 .. inf, or 0 to use default */ + +extern PGDLLIMPORT double Geqo_selection_bias; + +#define DEFAULT_GEQO_SELECTION_BIAS 2.0 +#define MIN_GEQO_SELECTION_BIAS 1.5 +#define MAX_GEQO_SELECTION_BIAS 2.0 + +extern PGDLLIMPORT double Geqo_seed; /* 0 .. 1 */ + + +/* + * Private state for a GEQO run --- accessible via root->join_search_private + */ +typedef struct +{ + List *initial_rels; /* the base relations we are joining */ + pg_prng_state random_state; /* PRNG state */ +} GeqoPrivateData; + + +/* routines in geqo_main.c */ +extern RelOptInfo *geqo(PlannerInfo *root, + int number_of_rels, List *initial_rels); + +/* routines in geqo_eval.c */ +extern Cost geqo_eval(PlannerInfo *root, Gene *tour, int num_gene); +extern RelOptInfo *gimme_tree(PlannerInfo *root, Gene *tour, int num_gene); + +#endif /* GEQO_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_copy.h b/install/include/postgresql/server/optimizer/geqo_copy.h new file mode 100644 index 00000000000..9a78de65c97 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_copy.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * geqo_copy.h + * prototypes for copy functions in optimizer/geqo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_copy.h + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +#ifndef GEQO_COPY_H +#define GEQO_COPY_H + +#include "optimizer/geqo.h" + + +extern void geqo_copy(PlannerInfo *root, Chromosome *chromo1, Chromosome *chromo2, int string_length); + +#endif /* GEQO_COPY_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_gene.h b/install/include/postgresql/server/optimizer/geqo_gene.h new file mode 100644 index 00000000000..40256a4cde6 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_gene.h @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------- + * + * geqo_gene.h + * genome representation in optimizer/geqo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_gene.h + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + + +#ifndef GEQO_GENE_H +#define GEQO_GENE_H + +#include "nodes/nodes.h" + +/* we presume that int instead of Relid + is o.k. for Gene; so don't change it! */ +typedef int Gene; + +typedef struct Chromosome +{ + Gene *string; + Cost worth; +} Chromosome; + +typedef struct Pool +{ + Chromosome *data; + int size; + int string_length; +} Pool; + +#endif /* GEQO_GENE_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_misc.h b/install/include/postgresql/server/optimizer/geqo_misc.h new file mode 100644 index 00000000000..25e16812739 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_misc.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * geqo_misc.h + * prototypes for printout routines in optimizer/geqo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_misc.h + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +#ifndef GEQO_MISC_H +#define GEQO_MISC_H + +#include "optimizer/geqo_recombination.h" + +#ifdef GEQO_DEBUG + +extern void print_pool(FILE *fp, Pool *pool, int start, int stop); +extern void print_gen(FILE *fp, Pool *pool, int generation); +extern void print_edge_table(FILE *fp, Edge *edge_table, int num_gene); +#endif /* GEQO_DEBUG */ + +#endif /* GEQO_MISC_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_mutation.h b/install/include/postgresql/server/optimizer/geqo_mutation.h new file mode 100644 index 00000000000..d0f7ed94206 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_mutation.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * geqo_mutation.h + * prototypes for mutation functions in optimizer/geqo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_mutation.h + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +#ifndef GEQO_MUTATION_H +#define GEQO_MUTATION_H + +#include "optimizer/geqo.h" + + +extern void geqo_mutation(PlannerInfo *root, Gene *tour, int num_gene); + +#endif /* GEQO_MUTATION_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_pool.h b/install/include/postgresql/server/optimizer/geqo_pool.h new file mode 100644 index 00000000000..d1464f70aa8 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_pool.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------- + * + * geqo_pool.h + * pool representation in optimizer/geqo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_pool.h + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + + +#ifndef GEQO_POOL_H +#define GEQO_POOL_H + +#include "optimizer/geqo.h" + + +extern Pool *alloc_pool(PlannerInfo *root, int pool_size, int string_length); +extern void free_pool(PlannerInfo *root, Pool *pool); + +extern void random_init_pool(PlannerInfo *root, Pool *pool); +extern Chromosome *alloc_chromo(PlannerInfo *root, int string_length); +extern void free_chromo(PlannerInfo *root, Chromosome *chromo); + +extern void spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool); + +extern void sort_pool(PlannerInfo *root, Pool *pool); + +#endif /* GEQO_POOL_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_random.h b/install/include/postgresql/server/optimizer/geqo_random.h new file mode 100644 index 00000000000..08b0c08d85f --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_random.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------- + * + * geqo_random.h + * random number generator + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_random.h + * + *------------------------------------------------------------------------- + */ + +/* 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 -- */ + +#ifndef GEQO_RANDOM_H +#define GEQO_RANDOM_H + +#include + +#include "optimizer/geqo.h" + + +extern void geqo_set_seed(PlannerInfo *root, double seed); + +/* geqo_rand returns a random float value in the range [0.0, 1.0) */ +extern double geqo_rand(PlannerInfo *root); + +/* geqo_randint returns integer value between lower and upper inclusive */ +extern int geqo_randint(PlannerInfo *root, int upper, int lower); + +#endif /* GEQO_RANDOM_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_recombination.h b/install/include/postgresql/server/optimizer/geqo_recombination.h new file mode 100644 index 00000000000..1c3c7d5f646 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_recombination.h @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------- + * + * geqo_recombination.h + * prototypes for recombination in the genetic query optimizer + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_recombination.h + * + *------------------------------------------------------------------------- + */ + +/* 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 -- */ + +#ifndef GEQO_RECOMBINATION_H +#define GEQO_RECOMBINATION_H + +#include "optimizer/geqo.h" + + +extern void init_tour(PlannerInfo *root, Gene *tour, int num_gene); + + +/* edge recombination crossover [ERX] */ + +typedef struct Edge +{ + Gene edge_list[4]; /* list of edges */ + int total_edges; + int unused_edges; +} Edge; + +extern Edge *alloc_edge_table(PlannerInfo *root, int num_gene); +extern void free_edge_table(PlannerInfo *root, Edge *edge_table); + +extern float gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2, + int num_gene, Edge *edge_table); + +extern int gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, + int num_gene); + + +/* partially matched crossover [PMX] */ + +#define DAD 1 /* indicator for gene from dad */ +#define MOM 0 /* indicator for gene from mom */ + +extern void pmx(PlannerInfo *root, + Gene *tour1, Gene *tour2, + Gene *offspring, int num_gene); + + +typedef struct City +{ + int tour2_position; + int tour1_position; + int used; + int select_list; +} City; + +extern City * alloc_city_table(PlannerInfo *root, int num_gene); +extern void free_city_table(PlannerInfo *root, City * city_table); + +/* cycle crossover [CX] */ +extern int cx(PlannerInfo *root, Gene *tour1, Gene *tour2, + Gene *offspring, int num_gene, City * city_table); + +/* position crossover [PX] */ +extern void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, + int num_gene, City * city_table); + +/* order crossover [OX1] according to Davis */ +extern void ox1(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring, + int num_gene, City * city_table); + +/* order crossover [OX2] according to Syswerda */ +extern void ox2(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring, + int num_gene, City * city_table); + +#endif /* GEQO_RECOMBINATION_H */ diff --git a/install/include/postgresql/server/optimizer/geqo_selection.h b/install/include/postgresql/server/optimizer/geqo_selection.h new file mode 100644 index 00000000000..45d1078e696 --- /dev/null +++ b/install/include/postgresql/server/optimizer/geqo_selection.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * geqo_selection.h + * prototypes for selection routines in optimizer/geqo + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/geqo_selection.h + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + + +#ifndef GEQO_SELECTION_H +#define GEQO_SELECTION_H + +#include "optimizer/geqo.h" + + +extern void geqo_selection(PlannerInfo *root, + Chromosome *momma, Chromosome *daddy, + Pool *pool, double bias); + +#endif /* GEQO_SELECTION_H */ diff --git a/install/include/postgresql/server/optimizer/inherit.h b/install/include/postgresql/server/optimizer/inherit.h new file mode 100644 index 00000000000..76e958d639e --- /dev/null +++ b/install/include/postgresql/server/optimizer/inherit.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * inherit.h + * prototypes for inherit.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/inherit.h + * + *------------------------------------------------------------------------- + */ +#ifndef INHERIT_H +#define INHERIT_H + +#include "nodes/pathnodes.h" + + +extern void expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte, Index rti); + +extern Bitmapset *get_rel_all_updated_cols(PlannerInfo *root, RelOptInfo *rel); + +extern bool apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, + RelOptInfo *childrel, RangeTblEntry *childRTE, + AppendRelInfo *appinfo); + +#endif /* INHERIT_H */ diff --git a/install/include/postgresql/server/optimizer/joininfo.h b/install/include/postgresql/server/optimizer/joininfo.h new file mode 100644 index 00000000000..2cd6a132234 --- /dev/null +++ b/install/include/postgresql/server/optimizer/joininfo.h @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------- + * + * joininfo.h + * prototypes for joininfo.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/joininfo.h + * + *------------------------------------------------------------------------- + */ +#ifndef JOININFO_H +#define JOININFO_H + +#include "nodes/pathnodes.h" + + +extern bool have_relevant_joinclause(PlannerInfo *root, + RelOptInfo *rel1, RelOptInfo *rel2); + +extern void add_join_clause_to_rels(PlannerInfo *root, + RestrictInfo *restrictinfo, + Relids join_relids); +extern void remove_join_clause_from_rels(PlannerInfo *root, + RestrictInfo *restrictinfo, + Relids join_relids); + +#endif /* JOININFO_H */ diff --git a/install/include/postgresql/server/optimizer/optimizer.h b/install/include/postgresql/server/optimizer/optimizer.h new file mode 100644 index 00000000000..e7a557ef7b0 --- /dev/null +++ b/install/include/postgresql/server/optimizer/optimizer.h @@ -0,0 +1,204 @@ +/*------------------------------------------------------------------------- + * + * optimizer.h + * External API for the Postgres planner. + * + * This header is meant to define everything that the core planner + * exposes for use by non-planner modules. + * + * Note that there are files outside src/backend/optimizer/ that are + * considered planner modules, because they're too much in bed with + * planner operations to be treated otherwise. FDW planning code is an + * example. For the most part, however, code outside the core planner + * should not need to include any optimizer/ header except this one. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/optimizer.h + * + *------------------------------------------------------------------------- + */ +#ifndef OPTIMIZER_H +#define OPTIMIZER_H + +#include "nodes/parsenodes.h" + +/* + * We don't want to include nodes/pathnodes.h here, because non-planner + * code should generally treat PlannerInfo as an opaque typedef. + * But we'd like such code to use that typedef name, so define the + * typedef either here or in pathnodes.h, whichever is read first. + */ +#ifndef HAVE_PLANNERINFO_TYPEDEF +typedef struct PlannerInfo PlannerInfo; +#define HAVE_PLANNERINFO_TYPEDEF 1 +#endif + +/* Likewise for IndexOptInfo and SpecialJoinInfo. */ +#ifndef HAVE_INDEXOPTINFO_TYPEDEF +typedef struct IndexOptInfo IndexOptInfo; +#define HAVE_INDEXOPTINFO_TYPEDEF 1 +#endif +#ifndef HAVE_SPECIALJOININFO_TYPEDEF +typedef struct SpecialJoinInfo SpecialJoinInfo; +#define HAVE_SPECIALJOININFO_TYPEDEF 1 +#endif + +/* It also seems best not to include plannodes.h, params.h, or htup.h here */ +struct PlannedStmt; +struct ParamListInfoData; +struct HeapTupleData; + + +/* in path/clausesel.c: */ + +extern Selectivity clause_selectivity(PlannerInfo *root, + Node *clause, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo); +extern Selectivity clause_selectivity_ext(PlannerInfo *root, + Node *clause, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + bool use_extended_stats); +extern Selectivity clauselist_selectivity(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo); +extern Selectivity clauselist_selectivity_ext(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + bool use_extended_stats); + +/* in path/costsize.c: */ + +/* widely used cost parameters */ +extern PGDLLIMPORT double seq_page_cost; +extern PGDLLIMPORT double random_page_cost; +extern PGDLLIMPORT double cpu_tuple_cost; +extern PGDLLIMPORT double cpu_index_tuple_cost; +extern PGDLLIMPORT double cpu_operator_cost; +extern PGDLLIMPORT double parallel_tuple_cost; +extern PGDLLIMPORT double parallel_setup_cost; +extern PGDLLIMPORT double recursive_worktable_factor; +extern PGDLLIMPORT int effective_cache_size; + +extern double clamp_row_est(double nrows); +extern long clamp_cardinality_to_long(Cardinality x); + +/* in path/indxpath.c: */ + +extern bool is_pseudo_constant_for_index(PlannerInfo *root, Node *expr, + IndexOptInfo *index); + +/* in plan/planner.c: */ + +/* possible values for debug_parallel_query */ +typedef enum +{ + DEBUG_PARALLEL_OFF, + DEBUG_PARALLEL_ON, + DEBUG_PARALLEL_REGRESS +} DebugParallelMode; + +/* GUC parameters */ +extern PGDLLIMPORT int debug_parallel_query; +extern PGDLLIMPORT bool parallel_leader_participation; + +extern struct PlannedStmt *planner(Query *parse, const char *query_string, + int cursorOptions, + struct ParamListInfoData *boundParams); + +extern Expr *expression_planner(Expr *expr); +extern Expr *expression_planner_with_deps(Expr *expr, + List **relationOids, + List **invalItems); + +extern bool plan_cluster_use_sort(Oid tableOid, Oid indexOid); +extern int plan_create_index_workers(Oid tableOid, Oid indexOid); + +/* in plan/setrefs.c: */ + +extern void extract_query_dependencies(Node *query, + List **relationOids, + List **invalItems, + bool *hasRowSecurity); + +/* in prep/prepqual.c: */ + +extern Node *negate_clause(Node *node); +extern Expr *canonicalize_qual(Expr *qual, bool is_check); + +/* in util/clauses.c: */ + +extern bool contain_mutable_functions(Node *clause); +extern bool contain_mutable_functions_after_planning(Expr *expr); +extern bool contain_volatile_functions(Node *clause); +extern bool contain_volatile_functions_after_planning(Expr *expr); +extern bool contain_volatile_functions_not_nextval(Node *clause); + +extern Node *eval_const_expressions(PlannerInfo *root, Node *node); + +extern void convert_saop_to_hashed_saop(Node *node); + +extern Node *estimate_expression_value(PlannerInfo *root, Node *node); + +extern Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, + Oid result_collation); + +extern List *expand_function_arguments(List *args, bool include_out_arguments, + Oid result_type, + struct HeapTupleData *func_tuple); + +/* in util/predtest.c: */ + +extern bool predicate_implied_by(List *predicate_list, List *clause_list, + bool weak); +extern bool predicate_refuted_by(List *predicate_list, List *clause_list, + bool weak); + +/* in util/tlist.c: */ + +extern int count_nonjunk_tlist_entries(List *tlist); +extern TargetEntry *get_sortgroupref_tle(Index sortref, + List *targetList); +extern TargetEntry *get_sortgroupclause_tle(SortGroupClause *sgClause, + List *targetList); +extern Node *get_sortgroupclause_expr(SortGroupClause *sgClause, + List *targetList); +extern List *get_sortgrouplist_exprs(List *sgClauses, + List *targetList); +extern SortGroupClause *get_sortgroupref_clause(Index sortref, + List *clauses); +extern SortGroupClause *get_sortgroupref_clause_noerr(Index sortref, + List *clauses); + +/* in util/var.c: */ + +/* Bits that can be OR'd into the flags argument of pull_var_clause() */ +#define PVC_INCLUDE_AGGREGATES 0x0001 /* include Aggrefs in output list */ +#define PVC_RECURSE_AGGREGATES 0x0002 /* recurse into Aggref arguments */ +#define PVC_INCLUDE_WINDOWFUNCS 0x0004 /* include WindowFuncs in output list */ +#define PVC_RECURSE_WINDOWFUNCS 0x0008 /* recurse into WindowFunc arguments */ +#define PVC_INCLUDE_PLACEHOLDERS 0x0010 /* include PlaceHolderVars in + * output list */ +#define PVC_RECURSE_PLACEHOLDERS 0x0020 /* recurse into PlaceHolderVar + * arguments */ + +extern Bitmapset *pull_varnos(PlannerInfo *root, Node *node); +extern Bitmapset *pull_varnos_of_level(PlannerInfo *root, Node *node, int levelsup); +extern void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos); +extern List *pull_vars_of_level(Node *node, int levelsup); +extern bool contain_var_clause(Node *node); +extern bool contain_vars_of_level(Node *node, int levelsup); +extern int locate_var_of_level(Node *node, int levelsup); +extern List *pull_var_clause(Node *node, int flags); +extern Node *flatten_join_alias_vars(PlannerInfo *root, Query *query, Node *node); + +#endif /* OPTIMIZER_H */ diff --git a/install/include/postgresql/server/optimizer/orclauses.h b/install/include/postgresql/server/optimizer/orclauses.h new file mode 100644 index 00000000000..f9dbe6a2972 --- /dev/null +++ b/install/include/postgresql/server/optimizer/orclauses.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * orclauses.h + * prototypes for orclauses.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/orclauses.h + * + *------------------------------------------------------------------------- + */ +#ifndef ORCLAUSES_H +#define ORCLAUSES_H + +#include "nodes/pathnodes.h" + +extern void extract_restriction_or_clauses(PlannerInfo *root); + +#endif /* ORCLAUSES_H */ diff --git a/install/include/postgresql/server/optimizer/paramassign.h b/install/include/postgresql/server/optimizer/paramassign.h new file mode 100644 index 00000000000..55c27a62e57 --- /dev/null +++ b/install/include/postgresql/server/optimizer/paramassign.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * paramassign.h + * Functions for assigning PARAM_EXEC slots during planning. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/paramassign.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARAMASSIGN_H +#define PARAMASSIGN_H + +#include "nodes/pathnodes.h" + +extern Param *replace_outer_var(PlannerInfo *root, Var *var); +extern Param *replace_outer_placeholdervar(PlannerInfo *root, + PlaceHolderVar *phv); +extern Param *replace_outer_agg(PlannerInfo *root, Aggref *agg); +extern Param *replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp); +extern Param *replace_nestloop_param_var(PlannerInfo *root, Var *var); +extern Param *replace_nestloop_param_placeholdervar(PlannerInfo *root, + PlaceHolderVar *phv); +extern void process_subquery_nestloop_params(PlannerInfo *root, + List *subplan_params); +extern List *identify_current_nestloop_params(PlannerInfo *root, + Relids leftrelids); +extern Param *generate_new_exec_param(PlannerInfo *root, Oid paramtype, + int32 paramtypmod, Oid paramcollation); +extern int assign_special_exec_param(PlannerInfo *root); + +#endif /* PARAMASSIGN_H */ diff --git a/install/include/postgresql/server/optimizer/pathnode.h b/install/include/postgresql/server/optimizer/pathnode.h new file mode 100644 index 00000000000..001e75b5b76 --- /dev/null +++ b/install/include/postgresql/server/optimizer/pathnode.h @@ -0,0 +1,343 @@ +/*------------------------------------------------------------------------- + * + * pathnode.h + * prototypes for pathnode.c, relnode.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/pathnode.h + * + *------------------------------------------------------------------------- + */ +#ifndef PATHNODE_H +#define PATHNODE_H + +#include "nodes/bitmapset.h" +#include "nodes/pathnodes.h" + + +/* + * prototypes for pathnode.c + */ +extern int compare_path_costs(Path *path1, Path *path2, + CostSelector criterion); +extern int compare_fractional_path_costs(Path *path1, Path *path2, + double fraction); +extern void set_cheapest(RelOptInfo *parent_rel); +extern void add_path(RelOptInfo *parent_rel, Path *new_path); +extern bool add_path_precheck(RelOptInfo *parent_rel, + Cost startup_cost, Cost total_cost, + List *pathkeys, Relids required_outer); +extern void add_partial_path(RelOptInfo *parent_rel, Path *new_path); +extern bool add_partial_path_precheck(RelOptInfo *parent_rel, + Cost total_cost, List *pathkeys); + +extern Path *create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer, int parallel_workers); +extern Path *create_samplescan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern IndexPath *create_index_path(PlannerInfo *root, + IndexOptInfo *index, + List *indexclauses, + List *indexorderbys, + List *indexorderbycols, + List *pathkeys, + ScanDirection indexscandir, + bool indexonly, + Relids required_outer, + double loop_count, + bool partial_path); +extern BitmapHeapPath *create_bitmap_heap_path(PlannerInfo *root, + RelOptInfo *rel, + Path *bitmapqual, + Relids required_outer, + double loop_count, + int parallel_degree); +extern BitmapAndPath *create_bitmap_and_path(PlannerInfo *root, + RelOptInfo *rel, + List *bitmapquals); +extern BitmapOrPath *create_bitmap_or_path(PlannerInfo *root, + RelOptInfo *rel, + List *bitmapquals); +extern TidPath *create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, + List *tidquals, Relids required_outer); +extern TidRangePath *create_tidrangescan_path(PlannerInfo *root, + RelOptInfo *rel, + List *tidrangequals, + Relids required_outer); +extern AppendPath *create_append_path(PlannerInfo *root, RelOptInfo *rel, + List *subpaths, List *partial_subpaths, + List *pathkeys, Relids required_outer, + int parallel_workers, bool parallel_aware, + double rows); +extern MergeAppendPath *create_merge_append_path(PlannerInfo *root, + RelOptInfo *rel, + List *subpaths, + List *pathkeys, + Relids required_outer); +extern GroupResultPath *create_group_result_path(PlannerInfo *root, + RelOptInfo *rel, + PathTarget *target, + List *havingqual); +extern MaterialPath *create_material_path(RelOptInfo *rel, Path *subpath); +extern MemoizePath *create_memoize_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + List *param_exprs, + List *hash_operators, + bool singlerow, + bool binary_mode, + double calls); +extern UniquePath *create_unique_path(PlannerInfo *root, RelOptInfo *rel, + Path *subpath, SpecialJoinInfo *sjinfo); +extern GatherPath *create_gather_path(PlannerInfo *root, + RelOptInfo *rel, Path *subpath, PathTarget *target, + Relids required_outer, double *rows); +extern GatherMergePath *create_gather_merge_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + PathTarget *target, + List *pathkeys, + Relids required_outer, + double *rows); +extern SubqueryScanPath *create_subqueryscan_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + bool trivial_pathtarget, + List *pathkeys, + Relids required_outer); +extern Path *create_functionscan_path(PlannerInfo *root, RelOptInfo *rel, + List *pathkeys, Relids required_outer); +extern Path *create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern Path *create_tablefuncscan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern Path *create_ctescan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern Path *create_namedtuplestorescan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern Path *create_resultscan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern Path *create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern ForeignPath *create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Relids required_outer, + Path *fdw_outerpath, + List *fdw_private); +extern ForeignPath *create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Relids required_outer, + Path *fdw_outerpath, + List *fdw_private); +extern ForeignPath *create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Path *fdw_outerpath, + List *fdw_private); + +extern Relids calc_nestloop_required_outer(Relids outerrelids, + Relids outer_paramrels, + Relids innerrelids, + Relids inner_paramrels); +extern Relids calc_non_nestloop_required_outer(Path *outer_path, Path *inner_path); + +extern NestPath *create_nestloop_path(PlannerInfo *root, + RelOptInfo *joinrel, + JoinType jointype, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra, + Path *outer_path, + Path *inner_path, + List *restrict_clauses, + List *pathkeys, + Relids required_outer); + +extern MergePath *create_mergejoin_path(PlannerInfo *root, + RelOptInfo *joinrel, + JoinType jointype, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra, + Path *outer_path, + Path *inner_path, + List *restrict_clauses, + List *pathkeys, + Relids required_outer, + List *mergeclauses, + List *outersortkeys, + List *innersortkeys); + +extern HashPath *create_hashjoin_path(PlannerInfo *root, + RelOptInfo *joinrel, + JoinType jointype, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra, + Path *outer_path, + Path *inner_path, + bool parallel_hash, + List *restrict_clauses, + Relids required_outer, + List *hashclauses); + +extern ProjectionPath *create_projection_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + PathTarget *target); +extern Path *apply_projection_to_path(PlannerInfo *root, + RelOptInfo *rel, + Path *path, + PathTarget *target); +extern ProjectSetPath *create_set_projection_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + PathTarget *target); +extern SortPath *create_sort_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + List *pathkeys, + double limit_tuples); +extern IncrementalSortPath *create_incremental_sort_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + List *pathkeys, + int presorted_keys, + double limit_tuples); +extern GroupPath *create_group_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + List *groupClause, + List *qual, + double numGroups); +extern UpperUniquePath *create_upper_unique_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + int numCols, + double numGroups); +extern AggPath *create_agg_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + PathTarget *target, + AggStrategy aggstrategy, + AggSplit aggsplit, + List *groupClause, + List *qual, + const AggClauseCosts *aggcosts, + double numGroups); +extern GroupingSetsPath *create_groupingsets_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + List *having_qual, + AggStrategy aggstrategy, + List *rollups, + const AggClauseCosts *agg_costs); +extern MinMaxAggPath *create_minmaxagg_path(PlannerInfo *root, + RelOptInfo *rel, + PathTarget *target, + List *mmaggregates, + List *quals); +extern WindowAggPath *create_windowagg_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + PathTarget *target, + List *windowFuncs, + WindowClause *winclause, + List *qual, + bool topwindow); +extern SetOpPath *create_setop_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + SetOpCmd cmd, + SetOpStrategy strategy, + List *distinctList, + AttrNumber flagColIdx, + int firstFlag, + double numGroups, + double outputRows); +extern RecursiveUnionPath *create_recursiveunion_path(PlannerInfo *root, + RelOptInfo *rel, + Path *leftpath, + Path *rightpath, + PathTarget *target, + List *distinctList, + int wtParam, + double numGroups); +extern LockRowsPath *create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, + Path *subpath, List *rowMarks, int epqParam); +extern ModifyTablePath *create_modifytable_path(PlannerInfo *root, + RelOptInfo *rel, + Path *subpath, + CmdType operation, bool canSetTag, + Index nominalRelation, Index rootRelation, + bool partColsUpdated, + List *resultRelations, + List *updateColnosLists, + List *withCheckOptionLists, List *returningLists, + List *rowMarks, OnConflictExpr *onconflict, + List *mergeActionLists, int epqParam); +extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel, + Path *subpath, + Node *limitOffset, Node *limitCount, + LimitOption limitOption, + int64 offset_est, int64 count_est); +extern void adjust_limit_rows_costs(double *rows, + Cost *startup_cost, Cost *total_cost, + int64 offset_est, int64 count_est); + +extern Path *reparameterize_path(PlannerInfo *root, Path *path, + Relids required_outer, + double loop_count); +extern Path *reparameterize_path_by_child(PlannerInfo *root, Path *path, + RelOptInfo *child_rel); + +/* + * prototypes for relnode.c + */ +extern void setup_simple_rel_arrays(PlannerInfo *root); +extern void expand_planner_arrays(PlannerInfo *root, int add_size); +extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid, + RelOptInfo *parent); +extern RelOptInfo *find_base_rel(PlannerInfo *root, int relid); +extern RelOptInfo *find_base_rel_ignore_join(PlannerInfo *root, int relid); +extern RelOptInfo *find_join_rel(PlannerInfo *root, Relids relids); +extern RelOptInfo *build_join_rel(PlannerInfo *root, + Relids joinrelids, + RelOptInfo *outer_rel, + RelOptInfo *inner_rel, + SpecialJoinInfo *sjinfo, + List *pushed_down_joins, + List **restrictlist_ptr); +extern Relids min_join_parameterization(PlannerInfo *root, + Relids joinrelids, + RelOptInfo *outer_rel, + RelOptInfo *inner_rel); +extern RelOptInfo *fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, + Relids relids); +extern Relids find_childrel_parents(PlannerInfo *root, RelOptInfo *rel); +extern ParamPathInfo *get_baserel_parampathinfo(PlannerInfo *root, + RelOptInfo *baserel, + Relids required_outer); +extern ParamPathInfo *get_joinrel_parampathinfo(PlannerInfo *root, + RelOptInfo *joinrel, + Path *outer_path, + Path *inner_path, + SpecialJoinInfo *sjinfo, + Relids required_outer, + List **restrict_clauses); +extern ParamPathInfo *get_appendrel_parampathinfo(RelOptInfo *appendrel, + Relids required_outer); +extern ParamPathInfo *find_param_path_info(RelOptInfo *rel, + Relids required_outer); +extern Bitmapset *get_param_path_clause_serials(Path *path); +extern RelOptInfo *build_child_join_rel(PlannerInfo *root, + RelOptInfo *outer_rel, RelOptInfo *inner_rel, + RelOptInfo *parent_joinrel, List *restrictlist, + SpecialJoinInfo *sjinfo); + +#endif /* PATHNODE_H */ diff --git a/install/include/postgresql/server/optimizer/paths.h b/install/include/postgresql/server/optimizer/paths.h new file mode 100644 index 00000000000..50bc3b503a6 --- /dev/null +++ b/install/include/postgresql/server/optimizer/paths.h @@ -0,0 +1,266 @@ +/*------------------------------------------------------------------------- + * + * paths.h + * prototypes for various files in optimizer/path + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/paths.h + * + *------------------------------------------------------------------------- + */ +#ifndef PATHS_H +#define PATHS_H + +#include "nodes/pathnodes.h" + + +/* + * allpaths.c + */ +extern PGDLLIMPORT bool enable_geqo; +extern PGDLLIMPORT int geqo_threshold; +extern PGDLLIMPORT int min_parallel_table_scan_size; +extern PGDLLIMPORT int min_parallel_index_scan_size; + +/* Hook for plugins to get control in set_rel_pathlist() */ +typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root, + RelOptInfo *rel, + Index rti, + RangeTblEntry *rte); +extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook; + +/* Hook for plugins to get control in add_paths_to_joinrel() */ +typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root, + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + JoinPathExtraData *extra); +extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook; + +/* Hook for plugins to replace standard_join_search() */ +typedef RelOptInfo *(*join_search_hook_type) (PlannerInfo *root, + int levels_needed, + List *initial_rels); +extern PGDLLIMPORT join_search_hook_type join_search_hook; + + +extern RelOptInfo *make_one_rel(PlannerInfo *root, List *joinlist); +extern RelOptInfo *standard_join_search(PlannerInfo *root, int levels_needed, + List *initial_rels); + +extern void generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, + bool override_rows); +extern void generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, + bool override_rows); +extern int compute_parallel_worker(RelOptInfo *rel, double heap_pages, + double index_pages, int max_workers); +extern void create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel, + Path *bitmapqual); +extern void generate_partitionwise_join_paths(PlannerInfo *root, + RelOptInfo *rel); + +#ifdef OPTIMIZER_DEBUG +extern void debug_print_rel(PlannerInfo *root, RelOptInfo *rel); +#endif + +/* + * indxpath.c + * routines to generate index paths + */ +extern void create_index_paths(PlannerInfo *root, RelOptInfo *rel); +extern bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, + List *restrictlist, + List *exprlist, List *oprlist); +extern bool indexcol_is_bool_constant_for_query(PlannerInfo *root, + IndexOptInfo *index, + int indexcol); +extern bool match_index_to_operand(Node *operand, int indexcol, + IndexOptInfo *index); +extern void check_index_predicates(PlannerInfo *root, RelOptInfo *rel); + +/* + * tidpath.h + * routines to generate tid paths + */ +extern void create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel); + +/* + * joinpath.c + * routines to create join paths + */ +extern void add_paths_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, + RelOptInfo *outerrel, RelOptInfo *innerrel, + JoinType jointype, SpecialJoinInfo *sjinfo, + List *restrictlist); + +/* + * joinrels.c + * routines to determine which relations to join + */ +extern void join_search_one_level(PlannerInfo *root, int level); +extern RelOptInfo *make_join_rel(PlannerInfo *root, + RelOptInfo *rel1, RelOptInfo *rel2); +extern Relids add_outer_joins_to_relids(PlannerInfo *root, Relids input_relids, + SpecialJoinInfo *sjinfo, + List **pushed_down_joins); +extern bool have_join_order_restriction(PlannerInfo *root, + RelOptInfo *rel1, RelOptInfo *rel2); +extern bool have_dangerous_phv(PlannerInfo *root, + Relids outer_relids, Relids inner_params); +extern void mark_dummy_rel(RelOptInfo *rel); + +/* + * equivclass.c + * routines for managing EquivalenceClasses + */ +typedef bool (*ec_matches_callback_type) (PlannerInfo *root, + RelOptInfo *rel, + EquivalenceClass *ec, + EquivalenceMember *em, + void *arg); + +extern bool process_equivalence(PlannerInfo *root, + RestrictInfo **p_restrictinfo, + JoinDomain *jdomain); +extern Expr *canonicalize_ec_expression(Expr *expr, + Oid req_type, Oid req_collation); +extern void reconsider_outer_join_clauses(PlannerInfo *root); +extern EquivalenceClass *get_eclass_for_sort_expr(PlannerInfo *root, + Expr *expr, + List *opfamilies, + Oid opcintype, + Oid collation, + Index sortref, + Relids rel, + bool create_it); +extern EquivalenceMember *find_ec_member_matching_expr(EquivalenceClass *ec, + Expr *expr, + Relids relids); +extern EquivalenceMember *find_computable_ec_member(PlannerInfo *root, + EquivalenceClass *ec, + List *exprs, + Relids relids, + bool require_parallel_safe); +extern bool relation_can_be_sorted_early(PlannerInfo *root, RelOptInfo *rel, + EquivalenceClass *ec, + bool require_parallel_safe); +extern void generate_base_implied_equalities(PlannerInfo *root); +extern List *generate_join_implied_equalities(PlannerInfo *root, + Relids join_relids, + Relids outer_relids, + RelOptInfo *inner_rel, + SpecialJoinInfo *sjinfo); +extern List *generate_join_implied_equalities_for_ecs(PlannerInfo *root, + List *eclasses, + Relids join_relids, + Relids outer_relids, + RelOptInfo *inner_rel); +extern bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2); +extern EquivalenceClass *match_eclasses_to_foreign_key_col(PlannerInfo *root, + ForeignKeyOptInfo *fkinfo, + int colno); +extern RestrictInfo *find_derived_clause_for_ec_member(EquivalenceClass *ec, + EquivalenceMember *em); +extern void add_child_rel_equivalences(PlannerInfo *root, + AppendRelInfo *appinfo, + RelOptInfo *parent_rel, + RelOptInfo *child_rel); +extern void add_child_join_rel_equivalences(PlannerInfo *root, + int nappinfos, + AppendRelInfo **appinfos, + RelOptInfo *parent_joinrel, + RelOptInfo *child_joinrel); +extern List *generate_implied_equalities_for_column(PlannerInfo *root, + RelOptInfo *rel, + ec_matches_callback_type callback, + void *callback_arg, + Relids prohibited_rels); +extern bool have_relevant_eclass_joinclause(PlannerInfo *root, + RelOptInfo *rel1, RelOptInfo *rel2); +extern bool has_relevant_eclass_joinclause(PlannerInfo *root, + RelOptInfo *rel1); +extern bool eclass_useful_for_merging(PlannerInfo *root, + EquivalenceClass *eclass, + RelOptInfo *rel); +extern bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist); +extern bool is_redundant_with_indexclauses(RestrictInfo *rinfo, + List *indexclauses); + +/* + * pathkeys.c + * utilities for matching and building path keys + */ +typedef enum +{ + PATHKEYS_EQUAL, /* pathkeys are identical */ + PATHKEYS_BETTER1, /* pathkey 1 is a superset of pathkey 2 */ + PATHKEYS_BETTER2, /* vice versa */ + PATHKEYS_DIFFERENT /* neither pathkey includes the other */ +} PathKeysComparison; + +extern PathKeysComparison compare_pathkeys(List *keys1, List *keys2); +extern bool pathkeys_contained_in(List *keys1, List *keys2); +extern bool pathkeys_count_contained_in(List *keys1, List *keys2, int *n_common); +extern Path *get_cheapest_path_for_pathkeys(List *paths, List *pathkeys, + Relids required_outer, + CostSelector cost_criterion, + bool require_parallel_safe); +extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths, + List *pathkeys, + Relids required_outer, + double fraction); +extern Path *get_cheapest_parallel_safe_total_inner(List *paths); +extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index, + ScanDirection scandir); +extern List *build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel, + ScanDirection scandir, bool *partialkeys); +extern List *build_expression_pathkey(PlannerInfo *root, Expr *expr, + Oid opno, + Relids rel, bool create_it); +extern List *convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, + List *subquery_pathkeys, + List *subquery_tlist); +extern List *build_join_pathkeys(PlannerInfo *root, + RelOptInfo *joinrel, + JoinType jointype, + List *outer_pathkeys); +extern List *make_pathkeys_for_sortclauses(PlannerInfo *root, + List *sortclauses, + List *tlist); +extern List *make_pathkeys_for_sortclauses_extended(PlannerInfo *root, + List **sortclauses, + List *tlist, + bool remove_redundant, + bool *sortable); +extern void initialize_mergeclause_eclasses(PlannerInfo *root, + RestrictInfo *restrictinfo); +extern void update_mergeclause_eclasses(PlannerInfo *root, + RestrictInfo *restrictinfo); +extern List *find_mergeclauses_for_outer_pathkeys(PlannerInfo *root, + List *pathkeys, + List *restrictinfos); +extern List *select_outer_pathkeys_for_merge(PlannerInfo *root, + List *mergeclauses, + RelOptInfo *joinrel); +extern List *make_inner_pathkeys_for_merge(PlannerInfo *root, + List *mergeclauses, + List *outer_pathkeys); +extern List *trim_mergeclauses_for_inner_pathkeys(PlannerInfo *root, + List *mergeclauses, + List *pathkeys); +extern List *truncate_useless_pathkeys(PlannerInfo *root, + RelOptInfo *rel, + List *pathkeys); +extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel); +extern List *append_pathkeys(List *target, List *source); +extern PathKey *make_canonical_pathkey(PlannerInfo *root, + EquivalenceClass *eclass, Oid opfamily, + int strategy, bool nulls_first); +extern void add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, + List *live_childrels); + +#endif /* PATHS_H */ diff --git a/install/include/postgresql/server/optimizer/placeholder.h b/install/include/postgresql/server/optimizer/placeholder.h new file mode 100644 index 00000000000..acb9cf9f05c --- /dev/null +++ b/install/include/postgresql/server/optimizer/placeholder.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * placeholder.h + * prototypes for optimizer/util/placeholder.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/placeholder.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLACEHOLDER_H +#define PLACEHOLDER_H + +#include "nodes/pathnodes.h" + + +extern PlaceHolderVar *make_placeholder_expr(PlannerInfo *root, Expr *expr, + Relids phrels); +extern PlaceHolderInfo *find_placeholder_info(PlannerInfo *root, + PlaceHolderVar *phv); +extern void find_placeholders_in_jointree(PlannerInfo *root); +extern void fix_placeholder_input_needed_levels(PlannerInfo *root); +extern void add_placeholders_to_base_rels(PlannerInfo *root); +extern void add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, + RelOptInfo *outer_rel, RelOptInfo *inner_rel, + SpecialJoinInfo *sjinfo); +extern bool contain_placeholder_references_to(PlannerInfo *root, Node *clause, + int relid); + +#endif /* PLACEHOLDER_H */ diff --git a/install/include/postgresql/server/optimizer/plancat.h b/install/include/postgresql/server/optimizer/plancat.h new file mode 100644 index 00000000000..dbb7eb86808 --- /dev/null +++ b/install/include/postgresql/server/optimizer/plancat.h @@ -0,0 +1,82 @@ +/*------------------------------------------------------------------------- + * + * plancat.h + * prototypes for plancat.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/plancat.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLANCAT_H +#define PLANCAT_H + +#include "nodes/pathnodes.h" +#include "utils/relcache.h" + +/* Hook for plugins to get control in get_relation_info() */ +typedef void (*get_relation_info_hook_type) (PlannerInfo *root, + Oid relationObjectId, + bool inhparent, + RelOptInfo *rel); +extern PGDLLIMPORT get_relation_info_hook_type get_relation_info_hook; + + +extern void get_relation_info(PlannerInfo *root, Oid relationObjectId, + bool inhparent, RelOptInfo *rel); + +extern List *infer_arbiter_indexes(PlannerInfo *root); + +extern void estimate_rel_size(Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, double *allvisfrac); + +extern int32 get_rel_data_width(Relation rel, int32 *attr_widths); +extern int32 get_relation_data_width(Oid relid, int32 *attr_widths); + +extern bool relation_excluded_by_constraints(PlannerInfo *root, + RelOptInfo *rel, RangeTblEntry *rte); + +extern List *build_physical_tlist(PlannerInfo *root, RelOptInfo *rel); + +extern bool has_unique_index(RelOptInfo *rel, AttrNumber attno); + +extern Selectivity restriction_selectivity(PlannerInfo *root, + Oid operatorid, + List *args, + Oid inputcollid, + int varRelid); + +extern Selectivity join_selectivity(PlannerInfo *root, + Oid operatorid, + List *args, + Oid inputcollid, + JoinType jointype, + SpecialJoinInfo *sjinfo); + +extern Selectivity function_selectivity(PlannerInfo *root, + Oid funcid, + List *args, + Oid inputcollid, + bool is_join, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo); + +extern void add_function_cost(PlannerInfo *root, Oid funcid, Node *node, + QualCost *cost); + +extern double get_function_rows(PlannerInfo *root, Oid funcid, Node *node); + +extern bool has_row_triggers(PlannerInfo *root, Index rti, CmdType event); + +extern bool has_transition_tables(PlannerInfo *root, Index rti, CmdType event); + +extern bool has_stored_generated_columns(PlannerInfo *root, Index rti); + +extern Bitmapset *get_dependent_generated_columns(PlannerInfo *root, Index rti, + Bitmapset *target_cols); + +#endif /* PLANCAT_H */ diff --git a/install/include/postgresql/server/optimizer/planmain.h b/install/include/postgresql/server/optimizer/planmain.h new file mode 100644 index 00000000000..31c188176b7 --- /dev/null +++ b/install/include/postgresql/server/optimizer/planmain.h @@ -0,0 +1,119 @@ +/*------------------------------------------------------------------------- + * + * planmain.h + * prototypes for various files in optimizer/plan + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/planmain.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLANMAIN_H +#define PLANMAIN_H + +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" + +/* GUC parameters */ +#define DEFAULT_CURSOR_TUPLE_FRACTION 0.1 +extern PGDLLIMPORT double cursor_tuple_fraction; + +/* query_planner callback to compute query_pathkeys */ +typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra); + +/* + * prototypes for plan/planmain.c + */ +extern RelOptInfo *query_planner(PlannerInfo *root, + query_pathkeys_callback qp_callback, void *qp_extra); + +/* + * prototypes for plan/planagg.c + */ +extern void preprocess_minmax_aggregates(PlannerInfo *root); + +/* + * prototypes for plan/createplan.c + */ +extern Plan *create_plan(PlannerInfo *root, Path *best_path); +extern ForeignScan *make_foreignscan(List *qptlist, List *qpqual, + Index scanrelid, List *fdw_exprs, List *fdw_private, + List *fdw_scan_tlist, List *fdw_recheck_quals, + Plan *outer_plan); +extern Plan *change_plan_targetlist(Plan *subplan, List *tlist, + bool tlist_parallel_safe); +extern Plan *materialize_finished_plan(Plan *subplan); +extern bool is_projection_capable_path(Path *path); +extern bool is_projection_capable_plan(Plan *plan); + +/* External use of these functions is deprecated: */ +extern Sort *make_sort_from_sortclauses(List *sortcls, Plan *lefttree); +extern Agg *make_agg(List *tlist, List *qual, + AggStrategy aggstrategy, AggSplit aggsplit, + int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, + List *groupingSets, List *chain, double dNumGroups, + Size transitionSpace, Plan *lefttree); +extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount, + LimitOption limitOption, int uniqNumCols, + AttrNumber *uniqColIdx, Oid *uniqOperators, + Oid *uniqCollations); + +/* + * prototypes for plan/initsplan.c + */ +extern PGDLLIMPORT int from_collapse_limit; +extern PGDLLIMPORT int join_collapse_limit; + +extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode); +extern void add_other_rels_to_query(PlannerInfo *root); +extern void build_base_rel_tlists(PlannerInfo *root, List *final_tlist); +extern void add_vars_to_targetlist(PlannerInfo *root, List *vars, + Relids where_needed); +extern void find_lateral_references(PlannerInfo *root); +extern void create_lateral_join_info(PlannerInfo *root); +extern List *deconstruct_jointree(PlannerInfo *root); +extern void distribute_restrictinfo_to_rels(PlannerInfo *root, + RestrictInfo *restrictinfo); +extern RestrictInfo *process_implied_equality(PlannerInfo *root, + Oid opno, + Oid collation, + Expr *item1, + Expr *item2, + Relids qualscope, + Index security_level, + bool both_const); +extern RestrictInfo *build_implied_join_equality(PlannerInfo *root, + Oid opno, + Oid collation, + Expr *item1, + Expr *item2, + Relids qualscope, + Index security_level); +extern void match_foreign_keys_to_quals(PlannerInfo *root); + +/* + * prototypes for plan/analyzejoins.c + */ +extern List *remove_useless_joins(PlannerInfo *root, List *joinlist); +extern void reduce_unique_semijoins(PlannerInfo *root); +extern bool query_supports_distinctness(Query *query); +extern bool query_is_distinct_for(Query *query, List *colnos, List *opids); +extern bool innerrel_is_unique(PlannerInfo *root, + Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, + JoinType jointype, List *restrictlist, bool force_cache); + +/* + * prototypes for plan/setrefs.c + */ +extern Plan *set_plan_references(PlannerInfo *root, Plan *plan); +extern bool trivial_subqueryscan(SubqueryScan *plan); +extern Param *find_minmax_agg_replacement_param(PlannerInfo *root, + Aggref *aggref); +extern void record_plan_function_dependency(PlannerInfo *root, Oid funcid); +extern void record_plan_type_dependency(PlannerInfo *root, Oid typid); +extern bool extract_query_dependencies_walker(Node *node, PlannerInfo *context); + +#endif /* PLANMAIN_H */ diff --git a/install/include/postgresql/server/optimizer/planner.h b/install/include/postgresql/server/optimizer/planner.h new file mode 100644 index 00000000000..fc2e15496dd --- /dev/null +++ b/install/include/postgresql/server/optimizer/planner.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * planner.h + * prototypes for planner.c. + * + * Note that the primary entry points for planner.c are declared in + * optimizer/optimizer.h, because they're intended to be called from + * non-planner code. Declarations here are meant for use by other + * planner modules. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/planner.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLANNER_H +#define PLANNER_H + +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" + + +/* Hook for plugins to get control in planner() */ +typedef PlannedStmt *(*planner_hook_type) (Query *parse, + const char *query_string, + int cursorOptions, + ParamListInfo boundParams); +extern PGDLLIMPORT planner_hook_type planner_hook; + +/* Hook for plugins to get control when grouping_planner() plans upper rels */ +typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, + UpperRelationKind stage, + RelOptInfo *input_rel, + RelOptInfo *output_rel, + void *extra); +extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook; + + +extern PlannedStmt *standard_planner(Query *parse, const char *query_string, + int cursorOptions, + ParamListInfo boundParams); + +extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse, + PlannerInfo *parent_root, + bool hasRecursion, double tuple_fraction); + +extern RowMarkType select_rowmark_type(RangeTblEntry *rte, + LockClauseStrength strength); + +extern bool limit_needed(Query *parse); + +extern void mark_partial_aggref(Aggref *agg, AggSplit aggsplit); + +extern Path *get_cheapest_fractional_path(RelOptInfo *rel, + double tuple_fraction); + +extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr); + +#endif /* PLANNER_H */ diff --git a/install/include/postgresql/server/optimizer/prep.h b/install/include/postgresql/server/optimizer/prep.h new file mode 100644 index 00000000000..54fd61c9c3e --- /dev/null +++ b/install/include/postgresql/server/optimizer/prep.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * prep.h + * prototypes for files in optimizer/prep/ + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/prep.h + * + *------------------------------------------------------------------------- + */ +#ifndef PREP_H +#define PREP_H + +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" + + +/* + * prototypes for prepjointree.c + */ +extern void transform_MERGE_to_join(Query *parse); +extern void replace_empty_jointree(Query *parse); +extern void pull_up_sublinks(PlannerInfo *root); +extern void preprocess_function_rtes(PlannerInfo *root); +extern void pull_up_subqueries(PlannerInfo *root); +extern void flatten_simple_union_all(PlannerInfo *root); +extern void reduce_outer_joins(PlannerInfo *root); +extern void remove_useless_result_rtes(PlannerInfo *root); +extern Relids get_relids_in_jointree(Node *jtnode, bool include_outer_joins, + bool include_inner_joins); +extern Relids get_relids_for_join(Query *query, int joinrelid); + +/* + * prototypes for preptlist.c + */ +extern void preprocess_targetlist(PlannerInfo *root); + +extern List *extract_update_targetlist_colnos(List *tlist); + +extern PlanRowMark *get_plan_rowmark(List *rowmarks, Index rtindex); + +/* + * prototypes for prepagg.c + */ +extern void get_agg_clause_costs(PlannerInfo *root, AggSplit aggsplit, + AggClauseCosts *costs); +extern void preprocess_aggrefs(PlannerInfo *root, Node *clause); + +/* + * prototypes for prepunion.c + */ +extern RelOptInfo *plan_set_operations(PlannerInfo *root); + + +#endif /* PREP_H */ diff --git a/install/include/postgresql/server/optimizer/restrictinfo.h b/install/include/postgresql/server/optimizer/restrictinfo.h new file mode 100644 index 00000000000..14cdce750cb --- /dev/null +++ b/install/include/postgresql/server/optimizer/restrictinfo.h @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * restrictinfo.h + * prototypes for restrictinfo.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/restrictinfo.h + * + *------------------------------------------------------------------------- + */ +#ifndef RESTRICTINFO_H +#define RESTRICTINFO_H + +#include "nodes/pathnodes.h" + + +/* Convenience macro for the common case of a valid-everywhere qual */ +#define make_simple_restrictinfo(root, clause) \ + make_restrictinfo(root, clause, true, false, false, false, 0, \ + NULL, NULL, NULL) + +extern RestrictInfo *make_restrictinfo(PlannerInfo *root, + Expr *clause, + bool is_pushed_down, + bool has_clone, + bool is_clone, + bool pseudoconstant, + Index security_level, + Relids required_relids, + Relids incompatible_relids, + Relids outer_relids); +extern RestrictInfo *commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op); +extern bool restriction_is_or_clause(RestrictInfo *restrictinfo); +extern bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, + RelOptInfo *rel); +extern List *get_actual_clauses(List *restrictinfo_list); +extern List *extract_actual_clauses(List *restrictinfo_list, + bool pseudoconstant); +extern void extract_actual_join_clauses(List *restrictinfo_list, + Relids joinrelids, + List **joinquals, + List **otherquals); +extern bool has_pseudoconstant_clauses(PlannerInfo *root, + List *restrictinfo_list); +extern bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel); +extern bool join_clause_is_movable_into(RestrictInfo *rinfo, + Relids currentrelids, + Relids current_and_outer); + +#endif /* RESTRICTINFO_H */ diff --git a/install/include/postgresql/server/optimizer/subselect.h b/install/include/postgresql/server/optimizer/subselect.h new file mode 100644 index 00000000000..c03ffc56bf6 --- /dev/null +++ b/install/include/postgresql/server/optimizer/subselect.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------- + * + * subselect.h + * Planning routines for subselects. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/subselect.h + * + *------------------------------------------------------------------------- + */ +#ifndef SUBSELECT_H +#define SUBSELECT_H + +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" + +extern void SS_process_ctes(PlannerInfo *root); +extern JoinExpr *convert_ANY_sublink_to_join(PlannerInfo *root, + SubLink *sublink, + Relids available_rels); +extern JoinExpr *convert_EXISTS_sublink_to_join(PlannerInfo *root, + SubLink *sublink, + bool under_not, + Relids available_rels); +extern Node *SS_replace_correlation_vars(PlannerInfo *root, Node *expr); +extern Node *SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual); +extern void SS_identify_outer_params(PlannerInfo *root); +extern void SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel); +extern void SS_attach_initplans(PlannerInfo *root, Plan *plan); +extern void SS_finalize_plan(PlannerInfo *root, Plan *plan); +extern Param *SS_make_initplan_output_param(PlannerInfo *root, + Oid resulttype, int32 resulttypmod, + Oid resultcollation); +extern void SS_make_initplan_from_plan(PlannerInfo *root, + PlannerInfo *subroot, Plan *plan, + Param *prm); + +#endif /* SUBSELECT_H */ diff --git a/install/include/postgresql/server/optimizer/tlist.h b/install/include/postgresql/server/optimizer/tlist.h new file mode 100644 index 00000000000..ca64309c329 --- /dev/null +++ b/install/include/postgresql/server/optimizer/tlist.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * tlist.h + * prototypes for tlist.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/tlist.h + * + *------------------------------------------------------------------------- + */ +#ifndef TLIST_H +#define TLIST_H + +#include "nodes/pathnodes.h" + + +extern TargetEntry *tlist_member(Expr *node, List *targetlist); + +extern List *add_to_flat_tlist(List *tlist, List *exprs); + +extern List *get_tlist_exprs(List *tlist, bool includeJunk); + +extern bool tlist_same_exprs(List *tlist1, List *tlist2); + +extern bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK); +extern bool tlist_same_collations(List *tlist, List *colCollations, bool junkOK); + +extern void apply_tlist_labeling(List *dest_tlist, List *src_tlist); + +extern Oid *extract_grouping_ops(List *groupClause); +extern Oid *extract_grouping_collations(List *groupClause, List *tlist); +extern AttrNumber *extract_grouping_cols(List *groupClause, List *tlist); +extern bool grouping_is_sortable(List *groupClause); +extern bool grouping_is_hashable(List *groupClause); + +extern PathTarget *make_pathtarget_from_tlist(List *tlist); +extern List *make_tlist_from_pathtarget(PathTarget *target); +extern PathTarget *copy_pathtarget(PathTarget *src); +extern PathTarget *create_empty_pathtarget(void); +extern void add_column_to_pathtarget(PathTarget *target, + Expr *expr, Index sortgroupref); +extern void add_new_column_to_pathtarget(PathTarget *target, Expr *expr); +extern void add_new_columns_to_pathtarget(PathTarget *target, List *exprs); +extern void apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target); +extern void split_pathtarget_at_srfs(PlannerInfo *root, + PathTarget *target, PathTarget *input_target, + List **targets, List **targets_contain_srfs); + +/* Convenience macro to get a PathTarget with valid cost/width fields */ +#define create_pathtarget(root, tlist) \ + set_pathtarget_cost_width(root, make_pathtarget_from_tlist(tlist)) + +#endif /* TLIST_H */ diff --git a/install/include/postgresql/server/parser/analyze.h b/install/include/postgresql/server/parser/analyze.h new file mode 100644 index 00000000000..c96483ae784 --- /dev/null +++ b/install/include/postgresql/server/parser/analyze.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * analyze.h + * parse analysis for optimizable statements + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/analyze.h + * + *------------------------------------------------------------------------- + */ +#ifndef ANALYZE_H +#define ANALYZE_H + +#include "nodes/params.h" +#include "nodes/queryjumble.h" +#include "parser/parse_node.h" + +/* Hook for plugins to get control at end of parse analysis */ +typedef void (*post_parse_analyze_hook_type) (ParseState *pstate, + Query *query, + JumbleState *jstate); +extern PGDLLIMPORT post_parse_analyze_hook_type post_parse_analyze_hook; + + +extern Query *parse_analyze_fixedparams(RawStmt *parseTree, const char *sourceText, + const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv); +extern Query *parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, + Oid **paramTypes, int *numParams, QueryEnvironment *queryEnv); +extern Query *parse_analyze_withcb(RawStmt *parseTree, const char *sourceText, + ParserSetupHook parserSetup, + void *parserSetupArg, + QueryEnvironment *queryEnv); + +extern Query *parse_sub_analyze(Node *parseTree, ParseState *parentParseState, + CommonTableExpr *parentCTE, + bool locked_from_parent, + bool resolve_unknowns); + +extern List *transformInsertRow(ParseState *pstate, List *exprlist, + List *stmtcols, List *icolumns, List *attrnos, + bool strip_indirection); +extern List *transformUpdateTargetList(ParseState *pstate, + List *origTlist); +extern Query *transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree); +extern Query *transformStmt(ParseState *pstate, Node *parseTree); + +extern bool stmt_requires_parse_analysis(RawStmt *parseTree); +extern bool analyze_requires_snapshot(RawStmt *parseTree); + +extern const char *LCS_asString(LockClauseStrength strength); +extern void CheckSelectLocking(Query *qry, LockClauseStrength strength); +extern void applyLockingClause(Query *qry, Index rtindex, + LockClauseStrength strength, + LockWaitPolicy waitPolicy, bool pushedDown); + +extern List *BuildOnConflictExcludedTargetlist(Relation targetrel, + Index exclRelIndex); + +extern SortGroupClause *makeSortGroupClauseForSetOp(Oid rescoltype, bool require_hash); + +#endif /* ANALYZE_H */ diff --git a/install/include/postgresql/server/parser/kwlist.h b/install/include/postgresql/server/parser/kwlist.h new file mode 100644 index 00000000000..f5b2e61ca52 --- /dev/null +++ b/install/include/postgresql/server/parser/kwlist.h @@ -0,0 +1,498 @@ +/*------------------------------------------------------------------------- + * + * kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/parser/kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* there is deliberately not an #ifndef KWLIST_H here */ + +/* + * List of keyword (name, token-value, category, bare-label-status) entries. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value, category, is-bare-label */ +PG_KEYWORD("abort", ABORT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("absent", ABSENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("absolute", ABSOLUTE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("access", ACCESS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("add", ADD_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("admin", ADMIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("after", AFTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("aggregate", AGGREGATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("all", ALL, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("also", ALSO, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("alter", ALTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("always", ALWAYS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("analyse", ANALYSE, RESERVED_KEYWORD, BARE_LABEL) /* British spelling */ +PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("and", AND, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("any", ANY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("array", ARRAY, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("as", AS, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("asc", ASC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("asensitive", ASENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("assertion", ASSERTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("assignment", ASSIGNMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("asymmetric", ASYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("at", AT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("atomic", ATOMIC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("attach", ATTACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("attribute", ATTRIBUTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("authorization", AUTHORIZATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("backward", BACKWARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("before", BEFORE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("begin", BEGIN_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("between", BETWEEN, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("bigint", BIGINT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("binary", BINARY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("bit", BIT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("boolean", BOOLEAN_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("both", BOTH, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("breadth", BREADTH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("by", BY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cache", CACHE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("call", CALL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("called", CALLED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cascade", CASCADE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cascaded", CASCADED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("case", CASE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cast", CAST, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("catalog", CATALOG_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("chain", CHAIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("char", CHAR_P, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("character", CHARACTER, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("characteristics", CHARACTERISTICS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("check", CHECK, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("checkpoint", CHECKPOINT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("class", CLASS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("close", CLOSE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cluster", CLUSTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("coalesce", COALESCE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("collation", COLLATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("columns", COLUMNS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("compression", COMPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("constraint", CONSTRAINT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("constraints", CONSTRAINTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("content", CONTENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("continue", CONTINUE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("conversion", CONVERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("copy", COPY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cost", COST, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("create", CREATE, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("cross", CROSS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("csv", CSV, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cube", CUBE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current", CURRENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_catalog", CURRENT_CATALOG, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_date", CURRENT_DATE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_role", CURRENT_ROLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_schema", CURRENT_SCHEMA, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_time", CURRENT_TIME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_user", CURRENT_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cursor", CURSOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cycle", CYCLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("data", DATA_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("database", DATABASE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("day", DAY_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("deallocate", DEALLOCATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("dec", DEC, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("decimal", DECIMAL_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("declare", DECLARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("default", DEFAULT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("defaults", DEFAULTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("deferrable", DEFERRABLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("deferred", DEFERRED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("depends", DEPENDS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("depth", DEPTH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("desc", DESC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("detach", DETACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("do", DO, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("document", DOCUMENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("else", ELSE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("encoding", ENCODING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("end", END_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("expression", EXPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("family", FAMILY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("fetch", FETCH, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("filter", FILTER, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("finalize", FINALIZE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("first", FIRST_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("float", FLOAT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("following", FOLLOWING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("for", FOR, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("force", FORCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("foreign", FOREIGN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("format", FORMAT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("forward", FORWARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("from", FROM, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("grouping", GROUPING, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("groups", GROUPS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("handler", HANDLER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("having", HAVING, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("header", HEADER_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("implicit", IMPLICIT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("import", IMPORT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("in", IN_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("include", INCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("including", INCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("increment", INCREMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("indent", INDENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("index", INDEX, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("indexes", INDEXES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inherit", INHERIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inherits", INHERITS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("initially", INITIALLY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inline", INLINE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inner", INNER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("inout", INOUT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("input", INPUT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("insensitive", INSENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("insert", INSERT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("instead", INSTEAD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("int", INT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("integer", INTEGER, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("intersect", INTERSECT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("interval", INTERVAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("into", INTO, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("invoker", INVOKER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("is", IS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json", JSON, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_array", JSON_ARRAY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_arrayagg", JSON_ARRAYAGG, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_object", JSON_OBJECT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("keys", KEYS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("last", LAST_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("lateral", LATERAL_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("leading", LEADING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("leakproof", LEAKPROOF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("least", LEAST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("left", LEFT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("level", LEVEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("like", LIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("limit", LIMIT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("listen", LISTEN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("load", LOAD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("local", LOCAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("localtime", LOCALTIME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("matched", MATCHED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("merge", MERGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("mode", MODE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("month", MONTH_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("move", MOVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("name", NAME_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("names", NAMES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("national", NATIONAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("natural", NATURAL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nchar", NCHAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("new", NEW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfc", NFC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfd", NFD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfkc", NFKC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfkd", NFKD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("no", NO, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("none", NONE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("normalize", NORMALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("normalized", NORMALIZED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("not", NOT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("nowait", NOWAIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("null", NULL_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("of", OF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("old", OLD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("on", ON, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("only", ONLY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("option", OPTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("or", OR, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("order", ORDER, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("ordinality", ORDINALITY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("others", OTHERS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parallel", PARALLEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parameter", PARAMETER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("prepare", PREPARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("prepared", PREPARED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("preserve", PRESERVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("primary", PRIMARY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("prior", PRIOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("privileges", PRIVILEGES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedures", PROCEDURES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("read", READ, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("real", REAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("return", RETURN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("returns", RETURNS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("revoke", REVOKE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("right", RIGHT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("role", ROLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rollback", ROLLBACK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rollup", ROLLUP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("routine", ROUTINE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("routines", ROUTINES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("row", ROW, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("scalar", SCALAR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("select", SELECT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("serializable", SERIALIZABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("server", SERVER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("session", SESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("session_user", SESSION_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("set", SET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("setof", SETOF, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("sets", SETS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("share", SHARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("show", SHOW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("simple", SIMPLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("skip", SKIP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("some", SOME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("start", START, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("statement", STATEMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("statistics", STATISTICS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stdin", STDIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stored", STORED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("support", SUPPORT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("symmetric", SYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("system_user", SYSTEM_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("table", TABLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("tables", TABLES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("tablesample", TABLESAMPLE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("tablespace", TABLESPACE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("template", TEMPLATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("temporary", TEMPORARY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("text", TEXT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("then", THEN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ties", TIES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("time", TIME, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("timestamp", TIMESTAMP, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("to", TO, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("trailing", TRAILING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("transaction", TRANSACTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("transform", TRANSFORM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("treat", TREAT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("trigger", TRIGGER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("trim", TRIM, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("true", TRUE_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("truncate", TRUNCATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("trusted", TRUSTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("type", TYPE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("uescape", UESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("union", UNION, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("unique", UNIQUE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unknown", UNKNOWN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unlisten", UNLISTEN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unlogged", UNLOGGED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("until", UNTIL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("update", UPDATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("user", USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("using", USING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("vacuum", VACUUM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("valid", VALID, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("validate", VALIDATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("validator", VALIDATOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("value", VALUE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("values", VALUES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("varchar", VARCHAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("variadic", VARIADIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("when", WHEN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("where", WHERE, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("with", WITH, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlnamespaces", XMLNAMESPACES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlparse", XMLPARSE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlpi", XMLPI, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlroot", XMLROOT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmltable", XMLTABLE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("year", YEAR_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("yes", YES_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("zone", ZONE, UNRESERVED_KEYWORD, BARE_LABEL) diff --git a/install/include/postgresql/server/parser/parse_agg.h b/install/include/postgresql/server/parser/parse_agg.h new file mode 100644 index 00000000000..e9afd99d11f --- /dev/null +++ b/install/include/postgresql/server/parser/parse_agg.h @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------- + * + * parse_agg.h + * handle aggregates and window functions in parser + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_agg.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_AGG_H +#define PARSE_AGG_H + +#include "parser/parse_node.h" + +extern void transformAggregateCall(ParseState *pstate, Aggref *agg, + List *args, List *aggorder, + bool agg_distinct); + +extern Node *transformGroupingFunc(ParseState *pstate, GroupingFunc *p); + +extern void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, + WindowDef *windef); + +extern void parseCheckAggregates(ParseState *pstate, Query *qry); + +extern List *expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit); + +extern int get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes); + +extern Oid resolve_aggregate_transtype(Oid aggfuncid, + Oid aggtranstype, + Oid *inputTypes, + int numArguments); + +extern bool agg_args_support_sendreceive(Aggref *aggref); + +extern void build_aggregate_transfn_expr(Oid *agg_input_types, + int agg_num_inputs, + int agg_num_direct_inputs, + bool agg_variadic, + Oid agg_state_type, + Oid agg_input_collation, + Oid transfn_oid, + Oid invtransfn_oid, + Expr **transfnexpr, + Expr **invtransfnexpr); + +extern void build_aggregate_serialfn_expr(Oid serialfn_oid, + Expr **serialfnexpr); + +extern void build_aggregate_deserialfn_expr(Oid deserialfn_oid, + Expr **deserialfnexpr); + +extern void build_aggregate_finalfn_expr(Oid *agg_input_types, + int num_finalfn_inputs, + Oid agg_state_type, + Oid agg_result_type, + Oid agg_input_collation, + Oid finalfn_oid, + Expr **finalfnexpr); + +#endif /* PARSE_AGG_H */ diff --git a/install/include/postgresql/server/parser/parse_clause.h b/install/include/postgresql/server/parser/parse_clause.h new file mode 100644 index 00000000000..8e26482db42 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_clause.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * parse_clause.h + * handle clauses in parser + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_clause.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_CLAUSE_H +#define PARSE_CLAUSE_H + +#include "parser/parse_node.h" + +extern void transformFromClause(ParseState *pstate, List *frmList); +extern int setTargetTable(ParseState *pstate, RangeVar *relation, + bool inh, bool alsoSource, AclMode requiredPerms); + +extern Node *transformWhereClause(ParseState *pstate, Node *clause, + ParseExprKind exprKind, const char *constructName); +extern Node *transformLimitClause(ParseState *pstate, Node *clause, + ParseExprKind exprKind, const char *constructName, + LimitOption limitOption); +extern List *transformGroupClause(ParseState *pstate, List *grouplist, + List **groupingSets, + List **targetlist, List *sortClause, + ParseExprKind exprKind, bool useSQL99); +extern List *transformSortClause(ParseState *pstate, List *orderlist, + List **targetlist, ParseExprKind exprKind, + bool useSQL99); + +extern List *transformWindowDefinitions(ParseState *pstate, + List *windowdefs, + List **targetlist); + +extern List *transformDistinctClause(ParseState *pstate, + List **targetlist, List *sortClause, bool is_agg); +extern List *transformDistinctOnClause(ParseState *pstate, List *distinctlist, + List **targetlist, List *sortClause); +extern void transformOnConflictArbiter(ParseState *pstate, + OnConflictClause *onConflictClause, + List **arbiterExpr, Node **arbiterWhere, + Oid *constraint); + +extern List *addTargetToSortList(ParseState *pstate, TargetEntry *tle, + List *sortlist, List *targetlist, SortBy *sortby); +extern Index assignSortGroupRef(TargetEntry *tle, List *tlist); +extern bool targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList); + +#endif /* PARSE_CLAUSE_H */ diff --git a/install/include/postgresql/server/parser/parse_coerce.h b/install/include/postgresql/server/parser/parse_coerce.h new file mode 100644 index 00000000000..63486622631 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_coerce.h @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------- + * + * parse_coerce.h + * Routines for type coercion. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_coerce.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_COERCE_H +#define PARSE_COERCE_H + +#include "parser/parse_node.h" + + +/* Type categories (see TYPCATEGORY_xxx symbols in catalog/pg_type.h) */ +typedef char TYPCATEGORY; + +/* Result codes for find_coercion_pathway */ +typedef enum CoercionPathType +{ + COERCION_PATH_NONE, /* failed to find any coercion pathway */ + COERCION_PATH_FUNC, /* apply the specified coercion function */ + COERCION_PATH_RELABELTYPE, /* binary-compatible cast, no function */ + COERCION_PATH_ARRAYCOERCE, /* need an ArrayCoerceExpr node */ + COERCION_PATH_COERCEVIAIO /* need a CoerceViaIO node */ +} CoercionPathType; + + +extern bool IsBinaryCoercible(Oid srctype, Oid targettype); +extern bool IsBinaryCoercibleWithCast(Oid srctype, Oid targettype, + Oid *castoid); +extern bool IsPreferredType(TYPCATEGORY category, Oid type); +extern TYPCATEGORY TypeCategory(Oid type); + +extern Node *coerce_to_target_type(ParseState *pstate, + Node *expr, Oid exprtype, + Oid targettype, int32 targettypmod, + CoercionContext ccontext, + CoercionForm cformat, + int location); +extern bool can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids, + CoercionContext ccontext); +extern Node *coerce_type(ParseState *pstate, Node *node, + Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, + CoercionContext ccontext, CoercionForm cformat, int location); +extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, + Oid typeId, + CoercionContext ccontext, CoercionForm cformat, int location, + bool hideInputCoercion); + +extern Node *coerce_to_boolean(ParseState *pstate, Node *node, + const char *constructName); +extern Node *coerce_to_specific_type(ParseState *pstate, Node *node, + Oid targetTypeId, + const char *constructName); + +extern Node *coerce_to_specific_type_typmod(ParseState *pstate, Node *node, + Oid targetTypeId, int32 targetTypmod, + const char *constructName); + +extern Node *coerce_null_to_domain(Oid typid, int32 typmod, Oid collation, + int typlen, bool typbyval); + +extern int parser_coercion_errposition(ParseState *pstate, + int coerce_location, + Node *input_expr); + +extern Oid select_common_type(ParseState *pstate, List *exprs, + const char *context, Node **which_expr); +extern Node *coerce_to_common_type(ParseState *pstate, Node *node, + Oid targetTypeId, + const char *context); +extern bool verify_common_type(Oid common_type, List *exprs); + +extern int32 select_common_typmod(ParseState *pstate, List *exprs, Oid common_type); + +extern bool check_generic_type_consistency(const Oid *actual_arg_types, + const Oid *declared_arg_types, + int nargs); +extern Oid enforce_generic_type_consistency(const Oid *actual_arg_types, + Oid *declared_arg_types, + int nargs, + Oid rettype, + bool allow_poly); + +extern char *check_valid_polymorphic_signature(Oid ret_type, + const Oid *declared_arg_types, + int nargs); +extern char *check_valid_internal_signature(Oid ret_type, + const Oid *declared_arg_types, + int nargs); + +extern CoercionPathType find_coercion_pathway(Oid targetTypeId, + Oid sourceTypeId, + CoercionContext ccontext, + Oid *funcid); +extern CoercionPathType find_typmod_coercion_function(Oid typeId, + Oid *funcid); + +#endif /* PARSE_COERCE_H */ diff --git a/install/include/postgresql/server/parser/parse_collate.h b/install/include/postgresql/server/parser/parse_collate.h new file mode 100644 index 00000000000..a858deb0bce --- /dev/null +++ b/install/include/postgresql/server/parser/parse_collate.h @@ -0,0 +1,27 @@ +/*------------------------------------------------------------------------- + * + * parse_collate.h + * Routines for assigning collation information. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_collate.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_COLLATE_H +#define PARSE_COLLATE_H + +#include "parser/parse_node.h" + +extern void assign_query_collations(ParseState *pstate, Query *query); + +extern void assign_list_collations(ParseState *pstate, List *exprs); + +extern void assign_expr_collations(ParseState *pstate, Node *expr); + +extern Oid select_common_collation(ParseState *pstate, List *exprs, bool none_ok); + +#endif /* PARSE_COLLATE_H */ diff --git a/install/include/postgresql/server/parser/parse_cte.h b/install/include/postgresql/server/parser/parse_cte.h new file mode 100644 index 00000000000..3eebc770565 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_cte.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * parse_cte.h + * handle CTEs (common table expressions) in parser + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_cte.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_CTE_H +#define PARSE_CTE_H + +#include "parser/parse_node.h" + +extern List *transformWithClause(ParseState *pstate, WithClause *withClause); + +extern void analyzeCTETargetList(ParseState *pstate, CommonTableExpr *cte, + List *tlist); + +#endif /* PARSE_CTE_H */ diff --git a/install/include/postgresql/server/parser/parse_enr.h b/install/include/postgresql/server/parser/parse_enr.h new file mode 100644 index 00000000000..edb2ee0d03e --- /dev/null +++ b/install/include/postgresql/server/parser/parse_enr.h @@ -0,0 +1,22 @@ +/*------------------------------------------------------------------------- + * + * parse_enr.h + * Internal definitions for parser + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_enr.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_ENR_H +#define PARSE_ENR_H + +#include "parser/parse_node.h" + +extern bool name_matches_visible_ENR(ParseState *pstate, const char *refname); +extern EphemeralNamedRelationMetadata get_visible_ENR(ParseState *pstate, const char *refname); + +#endif /* PARSE_ENR_H */ diff --git a/install/include/postgresql/server/parser/parse_expr.h b/install/include/postgresql/server/parser/parse_expr.h new file mode 100644 index 00000000000..7d38ca75f7b --- /dev/null +++ b/install/include/postgresql/server/parser/parse_expr.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * + * parse_expr.h + * handle expressions in parser + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_expr.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_EXPR_H +#define PARSE_EXPR_H + +#include "parser/parse_node.h" + +/* GUC parameters */ +extern PGDLLIMPORT bool Transform_null_equals; + +extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind); + +extern const char *ParseExprKindName(ParseExprKind exprKind); + +#endif /* PARSE_EXPR_H */ diff --git a/install/include/postgresql/server/parser/parse_func.h b/install/include/postgresql/server/parser/parse_func.h new file mode 100644 index 00000000000..e316f5da498 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_func.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * parse_func.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_func.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_FUNC_H +#define PARSE_FUNC_H + +#include "catalog/namespace.h" +#include "parser/parse_node.h" + + +/* Result codes for func_get_detail */ +typedef enum +{ + FUNCDETAIL_NOTFOUND, /* no matching function */ + FUNCDETAIL_MULTIPLE, /* too many matching functions */ + FUNCDETAIL_NORMAL, /* found a matching regular function */ + FUNCDETAIL_PROCEDURE, /* found a matching procedure */ + FUNCDETAIL_AGGREGATE, /* found a matching aggregate function */ + FUNCDETAIL_WINDOWFUNC, /* found a matching window function */ + FUNCDETAIL_COERCION /* it's a type coercion request */ +} FuncDetailCode; + + +extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, + Node *last_srf, FuncCall *fn, bool proc_call, + int location); + +extern FuncDetailCode func_get_detail(List *funcname, + List *fargs, List *fargnames, + int nargs, Oid *argtypes, + bool expand_variadic, bool expand_defaults, + bool include_out_arguments, + Oid *funcid, Oid *rettype, + bool *retset, int *nvargs, Oid *vatype, + Oid **true_typeids, List **argdefaults); + +extern int func_match_argtypes(int nargs, + Oid *input_typeids, + FuncCandidateList raw_candidates, + FuncCandidateList *candidates); + +extern FuncCandidateList func_select_candidate(int nargs, + Oid *input_typeids, + FuncCandidateList candidates); + +extern void make_fn_arguments(ParseState *pstate, + List *fargs, + Oid *actual_arg_types, + Oid *declared_arg_types); + +extern const char *funcname_signature_string(const char *funcname, int nargs, + List *argnames, const Oid *argtypes); +extern const char *func_signature_string(List *funcname, int nargs, + List *argnames, const Oid *argtypes); + +extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, + bool missing_ok); +extern Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, + bool missing_ok); + +extern void check_srf_call_placement(ParseState *pstate, Node *last_srf, + int location); + +#endif /* PARSE_FUNC_H */ diff --git a/install/include/postgresql/server/parser/parse_merge.h b/install/include/postgresql/server/parser/parse_merge.h new file mode 100644 index 00000000000..751cbdf112a --- /dev/null +++ b/install/include/postgresql/server/parser/parse_merge.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * parse_merge.h + * handle MERGE statement in parser + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_merge.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_MERGE_H +#define PARSE_MERGE_H + +#include "parser/parse_node.h" + +extern Query *transformMergeStmt(ParseState *pstate, MergeStmt *stmt); + +#endif /* PARSE_MERGE_H */ diff --git a/install/include/postgresql/server/parser/parse_node.h b/install/include/postgresql/server/parser/parse_node.h new file mode 100644 index 00000000000..f589112d5e5 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_node.h @@ -0,0 +1,357 @@ +/*------------------------------------------------------------------------- + * + * parse_node.h + * Internal definitions for parser + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_node.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_NODE_H +#define PARSE_NODE_H + +#include "nodes/parsenodes.h" +#include "utils/queryenvironment.h" +#include "utils/relcache.h" + + +/* Forward references for some structs declared below */ +typedef struct ParseState ParseState; +typedef struct ParseNamespaceItem ParseNamespaceItem; +typedef struct ParseNamespaceColumn ParseNamespaceColumn; + +/* + * Expression kinds distinguished by transformExpr(). Many of these are not + * semantically distinct so far as expression transformation goes; rather, + * we distinguish them so that context-specific error messages can be printed. + * + * Note: EXPR_KIND_OTHER is not used in the core code, but is left for use + * by extension code that might need to call transformExpr(). The core code + * will not enforce any context-driven restrictions on EXPR_KIND_OTHER + * expressions, so the caller would have to check for sub-selects, aggregates, + * window functions, SRFs, etc if those need to be disallowed. + */ +typedef enum ParseExprKind +{ + EXPR_KIND_NONE = 0, /* "not in an expression" */ + EXPR_KIND_OTHER, /* reserved for extensions */ + EXPR_KIND_JOIN_ON, /* JOIN ON */ + EXPR_KIND_JOIN_USING, /* JOIN USING */ + EXPR_KIND_FROM_SUBSELECT, /* sub-SELECT in FROM clause */ + EXPR_KIND_FROM_FUNCTION, /* function in FROM clause */ + EXPR_KIND_WHERE, /* WHERE */ + EXPR_KIND_HAVING, /* HAVING */ + EXPR_KIND_FILTER, /* FILTER */ + EXPR_KIND_WINDOW_PARTITION, /* window definition PARTITION BY */ + EXPR_KIND_WINDOW_ORDER, /* window definition ORDER BY */ + EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */ + EXPR_KIND_WINDOW_FRAME_ROWS, /* window frame clause with ROWS */ + EXPR_KIND_WINDOW_FRAME_GROUPS, /* window frame clause with GROUPS */ + EXPR_KIND_SELECT_TARGET, /* SELECT target list item */ + EXPR_KIND_INSERT_TARGET, /* INSERT target list item */ + EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */ + EXPR_KIND_UPDATE_TARGET, /* UPDATE assignment target item */ + EXPR_KIND_MERGE_WHEN, /* MERGE WHEN [NOT] MATCHED condition */ + EXPR_KIND_GROUP_BY, /* GROUP BY */ + EXPR_KIND_ORDER_BY, /* ORDER BY */ + EXPR_KIND_DISTINCT_ON, /* DISTINCT ON */ + EXPR_KIND_LIMIT, /* LIMIT */ + EXPR_KIND_OFFSET, /* OFFSET */ + EXPR_KIND_RETURNING, /* RETURNING */ + EXPR_KIND_VALUES, /* VALUES */ + EXPR_KIND_VALUES_SINGLE, /* single-row VALUES (in INSERT only) */ + EXPR_KIND_CHECK_CONSTRAINT, /* CHECK constraint for a table */ + EXPR_KIND_DOMAIN_CHECK, /* CHECK constraint for a domain */ + EXPR_KIND_COLUMN_DEFAULT, /* default value for a table column */ + EXPR_KIND_FUNCTION_DEFAULT, /* default parameter value for function */ + EXPR_KIND_INDEX_EXPRESSION, /* index expression */ + EXPR_KIND_INDEX_PREDICATE, /* index predicate */ + EXPR_KIND_STATS_EXPRESSION, /* extended statistics expression */ + EXPR_KIND_ALTER_COL_TRANSFORM, /* transform expr in ALTER COLUMN TYPE */ + EXPR_KIND_EXECUTE_PARAMETER, /* parameter value in EXECUTE */ + EXPR_KIND_TRIGGER_WHEN, /* WHEN condition in CREATE TRIGGER */ + EXPR_KIND_POLICY, /* USING or WITH CHECK expr in policy */ + EXPR_KIND_PARTITION_BOUND, /* partition bound expression */ + EXPR_KIND_PARTITION_EXPRESSION, /* PARTITION BY expression */ + EXPR_KIND_CALL_ARGUMENT, /* procedure argument in CALL */ + EXPR_KIND_COPY_WHERE, /* WHERE condition in COPY FROM */ + EXPR_KIND_GENERATED_COLUMN, /* generation expression for a column */ + EXPR_KIND_CYCLE_MARK, /* cycle mark value */ +} ParseExprKind; + + +/* + * Function signatures for parser hooks + */ +typedef Node *(*PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref); +typedef Node *(*PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var); +typedef Node *(*ParseParamRefHook) (ParseState *pstate, ParamRef *pref); +typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param, + Oid targetTypeId, int32 targetTypeMod, + int location); + + +/* + * State information used during parse analysis + * + * parentParseState: NULL in a top-level ParseState. When parsing a subquery, + * links to current parse state of outer query. + * + * p_sourcetext: source string that generated the raw parsetree being + * analyzed, or NULL if not available. (The string is used only to + * generate cursor positions in error messages: we need it to convert + * byte-wise locations in parse structures to character-wise cursor + * positions.) + * + * p_rtable: list of RTEs that will become the rangetable of the query. + * Note that neither relname nor refname of these entries are necessarily + * unique; searching the rtable by name is a bad idea. + * + * p_rteperminfos: list of RTEPermissionInfo containing an entry corresponding + * to each RTE_RELATION entry in p_rtable. + * + * p_joinexprs: list of JoinExpr nodes associated with p_rtable entries. + * This is one-for-one with p_rtable, but contains NULLs for non-join + * RTEs, and may be shorter than p_rtable if the last RTE(s) aren't joins. + * + * p_nullingrels: list of Bitmapsets associated with p_rtable entries, each + * containing the set of outer-join RTE indexes that can null that relation + * at the current point in the parse tree. This is one-for-one with p_rtable, + * but may be shorter than p_rtable, in which case the missing entries are + * implicitly empty (NULL). That rule allows us to save work when the query + * contains no outer joins. + * + * p_joinlist: list of join items (RangeTblRef and JoinExpr nodes) that + * will become the fromlist of the query's top-level FromExpr node. + * + * p_namespace: list of ParseNamespaceItems that represents the current + * namespace for table and column lookup. (The RTEs listed here may be just + * a subset of the whole rtable. See ParseNamespaceItem comments below.) + * + * p_lateral_active: true if we are currently parsing a LATERAL subexpression + * of this parse level. This makes p_lateral_only namespace items visible, + * whereas they are not visible when p_lateral_active is FALSE. + * + * p_ctenamespace: list of CommonTableExprs (WITH items) that are visible + * at the moment. This is entirely different from p_namespace because a CTE + * is not an RTE, rather "visibility" means you could make an RTE from it. + * + * p_future_ctes: list of CommonTableExprs (WITH items) that are not yet + * visible due to scope rules. This is used to help improve error messages. + * + * p_parent_cte: CommonTableExpr that immediately contains the current query, + * if any. + * + * p_target_relation: target relation, if query is INSERT/UPDATE/DELETE/MERGE + * + * p_target_nsitem: target relation's ParseNamespaceItem. + * + * p_is_insert: true to process assignment expressions like INSERT, false + * to process them like UPDATE. (Note this can change intra-statement, for + * cases like INSERT ON CONFLICT UPDATE.) + * + * p_windowdefs: list of WindowDefs representing WINDOW and OVER clauses. + * We collect these while transforming expressions and then transform them + * afterwards (so that any resjunk tlist items needed for the sort/group + * clauses end up at the end of the query tlist). A WindowDef's location in + * this list, counting from 1, is the winref number to use to reference it. + * + * p_expr_kind: kind of expression we're currently parsing, as per enum above; + * EXPR_KIND_NONE when not in an expression. + * + * p_next_resno: next TargetEntry.resno to assign, starting from 1. + * + * p_multiassign_exprs: partially-processed MultiAssignRef source expressions. + * + * p_locking_clause: query's FOR UPDATE/FOR SHARE clause, if any. + * + * p_locked_from_parent: true if parent query level applies FOR UPDATE/SHARE + * to this subquery as a whole. + * + * p_resolve_unknowns: resolve unknown-type SELECT output columns as type TEXT + * (this is true by default). + * + * p_hasAggs, p_hasWindowFuncs, etc: true if we've found any of the indicated + * constructs in the query. + * + * p_last_srf: the set-returning FuncExpr or OpExpr most recently found in + * the query, or NULL if none. + * + * p_pre_columnref_hook, etc: optional parser hook functions for modifying the + * interpretation of ColumnRefs and ParamRefs. + * + * p_ref_hook_state: passthrough state for the parser hook functions. + */ +struct ParseState +{ + ParseState *parentParseState; /* stack link */ + const char *p_sourcetext; /* source text, or NULL if not available */ + List *p_rtable; /* range table so far */ + List *p_rteperminfos; /* list of RTEPermissionInfo nodes for each + * RTE_RELATION entry in rtable */ + List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */ + List *p_nullingrels; /* Bitmapsets showing nulling outer joins */ + List *p_joinlist; /* join items so far (will become FromExpr + * node's fromlist) */ + List *p_namespace; /* currently-referenceable RTEs (List of + * ParseNamespaceItem) */ + bool p_lateral_active; /* p_lateral_only items visible? */ + List *p_ctenamespace; /* current namespace for common table exprs */ + List *p_future_ctes; /* common table exprs not yet in namespace */ + CommonTableExpr *p_parent_cte; /* this query's containing CTE */ + Relation p_target_relation; /* INSERT/UPDATE/DELETE/MERGE target rel */ + ParseNamespaceItem *p_target_nsitem; /* target rel's NSItem, or NULL */ + bool p_is_insert; /* process assignment like INSERT not UPDATE */ + List *p_windowdefs; /* raw representations of window clauses */ + ParseExprKind p_expr_kind; /* what kind of expression we're parsing */ + int p_next_resno; /* next targetlist resno to assign */ + List *p_multiassign_exprs; /* junk tlist entries for multiassign */ + List *p_locking_clause; /* raw FOR UPDATE/FOR SHARE info */ + bool p_locked_from_parent; /* parent has marked this subquery + * with FOR UPDATE/FOR SHARE */ + bool p_resolve_unknowns; /* resolve unknown-type SELECT outputs as + * type text */ + + QueryEnvironment *p_queryEnv; /* curr env, incl refs to enclosing env */ + + /* Flags telling about things found in the query: */ + bool p_hasAggs; + bool p_hasWindowFuncs; + bool p_hasTargetSRFs; + bool p_hasSubLinks; + bool p_hasModifyingCTE; + + Node *p_last_srf; /* most recent set-returning func/op found */ + + /* + * Optional hook functions for parser callbacks. These are null unless + * set up by the caller of make_parsestate. + */ + PreParseColumnRefHook p_pre_columnref_hook; + PostParseColumnRefHook p_post_columnref_hook; + ParseParamRefHook p_paramref_hook; + CoerceParamHook p_coerce_param_hook; + void *p_ref_hook_state; /* common passthrough link for above */ +}; + +/* + * An element of a namespace list. + * + * p_names contains the table name and column names exposed by this nsitem. + * (Typically it's equal to p_rte->eref, but for a JOIN USING alias it's + * equal to p_rte->join_using_alias. Since the USING columns will be the + * join's first N columns, the net effect is just that we expose only those + * join columns via this nsitem.) + * + * p_rte and p_rtindex link to the underlying rangetable entry, and + * p_perminfo to the entry in rteperminfos. + * + * The p_nscolumns array contains info showing how to construct Vars + * referencing the names appearing in the p_names->colnames list. + * + * Namespace items with p_rel_visible set define which RTEs are accessible by + * qualified names, while those with p_cols_visible set define which RTEs are + * accessible by unqualified names. These sets are different because a JOIN + * without an alias does not hide the contained tables (so they must be + * visible for qualified references) but it does hide their columns + * (unqualified references to the columns refer to the JOIN, not the member + * tables, so we must not complain that such a reference is ambiguous). + * Conversely, a subquery without an alias does not hide the columns selected + * by the subquery, but it does hide the auto-generated relation name (so the + * subquery columns are visible for unqualified references only). Various + * special RTEs such as NEW/OLD for rules may also appear with only one flag + * set. + * + * While processing the FROM clause, namespace items may appear with + * p_lateral_only set, meaning they are visible only to LATERAL + * subexpressions. (The pstate's p_lateral_active flag tells whether we are + * inside such a subexpression at the moment.) If p_lateral_ok is not set, + * it's an error to actually use such a namespace item. One might think it + * would be better to just exclude such items from visibility, but the wording + * of SQL:2008 requires us to do it this way. We also use p_lateral_ok to + * forbid LATERAL references to an UPDATE/DELETE target table. + * + * At no time should a namespace list contain two entries that conflict + * according to the rules in checkNameSpaceConflicts; but note that those + * are more complicated than "must have different alias names", so in practice + * code searching a namespace list has to check for ambiguous references. + */ +struct ParseNamespaceItem +{ + Alias *p_names; /* Table and column names */ + RangeTblEntry *p_rte; /* The relation's rangetable entry */ + int p_rtindex; /* The relation's index in the rangetable */ + RTEPermissionInfo *p_perminfo; /* The relation's rteperminfos entry */ + /* array of same length as p_names->colnames: */ + ParseNamespaceColumn *p_nscolumns; /* per-column data */ + bool p_rel_visible; /* Relation name is visible? */ + bool p_cols_visible; /* Column names visible as unqualified refs? */ + bool p_lateral_only; /* Is only visible to LATERAL expressions? */ + bool p_lateral_ok; /* If so, does join type allow use? */ +}; + +/* + * Data about one column of a ParseNamespaceItem. + * + * We track the info needed to construct a Var referencing the column + * (but only for user-defined columns; system column references and + * whole-row references are handled separately). + * + * p_varno and p_varattno identify the semantic referent, which is a + * base-relation column unless the reference is to a join USING column that + * isn't semantically equivalent to either join input column (because it is a + * FULL join or the input column requires a type coercion). In those cases + * p_varno and p_varattno refer to the JOIN RTE. + * + * p_varnosyn and p_varattnosyn are either identical to p_varno/p_varattno, + * or they specify the column's position in an aliased JOIN RTE that hides + * the semantic referent RTE's refname. (That could be either the JOIN RTE + * in which this ParseNamespaceColumn entry exists, or some lower join level.) + * + * If an RTE contains a dropped column, its ParseNamespaceColumn struct + * is all-zeroes. (Conventionally, test for p_varno == 0 to detect this.) + */ +struct ParseNamespaceColumn +{ + Index p_varno; /* rangetable index */ + AttrNumber p_varattno; /* attribute number of the column */ + Oid p_vartype; /* pg_type OID */ + int32 p_vartypmod; /* type modifier value */ + Oid p_varcollid; /* OID of collation, or InvalidOid */ + Index p_varnosyn; /* rangetable index of syntactic referent */ + AttrNumber p_varattnosyn; /* attribute number of syntactic referent */ + bool p_dontexpand; /* not included in star expansion */ +}; + +/* Support for parser_errposition_callback function */ +typedef struct ParseCallbackState +{ + ParseState *pstate; + int location; + ErrorContextCallback errcallback; +} ParseCallbackState; + + +extern ParseState *make_parsestate(ParseState *parentParseState); +extern void free_parsestate(ParseState *pstate); +extern int parser_errposition(ParseState *pstate, int location); + +extern void setup_parser_errposition_callback(ParseCallbackState *pcbstate, + ParseState *pstate, int location); +extern void cancel_parser_errposition_callback(ParseCallbackState *pcbstate); + +extern void transformContainerType(Oid *containerType, int32 *containerTypmod); + +extern SubscriptingRef *transformContainerSubscripts(ParseState *pstate, + Node *containerBase, + Oid containerType, + int32 containerTypMod, + List *indirection, + bool isAssignment); +extern Const *make_const(ParseState *pstate, A_Const *aconst); + +#endif /* PARSE_NODE_H */ diff --git a/install/include/postgresql/server/parser/parse_oper.h b/install/include/postgresql/server/parser/parse_oper.h new file mode 100644 index 00000000000..5768a1ce87a --- /dev/null +++ b/install/include/postgresql/server/parser/parse_oper.h @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------- + * + * parse_oper.h + * handle operator things for parser + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_oper.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_OPER_H +#define PARSE_OPER_H + +#include "access/htup.h" +#include "nodes/parsenodes.h" +#include "parser/parse_node.h" + + +typedef HeapTuple Operator; + +/* Routines to look up an operator given name and exact input type(s) */ +extern Oid LookupOperName(ParseState *pstate, List *opername, + Oid oprleft, Oid oprright, + bool noError, int location); +extern Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError); + +/* Routines to find operators matching a name and given input types */ +/* NB: the selected operator may require coercion of the input types! */ +extern Operator oper(ParseState *pstate, List *opname, Oid ltypeId, + Oid rtypeId, bool noError, int location); +extern Operator left_oper(ParseState *pstate, List *op, Oid arg, + bool noError, int location); + +/* Routines to find operators that DO NOT require coercion --- ie, their */ +/* input types are either exactly as given, or binary-compatible */ +extern Operator compatible_oper(ParseState *pstate, List *op, + Oid arg1, Oid arg2, + bool noError, int location); + +/* currently no need for compatible_left_oper/compatible_right_oper */ + +/* Routines for identifying "<", "=", ">" operators for a type */ +extern void get_sort_group_operators(Oid argtype, + bool needLT, bool needEQ, bool needGT, + Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, + bool *isHashable); + +/* Convenience routines for common calls on the above */ +extern Oid compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError); + +/* Extract operator OID or underlying-function OID from an Operator tuple */ +extern Oid oprid(Operator op); +extern Oid oprfuncid(Operator op); + +/* Build expression tree for an operator invocation */ +extern Expr *make_op(ParseState *pstate, List *opname, + Node *ltree, Node *rtree, Node *last_srf, int location); +extern Expr *make_scalar_array_op(ParseState *pstate, List *opname, + bool useOr, + Node *ltree, Node *rtree, int location); + +#endif /* PARSE_OPER_H */ diff --git a/install/include/postgresql/server/parser/parse_param.h b/install/include/postgresql/server/parser/parse_param.h new file mode 100644 index 00000000000..d4865e50f67 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_param.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + * + * parse_param.h + * handle parameters in parser + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_param.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_PARAM_H +#define PARSE_PARAM_H + +#include "parser/parse_node.h" + +extern void setup_parse_fixed_parameters(ParseState *pstate, + const Oid *paramTypes, int numParams); +extern void setup_parse_variable_parameters(ParseState *pstate, + Oid **paramTypes, int *numParams); +extern void check_variable_parameters(ParseState *pstate, Query *query); +extern bool query_contains_extern_params(Query *query); + +#endif /* PARSE_PARAM_H */ diff --git a/install/include/postgresql/server/parser/parse_relation.h b/install/include/postgresql/server/parser/parse_relation.h new file mode 100644 index 00000000000..67d9b1e412c --- /dev/null +++ b/install/include/postgresql/server/parser/parse_relation.h @@ -0,0 +1,129 @@ +/*------------------------------------------------------------------------- + * + * parse_relation.h + * prototypes for parse_relation.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_relation.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_RELATION_H +#define PARSE_RELATION_H + +#include "parser/parse_node.h" + + +extern ParseNamespaceItem *refnameNamespaceItem(ParseState *pstate, + const char *schemaname, + const char *refname, + int location, + int *sublevels_up); +extern CommonTableExpr *scanNameSpaceForCTE(ParseState *pstate, + const char *refname, + Index *ctelevelsup); +extern bool scanNameSpaceForENR(ParseState *pstate, const char *refname); +extern void checkNameSpaceConflicts(ParseState *pstate, List *namespace1, + List *namespace2); +extern ParseNamespaceItem *GetNSItemByRangeTablePosn(ParseState *pstate, + int varno, + int sublevels_up); +extern RangeTblEntry *GetRTEByRangeTablePosn(ParseState *pstate, + int varno, + int sublevels_up); +extern CommonTableExpr *GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, + int rtelevelsup); +extern Node *scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, + int sublevels_up, const char *colname, + int location); +extern Node *colNameToVar(ParseState *pstate, const char *colname, bool localonly, + int location); +extern void markNullableIfNeeded(ParseState *pstate, Var *var); +extern void markVarForSelectPriv(ParseState *pstate, Var *var); +extern Relation parserOpenTable(ParseState *pstate, const RangeVar *relation, + int lockmode); +extern ParseNamespaceItem *addRangeTableEntry(ParseState *pstate, + RangeVar *relation, + Alias *alias, + bool inh, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForRelation(ParseState *pstate, + Relation rel, + int lockmode, + Alias *alias, + bool inh, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForSubquery(ParseState *pstate, + Query *subquery, + Alias *alias, + bool lateral, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForFunction(ParseState *pstate, + List *funcnames, + List *funcexprs, + List *coldeflists, + RangeFunction *rangefunc, + bool lateral, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForValues(ParseState *pstate, + List *exprs, + List *coltypes, + List *coltypmods, + List *colcollations, + Alias *alias, + bool lateral, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForTableFunc(ParseState *pstate, + TableFunc *tf, + Alias *alias, + bool lateral, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForJoin(ParseState *pstate, + List *colnames, + ParseNamespaceColumn *nscolumns, + JoinType jointype, + int nummergedcols, + List *aliasvars, + List *leftcols, + List *rightcols, + Alias *join_using_alias, + Alias *alias, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForCTE(ParseState *pstate, + CommonTableExpr *cte, + Index levelsup, + RangeVar *rv, + bool inFromCl); +extern ParseNamespaceItem *addRangeTableEntryForENR(ParseState *pstate, + RangeVar *rv, + bool inFromCl); +extern RTEPermissionInfo *addRTEPermissionInfo(List **rteperminfos, + RangeTblEntry *rte); +extern RTEPermissionInfo *getRTEPermissionInfo(List *rteperminfos, + RangeTblEntry *rte); +extern bool isLockedRefname(ParseState *pstate, const char *refname); +extern void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, + bool addToJoinList, + bool addToRelNameSpace, bool addToVarNameSpace); +extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) pg_attribute_noreturn(); +extern void errorMissingColumn(ParseState *pstate, + const char *relname, const char *colname, int location) pg_attribute_noreturn(); +extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, + int location, bool include_dropped, + List **colnames, List **colvars); +extern List *expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem, + int sublevels_up, int location, + List **colnames); +extern List *expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem, + int sublevels_up, bool require_col_privs, + int location); +extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK); +extern const NameData *attnumAttName(Relation rd, int attid); +extern Oid attnumTypeId(Relation rd, int attid); +extern Oid attnumCollationId(Relation rd, int attid); +extern bool isQueryUsingTempRelation(Query *query); + +#endif /* PARSE_RELATION_H */ diff --git a/install/include/postgresql/server/parser/parse_target.h b/install/include/postgresql/server/parser/parse_target.h new file mode 100644 index 00000000000..d84c311bbca --- /dev/null +++ b/install/include/postgresql/server/parser/parse_target.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * parse_target.h + * handle target lists + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_target.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_TARGET_H +#define PARSE_TARGET_H + +#include "parser/parse_node.h" + + +extern List *transformTargetList(ParseState *pstate, List *targetlist, + ParseExprKind exprKind); +extern List *transformExpressionList(ParseState *pstate, List *exprlist, + ParseExprKind exprKind, bool allowDefault); +extern void resolveTargetListUnknowns(ParseState *pstate, List *targetlist); +extern void markTargetListOrigins(ParseState *pstate, List *targetlist); +extern TargetEntry *transformTargetEntry(ParseState *pstate, + Node *node, Node *expr, ParseExprKind exprKind, + char *colname, bool resjunk); +extern Expr *transformAssignedExpr(ParseState *pstate, Expr *expr, + ParseExprKind exprKind, + const char *colname, + int attrno, + List *indirection, + int location); +extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle, + char *colname, int attrno, + List *indirection, + int location); +extern Node *transformAssignmentIndirection(ParseState *pstate, + Node *basenode, + const char *targetName, + bool targetIsSubscripting, + Oid targetTypeId, + int32 targetTypMod, + Oid targetCollation, + List *indirection, + ListCell *indirection_cell, + Node *rhs, + CoercionContext ccontext, + int location); +extern List *checkInsertTargets(ParseState *pstate, List *cols, + List **attrnos); +extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var, + int levelsup); +extern char *FigureColname(Node *node); +extern char *FigureIndexColname(Node *node); + +#endif /* PARSE_TARGET_H */ diff --git a/install/include/postgresql/server/parser/parse_type.h b/install/include/postgresql/server/parser/parse_type.h new file mode 100644 index 00000000000..848c467a182 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_type.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * parse_type.h + * handle type operations for parser + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_type.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_TYPE_H +#define PARSE_TYPE_H + +#include "access/htup.h" +#include "parser/parse_node.h" + + +typedef HeapTuple Type; + +extern Type LookupTypeName(ParseState *pstate, const TypeName *typeName, + int32 *typmod_p, bool missing_ok); +extern Type LookupTypeNameExtended(ParseState *pstate, + const TypeName *typeName, int32 *typmod_p, + bool temp_ok, bool missing_ok); +extern Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, + bool missing_ok); +extern Type typenameType(ParseState *pstate, const TypeName *typeName, + int32 *typmod_p); +extern Oid typenameTypeId(ParseState *pstate, const TypeName *typeName); +extern void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, + Oid *typeid_p, int32 *typmod_p); + +extern char *TypeNameToString(const TypeName *typeName); +extern char *TypeNameListToString(List *typenames); + +extern Oid LookupCollation(ParseState *pstate, List *collnames, int location); +extern Oid GetColumnDefCollation(ParseState *pstate, ColumnDef *coldef, Oid typeOid); + +extern Type typeidType(Oid id); + +extern Oid typeTypeId(Type tp); +extern int16 typeLen(Type t); +extern bool typeByVal(Type t); +extern char *typeTypeName(Type t); +extern Oid typeTypeRelid(Type typ); +extern Oid typeTypeCollation(Type typ); +extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod); + +extern Oid typeidTypeRelid(Oid type_id); +extern Oid typeOrDomainTypeRelid(Oid type_id); + +extern TypeName *typeStringToTypeName(const char *str, Node *escontext); +extern bool parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, + Node *escontext); + +/* true if typeid is composite, or domain over composite, but not RECORD */ +#define ISCOMPLEX(typeid) (typeOrDomainTypeRelid(typeid) != InvalidOid) + +#endif /* PARSE_TYPE_H */ diff --git a/install/include/postgresql/server/parser/parse_utilcmd.h b/install/include/postgresql/server/parser/parse_utilcmd.h new file mode 100644 index 00000000000..2b40a0b5b19 --- /dev/null +++ b/install/include/postgresql/server/parser/parse_utilcmd.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * parse_utilcmd.h + * parse analysis for utility commands + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parse_utilcmd.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSE_UTILCMD_H +#define PARSE_UTILCMD_H + +#include "parser/parse_node.h" + +struct AttrMap; /* avoid including attmap.h here */ + + +extern List *transformCreateStmt(CreateStmt *stmt, const char *queryString); +extern AlterTableStmt *transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, + const char *queryString, + List **beforeStmts, + List **afterStmts); +extern IndexStmt *transformIndexStmt(Oid relid, IndexStmt *stmt, + const char *queryString); +extern CreateStatsStmt *transformStatsStmt(Oid relid, CreateStatsStmt *stmt, + const char *queryString); +extern void transformRuleStmt(RuleStmt *stmt, const char *queryString, + List **actions, Node **whereClause); +extern List *transformCreateSchemaStmtElements(List *schemaElts, + const char *schemaName); +extern PartitionBoundSpec *transformPartitionBound(ParseState *pstate, Relation parent, + PartitionBoundSpec *spec); +extern List *expandTableLikeClause(RangeVar *heapRel, + TableLikeClause *table_like_clause); +extern IndexStmt *generateClonedIndexStmt(RangeVar *heapRel, + Relation source_idx, + const struct AttrMap *attmap, + Oid *constraintOid); + +#endif /* PARSE_UTILCMD_H */ diff --git a/install/include/postgresql/server/parser/parser.h b/install/include/postgresql/server/parser/parser.h new file mode 100644 index 00000000000..8d90064d87b --- /dev/null +++ b/install/include/postgresql/server/parser/parser.h @@ -0,0 +1,68 @@ +/*------------------------------------------------------------------------- + * + * parser.h + * Definitions for the "raw" parser (flex and bison phases only) + * + * This is the external API for the raw lexing/parsing functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parser.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSER_H +#define PARSER_H + +#include "nodes/parsenodes.h" + + +/* + * RawParseMode determines the form of the string that raw_parser() accepts: + * + * RAW_PARSE_DEFAULT: parse a semicolon-separated list of SQL commands, + * and return a List of RawStmt nodes. + * + * RAW_PARSE_TYPE_NAME: parse a type name, and return a one-element List + * containing a TypeName node. + * + * RAW_PARSE_PLPGSQL_EXPR: parse a PL/pgSQL expression, and return + * a one-element List containing a RawStmt node. + * + * RAW_PARSE_PLPGSQL_ASSIGNn: parse a PL/pgSQL assignment statement, + * and return a one-element List containing a RawStmt node. "n" + * gives the number of dotted names comprising the target ColumnRef. + */ +typedef enum +{ + RAW_PARSE_DEFAULT = 0, + RAW_PARSE_TYPE_NAME, + RAW_PARSE_PLPGSQL_EXPR, + RAW_PARSE_PLPGSQL_ASSIGN1, + RAW_PARSE_PLPGSQL_ASSIGN2, + RAW_PARSE_PLPGSQL_ASSIGN3 +} RawParseMode; + +/* Values for the backslash_quote GUC */ +typedef enum +{ + BACKSLASH_QUOTE_OFF, + BACKSLASH_QUOTE_ON, + BACKSLASH_QUOTE_SAFE_ENCODING +} BackslashQuoteType; + +/* GUC variables in scan.l (every one of these is a bad idea :-() */ +extern PGDLLIMPORT int backslash_quote; +extern PGDLLIMPORT bool escape_string_warning; +extern PGDLLIMPORT bool standard_conforming_strings; + + +/* Primary entry point for the raw parsing functions */ +extern List *raw_parser(const char *str, RawParseMode mode); + +/* Utility functions exported by gram.y (perhaps these should be elsewhere) */ +extern List *SystemFuncName(char *name); +extern TypeName *SystemTypeName(char *name); + +#endif /* PARSER_H */ diff --git a/install/include/postgresql/server/parser/parsetree.h b/install/include/postgresql/server/parser/parsetree.h new file mode 100644 index 00000000000..69a9a258318 --- /dev/null +++ b/install/include/postgresql/server/parser/parsetree.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * parsetree.h + * Routines to access various components and subcomponents of + * parse trees. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/parsetree.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARSETREE_H +#define PARSETREE_H + +#include "nodes/parsenodes.h" + + +/* ---------------- + * range table operations + * ---------------- + */ + +/* + * rt_fetch + * + * NB: this will crash and burn if handed an out-of-range RT index + */ +#define rt_fetch(rangetable_index, rangetable) \ + ((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1)) + +/* + * Given an RTE and an attribute number, return the appropriate + * variable name or alias for that attribute of that RTE. + */ +extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum); + +/* + * Check whether an attribute of an RTE has been dropped + */ +extern bool get_rte_attribute_is_dropped(RangeTblEntry *rte, + AttrNumber attnum); + + +/* ---------------- + * target list operations + * ---------------- + */ + +extern TargetEntry *get_tle_by_resno(List *tlist, AttrNumber resno); + +/* ---------------- + * FOR UPDATE/SHARE info + * ---------------- + */ + +extern RowMarkClause *get_parse_rowmark(Query *qry, Index rtindex); + +#endif /* PARSETREE_H */ diff --git a/install/include/postgresql/server/parser/scanner.h b/install/include/postgresql/server/parser/scanner.h new file mode 100644 index 00000000000..da013837cd9 --- /dev/null +++ b/install/include/postgresql/server/parser/scanner.h @@ -0,0 +1,150 @@ +/*------------------------------------------------------------------------- + * + * scanner.h + * API for the core scanner (flex machine) + * + * The core scanner is also used by PL/pgSQL, so we provide a public API + * for it. However, the rest of the backend is only expected to use the + * higher-level API provided by parser.h. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/scanner.h + * + *------------------------------------------------------------------------- + */ + +#ifndef SCANNER_H +#define SCANNER_H + +#include "common/keywords.h" + +/* + * The scanner returns extra data about scanned tokens in this union type. + * Note that this is a subset of the fields used in YYSTYPE of the bison + * parsers built atop the scanner. + */ +typedef union core_YYSTYPE +{ + int ival; /* for integer literals */ + char *str; /* for identifiers and non-integer literals */ + const char *keyword; /* canonical spelling of keywords */ +} core_YYSTYPE; + +/* + * We track token locations in terms of byte offsets from the start of the + * source string, not the column number/line number representation that + * bison uses by default. Also, to minimize overhead we track only one + * location (usually the first token location) for each construct, not + * the beginning and ending locations as bison does by default. It's + * therefore sufficient to make YYLTYPE an int. + */ +#define YYLTYPE int + +/* + * Another important component of the scanner's API is the token code numbers. + * However, those are not defined in this file, because bison insists on + * defining them for itself. The token codes used by the core scanner are + * the ASCII characters plus these: + * %token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op + * %token ICONST PARAM + * %token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER + * %token LESS_EQUALS GREATER_EQUALS NOT_EQUALS + * The above token definitions *must* be the first ones declared in any + * bison parser built atop this scanner, so that they will have consistent + * numbers assigned to them (specifically, IDENT = 258 and so on). + */ + +/* + * The YY_EXTRA data that a flex scanner allows us to pass around. + * Private state needed by the core scanner goes here. Note that the actual + * yy_extra struct may be larger and have this as its first component, thus + * allowing the calling parser to keep some fields of its own in YY_EXTRA. + */ +typedef struct core_yy_extra_type +{ + /* + * The string the scanner is physically scanning. We keep this mainly so + * that we can cheaply compute the offset of the current token (yytext). + */ + char *scanbuf; + Size scanbuflen; + + /* + * The keyword list to use, and the associated grammar token codes. + */ + const ScanKeywordList *keywordlist; + const uint16 *keyword_tokens; + + /* + * Scanner settings to use. These are initialized from the corresponding + * GUC variables by scanner_init(). Callers can modify them after + * scanner_init() if they don't want the scanner's behavior to follow the + * prevailing GUC settings. + */ + int backslash_quote; + bool escape_string_warning; + bool standard_conforming_strings; + + /* + * literalbuf is used to accumulate literal values when multiple rules are + * needed to parse a single literal. Call startlit() to reset buffer to + * empty, addlit() to add text. NOTE: the string in literalbuf is NOT + * necessarily null-terminated, but there always IS room to add a trailing + * null at offset literallen. We store a null only when we need it. + */ + char *literalbuf; /* palloc'd expandable buffer */ + int literallen; /* actual current string length */ + int literalalloc; /* current allocated buffer size */ + + /* + * Random assorted scanner state. + */ + int state_before_str_stop; /* start cond. before end quote */ + int xcdepth; /* depth of nesting in slash-star comments */ + char *dolqstart; /* current $foo$ quote start string */ + YYLTYPE save_yylloc; /* one-element stack for PUSH_YYLLOC() */ + + /* first part of UTF16 surrogate pair for Unicode escapes */ + int32 utf16_first_part; + + /* state variables for literal-lexing warnings */ + bool warn_on_first_escape; + bool saw_non_ascii; +} core_yy_extra_type; + +/* + * The type of yyscanner is opaque outside scan.l. + */ +typedef void *core_yyscan_t; + +/* Support for scanner_errposition_callback function */ +typedef struct ScannerCallbackState +{ + core_yyscan_t yyscanner; + int location; + ErrorContextCallback errcallback; +} ScannerCallbackState; + + +/* Constant data exported from parser/scan.l */ +extern PGDLLIMPORT const uint16 ScanKeywordTokens[]; + +/* Entry points in parser/scan.l */ +extern core_yyscan_t scanner_init(const char *str, + core_yy_extra_type *yyext, + const ScanKeywordList *keywordlist, + const uint16 *keyword_tokens); +extern void scanner_finish(core_yyscan_t yyscanner); +extern int core_yylex(core_YYSTYPE *yylval_param, YYLTYPE *yylloc_param, + core_yyscan_t yyscanner); +extern int scanner_errposition(int location, core_yyscan_t yyscanner); +extern void setup_scanner_errposition_callback(ScannerCallbackState *scbstate, + core_yyscan_t yyscanner, + int location); +extern void cancel_scanner_errposition_callback(ScannerCallbackState *scbstate); +extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner) pg_attribute_noreturn(); + +#endif /* SCANNER_H */ diff --git a/install/include/postgresql/server/parser/scansup.h b/install/include/postgresql/server/parser/scansup.h new file mode 100644 index 00000000000..f2fa1977918 --- /dev/null +++ b/install/include/postgresql/server/parser/scansup.h @@ -0,0 +1,27 @@ +/*------------------------------------------------------------------------- + * + * scansup.h + * scanner support routines used by the core lexer + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/scansup.h + * + *------------------------------------------------------------------------- + */ + +#ifndef SCANSUP_H +#define SCANSUP_H + +extern char *downcase_truncate_identifier(const char *ident, int len, + bool warn); + +extern char *downcase_identifier(const char *ident, int len, + bool warn, bool truncate); + +extern void truncate_identifier(char *ident, int len, bool warn); + +extern bool scanner_isspace(char ch); + +#endif /* SCANSUP_H */ diff --git a/install/include/postgresql/server/partitioning/partbounds.h b/install/include/postgresql/server/partitioning/partbounds.h new file mode 100644 index 00000000000..d2e01f92dfe --- /dev/null +++ b/install/include/postgresql/server/partitioning/partbounds.h @@ -0,0 +1,146 @@ +/*------------------------------------------------------------------------- + * + * partbounds.h + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/include/partitioning/partbounds.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARTBOUNDS_H +#define PARTBOUNDS_H + +#include "fmgr.h" +#include "parser/parse_node.h" +#include "partitioning/partdefs.h" + +struct RelOptInfo; /* avoid including pathnodes.h here */ + + +/* + * PartitionBoundInfoData encapsulates a set of partition bounds. It is + * usually associated with partitioned tables as part of its partition + * descriptor, but may also be used to represent a virtual partitioned + * table such as a partitioned joinrel within the planner. + * + * A list partition datum that is known to be NULL is never put into the + * datums array. Instead, it is tracked using the null_index field. + * + * In the case of range partitioning, ndatums will typically be far less than + * 2 * nparts, because a partition's upper bound and the next partition's lower + * bound are the same in most common cases, and we only store one of them (the + * upper bound). In case of hash partitioning, ndatums will be the same as the + * number of partitions. + * + * For range and list partitioned tables, datums is an array of datum-tuples + * with key->partnatts datums each. For hash partitioned tables, it is an array + * of datum-tuples with 2 datums, modulus and remainder, corresponding to a + * given partition. + * + * The datums in datums array are arranged in increasing order as defined by + * functions qsort_partition_rbound_cmp(), qsort_partition_list_value_cmp() and + * qsort_partition_hbound_cmp() for range, list and hash partitioned tables + * respectively. For range and list partitions this simply means that the + * datums in the datums array are arranged in increasing order as defined by + * the partition key's operator classes and collations. + * + * In the case of list partitioning, the indexes array stores one entry for + * each datum-array entry, which is the index of the partition that accepts + * rows matching that datum. So nindexes == ndatums. + * + * In the case of range partitioning, the indexes array stores one entry per + * distinct range datum, which is the index of the partition for which that + * datum is an upper bound (or -1 for a "gap" that has no partition). It is + * convenient to have an extra -1 entry representing values above the last + * range datum, so nindexes == ndatums + 1. + * + * In the case of hash partitioning, the number of entries in the indexes + * array is the same as the greatest modulus amongst all partitions (which + * is a multiple of all partition moduli), so nindexes == greatest modulus. + * The indexes array is indexed according to the hash key's remainder modulo + * the greatest modulus, and it contains either the partition index accepting + * that remainder, or -1 if there is no partition for that remainder. + * + * For LIST partitioned tables, we track the partition indexes of partitions + * which are possibly "interleaved" partitions. A partition is considered + * interleaved if it allows multiple values and there exists at least one + * other partition which could contain a value that lies between those values. + * For example, if a partition exists FOR VALUES IN(3,5) and another partition + * exists FOR VALUES IN (4), then the IN(3,5) partition is an interleaved + * partition. The same is possible with DEFAULT partitions since they can + * contain any value that does not belong in another partition. This field + * only serves as proof that a particular partition is not interleaved, not + * proof that it is interleaved. When we're uncertain, we marked the + * partition as interleaved. The interleaved_parts field is only ever set for + * RELOPT_BASEREL and RELOPT_OTHER_MEMBER_REL, it is always left NULL for join + * relations. + */ +typedef struct PartitionBoundInfoData +{ + PartitionStrategy strategy; /* hash, list or range? */ + int ndatums; /* Length of the datums[] array */ + Datum **datums; + PartitionRangeDatumKind **kind; /* The kind of each range bound datum; + * NULL for hash and list partitioned + * tables */ + Bitmapset *interleaved_parts; /* Partition indexes of partitions which + * may be interleaved. See above. This is + * only set for LIST partitioned tables */ + int nindexes; /* Length of the indexes[] array */ + int *indexes; /* Partition indexes */ + int null_index; /* Index of the null-accepting partition; -1 + * if there isn't one */ + int default_index; /* Index of the default partition; -1 if there + * isn't one */ +} PartitionBoundInfoData; + +#define partition_bound_accepts_nulls(bi) ((bi)->null_index != -1) +#define partition_bound_has_default(bi) ((bi)->default_index != -1) + +extern int get_hash_partition_greatest_modulus(PartitionBoundInfo bound); +extern uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, + Oid *partcollation, + Datum *values, bool *isnull); +extern List *get_qual_from_partbound(Relation parent, + PartitionBoundSpec *spec); +extern PartitionBoundInfo partition_bounds_create(PartitionBoundSpec **boundspecs, + int nparts, PartitionKey key, int **mapping); +extern bool partition_bounds_equal(int partnatts, int16 *parttyplen, + bool *parttypbyval, PartitionBoundInfo b1, + PartitionBoundInfo b2); +extern PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src, + PartitionKey key); +extern PartitionBoundInfo partition_bounds_merge(int partnatts, + FmgrInfo *partsupfunc, + Oid *partcollation, + struct RelOptInfo *outer_rel, + struct RelOptInfo *inner_rel, + JoinType jointype, + List **outer_parts, + List **inner_parts); +extern bool partitions_are_ordered(PartitionBoundInfo boundinfo, + Bitmapset *live_parts); +extern void check_new_partition_bound(char *relname, Relation parent, + PartitionBoundSpec *spec, + ParseState *pstate); +extern void check_default_partition_contents(Relation parent, + Relation default_rel, + PartitionBoundSpec *new_spec); + +extern int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, + Oid *partcollation, + Datum *rb_datums, PartitionRangeDatumKind *rb_kind, + Datum *tuple_datums, int n_tuple_datums); +extern int partition_list_bsearch(FmgrInfo *partsupfunc, + Oid *partcollation, + PartitionBoundInfo boundinfo, + Datum value, bool *is_equal); +extern int partition_range_datum_bsearch(FmgrInfo *partsupfunc, + Oid *partcollation, + PartitionBoundInfo boundinfo, + int nvalues, Datum *values, bool *is_equal); +extern int partition_hash_bsearch(PartitionBoundInfo boundinfo, + int modulus, int remainder); + +#endif /* PARTBOUNDS_H */ diff --git a/install/include/postgresql/server/partitioning/partdefs.h b/install/include/postgresql/server/partitioning/partdefs.h new file mode 100644 index 00000000000..55bb49c816c --- /dev/null +++ b/install/include/postgresql/server/partitioning/partdefs.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * partdefs.h + * Base definitions for partitioned table handling + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/include/partitioning/partdefs.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARTDEFS_H +#define PARTDEFS_H + + +typedef struct PartitionBoundInfoData *PartitionBoundInfo; + +typedef struct PartitionKeyData *PartitionKey; + +typedef struct PartitionBoundSpec PartitionBoundSpec; + +typedef struct PartitionDescData *PartitionDesc; + +typedef struct PartitionDirectoryData *PartitionDirectory; + +#endif /* PARTDEFS_H */ diff --git a/install/include/postgresql/server/partitioning/partdesc.h b/install/include/postgresql/server/partitioning/partdesc.h new file mode 100644 index 00000000000..e157eae9c1e --- /dev/null +++ b/install/include/postgresql/server/partitioning/partdesc.h @@ -0,0 +1,75 @@ +/*------------------------------------------------------------------------- + * + * partdesc.h + * + * Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/partitioning/partdesc.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PARTDESC_H +#define PARTDESC_H + +#include "partitioning/partdefs.h" +#include "utils/relcache.h" + +/* + * Information about partitions of a partitioned table. + * + * For partitioned tables where detached partitions exist, we only cache + * descriptors that include all partitions, including detached; when we're + * requested a descriptor without the detached partitions, we create one + * afresh each time. (The reason for this is that the set of detached + * partitions that are visible to each caller depends on the snapshot it has, + * so it's pretty much impossible to evict a descriptor from cache at the + * right time.) + */ +typedef struct PartitionDescData +{ + int nparts; /* Number of partitions */ + bool detached_exist; /* Are there any detached partitions? */ + Oid *oids; /* Array of 'nparts' elements containing + * partition OIDs in order of their bounds */ + bool *is_leaf; /* Array of 'nparts' elements storing whether + * the corresponding 'oids' element belongs to + * a leaf partition or not */ + PartitionBoundInfo boundinfo; /* collection of partition bounds */ + + /* Caching fields to cache lookups in get_partition_for_tuple() */ + + /* + * Index into the PartitionBoundInfo's datum array for the last found + * partition or -1 if none. + */ + int last_found_datum_index; + + /* + * Partition index of the last found partition or -1 if none has been + * found yet. + */ + int last_found_part_index; + + /* + * For LIST partitioning, this is the number of times in a row that the + * datum we're looking for a partition for matches the datum in the + * last_found_datum_index index of the boundinfo->datums array. For RANGE + * partitioning, this is the number of times in a row we've found that the + * datum we're looking for a partition for falls into the range of the + * partition corresponding to the last_found_datum_index index of the + * boundinfo->datums array. + */ + int last_found_count; +} PartitionDescData; + + +extern PartitionDesc RelationGetPartitionDesc(Relation rel, bool omit_detached); + +extern PartitionDirectory CreatePartitionDirectory(MemoryContext mcxt, bool omit_detached); +extern PartitionDesc PartitionDirectoryLookup(PartitionDirectory, Relation); +extern void DestroyPartitionDirectory(PartitionDirectory pdir); + +extern Oid get_default_oid_from_partdesc(PartitionDesc partdesc); + +#endif /* PARTCACHE_H */ diff --git a/install/include/postgresql/server/partitioning/partprune.h b/install/include/postgresql/server/partitioning/partprune.h new file mode 100644 index 00000000000..8636e04e374 --- /dev/null +++ b/install/include/postgresql/server/partitioning/partprune.h @@ -0,0 +1,81 @@ +/*------------------------------------------------------------------------- + * + * partprune.h + * prototypes for partprune.c + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/partitioning/partprune.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARTPRUNE_H +#define PARTPRUNE_H + +#include "nodes/execnodes.h" +#include "partitioning/partdefs.h" + +struct PlannerInfo; /* avoid including pathnodes.h here */ +struct RelOptInfo; + + +/* + * PartitionPruneContext + * Stores information needed at runtime for pruning computations + * related to a single partitioned table. + * + * strategy Partition strategy, e.g. LIST, RANGE, HASH. + * partnatts Number of columns in the partition key. + * nparts Number of partitions in this partitioned table. + * boundinfo Partition boundary info for the partitioned table. + * partcollation Array of partnatts elements, storing the collations of the + * partition key columns. + * partsupfunc Array of FmgrInfos for the comparison or hashing functions + * associated with the partition keys (partnatts elements). + * (This points into the partrel's partition key, typically.) + * stepcmpfuncs Array of FmgrInfos for the comparison or hashing function + * for each pruning step and partition key. + * ppccontext Memory context holding this PartitionPruneContext's + * subsidiary data, such as the FmgrInfos. + * planstate Points to the parent plan node's PlanState when called + * during execution; NULL when called from the planner. + * exprcontext ExprContext to use when evaluating pruning expressions + * exprstates Array of ExprStates, indexed as per PruneCxtStateIdx; one + * for each partition key in each pruning step. Allocated if + * planstate is non-NULL, otherwise NULL. + */ +typedef struct PartitionPruneContext +{ + char strategy; + int partnatts; + int nparts; + PartitionBoundInfo boundinfo; + Oid *partcollation; + FmgrInfo *partsupfunc; + FmgrInfo *stepcmpfuncs; + MemoryContext ppccontext; + PlanState *planstate; + ExprContext *exprcontext; + ExprState **exprstates; +} PartitionPruneContext; + +/* + * PruneCxtStateIdx() computes the correct index into the stepcmpfuncs[] + * and exprstates[] arrays for step step_id and partition key column keyno. + * (Note: there is code that assumes the entries for a given step are + * sequential, so this is not chosen freely.) + */ +#define PruneCxtStateIdx(partnatts, step_id, keyno) \ + ((partnatts) * (step_id) + (keyno)) + +extern PartitionPruneInfo *make_partition_pruneinfo(struct PlannerInfo *root, + struct RelOptInfo *parentrel, + List *subpaths, + List *prunequal); +extern Bitmapset *prune_append_rel_partitions(struct RelOptInfo *rel); +extern Bitmapset *get_matching_partitions(PartitionPruneContext *context, + List *pruning_steps); + +#endif /* PARTPRUNE_H */ diff --git a/install/include/postgresql/server/pg_config.h b/install/include/postgresql/server/pg_config.h new file mode 100644 index 00000000000..9af8a0586f7 --- /dev/null +++ b/install/include/postgresql/server/pg_config.h @@ -0,0 +1,830 @@ +/* src/include/pg_config.h. Generated from pg_config.h.in by configure. */ +/* src/include/pg_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* The normal alignment of `double', in bytes. */ +#define ALIGNOF_DOUBLE 8 + +/* The normal alignment of `int', in bytes. */ +#define ALIGNOF_INT 4 + +/* The normal alignment of `long', in bytes. */ +#define ALIGNOF_LONG 8 + +/* The normal alignment of `long long int', in bytes. */ +/* #undef ALIGNOF_LONG_LONG_INT */ + +/* The normal alignment of `PG_INT128_TYPE', in bytes. */ +#define ALIGNOF_PG_INT128_TYPE 16 + +/* The normal alignment of `short', in bytes. */ +#define ALIGNOF_SHORT 2 + +/* Size of a disk block --- this also limits the size of a tuple. You can set + it bigger if you need bigger tuples (although TOAST should reduce the need + to have large tuples, since fields can be spread across multiple tuples). + BLCKSZ must be a power of 2. The maximum possible value of BLCKSZ is + currently 2^15 (32768). This is determined by the 15-bit widths of the + lp_off and lp_len fields in ItemIdData (see include/storage/itemid.h). + Changing BLCKSZ requires an initdb. */ +#define BLCKSZ 8192 + +/* Saved arguments from configure */ +#define CONFIGURE_ARGS " '--prefix=/private/tmp/pgrac-worktrees/linkdb-spec-5.50-cr-profile/install' '--with-openssl' '--with-icu' '--with-lz4' '--with-zstd' '--enable-cluster' '--enable-injection-points' '--enable-tap-tests' '--enable-cassert' 'PKG_CONFIG_PATH=/opt/homebrew/opt/icu4c@78/lib/pkgconfig:/opt/homebrew/opt/openssl@3/lib/pkgconfig:/opt/homebrew/opt/lz4/lib/pkgconfig:/opt/homebrew/opt/zstd/lib/pkgconfig' 'LDFLAGS=-L/opt/homebrew/opt/openssl@3/lib' 'CPPFLAGS=-I/opt/homebrew/opt/openssl@3/include'" + +/* Define to the default TCP port number on which the server listens and to + which clients will try to connect. This can be overridden at run-time, but + it's convenient if your clients have the right default compiled in. + (--with-pgport=PORTNUM) */ +#define DEF_PGPORT 5432 + +/* Define to the default TCP port number as a string constant. */ +#define DEF_PGPORT_STR "5432" + +/* Define to the file name extension of dynamically-loadable modules. */ +#define DLSUFFIX ".dylib" + +/* Define to build with GSSAPI support. (--with-gssapi) */ +/* #undef ENABLE_GSS */ + +/* Define to 1 if you want National Language Support. (--enable-nls) */ +/* #undef ENABLE_NLS */ + +/* Define to 1 to build client libraries as thread-safe code. + (--enable-thread-safety) */ +#define ENABLE_THREAD_SAFETY 1 + +/* Define to 1 if you have the `append_history' function. */ +/* #undef HAVE_APPEND_HISTORY */ + +/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ +#define HAVE_ASN1_STRING_GET0_DATA 1 + +/* Define to 1 if you want to use atomics if available. */ +#define HAVE_ATOMICS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ATOMIC_H */ + +/* Define to 1 if you have the `backtrace_symbols' function. */ +#define HAVE_BACKTRACE_SYMBOLS 1 + +/* Define to 1 if you have the `BIO_meth_new' function. */ +#define HAVE_BIO_METH_NEW 1 + +/* Define to 1 if your compiler handles computed gotos. */ +#define HAVE_COMPUTED_GOTO 1 + +/* Define to 1 if you have the `copyfile' function. */ +#define HAVE_COPYFILE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_COPYFILE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRTDEFS_H */ + +/* Define to 1 if you have the `CRYPTO_lock' function. */ +/* #undef HAVE_CRYPTO_LOCK */ + +/* Define to 1 if you have the declaration of `fdatasync', and to 0 if you + don't. */ +#define HAVE_DECL_FDATASYNC 0 + +/* Define to 1 if you have the declaration of `F_FULLFSYNC', and to 0 if you + don't. */ +#define HAVE_DECL_F_FULLFSYNC 1 + +/* Define to 1 if you have the declaration of + `LLVMCreateGDBRegistrationListener', and to 0 if you don't. */ +/* #undef HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER */ + +/* Define to 1 if you have the declaration of + `LLVMCreatePerfJITEventListener', and to 0 if you don't. */ +/* #undef HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER */ + +/* Define to 1 if you have the declaration of `LLVMGetHostCPUFeatures', and to + 0 if you don't. */ +/* #undef HAVE_DECL_LLVMGETHOSTCPUFEATURES */ + +/* Define to 1 if you have the declaration of `LLVMGetHostCPUName', and to 0 + if you don't. */ +/* #undef HAVE_DECL_LLVMGETHOSTCPUNAME */ + +/* Define to 1 if you have the declaration of `LLVMOrcGetSymbolAddressIn', and + to 0 if you don't. */ +/* #undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN */ + +/* Define to 1 if you have the declaration of `memset_s', and to 0 if you + don't. */ +#define HAVE_DECL_MEMSET_S 1 + +/* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you + don't. */ +#define HAVE_DECL_POSIX_FADVISE 0 + +/* Define to 1 if you have the declaration of `preadv', and to 0 if you don't. + */ +#define HAVE_DECL_PREADV 1 + +/* Define to 1 if you have the declaration of `pwritev', and to 0 if you + don't. */ +#define HAVE_DECL_PWRITEV 1 + +/* Define to 1 if you have the declaration of `strchrnul', and to 0 if you + don't. */ +#define HAVE_DECL_STRCHRNUL 1 + +/* Define to 1 if you have the declaration of `strlcat', and to 0 if you + don't. */ +#define HAVE_DECL_STRLCAT 1 + +/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you + don't. */ +#define HAVE_DECL_STRLCPY 1 + +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +#define HAVE_DECL_STRNLEN 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDITLINE_HISTORY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDITLINE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_EXECINFO_H 1 + +/* Define to 1 if you have the `explicit_bzero' function. */ +/* #undef HAVE_EXPLICIT_BZERO */ + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#define HAVE_FSEEKO 1 + +/* Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int). */ +#define HAVE_GCC__ATOMIC_INT32_CAS 1 + +/* Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, + int64). */ +#define HAVE_GCC__ATOMIC_INT64_CAS 1 + +/* Define to 1 if you have __sync_lock_test_and_set(char *) and friends. */ +#define HAVE_GCC__SYNC_CHAR_TAS 1 + +/* Define to 1 if you have __sync_val_compare_and_swap(int *, int, int). */ +#define HAVE_GCC__SYNC_INT32_CAS 1 + +/* Define to 1 if you have __sync_lock_test_and_set(int *) and friends. */ +#define HAVE_GCC__SYNC_INT32_TAS 1 + +/* Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64). + */ +#define HAVE_GCC__SYNC_INT64_CAS 1 + +/* Define to 1 if you have the `getifaddrs' function. */ +#define HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the `getopt' function. */ +#define HAVE_GETOPT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the `getopt_long' function. */ +#define HAVE_GETOPT_LONG 1 + +/* Define to 1 if you have the `getpeereid' function. */ +#define HAVE_GETPEEREID 1 + +/* Define to 1 if you have the `getpeerucred' function. */ +/* #undef HAVE_GETPEERUCRED */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_EXT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_EXT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_HISTORY_H */ + +/* Define to 1 if you have the `history_truncate_file' function. */ +#define HAVE_HISTORY_TRUNCATE_FILE 1 + +/* Define to 1 if you have the `HMAC_CTX_free' function. */ +#define HAVE_HMAC_CTX_FREE 1 + +/* Define to 1 if you have the `HMAC_CTX_new' function. */ +#define HAVE_HMAC_CTX_NEW 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the `inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if the system has the type `int64'. */ +/* #undef HAVE_INT64 */ + +/* Define to 1 if the system has the type `int8'. */ +/* #undef HAVE_INT8 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the global variable 'int opterr'. */ +#define HAVE_INT_OPTERR 1 + +/* Define to 1 if you have the global variable 'int optreset'. */ +#define HAVE_INT_OPTRESET 1 + +/* Define to 1 if you have the global variable 'int timezone'. */ +#define HAVE_INT_TIMEZONE 1 + +/* Define to 1 if __builtin_constant_p(x) implies "i"(x) acceptance. */ +/* #undef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P */ + +/* Define to 1 if you have the `kqueue' function. */ +#define HAVE_KQUEUE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LANGINFO_H 1 + +/* Define to 1 if you have the `ldap_initialize' function. */ +/* #undef HAVE_LDAP_INITIALIZE */ + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#define HAVE_LIBCRYPTO 1 + +/* Define to 1 if you have the `ldap' library (-lldap). */ +/* #undef HAVE_LIBLDAP */ + +/* Define to 1 if you have the `lz4' library (-llz4). */ +#define HAVE_LIBLZ4 1 + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the `pam' library (-lpam). */ +/* #undef HAVE_LIBPAM */ + +/* Define if you have a function readline library */ +#define HAVE_LIBREADLINE 1 + +/* Define to 1 if you have the `selinux' library (-lselinux). */ +/* #undef HAVE_LIBSELINUX */ + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#define HAVE_LIBSSL 1 + +/* Define to 1 if you have the `wldap32' library (-lwldap32). */ +/* #undef HAVE_LIBWLDAP32 */ + +/* Define to 1 if you have the `xml2' library (-lxml2). */ +/* #undef HAVE_LIBXML2 */ + +/* Define to 1 if you have the `xslt' library (-lxslt). */ +/* #undef HAVE_LIBXSLT */ + +/* Define to 1 if you have the `z' library (-lz). */ +#define HAVE_LIBZ 1 + +/* Define to 1 if you have the `zstd' library (-lzstd). */ +#define HAVE_LIBZSTD 1 + +/* Define to 1 if the system has the type `locale_t'. */ +#define HAVE_LOCALE_T 1 + +/* Define to 1 if `long int' works and is 64 bits. */ +#define HAVE_LONG_INT_64 1 + +/* Define to 1 if `long long int' works and is 64 bits. */ +/* #undef HAVE_LONG_LONG_INT_64 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MBARRIER_H */ + +/* Define to 1 if you have the `mbstowcs_l' function. */ +#define HAVE_MBSTOWCS_L 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mkdtemp' function. */ +#define HAVE_MKDTEMP 1 + +/* Define to 1 if you have the `OPENSSL_init_ssl' function. */ +#define HAVE_OPENSSL_INIT_SSL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OSSP_UUID_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PAM_PAM_APPL_H */ + +/* Define to 1 if you have the `posix_fadvise' function. */ +/* #undef HAVE_POSIX_FADVISE */ + +/* Define to 1 if you have the `posix_fallocate' function. */ +/* #undef HAVE_POSIX_FALLOCATE */ + +/* Define to 1 if you have the `ppoll' function. */ +/* #undef HAVE_PPOLL */ + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the `pthread_barrier_wait' function. */ +/* #undef HAVE_PTHREAD_BARRIER_WAIT */ + +/* Define to 1 if you have the `pthread_is_threaded_np' function. */ +#define HAVE_PTHREAD_IS_THREADED_NP 1 + +/* Have PTHREAD_PRIO_INHERIT. */ +#define HAVE_PTHREAD_PRIO_INHERIT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_READLINE_HISTORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_READLINE_READLINE_H 1 + +/* Define to 1 if you have the `rl_completion_matches' function. */ +#define HAVE_RL_COMPLETION_MATCHES 1 + +/* Define to 1 if you have the global variable 'rl_completion_suppress_quote'. + */ +/* #undef HAVE_RL_COMPLETION_SUPPRESS_QUOTE */ + +/* Define to 1 if you have the `rl_filename_completion_function' function. */ +#define HAVE_RL_FILENAME_COMPLETION_FUNCTION 1 + +/* Define to 1 if you have the global variable 'rl_filename_quote_characters'. + */ +/* #undef HAVE_RL_FILENAME_QUOTE_CHARACTERS */ + +/* Define to 1 if you have the global variable 'rl_filename_quoting_function'. + */ +/* #undef HAVE_RL_FILENAME_QUOTING_FUNCTION */ + +/* Define to 1 if you have the `rl_reset_screen_size' function. */ +/* #undef HAVE_RL_RESET_SCREEN_SIZE */ + +/* Define to 1 if you have the `rl_variable_bind' function. */ +#define HAVE_RL_VARIABLE_BIND 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SECURITY_PAM_APPL_H */ + +/* Define to 1 if you have the `setproctitle' function. */ +/* #undef HAVE_SETPROCTITLE */ + +/* Define to 1 if you have the `setproctitle_fast' function. */ +/* #undef HAVE_SETPROCTITLE_FAST */ + +/* Define to 1 if the system has the type `socklen_t'. */ +#define HAVE_SOCKLEN_T 1 + +/* Define to 1 if you have spinlocks. */ +#define HAVE_SPINLOCKS 1 + +/* Define to 1 if you have the `SSL_CTX_set_cert_cb' function. */ +#define HAVE_SSL_CTX_SET_CERT_CB 1 + +/* Define to 1 if you have the `SSL_CTX_set_num_tickets' function. */ +#define HAVE_SSL_CTX_SET_NUM_TICKETS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +#define HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the `strnlen' function. */ +#define HAVE_STRNLEN 1 + +/* Define to 1 if you have the `strsignal' function. */ +#define HAVE_STRSIGNAL 1 + +/* Define to 1 if the system has the type `struct option'. */ +#define HAVE_STRUCT_OPTION 1 + +/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ +#define HAVE_STRUCT_SOCKADDR_SA_LEN 1 + +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +#define HAVE_STRUCT_TM_TM_ZONE 1 + +/* Define to 1 if you have the `syncfs' function. */ +/* #undef HAVE_SYNCFS */ + +/* Define to 1 if you have the `sync_file_range' function. */ +/* #undef HAVE_SYNC_FILE_RANGE */ + +/* Define to 1 if you have the syslog interface. */ +#define HAVE_SYSLOG 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_EPOLL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_EVENT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PERSONALITY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PROCCTL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SIGNALFD_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UCRED_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if your compiler understands `typeof' or something similar. */ +#define HAVE_TYPEOF 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UCRED_H */ + +/* Define to 1 if the system has the type `uint64'. */ +/* #undef HAVE_UINT64 */ + +/* Define to 1 if the system has the type `uint8'. */ +/* #undef HAVE_UINT8 */ + +/* Define to 1 if the system has the type `union semun'. */ +#define HAVE_UNION_SEMUN 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `uselocale' function. */ +#define HAVE_USELOCALE 1 + +/* Define to 1 if you have BSD UUID support. */ +/* #undef HAVE_UUID_BSD */ + +/* Define to 1 if you have E2FS UUID support. */ +/* #undef HAVE_UUID_E2FS */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UUID_H */ + +/* Define to 1 if you have OSSP UUID support. */ +/* #undef HAVE_UUID_OSSP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UUID_UUID_H */ + +/* Define to 1 if your compiler knows the visibility("hidden") attribute. */ +#define HAVE_VISIBILITY_ATTRIBUTE 1 + +/* Define to 1 if you have the `wcstombs_l' function. */ +#define HAVE_WCSTOMBS_L 1 + +/* Define to 1 if you have the `X509_get_signature_info' function. */ +#define HAVE_X509_GET_SIGNATURE_INFO 1 + +/* Define to 1 if you have the `X509_get_signature_nid' function. */ +#define HAVE_X509_GET_SIGNATURE_NID 1 + +/* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ +/* #undef HAVE_X86_64_POPCNTQ */ + +/* Define to 1 if your compiler understands __builtin_bswap16. */ +#define HAVE__BUILTIN_BSWAP16 1 + +/* Define to 1 if your compiler understands __builtin_bswap32. */ +#define HAVE__BUILTIN_BSWAP32 1 + +/* Define to 1 if your compiler understands __builtin_bswap64. */ +#define HAVE__BUILTIN_BSWAP64 1 + +/* Define to 1 if your compiler understands __builtin_clz. */ +#define HAVE__BUILTIN_CLZ 1 + +/* Define to 1 if your compiler understands __builtin_constant_p. */ +#define HAVE__BUILTIN_CONSTANT_P 1 + +/* Define to 1 if your compiler understands __builtin_ctz. */ +#define HAVE__BUILTIN_CTZ 1 + +/* Define to 1 if your compiler understands __builtin_frame_address. */ +#define HAVE__BUILTIN_FRAME_ADDRESS 1 + +/* Define to 1 if your compiler understands __builtin_$op_overflow. */ +#define HAVE__BUILTIN_OP_OVERFLOW 1 + +/* Define to 1 if your compiler understands __builtin_popcount. */ +#define HAVE__BUILTIN_POPCOUNT 1 + +/* Define to 1 if your compiler understands __builtin_types_compatible_p. */ +#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1 + +/* Define to 1 if your compiler understands __builtin_unreachable. */ +#define HAVE__BUILTIN_UNREACHABLE 1 + +/* Define to 1 if you have the `_configthreadlocale' function. */ +/* #undef HAVE__CONFIGTHREADLOCALE */ + +/* Define to 1 if you have __cpuid. */ +/* #undef HAVE__CPUID */ + +/* Define to 1 if you have __get_cpuid. */ +/* #undef HAVE__GET_CPUID */ + +/* Define to 1 if your compiler understands _Static_assert. */ +#define HAVE__STATIC_ASSERT 1 + +/* Define to the appropriate printf length modifier for 64-bit ints. */ +#define INT64_MODIFIER "l" + +/* Define to 1 if `locale_t' requires . */ +/* #undef LOCALE_T_IN_XLOCALE */ + +/* Define as the maximum alignment requirement of any C data type. */ +#define MAXIMUM_ALIGNOF 8 + +/* Define bytes to use libc memset(). */ +#define MEMSET_LOOP_LIMIT 1024 + +/* Define to the OpenSSL API version in use. This avoids deprecation warnings + from newer OpenSSL versions. */ +#define OPENSSL_API_COMPAT 0x10001000L + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "pgsql-bugs@lists.postgresql.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "PostgreSQL" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "PostgreSQL 16.13" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "postgresql" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "https://www.postgresql.org/" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "16.13" + +/* Define to the name of a signed 128-bit integer type. */ +#define PG_INT128_TYPE __int128 + +/* Define to the name of a signed 64-bit integer type. */ +#define PG_INT64_TYPE long int + +/* Define to the name of the default PostgreSQL service principal in Kerberos + (GSSAPI). (--with-krb-srvnam=NAME) */ +#define PG_KRB_SRVNAM "postgres" + +/* PostgreSQL major version as a string */ +#define PG_MAJORVERSION "16" + +/* PostgreSQL major version number */ +#define PG_MAJORVERSION_NUM 16 + +/* PostgreSQL minor version number */ +#define PG_MINORVERSION_NUM 13 + +/* Define to best printf format archetype, usually gnu_printf if available. */ +#define PG_PRINTF_ATTRIBUTE __syslog__ + +/* Define to 1 to use to define type bool. */ +#define PG_USE_STDBOOL 1 + +/* PostgreSQL version as a string */ +#define PG_VERSION "16.13" + +/* PostgreSQL version as a number */ +#define PG_VERSION_NUM 160013 + +/* A string containing the version number, platform, and C compiler */ +#define PG_VERSION_STR "PostgreSQL 16.13 on aarch64-apple-darwin25.4.0, compiled by Apple clang version 21.0.0 (clang-2100.0.123.102), 64-bit" + +/* Define to 1 to allow profiling output to be saved separately for each + process. */ +/* #undef PROFILE_PID_DIR */ + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* RELSEG_SIZE is the maximum number of blocks allowed in one disk file. Thus, + the maximum size of a single file is RELSEG_SIZE * BLCKSZ; relations bigger + than that are divided into multiple files. RELSEG_SIZE * BLCKSZ must be + less than your OS' limit on file size. This is often 2 GB or 4GB in a + 32-bit operating system, unless you have large file support enabled. By + default, we make the limit 1 GB to avoid any possible integer-overflow + problems within the OS. A limit smaller than necessary only means we divide + a large relation into more chunks than necessary, so it seems best to err + in the direction of a small limit. A power-of-2 value is recommended to + save a few cycles in md.c, but is not absolutely required. Changing + RELSEG_SIZE requires an initdb. */ +#define RELSEG_SIZE 131072 + +/* The size of `bool', as computed by sizeof. */ +#define SIZEOF_BOOL 1 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* The size of `off_t', as computed by sizeof. */ +#define SIZEOF_OFF_T 8 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 8 + +/* The size of `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 8 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if strerror_r() returns int. */ +#define STRERROR_R_INT 1 + +/* Define to 1 to use ARMv8 CRC Extension. */ +#define USE_ARMV8_CRC32C 1 + +/* Define to 1 to use ARMv8 CRC Extension with a runtime check. */ +/* #undef USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK */ + +/* Define to 1 to build with assertion checks. (--enable-cassert) */ +#define USE_ASSERT_CHECKING 1 + +/* PGRAC: Define to 1 to build test-only injection helpers. (--enable-injection-points) */ +#define ENABLE_INJECTION 1 + +/* Define to 1 to build with Bonjour support. (--with-bonjour) */ +/* #undef USE_BONJOUR */ + +/* PGRAC: Define to 1 to build pgrac cluster subsystem. (--enable-cluster) */ +#define USE_PGRAC_CLUSTER 1 + +/* Define to 1 to build with BSD Authentication support. (--with-bsd-auth) */ +/* #undef USE_BSD_AUTH */ + +/* Define to build with ICU support. (--with-icu) */ +#define USE_ICU 1 + +/* Define to 1 to build with LDAP support. (--with-ldap) */ +/* #undef USE_LDAP */ + +/* Define to 1 to build with XML support. (--with-libxml) */ +/* #undef USE_LIBXML */ + +/* Define to 1 to use XSLT support when building contrib/xml2. + (--with-libxslt) */ +/* #undef USE_LIBXSLT */ + +/* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ +/* #undef USE_LLVM */ + +/* Define to 1 to build with LZ4 support. (--with-lz4) */ +#define USE_LZ4 1 + +/* Define to select named POSIX semaphores. */ +/* #undef USE_NAMED_POSIX_SEMAPHORES */ + +/* Define to 1 to build with OpenSSL support. (--with-ssl=openssl) */ +#define USE_OPENSSL 1 + +/* Define to 1 to build with PAM support. (--with-pam) */ +/* #undef USE_PAM */ + +/* Define to 1 to use software CRC-32C implementation (slicing-by-8). */ +/* #undef USE_SLICING_BY_8_CRC32C */ + +/* Define to 1 use Intel SSE 4.2 CRC instructions. */ +/* #undef USE_SSE42_CRC32C */ + +/* Define to 1 to use Intel SSE 4.2 CRC instructions with a runtime check. */ +/* #undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK */ + +/* Define to build with systemd support. (--with-systemd) */ +/* #undef USE_SYSTEMD */ + +/* Define to select SysV-style semaphores. */ +#define USE_SYSV_SEMAPHORES 1 + +/* Define to select SysV-style shared memory. */ +#define USE_SYSV_SHARED_MEMORY 1 + +/* Define to select unnamed POSIX semaphores. */ +/* #undef USE_UNNAMED_POSIX_SEMAPHORES */ + +/* Define to select Win32-style semaphores. */ +/* #undef USE_WIN32_SEMAPHORES */ + +/* Define to select Win32-style shared memory. */ +/* #undef USE_WIN32_SHARED_MEMORY */ + +/* Define to 1 to build with ZSTD support. (--with-zstd) */ +#define USE_ZSTD 1 + +/* Define to 1 if `wcstombs_l' requires . */ +#define WCSTOMBS_L_IN_XLOCALE 1 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Size of a WAL file block. This need have no particular relation to BLCKSZ. + XLOG_BLCKSZ must be a power of 2, and if your system supports O_DIRECT I/O, + XLOG_BLCKSZ must be a multiple of the alignment requirement for direct-I/O + buffers, else direct I/O may fail. Changing XLOG_BLCKSZ requires an initdb. + */ +#define XLOG_BLCKSZ 8192 + + + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* #undef _LARGEFILE_SOURCE */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to keyword to use for C99 restrict support, or to nothing if not + supported */ +#define pg_restrict __restrict + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#define restrict __restrict +/* Work around a bug in Sun C++: it does not support _Restrict or + __restrict__, even though the corresponding Sun C compiler ends up with + "#define restrict _Restrict" or "#define restrict __restrict__" in the + previous line. Perhaps some future version of Sun C++ will work with + restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ +#if defined __SUNPRO_CC && !defined __RESTRICT +# define _Restrict +# define __restrict__ +#endif + +/* Define to how the compiler spells `typeof'. */ +/* #undef typeof */ diff --git a/install/include/postgresql/server/pg_config_ext.h b/install/include/postgresql/server/pg_config_ext.h new file mode 100644 index 00000000000..b4c07dd8572 --- /dev/null +++ b/install/include/postgresql/server/pg_config_ext.h @@ -0,0 +1,8 @@ +/* src/include/pg_config_ext.h. Generated from pg_config_ext.h.in by configure. */ +/* + * src/include/pg_config_ext.h.in. This is generated manually, not by + * autoheader, since we want to limit which symbols get defined here. + */ + +/* Define to the name of a signed 64-bit integer type. */ +#define PG_INT64_TYPE long int diff --git a/install/include/postgresql/server/pg_config_manual.h b/install/include/postgresql/server/pg_config_manual.h new file mode 100644 index 00000000000..a1a93ad706e --- /dev/null +++ b/install/include/postgresql/server/pg_config_manual.h @@ -0,0 +1,372 @@ +/*------------------------------------------------------------------------ + * PostgreSQL manual configuration settings + * + * This file contains various configuration symbols and limits. In + * all cases, changing them is only useful in very rare situations or + * for developers. If you edit any of these, be sure to do a *full* + * rebuild (and an initdb if noted). + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/pg_config_manual.h + *------------------------------------------------------------------------ + */ + +/* + * This is the default value for wal_segment_size to be used when initdb is run + * without the --wal-segsize option. It must be a valid segment size. + */ +#define DEFAULT_XLOG_SEG_SIZE (16*1024*1024) + +/* + * Maximum length for identifiers (e.g. table names, column names, + * function names). Names actually are limited to one fewer byte than this, + * because the length must include a trailing zero byte. + * + * Changing this requires an initdb. + */ +#define NAMEDATALEN 64 + +/* + * Maximum number of arguments to a function. + * + * The minimum value is 8 (GIN indexes use 8-argument support functions). + * The maximum possible value is around 600 (limited by index tuple size in + * pg_proc's index; BLCKSZ larger than 8K would allow more). Values larger + * than needed will waste memory and processing time, but do not directly + * cost disk space. + * + * Changing this does not require an initdb, but it does require a full + * backend recompile (including any user-defined C functions). + */ +#define FUNC_MAX_ARGS 100 + +/* + * When creating a product derived from PostgreSQL with changes that cause + * incompatibilities for loadable modules, it is recommended to change this + * string so that dfmgr.c can refuse to load incompatible modules with a clean + * error message. Typical examples that cause incompatibilities are any + * changes to node tags or node structures. (Note that dfmgr.c already + * detects common sources of incompatibilities due to major version + * differences and due to some changed compile-time constants. This setting + * is for catching anything that cannot be detected in a straightforward way.) + * + * There is no prescribed format for the string. The suggestion is to include + * product or company name, and optionally any internally-relevant ABI + * version. Example: "ACME Postgres/1.2". Note that the string will appear + * in a user-facing error message if an ABI mismatch is detected. + */ +#define FMGR_ABI_EXTRA "PostgreSQL" + +/* + * Maximum number of columns in an index. There is little point in making + * this anything but a multiple of 32, because the main cost is associated + * with index tuple header size (see access/itup.h). + * + * Changing this requires an initdb. + */ +#define INDEX_MAX_KEYS 32 + +/* + * Maximum number of columns in a partition key + */ +#define PARTITION_MAX_KEYS 32 + +/* + * Decide whether built-in 8-byte types, including float8, int8, and + * timestamp, are passed by value. This is on by default if sizeof(Datum) >= + * 8 (that is, on 64-bit platforms). If sizeof(Datum) < 8 (32-bit platforms), + * this must be off. We keep this here as an option so that it is easy to + * test the pass-by-reference code paths on 64-bit platforms. + * + * Changing this requires an initdb. + */ +#if SIZEOF_VOID_P >= 8 +#define USE_FLOAT8_BYVAL 1 +#endif + +/* + * When we don't have native spinlocks, we use semaphores to simulate them. + * Decreasing this value reduces consumption of OS resources; increasing it + * may improve performance, but supplying a real spinlock implementation is + * probably far better. + */ +#define NUM_SPINLOCK_SEMAPHORES 128 + +/* + * When we have neither spinlocks nor atomic operations support we're + * implementing atomic operations on top of spinlock on top of semaphores. To + * be safe against atomic operations while holding a spinlock separate + * semaphores have to be used. + */ +#define NUM_ATOMICS_SEMAPHORES 64 + +/* + * MAXPGPATH: standard size of a pathname buffer in PostgreSQL (hence, + * maximum usable pathname length is one less). + * + * We'd use a standard system header symbol for this, if there weren't + * so many to choose from: MAXPATHLEN, MAX_PATH, PATH_MAX are all + * defined by different "standards", and often have different values + * on the same platform! So we just punt and use a reasonably + * generous setting here. + */ +#define MAXPGPATH 1024 + +/* + * You can try changing this if you have a machine with bytes of + * another size, but no guarantee... + */ +#define BITS_PER_BYTE 8 + +/* + * Preferred alignment for disk I/O buffers. On some CPUs, copies between + * user space and kernel space are significantly faster if the user buffer + * is aligned on a larger-than-MAXALIGN boundary. Ideally this should be + * a platform-dependent value, but for now we just hard-wire it. + */ +#define ALIGNOF_BUFFER 32 + +/* + * If EXEC_BACKEND is defined, the postmaster uses an alternative method for + * starting subprocesses: Instead of simply using fork(), as is standard on + * Unix platforms, it uses fork()+exec() or something equivalent on Windows, + * as well as lots of extra code to bring the required global state to those + * new processes. This must be enabled on Windows (because there is no + * fork()). On other platforms, it's only useful for verifying those + * otherwise Windows-specific code paths. + */ +#if defined(WIN32) && !defined(__CYGWIN__) +#define EXEC_BACKEND +#endif + +/* + * USE_POSIX_FADVISE controls whether Postgres will attempt to use the + * posix_fadvise() kernel call. Usually the automatic configure tests are + * sufficient, but some older Linux distributions had broken versions of + * posix_fadvise(). If necessary you can remove the #define here. + */ +#if HAVE_DECL_POSIX_FADVISE && defined(HAVE_POSIX_FADVISE) +#define USE_POSIX_FADVISE +#endif + +/* + * USE_PREFETCH code should be compiled only if we have a way to implement + * prefetching. (This is decoupled from USE_POSIX_FADVISE because there + * might in future be support for alternative low-level prefetch APIs. + * If you change this, you probably need to adjust the error message in + * check_effective_io_concurrency.) + */ +#ifdef USE_POSIX_FADVISE +#define USE_PREFETCH +#endif + +/* + * Default and maximum values for backend_flush_after, bgwriter_flush_after + * and checkpoint_flush_after; measured in blocks. Currently, these are + * enabled by default if sync_file_range() exists, ie, only on Linux. Perhaps + * we could also enable by default if we have mmap and msync(MS_ASYNC)? + */ +#ifdef HAVE_SYNC_FILE_RANGE +#define DEFAULT_BACKEND_FLUSH_AFTER 0 /* never enabled by default */ +#define DEFAULT_BGWRITER_FLUSH_AFTER 64 +#define DEFAULT_CHECKPOINT_FLUSH_AFTER 32 +#else +#define DEFAULT_BACKEND_FLUSH_AFTER 0 +#define DEFAULT_BGWRITER_FLUSH_AFTER 0 +#define DEFAULT_CHECKPOINT_FLUSH_AFTER 0 +#endif +/* upper limit for all three variables */ +#define WRITEBACK_MAX_PENDING_FLUSHES 256 + +/* + * USE_SSL code should be compiled only when compiling with an SSL + * implementation. + */ +#ifdef USE_OPENSSL +#define USE_SSL +#endif + +/* + * This is the default directory in which AF_UNIX socket files are + * placed. Caution: changing this risks breaking your existing client + * applications, which are likely to continue to look in the old + * directory. But if you just hate the idea of sockets in /tmp, + * here's where to twiddle it. You can also override this at runtime + * with the postmaster's -k switch. + * + * If set to an empty string, then AF_UNIX sockets are not used by default: A + * server will not create an AF_UNIX socket unless the run-time configuration + * is changed, a client will connect via TCP/IP by default and will only use + * an AF_UNIX socket if one is explicitly specified. + * + * This is done by default on Windows because there is no good standard + * location for AF_UNIX sockets and many installations on Windows don't + * support them yet. + */ +#ifndef WIN32 +#define DEFAULT_PGSOCKET_DIR "/tmp" +#else +#define DEFAULT_PGSOCKET_DIR "" +#endif + +/* + * This is the default event source for Windows event log. + */ +#define DEFAULT_EVENT_SOURCE "PostgreSQL" + +/* + * Assumed cache line size. This doesn't affect correctness, but can be used + * for low-level optimizations. Currently, this is used to pad some data + * structures in xlog.c, to ensure that highly-contended fields are on + * different cache lines. Too small a value can hurt performance due to false + * sharing, while the only downside of too large a value is a few bytes of + * wasted memory. The default is 128, which should be large enough for all + * supported platforms. + */ +#define PG_CACHE_LINE_SIZE 128 + +/* + * Assumed alignment requirement for direct I/O. 4K corresponds to common + * sector and memory page size. + */ +#define PG_IO_ALIGN_SIZE 4096 + +/* + *------------------------------------------------------------------------ + * The following symbols are for enabling debugging code, not for + * controlling user-visible features or resource limits. + *------------------------------------------------------------------------ + */ + +/* + * Include Valgrind "client requests", mostly in the memory allocator, so + * Valgrind understands PostgreSQL memory contexts. This permits detecting + * memory errors that Valgrind would not detect on a vanilla build. It also + * enables detection of buffer accesses that take place without holding a + * buffer pin (or without holding a buffer lock in the case of index access + * methods that superimpose their own custom client requests on top of the + * generic bufmgr.c requests). + * + * "make installcheck" is significantly slower under Valgrind. The client + * requests fall in hot code paths, so USE_VALGRIND slows execution by a few + * percentage points even when not run under Valgrind. + * + * Do not try to test the server under Valgrind without having built the + * server with USE_VALGRIND; else you will get false positives from sinval + * messaging (see comments in AddCatcacheInvalidationMessage). It's also + * important to use the suppression file src/tools/valgrind.supp to + * exclude other known false positives. + * + * You should normally use MEMORY_CONTEXT_CHECKING with USE_VALGRIND; + * instrumentation of repalloc() is inferior without it. + */ +/* #define USE_VALGRIND */ + +/* + * Define this to cause pfree()'d memory to be cleared immediately, to + * facilitate catching bugs that refer to already-freed values. + * Right now, this gets defined automatically if --enable-cassert. + */ +#ifdef USE_ASSERT_CHECKING +#define CLOBBER_FREED_MEMORY +#endif + +/* + * Define this to check memory allocation errors (scribbling on more + * bytes than were allocated). Right now, this gets defined + * automatically if --enable-cassert or USE_VALGRIND. + */ +#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND) +#define MEMORY_CONTEXT_CHECKING +#endif + +/* + * Define this to cause palloc()'d memory to be filled with random data, to + * facilitate catching code that depends on the contents of uninitialized + * memory. Caution: this is horrendously expensive. + */ +/* #define RANDOMIZE_ALLOCATED_MEMORY */ + +/* + * For cache-invalidation debugging, define DISCARD_CACHES_ENABLED to enable + * use of the debug_discard_caches GUC to aggressively flush syscache/relcache + * entries whenever it's possible to deliver invalidations. See + * AcceptInvalidationMessages() in src/backend/utils/cache/inval.c for + * details. + * + * USE_ASSERT_CHECKING builds default to enabling this. It's possible to use + * DISCARD_CACHES_ENABLED without a cassert build and the implied + * CLOBBER_FREED_MEMORY and MEMORY_CONTEXT_CHECKING options, but it's unlikely + * to be as effective at identifying problems. + */ +/* #define DISCARD_CACHES_ENABLED */ + +#if defined(USE_ASSERT_CHECKING) && !defined(DISCARD_CACHES_ENABLED) +#define DISCARD_CACHES_ENABLED +#endif + +/* + * Backwards compatibility for the older compile-time-only clobber-cache + * macros. + */ +#if !defined(DISCARD_CACHES_ENABLED) && (defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY)) +#define DISCARD_CACHES_ENABLED +#endif + +/* + * Recover memory used for relcache entries when invalidated. See + * RelationBuildDesc() in src/backend/utils/cache/relcache.c. + * + * This is active automatically for clobber-cache builds when clobbering is + * active, but can be overridden here by explicitly defining + * RECOVER_RELATION_BUILD_MEMORY. Define to 1 to always free relation cache + * memory even when clobber is off, or to 0 to never free relation cache + * memory even when clobbering is on. + */ + /* #define RECOVER_RELATION_BUILD_MEMORY 0 */ /* Force disable */ + /* #define RECOVER_RELATION_BUILD_MEMORY 1 */ /* Force enable */ + +/* + * Define this to force all parse and plan trees to be passed through + * copyObject(), to facilitate catching errors and omissions in + * copyObject(). + */ +/* #define COPY_PARSE_PLAN_TREES */ + +/* + * Define this to force all parse and plan trees to be passed through + * outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in + * those modules. + */ +/* #define WRITE_READ_PARSE_PLAN_TREES */ + +/* + * Define this to force all raw parse trees for DML statements to be scanned + * by raw_expression_tree_walker(), to facilitate catching errors and + * omissions in that function. + */ +/* #define RAW_EXPRESSION_COVERAGE_TEST */ + +/* + * Enable debugging print statements for lock-related operations. + */ +/* #define LOCK_DEBUG */ + +/* + * Enable debugging print statements for WAL-related operations; see + * also the wal_debug GUC var. + */ +/* #define WAL_DEBUG */ + +/* + * Enable tracing of resource consumption during sort operations; + * see also the trace_sort GUC var. For 8.1 this is enabled by default. + */ +#define TRACE_SORT 1 + +/* + * Enable tracing of syncscan operations (see also the trace_syncscan GUC var). + */ +/* #define TRACE_SYNCSCAN */ diff --git a/install/include/postgresql/server/pg_config_os.h b/install/include/postgresql/server/pg_config_os.h new file mode 100644 index 00000000000..15fb69d6dbb --- /dev/null +++ b/install/include/postgresql/server/pg_config_os.h @@ -0,0 +1,8 @@ +/* src/include/port/darwin.h */ + +#define __darwin__ 1 + +#if HAVE_DECL_F_FULLFSYNC /* not present before macOS 10.3 */ +#define HAVE_FSYNC_WRITETHROUGH + +#endif diff --git a/install/include/postgresql/server/pg_getopt.h b/install/include/postgresql/server/pg_getopt.h new file mode 100644 index 00000000000..252b4e193b9 --- /dev/null +++ b/install/include/postgresql/server/pg_getopt.h @@ -0,0 +1,56 @@ +/* + * Postgres files that use getopt(3) always include this file. + * We must cope with three different scenarios: + * 1. We're using the platform's getopt(), and we should just import the + * appropriate declarations. + * 2. The platform lacks getopt(), and we must declare everything. + * 3. The platform has getopt(), but we're not using it because we don't + * like its behavior. The declarations we make here must be compatible + * with both the platform's getopt() and our src/port/getopt.c. + * + * Portions Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Portions Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/include/pg_getopt.h + */ +#ifndef PG_GETOPT_H +#define PG_GETOPT_H + +/* POSIX says getopt() is provided by unistd.h */ +#include + +/* rely on the system's getopt.h if present */ +#ifdef HAVE_GETOPT_H +#include +#endif + +/* + * If we have , assume it declares these variables, else do that + * ourselves. (We used to just declare them unconditionally, but Cygwin + * doesn't like that.) + */ +#ifndef HAVE_GETOPT_H + +extern PGDLLIMPORT char *optarg; +extern PGDLLIMPORT int optind; +extern PGDLLIMPORT int opterr; +extern PGDLLIMPORT int optopt; + +#endif /* HAVE_GETOPT_H */ + +/* + * Some platforms have optreset but fail to declare it in , so cope. + * Cygwin, however, doesn't like this either. + */ +#if defined(HAVE_INT_OPTRESET) && !defined(__CYGWIN__) +extern PGDLLIMPORT int optreset; +#endif + +/* Provide getopt() declaration if the platform doesn't have it */ +#ifndef HAVE_GETOPT +extern int getopt(int nargc, char *const *nargv, const char *ostr); +#endif + +#endif /* PG_GETOPT_H */ diff --git a/install/include/postgresql/server/pg_trace.h b/install/include/postgresql/server/pg_trace.h new file mode 100644 index 00000000000..c31bb4a746b --- /dev/null +++ b/install/include/postgresql/server/pg_trace.h @@ -0,0 +1,17 @@ +/* ---------- + * pg_trace.h + * + * Definitions for the PostgreSQL tracing framework + * + * Copyright (c) 2006-2023, PostgreSQL Global Development Group + * + * src/include/pg_trace.h + * ---------- + */ + +#ifndef PG_TRACE_H +#define PG_TRACE_H + +#include "utils/probes.h" /* pgrminclude ignore */ + +#endif /* PG_TRACE_H */ diff --git a/install/include/postgresql/server/pgstat.h b/install/include/postgresql/server/pgstat.h new file mode 100644 index 00000000000..57a2c0866a2 --- /dev/null +++ b/install/include/postgresql/server/pgstat.h @@ -0,0 +1,778 @@ +/* ---------- + * pgstat.h + * + * Definitions for the PostgreSQL cumulative statistics system. + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/pgstat.h + * ---------- + */ +#ifndef PGSTAT_H +#define PGSTAT_H + +#include "datatype/timestamp.h" +#include "portability/instr_time.h" +#include "postmaster/pgarch.h" /* for MAX_XFN_CHARS */ +#include "utils/backend_progress.h" /* for backward compatibility */ +#include "utils/backend_status.h" /* for backward compatibility */ +#include "utils/relcache.h" +#include "utils/wait_event.h" /* for backward compatibility */ + + +/* ---------- + * Paths for the statistics files (relative to installation's $PGDATA). + * ---------- + */ +#define PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat" +#define PGSTAT_STAT_PERMANENT_FILENAME "pg_stat/pgstat.stat" +#define PGSTAT_STAT_PERMANENT_TMPFILE "pg_stat/pgstat.tmp" + +/* Default directory to store temporary statistics data in */ +#define PG_STAT_TMP_DIR "pg_stat_tmp" + +/* The types of statistics entries */ +typedef enum PgStat_Kind +{ + /* use 0 for INVALID, to catch zero-initialized data */ + PGSTAT_KIND_INVALID = 0, + + /* stats for variable-numbered objects */ + PGSTAT_KIND_DATABASE, /* database-wide statistics */ + PGSTAT_KIND_RELATION, /* per-table statistics */ + PGSTAT_KIND_FUNCTION, /* per-function statistics */ + PGSTAT_KIND_REPLSLOT, /* per-slot statistics */ + PGSTAT_KIND_SUBSCRIPTION, /* per-subscription statistics */ + + /* stats for fixed-numbered objects */ + PGSTAT_KIND_ARCHIVER, + PGSTAT_KIND_BGWRITER, + PGSTAT_KIND_CHECKPOINTER, + PGSTAT_KIND_IO, + PGSTAT_KIND_SLRU, + PGSTAT_KIND_WAL, +} PgStat_Kind; + +#define PGSTAT_KIND_FIRST_VALID PGSTAT_KIND_DATABASE +#define PGSTAT_KIND_LAST PGSTAT_KIND_WAL +#define PGSTAT_NUM_KINDS (PGSTAT_KIND_LAST + 1) + +/* Values for track_functions GUC variable --- order is significant! */ +typedef enum TrackFunctionsLevel +{ + TRACK_FUNC_OFF, + TRACK_FUNC_PL, + TRACK_FUNC_ALL +} TrackFunctionsLevel; + +typedef enum PgStat_FetchConsistency +{ + PGSTAT_FETCH_CONSISTENCY_NONE, + PGSTAT_FETCH_CONSISTENCY_CACHE, + PGSTAT_FETCH_CONSISTENCY_SNAPSHOT, +} PgStat_FetchConsistency; + +/* Values to track the cause of session termination */ +typedef enum SessionEndType +{ + DISCONNECT_NOT_YET, /* still active */ + DISCONNECT_NORMAL, + DISCONNECT_CLIENT_EOF, + DISCONNECT_FATAL, + DISCONNECT_KILLED +} SessionEndType; + +/* ---------- + * The data type used for counters. + * ---------- + */ +typedef int64 PgStat_Counter; + + +/* ------------------------------------------------------------ + * Structures kept in backend local memory while accumulating counts + * ------------------------------------------------------------ + */ + +/* ---------- + * PgStat_FunctionCounts The actual per-function counts kept by a backend + * + * This struct should contain only actual event counters, because we memcmp + * it against zeroes to detect whether there are any pending stats. + * + * Note that the time counters are in instr_time format here. We convert to + * microseconds in PgStat_Counter format when flushing out pending statistics. + * ---------- + */ +typedef struct PgStat_FunctionCounts +{ + PgStat_Counter numcalls; + instr_time total_time; + instr_time self_time; +} PgStat_FunctionCounts; + +/* + * Working state needed to accumulate per-function-call timing statistics. + */ +typedef struct PgStat_FunctionCallUsage +{ + /* Link to function's hashtable entry (must still be there at exit!) */ + /* NULL means we are not tracking the current function call */ + PgStat_FunctionCounts *fs; + /* Total time previously charged to function, as of function start */ + instr_time save_f_total_time; + /* Backend-wide total time as of function start */ + instr_time save_total; + /* system clock as of function start */ + instr_time start; +} PgStat_FunctionCallUsage; + +/* ---------- + * PgStat_BackendSubEntry Non-flushed subscription stats. + * ---------- + */ +typedef struct PgStat_BackendSubEntry +{ + PgStat_Counter apply_error_count; + PgStat_Counter sync_error_count; +} PgStat_BackendSubEntry; + +/* ---------- + * PgStat_TableCounts The actual per-table counts kept by a backend + * + * This struct should contain only actual event counters, because we memcmp + * it against zeroes to detect whether there are any stats updates to apply. + * It is a component of PgStat_TableStatus (within-backend state). + * + * Note: for a table, tuples_returned is the number of tuples successfully + * fetched by heap_getnext, while tuples_fetched is the number of tuples + * successfully fetched by heap_fetch under the control of bitmap indexscans. + * For an index, tuples_returned is the number of index entries returned by + * the index AM, while tuples_fetched is the number of tuples successfully + * fetched by heap_fetch under the control of simple indexscans for this index. + * + * tuples_inserted/updated/deleted/hot_updated/newpage_updated count attempted + * actions, regardless of whether the transaction committed. delta_live_tuples, + * delta_dead_tuples, and changed_tuples are set depending on commit or abort. + * Note that delta_live_tuples and delta_dead_tuples can be negative! + * ---------- + */ +typedef struct PgStat_TableCounts +{ + PgStat_Counter numscans; + + PgStat_Counter tuples_returned; + PgStat_Counter tuples_fetched; + + PgStat_Counter tuples_inserted; + PgStat_Counter tuples_updated; + PgStat_Counter tuples_deleted; + PgStat_Counter tuples_hot_updated; + PgStat_Counter tuples_newpage_updated; + bool truncdropped; + + PgStat_Counter delta_live_tuples; + PgStat_Counter delta_dead_tuples; + PgStat_Counter changed_tuples; + + PgStat_Counter blocks_fetched; + PgStat_Counter blocks_hit; +} PgStat_TableCounts; + +/* ---------- + * PgStat_TableStatus Per-table status within a backend + * + * Many of the event counters are nontransactional, ie, we count events + * in committed and aborted transactions alike. For these, we just count + * directly in the PgStat_TableStatus. However, delta_live_tuples, + * delta_dead_tuples, and changed_tuples must be derived from event counts + * with awareness of whether the transaction or subtransaction committed or + * aborted. Hence, we also keep a stack of per-(sub)transaction status + * records for every table modified in the current transaction. At commit + * or abort, we propagate tuples_inserted/updated/deleted up to the + * parent subtransaction level, or out to the parent PgStat_TableStatus, + * as appropriate. + * ---------- + */ +typedef struct PgStat_TableStatus +{ + Oid id; /* table's OID */ + bool shared; /* is it a shared catalog? */ + struct PgStat_TableXactStatus *trans; /* lowest subxact's counts */ + PgStat_TableCounts counts; /* event counts to be sent */ + Relation relation; /* rel that is using this entry */ +} PgStat_TableStatus; + +/* ---------- + * PgStat_TableXactStatus Per-table, per-subtransaction status + * ---------- + */ +typedef struct PgStat_TableXactStatus +{ + PgStat_Counter tuples_inserted; /* tuples inserted in (sub)xact */ + PgStat_Counter tuples_updated; /* tuples updated in (sub)xact */ + PgStat_Counter tuples_deleted; /* tuples deleted in (sub)xact */ + bool truncdropped; /* relation truncated/dropped in this + * (sub)xact */ + /* tuples i/u/d prior to truncate/drop */ + PgStat_Counter inserted_pre_truncdrop; + PgStat_Counter updated_pre_truncdrop; + PgStat_Counter deleted_pre_truncdrop; + int nest_level; /* subtransaction nest level */ + /* links to other structs for same relation: */ + struct PgStat_TableXactStatus *upper; /* next higher subxact if any */ + PgStat_TableStatus *parent; /* per-table status */ + /* structs of same subxact level are linked here: */ + struct PgStat_TableXactStatus *next; /* next of same subxact */ +} PgStat_TableXactStatus; + + +/* ------------------------------------------------------------ + * Data structures on disk and in shared memory follow + * + * PGSTAT_FILE_FORMAT_ID should be changed whenever any of these + * data structures change. + * ------------------------------------------------------------ + */ + +#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAC + +typedef struct PgStat_ArchiverStats +{ + PgStat_Counter archived_count; /* archival successes */ + char last_archived_wal[MAX_XFN_CHARS + 1]; /* last WAL file + * archived */ + TimestampTz last_archived_timestamp; /* last archival success time */ + PgStat_Counter failed_count; /* failed archival attempts */ + char last_failed_wal[MAX_XFN_CHARS + 1]; /* WAL file involved in + * last failure */ + TimestampTz last_failed_timestamp; /* last archival failure time */ + TimestampTz stat_reset_timestamp; +} PgStat_ArchiverStats; + +typedef struct PgStat_BgWriterStats +{ + PgStat_Counter buf_written_clean; + PgStat_Counter maxwritten_clean; + PgStat_Counter buf_alloc; + TimestampTz stat_reset_timestamp; +} PgStat_BgWriterStats; + +typedef struct PgStat_CheckpointerStats +{ + PgStat_Counter timed_checkpoints; + PgStat_Counter requested_checkpoints; + PgStat_Counter checkpoint_write_time; /* times in milliseconds */ + PgStat_Counter checkpoint_sync_time; + PgStat_Counter buf_written_checkpoints; + PgStat_Counter buf_written_backend; + PgStat_Counter buf_fsync_backend; +} PgStat_CheckpointerStats; + + +/* + * Types related to counting IO operations + */ +typedef enum IOObject +{ + IOOBJECT_RELATION, + IOOBJECT_TEMP_RELATION, +} IOObject; + +#define IOOBJECT_NUM_TYPES (IOOBJECT_TEMP_RELATION + 1) + +typedef enum IOContext +{ + IOCONTEXT_BULKREAD, + IOCONTEXT_BULKWRITE, + IOCONTEXT_NORMAL, + IOCONTEXT_VACUUM, +} IOContext; + +#define IOCONTEXT_NUM_TYPES (IOCONTEXT_VACUUM + 1) + +typedef enum IOOp +{ + IOOP_EVICT, + IOOP_EXTEND, + IOOP_FSYNC, + IOOP_HIT, + IOOP_READ, + IOOP_REUSE, + IOOP_WRITE, + IOOP_WRITEBACK, +} IOOp; + +#define IOOP_NUM_TYPES (IOOP_WRITEBACK + 1) + +typedef struct PgStat_BktypeIO +{ + PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]; + PgStat_Counter times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]; +} PgStat_BktypeIO; + +typedef struct PgStat_IO +{ + TimestampTz stat_reset_timestamp; + PgStat_BktypeIO stats[BACKEND_NUM_TYPES]; +} PgStat_IO; + + +typedef struct PgStat_StatDBEntry +{ + PgStat_Counter xact_commit; + PgStat_Counter xact_rollback; + PgStat_Counter blocks_fetched; + PgStat_Counter blocks_hit; + PgStat_Counter tuples_returned; + PgStat_Counter tuples_fetched; + PgStat_Counter tuples_inserted; + PgStat_Counter tuples_updated; + PgStat_Counter tuples_deleted; + TimestampTz last_autovac_time; + PgStat_Counter conflict_tablespace; + PgStat_Counter conflict_lock; + PgStat_Counter conflict_snapshot; + PgStat_Counter conflict_logicalslot; + PgStat_Counter conflict_bufferpin; + PgStat_Counter conflict_startup_deadlock; + PgStat_Counter temp_files; + PgStat_Counter temp_bytes; + PgStat_Counter deadlocks; + PgStat_Counter checksum_failures; + TimestampTz last_checksum_failure; + PgStat_Counter blk_read_time; /* times in microseconds */ + PgStat_Counter blk_write_time; + PgStat_Counter sessions; + PgStat_Counter session_time; + PgStat_Counter active_time; + PgStat_Counter idle_in_transaction_time; + PgStat_Counter sessions_abandoned; + PgStat_Counter sessions_fatal; + PgStat_Counter sessions_killed; + + TimestampTz stat_reset_timestamp; +} PgStat_StatDBEntry; + +typedef struct PgStat_StatFuncEntry +{ + PgStat_Counter numcalls; + + PgStat_Counter total_time; /* times in microseconds */ + PgStat_Counter self_time; +} PgStat_StatFuncEntry; + +typedef struct PgStat_StatReplSlotEntry +{ + PgStat_Counter spill_txns; + PgStat_Counter spill_count; + PgStat_Counter spill_bytes; + PgStat_Counter stream_txns; + PgStat_Counter stream_count; + PgStat_Counter stream_bytes; + PgStat_Counter total_txns; + PgStat_Counter total_bytes; + TimestampTz stat_reset_timestamp; +} PgStat_StatReplSlotEntry; + +typedef struct PgStat_SLRUStats +{ + PgStat_Counter blocks_zeroed; + PgStat_Counter blocks_hit; + PgStat_Counter blocks_read; + PgStat_Counter blocks_written; + PgStat_Counter blocks_exists; + PgStat_Counter flush; + PgStat_Counter truncate; + TimestampTz stat_reset_timestamp; +} PgStat_SLRUStats; + +typedef struct PgStat_StatSubEntry +{ + PgStat_Counter apply_error_count; + PgStat_Counter sync_error_count; + TimestampTz stat_reset_timestamp; +} PgStat_StatSubEntry; + +typedef struct PgStat_StatTabEntry +{ + PgStat_Counter numscans; + TimestampTz lastscan; + + PgStat_Counter tuples_returned; + PgStat_Counter tuples_fetched; + + PgStat_Counter tuples_inserted; + PgStat_Counter tuples_updated; + PgStat_Counter tuples_deleted; + PgStat_Counter tuples_hot_updated; + PgStat_Counter tuples_newpage_updated; + + PgStat_Counter live_tuples; + PgStat_Counter dead_tuples; + PgStat_Counter mod_since_analyze; + PgStat_Counter ins_since_vacuum; + + PgStat_Counter blocks_fetched; + PgStat_Counter blocks_hit; + + TimestampTz last_vacuum_time; /* user initiated vacuum */ + PgStat_Counter vacuum_count; + TimestampTz last_autovacuum_time; /* autovacuum initiated */ + PgStat_Counter autovacuum_count; + TimestampTz last_analyze_time; /* user initiated */ + PgStat_Counter analyze_count; + TimestampTz last_autoanalyze_time; /* autovacuum initiated */ + PgStat_Counter autoanalyze_count; +} PgStat_StatTabEntry; + +typedef struct PgStat_WalStats +{ + PgStat_Counter wal_records; + PgStat_Counter wal_fpi; + uint64 wal_bytes; + PgStat_Counter wal_buffers_full; + PgStat_Counter wal_write; + PgStat_Counter wal_sync; + PgStat_Counter wal_write_time; + PgStat_Counter wal_sync_time; + TimestampTz stat_reset_timestamp; +} PgStat_WalStats; + +/* + * This struct stores wal-related durations as instr_time, which makes it + * cheaper and easier to accumulate them, by not requiring type + * conversions. During stats flush instr_time will be converted into + * microseconds. + */ +typedef struct PgStat_PendingWalStats +{ + PgStat_Counter wal_buffers_full; + PgStat_Counter wal_write; + PgStat_Counter wal_sync; + instr_time wal_write_time; + instr_time wal_sync_time; +} PgStat_PendingWalStats; + + +/* + * Functions in pgstat.c + */ + +/* functions called from postmaster */ +extern Size StatsShmemSize(void); +extern void StatsShmemInit(void); + +/* Functions called during server startup / shutdown */ +extern void pgstat_restore_stats(void); +extern void pgstat_discard_stats(void); +extern void pgstat_before_server_shutdown(int code, Datum arg); + +/* Functions for backend initialization */ +extern void pgstat_initialize(void); + +/* Functions called from backends */ +extern long pgstat_report_stat(bool force); +extern void pgstat_force_next_flush(void); + +extern void pgstat_reset_counters(void); +extern void pgstat_reset(PgStat_Kind kind, Oid dboid, Oid objoid); +extern void pgstat_reset_of_kind(PgStat_Kind kind); + +/* stats accessors */ +extern void pgstat_clear_snapshot(void); +extern TimestampTz pgstat_get_stat_snapshot_timestamp(bool *have_snapshot); + +/* helpers */ +extern PgStat_Kind pgstat_get_kind_from_str(char *kind_str); +extern bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, Oid objoid); + + +/* + * Functions in pgstat_archiver.c + */ + +extern void pgstat_report_archiver(const char *xlog, bool failed); +extern PgStat_ArchiverStats *pgstat_fetch_stat_archiver(void); + + +/* + * Functions in pgstat_bgwriter.c + */ + +extern void pgstat_report_bgwriter(void); +extern PgStat_BgWriterStats *pgstat_fetch_stat_bgwriter(void); + + +/* + * Functions in pgstat_checkpointer.c + */ + +extern void pgstat_report_checkpointer(void); +extern PgStat_CheckpointerStats *pgstat_fetch_stat_checkpointer(void); + + +/* + * Functions in pgstat_io.c + */ + +extern bool pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io, + BackendType bktype); +extern void pgstat_count_io_op(IOObject io_object, IOContext io_context, IOOp io_op); +extern void pgstat_count_io_op_n(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt); +extern instr_time pgstat_prepare_io_time(void); +extern void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, + IOOp io_op, instr_time start_time, uint32 cnt); + +extern PgStat_IO *pgstat_fetch_stat_io(void); +extern const char *pgstat_get_io_context_name(IOContext io_context); +extern const char *pgstat_get_io_object_name(IOObject io_object); + +extern bool pgstat_tracks_io_bktype(BackendType bktype); +extern bool pgstat_tracks_io_object(BackendType bktype, + IOObject io_object, IOContext io_context); +extern bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, + IOContext io_context, IOOp io_op); + + +/* + * Functions in pgstat_database.c + */ + +extern void pgstat_drop_database(Oid databaseid); +extern void pgstat_report_autovac(Oid dboid); +extern void pgstat_report_recovery_conflict(int reason); +extern void pgstat_report_deadlock(void); +extern void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount); +extern void pgstat_report_checksum_failure(void); +extern void pgstat_report_connect(Oid dboid); + +#define pgstat_count_buffer_read_time(n) \ + (pgStatBlockReadTime += (n)) +#define pgstat_count_buffer_write_time(n) \ + (pgStatBlockWriteTime += (n)) +#define pgstat_count_conn_active_time(n) \ + (pgStatActiveTime += (n)) +#define pgstat_count_conn_txn_idle_time(n) \ + (pgStatTransactionIdleTime += (n)) + +extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dboid); + + +/* + * Functions in pgstat_function.c + */ + +extern void pgstat_create_function(Oid proid); +extern void pgstat_drop_function(Oid proid); + +struct FunctionCallInfoBaseData; +extern void pgstat_init_function_usage(struct FunctionCallInfoBaseData *fcinfo, + PgStat_FunctionCallUsage *fcu); +extern void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, + bool finalize); + +extern PgStat_StatFuncEntry *pgstat_fetch_stat_funcentry(Oid func_id); +extern PgStat_FunctionCounts *find_funcstat_entry(Oid func_id); + + +/* + * Functions in pgstat_relation.c + */ + +extern void pgstat_create_relation(Relation rel); +extern void pgstat_drop_relation(Relation rel); +extern void pgstat_copy_relation_stats(Relation dst, Relation src); + +extern void pgstat_init_relation(Relation rel); +extern void pgstat_assoc_relation(Relation rel); +extern void pgstat_unlink_relation(Relation rel); + +extern void pgstat_report_vacuum(Oid tableoid, bool shared, + PgStat_Counter livetuples, PgStat_Counter deadtuples); +extern void pgstat_report_analyze(Relation rel, + PgStat_Counter livetuples, PgStat_Counter deadtuples, + bool resetcounter); + +/* + * If stats are enabled, but pending data hasn't been prepared yet, call + * pgstat_assoc_relation() to do so. See its comment for why this is done + * separately from pgstat_init_relation(). + */ +#define pgstat_should_count_relation(rel) \ + (likely((rel)->pgstat_info != NULL) ? true : \ + ((rel)->pgstat_enabled ? pgstat_assoc_relation(rel), true : false)) + +/* nontransactional event counts are simple enough to inline */ + +#define pgstat_count_heap_scan(rel) \ + do { \ + if (pgstat_should_count_relation(rel)) \ + (rel)->pgstat_info->counts.numscans++; \ + } while (0) +#define pgstat_count_heap_getnext(rel) \ + do { \ + if (pgstat_should_count_relation(rel)) \ + (rel)->pgstat_info->counts.tuples_returned++; \ + } while (0) +#define pgstat_count_heap_fetch(rel) \ + do { \ + if (pgstat_should_count_relation(rel)) \ + (rel)->pgstat_info->counts.tuples_fetched++; \ + } while (0) +#define pgstat_count_index_scan(rel) \ + do { \ + if (pgstat_should_count_relation(rel)) \ + (rel)->pgstat_info->counts.numscans++; \ + } while (0) +#define pgstat_count_index_tuples(rel, n) \ + do { \ + if (pgstat_should_count_relation(rel)) \ + (rel)->pgstat_info->counts.tuples_returned += (n); \ + } while (0) +#define pgstat_count_buffer_read(rel) \ + do { \ + if (pgstat_should_count_relation(rel)) \ + (rel)->pgstat_info->counts.blocks_fetched++; \ + } while (0) +#define pgstat_count_buffer_hit(rel) \ + do { \ + if (pgstat_should_count_relation(rel)) \ + (rel)->pgstat_info->counts.blocks_hit++; \ + } while (0) + +extern void pgstat_count_heap_insert(Relation rel, PgStat_Counter n); +extern void pgstat_count_heap_update(Relation rel, bool hot, bool newpage); +extern void pgstat_count_heap_delete(Relation rel); +extern void pgstat_count_truncate(Relation rel); +extern void pgstat_update_heap_dead_tuples(Relation rel, int delta); + +extern void pgstat_twophase_postcommit(TransactionId xid, uint16 info, + void *recdata, uint32 len); +extern void pgstat_twophase_postabort(TransactionId xid, uint16 info, + void *recdata, uint32 len); + +extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid); +extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry_ext(bool shared, + Oid reloid); +extern PgStat_TableStatus *find_tabstat_entry(Oid rel_id); + + +/* + * Functions in pgstat_replslot.c + */ + +extern void pgstat_reset_replslot(const char *name); +struct ReplicationSlot; +extern void pgstat_report_replslot(struct ReplicationSlot *slot, const PgStat_StatReplSlotEntry *repSlotStat); +extern void pgstat_create_replslot(struct ReplicationSlot *slot); +extern void pgstat_acquire_replslot(struct ReplicationSlot *slot); +extern void pgstat_drop_replslot(struct ReplicationSlot *slot); +extern PgStat_StatReplSlotEntry *pgstat_fetch_replslot(NameData slotname); + + +/* + * Functions in pgstat_slru.c + */ + +extern void pgstat_reset_slru(const char *); +extern void pgstat_count_slru_page_zeroed(int slru_idx); +extern void pgstat_count_slru_page_hit(int slru_idx); +extern void pgstat_count_slru_page_read(int slru_idx); +extern void pgstat_count_slru_page_written(int slru_idx); +extern void pgstat_count_slru_page_exists(int slru_idx); +extern void pgstat_count_slru_flush(int slru_idx); +extern void pgstat_count_slru_truncate(int slru_idx); +extern const char *pgstat_get_slru_name(int slru_idx); +extern int pgstat_get_slru_index(const char *name); +extern PgStat_SLRUStats *pgstat_fetch_slru(void); + + +/* + * Functions in pgstat_subscription.c + */ + +extern void pgstat_report_subscription_error(Oid subid, bool is_apply_error); +extern void pgstat_create_subscription(Oid subid); +extern void pgstat_drop_subscription(Oid subid); +extern PgStat_StatSubEntry *pgstat_fetch_stat_subscription(Oid subid); + + +/* + * Functions in pgstat_xact.c + */ + +extern void AtEOXact_PgStat(bool isCommit, bool parallel); +extern void AtEOSubXact_PgStat(bool isCommit, int nestDepth); +extern void AtPrepare_PgStat(void); +extern void PostPrepare_PgStat(void); +struct xl_xact_stats_item; +extern int pgstat_get_transactional_drops(bool isCommit, struct xl_xact_stats_item **items); +extern void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo); + + +/* + * Functions in pgstat_wal.c + */ + +extern void pgstat_report_wal(bool force); +extern PgStat_WalStats *pgstat_fetch_stat_wal(void); + + +/* + * Variables in pgstat.c + */ + +/* GUC parameters */ +extern PGDLLIMPORT bool pgstat_track_counts; +extern PGDLLIMPORT int pgstat_track_functions; +extern PGDLLIMPORT int pgstat_fetch_consistency; + + +/* + * Variables in pgstat_bgwriter.c + */ + +/* updated directly by bgwriter and bufmgr */ +extern PGDLLIMPORT PgStat_BgWriterStats PendingBgWriterStats; + + +/* + * Variables in pgstat_checkpointer.c + */ + +/* + * Checkpointer statistics counters are updated directly by checkpointer and + * bufmgr. + */ +extern PGDLLIMPORT PgStat_CheckpointerStats PendingCheckpointerStats; + + +/* + * Variables in pgstat_database.c + */ + +/* Updated by pgstat_count_buffer_*_time macros */ +extern PGDLLIMPORT PgStat_Counter pgStatBlockReadTime; +extern PGDLLIMPORT PgStat_Counter pgStatBlockWriteTime; + +/* + * Updated by pgstat_count_conn_*_time macros, called by + * pgstat_report_activity(). + */ +extern PGDLLIMPORT PgStat_Counter pgStatActiveTime; +extern PGDLLIMPORT PgStat_Counter pgStatTransactionIdleTime; + +/* updated by the traffic cop and in errfinish() */ +extern PGDLLIMPORT SessionEndType pgStatSessionEndCause; + + +/* + * Variables in pgstat_wal.c + */ + +/* updated directly by backends and background processes */ +extern PGDLLIMPORT PgStat_PendingWalStats PendingWalStats; + + +#endif /* PGSTAT_H */ diff --git a/install/include/postgresql/server/pgtar.h b/install/include/postgresql/server/pgtar.h new file mode 100644 index 00000000000..661f9d7c59f --- /dev/null +++ b/install/include/postgresql/server/pgtar.h @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------- + * + * pgtar.h + * Functions for manipulating tarfile datastructures (src/port/tar.c) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/pgtar.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_TAR_H +#define PG_TAR_H + +#define TAR_BLOCK_SIZE 512 + +enum tarError +{ + TAR_OK = 0, + TAR_NAME_TOO_LONG, + TAR_SYMLINK_TOO_LONG +}; + +extern enum tarError tarCreateHeader(char *h, const char *filename, + const char *linktarget, pgoff_t size, + mode_t mode, uid_t uid, gid_t gid, + time_t mtime); +extern uint64 read_tar_number(const char *s, int len); +extern void print_tar_number(char *s, int len, uint64 val); +extern int tarChecksum(char *header); + +/* + * Compute the number of padding bytes required for an entry in a tar + * archive. We must pad out to a multiple of TAR_BLOCK_SIZE. Since that's + * a power of 2, we can use TYPEALIGN(). + */ +static inline size_t +tarPaddingBytesRequired(size_t len) +{ + return TYPEALIGN(TAR_BLOCK_SIZE, len) - len; +} + +#endif diff --git a/install/include/postgresql/server/pgtime.h b/install/include/postgresql/server/pgtime.h new file mode 100644 index 00000000000..9d4b2efe942 --- /dev/null +++ b/install/include/postgresql/server/pgtime.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------- + * + * pgtime.h + * PostgreSQL internal timezone library + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/pgtime.h + * + *------------------------------------------------------------------------- + */ +#ifndef _PGTIME_H +#define _PGTIME_H + + +/* + * The API of this library is generally similar to the corresponding + * C library functions, except that we use pg_time_t which (we hope) is + * 64 bits wide, and which is most definitely signed not unsigned. + */ + +typedef int64 pg_time_t; + +/* + * Data structure representing a broken-down timestamp. + * + * CAUTION: the IANA timezone library (src/timezone/) follows the POSIX + * convention that tm_mon counts from 0 and tm_year is relative to 1900. + * However, Postgres' datetime functions generally treat tm_mon as counting + * from 1 and tm_year as relative to 1 BC. Be sure to make the appropriate + * adjustments when moving from one code domain to the other. + */ +struct pg_tm +{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; /* see above */ + int tm_year; /* see above */ + int tm_wday; + int tm_yday; + int tm_isdst; + long int tm_gmtoff; + const char *tm_zone; +}; + +/* These structs are opaque outside the timezone library */ +typedef struct pg_tz pg_tz; +typedef struct pg_tzenum pg_tzenum; + +/* Maximum length of a timezone name (not including trailing null) */ +#define TZ_STRLEN_MAX 255 + +/* these functions are in localtime.c */ + +extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz); +extern struct pg_tm *pg_gmtime(const pg_time_t *timep); +extern int pg_next_dst_boundary(const pg_time_t *timep, + long int *before_gmtoff, + int *before_isdst, + pg_time_t *boundary, + long int *after_gmtoff, + int *after_isdst, + const pg_tz *tz); +extern bool pg_interpret_timezone_abbrev(const char *abbrev, + const pg_time_t *timep, + long int *gmtoff, + int *isdst, + const pg_tz *tz); +extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff); +extern const char *pg_get_timezone_name(pg_tz *tz); +extern bool pg_tz_acceptable(pg_tz *tz); + +/* these functions are in strftime.c */ + +extern size_t pg_strftime(char *s, size_t maxsize, const char *format, + const struct pg_tm *t); + +/* these functions and variables are in pgtz.c */ + +extern PGDLLIMPORT pg_tz *session_timezone; +extern PGDLLIMPORT pg_tz *log_timezone; + +extern void pg_timezone_initialize(void); +extern pg_tz *pg_tzset(const char *tzname); +extern pg_tz *pg_tzset_offset(long gmtoffset); + +extern pg_tzenum *pg_tzenumerate_start(void); +extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir); +extern void pg_tzenumerate_end(pg_tzenum *dir); + +#endif /* _PGTIME_H */ diff --git a/install/include/postgresql/server/plpgsql.h b/install/include/postgresql/server/plpgsql.h new file mode 100644 index 00000000000..cead9eb7263 --- /dev/null +++ b/install/include/postgresql/server/plpgsql.h @@ -0,0 +1,1339 @@ +/*------------------------------------------------------------------------- + * + * plpgsql.h - Definitions for the PL/pgSQL + * procedural language + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/pl/plpgsql/src/plpgsql.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PLPGSQL_H +#define PLPGSQL_H + +#include "access/xact.h" +#include "commands/event_trigger.h" +#include "commands/trigger.h" +#include "executor/spi.h" +#include "utils/expandedrecord.h" +#include "utils/typcache.h" + + +/********************************************************************** + * Definitions + **********************************************************************/ + +/* define our text domain for translations */ +#undef TEXTDOMAIN +#define TEXTDOMAIN PG_TEXTDOMAIN("plpgsql") + +#undef _ +#define _(x) dgettext(TEXTDOMAIN, x) + +/* + * Compiler's namespace item types + */ +typedef enum PLpgSQL_nsitem_type +{ + PLPGSQL_NSTYPE_LABEL, /* block label */ + PLPGSQL_NSTYPE_VAR, /* scalar variable */ + PLPGSQL_NSTYPE_REC /* composite variable */ +} PLpgSQL_nsitem_type; + +/* + * A PLPGSQL_NSTYPE_LABEL stack entry must be one of these types + */ +typedef enum PLpgSQL_label_type +{ + PLPGSQL_LABEL_BLOCK, /* DECLARE/BEGIN block */ + PLPGSQL_LABEL_LOOP, /* looping construct */ + PLPGSQL_LABEL_OTHER /* anything else */ +} PLpgSQL_label_type; + +/* + * Datum array node types + */ +typedef enum PLpgSQL_datum_type +{ + PLPGSQL_DTYPE_VAR, + PLPGSQL_DTYPE_ROW, + PLPGSQL_DTYPE_REC, + PLPGSQL_DTYPE_RECFIELD, + PLPGSQL_DTYPE_PROMISE +} PLpgSQL_datum_type; + +/* + * DTYPE_PROMISE datums have these possible ways of computing the promise + */ +typedef enum PLpgSQL_promise_type +{ + PLPGSQL_PROMISE_NONE = 0, /* not a promise, or promise satisfied */ + PLPGSQL_PROMISE_TG_NAME, + PLPGSQL_PROMISE_TG_WHEN, + PLPGSQL_PROMISE_TG_LEVEL, + PLPGSQL_PROMISE_TG_OP, + PLPGSQL_PROMISE_TG_RELID, + PLPGSQL_PROMISE_TG_TABLE_NAME, + PLPGSQL_PROMISE_TG_TABLE_SCHEMA, + PLPGSQL_PROMISE_TG_NARGS, + PLPGSQL_PROMISE_TG_ARGV, + PLPGSQL_PROMISE_TG_EVENT, + PLPGSQL_PROMISE_TG_TAG +} PLpgSQL_promise_type; + +/* + * Variants distinguished in PLpgSQL_type structs + */ +typedef enum PLpgSQL_type_type +{ + PLPGSQL_TTYPE_SCALAR, /* scalar types and domains */ + PLPGSQL_TTYPE_REC, /* composite types, including RECORD */ + PLPGSQL_TTYPE_PSEUDO /* pseudotypes */ +} PLpgSQL_type_type; + +/* + * Execution tree node types + */ +typedef enum PLpgSQL_stmt_type +{ + PLPGSQL_STMT_BLOCK, + PLPGSQL_STMT_ASSIGN, + PLPGSQL_STMT_IF, + PLPGSQL_STMT_CASE, + PLPGSQL_STMT_LOOP, + PLPGSQL_STMT_WHILE, + PLPGSQL_STMT_FORI, + PLPGSQL_STMT_FORS, + PLPGSQL_STMT_FORC, + PLPGSQL_STMT_FOREACH_A, + PLPGSQL_STMT_EXIT, + PLPGSQL_STMT_RETURN, + PLPGSQL_STMT_RETURN_NEXT, + PLPGSQL_STMT_RETURN_QUERY, + PLPGSQL_STMT_RAISE, + PLPGSQL_STMT_ASSERT, + PLPGSQL_STMT_EXECSQL, + PLPGSQL_STMT_DYNEXECUTE, + PLPGSQL_STMT_DYNFORS, + PLPGSQL_STMT_GETDIAG, + PLPGSQL_STMT_OPEN, + PLPGSQL_STMT_FETCH, + PLPGSQL_STMT_CLOSE, + PLPGSQL_STMT_PERFORM, + PLPGSQL_STMT_CALL, + PLPGSQL_STMT_COMMIT, + PLPGSQL_STMT_ROLLBACK +} PLpgSQL_stmt_type; + +/* + * Execution node return codes + */ +enum +{ + PLPGSQL_RC_OK, + PLPGSQL_RC_EXIT, + PLPGSQL_RC_RETURN, + PLPGSQL_RC_CONTINUE +}; + +/* + * GET DIAGNOSTICS information items + */ +typedef enum PLpgSQL_getdiag_kind +{ + PLPGSQL_GETDIAG_ROW_COUNT, + PLPGSQL_GETDIAG_ROUTINE_OID, + PLPGSQL_GETDIAG_CONTEXT, + PLPGSQL_GETDIAG_ERROR_CONTEXT, + PLPGSQL_GETDIAG_ERROR_DETAIL, + PLPGSQL_GETDIAG_ERROR_HINT, + PLPGSQL_GETDIAG_RETURNED_SQLSTATE, + PLPGSQL_GETDIAG_COLUMN_NAME, + PLPGSQL_GETDIAG_CONSTRAINT_NAME, + PLPGSQL_GETDIAG_DATATYPE_NAME, + PLPGSQL_GETDIAG_MESSAGE_TEXT, + PLPGSQL_GETDIAG_TABLE_NAME, + PLPGSQL_GETDIAG_SCHEMA_NAME +} PLpgSQL_getdiag_kind; + +/* + * RAISE statement options + */ +typedef enum PLpgSQL_raise_option_type +{ + PLPGSQL_RAISEOPTION_ERRCODE, + PLPGSQL_RAISEOPTION_MESSAGE, + PLPGSQL_RAISEOPTION_DETAIL, + PLPGSQL_RAISEOPTION_HINT, + PLPGSQL_RAISEOPTION_COLUMN, + PLPGSQL_RAISEOPTION_CONSTRAINT, + PLPGSQL_RAISEOPTION_DATATYPE, + PLPGSQL_RAISEOPTION_TABLE, + PLPGSQL_RAISEOPTION_SCHEMA +} PLpgSQL_raise_option_type; + +/* + * Behavioral modes for plpgsql variable resolution + */ +typedef enum PLpgSQL_resolve_option +{ + PLPGSQL_RESOLVE_ERROR, /* throw error if ambiguous */ + PLPGSQL_RESOLVE_VARIABLE, /* prefer plpgsql var to table column */ + PLPGSQL_RESOLVE_COLUMN /* prefer table column to plpgsql var */ +} PLpgSQL_resolve_option; + + +/********************************************************************** + * Node and structure definitions + **********************************************************************/ + +/* + * Postgres data type + */ +typedef struct PLpgSQL_type +{ + char *typname; /* (simple) name of the type */ + Oid typoid; /* OID of the data type */ + PLpgSQL_type_type ttype; /* PLPGSQL_TTYPE_ code */ + int16 typlen; /* stuff copied from its pg_type entry */ + bool typbyval; + char typtype; + Oid collation; /* from pg_type, but can be overridden */ + bool typisarray; /* is "true" array, or domain over one */ + int32 atttypmod; /* typmod (taken from someplace else) */ + /* Remaining fields are used only for named composite types (not RECORD) */ + TypeName *origtypname; /* type name as written by user */ + TypeCacheEntry *tcache; /* typcache entry for composite type */ + uint64 tupdesc_id; /* last-seen tupdesc identifier */ +} PLpgSQL_type; + +/* + * SQL Query to plan and execute + */ +typedef struct PLpgSQL_expr +{ + char *query; /* query string, verbatim from function body */ + RawParseMode parseMode; /* raw_parser() mode to use */ + SPIPlanPtr plan; /* plan, or NULL if not made yet */ + Bitmapset *paramnos; /* all dnos referenced by this query */ + + /* function containing this expr (not set until we first parse query) */ + struct PLpgSQL_function *func; + + /* namespace chain visible to this expr */ + struct PLpgSQL_nsitem *ns; + + /* fields for "simple expression" fast-path execution: */ + Expr *expr_simple_expr; /* NULL means not a simple expr */ + Oid expr_simple_type; /* result type Oid, if simple */ + int32 expr_simple_typmod; /* result typmod, if simple */ + bool expr_simple_mutable; /* true if simple expr is mutable */ + + /* + * These fields are used to optimize assignments to expanded-datum + * variables. If this expression is the source of an assignment to a + * simple variable, target_param holds that variable's dno; else it's -1. + * If we match a Param within expr_simple_expr to such a variable, that + * Param's address is stored in expr_rw_param; then expression code + * generation will allow the value for that Param to be passed read/write. + */ + int target_param; /* dno of assign target, or -1 if none */ + Param *expr_rw_param; /* read/write Param within expr, if any */ + + /* + * If the expression was ever determined to be simple, we remember its + * CachedPlanSource and CachedPlan here. If expr_simple_plan_lxid matches + * current LXID, then we hold a refcount on expr_simple_plan in the + * current transaction. Otherwise we need to get one before re-using it. + */ + CachedPlanSource *expr_simple_plansource; /* extracted from "plan" */ + CachedPlan *expr_simple_plan; /* extracted from "plan" */ + LocalTransactionId expr_simple_plan_lxid; + + /* + * if expr is simple AND prepared in current transaction, + * expr_simple_state and expr_simple_in_use are valid. Test validity by + * seeing if expr_simple_lxid matches current LXID. (If not, + * expr_simple_state probably points at garbage!) + */ + ExprState *expr_simple_state; /* eval tree for expr_simple_expr */ + bool expr_simple_in_use; /* true if eval tree is active */ + LocalTransactionId expr_simple_lxid; +} PLpgSQL_expr; + +/* + * Generic datum array item + * + * PLpgSQL_datum is the common supertype for PLpgSQL_var, PLpgSQL_row, + * PLpgSQL_rec, and PLpgSQL_recfield. + */ +typedef struct PLpgSQL_datum +{ + PLpgSQL_datum_type dtype; + int dno; +} PLpgSQL_datum; + +/* + * Scalar or composite variable + * + * The variants PLpgSQL_var, PLpgSQL_row, and PLpgSQL_rec share these + * fields. + */ +typedef struct PLpgSQL_variable +{ + PLpgSQL_datum_type dtype; + int dno; + char *refname; + int lineno; + bool isconst; + bool notnull; + PLpgSQL_expr *default_val; +} PLpgSQL_variable; + +/* + * Scalar variable + * + * DTYPE_VAR and DTYPE_PROMISE datums both use this struct type. + * A PROMISE datum works exactly like a VAR datum for most purposes, + * but if it is read without having previously been assigned to, then + * a special "promised" value is computed and assigned to the datum + * before the read is performed. This technique avoids the overhead of + * computing the variable's value in cases where we expect that many + * functions will never read it. + */ +typedef struct PLpgSQL_var +{ + PLpgSQL_datum_type dtype; + int dno; + char *refname; + int lineno; + bool isconst; + bool notnull; + PLpgSQL_expr *default_val; + /* end of PLpgSQL_variable fields */ + + PLpgSQL_type *datatype; + + /* + * Variables declared as CURSOR FOR are mostly like ordinary + * scalar variables of type refcursor, but they have these additional + * properties: + */ + PLpgSQL_expr *cursor_explicit_expr; + int cursor_explicit_argrow; + int cursor_options; + + /* Fields below here can change at runtime */ + + Datum value; + bool isnull; + bool freeval; + + /* + * The promise field records which "promised" value to assign if the + * promise must be honored. If it's a normal variable, or the promise has + * been fulfilled, this is PLPGSQL_PROMISE_NONE. + */ + PLpgSQL_promise_type promise; +} PLpgSQL_var; + +/* + * Row variable - this represents one or more variables that are listed in an + * INTO clause, FOR-loop targetlist, cursor argument list, etc. We also use + * a row to represent a function's OUT parameters when there's more than one. + * + * Note that there's no way to name the row as such from PL/pgSQL code, + * so many functions don't need to support these. + * + * That also means that there's no real name for the row variable, so we + * conventionally set refname to "(unnamed row)". We could leave it NULL, + * but it's too convenient to be able to assume that refname is valid in + * all variants of PLpgSQL_variable. + * + * isconst, notnull, and default_val are unsupported (and hence + * always zero/null) for a row. The member variables of a row should have + * been checked to be writable at compile time, so isconst is correctly set + * to false. notnull and default_val aren't applicable. + */ +typedef struct PLpgSQL_row +{ + PLpgSQL_datum_type dtype; + int dno; + char *refname; + int lineno; + bool isconst; + bool notnull; + PLpgSQL_expr *default_val; + /* end of PLpgSQL_variable fields */ + + /* + * rowtupdesc is only set up if we might need to convert the row into a + * composite datum, which currently only happens for OUT parameters. + * Otherwise it is NULL. + */ + TupleDesc rowtupdesc; + + int nfields; + char **fieldnames; + int *varnos; +} PLpgSQL_row; + +/* + * Record variable (any composite type, including RECORD) + */ +typedef struct PLpgSQL_rec +{ + PLpgSQL_datum_type dtype; + int dno; + char *refname; + int lineno; + bool isconst; + bool notnull; + PLpgSQL_expr *default_val; + /* end of PLpgSQL_variable fields */ + + /* + * Note: for non-RECORD cases, we may from time to time re-look-up the + * composite type, using datatype->origtypname. That can result in + * changing rectypeid. + */ + + PLpgSQL_type *datatype; /* can be NULL, if rectypeid is RECORDOID */ + Oid rectypeid; /* declared type of variable */ + /* RECFIELDs for this record are chained together for easy access */ + int firstfield; /* dno of first RECFIELD, or -1 if none */ + + /* Fields below here can change at runtime */ + + /* We always store record variables as "expanded" records */ + ExpandedRecordHeader *erh; +} PLpgSQL_rec; + +/* + * Field in record + */ +typedef struct PLpgSQL_recfield +{ + PLpgSQL_datum_type dtype; + int dno; + /* end of PLpgSQL_datum fields */ + + char *fieldname; /* name of field */ + int recparentno; /* dno of parent record */ + int nextfield; /* dno of next child, or -1 if none */ + uint64 rectupledescid; /* record's tupledesc ID as of last lookup */ + ExpandedRecordFieldInfo finfo; /* field's attnum and type info */ + /* if rectupledescid == INVALID_TUPLEDESC_IDENTIFIER, finfo isn't valid */ +} PLpgSQL_recfield; + +/* + * Item in the compilers namespace tree + */ +typedef struct PLpgSQL_nsitem +{ + PLpgSQL_nsitem_type itemtype; + + /* + * For labels, itemno is a value of enum PLpgSQL_label_type. For other + * itemtypes, itemno is the associated PLpgSQL_datum's dno. + */ + int itemno; + struct PLpgSQL_nsitem *prev; + char name[FLEXIBLE_ARRAY_MEMBER]; /* nul-terminated string */ +} PLpgSQL_nsitem; + +/* + * Generic execution node + */ +typedef struct PLpgSQL_stmt +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + + /* + * Unique statement ID in this function (starting at 1; 0 is invalid/not + * set). This can be used by a profiler as the index for an array of + * per-statement metrics. + */ + unsigned int stmtid; +} PLpgSQL_stmt; + +/* + * One EXCEPTION condition name + */ +typedef struct PLpgSQL_condition +{ + int sqlerrstate; /* SQLSTATE code */ + char *condname; /* condition name (for debugging) */ + struct PLpgSQL_condition *next; +} PLpgSQL_condition; + +/* + * EXCEPTION block + */ +typedef struct PLpgSQL_exception_block +{ + int sqlstate_varno; + int sqlerrm_varno; + List *exc_list; /* List of WHEN clauses */ +} PLpgSQL_exception_block; + +/* + * One EXCEPTION ... WHEN clause + */ +typedef struct PLpgSQL_exception +{ + int lineno; + PLpgSQL_condition *conditions; + List *action; /* List of statements */ +} PLpgSQL_exception; + +/* + * Block of statements + */ +typedef struct PLpgSQL_stmt_block +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + List *body; /* List of statements */ + int n_initvars; /* Length of initvarnos[] */ + int *initvarnos; /* dnos of variables declared in this block */ + PLpgSQL_exception_block *exceptions; +} PLpgSQL_stmt_block; + +/* + * Assign statement + */ +typedef struct PLpgSQL_stmt_assign +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + int varno; + PLpgSQL_expr *expr; +} PLpgSQL_stmt_assign; + +/* + * PERFORM statement + */ +typedef struct PLpgSQL_stmt_perform +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *expr; +} PLpgSQL_stmt_perform; + +/* + * CALL statement + */ +typedef struct PLpgSQL_stmt_call +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *expr; + bool is_call; + PLpgSQL_variable *target; +} PLpgSQL_stmt_call; + +/* + * COMMIT statement + */ +typedef struct PLpgSQL_stmt_commit +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + bool chain; +} PLpgSQL_stmt_commit; + +/* + * ROLLBACK statement + */ +typedef struct PLpgSQL_stmt_rollback +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + bool chain; +} PLpgSQL_stmt_rollback; + +/* + * GET DIAGNOSTICS item + */ +typedef struct PLpgSQL_diag_item +{ + PLpgSQL_getdiag_kind kind; /* id for diagnostic value desired */ + int target; /* where to assign it */ +} PLpgSQL_diag_item; + +/* + * GET DIAGNOSTICS statement + */ +typedef struct PLpgSQL_stmt_getdiag +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + bool is_stacked; /* STACKED or CURRENT diagnostics area? */ + List *diag_items; /* List of PLpgSQL_diag_item */ +} PLpgSQL_stmt_getdiag; + +/* + * IF statement + */ +typedef struct PLpgSQL_stmt_if +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *cond; /* boolean expression for THEN */ + List *then_body; /* List of statements */ + List *elsif_list; /* List of PLpgSQL_if_elsif structs */ + List *else_body; /* List of statements */ +} PLpgSQL_stmt_if; + +/* + * one ELSIF arm of IF statement + */ +typedef struct PLpgSQL_if_elsif +{ + int lineno; + PLpgSQL_expr *cond; /* boolean expression for this case */ + List *stmts; /* List of statements */ +} PLpgSQL_if_elsif; + +/* + * CASE statement + */ +typedef struct PLpgSQL_stmt_case +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *t_expr; /* test expression, or NULL if none */ + int t_varno; /* var to store test expression value into */ + List *case_when_list; /* List of PLpgSQL_case_when structs */ + bool have_else; /* flag needed because list could be empty */ + List *else_stmts; /* List of statements */ +} PLpgSQL_stmt_case; + +/* + * one arm of CASE statement + */ +typedef struct PLpgSQL_case_when +{ + int lineno; + PLpgSQL_expr *expr; /* boolean expression for this case */ + List *stmts; /* List of statements */ +} PLpgSQL_case_when; + +/* + * Unconditional LOOP statement + */ +typedef struct PLpgSQL_stmt_loop +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + List *body; /* List of statements */ +} PLpgSQL_stmt_loop; + +/* + * WHILE cond LOOP statement + */ +typedef struct PLpgSQL_stmt_while +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + PLpgSQL_expr *cond; + List *body; /* List of statements */ +} PLpgSQL_stmt_while; + +/* + * FOR statement with integer loopvar + */ +typedef struct PLpgSQL_stmt_fori +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + PLpgSQL_var *var; + PLpgSQL_expr *lower; + PLpgSQL_expr *upper; + PLpgSQL_expr *step; /* NULL means default (ie, BY 1) */ + int reverse; + List *body; /* List of statements */ +} PLpgSQL_stmt_fori; + +/* + * PLpgSQL_stmt_forq represents a FOR statement running over a SQL query. + * It is the common supertype of PLpgSQL_stmt_fors, PLpgSQL_stmt_forc + * and PLpgSQL_stmt_dynfors. + */ +typedef struct PLpgSQL_stmt_forq +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + PLpgSQL_variable *var; /* Loop variable (record or row) */ + List *body; /* List of statements */ +} PLpgSQL_stmt_forq; + +/* + * FOR statement running over SELECT + */ +typedef struct PLpgSQL_stmt_fors +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + PLpgSQL_variable *var; /* Loop variable (record or row) */ + List *body; /* List of statements */ + /* end of fields that must match PLpgSQL_stmt_forq */ + PLpgSQL_expr *query; +} PLpgSQL_stmt_fors; + +/* + * FOR statement running over cursor + */ +typedef struct PLpgSQL_stmt_forc +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + PLpgSQL_variable *var; /* Loop variable (record or row) */ + List *body; /* List of statements */ + /* end of fields that must match PLpgSQL_stmt_forq */ + int curvar; + PLpgSQL_expr *argquery; /* cursor arguments if any */ +} PLpgSQL_stmt_forc; + +/* + * FOR statement running over EXECUTE + */ +typedef struct PLpgSQL_stmt_dynfors +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + PLpgSQL_variable *var; /* Loop variable (record or row) */ + List *body; /* List of statements */ + /* end of fields that must match PLpgSQL_stmt_forq */ + PLpgSQL_expr *query; + List *params; /* USING expressions */ +} PLpgSQL_stmt_dynfors; + +/* + * FOREACH item in array loop + */ +typedef struct PLpgSQL_stmt_foreach_a +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + char *label; + int varno; /* loop target variable */ + int slice; /* slice dimension, or 0 */ + PLpgSQL_expr *expr; /* array expression */ + List *body; /* List of statements */ +} PLpgSQL_stmt_foreach_a; + +/* + * OPEN a curvar + */ +typedef struct PLpgSQL_stmt_open +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + int curvar; + int cursor_options; + PLpgSQL_expr *argquery; + PLpgSQL_expr *query; + PLpgSQL_expr *dynquery; + List *params; /* USING expressions */ +} PLpgSQL_stmt_open; + +/* + * FETCH or MOVE statement + */ +typedef struct PLpgSQL_stmt_fetch +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_variable *target; /* target (record or row) */ + int curvar; /* cursor variable to fetch from */ + FetchDirection direction; /* fetch direction */ + long how_many; /* count, if constant (expr is NULL) */ + PLpgSQL_expr *expr; /* count, if expression */ + bool is_move; /* is this a fetch or move? */ + bool returns_multiple_rows; /* can return more than one row? */ +} PLpgSQL_stmt_fetch; + +/* + * CLOSE curvar + */ +typedef struct PLpgSQL_stmt_close +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + int curvar; +} PLpgSQL_stmt_close; + +/* + * EXIT or CONTINUE statement + */ +typedef struct PLpgSQL_stmt_exit +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + bool is_exit; /* Is this an exit or a continue? */ + char *label; /* NULL if it's an unlabeled EXIT/CONTINUE */ + PLpgSQL_expr *cond; +} PLpgSQL_stmt_exit; + +/* + * RETURN statement + */ +typedef struct PLpgSQL_stmt_return +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *expr; + int retvarno; +} PLpgSQL_stmt_return; + +/* + * RETURN NEXT statement + */ +typedef struct PLpgSQL_stmt_return_next +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *expr; + int retvarno; +} PLpgSQL_stmt_return_next; + +/* + * RETURN QUERY statement + */ +typedef struct PLpgSQL_stmt_return_query +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *query; /* if static query */ + PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */ + List *params; /* USING arguments for dynamic query */ +} PLpgSQL_stmt_return_query; + +/* + * RAISE statement + */ +typedef struct PLpgSQL_stmt_raise +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + int elog_level; + char *condname; /* condition name, SQLSTATE, or NULL */ + char *message; /* old-style message format literal, or NULL */ + List *params; /* list of expressions for old-style message */ + List *options; /* list of PLpgSQL_raise_option */ +} PLpgSQL_stmt_raise; + +/* + * RAISE statement option + */ +typedef struct PLpgSQL_raise_option +{ + PLpgSQL_raise_option_type opt_type; + PLpgSQL_expr *expr; +} PLpgSQL_raise_option; + +/* + * ASSERT statement + */ +typedef struct PLpgSQL_stmt_assert +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *cond; + PLpgSQL_expr *message; +} PLpgSQL_stmt_assert; + +/* + * Generic SQL statement to execute + */ +typedef struct PLpgSQL_stmt_execsql +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *sqlstmt; + bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE/MERGE? */ + bool mod_stmt_set; /* is mod_stmt valid yet? */ + bool into; /* INTO supplied? */ + bool strict; /* INTO STRICT flag */ + PLpgSQL_variable *target; /* INTO target (record or row) */ +} PLpgSQL_stmt_execsql; + +/* + * Dynamic SQL string to execute + */ +typedef struct PLpgSQL_stmt_dynexecute +{ + PLpgSQL_stmt_type cmd_type; + int lineno; + unsigned int stmtid; + PLpgSQL_expr *query; /* string expression */ + bool into; /* INTO supplied? */ + bool strict; /* INTO STRICT flag */ + PLpgSQL_variable *target; /* INTO target (record or row) */ + List *params; /* USING expressions */ +} PLpgSQL_stmt_dynexecute; + +/* + * Hash lookup key for functions + */ +typedef struct PLpgSQL_func_hashkey +{ + Oid funcOid; + + bool isTrigger; /* true if called as a DML trigger */ + bool isEventTrigger; /* true if called as an event trigger */ + + /* be careful that pad bytes in this struct get zeroed! */ + + /* + * For a trigger function, the OID of the trigger is part of the hash key + * --- we want to compile the trigger function separately for each trigger + * it is used with, in case the rowtype or transition table names are + * different. Zero if not called as a DML trigger. + */ + Oid trigOid; + + /* + * We must include the input collation as part of the hash key too, + * because we have to generate different plans (with different Param + * collations) for different collation settings. + */ + Oid inputCollation; + + /* + * We include actual argument types in the hash key to support polymorphic + * PLpgSQL functions. Be careful that extra positions are zeroed! + */ + Oid argtypes[FUNC_MAX_ARGS]; +} PLpgSQL_func_hashkey; + +/* + * Trigger type + */ +typedef enum PLpgSQL_trigtype +{ + PLPGSQL_DML_TRIGGER, + PLPGSQL_EVENT_TRIGGER, + PLPGSQL_NOT_TRIGGER +} PLpgSQL_trigtype; + +/* + * Complete compiled function + */ +typedef struct PLpgSQL_function +{ + char *fn_signature; + Oid fn_oid; + TransactionId fn_xmin; + ItemPointerData fn_tid; + PLpgSQL_trigtype fn_is_trigger; + Oid fn_input_collation; + PLpgSQL_func_hashkey *fn_hashkey; /* back-link to hashtable key */ + MemoryContext fn_cxt; + + Oid fn_rettype; + int fn_rettyplen; + bool fn_retbyval; + bool fn_retistuple; + bool fn_retisdomain; + bool fn_retset; + bool fn_readonly; + char fn_prokind; + + int fn_nargs; + int fn_argvarnos[FUNC_MAX_ARGS]; + int out_param_varno; + int found_varno; + int new_varno; + int old_varno; + + PLpgSQL_resolve_option resolve_option; + + bool print_strict_params; + + /* extra checks */ + int extra_warnings; + int extra_errors; + + /* the datums representing the function's local variables */ + int ndatums; + PLpgSQL_datum **datums; + Size copiable_size; /* space for locally instantiated datums */ + + /* function body parsetree */ + PLpgSQL_stmt_block *action; + + /* data derived while parsing body */ + unsigned int nstatements; /* counter for assigning stmtids */ + bool requires_procedure_resowner; /* contains CALL or DO? */ + + /* these fields change when the function is used */ + struct PLpgSQL_execstate *cur_estate; + unsigned long use_count; +} PLpgSQL_function; + +/* + * Runtime execution data + */ +typedef struct PLpgSQL_execstate +{ + PLpgSQL_function *func; /* function being executed */ + + TriggerData *trigdata; /* if regular trigger, data about firing */ + EventTriggerData *evtrigdata; /* if event trigger, data about firing */ + + Datum retval; + bool retisnull; + Oid rettype; /* type of current retval */ + + Oid fn_rettype; /* info about declared function rettype */ + bool retistuple; + bool retisset; + + bool readonly_func; + bool atomic; + + char *exitlabel; /* the "target" label of the current EXIT or + * CONTINUE stmt, if any */ + ErrorData *cur_error; /* current exception handler's error */ + + Tuplestorestate *tuple_store; /* SRFs accumulate results here */ + TupleDesc tuple_store_desc; /* descriptor for tuples in tuple_store */ + MemoryContext tuple_store_cxt; + ResourceOwner tuple_store_owner; + ReturnSetInfo *rsi; + + int found_varno; + + /* + * The datums representing the function's local variables. Some of these + * are local storage in this execstate, but some just point to the shared + * copy belonging to the PLpgSQL_function, depending on whether or not we + * need any per-execution state for the datum's dtype. + */ + int ndatums; + PLpgSQL_datum **datums; + /* context containing variable values (same as func's SPI_proc context) */ + MemoryContext datum_context; + + /* + * paramLI is what we use to pass local variable values to the executor. + * It does not have a ParamExternData array; we just dynamically + * instantiate parameter data as needed. By convention, PARAM_EXTERN + * Params have paramid equal to the dno of the referenced local variable. + */ + ParamListInfo paramLI; + + /* EState and resowner to use for "simple" expression evaluation */ + EState *simple_eval_estate; + ResourceOwner simple_eval_resowner; + + /* if running nonatomic procedure or DO block, resowner to use for CALL */ + ResourceOwner procedure_resowner; + + /* lookup table to use for executing type casts */ + HTAB *cast_hash; + + /* memory context for statement-lifespan temporary values */ + MemoryContext stmt_mcontext; /* current stmt context, or NULL if none */ + MemoryContext stmt_mcontext_parent; /* parent of current context */ + + /* temporary state for results from evaluation of query or expr */ + SPITupleTable *eval_tuptable; + uint64 eval_processed; + ExprContext *eval_econtext; /* for executing simple expressions */ + + /* status information for error context reporting */ + PLpgSQL_stmt *err_stmt; /* current stmt */ + PLpgSQL_variable *err_var; /* current variable, if in a DECLARE section */ + const char *err_text; /* additional state info */ + + void *plugin_info; /* reserved for use by optional plugin */ +} PLpgSQL_execstate; + +/* + * A PLpgSQL_plugin structure represents an instrumentation plugin. + * To instrument PL/pgSQL, a plugin library must access the rendezvous + * variable "PLpgSQL_plugin" and set it to point to a PLpgSQL_plugin struct. + * Typically the struct could just be static data in the plugin library. + * We expect that a plugin would do this at library load time (_PG_init()). + * + * This structure is basically a collection of function pointers --- at + * various interesting points in pl_exec.c, we call these functions + * (if the pointers are non-NULL) to give the plugin a chance to watch + * what we are doing. + * + * func_setup is called when we start a function, before we've initialized + * the local variables defined by the function. + * + * func_beg is called when we start a function, after we've initialized + * the local variables. + * + * func_end is called at the end of a function. + * + * stmt_beg and stmt_end are called before and after (respectively) each + * statement. + * + * Also, immediately before any call to func_setup, PL/pgSQL fills in the + * remaining fields with pointers to some of its own functions, allowing the + * plugin to invoke those functions conveniently. The exposed functions are: + * plpgsql_exec_error_callback + * exec_assign_expr + * exec_assign_value + * exec_eval_datum + * exec_cast_value + * (plpgsql_exec_error_callback is not actually meant to be called by the + * plugin, but rather to allow it to identify PL/pgSQL error context stack + * frames. The others are useful for debugger-like plugins to examine and + * set variables.) + */ +typedef struct PLpgSQL_plugin +{ + /* Function pointers set up by the plugin */ + void (*func_setup) (PLpgSQL_execstate *estate, PLpgSQL_function *func); + void (*func_beg) (PLpgSQL_execstate *estate, PLpgSQL_function *func); + void (*func_end) (PLpgSQL_execstate *estate, PLpgSQL_function *func); + void (*stmt_beg) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt); + void (*stmt_end) (PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt); + + /* Function pointers set by PL/pgSQL itself */ + void (*error_callback) (void *arg); + void (*assign_expr) (PLpgSQL_execstate *estate, + PLpgSQL_datum *target, + PLpgSQL_expr *expr); + void (*assign_value) (PLpgSQL_execstate *estate, + PLpgSQL_datum *target, + Datum value, bool isNull, + Oid valtype, int32 valtypmod); + void (*eval_datum) (PLpgSQL_execstate *estate, PLpgSQL_datum *datum, + Oid *typeId, int32 *typetypmod, + Datum *value, bool *isnull); + Datum (*cast_value) (PLpgSQL_execstate *estate, + Datum value, bool *isnull, + Oid valtype, int32 valtypmod, + Oid reqtype, int32 reqtypmod); +} PLpgSQL_plugin; + +/* + * Struct types used during parsing + */ + +typedef struct PLword +{ + char *ident; /* palloc'd converted identifier */ + bool quoted; /* Was it double-quoted? */ +} PLword; + +typedef struct PLcword +{ + List *idents; /* composite identifiers (list of String) */ +} PLcword; + +typedef struct PLwdatum +{ + PLpgSQL_datum *datum; /* referenced variable */ + char *ident; /* valid if simple name */ + bool quoted; + List *idents; /* valid if composite name */ +} PLwdatum; + +/********************************************************************** + * Global variable declarations + **********************************************************************/ + +typedef enum +{ + IDENTIFIER_LOOKUP_NORMAL, /* normal processing of var names */ + IDENTIFIER_LOOKUP_DECLARE, /* In DECLARE --- don't look up names */ + IDENTIFIER_LOOKUP_EXPR /* In SQL expression --- special case */ +} IdentifierLookup; + +extern IdentifierLookup plpgsql_IdentifierLookup; + +extern int plpgsql_variable_conflict; + +extern bool plpgsql_print_strict_params; + +extern bool plpgsql_check_asserts; + +/* extra compile-time and run-time checks */ +#define PLPGSQL_XCHECK_NONE 0 +#define PLPGSQL_XCHECK_SHADOWVAR (1 << 1) +#define PLPGSQL_XCHECK_TOOMANYROWS (1 << 2) +#define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT (1 << 3) +#define PLPGSQL_XCHECK_ALL ((int) ~0) + +extern int plpgsql_extra_warnings; +extern int plpgsql_extra_errors; + +extern bool plpgsql_check_syntax; +extern bool plpgsql_DumpExecTree; + +extern PLpgSQL_stmt_block *plpgsql_parse_result; + +extern int plpgsql_nDatums; +extern PLpgSQL_datum **plpgsql_Datums; + +extern char *plpgsql_error_funcname; + +extern PLpgSQL_function *plpgsql_curr_compile; +extern MemoryContext plpgsql_compile_tmp_cxt; + +extern PLpgSQL_plugin **plpgsql_plugin_ptr; + +/********************************************************************** + * Function declarations + **********************************************************************/ + +/* + * Functions in pl_comp.c + */ +extern PGDLLEXPORT PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo, + bool forValidator); +extern PLpgSQL_function *plpgsql_compile_inline(char *proc_source); +extern PGDLLEXPORT void plpgsql_parser_setup(struct ParseState *pstate, + PLpgSQL_expr *expr); +extern bool plpgsql_parse_word(char *word1, const char *yytxt, bool lookup, + PLwdatum *wdatum, PLword *word); +extern bool plpgsql_parse_dblword(char *word1, char *word2, + PLwdatum *wdatum, PLcword *cword); +extern bool plpgsql_parse_tripword(char *word1, char *word2, char *word3, + PLwdatum *wdatum, PLcword *cword); +extern PLpgSQL_type *plpgsql_parse_wordtype(char *ident); +extern PLpgSQL_type *plpgsql_parse_cwordtype(List *idents); +extern PLpgSQL_type *plpgsql_parse_wordrowtype(char *ident); +extern PLpgSQL_type *plpgsql_parse_cwordrowtype(List *idents); +extern PGDLLEXPORT PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod, + Oid collation, + TypeName *origtypname); +extern PLpgSQL_variable *plpgsql_build_variable(const char *refname, int lineno, + PLpgSQL_type *dtype, + bool add2namespace); +extern PLpgSQL_rec *plpgsql_build_record(const char *refname, int lineno, + PLpgSQL_type *dtype, Oid rectypeid, + bool add2namespace); +extern PLpgSQL_recfield *plpgsql_build_recfield(PLpgSQL_rec *rec, + const char *fldname); +extern PGDLLEXPORT int plpgsql_recognize_err_condition(const char *condname, + bool allow_sqlstate); +extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname); +extern void plpgsql_adddatum(PLpgSQL_datum *newdatum); +extern int plpgsql_add_initdatums(int **varnos); +extern void plpgsql_HashTableInit(void); + +/* + * Functions in pl_exec.c + */ +extern Datum plpgsql_exec_function(PLpgSQL_function *func, + FunctionCallInfo fcinfo, + EState *simple_eval_estate, + ResourceOwner simple_eval_resowner, + ResourceOwner procedure_resowner, + bool atomic); +extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function *func, + TriggerData *trigdata); +extern void plpgsql_exec_event_trigger(PLpgSQL_function *func, + EventTriggerData *trigdata); +extern void plpgsql_xact_cb(XactEvent event, void *arg); +extern void plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid, + SubTransactionId parentSubid, void *arg); +extern PGDLLEXPORT Oid plpgsql_exec_get_datum_type(PLpgSQL_execstate *estate, + PLpgSQL_datum *datum); +extern void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, + PLpgSQL_datum *datum, + Oid *typeId, int32 *typMod, + Oid *collation); + +/* + * Functions for namespace handling in pl_funcs.c + */ +extern void plpgsql_ns_init(void); +extern void plpgsql_ns_push(const char *label, + PLpgSQL_label_type label_type); +extern void plpgsql_ns_pop(void); +extern PLpgSQL_nsitem *plpgsql_ns_top(void); +extern void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name); +extern PGDLLEXPORT PLpgSQL_nsitem *plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, + const char *name1, const char *name2, + const char *name3, int *names_used); +extern PLpgSQL_nsitem *plpgsql_ns_lookup_label(PLpgSQL_nsitem *ns_cur, + const char *name); +extern PLpgSQL_nsitem *plpgsql_ns_find_nearest_loop(PLpgSQL_nsitem *ns_cur); + +/* + * Other functions in pl_funcs.c + */ +extern PGDLLEXPORT const char *plpgsql_stmt_typename(PLpgSQL_stmt *stmt); +extern const char *plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind); +extern void plpgsql_free_function_memory(PLpgSQL_function *func); +extern void plpgsql_dumptree(PLpgSQL_function *func); + +/* + * Scanner functions in pl_scanner.c + */ +extern int plpgsql_base_yylex(void); +extern int plpgsql_yylex(void); +extern int plpgsql_token_length(void); +extern void plpgsql_push_back_token(int token); +extern bool plpgsql_token_is_unreserved_keyword(int token); +extern void plpgsql_append_source_text(StringInfo buf, + int startlocation, int endlocation); +extern int plpgsql_peek(void); +extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc, + int *tok2_loc); +extern int plpgsql_scanner_errposition(int location); +extern void plpgsql_yyerror(const char *message) pg_attribute_noreturn(); +extern int plpgsql_location_to_lineno(int location); +extern int plpgsql_latest_lineno(void); +extern void plpgsql_scanner_init(const char *str); +extern void plpgsql_scanner_finish(void); + +/* + * Externs in gram.y + */ +extern int plpgsql_yyparse(void); + +#endif /* PLPGSQL_H */ diff --git a/install/include/postgresql/server/port.h b/install/include/postgresql/server/port.h new file mode 100644 index 00000000000..2b2ea07ce5e --- /dev/null +++ b/install/include/postgresql/server/port.h @@ -0,0 +1,550 @@ +/*------------------------------------------------------------------------- + * + * port.h + * Header for src/port/ compatibility functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PORT_H +#define PG_PORT_H + +#include + +/* + * Windows has enough specialized port stuff that we push most of it off + * into another file. + * Note: Some CYGWIN includes might #define WIN32. + */ +#if defined(WIN32) && !defined(__CYGWIN__) +#include "port/win32_port.h" +#endif + +/* socket has a different definition on WIN32 */ +#ifndef WIN32 +typedef int pgsocket; + +#define PGINVALID_SOCKET (-1) +#else +typedef SOCKET pgsocket; + +#define PGINVALID_SOCKET INVALID_SOCKET +#endif + +/* if platform lacks socklen_t, we assume this will work */ +#ifndef HAVE_SOCKLEN_T +typedef unsigned int socklen_t; +#endif + +/* non-blocking */ +extern bool pg_set_noblock(pgsocket sock); +extern bool pg_set_block(pgsocket sock); + +/* Portable path handling for Unix/Win32 (in path.c) */ + +extern bool has_drive_prefix(const char *path); +extern char *first_dir_separator(const char *filename); +extern char *last_dir_separator(const char *filename); +extern char *first_path_var_separator(const char *pathlist); +extern void join_path_components(char *ret_path, + const char *head, const char *tail); +extern void canonicalize_path(char *path); +extern void canonicalize_path_enc(char *path, int encoding); +extern void make_native_path(char *filename); +extern void cleanup_path(char *path); +extern bool path_contains_parent_reference(const char *path); +extern bool path_is_relative_and_below_cwd(const char *path); +extern bool path_is_prefix_of_path(const char *path1, const char *path2); +extern char *make_absolute_path(const char *path); +extern const char *get_progname(const char *argv0); +extern void get_share_path(const char *my_exec_path, char *ret_path); +extern void get_etc_path(const char *my_exec_path, char *ret_path); +extern void get_include_path(const char *my_exec_path, char *ret_path); +extern void get_pkginclude_path(const char *my_exec_path, char *ret_path); +extern void get_includeserver_path(const char *my_exec_path, char *ret_path); +extern void get_lib_path(const char *my_exec_path, char *ret_path); +extern void get_pkglib_path(const char *my_exec_path, char *ret_path); +extern void get_locale_path(const char *my_exec_path, char *ret_path); +extern void get_doc_path(const char *my_exec_path, char *ret_path); +extern void get_html_path(const char *my_exec_path, char *ret_path); +extern void get_man_path(const char *my_exec_path, char *ret_path); +extern bool get_home_path(char *ret_path); +extern void get_parent_directory(char *path); + +/* common/pgfnames.c */ +extern char **pgfnames(const char *path); +extern void pgfnames_cleanup(char **filenames); + +#define IS_NONWINDOWS_DIR_SEP(ch) ((ch) == '/') +#define is_nonwindows_absolute_path(filename) \ +( \ + IS_NONWINDOWS_DIR_SEP((filename)[0]) \ +) + +#define IS_WINDOWS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') +/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */ +#define is_windows_absolute_path(filename) \ +( \ + IS_WINDOWS_DIR_SEP((filename)[0]) || \ + (isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \ + IS_WINDOWS_DIR_SEP((filename)[2])) \ +) + +/* + * is_absolute_path and IS_DIR_SEP + * + * By using macros here we avoid needing to include path.c in libpq. + */ +#ifndef WIN32 +#define IS_DIR_SEP(ch) IS_NONWINDOWS_DIR_SEP(ch) +#define is_absolute_path(filename) is_nonwindows_absolute_path(filename) +#else +#define IS_DIR_SEP(ch) IS_WINDOWS_DIR_SEP(ch) +#define is_absolute_path(filename) is_windows_absolute_path(filename) +#endif + +/* + * This macro provides a centralized list of all errnos that identify + * hard failure of a previously-established network connection. + * The macro is intended to be used in a switch statement, in the form + * "case ALL_CONNECTION_FAILURE_ERRNOS:". + * + * Note: this groups EPIPE and ECONNRESET, which we take to indicate a + * probable server crash, with other errors that indicate loss of network + * connectivity without proving much about the server's state. Places that + * are actually reporting errors typically single out EPIPE and ECONNRESET, + * while allowing the network failures to be reported generically. + */ +#define ALL_CONNECTION_FAILURE_ERRNOS \ + EPIPE: \ + case ECONNRESET: \ + case ECONNABORTED: \ + case EHOSTDOWN: \ + case EHOSTUNREACH: \ + case ENETDOWN: \ + case ENETRESET: \ + case ENETUNREACH: \ + case ETIMEDOUT + +/* Portable locale initialization (in exec.c) */ +extern void set_pglocale_pgservice(const char *argv0, const char *app); + +/* Portable way to find and execute binaries (in exec.c) */ +extern int validate_exec(const char *path); +extern int find_my_exec(const char *argv0, char *retpath); +extern int find_other_exec(const char *argv0, const char *target, + const char *versionstr, char *retpath); +extern char *pipe_read_line(char *cmd, char *line, int maxsize); + +/* Doesn't belong here, but this is used with find_other_exec(), so... */ +#define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n" + +#ifdef EXEC_BACKEND +/* Disable ASLR before exec, for developer builds only (in exec.c) */ +extern int pg_disable_aslr(void); +#endif + + +#if defined(WIN32) || defined(__CYGWIN__) +#define EXE ".exe" +#else +#define EXE "" +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +#define DEVNULL "nul" +#else +#define DEVNULL "/dev/null" +#endif + +/* Portable delay handling */ +extern void pg_usleep(long microsec); + +/* Portable SQL-like case-independent comparisons and conversions */ +extern int pg_strcasecmp(const char *s1, const char *s2); +extern int pg_strncasecmp(const char *s1, const char *s2, size_t n); +extern unsigned char pg_toupper(unsigned char ch); +extern unsigned char pg_tolower(unsigned char ch); +extern unsigned char pg_ascii_toupper(unsigned char ch); +extern unsigned char pg_ascii_tolower(unsigned char ch); + +/* + * Beginning in v12, we always replace snprintf() and friends with our own + * implementation. This symbol is no longer consulted by the core code, + * but keep it defined anyway in case any extensions are looking at it. + */ +#define USE_REPL_SNPRINTF 1 + +/* + * Versions of libintl >= 0.13 try to replace printf() and friends with + * macros to their own versions that understand the %$ format. We do the + * same, so disable their macros, if they exist. + */ +#ifdef vsnprintf +#undef vsnprintf +#endif +#ifdef snprintf +#undef snprintf +#endif +#ifdef vsprintf +#undef vsprintf +#endif +#ifdef sprintf +#undef sprintf +#endif +#ifdef vfprintf +#undef vfprintf +#endif +#ifdef fprintf +#undef fprintf +#endif +#ifdef vprintf +#undef vprintf +#endif +#ifdef printf +#undef printf +#endif + +extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) pg_attribute_printf(3, 0); +extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); +extern int pg_vsprintf(char *str, const char *fmt, va_list args) pg_attribute_printf(2, 0); +extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3); +extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args) pg_attribute_printf(2, 0); +extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3); +extern int pg_vprintf(const char *fmt, va_list args) pg_attribute_printf(1, 0); +extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2); + +#ifndef WIN32 +/* + * We add a pg_ prefix as a warning that the Windows implementations have the + * non-standard side-effect of changing the current file position. + */ +#define pg_pread pread +#define pg_pwrite pwrite +#endif + +/* + * We use __VA_ARGS__ for printf to prevent replacing references to + * the "printf" format archetype in format() attribute declarations. + * That unfortunately means that taking a function pointer to printf + * will not do what we'd wish. (If you need to do that, you must name + * pg_printf explicitly.) For printf's sibling functions, use + * parameterless macros so that function pointers will work unsurprisingly. + */ +#define vsnprintf pg_vsnprintf +#define snprintf pg_snprintf +#define vsprintf pg_vsprintf +#define sprintf pg_sprintf +#define vfprintf pg_vfprintf +#define fprintf pg_fprintf +#define vprintf pg_vprintf +#define printf(...) pg_printf(__VA_ARGS__) + +/* This is also provided by snprintf.c */ +extern int pg_strfromd(char *str, size_t count, int precision, double value); + +/* Replace strerror() with our own, somewhat more robust wrapper */ +extern char *pg_strerror(int errnum); +#define strerror pg_strerror + +/* Likewise for strerror_r(); note we prefer the GNU API for that */ +extern char *pg_strerror_r(int errnum, char *buf, size_t buflen); +#define strerror_r pg_strerror_r +#define PG_STRERROR_R_BUFLEN 256 /* Recommended buffer size for strerror_r */ + +/* Wrap strsignal(), or provide our own version if necessary */ +extern const char *pg_strsignal(int signum); + +extern int pclose_check(FILE *stream); + +/* Global variable holding time zone information. */ +#if defined(WIN32) || defined(__CYGWIN__) +#define TIMEZONE_GLOBAL _timezone +#define TZNAME_GLOBAL _tzname +#else +#define TIMEZONE_GLOBAL timezone +#define TZNAME_GLOBAL tzname +#endif + +#if defined(WIN32) || defined(__CYGWIN__) +/* + * Win32 doesn't have reliable rename/unlink during concurrent access. + */ +extern int pgrename(const char *from, const char *to); +extern int pgunlink(const char *path); + +/* Include this first so later includes don't see these defines */ +#ifdef _MSC_VER +#include +#endif + +#define rename(from, to) pgrename(from, to) +#define unlink(path) pgunlink(path) +#endif /* defined(WIN32) || defined(__CYGWIN__) */ + +/* + * Win32 also doesn't have symlinks, but we can emulate them with + * junction points on newer Win32 versions. + * + * Cygwin has its own symlinks which work on Win95/98/ME where + * junction points don't, so use those instead. We have no way of + * knowing what type of system Cygwin binaries will be run on. + * Note: Some CYGWIN includes might #define WIN32. + */ +#if defined(WIN32) && !defined(__CYGWIN__) +extern int pgsymlink(const char *oldpath, const char *newpath); +extern int pgreadlink(const char *path, char *buf, size_t size); + +#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) +#define readlink(path, buf, size) pgreadlink(path, buf, size) +#endif + +extern bool rmtree(const char *path, bool rmtopdir); + +#if defined(WIN32) && !defined(__CYGWIN__) + +/* + * We want the 64-bit variant of lseek(). + * + * For Visual Studio, this must be after to avoid messing up its + * lseek() and _lseeki64() function declarations. + * + * For MinGW there is already a macro, so we have to undefine it (depending on + * _FILE_OFFSET_BITS, it may point at its own lseek64, but we don't want to + * count on that being set). + */ +#undef lseek +#define lseek(a,b,c) _lseeki64((a),(b),(c)) + +/* + * We want the 64-bit variant of chsize(). It sets errno and also returns it, + * so convert non-zero result to -1 to match POSIX. + * + * Prevent MinGW from declaring functions, and undefine its macro before we + * define our own. + */ +#ifndef _MSC_VER +#define FTRUNCATE_DEFINED +#include +#undef ftruncate +#endif +#define ftruncate(a,b) (_chsize_s((a),(b)) == 0 ? 0 : -1) + +/* + * open() and fopen() replacements to allow deletion of open files and + * passing of other special options. + */ +extern HANDLE pgwin32_open_handle(const char *, int, bool); +extern int pgwin32_open(const char *, int,...); +extern FILE *pgwin32_fopen(const char *, const char *); +#define open(a,b,c) pgwin32_open(a,b,c) +#define fopen(a,b) pgwin32_fopen(a,b) + +/* + * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want + * to use our popen wrapper, rather than plain _popen, so override that. For + * consistency, use our version of pclose, too. + */ +#ifdef popen +#undef popen +#endif +#ifdef pclose +#undef pclose +#endif + +/* + * system() and popen() replacements to enclose the command in an extra + * pair of quotes. + */ +extern int pgwin32_system(const char *command); +extern FILE *pgwin32_popen(const char *command, const char *type); + +#define system(a) pgwin32_system(a) +#define popen(a,b) pgwin32_popen(a,b) +#define pclose(a) _pclose(a) + +#else /* !WIN32 */ + +/* + * Win32 requires a special close for sockets and pipes, while on Unix + * close() does them all. + */ +#define closesocket close +#endif /* WIN32 */ + +/* + * On Windows, setvbuf() does not support _IOLBF mode, and interprets that + * as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0) + * crashes outright if "parameter validation" is enabled. Therefore, in + * places where we'd like to select line-buffered mode, we fall back to + * unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF + * directly in order to implement this behavior. + */ +#ifndef WIN32 +#define PG_IOLBF _IOLBF +#else +#define PG_IOLBF _IONBF +#endif + +/* + * Default "extern" declarations or macro substitutes for library routines. + * When necessary, these routines are provided by files in src/port/. + */ + +/* Type to use with fseeko/ftello */ +#ifndef WIN32 /* WIN32 is handled in port/win32_port.h */ +#define pgoff_t off_t +#endif + +#ifndef HAVE_GETPEEREID +/* On Windows, Perl might have incompatible definitions of uid_t and gid_t. */ +#ifndef PLPERL_HAVE_UID_GID +extern int getpeereid(int sock, uid_t *uid, gid_t *gid); +#endif +#endif + +/* + * Glibc doesn't use the builtin for clang due to a *gcc* bug in a version + * newer than the gcc compatibility clang claims to have. This would cause a + * *lot* of superfluous function calls, therefore revert when using clang. In + * C++ there's issues with libc++ (not libstdc++), so disable as well. + */ +#if defined(__clang__) && !defined(__cplusplus) +/* needs to be separate to not confuse other compilers */ +#if __has_builtin(__builtin_isinf) +/* need to include before, to avoid getting overwritten */ +#include +#undef isinf +#define isinf __builtin_isinf +#endif /* __has_builtin(isinf) */ +#endif /* __clang__ && !__cplusplus */ + +#ifndef HAVE_EXPLICIT_BZERO +extern void explicit_bzero(void *buf, size_t len); +#endif + +#ifdef HAVE_BUGGY_STRTOF +extern float pg_strtof(const char *nptr, char **endptr); +#define strtof(a,b) (pg_strtof((a),(b))) +#endif + +#ifdef WIN32 +/* src/port/win32link.c */ +extern int link(const char *src, const char *dst); +#endif + +#ifndef HAVE_MKDTEMP +extern char *mkdtemp(char *path); +#endif + +#ifndef HAVE_INET_ATON +#include +#include +extern int inet_aton(const char *cp, struct in_addr *addr); +#endif + +#if !HAVE_DECL_STRLCAT +extern size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#if !HAVE_DECL_STRLCPY +extern size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#if !HAVE_DECL_STRNLEN +extern size_t strnlen(const char *str, size_t maxlen); +#endif + +/* thread.c */ +#ifndef WIN32 +extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen); +extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen); +#endif + +extern void pg_qsort(void *base, size_t nel, size_t elsize, + int (*cmp) (const void *, const void *)); +extern int pg_qsort_strcmp(const void *a, const void *b); + +#define qsort(a,b,c,d) pg_qsort(a,b,c,d) + +typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg); + +extern void qsort_arg(void *base, size_t nel, size_t elsize, + qsort_arg_comparator cmp, void *arg); + +extern void qsort_interruptible(void *base, size_t nel, size_t elsize, + qsort_arg_comparator cmp, void *arg); + +extern void *bsearch_arg(const void *key, const void *base0, + size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg); + +/* port/chklocale.c */ +extern int pg_get_encoding_from_locale(const char *ctype, bool write_message); + +#if defined(WIN32) && !defined(FRONTEND) +extern int pg_codepage_to_encoding(UINT cp); +#endif + +/* port/inet_net_ntop.c */ +extern char *pg_inet_net_ntop(int af, const void *src, int bits, + char *dst, size_t size); + +/* port/pg_strong_random.c */ +extern void pg_strong_random_init(void); +extern bool pg_strong_random(void *buf, size_t len); + +/* + * pg_backend_random used to be a wrapper for pg_strong_random before + * Postgres 12 for the backend code. + */ +#define pg_backend_random pg_strong_random + +/* port/pgcheckdir.c */ +extern int pg_check_dir(const char *dir); + +/* port/pgmkdirp.c */ +extern int pg_mkdir_p(char *path, int omode); + +/* port/pqsignal.c (see also interfaces/libpq/legacy-pqsignal.c) */ +#ifdef FRONTEND +#define pqsignal pqsignal_fe +#endif +typedef void (*pqsigfunc) (SIGNAL_ARGS); +extern pqsigfunc pqsignal(int signo, pqsigfunc func); + +/* port/quotes.c */ +extern char *escape_single_quotes_ascii(const char *src); + +/* common/wait_error.c */ +extern char *wait_result_to_str(int exitstatus); +extern bool wait_result_is_signal(int exit_status, int signum); +extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found); +extern int wait_result_to_exit_code(int exit_status); + +/* + * Interfaces that we assume all Unix system have. We retain individual macros + * for better documentation. + * + * For symlink-related functions, there is often no need to test these macros, + * because we provided basic support on Windows that can work with absolute + * paths to directories. Code that wants to test for complete symlink support + * (including relative paths and non-directories) should be conditional on + * HAVE_READLINK or HAVE_SYMLINK. + */ +#ifndef WIN32 +#define HAVE_GETRLIMIT 1 +#define HAVE_POLL 1 +#define HAVE_POLL_H 1 +#define HAVE_READLINK 1 +#define HAVE_SETSID 1 +#define HAVE_SHM_OPEN 1 +#define HAVE_SYMLINK 1 +#endif + +#endif /* PG_PORT_H */ diff --git a/install/include/postgresql/server/port/aix.h b/install/include/postgresql/server/port/aix.h new file mode 100644 index 00000000000..5b1159c5785 --- /dev/null +++ b/install/include/postgresql/server/port/aix.h @@ -0,0 +1,14 @@ +/* + * src/include/port/aix.h + */ +#define CLASS_CONFLICT +#define DISABLE_XOPEN_NLS + +/* + * "IBM XL C/C++ for AIX, V12.1" miscompiles, for 32-bit, some inline + * expansions of ginCompareItemPointers() "long long" arithmetic. To take + * advantage of inlining, build a 64-bit PostgreSQL. + */ +#if defined(__ILP32__) && defined(__IBMC__) +#define PG_FORCE_DISABLE_INLINE +#endif diff --git a/install/include/postgresql/server/port/atomics.h b/install/include/postgresql/server/port/atomics.h new file mode 100644 index 00000000000..bbff945ebad --- /dev/null +++ b/install/include/postgresql/server/port/atomics.h @@ -0,0 +1,519 @@ +/*------------------------------------------------------------------------- + * + * atomics.h + * Atomic operations. + * + * Hardware and compiler dependent functions for manipulating memory + * atomically and dealing with cache coherency. Used to implement locking + * facilities and lockless algorithms/data structures. + * + * To bring up postgres on a platform/compiler at the very least + * implementations for the following operations should be provided: + * * pg_compiler_barrier(), pg_write_barrier(), pg_read_barrier() + * * pg_atomic_compare_exchange_u32(), pg_atomic_fetch_add_u32() + * * pg_atomic_test_set_flag(), pg_atomic_init_flag(), pg_atomic_clear_flag() + * * PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY should be defined if appropriate. + * + * There exist generic, hardware independent, implementations for several + * compilers which might be sufficient, although possibly not optimal, for a + * new platform. If no such generic implementation is available spinlocks (or + * even OS provided semaphores) will be used to implement the API. + * + * Implement _u64 atomics if and only if your platform can use them + * efficiently (and obviously correctly). + * + * Use higher level functionality (lwlocks, spinlocks, heavyweight locks) + * whenever possible. Writing correct code using these facilities is hard. + * + * For an introduction to using memory barriers within the PostgreSQL backend, + * see src/backend/storage/lmgr/README.barrier + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/atomics.h + * + *------------------------------------------------------------------------- + */ +#ifndef ATOMICS_H +#define ATOMICS_H + +#ifdef FRONTEND +#error "atomics.h may not be included from frontend code" +#endif + +#define INSIDE_ATOMICS_H + +#include + +/* + * First a set of architecture specific files is included. + * + * These files can provide the full set of atomics or can do pretty much + * nothing if all the compilers commonly used on these platforms provide + * usable generics. + * + * Don't add an inline assembly of the actual atomic operations if all the + * common implementations of your platform provide intrinsics. Intrinsics are + * much easier to understand and potentially support more architectures. + * + * It will often make sense to define memory barrier semantics here, since + * e.g. generic compiler intrinsics for x86 memory barriers can't know that + * postgres doesn't need x86 read/write barriers do anything more than a + * compiler barrier. + * + */ +#if defined(__arm__) || defined(__arm) || defined(__aarch64__) +#include "port/atomics/arch-arm.h" +#elif defined(__i386__) || defined(__i386) || defined(__x86_64__) +#include "port/atomics/arch-x86.h" +#elif defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__) +#include "port/atomics/arch-ppc.h" +#elif defined(__hppa) || defined(__hppa__) +#include "port/atomics/arch-hppa.h" +#endif + +/* + * Compiler specific, but architecture independent implementations. + * + * Provide architecture independent implementations of the atomic + * facilities. At the very least compiler barriers should be provided, but a + * full implementation of + * * pg_compiler_barrier(), pg_write_barrier(), pg_read_barrier() + * * pg_atomic_compare_exchange_u32(), pg_atomic_fetch_add_u32() + * using compiler intrinsics are a good idea. + */ +/* + * gcc or compatible, including clang and icc. Exclude xlc. The ppc64le "IBM + * XL C/C++ for Linux, V13.1.2" emulates gcc, but __sync_lock_test_and_set() + * of one-byte types elicits SIGSEGV. That bug was gone by V13.1.5 (2016-12). + */ +#if (defined(__GNUC__) || defined(__INTEL_COMPILER)) && !(defined(__IBMC__) || defined(__IBMCPP__)) +#include "port/atomics/generic-gcc.h" +#elif defined(_MSC_VER) +#include "port/atomics/generic-msvc.h" +#elif defined(__SUNPRO_C) && !defined(__GNUC__) +#include "port/atomics/generic-sunpro.h" +#else +/* + * Unsupported compiler, we'll likely use slower fallbacks... At least + * compiler barriers should really be provided. + */ +#endif + +/* + * Provide a full fallback of the pg_*_barrier(), pg_atomic**_flag and + * pg_atomic_* APIs for platforms without sufficient spinlock and/or atomics + * support. In the case of spinlock backed atomics the emulation is expected + * to be efficient, although less so than native atomics support. + */ +#include "port/atomics/fallback.h" + +/* + * Provide additional operations using supported infrastructure. These are + * expected to be efficient if the underlying atomic operations are efficient. + */ +#include "port/atomics/generic.h" + + +/* + * pg_compiler_barrier - prevent the compiler from moving code across + * + * A compiler barrier need not (and preferably should not) emit any actual + * machine code, but must act as an optimization fence: the compiler must not + * reorder loads or stores to main memory around the barrier. However, the + * CPU may still reorder loads or stores at runtime, if the architecture's + * memory model permits this. + */ +#define pg_compiler_barrier() pg_compiler_barrier_impl() + +/* + * pg_memory_barrier - prevent the CPU from reordering memory access + * + * A memory barrier must act as a compiler barrier, and in addition must + * guarantee that all loads and stores issued prior to the barrier are + * completed before any loads or stores issued after the barrier. Unless + * loads and stores are totally ordered (which is not the case on most + * architectures) this requires issuing some sort of memory fencing + * instruction. + */ +#define pg_memory_barrier() pg_memory_barrier_impl() + +/* + * pg_(read|write)_barrier - prevent the CPU from reordering memory access + * + * A read barrier must act as a compiler barrier, and in addition must + * guarantee that any loads issued prior to the barrier are completed before + * any loads issued after the barrier. Similarly, a write barrier acts + * as a compiler barrier, and also orders stores. Read and write barriers + * are thus weaker than a full memory barrier, but stronger than a compiler + * barrier. In practice, on machines with strong memory ordering, read and + * write barriers may require nothing more than a compiler barrier. + */ +#define pg_read_barrier() pg_read_barrier_impl() +#define pg_write_barrier() pg_write_barrier_impl() + +/* + * Spinloop delay - Allow CPU to relax in busy loops + */ +#define pg_spin_delay() pg_spin_delay_impl() + +/* + * pg_atomic_init_flag - initialize atomic flag. + * + * No barrier semantics. + */ +static inline void +pg_atomic_init_flag(volatile pg_atomic_flag *ptr) +{ + pg_atomic_init_flag_impl(ptr); +} + +/* + * pg_atomic_test_set_flag - TAS() + * + * Returns true if the flag has successfully been set, false otherwise. + * + * Acquire (including read barrier) semantics. + */ +static inline bool +pg_atomic_test_set_flag(volatile pg_atomic_flag *ptr) +{ + return pg_atomic_test_set_flag_impl(ptr); +} + +/* + * pg_atomic_unlocked_test_flag - Check if the lock is free + * + * Returns true if the flag currently is not set, false otherwise. + * + * No barrier semantics. + */ +static inline bool +pg_atomic_unlocked_test_flag(volatile pg_atomic_flag *ptr) +{ + return pg_atomic_unlocked_test_flag_impl(ptr); +} + +/* + * pg_atomic_clear_flag - release lock set by TAS() + * + * Release (including write barrier) semantics. + */ +static inline void +pg_atomic_clear_flag(volatile pg_atomic_flag *ptr) +{ + pg_atomic_clear_flag_impl(ptr); +} + + +/* + * pg_atomic_init_u32 - initialize atomic variable + * + * Has to be done before any concurrent usage.. + * + * No barrier semantics. + */ +static inline void +pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val) +{ + AssertPointerAlignment(ptr, 4); + + pg_atomic_init_u32_impl(ptr, val); +} + +/* + * pg_atomic_read_u32 - unlocked read from atomic variable. + * + * The read is guaranteed to return a value as it has been written by this or + * another process at some point in the past. There's however no cache + * coherency interaction guaranteeing the value hasn't since been written to + * again. + * + * No barrier semantics. + */ +static inline uint32 +pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr) +{ + AssertPointerAlignment(ptr, 4); + return pg_atomic_read_u32_impl(ptr); +} + +/* + * pg_atomic_write_u32 - write to atomic variable. + * + * The write is guaranteed to succeed as a whole, i.e. it's not possible to + * observe a partial write for any reader. Note that this correctly interacts + * with pg_atomic_compare_exchange_u32, in contrast to + * pg_atomic_unlocked_write_u32(). + * + * No barrier semantics. + */ +static inline void +pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val) +{ + AssertPointerAlignment(ptr, 4); + + pg_atomic_write_u32_impl(ptr, val); +} + +/* + * pg_atomic_unlocked_write_u32 - unlocked write to atomic variable. + * + * The write is guaranteed to succeed as a whole, i.e. it's not possible to + * observe a partial write for any reader. But note that writing this way is + * not guaranteed to correctly interact with read-modify-write operations like + * pg_atomic_compare_exchange_u32. This should only be used in cases where + * minor performance regressions due to atomics emulation are unacceptable. + * + * No barrier semantics. + */ +static inline void +pg_atomic_unlocked_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val) +{ + AssertPointerAlignment(ptr, 4); + + pg_atomic_unlocked_write_u32_impl(ptr, val); +} + +/* + * pg_atomic_exchange_u32 - exchange newval with current value + * + * Returns the old value of 'ptr' before the swap. + * + * Full barrier semantics. + */ +static inline uint32 +pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval) +{ + AssertPointerAlignment(ptr, 4); + + return pg_atomic_exchange_u32_impl(ptr, newval); +} + +/* + * pg_atomic_compare_exchange_u32 - CAS operation + * + * Atomically compare the current value of ptr with *expected and store newval + * iff ptr and *expected have the same value. The current value of *ptr will + * always be stored in *expected. + * + * Return true if values have been exchanged, false otherwise. + * + * Full barrier semantics. + */ +static inline bool +pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval) +{ + AssertPointerAlignment(ptr, 4); + AssertPointerAlignment(expected, 4); + + return pg_atomic_compare_exchange_u32_impl(ptr, expected, newval); +} + +/* + * pg_atomic_fetch_add_u32 - atomically add to variable + * + * Returns the value of ptr before the arithmetic operation. + * + * Full barrier semantics. + */ +static inline uint32 +pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + AssertPointerAlignment(ptr, 4); + return pg_atomic_fetch_add_u32_impl(ptr, add_); +} + +/* + * pg_atomic_fetch_sub_u32 - atomically subtract from variable + * + * Returns the value of ptr before the arithmetic operation. Note that sub_ + * may not be INT_MIN due to platform limitations. + * + * Full barrier semantics. + */ +static inline uint32 +pg_atomic_fetch_sub_u32(volatile pg_atomic_uint32 *ptr, int32 sub_) +{ + AssertPointerAlignment(ptr, 4); + Assert(sub_ != INT_MIN); + return pg_atomic_fetch_sub_u32_impl(ptr, sub_); +} + +/* + * pg_atomic_fetch_and_u32 - atomically bit-and and_ with variable + * + * Returns the value of ptr before the arithmetic operation. + * + * Full barrier semantics. + */ +static inline uint32 +pg_atomic_fetch_and_u32(volatile pg_atomic_uint32 *ptr, uint32 and_) +{ + AssertPointerAlignment(ptr, 4); + return pg_atomic_fetch_and_u32_impl(ptr, and_); +} + +/* + * pg_atomic_fetch_or_u32 - atomically bit-or or_ with variable + * + * Returns the value of ptr before the arithmetic operation. + * + * Full barrier semantics. + */ +static inline uint32 +pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_) +{ + AssertPointerAlignment(ptr, 4); + return pg_atomic_fetch_or_u32_impl(ptr, or_); +} + +/* + * pg_atomic_add_fetch_u32 - atomically add to variable + * + * Returns the value of ptr after the arithmetic operation. + * + * Full barrier semantics. + */ +static inline uint32 +pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + AssertPointerAlignment(ptr, 4); + return pg_atomic_add_fetch_u32_impl(ptr, add_); +} + +/* + * pg_atomic_sub_fetch_u32 - atomically subtract from variable + * + * Returns the value of ptr after the arithmetic operation. Note that sub_ may + * not be INT_MIN due to platform limitations. + * + * Full barrier semantics. + */ +static inline uint32 +pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_) +{ + AssertPointerAlignment(ptr, 4); + Assert(sub_ != INT_MIN); + return pg_atomic_sub_fetch_u32_impl(ptr, sub_); +} + +/* ---- + * The 64 bit operations have the same semantics as their 32bit counterparts + * if they are available. Check the corresponding 32bit function for + * documentation. + * ---- + */ +static inline void +pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val) +{ + /* + * Can't necessarily enforce alignment - and don't need it - when using + * the spinlock based fallback implementation. Therefore only assert when + * not using it. + */ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + pg_atomic_init_u64_impl(ptr, val); +} + +static inline uint64 +pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + return pg_atomic_read_u64_impl(ptr); +} + +static inline void +pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + pg_atomic_write_u64_impl(ptr, val); +} + +static inline uint64 +pg_atomic_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 newval) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + return pg_atomic_exchange_u64_impl(ptr, newval); +} + +static inline bool +pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); + AssertPointerAlignment(expected, 8); +#endif + return pg_atomic_compare_exchange_u64_impl(ptr, expected, newval); +} + +static inline uint64 +pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + return pg_atomic_fetch_add_u64_impl(ptr, add_); +} + +static inline uint64 +pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + Assert(sub_ != PG_INT64_MIN); + return pg_atomic_fetch_sub_u64_impl(ptr, sub_); +} + +static inline uint64 +pg_atomic_fetch_and_u64(volatile pg_atomic_uint64 *ptr, uint64 and_) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + return pg_atomic_fetch_and_u64_impl(ptr, and_); +} + +static inline uint64 +pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + return pg_atomic_fetch_or_u64_impl(ptr, or_); +} + +static inline uint64 +pg_atomic_add_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 add_) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + return pg_atomic_add_fetch_u64_impl(ptr, add_); +} + +static inline uint64 +pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_) +{ +#ifndef PG_HAVE_ATOMIC_U64_SIMULATION + AssertPointerAlignment(ptr, 8); +#endif + Assert(sub_ != PG_INT64_MIN); + return pg_atomic_sub_fetch_u64_impl(ptr, sub_); +} + +#undef INSIDE_ATOMICS_H + +#endif /* ATOMICS_H */ diff --git a/install/include/postgresql/server/port/atomics/arch-arm.h b/install/include/postgresql/server/port/atomics/arch-arm.h new file mode 100644 index 00000000000..c90bf58029c --- /dev/null +++ b/install/include/postgresql/server/port/atomics/arch-arm.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * arch-arm.h + * Atomic operations considerations specific to ARM + * + * Portions Copyright (c) 2013-2023, PostgreSQL Global Development Group + * + * NOTES: + * + * src/include/port/atomics/arch-arm.h + * + *------------------------------------------------------------------------- + */ + +/* intentionally no include guards, should only be included by atomics.h */ +#ifndef INSIDE_ATOMICS_H +#error "should be included via atomics.h" +#endif + +/* + * 64 bit atomics on ARM32 are implemented using kernel fallbacks and thus + * might be slow, so disable entirely. On ARM64 that problem doesn't exist. + */ +#if !defined(__aarch64__) +#define PG_DISABLE_64_BIT_ATOMICS +#else +/* + * Architecture Reference Manual for ARMv8 states aligned read/write to/from + * general purpose register is atomic. + */ +#define PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY +#endif /* __aarch64__ */ diff --git a/install/include/postgresql/server/port/atomics/arch-hppa.h b/install/include/postgresql/server/port/atomics/arch-hppa.h new file mode 100644 index 00000000000..4c89fbff719 --- /dev/null +++ b/install/include/postgresql/server/port/atomics/arch-hppa.h @@ -0,0 +1,17 @@ +/*------------------------------------------------------------------------- + * + * arch-hppa.h + * Atomic operations considerations specific to HPPA + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES: + * + * src/include/port/atomics/arch-hppa.h + * + *------------------------------------------------------------------------- + */ + +/* HPPA doesn't do either read or write reordering */ +#define pg_memory_barrier_impl() pg_compiler_barrier_impl() diff --git a/install/include/postgresql/server/port/atomics/arch-ppc.h b/install/include/postgresql/server/port/atomics/arch-ppc.h new file mode 100644 index 00000000000..d992d4c8a26 --- /dev/null +++ b/install/include/postgresql/server/port/atomics/arch-ppc.h @@ -0,0 +1,254 @@ +/*------------------------------------------------------------------------- + * + * arch-ppc.h + * Atomic operations considerations specific to PowerPC + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES: + * + * src/include/port/atomics/arch-ppc.h + * + *------------------------------------------------------------------------- + */ + +#if defined(__GNUC__) + +/* + * lwsync orders loads with respect to each other, and similarly with stores. + * But a load can be performed before a subsequent store, so sync must be used + * for a full memory barrier. + */ +#define pg_memory_barrier_impl() __asm__ __volatile__ ("sync" : : : "memory") +#define pg_read_barrier_impl() __asm__ __volatile__ ("lwsync" : : : "memory") +#define pg_write_barrier_impl() __asm__ __volatile__ ("lwsync" : : : "memory") +#endif + +#define PG_HAVE_ATOMIC_U32_SUPPORT +typedef struct pg_atomic_uint32 +{ + volatile uint32 value; +} pg_atomic_uint32; + +/* 64bit atomics are only supported in 64bit mode */ +#if SIZEOF_VOID_P >= 8 +#define PG_HAVE_ATOMIC_U64_SUPPORT +typedef struct pg_atomic_uint64 +{ + volatile uint64 value pg_attribute_aligned(8); +} pg_atomic_uint64; + +#endif + +/* + * This mimics gcc __atomic_compare_exchange_n(..., __ATOMIC_SEQ_CST), but + * code generation differs at the end. __atomic_compare_exchange_n(): + * 100: isync + * 104: mfcr r3 + * 108: rlwinm r3,r3,3,31,31 + * 10c: bne 120 <.eb+0x10> + * 110: clrldi r3,r3,63 + * 114: addi r1,r1,112 + * 118: blr + * 11c: nop + * 120: clrldi r3,r3,63 + * 124: stw r9,0(r4) + * 128: addi r1,r1,112 + * 12c: blr + * + * This: + * f0: isync + * f4: mfcr r9 + * f8: rldicl. r3,r9,35,63 + * fc: bne 104 <.eb> + * 100: stw r10,0(r4) + * 104: addi r1,r1,112 + * 108: blr + * + * This implementation may or may not have materially different performance. + * It's not exploiting the fact that cr0 still holds the relevant comparison + * bits, set during the __asm__. One could fix that by moving more code into + * the __asm__. (That would remove the freedom to eliminate dead stores when + * the caller ignores "expected", but few callers do.) + * + * Recognizing constant "newval" would be superfluous, because there's no + * immediate-operand version of stwcx. + */ +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 +static inline bool +pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval) +{ + uint32 found; + uint32 condition_register; + bool ret; + +#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P + if (__builtin_constant_p(*expected) && + (int32) *expected <= PG_INT16_MAX && + (int32) *expected >= PG_INT16_MIN) + __asm__ __volatile__( + " sync \n" + " lwarx %0,0,%5,1 \n" + " cmpwi %0,%3 \n" + " bne $+12 \n" /* branch to lwsync */ + " stwcx. %4,0,%5 \n" + " bne $-16 \n" /* branch to lwarx */ + " lwsync \n" + " mfcr %1 \n" +: "=&r"(found), "=r"(condition_register), "+m"(ptr->value) +: "i"(*expected), "r"(newval), "r"(&ptr->value) +: "memory", "cc"); + else +#endif + __asm__ __volatile__( + " sync \n" + " lwarx %0,0,%5,1 \n" + " cmpw %0,%3 \n" + " bne $+12 \n" /* branch to lwsync */ + " stwcx. %4,0,%5 \n" + " bne $-16 \n" /* branch to lwarx */ + " lwsync \n" + " mfcr %1 \n" +: "=&r"(found), "=r"(condition_register), "+m"(ptr->value) +: "r"(*expected), "r"(newval), "r"(&ptr->value) +: "memory", "cc"); + + ret = (condition_register >> 29) & 1; /* test eq bit of cr0 */ + if (!ret) + *expected = found; + return ret; +} + +/* + * This mirrors gcc __sync_fetch_and_add(). + * + * Like tas(), use constraint "=&b" to avoid allocating r0. + */ +#define PG_HAVE_ATOMIC_FETCH_ADD_U32 +static inline uint32 +pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + uint32 _t; + uint32 res; + +#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P + if (__builtin_constant_p(add_) && + add_ <= PG_INT16_MAX && add_ >= PG_INT16_MIN) + __asm__ __volatile__( + " sync \n" + " lwarx %1,0,%4,1 \n" + " addi %0,%1,%3 \n" + " stwcx. %0,0,%4 \n" + " bne $-12 \n" /* branch to lwarx */ + " lwsync \n" +: "=&r"(_t), "=&b"(res), "+m"(ptr->value) +: "i"(add_), "r"(&ptr->value) +: "memory", "cc"); + else +#endif + __asm__ __volatile__( + " sync \n" + " lwarx %1,0,%4,1 \n" + " add %0,%1,%3 \n" + " stwcx. %0,0,%4 \n" + " bne $-12 \n" /* branch to lwarx */ + " lwsync \n" +: "=&r"(_t), "=&r"(res), "+m"(ptr->value) +: "r"(add_), "r"(&ptr->value) +: "memory", "cc"); + + return res; +} + +#ifdef PG_HAVE_ATOMIC_U64_SUPPORT + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 +static inline bool +pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval) +{ + uint64 found; + uint32 condition_register; + bool ret; + + /* Like u32, but s/lwarx/ldarx/; s/stwcx/stdcx/; s/cmpw/cmpd/ */ +#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P + if (__builtin_constant_p(*expected) && + (int64) *expected <= PG_INT16_MAX && + (int64) *expected >= PG_INT16_MIN) + __asm__ __volatile__( + " sync \n" + " ldarx %0,0,%5,1 \n" + " cmpdi %0,%3 \n" + " bne $+12 \n" /* branch to lwsync */ + " stdcx. %4,0,%5 \n" + " bne $-16 \n" /* branch to ldarx */ + " lwsync \n" + " mfcr %1 \n" +: "=&r"(found), "=r"(condition_register), "+m"(ptr->value) +: "i"(*expected), "r"(newval), "r"(&ptr->value) +: "memory", "cc"); + else +#endif + __asm__ __volatile__( + " sync \n" + " ldarx %0,0,%5,1 \n" + " cmpd %0,%3 \n" + " bne $+12 \n" /* branch to lwsync */ + " stdcx. %4,0,%5 \n" + " bne $-16 \n" /* branch to ldarx */ + " lwsync \n" + " mfcr %1 \n" +: "=&r"(found), "=r"(condition_register), "+m"(ptr->value) +: "r"(*expected), "r"(newval), "r"(&ptr->value) +: "memory", "cc"); + + ret = (condition_register >> 29) & 1; /* test eq bit of cr0 */ + if (!ret) + *expected = found; + return ret; +} + +#define PG_HAVE_ATOMIC_FETCH_ADD_U64 +static inline uint64 +pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) +{ + uint64 _t; + uint64 res; + + /* Like u32, but s/lwarx/ldarx/; s/stwcx/stdcx/ */ +#ifdef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P + if (__builtin_constant_p(add_) && + add_ <= PG_INT16_MAX && add_ >= PG_INT16_MIN) + __asm__ __volatile__( + " sync \n" + " ldarx %1,0,%4,1 \n" + " addi %0,%1,%3 \n" + " stdcx. %0,0,%4 \n" + " bne $-12 \n" /* branch to ldarx */ + " lwsync \n" +: "=&r"(_t), "=&b"(res), "+m"(ptr->value) +: "i"(add_), "r"(&ptr->value) +: "memory", "cc"); + else +#endif + __asm__ __volatile__( + " sync \n" + " ldarx %1,0,%4,1 \n" + " add %0,%1,%3 \n" + " stdcx. %0,0,%4 \n" + " bne $-12 \n" /* branch to ldarx */ + " lwsync \n" +: "=&r"(_t), "=&r"(res), "+m"(ptr->value) +: "r"(add_), "r"(&ptr->value) +: "memory", "cc"); + + return res; +} + +#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */ + +/* per architecture manual doubleword accesses have single copy atomicity */ +#define PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY diff --git a/install/include/postgresql/server/port/atomics/arch-x86.h b/install/include/postgresql/server/port/atomics/arch-x86.h new file mode 100644 index 00000000000..bb84b9bad83 --- /dev/null +++ b/install/include/postgresql/server/port/atomics/arch-x86.h @@ -0,0 +1,252 @@ +/*------------------------------------------------------------------------- + * + * arch-x86.h + * Atomic operations considerations specific to intel x86 + * + * Note that we actually require a 486 upwards because the 386 doesn't have + * support for xadd and cmpxchg. Given that the 386 isn't supported anywhere + * anymore that's not much of a restriction luckily. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES: + * + * src/include/port/atomics/arch-x86.h + * + *------------------------------------------------------------------------- + */ + +/* + * Both 32 and 64 bit x86 do not allow loads to be reordered with other loads, + * or stores to be reordered with other stores, but a load can be performed + * before a subsequent store. + * + * Technically, some x86-ish chips support uncached memory access and/or + * special instructions that are weakly ordered. In those cases we'd need + * the read and write barriers to be lfence and sfence. But since we don't + * do those things, a compiler barrier should be enough. + * + * "lock; addl" has worked for longer than "mfence". It's also rumored to be + * faster in many scenarios. + */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#if defined(__i386__) || defined(__i386) +#define pg_memory_barrier_impl() \ + __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory", "cc") +#elif defined(__x86_64__) +#define pg_memory_barrier_impl() \ + __asm__ __volatile__ ("lock; addl $0,0(%%rsp)" : : : "memory", "cc") +#endif +#endif /* defined(__GNUC__) || defined(__INTEL_COMPILER) */ + +#define pg_read_barrier_impl() pg_compiler_barrier_impl() +#define pg_write_barrier_impl() pg_compiler_barrier_impl() + +/* + * Provide implementation for atomics using inline assembly on x86 gcc. It's + * nice to support older gcc's and the compare/exchange implementation here is + * actually more efficient than the * __sync variant. + */ +#if defined(HAVE_ATOMICS) + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) + +#define PG_HAVE_ATOMIC_FLAG_SUPPORT +typedef struct pg_atomic_flag +{ + volatile char value; +} pg_atomic_flag; + +#define PG_HAVE_ATOMIC_U32_SUPPORT +typedef struct pg_atomic_uint32 +{ + volatile uint32 value; +} pg_atomic_uint32; + +/* + * It's too complicated to write inline asm for 64bit types on 32bit and the + * 486 can't do it anyway. + */ +#ifdef __x86_64__ +#define PG_HAVE_ATOMIC_U64_SUPPORT +typedef struct pg_atomic_uint64 +{ + /* alignment guaranteed due to being on a 64bit platform */ + volatile uint64 value; +} pg_atomic_uint64; +#endif /* __x86_64__ */ + +#endif /* defined(__GNUC__) || defined(__INTEL_COMPILER) */ + +#endif /* defined(HAVE_ATOMICS) */ + +#if !defined(PG_HAVE_SPIN_DELAY) +/* + * This sequence is equivalent to the PAUSE instruction ("rep" is + * ignored by old IA32 processors if the following instruction is + * not a string operation); the IA-32 Architecture Software + * Developer's Manual, Vol. 3, Section 7.7.2 describes why using + * PAUSE in the inner loop of a spin lock is necessary for good + * performance: + * + * The PAUSE instruction improves the performance of IA-32 + * processors supporting Hyper-Threading Technology when + * executing spin-wait loops and other routines where one + * thread is accessing a shared lock or semaphore in a tight + * polling loop. When executing a spin-wait loop, the + * processor can suffer a severe performance penalty when + * exiting the loop because it detects a possible memory order + * violation and flushes the core processor's pipeline. The + * PAUSE instruction provides a hint to the processor that the + * code sequence is a spin-wait loop. The processor uses this + * hint to avoid the memory order violation and prevent the + * pipeline flush. In addition, the PAUSE instruction + * de-pipelines the spin-wait loop to prevent it from + * consuming execution resources excessively. + */ +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define PG_HAVE_SPIN_DELAY +static __inline__ void +pg_spin_delay_impl(void) +{ + __asm__ __volatile__(" rep; nop \n"); +} +#elif defined(_MSC_VER) && defined(__x86_64__) +#define PG_HAVE_SPIN_DELAY +static __forceinline void +pg_spin_delay_impl(void) +{ + _mm_pause(); +} +#elif defined(_MSC_VER) +#define PG_HAVE_SPIN_DELAY +static __forceinline void +pg_spin_delay_impl(void) +{ + /* See comment for gcc code. Same code, MASM syntax */ + __asm rep nop; +} +#endif +#endif /* !defined(PG_HAVE_SPIN_DELAY) */ + + +#if defined(HAVE_ATOMICS) + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) + +#define PG_HAVE_ATOMIC_TEST_SET_FLAG +static inline bool +pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr) +{ + char _res = 1; + + __asm__ __volatile__( + " lock \n" + " xchgb %0,%1 \n" +: "+q"(_res), "+m"(ptr->value) +: +: "memory"); + return _res == 0; +} + +#define PG_HAVE_ATOMIC_CLEAR_FLAG +static inline void +pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr) +{ + /* + * On a TSO architecture like x86 it's sufficient to use a compiler + * barrier to achieve release semantics. + */ + __asm__ __volatile__("" ::: "memory"); + ptr->value = 0; +} + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 +static inline bool +pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval) +{ + char ret; + + /* + * Perform cmpxchg and use the zero flag which it implicitly sets when + * equal to measure the success. + */ + __asm__ __volatile__( + " lock \n" + " cmpxchgl %4,%5 \n" + " setz %2 \n" +: "=a" (*expected), "=m"(ptr->value), "=q" (ret) +: "a" (*expected), "r" (newval), "m"(ptr->value) +: "memory", "cc"); + return (bool) ret; +} + +#define PG_HAVE_ATOMIC_FETCH_ADD_U32 +static inline uint32 +pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + uint32 res; + __asm__ __volatile__( + " lock \n" + " xaddl %0,%1 \n" +: "=q"(res), "=m"(ptr->value) +: "0" (add_), "m"(ptr->value) +: "memory", "cc"); + return res; +} + +#ifdef __x86_64__ + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 +static inline bool +pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval) +{ + char ret; + + /* + * Perform cmpxchg and use the zero flag which it implicitly sets when + * equal to measure the success. + */ + __asm__ __volatile__( + " lock \n" + " cmpxchgq %4,%5 \n" + " setz %2 \n" +: "=a" (*expected), "=m"(ptr->value), "=q" (ret) +: "a" (*expected), "r" (newval), "m"(ptr->value) +: "memory", "cc"); + return (bool) ret; +} + +#define PG_HAVE_ATOMIC_FETCH_ADD_U64 +static inline uint64 +pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) +{ + uint64 res; + __asm__ __volatile__( + " lock \n" + " xaddq %0,%1 \n" +: "=q"(res), "=m"(ptr->value) +: "0" (add_), "m"(ptr->value) +: "memory", "cc"); + return res; +} + +#endif /* __x86_64__ */ + +#endif /* defined(__GNUC__) || defined(__INTEL_COMPILER) */ + +/* + * 8 byte reads / writes have single-copy atomicity on 32 bit x86 platforms + * since at least the 586. As well as on all x86-64 cpus. + */ +#if defined(__i568__) || defined(__i668__) || /* gcc i586+ */ \ + (defined(_M_IX86) && _M_IX86 >= 500) || /* msvc i586+ */ \ + defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) /* gcc, sunpro, msvc */ +#define PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY +#endif /* 8 byte single-copy atomicity */ + +#endif /* HAVE_ATOMICS */ diff --git a/install/include/postgresql/server/port/atomics/fallback.h b/install/include/postgresql/server/port/atomics/fallback.h new file mode 100644 index 00000000000..a9e8e77c036 --- /dev/null +++ b/install/include/postgresql/server/port/atomics/fallback.h @@ -0,0 +1,170 @@ +/*------------------------------------------------------------------------- + * + * fallback.h + * Fallback for platforms without spinlock and/or atomics support. Slower + * than native atomics support, but not unusably slow. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/atomics/fallback.h + * + *------------------------------------------------------------------------- + */ + +/* intentionally no include guards, should only be included by atomics.h */ +#ifndef INSIDE_ATOMICS_H +# error "should be included via atomics.h" +#endif + +#ifndef pg_memory_barrier_impl +/* + * If we have no memory barrier implementation for this architecture, we + * fall back to acquiring and releasing a spinlock. This might, in turn, + * fall back to the semaphore-based spinlock implementation, which will be + * amazingly slow. + * + * It's not self-evident that every possible legal implementation of a + * spinlock acquire-and-release would be equivalent to a full memory barrier. + * For example, I'm not sure that Itanium's acq and rel add up to a full + * fence. But all of our actual implementations seem OK in this regard. + */ +#define PG_HAVE_MEMORY_BARRIER_EMULATION + +extern void pg_spinlock_barrier(void); +#define pg_memory_barrier_impl pg_spinlock_barrier +#endif + +#ifndef pg_compiler_barrier_impl +/* + * If the compiler/arch combination does not provide compiler barriers, + * provide a fallback. The fallback simply consists of a function call into + * an externally defined function. That should guarantee compiler barrier + * semantics except for compilers that do inter translation unit/global + * optimization - those better provide an actual compiler barrier. + * + * A native compiler barrier for sure is a lot faster than this... + */ +#define PG_HAVE_COMPILER_BARRIER_EMULATION +extern void pg_extern_compiler_barrier(void); +#define pg_compiler_barrier_impl pg_extern_compiler_barrier +#endif + + +/* + * If we have atomics implementation for this platform, fall back to providing + * the atomics API using a spinlock to protect the internal state. Possibly + * the spinlock implementation uses semaphores internally... + * + * We have to be a bit careful here, as it's not guaranteed that atomic + * variables are mapped to the same address in every process (e.g. dynamic + * shared memory segments). We can't just hash the address and use that to map + * to a spinlock. Instead assign a spinlock on initialization of the atomic + * variable. + */ +#if !defined(PG_HAVE_ATOMIC_FLAG_SUPPORT) && !defined(PG_HAVE_ATOMIC_U32_SUPPORT) + +#define PG_HAVE_ATOMIC_FLAG_SIMULATION +#define PG_HAVE_ATOMIC_FLAG_SUPPORT + +typedef struct pg_atomic_flag +{ + /* + * To avoid circular includes we can't use s_lock as a type here. Instead + * just reserve enough space for all spinlock types. Some platforms would + * be content with just one byte instead of 4, but that's not too much + * waste. + */ +#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC, GCC and HP compilers */ + int sema[4]; +#else + int sema; +#endif + volatile bool value; +} pg_atomic_flag; + +#endif /* PG_HAVE_ATOMIC_FLAG_SUPPORT */ + +#if !defined(PG_HAVE_ATOMIC_U32_SUPPORT) + +#define PG_HAVE_ATOMIC_U32_SIMULATION + +#define PG_HAVE_ATOMIC_U32_SUPPORT +typedef struct pg_atomic_uint32 +{ + /* Check pg_atomic_flag's definition above for an explanation */ +#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC */ + int sema[4]; +#else + int sema; +#endif + volatile uint32 value; +} pg_atomic_uint32; + +#endif /* PG_HAVE_ATOMIC_U32_SUPPORT */ + +#if !defined(PG_HAVE_ATOMIC_U64_SUPPORT) + +#define PG_HAVE_ATOMIC_U64_SIMULATION + +#define PG_HAVE_ATOMIC_U64_SUPPORT +typedef struct pg_atomic_uint64 +{ + /* Check pg_atomic_flag's definition above for an explanation */ +#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC */ + int sema[4]; +#else + int sema; +#endif + volatile uint64 value; +} pg_atomic_uint64; + +#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */ + +#ifdef PG_HAVE_ATOMIC_FLAG_SIMULATION + +#define PG_HAVE_ATOMIC_INIT_FLAG +extern void pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr); + +#define PG_HAVE_ATOMIC_TEST_SET_FLAG +extern bool pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr); + +#define PG_HAVE_ATOMIC_CLEAR_FLAG +extern void pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr); + +#define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG +extern bool pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr); + +#endif /* PG_HAVE_ATOMIC_FLAG_SIMULATION */ + +#ifdef PG_HAVE_ATOMIC_U32_SIMULATION + +#define PG_HAVE_ATOMIC_INIT_U32 +extern void pg_atomic_init_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val_); + +#define PG_HAVE_ATOMIC_WRITE_U32 +extern void pg_atomic_write_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val); + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 +extern bool pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval); + +#define PG_HAVE_ATOMIC_FETCH_ADD_U32 +extern uint32 pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_); + +#endif /* PG_HAVE_ATOMIC_U32_SIMULATION */ + + +#ifdef PG_HAVE_ATOMIC_U64_SIMULATION + +#define PG_HAVE_ATOMIC_INIT_U64 +extern void pg_atomic_init_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val_); + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 +extern bool pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval); + +#define PG_HAVE_ATOMIC_FETCH_ADD_U64 +extern uint64 pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_); + +#endif /* PG_HAVE_ATOMIC_U64_SIMULATION */ diff --git a/install/include/postgresql/server/port/atomics/generic-gcc.h b/install/include/postgresql/server/port/atomics/generic-gcc.h new file mode 100644 index 00000000000..f9698a4876c --- /dev/null +++ b/install/include/postgresql/server/port/atomics/generic-gcc.h @@ -0,0 +1,294 @@ +/*------------------------------------------------------------------------- + * + * generic-gcc.h + * Atomic operations, implemented using gcc (or compatible) intrinsics. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES: + * + * Documentation: + * * Legacy __sync Built-in Functions for Atomic Memory Access + * https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/_005f_005fsync-Builtins.html + * * Built-in functions for memory model aware atomic operations + * https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/_005f_005fatomic-Builtins.html + * + * src/include/port/atomics/generic-gcc.h + * + *------------------------------------------------------------------------- + */ + +/* intentionally no include guards, should only be included by atomics.h */ +#ifndef INSIDE_ATOMICS_H +#error "should be included via atomics.h" +#endif + +/* + * An empty asm block should be a sufficient compiler barrier. + */ +#define pg_compiler_barrier_impl() __asm__ __volatile__("" ::: "memory") + +/* + * If we're on GCC 4.1.0 or higher, we should be able to get a memory barrier + * out of this compiler built-in. But we prefer to rely on platform specific + * definitions where possible, and use this only as a fallback. + */ +#if !defined(pg_memory_barrier_impl) +# if defined(HAVE_GCC__ATOMIC_INT32_CAS) +# define pg_memory_barrier_impl() __atomic_thread_fence(__ATOMIC_SEQ_CST) +# elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) +# define pg_memory_barrier_impl() __sync_synchronize() +# endif +#endif /* !defined(pg_memory_barrier_impl) */ + +#if !defined(pg_read_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS) +/* acquire semantics include read barrier semantics */ +# define pg_read_barrier_impl() do \ +{ \ + pg_compiler_barrier_impl(); \ + __atomic_thread_fence(__ATOMIC_ACQUIRE); \ +} while (0) +#endif + +#if !defined(pg_write_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS) +/* release semantics include write barrier semantics */ +# define pg_write_barrier_impl() do \ +{ \ + pg_compiler_barrier_impl(); \ + __atomic_thread_fence(__ATOMIC_RELEASE); \ +} while (0) +#endif + + +#ifdef HAVE_ATOMICS + +/* generic gcc based atomic flag implementation */ +#if !defined(PG_HAVE_ATOMIC_FLAG_SUPPORT) \ + && (defined(HAVE_GCC__SYNC_INT32_TAS) || defined(HAVE_GCC__SYNC_CHAR_TAS)) + +#define PG_HAVE_ATOMIC_FLAG_SUPPORT +typedef struct pg_atomic_flag +{ + /* + * If we have a choice, use int-width TAS, because that is more efficient + * and/or more reliably implemented on most non-Intel platforms. (Note + * that this code isn't used on x86[_64]; see arch-x86.h for that.) + */ +#ifdef HAVE_GCC__SYNC_INT32_TAS + volatile int value; +#else + volatile char value; +#endif +} pg_atomic_flag; + +#endif /* !ATOMIC_FLAG_SUPPORT && SYNC_INT32_TAS */ + +/* generic gcc based atomic uint32 implementation */ +#if !defined(PG_HAVE_ATOMIC_U32_SUPPORT) \ + && (defined(HAVE_GCC__ATOMIC_INT32_CAS) || defined(HAVE_GCC__SYNC_INT32_CAS)) + +#define PG_HAVE_ATOMIC_U32_SUPPORT +typedef struct pg_atomic_uint32 +{ + volatile uint32 value; +} pg_atomic_uint32; + +#endif /* defined(HAVE_GCC__ATOMIC_INT32_CAS) || defined(HAVE_GCC__SYNC_INT32_CAS) */ + +/* generic gcc based atomic uint64 implementation */ +#if !defined(PG_HAVE_ATOMIC_U64_SUPPORT) \ + && !defined(PG_DISABLE_64_BIT_ATOMICS) \ + && (defined(HAVE_GCC__ATOMIC_INT64_CAS) || defined(HAVE_GCC__SYNC_INT64_CAS)) + +#define PG_HAVE_ATOMIC_U64_SUPPORT + +typedef struct pg_atomic_uint64 +{ + volatile uint64 value pg_attribute_aligned(8); +} pg_atomic_uint64; + +#endif /* defined(HAVE_GCC__ATOMIC_INT64_CAS) || defined(HAVE_GCC__SYNC_INT64_CAS) */ + +#ifdef PG_HAVE_ATOMIC_FLAG_SUPPORT + +#if defined(HAVE_GCC__SYNC_CHAR_TAS) || defined(HAVE_GCC__SYNC_INT32_TAS) + +#ifndef PG_HAVE_ATOMIC_TEST_SET_FLAG +#define PG_HAVE_ATOMIC_TEST_SET_FLAG +static inline bool +pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr) +{ + /* NB: only an acquire barrier, not a full one */ + /* some platform only support a 1 here */ + return __sync_lock_test_and_set(&ptr->value, 1) == 0; +} +#endif + +#endif /* defined(HAVE_GCC__SYNC_*_TAS) */ + +#ifndef PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG +#define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG +static inline bool +pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr) +{ + return ptr->value == 0; +} +#endif + +#ifndef PG_HAVE_ATOMIC_CLEAR_FLAG +#define PG_HAVE_ATOMIC_CLEAR_FLAG +static inline void +pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr) +{ + __sync_lock_release(&ptr->value); +} +#endif + +#ifndef PG_HAVE_ATOMIC_INIT_FLAG +#define PG_HAVE_ATOMIC_INIT_FLAG +static inline void +pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr) +{ + pg_atomic_clear_flag_impl(ptr); +} +#endif + +#endif /* defined(PG_HAVE_ATOMIC_FLAG_SUPPORT) */ + +/* prefer __atomic, it has a better API */ +#if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) && defined(HAVE_GCC__ATOMIC_INT32_CAS) +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 +static inline bool +pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval) +{ + /* FIXME: we can probably use a lower consistency model */ + return __atomic_compare_exchange_n(&ptr->value, expected, newval, false, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) && defined(HAVE_GCC__SYNC_INT32_CAS) +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 +static inline bool +pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval) +{ + bool ret; + uint32 current; + current = __sync_val_compare_and_swap(&ptr->value, *expected, newval); + ret = current == *expected; + *expected = current; + return ret; +} +#endif + +/* if we have 32-bit __sync_val_compare_and_swap, assume we have these too: */ + +#if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U32) && defined(HAVE_GCC__SYNC_INT32_CAS) +#define PG_HAVE_ATOMIC_FETCH_ADD_U32 +static inline uint32 +pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + return __sync_fetch_and_add(&ptr->value, add_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U32) && defined(HAVE_GCC__SYNC_INT32_CAS) +#define PG_HAVE_ATOMIC_FETCH_SUB_U32 +static inline uint32 +pg_atomic_fetch_sub_u32_impl(volatile pg_atomic_uint32 *ptr, int32 sub_) +{ + return __sync_fetch_and_sub(&ptr->value, sub_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_AND_U32) && defined(HAVE_GCC__SYNC_INT32_CAS) +#define PG_HAVE_ATOMIC_FETCH_AND_U32 +static inline uint32 +pg_atomic_fetch_and_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 and_) +{ + return __sync_fetch_and_and(&ptr->value, and_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_OR_U32) && defined(HAVE_GCC__SYNC_INT32_CAS) +#define PG_HAVE_ATOMIC_FETCH_OR_U32 +static inline uint32 +pg_atomic_fetch_or_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 or_) +{ + return __sync_fetch_and_or(&ptr->value, or_); +} +#endif + + +#if !defined(PG_DISABLE_64_BIT_ATOMICS) + +#if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) && defined(HAVE_GCC__ATOMIC_INT64_CAS) +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 +static inline bool +pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval) +{ + return __atomic_compare_exchange_n(&ptr->value, expected, newval, false, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) && defined(HAVE_GCC__SYNC_INT64_CAS) +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 +static inline bool +pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval) +{ + bool ret; + uint64 current; + current = __sync_val_compare_and_swap(&ptr->value, *expected, newval); + ret = current == *expected; + *expected = current; + return ret; +} +#endif + +/* if we have 64-bit __sync_val_compare_and_swap, assume we have these too: */ + +#if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U64) && defined(HAVE_GCC__SYNC_INT64_CAS) +#define PG_HAVE_ATOMIC_FETCH_ADD_U64 +static inline uint64 +pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) +{ + return __sync_fetch_and_add(&ptr->value, add_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U64) && defined(HAVE_GCC__SYNC_INT64_CAS) +#define PG_HAVE_ATOMIC_FETCH_SUB_U64 +static inline uint64 +pg_atomic_fetch_sub_u64_impl(volatile pg_atomic_uint64 *ptr, int64 sub_) +{ + return __sync_fetch_and_sub(&ptr->value, sub_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_AND_U64) && defined(HAVE_GCC__SYNC_INT64_CAS) +#define PG_HAVE_ATOMIC_FETCH_AND_U64 +static inline uint64 +pg_atomic_fetch_and_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 and_) +{ + return __sync_fetch_and_and(&ptr->value, and_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_OR_U64) && defined(HAVE_GCC__SYNC_INT64_CAS) +#define PG_HAVE_ATOMIC_FETCH_OR_U64 +static inline uint64 +pg_atomic_fetch_or_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 or_) +{ + return __sync_fetch_and_or(&ptr->value, or_); +} +#endif + +#endif /* !defined(PG_DISABLE_64_BIT_ATOMICS) */ + +#endif /* defined(HAVE_ATOMICS) */ diff --git a/install/include/postgresql/server/port/atomics/generic-msvc.h b/install/include/postgresql/server/port/atomics/generic-msvc.h new file mode 100644 index 00000000000..8835f4ceea8 --- /dev/null +++ b/install/include/postgresql/server/port/atomics/generic-msvc.h @@ -0,0 +1,101 @@ +/*------------------------------------------------------------------------- + * + * generic-msvc.h + * Atomic operations support when using MSVC + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES: + * + * Documentation: + * * Interlocked Variable Access + * http://msdn.microsoft.com/en-us/library/ms684122%28VS.85%29.aspx + * + * src/include/port/atomics/generic-msvc.h + * + *------------------------------------------------------------------------- + */ +#include + +/* intentionally no include guards, should only be included by atomics.h */ +#ifndef INSIDE_ATOMICS_H +#error "should be included via atomics.h" +#endif + +#pragma intrinsic(_ReadWriteBarrier) +#define pg_compiler_barrier_impl() _ReadWriteBarrier() + +#ifndef pg_memory_barrier_impl +#define pg_memory_barrier_impl() MemoryBarrier() +#endif + +#if defined(HAVE_ATOMICS) + +#define PG_HAVE_ATOMIC_U32_SUPPORT +typedef struct pg_atomic_uint32 +{ + volatile uint32 value; +} pg_atomic_uint32; + +#define PG_HAVE_ATOMIC_U64_SUPPORT +typedef struct pg_attribute_aligned(8) pg_atomic_uint64 +{ + volatile uint64 value; +} pg_atomic_uint64; + + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 +static inline bool +pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval) +{ + bool ret; + uint32 current; + current = InterlockedCompareExchange(&ptr->value, newval, *expected); + ret = current == *expected; + *expected = current; + return ret; +} + +#define PG_HAVE_ATOMIC_FETCH_ADD_U32 +static inline uint32 +pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + return InterlockedExchangeAdd(&ptr->value, add_); +} + +/* + * The non-intrinsics versions are only available in vista upwards, so use the + * intrinsic version. Only supported on >486, but we require XP as a minimum + * baseline, which doesn't support the 486, so we don't need to add checks for + * that case. + */ +#pragma intrinsic(_InterlockedCompareExchange64) + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 +static inline bool +pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval) +{ + bool ret; + uint64 current; + current = _InterlockedCompareExchange64(&ptr->value, newval, *expected); + ret = current == *expected; + *expected = current; + return ret; +} + +/* Only implemented on 64bit builds */ +#ifdef _WIN64 +#pragma intrinsic(_InterlockedExchangeAdd64) + +#define PG_HAVE_ATOMIC_FETCH_ADD_U64 +static inline uint64 +pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) +{ + return _InterlockedExchangeAdd64(&ptr->value, add_); +} +#endif /* _WIN64 */ + +#endif /* HAVE_ATOMICS */ diff --git a/install/include/postgresql/server/port/atomics/generic-sunpro.h b/install/include/postgresql/server/port/atomics/generic-sunpro.h new file mode 100644 index 00000000000..30f7d8b5362 --- /dev/null +++ b/install/include/postgresql/server/port/atomics/generic-sunpro.h @@ -0,0 +1,106 @@ +/*------------------------------------------------------------------------- + * + * generic-sunpro.h + * Atomic operations for solaris' CC + * + * Portions Copyright (c) 2013-2023, PostgreSQL Global Development Group + * + * NOTES: + * + * Documentation: + * * manpage for atomic_cas(3C) + * http://www.unix.com/man-page/opensolaris/3c/atomic_cas/ + * http://docs.oracle.com/cd/E23824_01/html/821-1465/atomic-cas-3c.html + * + * src/include/port/atomics/generic-sunpro.h + * + * ------------------------------------------------------------------------- + */ + +#if defined(HAVE_ATOMICS) + +#ifdef HAVE_MBARRIER_H +#include + +#define pg_compiler_barrier_impl() __compiler_barrier() + +#ifndef pg_memory_barrier_impl +/* + * Despite the name this is actually a full barrier. Expanding to mfence/ + * membar #StoreStore | #LoadStore | #StoreLoad | #LoadLoad on x86/sparc + * respectively. + */ +# define pg_memory_barrier_impl() __machine_rw_barrier() +#endif +#ifndef pg_read_barrier_impl +# define pg_read_barrier_impl() __machine_r_barrier() +#endif +#ifndef pg_write_barrier_impl +# define pg_write_barrier_impl() __machine_w_barrier() +#endif + +#endif /* HAVE_MBARRIER_H */ + +/* Older versions of the compiler don't have atomic.h... */ +#ifdef HAVE_ATOMIC_H + +#include + +#define PG_HAVE_ATOMIC_U32_SUPPORT +typedef struct pg_atomic_uint32 +{ + volatile uint32 value; +} pg_atomic_uint32; + +#define PG_HAVE_ATOMIC_U64_SUPPORT +typedef struct pg_atomic_uint64 +{ + /* + * Syntax to enforce variable alignment should be supported by versions + * supporting atomic.h, but it's hard to find accurate documentation. If + * it proves to be a problem, we'll have to add more version checks for 64 + * bit support. + */ + volatile uint64 value pg_attribute_aligned(8); +} pg_atomic_uint64; + +#endif /* HAVE_ATOMIC_H */ + +#endif /* defined(HAVE_ATOMICS) */ + + +#if defined(HAVE_ATOMICS) + +#ifdef HAVE_ATOMIC_H + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32 +static inline bool +pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, + uint32 *expected, uint32 newval) +{ + bool ret; + uint32 current; + + current = atomic_cas_32(&ptr->value, *expected, newval); + ret = current == *expected; + *expected = current; + return ret; +} + +#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 +static inline bool +pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, + uint64 *expected, uint64 newval) +{ + bool ret; + uint64 current; + + current = atomic_cas_64(&ptr->value, *expected, newval); + ret = current == *expected; + *expected = current; + return ret; +} + +#endif /* HAVE_ATOMIC_H */ + +#endif /* defined(HAVE_ATOMICS) */ diff --git a/install/include/postgresql/server/port/atomics/generic.h b/install/include/postgresql/server/port/atomics/generic.h new file mode 100644 index 00000000000..95d99dd0be0 --- /dev/null +++ b/install/include/postgresql/server/port/atomics/generic.h @@ -0,0 +1,401 @@ +/*------------------------------------------------------------------------- + * + * generic.h + * Implement higher level operations based on some lower level atomic + * operations. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/atomics/generic.h + * + *------------------------------------------------------------------------- + */ + +/* intentionally no include guards, should only be included by atomics.h */ +#ifndef INSIDE_ATOMICS_H +# error "should be included via atomics.h" +#endif + +/* + * If read or write barriers are undefined, we upgrade them to full memory + * barriers. + */ +#if !defined(pg_read_barrier_impl) +# define pg_read_barrier_impl pg_memory_barrier_impl +#endif +#if !defined(pg_write_barrier_impl) +# define pg_write_barrier_impl pg_memory_barrier_impl +#endif + +#ifndef PG_HAVE_SPIN_DELAY +#define PG_HAVE_SPIN_DELAY +#define pg_spin_delay_impl() ((void)0) +#endif + + +/* provide fallback */ +#if !defined(PG_HAVE_ATOMIC_FLAG_SUPPORT) && defined(PG_HAVE_ATOMIC_U32_SUPPORT) +#define PG_HAVE_ATOMIC_FLAG_SUPPORT +typedef pg_atomic_uint32 pg_atomic_flag; +#endif + +#ifndef PG_HAVE_ATOMIC_READ_U32 +#define PG_HAVE_ATOMIC_READ_U32 +static inline uint32 +pg_atomic_read_u32_impl(volatile pg_atomic_uint32 *ptr) +{ + return ptr->value; +} +#endif + +#ifndef PG_HAVE_ATOMIC_WRITE_U32 +#define PG_HAVE_ATOMIC_WRITE_U32 +static inline void +pg_atomic_write_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val) +{ + ptr->value = val; +} +#endif + +#ifndef PG_HAVE_ATOMIC_UNLOCKED_WRITE_U32 +#define PG_HAVE_ATOMIC_UNLOCKED_WRITE_U32 +static inline void +pg_atomic_unlocked_write_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val) +{ + ptr->value = val; +} +#endif + +/* + * provide fallback for test_and_set using atomic_exchange if available + */ +#if !defined(PG_HAVE_ATOMIC_TEST_SET_FLAG) && defined(PG_HAVE_ATOMIC_EXCHANGE_U32) + +#define PG_HAVE_ATOMIC_INIT_FLAG +static inline void +pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr) +{ + pg_atomic_write_u32_impl(ptr, 0); +} + +#define PG_HAVE_ATOMIC_TEST_SET_FLAG +static inline bool +pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr) +{ + return pg_atomic_exchange_u32_impl(ptr, 1) == 0; +} + +#define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG +static inline bool +pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr) +{ + return pg_atomic_read_u32_impl(ptr) == 0; +} + + +#define PG_HAVE_ATOMIC_CLEAR_FLAG +static inline void +pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr) +{ + /* XXX: release semantics suffice? */ + pg_memory_barrier_impl(); + pg_atomic_write_u32_impl(ptr, 0); +} + +/* + * provide fallback for test_and_set using atomic_compare_exchange if + * available. + */ +#elif !defined(PG_HAVE_ATOMIC_TEST_SET_FLAG) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) + +#define PG_HAVE_ATOMIC_INIT_FLAG +static inline void +pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr) +{ + pg_atomic_write_u32_impl(ptr, 0); +} + +#define PG_HAVE_ATOMIC_TEST_SET_FLAG +static inline bool +pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr) +{ + uint32 value = 0; + return pg_atomic_compare_exchange_u32_impl(ptr, &value, 1); +} + +#define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG +static inline bool +pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr) +{ + return pg_atomic_read_u32_impl(ptr) == 0; +} + +#define PG_HAVE_ATOMIC_CLEAR_FLAG +static inline void +pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr) +{ + /* + * Use a memory barrier + plain write if we have a native memory + * barrier. But don't do so if memory barriers use spinlocks - that'd lead + * to circularity if flags are used to implement spinlocks. + */ +#ifndef PG_HAVE_MEMORY_BARRIER_EMULATION + /* XXX: release semantics suffice? */ + pg_memory_barrier_impl(); + pg_atomic_write_u32_impl(ptr, 0); +#else + uint32 value = 1; + pg_atomic_compare_exchange_u32_impl(ptr, &value, 0); +#endif +} + +#elif !defined(PG_HAVE_ATOMIC_TEST_SET_FLAG) +# error "No pg_atomic_test_and_set provided" +#endif /* !defined(PG_HAVE_ATOMIC_TEST_SET_FLAG) */ + + +#ifndef PG_HAVE_ATOMIC_INIT_U32 +#define PG_HAVE_ATOMIC_INIT_U32 +static inline void +pg_atomic_init_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val_) +{ + ptr->value = val_; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_EXCHANGE_U32) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) +#define PG_HAVE_ATOMIC_EXCHANGE_U32 +static inline uint32 +pg_atomic_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 xchg_) +{ + uint32 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u32_impl(ptr, &old, xchg_)) + /* skip */; + return old; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U32) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) +#define PG_HAVE_ATOMIC_FETCH_ADD_U32 +static inline uint32 +pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + uint32 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u32_impl(ptr, &old, old + add_)) + /* skip */; + return old; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U32) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) +#define PG_HAVE_ATOMIC_FETCH_SUB_U32 +static inline uint32 +pg_atomic_fetch_sub_u32_impl(volatile pg_atomic_uint32 *ptr, int32 sub_) +{ + return pg_atomic_fetch_add_u32_impl(ptr, -sub_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_AND_U32) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) +#define PG_HAVE_ATOMIC_FETCH_AND_U32 +static inline uint32 +pg_atomic_fetch_and_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 and_) +{ + uint32 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u32_impl(ptr, &old, old & and_)) + /* skip */; + return old; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_OR_U32) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) +#define PG_HAVE_ATOMIC_FETCH_OR_U32 +static inline uint32 +pg_atomic_fetch_or_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 or_) +{ + uint32 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u32_impl(ptr, &old, old | or_)) + /* skip */; + return old; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_ADD_FETCH_U32) && defined(PG_HAVE_ATOMIC_FETCH_ADD_U32) +#define PG_HAVE_ATOMIC_ADD_FETCH_U32 +static inline uint32 +pg_atomic_add_fetch_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) +{ + return pg_atomic_fetch_add_u32_impl(ptr, add_) + add_; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_SUB_FETCH_U32) && defined(PG_HAVE_ATOMIC_FETCH_SUB_U32) +#define PG_HAVE_ATOMIC_SUB_FETCH_U32 +static inline uint32 +pg_atomic_sub_fetch_u32_impl(volatile pg_atomic_uint32 *ptr, int32 sub_) +{ + return pg_atomic_fetch_sub_u32_impl(ptr, sub_) - sub_; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_EXCHANGE_U64) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) +#define PG_HAVE_ATOMIC_EXCHANGE_U64 +static inline uint64 +pg_atomic_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 xchg_) +{ + uint64 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u64_impl(ptr, &old, xchg_)) + /* skip */; + return old; +} +#endif + +#ifndef PG_HAVE_ATOMIC_WRITE_U64 +#define PG_HAVE_ATOMIC_WRITE_U64 + +#if defined(PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY) && \ + !defined(PG_HAVE_ATOMIC_U64_SIMULATION) + +static inline void +pg_atomic_write_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val) +{ + /* + * On this platform aligned 64bit writes are guaranteed to be atomic, + * except if using the fallback implementation, where can't guarantee the + * required alignment. + */ + AssertPointerAlignment(ptr, 8); + ptr->value = val; +} + +#else + +static inline void +pg_atomic_write_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val) +{ + /* + * 64 bit writes aren't safe on all platforms. In the generic + * implementation implement them as an atomic exchange. + */ + pg_atomic_exchange_u64_impl(ptr, val); +} + +#endif /* PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY && !PG_HAVE_ATOMIC_U64_SIMULATION */ +#endif /* PG_HAVE_ATOMIC_WRITE_U64 */ + +#ifndef PG_HAVE_ATOMIC_READ_U64 +#define PG_HAVE_ATOMIC_READ_U64 + +#if defined(PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY) && \ + !defined(PG_HAVE_ATOMIC_U64_SIMULATION) + +static inline uint64 +pg_atomic_read_u64_impl(volatile pg_atomic_uint64 *ptr) +{ + /* + * On this platform aligned 64-bit reads are guaranteed to be atomic. + */ + AssertPointerAlignment(ptr, 8); + return ptr->value; +} + +#else + +static inline uint64 +pg_atomic_read_u64_impl(volatile pg_atomic_uint64 *ptr) +{ + uint64 old = 0; + + /* + * 64-bit reads aren't atomic on all platforms. In the generic + * implementation implement them as a compare/exchange with 0. That'll + * fail or succeed, but always return the old value. Possibly might store + * a 0, but only if the previous value also was a 0 - i.e. harmless. + */ + pg_atomic_compare_exchange_u64_impl(ptr, &old, 0); + + return old; +} +#endif /* PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY && !PG_HAVE_ATOMIC_U64_SIMULATION */ +#endif /* PG_HAVE_ATOMIC_READ_U64 */ + +#ifndef PG_HAVE_ATOMIC_INIT_U64 +#define PG_HAVE_ATOMIC_INIT_U64 +static inline void +pg_atomic_init_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val_) +{ + ptr->value = val_; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U64) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) +#define PG_HAVE_ATOMIC_FETCH_ADD_U64 +static inline uint64 +pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) +{ + uint64 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u64_impl(ptr, &old, old + add_)) + /* skip */; + return old; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U64) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) +#define PG_HAVE_ATOMIC_FETCH_SUB_U64 +static inline uint64 +pg_atomic_fetch_sub_u64_impl(volatile pg_atomic_uint64 *ptr, int64 sub_) +{ + return pg_atomic_fetch_add_u64_impl(ptr, -sub_); +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_AND_U64) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) +#define PG_HAVE_ATOMIC_FETCH_AND_U64 +static inline uint64 +pg_atomic_fetch_and_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 and_) +{ + uint64 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u64_impl(ptr, &old, old & and_)) + /* skip */; + return old; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_FETCH_OR_U64) && defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) +#define PG_HAVE_ATOMIC_FETCH_OR_U64 +static inline uint64 +pg_atomic_fetch_or_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 or_) +{ + uint64 old; + old = ptr->value; /* ok if read is not atomic */ + while (!pg_atomic_compare_exchange_u64_impl(ptr, &old, old | or_)) + /* skip */; + return old; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_ADD_FETCH_U64) && defined(PG_HAVE_ATOMIC_FETCH_ADD_U64) +#define PG_HAVE_ATOMIC_ADD_FETCH_U64 +static inline uint64 +pg_atomic_add_fetch_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) +{ + return pg_atomic_fetch_add_u64_impl(ptr, add_) + add_; +} +#endif + +#if !defined(PG_HAVE_ATOMIC_SUB_FETCH_U64) && defined(PG_HAVE_ATOMIC_FETCH_SUB_U64) +#define PG_HAVE_ATOMIC_SUB_FETCH_U64 +static inline uint64 +pg_atomic_sub_fetch_u64_impl(volatile pg_atomic_uint64 *ptr, int64 sub_) +{ + return pg_atomic_fetch_sub_u64_impl(ptr, sub_) - sub_; +} +#endif diff --git a/install/include/postgresql/server/port/cygwin.h b/install/include/postgresql/server/port/cygwin.h new file mode 100644 index 00000000000..44bf8533729 --- /dev/null +++ b/install/include/postgresql/server/port/cygwin.h @@ -0,0 +1,23 @@ +/* src/include/port/cygwin.h */ + +/* + * Variables declared in the core backend and referenced by loadable + * modules need to be marked "dllimport" in the core build, but + * "dllexport" when the declaration is read in a loadable module. + * No special markings should be used when compiling frontend code. + */ +#ifndef FRONTEND +#ifdef BUILDING_DLL +#define PGDLLIMPORT __declspec (dllexport) +#else +#define PGDLLIMPORT __declspec (dllimport) +#endif +#endif + +/* + * Cygwin has a strtof() which is literally just (float)strtod(), which means + * we get misrounding _and_ silent over/underflow. Using our wrapper doesn't + * fix the misrounding but does fix the error checks, which cuts down on the + * number of test variant files needed. + */ +#define HAVE_BUGGY_STRTOF 1 diff --git a/install/include/postgresql/server/port/darwin.h b/install/include/postgresql/server/port/darwin.h new file mode 100644 index 00000000000..15fb69d6dbb --- /dev/null +++ b/install/include/postgresql/server/port/darwin.h @@ -0,0 +1,8 @@ +/* src/include/port/darwin.h */ + +#define __darwin__ 1 + +#if HAVE_DECL_F_FULLFSYNC /* not present before macOS 10.3 */ +#define HAVE_FSYNC_WRITETHROUGH + +#endif diff --git a/install/include/postgresql/server/port/freebsd.h b/install/include/postgresql/server/port/freebsd.h new file mode 100644 index 00000000000..0e3fde55d6d --- /dev/null +++ b/install/include/postgresql/server/port/freebsd.h @@ -0,0 +1,8 @@ +/* src/include/port/freebsd.h */ + +/* + * Set the default wal_sync_method to fdatasync. xlogdefs.h's normal rules + * would prefer open_datasync on FreeBSD 13+, but that is not a good choice on + * many systems. + */ +#define PLATFORM_DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC diff --git a/install/include/postgresql/server/port/linux.h b/install/include/postgresql/server/port/linux.h new file mode 100644 index 00000000000..7a6e46cdbb7 --- /dev/null +++ b/install/include/postgresql/server/port/linux.h @@ -0,0 +1,22 @@ +/* src/include/port/linux.h */ + +/* + * As of July 2007, all known versions of the Linux kernel will sometimes + * return EIDRM for a shmctl() operation when EINVAL is correct (it happens + * when the low-order 15 bits of the supplied shm ID match the slot number + * assigned to a newer shmem segment). We deal with this by assuming that + * EIDRM means EINVAL in PGSharedMemoryIsInUse(). This is reasonably safe + * since in fact Linux has no excuse for ever returning EIDRM; it doesn't + * track removed segments in a way that would allow distinguishing them from + * private ones. But someday that code might get upgraded, and we'd have + * to have a kernel version test here. + */ +#define HAVE_LINUX_EIDRM_BUG + +/* + * Set the default wal_sync_method to fdatasync. With recent Linux versions, + * xlogdefs.h's normal rules will prefer open_datasync, which (a) doesn't + * perform better and (b) causes outright failures on ext4 data=journal + * filesystems, because those don't support O_DIRECT. + */ +#define PLATFORM_DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC diff --git a/install/include/postgresql/server/port/netbsd.h b/install/include/postgresql/server/port/netbsd.h new file mode 100644 index 00000000000..590233fbdb4 --- /dev/null +++ b/install/include/postgresql/server/port/netbsd.h @@ -0,0 +1 @@ +/* src/include/port/netbsd.h */ diff --git a/install/include/postgresql/server/port/openbsd.h b/install/include/postgresql/server/port/openbsd.h new file mode 100644 index 00000000000..395319bd77c --- /dev/null +++ b/install/include/postgresql/server/port/openbsd.h @@ -0,0 +1 @@ +/* src/include/port/openbsd.h */ diff --git a/install/include/postgresql/server/port/pg_bitutils.h b/install/include/postgresql/server/port/pg_bitutils.h new file mode 100644 index 00000000000..21a4fa03410 --- /dev/null +++ b/install/include/postgresql/server/port/pg_bitutils.h @@ -0,0 +1,339 @@ +/*------------------------------------------------------------------------- + * + * pg_bitutils.h + * Miscellaneous functions for bit-wise operations. + * + * + * Copyright (c) 2019-2023, PostgreSQL Global Development Group + * + * src/include/port/pg_bitutils.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_BITUTILS_H +#define PG_BITUTILS_H + +#ifdef _MSC_VER +#include +#define HAVE_BITSCAN_FORWARD +#define HAVE_BITSCAN_REVERSE + +#else +#if defined(HAVE__BUILTIN_CTZ) +#define HAVE_BITSCAN_FORWARD +#endif + +#if defined(HAVE__BUILTIN_CLZ) +#define HAVE_BITSCAN_REVERSE +#endif +#endif /* _MSC_VER */ + +extern PGDLLIMPORT const uint8 pg_leftmost_one_pos[256]; +extern PGDLLIMPORT const uint8 pg_rightmost_one_pos[256]; +extern PGDLLIMPORT const uint8 pg_number_of_ones[256]; + +/* + * pg_leftmost_one_pos32 + * Returns the position of the most significant set bit in "word", + * measured from the least significant bit. word must not be 0. + */ +static inline int +pg_leftmost_one_pos32(uint32 word) +{ +#ifdef HAVE__BUILTIN_CLZ + Assert(word != 0); + + return 31 - __builtin_clz(word); +#elif defined(_MSC_VER) + unsigned long result; + bool non_zero; + + non_zero = _BitScanReverse(&result, word); + Assert(non_zero); + return (int) result; +#else + int shift = 32 - 8; + + Assert(word != 0); + + while ((word >> shift) == 0) + shift -= 8; + + return shift + pg_leftmost_one_pos[(word >> shift) & 255]; +#endif /* HAVE__BUILTIN_CLZ */ +} + +/* + * pg_leftmost_one_pos64 + * As above, but for a 64-bit word. + */ +static inline int +pg_leftmost_one_pos64(uint64 word) +{ +#ifdef HAVE__BUILTIN_CLZ + Assert(word != 0); + +#if defined(HAVE_LONG_INT_64) + return 63 - __builtin_clzl(word); +#elif defined(HAVE_LONG_LONG_INT_64) + return 63 - __builtin_clzll(word); +#else +#error must have a working 64-bit integer datatype +#endif /* HAVE_LONG_INT_64 */ + +#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64)) + unsigned long result; + bool non_zero; + + non_zero = _BitScanReverse64(&result, word); + Assert(non_zero); + return (int) result; +#else + int shift = 64 - 8; + + Assert(word != 0); + + while ((word >> shift) == 0) + shift -= 8; + + return shift + pg_leftmost_one_pos[(word >> shift) & 255]; +#endif /* HAVE__BUILTIN_CLZ */ +} + +/* + * pg_rightmost_one_pos32 + * Returns the position of the least significant set bit in "word", + * measured from the least significant bit. word must not be 0. + */ +static inline int +pg_rightmost_one_pos32(uint32 word) +{ +#ifdef HAVE__BUILTIN_CTZ + Assert(word != 0); + + return __builtin_ctz(word); +#elif defined(_MSC_VER) + unsigned long result; + bool non_zero; + + non_zero = _BitScanForward(&result, word); + Assert(non_zero); + return (int) result; +#else + int result = 0; + + Assert(word != 0); + + while ((word & 255) == 0) + { + word >>= 8; + result += 8; + } + result += pg_rightmost_one_pos[word & 255]; + return result; +#endif /* HAVE__BUILTIN_CTZ */ +} + +/* + * pg_rightmost_one_pos64 + * As above, but for a 64-bit word. + */ +static inline int +pg_rightmost_one_pos64(uint64 word) +{ +#ifdef HAVE__BUILTIN_CTZ + Assert(word != 0); + +#if defined(HAVE_LONG_INT_64) + return __builtin_ctzl(word); +#elif defined(HAVE_LONG_LONG_INT_64) + return __builtin_ctzll(word); +#else +#error must have a working 64-bit integer datatype +#endif /* HAVE_LONG_INT_64 */ + +#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64)) + unsigned long result; + bool non_zero; + + non_zero = _BitScanForward64(&result, word); + Assert(non_zero); + return (int) result; +#else + int result = 0; + + Assert(word != 0); + + while ((word & 255) == 0) + { + word >>= 8; + result += 8; + } + result += pg_rightmost_one_pos[word & 255]; + return result; +#endif /* HAVE__BUILTIN_CTZ */ +} + +/* + * pg_nextpower2_32 + * Returns the next higher power of 2 above 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0 or be above PG_UINT32_MAX / 2 + 1. + */ +static inline uint32 +pg_nextpower2_32(uint32 num) +{ + Assert(num > 0 && num <= PG_UINT32_MAX / 2 + 1); + + /* + * A power 2 number has only 1 bit set. Subtracting 1 from such a number + * will turn on all previous bits resulting in no common bits being set + * between num and num-1. + */ + if ((num & (num - 1)) == 0) + return num; /* already power 2 */ + + return ((uint32) 1) << (pg_leftmost_one_pos32(num) + 1); +} + +/* + * pg_nextpower2_64 + * Returns the next higher power of 2 above 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0 or be above PG_UINT64_MAX / 2 + 1. + */ +static inline uint64 +pg_nextpower2_64(uint64 num) +{ + Assert(num > 0 && num <= PG_UINT64_MAX / 2 + 1); + + /* + * A power 2 number has only 1 bit set. Subtracting 1 from such a number + * will turn on all previous bits resulting in no common bits being set + * between num and num-1. + */ + if ((num & (num - 1)) == 0) + return num; /* already power 2 */ + + return ((uint64) 1) << (pg_leftmost_one_pos64(num) + 1); +} + +/* + * pg_prevpower2_32 + * Returns the next lower power of 2 below 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0. + */ +static inline uint32 +pg_prevpower2_32(uint32 num) +{ + return ((uint32) 1) << pg_leftmost_one_pos32(num); +} + +/* + * pg_prevpower2_64 + * Returns the next lower power of 2 below 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0. + */ +static inline uint64 +pg_prevpower2_64(uint64 num) +{ + return ((uint64) 1) << pg_leftmost_one_pos64(num); +} + +/* + * pg_ceil_log2_32 + * Returns equivalent of ceil(log2(num)) + */ +static inline uint32 +pg_ceil_log2_32(uint32 num) +{ + if (num < 2) + return 0; + else + return pg_leftmost_one_pos32(num - 1) + 1; +} + +/* + * pg_ceil_log2_64 + * Returns equivalent of ceil(log2(num)) + */ +static inline uint64 +pg_ceil_log2_64(uint64 num) +{ + if (num < 2) + return 0; + else + return pg_leftmost_one_pos64(num - 1) + 1; +} + +/* + * With MSVC on x86_64 builds, try using native popcnt instructions via the + * __popcnt and __popcnt64 intrinsics. These don't work the same as GCC's + * __builtin_popcount* intrinsic functions as they always emit popcnt + * instructions. + */ +#if defined(_MSC_VER) && defined(_M_AMD64) +#define HAVE_X86_64_POPCNTQ +#endif + +/* + * On x86_64, we can use the hardware popcount instruction, but only if + * we can verify that the CPU supports it via the cpuid instruction. + * + * Otherwise, we fall back to a hand-rolled implementation. + */ +#ifdef HAVE_X86_64_POPCNTQ +#if defined(HAVE__GET_CPUID) || defined(HAVE__CPUID) +#define TRY_POPCNT_FAST 1 +#endif +#endif + +#ifdef TRY_POPCNT_FAST +/* Attempt to use the POPCNT instruction, but perform a runtime check first */ +extern int (*pg_popcount32) (uint32 word); +extern int (*pg_popcount64) (uint64 word); + +#else +/* Use a portable implementation -- no need for a function pointer. */ +extern int pg_popcount32(uint32 word); +extern int pg_popcount64(uint64 word); + +#endif /* TRY_POPCNT_FAST */ + +/* Count the number of one-bits in a byte array */ +extern uint64 pg_popcount(const char *buf, int bytes); + +/* + * Rotate the bits of "word" to the right/left by n bits. + */ +static inline uint32 +pg_rotate_right32(uint32 word, int n) +{ + return (word >> n) | (word << (32 - n)); +} + +static inline uint32 +pg_rotate_left32(uint32 word, int n) +{ + return (word << n) | (word >> (32 - n)); +} + +/* size_t variants of the above, as required */ + +#if SIZEOF_SIZE_T == 4 +#define pg_leftmost_one_pos_size_t pg_leftmost_one_pos32 +#define pg_nextpower2_size_t pg_nextpower2_32 +#define pg_prevpower2_size_t pg_prevpower2_32 +#else +#define pg_leftmost_one_pos_size_t pg_leftmost_one_pos64 +#define pg_nextpower2_size_t pg_nextpower2_64 +#define pg_prevpower2_size_t pg_prevpower2_64 +#endif + +#endif /* PG_BITUTILS_H */ diff --git a/install/include/postgresql/server/port/pg_bswap.h b/install/include/postgresql/server/port/pg_bswap.h new file mode 100644 index 00000000000..80abd750d41 --- /dev/null +++ b/install/include/postgresql/server/port/pg_bswap.h @@ -0,0 +1,161 @@ +/*------------------------------------------------------------------------- + * + * pg_bswap.h + * Byte swapping. + * + * Macros for reversing the byte order of 16, 32 and 64-bit unsigned integers. + * For example, 0xAABBCCDD becomes 0xDDCCBBAA. These are just wrappers for + * built-in functions provided by the compiler where support exists. + * + * Note that all of these functions accept unsigned integers as arguments and + * return the same. Use caution when using these wrapper macros with signed + * integers. + * + * Copyright (c) 2015-2023, PostgreSQL Global Development Group + * + * src/include/port/pg_bswap.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_BSWAP_H +#define PG_BSWAP_H + + +/* + * In all supported versions msvc provides _byteswap_* functions in stdlib.h, + * already included by c.h. + */ + + +/* implementation of uint16 pg_bswap16(uint16) */ +#if defined(HAVE__BUILTIN_BSWAP16) + +#define pg_bswap16(x) __builtin_bswap16(x) + +#elif defined(_MSC_VER) + +#define pg_bswap16(x) _byteswap_ushort(x) + +#else + +static inline uint16 +pg_bswap16(uint16 x) +{ + return + ((x << 8) & 0xff00) | + ((x >> 8) & 0x00ff); +} + +#endif /* HAVE__BUILTIN_BSWAP16 */ + + +/* implementation of uint32 pg_bswap32(uint32) */ +#if defined(HAVE__BUILTIN_BSWAP32) + +#define pg_bswap32(x) __builtin_bswap32(x) + +#elif defined(_MSC_VER) + +#define pg_bswap32(x) _byteswap_ulong(x) + +#else + +static inline uint32 +pg_bswap32(uint32 x) +{ + return + ((x << 24) & 0xff000000) | + ((x << 8) & 0x00ff0000) | + ((x >> 8) & 0x0000ff00) | + ((x >> 24) & 0x000000ff); +} + +#endif /* HAVE__BUILTIN_BSWAP32 */ + + +/* implementation of uint64 pg_bswap64(uint64) */ +#if defined(HAVE__BUILTIN_BSWAP64) + +#define pg_bswap64(x) __builtin_bswap64(x) + + +#elif defined(_MSC_VER) + +#define pg_bswap64(x) _byteswap_uint64(x) + +#else + +static inline uint64 +pg_bswap64(uint64 x) +{ + return + ((x << 56) & UINT64CONST(0xff00000000000000)) | + ((x << 40) & UINT64CONST(0x00ff000000000000)) | + ((x << 24) & UINT64CONST(0x0000ff0000000000)) | + ((x << 8) & UINT64CONST(0x000000ff00000000)) | + ((x >> 8) & UINT64CONST(0x00000000ff000000)) | + ((x >> 24) & UINT64CONST(0x0000000000ff0000)) | + ((x >> 40) & UINT64CONST(0x000000000000ff00)) | + ((x >> 56) & UINT64CONST(0x00000000000000ff)); +} +#endif /* HAVE__BUILTIN_BSWAP64 */ + + +/* + * Portable and fast equivalents for ntohs, ntohl, htons, htonl, + * additionally extended to 64 bits. + */ +#ifdef WORDS_BIGENDIAN + +#define pg_hton16(x) (x) +#define pg_hton32(x) (x) +#define pg_hton64(x) (x) + +#define pg_ntoh16(x) (x) +#define pg_ntoh32(x) (x) +#define pg_ntoh64(x) (x) + +#else + +#define pg_hton16(x) pg_bswap16(x) +#define pg_hton32(x) pg_bswap32(x) +#define pg_hton64(x) pg_bswap64(x) + +#define pg_ntoh16(x) pg_bswap16(x) +#define pg_ntoh32(x) pg_bswap32(x) +#define pg_ntoh64(x) pg_bswap64(x) + +#endif /* WORDS_BIGENDIAN */ + + +/* + * Rearrange the bytes of a Datum from big-endian order into the native byte + * order. On big-endian machines, this does nothing at all. Note that the C + * type Datum is an unsigned integer type on all platforms. + * + * One possible application of the DatumBigEndianToNative() macro is to make + * bitwise comparisons cheaper. A simple 3-way comparison of Datums + * transformed by the macro (based on native, unsigned comparisons) will return + * the same result as a memcmp() of the corresponding original Datums, but can + * be much cheaper. It's generally safe to do this on big-endian systems + * without any special transformation occurring first. + * + * If SIZEOF_DATUM is not defined, then postgres.h wasn't included and these + * macros probably shouldn't be used, so we define nothing. Note that + * SIZEOF_DATUM == 8 would evaluate as 0 == 8 in that case, potentially + * leading to the wrong implementation being selected and confusing errors, so + * defining nothing is safest. + */ +#ifdef SIZEOF_DATUM +#ifdef WORDS_BIGENDIAN +#define DatumBigEndianToNative(x) (x) +#else /* !WORDS_BIGENDIAN */ +#if SIZEOF_DATUM == 8 +#define DatumBigEndianToNative(x) pg_bswap64(x) +#else /* SIZEOF_DATUM != 8 */ +#define DatumBigEndianToNative(x) pg_bswap32(x) +#endif /* SIZEOF_DATUM == 8 */ +#endif /* WORDS_BIGENDIAN */ +#endif /* SIZEOF_DATUM */ + +#endif /* PG_BSWAP_H */ diff --git a/install/include/postgresql/server/port/pg_crc32c.h b/install/include/postgresql/server/port/pg_crc32c.h new file mode 100644 index 00000000000..7f8779261c3 --- /dev/null +++ b/install/include/postgresql/server/port/pg_crc32c.h @@ -0,0 +1,101 @@ +/*------------------------------------------------------------------------- + * + * pg_crc32c.h + * Routines for computing CRC-32C checksums. + * + * The speed of CRC-32C calculation has a big impact on performance, so we + * jump through some hoops to get the best implementation for each + * platform. Some CPU architectures have special instructions for speeding + * up CRC calculations (e.g. Intel SSE 4.2), on other platforms we use the + * Slicing-by-8 algorithm which uses lookup tables. + * + * The public interface consists of four macros: + * + * INIT_CRC32C(crc) + * Initialize a CRC accumulator + * + * COMP_CRC32C(crc, data, len) + * Accumulate some (more) bytes into a CRC + * + * FIN_CRC32C(crc) + * Finish a CRC calculation + * + * EQ_CRC32C(c1, c2) + * Check for equality of two CRCs. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/pg_crc32c.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CRC32C_H +#define PG_CRC32C_H + +#include "port/pg_bswap.h" + +typedef uint32 pg_crc32c; + +/* The INIT and EQ macros are the same for all implementations. */ +#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF) +#define EQ_CRC32C(c1, c2) ((c1) == (c2)) + +#if defined(USE_SSE42_CRC32C) +/* Use Intel SSE4.2 instructions. */ +#define COMP_CRC32C(crc, data, len) \ + ((crc) = pg_comp_crc32c_sse42((crc), (data), (len))) +#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) + +extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len); + +#elif defined(USE_ARMV8_CRC32C) +/* Use ARMv8 CRC Extension instructions. */ + +#define COMP_CRC32C(crc, data, len) \ + ((crc) = pg_comp_crc32c_armv8((crc), (data), (len))) +#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) + +extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len); + +#elif defined(USE_SSE42_CRC32C_WITH_RUNTIME_CHECK) || defined(USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK) + +/* + * Use Intel SSE 4.2 or ARMv8 instructions, but perform a runtime check first + * to check that they are available. + */ +#define COMP_CRC32C(crc, data, len) \ + ((crc) = pg_comp_crc32c((crc), (data), (len))) +#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) + +extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len); +extern pg_crc32c (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len); + +#ifdef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK +extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len); +#endif +#ifdef USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK +extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len); +#endif + +#else +/* + * Use slicing-by-8 algorithm. + * + * On big-endian systems, the intermediate value is kept in reverse byte + * order, to avoid byte-swapping during the calculation. FIN_CRC32C reverses + * the bytes to the final order. + */ +#define COMP_CRC32C(crc, data, len) \ + ((crc) = pg_comp_crc32c_sb8((crc), (data), (len))) +#ifdef WORDS_BIGENDIAN +#define FIN_CRC32C(crc) ((crc) = pg_bswap32(crc) ^ 0xFFFFFFFF) +#else +#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) +#endif + +extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len); + +#endif + +#endif /* PG_CRC32C_H */ diff --git a/install/include/postgresql/server/port/pg_iovec.h b/install/include/postgresql/server/port/pg_iovec.h new file mode 100644 index 00000000000..5882c5b20f0 --- /dev/null +++ b/install/include/postgresql/server/port/pg_iovec.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * pg_iovec.h + * Header for vectored I/O functions, to use in place of . + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/pg_iovec.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_IOVEC_H +#define PG_IOVEC_H + +#ifndef WIN32 + +#include +#include + +#else + +/* Define our own POSIX-compatible iovec struct. */ +struct iovec +{ + void *iov_base; + size_t iov_len; +}; + +#endif + +/* + * If didn't define IOV_MAX, define our own. X/Open requires at + * least 16. (GNU Hurd apparently feel that they're not bound by X/Open, + * because they don't define this symbol at all.) + */ +#ifndef IOV_MAX +#define IOV_MAX 16 +#endif + +/* Define a reasonable maximum that is safe to use on the stack. */ +#define PG_IOV_MAX Min(IOV_MAX, 32) + +/* + * Note that pg_preadv and pg_pwritev have a pg_ prefix as a warning that the + * Windows implementations have the side-effect of changing the file position. + */ + +#if HAVE_DECL_PREADV +#define pg_preadv preadv +#else +extern ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); +#endif + +#if HAVE_DECL_PWRITEV +#define pg_pwritev pwritev +#else +extern ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); +#endif + +#endif /* PG_IOVEC_H */ diff --git a/install/include/postgresql/server/port/pg_lfind.h b/install/include/postgresql/server/port/pg_lfind.h new file mode 100644 index 00000000000..59aa8245edc --- /dev/null +++ b/install/include/postgresql/server/port/pg_lfind.h @@ -0,0 +1,180 @@ +/*------------------------------------------------------------------------- + * + * pg_lfind.h + * Optimized linear search routines using SIMD intrinsics where + * available. + * + * Copyright (c) 2022-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/port/pg_lfind.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LFIND_H +#define PG_LFIND_H + +#include "port/simd.h" + +/* + * pg_lfind8 + * + * Return true if there is an element in 'base' that equals 'key', otherwise + * return false. + */ +static inline bool +pg_lfind8(uint8 key, uint8 *base, uint32 nelem) +{ + uint32 i; + + /* round down to multiple of vector length */ + uint32 tail_idx = nelem & ~(sizeof(Vector8) - 1); + Vector8 chunk; + + for (i = 0; i < tail_idx; i += sizeof(Vector8)) + { + vector8_load(&chunk, &base[i]); + if (vector8_has(chunk, key)) + return true; + } + + /* Process the remaining elements one at a time. */ + for (; i < nelem; i++) + { + if (key == base[i]) + return true; + } + + return false; +} + +/* + * pg_lfind8_le + * + * Return true if there is an element in 'base' that is less than or equal to + * 'key', otherwise return false. + */ +static inline bool +pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem) +{ + uint32 i; + + /* round down to multiple of vector length */ + uint32 tail_idx = nelem & ~(sizeof(Vector8) - 1); + Vector8 chunk; + + for (i = 0; i < tail_idx; i += sizeof(Vector8)) + { + vector8_load(&chunk, &base[i]); + if (vector8_has_le(chunk, key)) + return true; + } + + /* Process the remaining elements one at a time. */ + for (; i < nelem; i++) + { + if (base[i] <= key) + return true; + } + + return false; +} + +/* + * pg_lfind32 + * + * Return true if there is an element in 'base' that equals 'key', otherwise + * return false. + */ +static inline bool +pg_lfind32(uint32 key, uint32 *base, uint32 nelem) +{ + uint32 i = 0; + +#ifndef USE_NO_SIMD + + /* + * For better instruction-level parallelism, each loop iteration operates + * on a block of four registers. Testing for SSE2 has showed this is ~40% + * faster than using a block of two registers. + */ + const Vector32 keys = vector32_broadcast(key); /* load copies of key */ + const uint32 nelem_per_vector = sizeof(Vector32) / sizeof(uint32); + const uint32 nelem_per_iteration = 4 * nelem_per_vector; + + /* round down to multiple of elements per iteration */ + const uint32 tail_idx = nelem & ~(nelem_per_iteration - 1); + +#if defined(USE_ASSERT_CHECKING) + bool assert_result = false; + + /* pre-compute the result for assert checking */ + for (i = 0; i < nelem; i++) + { + if (key == base[i]) + { + assert_result = true; + break; + } + } +#endif + + for (i = 0; i < tail_idx; i += nelem_per_iteration) + { + Vector32 vals1, + vals2, + vals3, + vals4, + result1, + result2, + result3, + result4, + tmp1, + tmp2, + result; + + /* load the next block into 4 registers */ + vector32_load(&vals1, &base[i]); + vector32_load(&vals2, &base[i + nelem_per_vector]); + vector32_load(&vals3, &base[i + nelem_per_vector * 2]); + vector32_load(&vals4, &base[i + nelem_per_vector * 3]); + + /* compare each value to the key */ + result1 = vector32_eq(keys, vals1); + result2 = vector32_eq(keys, vals2); + result3 = vector32_eq(keys, vals3); + result4 = vector32_eq(keys, vals4); + + /* combine the results into a single variable */ + tmp1 = vector32_or(result1, result2); + tmp2 = vector32_or(result3, result4); + result = vector32_or(tmp1, tmp2); + + /* see if there was a match */ + if (vector32_is_highbit_set(result)) + { + Assert(assert_result == true); + return true; + } + } +#endif /* ! USE_NO_SIMD */ + + /* Process the remaining elements one at a time. */ + for (; i < nelem; i++) + { + if (key == base[i]) + { +#ifndef USE_NO_SIMD + Assert(assert_result == true); +#endif + return true; + } + } + +#ifndef USE_NO_SIMD + Assert(assert_result == false); +#endif + return false; +} + +#endif /* PG_LFIND_H */ diff --git a/install/include/postgresql/server/port/pg_pthread.h b/install/include/postgresql/server/port/pg_pthread.h new file mode 100644 index 00000000000..d102ce9d6f3 --- /dev/null +++ b/install/include/postgresql/server/port/pg_pthread.h @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------- + * + * Declarations for missing POSIX thread components. + * + * Currently this supplies an implementation of pthread_barrier_t for the + * benefit of macOS, which lacks it. These declarations are not in port.h, + * because that'd require to be included by every translation + * unit. + * + *------------------------------------------------------------------------- + */ + +#ifndef PG_PTHREAD_H +#define PG_PTHREAD_H + +#include + +#ifndef HAVE_PTHREAD_BARRIER_WAIT + +#ifndef PTHREAD_BARRIER_SERIAL_THREAD +#define PTHREAD_BARRIER_SERIAL_THREAD (-1) +#endif + +typedef struct pg_pthread_barrier +{ + bool sense; /* we only need a one bit phase */ + int count; /* number of threads expected */ + int arrived; /* number of threads that have arrived */ + pthread_mutex_t mutex; + pthread_cond_t cond; +} pthread_barrier_t; + +extern int pthread_barrier_init(pthread_barrier_t *barrier, + const void *attr, + int count); +extern int pthread_barrier_wait(pthread_barrier_t *barrier); +extern int pthread_barrier_destroy(pthread_barrier_t *barrier); + +#endif + +#endif diff --git a/install/include/postgresql/server/port/simd.h b/install/include/postgresql/server/port/simd.h new file mode 100644 index 00000000000..1fa6c3bc6c4 --- /dev/null +++ b/install/include/postgresql/server/port/simd.h @@ -0,0 +1,375 @@ +/*------------------------------------------------------------------------- + * + * simd.h + * Support for platform-specific vector operations. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/simd.h + * + * NOTES + * - VectorN in this file refers to a register where the element operands + * are N bits wide. The vector width is platform-specific, so users that care + * about that will need to inspect "sizeof(VectorN)". + * + *------------------------------------------------------------------------- + */ +#ifndef SIMD_H +#define SIMD_H + +#if (defined(__x86_64__) || defined(_M_AMD64)) +/* + * SSE2 instructions are part of the spec for the 64-bit x86 ISA. We assume + * that compilers targeting this architecture understand SSE2 intrinsics. + * + * We use emmintrin.h rather than the comprehensive header immintrin.h in + * order to exclude extensions beyond SSE2. This is because MSVC, at least, + * will allow the use of intrinsics that haven't been enabled at compile + * time. + */ +#include +#define USE_SSE2 +typedef __m128i Vector8; +typedef __m128i Vector32; + +#elif defined(__aarch64__) && defined(__ARM_NEON) +/* + * We use the Neon instructions if the compiler provides access to them (as + * indicated by __ARM_NEON) and we are on aarch64. While Neon support is + * technically optional for aarch64, it appears that all available 64-bit + * hardware does have it. Neon exists in some 32-bit hardware too, but we + * could not realistically use it there without a run-time check, which seems + * not worth the trouble for now. + */ +#include +#define USE_NEON +typedef uint8x16_t Vector8; +typedef uint32x4_t Vector32; + +#else +/* + * If no SIMD instructions are available, we can in some cases emulate vector + * operations using bitwise operations on unsigned integers. Note that many + * of the functions in this file presently do not have non-SIMD + * implementations. In particular, none of the functions involving Vector32 + * are implemented without SIMD since it's likely not worthwhile to represent + * two 32-bit integers using a uint64. + */ +#define USE_NO_SIMD +typedef uint64 Vector8; +#endif + +/* load/store operations */ +static inline void vector8_load(Vector8 *v, const uint8 *s); +#ifndef USE_NO_SIMD +static inline void vector32_load(Vector32 *v, const uint32 *s); +#endif + +/* assignment operations */ +static inline Vector8 vector8_broadcast(const uint8 c); +#ifndef USE_NO_SIMD +static inline Vector32 vector32_broadcast(const uint32 c); +#endif + +/* element-wise comparisons to a scalar */ +static inline bool vector8_has(const Vector8 v, const uint8 c); +static inline bool vector8_has_zero(const Vector8 v); +static inline bool vector8_has_le(const Vector8 v, const uint8 c); +static inline bool vector8_is_highbit_set(const Vector8 v); +#ifndef USE_NO_SIMD +static inline bool vector32_is_highbit_set(const Vector32 v); +#endif + +/* arithmetic operations */ +static inline Vector8 vector8_or(const Vector8 v1, const Vector8 v2); +#ifndef USE_NO_SIMD +static inline Vector32 vector32_or(const Vector32 v1, const Vector32 v2); +static inline Vector8 vector8_ssub(const Vector8 v1, const Vector8 v2); +#endif + +/* + * comparisons between vectors + * + * Note: These return a vector rather than boolean, which is why we don't + * have non-SIMD implementations. + */ +#ifndef USE_NO_SIMD +static inline Vector8 vector8_eq(const Vector8 v1, const Vector8 v2); +static inline Vector32 vector32_eq(const Vector32 v1, const Vector32 v2); +#endif + +/* + * Load a chunk of memory into the given vector. + */ +static inline void +vector8_load(Vector8 *v, const uint8 *s) +{ +#if defined(USE_SSE2) + *v = _mm_loadu_si128((const __m128i *) s); +#elif defined(USE_NEON) + *v = vld1q_u8(s); +#else + memcpy(v, s, sizeof(Vector8)); +#endif +} + +#ifndef USE_NO_SIMD +static inline void +vector32_load(Vector32 *v, const uint32 *s) +{ +#ifdef USE_SSE2 + *v = _mm_loadu_si128((const __m128i *) s); +#elif defined(USE_NEON) + *v = vld1q_u32(s); +#endif +} +#endif /* ! USE_NO_SIMD */ + +/* + * Create a vector with all elements set to the same value. + */ +static inline Vector8 +vector8_broadcast(const uint8 c) +{ +#if defined(USE_SSE2) + return _mm_set1_epi8(c); +#elif defined(USE_NEON) + return vdupq_n_u8(c); +#else + return ~UINT64CONST(0) / 0xFF * c; +#endif +} + +#ifndef USE_NO_SIMD +static inline Vector32 +vector32_broadcast(const uint32 c) +{ +#ifdef USE_SSE2 + return _mm_set1_epi32(c); +#elif defined(USE_NEON) + return vdupq_n_u32(c); +#endif +} +#endif /* ! USE_NO_SIMD */ + +/* + * Return true if any elements in the vector are equal to the given scalar. + */ +static inline bool +vector8_has(const Vector8 v, const uint8 c) +{ + bool result; + + /* pre-compute the result for assert checking */ +#ifdef USE_ASSERT_CHECKING + bool assert_result = false; + + for (Size i = 0; i < sizeof(Vector8); i++) + { + if (((const uint8 *) &v)[i] == c) + { + assert_result = true; + break; + } + } +#endif /* USE_ASSERT_CHECKING */ + +#if defined(USE_NO_SIMD) + /* any bytes in v equal to c will evaluate to zero via XOR */ + result = vector8_has_zero(v ^ vector8_broadcast(c)); +#else + result = vector8_is_highbit_set(vector8_eq(v, vector8_broadcast(c))); +#endif + + Assert(assert_result == result); + return result; +} + +/* + * Convenience function equivalent to vector8_has(v, 0) + */ +static inline bool +vector8_has_zero(const Vector8 v) +{ +#if defined(USE_NO_SIMD) + /* + * We cannot call vector8_has() here, because that would lead to a + * circular definition. + */ + return vector8_has_le(v, 0); +#else + return vector8_has(v, 0); +#endif +} + +/* + * Return true if any elements in the vector are less than or equal to the + * given scalar. + */ +static inline bool +vector8_has_le(const Vector8 v, const uint8 c) +{ + bool result = false; + + /* pre-compute the result for assert checking */ +#ifdef USE_ASSERT_CHECKING + bool assert_result = false; + + for (Size i = 0; i < sizeof(Vector8); i++) + { + if (((const uint8 *) &v)[i] <= c) + { + assert_result = true; + break; + } + } +#endif /* USE_ASSERT_CHECKING */ + +#if defined(USE_NO_SIMD) + + /* + * To find bytes <= c, we can use bitwise operations to find bytes < c+1, + * but it only works if c+1 <= 128 and if the highest bit in v is not set. + * Adapted from + * https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord + */ + if ((int64) v >= 0 && c < 0x80) + result = (v - vector8_broadcast(c + 1)) & ~v & vector8_broadcast(0x80); + else + { + /* one byte at a time */ + for (Size i = 0; i < sizeof(Vector8); i++) + { + if (((const uint8 *) &v)[i] <= c) + { + result = true; + break; + } + } + } +#else + + /* + * Use saturating subtraction to find bytes <= c, which will present as + * NUL bytes. This approach is a workaround for the lack of unsigned + * comparison instructions on some architectures. + */ + result = vector8_has_zero(vector8_ssub(v, vector8_broadcast(c))); +#endif + + Assert(assert_result == result); + return result; +} + +/* + * Return true if the high bit of any element is set + */ +static inline bool +vector8_is_highbit_set(const Vector8 v) +{ +#ifdef USE_SSE2 + return _mm_movemask_epi8(v) != 0; +#elif defined(USE_NEON) + return vmaxvq_u8(v) > 0x7F; +#else + return v & vector8_broadcast(0x80); +#endif +} + +/* + * Exactly like vector8_is_highbit_set except for the input type, so it + * looks at each byte separately. + * + * XXX x86 uses the same underlying type for 8-bit, 16-bit, and 32-bit + * integer elements, but Arm does not, hence the need for a separate + * function. We could instead adopt the behavior of Arm's vmaxvq_u32(), i.e. + * check each 32-bit element, but that would require an additional mask + * operation on x86. + */ +#ifndef USE_NO_SIMD +static inline bool +vector32_is_highbit_set(const Vector32 v) +{ +#if defined(USE_NEON) + return vector8_is_highbit_set((Vector8) v); +#else + return vector8_is_highbit_set(v); +#endif +} +#endif /* ! USE_NO_SIMD */ + +/* + * Return the bitwise OR of the inputs + */ +static inline Vector8 +vector8_or(const Vector8 v1, const Vector8 v2) +{ +#ifdef USE_SSE2 + return _mm_or_si128(v1, v2); +#elif defined(USE_NEON) + return vorrq_u8(v1, v2); +#else + return v1 | v2; +#endif +} + +#ifndef USE_NO_SIMD +static inline Vector32 +vector32_or(const Vector32 v1, const Vector32 v2) +{ +#ifdef USE_SSE2 + return _mm_or_si128(v1, v2); +#elif defined(USE_NEON) + return vorrq_u32(v1, v2); +#endif +} +#endif /* ! USE_NO_SIMD */ + +/* + * Return the result of subtracting the respective elements of the input + * vectors using saturation (i.e., if the operation would yield a value less + * than zero, zero is returned instead). For more information on saturation + * arithmetic, see https://en.wikipedia.org/wiki/Saturation_arithmetic + */ +#ifndef USE_NO_SIMD +static inline Vector8 +vector8_ssub(const Vector8 v1, const Vector8 v2) +{ +#ifdef USE_SSE2 + return _mm_subs_epu8(v1, v2); +#elif defined(USE_NEON) + return vqsubq_u8(v1, v2); +#endif +} +#endif /* ! USE_NO_SIMD */ + +/* + * Return a vector with all bits set in each lane where the corresponding + * lanes in the inputs are equal. + */ +#ifndef USE_NO_SIMD +static inline Vector8 +vector8_eq(const Vector8 v1, const Vector8 v2) +{ +#ifdef USE_SSE2 + return _mm_cmpeq_epi8(v1, v2); +#elif defined(USE_NEON) + return vceqq_u8(v1, v2); +#endif +} +#endif /* ! USE_NO_SIMD */ + +#ifndef USE_NO_SIMD +static inline Vector32 +vector32_eq(const Vector32 v1, const Vector32 v2) +{ +#ifdef USE_SSE2 + return _mm_cmpeq_epi32(v1, v2); +#elif defined(USE_NEON) + return vceqq_u32(v1, v2); +#endif +} +#endif /* ! USE_NO_SIMD */ + +#endif /* SIMD_H */ diff --git a/install/include/postgresql/server/port/solaris.h b/install/include/postgresql/server/port/solaris.h new file mode 100644 index 00000000000..8ff40007c7f --- /dev/null +++ b/install/include/postgresql/server/port/solaris.h @@ -0,0 +1,35 @@ +/* src/include/port/solaris.h */ + +/* + * Sort this out for all operating systems some time. The __xxx + * symbols are defined on both GCC and Solaris CC, although GCC + * doesn't document them. The __xxx__ symbols are only on GCC. + */ +#if defined(__i386) && !defined(__i386__) +#define __i386__ +#endif + +#if defined(__amd64) && !defined(__amd64__) +#define __amd64__ +#endif + +#if defined(__x86_64) && !defined(__x86_64__) +#define __x86_64__ +#endif + +#if defined(__sparc) && !defined(__sparc__) +#define __sparc__ +#endif + +#if defined(__i386__) +#include +#endif + +/* + * On original Solaris, PAM conversation procs lack a "const" in their + * declaration; but recent OpenIndiana versions put it there by default. + * The least messy way to deal with this is to define _PAM_LEGACY_NONCONST, + * which causes OpenIndiana to declare pam_conv per the Solaris tradition, + * and also use that symbol to control omitting the "const" in our own code. + */ +#define _PAM_LEGACY_NONCONST 1 diff --git a/install/include/postgresql/server/port/win32.h b/install/include/postgresql/server/port/win32.h new file mode 100644 index 00000000000..d6c13d0bb8f --- /dev/null +++ b/install/include/postgresql/server/port/win32.h @@ -0,0 +1,59 @@ +/* src/include/port/win32.h */ + +/* + * We always rely on the WIN32 macro being set by our build system, + * but _WIN32 is the compiler pre-defined macro. So make sure we define + * WIN32 whenever _WIN32 is set, to facilitate standalone building. + */ +#if defined(_WIN32) && !defined(WIN32) +#define WIN32 +#endif + +/* + * Make sure _WIN32_WINNT has the minimum required value. + * Leave a higher value in place. The minimum requirement is Windows 10. + */ +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif + +#define _WIN32_WINNT 0x0A00 + +/* + * We need to prevent from defining a symbol conflicting with + * our errcode() function. Since it's likely to get included by standard + * system headers, pre-emptively include it now. + */ +#if defined(_MSC_VER) || defined(HAVE_CRTDEFS_H) +#define errcode __msvc_errcode +#include +#undef errcode +#endif + +/* + * defines for dynamic linking on Win32 platform + */ + +/* + * Variables declared in the core backend and referenced by loadable + * modules need to be marked "dllimport" in the core build, but + * "dllexport" when the declaration is read in a loadable module. + * No special markings should be used when compiling frontend code. + */ +#ifndef FRONTEND +#ifdef BUILDING_DLL +#define PGDLLIMPORT __declspec (dllexport) +#else +#define PGDLLIMPORT __declspec (dllimport) +#endif +#endif + +/* + * Functions exported by a loadable module must be marked "dllexport". + * + * While mingw would otherwise fall back to + * __attribute__((visibility("default"))), that appears to only work as long + * as no symbols are declared with __declspec(dllexport). But we can end up + * with some, e.g. plpython's Py_Init. + */ +#define PGDLLEXPORT __declspec (dllexport) diff --git a/install/include/postgresql/server/port/win32/arpa/inet.h b/install/include/postgresql/server/port/win32/arpa/inet.h new file mode 100644 index 00000000000..ad1803179c7 --- /dev/null +++ b/install/include/postgresql/server/port/win32/arpa/inet.h @@ -0,0 +1,3 @@ +/* src/include/port/win32/arpa/inet.h */ + +#include diff --git a/install/include/postgresql/server/port/win32/dlfcn.h b/install/include/postgresql/server/port/win32/dlfcn.h new file mode 100644 index 00000000000..b6e43c091d6 --- /dev/null +++ b/install/include/postgresql/server/port/win32/dlfcn.h @@ -0,0 +1 @@ +/* src/include/port/win32/dlfcn.h */ diff --git a/install/include/postgresql/server/port/win32/grp.h b/install/include/postgresql/server/port/win32/grp.h new file mode 100644 index 00000000000..8b4f21310e9 --- /dev/null +++ b/install/include/postgresql/server/port/win32/grp.h @@ -0,0 +1 @@ +/* src/include/port/win32/grp.h */ diff --git a/install/include/postgresql/server/port/win32/netdb.h b/install/include/postgresql/server/port/win32/netdb.h new file mode 100644 index 00000000000..9ed13e457b8 --- /dev/null +++ b/install/include/postgresql/server/port/win32/netdb.h @@ -0,0 +1,7 @@ +/* src/include/port/win32/netdb.h */ +#ifndef WIN32_NETDB_H +#define WIN32_NETDB_H + +#include + +#endif diff --git a/install/include/postgresql/server/port/win32/netinet/in.h b/install/include/postgresql/server/port/win32/netinet/in.h new file mode 100644 index 00000000000..a4e22f89f49 --- /dev/null +++ b/install/include/postgresql/server/port/win32/netinet/in.h @@ -0,0 +1,3 @@ +/* src/include/port/win32/netinet/in.h */ + +#include diff --git a/install/include/postgresql/server/port/win32/netinet/tcp.h b/install/include/postgresql/server/port/win32/netinet/tcp.h new file mode 100644 index 00000000000..1d377b6adc2 --- /dev/null +++ b/install/include/postgresql/server/port/win32/netinet/tcp.h @@ -0,0 +1,7 @@ +/* src/include/port/win32/netinet/tcp.h */ +#ifndef WIN32_NETINET_TCP_H +#define WIN32_NETINET_TCP_H + +#include + +#endif diff --git a/install/include/postgresql/server/port/win32/pwd.h b/install/include/postgresql/server/port/win32/pwd.h new file mode 100644 index 00000000000..b8c7178fc06 --- /dev/null +++ b/install/include/postgresql/server/port/win32/pwd.h @@ -0,0 +1,3 @@ +/* + * src/include/port/win32/pwd.h + */ diff --git a/install/include/postgresql/server/port/win32/sys/resource.h b/install/include/postgresql/server/port/win32/sys/resource.h new file mode 100644 index 00000000000..a14feeb5844 --- /dev/null +++ b/install/include/postgresql/server/port/win32/sys/resource.h @@ -0,0 +1,20 @@ +/* + * Replacement for for Windows. + */ +#ifndef WIN32_SYS_RESOURCE_H +#define WIN32_SYS_RESOURCE_H + +#include /* for struct timeval */ + +#define RUSAGE_SELF 0 +#define RUSAGE_CHILDREN (-1) + +struct rusage +{ + struct timeval ru_utime; /* user time used */ + struct timeval ru_stime; /* system time used */ +}; + +extern int getrusage(int who, struct rusage *rusage); + +#endif /* WIN32_SYS_RESOURCE_H */ diff --git a/install/include/postgresql/server/port/win32/sys/select.h b/install/include/postgresql/server/port/win32/sys/select.h new file mode 100644 index 00000000000..f8a877accd6 --- /dev/null +++ b/install/include/postgresql/server/port/win32/sys/select.h @@ -0,0 +1,3 @@ +/* + * src/include/port/win32/sys/select.h + */ diff --git a/install/include/postgresql/server/port/win32/sys/socket.h b/install/include/postgresql/server/port/win32/sys/socket.h new file mode 100644 index 00000000000..f2b475df5e5 --- /dev/null +++ b/install/include/postgresql/server/port/win32/sys/socket.h @@ -0,0 +1,34 @@ +/* + * src/include/port/win32/sys/socket.h + */ +#ifndef WIN32_SYS_SOCKET_H +#define WIN32_SYS_SOCKET_H + +/* + * Unfortunately, of VC++ also defines ERROR. + * To avoid the conflict, we include here and undefine ERROR + * immediately. + * + * Note: Don't include directly. It causes compile errors. + */ +#include +#include +#include + +#undef ERROR +#undef small + +/* Restore old ERROR value */ +#ifdef PGERROR +#define ERROR PGERROR +#endif + +/* + * We don't use the Windows gai_strerror[A] function because it is not + * thread-safe. We define our own in src/port/win32gai_strerror.c. + */ +#undef gai_strerror + +extern const char *gai_strerror(int ecode); + +#endif /* WIN32_SYS_SOCKET_H */ diff --git a/install/include/postgresql/server/port/win32/sys/un.h b/install/include/postgresql/server/port/win32/sys/un.h new file mode 100644 index 00000000000..4fc13a23fd1 --- /dev/null +++ b/install/include/postgresql/server/port/win32/sys/un.h @@ -0,0 +1,17 @@ +/* + * src/include/port/win32/sys/un.h + */ +#ifndef WIN32_SYS_UN_H +#define WIN32_SYS_UN_H + +/* + * Windows defines this structure in , but not all tool chains have + * the header yet, so we define it here for now. + */ +struct sockaddr_un +{ + unsigned short sun_family; + char sun_path[108]; +}; + +#endif diff --git a/install/include/postgresql/server/port/win32/sys/wait.h b/install/include/postgresql/server/port/win32/sys/wait.h new file mode 100644 index 00000000000..eaeb5661c98 --- /dev/null +++ b/install/include/postgresql/server/port/win32/sys/wait.h @@ -0,0 +1,3 @@ +/* + * src/include/port/win32/sys/wait.h + */ diff --git a/install/include/postgresql/server/port/win32_msvc/dirent.h b/install/include/postgresql/server/port/win32_msvc/dirent.h new file mode 100644 index 00000000000..62799db0014 --- /dev/null +++ b/install/include/postgresql/server/port/win32_msvc/dirent.h @@ -0,0 +1,34 @@ +/* + * Headers for port/dirent.c, win32 native implementation of dirent functions + * + * src/include/port/win32_msvc/dirent.h + */ + +#ifndef _WIN32VC_DIRENT_H +#define _WIN32VC_DIRENT_H +struct dirent +{ + long d_ino; + unsigned short d_reclen; + unsigned char d_type; + unsigned short d_namlen; + char d_name[MAX_PATH]; +}; + +typedef struct DIR DIR; + +DIR *opendir(const char *); +struct dirent *readdir(DIR *); +int closedir(DIR *); + +/* File types for 'd_type'. */ +#define DT_UNKNOWN 0 +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 +#define DT_WHT 14 +#endif diff --git a/install/include/postgresql/server/port/win32_msvc/sys/file.h b/install/include/postgresql/server/port/win32_msvc/sys/file.h new file mode 100644 index 00000000000..76be3e77740 --- /dev/null +++ b/install/include/postgresql/server/port/win32_msvc/sys/file.h @@ -0,0 +1 @@ +/* src/include/port/win32_msvc/sys/file.h */ diff --git a/install/include/postgresql/server/port/win32_msvc/sys/param.h b/install/include/postgresql/server/port/win32_msvc/sys/param.h new file mode 100644 index 00000000000..160df3b25e1 --- /dev/null +++ b/install/include/postgresql/server/port/win32_msvc/sys/param.h @@ -0,0 +1 @@ +/* src/include/port/win32_msvc/sys/param.h */ diff --git a/install/include/postgresql/server/port/win32_msvc/sys/time.h b/install/include/postgresql/server/port/win32_msvc/sys/time.h new file mode 100644 index 00000000000..9d943ecc6fa --- /dev/null +++ b/install/include/postgresql/server/port/win32_msvc/sys/time.h @@ -0,0 +1 @@ +/* src/include/port/win32_msvc/sys/time.h */ diff --git a/install/include/postgresql/server/port/win32_msvc/unistd.h b/install/include/postgresql/server/port/win32_msvc/unistd.h new file mode 100644 index 00000000000..b7795ba03c4 --- /dev/null +++ b/install/include/postgresql/server/port/win32_msvc/unistd.h @@ -0,0 +1,9 @@ +/* src/include/port/win32_msvc/unistd.h */ + +/* + * MSVC does not define these, nor does _fileno(stdin) etc reliably work + * (returns -1 if stdin/out/err are closed). + */ +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 diff --git a/install/include/postgresql/server/port/win32_msvc/utime.h b/install/include/postgresql/server/port/win32_msvc/utime.h new file mode 100644 index 00000000000..c78e79c33d3 --- /dev/null +++ b/install/include/postgresql/server/port/win32_msvc/utime.h @@ -0,0 +1,3 @@ +/* src/include/port/win32_msvc/utime.h */ + +#include /* for non-unicode version */ diff --git a/install/include/postgresql/server/port/win32_port.h b/install/include/postgresql/server/port/win32_port.h new file mode 100644 index 00000000000..8783378b950 --- /dev/null +++ b/install/include/postgresql/server/port/win32_port.h @@ -0,0 +1,589 @@ +/*------------------------------------------------------------------------- + * + * win32_port.h + * Windows-specific compatibility stuff. + * + * Note this is read in MinGW as well as native Windows builds, + * but not in Cygwin builds. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/win32_port.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_WIN32_PORT_H +#define PG_WIN32_PORT_H + +/* + * Always build with SSPI support. Keep it as a #define in case + * we want a switch to disable it sometime in the future. + */ +#define ENABLE_SSPI 1 + +/* undefine and redefine after #include */ +#undef mkdir + +#undef ERROR + +/* + * VS2013 and later issue warnings about using the old Winsock API, + * which we don't really want to hear about. + */ +#ifdef _MSC_VER +#define _WINSOCK_DEPRECATED_NO_WARNINGS +#endif + +/* + * The MinGW64 headers choke if this is already defined - they + * define it themselves. + */ +#if !defined(__MINGW64_VERSION_MAJOR) || defined(_MSC_VER) +#define _WINSOCKAPI_ +#endif + +/* + * windows.h includes a lot of other headers, slowing down compilation + * significantly. WIN32_LEAN_AND_MEAN reduces that a bit. It'd be better to + * remove the include of windows.h (as well as indirect inclusions of it) from + * such a central place, but until then... + * + * To be able to include ntstatus.h tell windows.h to not declare NTSTATUS by + * temporarily defining UMDF_USING_NTSTATUS, otherwise we'll get warning about + * macro redefinitions, as windows.h also defines NTSTATUS (yuck). That in + * turn requires including ntstatus.h, winternl.h to get common symbols. + */ +#define WIN32_LEAN_AND_MEAN +#define UMDF_USING_NTSTATUS + +#include +#include +#include +#include +#include + +#undef small +#include +#include +#include +#undef near + +/* needed before sys/stat hacking below: */ +#define fstat microsoft_native_fstat +#define stat microsoft_native_stat +#include +#undef fstat +#undef stat + +/* Must be here to avoid conflicting with prototype in windows.h */ +#define mkdir(a,b) mkdir(a) + +/* Windows doesn't have fsync() as such, use _commit() */ +#define fsync(fd) _commit(fd) + +/* + * For historical reasons, we allow setting wal_sync_method to + * fsync_writethrough on Windows, even though it's really identical to fsync + * (both code paths wind up at _commit()). + */ +#define HAVE_FSYNC_WRITETHROUGH +#define FSYNC_WRITETHROUGH_IS_FSYNC + +#define USES_WINSOCK + +/* + * IPC defines + */ +#undef HAVE_UNION_SEMUN +#define HAVE_UNION_SEMUN 1 + +#define IPC_RMID 256 +#define IPC_CREAT 512 +#define IPC_EXCL 1024 +#define IPC_PRIVATE 234564 +#define IPC_NOWAIT 2048 +#define IPC_STAT 4096 + +#define EACCESS 2048 +#ifndef EIDRM +#define EIDRM 4096 +#endif + +#define SETALL 8192 +#define GETNCNT 16384 +#define GETVAL 65536 +#define SETVAL 131072 +#define GETPID 262144 + + +/* + * Signal stuff + * + * For WIN32, there is no wait() call so there are no wait() macros + * to interpret the return value of system(). Instead, system() + * return values < 0x100 are used for exit() termination, and higher + * values are used to indicate non-exit() termination, which is + * similar to a unix-style signal exit (think SIGSEGV == + * STATUS_ACCESS_VIOLATION). Return values are broken up into groups: + * + * https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values + * + * NT_SUCCESS 0 - 0x3FFFFFFF + * NT_INFORMATION 0x40000000 - 0x7FFFFFFF + * NT_WARNING 0x80000000 - 0xBFFFFFFF + * NT_ERROR 0xC0000000 - 0xFFFFFFFF + * + * Effectively, we don't care on the severity of the return value from + * system(), we just need to know if it was because of exit() or generated + * by the system, and it seems values >= 0x100 are system-generated. + * See this URL for a list of WIN32 STATUS_* values: + * + * Wine (URL used in our error messages) - + * http://source.winehq.org/source/include/ntstatus.h + * Descriptions - + * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 + * + * The comprehensive exception list is included in ntstatus.h from the + * Windows Driver Kit (WDK). A subset of the list is also included in + * winnt.h from the Windows SDK. Defining WIN32_NO_STATUS before including + * windows.h helps to avoid any conflicts. + * + * Some day we might want to print descriptions for the most common + * exceptions, rather than printing an include file name. We could use + * RtlNtStatusToDosError() and pass to FormatMessage(), which can print + * the text of error values, but MinGW does not support + * RtlNtStatusToDosError(). + */ +#define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0) +#define WIFSIGNALED(w) (!WIFEXITED(w)) +#define WEXITSTATUS(w) (w) +#define WTERMSIG(w) (w) + +#define sigmask(sig) ( 1 << ((sig)-1) ) + +/* Signal function return values */ +#undef SIG_DFL +#undef SIG_ERR +#undef SIG_IGN +#define SIG_DFL ((pqsigfunc)0) +#define SIG_ERR ((pqsigfunc)-1) +#define SIG_IGN ((pqsigfunc)1) + +/* Some extra signals */ +#define SIGHUP 1 +#define SIGQUIT 3 +#define SIGTRAP 5 +#define SIGABRT 22 /* Set to match W32 value -- not UNIX value */ +#define SIGKILL 9 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGSTOP 17 +#define SIGTSTP 18 +#define SIGCONT 19 +#define SIGCHLD 20 +#define SIGWINCH 28 +#define SIGUSR1 30 +#define SIGUSR2 31 + +/* MinGW has gettimeofday(), but MSVC doesn't */ +#ifdef _MSC_VER +/* Last parameter not used */ +extern int gettimeofday(struct timeval *tp, void *tzp); +#endif + +/* for setitimer in backend/port/win32/timer.c */ +#define ITIMER_REAL 0 +struct itimerval +{ + struct timeval it_interval; + struct timeval it_value; +}; + +int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); + +/* Convenience wrapper for GetFileType() */ +extern DWORD pgwin32_get_file_type(HANDLE hFile); + +/* + * WIN32 does not provide 64-bit off_t, but does provide the functions operating + * with 64-bit offsets. Also, fseek() might not give an error for unseekable + * streams, so harden that function with our version. + */ +#define pgoff_t __int64 + +#ifdef _MSC_VER +extern int _pgfseeko64(FILE *stream, pgoff_t offset, int origin); +extern pgoff_t _pgftello64(FILE *stream); +#define fseeko(stream, offset, origin) _pgfseeko64(stream, offset, origin) +#define ftello(stream) _pgftello64(stream) +#else +#ifndef fseeko +#define fseeko(stream, offset, origin) fseeko64(stream, offset, origin) +#endif +#ifndef ftello +#define ftello(stream) ftello64(stream) +#endif +#endif + +/* + * Win32 also doesn't have symlinks, but we can emulate them with + * junction points on newer Win32 versions. + * + * Cygwin has its own symlinks which work on Win95/98/ME where + * junction points don't, so use those instead. We have no way of + * knowing what type of system Cygwin binaries will be run on. + * Note: Some CYGWIN includes might #define WIN32. + */ +extern int pgsymlink(const char *oldpath, const char *newpath); +extern int pgreadlink(const char *path, char *buf, size_t size); + +#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) +#define readlink(path, buf, size) pgreadlink(path, buf, size) + +/* + * Supplement to . + * + * Perl already has typedefs for uid_t and gid_t. + */ +#ifndef PLPERL_HAVE_UID_GID +typedef int uid_t; +typedef int gid_t; +#endif +typedef long key_t; + +#ifdef _MSC_VER +typedef int pid_t; +#endif + +/* + * Supplement to . + * + * We must pull in sys/stat.h before this part, else our overrides lose. + * + * stat() is not guaranteed to set the st_size field on win32, so we + * redefine it to our own implementation. See src/port/win32stat.c. + * + * The struct stat is 32 bit in MSVC, so we redefine it as a copy of + * struct __stat64. This also fixes the struct size for MINGW builds. + */ +struct stat /* This should match struct __stat64 */ +{ + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; +}; + +extern int _pgfstat64(int fileno, struct stat *buf); +extern int _pgstat64(const char *name, struct stat *buf); +extern int _pglstat64(const char *name, struct stat *buf); + +#define fstat(fileno, sb) _pgfstat64(fileno, sb) +#define stat(path, sb) _pgstat64(path, sb) +#define lstat(path, sb) _pglstat64(path, sb) + +/* These macros are not provided by older MinGW, nor by MSVC */ +#ifndef S_IRUSR +#define S_IRUSR _S_IREAD +#endif +#ifndef S_IWUSR +#define S_IWUSR _S_IWRITE +#endif +#ifndef S_IXUSR +#define S_IXUSR _S_IEXEC +#endif +#ifndef S_IRWXU +#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +#endif +#ifndef S_IRGRP +#define S_IRGRP 0 +#endif +#ifndef S_IWGRP +#define S_IWGRP 0 +#endif +#ifndef S_IXGRP +#define S_IXGRP 0 +#endif +#ifndef S_IRWXG +#define S_IRWXG 0 +#endif +#ifndef S_IROTH +#define S_IROTH 0 +#endif +#ifndef S_IWOTH +#define S_IWOTH 0 +#endif +#ifndef S_IXOTH +#define S_IXOTH 0 +#endif +#ifndef S_IRWXO +#define S_IRWXO 0 +#endif +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif +#ifndef S_ISREG +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + +/* + * In order for lstat() to be able to report junction points as symlinks, we + * need to hijack a bit in st_mode, since neither MSVC nor MinGW provides + * S_ISLNK and there aren't any spare bits. We'll steal the one for character + * devices, because we don't otherwise make use of those. + */ +#ifdef S_ISLNK +#error "S_ISLNK is already defined" +#endif +#ifdef S_IFLNK +#error "S_IFLNK is already defined" +#endif +#define S_IFLNK S_IFCHR +#define S_ISLNK(m) (((m) & S_IFLNK) == S_IFLNK) + +/* + * Supplement to . + * + * We borrow bits from the high end when we have to, to avoid colliding with + * the system-defined values. Our open() replacement in src/port/open.c + * converts these to the equivalent CreateFile() flags, along with the ones + * from fcntl.h. + */ +#define O_CLOEXEC 0x04000000 +#define O_DIRECT 0x80000000 +#define O_DSYNC _O_NOINHERIT + +/* + * Supplement to . + * + * We redefine network-related Berkeley error symbols as the corresponding WSA + * constants. This allows strerror.c to recognize them as being in the Winsock + * error code range and pass them off to win32_socket_strerror(), since + * Windows' version of plain strerror() won't cope. Note that this will break + * if these names are used for anything else besides Windows Sockets errors. + * See TranslateSocketError() when changing this list. + */ +#undef EAGAIN +#define EAGAIN WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#undef EMSGSIZE +#define EMSGSIZE WSAEMSGSIZE +#undef EAFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef ECONNABORTED +#define ECONNABORTED WSAECONNABORTED +#undef ECONNRESET +#define ECONNRESET WSAECONNRESET +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS +#undef EISCONN +#define EISCONN WSAEISCONN +#undef ENOBUFS +#define ENOBUFS WSAENOBUFS +#undef EPROTONOSUPPORT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#undef ECONNREFUSED +#define ECONNREFUSED WSAECONNREFUSED +#undef ENOTSOCK +#define ENOTSOCK WSAENOTSOCK +#undef EOPNOTSUPP +#define EOPNOTSUPP WSAEOPNOTSUPP +#undef EADDRINUSE +#define EADDRINUSE WSAEADDRINUSE +#undef EADDRNOTAVAIL +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL +#undef EHOSTDOWN +#define EHOSTDOWN WSAEHOSTDOWN +#undef EHOSTUNREACH +#define EHOSTUNREACH WSAEHOSTUNREACH +#undef ENETDOWN +#define ENETDOWN WSAENETDOWN +#undef ENETRESET +#define ENETRESET WSAENETRESET +#undef ENETUNREACH +#define ENETUNREACH WSAENETUNREACH +#undef ENOTCONN +#define ENOTCONN WSAENOTCONN +#undef ETIMEDOUT +#define ETIMEDOUT WSAETIMEDOUT + +/* + * Locale stuff. + * + * Extended locale functions with gratuitous underscore prefixes. + * (These APIs are nevertheless fully documented by Microsoft.) + */ +#define locale_t _locale_t +#define tolower_l _tolower_l +#define toupper_l _toupper_l +#define towlower_l _towlower_l +#define towupper_l _towupper_l +#define isdigit_l _isdigit_l +#define iswdigit_l _iswdigit_l +#define isalpha_l _isalpha_l +#define iswalpha_l _iswalpha_l +#define isalnum_l _isalnum_l +#define iswalnum_l _iswalnum_l +#define isupper_l _isupper_l +#define iswupper_l _iswupper_l +#define islower_l _islower_l +#define iswlower_l _iswlower_l +#define isgraph_l _isgraph_l +#define iswgraph_l _iswgraph_l +#define isprint_l _isprint_l +#define iswprint_l _iswprint_l +#define ispunct_l _ispunct_l +#define iswpunct_l _iswpunct_l +#define isspace_l _isspace_l +#define iswspace_l _iswspace_l +#define strcoll_l _strcoll_l +#define strxfrm_l _strxfrm_l +#define wcscoll_l _wcscoll_l +#define wcstombs_l _wcstombs_l +#define mbstowcs_l _mbstowcs_l + +/* + * Versions of libintl >= 0.18? try to replace setlocale() with a macro + * to their own versions. Remove the macro, if it exists, because it + * ends up calling the wrong version when the backend and libintl use + * different versions of msvcrt. + */ +#if defined(setlocale) +#undef setlocale +#endif + +/* + * Define our own wrapper macro around setlocale() to work around bugs in + * Windows' native setlocale() function. + */ +extern char *pgwin32_setlocale(int category, const char *locale); + +#define setlocale(a,b) pgwin32_setlocale(a,b) + + +/* In backend/port/win32/signal.c */ +extern PGDLLIMPORT volatile int pg_signal_queue; +extern PGDLLIMPORT int pg_signal_mask; +extern PGDLLIMPORT HANDLE pgwin32_signal_event; +extern PGDLLIMPORT HANDLE pgwin32_initial_signal_pipe; + +#define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask) +#define PG_SIGNAL_COUNT 32 + +extern void pgwin32_signal_initialize(void); +extern HANDLE pgwin32_create_signal_listener(pid_t pid); +extern void pgwin32_dispatch_queued_signals(void); +extern void pg_queue_signal(int signum); + +/* In src/port/kill.c */ +#define kill(pid,sig) pgkill(pid,sig) +extern int pgkill(int pid, int sig); + +/* In backend/port/win32/socket.c */ +#ifndef FRONTEND +#define socket(af, type, protocol) pgwin32_socket(af, type, protocol) +#define bind(s, addr, addrlen) pgwin32_bind(s, addr, addrlen) +#define listen(s, backlog) pgwin32_listen(s, backlog) +#define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen) +#define connect(s, name, namelen) pgwin32_connect(s, name, namelen) +#define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout) +#define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags) +#define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags) + +extern SOCKET pgwin32_socket(int af, int type, int protocol); +extern int pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen); +extern int pgwin32_listen(SOCKET s, int backlog); +extern SOCKET pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen); +extern int pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen); +extern int pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout); +extern int pgwin32_recv(SOCKET s, char *buf, int len, int flags); +extern int pgwin32_send(SOCKET s, const void *buf, int len, int flags); +extern int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout); + +extern PGDLLIMPORT int pgwin32_noblock; + +#endif /* FRONTEND */ + +/* in backend/port/win32_shmem.c */ +extern int pgwin32_ReserveSharedMemoryRegion(HANDLE); + +/* in backend/port/win32/crashdump.c */ +extern void pgwin32_install_crashdump_handler(void); + +/* in port/win32dlopen.c */ +extern void *dlopen(const char *file, int mode); +extern void *dlsym(void *handle, const char *symbol); +extern int dlclose(void *handle); +extern char *dlerror(void); + +#define RTLD_NOW 1 +#define RTLD_GLOBAL 0 + +/* in port/win32error.c */ +extern void _dosmaperr(unsigned long); + +/* in port/win32env.c */ +extern int pgwin32_putenv(const char *); +extern int pgwin32_setenv(const char *name, const char *value, int overwrite); +extern int pgwin32_unsetenv(const char *name); + +#define putenv(x) pgwin32_putenv(x) +#define setenv(x,y,z) pgwin32_setenv(x,y,z) +#define unsetenv(x) pgwin32_unsetenv(x) + +/* in port/win32security.c */ +extern int pgwin32_is_service(void); +extern int pgwin32_is_admin(void); + +/* Windows security token manipulation (in src/common/exec.c) */ +extern BOOL AddUserToTokenDacl(HANDLE hToken); + +/* Things that exist in MinGW headers, but need to be added to MSVC */ +#ifdef _MSC_VER + +#ifndef _WIN64 +typedef long ssize_t; +#else +typedef __int64 ssize_t; +#endif + +typedef unsigned short mode_t; + +#define F_OK 0 +#define W_OK 2 +#define R_OK 4 + +#endif /* _MSC_VER */ + +#if defined(__MINGW32__) || defined(__MINGW64__) +/* + * Mingw claims to have a strtof, and my reading of its source code suggests + * that it ought to work (and not need this hack), but the regression test + * results disagree with me; whether this is a version issue or not is not + * clear. However, using our wrapper (and the misrounded-input variant file, + * already required for supporting ancient systems) can't make things any + * worse, except for a tiny performance loss when reading zeros. + * + * See also cygwin.h for another instance of this. + */ +#define HAVE_BUGGY_STRTOF 1 +#endif + +/* in port/win32pread.c */ +extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset); + +/* in port/win32pwrite.c */ +extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset); + +#endif /* PG_WIN32_PORT_H */ diff --git a/install/include/postgresql/server/port/win32ntdll.h b/install/include/postgresql/server/port/win32ntdll.h new file mode 100644 index 00000000000..1ce9360ec12 --- /dev/null +++ b/install/include/postgresql/server/port/win32ntdll.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * win32ntdll.h + * Dynamically loaded Windows NT functions. + * + * Portions Copyright (c) 2021-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/port/win32ntdll.h + * + *------------------------------------------------------------------------- + */ + +#ifndef WIN32NTDLL_H +#define WIN32NTDLL_H + +#include +#include + +#ifndef FLUSH_FLAGS_FILE_DATA_SYNC_ONLY +#define FLUSH_FLAGS_FILE_DATA_SYNC_ONLY 0x4 +#endif + +typedef NTSTATUS (__stdcall * RtlGetLastNtStatus_t) (void); +typedef ULONG (__stdcall * RtlNtStatusToDosError_t) (NTSTATUS); +typedef NTSTATUS (__stdcall * NtFlushBuffersFileEx_t) (HANDLE, ULONG, PVOID, ULONG, PIO_STATUS_BLOCK); + +extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus; +extern PGDLLIMPORT RtlNtStatusToDosError_t pg_RtlNtStatusToDosError; +extern PGDLLIMPORT NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx; + +extern int initialize_ntdll(void); + +#endif /* WIN32NTDLL_H */ diff --git a/install/include/postgresql/server/portability/instr_time.h b/install/include/postgresql/server/portability/instr_time.h new file mode 100644 index 00000000000..cc85138e21f --- /dev/null +++ b/install/include/postgresql/server/portability/instr_time.h @@ -0,0 +1,197 @@ +/*------------------------------------------------------------------------- + * + * instr_time.h + * portable high-precision interval timing + * + * This file provides an abstraction layer to hide portability issues in + * interval timing. On Unix we use clock_gettime(), and on Windows we use + * QueryPerformanceCounter(). These macros also give some breathing room to + * use other high-precision-timing APIs. + * + * The basic data type is instr_time, which all callers should treat as an + * opaque typedef. instr_time can store either an absolute time (of + * unspecified reference time) or an interval. The operations provided + * for it are: + * + * INSTR_TIME_IS_ZERO(t) is t equal to zero? + * + * INSTR_TIME_SET_ZERO(t) set t to zero (memset is acceptable too) + * + * INSTR_TIME_SET_CURRENT(t) set t to current time + * + * INSTR_TIME_SET_CURRENT_LAZY(t) set t to current time if t is zero, + * evaluates to whether t changed + * + * INSTR_TIME_ADD(x, y) x += y + * + * INSTR_TIME_SUBTRACT(x, y) x -= y + * + * INSTR_TIME_ACCUM_DIFF(x, y, z) x += (y - z) + * + * INSTR_TIME_GET_DOUBLE(t) convert t to double (in seconds) + * + * INSTR_TIME_GET_MILLISEC(t) convert t to double (in milliseconds) + * + * INSTR_TIME_GET_MICROSEC(t) convert t to uint64 (in microseconds) + * + * INSTR_TIME_GET_NANOSEC(t) convert t to uint64 (in nanoseconds) + * + * Note that INSTR_TIME_SUBTRACT and INSTR_TIME_ACCUM_DIFF convert + * absolute times to intervals. The INSTR_TIME_GET_xxx operations are + * only useful on intervals. + * + * When summing multiple measurements, it's recommended to leave the + * running sum in instr_time form (ie, use INSTR_TIME_ADD or + * INSTR_TIME_ACCUM_DIFF) and convert to a result format only at the end. + * + * Beware of multiple evaluations of the macro arguments. + * + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/portability/instr_time.h + * + *------------------------------------------------------------------------- + */ +#ifndef INSTR_TIME_H +#define INSTR_TIME_H + + +/* + * We store interval times as an int64 integer on all platforms, as int64 is + * cheap to add/subtract, the most common operation for instr_time. The + * acquisition of time and converting to specific units of time is platform + * specific. + * + * To avoid users of the API relying on the integer representation, we wrap + * the 64bit integer in a struct. + */ +typedef struct instr_time +{ + int64 ticks; /* in platforms specific unit */ +} instr_time; + + +/* helpers macros used in platform specific code below */ + +#define NS_PER_S INT64CONST(1000000000) +#define NS_PER_MS INT64CONST(1000000) +#define NS_PER_US INT64CONST(1000) + + +#ifndef WIN32 + + +/* Use clock_gettime() */ + +#include + +/* + * The best clockid to use according to the POSIX spec is CLOCK_MONOTONIC, + * since that will give reliable interval timing even in the face of changes + * to the system clock. However, POSIX doesn't require implementations to + * provide anything except CLOCK_REALTIME, so fall back to that if we don't + * find CLOCK_MONOTONIC. + * + * Also, some implementations have nonstandard clockids with better properties + * than CLOCK_MONOTONIC. In particular, as of macOS 10.12, Apple provides + * CLOCK_MONOTONIC_RAW which is both faster to read and higher resolution than + * their version of CLOCK_MONOTONIC. + */ +#if defined(__darwin__) && defined(CLOCK_MONOTONIC_RAW) +#define PG_INSTR_CLOCK CLOCK_MONOTONIC_RAW +#elif defined(CLOCK_MONOTONIC) +#define PG_INSTR_CLOCK CLOCK_MONOTONIC +#else +#define PG_INSTR_CLOCK CLOCK_REALTIME +#endif + +/* helper for INSTR_TIME_SET_CURRENT */ +static inline instr_time +pg_clock_gettime_ns(void) +{ + instr_time now; + struct timespec tmp; + + clock_gettime(PG_INSTR_CLOCK, &tmp); + now.ticks = tmp.tv_sec * NS_PER_S + tmp.tv_nsec; + + return now; +} + +#define INSTR_TIME_SET_CURRENT(t) \ + ((t) = pg_clock_gettime_ns()) + +#define INSTR_TIME_GET_NANOSEC(t) \ + ((int64) (t).ticks) + + +#else /* WIN32 */ + + +/* Use QueryPerformanceCounter() */ + +/* helper for INSTR_TIME_SET_CURRENT */ +static inline instr_time +pg_query_performance_counter(void) +{ + instr_time now; + LARGE_INTEGER tmp; + + QueryPerformanceCounter(&tmp); + now.ticks = tmp.QuadPart; + + return now; +} + +static inline double +GetTimerFrequency(void) +{ + LARGE_INTEGER f; + + QueryPerformanceFrequency(&f); + return (double) f.QuadPart; +} + +#define INSTR_TIME_SET_CURRENT(t) \ + ((t) = pg_query_performance_counter()) + +#define INSTR_TIME_GET_NANOSEC(t) \ + ((int64) ((t).ticks * ((double) NS_PER_S / GetTimerFrequency()))) + +#endif /* WIN32 */ + + +/* + * Common macros + */ + +#define INSTR_TIME_IS_ZERO(t) ((t).ticks == 0) + + +#define INSTR_TIME_SET_ZERO(t) ((t).ticks = 0) + +#define INSTR_TIME_SET_CURRENT_LAZY(t) \ + (INSTR_TIME_IS_ZERO(t) ? INSTR_TIME_SET_CURRENT(t), true : false) + + +#define INSTR_TIME_ADD(x,y) \ + ((x).ticks += (y).ticks) + +#define INSTR_TIME_SUBTRACT(x,y) \ + ((x).ticks -= (y).ticks) + +#define INSTR_TIME_ACCUM_DIFF(x,y,z) \ + ((x).ticks += (y).ticks - (z).ticks) + + +#define INSTR_TIME_GET_DOUBLE(t) \ + ((double) INSTR_TIME_GET_NANOSEC(t) / NS_PER_S) + +#define INSTR_TIME_GET_MILLISEC(t) \ + ((double) INSTR_TIME_GET_NANOSEC(t) / NS_PER_MS) + +#define INSTR_TIME_GET_MICROSEC(t) \ + (INSTR_TIME_GET_NANOSEC(t) / NS_PER_US) + +#endif /* INSTR_TIME_H */ diff --git a/install/include/postgresql/server/portability/mem.h b/install/include/postgresql/server/portability/mem.h new file mode 100644 index 00000000000..92c56225ae7 --- /dev/null +++ b/install/include/postgresql/server/portability/mem.h @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------- + * + * mem.h + * portability definitions for various memory operations + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/portability/mem.h + * + *------------------------------------------------------------------------- + */ +#ifndef MEM_H +#define MEM_H + +#define IPCProtection (0600) /* access/modify by user only */ + +#ifdef SHM_SHARE_MMU /* use intimate shared memory on Solaris */ +#define PG_SHMAT_FLAGS SHM_SHARE_MMU +#else +#define PG_SHMAT_FLAGS 0 +#endif + +/* Linux prefers MAP_ANONYMOUS, but the flag is called MAP_ANON on other systems. */ +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +/* BSD-derived systems have MAP_HASSEMAPHORE, but it's not present (or needed) on Linux. */ +#ifndef MAP_HASSEMAPHORE +#define MAP_HASSEMAPHORE 0 +#endif + +/* + * BSD-derived systems use the MAP_NOSYNC flag to prevent dirty mmap(2) + * pages from being gratuitously flushed to disk. + */ +#ifndef MAP_NOSYNC +#define MAP_NOSYNC 0 +#endif + +#define PG_MMAP_FLAGS (MAP_SHARED|MAP_ANONYMOUS|MAP_HASSEMAPHORE) + +/* Some really old systems don't define MAP_FAILED. */ +#ifndef MAP_FAILED +#define MAP_FAILED ((void *) -1) +#endif + +#endif /* MEM_H */ diff --git a/install/include/postgresql/server/postgres.h b/install/include/postgresql/server/postgres.h new file mode 100644 index 00000000000..8a028ff789b --- /dev/null +++ b/install/include/postgresql/server/postgres.h @@ -0,0 +1,579 @@ +/*------------------------------------------------------------------------- + * + * postgres.h + * Primary include file for PostgreSQL server .c files + * + * This should be the first file included by PostgreSQL backend modules. + * Client-side code should include postgres_fe.h instead. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1995, Regents of the University of California + * + * src/include/postgres.h + * + *------------------------------------------------------------------------- + */ +/* + *---------------------------------------------------------------- + * TABLE OF CONTENTS + * + * When adding stuff to this file, please try to put stuff + * into the relevant section, or add new sections as appropriate. + * + * section description + * ------- ------------------------------------------------ + * 1) Datum type + support functions + * 2) miscellaneous + * + * NOTES + * + * In general, this file should contain declarations that are widely needed + * in the backend environment, but are of no interest outside the backend. + * + * Simple type definitions live in c.h, where they are shared with + * postgres_fe.h. We do that since those type definitions are needed by + * frontend modules that want to deal with binary data transmission to or + * from the backend. Type definitions in this file should be for + * representations that never escape the backend, such as Datum. + * + *---------------------------------------------------------------- + */ +#ifndef POSTGRES_H +#define POSTGRES_H + +#include "c.h" +#include "utils/elog.h" +#include "utils/palloc.h" + +/* ---------------------------------------------------------------- + * Section 1: Datum type + support functions + * ---------------------------------------------------------------- + */ + +/* + * A Datum contains either a value of a pass-by-value type or a pointer to a + * value of a pass-by-reference type. Therefore, we require: + * + * sizeof(Datum) == sizeof(void *) == 4 or 8 + * + * The functions below and the analogous functions for other types should be used to + * convert between a Datum and the appropriate C type. + */ + +typedef uintptr_t Datum; + +/* + * A NullableDatum is used in places where both a Datum and its nullness needs + * to be stored. This can be more efficient than storing datums and nullness + * in separate arrays, due to better spatial locality, even if more space may + * be wasted due to padding. + */ +typedef struct NullableDatum +{ +#define FIELDNO_NULLABLE_DATUM_DATUM 0 + Datum value; +#define FIELDNO_NULLABLE_DATUM_ISNULL 1 + bool isnull; + /* due to alignment padding this could be used for flags for free */ +} NullableDatum; + +#define SIZEOF_DATUM SIZEOF_VOID_P + +/* + * DatumGetBool + * Returns boolean value of a datum. + * + * Note: any nonzero value will be considered true. + */ +static inline bool +DatumGetBool(Datum X) +{ + return (X != 0); +} + +/* + * BoolGetDatum + * Returns datum representation for a boolean. + * + * Note: any nonzero value will be considered true. + */ +static inline Datum +BoolGetDatum(bool X) +{ + return (Datum) (X ? 1 : 0); +} + +/* + * DatumGetChar + * Returns character value of a datum. + */ +static inline char +DatumGetChar(Datum X) +{ + return (char) X; +} + +/* + * CharGetDatum + * Returns datum representation for a character. + */ +static inline Datum +CharGetDatum(char X) +{ + return (Datum) X; +} + +/* + * Int8GetDatum + * Returns datum representation for an 8-bit integer. + */ +static inline Datum +Int8GetDatum(int8 X) +{ + return (Datum) X; +} + +/* + * DatumGetUInt8 + * Returns 8-bit unsigned integer value of a datum. + */ +static inline uint8 +DatumGetUInt8(Datum X) +{ + return (uint8) X; +} + +/* + * UInt8GetDatum + * Returns datum representation for an 8-bit unsigned integer. + */ +static inline Datum +UInt8GetDatum(uint8 X) +{ + return (Datum) X; +} + +/* + * DatumGetInt16 + * Returns 16-bit integer value of a datum. + */ +static inline int16 +DatumGetInt16(Datum X) +{ + return (int16) X; +} + +/* + * Int16GetDatum + * Returns datum representation for a 16-bit integer. + */ +static inline Datum +Int16GetDatum(int16 X) +{ + return (Datum) X; +} + +/* + * DatumGetUInt16 + * Returns 16-bit unsigned integer value of a datum. + */ +static inline uint16 +DatumGetUInt16(Datum X) +{ + return (uint16) X; +} + +/* + * UInt16GetDatum + * Returns datum representation for a 16-bit unsigned integer. + */ +static inline Datum +UInt16GetDatum(uint16 X) +{ + return (Datum) X; +} + +/* + * DatumGetInt32 + * Returns 32-bit integer value of a datum. + */ +static inline int32 +DatumGetInt32(Datum X) +{ + return (int32) X; +} + +/* + * Int32GetDatum + * Returns datum representation for a 32-bit integer. + */ +static inline Datum +Int32GetDatum(int32 X) +{ + return (Datum) X; +} + +/* + * DatumGetUInt32 + * Returns 32-bit unsigned integer value of a datum. + */ +static inline uint32 +DatumGetUInt32(Datum X) +{ + return (uint32) X; +} + +/* + * UInt32GetDatum + * Returns datum representation for a 32-bit unsigned integer. + */ +static inline Datum +UInt32GetDatum(uint32 X) +{ + return (Datum) X; +} + +/* + * DatumGetObjectId + * Returns object identifier value of a datum. + */ +static inline Oid +DatumGetObjectId(Datum X) +{ + return (Oid) X; +} + +/* + * ObjectIdGetDatum + * Returns datum representation for an object identifier. + */ +static inline Datum +ObjectIdGetDatum(Oid X) +{ + return (Datum) X; +} + +/* + * DatumGetTransactionId + * Returns transaction identifier value of a datum. + */ +static inline TransactionId +DatumGetTransactionId(Datum X) +{ + return (TransactionId) X; +} + +/* + * TransactionIdGetDatum + * Returns datum representation for a transaction identifier. + */ +static inline Datum +TransactionIdGetDatum(TransactionId X) +{ + return (Datum) X; +} + +/* + * MultiXactIdGetDatum + * Returns datum representation for a multixact identifier. + */ +static inline Datum +MultiXactIdGetDatum(MultiXactId X) +{ + return (Datum) X; +} + +/* + * DatumGetCommandId + * Returns command identifier value of a datum. + */ +static inline CommandId +DatumGetCommandId(Datum X) +{ + return (CommandId) X; +} + +/* + * CommandIdGetDatum + * Returns datum representation for a command identifier. + */ +static inline Datum +CommandIdGetDatum(CommandId X) +{ + return (Datum) X; +} + +/* + * DatumGetPointer + * Returns pointer value of a datum. + */ +static inline Pointer +DatumGetPointer(Datum X) +{ + return (Pointer) X; +} + +/* + * PointerGetDatum + * Returns datum representation for a pointer. + */ +static inline Datum +PointerGetDatum(const void *X) +{ + return (Datum) X; +} + +/* + * DatumGetCString + * Returns C string (null-terminated string) value of a datum. + * + * Note: C string is not a full-fledged Postgres type at present, + * but type input functions use this conversion for their inputs. + */ +static inline char * +DatumGetCString(Datum X) +{ + return (char *) DatumGetPointer(X); +} + +/* + * CStringGetDatum + * Returns datum representation for a C string (null-terminated string). + * + * Note: C string is not a full-fledged Postgres type at present, + * but type output functions use this conversion for their outputs. + * Note: CString is pass-by-reference; caller must ensure the pointed-to + * value has adequate lifetime. + */ +static inline Datum +CStringGetDatum(const char *X) +{ + return PointerGetDatum(X); +} + +/* + * DatumGetName + * Returns name value of a datum. + */ +static inline Name +DatumGetName(Datum X) +{ + return (Name) DatumGetPointer(X); +} + +/* + * NameGetDatum + * Returns datum representation for a name. + * + * Note: Name is pass-by-reference; caller must ensure the pointed-to + * value has adequate lifetime. + */ +static inline Datum +NameGetDatum(const NameData *X) +{ + return CStringGetDatum(NameStr(*X)); +} + +/* + * DatumGetInt64 + * Returns 64-bit integer value of a datum. + * + * Note: this function hides whether int64 is pass by value or by reference. + */ +static inline int64 +DatumGetInt64(Datum X) +{ +#ifdef USE_FLOAT8_BYVAL + return (int64) X; +#else + return *((int64 *) DatumGetPointer(X)); +#endif +} + +/* + * Int64GetDatum + * Returns datum representation for a 64-bit integer. + * + * Note: if int64 is pass by reference, this function returns a reference + * to palloc'd space. + */ +#ifdef USE_FLOAT8_BYVAL +static inline Datum +Int64GetDatum(int64 X) +{ + return (Datum) X; +} +#else +extern Datum Int64GetDatum(int64 X); +#endif + + +/* + * DatumGetUInt64 + * Returns 64-bit unsigned integer value of a datum. + * + * Note: this function hides whether int64 is pass by value or by reference. + */ +static inline uint64 +DatumGetUInt64(Datum X) +{ +#ifdef USE_FLOAT8_BYVAL + return (uint64) X; +#else + return *((uint64 *) DatumGetPointer(X)); +#endif +} + +/* + * UInt64GetDatum + * Returns datum representation for a 64-bit unsigned integer. + * + * Note: if int64 is pass by reference, this function returns a reference + * to palloc'd space. + */ +static inline Datum +UInt64GetDatum(uint64 X) +{ +#ifdef USE_FLOAT8_BYVAL + return (Datum) X; +#else + return Int64GetDatum((int64) X); +#endif +} + +/* + * Float <-> Datum conversions + * + * These have to be implemented as inline functions rather than macros, when + * passing by value, because many machines pass int and float function + * parameters/results differently; so we need to play weird games with unions. + */ + +/* + * DatumGetFloat4 + * Returns 4-byte floating point value of a datum. + */ +static inline float4 +DatumGetFloat4(Datum X) +{ + union + { + int32 value; + float4 retval; + } myunion; + + myunion.value = DatumGetInt32(X); + return myunion.retval; +} + +/* + * Float4GetDatum + * Returns datum representation for a 4-byte floating point number. + */ +static inline Datum +Float4GetDatum(float4 X) +{ + union + { + float4 value; + int32 retval; + } myunion; + + myunion.value = X; + return Int32GetDatum(myunion.retval); +} + +/* + * DatumGetFloat8 + * Returns 8-byte floating point value of a datum. + * + * Note: this function hides whether float8 is pass by value or by reference. + */ +static inline float8 +DatumGetFloat8(Datum X) +{ +#ifdef USE_FLOAT8_BYVAL + union + { + int64 value; + float8 retval; + } myunion; + + myunion.value = DatumGetInt64(X); + return myunion.retval; +#else + return *((float8 *) DatumGetPointer(X)); +#endif +} + +/* + * Float8GetDatum + * Returns datum representation for an 8-byte floating point number. + * + * Note: if float8 is pass by reference, this function returns a reference + * to palloc'd space. + */ +#ifdef USE_FLOAT8_BYVAL +static inline Datum +Float8GetDatum(float8 X) +{ + union + { + float8 value; + int64 retval; + } myunion; + + myunion.value = X; + return Int64GetDatum(myunion.retval); +} +#else +extern Datum Float8GetDatum(float8 X); +#endif + + +/* + * Int64GetDatumFast + * Float8GetDatumFast + * + * These macros are intended to allow writing code that does not depend on + * whether int64 and float8 are pass-by-reference types, while not + * sacrificing performance when they are. The argument must be a variable + * that will exist and have the same value for as long as the Datum is needed. + * In the pass-by-ref case, the address of the variable is taken to use as + * the Datum. In the pass-by-val case, these are the same as the non-Fast + * functions, except for asserting that the variable is of the correct type. + */ + +#ifdef USE_FLOAT8_BYVAL +#define Int64GetDatumFast(X) \ + (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X)) +#define Float8GetDatumFast(X) \ + (AssertVariableIsOfTypeMacro(X, double), Float8GetDatum(X)) +#else +#define Int64GetDatumFast(X) \ + (AssertVariableIsOfTypeMacro(X, int64), PointerGetDatum(&(X))) +#define Float8GetDatumFast(X) \ + (AssertVariableIsOfTypeMacro(X, double), PointerGetDatum(&(X))) +#endif + + +/* ---------------------------------------------------------------- + * Section 2: miscellaneous + * ---------------------------------------------------------------- + */ + +/* + * NON_EXEC_STATIC: It's sometimes useful to define a variable or function + * that is normally static but extern when using EXEC_BACKEND (see + * pg_config_manual.h). There would then typically be some code in + * postmaster.c that uses those extern symbols to transfer state between + * processes or do whatever other things it needs to do in EXEC_BACKEND mode. + */ +#ifdef EXEC_BACKEND +#define NON_EXEC_STATIC +#else +#define NON_EXEC_STATIC static +#endif + +#endif /* POSTGRES_H */ diff --git a/install/include/postgresql/server/postgres_ext.h b/install/include/postgresql/server/postgres_ext.h new file mode 100644 index 00000000000..240ad4e93bf --- /dev/null +++ b/install/include/postgresql/server/postgres_ext.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * postgres_ext.h + * + * This file contains declarations of things that are visible everywhere + * in PostgreSQL *and* are visible to clients of frontend interface libraries. + * For example, the Oid type is part of the API of libpq and other libraries. + * + * Declarations which are specific to a particular interface should + * go in the header file for that interface (such as libpq-fe.h). This + * file is only for fundamental Postgres declarations. + * + * User-written C functions don't count as "external to Postgres." + * Those function much as local modifications to the backend itself, and + * use header files that are otherwise internal to Postgres to interface + * with the backend. + * + * src/include/postgres_ext.h + * + *------------------------------------------------------------------------- + */ + +#ifndef POSTGRES_EXT_H +#define POSTGRES_EXT_H + +#include "pg_config_ext.h" + +/* + * Object ID is a fundamental type in Postgres. + */ +typedef unsigned int Oid; + +#ifdef __cplusplus +#define InvalidOid (Oid(0)) +#else +#define InvalidOid ((Oid) 0) +#endif + +#define OID_MAX UINT_MAX +/* you will need to include to use the above #define */ + +#define atooid(x) ((Oid) strtoul((x), NULL, 10)) +/* the above needs */ + + +/* Define a signed 64-bit integer type for use in client API declarations. */ +typedef PG_INT64_TYPE pg_int64; + +/* + * Identifiers of error message fields. Kept here to keep common + * between frontend and backend, and also to export them to libpq + * applications. + */ +#define PG_DIAG_SEVERITY 'S' +#define PG_DIAG_SEVERITY_NONLOCALIZED 'V' +#define PG_DIAG_SQLSTATE 'C' +#define PG_DIAG_MESSAGE_PRIMARY 'M' +#define PG_DIAG_MESSAGE_DETAIL 'D' +#define PG_DIAG_MESSAGE_HINT 'H' +#define PG_DIAG_STATEMENT_POSITION 'P' +#define PG_DIAG_INTERNAL_POSITION 'p' +#define PG_DIAG_INTERNAL_QUERY 'q' +#define PG_DIAG_CONTEXT 'W' +#define PG_DIAG_SCHEMA_NAME 's' +#define PG_DIAG_TABLE_NAME 't' +#define PG_DIAG_COLUMN_NAME 'c' +#define PG_DIAG_DATATYPE_NAME 'd' +#define PG_DIAG_CONSTRAINT_NAME 'n' +#define PG_DIAG_SOURCE_FILE 'F' +#define PG_DIAG_SOURCE_LINE 'L' +#define PG_DIAG_SOURCE_FUNCTION 'R' + +#endif /* POSTGRES_EXT_H */ diff --git a/install/include/postgresql/server/postgres_fe.h b/install/include/postgresql/server/postgres_fe.h new file mode 100644 index 00000000000..5bc71dd0b37 --- /dev/null +++ b/install/include/postgresql/server/postgres_fe.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * postgres_fe.h + * Primary include file for PostgreSQL client-side .c files + * + * This should be the first file included by PostgreSQL client libraries and + * application programs --- but not by backend modules, which should include + * postgres.h. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1995, Regents of the University of California + * + * src/include/postgres_fe.h + * + *------------------------------------------------------------------------- + */ +#ifndef POSTGRES_FE_H +#define POSTGRES_FE_H + +#ifndef FRONTEND +#define FRONTEND 1 +#endif + +#include "c.h" + +#include "common/fe_memutils.h" + +#endif /* POSTGRES_FE_H */ diff --git a/install/include/postgresql/server/postmaster/autovacuum.h b/install/include/postgresql/server/postmaster/autovacuum.h new file mode 100644 index 00000000000..65afd1ea1e8 --- /dev/null +++ b/install/include/postgresql/server/postmaster/autovacuum.h @@ -0,0 +1,80 @@ +/*------------------------------------------------------------------------- + * + * autovacuum.h + * header file for integrated autovacuum daemon + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/postmaster/autovacuum.h + * + *------------------------------------------------------------------------- + */ +#ifndef AUTOVACUUM_H +#define AUTOVACUUM_H + +#include "storage/block.h" + +/* + * Other processes can request specific work from autovacuum, identified by + * AutoVacuumWorkItem elements. + */ +typedef enum +{ + AVW_BRINSummarizeRange +} AutoVacuumWorkItemType; + + +/* GUC variables */ +extern PGDLLIMPORT bool autovacuum_start_daemon; +extern PGDLLIMPORT int autovacuum_max_workers; +extern PGDLLIMPORT int autovacuum_work_mem; +extern PGDLLIMPORT int autovacuum_naptime; +extern PGDLLIMPORT int autovacuum_vac_thresh; +extern PGDLLIMPORT double autovacuum_vac_scale; +extern PGDLLIMPORT int autovacuum_vac_ins_thresh; +extern PGDLLIMPORT double autovacuum_vac_ins_scale; +extern PGDLLIMPORT int autovacuum_anl_thresh; +extern PGDLLIMPORT double autovacuum_anl_scale; +extern PGDLLIMPORT int autovacuum_freeze_max_age; +extern PGDLLIMPORT int autovacuum_multixact_freeze_max_age; +extern PGDLLIMPORT double autovacuum_vac_cost_delay; +extern PGDLLIMPORT int autovacuum_vac_cost_limit; + +/* autovacuum launcher PID, only valid when worker is shutting down */ +extern PGDLLIMPORT int AutovacuumLauncherPid; + +extern PGDLLIMPORT int Log_autovacuum_min_duration; + +/* Status inquiry functions */ +extern bool AutoVacuumingActive(void); +extern bool IsAutoVacuumLauncherProcess(void); +extern bool IsAutoVacuumWorkerProcess(void); + +#define IsAnyAutoVacuumProcess() \ + (IsAutoVacuumLauncherProcess() || IsAutoVacuumWorkerProcess()) + +/* Functions to start autovacuum process, called from postmaster */ +extern void autovac_init(void); +extern int StartAutoVacLauncher(void); +extern int StartAutoVacWorker(void); + +/* called from postmaster when a worker could not be forked */ +extern void AutoVacWorkerFailed(void); + +#ifdef EXEC_BACKEND +extern void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn(); +extern void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn(); +extern void AutovacuumWorkerIAm(void); +extern void AutovacuumLauncherIAm(void); +#endif + +extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type, + Oid relationId, BlockNumber blkno); + +/* shared memory stuff */ +extern Size AutoVacuumShmemSize(void); +extern void AutoVacuumShmemInit(void); + +#endif /* AUTOVACUUM_H */ diff --git a/install/include/postgresql/server/postmaster/auxprocess.h b/install/include/postgresql/server/postmaster/auxprocess.h new file mode 100644 index 00000000000..5c2d6527ff6 --- /dev/null +++ b/install/include/postgresql/server/postmaster/auxprocess.h @@ -0,0 +1,20 @@ +/*------------------------------------------------------------------------- + * auxprocess.h + * include file for functions related to auxiliary processes. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/postmaster/auxprocess.h + *------------------------------------------------------------------------- + */ +#ifndef AUXPROCESS_H +#define AUXPROCESS_H + +#include "miscadmin.h" + +extern void AuxiliaryProcessMain(AuxProcType auxtype) pg_attribute_noreturn(); + +#endif /* AUXPROCESS_H */ diff --git a/install/include/postgresql/server/postmaster/bgworker.h b/install/include/postgresql/server/postmaster/bgworker.h new file mode 100644 index 00000000000..845d4498e65 --- /dev/null +++ b/install/include/postgresql/server/postmaster/bgworker.h @@ -0,0 +1,162 @@ +/*-------------------------------------------------------------------- + * bgworker.h + * POSTGRES pluggable background workers interface + * + * A background worker is a process able to run arbitrary, user-supplied code, + * including normal transactions. + * + * Any external module loaded via shared_preload_libraries can register a + * worker. Workers can also be registered dynamically at runtime. In either + * case, the worker process is forked from the postmaster and runs the + * user-supplied "main" function. This code may connect to a database and + * run transactions. Workers can remain active indefinitely, but will be + * terminated if a shutdown or crash occurs. + * + * If the fork() call fails in the postmaster, it will try again later. Note + * that the failure can only be transient (fork failure due to high load, + * memory pressure, too many processes, etc); more permanent problems, like + * failure to connect to a database, are detected later in the worker and dealt + * with just by having the worker exit normally. A worker which exits with + * a return code of 0 will never be restarted and will be removed from worker + * list. A worker which exits with a return code of 1 will be restarted after + * the configured restart interval (unless that interval is BGW_NEVER_RESTART). + * The TerminateBackgroundWorker() function can be used to terminate a + * dynamically registered background worker; the worker will be sent a SIGTERM + * and will not be restarted after it exits. Whenever the postmaster knows + * that a worker will not be restarted, it unregisters the worker, freeing up + * that worker's slot for use by a new worker. + * + * Note that there might be more than one worker in a database concurrently, + * and the same module may request more than one worker running the same (or + * different) code. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/postmaster/bgworker.h + *-------------------------------------------------------------------- + */ +#ifndef BGWORKER_H +#define BGWORKER_H + +/*--------------------------------------------------------------------- + * External module API. + *--------------------------------------------------------------------- + */ + +/* + * Pass this flag to have your worker be able to connect to shared memory. + * This flag is required. + */ +#define BGWORKER_SHMEM_ACCESS 0x0001 + +/* + * This flag means the bgworker requires a database connection. The connection + * is not established automatically; the worker must establish it later. + * It requires that BGWORKER_SHMEM_ACCESS was passed too. + */ +#define BGWORKER_BACKEND_DATABASE_CONNECTION 0x0002 + +/* + * This class is used internally for parallel queries, to keep track of the + * number of active parallel workers and make sure we never launch more than + * max_parallel_workers parallel workers at the same time. Third party + * background workers should not use this class. + */ +#define BGWORKER_CLASS_PARALLEL 0x0010 +/* add additional bgworker classes here */ + + +typedef void (*bgworker_main_type) (Datum main_arg); + +/* + * Points in time at which a bgworker can request to be started + */ +typedef enum +{ + BgWorkerStart_PostmasterStart, + BgWorkerStart_ConsistentState, + BgWorkerStart_RecoveryFinished +} BgWorkerStartTime; + +#define BGW_DEFAULT_RESTART_INTERVAL 60 +#define BGW_NEVER_RESTART -1 +#define BGW_MAXLEN 96 +#define BGW_EXTRALEN 128 + +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]; + pid_t bgw_notify_pid; /* SIGUSR1 this backend on start/stop */ +} BackgroundWorker; + +typedef enum BgwHandleStatus +{ + BGWH_STARTED, /* worker is running */ + BGWH_NOT_YET_STARTED, /* worker hasn't been started yet */ + BGWH_STOPPED, /* worker has exited */ + BGWH_POSTMASTER_DIED /* postmaster died; worker status unclear */ +} BgwHandleStatus; + +struct BackgroundWorkerHandle; +typedef struct BackgroundWorkerHandle BackgroundWorkerHandle; + +/* Register a new bgworker during shared_preload_libraries */ +extern void RegisterBackgroundWorker(BackgroundWorker *worker); + +/* Register a new bgworker from a regular backend */ +extern bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker, + BackgroundWorkerHandle **handle); + +/* Query the status of a bgworker */ +extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, + pid_t *pidp); +extern BgwHandleStatus WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp); +extern BgwHandleStatus + WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *); +extern const char *GetBackgroundWorkerTypeByPid(pid_t pid); + +/* Terminate a bgworker */ +extern void TerminateBackgroundWorker(BackgroundWorkerHandle *handle); + +/* This is valid in a running worker */ +extern PGDLLIMPORT BackgroundWorker *MyBgworkerEntry; + +/* + * Connect to the specified database, as the specified user. Only a worker + * that passed BGWORKER_BACKEND_DATABASE_CONNECTION during registration may + * call this. + * + * If username is NULL, bootstrapping superuser is used. + * If dbname is NULL, connection is made to no specific database; + * only shared catalogs can be accessed. + */ +extern void BackgroundWorkerInitializeConnection(const char *dbname, const char *username, uint32 flags); + +/* Just like the above, but specifying database and user by OID. */ +extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags); + +/* + * Flags to BackgroundWorkerInitializeConnection et al + * + * + * Allow bypassing datallowconn restrictions when connecting to database + */ +#define BGWORKER_BYPASS_ALLOWCONN 1 + + +/* Block/unblock signals in a background worker process */ +extern void BackgroundWorkerBlockSignals(void); +extern void BackgroundWorkerUnblockSignals(void); + +#endif /* BGWORKER_H */ diff --git a/install/include/postgresql/server/postmaster/bgworker_internals.h b/install/include/postgresql/server/postmaster/bgworker_internals.h new file mode 100644 index 00000000000..4ad63fd9bd7 --- /dev/null +++ b/install/include/postgresql/server/postmaster/bgworker_internals.h @@ -0,0 +1,64 @@ +/*-------------------------------------------------------------------- + * bgworker_internals.h + * POSTGRES pluggable background workers internals + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/postmaster/bgworker_internals.h + *-------------------------------------------------------------------- + */ +#ifndef BGWORKER_INTERNALS_H +#define BGWORKER_INTERNALS_H + +#include "datatype/timestamp.h" +#include "lib/ilist.h" +#include "postmaster/bgworker.h" + +/* GUC options */ + +/* + * Maximum possible value of parallel workers. + */ +#define MAX_PARALLEL_WORKER_LIMIT 1024 + +/* + * List of background workers, private to postmaster. + * + * A worker that requests a database connection during registration will have + * rw_backend set, and will be present in BackendList. Note: do not rely on + * rw_backend being non-NULL for shmem-connected workers! + */ +typedef struct RegisteredBgWorker +{ + BackgroundWorker rw_worker; /* its registry entry */ + struct bkend *rw_backend; /* its BackendList entry, or NULL */ + pid_t rw_pid; /* 0 if not running */ + int rw_child_slot; + TimestampTz rw_crashed_at; /* if not 0, time it last crashed */ + int rw_shmem_slot; + bool rw_terminate; + slist_node rw_lnode; /* list link */ +} RegisteredBgWorker; + +extern PGDLLIMPORT slist_head BackgroundWorkerList; + +extern Size BackgroundWorkerShmemSize(void); +extern void BackgroundWorkerShmemInit(void); +extern void BackgroundWorkerStateChange(bool allow_new_workers); +extern void ForgetBackgroundWorker(slist_mutable_iter *cur); +extern void ReportBackgroundWorkerPID(RegisteredBgWorker *); +extern void ReportBackgroundWorkerExit(slist_mutable_iter *cur); +extern void BackgroundWorkerStopNotifications(pid_t pid); +extern void ForgetUnstartedBackgroundWorkers(void); +extern void ResetBackgroundWorkerCrashTimes(void); + +/* Function to start a background worker, called from postmaster.c */ +extern void StartBackgroundWorker(void) pg_attribute_noreturn(); + +#ifdef EXEC_BACKEND +extern BackgroundWorker *BackgroundWorkerEntry(int slotno); +#endif + +#endif /* BGWORKER_INTERNALS_H */ diff --git a/install/include/postgresql/server/postmaster/bgwriter.h b/install/include/postgresql/server/postmaster/bgwriter.h new file mode 100644 index 00000000000..a66722873f4 --- /dev/null +++ b/install/include/postgresql/server/postmaster/bgwriter.h @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------- + * + * bgwriter.h + * Exports from postmaster/bgwriter.c and postmaster/checkpointer.c. + * + * The bgwriter process used to handle checkpointing duties too. Now + * there is a separate process, but we did not bother to split this header. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/postmaster/bgwriter.h + * + *------------------------------------------------------------------------- + */ +#ifndef _BGWRITER_H +#define _BGWRITER_H + +#include "storage/block.h" +#include "storage/relfilelocator.h" +#include "storage/smgr.h" +#include "storage/sync.h" + + +/* GUC options */ +extern PGDLLIMPORT int BgWriterDelay; +extern PGDLLIMPORT int CheckPointTimeout; +extern PGDLLIMPORT int CheckPointWarning; +extern PGDLLIMPORT double CheckPointCompletionTarget; + +extern void BackgroundWriterMain(void) pg_attribute_noreturn(); +extern void CheckpointerMain(void) pg_attribute_noreturn(); + +extern void RequestCheckpoint(int flags); +extern void CheckpointWriteDelay(int flags, double progress); + +extern bool ForwardSyncRequest(const FileTag *ftag, SyncRequestType type); + +extern void AbsorbSyncRequests(void); + +extern Size CheckpointerShmemSize(void); +extern void CheckpointerShmemInit(void); + +extern bool FirstCallSinceLastCheckpoint(void); + +#endif /* _BGWRITER_H */ diff --git a/install/include/postgresql/server/postmaster/fork_process.h b/install/include/postgresql/server/postmaster/fork_process.h new file mode 100644 index 00000000000..12decc8133b --- /dev/null +++ b/install/include/postgresql/server/postmaster/fork_process.h @@ -0,0 +1,17 @@ +/*------------------------------------------------------------------------- + * + * fork_process.h + * Exports from postmaster/fork_process.c. + * + * Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/postmaster/fork_process.h + * + *------------------------------------------------------------------------- + */ +#ifndef FORK_PROCESS_H +#define FORK_PROCESS_H + +extern pid_t fork_process(void); + +#endif /* FORK_PROCESS_H */ diff --git a/install/include/postgresql/server/postmaster/interrupt.h b/install/include/postgresql/server/postmaster/interrupt.h new file mode 100644 index 00000000000..218f5ea3b12 --- /dev/null +++ b/install/include/postgresql/server/postmaster/interrupt.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * interrupt.h + * Interrupt handling routines. + * + * Responses to interrupts are fairly varied and many types of backends + * have their own implementations, but we provide a few generic things + * here to facilitate code reuse. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/postmaster/interrupt.h + * + *------------------------------------------------------------------------- + */ + +#ifndef INTERRUPT_H +#define INTERRUPT_H + +#include + +extern PGDLLIMPORT volatile sig_atomic_t ConfigReloadPending; +extern PGDLLIMPORT volatile sig_atomic_t ShutdownRequestPending; + +extern void HandleMainLoopInterrupts(void); +extern void SignalHandlerForConfigReload(SIGNAL_ARGS); +extern void SignalHandlerForCrashExit(SIGNAL_ARGS); +extern void SignalHandlerForShutdownRequest(SIGNAL_ARGS); + +#endif diff --git a/install/include/postgresql/server/postmaster/pgarch.h b/install/include/postgresql/server/postmaster/pgarch.h new file mode 100644 index 00000000000..3bd4fac71e5 --- /dev/null +++ b/install/include/postgresql/server/postmaster/pgarch.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * pgarch.h + * Exports from postmaster/pgarch.c. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/postmaster/pgarch.h + * + *------------------------------------------------------------------------- + */ +#ifndef _PGARCH_H +#define _PGARCH_H + +/* ---------- + * Archiver control info. + * + * We expect that archivable files within pg_wal will have names between + * MIN_XFN_CHARS and MAX_XFN_CHARS in length, consisting only of characters + * appearing in VALID_XFN_CHARS. The status files in archive_status have + * corresponding names with ".ready" or ".done" appended. + * ---------- + */ +#define MIN_XFN_CHARS 16 +#define MAX_XFN_CHARS 40 +#define VALID_XFN_CHARS "0123456789ABCDEF.history.backup.partial" + +extern Size PgArchShmemSize(void); +extern void PgArchShmemInit(void); +extern bool PgArchCanRestart(void); +extern void PgArchiverMain(void) pg_attribute_noreturn(); +extern void PgArchWakeup(void); +extern void PgArchForceDirScan(void); + +#endif /* _PGARCH_H */ diff --git a/install/include/postgresql/server/postmaster/postmaster.h b/install/include/postgresql/server/postmaster/postmaster.h new file mode 100644 index 00000000000..3b3889c58c0 --- /dev/null +++ b/install/include/postgresql/server/postmaster/postmaster.h @@ -0,0 +1,81 @@ +/*------------------------------------------------------------------------- + * + * postmaster.h + * Exports from postmaster/postmaster.c. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/postmaster/postmaster.h + * + *------------------------------------------------------------------------- + */ +#ifndef _POSTMASTER_H +#define _POSTMASTER_H + +/* GUC options */ +extern PGDLLIMPORT bool EnableSSL; +extern PGDLLIMPORT int SuperuserReservedConnections; +extern PGDLLIMPORT int ReservedConnections; +extern PGDLLIMPORT int PostPortNumber; +extern PGDLLIMPORT int Unix_socket_permissions; +extern PGDLLIMPORT char *Unix_socket_group; +extern PGDLLIMPORT char *Unix_socket_directories; +extern PGDLLIMPORT char *ListenAddresses; +extern PGDLLIMPORT bool ClientAuthInProgress; +extern PGDLLIMPORT int PreAuthDelay; +extern PGDLLIMPORT int AuthenticationTimeout; +extern PGDLLIMPORT bool Log_connections; +extern PGDLLIMPORT bool log_hostname; +extern PGDLLIMPORT bool enable_bonjour; +extern PGDLLIMPORT char *bonjour_name; +extern PGDLLIMPORT bool restart_after_crash; +extern PGDLLIMPORT bool remove_temp_files_after_crash; +extern PGDLLIMPORT bool send_abort_for_crash; +extern PGDLLIMPORT bool send_abort_for_kill; + +#ifdef WIN32 +extern PGDLLIMPORT HANDLE PostmasterHandle; +#else +extern PGDLLIMPORT int postmaster_alive_fds[2]; + +/* + * Constants that represent which of postmaster_alive_fds is held by + * postmaster, and which is used in children to check for postmaster death. + */ +#define POSTMASTER_FD_WATCH 0 /* used in children to check for + * postmaster death */ +#define POSTMASTER_FD_OWN 1 /* kept open by postmaster only */ +#endif + +extern PGDLLIMPORT const char *progname; + +extern void PostmasterMain(int argc, char *argv[]) pg_attribute_noreturn(); +extern void ClosePostmasterPorts(bool am_syslogger); +extern void InitProcessGlobals(void); + +extern int MaxLivePostmasterChildren(void); + +extern bool PostmasterMarkPIDForWorkerNotify(int); + +#ifdef EXEC_BACKEND +extern pid_t postmaster_forkexec(int argc, char *argv[]); +extern void SubPostmasterMain(int argc, char *argv[]) pg_attribute_noreturn(); + +extern Size ShmemBackendArraySize(void); +extern void ShmemBackendArrayAllocation(void); +#endif + +/* + * Note: MAX_BACKENDS is limited to 2^18-1 because that's the width reserved + * for buffer references in buf_internals.h. This limitation could be lifted + * by using a 64bit state; but it's unlikely to be worthwhile as 2^18-1 + * backends exceed currently realistic configurations. Even if that limitation + * were removed, we still could not a) exceed 2^23-1 because inval.c stores + * the backend ID as a 3-byte signed integer, b) INT_MAX/4 because some places + * compute 4*MaxBackends without any overflow check. This is rechecked in the + * relevant GUC check hooks and in RegisterBackgroundWorker(). + */ +#define MAX_BACKENDS 0x3FFFF + +#endif /* _POSTMASTER_H */ diff --git a/install/include/postgresql/server/postmaster/startup.h b/install/include/postgresql/server/postmaster/startup.h new file mode 100644 index 00000000000..6a2e4c4526b --- /dev/null +++ b/install/include/postgresql/server/postmaster/startup.h @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------- + * + * startup.h + * Exports from postmaster/startup.c. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/postmaster/startup.h + * + *------------------------------------------------------------------------- + */ +#ifndef _STARTUP_H +#define _STARTUP_H + +/* + * Log the startup progress message if a timer has expired. + */ +#define ereport_startup_progress(msg, ...) \ + do { \ + long secs; \ + int usecs; \ + if (has_startup_progress_timeout_expired(&secs, &usecs)) \ + ereport(LOG, errmsg(msg, secs, (usecs / 10000), __VA_ARGS__ )); \ + } while(0) + +extern PGDLLIMPORT int log_startup_progress_interval; + +extern void HandleStartupProcInterrupts(void); +extern void StartupProcessMain(void) pg_attribute_noreturn(); +extern void PreRestoreCommand(void); +extern void PostRestoreCommand(void); +extern bool IsPromoteSignaled(void); +extern void ResetPromoteSignaled(void); + +extern void enable_startup_progress_timeout(void); +extern void disable_startup_progress_timeout(void); +extern void begin_startup_progress_phase(void); +extern void startup_progress_timeout_handler(void); +extern bool has_startup_progress_timeout_expired(long *secs, int *usecs); + +#endif /* _STARTUP_H */ diff --git a/install/include/postgresql/server/postmaster/syslogger.h b/install/include/postgresql/server/postmaster/syslogger.h new file mode 100644 index 00000000000..34da778f1ef --- /dev/null +++ b/install/include/postgresql/server/postmaster/syslogger.h @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------------- + * + * syslogger.h + * Exports from postmaster/syslogger.c. + * + * Copyright (c) 2004-2023, PostgreSQL Global Development Group + * + * src/include/postmaster/syslogger.h + * + *------------------------------------------------------------------------- + */ +#ifndef _SYSLOGGER_H +#define _SYSLOGGER_H + +#include /* for PIPE_BUF */ + + +/* + * Primitive protocol structure for writing to syslogger pipe(s). The idea + * here is to divide long messages into chunks that are not more than + * PIPE_BUF bytes long, which according to POSIX spec must be written into + * the pipe atomically. The pipe reader then uses the protocol headers to + * reassemble the parts of a message into a single string. The reader can + * also cope with non-protocol data coming down the pipe, though we cannot + * guarantee long strings won't get split apart. + * + * We use non-nul bytes in is_last to make the protocol a tiny bit + * more robust against finding a false double nul byte prologue. But + * we still might find it in the len and/or pid bytes unless we're careful. + */ + +#ifdef PIPE_BUF +/* Are there any systems with PIPE_BUF > 64K? Unlikely, but ... */ +#if PIPE_BUF > 65536 +#define PIPE_CHUNK_SIZE 65536 +#else +#define PIPE_CHUNK_SIZE ((int) PIPE_BUF) +#endif +#else /* not defined */ +/* POSIX says the value of PIPE_BUF must be at least 512, so use that */ +#define PIPE_CHUNK_SIZE 512 +#endif + +typedef struct +{ + char nuls[2]; /* always \0\0 */ + uint16 len; /* size of this chunk (counts data only) */ + int32 pid; /* writer's pid */ + bits8 flags; /* bitmask of PIPE_PROTO_* */ + char data[FLEXIBLE_ARRAY_MEMBER]; /* data payload starts here */ +} PipeProtoHeader; + +typedef union +{ + PipeProtoHeader proto; + char filler[PIPE_CHUNK_SIZE]; +} PipeProtoChunk; + +#define PIPE_HEADER_SIZE offsetof(PipeProtoHeader, data) +#define PIPE_MAX_PAYLOAD ((int) (PIPE_CHUNK_SIZE - PIPE_HEADER_SIZE)) + +/* flag bits for PipeProtoHeader->flags */ +#define PIPE_PROTO_IS_LAST 0x01 /* last chunk of message? */ +/* log destinations */ +#define PIPE_PROTO_DEST_STDERR 0x10 +#define PIPE_PROTO_DEST_CSVLOG 0x20 +#define PIPE_PROTO_DEST_JSONLOG 0x40 + +/* GUC options */ +extern PGDLLIMPORT bool Logging_collector; +extern PGDLLIMPORT int Log_RotationAge; +extern PGDLLIMPORT int Log_RotationSize; +extern PGDLLIMPORT char *Log_directory; +extern PGDLLIMPORT char *Log_filename; +extern PGDLLIMPORT bool Log_truncate_on_rotation; +extern PGDLLIMPORT int Log_file_mode; + +#ifndef WIN32 +extern PGDLLIMPORT int syslogPipe[2]; +#else +extern PGDLLIMPORT HANDLE syslogPipe[2]; +#endif + + +extern int SysLogger_Start(void); + +extern void write_syslogger_file(const char *buffer, int count, int destination); + +#ifdef EXEC_BACKEND +extern void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn(); +#endif + +extern bool CheckLogrotateSignal(void); +extern void RemoveLogrotateSignalFiles(void); + +/* + * Name of files saving meta-data information about the log + * files currently in use by the syslogger + */ +#define LOG_METAINFO_DATAFILE "current_logfiles" +#define LOG_METAINFO_DATAFILE_TMP LOG_METAINFO_DATAFILE ".tmp" + +#endif /* _SYSLOGGER_H */ diff --git a/install/include/postgresql/server/postmaster/walwriter.h b/install/include/postgresql/server/postmaster/walwriter.h new file mode 100644 index 00000000000..6eba7ad79cf --- /dev/null +++ b/install/include/postgresql/server/postmaster/walwriter.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------- + * + * walwriter.h + * Exports from postmaster/walwriter.c. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/postmaster/walwriter.h + * + *------------------------------------------------------------------------- + */ +#ifndef _WALWRITER_H +#define _WALWRITER_H + +#define DEFAULT_WAL_WRITER_FLUSH_AFTER ((1024 * 1024) / XLOG_BLCKSZ) + +/* GUC options */ +extern PGDLLIMPORT int WalWriterDelay; +extern PGDLLIMPORT int WalWriterFlushAfter; + +extern void WalWriterMain(void) pg_attribute_noreturn(); + +#endif /* _WALWRITER_H */ diff --git a/install/include/postgresql/server/regex/regcustom.h b/install/include/postgresql/server/regex/regcustom.h new file mode 100644 index 00000000000..af0fe97c796 --- /dev/null +++ b/install/include/postgresql/server/regex/regcustom.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. + * + * Development of this software was funded, in part, by Cray Research Inc., + * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics + * Corporation, none of whom are responsible for the results. The author + * thanks all of them. + * + * Redistribution and use in source and binary forms -- with or without + * modification -- are permitted for any purpose, provided that + * redistributions in source form retain this entire copyright notice and + * indicate the origin and nature of any modifications. + * + * I'd appreciate being given credit for this package in the documentation + * of software which uses it, but that is not a requirement. + * + * THIS SOFTWARE IS PROVIDED ``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 + * HENRY SPENCER 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. + * + * src/include/regex/regcustom.h + */ + +/* headers if any */ + +/* + * It's against Postgres coding conventions to include postgres.h in a + * header file, but we allow the violation here because the regexp library + * files specifically intend this file to supply application-dependent + * headers, and are careful to include this file before anything else. + */ +#include "postgres.h" + +#include +#include +#include + +#include "mb/pg_wchar.h" + +#include "miscadmin.h" /* needed by rstacktoodeep */ + + +/* overrides for regguts.h definitions, if any */ +#define FUNCPTR(name, args) (*name) args +#define MALLOC(n) palloc_extended((n), MCXT_ALLOC_NO_OOM) +#define FREE(p) pfree(VS(p)) +#define REALLOC(p,n) repalloc_extended(VS(p),(n), MCXT_ALLOC_NO_OOM) +#define INTERRUPT(re) CHECK_FOR_INTERRUPTS() +#define assert(x) Assert(x) + +/* internal character type and related */ +typedef pg_wchar chr; /* the type itself */ +typedef unsigned uchr; /* unsigned type that will hold a chr */ + +#define CHR(c) ((unsigned char) (c)) /* turn char literal into chr literal */ +#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */ +#define CHRBITS 32 /* bits in a chr; must not use sizeof */ +#define CHR_MIN 0x00000000 /* smallest and largest chr; the value */ +#define CHR_MAX 0x7ffffffe /* CHR_MAX-CHR_MIN+1 must fit in an int, and + * CHR_MAX+1 must fit in a chr variable */ + +/* + * Check if a chr value is in range. Ideally we'd just write this as + * ((c) >= CHR_MIN && (c) <= CHR_MAX) + * However, if chr is unsigned and CHR_MIN is zero, the first part of that + * is a no-op, and certain overly-nannyish compilers give warnings about it. + * So we leave that out here. If you want to make chr signed and/or CHR_MIN + * not zero, redefine this macro as above. Callers should assume that the + * macro may multiply evaluate its argument, even though it does not today. + */ +#define CHR_IS_IN_RANGE(c) ((c) <= CHR_MAX) + +/* + * MAX_SIMPLE_CHR is the cutoff between "simple" and "complicated" processing + * in the color map logic. It should usually be chosen high enough to ensure + * that all common characters are <= MAX_SIMPLE_CHR. However, very large + * values will be counterproductive since they cause more regex setup time. + * Also, small values can be helpful for testing the high-color-map logic + * with plain old ASCII input. + */ +#define MAX_SIMPLE_CHR 0x7FF /* suitable value for Unicode */ + +/* functions operating on chr */ +#define iscalnum(x) pg_wc_isalnum(x) +#define iscalpha(x) pg_wc_isalpha(x) +#define iscdigit(x) pg_wc_isdigit(x) +#define iscspace(x) pg_wc_isspace(x) + +/* and pick up the standard header */ +#include "regex.h" diff --git a/install/include/postgresql/server/regex/regerrs.h b/install/include/postgresql/server/regex/regerrs.h new file mode 100644 index 00000000000..2c8873eb810 --- /dev/null +++ b/install/include/postgresql/server/regex/regerrs.h @@ -0,0 +1,83 @@ +/* + * src/include/regex/regerrs.h + */ + +{ + REG_OKAY, "REG_OKAY", "no errors detected" +}, + +{ + REG_NOMATCH, "REG_NOMATCH", "failed to match" +}, + +{ + REG_BADPAT, "REG_BADPAT", "invalid regexp (reg version 0.8)" +}, + +{ + REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element" +}, + +{ + REG_ECTYPE, "REG_ECTYPE", "invalid character class" +}, + +{ + REG_EESCAPE, "REG_EESCAPE", "invalid escape \\ sequence" +}, + +{ + REG_ESUBREG, "REG_ESUBREG", "invalid backreference number" +}, + +{ + REG_EBRACK, "REG_EBRACK", "brackets [] not balanced" +}, + +{ + REG_EPAREN, "REG_EPAREN", "parentheses () not balanced" +}, + +{ + REG_EBRACE, "REG_EBRACE", "braces {} not balanced" +}, + +{ + REG_BADBR, "REG_BADBR", "invalid repetition count(s)" +}, + +{ + REG_ERANGE, "REG_ERANGE", "invalid character range" +}, + +{ + REG_ESPACE, "REG_ESPACE", "out of memory" +}, + +{ + REG_BADRPT, "REG_BADRPT", "quantifier operand invalid" +}, + +{ + REG_ASSERT, "REG_ASSERT", "\"cannot happen\" -- you found a bug" +}, + +{ + REG_INVARG, "REG_INVARG", "invalid argument to regex function" +}, + +{ + REG_MIXED, "REG_MIXED", "character widths of regex and string differ" +}, + +{ + REG_BADOPT, "REG_BADOPT", "invalid embedded option" +}, + +{ + REG_ETOOBIG, "REG_ETOOBIG", "regular expression is too complex" +}, + +{ + REG_ECOLORS, "REG_ECOLORS", "too many colors" +}, diff --git a/install/include/postgresql/server/regex/regex.h b/install/include/postgresql/server/regex/regex.h new file mode 100644 index 00000000000..f34ee3a85bd --- /dev/null +++ b/install/include/postgresql/server/regex/regex.h @@ -0,0 +1,272 @@ +#ifndef _PG_REGEX_H_ +#define _PG_REGEX_H_ /* never again */ +/* + * regular expressions + * + * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. + * + * Development of this software was funded, in part, by Cray Research Inc., + * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics + * Corporation, none of whom are responsible for the results. The author + * thanks all of them. + * + * Redistribution and use in source and binary forms -- with or without + * modification -- are permitted for any purpose, provided that + * redistributions in source form retain this entire copyright notice and + * indicate the origin and nature of any modifications. + * + * I'd appreciate being given credit for this package in the documentation + * of software which uses it, but that is not a requirement. + * + * THIS SOFTWARE IS PROVIDED ``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 + * HENRY SPENCER 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. + * + * src/include/regex/regex.h + */ + +/* + * This is an implementation of POSIX regex_t, so it clashes with the + * system-provided header. That header might be unintentionally + * included already, so we force that to happen now on all systems to show that + * we can cope and that we completely replace the system regex interfaces. + * + * Note that we avoided using _REGEX_H_ as an include guard, as that confuses + * matters on BSD family systems including macOS that use the same include + * guard. + */ +#ifndef _WIN32 +#include +#endif + +/* Avoid redefinition errors due to the system header. */ +#undef REG_UBACKREF +#undef REG_ULOOKAROUND +#undef REG_UBOUNDS +#undef REG_UBRACES +#undef REG_UBSALNUM +#undef REG_UPBOTCH +#undef REG_UBBS +#undef REG_UNONPOSIX +#undef REG_UUNSPEC +#undef REG_UUNPORT +#undef REG_ULOCALE +#undef REG_UEMPTYMATCH +#undef REG_UIMPOSSIBLE +#undef REG_USHORTEST +#undef REG_BASIC +#undef REG_EXTENDED +#undef REG_ADVF +#undef REG_ADVANCED +#undef REG_QUOTE +#undef REG_NOSPEC +#undef REG_ICASE +#undef REG_NOSUB +#undef REG_EXPANDED +#undef REG_NLSTOP +#undef REG_NLANCH +#undef REG_NEWLINE +#undef REG_PEND +#undef REG_EXPECT +#undef REG_BOSONLY +#undef REG_DUMP +#undef REG_FAKE +#undef REG_PROGRESS +#undef REG_NOTBOL +#undef REG_NOTEOL +#undef REG_STARTEND +#undef REG_FTRACE +#undef REG_MTRACE +#undef REG_SMALL +#undef REG_OKAY +#undef REG_NOMATCH +#undef REG_BADPAT +#undef REG_ECOLLATE +#undef REG_ECTYPE +#undef REG_EESCAPE +#undef REG_ESUBREG +#undef REG_EBRACK +#undef REG_EPAREN +#undef REG_EBRACE +#undef REG_BADBR +#undef REG_ERANGE +#undef REG_ESPACE +#undef REG_BADRPT +#undef REG_ASSERT +#undef REG_INVARG +#undef REG_MIXED +#undef REG_BADOPT +#undef REG_ETOOBIG +#undef REG_ECOLORS +#undef REG_ATOI +#undef REG_ITOA +#undef REG_PREFIX +#undef REG_EXACT + +/* + * Add your own defines, if needed, here. + */ +#include "mb/pg_wchar.h" + +/* + * interface types etc. + */ + +/* + * regoff_t has to be large enough to hold either off_t or ssize_t, + * and must be signed; it's only a guess that long is suitable. + */ +typedef long pg_regoff_t; + +/* + * other interface types + */ + +/* the biggie, a compiled RE (or rather, a front end to same) */ +typedef struct +{ + int re_magic; /* magic number */ + size_t re_nsub; /* number of subexpressions */ + long re_info; /* bitmask of the following flags: */ +#define REG_UBACKREF 000001 /* has back-reference (\n) */ +#define REG_ULOOKAROUND 000002 /* has lookahead/lookbehind constraint */ +#define REG_UBOUNDS 000004 /* has bounded quantifier ({m,n}) */ +#define REG_UBRACES 000010 /* has { that doesn't begin a quantifier */ +#define REG_UBSALNUM 000020 /* has backslash-alphanumeric in non-ARE */ +#define REG_UPBOTCH 000040 /* has unmatched right paren in ERE (legal + * per spec, but that was a mistake) */ +#define REG_UBBS 000100 /* has backslash within bracket expr */ +#define REG_UNONPOSIX 000200 /* has any construct that extends POSIX */ +#define REG_UUNSPEC 000400 /* has any case disallowed by POSIX, e.g. + * an empty branch */ +#define REG_UUNPORT 001000 /* has numeric character code dependency */ +#define REG_ULOCALE 002000 /* has locale dependency */ +#define REG_UEMPTYMATCH 004000 /* can match a zero-length string */ +#define REG_UIMPOSSIBLE 010000 /* provably cannot match anything */ +#define REG_USHORTEST 020000 /* has non-greedy quantifier */ + int re_csize; /* sizeof(character) */ + char *re_endp; /* backward compatibility kludge */ + Oid re_collation; /* Collation that defines LC_CTYPE behavior */ + /* the rest is opaque pointers to hidden innards */ + char *re_guts; /* `char *' is more portable than `void *' */ + char *re_fns; +} pg_regex_t; + +/* result reporting (may acquire more fields later) */ +typedef struct +{ + pg_regoff_t rm_so; /* start of substring */ + pg_regoff_t rm_eo; /* end of substring */ +} pg_regmatch_t; + +/* supplementary control and reporting */ +typedef struct +{ + pg_regmatch_t rm_extend; /* see REG_EXPECT */ +} rm_detail_t; + + + +/* + * regex compilation flags + */ +#define REG_BASIC 000000 /* BREs (convenience) */ +#define REG_EXTENDED 000001 /* EREs */ +#define REG_ADVF 000002 /* advanced features in EREs */ +#define REG_ADVANCED 000003 /* AREs (which are also EREs) */ +#define REG_QUOTE 000004 /* no special characters, none */ +#define REG_NOSPEC REG_QUOTE /* historical synonym */ +#define REG_ICASE 000010 /* ignore case */ +#define REG_NOSUB 000020 /* caller doesn't need subexpr match data */ +#define REG_EXPANDED 000040 /* expanded format, white space & comments */ +#define REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */ +#define REG_NLANCH 000200 /* ^ matches after \n, $ before */ +#define REG_NEWLINE 000300 /* newlines are line terminators */ +#define REG_PEND 000400 /* ugh -- backward-compatibility hack */ +#define REG_EXPECT 001000 /* report details on partial/limited matches */ +#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */ +#define REG_DUMP 004000 /* none of your business :-) */ +#define REG_FAKE 010000 /* none of your business :-) */ +#define REG_PROGRESS 020000 /* none of your business :-) */ + + + +/* + * regex execution flags + */ +#define REG_NOTBOL 0001 /* BOS is not BOL */ +#define REG_NOTEOL 0002 /* EOS is not EOL */ +#define REG_STARTEND 0004 /* backward compatibility kludge */ +#define REG_FTRACE 0010 /* none of your business */ +#define REG_MTRACE 0020 /* none of your business */ +#define REG_SMALL 0040 /* none of your business */ + + +/* + * error reporting + * Be careful if modifying the list of error codes -- the table used by + * regerror() is generated automatically from this file! + */ +#define REG_OKAY 0 /* no errors detected */ +#define REG_NOMATCH 1 /* failed to match */ +#define REG_BADPAT 2 /* invalid regexp */ +#define REG_ECOLLATE 3 /* invalid collating element */ +#define REG_ECTYPE 4 /* invalid character class */ +#define REG_EESCAPE 5 /* invalid escape \ sequence */ +#define REG_ESUBREG 6 /* invalid backreference number */ +#define REG_EBRACK 7 /* brackets [] not balanced */ +#define REG_EPAREN 8 /* parentheses () not balanced */ +#define REG_EBRACE 9 /* braces {} not balanced */ +#define REG_BADBR 10 /* invalid repetition count(s) */ +#define REG_ERANGE 11 /* invalid character range */ +#define REG_ESPACE 12 /* out of memory */ +#define REG_BADRPT 13 /* quantifier operand invalid */ +#define REG_ASSERT 15 /* "can't happen" -- you found a bug */ +#define REG_INVARG 16 /* invalid argument to regex function */ +#define REG_MIXED 17 /* character widths of regex and string differ */ +#define REG_BADOPT 18 /* invalid embedded option */ +#define REG_ETOOBIG 19 /* regular expression is too complex */ +#define REG_ECOLORS 20 /* too many colors */ +/* two specials for debugging and testing */ +#define REG_ATOI 101 /* convert error-code name to number */ +#define REG_ITOA 102 /* convert error-code number to name */ +/* non-error result codes for pg_regprefix */ +#define REG_PREFIX (-1) /* identified a common prefix */ +#define REG_EXACT (-2) /* identified an exact match */ + + +/* Redirect the standard typenames to our typenames. */ +#define regoff_t pg_regoff_t +#define regex_t pg_regex_t +#define regmatch_t pg_regmatch_t + + +/* + * the prototypes for exported functions + */ + +/* regcomp.c */ +extern int pg_regcomp(regex_t *re, const pg_wchar *string, size_t len, + int flags, Oid collation); +extern int pg_regexec(regex_t *re, const pg_wchar *string, size_t len, + size_t search_start, rm_detail_t *details, + size_t nmatch, regmatch_t pmatch[], int flags); +extern int pg_regprefix(regex_t *re, pg_wchar **string, size_t *slength); +extern void pg_regfree(regex_t *re); +extern size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, + size_t errbuf_size); + +/* regexp.c */ +extern regex_t *RE_compile_and_cache(text *text_re, int cflags, Oid collation); +extern bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, + int cflags, Oid collation, + int nmatch, regmatch_t *pmatch); + +#endif /* _PG_REGEX_H_ */ diff --git a/install/include/postgresql/server/regex/regexport.h b/install/include/postgresql/server/regex/regexport.h new file mode 100644 index 00000000000..8fdddc18805 --- /dev/null +++ b/install/include/postgresql/server/regex/regexport.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * regexport.h + * Declarations for exporting info about a regex's NFA (nondeterministic + * finite automaton) + * + * The functions declared here provide accessors to extract the NFA state + * graph and color character sets of a successfully-compiled regex. + * + * An NFA contains one or more states, numbered 0..N-1. There is an initial + * state, as well as a final state --- reaching the final state denotes + * successful matching of an input string. Each state except the final one + * has some out-arcs that lead to successor states, each arc being labeled + * with a color that represents one or more concrete character codes. + * (The colors of a state's out-arcs need not be distinct, since this is an + * NFA not a DFA.) There are also "pseudocolors" representing start/end of + * line and start/end of string. Colors are numbered 0..C-1, but note that + * color 0 is "white" (all unused characters) and can generally be ignored. + * + * Portions Copyright (c) 2013-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1998, 1999 Henry Spencer + * + * IDENTIFICATION + * src/include/regex/regexport.h + * + *------------------------------------------------------------------------- + */ +#ifndef _REGEXPORT_H_ +#define _REGEXPORT_H_ + +#include "regex/regex.h" + +/* These macros must match corresponding ones in regguts.h: */ +#define COLOR_WHITE 0 /* color for chars not appearing in regex */ +#define COLOR_RAINBOW (-2) /* represents all colors except pseudocolors */ + +/* information about one arc of a regex's NFA */ +typedef struct +{ + int co; /* label (character-set color) of arc */ + int to; /* next state number */ +} regex_arc_t; + + +/* Functions for gathering information about NFA states and arcs */ +extern int pg_reg_getnumstates(const regex_t *regex); +extern int pg_reg_getinitialstate(const regex_t *regex); +extern int pg_reg_getfinalstate(const regex_t *regex); +extern int pg_reg_getnumoutarcs(const regex_t *regex, int st); +extern void pg_reg_getoutarcs(const regex_t *regex, int st, + regex_arc_t *arcs, int arcs_len); + +/* Functions for gathering information about colors */ +extern int pg_reg_getnumcolors(const regex_t *regex); +extern int pg_reg_colorisbegin(const regex_t *regex, int co); +extern int pg_reg_colorisend(const regex_t *regex, int co); +extern int pg_reg_getnumcharacters(const regex_t *regex, int co); +extern void pg_reg_getcharacters(const regex_t *regex, int co, + pg_wchar *chars, int chars_len); + +#endif /* _REGEXPORT_H_ */ diff --git a/install/include/postgresql/server/regex/regguts.h b/install/include/postgresql/server/regex/regguts.h new file mode 100644 index 00000000000..fd69299a16d --- /dev/null +++ b/install/include/postgresql/server/regex/regguts.h @@ -0,0 +1,550 @@ +/* + * Internal interface definitions, etc., for the reg package + * + * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. + * + * Development of this software was funded, in part, by Cray Research Inc., + * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics + * Corporation, none of whom are responsible for the results. The author + * thanks all of them. + * + * Redistribution and use in source and binary forms -- with or without + * modification -- are permitted for any purpose, provided that + * redistributions in source form retain this entire copyright notice and + * indicate the origin and nature of any modifications. + * + * I'd appreciate being given credit for this package in the documentation + * of software which uses it, but that is not a requirement. + * + * THIS SOFTWARE IS PROVIDED ``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 + * HENRY SPENCER 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. + * + * src/include/regex/regguts.h + */ + + + +/* + * Environmental customization. It should not (I hope) be necessary to + * alter the file you are now reading -- regcustom.h should handle it all, + * given care here and elsewhere. + */ +#include "regcustom.h" + + + +/* + * Things that regcustom.h might override. + */ + +/* assertions */ +#ifndef assert +#ifndef REG_DEBUG +#define NDEBUG /* no assertions */ +#endif +#include +#endif + +/* voids */ +#ifndef DISCARD +#define DISCARD void /* for throwing values away */ +#endif +#ifndef VS +#define VS(x) ((void *)(x)) /* cast something to generic ptr */ +#endif + +/* function-pointer declarator */ +#ifndef FUNCPTR +#define FUNCPTR(name, args) (*(name)) args +#endif + +/* memory allocation */ +#ifndef MALLOC +#define MALLOC(n) malloc(n) +#endif +#ifndef REALLOC +#define REALLOC(p, n) realloc(VS(p), n) +#endif +#ifndef FREE +#define FREE(p) free(VS(p)) +#endif + +/* interruption */ +#ifndef INTERRUPT +#define INTERRUPT(re) +#endif + +/* want size of a char in bits, and max value in bounded quantifiers */ +#ifndef _POSIX2_RE_DUP_MAX +#define _POSIX2_RE_DUP_MAX 255 /* normally from */ +#endif + + + +/* + * misc + */ + +#define NOTREACHED 0 + +#define DUPMAX _POSIX2_RE_DUP_MAX +#define DUPINF (DUPMAX+1) + +#define REMAGIC 0xfed7 /* magic number for main struct */ + +/* Type codes for lookaround constraints */ +#define LATYPE_AHEAD_POS 03 /* positive lookahead */ +#define LATYPE_AHEAD_NEG 02 /* negative lookahead */ +#define LATYPE_BEHIND_POS 01 /* positive lookbehind */ +#define LATYPE_BEHIND_NEG 00 /* negative lookbehind */ +#define LATYPE_IS_POS(la) ((la) & 01) +#define LATYPE_IS_AHEAD(la) ((la) & 02) + + +/* + * debugging facilities + */ +#ifdef REG_DEBUG +/* FDEBUG does finite-state tracing */ +#define FDEBUG(arglist) { if (v->eflags®_FTRACE) printf arglist; } +/* MDEBUG does higher-level tracing */ +#define MDEBUG(arglist) { if (v->eflags®_MTRACE) printf arglist; } +#else +#define FDEBUG(arglist) {} +#define MDEBUG(arglist) {} +#endif + + + +/* + * bitmap manipulation + */ +#define UBITS (CHAR_BIT * sizeof(unsigned)) +#define BSET(uv, sn) ((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS)) +#define ISBSET(uv, sn) ((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS))) + + +/* + * known character classes + */ +enum char_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, CC_WORD +}; + +#define NUM_CCLASSES 14 + + +/* + * As soon as possible, we map chrs into equivalence classes -- "colors" -- + * which are of much more manageable number. + * + * To further reduce the number of arcs in NFAs and DFAs, we also have a + * special RAINBOW "color" that can be assigned to an arc. This is not a + * real color, in that it has no entry in color maps. + */ +typedef short color; /* colors of characters */ + +#define MAX_COLOR 32767 /* max color (must fit in 'color' datatype) */ +#define COLORLESS (-1) /* impossible color */ +#define RAINBOW (-2) /* represents all colors except pseudocolors */ +#define WHITE 0 /* default color, parent of all others */ +/* Note: various places in the code know that WHITE is zero */ + + +/* + * Per-color data structure for the compile-time color machinery + * + * If "sub" is not NOSUB then it is the number of the color's current + * subcolor, i.e. we are in process of dividing this color (character + * equivalence class) into two colors. See src/backend/regex/README for + * discussion of subcolors. + * + * Currently-unused colors have the FREECOL bit set and are linked into a + * freelist using their "sub" fields, but only if their color numbers are + * less than colormap.max. Any array entries beyond "max" are just garbage. + */ +struct colordesc +{ + int nschrs; /* number of simple chars of this color */ + int nuchrs; /* number of upper map entries of this color */ + color sub; /* open subcolor, if any; or free-chain ptr */ +#define NOSUB COLORLESS /* value of "sub" when no open subcolor */ + struct arc *arcs; /* chain of all arcs of this color */ + chr firstchr; /* simple char first assigned to this color */ + int flags; /* bitmask of the following flags: */ +#define FREECOL 01 /* currently free */ +#define PSEUDO 02 /* pseudocolor, no real chars */ +#define COLMARK 04 /* temporary marker used in some functions */ +}; + +#define UNUSEDCOLOR(cd) ((cd)->flags & FREECOL) + +/* + * The color map itself + * + * This struct holds both data used only at compile time, and the chr to + * color mapping information, used at both compile and run time. The latter + * is the bulk of the space, so it's not really worth separating out the + * compile-only portion. + * + * Ideally, the mapping data would just be an array of colors indexed by + * chr codes; but for large character sets that's impractical. Fortunately, + * common characters have smaller codes, so we can use a simple array for chr + * codes up to MAX_SIMPLE_CHR, and do something more complex for codes above + * that, without much loss of performance. The "something more complex" is a + * 2-D array of color entries, where row indexes correspond to individual chrs + * or chr ranges that have been mentioned in the regex (with row zero + * representing all other chrs), and column indexes correspond to different + * sets of locale-dependent character classes such as "isalpha". The + * classbits[k] entry is zero if we do not care about the k'th character class + * in this regex, and otherwise it is the bit to be OR'd into the column index + * if the character in question is a member of that class. We find the color + * of a high-valued chr by identifying which colormaprange it is in to get + * the row index (use row zero if it's in none of them), identifying which of + * the interesting cclasses it's in to get the column index, and then indexing + * into the 2-D hicolormap array. + * + * The colormapranges are required to be nonempty, nonoverlapping, and to + * appear in increasing chr-value order. + */ + +typedef struct colormaprange +{ + chr cmin; /* range represents cmin..cmax inclusive */ + chr cmax; + int rownum; /* row index in hicolormap array (>= 1) */ +} colormaprange; + +struct colormap +{ + int magic; +#define CMMAGIC 0x876 + struct vars *v; /* for compile error reporting */ + size_t ncds; /* allocated length of colordescs array */ + size_t max; /* highest color number currently in use */ + color free; /* beginning of free chain (if non-0) */ + struct colordesc *cd; /* pointer to array of colordescs */ +#define CDEND(cm) (&(cm)->cd[(cm)->max + 1]) + + /* mapping data for chrs <= MAX_SIMPLE_CHR: */ + color *locolormap; /* simple array indexed by chr code */ + + /* mapping data for chrs > MAX_SIMPLE_CHR: */ + int classbits[NUM_CCLASSES]; /* see comment above */ + int numcmranges; /* number of colormapranges */ + colormaprange *cmranges; /* ranges of high chrs */ + color *hicolormap; /* 2-D array of color entries */ + int maxarrayrows; /* number of array rows allocated */ + int hiarrayrows; /* number of array rows in use */ + int hiarraycols; /* number of array columns (2^N) */ + + /* If we need up to NINLINECDS, we store them here to save a malloc */ +#define NINLINECDS ((size_t) 10) + struct colordesc cdspace[NINLINECDS]; +}; + +/* fetch color for chr; beware of multiple evaluation of c argument */ +#define GETCOLOR(cm, c) \ + ((c) <= MAX_SIMPLE_CHR ? (cm)->locolormap[(c) - CHR_MIN] : pg_reg_getcolor(cm, c)) + + +/* + * Interface definitions for locale-interface functions in regc_locale.c. + */ + +/* + * Representation of a set of characters. chrs[] represents individual + * code points, ranges[] represents ranges in the form min..max inclusive. + * + * If the cvec represents a locale-specific character class, eg [[:alpha:]], + * then the chrs[] and ranges[] arrays contain only members of that class + * up to MAX_SIMPLE_CHR (inclusive). cclasscode is set to regc_locale.c's + * code for the class, rather than being -1 as it is in an ordinary cvec. + * + * Note that in cvecs gotten from newcvec() and intended to be freed by + * freecvec(), both arrays of chrs are after the end of the struct, not + * separately malloc'd; so chrspace and rangespace are effectively immutable. + */ +struct cvec +{ + int nchrs; /* number of chrs */ + int chrspace; /* number of chrs allocated in chrs[] */ + chr *chrs; /* pointer to vector of chrs */ + int nranges; /* number of ranges (chr pairs) */ + int rangespace; /* number of ranges allocated in ranges[] */ + chr *ranges; /* pointer to vector of chr pairs */ + int cclasscode; /* value of "enum classes", or -1 */ +}; + + +/* + * definitions for NFA internal representation + */ +struct state; + +struct arc +{ + int type; /* 0 if free, else an NFA arc type code */ + color co; /* color the arc matches (possibly RAINBOW) */ + struct state *from; /* where it's from */ + struct state *to; /* where it's to */ + struct arc *outchain; /* link in *from's outs chain or free chain */ + struct arc *outchainRev; /* back-link in *from's outs chain */ +#define freechain outchain /* we do not maintain "freechainRev" */ + struct arc *inchain; /* link in *to's ins chain */ + struct arc *inchainRev; /* back-link in *to's ins chain */ + /* these fields are not used when co == RAINBOW: */ + struct arc *colorchain; /* link in color's arc chain */ + struct arc *colorchainRev; /* back-link in color's arc chain */ +}; + +struct arcbatch +{ /* for bulk allocation of arcs */ + struct arcbatch *next; /* chain link */ + size_t narcs; /* number of arcs allocated in this arcbatch */ + struct arc a[FLEXIBLE_ARRAY_MEMBER]; +}; +#define ARCBATCHSIZE(n) ((n) * sizeof(struct arc) + offsetof(struct arcbatch, a)) +/* first batch will have FIRSTABSIZE arcs; then double it until MAXABSIZE */ +#define FIRSTABSIZE 64 +#define MAXABSIZE 1024 + +struct state +{ + int no; /* state number, zero and up; or FREESTATE */ +#define FREESTATE (-1) + char flag; /* marks special states */ + int nins; /* number of inarcs */ + int nouts; /* number of outarcs */ + struct arc *ins; /* chain of inarcs */ + struct arc *outs; /* chain of outarcs */ + struct state *tmp; /* temporary for traversal algorithms */ + struct state *next; /* chain for traversing all live states */ + /* the "next" field is also used to chain free states together */ + struct state *prev; /* back-link in chain of all live states */ +}; + +struct statebatch +{ /* for bulk allocation of states */ + struct statebatch *next; /* chain link */ + size_t nstates; /* number of states allocated in this batch */ + struct state s[FLEXIBLE_ARRAY_MEMBER]; +}; +#define STATEBATCHSIZE(n) ((n) * sizeof(struct state) + offsetof(struct statebatch, s)) +/* first batch will have FIRSTSBSIZE states; then double it until MAXSBSIZE */ +#define FIRSTSBSIZE 32 +#define MAXSBSIZE 1024 + +struct nfa +{ + struct state *pre; /* pre-initial state */ + struct state *init; /* initial state */ + struct state *final; /* final state */ + struct state *post; /* post-final state */ + int nstates; /* for numbering states */ + struct state *states; /* chain of live states */ + struct state *slast; /* tail of the chain */ + struct state *freestates; /* chain of free states */ + struct arc *freearcs; /* chain of free arcs */ + struct statebatch *lastsb; /* chain of statebatches */ + struct arcbatch *lastab; /* chain of arcbatches */ + size_t lastsbused; /* number of states consumed from *lastsb */ + size_t lastabused; /* number of arcs consumed from *lastab */ + struct colormap *cm; /* the color map */ + color bos[2]; /* colors, if any, assigned to BOS and BOL */ + color eos[2]; /* colors, if any, assigned to EOS and EOL */ + int flags; /* flags to pass forward to cNFA */ + int minmatchall; /* min number of chrs to match, if matchall */ + int maxmatchall; /* max number of chrs to match, or DUPINF */ + struct vars *v; /* simplifies compile error reporting */ + struct nfa *parent; /* parent NFA, if any */ +}; + + + +/* + * definitions for compacted NFA + * + * The main space savings in a compacted NFA is from making the arcs as small + * as possible. We store only the transition color and next-state number for + * each arc. The list of out arcs for each state is an array beginning at + * cnfa.states[statenumber], and terminated by a dummy carc struct with + * co == COLORLESS. + * + * The non-dummy carc structs are of two types: plain arcs and LACON arcs. + * Plain arcs just store the transition color number as "co". LACON arcs + * store the lookaround constraint number plus cnfa.ncolors as "co". LACON + * arcs can be distinguished from plain by testing for co >= cnfa.ncolors. + * + * Note that in a plain arc, "co" can be RAINBOW; since that's negative, + * it doesn't break the rule about how to recognize LACON arcs. + * + * We have special markings for "trivial" NFAs that can match any string + * (possibly with limits on the number of characters therein). In such a + * case, flags & MATCHALL is set (and HASLACONS can't be set). Then the + * fields minmatchall and maxmatchall give the minimum and maximum numbers + * of characters to match. For example, ".*" produces minmatchall = 0 + * and maxmatchall = DUPINF, while ".+" produces minmatchall = 1 and + * maxmatchall = DUPINF. + */ +struct carc +{ + color co; /* COLORLESS is list terminator */ + int to; /* next-state number */ +}; + +struct cnfa +{ + int nstates; /* number of states */ + int ncolors; /* number of colors (max color in use + 1) */ + int flags; /* bitmask of the following flags: */ +#define HASLACONS 01 /* uses lookaround constraints */ +#define MATCHALL 02 /* matches all strings of a range of lengths */ +#define HASCANTMATCH 04 /* contains CANTMATCH arcs */ + /* Note: HASCANTMATCH appears in nfa structs' flags, but never in cnfas */ + int pre; /* setup state number */ + int post; /* teardown state number */ + color bos[2]; /* colors, if any, assigned to BOS and BOL */ + color eos[2]; /* colors, if any, assigned to EOS and EOL */ + char *stflags; /* vector of per-state flags bytes */ +#define CNFA_NOPROGRESS 01 /* flag bit for a no-progress state */ + struct carc **states; /* vector of pointers to outarc lists */ + /* states[n] are pointers into a single malloc'd array of arcs */ + struct carc *arcs; /* the area for the lists */ + /* these fields are used only in a MATCHALL NFA (else they're -1): */ + int minmatchall; /* min number of chrs to match */ + int maxmatchall; /* max number of chrs to match, or DUPINF */ +}; + +/* + * When debugging, it's helpful if an un-filled CNFA is all-zeroes. + * In production, though, we only require nstates to be zero. + */ +#ifdef REG_DEBUG +#define ZAPCNFA(cnfa) memset(&(cnfa), 0, sizeof(cnfa)) +#else +#define ZAPCNFA(cnfa) ((cnfa).nstates = 0) +#endif +#define NULLCNFA(cnfa) ((cnfa).nstates == 0) + +/* + * This symbol limits the transient heap space used by the regex compiler, + * and thereby also the maximum complexity of NFAs that we'll deal with. + * Currently we only count NFA states and arcs against this; the other + * transient data is generally not large enough to notice compared to those. + * Note that we do not charge anything for the final output data structures + * (the compacted NFA and the colormap). + * The scaling here is based on an empirical measurement that very large + * NFAs tend to have about 4 arcs/state. + */ +#ifndef REG_MAX_COMPILE_SPACE +#define REG_MAX_COMPILE_SPACE \ + (500000 * (sizeof(struct state) + 4 * sizeof(struct arc))) +#endif + +/* + * subexpression tree + * + * "op" is one of: + * '=' plain regex without interesting substructure (implemented as DFA) + * 'b' back-reference (has no substructure either) + * '(' no-op capture node: captures the match of its single child + * '.' concatenation: matches a match for first child, then second child + * '|' alternation: matches a match for any of its children + * '*' iteration: matches some number of matches of its single child + * + * An alternation node can have any number of children (but at least two), + * linked through their sibling fields. + * + * A concatenation node must have exactly two children. It might be useful + * to support more, but that would complicate the executor. Note that it is + * the first child's greediness that determines the node's preference for + * where to split a match. + * + * Note: when a backref is directly quantified, we stick the min/max counts + * into the backref rather than plastering an iteration node on top. This is + * for efficiency: there is no need to search for possible division points. + */ +struct subre +{ + char op; /* see type codes above */ + char flags; +#define LONGER 01 /* prefers longer match */ +#define SHORTER 02 /* prefers shorter match */ +#define MIXED 04 /* mixed preference below */ +#define CAP 010 /* capturing parens here or below */ +#define BACKR 020 /* back reference here or below */ +#define BRUSE 040 /* is referenced by a back reference */ +#define INUSE 0100 /* in use in final tree */ +#define UPPROP (MIXED|CAP|BACKR) /* flags which should propagate up */ +#define LMIX(f) ((f)<<2) /* LONGER -> MIXED */ +#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */ +#define UP(f) (((f)&UPPROP) | (LMIX(f) & SMIX(f) & MIXED)) +#define MESSY(f) ((f)&(MIXED|CAP|BACKR)) +#define PREF(f) ((f)&(LONGER|SHORTER)) +#define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2)) +#define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2)) + char latype; /* LATYPE code, if lookaround constraint */ + int id; /* ID of subre (1..ntree-1) */ + int capno; /* if capture node, subno to capture into */ + int backno; /* if backref node, subno it refers to */ + short min; /* min repetitions for iteration or backref */ + short max; /* max repetitions for iteration or backref */ + struct subre *child; /* first child, if any (also freelist chain) */ + struct subre *sibling; /* next child of same parent, if any */ + struct state *begin; /* outarcs from here... */ + struct state *end; /* ...ending in inarcs here */ + struct cnfa cnfa; /* compacted NFA, if any */ + struct subre *chain; /* for bookkeeping and error cleanup */ +}; + + + +/* + * table of function pointers for generic manipulation functions + * A regex_t's re_fns points to one of these. + */ +struct fns +{ + void FUNCPTR(free, (regex_t *)); + int FUNCPTR(stack_too_deep, (void)); +}; + +#define STACK_TOO_DEEP(re) \ + ((*((struct fns *) (re)->re_fns)->stack_too_deep) ()) + + +/* + * the insides of a regex_t, hidden behind a void * + */ +struct guts +{ + int magic; +#define GUTSMAGIC 0xfed9 + int cflags; /* copy of compile flags */ + long info; /* copy of re_info */ + size_t nsub; /* copy of re_nsub */ + struct subre *tree; + struct cnfa search; /* for fast preliminary search */ + int ntree; /* number of subre's, plus one */ + struct colormap cmap; + int FUNCPTR(compare, (const chr *, const chr *, size_t)); + struct subre *lacons; /* lookaround-constraint vector */ + int nlacons; /* size of lacons[]; note that only slots + * numbered 1 .. nlacons-1 are used */ +}; + + +/* prototypes for functions that are exported from regcomp.c to regexec.c */ +extern void pg_set_regex_collation(Oid collation); +extern color pg_reg_getcolor(struct colormap *cm, chr c); diff --git a/install/include/postgresql/server/replication/decode.h b/install/include/postgresql/server/replication/decode.h new file mode 100644 index 00000000000..14fa921ab47 --- /dev/null +++ b/install/include/postgresql/server/replication/decode.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * decode.h + * PostgreSQL WAL to logical transformation + * + * Portions Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef DECODE_H +#define DECODE_H + +#include "access/xlogreader.h" +#include "access/xlogrecord.h" +#include "replication/logical.h" +#include "replication/reorderbuffer.h" + +typedef struct XLogRecordBuffer +{ + XLogRecPtr origptr; + XLogRecPtr endptr; + XLogReaderState *record; +} XLogRecordBuffer; + +extern void xlog_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); +extern void heap_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); +extern void heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); +extern void xact_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); +extern void standby_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); +extern void logicalmsg_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); + +extern void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, + XLogReaderState *record); + +#endif diff --git a/install/include/postgresql/server/replication/logical.h b/install/include/postgresql/server/replication/logical.h new file mode 100644 index 00000000000..68d1c37230a --- /dev/null +++ b/install/include/postgresql/server/replication/logical.h @@ -0,0 +1,154 @@ +/*------------------------------------------------------------------------- + * logical.h + * PostgreSQL logical decoding coordination + * + * Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef LOGICAL_H +#define LOGICAL_H + +#include "access/xlog.h" +#include "access/xlogreader.h" +#include "replication/output_plugin.h" +#include "replication/slot.h" + +struct LogicalDecodingContext; + +typedef void (*LogicalOutputPluginWriterWrite) (struct LogicalDecodingContext *lr, + XLogRecPtr Ptr, + TransactionId xid, + bool last_write +); + +typedef LogicalOutputPluginWriterWrite LogicalOutputPluginWriterPrepareWrite; + +typedef void (*LogicalOutputPluginWriterUpdateProgress) (struct LogicalDecodingContext *lr, + XLogRecPtr Ptr, + TransactionId xid, + bool skipped_xact +); + +typedef struct LogicalDecodingContext +{ + /* memory context this is all allocated in */ + MemoryContext context; + + /* The associated replication slot */ + ReplicationSlot *slot; + + /* infrastructure pieces for decoding */ + XLogReaderState *reader; + struct ReorderBuffer *reorder; + struct SnapBuild *snapshot_builder; + + /* + * Marks the logical decoding context as fast forward decoding one. Such a + * context does not have plugin loaded so most of the following properties + * are unused. + */ + bool fast_forward; + + OutputPluginCallbacks callbacks; + OutputPluginOptions options; + + /* + * User specified options + */ + List *output_plugin_options; + + /* + * User-Provided callback for writing/streaming out data. + */ + LogicalOutputPluginWriterPrepareWrite prepare_write; + LogicalOutputPluginWriterWrite write; + LogicalOutputPluginWriterUpdateProgress update_progress; + + /* + * Output buffer. + */ + StringInfo out; + + /* + * Private data pointer of the output plugin. + */ + void *output_plugin_private; + + /* + * Private data pointer for the data writer. + */ + void *output_writer_private; + + /* + * Does the output plugin support streaming, and is it enabled? + */ + bool streaming; + + /* + * Does the output plugin support two-phase decoding, and is it enabled? + */ + bool twophase; + + /* + * Is two-phase option given by output plugin? + * + * This flag indicates that the plugin passed in the two-phase option as + * part of the START_STREAMING command. We can't rely solely on the + * twophase flag which only tells whether the plugin provided all the + * necessary two-phase callbacks. + */ + bool twophase_opt_given; + + /* + * State for writing output. + */ + bool accept_writes; + bool prepared_write; + XLogRecPtr write_location; + TransactionId write_xid; + /* Are we processing the end LSN of a transaction? */ + bool end_xact; + + /* + * True if the logical decoding context being used for the creation + * of a logical replication slot. + */ + bool in_create; +} LogicalDecodingContext; + + +extern void CheckLogicalDecodingRequirements(void); + +extern LogicalDecodingContext *CreateInitDecodingContext(const char *plugin, + List *output_plugin_options, + bool need_full_snapshot, + XLogRecPtr restart_lsn, + XLogReaderRoutine *xl_routine, + LogicalOutputPluginWriterPrepareWrite prepare_write, + LogicalOutputPluginWriterWrite do_write, + LogicalOutputPluginWriterUpdateProgress update_progress); +extern LogicalDecodingContext *CreateDecodingContext(XLogRecPtr start_lsn, + List *output_plugin_options, + bool fast_forward, + XLogReaderRoutine *xl_routine, + LogicalOutputPluginWriterPrepareWrite prepare_write, + LogicalOutputPluginWriterWrite do_write, + LogicalOutputPluginWriterUpdateProgress update_progress); +extern void DecodingContextFindStartpoint(LogicalDecodingContext *ctx); +extern bool DecodingContextReady(LogicalDecodingContext *ctx); +extern void FreeDecodingContext(LogicalDecodingContext *ctx); + +extern void LogicalIncreaseXminForSlot(XLogRecPtr current_lsn, + TransactionId xmin); +extern void LogicalIncreaseRestartDecodingForSlot(XLogRecPtr current_lsn, + XLogRecPtr restart_lsn); +extern void LogicalConfirmReceivedLocation(XLogRecPtr lsn); + +extern bool filter_prepare_cb_wrapper(LogicalDecodingContext *ctx, + TransactionId xid, const char *gid); +extern bool filter_by_origin_cb_wrapper(LogicalDecodingContext *ctx, RepOriginId origin_id); +extern void ResetLogicalStreamingState(void); +extern void UpdateDecodingStats(LogicalDecodingContext *ctx); + +#endif diff --git a/install/include/postgresql/server/replication/logicallauncher.h b/install/include/postgresql/server/replication/logicallauncher.h new file mode 100644 index 00000000000..a07c9cb311a --- /dev/null +++ b/install/include/postgresql/server/replication/logicallauncher.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * logicallauncher.h + * Exports for logical replication launcher. + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/replication/logicallauncher.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOGICALLAUNCHER_H +#define LOGICALLAUNCHER_H + +extern PGDLLIMPORT int max_logical_replication_workers; +extern PGDLLIMPORT int max_sync_workers_per_subscription; +extern PGDLLIMPORT int max_parallel_apply_workers_per_subscription; + +extern void ApplyLauncherRegister(void); +extern void ApplyLauncherMain(Datum main_arg); + +extern Size ApplyLauncherShmemSize(void); +extern void ApplyLauncherShmemInit(void); + +extern void ApplyLauncherForgetWorkerStartTime(Oid subid); + +extern void ApplyLauncherWakeupAtCommit(void); +extern void AtEOXact_ApplyLauncher(bool isCommit); + +extern bool IsLogicalLauncher(void); + +extern pid_t GetLeaderApplyWorkerPid(pid_t pid); + +#endif /* LOGICALLAUNCHER_H */ diff --git a/install/include/postgresql/server/replication/logicalproto.h b/install/include/postgresql/server/replication/logicalproto.h new file mode 100644 index 00000000000..c5be981eae6 --- /dev/null +++ b/install/include/postgresql/server/replication/logicalproto.h @@ -0,0 +1,274 @@ +/*------------------------------------------------------------------------- + * + * logicalproto.h + * logical replication protocol + * + * Copyright (c) 2015-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/replication/logicalproto.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOGICAL_PROTO_H +#define LOGICAL_PROTO_H + +#include "access/xact.h" +#include "executor/tuptable.h" +#include "replication/reorderbuffer.h" +#include "utils/rel.h" + +/* + * Protocol capabilities + * + * LOGICALREP_PROTO_VERSION_NUM is our native protocol. + * LOGICALREP_PROTO_MAX_VERSION_NUM is the greatest version we can support. + * LOGICALREP_PROTO_MIN_VERSION_NUM is the oldest version we + * have backwards compatibility for. The client requests protocol version at + * connect time. + * + * LOGICALREP_PROTO_STREAM_VERSION_NUM is the minimum protocol version with + * support for streaming large transactions. Introduced in PG14. + * + * LOGICALREP_PROTO_TWOPHASE_VERSION_NUM is the minimum protocol version with + * support for two-phase commit decoding (at prepare time). Introduced in PG15. + * + * LOGICALREP_PROTO_STREAM_PARALLEL_VERSION_NUM is the minimum protocol version + * where we support applying large streaming transactions in parallel. + * Introduced in PG16. + */ +#define LOGICALREP_PROTO_MIN_VERSION_NUM 1 +#define LOGICALREP_PROTO_VERSION_NUM 1 +#define LOGICALREP_PROTO_STREAM_VERSION_NUM 2 +#define LOGICALREP_PROTO_TWOPHASE_VERSION_NUM 3 +#define LOGICALREP_PROTO_STREAM_PARALLEL_VERSION_NUM 4 +#define LOGICALREP_PROTO_MAX_VERSION_NUM LOGICALREP_PROTO_STREAM_PARALLEL_VERSION_NUM + +/* + * Logical message types + * + * Used by logical replication wire protocol. + * + * Note: though this is an enum, the values are used to identify message types + * in logical replication protocol, which uses a single byte to identify a + * message type. Hence the values should be single-byte wide and preferably + * human-readable characters. + */ +typedef enum LogicalRepMsgType +{ + LOGICAL_REP_MSG_BEGIN = 'B', + LOGICAL_REP_MSG_COMMIT = 'C', + LOGICAL_REP_MSG_ORIGIN = 'O', + LOGICAL_REP_MSG_INSERT = 'I', + LOGICAL_REP_MSG_UPDATE = 'U', + LOGICAL_REP_MSG_DELETE = 'D', + LOGICAL_REP_MSG_TRUNCATE = 'T', + LOGICAL_REP_MSG_RELATION = 'R', + LOGICAL_REP_MSG_TYPE = 'Y', + LOGICAL_REP_MSG_MESSAGE = 'M', + LOGICAL_REP_MSG_BEGIN_PREPARE = 'b', + LOGICAL_REP_MSG_PREPARE = 'P', + LOGICAL_REP_MSG_COMMIT_PREPARED = 'K', + LOGICAL_REP_MSG_ROLLBACK_PREPARED = 'r', + LOGICAL_REP_MSG_STREAM_START = 'S', + LOGICAL_REP_MSG_STREAM_STOP = 'E', + LOGICAL_REP_MSG_STREAM_COMMIT = 'c', + LOGICAL_REP_MSG_STREAM_ABORT = 'A', + LOGICAL_REP_MSG_STREAM_PREPARE = 'p' +} LogicalRepMsgType; + +/* + * This struct stores a tuple received via logical replication. + * Keep in mind that the columns correspond to the *remote* table. + */ +typedef struct LogicalRepTupleData +{ + /* Array of StringInfos, one per column; some may be unused */ + StringInfoData *colvalues; + /* Array of markers for null/unchanged/text/binary, one per column */ + char *colstatus; + /* Length of above arrays */ + int ncols; +} LogicalRepTupleData; + +/* Possible values for LogicalRepTupleData.colstatus[colnum] */ +/* These values are also used in the on-the-wire protocol */ +#define LOGICALREP_COLUMN_NULL 'n' +#define LOGICALREP_COLUMN_UNCHANGED 'u' +#define LOGICALREP_COLUMN_TEXT 't' +#define LOGICALREP_COLUMN_BINARY 'b' /* added in PG14 */ + +typedef uint32 LogicalRepRelId; + +/* Relation information */ +typedef struct LogicalRepRelation +{ + /* Info coming from the remote side. */ + LogicalRepRelId remoteid; /* unique id of the relation */ + char *nspname; /* schema name */ + char *relname; /* relation name */ + int natts; /* number of columns */ + char **attnames; /* column names */ + Oid *atttyps; /* column types */ + char replident; /* replica identity */ + char relkind; /* remote relation kind */ + Bitmapset *attkeys; /* Bitmap of key columns */ +} LogicalRepRelation; + +/* Type mapping info */ +typedef struct LogicalRepTyp +{ + Oid remoteid; /* unique id of the remote type */ + char *nspname; /* schema name of remote type */ + char *typname; /* name of the remote type */ +} LogicalRepTyp; + +/* Transaction info */ +typedef struct LogicalRepBeginData +{ + XLogRecPtr final_lsn; + TimestampTz committime; + TransactionId xid; +} LogicalRepBeginData; + +typedef struct LogicalRepCommitData +{ + XLogRecPtr commit_lsn; + XLogRecPtr end_lsn; + TimestampTz committime; +} LogicalRepCommitData; + +/* + * Prepared transaction protocol information for begin_prepare, and prepare. + */ +typedef struct LogicalRepPreparedTxnData +{ + XLogRecPtr prepare_lsn; + XLogRecPtr end_lsn; + TimestampTz prepare_time; + TransactionId xid; + char gid[GIDSIZE]; +} LogicalRepPreparedTxnData; + +/* + * Prepared transaction protocol information for commit prepared. + */ +typedef struct LogicalRepCommitPreparedTxnData +{ + XLogRecPtr commit_lsn; + XLogRecPtr end_lsn; + TimestampTz commit_time; + TransactionId xid; + char gid[GIDSIZE]; +} LogicalRepCommitPreparedTxnData; + +/* + * Rollback Prepared transaction protocol information. The prepare information + * prepare_end_lsn and prepare_time are used to check if the downstream has + * received this prepared 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 struct LogicalRepRollbackPreparedTxnData +{ + XLogRecPtr prepare_end_lsn; + XLogRecPtr rollback_end_lsn; + TimestampTz prepare_time; + TimestampTz rollback_time; + TransactionId xid; + char gid[GIDSIZE]; +} LogicalRepRollbackPreparedTxnData; + +/* + * Transaction protocol information for stream abort. + */ +typedef struct LogicalRepStreamAbortData +{ + TransactionId xid; + TransactionId subxid; + XLogRecPtr abort_lsn; + TimestampTz abort_time; +} LogicalRepStreamAbortData; + +extern void logicalrep_write_begin(StringInfo out, ReorderBufferTXN *txn); +extern void logicalrep_read_begin(StringInfo in, + LogicalRepBeginData *begin_data); +extern void logicalrep_write_commit(StringInfo out, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +extern void logicalrep_read_commit(StringInfo in, + LogicalRepCommitData *commit_data); +extern void logicalrep_write_begin_prepare(StringInfo out, ReorderBufferTXN *txn); +extern void logicalrep_read_begin_prepare(StringInfo in, + LogicalRepPreparedTxnData *begin_data); +extern void logicalrep_write_prepare(StringInfo out, ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); +extern void logicalrep_read_prepare(StringInfo in, + LogicalRepPreparedTxnData *prepare_data); +extern void logicalrep_write_commit_prepared(StringInfo out, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +extern void logicalrep_read_commit_prepared(StringInfo in, + LogicalRepCommitPreparedTxnData *prepare_data); +extern void logicalrep_write_rollback_prepared(StringInfo out, ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time); +extern void logicalrep_read_rollback_prepared(StringInfo in, + LogicalRepRollbackPreparedTxnData *rollback_data); +extern void logicalrep_write_stream_prepare(StringInfo out, ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); +extern void logicalrep_read_stream_prepare(StringInfo in, + LogicalRepPreparedTxnData *prepare_data); + +extern void logicalrep_write_origin(StringInfo out, const char *origin, + XLogRecPtr origin_lsn); +extern char *logicalrep_read_origin(StringInfo in, XLogRecPtr *origin_lsn); +extern void logicalrep_write_insert(StringInfo out, TransactionId xid, + Relation rel, + TupleTableSlot *newslot, + bool binary, Bitmapset *columns); +extern LogicalRepRelId logicalrep_read_insert(StringInfo in, LogicalRepTupleData *newtup); +extern void logicalrep_write_update(StringInfo out, TransactionId xid, + Relation rel, + TupleTableSlot *oldslot, + TupleTableSlot *newslot, bool binary, Bitmapset *columns); +extern LogicalRepRelId logicalrep_read_update(StringInfo in, + bool *has_oldtuple, LogicalRepTupleData *oldtup, + LogicalRepTupleData *newtup); +extern void logicalrep_write_delete(StringInfo out, TransactionId xid, + Relation rel, TupleTableSlot *oldslot, + bool binary, Bitmapset *columns); +extern LogicalRepRelId logicalrep_read_delete(StringInfo in, + LogicalRepTupleData *oldtup); +extern void logicalrep_write_truncate(StringInfo out, TransactionId xid, + int nrelids, Oid relids[], + bool cascade, bool restart_seqs); +extern List *logicalrep_read_truncate(StringInfo in, + bool *cascade, bool *restart_seqs); +extern void logicalrep_write_message(StringInfo out, TransactionId xid, XLogRecPtr lsn, + bool transactional, const char *prefix, Size sz, const char *message); +extern void logicalrep_write_rel(StringInfo out, TransactionId xid, + Relation rel, Bitmapset *columns); +extern LogicalRepRelation *logicalrep_read_rel(StringInfo in); +extern void logicalrep_write_typ(StringInfo out, TransactionId xid, + Oid typoid); +extern void logicalrep_read_typ(StringInfo in, LogicalRepTyp *ltyp); +extern void logicalrep_write_stream_start(StringInfo out, TransactionId xid, + bool first_segment); +extern TransactionId logicalrep_read_stream_start(StringInfo in, + bool *first_segment); +extern void logicalrep_write_stream_stop(StringInfo out); +extern void logicalrep_write_stream_commit(StringInfo out, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +extern TransactionId logicalrep_read_stream_commit(StringInfo in, + LogicalRepCommitData *commit_data); +extern void logicalrep_write_stream_abort(StringInfo out, TransactionId xid, + TransactionId subxid, + XLogRecPtr abort_lsn, + TimestampTz abort_time, + bool write_abort_info); +extern void logicalrep_read_stream_abort(StringInfo in, + LogicalRepStreamAbortData *abort_data, + bool read_abort_info); +extern const char *logicalrep_message_type(LogicalRepMsgType action); + +#endif /* LOGICAL_PROTO_H */ diff --git a/install/include/postgresql/server/replication/logicalrelation.h b/install/include/postgresql/server/replication/logicalrelation.h new file mode 100644 index 00000000000..3f4d906d741 --- /dev/null +++ b/install/include/postgresql/server/replication/logicalrelation.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * logicalrelation.h + * Relation definitions for logical replication relation mapping. + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/replication/logicalrelation.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOGICALRELATION_H +#define LOGICALRELATION_H + +#include "access/attmap.h" +#include "catalog/index.h" +#include "replication/logicalproto.h" + +typedef struct LogicalRepRelMapEntry +{ + LogicalRepRelation remoterel; /* key is remoterel.remoteid */ + + /* + * Validity flag -- when false, revalidate all derived info at next + * logicalrep_rel_open. (While the localrel is open, we assume our lock + * on that rel ensures the info remains good.) + */ + bool localrelvalid; + + /* Mapping to local relation. */ + Oid localreloid; /* local relation id */ + Relation localrel; /* relcache entry (NULL when closed) */ + AttrMap *attrmap; /* map of local attributes to remote ones */ + bool updatable; /* Can apply updates/deletes? */ + Oid localindexoid; /* which index to use, or InvalidOid if none */ + + /* Sync state. */ + char state; + XLogRecPtr statelsn; +} LogicalRepRelMapEntry; + +extern void logicalrep_relmap_update(LogicalRepRelation *remoterel); +extern void logicalrep_partmap_reset_relmap(LogicalRepRelation *remoterel); + +extern LogicalRepRelMapEntry *logicalrep_rel_open(LogicalRepRelId remoteid, + LOCKMODE lockmode); +extern LogicalRepRelMapEntry *logicalrep_partition_open(LogicalRepRelMapEntry *root, + Relation partrel, AttrMap *map); +extern void logicalrep_rel_close(LogicalRepRelMapEntry *rel, + LOCKMODE lockmode); +extern bool IsIndexUsableForReplicaIdentityFull(IndexInfo *indexInfo, AttrMap *attrmap); +extern Oid GetRelationIdentityOrPK(Relation rel); + +#endif /* LOGICALRELATION_H */ diff --git a/install/include/postgresql/server/replication/logicalworker.h b/install/include/postgresql/server/replication/logicalworker.h new file mode 100644 index 00000000000..39588da79fd --- /dev/null +++ b/install/include/postgresql/server/replication/logicalworker.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * logicalworker.h + * Exports for logical replication workers. + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/replication/logicalworker.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOGICALWORKER_H +#define LOGICALWORKER_H + +#include + +extern PGDLLIMPORT volatile sig_atomic_t ParallelApplyMessagePending; + +extern void ApplyWorkerMain(Datum main_arg); +extern void ParallelApplyWorkerMain(Datum main_arg); + +extern bool IsLogicalWorker(void); +extern bool IsLogicalParallelApplyWorker(void); + +extern void HandleParallelApplyMessageInterrupt(void); +extern void HandleParallelApplyMessages(void); + +extern void LogicalRepWorkersWakeupAtCommit(Oid subid); + +extern void AtEOXact_LogicalRepWorkers(bool isCommit); + +#endif /* LOGICALWORKER_H */ diff --git a/install/include/postgresql/server/replication/message.h b/install/include/postgresql/server/replication/message.h new file mode 100644 index 00000000000..6ce7f2038b2 --- /dev/null +++ b/install/include/postgresql/server/replication/message.h @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------- + * message.h + * Exports from replication/logical/message.c + * + * Copyright (c) 2013-2023, PostgreSQL Global Development Group + * + * src/include/replication/message.h + *------------------------------------------------------------------------- + */ +#ifndef PG_LOGICAL_MESSAGE_H +#define PG_LOGICAL_MESSAGE_H + +#include "access/xlog.h" +#include "access/xlogdefs.h" +#include "access/xlogreader.h" + +/* + * Generic logical decoding message wal record. + */ +typedef struct xl_logical_message +{ + Oid dbId; /* database Oid emitted from */ + bool transactional; /* is message transactional? */ + Size prefix_size; /* length of prefix */ + Size message_size; /* size of the message */ + /* payload, including null-terminated prefix of length prefix_size */ + char message[FLEXIBLE_ARRAY_MEMBER]; +} xl_logical_message; + +#define SizeOfLogicalMessage (offsetof(xl_logical_message, message)) + +extern XLogRecPtr LogLogicalMessage(const char *prefix, const char *message, + size_t size, bool transactional); + +/* RMGR API */ +#define XLOG_LOGICAL_MESSAGE 0x00 +extern void logicalmsg_redo(XLogReaderState *record); +extern void logicalmsg_desc(StringInfo buf, XLogReaderState *record); +extern const char *logicalmsg_identify(uint8 info); + +#endif /* PG_LOGICAL_MESSAGE_H */ diff --git a/install/include/postgresql/server/replication/origin.h b/install/include/postgresql/server/replication/origin.h new file mode 100644 index 00000000000..531351093e6 --- /dev/null +++ b/install/include/postgresql/server/replication/origin.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * origin.h + * Exports from replication/logical/origin.c + * + * Copyright (c) 2013-2023, PostgreSQL Global Development Group + * + * src/include/replication/origin.h + *------------------------------------------------------------------------- + */ +#ifndef PG_ORIGIN_H +#define PG_ORIGIN_H + +#include "access/xlog.h" +#include "access/xlogdefs.h" +#include "access/xlogreader.h" +#include "catalog/pg_replication_origin.h" + +typedef struct xl_replorigin_set +{ + XLogRecPtr remote_lsn; + RepOriginId node_id; + bool force; +} xl_replorigin_set; + +typedef struct xl_replorigin_drop +{ + RepOriginId node_id; +} xl_replorigin_drop; + +#define XLOG_REPLORIGIN_SET 0x00 +#define XLOG_REPLORIGIN_DROP 0x10 + +#define InvalidRepOriginId 0 +#define DoNotReplicateId PG_UINT16_MAX + +extern PGDLLIMPORT RepOriginId replorigin_session_origin; +extern PGDLLIMPORT XLogRecPtr replorigin_session_origin_lsn; +extern PGDLLIMPORT TimestampTz replorigin_session_origin_timestamp; + +/* API for querying & manipulating replication origins */ +extern RepOriginId replorigin_by_name(const char *roname, bool missing_ok); +extern RepOriginId replorigin_create(const char *roname); +extern void replorigin_drop_by_name(const char *name, bool missing_ok, bool nowait); +extern bool replorigin_by_oid(RepOriginId roident, bool missing_ok, + char **roname); + +/* API for querying & manipulating replication progress tracking */ +extern void replorigin_advance(RepOriginId node, + XLogRecPtr remote_commit, + XLogRecPtr local_commit, + bool go_backward, bool wal_log); +extern XLogRecPtr replorigin_get_progress(RepOriginId node, bool flush); + +extern void replorigin_session_advance(XLogRecPtr remote_commit, + XLogRecPtr local_commit); +extern void replorigin_session_setup(RepOriginId node, int acquired_by); +extern void replorigin_session_reset(void); +extern XLogRecPtr replorigin_session_get_progress(bool flush); + +/* Checkpoint/Startup integration */ +extern void CheckPointReplicationOrigin(void); +extern void StartupReplicationOrigin(void); + +/* WAL logging */ +extern void replorigin_redo(XLogReaderState *record); +extern void replorigin_desc(StringInfo buf, XLogReaderState *record); +extern const char *replorigin_identify(uint8 info); + +/* shared memory allocation */ +extern Size ReplicationOriginShmemSize(void); +extern void ReplicationOriginShmemInit(void); + +#endif /* PG_ORIGIN_H */ diff --git a/install/include/postgresql/server/replication/output_plugin.h b/install/include/postgresql/server/replication/output_plugin.h new file mode 100644 index 00000000000..3ac67293861 --- /dev/null +++ b/install/include/postgresql/server/replication/output_plugin.h @@ -0,0 +1,250 @@ +/*------------------------------------------------------------------------- + * output_plugin.h + * PostgreSQL Logical Decode Plugin Interface + * + * Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef OUTPUT_PLUGIN_H +#define OUTPUT_PLUGIN_H + +#include "replication/reorderbuffer.h" + +struct LogicalDecodingContext; +struct OutputPluginCallbacks; + +typedef enum OutputPluginOutputType +{ + OUTPUT_PLUGIN_BINARY_OUTPUT, + OUTPUT_PLUGIN_TEXTUAL_OUTPUT +} OutputPluginOutputType; + +/* + * Options set by the output plugin, in the startup callback. + */ +typedef struct OutputPluginOptions +{ + OutputPluginOutputType output_type; + bool receive_rewrites; +} OutputPluginOptions; + +/* + * Type of the shared library symbol _PG_output_plugin_init that is looked up + * when loading an output plugin shared library. + */ +typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb); + +extern PGDLLEXPORT void _PG_output_plugin_init(struct OutputPluginCallbacks *cb); + +/* + * Callback that gets called in a user-defined plugin. ctx->private_data can + * be set to some private data. + * + * "is_init" will be set to "true" if the decoding slot just got defined. When + * the same slot is used from there one, it will be "false". + */ +typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx, + OutputPluginOptions *options, + bool is_init); + +/* + * Callback called for every (explicit or implicit) BEGIN of a successful + * transaction. + */ +typedef void (*LogicalDecodeBeginCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + +/* + * Callback for every individual change in a successful transaction. + */ +typedef void (*LogicalDecodeChangeCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); + +/* + * Callback for every TRUNCATE in a successful transaction. + */ +typedef void (*LogicalDecodeTruncateCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); + +/* + * Called for every (explicit or implicit) COMMIT of a successful transaction. + */ +typedef void (*LogicalDecodeCommitCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +/* + * Called for the generic logical decoding messages. + */ +typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, + Size message_size, + const char *message); + +/* + * Filter changes by origin. + */ +typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx, + RepOriginId origin_id); + +/* + * Called to shutdown an output plugin. + */ +typedef void (*LogicalDecodeShutdownCB) (struct LogicalDecodingContext *ctx); + +/* + * Called before decoding of PREPARE record to decide whether this + * transaction should be decoded with separate calls to prepare and + * commit_prepared/rollback_prepared callbacks or wait till COMMIT PREPARED + * and sent as usual transaction. + */ +typedef bool (*LogicalDecodeFilterPrepareCB) (struct LogicalDecodingContext *ctx, + TransactionId xid, + const char *gid); + +/* + * Callback called for every BEGIN of a prepared transaction. + */ +typedef void (*LogicalDecodeBeginPrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + +/* + * Called for PREPARE record unless it was filtered by filter_prepare() + * callback. + */ +typedef void (*LogicalDecodePrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); + +/* + * Called for COMMIT PREPARED. + */ +typedef void (*LogicalDecodeCommitPreparedCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +/* + * Called for ROLLBACK PREPARED. + */ +typedef void (*LogicalDecodeRollbackPreparedCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time); + + +/* + * Called when starting to stream a block of changes from in-progress + * transaction (may be called repeatedly, if it's streamed in multiple + * chunks). + */ +typedef void (*LogicalDecodeStreamStartCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + +/* + * Called when stopping to stream a block of changes from in-progress + * transaction to a remote node (may be called repeatedly, if it's streamed + * in multiple chunks). + */ +typedef void (*LogicalDecodeStreamStopCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + +/* + * Called to discard changes streamed to remote node from in-progress + * transaction. + */ +typedef void (*LogicalDecodeStreamAbortCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr abort_lsn); + +/* + * Called to prepare changes streamed to remote node from in-progress + * transaction. This is called as part of a two-phase commit. + */ +typedef void (*LogicalDecodeStreamPrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); + +/* + * Called to apply changes streamed to remote node from in-progress + * transaction. + */ +typedef void (*LogicalDecodeStreamCommitCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +/* + * Callback for streaming individual changes from in-progress transactions. + */ +typedef void (*LogicalDecodeStreamChangeCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); + +/* + * Callback for streaming generic logical decoding messages from in-progress + * transactions. + */ +typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, + Size message_size, + const char *message); + +/* + * Callback for streaming truncates from in-progress transactions. + */ +typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); + +/* + * Output plugin callbacks + */ +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; + + /* streaming of changes at prepare time */ + LogicalDecodeFilterPrepareCB filter_prepare_cb; + LogicalDecodeBeginPrepareCB begin_prepare_cb; + LogicalDecodePrepareCB prepare_cb; + LogicalDecodeCommitPreparedCB commit_prepared_cb; + LogicalDecodeRollbackPreparedCB rollback_prepared_cb; + + /* streaming of changes */ + 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; + +/* Functions in replication/logical/logical.c */ +extern void OutputPluginPrepareWrite(struct LogicalDecodingContext *ctx, bool last_write); +extern void OutputPluginWrite(struct LogicalDecodingContext *ctx, bool last_write); +extern void OutputPluginUpdateProgress(struct LogicalDecodingContext *ctx, bool skipped_xact); + +#endif /* OUTPUT_PLUGIN_H */ diff --git a/install/include/postgresql/server/replication/pgoutput.h b/install/include/postgresql/server/replication/pgoutput.h new file mode 100644 index 00000000000..b4a8015403b --- /dev/null +++ b/install/include/postgresql/server/replication/pgoutput.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * pgoutput.h + * Logical Replication output plugin + * + * Copyright (c) 2015-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/replication/pgoutput.h + * + *------------------------------------------------------------------------- + */ +#ifndef PGOUTPUT_H +#define PGOUTPUT_H + +#include "nodes/pg_list.h" + +typedef struct PGOutputData +{ + MemoryContext context; /* private memory context for transient + * allocations */ + MemoryContext cachectx; /* private memory context for cache data */ + + /* client-supplied info: */ + uint32 protocol_version; + List *publication_names; + List *publications; + bool binary; + char streaming; + bool messages; + bool two_phase; + char *origin; +} PGOutputData; + +#endif /* PGOUTPUT_H */ diff --git a/install/include/postgresql/server/replication/reorderbuffer.h b/install/include/postgresql/server/replication/reorderbuffer.h new file mode 100644 index 00000000000..1606e0ea007 --- /dev/null +++ b/install/include/postgresql/server/replication/reorderbuffer.h @@ -0,0 +1,773 @@ +/* + * reorderbuffer.h + * PostgreSQL logical replay/reorder buffer management. + * + * Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + * src/include/replication/reorderbuffer.h + */ +#ifndef REORDERBUFFER_H +#define REORDERBUFFER_H + +#include "access/htup_details.h" +#include "lib/ilist.h" +#include "storage/sinval.h" +#include "utils/hsearch.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" +#include "utils/timestamp.h" + +/* GUC variables */ +extern PGDLLIMPORT int logical_decoding_work_mem; +extern PGDLLIMPORT int debug_logical_replication_streaming; + +/* possible values for debug_logical_replication_streaming */ +typedef enum +{ + DEBUG_LOGICAL_REP_STREAMING_BUFFERED, + DEBUG_LOGICAL_REP_STREAMING_IMMEDIATE +} DebugLogicalRepStreamingMode; + +/* an individual tuple, stored in one chunk of memory */ +typedef struct ReorderBufferTupleBuf +{ + /* position in preallocated list */ + slist_node node; + + /* tuple header, the interesting bit for users of logical decoding */ + HeapTupleData tuple; + + /* pre-allocated size of tuple buffer, different from tuple size */ + Size alloc_tuple_size; + + /* actual tuple data follows */ +} ReorderBufferTupleBuf; + +/* pointer to the data stored in a TupleBuf */ +#define ReorderBufferTupleBufData(p) \ + ((HeapTupleHeader) MAXALIGN(((char *) p) + sizeof(ReorderBufferTupleBuf))) + +/* + * Types of the change passed to a 'change' callback. + * + * For efficiency and simplicity reasons we want to keep Snapshots, CommandIds + * and ComboCids in the same list with the user visible INSERT/UPDATE/DELETE + * changes. Users of the decoding facilities will never see changes with + * *_INTERNAL_* actions. + * + * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM, and INTERNAL_SPEC_ABORT + * changes concern "speculative insertions", their confirmation, and abort + * respectively. They're used by INSERT .. ON CONFLICT .. UPDATE. Users of + * logical decoding don't have to care about these. + */ +typedef enum ReorderBufferChangeType +{ + REORDER_BUFFER_CHANGE_INSERT, + REORDER_BUFFER_CHANGE_UPDATE, + REORDER_BUFFER_CHANGE_DELETE, + REORDER_BUFFER_CHANGE_MESSAGE, + REORDER_BUFFER_CHANGE_INVALIDATION, + REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT, + REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID, + REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID, + REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT, + REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM, + REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT, + REORDER_BUFFER_CHANGE_TRUNCATE +} ReorderBufferChangeType; + +/* forward declaration */ +struct ReorderBufferTXN; + +/* + * a single 'change', can be an insert (with one tuple), an update (old, new), + * or a delete (old). + * + * The same struct is also used internally for other purposes but that should + * never be visible outside reorderbuffer.c. + */ +typedef struct ReorderBufferChange +{ + XLogRecPtr lsn; + + /* The type of change. */ + ReorderBufferChangeType action; + + /* Transaction this change belongs to. */ + struct ReorderBufferTXN *txn; + + RepOriginId origin_id; + + /* + * Context data for the change. Which part of the union is valid depends + * on action. + */ + union + { + /* Old, new tuples when action == *_INSERT|UPDATE|DELETE */ + struct + { + /* relation that has been changed */ + RelFileLocator rlocator; + + /* no previously reassembled toast chunks are necessary anymore */ + bool clear_toast_afterwards; + + /* valid for DELETE || UPDATE */ + ReorderBufferTupleBuf *oldtuple; + /* valid for INSERT || UPDATE */ + ReorderBufferTupleBuf *newtuple; + } tp; + + /* + * Truncate data for REORDER_BUFFER_CHANGE_TRUNCATE representing one + * set of relations to be truncated. + */ + struct + { + Size nrelids; + bool cascade; + bool restart_seqs; + Oid *relids; + } truncate; + + /* Message with arbitrary data. */ + struct + { + char *prefix; + Size message_size; + char *message; + } msg; + + /* New snapshot, set when action == *_INTERNAL_SNAPSHOT */ + Snapshot snapshot; + + /* + * New command id for existing snapshot in a catalog changing tx. Set + * when action == *_INTERNAL_COMMAND_ID. + */ + CommandId command_id; + + /* + * New cid mapping for catalog changing transaction, set when action + * == *_INTERNAL_TUPLECID. + */ + struct + { + RelFileLocator locator; + ItemPointerData tid; + CommandId cmin; + CommandId cmax; + CommandId combocid; + } tuplecid; + + /* Invalidation. */ + struct + { + uint32 ninvalidations; /* Number of messages */ + SharedInvalidationMessage *invalidations; /* invalidation message */ + } inval; + } data; + + /* + * While in use this is how a change is linked into a transactions, + * otherwise it's the preallocated list. + */ + dlist_node node; +} ReorderBufferChange; + +/* ReorderBufferTXN txn_flags */ +#define RBTXN_HAS_CATALOG_CHANGES 0x0001 +#define RBTXN_IS_SUBXACT 0x0002 +#define RBTXN_IS_SERIALIZED 0x0004 +#define RBTXN_IS_SERIALIZED_CLEAR 0x0008 +#define RBTXN_IS_STREAMED 0x0010 +#define RBTXN_HAS_PARTIAL_CHANGE 0x0020 +#define RBTXN_PREPARE 0x0040 +#define RBTXN_SKIPPED_PREPARE 0x0080 +#define RBTXN_HAS_STREAMABLE_CHANGE 0x0100 +#define RBTXN_DISTR_INVAL_OVERFLOWED 0x0200 + +/* Does the transaction have catalog changes? */ +#define rbtxn_has_catalog_changes(txn) \ +( \ + ((txn)->txn_flags & RBTXN_HAS_CATALOG_CHANGES) != 0 \ +) + +/* Is the transaction known as a subxact? */ +#define rbtxn_is_known_subxact(txn) \ +( \ + ((txn)->txn_flags & RBTXN_IS_SUBXACT) != 0 \ +) + +/* Has this transaction been spilled to disk? */ +#define rbtxn_is_serialized(txn) \ +( \ + ((txn)->txn_flags & RBTXN_IS_SERIALIZED) != 0 \ +) + +/* Has this transaction ever been spilled to disk? */ +#define rbtxn_is_serialized_clear(txn) \ +( \ + ((txn)->txn_flags & RBTXN_IS_SERIALIZED_CLEAR) != 0 \ +) + +/* Has this transaction contains partial changes? */ +#define rbtxn_has_partial_change(txn) \ +( \ + ((txn)->txn_flags & RBTXN_HAS_PARTIAL_CHANGE) != 0 \ +) + +/* Does this transaction contain streamable changes? */ +#define rbtxn_has_streamable_change(txn) \ +( \ + ((txn)->txn_flags & RBTXN_HAS_STREAMABLE_CHANGE) != 0 \ +) + +/* + * Has this transaction been streamed to downstream? + * + * (It's not possible to deduce this from nentries and nentries_mem for + * various reasons. For example, all changes may be in subtransactions in + * which case we'd have nentries==0 for the toplevel one, which would say + * nothing about the streaming. So we maintain this flag, but only for the + * toplevel transaction.) + */ +#define rbtxn_is_streamed(txn) \ +( \ + ((txn)->txn_flags & RBTXN_IS_STREAMED) != 0 \ +) + +/* Has this transaction been prepared? */ +#define rbtxn_prepared(txn) \ +( \ + ((txn)->txn_flags & RBTXN_PREPARE) != 0 \ +) + +/* prepare for this transaction skipped? */ +#define rbtxn_skip_prepared(txn) \ +( \ + ((txn)->txn_flags & RBTXN_SKIPPED_PREPARE) != 0 \ +) + +/* Is the array of distributed inval messages overflowed? */ +#define rbtxn_distr_inval_overflowed(txn) \ +( \ + ((txn)->txn_flags & RBTXN_DISTR_INVAL_OVERFLOWED) != 0 \ +) + +/* Is this a top-level transaction? */ +#define rbtxn_is_toptxn(txn) \ +( \ + (txn)->toptxn == NULL \ +) + +/* Is this a subtransaction? */ +#define rbtxn_is_subtxn(txn) \ +( \ + (txn)->toptxn != NULL \ +) + +/* Get the top-level transaction of this (sub)transaction. */ +#define rbtxn_get_toptxn(txn) \ +( \ + rbtxn_is_subtxn(txn) ? (txn)->toptxn : (txn) \ +) + +typedef struct ReorderBufferTXN +{ + /* See above */ + bits32 txn_flags; + + /* The transaction's transaction id, can be a toplevel or sub xid. */ + TransactionId xid; + + /* Xid of top-level transaction, if known */ + TransactionId toplevel_xid; + + /* + * Global transaction id required for identification of prepared + * transactions. + */ + char *gid; + + /* + * LSN of the first data carrying, WAL record with knowledge about this + * xid. This is allowed to *not* be first record adorned with this xid, if + * the previous records aren't relevant for logical decoding. + */ + XLogRecPtr first_lsn; + + /* ---- + * LSN of the record that lead to this xact to be prepared or committed or + * aborted. This can be a + * * plain commit record + * * plain commit record, of a parent transaction + * * prepared transaction + * * prepared transaction commit + * * plain abort record + * * prepared transaction abort + * + * This can also become set to earlier values than transaction end when + * a transaction is spilled to disk; specifically it's set to the LSN of + * the latest change written to disk so far. + * ---- + */ + XLogRecPtr final_lsn; + + /* + * LSN pointing to the end of the commit record + 1. + */ + XLogRecPtr end_lsn; + + /* Toplevel transaction for this subxact (NULL for top-level). */ + struct ReorderBufferTXN *toptxn; + + /* + * LSN of the last lsn at which snapshot information reside, so we can + * restart decoding from there and fully recover this transaction from + * WAL. + */ + XLogRecPtr restart_decoding_lsn; + + /* origin of the change that caused this transaction */ + RepOriginId origin_id; + XLogRecPtr origin_lsn; + + /* + * Commit or Prepare time, only known when we read the actual commit or + * prepare record. + */ + union + { + TimestampTz commit_time; + TimestampTz prepare_time; + TimestampTz abort_time; + } xact_time; + + /* + * The base snapshot is used to decode all changes until either this + * transaction modifies the catalog, or another catalog-modifying + * transaction commits. + */ + Snapshot base_snapshot; + XLogRecPtr base_snapshot_lsn; + dlist_node base_snapshot_node; /* link in txns_by_base_snapshot_lsn */ + + /* + * Snapshot/CID from the previous streaming run. Only valid for already + * streamed transactions (NULL/InvalidCommandId otherwise). + */ + Snapshot snapshot_now; + CommandId command_id; + + /* + * How many ReorderBufferChange's do we have in this txn. + * + * Changes in subtransactions are *not* included but tracked separately. + */ + uint64 nentries; + + /* + * How many of the above entries are stored in memory in contrast to being + * spilled to disk. + */ + uint64 nentries_mem; + + /* + * List of ReorderBufferChange structs, including new Snapshots, new + * CommandIds and command invalidation messages. + */ + dlist_head changes; + + /* + * List of (relation, ctid) => (cmin, cmax) mappings for catalog tuples. + * Those are always assigned to the toplevel transaction. (Keep track of + * #entries to create a hash of the right size) + */ + dlist_head tuplecids; + uint64 ntuplecids; + + /* + * On-demand built hash for looking up the above values. + */ + HTAB *tuplecid_hash; + + /* + * Hash containing (potentially partial) toast entries. NULL if no toast + * tuples have been found for the current change. + */ + HTAB *toast_hash; + + /* + * non-hierarchical list of subtransactions that are *not* aborted. Only + * used in toplevel transactions. + */ + dlist_head subtxns; + uint32 nsubtxns; + + /* + * Stored cache invalidations. This is not a linked list because we get + * all the invalidations at once. + */ + uint32 ninvalidations; + SharedInvalidationMessage *invalidations; + + /* --- + * Position in one of three lists: + * * list of subtransactions if we are *known* to be subxact + * * list of toplevel xacts (can be an as-yet unknown subxact) + * * list of preallocated ReorderBufferTXNs (if unused) + * --- + */ + dlist_node node; + + /* + * A node in the list of catalog modifying transactions + */ + dlist_node catchange_node; + + /* + * Size of this transaction (changes currently in memory, in bytes). + */ + Size size; + + /* Size of top-transaction including sub-transactions. */ + Size total_size; + + /* If we have detected concurrent abort then ignore future changes. */ + bool concurrent_abort; + + /* + * Private data pointer of the output plugin. + */ + void *output_plugin_private; + + /* + * Stores cache invalidation messages distributed by other transactions. + */ + uint32 ninvalidations_distributed; + SharedInvalidationMessage *invalidations_distributed; +} ReorderBufferTXN; + +/* so we can define the callbacks used inside struct ReorderBuffer itself */ +typedef struct ReorderBuffer ReorderBuffer; + +/* change callback signature */ +typedef void (*ReorderBufferApplyChangeCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); + +/* truncate callback signature */ +typedef void (*ReorderBufferApplyTruncateCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); + +/* begin callback signature */ +typedef void (*ReorderBufferBeginCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn); + +/* commit callback signature */ +typedef void (*ReorderBufferCommitCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +/* message callback signature */ +typedef void (*ReorderBufferMessageCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, Size sz, + const char *message); + +/* begin prepare callback signature */ +typedef void (*ReorderBufferBeginPrepareCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn); + +/* prepare callback signature */ +typedef void (*ReorderBufferPrepareCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); + +/* commit prepared callback signature */ +typedef void (*ReorderBufferCommitPreparedCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +/* rollback prepared callback signature */ +typedef void (*ReorderBufferRollbackPreparedCB) (ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time); + +/* start streaming transaction callback signature */ +typedef void (*ReorderBufferStreamStartCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr first_lsn); + +/* stop streaming transaction callback signature */ +typedef void (*ReorderBufferStreamStopCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr last_lsn); + +/* discard streamed transaction callback signature */ +typedef void (*ReorderBufferStreamAbortCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr abort_lsn); + +/* prepare streamed transaction callback signature */ +typedef void (*ReorderBufferStreamPrepareCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); + +/* commit streamed transaction callback signature */ +typedef void (*ReorderBufferStreamCommitCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +/* stream change callback signature */ +typedef void (*ReorderBufferStreamChangeCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); + +/* stream message callback signature */ +typedef void (*ReorderBufferStreamMessageCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, Size sz, + const char *message); + +/* stream truncate callback signature */ +typedef void (*ReorderBufferStreamTruncateCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); + +/* update progress txn callback signature */ +typedef void (*ReorderBufferUpdateProgressTxnCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr lsn); + +struct ReorderBuffer +{ + /* + * xid => ReorderBufferTXN lookup table + */ + HTAB *by_txn; + + /* + * Transactions that could be a toplevel xact, ordered by LSN of the first + * record bearing that xid. + */ + dlist_head toplevel_by_lsn; + + /* + * Transactions and subtransactions that have a base snapshot, ordered by + * LSN of the record which caused us to first obtain the base snapshot. + * This is not the same as toplevel_by_lsn, because we only set the base + * snapshot on the first logical-decoding-relevant record (eg. heap + * writes), whereas the initial LSN could be set by other operations. + */ + dlist_head txns_by_base_snapshot_lsn; + + /* + * Transactions and subtransactions that have modified system catalogs. + */ + dclist_head catchange_txns; + + /* + * one-entry sized cache for by_txn. Very frequently the same txn gets + * looked up over and over again. + */ + TransactionId by_txn_last_xid; + ReorderBufferTXN *by_txn_last_txn; + + /* + * Callbacks to be called when a transactions commits. + */ + ReorderBufferBeginCB begin; + ReorderBufferApplyChangeCB apply_change; + ReorderBufferApplyTruncateCB apply_truncate; + ReorderBufferCommitCB commit; + ReorderBufferMessageCB message; + + /* + * Callbacks to be called when streaming a transaction at prepare time. + */ + ReorderBufferBeginCB begin_prepare; + ReorderBufferPrepareCB prepare; + ReorderBufferCommitPreparedCB commit_prepared; + ReorderBufferRollbackPreparedCB rollback_prepared; + + /* + * Callbacks to be called when streaming a transaction. + */ + ReorderBufferStreamStartCB stream_start; + ReorderBufferStreamStopCB stream_stop; + ReorderBufferStreamAbortCB stream_abort; + ReorderBufferStreamPrepareCB stream_prepare; + ReorderBufferStreamCommitCB stream_commit; + ReorderBufferStreamChangeCB stream_change; + ReorderBufferStreamMessageCB stream_message; + ReorderBufferStreamTruncateCB stream_truncate; + + /* + * Callback to be called when updating progress during sending data of a + * transaction (and its subtransactions) to the output plugin. + */ + ReorderBufferUpdateProgressTxnCB update_progress_txn; + + /* + * Pointer that will be passed untouched to the callbacks. + */ + void *private_data; + + /* + * Saved output plugin option + */ + bool output_rewrites; + + /* + * Private memory context. + */ + MemoryContext context; + + /* + * Memory contexts for specific types objects + */ + MemoryContext change_context; + MemoryContext txn_context; + MemoryContext tup_context; + + XLogRecPtr current_restart_decoding_lsn; + + /* buffer for disk<->memory conversions */ + char *outbuf; + Size outbufsize; + + /* memory accounting */ + Size size; + + /* + * Statistics about transactions spilled to disk. + * + * A single transaction may be spilled repeatedly, which is why we keep + * two different counters. For spilling, the transaction counter includes + * both toplevel transactions and subtransactions. + */ + int64 spillTxns; /* number of transactions spilled to disk */ + int64 spillCount; /* spill-to-disk invocation counter */ + int64 spillBytes; /* amount of data spilled to disk */ + + /* Statistics about transactions streamed to the decoding output plugin */ + int64 streamTxns; /* number of transactions streamed */ + int64 streamCount; /* streaming invocation counter */ + int64 streamBytes; /* amount of data decoded */ + + /* + * Statistics about all the transactions sent to the decoding output + * plugin + */ + int64 totalTxns; /* total number of transactions sent */ + int64 totalBytes; /* total amount of data decoded */ +}; + + +extern ReorderBuffer *ReorderBufferAllocate(void); +extern void ReorderBufferFree(ReorderBuffer *rb); + +extern ReorderBufferTupleBuf *ReorderBufferGetTupleBuf(ReorderBuffer *rb, + Size tuple_len); +extern void ReorderBufferReturnTupleBuf(ReorderBuffer *rb, + ReorderBufferTupleBuf *tuple); +extern ReorderBufferChange *ReorderBufferGetChange(ReorderBuffer *rb); +extern void ReorderBufferReturnChange(ReorderBuffer *rb, + ReorderBufferChange *change, bool upd_mem); + +extern Oid *ReorderBufferGetRelids(ReorderBuffer *rb, int nrelids); +extern void ReorderBufferReturnRelids(ReorderBuffer *rb, Oid *relids); + +extern void ReorderBufferQueueChange(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr lsn, ReorderBufferChange *change, + bool toast_insert); +extern void ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid, + Snapshot snap, XLogRecPtr lsn, + bool transactional, const char *prefix, + Size message_size, const char *message); +extern void ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn, + TimestampTz commit_time, RepOriginId origin_id, XLogRecPtr origin_lsn); +extern void ReorderBufferFinishPrepared(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn, + XLogRecPtr two_phase_at, + TimestampTz commit_time, + RepOriginId origin_id, XLogRecPtr origin_lsn, + char *gid, bool is_commit); +extern void ReorderBufferAssignChild(ReorderBuffer *rb, TransactionId xid, + TransactionId subxid, XLogRecPtr lsn); +extern void ReorderBufferCommitChild(ReorderBuffer *rb, TransactionId xid, + TransactionId subxid, XLogRecPtr commit_lsn, + XLogRecPtr end_lsn); +extern void ReorderBufferAbort(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn, + TimestampTz abort_time); +extern void ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid); +extern void ReorderBufferForget(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn); +extern void ReorderBufferInvalidate(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn); + +extern void ReorderBufferSetBaseSnapshot(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr lsn, Snapshot snap); +extern void ReorderBufferAddSnapshot(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr lsn, Snapshot snap); +extern void ReorderBufferAddNewCommandId(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr lsn, CommandId cid); +extern void ReorderBufferAddNewTupleCids(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr lsn, RelFileLocator locator, + ItemPointerData tid, + CommandId cmin, CommandId cmax, CommandId combocid); +extern void ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn, + Size nmsgs, SharedInvalidationMessage *msgs); +extern void ReorderBufferAddDistributedInvalidations(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr lsn, Size nmsgs, + SharedInvalidationMessage *msgs); +extern void ReorderBufferImmediateInvalidation(ReorderBuffer *rb, uint32 ninvalidations, + SharedInvalidationMessage *invalidations); +extern void ReorderBufferProcessXid(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn); + +extern void ReorderBufferXidSetCatalogChanges(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn); +extern bool ReorderBufferXidHasCatalogChanges(ReorderBuffer *rb, TransactionId xid); +extern bool ReorderBufferXidHasBaseSnapshot(ReorderBuffer *rb, TransactionId xid); + +extern bool ReorderBufferRememberPrepareInfo(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr prepare_lsn, XLogRecPtr end_lsn, + TimestampTz prepare_time, + RepOriginId origin_id, XLogRecPtr origin_lsn); +extern void ReorderBufferSkipPrepare(ReorderBuffer *rb, TransactionId xid); +extern void ReorderBufferPrepare(ReorderBuffer *rb, TransactionId xid, char *gid); +extern ReorderBufferTXN *ReorderBufferGetOldestTXN(ReorderBuffer *rb); +extern TransactionId ReorderBufferGetOldestXmin(ReorderBuffer *rb); +extern TransactionId *ReorderBufferGetCatalogChangesXacts(ReorderBuffer *rb); + +extern void ReorderBufferSetRestartPoint(ReorderBuffer *rb, XLogRecPtr ptr); + +extern uint32 ReorderBufferGetInvalidations(ReorderBuffer *rb, + TransactionId xid, + SharedInvalidationMessage **msgs); + +extern void StartupReorderBuffer(void); + +#endif diff --git a/install/include/postgresql/server/replication/slot.h b/install/include/postgresql/server/replication/slot.h new file mode 100644 index 00000000000..96e9181aeb2 --- /dev/null +++ b/install/include/postgresql/server/replication/slot.h @@ -0,0 +1,251 @@ +/*------------------------------------------------------------------------- + * slot.h + * Replication slot management. + * + * Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef SLOT_H +#define SLOT_H + +#include "access/xlog.h" +#include "access/xlogreader.h" +#include "storage/condition_variable.h" +#include "storage/lwlock.h" +#include "storage/shmem.h" +#include "storage/spin.h" +#include "replication/walreceiver.h" + +/* + * Behaviour of replication slots, upon release or crash. + * + * Slots marked as PERSISTENT are crash-safe and will not be dropped when + * released. Slots marked as EPHEMERAL will be dropped when released or after + * restarts. Slots marked TEMPORARY will be dropped at the end of a session + * or on error. + * + * EPHEMERAL is used as a not-quite-ready state when creating persistent + * slots. EPHEMERAL slots can be made PERSISTENT by calling + * ReplicationSlotPersist(). For a slot that goes away at the end of a + * session, TEMPORARY is the appropriate choice. + */ +typedef enum ReplicationSlotPersistency +{ + RS_PERSISTENT, + RS_EPHEMERAL, + RS_TEMPORARY +} ReplicationSlotPersistency; + +/* + * Slots can be invalidated, e.g. due to max_slot_wal_keep_size. If so, the + * 'invalidated' field is set to a value other than _NONE. + */ +typedef enum ReplicationSlotInvalidationCause +{ + RS_INVAL_NONE, + /* required WAL has been removed */ + RS_INVAL_WAL_REMOVED, + /* required rows have been removed */ + RS_INVAL_HORIZON, + /* wal_level insufficient for slot */ + RS_INVAL_WAL_LEVEL, +} ReplicationSlotInvalidationCause; + +/* + * On-Disk data of a replication slot, preserved across restarts. + */ +typedef struct ReplicationSlotPersistentData +{ + /* The slot's identifier */ + NameData name; + + /* database the slot is active on */ + Oid database; + + /* + * The slot's behaviour when being dropped (or restored after a crash). + */ + ReplicationSlotPersistency persistency; + + /* + * xmin horizon for data + * + * NB: This may represent a value that hasn't been written to disk yet; + * see notes for effective_xmin, below. + */ + TransactionId xmin; + + /* + * xmin horizon for catalog tuples + * + * NB: This may represent a value that hasn't been written to disk yet; + * see notes for effective_xmin, below. + */ + TransactionId catalog_xmin; + + /* oldest LSN that might be required by this replication slot */ + XLogRecPtr restart_lsn; + + /* RS_INVAL_NONE if valid, or the reason for having been invalidated */ + ReplicationSlotInvalidationCause invalidated; + + /* + * Oldest LSN that the client has acked receipt for. This is used as the + * start_lsn point in case the client doesn't specify one, and also as a + * safety measure to jump forwards in case the client specifies a + * start_lsn that's further in the past than this value. + */ + XLogRecPtr confirmed_flush; + + /* + * LSN at which we enabled two_phase commit for this slot or LSN at which + * we found a consistent point at the time of slot creation. + */ + XLogRecPtr two_phase_at; + + /* + * Allow decoding of prepared transactions? + */ + bool two_phase; + + /* plugin name */ + NameData plugin; +} ReplicationSlotPersistentData; + +/* + * Shared memory state of a single replication slot. + * + * The in-memory data of replication slots follows a locking model based + * on two linked concepts: + * - A replication slot's in_use flag is switched when added or discarded using + * the LWLock ReplicationSlotControlLock, which needs to be hold in exclusive + * mode when updating the flag by the backend owning the slot and doing the + * operation, while readers (concurrent backends not owning the slot) need + * to hold it in shared mode when looking at replication slot data. + * - Individual fields are protected by mutex where only the backend owning + * the slot is authorized to update the fields from its own slot. The + * backend owning the slot does not need to take this lock when reading its + * own fields, while concurrent backends not owning this slot should take the + * lock when reading this slot's data. + */ +typedef struct ReplicationSlot +{ + /* lock, on same cacheline as effective_xmin */ + slock_t mutex; + + /* is this slot defined */ + bool in_use; + + /* Who is streaming out changes for this slot? 0 in unused slots. */ + pid_t active_pid; + + /* any outstanding modifications? */ + bool just_dirtied; + bool dirty; + + /* + * For logical decoding, it's extremely important that we never remove any + * data that's still needed for decoding purposes, even after a crash; + * otherwise, decoding will produce wrong answers. Ordinary streaming + * replication also needs to prevent old row versions from being removed + * too soon, but the worst consequence we might encounter there is + * unwanted query cancellations on the standby. Thus, for logical + * decoding, this value represents the latest xmin that has actually been + * written to disk, whereas for streaming replication, it's just the same + * as the persistent value (data.xmin). + */ + TransactionId effective_xmin; + TransactionId effective_catalog_xmin; + + /* data surviving shutdowns and crashes */ + ReplicationSlotPersistentData data; + + /* is somebody performing io on this slot? */ + LWLock io_in_progress_lock; + + /* Condition variable signaled when active_pid changes */ + ConditionVariable active_cv; + + /* all the remaining data is only used for logical slots */ + + /* + * When the client has confirmed flushes >= candidate_xmin_lsn we can + * advance the catalog xmin. When restart_valid has been passed, + * restart_lsn can be increased. + */ + TransactionId candidate_catalog_xmin; + XLogRecPtr candidate_xmin_lsn; + XLogRecPtr candidate_restart_valid; + XLogRecPtr candidate_restart_lsn; +} ReplicationSlot; + +#define SlotIsPhysical(slot) ((slot)->data.database == InvalidOid) +#define SlotIsLogical(slot) ((slot)->data.database != InvalidOid) + +/* + * Shared memory control area for all of replication slots. + */ +typedef struct ReplicationSlotCtlData +{ + /* + * This array should be declared [FLEXIBLE_ARRAY_MEMBER], but for some + * reason you can't do that in an otherwise-empty struct. + */ + ReplicationSlot replication_slots[1]; +} ReplicationSlotCtlData; + +/* + * Pointers to shared memory + */ +extern PGDLLIMPORT ReplicationSlotCtlData *ReplicationSlotCtl; +extern PGDLLIMPORT ReplicationSlot *MyReplicationSlot; + +/* GUCs */ +extern PGDLLIMPORT int max_replication_slots; + +/* shmem initialization functions */ +extern Size ReplicationSlotsShmemSize(void); +extern void ReplicationSlotsShmemInit(void); + +/* management of individual slots */ +extern void ReplicationSlotCreate(const char *name, bool db_specific, + ReplicationSlotPersistency persistency, + bool two_phase); +extern void ReplicationSlotPersist(void); +extern void ReplicationSlotDrop(const char *name, bool nowait); + +extern void ReplicationSlotAcquire(const char *name, bool nowait); +extern void ReplicationSlotRelease(void); +extern void ReplicationSlotCleanup(void); +extern void ReplicationSlotSave(void); +extern void ReplicationSlotMarkDirty(void); + +/* misc stuff */ +extern void ReplicationSlotInitialize(void); +extern bool ReplicationSlotValidateName(const char *name, int elevel); +extern bool ReplicationSlotValidateNameInternal(const char *name, + int *err_code, char **err_msg, char **err_hint); +extern void ReplicationSlotReserveWal(void); +extern void ReplicationSlotsComputeRequiredXmin(bool already_locked); +extern void ReplicationSlotsComputeRequiredLSN(void); +extern XLogRecPtr ReplicationSlotsComputeLogicalRestartLSN(void); +extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive); +extern void ReplicationSlotsDropDBSlots(Oid dboid); +extern bool InvalidateObsoleteReplicationSlots(ReplicationSlotInvalidationCause cause, + XLogSegNo oldestSegno, + Oid dboid, + TransactionId snapshotConflictHorizon); +extern ReplicationSlot *SearchNamedReplicationSlot(const char *name, bool need_lock); +extern int ReplicationSlotIndex(ReplicationSlot *slot); +extern bool ReplicationSlotName(int index, Name name); +extern void ReplicationSlotNameForTablesync(Oid suboid, Oid relid, char *syncslotname, Size szslot); +extern void ReplicationSlotDropAtPubNode(WalReceiverConn *wrconn, char *slotname, bool missing_ok); + +extern void StartupReplicationSlots(void); +extern void CheckPointReplicationSlots(void); + +extern void CheckSlotRequirements(void); +extern void CheckSlotPermissions(void); + +#endif /* SLOT_H */ diff --git a/install/include/postgresql/server/replication/snapbuild.h b/install/include/postgresql/server/replication/snapbuild.h new file mode 100644 index 00000000000..f49b941b53e --- /dev/null +++ b/install/include/postgresql/server/replication/snapbuild.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------- + * + * snapbuild.h + * Exports from replication/logical/snapbuild.c. + * + * Copyright (c) 2012-2023, PostgreSQL Global Development Group + * + * src/include/replication/snapbuild.h + * + *------------------------------------------------------------------------- + */ +#ifndef SNAPBUILD_H +#define SNAPBUILD_H + +#include "access/xlogdefs.h" +#include "utils/snapmgr.h" + +typedef enum +{ + /* + * Initial state, we can't do much yet. + */ + SNAPBUILD_START = -1, + + /* + * Collecting committed transactions, to build the initial catalog + * snapshot. + */ + SNAPBUILD_BUILDING_SNAPSHOT = 0, + + /* + * We have collected enough information to decode tuples in transactions + * that started after this. + * + * Once we reached this we start to collect changes. We cannot apply them + * yet, because they might be based on transactions that were still + * running when FULL_SNAPSHOT was reached. + */ + SNAPBUILD_FULL_SNAPSHOT = 1, + + /* + * Found a point after SNAPBUILD_FULL_SNAPSHOT where all transactions that + * were running at that point finished. Till we reach that we hold off + * calling any commit callbacks. + */ + SNAPBUILD_CONSISTENT = 2 +} SnapBuildState; + +/* forward declare so we don't have to expose the struct to the public */ +struct SnapBuild; +typedef struct SnapBuild SnapBuild; + +/* forward declare so we don't have to include reorderbuffer.h */ +struct ReorderBuffer; + +/* forward declare so we don't have to include heapam_xlog.h */ +struct xl_heap_new_cid; +struct xl_running_xacts; + +extern void CheckPointSnapBuild(void); + +extern SnapBuild *AllocateSnapshotBuilder(struct ReorderBuffer *reorder, + TransactionId xmin_horizon, XLogRecPtr start_lsn, + bool need_full_snapshot, + XLogRecPtr two_phase_at); +extern void FreeSnapshotBuilder(SnapBuild *builder); + +extern void SnapBuildSnapDecRefcount(Snapshot snap); + +extern Snapshot SnapBuildInitialSnapshot(SnapBuild *builder); +extern const char *SnapBuildExportSnapshot(SnapBuild *builder); +extern void SnapBuildClearExportedSnapshot(void); +extern void SnapBuildResetExportedSnapshotState(void); + +extern SnapBuildState SnapBuildCurrentState(SnapBuild *builder); +extern Snapshot SnapBuildGetOrBuildSnapshot(SnapBuild *builder); + +extern bool SnapBuildXactNeedsSkip(SnapBuild *builder, XLogRecPtr ptr); +extern XLogRecPtr SnapBuildGetTwoPhaseAt(SnapBuild *builder); +extern void SnapBuildSetTwoPhaseAt(SnapBuild *builder, XLogRecPtr ptr); + +extern void SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, + TransactionId xid, int nsubxacts, + TransactionId *subxacts, uint32 xinfo); +extern bool SnapBuildProcessChange(SnapBuild *builder, TransactionId xid, + XLogRecPtr lsn); +extern void SnapBuildProcessNewCid(SnapBuild *builder, TransactionId xid, + XLogRecPtr lsn, + struct xl_heap_new_cid *xlrec); +extern void SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, + struct xl_running_xacts *running); +extern void SnapBuildSerializationPoint(SnapBuild *builder, XLogRecPtr lsn); + +#endif /* SNAPBUILD_H */ diff --git a/install/include/postgresql/server/replication/syncrep.h b/install/include/postgresql/server/replication/syncrep.h new file mode 100644 index 00000000000..0aec4cb1d51 --- /dev/null +++ b/install/include/postgresql/server/replication/syncrep.h @@ -0,0 +1,109 @@ +/*------------------------------------------------------------------------- + * + * syncrep.h + * Exports from replication/syncrep.c. + * + * Portions Copyright (c) 2010-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/replication/syncrep.h + * + *------------------------------------------------------------------------- + */ +#ifndef _SYNCREP_H +#define _SYNCREP_H + +#include "access/xlogdefs.h" + +#define SyncRepRequested() \ + (max_wal_senders > 0 && synchronous_commit > SYNCHRONOUS_COMMIT_LOCAL_FLUSH) + +/* SyncRepWaitMode */ +#define SYNC_REP_NO_WAIT (-1) +#define SYNC_REP_WAIT_WRITE 0 +#define SYNC_REP_WAIT_FLUSH 1 +#define SYNC_REP_WAIT_APPLY 2 + +#define NUM_SYNC_REP_WAIT_MODE 3 + +/* syncRepState */ +#define SYNC_REP_NOT_WAITING 0 +#define SYNC_REP_WAITING 1 +#define SYNC_REP_WAIT_COMPLETE 2 + +/* syncrep_method of SyncRepConfigData */ +#define SYNC_REP_PRIORITY 0 +#define SYNC_REP_QUORUM 1 + +/* + * SyncRepGetCandidateStandbys returns an array of these structs, + * one per candidate synchronous walsender. + */ +typedef struct SyncRepStandbyData +{ + /* Copies of relevant fields from WalSnd shared-memory struct */ + pid_t pid; + XLogRecPtr write; + XLogRecPtr flush; + XLogRecPtr apply; + int sync_standby_priority; + /* Index of this walsender in the WalSnd shared-memory array */ + int walsnd_index; + /* This flag indicates whether this struct is about our own process */ + bool is_me; +} SyncRepStandbyData; + +/* + * Struct for the configuration of synchronous replication. + * + * Note: this must be a flat representation that can be held in a single + * chunk of malloc'd memory, so that it can be stored as the "extra" data + * for the synchronous_standby_names GUC. + */ +typedef struct SyncRepConfigData +{ + int config_size; /* total size of this struct, in bytes */ + int num_sync; /* number of sync standbys that we need to + * wait for */ + uint8 syncrep_method; /* method to choose sync standbys */ + int nmembers; /* number of members in the following list */ + /* member_names contains nmembers consecutive nul-terminated C strings */ + char member_names[FLEXIBLE_ARRAY_MEMBER]; +} SyncRepConfigData; + +extern PGDLLIMPORT SyncRepConfigData *SyncRepConfig; + +/* communication variables for parsing synchronous_standby_names GUC */ +extern PGDLLIMPORT SyncRepConfigData *syncrep_parse_result; +extern PGDLLIMPORT char *syncrep_parse_error_msg; + +/* user-settable parameters for synchronous replication */ +extern PGDLLIMPORT char *SyncRepStandbyNames; + +/* called by user backend */ +extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit); + +/* called at backend exit */ +extern void SyncRepCleanupAtProcExit(void); + +/* called by wal sender */ +extern void SyncRepInitConfig(void); +extern void SyncRepReleaseWaiters(void); + +/* called by wal sender and user backend */ +extern int SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys); + +/* called by checkpointer */ +extern void SyncRepUpdateSyncStandbysDefined(void); + +/* + * Internal functions for parsing synchronous_standby_names grammar, + * in syncrep_gram.y and syncrep_scanner.l + */ +extern int syncrep_yyparse(void); +extern int syncrep_yylex(void); +extern void syncrep_yyerror(const char *str); +extern void syncrep_scanner_init(const char *str); +extern void syncrep_scanner_finish(void); + +#endif /* _SYNCREP_H */ diff --git a/install/include/postgresql/server/replication/walreceiver.h b/install/include/postgresql/server/replication/walreceiver.h new file mode 100644 index 00000000000..281626fa6f5 --- /dev/null +++ b/install/include/postgresql/server/replication/walreceiver.h @@ -0,0 +1,478 @@ +/*------------------------------------------------------------------------- + * + * walreceiver.h + * Exports from replication/walreceiverfuncs.c. + * + * Portions Copyright (c) 2010-2023, PostgreSQL Global Development Group + * + * src/include/replication/walreceiver.h + * + *------------------------------------------------------------------------- + */ +#ifndef _WALRECEIVER_H +#define _WALRECEIVER_H + +#include +#include + +#include "access/xlog.h" +#include "access/xlogdefs.h" +#include "pgtime.h" +#include "port/atomics.h" +#include "replication/logicalproto.h" +#include "replication/walsender.h" +#include "storage/condition_variable.h" +#include "storage/latch.h" +#include "storage/spin.h" +#include "utils/tuplestore.h" + +/* user-settable parameters */ +extern PGDLLIMPORT int wal_receiver_status_interval; +extern PGDLLIMPORT int wal_receiver_timeout; +extern PGDLLIMPORT bool hot_standby_feedback; + +/* + * MAXCONNINFO: maximum size of a connection string. + * + * XXX: Should this move to pg_config_manual.h? + */ +#define MAXCONNINFO 1024 + +/* Can we allow the standby to accept replication connection from another standby? */ +#define AllowCascadeReplication() (EnableHotStandby && max_wal_senders > 0) + +/* + * Values for WalRcv->walRcvState. + */ +typedef enum +{ + WALRCV_STOPPED, /* stopped and mustn't start up again */ + WALRCV_STARTING, /* launched, but the process hasn't + * initialized yet */ + WALRCV_STREAMING, /* walreceiver is streaming */ + WALRCV_WAITING, /* stopped streaming, waiting for orders */ + WALRCV_RESTARTING, /* asked to restart streaming */ + WALRCV_STOPPING /* requested to stop, but still running */ +} WalRcvState; + +/* Shared memory area for management of walreceiver process */ +typedef struct +{ + /* + * PID of currently active walreceiver process, its current state and + * start time (actually, the time at which it was requested to be + * started). + */ + pid_t pid; + WalRcvState walRcvState; + ConditionVariable walRcvStoppedCV; + pg_time_t startTime; + + /* + * receiveStart and receiveStartTLI indicate the first byte position and + * timeline that will be received. When startup process starts the + * walreceiver, it sets these to the point where it wants the streaming to + * begin. + */ + XLogRecPtr receiveStart; + TimeLineID receiveStartTLI; + + /* + * flushedUpto-1 is the last byte position that has already been received, + * and receivedTLI is the timeline it came from. At the first startup of + * walreceiver, these are set to receiveStart and receiveStartTLI. After + * that, walreceiver updates these whenever it flushes the received WAL to + * disk. + */ + XLogRecPtr flushedUpto; + TimeLineID receivedTLI; + + /* + * latestChunkStart is the starting byte position of the current "batch" + * of received WAL. It's actually the same as the previous value of + * flushedUpto before the last flush to disk. Startup process can use + * this to detect whether it's keeping up or not. + */ + XLogRecPtr latestChunkStart; + + /* + * Time of send and receive of any message received. + */ + TimestampTz lastMsgSendTime; + TimestampTz lastMsgReceiptTime; + + /* + * Latest reported end of WAL on the sender + */ + XLogRecPtr latestWalEnd; + TimestampTz latestWalEndTime; + + /* + * connection string; initially set to connect to the primary, and later + * clobbered to hide security-sensitive fields. + */ + char conninfo[MAXCONNINFO]; + + /* + * Host name (this can be a host name, an IP address, or a directory path) + * and port number of the active replication connection. + */ + char sender_host[NI_MAXHOST]; + int sender_port; + + /* + * replication slot name; is also used for walreceiver to connect with the + * primary + */ + char slotname[NAMEDATALEN]; + + /* + * If it's a temporary replication slot, it needs to be recreated when + * connecting. + */ + bool is_temp_slot; + + /* set true once conninfo is ready to display (obfuscated pwds etc) */ + bool ready_to_display; + + /* + * Latch used by startup process to wake up walreceiver after telling it + * where to start streaming (after setting receiveStart and + * receiveStartTLI), and also to tell it to send apply feedback to the + * primary whenever specially marked commit records are applied. This is + * normally mapped to procLatch when walreceiver is running. + */ + Latch *latch; + + slock_t mutex; /* locks shared variables shown above */ + + /* + * Like flushedUpto, but advanced after writing and before flushing, + * without the need to acquire the spin lock. Data can be read by another + * process up to this point, but shouldn't be used for data integrity + * purposes. + */ + pg_atomic_uint64 writtenUpto; + + /* + * force walreceiver reply? This doesn't need to be locked; memory + * barriers for ordering are sufficient. But we do need atomic fetch and + * store semantics, so use sig_atomic_t. + */ + sig_atomic_t force_reply; /* used as a bool */ +} WalRcvData; + +extern PGDLLIMPORT WalRcvData *WalRcv; + +typedef struct +{ + bool logical; /* True if this is logical replication stream, + * false if physical stream. */ + char *slotname; /* Name of the replication slot or NULL. */ + XLogRecPtr startpoint; /* LSN of starting point. */ + + union + { + struct + { + TimeLineID startpointTLI; /* Starting timeline */ + } physical; + struct + { + uint32 proto_version; /* Logical protocol version */ + List *publication_names; /* String list of publications */ + bool binary; /* Ask publisher to use binary */ + char *streaming_str; /* Streaming of large transactions */ + bool twophase; /* Streaming of two-phase transactions at + * prepare time */ + char *origin; /* Only publish data originating from the + * specified origin */ + } logical; + } proto; +} WalRcvStreamOptions; + +struct WalReceiverConn; +typedef struct WalReceiverConn WalReceiverConn; + +/* + * Status of walreceiver query execution. + * + * We only define statuses that are currently used. + */ +typedef enum +{ + WALRCV_ERROR, /* There was error when executing the query. */ + WALRCV_OK_COMMAND, /* Query executed utility or replication + * command. */ + WALRCV_OK_TUPLES, /* Query returned tuples. */ + WALRCV_OK_COPY_IN, /* Query started COPY FROM. */ + WALRCV_OK_COPY_OUT, /* Query started COPY TO. */ + WALRCV_OK_COPY_BOTH /* Query started COPY BOTH replication + * protocol. */ +} WalRcvExecStatus; + +/* + * Return value for walrcv_exec, returns the status of the execution and + * tuples if any. + */ +typedef struct WalRcvExecResult +{ + WalRcvExecStatus status; + int sqlstate; + char *err; + Tuplestorestate *tuplestore; + TupleDesc tupledesc; +} WalRcvExecResult; + +/* WAL receiver - libpqwalreceiver hooks */ + +/* + * walrcv_connect_fn + * + * Establish connection to a cluster. 'logical' is true if the + * connection is logical, and false if the connection is physical. + * 'appname' is a name associated to the connection, to use for example + * with fallback_application_name or application_name. Returns the + * details about the connection established, as defined by + * WalReceiverConn for each WAL receiver module. On error, NULL is + * returned with 'err' including the error generated. + */ +typedef WalReceiverConn *(*walrcv_connect_fn) (const char *conninfo, + bool logical, + bool must_use_password, + const char *appname, + char **err); + +/* + * walrcv_check_conninfo_fn + * + * Parse and validate the connection string given as of 'conninfo'. + */ +typedef void (*walrcv_check_conninfo_fn) (const char *conninfo, + bool must_use_password); + +/* + * walrcv_get_conninfo_fn + * + * Returns a user-displayable conninfo string. Note that any + * security-sensitive fields should be obfuscated. + */ +typedef char *(*walrcv_get_conninfo_fn) (WalReceiverConn *conn); + +/* + * walrcv_get_senderinfo_fn + * + * Provide information of the WAL sender this WAL receiver is connected + * to, as of 'sender_host' for the host of the sender and 'sender_port' + * for its port. + */ +typedef void (*walrcv_get_senderinfo_fn) (WalReceiverConn *conn, + char **sender_host, + int *sender_port); + +/* + * walrcv_identify_system_fn + * + * Run IDENTIFY_SYSTEM on the cluster connected to and validate the + * identity of the cluster. Returns the system ID of the cluster + * connected to. 'primary_tli' is the timeline ID of the sender. + */ +typedef char *(*walrcv_identify_system_fn) (WalReceiverConn *conn, + TimeLineID *primary_tli); + +/* + * walrcv_server_version_fn + * + * Returns the version number of the cluster connected to. + */ +typedef int (*walrcv_server_version_fn) (WalReceiverConn *conn); + +/* + * walrcv_readtimelinehistoryfile_fn + * + * Fetch from cluster the timeline history file for timeline 'tli'. + * Returns the name of the timeline history file as of 'filename', its + * contents as of 'content' and its 'size'. + */ +typedef void (*walrcv_readtimelinehistoryfile_fn) (WalReceiverConn *conn, + TimeLineID tli, + char **filename, + char **content, + int *size); + +/* + * walrcv_startstreaming_fn + * + * Start streaming WAL data from given streaming options. Returns true + * if the connection has switched successfully to copy-both mode and false + * if the server received the command and executed it successfully, but + * didn't switch to copy-mode. + */ +typedef bool (*walrcv_startstreaming_fn) (WalReceiverConn *conn, + const WalRcvStreamOptions *options); + +/* + * walrcv_endstreaming_fn + * + * Stop streaming of WAL data. Returns the next timeline ID of the cluster + * connected to in 'next_tli', or 0 if there was no report. + */ +typedef void (*walrcv_endstreaming_fn) (WalReceiverConn *conn, + TimeLineID *next_tli); + +/* + * walrcv_receive_fn + * + * Receive a message available from the WAL stream. 'buffer' is a pointer + * to a buffer holding the message received. Returns the length of the data, + * 0 if no data is available yet ('wait_fd' is a socket descriptor which can + * be waited on before a retry), and -1 if the cluster ended the COPY. + */ +typedef int (*walrcv_receive_fn) (WalReceiverConn *conn, + char **buffer, + pgsocket *wait_fd); + +/* + * walrcv_send_fn + * + * Send a message of size 'nbytes' to the WAL stream with 'buffer' as + * contents. + */ +typedef void (*walrcv_send_fn) (WalReceiverConn *conn, + const char *buffer, + int nbytes); + +/* + * walrcv_create_slot_fn + * + * Create a new replication slot named 'slotname'. 'temporary' defines + * if the slot is temporary. 'snapshot_action' defines the behavior wanted + * for an exported snapshot (see replication protocol for more details). + * 'lsn' includes the LSN position at which the created slot became + * consistent. Returns the name of the exported snapshot for a logical + * slot, or NULL for a physical slot. + */ +typedef char *(*walrcv_create_slot_fn) (WalReceiverConn *conn, + const char *slotname, + bool temporary, + bool two_phase, + CRSSnapshotAction snapshot_action, + XLogRecPtr *lsn); + +/* + * walrcv_get_backend_pid_fn + * + * Returns the PID of the remote backend process. + */ +typedef pid_t (*walrcv_get_backend_pid_fn) (WalReceiverConn *conn); + +/* + * walrcv_exec_fn + * + * Send generic queries (and commands) to the remote cluster. 'nRetTypes' + * is the expected number of returned attributes, and 'retTypes' an array + * including their type OIDs. Returns the status of the execution and + * tuples if any. + */ +typedef WalRcvExecResult *(*walrcv_exec_fn) (WalReceiverConn *conn, + const char *query, + const int nRetTypes, + const Oid *retTypes); + +/* + * walrcv_disconnect_fn + * + * Disconnect with the cluster. + */ +typedef void (*walrcv_disconnect_fn) (WalReceiverConn *conn); + +typedef struct WalReceiverFunctionsType +{ + walrcv_connect_fn walrcv_connect; + walrcv_check_conninfo_fn walrcv_check_conninfo; + walrcv_get_conninfo_fn walrcv_get_conninfo; + walrcv_get_senderinfo_fn walrcv_get_senderinfo; + walrcv_identify_system_fn walrcv_identify_system; + walrcv_server_version_fn walrcv_server_version; + walrcv_readtimelinehistoryfile_fn walrcv_readtimelinehistoryfile; + walrcv_startstreaming_fn walrcv_startstreaming; + walrcv_endstreaming_fn walrcv_endstreaming; + walrcv_receive_fn walrcv_receive; + walrcv_send_fn walrcv_send; + walrcv_create_slot_fn walrcv_create_slot; + walrcv_get_backend_pid_fn walrcv_get_backend_pid; + walrcv_exec_fn walrcv_exec; + walrcv_disconnect_fn walrcv_disconnect; +} WalReceiverFunctionsType; + +extern PGDLLIMPORT WalReceiverFunctionsType *WalReceiverFunctions; + +#define walrcv_connect(conninfo, logical, must_use_password, appname, err) \ + WalReceiverFunctions->walrcv_connect(conninfo, logical, must_use_password, appname, err) +#define walrcv_check_conninfo(conninfo, must_use_password) \ + WalReceiverFunctions->walrcv_check_conninfo(conninfo, must_use_password) +#define walrcv_get_conninfo(conn) \ + WalReceiverFunctions->walrcv_get_conninfo(conn) +#define walrcv_get_senderinfo(conn, sender_host, sender_port) \ + WalReceiverFunctions->walrcv_get_senderinfo(conn, sender_host, sender_port) +#define walrcv_identify_system(conn, primary_tli) \ + WalReceiverFunctions->walrcv_identify_system(conn, primary_tli) +#define walrcv_server_version(conn) \ + WalReceiverFunctions->walrcv_server_version(conn) +#define walrcv_readtimelinehistoryfile(conn, tli, filename, content, size) \ + WalReceiverFunctions->walrcv_readtimelinehistoryfile(conn, tli, filename, content, size) +#define walrcv_startstreaming(conn, options) \ + WalReceiverFunctions->walrcv_startstreaming(conn, options) +#define walrcv_endstreaming(conn, next_tli) \ + WalReceiverFunctions->walrcv_endstreaming(conn, next_tli) +#define walrcv_receive(conn, buffer, wait_fd) \ + WalReceiverFunctions->walrcv_receive(conn, buffer, wait_fd) +#define walrcv_send(conn, buffer, nbytes) \ + WalReceiverFunctions->walrcv_send(conn, buffer, nbytes) +#define walrcv_create_slot(conn, slotname, temporary, two_phase, snapshot_action, lsn) \ + WalReceiverFunctions->walrcv_create_slot(conn, slotname, temporary, two_phase, snapshot_action, lsn) +#define walrcv_get_backend_pid(conn) \ + WalReceiverFunctions->walrcv_get_backend_pid(conn) +#define walrcv_exec(conn, exec, nRetTypes, retTypes) \ + WalReceiverFunctions->walrcv_exec(conn, exec, nRetTypes, retTypes) +#define walrcv_disconnect(conn) \ + WalReceiverFunctions->walrcv_disconnect(conn) + +static inline void +walrcv_clear_result(WalRcvExecResult *walres) +{ + if (!walres) + return; + + if (walres->err) + pfree(walres->err); + + if (walres->tuplestore) + tuplestore_end(walres->tuplestore); + + if (walres->tupledesc) + FreeTupleDesc(walres->tupledesc); + + pfree(walres); +} + +/* prototypes for functions in walreceiver.c */ +extern void WalReceiverMain(void) pg_attribute_noreturn(); +extern void ProcessWalRcvInterrupts(void); +extern void WalRcvForceReply(void); + +/* prototypes for functions in walreceiverfuncs.c */ +extern Size WalRcvShmemSize(void); +extern void WalRcvShmemInit(void); +extern void ShutdownWalRcv(void); +extern bool WalRcvStreaming(void); +extern bool WalRcvRunning(void); +extern void RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, + const char *conninfo, const char *slotname, + bool create_temp_slot); +extern XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI); +extern XLogRecPtr GetWalRcvWriteRecPtr(void); +extern int GetReplicationApplyDelay(void); +extern int GetReplicationTransferLatency(void); + +#endif /* _WALRECEIVER_H */ diff --git a/install/include/postgresql/server/replication/walsender.h b/install/include/postgresql/server/replication/walsender.h new file mode 100644 index 00000000000..9df7e50f943 --- /dev/null +++ b/install/include/postgresql/server/replication/walsender.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * walsender.h + * Exports from replication/walsender.c. + * + * Portions Copyright (c) 2010-2023, PostgreSQL Global Development Group + * + * src/include/replication/walsender.h + * + *------------------------------------------------------------------------- + */ +#ifndef _WALSENDER_H +#define _WALSENDER_H + +#include + +/* + * What to do with a snapshot in create replication slot command. + */ +typedef enum +{ + CRS_EXPORT_SNAPSHOT, + CRS_NOEXPORT_SNAPSHOT, + CRS_USE_SNAPSHOT +} CRSSnapshotAction; + +/* global state */ +extern PGDLLIMPORT bool am_walsender; +extern PGDLLIMPORT bool am_cascading_walsender; +extern PGDLLIMPORT bool am_db_walsender; +extern PGDLLIMPORT bool wake_wal_senders; + +/* user-settable parameters */ +extern PGDLLIMPORT int max_wal_senders; +extern PGDLLIMPORT int wal_sender_timeout; +extern PGDLLIMPORT bool log_replication_commands; + +extern void InitWalSender(void); +extern bool exec_replication_command(const char *cmd_string); +extern void WalSndErrorCleanup(void); +extern void WalSndResourceCleanup(bool isCommit); +extern void WalSndSignals(void); +extern Size WalSndShmemSize(void); +extern void WalSndShmemInit(void); +extern void WalSndWakeup(bool physical, bool logical); +extern void WalSndInitStopping(void); +extern void WalSndWaitStopping(void); +extern void HandleWalSndInitStopping(void); +extern void WalSndRqstFileReload(void); + +/* + * Remember that we want to wakeup walsenders later + * + * This is separated from doing the actual wakeup because the writeout is done + * while holding contended locks. + */ +#define WalSndWakeupRequest() \ + do { wake_wal_senders = true; } while (0) + +/* + * wakeup walsenders if there is work to be done + */ +static inline void +WalSndWakeupProcessRequests(bool physical, bool logical) +{ + if (wake_wal_senders) + { + wake_wal_senders = false; + if (max_wal_senders > 0) + WalSndWakeup(physical, logical); + } +} + +#endif /* _WALSENDER_H */ diff --git a/install/include/postgresql/server/replication/walsender_private.h b/install/include/postgresql/server/replication/walsender_private.h new file mode 100644 index 00000000000..48e1bd1a5aa --- /dev/null +++ b/install/include/postgresql/server/replication/walsender_private.h @@ -0,0 +1,152 @@ +/*------------------------------------------------------------------------- + * + * walsender_private.h + * Private definitions from replication/walsender.c. + * + * Portions Copyright (c) 2010-2023, PostgreSQL Global Development Group + * + * src/include/replication/walsender_private.h + * + *------------------------------------------------------------------------- + */ +#ifndef _WALSENDER_PRIVATE_H +#define _WALSENDER_PRIVATE_H + +#include "access/xlog.h" +#include "lib/ilist.h" +#include "nodes/nodes.h" +#include "nodes/replnodes.h" +#include "replication/syncrep.h" +#include "storage/condition_variable.h" +#include "storage/latch.h" +#include "storage/shmem.h" +#include "storage/spin.h" + +typedef enum WalSndState +{ + WALSNDSTATE_STARTUP = 0, + WALSNDSTATE_BACKUP, + WALSNDSTATE_CATCHUP, + WALSNDSTATE_STREAMING, + WALSNDSTATE_STOPPING +} WalSndState; + +/* + * Each walsender has a WalSnd struct in shared memory. + * + * This struct is protected by its 'mutex' spinlock field, except that some + * members are only written by the walsender process itself, and thus that + * process is free to read those members without holding spinlock. pid and + * needreload always require the spinlock to be held for all accesses. + */ +typedef struct WalSnd +{ + pid_t pid; /* this walsender's PID, or 0 if not active */ + + WalSndState state; /* this walsender's state */ + XLogRecPtr sentPtr; /* WAL has been sent up to this point */ + bool needreload; /* does currently-open file need to be + * reloaded? */ + + /* + * The xlog locations that have been written, flushed, and applied by + * standby-side. These may be invalid if the standby-side has not offered + * values yet. + */ + XLogRecPtr write; + XLogRecPtr flush; + XLogRecPtr apply; + + /* Measured lag times, or -1 for unknown/none. */ + TimeOffset writeLag; + TimeOffset flushLag; + TimeOffset applyLag; + + /* + * The priority order of the standby managed by this WALSender, as listed + * in synchronous_standby_names, or 0 if not-listed. + */ + int sync_standby_priority; + + /* Protects shared variables in this structure. */ + slock_t mutex; + + /* + * Pointer to the walsender's latch. Used by backends to wake up this + * walsender when it has work to do. NULL if the walsender isn't active. + */ + Latch *latch; + + /* + * Timestamp of the last message received from standby. + */ + TimestampTz replyTime; + + ReplicationKind kind; +} WalSnd; + +extern PGDLLIMPORT WalSnd *MyWalSnd; + +/* There is one WalSndCtl struct for the whole database cluster */ +typedef struct +{ + /* + * Synchronous replication queue with one queue per request type. + * Protected by SyncRepLock. + */ + dlist_head SyncRepQueue[NUM_SYNC_REP_WAIT_MODE]; + + /* + * Current location of the head of the queue. All waiters should have a + * waitLSN that follows this value. Protected by SyncRepLock. + */ + XLogRecPtr lsn[NUM_SYNC_REP_WAIT_MODE]; + + /* + * Status of data related to the synchronous standbys. Waiting backends + * can't reload the config file safely, so checkpointer updates this value + * as needed. Protected by SyncRepLock. + */ + bits8 sync_standbys_status; + + /* used as a registry of physical / logical walsenders to wake */ + ConditionVariable wal_flush_cv; + ConditionVariable wal_replay_cv; + + WalSnd walsnds[FLEXIBLE_ARRAY_MEMBER]; +} WalSndCtlData; + +/* Flags for WalSndCtlData->sync_standbys_status */ + +/* + * Is the synchronous standby data initialized from the GUC? This is set the + * first time synchronous_standby_names is processed by the checkpointer. + */ +#define SYNC_STANDBY_INIT (1 << 0) + +/* + * Is the synchronous standby data defined? This is set when + * synchronous_standby_names has some data, after being processed by the + * checkpointer. + */ +#define SYNC_STANDBY_DEFINED (1 << 1) + +extern PGDLLIMPORT WalSndCtlData *WalSndCtl; + + +extern void WalSndSetState(WalSndState state); + +/* + * Internal functions for parsing the replication grammar, in repl_gram.y and + * repl_scanner.l + */ +extern int replication_yyparse(void); +extern int replication_yylex(void); +extern void replication_yyerror(const char *message) pg_attribute_noreturn(); +extern void replication_scanner_init(const char *str); +extern void replication_scanner_finish(void); +extern bool replication_scanner_is_replication_command(void); + +extern PGDLLIMPORT Node *replication_parse_result; + +#endif /* _WALSENDER_PRIVATE_H */ diff --git a/install/include/postgresql/server/replication/worker_internal.h b/install/include/postgresql/server/replication/worker_internal.h new file mode 100644 index 00000000000..343e7818965 --- /dev/null +++ b/install/include/postgresql/server/replication/worker_internal.h @@ -0,0 +1,329 @@ +/*------------------------------------------------------------------------- + * + * worker_internal.h + * Internal headers shared by logical replication workers. + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * src/include/replication/worker_internal.h + * + *------------------------------------------------------------------------- + */ +#ifndef WORKER_INTERNAL_H +#define WORKER_INTERNAL_H + +#include + +#include "access/xlogdefs.h" +#include "catalog/pg_subscription.h" +#include "datatype/timestamp.h" +#include "miscadmin.h" +#include "replication/logicalrelation.h" +#include "storage/buffile.h" +#include "storage/fileset.h" +#include "storage/lock.h" +#include "storage/shm_mq.h" +#include "storage/shm_toc.h" +#include "storage/spin.h" + + +typedef struct LogicalRepWorker +{ + /* Time at which this worker was launched. */ + TimestampTz launch_time; + + /* Indicates if this slot is used or free. */ + bool in_use; + + /* Increased every time the slot is taken by new worker. */ + uint16 generation; + + /* Pointer to proc array. NULL if not running. */ + PGPROC *proc; + + /* Database id to connect to. */ + Oid dbid; + + /* User to use for connection (will be same as owner of subscription). */ + Oid userid; + + /* Subscription id for the worker. */ + Oid subid; + + /* Used for initial table synchronization. */ + Oid relid; + char relstate; + XLogRecPtr relstate_lsn; + slock_t relmutex; + + /* + * Used to create the changes and subxact files for the streaming + * transactions. Upon the arrival of the first streaming transaction or + * when the first-time leader apply worker times out while sending changes + * to the parallel apply worker, the fileset will be initialized, and it + * will be deleted when the worker exits. Under this, separate buffiles + * would be created for each transaction which will be deleted after the + * transaction is finished. + */ + FileSet *stream_fileset; + + /* + * PID of leader apply worker if this slot is used for a parallel apply + * worker, InvalidPid otherwise. + */ + pid_t leader_pid; + + /* Indicates whether apply can be performed in parallel. */ + bool parallel_apply; + + /* Stats. */ + XLogRecPtr last_lsn; + TimestampTz last_send_time; + TimestampTz last_recv_time; + XLogRecPtr reply_lsn; + TimestampTz reply_time; +} LogicalRepWorker; + +/* + * State of the transaction in parallel apply worker. + * + * The enum values must have the same order as the transaction state + * transitions. + */ +typedef enum ParallelTransState +{ + PARALLEL_TRANS_UNKNOWN, + PARALLEL_TRANS_STARTED, + PARALLEL_TRANS_FINISHED +} ParallelTransState; + +/* + * State of fileset used to communicate changes from leader to parallel + * apply worker. + * + * FS_EMPTY indicates an initial state where the leader doesn't need to use + * the file to communicate with the parallel apply worker. + * + * FS_SERIALIZE_IN_PROGRESS indicates that the leader is serializing changes + * to the file. + * + * FS_SERIALIZE_DONE indicates that the leader has serialized all changes to + * the file. + * + * FS_READY indicates that it is now ok for a parallel apply worker to + * read the file. + */ +typedef enum PartialFileSetState +{ + FS_EMPTY, + FS_SERIALIZE_IN_PROGRESS, + FS_SERIALIZE_DONE, + FS_READY +} PartialFileSetState; + +/* + * Struct for sharing information between leader apply worker and parallel + * apply workers. + */ +typedef struct ParallelApplyWorkerShared +{ + slock_t mutex; + + TransactionId xid; + + /* + * State used to ensure commit ordering. + * + * The parallel apply worker will set it to PARALLEL_TRANS_FINISHED after + * handling the transaction finish commands while the apply leader will + * wait for it to become PARALLEL_TRANS_FINISHED before proceeding in + * transaction finish commands (e.g. STREAM_COMMIT/STREAM_PREPARE/ + * STREAM_ABORT). + */ + ParallelTransState xact_state; + + /* Information from the corresponding LogicalRepWorker slot. */ + uint16 logicalrep_worker_generation; + int logicalrep_worker_slot_no; + + /* + * Indicates whether there are pending streaming blocks in the queue. The + * parallel apply worker will check it before starting to wait. + */ + pg_atomic_uint32 pending_stream_count; + + /* + * XactLastCommitEnd from the parallel apply worker. This is required by + * the leader worker so it can update the lsn_mappings. + */ + XLogRecPtr last_commit_end; + + /* + * After entering PARTIAL_SERIALIZE mode, the leader apply worker will + * serialize changes to the file, and share the fileset with the parallel + * apply worker when processing the transaction finish command. Then the + * parallel apply worker will apply all the spooled messages. + * + * FileSet is used here instead of SharedFileSet because we need it to + * survive after releasing the shared memory so that the leader apply + * worker can re-use the same fileset for the next streaming transaction. + */ + PartialFileSetState fileset_state; + FileSet fileset; +} ParallelApplyWorkerShared; + +/* + * Information which is used to manage the parallel apply worker. + */ +typedef struct ParallelApplyWorkerInfo +{ + /* + * This queue is used to send changes from the leader apply worker to the + * parallel apply worker. + */ + shm_mq_handle *mq_handle; + + /* + * This queue is used to transfer error messages from the parallel apply + * worker to the leader apply worker. + */ + shm_mq_handle *error_mq_handle; + + dsm_segment *dsm_seg; + + /* + * Indicates whether the leader apply worker needs to serialize the + * remaining changes to a file due to timeout when attempting to send data + * to the parallel apply worker via shared memory. + */ + bool serialize_changes; + + /* + * True if the worker is being used to process a parallel apply + * transaction. False indicates this worker is available for re-use. + */ + bool in_use; + + ParallelApplyWorkerShared *shared; +} ParallelApplyWorkerInfo; + +/* Main memory context for apply worker. Permanent during worker lifetime. */ +extern PGDLLIMPORT MemoryContext ApplyContext; + +extern PGDLLIMPORT MemoryContext ApplyMessageContext; + +extern PGDLLIMPORT ErrorContextCallback *apply_error_context_stack; + +extern PGDLLIMPORT ParallelApplyWorkerShared *MyParallelShared; + +/* libpqreceiver connection */ +extern PGDLLIMPORT struct WalReceiverConn *LogRepWorkerWalRcvConn; + +/* Worker and subscription objects. */ +extern PGDLLIMPORT Subscription *MySubscription; +extern PGDLLIMPORT LogicalRepWorker *MyLogicalRepWorker; + +extern PGDLLIMPORT bool in_remote_transaction; + +extern PGDLLIMPORT bool InitializingApplyWorker; + +extern void logicalrep_worker_attach(int slot); +extern LogicalRepWorker *logicalrep_worker_find(Oid subid, Oid relid, + bool only_running); +extern List *logicalrep_workers_find(Oid subid, bool only_running); +extern bool logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, + Oid userid, Oid relid, + dsm_handle subworker_dsm); +extern void logicalrep_worker_stop(Oid subid, Oid relid); +extern void logicalrep_pa_worker_stop(ParallelApplyWorkerInfo *winfo); +extern void logicalrep_worker_wakeup(Oid subid, Oid relid); +extern void logicalrep_worker_wakeup_ptr(LogicalRepWorker *worker); + +extern int logicalrep_sync_worker_count(Oid subid); + +extern void ReplicationOriginNameForLogicalRep(Oid suboid, Oid relid, + char *originname, Size szoriginname); +extern char *LogicalRepSyncTableStart(XLogRecPtr *origin_startpos); + +extern bool AllTablesyncsReady(void); +extern void UpdateTwoPhaseState(Oid suboid, char new_state); + +extern void process_syncing_tables(XLogRecPtr current_lsn); +extern void invalidate_syncing_table_states(Datum arg, int cacheid, + uint32 hashvalue); + +extern void stream_start_internal(TransactionId xid, bool first_segment); +extern void stream_stop_internal(TransactionId xid); + +/* Common streaming function to apply all the spooled messages */ +extern void apply_spooled_messages(FileSet *stream_fileset, TransactionId xid, + XLogRecPtr lsn); + +extern void apply_dispatch(StringInfo s); + +extern void maybe_reread_subscription(void); + +extern void stream_cleanup_files(Oid subid, TransactionId xid); + +extern void InitializeApplyWorker(void); + +extern void store_flush_position(XLogRecPtr remote_lsn, XLogRecPtr local_lsn); + +/* Function for apply error callback */ +extern void apply_error_callback(void *arg); +extern void set_apply_error_context_origin(char *originname); + +/* Parallel apply worker setup and interactions */ +extern void pa_allocate_worker(TransactionId xid); +extern ParallelApplyWorkerInfo *pa_find_worker(TransactionId xid); +extern void pa_detach_all_error_mq(void); + +extern bool pa_send_data(ParallelApplyWorkerInfo *winfo, Size nbytes, + const void *data); +extern void pa_switch_to_partial_serialize(ParallelApplyWorkerInfo *winfo, + bool stream_locked); + +extern void pa_set_xact_state(ParallelApplyWorkerShared *wshared, + ParallelTransState xact_state); +extern void pa_set_stream_apply_worker(ParallelApplyWorkerInfo *winfo); + +extern void pa_start_subtrans(TransactionId current_xid, + TransactionId top_xid); +extern void pa_reset_subtrans(void); +extern void pa_stream_abort(LogicalRepStreamAbortData *abort_data); +extern void pa_set_fileset_state(ParallelApplyWorkerShared *wshared, + PartialFileSetState fileset_state); + +extern void pa_lock_stream(TransactionId xid, LOCKMODE lockmode); +extern void pa_unlock_stream(TransactionId xid, LOCKMODE lockmode); + +extern void pa_lock_transaction(TransactionId xid, LOCKMODE lockmode); +extern void pa_unlock_transaction(TransactionId xid, LOCKMODE lockmode); + +extern void pa_decr_and_wait_stream_block(void); + +extern void pa_xact_finish(ParallelApplyWorkerInfo *winfo, + XLogRecPtr remote_lsn); + +#define isParallelApplyWorker(worker) ((worker)->leader_pid != InvalidPid) + +static inline bool +am_tablesync_worker(void) +{ + return OidIsValid(MyLogicalRepWorker->relid); +} + +static inline bool +am_leader_apply_worker(void) +{ + return (!am_tablesync_worker() && + !isParallelApplyWorker(MyLogicalRepWorker)); +} + +static inline bool +am_parallel_apply_worker(void) +{ + return isParallelApplyWorker(MyLogicalRepWorker); +} + +#endif /* WORKER_INTERNAL_H */ diff --git a/install/include/postgresql/server/rewrite/prs2lock.h b/install/include/postgresql/server/rewrite/prs2lock.h new file mode 100644 index 00000000000..f94bdfd245e --- /dev/null +++ b/install/include/postgresql/server/rewrite/prs2lock.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + * + * prs2lock.h + * data structures for POSTGRES Rule System II (rewrite rules only) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/rewrite/prs2lock.h + * + *------------------------------------------------------------------------- + */ +#ifndef PRS2LOCK_H +#define PRS2LOCK_H + +#include "access/attnum.h" +#include "nodes/pg_list.h" + +/* + * RewriteRule - + * holds an info for a rewrite rule + * + */ +typedef struct RewriteRule +{ + Oid ruleId; + CmdType event; + Node *qual; + List *actions; + char enabled; + bool isInstead; +} RewriteRule; + +/* + * RuleLock - + * all rules that apply to a particular relation. Even though we only + * have the rewrite rule system left and these are not really "locks", + * the name is kept for historical reasons. + */ +typedef struct RuleLock +{ + int numLocks; + RewriteRule **rules; +} RuleLock; + +#endif /* PRS2LOCK_H */ diff --git a/install/include/postgresql/server/rewrite/rewriteDefine.h b/install/include/postgresql/server/rewrite/rewriteDefine.h new file mode 100644 index 00000000000..81a7ea034f3 --- /dev/null +++ b/install/include/postgresql/server/rewrite/rewriteDefine.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * rewriteDefine.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/rewrite/rewriteDefine.h + * + *------------------------------------------------------------------------- + */ +#ifndef REWRITEDEFINE_H +#define REWRITEDEFINE_H + +#include "catalog/objectaddress.h" +#include "nodes/parsenodes.h" +#include "utils/relcache.h" + +#define RULE_FIRES_ON_ORIGIN 'O' +#define RULE_FIRES_ALWAYS 'A' +#define RULE_FIRES_ON_REPLICA 'R' +#define RULE_DISABLED 'D' + +extern ObjectAddress DefineRule(RuleStmt *stmt, const char *queryString); + +extern ObjectAddress DefineQueryRewrite(const char *rulename, + Oid event_relid, + Node *event_qual, + CmdType event_type, + bool is_instead, + bool replace, + List *action); + +extern ObjectAddress RenameRewriteRule(RangeVar *relation, const char *oldName, + const char *newName); + +extern void setRuleCheckAsUser(Node *node, Oid userid); + +extern void EnableDisableRule(Relation rel, const char *rulename, + char fires_when); + +#endif /* REWRITEDEFINE_H */ diff --git a/install/include/postgresql/server/rewrite/rewriteHandler.h b/install/include/postgresql/server/rewrite/rewriteHandler.h new file mode 100644 index 00000000000..b71e20b087c --- /dev/null +++ b/install/include/postgresql/server/rewrite/rewriteHandler.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * rewriteHandler.h + * External interface to query rewriter. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/rewrite/rewriteHandler.h + * + *------------------------------------------------------------------------- + */ +#ifndef REWRITEHANDLER_H +#define REWRITEHANDLER_H + +#include "nodes/parsenodes.h" +#include "utils/relcache.h" + +extern List *QueryRewrite(Query *parsetree); +extern void AcquireRewriteLocks(Query *parsetree, + bool forExecute, + bool forUpdatePushedDown); + +extern Node *build_column_default(Relation rel, int attrno); + +extern Query *get_view_query(Relation view); +extern const char *view_query_is_auto_updatable(Query *viewquery, + bool check_cols); +extern int relation_is_updatable(Oid reloid, + List *outer_reloids, + bool include_triggers, + Bitmapset *include_cols); + +#endif /* REWRITEHANDLER_H */ diff --git a/install/include/postgresql/server/rewrite/rewriteManip.h b/install/include/postgresql/server/rewrite/rewriteManip.h new file mode 100644 index 00000000000..365061fff44 --- /dev/null +++ b/install/include/postgresql/server/rewrite/rewriteManip.h @@ -0,0 +1,96 @@ +/*------------------------------------------------------------------------- + * + * rewriteManip.h + * Querytree manipulation subroutines for query rewriter. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/rewrite/rewriteManip.h + * + *------------------------------------------------------------------------- + */ +#ifndef REWRITEMANIP_H +#define REWRITEMANIP_H + +#include "nodes/parsenodes.h" + +struct AttrMap; /* avoid including attmap.h here */ + + +typedef struct replace_rte_variables_context replace_rte_variables_context; + +typedef Node *(*replace_rte_variables_callback) (Var *var, + replace_rte_variables_context *context); + +struct replace_rte_variables_context +{ + replace_rte_variables_callback callback; /* callback function */ + void *callback_arg; /* context data for callback function */ + int target_varno; /* RTE index to search for */ + int sublevels_up; /* (current) nesting depth */ + bool inserted_sublink; /* have we inserted a SubLink? */ +}; + +typedef enum ReplaceVarsNoMatchOption +{ + REPLACEVARS_REPORT_ERROR, /* throw error if no match */ + REPLACEVARS_CHANGE_VARNO, /* change the Var's varno, nothing else */ + REPLACEVARS_SUBSTITUTE_NULL /* replace with a NULL Const */ +} ReplaceVarsNoMatchOption; + + +extern void CombineRangeTables(List **dst_rtable, List **dst_perminfos, + List *src_rtable, List *src_perminfos); +extern void OffsetVarNodes(Node *node, int offset, int sublevels_up); +extern void ChangeVarNodes(Node *node, int rt_index, int new_index, + int sublevels_up); +extern void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, + int min_sublevels_up); +extern void IncrementVarSublevelsUp_rtable(List *rtable, + int delta_sublevels_up, int min_sublevels_up); + +extern bool rangeTableEntry_used(Node *node, int rt_index, + int sublevels_up); + +extern Query *getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr); + +extern void AddQual(Query *parsetree, Node *qual); +extern void AddInvertedQual(Query *parsetree, Node *qual); + +extern bool contain_aggs_of_level(Node *node, int levelsup); +extern int locate_agg_of_level(Node *node, int levelsup); +extern bool contain_windowfuncs(Node *node); +extern int locate_windowfunc(Node *node); +extern bool checkExprHasSubLink(Node *node); + +extern Node *add_nulling_relids(Node *node, + const Bitmapset *target_relids, + const Bitmapset *added_relids); +extern Node *remove_nulling_relids(Node *node, + const Bitmapset *removable_relids, + const Bitmapset *except_relids); + +extern Node *replace_rte_variables(Node *node, + int target_varno, int sublevels_up, + replace_rte_variables_callback callback, + void *callback_arg, + bool *outer_hasSubLinks); +extern Node *replace_rte_variables_mutator(Node *node, + replace_rte_variables_context *context); + +extern Node *map_variable_attnos(Node *node, + int target_varno, int sublevels_up, + const struct AttrMap *attno_map, + Oid to_rowtype, bool *found_whole_row); + +extern Node *ReplaceVarsFromTargetList(Node *node, + int target_varno, int sublevels_up, + RangeTblEntry *target_rte, + List *targetlist, + ReplaceVarsNoMatchOption nomatch_option, + int nomatch_varno, + bool *outer_hasSubLinks); + +#endif /* REWRITEMANIP_H */ diff --git a/install/include/postgresql/server/rewrite/rewriteRemove.h b/install/include/postgresql/server/rewrite/rewriteRemove.h new file mode 100644 index 00000000000..1413c11b667 --- /dev/null +++ b/install/include/postgresql/server/rewrite/rewriteRemove.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * rewriteRemove.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/rewrite/rewriteRemove.h + * + *------------------------------------------------------------------------- + */ +#ifndef REWRITEREMOVE_H +#define REWRITEREMOVE_H + +#include "nodes/parsenodes.h" + +extern void RemoveRewriteRuleById(Oid ruleOid); + +#endif /* REWRITEREMOVE_H */ diff --git a/install/include/postgresql/server/rewrite/rewriteSearchCycle.h b/install/include/postgresql/server/rewrite/rewriteSearchCycle.h new file mode 100644 index 00000000000..102db81dc40 --- /dev/null +++ b/install/include/postgresql/server/rewrite/rewriteSearchCycle.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * rewriteSearchCycle.h + * Support for rewriting SEARCH and CYCLE clauses. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/rewrite/rewriteSearchCycle.h + * + *------------------------------------------------------------------------- + */ +#ifndef REWRITESEARCHCYCLE_H +#define REWRITESEARCHCYCLE_H + +#include "nodes/parsenodes.h" + +extern CommonTableExpr *rewriteSearchAndCycle(CommonTableExpr *cte); + +#endif /* REWRITESEARCHCYCLE_H */ diff --git a/install/include/postgresql/server/rewrite/rewriteSupport.h b/install/include/postgresql/server/rewrite/rewriteSupport.h new file mode 100644 index 00000000000..e5dc367e23a --- /dev/null +++ b/install/include/postgresql/server/rewrite/rewriteSupport.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * rewriteSupport.h + * + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/rewrite/rewriteSupport.h + * + *------------------------------------------------------------------------- + */ +#ifndef REWRITESUPPORT_H +#define REWRITESUPPORT_H + +/* The ON SELECT rule of a view is always named this: */ +#define ViewSelectRuleName "_RETURN" + +extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName); + +extern void SetRelationRuleStatus(Oid relationId, bool relHasRules); + +extern Oid get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok); + +#endif /* REWRITESUPPORT_H */ diff --git a/install/include/postgresql/server/rewrite/rowsecurity.h b/install/include/postgresql/server/rewrite/rowsecurity.h new file mode 100644 index 00000000000..d2084357234 --- /dev/null +++ b/install/include/postgresql/server/rewrite/rowsecurity.h @@ -0,0 +1,49 @@ +/* ------------------------------------------------------------------------- + * + * rowsecurity.h + * + * prototypes for rewrite/rowsecurity.c and the structures for managing + * the row security policies for relations in relcache. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * ------------------------------------------------------------------------- + */ +#ifndef ROWSECURITY_H +#define ROWSECURITY_H + +#include "nodes/parsenodes.h" +#include "utils/array.h" +#include "utils/relcache.h" + +typedef struct RowSecurityPolicy +{ + char *policy_name; /* Name of the policy */ + char polcmd; /* Type of command policy is for */ + ArrayType *roles; /* Array of roles policy is for */ + bool permissive; /* restrictive or permissive policy */ + Expr *qual; /* Expression to filter rows */ + Expr *with_check_qual; /* Expression to limit rows allowed */ + bool hassublinks; /* If either expression has sublinks */ +} RowSecurityPolicy; + +typedef struct RowSecurityDesc +{ + MemoryContext rscxt; /* row security memory context */ + List *policies; /* list of row security policies */ +} RowSecurityDesc; + +typedef List *(*row_security_policy_hook_type) (CmdType cmdtype, + Relation relation); + +extern PGDLLIMPORT row_security_policy_hook_type row_security_policy_hook_permissive; + +extern PGDLLIMPORT row_security_policy_hook_type row_security_policy_hook_restrictive; + +extern void get_row_security_policies(Query *root, + RangeTblEntry *rte, int rt_index, + List **securityQuals, List **withCheckOptions, + bool *hasRowSecurity, bool *hasSubLinks); + +#endif /* ROWSECURITY_H */ diff --git a/install/include/postgresql/server/snowball/header.h b/install/include/postgresql/server/snowball/header.h new file mode 100644 index 00000000000..dbf04e39657 --- /dev/null +++ b/install/include/postgresql/server/snowball/header.h @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------- + * + * header.h + * Replacement header file for Snowball stemmer modules + * + * The Snowball stemmer modules do #include "header.h", and think they + * are including snowball/libstemmer/header.h. We adjust the CPPFLAGS + * so that this file is found instead, and thereby we can modify the + * headers they see. The main point here is to ensure that pg_config.h + * is included before any system headers such as ; without that, + * we have portability issues on some platforms due to variation in + * largefile options across different modules in the backend. + * + * NOTE: this file should not be included into any non-snowball sources! + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/snowball/header.h + * + *------------------------------------------------------------------------- + */ +#ifndef SNOWBALL_HEADR_H +#define SNOWBALL_HEADR_H + +/* + * It's against Postgres coding conventions to include postgres.h in a + * header file, but we allow the violation here because the alternative is + * to modify the machine-generated .c files provided by the Snowball project. + */ +#include "postgres.h" + +/* Some platforms define MAXINT and/or MININT, causing conflicts */ +#ifdef MAXINT +#undef MAXINT +#endif +#ifdef MININT +#undef MININT +#endif + +/* Now we can include the original Snowball header.h */ +#include "snowball/libstemmer/header.h" /* pgrminclude ignore */ + +/* + * Redefine standard memory allocation interface to pgsql's one. + * This allows us to control where the Snowball code allocates stuff. + */ +#ifdef malloc +#undef malloc +#endif +#define malloc(a) palloc(a) + +#ifdef calloc +#undef calloc +#endif +#define calloc(a,b) palloc0((a) * (b)) + +#ifdef realloc +#undef realloc +#endif +#define realloc(a,b) repalloc(a,b) + +#ifdef free +#undef free +#endif +#define free(a) pfree(a) + +#endif /* SNOWBALL_HEADR_H */ diff --git a/install/include/postgresql/server/snowball/libstemmer/api.h b/install/include/postgresql/server/snowball/libstemmer/api.h new file mode 100644 index 00000000000..ba9d1c14bca --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/api.h @@ -0,0 +1,32 @@ + +typedef unsigned char symbol; + +/* Or replace 'char' above with 'short' for 16 bit characters. + + More precisely, replace 'char' with whatever type guarantees the + character width you need. Note however that sizeof(symbol) should divide + HEAD, defined in header.h as 2*sizeof(int), without remainder, otherwise + there is an alignment problem. In the unlikely event of a problem here, + consult Martin Porter. + +*/ + +struct SN_env { + symbol * p; + int c; int l; int lb; int bra; int ket; + symbol * * S; + int * I; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * SN_create_env(int S_size, int I_size); +extern void SN_close_env(struct SN_env * z, int S_size); + +extern int SN_set_current(struct SN_env * z, int size, const symbol * s); + +#ifdef __cplusplus +} +#endif diff --git a/install/include/postgresql/server/snowball/libstemmer/header.h b/install/include/postgresql/server/snowball/libstemmer/header.h new file mode 100644 index 00000000000..ef5a5464067 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/header.h @@ -0,0 +1,61 @@ + +#include + +#include "api.h" + +#define MAXINT INT_MAX +#define MININT INT_MIN + +#define HEAD 2*sizeof(int) + +#define SIZE(p) ((int *)(p))[-1] +#define SET_SIZE(p, n) ((int *)(p))[-1] = n +#define CAPACITY(p) ((int *)(p))[-2] + +struct among +{ int s_size; /* number of chars in string */ + const symbol * s; /* search string */ + int substring_i;/* index to longest matching substring */ + int result; /* result of the lookup */ + int (* function)(struct SN_env *); +}; + +extern symbol * create_s(void); +extern void lose_s(symbol * p); + +extern int skip_utf8(const symbol * p, int c, int limit, int n); + +extern int skip_b_utf8(const symbol * p, int c, int limit, int n); + +extern int in_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int in_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int out_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int out_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); + +extern int in_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int in_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int out_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int out_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); + +extern int eq_s(struct SN_env * z, int s_size, const symbol * s); +extern int eq_s_b(struct SN_env * z, int s_size, const symbol * s); +extern int eq_v(struct SN_env * z, const symbol * p); +extern int eq_v_b(struct SN_env * z, const symbol * p); + +extern int find_among(struct SN_env * z, const struct among * v, int v_size); +extern int find_among_b(struct SN_env * z, const struct among * v, int v_size); + +extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int * adjptr); +extern int slice_from_s(struct SN_env * z, int s_size, const symbol * s); +extern int slice_from_v(struct SN_env * z, const symbol * p); +extern int slice_del(struct SN_env * z); + +extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, const symbol * s); +extern int insert_v(struct SN_env * z, int bra, int ket, const symbol * p); + +extern symbol * slice_to(struct SN_env * z, symbol * p); +extern symbol * assign_to(struct SN_env * z, symbol * p); + +extern int len_utf8(const symbol * p); + +extern void debug(struct SN_env * z, int number, int line_count); diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_basque.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_basque.h new file mode 100644 index 00000000000..bffb6e9043e --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_basque.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * basque_ISO_8859_1_create_env(void); +extern void basque_ISO_8859_1_close_env(struct SN_env * z); + +extern int basque_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_catalan.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_catalan.h new file mode 100644 index 00000000000..96e97ddfa2a --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_catalan.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * catalan_ISO_8859_1_create_env(void); +extern void catalan_ISO_8859_1_close_env(struct SN_env * z); + +extern int catalan_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_danish.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_danish.h new file mode 100644 index 00000000000..965436d9a1e --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_danish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * danish_ISO_8859_1_create_env(void); +extern void danish_ISO_8859_1_close_env(struct SN_env * z); + +extern int danish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_dutch.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_dutch.h new file mode 100644 index 00000000000..64f1c6d9163 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_dutch.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * dutch_ISO_8859_1_create_env(void); +extern void dutch_ISO_8859_1_close_env(struct SN_env * z); + +extern int dutch_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_english.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_english.h new file mode 100644 index 00000000000..ea90984b002 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_english.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * english_ISO_8859_1_create_env(void); +extern void english_ISO_8859_1_close_env(struct SN_env * z); + +extern int english_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_finnish.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_finnish.h new file mode 100644 index 00000000000..2c80e4cdead --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_finnish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * finnish_ISO_8859_1_create_env(void); +extern void finnish_ISO_8859_1_close_env(struct SN_env * z); + +extern int finnish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_french.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_french.h new file mode 100644 index 00000000000..1febb49d204 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_french.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * french_ISO_8859_1_create_env(void); +extern void french_ISO_8859_1_close_env(struct SN_env * z); + +extern int french_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_german.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_german.h new file mode 100644 index 00000000000..98696bb336d --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_german.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * german_ISO_8859_1_create_env(void); +extern void german_ISO_8859_1_close_env(struct SN_env * z); + +extern int german_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_indonesian.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_indonesian.h new file mode 100644 index 00000000000..d998b41b2cf --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_indonesian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * indonesian_ISO_8859_1_create_env(void); +extern void indonesian_ISO_8859_1_close_env(struct SN_env * z); + +extern int indonesian_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_irish.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_irish.h new file mode 100644 index 00000000000..d91d2317906 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_irish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * irish_ISO_8859_1_create_env(void); +extern void irish_ISO_8859_1_close_env(struct SN_env * z); + +extern int irish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_italian.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_italian.h new file mode 100644 index 00000000000..22950bd2347 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_italian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * italian_ISO_8859_1_create_env(void); +extern void italian_ISO_8859_1_close_env(struct SN_env * z); + +extern int italian_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_norwegian.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_norwegian.h new file mode 100644 index 00000000000..53930960569 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_norwegian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * norwegian_ISO_8859_1_create_env(void); +extern void norwegian_ISO_8859_1_close_env(struct SN_env * z); + +extern int norwegian_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_porter.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_porter.h new file mode 100644 index 00000000000..f504be101a6 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_porter.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * porter_ISO_8859_1_create_env(void); +extern void porter_ISO_8859_1_close_env(struct SN_env * z); + +extern int porter_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_portuguese.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_portuguese.h new file mode 100644 index 00000000000..c7b517c0912 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_portuguese.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * portuguese_ISO_8859_1_create_env(void); +extern void portuguese_ISO_8859_1_close_env(struct SN_env * z); + +extern int portuguese_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_spanish.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_spanish.h new file mode 100644 index 00000000000..b066b4fc26f --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_spanish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * spanish_ISO_8859_1_create_env(void); +extern void spanish_ISO_8859_1_close_env(struct SN_env * z); + +extern int spanish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_swedish.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_swedish.h new file mode 100644 index 00000000000..7b5ec75523c --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_swedish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * swedish_ISO_8859_1_create_env(void); +extern void swedish_ISO_8859_1_close_env(struct SN_env * z); + +extern int swedish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_2_hungarian.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_2_hungarian.h new file mode 100644 index 00000000000..be6ebf685ab --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_2_hungarian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * hungarian_ISO_8859_2_create_env(void); +extern void hungarian_ISO_8859_2_close_env(struct SN_env * z); + +extern int hungarian_ISO_8859_2_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_2_romanian.h b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_2_romanian.h new file mode 100644 index 00000000000..a7acc38e17d --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_ISO_8859_2_romanian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * romanian_ISO_8859_2_create_env(void); +extern void romanian_ISO_8859_2_close_env(struct SN_env * z); + +extern int romanian_ISO_8859_2_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_KOI8_R_russian.h b/install/include/postgresql/server/snowball/libstemmer/stem_KOI8_R_russian.h new file mode 100644 index 00000000000..42a8518b953 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_KOI8_R_russian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * russian_KOI8_R_create_env(void); +extern void russian_KOI8_R_close_env(struct SN_env * z); + +extern int russian_KOI8_R_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_arabic.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_arabic.h new file mode 100644 index 00000000000..cad02f3453a --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_arabic.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * arabic_UTF_8_create_env(void); +extern void arabic_UTF_8_close_env(struct SN_env * z); + +extern int arabic_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_armenian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_armenian.h new file mode 100644 index 00000000000..793fd09e6c0 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_armenian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#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); + +extern int armenian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_basque.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_basque.h new file mode 100644 index 00000000000..79ddc983af4 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_basque.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * basque_UTF_8_create_env(void); +extern void basque_UTF_8_close_env(struct SN_env * z); + +extern int basque_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_catalan.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_catalan.h new file mode 100644 index 00000000000..58c9995d71c --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_catalan.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * catalan_UTF_8_create_env(void); +extern void catalan_UTF_8_close_env(struct SN_env * z); + +extern int catalan_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_danish.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_danish.h new file mode 100644 index 00000000000..a5084dc60f2 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_danish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * danish_UTF_8_create_env(void); +extern void danish_UTF_8_close_env(struct SN_env * z); + +extern int danish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_dutch.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_dutch.h new file mode 100644 index 00000000000..16cb995413f --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_dutch.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * dutch_UTF_8_create_env(void); +extern void dutch_UTF_8_close_env(struct SN_env * z); + +extern int dutch_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_english.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_english.h new file mode 100644 index 00000000000..11fa090e7db --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_english.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * english_UTF_8_create_env(void); +extern void english_UTF_8_close_env(struct SN_env * z); + +extern int english_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_finnish.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_finnish.h new file mode 100644 index 00000000000..eebaa2de9e9 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_finnish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * finnish_UTF_8_create_env(void); +extern void finnish_UTF_8_close_env(struct SN_env * z); + +extern int finnish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_french.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_french.h new file mode 100644 index 00000000000..22158b07c78 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_french.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * french_UTF_8_create_env(void); +extern void french_UTF_8_close_env(struct SN_env * z); + +extern int french_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_german.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_german.h new file mode 100644 index 00000000000..f276c53b265 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_german.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * german_UTF_8_create_env(void); +extern void german_UTF_8_close_env(struct SN_env * z); + +extern int german_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_greek.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_greek.h new file mode 100644 index 00000000000..77667a31f00 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_greek.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * greek_UTF_8_create_env(void); +extern void greek_UTF_8_close_env(struct SN_env * z); + +extern int greek_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_hindi.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_hindi.h new file mode 100644 index 00000000000..bbc2e9b7231 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_hindi.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * hindi_UTF_8_create_env(void); +extern void hindi_UTF_8_close_env(struct SN_env * z); + +extern int hindi_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_hungarian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_hungarian.h new file mode 100644 index 00000000000..cc29d77b997 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_hungarian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * hungarian_UTF_8_create_env(void); +extern void hungarian_UTF_8_close_env(struct SN_env * z); + +extern int hungarian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_indonesian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_indonesian.h new file mode 100644 index 00000000000..9f51324ca92 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_indonesian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * indonesian_UTF_8_create_env(void); +extern void indonesian_UTF_8_close_env(struct SN_env * z); + +extern int indonesian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_irish.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_irish.h new file mode 100644 index 00000000000..f06da96d4c7 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_irish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * irish_UTF_8_create_env(void); +extern void irish_UTF_8_close_env(struct SN_env * z); + +extern int irish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_italian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_italian.h new file mode 100644 index 00000000000..f00dcaa5dc1 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_italian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * italian_UTF_8_create_env(void); +extern void italian_UTF_8_close_env(struct SN_env * z); + +extern int italian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_lithuanian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_lithuanian.h new file mode 100644 index 00000000000..e62ff1c9d58 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_lithuanian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * lithuanian_UTF_8_create_env(void); +extern void lithuanian_UTF_8_close_env(struct SN_env * z); + +extern int lithuanian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_nepali.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_nepali.h new file mode 100644 index 00000000000..f8f50af8a0c --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_nepali.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * nepali_UTF_8_create_env(void); +extern void nepali_UTF_8_close_env(struct SN_env * z); + +extern int nepali_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_norwegian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_norwegian.h new file mode 100644 index 00000000000..72aab40230d --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_norwegian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * norwegian_UTF_8_create_env(void); +extern void norwegian_UTF_8_close_env(struct SN_env * z); + +extern int norwegian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_porter.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_porter.h new file mode 100644 index 00000000000..00685b2c96a --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_porter.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * porter_UTF_8_create_env(void); +extern void porter_UTF_8_close_env(struct SN_env * z); + +extern int porter_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_portuguese.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_portuguese.h new file mode 100644 index 00000000000..7be43352c14 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_portuguese.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * portuguese_UTF_8_create_env(void); +extern void portuguese_UTF_8_close_env(struct SN_env * z); + +extern int portuguese_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_romanian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_romanian.h new file mode 100644 index 00000000000..c93cd335b90 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_romanian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * romanian_UTF_8_create_env(void); +extern void romanian_UTF_8_close_env(struct SN_env * z); + +extern int romanian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_russian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_russian.h new file mode 100644 index 00000000000..ca1d88216ca --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_russian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * russian_UTF_8_create_env(void); +extern void russian_UTF_8_close_env(struct SN_env * z); + +extern int russian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_serbian.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_serbian.h new file mode 100644 index 00000000000..1df04f64674 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_serbian.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#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); + +extern int serbian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_spanish.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_spanish.h new file mode 100644 index 00000000000..dfd8dc3649d --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_spanish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * spanish_UTF_8_create_env(void); +extern void spanish_UTF_8_close_env(struct SN_env * z); + +extern int spanish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_swedish.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_swedish.h new file mode 100644 index 00000000000..ca08a64750e --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_swedish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * swedish_UTF_8_create_env(void); +extern void swedish_UTF_8_close_env(struct SN_env * z); + +extern int swedish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_tamil.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_tamil.h new file mode 100644 index 00000000000..5f5ae352baa --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_tamil.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * tamil_UTF_8_create_env(void); +extern void tamil_UTF_8_close_env(struct SN_env * z); + +extern int tamil_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_turkish.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_turkish.h new file mode 100644 index 00000000000..68405929c3b --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_turkish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * turkish_UTF_8_create_env(void); +extern void turkish_UTF_8_close_env(struct SN_env * z); + +extern int turkish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_yiddish.h b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_yiddish.h new file mode 100644 index 00000000000..55b66256a27 --- /dev/null +++ b/install/include/postgresql/server/snowball/libstemmer/stem_UTF_8_yiddish.h @@ -0,0 +1,15 @@ +/* Generated by Snowball 2.2.0 - https://snowballstem.org/ */ + +#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); + +extern int yiddish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/install/include/postgresql/server/statistics/extended_stats_internal.h b/install/include/postgresql/server/statistics/extended_stats_internal.h new file mode 100644 index 00000000000..7b55eb8ffac --- /dev/null +++ b/install/include/postgresql/server/statistics/extended_stats_internal.h @@ -0,0 +1,130 @@ +/*------------------------------------------------------------------------- + * + * extended_stats_internal.h + * POSTGRES extended statistics internal declarations + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/statistics/extended_stats_internal.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXTENDED_STATS_INTERNAL_H +#define EXTENDED_STATS_INTERNAL_H + +#include "statistics/statistics.h" +#include "utils/sortsupport.h" + +typedef struct +{ + Oid eqopr; /* '=' operator for datatype, if any */ + Oid eqfunc; /* and associated function */ + Oid ltopr; /* '<' operator for datatype, if any */ +} StdAnalyzeData; + +typedef struct +{ + Datum value; /* a data value */ + int tupno; /* position index for tuple it came from */ +} ScalarItem; + +/* (de)serialization info */ +typedef struct DimensionInfo +{ + int nvalues; /* number of deduplicated values */ + int nbytes; /* number of bytes (serialized) */ + int nbytes_aligned; /* size of deserialized data with alignment */ + int typlen; /* pg_type.typlen */ + bool typbyval; /* pg_type.typbyval */ +} DimensionInfo; + +/* multi-sort */ +typedef struct MultiSortSupportData +{ + int ndims; /* number of dimensions */ + /* sort support data for each dimension: */ + SortSupportData ssup[FLEXIBLE_ARRAY_MEMBER]; +} MultiSortSupportData; + +typedef MultiSortSupportData *MultiSortSupport; + +typedef struct SortItem +{ + Datum *values; + bool *isnull; + int count; +} SortItem; + +/* a unified representation of the data the statistics is built on */ +typedef struct StatsBuildData +{ + int numrows; + int nattnums; + AttrNumber *attnums; + VacAttrStats **stats; + Datum **values; + bool **nulls; +} StatsBuildData; + + +extern MVNDistinct *statext_ndistinct_build(double totalrows, StatsBuildData *data); +extern bytea *statext_ndistinct_serialize(MVNDistinct *ndistinct); +extern MVNDistinct *statext_ndistinct_deserialize(bytea *data); + +extern MVDependencies *statext_dependencies_build(StatsBuildData *data); +extern bytea *statext_dependencies_serialize(MVDependencies *dependencies); +extern MVDependencies *statext_dependencies_deserialize(bytea *data); + +extern MCVList *statext_mcv_build(StatsBuildData *data, + double totalrows, int stattarget); +extern bytea *statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats); +extern MCVList *statext_mcv_deserialize(bytea *data); + +extern MultiSortSupport multi_sort_init(int ndims); +extern void multi_sort_add_dimension(MultiSortSupport mss, int sortdim, + Oid oper, Oid collation); +extern int multi_sort_compare(const void *a, const void *b, void *arg); +extern int multi_sort_compare_dim(int dim, const SortItem *a, + const SortItem *b, MultiSortSupport mss); +extern int multi_sort_compare_dims(int start, int end, const SortItem *a, + const SortItem *b, MultiSortSupport mss); +extern int compare_scalars_simple(const void *a, const void *b, void *arg); +extern int compare_datums_simple(Datum a, Datum b, SortSupport ssup); + +extern AttrNumber *build_attnums_array(Bitmapset *attrs, int nexprs, int *numattrs); + +extern SortItem *build_sorted_items(StatsBuildData *data, int *nitems, + MultiSortSupport mss, + int numattrs, AttrNumber *attnums); + +extern bool examine_opclause_args(List *args, Node **exprp, + Const **cstp, bool *expronleftp); + +extern Selectivity mcv_combine_selectivities(Selectivity simple_sel, + Selectivity mcv_sel, + Selectivity mcv_basesel, + Selectivity mcv_totalsel); + +extern Selectivity mcv_clauselist_selectivity(PlannerInfo *root, + StatisticExtInfo *stat, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + RelOptInfo *rel, + Selectivity *basesel, + Selectivity *totalsel); + +extern 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); + +#endif /* EXTENDED_STATS_INTERNAL_H */ diff --git a/install/include/postgresql/server/statistics/statistics.h b/install/include/postgresql/server/statistics/statistics.h new file mode 100644 index 00000000000..17e3e7f881d --- /dev/null +++ b/install/include/postgresql/server/statistics/statistics.h @@ -0,0 +1,130 @@ +/*------------------------------------------------------------------------- + * + * statistics.h + * Extended statistics and selectivity estimation functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/statistics/statistics.h + * + *------------------------------------------------------------------------- + */ +#ifndef STATISTICS_H +#define STATISTICS_H + +#include "commands/vacuum.h" +#include "nodes/pathnodes.h" + +#define STATS_MAX_DIMENSIONS 8 /* max number of attributes */ + +/* Multivariate distinct coefficients */ +#define STATS_NDISTINCT_MAGIC 0xA352BFA4 /* struct identifier */ +#define STATS_NDISTINCT_TYPE_BASIC 1 /* struct version */ + +/* MVNDistinctItem represents a single combination of columns */ +typedef struct MVNDistinctItem +{ + double ndistinct; /* ndistinct value for this combination */ + int nattributes; /* number of attributes */ + AttrNumber *attributes; /* attribute numbers */ +} MVNDistinctItem; + +/* A MVNDistinct object, comprising all possible combinations of columns */ +typedef struct MVNDistinct +{ + uint32 magic; /* magic constant marker */ + uint32 type; /* type of ndistinct (BASIC) */ + uint32 nitems; /* number of items in the statistic */ + MVNDistinctItem items[FLEXIBLE_ARRAY_MEMBER]; +} MVNDistinct; + +/* Multivariate functional dependencies */ +#define STATS_DEPS_MAGIC 0xB4549A2C /* marks serialized bytea */ +#define STATS_DEPS_TYPE_BASIC 1 /* basic dependencies type */ + +/* + * Functional dependencies, tracking column-level relationships (values + * in one column determine values in another one). + */ +typedef struct MVDependency +{ + double degree; /* degree of validity (0-1) */ + AttrNumber nattributes; /* number of attributes */ + AttrNumber attributes[FLEXIBLE_ARRAY_MEMBER]; /* attribute numbers */ +} MVDependency; + +typedef struct MVDependencies +{ + uint32 magic; /* magic constant marker */ + uint32 type; /* type of MV Dependencies (BASIC) */ + uint32 ndeps; /* number of dependencies */ + MVDependency *deps[FLEXIBLE_ARRAY_MEMBER]; /* dependencies */ +} MVDependencies; + +/* used to flag stats serialized to bytea */ +#define STATS_MCV_MAGIC 0xE1A651C2 /* marks serialized bytea */ +#define STATS_MCV_TYPE_BASIC 1 /* basic MCV list type */ + +/* max items in MCV list (should be equal to max default_statistics_target) */ +#define STATS_MCVLIST_MAX_ITEMS 10000 + +/* + * Multivariate MCV (most-common value) lists + * + * A straightforward extension of MCV items - i.e. a list (array) of + * combinations of attribute values, together with a frequency and null flags. + */ +typedef struct MCVItem +{ + double frequency; /* frequency of this combination */ + double base_frequency; /* frequency if independent */ + bool *isnull; /* NULL flags */ + Datum *values; /* item values */ +} MCVItem; + +/* multivariate MCV list - essentially an array of MCV items */ +typedef struct MCVList +{ + uint32 magic; /* magic constant marker */ + uint32 type; /* type of MCV list (BASIC) */ + uint32 nitems; /* number of MCV items in the array */ + AttrNumber ndimensions; /* number of dimensions */ + Oid types[STATS_MAX_DIMENSIONS]; /* OIDs of data types */ + MCVItem items[FLEXIBLE_ARRAY_MEMBER]; /* array of MCV items */ +} MCVList; + +extern MVNDistinct *statext_ndistinct_load(Oid mvoid, bool inh); +extern MVDependencies *statext_dependencies_load(Oid mvoid, bool inh); +extern MCVList *statext_mcv_load(Oid mvoid, bool inh); + +extern void BuildRelationExtStatistics(Relation onerel, bool inh, double totalrows, + int numrows, HeapTuple *rows, + int natts, VacAttrStats **vacattrstats); +extern int ComputeExtStatisticsRows(Relation onerel, + int natts, VacAttrStats **vacattrstats); +extern bool statext_is_kind_built(HeapTuple htup, char type); +extern Selectivity dependencies_clauselist_selectivity(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + RelOptInfo *rel, + Bitmapset **estimatedclauses); +extern Selectivity statext_clauselist_selectivity(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + RelOptInfo *rel, + Bitmapset **estimatedclauses, + bool is_or); +extern bool has_stats_of_kind(List *stats, char requiredkind); +extern StatisticExtInfo *choose_best_statistics(List *stats, char requiredkind, + bool inh, + Bitmapset **clause_attnums, + List **clause_exprs, + int nclauses); +extern HeapTuple statext_expressions_load(Oid stxoid, bool inh, int idx); + +#endif /* STATISTICS_H */ diff --git a/install/include/postgresql/server/storage/backendid.h b/install/include/postgresql/server/storage/backendid.h new file mode 100644 index 00000000000..1e90b602f0c --- /dev/null +++ b/install/include/postgresql/server/storage/backendid.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * backendid.h + * POSTGRES backend id communication definitions + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/backendid.h + * + *------------------------------------------------------------------------- + */ +#ifndef BACKENDID_H +#define BACKENDID_H + +/* ---------------- + * -cim 8/17/90 + * ---------------- + */ +typedef int BackendId; /* unique currently active backend identifier */ + +#define InvalidBackendId (-1) + +extern PGDLLIMPORT BackendId MyBackendId; /* backend id of this backend */ + +/* backend id of our parallel session leader, or InvalidBackendId if none */ +extern PGDLLIMPORT BackendId ParallelLeaderBackendId; + +/* + * The BackendId to use for our session's temp relations is normally our own, + * but parallel workers should use their leader's ID. + */ +#define BackendIdForTempRelations() \ + (ParallelLeaderBackendId == InvalidBackendId ? MyBackendId : ParallelLeaderBackendId) + +#endif /* BACKENDID_H */ diff --git a/install/include/postgresql/server/storage/barrier.h b/install/include/postgresql/server/storage/barrier.h new file mode 100644 index 00000000000..e965c7ba75f --- /dev/null +++ b/install/include/postgresql/server/storage/barrier.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + * + * barrier.h + * Barriers for synchronizing cooperating processes. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/barrier.h + * + *------------------------------------------------------------------------- + */ +#ifndef BARRIER_H +#define BARRIER_H + +/* + * For the header previously known as "barrier.h", please include + * "port/atomics.h", which deals with atomics, compiler barriers and memory + * barriers. + */ + +#include "storage/condition_variable.h" +#include "storage/spin.h" + +typedef struct Barrier +{ + slock_t mutex; + int phase; /* phase counter */ + int participants; /* the number of participants attached */ + int arrived; /* the number of participants that have + * arrived */ + int elected; /* highest phase elected */ + bool static_party; /* used only for assertions */ + ConditionVariable condition_variable; +} Barrier; + +extern void BarrierInit(Barrier *barrier, int participants); +extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info); +extern bool BarrierArriveAndDetach(Barrier *barrier); +extern bool BarrierArriveAndDetachExceptLast(Barrier *barrier); +extern int BarrierAttach(Barrier *barrier); +extern bool BarrierDetach(Barrier *barrier); +extern int BarrierPhase(Barrier *barrier); +extern int BarrierParticipants(Barrier *barrier); + +#endif /* BARRIER_H */ diff --git a/install/include/postgresql/server/storage/block.h b/install/include/postgresql/server/storage/block.h new file mode 100644 index 00000000000..31a036df0db --- /dev/null +++ b/install/include/postgresql/server/storage/block.h @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------- + * + * block.h + * POSTGRES disk block definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/block.h + * + *------------------------------------------------------------------------- + */ +#ifndef BLOCK_H +#define BLOCK_H + +/* + * BlockNumber: + * + * each data file (heap or index) is divided into postgres disk blocks + * (which may be thought of as the unit of i/o -- a postgres buffer + * contains exactly one disk block). the blocks are numbered + * sequentially, 0 to 0xFFFFFFFE. + * + * InvalidBlockNumber is the same thing as P_NEW in bufmgr.h. + * + * the access methods, the buffer manager and the storage manager are + * more or less the only pieces of code that should be accessing disk + * blocks directly. + */ +typedef uint32 BlockNumber; + +#define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF) + +#define MaxBlockNumber ((BlockNumber) 0xFFFFFFFE) + +/* + * BlockId: + * + * this is a storage type for BlockNumber. in other words, this type + * is used for on-disk structures (e.g., in HeapTupleData) whereas + * BlockNumber is the type on which calculations are performed (e.g., + * in access method code). + * + * there doesn't appear to be any reason to have separate types except + * for the fact that BlockIds can be SHORTALIGN'd (and therefore any + * structures that contains them, such as ItemPointerData, can also be + * SHORTALIGN'd). this is an important consideration for reducing the + * space requirements of the line pointer (ItemIdData) array on each + * page and the header of each heap or index tuple, so it doesn't seem + * wise to change this without good reason. + */ +typedef struct BlockIdData +{ + uint16 bi_hi; + uint16 bi_lo; +} BlockIdData; + +typedef BlockIdData *BlockId; /* block identifier */ + +/* ---------------- + * support functions + * ---------------- + */ + +/* + * BlockNumberIsValid + * True iff blockNumber is valid. + */ +static inline bool +BlockNumberIsValid(BlockNumber blockNumber) +{ + return blockNumber != InvalidBlockNumber; +} + +/* + * BlockIdSet + * Sets a block identifier to the specified value. + */ +static inline void +BlockIdSet(BlockIdData *blockId, BlockNumber blockNumber) +{ + blockId->bi_hi = blockNumber >> 16; + blockId->bi_lo = blockNumber & 0xffff; +} + +/* + * BlockIdEquals + * Check for block number equality. + */ +static inline bool +BlockIdEquals(const BlockIdData *blockId1, const BlockIdData *blockId2) +{ + return (blockId1->bi_hi == blockId2->bi_hi && + blockId1->bi_lo == blockId2->bi_lo); +} + +/* + * BlockIdGetBlockNumber + * Retrieve the block number from a block identifier. + */ +static inline BlockNumber +BlockIdGetBlockNumber(const BlockIdData *blockId) +{ + return (((BlockNumber) blockId->bi_hi) << 16) | ((BlockNumber) blockId->bi_lo); +} + +#endif /* BLOCK_H */ diff --git a/install/include/postgresql/server/storage/buf.h b/install/include/postgresql/server/storage/buf.h new file mode 100644 index 00000000000..6520d9ae1e8 --- /dev/null +++ b/install/include/postgresql/server/storage/buf.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + * + * buf.h + * Basic buffer manager data types. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/buf.h + * + *------------------------------------------------------------------------- + */ +#ifndef BUF_H +#define BUF_H + +/* + * Buffer identifiers. + * + * Zero is invalid, positive is the index of a shared buffer (1..NBuffers), + * negative is the index of a local buffer (-1 .. -NLocBuffer). + */ +typedef int Buffer; + +#define InvalidBuffer 0 + +/* + * BufferIsInvalid + * True iff the buffer is invalid. + */ +#define BufferIsInvalid(buffer) ((buffer) == InvalidBuffer) + +/* + * BufferIsLocal + * True iff the buffer is local (not visible to other backends). + */ +#define BufferIsLocal(buffer) ((buffer) < 0) + +/* + * Buffer access strategy objects. + * + * BufferAccessStrategyData is private to freelist.c + */ +typedef struct BufferAccessStrategyData *BufferAccessStrategy; + +#endif /* BUF_H */ diff --git a/install/include/postgresql/server/storage/buf_internals.h b/install/include/postgresql/server/storage/buf_internals.h new file mode 100644 index 00000000000..c369d954248 --- /dev/null +++ b/install/include/postgresql/server/storage/buf_internals.h @@ -0,0 +1,644 @@ +/*------------------------------------------------------------------------- + * + * buf_internals.h + * Internal definitions for buffer manager and the buffer replacement + * strategy. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/buf_internals.h + * + * PGRAC MODIFICATIONS (12th + 13th, in BufferDesc struct + BUFFERDESC_PAD_TO_SIZE) + * ----------------------------------------------------------------------------- + * Modified by: SqlRush + * + * What changed (USE_PGRAC_CLUSTER guarded): + * 1. BufferDesc struct: append 12B hot cluster tail in 64B BufferDesc segment 1 + * ([52, 64)) + 64B cold cluster fields in 64B BufferDesc segment 2 ([64, 128)) + * after PG-original 52B (PG 16.13: BufferTag 20B + buf_id 4B + + * state 4B + wait_backend 4B + freeNext 4B + content_lock 16B). + * block_scn lives in 64B BufferDesc segment 1 (Stage 2-3 visibility hot path); + * cr_chain_head in 64B BufferDesc segment 2 (cold; CR construction path only). + * See spec-1.6 PIVOT B (2026-05-02 user approve). + * 2. BUFFERDESC_PAD_TO_SIZE bumped 64 -> 128 (cluster fields require + * 2 cache lines per slot). + * 3. ClusterInitBufferDescFields: static inline helper writing the 17 + * placeholder values at InitBufferPool / InitLocalBuffers time. + * 4. 5 StaticAssertDecl layout invariants -- catch field reorder / + * size drift at compile time using semantic constraints (block_scn + * stays in 64B BufferDesc segment 1; cr_chain_head starts 64B BufferDesc segment 2; + * cluster fields follow PG-original content_lock so bufmgr.c:3275 + * AssertNotCatalogBufferLock reverse-deref stays correct). + * + * Why: + * pgrac needs PCM lock state machine + CR chain + PI chain + Cache + * Fusion + GRD master cache fields per buffer (Stage 2-3 真值激活). + * Stage 1.6 places the structural foundation; runtime semantics land + * later. Hot path performance preserved by keeping all hot fields + * in 64B BufferDesc segment 1 (PG 16.13: 52B + cluster 12B tail = 64B). + * + * Spec: spec-1.6-buffer-descriptor.md (frozen 2026-05-02) + * Design: docs/buffer-pool-design.md v1.2 §4.3 + §12 + §15.4 + * + *------------------------------------------------------------------------- + */ +#ifndef BUFMGR_INTERNALS_H +#define BUFMGR_INTERNALS_H + +#include "pgstat.h" +#include "port/atomics.h" +#include "storage/buf.h" +#include "storage/bufmgr.h" +#include "storage/condition_variable.h" +#include "storage/latch.h" +#include "storage/lwlock.h" +#include "storage/shmem.h" +#include "storage/smgr.h" +#include "storage/spin.h" +#include "utils/relcache.h" + +#ifdef USE_PGRAC_CLUSTER +#include "access/xlogdefs.h" /* PGRAC: XLogRecPtr, InvalidXLogRecPtr */ +#include "cluster/cluster_buffer_desc.h" /* PGRAC: BufferType / PcmState / CacheFusionState / BufferFlags / INVALID_BUFFER_ID / INVALID_NODE_ID */ +#include "cluster/cluster_scn.h" /* PGRAC: SCN, InvalidScn */ +#include "datatype/timestamp.h" /* PGRAC: TimestampTz */ +#endif + +/* + * Buffer state is a single 32-bit variable where following data is combined. + * + * - 18 bits refcount + * - 4 bits usage count + * - 10 bits of flags + * + * Combining these values allows to perform some operations without locking + * the buffer header, by modifying them together with a CAS loop. + * + * The definition of buffer state components is below. + */ +#define BUF_REFCOUNT_ONE 1 +#define BUF_REFCOUNT_MASK ((1U << 18) - 1) +#define BUF_USAGECOUNT_MASK 0x003C0000U +#define BUF_USAGECOUNT_ONE (1U << 18) +#define BUF_USAGECOUNT_SHIFT 18 +#define BUF_FLAG_MASK 0xFFC00000U + +/* Get refcount and usagecount from buffer state */ +#define BUF_STATE_GET_REFCOUNT(state) ((state) & BUF_REFCOUNT_MASK) +#define BUF_STATE_GET_USAGECOUNT(state) (((state) & BUF_USAGECOUNT_MASK) >> BUF_USAGECOUNT_SHIFT) + +/* + * Flags for buffer descriptors + * + * Note: BM_TAG_VALID essentially means that there is a buffer hashtable + * entry associated with the buffer's tag. + */ +#define BM_LOCKED (1U << 22) /* buffer header is locked */ +#define BM_DIRTY (1U << 23) /* data needs writing */ +#define BM_VALID (1U << 24) /* data is valid */ +#define BM_TAG_VALID (1U << 25) /* tag is assigned */ +#define BM_IO_IN_PROGRESS (1U << 26) /* read or write in progress */ +#define BM_IO_ERROR (1U << 27) /* previous I/O failed */ +#define BM_JUST_DIRTIED (1U << 28) /* dirtied since write started */ +#define BM_PIN_COUNT_WAITER (1U << 29) /* have waiter for sole pin */ +#define BM_CHECKPOINT_NEEDED (1U << 30) /* must write for checkpoint */ +#define BM_PERMANENT (1U << 31) /* permanent buffer (not unlogged, + * or init fork) */ +/* + * The maximum allowed value of usage_count represents a tradeoff between + * accuracy and speed of the clock-sweep buffer management algorithm. A + * large value (comparable to NBuffers) would approximate LRU semantics. + * But it can take as many as BM_MAX_USAGE_COUNT+1 complete cycles of + * clock sweeps to find a free buffer, so in practice we don't want the + * value to be very large. + */ +#define BM_MAX_USAGE_COUNT 5 + +/* + * Buffer tag identifies which disk block the buffer contains. + * + * Note: the BufferTag data must be sufficient to determine where to write the + * block, without reference to pg_class or pg_tablespace entries. It's + * possible that the backend flushing the buffer doesn't even believe the + * relation is visible yet (its xact may have started before the xact that + * created the rel). The storage manager must be able to cope anyway. + * + * Note: if there's any pad bytes in the struct, InitBufferTag will have + * to be fixed to zero them, since this struct is used as a hash key. + */ +typedef struct buftag +{ + Oid spcOid; /* tablespace oid */ + Oid dbOid; /* database oid */ + RelFileNumber relNumber; /* relation file number */ + ForkNumber forkNum; /* fork number */ + BlockNumber blockNum; /* blknum relative to begin of reln */ +} BufferTag; + +static inline RelFileNumber +BufTagGetRelNumber(const BufferTag *tag) +{ + return tag->relNumber; +} + +static inline ForkNumber +BufTagGetForkNum(const BufferTag *tag) +{ + return tag->forkNum; +} + +static inline void +BufTagSetRelForkDetails(BufferTag *tag, RelFileNumber relnumber, + ForkNumber forknum) +{ + tag->relNumber = relnumber; + tag->forkNum = forknum; +} + +static inline RelFileLocator +BufTagGetRelFileLocator(const BufferTag *tag) +{ + RelFileLocator rlocator; + + rlocator.spcOid = tag->spcOid; + rlocator.dbOid = tag->dbOid; + rlocator.relNumber = BufTagGetRelNumber(tag); + + return rlocator; +} + +static inline void +ClearBufferTag(BufferTag *tag) +{ + tag->spcOid = InvalidOid; + tag->dbOid = InvalidOid; + BufTagSetRelForkDetails(tag, InvalidRelFileNumber, InvalidForkNumber); + tag->blockNum = InvalidBlockNumber; +} + +static inline void +InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, + ForkNumber forkNum, BlockNumber blockNum) +{ + tag->spcOid = rlocator->spcOid; + tag->dbOid = rlocator->dbOid; + BufTagSetRelForkDetails(tag, rlocator->relNumber, forkNum); + tag->blockNum = blockNum; +} + +static inline bool +BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2) +{ + return (tag1->spcOid == tag2->spcOid) && + (tag1->dbOid == tag2->dbOid) && + (tag1->relNumber == tag2->relNumber) && + (tag1->blockNum == tag2->blockNum) && + (tag1->forkNum == tag2->forkNum); +} + +static inline bool +BufTagMatchesRelFileLocator(const BufferTag *tag, + const RelFileLocator *rlocator) +{ + return (tag->spcOid == rlocator->spcOid) && + (tag->dbOid == rlocator->dbOid) && + (BufTagGetRelNumber(tag) == rlocator->relNumber); +} + + +/* + * The shared buffer mapping table is partitioned to reduce contention. + * To determine which partition lock a given tag requires, compute the tag's + * hash code with BufTableHashCode(), then apply BufMappingPartitionLock(). + * NB: NUM_BUFFER_PARTITIONS must be a power of 2! + */ +static inline uint32 +BufTableHashPartition(uint32 hashcode) +{ + return hashcode % NUM_BUFFER_PARTITIONS; +} + +static inline LWLock * +BufMappingPartitionLock(uint32 hashcode) +{ + return &MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + + BufTableHashPartition(hashcode)].lock; +} + +static inline LWLock * +BufMappingPartitionLockByIndex(uint32 index) +{ + return &MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + index].lock; +} + +/* + * BufferDesc -- shared descriptor/state data for a single shared buffer. + * + * Note: Buffer header lock (BM_LOCKED flag) must be held to examine or change + * tag, state or wait_backend_pgprocno fields. In general, buffer header lock + * is a spinlock which is combined with flags, refcount and usagecount into + * single atomic variable. This layout allow us to do some operations in a + * single atomic operation, without actually acquiring and releasing spinlock; + * for instance, increase or decrease refcount. buf_id field never changes + * after initialization, so does not need locking. freeNext is protected by + * the buffer_strategy_lock not buffer header lock. The LWLock can take care + * of itself. The buffer header lock is *not* used to control access to the + * data in the buffer! + * + * It's assumed that nobody changes the state field while buffer header lock + * is held. Thus buffer header lock holder can do complex updates of the + * state variable in single write, simultaneously with lock release (cleaning + * BM_LOCKED flag). On the other hand, updating of state without holding + * buffer header lock is restricted to CAS, which ensures that BM_LOCKED flag + * is not set. Atomic increment/decrement, OR/AND etc. are not allowed. + * + * An exception is that if we have the buffer pinned, its tag can't change + * underneath us, so we can examine the tag without locking the buffer header. + * Also, in places we do one-time reads of the flags without bothering to + * lock the buffer header; this is generally for situations where we don't + * expect the flag bit being tested to be changing. + * + * We can't physically remove items from a disk page if another backend has + * the buffer pinned. Hence, a backend may need to wait for all other pins + * to go away. This is signaled by storing its own pgprocno into + * wait_backend_pgprocno and setting flag bit BM_PIN_COUNT_WAITER. At present, + * there can be only one such waiter per buffer. + * + * We use this same struct for local buffer headers, but the locks are not + * used and not all of the flag bits are useful either. To avoid unnecessary + * overhead, manipulations of the state field should be done without actual + * atomic operations (i.e. only pg_atomic_read_u32() and + * pg_atomic_unlocked_write_u32()). + * + * Be careful to avoid increasing the size of the struct when adding or + * reordering members. Keeping it below 64 bytes (the most common CPU + * cache line size) is fairly important for performance. + * + * Per-buffer I/O condition variables are currently kept outside this struct in + * a separate array. They could be moved in here and still fit within that + * limit on common systems, but for now that is not done. + */ +typedef struct BufferDesc +{ + BufferTag tag; /* ID of page contained in buffer */ + int buf_id; /* buffer's index number (from 0) */ + + /* state of the tag, containing flags, refcount and usagecount */ + pg_atomic_uint32 state; + + int wait_backend_pgprocno; /* backend of pin-count waiter */ + int freeNext; /* link in freelist chain */ + LWLock content_lock; /* to lock access to buffer contents */ + +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC: cluster fields (stage 1.6, ~76B + alignment). + * + * On PG 16.13 the original BufferDesc fields above end at offset 52 + * (BufferTag 20B + buf_id 4B + state 4B + wait_backend_pgprocno 4B + * + freeNext 4B + content_lock 16B = 52B). This leaves only 12B of + * 64B BufferDesc segment 1 for cluster fields ([52, 64)) -- the "12B hot + * cluster tail". Cache line 2 ([64, 128)) holds the 64B cold + * cluster fields accessed only on cluster-specific paths. + * + * PIVOT B (2026-05-02 user approve): block_scn must stay in cache + * line 1 because it's read on every visibility check (Stage 2-3 + * hot path). cr_chain_head moves to 64B BufferDesc segment 2 because CR + * construction is a cold path. See spec-1.6 §1.4 example #5 and + * docs/buffer-pool-design.md v1.2 §4.3. + * + * All values are placeholders at stage 1.6 -- + * ClusterInitBufferDescFields (defined below) writes them explicitly + * at InitBufferPool / InitLocalBuffers time. Stage 2-3 真值激活 spec + * brings the actual PCM state machine / CR chain / PI / Cache + * Fusion / GRD master cache semantics. + * + * Spec: spec-1.6-buffer-descriptor.md + * Design: docs/buffer-pool-design.md v1.2 §4.3 + */ + + /* === Cache line 1 hot cluster tail ([52, 64), 12B usable) === */ + uint8 buffer_type; /* offset 52; BufferType enum; BUF_TYPE_CURRENT at stage 1.6 */ + uint8 pcm_state; /* offset 53; PcmState enum; PCM_STATE_N at stage 1.6 */ + uint8 pi_flags; /* offset 54; BufferFlags bitfield; 0 at stage 1.6 (no PI) */ + uint8 cluster_padding_1; /* offset 55; 1B padding for 8B alignment of block_scn; 0 at stage 1.6 */ + SCN block_scn; /* offset 56; page-level SCN (spec-1.4 typedef); InvalidScn at stage 1.6 */ + /* end of 64B BufferDesc segment 1 at offset 64 */ + + /* === Cache line 2 cold cluster fields ([64, 128), 64B) === */ + int cr_chain_head; /* offset 64; CR chain head buf_id; INVALID_BUFFER_ID at stage 1.6 */ + int cr_chain_next; /* offset 68; next CR in chain; INVALID_BUFFER_ID at stage 1.6 */ + SCN cr_scn; /* offset 72; CR buffer's read SCN; InvalidScn at stage 1.6 */ + int pi_buf_id; /* offset 80; PI buffer's buf_id; INVALID_BUFFER_ID at stage 1.6 */ + /* offset 84..87: 4B implicit padding for pi_lsn 8-byte alignment */ + XLogRecPtr pi_lsn; /* offset 88; PI buffer's let-go LSN; InvalidXLogRecPtr at stage 1.6 */ + uint16 grd_master_node; /* offset 96; GRD master node id; INVALID_NODE_ID at stage 1.6 */ + uint16 grd_master_seq; /* offset 98; GRD master seq; 0 at stage 1.6 */ + uint8 cf_state; /* offset 100; CacheFusionState enum; CF_STATE_NONE at stage 1.6 */ + uint8 cf_owner_node; /* offset 101; CF transfer owner node; 0 at stage 1.6 */ + uint16 cf_request_count; /* offset 102; CF transfer request count; 0 at stage 1.6 */ + LWLock pcm_lock; /* offset 104; PCM lock; LWLockInitialize'd at stage 1.6 (not held) */ + TimestampTz pi_created_at; /* offset 120; PI creation timestamp; 0 at stage 1.6 */ + /* end of 64B BufferDesc segment 2 at offset 128 */ +#endif /* USE_PGRAC_CLUSTER */ +} BufferDesc; + +/* + * Concurrent access to buffer headers has proven to be more efficient if + * they're cache line aligned. So we force the start of the BufferDescriptors + * array to be on a cache line boundary and force the elements to be cache + * line sized. + * + * XXX: As this is primarily matters in highly concurrent workloads which + * probably all are 64bit these days, and the space wastage would be a bit + * more noticeable on 32bit systems, we don't force the stride to be cache + * line sized on those. If somebody does actual performance testing, we can + * reevaluate. + * + * Note that local buffer descriptors aren't forced to be aligned - as there's + * no concurrent access to those it's unlikely to be beneficial. + * + * We use a 64-byte cache line size here, because that's the most common + * size. Making it bigger would be a waste of memory. Even if running on a + * platform with either 32 or 128 byte line sizes, it's good to align to + * boundaries and avoid false sharing. + */ +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC: BufferDesc grew from PG-vanilla ~52B (padded to 64) to ~120B + * (padded to 128) on PG 16.13. 12B hot cluster tail shares 64B BufferDesc segment 1 + * with PG-original 52B; 64B cold cluster fields occupy 64B BufferDesc segment 2 and + * are accessed only on cluster-specific paths (Stage 2-3 真值激活). + * + * Hot path cache behaviour preserved: ReadBuffer / BufferAlloc / + * UnpinBuffer / IncrBufferRefCount continue to read only 64B BufferDesc segment 1 + * (offsets 0..63), exactly the same cache miss profile as PG vanilla. + * + * Spec: spec-1.6-buffer-descriptor.md Design: docs/buffer-pool-design.md v1.2 §4.3 + */ +#define BUFFERDESC_PAD_TO_SIZE (SIZEOF_VOID_P == 8 ? 128 : 1) +#else +#define BUFFERDESC_PAD_TO_SIZE (SIZEOF_VOID_P == 8 ? 64 : 1) +#endif + +typedef union BufferDescPadded +{ + BufferDesc bufferdesc; + char pad[BUFFERDESC_PAD_TO_SIZE]; +} BufferDescPadded; + +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC: compile-time layout invariants for cluster BufferDesc fields. + * + * These StaticAssertDecls catch any field reorder / size drift at + * build time, before any runtime test runs. + * + * PIVOT B (2026-05-02): use semantic constraints instead of magic + * offset numbers. PG 16.13 实测 sizeof(BufferTag) == 20 (not 16), + * pushing PG-original fields to offset 52 (not 48). Hard-coded + * "offset 32 / 48 / 64" assertions break on any future PG version + * that grows BufferTag again; semantic constraints survive. + * + * Critical: PG bufmgr.c:AssertNotCatalogBufferLock reverse-derefs + * BufferDesc from an LWLock pointer using + * bufHdr = (BufferDesc *) ((char *) lock - offsetof(BufferDesc, content_lock)) + * which uses the offsetof() macro and therefore adapts to whatever + * the actual content_lock offset is on the current PG version + * (36 on PG 16.13; 32 on earlier PG with smaller BufferTag). + * The semantic invariant we lock below is "cluster fields appear + * *after* content_lock"; any future reorder breaking that semantic + * fails to compile. + * + * Spec: spec-1.6-buffer-descriptor.md §1.2 Deliverable 3.6 + §8 Q2. + */ +StaticAssertDecl(BUFFERDESC_PAD_TO_SIZE == 128, + "PGRAC: BUFFERDESC_PAD_TO_SIZE must be 128 in USE_PGRAC_CLUSTER mode"); +StaticAssertDecl(sizeof(BufferDesc) <= BUFFERDESC_PAD_TO_SIZE, + "PGRAC: BufferDesc with cluster fields exceeds padded size"); +StaticAssertDecl(offsetof(BufferDesc, block_scn) + sizeof(SCN) <= 64, + "PGRAC: block_scn must stay in BufferDesc 64B BufferDesc segment 1 (Stage 2-3 visibility hot path)"); +StaticAssertDecl(offsetof(BufferDesc, cr_chain_head) >= 64, + "PGRAC: cr_chain_head (cold field) must start at or after 64B BufferDesc segment 2 boundary"); +StaticAssertDecl(offsetof(BufferDesc, content_lock) < + offsetof(BufferDesc, buffer_type), + "PGRAC: cluster fields must follow PG-original content_lock so bufmgr.c:3275 reverse-deref stays correct"); + +/* + * PGRAC: ClusterInitBufferDescFields -- write placeholder values to all + * 17 cluster fields of a BufferDesc. + * + * Called from both InitBufferPool() (shared buffer; PGRAC MODIFICATIONS + * 14th in buf_init.c) and InitLocalBuffers() (local / temp buffer per + * backend; PGRAC MODIFICATIONS 16th in localbuf.c). Any future + * BufferDesc init path (e.g. Stage 2 dynamic buffer pool resizing) + * MUST also call this helper to keep cluster fields in valid + * placeholder state. + * + * Stage 1.6 stub; Stage 2-3 真值激活时调用方负责状态转换 (PCM 锁 / + * CR chain / PI chain / Cache Fusion / GRD). + * + * Critical: cr_chain_head / cr_chain_next / pi_buf_id MUST be set to + * INVALID_BUFFER_ID (-1) explicitly -- calloc zero-fill (used by + * localbuf.c LocalBufferDescriptors = calloc(...)) leaves them as 0, + * which is a *valid* buffer_id and would mislead Stage 3 CR-path + * reads of local buffers. pcm_lock also MUST be LWLockInitialize'd + * explicitly -- calloc 0 is not a valid LWLock state. This is the + * entire reason this helper exists. + * + * Spec: spec-1.6-buffer-descriptor.md §1.2 Deliverable 3.5 + §8 Q1. + */ +static inline void +ClusterInitBufferDescFields(BufferDesc *buf) +{ + /* hot cluster fields */ + buf->buffer_type = BUF_TYPE_CURRENT; + buf->pcm_state = PCM_STATE_N; + buf->pi_flags = 0; + buf->cluster_padding_1 = 0; + buf->cr_chain_head = INVALID_BUFFER_ID; + buf->block_scn = InvalidScn; + + /* cold cluster fields */ + buf->cr_scn = InvalidScn; + buf->cr_chain_next = INVALID_BUFFER_ID; + buf->pi_buf_id = INVALID_BUFFER_ID; + buf->pi_lsn = InvalidXLogRecPtr; + buf->grd_master_node = INVALID_NODE_ID; + buf->grd_master_seq = 0; + buf->cf_state = CF_STATE_NONE; + buf->cf_owner_node = 0; + buf->cf_request_count = 0; + + /* + * pcm_lock: dedicated LWTRANCHE_BUFFER_PCM_LOCK tranche (registered + * by spec-stage1-codex-fixes Deliverable 5). Stage 1.6 hardening: + * independent tranche distinguishes pcm_lock from content_lock in + * lock trace / pg_stat_activity wait events. Complements the + * bufmgr.c:AssertNotCatalogBufferLock runtime guard (spec-1.6 + * hardening) preventing reverse-deref misidentification. + */ + LWLockInitialize(&buf->pcm_lock, LWTRANCHE_BUFFER_PCM_LOCK); + + buf->pi_created_at = 0; +} +#endif /* USE_PGRAC_CLUSTER */ + +/* + * The PendingWriteback & WritebackContext structure are used to keep + * information about pending flush requests to be issued to the OS. + */ +typedef struct PendingWriteback +{ + /* could store different types of pending flushes here */ + BufferTag tag; +} PendingWriteback; + +/* struct forward declared in bufmgr.h */ +typedef struct WritebackContext +{ + /* pointer to the max number of writeback requests to coalesce */ + int *max_pending; + + /* current number of pending writeback requests */ + int nr_pending; + + /* pending requests */ + PendingWriteback pending_writebacks[WRITEBACK_MAX_PENDING_FLUSHES]; +} WritebackContext; + +/* in buf_init.c */ +extern PGDLLIMPORT BufferDescPadded *BufferDescriptors; +extern PGDLLIMPORT ConditionVariableMinimallyPadded *BufferIOCVArray; +extern PGDLLIMPORT WritebackContext BackendWritebackContext; + +/* in localbuf.c */ +extern PGDLLIMPORT BufferDesc *LocalBufferDescriptors; + + +static inline BufferDesc * +GetBufferDescriptor(uint32 id) +{ + return &(BufferDescriptors[id]).bufferdesc; +} + +static inline BufferDesc * +GetLocalBufferDescriptor(uint32 id) +{ + return &LocalBufferDescriptors[id]; +} + +static inline Buffer +BufferDescriptorGetBuffer(const BufferDesc *bdesc) +{ + return (Buffer) (bdesc->buf_id + 1); +} + +static inline ConditionVariable * +BufferDescriptorGetIOCV(const BufferDesc *bdesc) +{ + return &(BufferIOCVArray[bdesc->buf_id]).cv; +} + +static inline LWLock * +BufferDescriptorGetContentLock(const BufferDesc *bdesc) +{ + return (LWLock *) (&bdesc->content_lock); +} + +/* + * The freeNext field is either the index of the next freelist entry, + * or one of these special values: + */ +#define FREENEXT_END_OF_LIST (-1) +#define FREENEXT_NOT_IN_LIST (-2) + +/* + * Functions for acquiring/releasing a shared buffer header's spinlock. Do + * not apply these to local buffers! + */ +extern uint32 LockBufHdr(BufferDesc *desc); + +static inline void +UnlockBufHdr(BufferDesc *desc, uint32 buf_state) +{ + pg_write_barrier(); + pg_atomic_write_u32(&desc->state, buf_state & (~BM_LOCKED)); +} + +/* in bufmgr.c */ + +/* + * Structure to sort buffers per file on checkpoints. + * + * This structure is allocated per buffer in shared memory, so it should be + * kept as small as possible. + */ +typedef struct CkptSortItem +{ + Oid tsId; + RelFileNumber relNumber; + ForkNumber forkNum; + BlockNumber blockNum; + int buf_id; +} CkptSortItem; + +extern PGDLLIMPORT CkptSortItem *CkptBufferIds; + +/* + * Internal buffer management routines + */ +/* bufmgr.c */ +extern void WritebackContextInit(WritebackContext *context, int *max_pending); +extern void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context); +extern void ScheduleBufferTagForWriteback(WritebackContext *wb_context, + IOContext io_context, BufferTag *tag); + +/* freelist.c */ +extern IOContext IOContextForStrategy(BufferAccessStrategy strategy); +extern BufferDesc *StrategyGetBuffer(BufferAccessStrategy strategy, + uint32 *buf_state, bool *from_ring); +extern void StrategyFreeBuffer(BufferDesc *buf); +extern bool StrategyRejectBuffer(BufferAccessStrategy strategy, + BufferDesc *buf, bool from_ring); + +extern int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc); +extern void StrategyNotifyBgWriter(int bgwprocno); + +extern Size StrategyShmemSize(void); +extern void StrategyInitialize(bool init); +extern bool have_free_buffer(void); + +/* buf_table.c */ +extern Size BufTableShmemSize(int size); +extern void InitBufTable(int size); +extern uint32 BufTableHashCode(BufferTag *tagPtr); +extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode); +extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id); +extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode); + +/* localbuf.c */ +extern bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount); +extern void UnpinLocalBuffer(Buffer buffer); +extern PrefetchBufferResult PrefetchLocalBuffer(SMgrRelation smgr, + ForkNumber forkNum, + BlockNumber blockNum); +extern BufferDesc *LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, + BlockNumber blockNum, bool *foundPtr); +extern BlockNumber ExtendBufferedRelLocal(BufferManagerRelation bmr, + ForkNumber fork, + uint32 flags, + uint32 extend_by, + BlockNumber extend_upto, + Buffer *buffers, + uint32 *extended_by); +extern void MarkLocalBufferDirty(Buffer buffer); +extern void DropRelationLocalBuffers(RelFileLocator rlocator, + ForkNumber forkNum, + BlockNumber firstDelBlock); +extern void DropRelationAllLocalBuffers(RelFileLocator rlocator); +extern void AtEOXact_LocalBuffers(bool isCommit); + +#endif /* BUFMGR_INTERNALS_H */ diff --git a/install/include/postgresql/server/storage/buffile.h b/install/include/postgresql/server/storage/buffile.h new file mode 100644 index 00000000000..65837667193 --- /dev/null +++ b/install/include/postgresql/server/storage/buffile.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * buffile.h + * Management of large buffered temporary files. + * + * The BufFile routines provide a partial replacement for stdio atop + * virtual file descriptors managed by fd.c. Currently they only support + * buffered access to a virtual file, without any of stdio's formatting + * features. That's enough for immediate needs, but the set of facilities + * could be expanded if necessary. + * + * BufFile also supports working with temporary files that exceed the OS + * file size limit and/or the largest offset representable in an int. + * It might be better to split that out as a separately accessible module, + * but currently we have no need for oversize temp files without buffered + * access. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/buffile.h + * + *------------------------------------------------------------------------- + */ + +#ifndef BUFFILE_H +#define BUFFILE_H + +#include "storage/fileset.h" + +/* BufFile is an opaque type whose details are not known outside buffile.c. */ + +typedef struct BufFile BufFile; + +/* + * prototypes for functions in buffile.c + */ + +extern BufFile *BufFileCreateTemp(bool interXact); +extern void BufFileClose(BufFile *file); +extern pg_nodiscard size_t BufFileRead(BufFile *file, void *ptr, size_t size); +extern void BufFileReadExact(BufFile *file, void *ptr, size_t size); +extern size_t BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool eofOK); +extern void BufFileWrite(BufFile *file, const void *ptr, size_t size); +extern int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence); +extern void BufFileTell(BufFile *file, int *fileno, off_t *offset); +extern int BufFileSeekBlock(BufFile *file, long blknum); +extern int64 BufFileSize(BufFile *file); +extern long BufFileAppend(BufFile *target, BufFile *source); + +extern BufFile *BufFileCreateFileSet(FileSet *fileset, const char *name); +extern void BufFileExportFileSet(BufFile *file); +extern BufFile *BufFileOpenFileSet(FileSet *fileset, const char *name, + int mode, bool missing_ok); +extern void BufFileDeleteFileSet(FileSet *fileset, const char *name, + bool missing_ok); +extern void BufFileTruncateFileSet(BufFile *file, int fileno, off_t offset); + +#endif /* BUFFILE_H */ diff --git a/install/include/postgresql/server/storage/bufmgr.h b/install/include/postgresql/server/storage/bufmgr.h new file mode 100644 index 00000000000..166524c50e0 --- /dev/null +++ b/install/include/postgresql/server/storage/bufmgr.h @@ -0,0 +1,396 @@ +/*------------------------------------------------------------------------- + * + * bufmgr.h + * POSTGRES buffer manager definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/bufmgr.h + * + *------------------------------------------------------------------------- + */ +#ifndef BUFMGR_H +#define BUFMGR_H + +#include "storage/block.h" +#include "storage/buf.h" +#include "storage/bufpage.h" +#include "storage/relfilelocator.h" +#include "utils/relcache.h" +#include "utils/snapmgr.h" + +typedef void *Block; + +/* + * Possible arguments for GetAccessStrategy(). + * + * If adding a new BufferAccessStrategyType, also add a new IOContext so + * IO statistics using this strategy are tracked. + */ +typedef enum BufferAccessStrategyType +{ + BAS_NORMAL, /* Normal random access */ + BAS_BULKREAD, /* Large read-only scan (hint bit updates are + * ok) */ + BAS_BULKWRITE, /* Large multi-block write (e.g. COPY IN) */ + BAS_VACUUM /* VACUUM */ +} BufferAccessStrategyType; + +/* Possible modes for ReadBufferExtended() */ +typedef enum +{ + RBM_NORMAL, /* Normal read */ + RBM_ZERO_AND_LOCK, /* Don't read from disk, caller will + * initialize. Also locks the page. */ + RBM_ZERO_AND_CLEANUP_LOCK, /* Like RBM_ZERO_AND_LOCK, but locks the page + * in "cleanup" mode */ + RBM_ZERO_ON_ERROR, /* Read, but return an all-zeros page on error */ + RBM_NORMAL_NO_LOG /* Don't log page as invalid during WAL + * replay; otherwise same as RBM_NORMAL */ +} ReadBufferMode; + +/* + * Type returned by PrefetchBuffer(). + */ +typedef struct PrefetchBufferResult +{ + Buffer recent_buffer; /* If valid, a hit (recheck needed!) */ + bool initiated_io; /* If true, a miss resulting in async I/O */ +} PrefetchBufferResult; + +/* + * Flags influencing the behaviour of ExtendBufferedRel* + */ +typedef enum ExtendBufferedFlags +{ + /* + * Don't acquire extension lock. This is safe only if the relation isn't + * shared, an access exclusive lock is held or if this is the startup + * process. + */ + EB_SKIP_EXTENSION_LOCK = (1 << 0), + + /* Is this extension part of recovery? */ + EB_PERFORMING_RECOVERY = (1 << 1), + + /* + * Should the fork be created if it does not currently exist? This likely + * only ever makes sense for relation forks. + */ + EB_CREATE_FORK_IF_NEEDED = (1 << 2), + + /* Should the first (possibly only) return buffer be returned locked? */ + EB_LOCK_FIRST = (1 << 3), + + /* Should the smgr size cache be cleared? */ + EB_CLEAR_SIZE_CACHE = (1 << 4), + + /* internal flags follow */ + EB_LOCK_TARGET = (1 << 5), +} ExtendBufferedFlags; + +/* + * Some functions identify relations either by relation or smgr + + * relpersistence. Used via the BMR_REL()/BMR_SMGR() macros below. This + * allows us to use the same function for both recovery and normal operation. + */ +typedef struct BufferManagerRelation +{ + Relation rel; + struct SMgrRelationData *smgr; + char relpersistence; +} BufferManagerRelation; + +#define BMR_REL(p_rel) ((BufferManagerRelation){.rel = p_rel}) +#define BMR_SMGR(p_smgr, p_relpersistence) ((BufferManagerRelation){.smgr = p_smgr, .relpersistence = p_relpersistence}) + + +/* forward declared, to avoid having to expose buf_internals.h here */ +struct WritebackContext; + +/* forward declared, to avoid including smgr.h here */ +struct SMgrRelationData; + +/* in globals.c ... this duplicates miscadmin.h */ +extern PGDLLIMPORT int NBuffers; + +/* in bufmgr.c */ +extern PGDLLIMPORT bool zero_damaged_pages; +extern PGDLLIMPORT int bgwriter_lru_maxpages; +extern PGDLLIMPORT double bgwriter_lru_multiplier; +extern PGDLLIMPORT bool track_io_timing; + +/* only applicable when prefetching is available */ +#ifdef USE_PREFETCH +#define DEFAULT_EFFECTIVE_IO_CONCURRENCY 1 +#define DEFAULT_MAINTENANCE_IO_CONCURRENCY 10 +#else +#define DEFAULT_EFFECTIVE_IO_CONCURRENCY 0 +#define DEFAULT_MAINTENANCE_IO_CONCURRENCY 0 +#endif +extern PGDLLIMPORT int effective_io_concurrency; +extern PGDLLIMPORT int maintenance_io_concurrency; + +extern PGDLLIMPORT int checkpoint_flush_after; +extern PGDLLIMPORT int backend_flush_after; +extern PGDLLIMPORT int bgwriter_flush_after; + +/* in buf_init.c */ +extern PGDLLIMPORT char *BufferBlocks; + +/* in localbuf.c */ +extern PGDLLIMPORT int NLocBuffer; +extern PGDLLIMPORT Block *LocalBufferBlockPointers; +extern PGDLLIMPORT int32 *LocalRefCount; + +/* upper limit for effective_io_concurrency */ +#define MAX_IO_CONCURRENCY 1000 + +/* special block number for ReadBuffer() */ +#define P_NEW InvalidBlockNumber /* grow the file to get a new page */ + +/* + * Buffer content lock modes (mode argument for LockBuffer()) + */ +#define BUFFER_LOCK_UNLOCK 0 +#define BUFFER_LOCK_SHARE 1 +#define BUFFER_LOCK_EXCLUSIVE 2 + + +/* + * prototypes for functions in bufmgr.c + */ +extern PrefetchBufferResult PrefetchSharedBuffer(struct SMgrRelationData *smgr_reln, + ForkNumber forkNum, + BlockNumber blockNum); +extern PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, + BlockNumber blockNum); +extern bool ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum, + BlockNumber blockNum, Buffer recent_buffer); +extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum); +extern Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, + BlockNumber blockNum, ReadBufferMode mode, + BufferAccessStrategy strategy); +extern Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator, + ForkNumber forkNum, BlockNumber blockNum, + ReadBufferMode mode, BufferAccessStrategy strategy, + bool permanent); +extern void ReleaseBuffer(Buffer buffer); +extern void UnlockReleaseBuffer(Buffer buffer); +extern void MarkBufferDirty(Buffer buffer); +extern void IncrBufferRefCount(Buffer buffer); +extern void CheckBufferIsPinnedOnce(Buffer buffer); +extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, + BlockNumber blockNum); + +extern Buffer ExtendBufferedRel(BufferManagerRelation bmr, + ForkNumber forkNum, + BufferAccessStrategy strategy, + uint32 flags); +extern BlockNumber ExtendBufferedRelBy(BufferManagerRelation bmr, + ForkNumber fork, + BufferAccessStrategy strategy, + uint32 flags, + uint32 extend_by, + Buffer *buffers, + uint32 *extended_by); +extern Buffer ExtendBufferedRelTo(BufferManagerRelation bmr, + ForkNumber fork, + BufferAccessStrategy strategy, + uint32 flags, + BlockNumber extend_to, + ReadBufferMode mode); + +extern void InitBufferPoolAccess(void); +extern void AtEOXact_Buffers(bool isCommit); +#ifdef USE_ASSERT_CHECKING +extern void AssertBufferLocksPermitCatalogRead(void); +#endif +extern void PrintBufferLeakWarning(Buffer buffer); +extern void CheckPointBuffers(int flags); +extern BlockNumber BufferGetBlockNumber(Buffer buffer); +extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, + ForkNumber forkNum); +extern void FlushOneBuffer(Buffer buffer); +extern void FlushRelationBuffers(Relation rel); +extern void FlushRelationsAllBuffers(struct SMgrRelationData **smgrs, int nrels); +extern void CreateAndCopyRelationData(RelFileLocator src_rlocator, + RelFileLocator dst_rlocator, + bool permanent); +extern void FlushDatabaseBuffers(Oid dbid); +extern void DropRelationBuffers(struct SMgrRelationData *smgr_reln, + ForkNumber *forkNum, + int nforks, BlockNumber *firstDelBlock); +extern void DropRelationsAllBuffers(struct SMgrRelationData **smgr_reln, + int nlocators); +extern void DropDatabaseBuffers(Oid dbid); + +#define RelationGetNumberOfBlocks(reln) \ + RelationGetNumberOfBlocksInFork(reln, MAIN_FORKNUM) + +extern bool BufferIsPermanent(Buffer buffer); +extern XLogRecPtr BufferGetLSNAtomic(Buffer buffer); + +#ifdef NOT_USED +extern void PrintPinnedBufs(void); +#endif +extern void BufferGetTag(Buffer buffer, RelFileLocator *rlocator, + ForkNumber *forknum, BlockNumber *blknum); + +extern void MarkBufferDirtyHint(Buffer buffer, bool buffer_std); + +extern void UnlockBuffers(void); +extern void LockBuffer(Buffer buffer, int mode); +extern bool ConditionalLockBuffer(Buffer buffer); +extern void LockBufferForCleanup(Buffer buffer); +extern bool ConditionalLockBufferForCleanup(Buffer buffer); +extern bool IsBufferCleanupOK(Buffer buffer); +extern bool HoldingBufferPinThatDelaysRecovery(void); + +extern void AbortBufferIO(Buffer buffer); + +extern bool BgBufferSync(struct WritebackContext *wb_context); + +extern void TestForOldSnapshot_impl(Snapshot snapshot, Relation relation); + +/* in buf_init.c */ +extern void InitBufferPool(void); +extern Size BufferShmemSize(void); + +/* in localbuf.c */ +extern void AtProcExit_LocalBuffers(void); + +/* in freelist.c */ + +extern BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype); +extern BufferAccessStrategy GetAccessStrategyWithSize(BufferAccessStrategyType btype, + int ring_size_kb); +extern int GetAccessStrategyBufferCount(BufferAccessStrategy strategy); + +extern void FreeAccessStrategy(BufferAccessStrategy strategy); + + +/* inline functions */ + +/* + * Although this header file is nominally backend-only, certain frontend + * programs like pg_waldump include it. For compilers that emit static + * inline functions even when they're unused, that leads to unsatisfied + * external references; hence hide these with #ifndef FRONTEND. + */ + +#ifndef FRONTEND + +/* + * BufferIsValid + * True iff the given buffer number is valid (either as a shared + * or local buffer). + * + * Note: For a long time this was defined the same as BufferIsPinned, + * that is it would say False if you didn't hold a pin on the buffer. + * I believe this was bogus and served only to mask logic errors. + * Code should always know whether it has a buffer reference, + * independently of the pin state. + * + * Note: For a further long time this was not quite the inverse of the + * BufferIsInvalid() macro, in that it also did sanity checks to verify + * that the buffer number was in range. Most likely, this macro was + * originally intended only to be used in assertions, but its use has + * since expanded quite a bit, and the overhead of making those checks + * even in non-assert-enabled builds can be significant. Thus, we've + * now demoted the range checks to assertions within the macro itself. + */ +static inline bool +BufferIsValid(Buffer bufnum) +{ + Assert(bufnum <= NBuffers); + Assert(bufnum >= -NLocBuffer); + + return bufnum != InvalidBuffer; +} + +/* + * BufferGetBlock + * Returns a reference to a disk page image associated with a buffer. + * + * Note: + * Assumes buffer is valid. + */ +static inline Block +BufferGetBlock(Buffer buffer) +{ + Assert(BufferIsValid(buffer)); + + if (BufferIsLocal(buffer)) + return LocalBufferBlockPointers[-buffer - 1]; + else + return (Block) (BufferBlocks + ((Size) (buffer - 1)) * BLCKSZ); +} + +/* + * BufferGetPageSize + * Returns the page size within a buffer. + * + * Notes: + * Assumes buffer is valid. + * + * The buffer can be a raw disk block and need not contain a valid + * (formatted) disk page. + */ +/* XXX should dig out of buffer descriptor */ +static inline Size +BufferGetPageSize(Buffer buffer) +{ + AssertMacro(BufferIsValid(buffer)); + return (Size) BLCKSZ; +} + +/* + * BufferGetPage + * Returns the page associated with a buffer. + * + * When this is called as part of a scan, there may be a need for a nearby + * call to TestForOldSnapshot(). See the definition of that for details. + */ +static inline Page +BufferGetPage(Buffer buffer) +{ + return (Page) BufferGetBlock(buffer); +} + +/* + * Check whether the given snapshot is too old to have safely read the given + * page from the given table. If so, throw a "snapshot too old" error. + * + * This test generally needs to be performed after every BufferGetPage() call + * that is executed as part of a scan. It is not needed for calls made for + * modifying the page (for example, to position to the right place to insert a + * new index tuple or for vacuuming). It may also be omitted where calls to + * lower-level functions will have already performed the test. + * + * Note that a NULL snapshot argument is allowed and causes a fast return + * without error; this is to support call sites which can be called from + * either scans or index modification areas. + * + * For best performance, keep the tests that are fastest and/or most likely to + * exclude a page from old snapshot testing near the front. + */ +static inline void +TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page) +{ + Assert(relation != NULL); + + if (old_snapshot_threshold >= 0 + && (snapshot) != NULL + && ((snapshot)->snapshot_type == SNAPSHOT_MVCC + || (snapshot)->snapshot_type == SNAPSHOT_TOAST) + && !XLogRecPtrIsInvalid((snapshot)->lsn) + && PageGetLSN(page) > (snapshot)->lsn) + TestForOldSnapshot_impl(snapshot, relation); +} + +#endif /* FRONTEND */ + +#endif /* BUFMGR_H */ diff --git a/install/include/postgresql/server/storage/bufpage.h b/install/include/postgresql/server/storage/bufpage.h new file mode 100644 index 00000000000..c7a47c19dee --- /dev/null +++ b/install/include/postgresql/server/storage/bufpage.h @@ -0,0 +1,889 @@ +/*------------------------------------------------------------------------- + * + * bufpage.h + * Standard POSTGRES buffer page definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/bufpage.h + * + *------------------------------------------------------------------------- + * + * PGRAC MODIFICATIONS (5th): + * Modified by: SqlRush + * + * What changed: When USE_PGRAC_CLUSTER is defined, extend + * PageHeaderData with an 8-byte pd_block_scn field + * (block-level SCN) and bump PG_PAGE_LAYOUT_VERSION + * 4 -> 5. + * Why: Stage 1.4 introduces cluster-aware MVCC SCN tracking + * at the page level; the +8B field is the on-disk + * anchor for spec-1.16's local_scn maintenance. The + * layout version bump uses PG's existing + * pd_pagesize_version sanity check (every page header + * byte 14-15) to make pgrac binary refuse vanilla PG + * 16 datafiles (and vice versa) with a clear FATAL, + * instead of silent corruption. Stage 1.4 only writes + * InvalidScn (0) as a placeholder; spec-1.16 takes + * over real SCN advancement. + * See docs/block-format-design.md v1.1 §4.2 + §15 + * stage 1, docs/scn-protocol-design.md v1.1 §3.2, + * specs/spec-1.4-block-format-pageheader-scn.md. + * + * PGRAC MODIFICATIONS (7th): + * Modified by: SqlRush + * + * What changed: When USE_PGRAC_CLUSTER is defined, declare: + * 1. PageInitHeapPage extern -- heap-specific PageInit + * variant that calls PG PageInit with specialSize + * = CLUSTER_ITL_ARRAY_SIZE (384), placing 8 ITL + * slots in PG's special area at the page tail. + * 2. ClusterPageGetItlSlots inline helper that wraps + * PageGetSpecialPointer with PD_HAS_ITL + + * PageGetSpecialSize asserts. + * 3. PageHasItl inline helper. + * 4. PD_HAS_ITL flag bit (0x0008) -- set by + * PageInitHeapPage; reader uses it to distinguish + * heap pages (special = ITL) from index pages + * (special = btree/hash/gin opaque). + * Why: Stage 1.5 introduces the ITL slot array for Oracle- + * style row-level locking + per-block transaction + * queue. Heap pages get 384 B ITL in the PG special + * area at the page tail (NOT directly after the + * PageHeader -- doing so would break PG's pd_linp + * array access); index pages keep using their own + * special area for btree/hash/etc. opaque data. + * PageInitHeapPage carries the heap-specific knowledge + * (which PageInit cannot, since it's called from both + * heap am and index am). Stage 1.5 only writes + * placeholder ITL values (ITL_FLAG_FREE / InvalidScn / + * InvalidUba); Stage 3 (AD-006 第五轮) implements + * actual writes / reuse / cleanout. + * + * PIVOT A (2026-05-02): user-mandated relocation of + * ITL from "after PageHeader" to "in special area". + * The original layout broke PG's pd_linp[] struct + * access (PageGetMaxOffsetNumber / PageGetItemId etc. + * assume pd_linp starts at offsetof = SizeOfPageHeader- + * Data); special area is the only ABI-safe place to + * put 384 B of per-heap-page metadata. This is also + * how btree (BTPageOpaque) / hash / gist / brin / + * spgist / gin already use the special area. + * See specs/spec-1.5-itl-slot.md §1.4 例外说明 #6, + * docs/block-format-design.md v1.2 §4.1 layout. + * + * PGRAC MODIFICATIONS (Nth, stage 1.22): + * Modified by: SqlRush + * + * What changed: When USE_PGRAC_CLUSTER is defined, declare: + * 1. PD_UNDO_SEG_HEADER flag bit (0x0010) -- set by + * PageInitUndoSegmentHeader; reader uses it to + * identify block 0 of an undo segment file + * (pg_undo/instance_/seg_.dat). Mutually + * exclusive with PD_HAS_ITL by relation type. + * 2. PD_VALID_FLAG_BITS bumped 0x000F -> 0x001F to + * account for the new bit (cluster mode only). + * 3. PageInitUndoSegmentHeader extern -- writes a + * freshly-allocated UndoSegmentHeaderData layout + * to the page (delegates byte generation to the + * frontend-safe helper in cluster_undo_segment_init.h + * so backend and initdb produce byte-identical pages). + * 4. PageIsUndoSegmentHeader inline helper. + * Why: Stage 1.22 ships the dedicated undo tablespace + * (pg_undo OID 9100; UNDOTABLESPACE_OID per + * Hardening v1.0.2 OID conflict resolution) + atomic + * batch on-disk format change. block 0 of every + * seg_.dat is laid out + * as UndoSegmentHeaderData (cluster_undo_segment.h); + * PD_UNDO_SEG_HEADER lets tooling and visibility paths + * distinguish three page kinds (vanilla index / ITL + * heap / undo segment header). Stage 1.22 only writes + * placeholder TT slots (TT_SLOT_UNUSED) + zero + * retention/statistics fields; feature-117 activates + * real TT slot allocation and retention. + * See specs/spec-1.22-undo-tablespace-bootstrap.md §2.1 + * + §2.2 + §D1, docs/undo-segment-design.md §3.4-§3.6. + * + * PGRAC MODIFICATIONS (stage 4.5a): + * Modified by: SqlRush + * + * What changed: When USE_PGRAC_CLUSTER is defined (backend only), + * PageSetLSN additionally stamps the merged-recovery + * window SCN into pd_block_scn while the window is + * active, and the two window globals are declared. + * Why: spec-4.5a §3.3b -- inside k-way merged replay the + * page freshness authority is the per-record SCN + * (cross-thread LSNs are incomparable); the central + * PageSetLSN hook makes every redo handler stamp it + * without per-rmgr changes. Backends never enter the + * window, so the hook is a predictable-false branch. + */ +#ifndef BUFPAGE_H +#define BUFPAGE_H + +#include "access/xlogdefs.h" +#include "storage/block.h" +#include "storage/item.h" +#include "storage/off.h" + +#ifdef USE_PGRAC_CLUSTER +#include "cluster/cluster_scn.h" /* SCN typedef + InvalidScn (stage 1.4) */ +#include "cluster/cluster_itl_slot.h" /* ClusterItlSlotData + CLUSTER_ITL_ARRAY_SIZE (stage 1.5) */ +#endif + +/* + * A postgres disk page is an abstraction layered on top of a postgres + * disk block (which is simply a unit of i/o, see block.h). + * + * specifically, while a disk block can be unformatted, a postgres + * disk page is always a slotted page of the form: + * + * +----------------+---------------------------------+ + * | PageHeaderData | linp1 linp2 linp3 ... | + * +-----------+----+---------------------------------+ + * | ... linpN | | + * +-----------+--------------------------------------+ + * | ^ pd_lower | + * | | + * | v pd_upper | + * +-------------+------------------------------------+ + * | | tupleN ... | + * +-------------+------------------+-----------------+ + * | ... tuple3 tuple2 tuple1 | "special space" | + * +--------------------------------+-----------------+ + * ^ pd_special + * + * a page is full when nothing can be added between pd_lower and + * pd_upper. + * + * all blocks written out by an access method must be disk pages. + * + * EXCEPTIONS: + * + * obviously, a page is not formatted before it is initialized by + * a call to PageInit. + * + * NOTES: + * + * linp1..N form an ItemId (line pointer) array. ItemPointers point + * to a physical block number and a logical offset (line pointer + * number) within that block/page. Note that OffsetNumbers + * conventionally start at 1, not 0. + * + * tuple1..N are added "backwards" on the page. Since an ItemPointer + * offset is used to access an ItemId entry rather than an actual + * byte-offset position, tuples can be physically shuffled on a page + * whenever the need arises. This indirection also keeps crash recovery + * relatively simple, because the low-level details of page space + * management can be controlled by standard buffer page code during + * logging, and during recovery. + * + * AM-generic per-page information is kept in PageHeaderData. + * + * AM-specific per-page data (if any) is kept in the area marked "special + * space"; each AM has an "opaque" structure defined somewhere that is + * stored as the page trailer. an access method should always + * initialize its pages with PageInit and then set its own opaque + * fields. + */ + +typedef Pointer Page; + + +/* + * location (byte offset) within a page. + * + * note that this is actually limited to 2^15 because we have limited + * ItemIdData.lp_off and ItemIdData.lp_len to 15 bits (see itemid.h). + */ +typedef uint16 LocationIndex; + + +/* + * For historical reasons, the 64-bit LSN value is stored as two 32-bit + * values. + */ +typedef struct { + uint32 xlogid; /* high bits */ + uint32 xrecoff; /* low bits */ +} PageXLogRecPtr; + +static inline XLogRecPtr +PageXLogRecPtrGet(PageXLogRecPtr val) +{ + return (uint64)val.xlogid << 32 | val.xrecoff; +} + +#define PageXLogRecPtrSet(ptr, lsn) \ + ((ptr).xlogid = (uint32)((lsn) >> 32), (ptr).xrecoff = (uint32)(lsn)) + +/* + * disk page organization + * + * space management information generic to any page + * + * pd_lsn - identifies xlog record for last change to this page. + * pd_checksum - page checksum, if set. + * pd_flags - flag bits. + * pd_lower - offset to start of free space. + * pd_upper - offset to end of free space. + * pd_special - offset to start of special space. + * pd_pagesize_version - size in bytes and page layout version number. + * pd_prune_xid - oldest XID among potentially prunable tuples on page. + * + * The LSN is used by the buffer manager to enforce the basic rule of WAL: + * "thou shalt write xlog before data". A dirty buffer cannot be dumped + * to disk until xlog has been flushed at least as far as the page's LSN. + * + * pd_checksum stores the page checksum, if it has been set for this page; + * zero is a valid value for a checksum. If a checksum is not in use then + * we leave the field unset. This will typically mean the field is zero + * though non-zero values may also be present if databases have been + * pg_upgraded from releases prior to 9.3, when the same byte offset was + * used to store the current timelineid when the page was last updated. + * Note that there is no indication on a page as to whether the checksum + * is valid or not, a deliberate design choice which avoids the problem + * of relying on the page contents to decide whether to verify it. Hence + * there are no flag bits relating to checksums. + * + * pd_prune_xid is a hint field that helps determine whether pruning will be + * useful. It is currently unused in index pages. + * + * The page version number and page size are packed together into a single + * uint16 field. This is for historical reasons: before PostgreSQL 7.3, + * there was no concept of a page version number, and doing it this way + * lets us pretend that pre-7.3 databases have page version number zero. + * We constrain page sizes to be multiples of 256, leaving the low eight + * bits available for a version number. + * + * Minimum possible page size is perhaps 64B to fit page header, opaque space + * and a minimal tuple; of course, in reality you want it much bigger, so + * the constraint on pagesize mod 256 is not an important restriction. + * On the high end, we can only support pages up to 32KB because lp_off/lp_len + * are 15 bits. + */ + +typedef struct PageHeaderData { + /* XXX LSN is member of *any* block, not only page-organized ones */ + PageXLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog + * record for last change to this page */ + uint16 pd_checksum; /* checksum */ + uint16 pd_flags; /* flag bits, see below */ + LocationIndex pd_lower; /* offset to start of free space */ + LocationIndex pd_upper; /* offset to end of free space */ + LocationIndex pd_special; /* offset to start of special space */ + uint16 pd_pagesize_version; + TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */ +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC (stage 1.4): block-level SCN for cluster-aware MVCC. + * + * Placeholder InvalidScn (0) at stage 1.4; spec-1.16 takes over + * real value advancement (commit_scn-style writeback per AD-008). + * 8 bytes on 64-bit ABI; offset 24 from start of header (after + * pd_prune_xid) -> SizeOfPageHeaderData becomes 32 (was 24). + */ + SCN pd_block_scn; +#endif + ItemIdData pd_linp[FLEXIBLE_ARRAY_MEMBER]; /* line pointer array */ +} PageHeaderData; + +typedef PageHeaderData *PageHeader; + +/* + * pd_flags contains the following flag bits. Undefined bits are initialized + * to zero and may be used in the future. + * + * PD_HAS_FREE_LINES is set if there are any LP_UNUSED line pointers before + * pd_lower. This should be considered a hint rather than the truth, since + * changes to it are not WAL-logged. + * + * PD_PAGE_FULL is set if an UPDATE doesn't find enough free space in the + * page for its new tuple version; this suggests that a prune is needed. + * Again, this is just a hint. + */ +#define PD_HAS_FREE_LINES 0x0001 /* are there any unused line pointers? */ +#define PD_PAGE_FULL 0x0002 /* not enough free space for new tuple? */ +#define PD_ALL_VISIBLE \ + 0x0004 /* all tuples on page are visible to + * everyone */ + +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC (stage 1.5): heap pages contain an ITL slot array immediately + * after the PageHeader. Set by PageInitHeapPage (heap am path); + * cleared / never-set by PageInit (index am path). Reader uses this + * bit to know whether (page + SizeOfPageHeaderData) is the start of + * 384 bytes of ClusterItlSlotData or the start of pd_linp. + */ +#define PD_HAS_ITL 0x0008 +/* + * PGRAC (stage 1.22): block 0 of every undo segment file + * (pg_undo/instance_/seg_.dat) is laid out as + * UndoSegmentHeaderData (cluster_undo_segment.h). Set by + * PageInitUndoSegmentHeader (cluster_undo_alloc.c path); never set + * by heap or index paths. Mutually exclusive with PD_HAS_ITL by + * relation type — heap pages have ITL slots, undo segment header + * pages have segment metadata + 48 TT slots. + * + * Tooling (pg_filedump etc.) can distinguish 3 page kinds: + * vanilla index : neither bit + * ITL heap : PD_HAS_ITL only + * undo seg header : PD_UNDO_SEG_HEADER only + * + * Spec: spec-1.22-undo-tablespace-bootstrap.md §2.1 Q-1 ★ A. + */ +#define PD_UNDO_SEG_HEADER 0x0010 +/* + * PGRAC (spec-4.5 §3.3d): force a full-page image on the next + * WAL-logged modification of this page, regardless of the (possibly + * foreign-thread, hence incomparable) page LSN. Set when a GCS block + * ship installs a remote image; cleared ONLY after an FPI with + * BKPIMAGE_APPLY was actually emitted AND the insertion returned a + * valid EndPos (xloginsert.c). Persistent: rides the page to shared + * disk, so eviction/reload/crash keep the guarantee. Five-rule + * semantics in the spec (round-7): REGBUF_FORCE_IMAGE/NO_IMAGE/ + * WILL_INIT and !doPageWrites keep their existing priority over this + * bit; replay restoring a set bit costs one benign extra FPI. + */ +#define PD_CLUSTER_FORCE_FPI 0x0020 +#define PD_VALID_FLAG_BITS 0x003F /* OR of all valid pd_flags bits */ +#else +#define PD_VALID_FLAG_BITS 0x0007 /* OR of all valid pd_flags bits */ +#endif + +/* + * Page layout version number 0 is for pre-7.3 Postgres releases. + * Releases 7.3 and 7.4 use 1, denoting a new HeapTupleHeader layout. + * Release 8.0 uses 2; it changed the HeapTupleHeader layout again. + * Release 8.1 uses 3; it redefined HeapTupleHeader infomask bits. + * Release 8.3 uses 4; it changed the HeapTupleHeader layout again, and + * added the pd_flags field (by stealing some bits from pd_tli), + * as well as adding the pd_prune_xid field (which enlarges the header). + * + * As of Release 9.3, the checksum version must also be considered when + * handling pages. + * + * pgrac (stage 1.4) uses 5: extends PageHeaderData with pd_block_scn + * (8 bytes), enlarging SizeOfPageHeaderData from 24 to 32. The + * layout version bump intentionally makes pgrac binary refuse + * vanilla PG 16 datafiles (and vice versa) via PG's existing + * pd_pagesize_version sanity check. See docs/block-format-design.md + * v1.1 §15 stage 1 + spec-1.4. + */ +#ifdef USE_PGRAC_CLUSTER +#define PG_PAGE_LAYOUT_VERSION 5 +#else +#define PG_PAGE_LAYOUT_VERSION 4 +#endif +#define PG_DATA_CHECKSUM_VERSION 1 + +/* ---------------------------------------------------------------- + * page support functions + * ---------------------------------------------------------------- + */ + +/* + * line pointer(s) do not count as part of header + */ +#define SizeOfPageHeaderData (offsetof(PageHeaderData, pd_linp)) + +/* + * PageIsEmpty + * returns true iff no itemid has been allocated on the page + * + * NOTE (PGRAC stage 1.5): this checks pd_lower against the ITL-free + * header size. Heap pages with PD_HAS_ITL still pass this test if + * pd_lower has not been advanced past SizeOfPageHeaderWithItl, but + * heap am callers should use PageIsEmpty in conjunction with + * PageHasItl() when they care whether the ITL array is present. + * Most existing callers (vacuum, FSM) treat "empty" as "no rows yet" + * and the unchanged check is correct for both heap and index pages. + */ +static inline bool +PageIsEmpty(Page page) +{ + return ((PageHeader)page)->pd_lower <= SizeOfPageHeaderData; +} + +/* + * PageIsNew + * returns true iff page has not been initialized (by PageInit) + */ +static inline bool +PageIsNew(Page page) +{ + return ((PageHeader)page)->pd_upper == 0; +} + +/* + * PageGetItemId + * Returns an item identifier of a page. + */ +static inline ItemId +PageGetItemId(Page page, OffsetNumber offsetNumber) +{ + return &((PageHeader)page)->pd_linp[offsetNumber - 1]; +} + +/* + * PageGetContents + * To be used in cases where the page does not contain line pointers. + * + * Note: prior to 8.3 this was not guaranteed to yield a MAXALIGN'd result. + * Now it is. Beware of old code that might think the offset to the contents + * is just SizeOfPageHeaderData rather than MAXALIGN(SizeOfPageHeaderData). + */ +static inline char * +PageGetContents(Page page) +{ + return (char *)page + MAXALIGN(SizeOfPageHeaderData); +} + +/* ---------------- + * functions to access page size info + * ---------------- + */ + +/* + * PageGetPageSize + * Returns the page size of a page. + * + * this can only be called on a formatted page (unlike + * BufferGetPageSize, which can be called on an unformatted page). + * however, it can be called on a page that is not stored in a buffer. + */ +static inline Size +PageGetPageSize(Page page) +{ + return (Size)(((PageHeader)page)->pd_pagesize_version & (uint16)0xFF00); +} + +/* + * PageGetPageLayoutVersion + * Returns the page layout version of a page. + */ +static inline uint8 +PageGetPageLayoutVersion(Page page) +{ + return (((PageHeader)page)->pd_pagesize_version & 0x00FF); +} + +/* + * PageSetPageSizeAndVersion + * Sets the page size and page layout version number of a page. + * + * We could support setting these two values separately, but there's + * no real need for it at the moment. + */ +static inline void +PageSetPageSizeAndVersion(Page page, Size size, uint8 version) +{ + Assert((size & 0xFF00) == size); + Assert((version & 0x00FF) == version); + + ((PageHeader)page)->pd_pagesize_version = size | version; +} + +/* ---------------- + * page special data functions + * ---------------- + */ +/* + * PageGetSpecialSize + * Returns size of special space on a page. + */ +static inline uint16 +PageGetSpecialSize(Page page) +{ + return (PageGetPageSize(page) - ((PageHeader)page)->pd_special); +} + +/* + * Using assertions, validate that the page special pointer is OK. + * + * This is intended to catch use of the pointer before page initialization. + */ +static inline void +PageValidateSpecialPointer(Page page) +{ + Assert(page); + Assert(((PageHeader)page)->pd_special <= BLCKSZ); + Assert(((PageHeader)page)->pd_special >= SizeOfPageHeaderData); +} + +/* + * PageGetSpecialPointer + * Returns pointer to special space on a page. + */ +static inline char * +PageGetSpecialPointer(Page page) +{ + PageValidateSpecialPointer(page); + return (char *)page + ((PageHeader)page)->pd_special; +} + +/* + * PageGetItem + * Retrieves an item on the given page. + * + * Note: + * This does not change the status of any of the resources passed. + * The semantics may change in the future. + */ +static inline Item +PageGetItem(Page page, ItemId itemId) +{ + Assert(page); + Assert(ItemIdHasStorage(itemId)); + + return (Item)(((char *)page) + ItemIdGetOffset(itemId)); +} + +/* + * PageGetMaxOffsetNumber + * Returns the maximum offset number used by the given page. + * Since offset numbers are 1-based, this is also the number + * of items on the page. + * + * NOTE: if the page is not initialized (pd_lower == 0), we must + * return zero to ensure sane behavior. + */ +static inline OffsetNumber +PageGetMaxOffsetNumber(Page page) +{ + PageHeader pageheader = (PageHeader)page; + + if (pageheader->pd_lower <= SizeOfPageHeaderData) + return 0; + else + return (pageheader->pd_lower - SizeOfPageHeaderData) / sizeof(ItemIdData); +} + +/* + * Additional functions for access to page headers. + */ +static inline XLogRecPtr +PageGetLSN(Page page) +{ + return PageXLogRecPtrGet(((PageHeader)page)->pd_lsn); +} +#if defined(USE_PGRAC_CLUSTER) && !defined(FRONTEND) +/* + * PGRAC: spec-4.5a §3.3b -- merged-recovery window state, defined in + * cluster_recovery_merge.c. Declared as plain externs so this core + * header stays free of cluster includes; outside the startup process's + * merged-replay window every reader sees false/0 (backends never enter + * the window), so the PageSetLSN hook below is a predictable-false + * branch on all hot paths. + */ +extern bool cluster_recmerge_window_active; +extern uint64 cluster_recmerge_window_scn; +extern uint64 cluster_recmerge_window_own_lsn; +extern bool cluster_recmerge_apply_foreign; +#endif + +static inline void +PageSetLSN(Page page, XLogRecPtr lsn) +{ +#if defined(USE_PGRAC_CLUSTER) && !defined(FRONTEND) + /* + * PGRAC: spec-4.5a §3.3b -- a FOREIGN record's lsn is in the peer's + * WAL sequence and lies beyond this node's own WAL flush point, so + * clamp the materialized page's pd_lsn to the own recovery redo + * (durable, comparable). Otherwise the end-of-recovery checkpoint's + * FlushBuffer would demand an unsatisfiable XLogFlush of the peer's + * LSN. pd_block_scn (below) stays the window's freshness authority. + */ + if (cluster_recmerge_window_active && cluster_recmerge_apply_foreign) + lsn = (XLogRecPtr) cluster_recmerge_window_own_lsn; +#endif + PageXLogRecPtrSet(((PageHeader)page)->pd_lsn, lsn); +#if defined(USE_PGRAC_CLUSTER) && !defined(FRONTEND) + + /* + * Inside the merged-replay window every applied record stamps its SCN + * as the page's freshness watermark. Cross-thread pd_lsn values are + * incomparable, so pd_block_scn is the window's ordering authority + * (XLogReadBufferForRedoExtended judges BLK_DONE/BLK_NEEDS_REDO by it + * inside the window); the stamp also survives a window crash-rerun, + * making re-applied records skip. + */ + if (cluster_recmerge_window_active) + ((PageHeader)page)->pd_block_scn = (SCN)cluster_recmerge_window_scn; +#endif +} + +static inline bool +PageHasFreeLinePointers(Page page) +{ + return ((PageHeader)page)->pd_flags & PD_HAS_FREE_LINES; +} +static inline void +PageSetHasFreeLinePointers(Page page) +{ + ((PageHeader)page)->pd_flags |= PD_HAS_FREE_LINES; +} +static inline void +PageClearHasFreeLinePointers(Page page) +{ + ((PageHeader)page)->pd_flags &= ~PD_HAS_FREE_LINES; +} + +static inline bool +PageIsFull(Page page) +{ + return ((PageHeader)page)->pd_flags & PD_PAGE_FULL; +} +static inline void +PageSetFull(Page page) +{ + ((PageHeader)page)->pd_flags |= PD_PAGE_FULL; +} +static inline void +PageClearFull(Page page) +{ + ((PageHeader)page)->pd_flags &= ~PD_PAGE_FULL; +} + +static inline bool +PageIsAllVisible(Page page) +{ + return ((PageHeader)page)->pd_flags & PD_ALL_VISIBLE; +} +static inline void +PageSetAllVisible(Page page) +{ + ((PageHeader)page)->pd_flags |= PD_ALL_VISIBLE; +} +static inline void +PageClearAllVisible(Page page) +{ + ((PageHeader)page)->pd_flags &= ~PD_ALL_VISIBLE; +} + +#ifdef USE_PGRAC_CLUSTER +/* PGRAC spec-4.5 §3.3d: force-FPI bit accessors. */ +static inline bool +PageHasForceFpi(Page page) +{ + return (((PageHeader)page)->pd_flags & PD_CLUSTER_FORCE_FPI) != 0; +} +static inline void +PageSetForceFpi(Page page) +{ + ((PageHeader)page)->pd_flags |= PD_CLUSTER_FORCE_FPI; +} +static inline void +PageClearForceFpi(Page page) +{ + ((PageHeader)page)->pd_flags &= ~PD_CLUSTER_FORCE_FPI; +} +#endif + +/* + * These two require "access/transam.h", so left as macros. + */ +#define PageSetPrunable(page, xid) \ + do { \ + Assert(TransactionIdIsNormal(xid)); \ + if (!TransactionIdIsValid(((PageHeader)(page))->pd_prune_xid) \ + || TransactionIdPrecedes(xid, ((PageHeader)(page))->pd_prune_xid)) \ + ((PageHeader)(page))->pd_prune_xid = (xid); \ + } while (0) +#define PageClearPrunable(page) (((PageHeader)(page))->pd_prune_xid = InvalidTransactionId) + + +/* ---------------------------------------------------------------- + * extern declarations + * ---------------------------------------------------------------- + */ + +/* flags for PageAddItemExtended() */ +#define PAI_OVERWRITE (1 << 0) +#define PAI_IS_HEAP (1 << 1) + +/* flags for PageIsVerifiedExtended() */ +#define PIV_LOG_WARNING (1 << 0) +#define PIV_REPORT_STAT (1 << 1) + +#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap) \ + PageAddItemExtended(page, item, size, offsetNumber, \ + ((overwrite) ? PAI_OVERWRITE : 0) | ((is_heap) ? PAI_IS_HEAP : 0)) + +#define PageIsVerified(page, blkno) \ + PageIsVerifiedExtended(page, blkno, PIV_LOG_WARNING | PIV_REPORT_STAT) + +/* + * Check that BLCKSZ is a multiple of sizeof(size_t). In + * PageIsVerifiedExtended(), it is much faster to check if a page is + * full of zeroes using the native word size. Note that this assertion + * is kept within a header to make sure that StaticAssertDecl() works + * across various combinations of platforms and compilers. + */ +StaticAssertDecl(BLCKSZ == ((BLCKSZ / sizeof(size_t)) * sizeof(size_t)), + "BLCKSZ has to be a multiple of sizeof(size_t)"); + +extern void PageInit(Page page, Size pageSize, Size specialSize); +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC (stage 1.5): heap-specific PageInit that allocates the 384B + * ITL slot array immediately after the PageHeader. All ITL slot + * fields are written as placeholders (ITL_FLAG_FREE / InvalidScn / + * InvalidUba / InvalidTransactionId / InvalidXLogRecPtr) per + * spec-1.5 §3.2; Stage 3 (AD-006 第五轮) takes over real writes / + * reuse / cleanout. + * + * pd_lower starts at SizeOfPageHeaderWithItl (= 416); PD_HAS_ITL is + * set in pd_flags so readers can distinguish heap pages (with ITL) + * from index pages (PageInit, no ITL). + * + * Heap am paths (heapam.c, hio.c) MUST call this; index am paths + * (btree, hash, gin, gist, brin, spgist) MUST keep calling PageInit. + */ +extern void PageInitHeapPage(Page page, Size pageSize, Size specialSize); + +/* + * PageHasItl -- does this heap page carry an ITL slot array? + * + * Read PD_HAS_ITL bit; only heap pages set it (PageInitHeapPage + * above). Use this guard before ClusterPageGetItlSlots. + * + * Index am pages (btree, hash, gin, gist, brin, spgist) have their + * own special area data (BTPageOpaque etc.) and MUST NOT have this + * bit set. PG reuses the special area for am-specific metadata; the + * bit identifies which interpretation to use. + */ +static inline bool +PageHasItl(Page page) +{ + return (((PageHeader)page)->pd_flags & PD_HAS_ITL) != 0; +} + +/* + * ClusterPageGetItlSlots -- pointer to slot 0 of the per-page ITL array. + * + * Returns PageGetSpecialPointer(page) cast to ClusterItlSlotData *. + * Stage 1.5 stores the 8-slot array (384 B) in PG's special area at + * the page tail, NOT directly after the PageHeader (PIVOT A + * 2026-05-02; original layout broke PG's pd_linp[] struct access). + * + * The asserts catch two classes of misuse: + * 1. PageHasItl(page) -- caller fed an index page (no ITL) + * 2. PageGetSpecialSize(page) >= CLUSTER_ITL_ARRAY_SIZE -- caller + * fed a malformed heap page where the special area is smaller + * than the ITL array (corruption / bug) + */ +static inline ClusterItlSlotData * +ClusterPageGetItlSlots(Page page) +{ + Assert(PageHasItl(page)); + /* + * The slot array occupies the FIRST CLUSTER_ITL_ARRAY_SIZE (384) bytes of + * the special area, so slot access only requires >= 384 -- NOT the full + * 392 special size (spec-3.10 §v0.5: the 8B ITL header trails the slots). + * Keeping this at CLUSTER_ITL_ARRAY_SIZE lets pre-v0.5 unit-test fixtures + * that reserve a 384-byte special area (and never touch the header) keep + * exercising the slot reader. ClusterPageGetItlHeader below requires the + * full CLUSTER_ITL_SPECIAL_SIZE. + */ + Assert(PageGetSpecialSize(page) >= CLUSTER_ITL_ARRAY_SIZE); + return (ClusterItlSlotData *)PageGetSpecialPointer(page); +} + +/* + * ClusterPageGetItlHeader -- pointer to the 8-byte per-page ITL header + * (spec-3.10 §v0.5), which lives at the END of the special area, right + * after the 384-byte slot array (special offset CLUSTER_ITL_ARRAY_SIZE). + * Carries itl_recycle_watermark_scn (slot-reuse fail-closed guard). + */ +static inline ClusterItlPageHeader * +ClusterPageGetItlHeader(Page page) +{ + Assert(PageHasItl(page)); + Assert(PageGetSpecialSize(page) >= CLUSTER_ITL_SPECIAL_SIZE); + return (ClusterItlPageHeader *)((char *)PageGetSpecialPointer(page) + CLUSTER_ITL_ARRAY_SIZE); +} + +/* + * ClusterPageGetItlSlot -- the slot_idx-th ITL slot (0-based). + * + * Stage 1.5 returns slots in ITL_FLAG_FREE state with all SCN / + * UBA / xid fields zero-init'd. Stage 3 (AD-006 第五轮) populates + * real values during heap_insert / heap_update / heap_delete. + * + * slot_idx in 0..CLUSTER_ITL_INITRANS_DEFAULT-1; out-of-range trips + * an Assert. Heap tuple's t_itl_slot_idx == 255 means "no slot + * assigned" -- callers must not pass 255 here. + */ +static inline ClusterItlSlotData * +ClusterPageGetItlSlot(Page page, uint8 slot_idx) +{ + Assert(slot_idx < CLUSTER_ITL_INITRANS_DEFAULT); + return &ClusterPageGetItlSlots(page)[slot_idx]; +} + +/* + * PageInitUndoSegmentHeader -- initialize block 0 of an undo segment. + * + * Stage 1.22: writes a freshly-allocated UndoSegmentHeaderData layout + * to `page` (8 KB). Mirrors PageInitHeapPage (spec-1.5) and PageInit + * (vanilla) but for undo segment header blocks instead of heap / index + * pages. Sets PD_UNDO_SEG_HEADER bit; specialSize is fixed to 0 + * (undo segment header uses the entire 8 KB block as a fixed-layout + * struct; no special area). + * + * Caller responsibilities: + * - hold an exclusive lock on the buffer (or be running in + * single-process initdb / bootstrap context) + * - pageSize must equal BLCKSZ (asserted) + * - owner_instance must be in [1, UNDO_OWNER_INSTANCE_MAX] (asserted) + * + * Body delegates byte-generation to the frontend-safe helper + * cluster_undo_segment_make_header_bytes (cluster_undo_segment_init.h) + * so backend (this function) and frontend (initdb) write byte-identical + * pages. + * + * Spec: spec-1.22-undo-tablespace-bootstrap.md §2.2 + §D2 (v0.2 Q-6 ★ A). + */ +extern void PageInitUndoSegmentHeader(Page page, Size pageSize, uint32 segment_id, + uint8 owner_instance); + +/* + * PageIsUndoSegmentHeader -- is this page block 0 of an undo segment? + * + * Read PD_UNDO_SEG_HEADER bit; only set by PageInitUndoSegmentHeader + * above. Mutually exclusive with PD_HAS_ITL (heap pages do not have + * segment headers and undo pages do not have ITL slots). + * + * Use this guard before casting (UndoSegmentHeaderData *) page. + */ +static inline bool +PageIsUndoSegmentHeader(Page page) +{ + return (((PageHeader)page)->pd_flags & PD_UNDO_SEG_HEADER) != 0; +} +#endif +extern bool PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags); +extern OffsetNumber PageAddItemExtended(Page page, Item item, Size size, OffsetNumber offsetNumber, + int flags); +extern Page PageGetTempPage(Page page); +extern Page PageGetTempPageCopy(Page page); +extern Page PageGetTempPageCopySpecial(Page page); +extern void PageRestoreTempPage(Page tempPage, Page oldPage); +extern void PageRepairFragmentation(Page page); +extern void PageTruncateLinePointerArray(Page page); +extern Size PageGetFreeSpace(Page page); +extern Size PageGetFreeSpaceForMultipleTuples(Page page, int ntups); +extern Size PageGetExactFreeSpace(Page page); +extern Size PageGetHeapFreeSpace(Page page); +extern void PageIndexTupleDelete(Page page, OffsetNumber offnum); +extern void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems); +extern void PageIndexTupleDeleteNoCompact(Page page, OffsetNumber offnum); +extern bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize); +extern char *PageSetChecksumCopy(Page page, BlockNumber blkno); +extern void PageSetChecksumInplace(Page page, BlockNumber blkno); + +#endif /* BUFPAGE_H */ diff --git a/install/include/postgresql/server/storage/checksum.h b/install/include/postgresql/server/storage/checksum.h new file mode 100644 index 00000000000..4afd25a0af1 --- /dev/null +++ b/install/include/postgresql/server/storage/checksum.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * checksum.h + * Checksum implementation for data pages. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/checksum.h + * + *------------------------------------------------------------------------- + */ +#ifndef CHECKSUM_H +#define CHECKSUM_H + +#include "storage/block.h" + +/* + * Compute the checksum for a Postgres page. The page must be aligned on a + * 4-byte boundary. + */ +extern uint16 pg_checksum_page(char *page, BlockNumber blkno); + +#endif /* CHECKSUM_H */ diff --git a/install/include/postgresql/server/storage/checksum_impl.h b/install/include/postgresql/server/storage/checksum_impl.h new file mode 100644 index 00000000000..7b157161a2d --- /dev/null +++ b/install/include/postgresql/server/storage/checksum_impl.h @@ -0,0 +1,215 @@ +/*------------------------------------------------------------------------- + * + * checksum_impl.h + * Checksum implementation for data pages. + * + * This file exists for the benefit of external programs that may wish to + * check Postgres page checksums. They can #include this to get the code + * referenced by storage/checksum.h. (Note: you may need to redefine + * Assert() as empty to compile this successfully externally.) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/checksum_impl.h + * + *------------------------------------------------------------------------- + */ + +/* + * The algorithm used to checksum pages is chosen for very fast calculation. + * Workloads where the database working set fits into OS file cache but not + * into shared buffers can read in pages at a very fast pace and the checksum + * algorithm itself can become the largest bottleneck. + * + * The checksum algorithm itself is based on the FNV-1a hash (FNV is shorthand + * for Fowler/Noll/Vo). The primitive of a plain FNV-1a hash folds in data 1 + * byte at a time according to the formula: + * + * hash = (hash ^ value) * FNV_PRIME + * + * FNV-1a algorithm is described at http://www.isthe.com/chongo/tech/comp/fnv/ + * + * PostgreSQL doesn't use FNV-1a hash directly because it has bad mixing of + * high bits - high order bits in input data only affect high order bits in + * output data. To resolve this we xor in the value prior to multiplication + * shifted right by 17 bits. The number 17 was chosen because it doesn't + * have common denominator with set bit positions in FNV_PRIME and empirically + * provides the fastest mixing for high order bits of final iterations quickly + * avalanche into lower positions. For performance reasons we choose to combine + * 4 bytes at a time. The actual hash formula used as the basis is: + * + * hash = (hash ^ value) * FNV_PRIME ^ ((hash ^ value) >> 17) + * + * The main bottleneck in this calculation is the multiplication latency. To + * hide the latency and to make use of SIMD parallelism multiple hash values + * are calculated in parallel. The page is treated as a 32 column two + * dimensional array of 32 bit values. Each column is aggregated separately + * into a partial checksum. Each partial checksum uses a different initial + * value (offset basis in FNV terminology). The initial values actually used + * were chosen randomly, as the values themselves don't matter as much as that + * they are different and don't match anything in real data. After initializing + * partial checksums each value in the column is aggregated according to the + * above formula. Finally two more iterations of the formula are performed with + * value 0 to mix the bits of the last value added. + * + * The partial checksums are then folded together using xor to form a single + * 32-bit checksum. The caller can safely reduce the value to 16 bits + * using modulo 2^16-1. That will cause a very slight bias towards lower + * values but this is not significant for the performance of the + * checksum. + * + * The algorithm choice was based on what instructions are available in SIMD + * instruction sets. This meant that a fast and good algorithm needed to use + * multiplication as the main mixing operator. The simplest multiplication + * based checksum primitive is the one used by FNV. The prime used is chosen + * for good dispersion of values. It has no known simple patterns that result + * in collisions. Test of 5-bit differentials of the primitive over 64bit keys + * reveals no differentials with 3 or more values out of 100000 random keys + * colliding. Avalanche test shows that only high order bits of the last word + * have a bias. Tests of 1-4 uncorrelated bit errors, stray 0 and 0xFF bytes, + * overwriting page from random position to end with 0 bytes, and overwriting + * random segments of page with 0x00, 0xFF and random data all show optimal + * 2e-16 false positive rate within margin of error. + * + * Vectorization of the algorithm requires 32bit x 32bit -> 32bit integer + * multiplication instruction. As of 2013 the corresponding instruction is + * available on x86 SSE4.1 extensions (pmulld) and ARM NEON (vmul.i32). + * Vectorization requires a compiler to do the vectorization for us. For recent + * GCC versions the flags -msse4.1 -funroll-loops -ftree-vectorize are enough + * to achieve vectorization. + * + * The optimal amount of parallelism to use depends on CPU specific instruction + * latency, SIMD instruction width, throughput and the amount of registers + * available to hold intermediate state. Generally, more parallelism is better + * up to the point that state doesn't fit in registers and extra load-store + * instructions are needed to swap values in/out. The number chosen is a fixed + * part of the algorithm because changing the parallelism changes the checksum + * result. + * + * The parallelism number 32 was chosen based on the fact that it is the + * largest state that fits into architecturally visible x86 SSE registers while + * leaving some free registers for intermediate values. For future processors + * with 256bit vector registers this will leave some performance on the table. + * When vectorization is not available it might be beneficial to restructure + * the computation to calculate a subset of the columns at a time and perform + * multiple passes to avoid register spilling. This optimization opportunity + * is not used. Current coding also assumes that the compiler has the ability + * to unroll the inner loop to avoid loop overhead and minimize register + * spilling. For less sophisticated compilers it might be beneficial to + * manually unroll the inner loop. + */ + +#include "storage/bufpage.h" + +/* number of checksums to calculate in parallel */ +#define N_SUMS 32 +/* prime multiplier of FNV-1a hash */ +#define FNV_PRIME 16777619 + +/* Use a union so that this code is valid under strict aliasing */ +typedef union +{ + PageHeaderData phdr; + uint32 data[BLCKSZ / (sizeof(uint32) * N_SUMS)][N_SUMS]; +} PGChecksummablePage; + +/* + * Base offsets to initialize each of the parallel FNV hashes into a + * different initial state. + */ +static const uint32 checksumBaseOffsets[N_SUMS] = { + 0x5B1F36E9, 0xB8525960, 0x02AB50AA, 0x1DE66D2A, + 0x79FF467A, 0x9BB9F8A3, 0x217E7CD2, 0x83E13D2C, + 0xF8D4474F, 0xE39EB970, 0x42C6AE16, 0x993216FA, + 0x7B093B5D, 0x98DAFF3C, 0xF718902A, 0x0B1C9CDB, + 0xE58F764B, 0x187636BC, 0x5D7B3BB1, 0xE73DE7DE, + 0x92BEC979, 0xCCA6C0B2, 0x304A0979, 0x85AA43D4, + 0x783125BB, 0x6CA8EAA2, 0xE407EAC6, 0x4B5CFC3E, + 0x9FBF8C76, 0x15CA20BE, 0xF2CA9FD3, 0x959BD756 +}; + +/* + * Calculate one round of the checksum. + */ +#define CHECKSUM_COMP(checksum, value) \ +do { \ + uint32 __tmp = (checksum) ^ (value); \ + (checksum) = __tmp * FNV_PRIME ^ (__tmp >> 17); \ +} while (0) + +/* + * Block checksum algorithm. The page must be adequately aligned + * (at least on 4-byte boundary). + */ +static uint32 +pg_checksum_block(const PGChecksummablePage *page) +{ + uint32 sums[N_SUMS]; + uint32 result = 0; + uint32 i, + j; + + /* ensure that the size is compatible with the algorithm */ + Assert(sizeof(PGChecksummablePage) == BLCKSZ); + + /* initialize partial checksums to their corresponding offsets */ + memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets)); + + /* main checksum calculation */ + for (i = 0; i < (uint32) (BLCKSZ / (sizeof(uint32) * N_SUMS)); i++) + for (j = 0; j < N_SUMS; j++) + CHECKSUM_COMP(sums[j], page->data[i][j]); + + /* finally add in two rounds of zeroes for additional mixing */ + for (i = 0; i < 2; i++) + for (j = 0; j < N_SUMS; j++) + CHECKSUM_COMP(sums[j], 0); + + /* xor fold partial checksums together */ + for (i = 0; i < N_SUMS; i++) + result ^= sums[i]; + + return result; +} + +/* + * Compute the checksum for a Postgres page. + * + * The page must be adequately aligned (at least on a 4-byte boundary). + * Beware also that the checksum field of the page is transiently zeroed. + * + * The checksum includes the block number (to detect the case where a page is + * somehow moved to a different location), the page header (excluding the + * checksum itself), and the page data. + */ +uint16 +pg_checksum_page(char *page, BlockNumber blkno) +{ + PGChecksummablePage *cpage = (PGChecksummablePage *) page; + uint16 save_checksum; + uint32 checksum; + + /* We only calculate the checksum for properly-initialized pages */ + Assert(!PageIsNew((Page) page)); + + /* + * Save pd_checksum and temporarily set it to zero, so that the checksum + * calculation isn't affected by the old checksum stored on the page. + * Restore it after, because actually updating the checksum is NOT part of + * the API of this function. + */ + save_checksum = cpage->phdr.pd_checksum; + cpage->phdr.pd_checksum = 0; + checksum = pg_checksum_block(cpage); + cpage->phdr.pd_checksum = save_checksum; + + /* Mix in the block number to detect transposed pages */ + checksum ^= blkno; + + /* + * Reduce to a uint16 (to fit in the pd_checksum field) with an offset of + * one. That avoids checksums of zero, which seems like a good idea. + */ + return (uint16) ((checksum % 65535) + 1); +} diff --git a/install/include/postgresql/server/storage/condition_variable.h b/install/include/postgresql/server/storage/condition_variable.h new file mode 100644 index 00000000000..e218cb2c499 --- /dev/null +++ b/install/include/postgresql/server/storage/condition_variable.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * condition_variable.h + * Condition variables + * + * A condition variable is a method of waiting until a certain condition + * becomes true. Conventionally, a condition variable supports three + * operations: (1) sleep; (2) signal, which wakes up one process sleeping + * on the condition variable; and (3) broadcast, which wakes up every + * process sleeping on the condition variable. In our implementation, + * condition variables put a process into an interruptible sleep (so it + * can be canceled prior to the fulfillment of the condition) and do not + * use pointers internally (so that they are safe to use within DSMs). + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/condition_variable.h + * + *------------------------------------------------------------------------- + */ +#ifndef CONDITION_VARIABLE_H +#define CONDITION_VARIABLE_H + +#include "storage/proclist_types.h" +#include "storage/spin.h" + +typedef struct +{ + slock_t mutex; /* spinlock protecting the wakeup list */ + proclist_head wakeup; /* list of wake-able processes */ +} ConditionVariable; + +/* + * Pad a condition variable to a power-of-two size so that an array of + * condition variables does not cross a cache line boundary. + */ +#define CV_MINIMAL_SIZE (sizeof(ConditionVariable) <= 16 ? 16 : 32) +typedef union ConditionVariableMinimallyPadded +{ + ConditionVariable cv; + char pad[CV_MINIMAL_SIZE]; +} ConditionVariableMinimallyPadded; + +/* Initialize a condition variable. */ +extern void ConditionVariableInit(ConditionVariable *cv); + +/* + * To sleep on a condition variable, a process should use a loop which first + * checks the condition, exiting the loop if it is met, and then calls + * ConditionVariableSleep. Spurious wakeups are possible, but should be + * infrequent. After exiting the loop, ConditionVariableCancelSleep must + * be called to ensure that the process is no longer in the wait list for + * the condition variable. + */ +extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info); +extern bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, + uint32 wait_event_info); +extern bool ConditionVariableCancelSleep(void); + +/* + * Optionally, ConditionVariablePrepareToSleep can be called before entering + * the test-and-sleep loop described above. Doing so is more efficient if + * at least one sleep is needed, whereas not doing so is more efficient when + * no sleep is needed because the test condition is true the first time. + */ +extern void ConditionVariablePrepareToSleep(ConditionVariable *cv); + +/* Wake up a single waiter (via signal) or all waiters (via broadcast). */ +extern void ConditionVariableSignal(ConditionVariable *cv); +extern void ConditionVariableBroadcast(ConditionVariable *cv); + +#endif /* CONDITION_VARIABLE_H */ diff --git a/install/include/postgresql/server/storage/copydir.h b/install/include/postgresql/server/storage/copydir.h new file mode 100644 index 00000000000..a8be5b21e0b --- /dev/null +++ b/install/include/postgresql/server/storage/copydir.h @@ -0,0 +1,19 @@ +/*------------------------------------------------------------------------- + * + * copydir.h + * Copy a directory. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/copydir.h + * + *------------------------------------------------------------------------- + */ +#ifndef COPYDIR_H +#define COPYDIR_H + +extern void copydir(const char *fromdir, const char *todir, bool recurse); +extern void copy_file(const char *fromfile, const char *tofile); + +#endif /* COPYDIR_H */ diff --git a/install/include/postgresql/server/storage/dsm.h b/install/include/postgresql/server/storage/dsm.h new file mode 100644 index 00000000000..858bbf61c28 --- /dev/null +++ b/install/include/postgresql/server/storage/dsm.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * dsm.h + * manage dynamic shared memory segments + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/dsm.h + * + *------------------------------------------------------------------------- + */ +#ifndef DSM_H +#define DSM_H + +#include "storage/dsm_impl.h" + +typedef struct dsm_segment dsm_segment; + +#define DSM_CREATE_NULL_IF_MAXSEGMENTS 0x0001 + +/* Startup and shutdown functions. */ +struct PGShmemHeader; /* avoid including pg_shmem.h */ +extern void dsm_cleanup_using_control_segment(dsm_handle old_control_handle); +extern void dsm_postmaster_startup(struct PGShmemHeader *); +extern void dsm_backend_shutdown(void); +extern void dsm_detach_all(void); + +extern size_t dsm_estimate_size(void); +extern void dsm_shmem_init(void); + +#ifdef EXEC_BACKEND +extern void dsm_set_control_handle(dsm_handle h); +#endif + +/* Functions that create or remove mappings. */ +extern dsm_segment *dsm_create(Size size, int flags); +extern dsm_segment *dsm_attach(dsm_handle h); +extern void dsm_detach(dsm_segment *seg); + +/* Resource management functions. */ +extern void dsm_pin_mapping(dsm_segment *seg); +extern void dsm_unpin_mapping(dsm_segment *seg); +extern void dsm_pin_segment(dsm_segment *seg); +extern void dsm_unpin_segment(dsm_handle handle); +extern dsm_segment *dsm_find_mapping(dsm_handle handle); + +/* Informational functions. */ +extern void *dsm_segment_address(dsm_segment *seg); +extern Size dsm_segment_map_length(dsm_segment *seg); +extern dsm_handle dsm_segment_handle(dsm_segment *seg); + +/* Cleanup hooks. */ +typedef void (*on_dsm_detach_callback) (dsm_segment *, Datum arg); +extern void on_dsm_detach(dsm_segment *seg, + on_dsm_detach_callback function, Datum arg); +extern void cancel_on_dsm_detach(dsm_segment *seg, + on_dsm_detach_callback function, Datum arg); +extern void reset_on_dsm_detach(void); + +#endif /* DSM_H */ diff --git a/install/include/postgresql/server/storage/dsm_impl.h b/install/include/postgresql/server/storage/dsm_impl.h new file mode 100644 index 00000000000..daf07bd19cd --- /dev/null +++ b/install/include/postgresql/server/storage/dsm_impl.h @@ -0,0 +1,79 @@ +/*------------------------------------------------------------------------- + * + * dsm_impl.h + * low-level dynamic shared memory primitives + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/dsm_impl.h + * + *------------------------------------------------------------------------- + */ +#ifndef DSM_IMPL_H +#define DSM_IMPL_H + +/* Dynamic shared memory implementations. */ +#define DSM_IMPL_POSIX 1 +#define DSM_IMPL_SYSV 2 +#define DSM_IMPL_WINDOWS 3 +#define DSM_IMPL_MMAP 4 + +/* + * Determine which dynamic shared memory implementations will be supported + * on this platform, and which one will be the default. + */ +#ifdef WIN32 +#define USE_DSM_WINDOWS +#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_WINDOWS +#else +#ifdef HAVE_SHM_OPEN +#define USE_DSM_POSIX +#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_POSIX +#endif +#define USE_DSM_SYSV +#ifndef DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE +#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_SYSV +#endif +#define USE_DSM_MMAP +#endif + +/* GUC. */ +extern PGDLLIMPORT int dynamic_shared_memory_type; +extern PGDLLIMPORT int min_dynamic_shared_memory; + +/* + * Directory for on-disk state. + * + * This is used by all implementations for crash recovery and by the mmap + * implementation for storage. + */ +#define PG_DYNSHMEM_DIR "pg_dynshmem" +#define PG_DYNSHMEM_MMAP_FILE_PREFIX "mmap." + +/* A "name" for a dynamic shared memory segment. */ +typedef uint32 dsm_handle; + +/* Sentinel value to use for invalid DSM handles. */ +#define DSM_HANDLE_INVALID ((dsm_handle) 0) + +/* All the shared-memory operations we know about. */ +typedef enum +{ + DSM_OP_CREATE, + DSM_OP_ATTACH, + DSM_OP_DETACH, + DSM_OP_DESTROY +} dsm_op; + +/* Create, attach to, detach from, resize, or destroy a segment. */ +extern bool dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size, + void **impl_private, void **mapped_address, Size *mapped_size, + int elevel); + +/* Implementation-dependent actions required to keep segment until shutdown. */ +extern void dsm_impl_pin_segment(dsm_handle handle, void *impl_private, + void **impl_private_pm_handle); +extern void dsm_impl_unpin_segment(dsm_handle handle, void **impl_private); + +#endif /* DSM_IMPL_H */ diff --git a/install/include/postgresql/server/storage/fd.h b/install/include/postgresql/server/storage/fd.h new file mode 100644 index 00000000000..26809899591 --- /dev/null +++ b/install/include/postgresql/server/storage/fd.h @@ -0,0 +1,213 @@ +/*------------------------------------------------------------------------- + * + * fd.h + * Virtual file descriptor definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/fd.h + * + *------------------------------------------------------------------------- + */ + +/* + * calls: + * + * File {Close, Read, Write, Size, Sync} + * {Path Name Open, Allocate, Free} File + * + * These are NOT JUST RENAMINGS OF THE UNIX ROUTINES. + * Use them for all file activity... + * + * File fd; + * fd = PathNameOpenFile("foo", O_RDONLY); + * + * AllocateFile(); + * FreeFile(); + * + * Use AllocateFile, not fopen, if you need a stdio file (FILE*); then + * use FreeFile, not fclose, to close it. AVOID using stdio for files + * that you intend to hold open for any length of time, since there is + * no way for them to share kernel file descriptors with other files. + * + * Likewise, use AllocateDir/FreeDir, not opendir/closedir, to allocate + * open directories (DIR*), and OpenTransientFile/CloseTransientFile for an + * unbuffered file descriptor. + * + * If you really can't use any of the above, at least call AcquireExternalFD + * or ReserveExternalFD to report any file descriptors that are held for any + * length of time. Failure to do so risks unnecessary EMFILE errors. + */ +#ifndef FD_H +#define FD_H + +#include +#include + +typedef enum RecoveryInitSyncMethod +{ + RECOVERY_INIT_SYNC_METHOD_FSYNC, + RECOVERY_INIT_SYNC_METHOD_SYNCFS +} RecoveryInitSyncMethod; + +typedef int File; + + +#define IO_DIRECT_DATA 0x01 +#define IO_DIRECT_WAL 0x02 +#define IO_DIRECT_WAL_INIT 0x04 + +enum FileExtendMethod +{ +#ifdef HAVE_POSIX_FALLOCATE + FILE_EXTEND_METHOD_POSIX_FALLOCATE, +#endif + FILE_EXTEND_METHOD_WRITE_ZEROS, +}; + +/* Default to the first available file_extend_method. */ +#define DEFAULT_FILE_EXTEND_METHOD 0 + +/* GUC parameter */ +extern PGDLLIMPORT int max_files_per_process; +extern PGDLLIMPORT bool data_sync_retry; +extern PGDLLIMPORT int recovery_init_sync_method; +extern PGDLLIMPORT int io_direct_flags; +extern PGDLLIMPORT int file_extend_method; + +/* + * This is private to fd.c, but exported for save/restore_backend_variables() + */ +extern PGDLLIMPORT int max_safe_fds; + +/* + * On Windows, we have to interpret EACCES as possibly meaning the same as + * ENOENT, because if a file is unlinked-but-not-yet-gone on that platform, + * that's what you get. Ugh. This code is designed so that we don't + * actually believe these cases are okay without further evidence (namely, + * a pending fsync request getting canceled ... see ProcessSyncRequests). + */ +#ifndef WIN32 +#define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT) +#else +#define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT || (err) == EACCES) +#endif + +/* + * O_DIRECT is not standard, but almost every Unix has it. We translate it + * to the appropriate Windows flag in src/port/open.c. We simulate it with + * fcntl(F_NOCACHE) on macOS inside fd.c's open() wrapper. We use the name + * PG_O_DIRECT rather than defining O_DIRECT in that case (probably not a good + * idea on a Unix). We can only use it if the compiler will correctly align + * PGIOAlignedBlock for us, though. + */ +#if defined(O_DIRECT) && defined(pg_attribute_aligned) +#define PG_O_DIRECT O_DIRECT +#elif defined(F_NOCACHE) +#define PG_O_DIRECT 0x80000000 +#define PG_O_DIRECT_USE_F_NOCACHE +#else +#define PG_O_DIRECT 0 +#endif + +/* + * prototypes for functions in fd.c + */ + +/* Operations on virtual Files --- equivalent to Unix kernel file ops */ +extern File PathNameOpenFile(const char *fileName, int fileFlags); +extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode); +extern File OpenTemporaryFile(bool interXact); +extern void FileClose(File file); +extern int FilePrefetch(File file, off_t offset, off_t amount, uint32 wait_event_info); +extern int FileRead(File file, void *buffer, size_t amount, off_t offset, uint32 wait_event_info); +extern int FileWrite(File file, const void *buffer, size_t amount, off_t offset, uint32 wait_event_info); +extern int FileSync(File file, uint32 wait_event_info); +extern int FileZero(File file, off_t offset, off_t amount, uint32 wait_event_info); +extern int FileFallocate(File file, off_t offset, off_t amount, uint32 wait_event_info); + +extern off_t FileSize(File file); +extern int FileTruncate(File file, off_t offset, uint32 wait_event_info); +extern void FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info); +extern char *FilePathName(File file); +extern int FileGetRawDesc(File file); +extern int FileGetRawFlags(File file); +extern mode_t FileGetRawMode(File file); + +/* Operations used for sharing named temporary files */ +extern File PathNameCreateTemporaryFile(const char *path, bool error_on_failure); +extern File PathNameOpenTemporaryFile(const char *path, int mode); +extern bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure); +extern void PathNameCreateTemporaryDir(const char *basedir, const char *directory); +extern void PathNameDeleteTemporaryDir(const char *dirname); +extern void TempTablespacePath(char *path, Oid tablespace); + +/* Operations that allow use of regular stdio --- USE WITH CAUTION */ +extern FILE *AllocateFile(const char *name, const char *mode); +extern int FreeFile(FILE *file); + +/* Operations that allow use of pipe streams (popen/pclose) */ +extern FILE *OpenPipeStream(const char *command, const char *mode); +extern int ClosePipeStream(FILE *file); + +/* Operations to allow use of the library routines */ +extern DIR *AllocateDir(const char *dirname); +extern struct dirent *ReadDir(DIR *dir, const char *dirname); +extern struct dirent *ReadDirExtended(DIR *dir, const char *dirname, + int elevel); +extern int FreeDir(DIR *dir); + +/* Operations to allow use of a plain kernel FD, with automatic cleanup */ +extern int OpenTransientFile(const char *fileName, int fileFlags); +extern int OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode); +extern int CloseTransientFile(int fd); + +/* If you've really really gotta have a plain kernel FD, use this */ +extern int BasicOpenFile(const char *fileName, int fileFlags); +extern int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode); + +/* Use these for other cases, and also for long-lived BasicOpenFile FDs */ +extern bool AcquireExternalFD(void); +extern void ReserveExternalFD(void); +extern void ReleaseExternalFD(void); + +/* Make a directory with default permissions */ +extern int MakePGDirectory(const char *directoryName); + +/* Miscellaneous support routines */ +extern void InitFileAccess(void); +extern void InitTemporaryFileAccess(void); +extern void set_max_safe_fds(void); +extern void closeAllVfds(void); +extern void SetTempTablespaces(Oid *tableSpaces, int numSpaces); +extern bool TempTablespacesAreSet(void); +extern int GetTempTablespaces(Oid *tableSpaces, int numSpaces); +extern Oid GetNextTempTableSpace(void); +extern void AtEOXact_Files(bool isCommit); +extern void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, + SubTransactionId parentSubid); +extern void RemovePgTempFiles(void); +extern void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, + bool unlink_all); +extern bool looks_like_temp_rel_name(const char *name); + +extern int pg_fsync(int fd); +extern int pg_fsync_no_writethrough(int fd); +extern int pg_fsync_writethrough(int fd); +extern int pg_fdatasync(int fd); +extern void pg_flush_data(int fd, off_t offset, off_t nbytes); +extern int pg_truncate(const char *path, off_t length); +extern void fsync_fname(const char *fname, bool isdir); +extern int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel); +extern int durable_rename(const char *oldfile, const char *newfile, int elevel); +extern int durable_unlink(const char *fname, int elevel); +extern void SyncDataDirectory(void); +extern int data_sync_elevel(int elevel); + +/* Filename components */ +#define PG_TEMP_FILES_DIR "pgsql_tmp" +#define PG_TEMP_FILE_PREFIX "pgsql_tmp" + +#endif /* FD_H */ diff --git a/install/include/postgresql/server/storage/fileset.h b/install/include/postgresql/server/storage/fileset.h new file mode 100644 index 00000000000..9aa6581d296 --- /dev/null +++ b/install/include/postgresql/server/storage/fileset.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------- + * + * fileset.h + * Management of named temporary files. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/fileset.h + * + *------------------------------------------------------------------------- + */ + +#ifndef FILESET_H +#define FILESET_H + +#include "storage/fd.h" + +/* + * A set of temporary files. + */ +typedef struct FileSet +{ + pid_t creator_pid; /* PID of the creating process */ + uint32 number; /* per-PID identifier */ + int ntablespaces; /* number of tablespaces to use */ + Oid tablespaces[8]; /* OIDs of tablespaces to use. Assumes that + * it's rare that there more than temp + * tablespaces. */ +} FileSet; + +extern void FileSetInit(FileSet *fileset); +extern File FileSetCreate(FileSet *fileset, const char *name); +extern File FileSetOpen(FileSet *fileset, const char *name, + int mode); +extern bool FileSetDelete(FileSet *fileset, const char *name, + bool error_on_failure); +extern void FileSetDeleteAll(FileSet *fileset); + +#endif diff --git a/install/include/postgresql/server/storage/freespace.h b/install/include/postgresql/server/storage/freespace.h new file mode 100644 index 00000000000..9e1a85a141c --- /dev/null +++ b/install/include/postgresql/server/storage/freespace.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * freespace.h + * POSTGRES free space map for quickly finding free space in relations + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/freespace.h + * + *------------------------------------------------------------------------- + */ +#ifndef FREESPACE_H_ +#define FREESPACE_H_ + +#include "storage/block.h" +#include "storage/relfilelocator.h" +#include "utils/relcache.h" + +/* prototypes for public functions in freespace.c */ +extern Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk); +extern BlockNumber GetPageWithFreeSpace(Relation rel, Size spaceNeeded); +extern BlockNumber RecordAndGetPageWithFreeSpace(Relation rel, + BlockNumber oldPage, + Size oldSpaceAvail, + Size spaceNeeded); +extern void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, + Size spaceAvail); +extern void XLogRecordPageWithFreeSpace(RelFileLocator rlocator, BlockNumber heapBlk, + Size spaceAvail); + +extern BlockNumber FreeSpaceMapPrepareTruncateRel(Relation rel, + BlockNumber nblocks); +extern void FreeSpaceMapVacuum(Relation rel); +extern void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start, + BlockNumber end); + +#endif /* FREESPACE_H_ */ diff --git a/install/include/postgresql/server/storage/fsm_internals.h b/install/include/postgresql/server/storage/fsm_internals.h new file mode 100644 index 00000000000..9e314c83fa4 --- /dev/null +++ b/install/include/postgresql/server/storage/fsm_internals.h @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------- + * + * fsm_internals.h + * internal functions for free space map + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/fsm_internals.h + * + *------------------------------------------------------------------------- + */ +#ifndef FSM_INTERNALS_H +#define FSM_INTERNALS_H + +#include "storage/buf.h" +#include "storage/bufpage.h" + +/* + * Structure of a FSM page. See src/backend/storage/freespace/README for + * details. + */ +typedef struct +{ + /* + * fsm_search_avail() tries to spread the load of multiple backends by + * returning different pages to different backends in a round-robin + * fashion. fp_next_slot points to the next slot to be returned (assuming + * there's enough space on it for the request). It's defined as an int, + * because it's updated without an exclusive lock. uint16 would be more + * appropriate, but int is more likely to be atomically + * fetchable/storable. + */ + int fp_next_slot; + + /* + * fp_nodes contains the binary tree, stored in array. The first + * NonLeafNodesPerPage elements are upper nodes, and the following + * LeafNodesPerPage elements are leaf nodes. Unused nodes are zero. + */ + uint8 fp_nodes[FLEXIBLE_ARRAY_MEMBER]; +} FSMPageData; + +typedef FSMPageData *FSMPage; + +/* + * Number of non-leaf and leaf nodes, and nodes in total, on an FSM page. + * These definitions are internal to fsmpage.c. + */ +#define NodesPerPage (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - \ + offsetof(FSMPageData, fp_nodes)) + +#define NonLeafNodesPerPage (BLCKSZ / 2 - 1) +#define LeafNodesPerPage (NodesPerPage - NonLeafNodesPerPage) + +/* + * Number of FSM "slots" on a FSM page. This is what should be used + * outside fsmpage.c. + */ +#define SlotsPerFSMPage LeafNodesPerPage + +/* Prototypes for functions in fsmpage.c */ +extern int fsm_search_avail(Buffer buf, uint8 minvalue, bool advancenext, + bool exclusive_lock_held); +extern uint8 fsm_get_avail(Page page, int slot); +extern uint8 fsm_get_max_avail(Page page); +extern bool fsm_set_avail(Page page, int slot, uint8 value); +extern bool fsm_truncate_avail(Page page, int nslots); +extern bool fsm_rebuild_page(Page page); + +#endif /* FSM_INTERNALS_H */ diff --git a/install/include/postgresql/server/storage/indexfsm.h b/install/include/postgresql/server/storage/indexfsm.h new file mode 100644 index 00000000000..aed77a7a9f0 --- /dev/null +++ b/install/include/postgresql/server/storage/indexfsm.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * indexfsm.h + * POSTGRES free space map for quickly finding an unused page in index + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/indexfsm.h + * + *------------------------------------------------------------------------- + */ +#ifndef INDEXFSM_H_ +#define INDEXFSM_H_ + +#include "storage/block.h" +#include "utils/relcache.h" + +extern BlockNumber GetFreeIndexPage(Relation rel); +extern void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock); +extern void RecordUsedIndexPage(Relation rel, BlockNumber usedBlock); + +extern void IndexFreeSpaceMapVacuum(Relation rel); + +#endif /* INDEXFSM_H_ */ diff --git a/install/include/postgresql/server/storage/ipc.h b/install/include/postgresql/server/storage/ipc.h new file mode 100644 index 00000000000..888c08b3067 --- /dev/null +++ b/install/include/postgresql/server/storage/ipc.h @@ -0,0 +1,84 @@ +/*------------------------------------------------------------------------- + * + * ipc.h + * POSTGRES inter-process communication definitions. + * + * This file is misnamed, as it no longer has much of anything directly + * to do with IPC. The functionality here is concerned with managing + * exit-time cleanup for either a postmaster or a backend. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/ipc.h + * + *------------------------------------------------------------------------- + */ +#ifndef IPC_H +#define IPC_H + +typedef void (*pg_on_exit_callback) (int code, Datum arg); +typedef void (*shmem_startup_hook_type) (void); + +/*---------- + * API for handling cleanup that must occur during either ereport(ERROR) + * or ereport(FATAL) exits from a block of code. (Typical examples are + * undoing transient changes to shared-memory state.) + * + * PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg); + * { + * ... code that might throw ereport(ERROR) or ereport(FATAL) ... + * } + * PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg); + * + * where the cleanup code is in a function declared per pg_on_exit_callback. + * The Datum value "arg" can carry any information the cleanup function + * needs. + * + * This construct ensures that cleanup_function() will be called during + * either ERROR or FATAL exits. It will not be called on successful + * exit from the controlled code. (If you want it to happen then too, + * call the function yourself from just after the construct.) + * + * Note: the macro arguments are multiply evaluated, so avoid side-effects. + *---------- + */ +#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg) \ + do { \ + before_shmem_exit(cleanup_function, arg); \ + PG_TRY() + +#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg) \ + cancel_before_shmem_exit(cleanup_function, arg); \ + PG_CATCH(); \ + { \ + cancel_before_shmem_exit(cleanup_function, arg); \ + cleanup_function (0, arg); \ + PG_RE_THROW(); \ + } \ + PG_END_TRY(); \ + } while (0) + + +/* ipc.c */ +extern PGDLLIMPORT bool proc_exit_inprogress; +extern PGDLLIMPORT bool shmem_exit_inprogress; + +extern void proc_exit(int code) pg_attribute_noreturn(); +extern void shmem_exit(int code); +extern void on_proc_exit(pg_on_exit_callback function, Datum arg); +extern void on_shmem_exit(pg_on_exit_callback function, Datum arg); +extern void before_shmem_exit(pg_on_exit_callback function, Datum arg); +extern void cancel_before_shmem_exit(pg_on_exit_callback function, Datum arg); +extern void on_exit_reset(void); +extern void check_on_shmem_exit_lists_are_empty(void); + +/* ipci.c */ +extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook; + +extern Size CalculateShmemSize(int *num_semaphores); +extern void CreateSharedMemoryAndSemaphores(void); +extern void InitializeShmemGUCs(void); + +#endif /* IPC_H */ diff --git a/install/include/postgresql/server/storage/item.h b/install/include/postgresql/server/storage/item.h new file mode 100644 index 00000000000..56d59a70cdf --- /dev/null +++ b/install/include/postgresql/server/storage/item.h @@ -0,0 +1,19 @@ +/*------------------------------------------------------------------------- + * + * item.h + * POSTGRES disk item definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/item.h + * + *------------------------------------------------------------------------- + */ +#ifndef ITEM_H +#define ITEM_H + +typedef Pointer Item; + +#endif /* ITEM_H */ diff --git a/install/include/postgresql/server/storage/itemid.h b/install/include/postgresql/server/storage/itemid.h new file mode 100644 index 00000000000..e5cfb8c3ccb --- /dev/null +++ b/install/include/postgresql/server/storage/itemid.h @@ -0,0 +1,184 @@ +/*------------------------------------------------------------------------- + * + * itemid.h + * Standard POSTGRES buffer page item identifier/line pointer definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/itemid.h + * + *------------------------------------------------------------------------- + */ +#ifndef ITEMID_H +#define ITEMID_H + +/* + * A line pointer on a buffer page. See buffer page definitions and comments + * for an explanation of how line pointers are used. + * + * In some cases a line pointer is "in use" but does not have any associated + * storage on the page. By convention, lp_len == 0 in every line pointer + * that does not have storage, independently of its lp_flags state. + */ +typedef struct ItemIdData +{ + unsigned lp_off:15, /* offset to tuple (from start of page) */ + lp_flags:2, /* state of line pointer, see below */ + lp_len:15; /* byte length of tuple */ +} ItemIdData; + +typedef ItemIdData *ItemId; + +/* + * lp_flags has these possible states. An UNUSED line pointer is available + * for immediate re-use, the other states are not. + */ +#define LP_UNUSED 0 /* unused (should always have lp_len=0) */ +#define LP_NORMAL 1 /* used (should always have lp_len>0) */ +#define LP_REDIRECT 2 /* HOT redirect (should have lp_len=0) */ +#define LP_DEAD 3 /* dead, may or may not have storage */ + +/* + * Item offsets and lengths are represented by these types when + * they're not actually stored in an ItemIdData. + */ +typedef uint16 ItemOffset; +typedef uint16 ItemLength; + + +/* ---------------- + * support macros + * ---------------- + */ + +/* + * ItemIdGetLength + */ +#define ItemIdGetLength(itemId) \ + ((itemId)->lp_len) + +/* + * ItemIdGetOffset + */ +#define ItemIdGetOffset(itemId) \ + ((itemId)->lp_off) + +/* + * ItemIdGetFlags + */ +#define ItemIdGetFlags(itemId) \ + ((itemId)->lp_flags) + +/* + * ItemIdGetRedirect + * In a REDIRECT pointer, lp_off holds offset number for next line pointer + */ +#define ItemIdGetRedirect(itemId) \ + ((itemId)->lp_off) + +/* + * ItemIdIsValid + * True iff item identifier is valid. + * This is a pretty weak test, probably useful only in Asserts. + */ +#define ItemIdIsValid(itemId) PointerIsValid(itemId) + +/* + * ItemIdIsUsed + * True iff item identifier is in use. + */ +#define ItemIdIsUsed(itemId) \ + ((itemId)->lp_flags != LP_UNUSED) + +/* + * ItemIdIsNormal + * True iff item identifier is in state NORMAL. + */ +#define ItemIdIsNormal(itemId) \ + ((itemId)->lp_flags == LP_NORMAL) + +/* + * ItemIdIsRedirected + * True iff item identifier is in state REDIRECT. + */ +#define ItemIdIsRedirected(itemId) \ + ((itemId)->lp_flags == LP_REDIRECT) + +/* + * ItemIdIsDead + * True iff item identifier is in state DEAD. + */ +#define ItemIdIsDead(itemId) \ + ((itemId)->lp_flags == LP_DEAD) + +/* + * ItemIdHasStorage + * True iff item identifier has associated storage. + */ +#define ItemIdHasStorage(itemId) \ + ((itemId)->lp_len != 0) + +/* + * ItemIdSetUnused + * Set the item identifier to be UNUSED, with no storage. + * Beware of multiple evaluations of itemId! + */ +#define ItemIdSetUnused(itemId) \ +( \ + (itemId)->lp_flags = LP_UNUSED, \ + (itemId)->lp_off = 0, \ + (itemId)->lp_len = 0 \ +) + +/* + * ItemIdSetNormal + * Set the item identifier to be NORMAL, with the specified storage. + * Beware of multiple evaluations of itemId! + */ +#define ItemIdSetNormal(itemId, off, len) \ +( \ + (itemId)->lp_flags = LP_NORMAL, \ + (itemId)->lp_off = (off), \ + (itemId)->lp_len = (len) \ +) + +/* + * ItemIdSetRedirect + * Set the item identifier to be REDIRECT, with the specified link. + * Beware of multiple evaluations of itemId! + */ +#define ItemIdSetRedirect(itemId, link) \ +( \ + (itemId)->lp_flags = LP_REDIRECT, \ + (itemId)->lp_off = (link), \ + (itemId)->lp_len = 0 \ +) + +/* + * ItemIdSetDead + * Set the item identifier to be DEAD, with no storage. + * Beware of multiple evaluations of itemId! + */ +#define ItemIdSetDead(itemId) \ +( \ + (itemId)->lp_flags = LP_DEAD, \ + (itemId)->lp_off = 0, \ + (itemId)->lp_len = 0 \ +) + +/* + * ItemIdMarkDead + * Set the item identifier to be DEAD, keeping its existing storage. + * + * Note: in indexes, this is used as if it were a hint-bit mechanism; + * we trust that multiple processors can do this in parallel and get + * the same result. + */ +#define ItemIdMarkDead(itemId) \ +( \ + (itemId)->lp_flags = LP_DEAD \ +) + +#endif /* ITEMID_H */ diff --git a/install/include/postgresql/server/storage/itemptr.h b/install/include/postgresql/server/storage/itemptr.h new file mode 100644 index 00000000000..fafefa14cd8 --- /dev/null +++ b/install/include/postgresql/server/storage/itemptr.h @@ -0,0 +1,245 @@ +/*------------------------------------------------------------------------- + * + * itemptr.h + * POSTGRES disk item pointer definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/itemptr.h + * + *------------------------------------------------------------------------- + */ +#ifndef ITEMPTR_H +#define ITEMPTR_H + +#include "storage/block.h" +#include "storage/off.h" + +/* + * ItemPointer: + * + * This is a pointer to an item within a disk page of a known file + * (for example, a cross-link from an index to its parent table). + * ip_blkid tells us which block, ip_posid tells us which entry in + * the linp (ItemIdData) array we want. + * + * Note: because there is an item pointer in each tuple header and index + * tuple header on disk, it's very important not to waste space with + * structure padding bytes. The struct is designed to be six bytes long + * (it contains three int16 fields) but a few compilers will pad it to + * eight bytes unless coerced. We apply appropriate persuasion where + * possible. If your compiler can't be made to play along, you'll waste + * lots of space. + */ +typedef struct ItemPointerData +{ + BlockIdData ip_blkid; + OffsetNumber ip_posid; +} + +/* If compiler understands packed and aligned pragmas, use those */ +#if defined(pg_attribute_packed) && defined(pg_attribute_aligned) + pg_attribute_packed() + pg_attribute_aligned(2) +#endif +ItemPointerData; + +typedef ItemPointerData *ItemPointer; + +/* ---------------- + * special values used in heap tuples (t_ctid) + * ---------------- + */ + +/* + * If a heap tuple holds a speculative insertion token rather than a real + * TID, ip_posid is set to SpecTokenOffsetNumber, and the token is stored in + * ip_blkid. SpecTokenOffsetNumber must be higher than MaxOffsetNumber, so + * that it can be distinguished from a valid offset number in a regular item + * pointer. + */ +#define SpecTokenOffsetNumber 0xfffe + +/* + * When a tuple is moved to a different partition by UPDATE, the t_ctid of + * the old tuple version is set to this magic value. + */ +#define MovedPartitionsOffsetNumber 0xfffd +#define MovedPartitionsBlockNumber InvalidBlockNumber + + +/* ---------------- + * support functions + * ---------------- + */ + +/* + * ItemPointerIsValid + * True iff the disk item pointer is not NULL. + */ +static inline bool +ItemPointerIsValid(const ItemPointerData *pointer) +{ + return PointerIsValid(pointer) && pointer->ip_posid != 0; +} + +/* + * ItemPointerGetBlockNumberNoCheck + * Returns the block number of a disk item pointer. + */ +static inline BlockNumber +ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer) +{ + return BlockIdGetBlockNumber(&pointer->ip_blkid); +} + +/* + * ItemPointerGetBlockNumber + * As above, but verifies that the item pointer looks valid. + */ +static inline BlockNumber +ItemPointerGetBlockNumber(const ItemPointerData *pointer) +{ + Assert(ItemPointerIsValid(pointer)); + return ItemPointerGetBlockNumberNoCheck(pointer); +} + +/* + * ItemPointerGetOffsetNumberNoCheck + * Returns the offset number of a disk item pointer. + */ +static inline OffsetNumber +ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer) +{ + return pointer->ip_posid; +} + +/* + * ItemPointerGetOffsetNumber + * As above, but verifies that the item pointer looks valid. + */ +static inline OffsetNumber +ItemPointerGetOffsetNumber(const ItemPointerData *pointer) +{ + Assert(ItemPointerIsValid(pointer)); + return ItemPointerGetOffsetNumberNoCheck(pointer); +} + +/* + * ItemPointerSet + * Sets a disk item pointer to the specified block and offset. + */ +static inline void +ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum) +{ + Assert(PointerIsValid(pointer)); + BlockIdSet(&pointer->ip_blkid, blockNumber); + pointer->ip_posid = offNum; +} + +/* + * ItemPointerSetBlockNumber + * Sets a disk item pointer to the specified block. + */ +static inline void +ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber) +{ + Assert(PointerIsValid(pointer)); + BlockIdSet(&pointer->ip_blkid, blockNumber); +} + +/* + * ItemPointerSetOffsetNumber + * Sets a disk item pointer to the specified offset. + */ +static inline void +ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber) +{ + Assert(PointerIsValid(pointer)); + pointer->ip_posid = offsetNumber; +} + +/* + * ItemPointerCopy + * Copies the contents of one disk item pointer to another. + * + * Should there ever be padding in an ItemPointer this would need to be handled + * differently as it's used as hash key. + */ +static inline void +ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer) +{ + Assert(PointerIsValid(toPointer)); + Assert(PointerIsValid(fromPointer)); + *toPointer = *fromPointer; +} + +/* + * ItemPointerSetInvalid + * Sets a disk item pointer to be invalid. + */ +static inline void +ItemPointerSetInvalid(ItemPointerData *pointer) +{ + Assert(PointerIsValid(pointer)); + BlockIdSet(&pointer->ip_blkid, InvalidBlockNumber); + pointer->ip_posid = InvalidOffsetNumber; +} + +/* + * ItemPointerIndicatesMovedPartitions + * True iff the block number indicates the tuple has moved to another + * partition. + */ +static inline bool +ItemPointerIndicatesMovedPartitions(const ItemPointerData *pointer) +{ + return + ItemPointerGetOffsetNumber(pointer) == MovedPartitionsOffsetNumber && + ItemPointerGetBlockNumberNoCheck(pointer) == MovedPartitionsBlockNumber; +} + +/* + * ItemPointerSetMovedPartitions + * Indicate that the item referenced by the itempointer has moved into a + * different partition. + */ +static inline void +ItemPointerSetMovedPartitions(ItemPointerData *pointer) +{ + ItemPointerSet(pointer, MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber); +} + +/* ---------------- + * externs + * ---------------- + */ + +extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2); +extern int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2); +extern void ItemPointerInc(ItemPointer pointer); +extern void ItemPointerDec(ItemPointer pointer); + +/* ---------------- + * Datum conversion functions + * ---------------- + */ + +static inline ItemPointer +DatumGetItemPointer(Datum X) +{ + return (ItemPointer) DatumGetPointer(X); +} + +static inline Datum +ItemPointerGetDatum(const ItemPointerData *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_ITEMPOINTER(n) DatumGetItemPointer(PG_GETARG_DATUM(n)) +#define PG_RETURN_ITEMPOINTER(x) return ItemPointerGetDatum(x) + +#endif /* ITEMPTR_H */ diff --git a/install/include/postgresql/server/storage/large_object.h b/install/include/postgresql/server/storage/large_object.h new file mode 100644 index 00000000000..db521f23eb8 --- /dev/null +++ b/install/include/postgresql/server/storage/large_object.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------- + * + * large_object.h + * Declarations for PostgreSQL large objects. POSTGRES 4.2 supported + * zillions of large objects (internal, external, jaquith, inversion). + * Now we only support inversion. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/large_object.h + * + *------------------------------------------------------------------------- + */ +#ifndef LARGE_OBJECT_H +#define LARGE_OBJECT_H + +#include "utils/snapshot.h" + + +/*---------- + * Data about a currently-open large object. + * + * id is the logical OID of the large object + * snapshot is the snapshot to use for read/write operations + * subid is the subtransaction that opened the desc (or currently owns it) + * offset is the current seek offset within the LO + * flags contains some flag bits + * + * NOTE: as of v11, permission checks are made when the large object is + * opened; therefore IFS_RDLOCK/IFS_WRLOCK indicate that read or write mode + * has been requested *and* the corresponding permission has been checked. + * + * NOTE: before 7.1, we also had to store references to the separate table + * and index of a specific large object. Now they all live in pg_largeobject + * and are accessed via a common relation descriptor. + *---------- + */ +typedef struct LargeObjectDesc +{ + Oid id; /* LO's identifier */ + Snapshot snapshot; /* snapshot to use */ + SubTransactionId subid; /* owning subtransaction ID */ + uint64 offset; /* current seek pointer */ + int flags; /* see flag bits below */ + +/* bits in flags: */ +#define IFS_RDLOCK (1 << 0) /* LO was opened for reading */ +#define IFS_WRLOCK (1 << 1) /* LO was opened for writing */ + +} LargeObjectDesc; + + +/* + * Each "page" (tuple) of a large object can hold this much data + * + * We could set this as high as BLCKSZ less some overhead, but it seems + * better to make it a smaller value, so that not as much space is used + * up when a page-tuple is updated. Note that the value is deliberately + * chosen large enough to trigger the tuple toaster, so that we will + * attempt to compress page tuples in-line. (But they won't be moved off + * unless the user creates a toast-table for pg_largeobject...) + * + * Also, it seems to be a smart move to make the page size be a power of 2, + * since clients will often be written to send data in power-of-2 blocks. + * This avoids unnecessary tuple updates caused by partial-page writes. + * + * NB: Changing LOBLKSIZE requires an initdb. + */ +#define LOBLKSIZE (BLCKSZ / 4) + +/* + * Maximum length in bytes for a large object. To make this larger, we'd + * have to widen pg_largeobject.pageno as well as various internal variables. + */ +#define MAX_LARGE_OBJECT_SIZE ((int64) INT_MAX * LOBLKSIZE) + + +/* + * GUC: backwards-compatibility flag to suppress LO permission checks + */ +extern PGDLLIMPORT bool lo_compat_privileges; + +/* + * Function definitions... + */ + +/* inversion stuff in inv_api.c */ +extern void close_lo_relation(bool isCommit); +extern Oid inv_create(Oid lobjId); +extern LargeObjectDesc *inv_open(Oid lobjId, int flags, MemoryContext mcxt); +extern void inv_close(LargeObjectDesc *obj_desc); +extern int inv_drop(Oid lobjId); +extern int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence); +extern int64 inv_tell(LargeObjectDesc *obj_desc); +extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes); +extern int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes); +extern void inv_truncate(LargeObjectDesc *obj_desc, int64 len); + +#endif /* LARGE_OBJECT_H */ diff --git a/install/include/postgresql/server/storage/latch.h b/install/include/postgresql/server/storage/latch.h new file mode 100644 index 00000000000..99cc47874ac --- /dev/null +++ b/install/include/postgresql/server/storage/latch.h @@ -0,0 +1,194 @@ +/*------------------------------------------------------------------------- + * + * latch.h + * Routines for interprocess latches + * + * A latch is a boolean variable, with operations that let processes sleep + * until it is set. A latch can be set from another process, or a signal + * handler within the same process. + * + * The latch interface is a reliable replacement for the common pattern of + * using pg_usleep() or select() to wait until a signal arrives, where the + * signal handler sets a flag variable. Because on some platforms an + * incoming signal doesn't interrupt sleep, and even on platforms where it + * does there is a race condition if the signal arrives just before + * entering the sleep, the common pattern must periodically wake up and + * poll the flag variable. The pselect() system call was invented to solve + * this problem, but it is not portable enough. Latches are designed to + * overcome these limitations, allowing you to sleep without polling and + * ensuring quick response to signals from other processes. + * + * There are two kinds of latches: local and shared. A local latch is + * initialized by InitLatch, and can only be set from the same process. + * A local latch can be used to wait for a signal to arrive, by calling + * SetLatch in the signal handler. A shared latch resides in shared memory, + * and must be initialized at postmaster startup by InitSharedLatch. Before + * a shared latch can be waited on, it must be associated with a process + * with OwnLatch. Only the process owning the latch can wait on it, but any + * process can set it. + * + * There are three basic operations on a latch: + * + * SetLatch - Sets the latch + * ResetLatch - Clears the latch, allowing it to be set again + * WaitLatch - Waits for the latch to become set + * + * WaitLatch includes a provision for timeouts (which should be avoided + * when possible, as they incur extra overhead) and a provision for + * postmaster child processes to wake up immediately on postmaster death. + * See latch.c for detailed specifications for the exported functions. + * + * The correct pattern to wait for event(s) is: + * + * for (;;) + * { + * ResetLatch(); + * if (work to do) + * Do Stuff(); + * WaitLatch(); + * } + * + * It's important to reset the latch *before* checking if there's work to + * do. Otherwise, if someone sets the latch between the check and the + * ResetLatch call, you will miss it and Wait will incorrectly block. + * + * Another valid coding pattern looks like: + * + * for (;;) + * { + * if (work to do) + * Do Stuff(); // in particular, exit loop if some condition satisfied + * WaitLatch(); + * ResetLatch(); + * } + * + * This is useful to reduce latch traffic if it's expected that the loop's + * termination condition will often be satisfied in the first iteration; + * the cost is an extra loop iteration before blocking when it is not. + * What must be avoided is placing any checks for asynchronous events after + * WaitLatch and before ResetLatch, as that creates a race condition. + * + * To wake up the waiter, you must first set a global flag or something + * else that the wait loop tests in the "if (work to do)" part, and call + * SetLatch *after* that. SetLatch is designed to return quickly if the + * latch is already set. + * + * On some platforms, signals will not interrupt the latch wait primitive + * by themselves. Therefore, it is critical that any signal handler that + * is meant to terminate a WaitLatch wait calls SetLatch. + * + * Note that use of the process latch (PGPROC.procLatch) is generally better + * than an ad-hoc shared latch for signaling auxiliary processes. This is + * because generic signal handlers will call SetLatch on the process latch + * only, so using any latch other than the process latch effectively precludes + * use of any generic handler. + * + * + * WaitEventSets allow to wait for latches being set and additional events - + * postmaster dying and socket readiness of several sockets currently - at the + * same time. On many platforms using a long lived event set is more + * efficient than using WaitLatch or WaitLatchOrSocket. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/latch.h + * + *------------------------------------------------------------------------- + */ +#ifndef LATCH_H +#define LATCH_H + +#include + +/* + * Latch structure should be treated as opaque and only accessed through + * the public functions. It is defined here to allow embedding Latches as + * part of bigger structs. + */ +typedef struct Latch +{ + sig_atomic_t is_set; + sig_atomic_t maybe_sleeping; + bool is_shared; + int owner_pid; +#ifdef WIN32 + HANDLE event; +#endif +} Latch; + +/* + * Bitmasks for events that may wake-up WaitLatch(), WaitLatchOrSocket(), or + * WaitEventSetWait(). + */ +#define WL_LATCH_SET (1 << 0) +#define WL_SOCKET_READABLE (1 << 1) +#define WL_SOCKET_WRITEABLE (1 << 2) +#define WL_TIMEOUT (1 << 3) /* not for WaitEventSetWait() */ +#define WL_POSTMASTER_DEATH (1 << 4) +#define WL_EXIT_ON_PM_DEATH (1 << 5) +#ifdef WIN32 +#define WL_SOCKET_CONNECTED (1 << 6) +#else +/* avoid having to deal with case on platforms not requiring it */ +#define WL_SOCKET_CONNECTED WL_SOCKET_WRITEABLE +#endif +#define WL_SOCKET_CLOSED (1 << 7) +#ifdef WIN32 +#define WL_SOCKET_ACCEPT (1 << 8) +#else +/* avoid having to deal with case on platforms not requiring it */ +#define WL_SOCKET_ACCEPT WL_SOCKET_READABLE +#endif +#define WL_SOCKET_MASK (WL_SOCKET_READABLE | \ + WL_SOCKET_WRITEABLE | \ + WL_SOCKET_CONNECTED | \ + WL_SOCKET_ACCEPT | \ + WL_SOCKET_CLOSED) + +typedef struct WaitEvent +{ + int pos; /* position in the event data structure */ + uint32 events; /* triggered events */ + pgsocket fd; /* socket fd associated with event */ + void *user_data; /* pointer provided in AddWaitEventToSet */ +#ifdef WIN32 + bool reset; /* Is reset of the event required? */ +#endif +} WaitEvent; + +/* forward declaration to avoid exposing latch.c implementation details */ +typedef struct WaitEventSet WaitEventSet; + +/* + * prototypes for functions in latch.c + */ +extern void InitializeLatchSupport(void); +extern void InitLatch(Latch *latch); +extern void InitSharedLatch(Latch *latch); +extern void OwnLatch(Latch *latch); +extern void DisownLatch(Latch *latch); +extern void SetLatch(Latch *latch); +extern void ResetLatch(Latch *latch); +extern void ShutdownLatchSupport(void); + +extern WaitEventSet *CreateWaitEventSet(MemoryContext context, int nevents); +extern void FreeWaitEventSet(WaitEventSet *set); +extern void FreeWaitEventSetAfterFork(WaitEventSet *set); +extern int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, + Latch *latch, void *user_data); +extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch); + +extern int WaitEventSetWait(WaitEventSet *set, long timeout, + WaitEvent *occurred_events, int nevents, + uint32 wait_event_info); +extern int WaitLatch(Latch *latch, int wakeEvents, long timeout, + uint32 wait_event_info); +extern int WaitLatchOrSocket(Latch *latch, int wakeEvents, + pgsocket sock, long timeout, uint32 wait_event_info); +extern void InitializeLatchWaitSet(void); +extern int GetNumRegisteredWaitEvents(WaitEventSet *set); +extern bool WaitEventSetCanReportClosed(void); + +#endif /* LATCH_H */ diff --git a/install/include/postgresql/server/storage/lmgr.h b/install/include/postgresql/server/storage/lmgr.h new file mode 100644 index 00000000000..555d7fdb347 --- /dev/null +++ b/install/include/postgresql/server/storage/lmgr.h @@ -0,0 +1,124 @@ +/*------------------------------------------------------------------------- + * + * lmgr.h + * POSTGRES lock manager definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/lmgr.h + * + *------------------------------------------------------------------------- + */ +#ifndef LMGR_H +#define LMGR_H + +#include "lib/stringinfo.h" +#include "storage/itemptr.h" +#include "storage/lock.h" +#include "utils/rel.h" + + +/* XactLockTableWait operations */ +typedef enum XLTW_Oper +{ + XLTW_None, + XLTW_Update, + XLTW_Delete, + XLTW_Lock, + XLTW_LockUpdated, + XLTW_InsertIndex, + XLTW_InsertIndexUnique, + XLTW_FetchUpdated, + XLTW_RecheckExclusionConstr +} XLTW_Oper; + +extern void RelationInitLockInfo(Relation relation); + +/* Lock a relation */ +extern void LockRelationOid(Oid relid, LOCKMODE lockmode); +extern void LockRelationId(LockRelId *relid, LOCKMODE lockmode); +extern bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode); +extern void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode); +extern void UnlockRelationOid(Oid relid, LOCKMODE lockmode); + +extern void LockRelation(Relation relation, LOCKMODE lockmode); +extern bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode); +extern void UnlockRelation(Relation relation, LOCKMODE lockmode); +extern bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, + bool orstronger); +extern bool CheckRelationOidLockedByMe(Oid relid, LOCKMODE lockmode, + bool orstronger); +extern bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode); + +extern void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode); +extern void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode); + +/* Lock a relation for extension */ +extern void LockRelationForExtension(Relation relation, LOCKMODE lockmode); +extern void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode); +extern bool ConditionalLockRelationForExtension(Relation relation, + LOCKMODE lockmode); +extern int RelationExtensionLockWaiterCount(Relation relation); + +/* Lock to recompute pg_database.datfrozenxid in the current database */ +extern void LockDatabaseFrozenIds(LOCKMODE lockmode); + +/* Lock a page (currently only used within indexes) */ +extern void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode); +extern bool ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode); +extern void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode); + +/* Lock a tuple (see heap_lock_tuple before assuming you understand this) */ +extern void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode); +extern bool ConditionalLockTuple(Relation relation, ItemPointer tid, + LOCKMODE lockmode); +extern void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode); + +/* Lock an XID (used to wait for a transaction to finish) */ +extern void XactLockTableInsert(TransactionId xid); +extern void XactLockTableDelete(TransactionId xid); +extern void XactLockTableWait(TransactionId xid, Relation rel, + ItemPointer ctid, XLTW_Oper oper); +extern bool ConditionalXactLockTableWait(TransactionId xid); + +/* Lock VXIDs, specified by conflicting locktags */ +extern void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress); +extern void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress); + +/* Lock an XID for tuple insertion (used to wait for an insertion to finish) */ +extern uint32 SpeculativeInsertionLockAcquire(TransactionId xid); +extern void SpeculativeInsertionLockRelease(TransactionId xid); +extern void SpeculativeInsertionWait(TransactionId xid, uint32 token); + +/* Lock a general object (other than a relation) of the current database */ +extern void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, + LOCKMODE lockmode); +extern bool ConditionalLockDatabaseObject(Oid classid, Oid objid, + uint16 objsubid, LOCKMODE lockmode); +extern void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, + LOCKMODE lockmode); + +/* Lock a shared-across-databases object (other than a relation) */ +extern void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, + LOCKMODE lockmode); +extern void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, + LOCKMODE lockmode); + +extern void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, + LOCKMODE lockmode); +extern void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, + LOCKMODE lockmode); + +extern void LockApplyTransactionForSession(Oid suboid, TransactionId xid, uint16 objid, + LOCKMODE lockmode); +extern void UnlockApplyTransactionForSession(Oid suboid, TransactionId xid, uint16 objid, + LOCKMODE lockmode); + +/* Describe a locktag for error messages */ +extern void DescribeLockTag(StringInfo buf, const LOCKTAG *tag); + +extern const char *GetLockNameFromTagType(uint16 locktag_type); + +#endif /* LMGR_H */ diff --git a/install/include/postgresql/server/storage/lock.h b/install/include/postgresql/server/storage/lock.h new file mode 100644 index 00000000000..14fa509188a --- /dev/null +++ b/install/include/postgresql/server/storage/lock.h @@ -0,0 +1,654 @@ +/*------------------------------------------------------------------------- + * + * lock.h + * POSTGRES low-level lock mechanism + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/lock.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOCK_H_ +#define LOCK_H_ + +#ifdef FRONTEND +#error "lock.h may not be included from frontend code" +#endif + +#include "lib/ilist.h" +#include "storage/backendid.h" +#include "storage/lockdefs.h" +#include "storage/lwlock.h" +#include "storage/shmem.h" +#include "utils/timestamp.h" + +/* struct PGPROC is declared in proc.h, but must forward-reference it */ +typedef struct PGPROC PGPROC; + +/* GUC variables */ +extern PGDLLIMPORT int max_locks_per_xact; + +#ifdef LOCK_DEBUG +extern PGDLLIMPORT int Trace_lock_oidmin; +extern PGDLLIMPORT bool Trace_locks; +extern PGDLLIMPORT bool Trace_userlocks; +extern PGDLLIMPORT int Trace_lock_table; +extern PGDLLIMPORT bool Debug_deadlocks; +#endif /* LOCK_DEBUG */ + + +/* + * Top-level transactions are identified by VirtualTransactionIDs comprising + * PGPROC fields backendId and lxid. For recovered prepared transactions, the + * LocalTransactionId is an ordinary XID; LOCKTAG_VIRTUALTRANSACTION never + * refers to that kind. These are guaranteed unique over the short term, but + * will be reused after a database restart or XID wraparound; hence they + * should never be stored on disk. + * + * Note that struct VirtualTransactionId can not be assumed to be atomically + * assignable as a whole. However, type LocalTransactionId is assumed to + * be atomically assignable, and the backend ID doesn't change often enough + * to be a problem, so we can fetch or assign the two fields separately. + * We deliberately refrain from using the struct within PGPROC, to prevent + * coding errors from trying to use struct assignment with it; instead use + * GET_VXID_FROM_PGPROC(). + */ +typedef struct +{ + BackendId backendId; /* backendId from PGPROC */ + LocalTransactionId localTransactionId; /* lxid from PGPROC */ +} VirtualTransactionId; + +#define InvalidLocalTransactionId 0 +#define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId) +#define VirtualTransactionIdIsValid(vxid) \ + (LocalTransactionIdIsValid((vxid).localTransactionId)) +#define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \ + ((vxid).backendId == InvalidBackendId) +#define VirtualTransactionIdEquals(vxid1, vxid2) \ + ((vxid1).backendId == (vxid2).backendId && \ + (vxid1).localTransactionId == (vxid2).localTransactionId) +#define SetInvalidVirtualTransactionId(vxid) \ + ((vxid).backendId = InvalidBackendId, \ + (vxid).localTransactionId = InvalidLocalTransactionId) +#define GET_VXID_FROM_PGPROC(vxid, proc) \ + ((vxid).backendId = (proc).backendId, \ + (vxid).localTransactionId = (proc).lxid) + +/* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */ +#define MAX_LOCKMODES 10 + +#define LOCKBIT_ON(lockmode) (1 << (lockmode)) +#define LOCKBIT_OFF(lockmode) (~(1 << (lockmode))) + + +/* + * This data structure defines the locking semantics associated with a + * "lock method". The semantics specify the meaning of each lock mode + * (by defining which lock modes it conflicts with). + * All of this data is constant and is kept in const tables. + * + * numLockModes -- number of lock modes (READ,WRITE,etc) that + * are defined in this lock method. Must be less than MAX_LOCKMODES. + * + * conflictTab -- this is an array of bitmasks showing lock + * mode conflicts. conflictTab[i] is a mask with the j-th bit + * turned on if lock modes i and j conflict. Lock modes are + * numbered 1..numLockModes; conflictTab[0] is unused. + * + * lockModeNames -- ID strings for debug printouts. + * + * trace_flag -- pointer to GUC trace flag for this lock method. (The + * GUC variable is not constant, but we use "const" here to denote that + * it can't be changed through this reference.) + */ +typedef struct LockMethodData +{ + int numLockModes; + const LOCKMASK *conflictTab; + const char *const *lockModeNames; + const bool *trace_flag; +} LockMethodData; + +typedef const LockMethodData *LockMethod; + +/* + * Lock methods are identified by LOCKMETHODID. (Despite the declaration as + * uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.) + */ +typedef uint16 LOCKMETHODID; + +/* These identify the known lock methods */ +#define DEFAULT_LOCKMETHOD 1 +#define USER_LOCKMETHOD 2 + +/* + * LOCKTAG is the key information needed to look up a LOCK item in the + * lock hashtable. A LOCKTAG value uniquely identifies a lockable object. + * + * The LockTagType enum defines the different kinds of objects we can lock. + * We can handle up to 256 different LockTagTypes. + */ +typedef enum LockTagType +{ + LOCKTAG_RELATION, /* whole relation */ + LOCKTAG_RELATION_EXTEND, /* the right to extend a relation */ + LOCKTAG_DATABASE_FROZEN_IDS, /* pg_database.datfrozenxid */ + LOCKTAG_PAGE, /* one page of a relation */ + LOCKTAG_TUPLE, /* one physical tuple */ + LOCKTAG_TRANSACTION, /* transaction (for waiting for xact done) */ + LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */ + LOCKTAG_SPECULATIVE_TOKEN, /* speculative insertion Xid and token */ + LOCKTAG_OBJECT, /* non-relation database object */ + LOCKTAG_USERLOCK, /* reserved for old contrib/userlock code */ + LOCKTAG_ADVISORY, /* advisory user locks */ + LOCKTAG_APPLY_TRANSACTION /* transaction being applied on a logical + * replication subscriber */ +} LockTagType; + +#define LOCKTAG_LAST_TYPE LOCKTAG_APPLY_TRANSACTION + +extern PGDLLIMPORT const char *const LockTagTypeNames[]; + +/* + * The LOCKTAG struct is defined with malice aforethought to fit into 16 + * bytes with no padding. Note that this would need adjustment if we were + * to widen Oid, BlockNumber, or TransactionId to more than 32 bits. + * + * We include lockmethodid in the locktag so that a single hash table in + * shared memory can store locks of different lockmethods. + */ +typedef struct LOCKTAG +{ + uint32 locktag_field1; /* a 32-bit ID field */ + uint32 locktag_field2; /* a 32-bit ID field */ + uint32 locktag_field3; /* a 32-bit ID field */ + uint16 locktag_field4; /* a 16-bit ID field */ + uint8 locktag_type; /* see enum LockTagType */ + uint8 locktag_lockmethodid; /* lockmethod indicator */ +} LOCKTAG; + +/* + * These macros define how we map logical IDs of lockable objects into + * the physical fields of LOCKTAG. Use these to set up LOCKTAG values, + * rather than accessing the fields directly. Note multiple eval of target! + */ + +/* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */ +#define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (reloid), \ + (locktag).locktag_field3 = 0, \ + (locktag).locktag_field4 = 0, \ + (locktag).locktag_type = LOCKTAG_RELATION, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* same ID info as RELATION */ +#define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (reloid), \ + (locktag).locktag_field3 = 0, \ + (locktag).locktag_field4 = 0, \ + (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* ID info for frozen IDs is DB OID */ +#define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = 0, \ + (locktag).locktag_field3 = 0, \ + (locktag).locktag_field4 = 0, \ + (locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* ID info for a page is RELATION info + BlockNumber */ +#define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (reloid), \ + (locktag).locktag_field3 = (blocknum), \ + (locktag).locktag_field4 = 0, \ + (locktag).locktag_type = LOCKTAG_PAGE, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* ID info for a tuple is PAGE info + OffsetNumber */ +#define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (reloid), \ + (locktag).locktag_field3 = (blocknum), \ + (locktag).locktag_field4 = (offnum), \ + (locktag).locktag_type = LOCKTAG_TUPLE, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* ID info for a transaction is its TransactionId */ +#define SET_LOCKTAG_TRANSACTION(locktag,xid) \ + ((locktag).locktag_field1 = (xid), \ + (locktag).locktag_field2 = 0, \ + (locktag).locktag_field3 = 0, \ + (locktag).locktag_field4 = 0, \ + (locktag).locktag_type = LOCKTAG_TRANSACTION, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* ID info for a virtual transaction is its VirtualTransactionId */ +#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \ + ((locktag).locktag_field1 = (vxid).backendId, \ + (locktag).locktag_field2 = (vxid).localTransactionId, \ + (locktag).locktag_field3 = 0, \ + (locktag).locktag_field4 = 0, \ + (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* + * ID info for a speculative insert is TRANSACTION info + + * its speculative insert counter. + */ +#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \ + ((locktag).locktag_field1 = (xid), \ + (locktag).locktag_field2 = (token), \ + (locktag).locktag_field3 = 0, \ + (locktag).locktag_field4 = 0, \ + (locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* + * ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID + * + * Note: object ID has same representation as in pg_depend and + * pg_description, but notice that we are constraining SUBID to 16 bits. + * Also, we use DB OID = 0 for shared objects such as tablespaces. + */ +#define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (classoid), \ + (locktag).locktag_field3 = (objoid), \ + (locktag).locktag_field4 = (objsubid), \ + (locktag).locktag_type = LOCKTAG_OBJECT, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +#define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \ + ((locktag).locktag_field1 = (id1), \ + (locktag).locktag_field2 = (id2), \ + (locktag).locktag_field3 = (id3), \ + (locktag).locktag_field4 = (id4), \ + (locktag).locktag_type = LOCKTAG_ADVISORY, \ + (locktag).locktag_lockmethodid = USER_LOCKMETHOD) + +/* + * ID info for a remote transaction on a logical replication subscriber is: DB + * OID + SUBSCRIPTION OID + TRANSACTION ID + OBJID + */ +#define SET_LOCKTAG_APPLY_TRANSACTION(locktag,dboid,suboid,xid,objid) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (suboid), \ + (locktag).locktag_field3 = (xid), \ + (locktag).locktag_field4 = (objid), \ + (locktag).locktag_type = LOCKTAG_APPLY_TRANSACTION, \ + (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) + +/* + * Per-locked-object lock information: + * + * tag -- uniquely identifies the object being locked + * grantMask -- bitmask for all lock types currently granted on this object. + * waitMask -- bitmask for all lock types currently awaited on this object. + * procLocks -- list of PROCLOCK objects for this lock. + * waitProcs -- queue of processes waiting for this lock. + * requested -- count of each lock type currently requested on the lock + * (includes requests already granted!!). + * nRequested -- total requested locks of all types. + * granted -- count of each lock type currently granted on the lock. + * nGranted -- total granted locks of all types. + * + * Note: these counts count 1 for each backend. Internally to a backend, + * there may be multiple grabs on a particular lock, but this is not reflected + * into shared memory. + */ +typedef struct LOCK +{ + /* hash key */ + LOCKTAG tag; /* unique identifier of lockable object */ + + /* data */ + LOCKMASK grantMask; /* bitmask for lock types already granted */ + LOCKMASK waitMask; /* bitmask for lock types awaited */ + dlist_head procLocks; /* list of PROCLOCK objects assoc. with lock */ + dclist_head waitProcs; /* list of PGPROC objects waiting on lock */ + int requested[MAX_LOCKMODES]; /* counts of requested locks */ + int nRequested; /* total of requested[] array */ + int granted[MAX_LOCKMODES]; /* counts of granted locks */ + int nGranted; /* total of granted[] array */ +} LOCK; + +#define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid) +#define LOCK_LOCKTAG(lock) ((LockTagType) (lock).tag.locktag_type) + + +/* + * We may have several different backends holding or awaiting locks + * on the same lockable object. We need to store some per-holder/waiter + * information for each such holder (or would-be holder). This is kept in + * a PROCLOCK struct. + * + * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the + * proclock hashtable. A PROCLOCKTAG value uniquely identifies the combination + * of a lockable object and a holder/waiter for that object. (We can use + * pointers here because the PROCLOCKTAG need only be unique for the lifespan + * of the PROCLOCK, and it will never outlive the lock or the proc.) + * + * Internally to a backend, it is possible for the same lock to be held + * for different purposes: the backend tracks transaction locks separately + * from session locks. However, this is not reflected in the shared-memory + * state: we only track which backend(s) hold the lock. This is OK since a + * backend can never block itself. + * + * The holdMask field shows the already-granted locks represented by this + * proclock. Note that there will be a proclock object, possibly with + * zero holdMask, for any lock that the process is currently waiting on. + * Otherwise, proclock objects whose holdMasks are zero are recycled + * as soon as convenient. + * + * releaseMask is workspace for LockReleaseAll(): it shows the locks due + * to be released during the current call. This must only be examined or + * set by the backend owning the PROCLOCK. + * + * Each PROCLOCK object is linked into lists for both the associated LOCK + * object and the owning PGPROC object. Note that the PROCLOCK is entered + * into these lists as soon as it is created, even if no lock has yet been + * granted. A PGPROC that is waiting for a lock to be granted will also be + * linked into the lock's waitProcs queue. + */ +typedef struct PROCLOCKTAG +{ + /* NB: we assume this struct contains no padding! */ + LOCK *myLock; /* link to per-lockable-object information */ + PGPROC *myProc; /* link to PGPROC of owning backend */ +} PROCLOCKTAG; + +typedef struct PROCLOCK +{ + /* tag */ + PROCLOCKTAG tag; /* unique identifier of proclock object */ + + /* data */ + PGPROC *groupLeader; /* proc's lock group leader, or proc itself */ + LOCKMASK holdMask; /* bitmask for lock types currently held */ + LOCKMASK releaseMask; /* bitmask for lock types to be released */ + dlist_node lockLink; /* list link in LOCK's list of proclocks */ + dlist_node procLink; /* list link in PGPROC's list of proclocks */ +} PROCLOCK; + +#define PROCLOCK_LOCKMETHOD(proclock) \ + LOCK_LOCKMETHOD(*((proclock).tag.myLock)) + +/* + * Each backend also maintains a local hash table with information about each + * lock it is currently interested in. In particular the local table counts + * the number of times that lock has been acquired. This allows multiple + * requests for the same lock to be executed without additional accesses to + * shared memory. We also track the number of lock acquisitions per + * ResourceOwner, so that we can release just those locks belonging to a + * particular ResourceOwner. + * + * When holding a lock taken "normally", the lock and proclock fields always + * point to the associated objects in shared memory. However, if we acquired + * the lock via the fast-path mechanism, the lock and proclock fields are set + * to NULL, since there probably aren't any such objects in shared memory. + * (If the lock later gets promoted to normal representation, we may eventually + * update our locallock's lock/proclock fields after finding the shared + * objects.) + * + * Caution: a locallock object can be left over from a failed lock acquisition + * attempt. In this case its lock/proclock fields are untrustworthy, since + * the shared lock object is neither held nor awaited, and hence is available + * to be reclaimed. If nLocks > 0 then these pointers must either be valid or + * NULL, but when nLocks == 0 they should be considered garbage. + */ +typedef struct LOCALLOCKTAG +{ + LOCKTAG lock; /* identifies the lockable object */ + LOCKMODE mode; /* lock mode for this table entry */ +} LOCALLOCKTAG; + +typedef struct LOCALLOCKOWNER +{ + /* + * Note: if owner is NULL then the lock is held on behalf of the session; + * otherwise it is held on behalf of my current transaction. + * + * Must use a forward struct reference to avoid circularity. + */ + struct ResourceOwnerData *owner; + int64 nLocks; /* # of times held by this owner */ +} LOCALLOCKOWNER; + +typedef struct LOCALLOCK +{ + /* tag */ + LOCALLOCKTAG tag; /* unique identifier of locallock entry */ + + /* data */ + uint32 hashcode; /* copy of LOCKTAG's hash value */ + LOCK *lock; /* associated LOCK object, if any */ + PROCLOCK *proclock; /* associated PROCLOCK object, if any */ + int64 nLocks; /* total number of times lock is held */ + int numLockOwners; /* # of relevant ResourceOwners */ + int maxLockOwners; /* allocated size of array */ + LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */ + bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */ + bool lockCleared; /* we read all sinval msgs for lock */ +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC: cluster-aware lock state — spec-2.21 D1 ABI extend. + * + * Modified by: SqlRush + * What changed: 3 cluster-aware private fields for exactly-once + * registration / release (HC9 grant-release 对称契约). + * Why: spec-2.21 D2 LockRelease/LockReleaseAll/ResourceOwnerRelease + * hook must read cluster_registered to gate cluster_lock_release + * call; cluster_holder + cluster_request_id are S5 promote outputs + * threaded through to S6 release. In-memory only, not persisted. + * Spec: spec-2.21-pg-lockacquire-integration-2node-smoke.md (D1 / P2.2) + */ + bool cluster_registered; /* PGRAC: true iff S5 promote success */ + uint64 cluster_request_id; /* PGRAC: from req.request_id */ + uint8 cluster_holder_raw[24]; /* PGRAC: ClusterGrdHolderId byte-image */ + /* + * PGRAC: spec-5.3 §3.1a convert release-ownership markers. Set on the + * NEW (stronger-mode) LOCALLOCK when it became the cluster owner via a + * convert; remember the pre-convert weaker mode + request id so a later + * backout (subxact abort releasing this lock while the weaker hold + * survives) can send a CONVERT_ROLLBACK (restore, not delete) and + * re-register the weaker lock. cluster_convert_old_request_id != 0 + * identifies a converted hold. In-memory only. + */ + uint64 cluster_convert_old_request_id; /* PGRAC: R_old (0 = not a convert) */ + int cluster_convert_old_mode; /* PGRAC: pre-convert LOCKMODE */ +#endif +} LOCALLOCK; + +#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid) +#define LOCALLOCK_LOCKTAG(llock) ((LockTagType) (llock).tag.lock.locktag_type) + + +/* + * These structures hold information passed from lmgr internals to the lock + * listing user-level functions (in lockfuncs.c). + */ + +typedef struct LockInstanceData +{ + LOCKTAG locktag; /* tag for locked object */ + LOCKMASK holdMask; /* locks held by this PGPROC */ + LOCKMODE waitLockMode; /* lock awaited by this PGPROC, if any */ + BackendId backend; /* backend ID of this PGPROC */ + LocalTransactionId lxid; /* local transaction ID of this PGPROC */ + TimestampTz waitStart; /* time at which this PGPROC started waiting + * for lock */ + int pid; /* pid of this PGPROC */ + int leaderPid; /* pid of group leader; = pid if no group */ + bool fastpath; /* taken via fastpath? */ +} LockInstanceData; + +typedef struct LockData +{ + int nelements; /* The length of the array */ + LockInstanceData *locks; /* Array of per-PROCLOCK information */ +} LockData; + +typedef struct BlockedProcData +{ + int pid; /* pid of a blocked PGPROC */ + /* Per-PROCLOCK information about PROCLOCKs of the lock the pid awaits */ + /* (these fields refer to indexes in BlockedProcsData.locks[]) */ + int first_lock; /* index of first relevant LockInstanceData */ + int num_locks; /* number of relevant LockInstanceDatas */ + /* PIDs of PGPROCs that are ahead of "pid" in the lock's wait queue */ + /* (these fields refer to indexes in BlockedProcsData.waiter_pids[]) */ + int first_waiter; /* index of first preceding waiter */ + int num_waiters; /* number of preceding waiters */ +} BlockedProcData; + +typedef struct BlockedProcsData +{ + BlockedProcData *procs; /* Array of per-blocked-proc information */ + LockInstanceData *locks; /* Array of per-PROCLOCK information */ + int *waiter_pids; /* Array of PIDs of other blocked PGPROCs */ + int nprocs; /* # of valid entries in procs[] array */ + int maxprocs; /* Allocated length of procs[] array */ + int nlocks; /* # of valid entries in locks[] array */ + int maxlocks; /* Allocated length of locks[] array */ + int npids; /* # of valid entries in waiter_pids[] array */ + int maxpids; /* Allocated length of waiter_pids[] array */ +} BlockedProcsData; + + +/* Result codes for LockAcquire() */ +typedef enum +{ + LOCKACQUIRE_NOT_AVAIL, /* lock not available, and dontWait=true */ + LOCKACQUIRE_OK, /* lock successfully acquired */ + LOCKACQUIRE_ALREADY_HELD, /* incremented count for lock already held */ + LOCKACQUIRE_ALREADY_CLEAR /* incremented count for lock already clear */ +} LockAcquireResult; + +/* Deadlock states identified by DeadLockCheck() */ +typedef enum +{ + DS_NOT_YET_CHECKED, /* no deadlock check has run yet */ + DS_NO_DEADLOCK, /* no deadlock detected */ + DS_SOFT_DEADLOCK, /* deadlock avoided by queue rearrangement */ + DS_HARD_DEADLOCK, /* deadlock, no way out but ERROR */ + DS_BLOCKED_BY_AUTOVACUUM /* no deadlock; queue blocked by autovacuum + * worker */ +} DeadLockState; + +/* + * The lockmgr's shared hash tables are partitioned to reduce contention. + * To determine which partition a given locktag belongs to, compute the tag's + * hash code with LockTagHashCode(), then apply one of these macros. + * NB: NUM_LOCK_PARTITIONS must be a power of 2! + */ +#define LockHashPartition(hashcode) \ + ((hashcode) % NUM_LOCK_PARTITIONS) +#define LockHashPartitionLock(hashcode) \ + (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + \ + LockHashPartition(hashcode)].lock) +#define LockHashPartitionLockByIndex(i) \ + (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + (i)].lock) + +/* + * The deadlock detector needs to be able to access lockGroupLeader and + * related fields in the PGPROC, so we arrange for those fields to be protected + * by one of the lock hash partition locks. Since the deadlock detector + * acquires all such locks anyway, this makes it safe for it to access these + * fields without doing anything extra. To avoid contention as much as + * possible, we map different PGPROCs to different partition locks. The lock + * used for a given lock group is determined by the group leader's pgprocno. + */ +#define LockHashPartitionLockByProc(leader_pgproc) \ + LockHashPartitionLock((leader_pgproc)->pgprocno) + +/* + * function prototypes + */ +extern void InitLocks(void); +extern LockMethod GetLocksMethodTable(const LOCK *lock); +extern LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag); +extern uint32 LockTagHashCode(const LOCKTAG *locktag); +extern bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2); +extern LockAcquireResult LockAcquire(const LOCKTAG *locktag, + LOCKMODE lockmode, + bool sessionLock, + bool dontWait); +extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, + LOCKMODE lockmode, + bool sessionLock, + bool dontWait, + bool reportMemoryError, + LOCALLOCK **locallockp); +extern void AbortStrongLockAcquire(void); +extern void MarkLockClear(LOCALLOCK *locallock); +extern bool LockRelease(const LOCKTAG *locktag, + LOCKMODE lockmode, bool sessionLock); +extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks); +extern void LockReleaseSession(LOCKMETHODID lockmethodid); +extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks); +extern void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks); +extern bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode); +extern bool LockOrStrongerHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode); +#if defined(USE_ASSERT_CHECKING) || defined(USE_PGRAC_CLUSTER) +/* PGRAC: also exported for the spec-4.6 D3 read-only LOCALLOCK walk. */ +extern HTAB *GetLockMethodLocalHash(void); +#endif +extern bool LockHasWaiters(const LOCKTAG *locktag, + LOCKMODE lockmode, bool sessionLock); +extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag, + LOCKMODE lockmode, int *countp); +extern void AtPrepare_Locks(void); +extern void PostPrepare_Locks(TransactionId xid); +extern bool LockCheckConflicts(LockMethod lockMethodTable, + LOCKMODE lockmode, + LOCK *lock, PROCLOCK *proclock); +extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode); +extern void GrantAwaitedLock(void); +extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode); +extern Size LockShmemSize(void); +extern LockData *GetLockStatusData(void); +extern BlockedProcsData *GetBlockerStatusData(int blocked_pid); + +extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks); +extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode); + +extern void lock_twophase_recover(TransactionId xid, uint16 info, + void *recdata, uint32 len); +extern void lock_twophase_postcommit(TransactionId xid, uint16 info, + void *recdata, uint32 len); +extern void lock_twophase_postabort(TransactionId xid, uint16 info, + void *recdata, uint32 len); +extern void lock_twophase_standby_recover(TransactionId xid, uint16 info, + void *recdata, uint32 len); + +extern DeadLockState DeadLockCheck(PGPROC *proc); +extern PGPROC *GetBlockingAutoVacuumPgproc(void); +extern void DeadLockReport(void) pg_attribute_noreturn(); +extern void RememberSimpleDeadLock(PGPROC *proc1, + LOCKMODE lockmode, + LOCK *lock, + PGPROC *proc2); +extern void InitDeadLockChecking(void); + +extern int LockWaiterCount(const LOCKTAG *locktag); + +#ifdef LOCK_DEBUG +extern void DumpLocks(PGPROC *proc); +extern void DumpAllLocks(void); +#endif + +/* Lock a VXID (used to wait for a transaction to finish) */ +extern void VirtualXactLockTableInsert(VirtualTransactionId vxid); +extern void VirtualXactLockTableCleanup(void); +extern bool VirtualXactLock(VirtualTransactionId vxid, bool wait); + +#endif /* LOCK_H_ */ diff --git a/install/include/postgresql/server/storage/lockdefs.h b/install/include/postgresql/server/storage/lockdefs.h new file mode 100644 index 00000000000..bc28d724f32 --- /dev/null +++ b/install/include/postgresql/server/storage/lockdefs.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled. This file + * contains definition that have to (indirectly) be available when included by + * FRONTEND code. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/lockdefs.h + * + *------------------------------------------------------------------------- + */ +#ifndef LOCKDEFS_H_ +#define LOCKDEFS_H_ + +/* + * LOCKMODE is an integer (1..N) indicating a lock type. LOCKMASK is a bit + * mask indicating a set of held or requested lock types (the bit 1<lwWaitMode, + * when waiting for lock to become free. Not + * to be used as LWLockAcquire argument */ +} LWLockMode; + + +#ifdef LOCK_DEBUG +extern PGDLLIMPORT bool Trace_lwlocks; +#endif + +extern bool LWLockAcquire(LWLock *lock, LWLockMode mode); +extern bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode); +extern bool LWLockAcquireOrWait(LWLock *lock, LWLockMode mode); +extern void LWLockRelease(LWLock *lock); +extern void LWLockReleaseClearVar(LWLock *lock, uint64 *valptr, uint64 val); +extern void LWLockReleaseAll(void); +extern void ForEachLWLockHeldByMe(void (*callback)(LWLock *, LWLockMode, void *), void *context); +extern bool LWLockHeldByMe(LWLock *lock); +extern bool LWLockAnyHeldByMe(LWLock *lock, int nlocks, size_t stride); +extern bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode); + +extern bool LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval); +extern void LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val); + +extern Size LWLockShmemSize(void); +extern void CreateLWLocks(void); +extern void InitLWLockAccess(void); + +extern const char *GetLWLockIdentifier(uint32 classId, uint16 eventId); + +/* + * Extensions (or core code) can obtain an LWLocks by calling + * RequestNamedLWLockTranche() during postmaster startup. Subsequently, + * call GetNamedLWLockTranche() to obtain a pointer to an array containing + * the number of LWLocks requested. + */ +extern void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks); +extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name); + +/* + * There is another, more flexible method of obtaining lwlocks. First, call + * LWLockNewTrancheId just once to obtain a tranche ID; this allocates from + * a shared counter. Next, each individual process using the tranche should + * call LWLockRegisterTranche() to associate that tranche ID with a name. + * Finally, LWLockInitialize should be called just once per lwlock, passing + * the tranche ID as an argument. + * + * It may seem strange that each process using the tranche must register it + * separately, but dynamic shared memory segments aren't guaranteed to be + * mapped at the same address in all coordinating backends, so storing the + * registration in the main shared memory segment wouldn't work for that case. + */ +extern int LWLockNewTrancheId(void); +extern void LWLockRegisterTranche(int tranche_id, const char *tranche_name); +extern void LWLockInitialize(LWLock *lock, int tranche_id); + +/* + * Every tranche ID less than NUM_INDIVIDUAL_LWLOCKS is reserved; also, + * we reserve additional tranche IDs for builtin tranches not included in + * the set of individual LWLocks. A call to LWLockNewTrancheId will never + * return a value less than LWTRANCHE_FIRST_USER_DEFINED. + */ +typedef enum BuiltinTrancheIds { + LWTRANCHE_XACT_BUFFER = NUM_INDIVIDUAL_LWLOCKS, + LWTRANCHE_COMMITTS_BUFFER, + LWTRANCHE_SUBTRANS_BUFFER, + LWTRANCHE_MULTIXACTOFFSET_BUFFER, + LWTRANCHE_MULTIXACTMEMBER_BUFFER, + LWTRANCHE_NOTIFY_BUFFER, + LWTRANCHE_SERIAL_BUFFER, + LWTRANCHE_WAL_INSERT, + LWTRANCHE_BUFFER_CONTENT, + LWTRANCHE_REPLICATION_ORIGIN_STATE, + LWTRANCHE_REPLICATION_SLOT_IO, + LWTRANCHE_LOCK_FASTPATH, + LWTRANCHE_BUFFER_MAPPING, + LWTRANCHE_LOCK_MANAGER, + LWTRANCHE_PREDICATE_LOCK_MANAGER, + LWTRANCHE_PARALLEL_HASH_JOIN, + LWTRANCHE_PARALLEL_QUERY_DSA, + LWTRANCHE_PER_SESSION_DSA, + LWTRANCHE_PER_SESSION_RECORD_TYPE, + LWTRANCHE_PER_SESSION_RECORD_TYPMOD, + LWTRANCHE_SHARED_TUPLESTORE, + LWTRANCHE_SHARED_TIDBITMAP, + LWTRANCHE_PARALLEL_APPEND, + LWTRANCHE_PER_XACT_PREDICATE_LIST, + LWTRANCHE_PGSTATS_DSA, + LWTRANCHE_PGSTATS_HASH, + LWTRANCHE_PGSTATS_DATA, + LWTRANCHE_LAUNCHER_DSA, + LWTRANCHE_LAUNCHER_HASH, +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC (stage 1.6 hardening): dedicated tranche for BufferDesc.pcm_lock + * (added at offset 104 in cluster mode). Independent tranche makes + * lock trace / pg_stat_activity wait-event distinguish content_lock + * from pcm_lock; complements the bufmgr.c:AssertNotCatalogBufferLock + * runtime guard that prevents reverse-deref misidentification. + * + * Spec: spec-stage1-codex-fixes.md §1.2 Deliverable 5 + spec-1.6 §11 + */ + LWTRANCHE_BUFFER_PCM_LOCK, + /* + * PGRAC (stage 1.10.1 hardening): dedicated tranche for the + * ClusterPhaseSharedState lwlock that guards postmaster startup + * phase state in shmem (current_phase / phase_start_times[] / + * phase_history[] ring). Migrated from process-local static + * globals to fix EXEC_BACKEND/Windows children seeing pre_init + * stale state after re-exec. + * + * Spec: spec-1.10.1-postmaster-phase-hardening.md F1 + */ + LWTRANCHE_CLUSTER_STARTUP_PHASE, + /* + * PGRAC (stage 1.11 Sprint A): dedicated tranche for + * ClusterLmonSharedState lwlock that guards LMON shmem state + * (status enum + pid + spawned_at + ready_at + last_liveness_tick_at + + * main_loop_iters + shutdown_requested). Single writer at runtime + * is the LMON aux process; postmaster also writes shutdown_requested + * during pmdie reverse path. + * + * Spec: spec-1.11-lmon-skeleton.md Sprint A D1+D2 + */ + LWTRANCHE_CLUSTER_LMON, + /* + * PGRAC (stage 1.12 Sprint A): dedicated tranche for + * ClusterLckSharedState lwlock — same pattern as LMON. + * + * Spec: spec-1.12-lck-skeleton.md Sprint A D1+D2 + */ + LWTRANCHE_CLUSTER_LCK, + /* + * PGRAC (stage 1.13 Sprint A): dedicated tranche for + * ClusterDiagSharedState lwlock — same pattern as LMON / LCK. + * + * Spec: spec-1.13-diag-skeleton.md Sprint A D1+D2 + */ + LWTRANCHE_CLUSTER_DIAG, + /* + * PGRAC (stage 1.14 Sprint A): dedicated tranche for + * ClusterStatsSharedState lwlock — same pattern as LMON / LCK / DIAG. + * + * Spec: spec-1.14-cluster-stats-skeleton.md Sprint A D1+D2 + */ + LWTRANCHE_CLUSTER_STATS, + /* PGRAC (stage 1.15): SCN encoding layer; cluster_scn_state lwlock. */ + LWTRANCHE_CLUSTER_SCN, + /* PGRAC (stage 2.5): CSSD aux process lifecycle lwlock (spec-2.5 D7). */ + LWTRANCHE_CLUSTER_CSSD, + /* PGRAC (spec-2.28 Sprint A Step 1): ClusterFenceShmem lwlock guards + * last_freeze_at_us / last_thaw_at_us / self_fence_requested_at_us + + * 3 lifetime counters. Single-tranche per region (Q3 LMON-mediated + * broadcast — only LMON acquires for write, postmaster_check + view + * SRF are read-only paths). */ + LWTRANCHE_CLUSTER_FENCE, + /* PGRAC (spec-2.29 Sprint A Step 1): ClusterReconfigState lwlock + * guards last_applied event publish path. Per L23 compound-atomic + * lesson — apply_counter inc + last_applied write share critical + * section so concurrent SRF reads see consistent snapshot. */ + LWTRANCHE_CLUSTER_RECONFIG, + /* PGRAC (spec-2.18 Sprint A Step 1): ClusterLmsSharedState lwlock + * guards non-atomic LMS fields (pid / spawned_at / ready_at / + * stopped_at / shutdown_requested). lms_state itself is atomic + * for HC4 single ownership lock-free read on the LMON hot path + * (cluster_lms_owns_grant). */ + LWTRANCHE_CLUSTER_LMS, + /* PGRAC (spec-2.19 Sprint A Step 1): ClusterLmdSharedState lwlock + * guards non-atomic LMD fields (pid / spawned_at / ready_at / + * stopped_at / shutdown_requested). lmd_state itself is atomic + * for HC4 exact-predicate readiness check on the caller-side + * ownership gate (cluster_lmd_is_ready). */ + LWTRANCHE_CLUSTER_LMD, + /* PGRAC (spec-2.22 D5): ClusterLmdGraphShared lwlock guards the + * wait-for graph hash table (waiter/blocker edges) + atomic + * generation counter. Separate tranche from CLUSTER_LMD because + * the graph subsystem has a different contention profile (high + * frequency add/remove during cluster lock acquire/release vs + * low-frequency daemon-state mutations under LMD lwlock). */ + LWTRANCHE_CLUSTER_LMD_GRAPH, + /* PGRAC (spec-2.23 D1): ClusterGesReplyWaitShared lwlock guards the + * cross-node GES reply wait HTAB (5-tuple key: request_id, + * source_node, dest_node, request_opcode, cluster_epoch). Backends + * insert on send_request_and_wait; reply handler looks up + wakes; + * timeout sweep deletes stale entries. HC17 invariant — late reply + * after entry deletion is silently dropped + counter++. */ + LWTRANCHE_CLUSTER_GES_REPLY_WAIT, + /* PGRAC (spec-2.30 D4): per-entry LWLockPadded on each GrdEntry slot in + * the cluster_pcm_grd HTAB. Guards transition mutation (master_state + * CAS + holder bitmap update + master_holder). HC57 invariant: every + * transition_apply MUST hold EXCLUSIVE; HC61 forbids upgrade to a + * per-shard / global lock granularity. */ + LWTRANCHE_CLUSTER_PCM, + /* PGRAC (spec-2.32 D2): per-backend outstanding-request block lock in + * cluster_gcs.c. Guards reservation/release of MAX_OUTSTANDING_REQUESTS_PER_BACKEND + * slots; per-backend granularity keeps contention surface tiny. */ + LWTRANCHE_CLUSTER_GCS, + /* PGRAC (spec-2.33 D3): per-backend outstanding-block-request block lock in + * cluster_gcs_block.c. Same per-backend granularity as spec-2.32 control + * plane; separate tranche so observability can distinguish data-plane + * (block ship) contention from control-plane (transition request) contention. */ + LWTRANCHE_CLUSTER_GCS_BLOCK, + /* PGRAC (spec-2.34 D2): master-side dedup HTAB partition + counter lock. + * Guards GcsBlockDedupEntry slot allocation / lookup / install / TTL sweep + * (HC90/HC91/HC92/HC93). LMON-owned region; backend producers (GCS_BLOCK_ + * REQUEST handler context) acquire briefly during lookup_or_register + + * install_reply. Separate tranche from CLUSTER_GCS_BLOCK so DBA can see + * data-plane reliability path contention distinctly. */ + LWTRANCHE_CLUSTER_GCS_BLOCK_DEDUP, + /* PGRAC (spec-2.38 D2): SI Broadcaster outbound + inbound ring buffer + * lock. Both queues share this tranche. Outbound uses LWLockAcquire + * EXCLUSIVE in backend context (cluster_sinval_enqueue_batch). Inbound + * uses LWLockConditionalAcquire only from the IC handler (HC133 + * nonblocking constraint) and LWLockAcquire EXCLUSIVE only from the + * SI Broadcaster aux process drain path. */ + LWTRANCHE_CLUSTER_SINVAL, + /* PGRAC: spec-3.1 D2 — Undo TT status overlay HTAB (single-partition; + * EXCLUSIVE for install/flush, SHARED for lookup_exact). */ + LWTRANCHE_CLUSTER_TT_STATUS, + /* PGRAC: spec-3.4b D3 — per-undo-segment TT slot allocator LWLock array. + * One LWLock per segment guards alloc / free / wrap mutations of the + * 48-entry TT slot array embedded in UndoSegmentHeader. */ + LWTRANCHE_CLUSTER_TT_SLOT, + /* PGRAC: spec-3.13 Undo Cleaner aux process state region. */ + LWTRANCHE_CLUSTER_UNDO_CLEANER, + /* PGRAC: spec-3.18 D1 — undo block buffer pool. Two sub-uses share this + * tranche: a single pool map_lock (slot lookup / allocate / evict) and a + * per-slot content_lock (SHARED reader / EXCLUSIVE writer; mode fixed at + * pin time — no in-place upgrade). */ + LWTRANCHE_CLUSTER_UNDO_BUF, + /* PGRAC: spec-5.4 D1 — SQ sequence node-level instance cache region. */ + LWTRANCHE_CLUSTER_SQ, +#endif + LWTRANCHE_FIRST_USER_DEFINED +} BuiltinTrancheIds; + +/* + * Prior to PostgreSQL 9.4, we used an enum type called LWLockId to refer + * to LWLocks. New code should instead use LWLock *. However, for the + * convenience of third-party code, we include the following typedef. + */ +typedef LWLock *LWLockId; + +#endif /* LWLOCK_H */ diff --git a/install/include/postgresql/server/storage/lwlocknames.h b/install/include/postgresql/server/storage/lwlocknames.h new file mode 100644 index 00000000000..e279f72b013 --- /dev/null +++ b/install/include/postgresql/server/storage/lwlocknames.h @@ -0,0 +1,50 @@ +/* autogenerated from src/backend/storage/lmgr/lwlocknames.txt, do not edit */ +/* there is deliberately not an #ifndef LWLOCKNAMES_H here */ + +#define ShmemIndexLock (&MainLWLockArray[1].lock) +#define OidGenLock (&MainLWLockArray[2].lock) +#define XidGenLock (&MainLWLockArray[3].lock) +#define ProcArrayLock (&MainLWLockArray[4].lock) +#define SInvalReadLock (&MainLWLockArray[5].lock) +#define SInvalWriteLock (&MainLWLockArray[6].lock) +#define WALBufMappingLock (&MainLWLockArray[7].lock) +#define WALWriteLock (&MainLWLockArray[8].lock) +#define ControlFileLock (&MainLWLockArray[9].lock) +#define XactSLRULock (&MainLWLockArray[11].lock) +#define SubtransSLRULock (&MainLWLockArray[12].lock) +#define MultiXactGenLock (&MainLWLockArray[13].lock) +#define MultiXactOffsetSLRULock (&MainLWLockArray[14].lock) +#define MultiXactMemberSLRULock (&MainLWLockArray[15].lock) +#define RelCacheInitLock (&MainLWLockArray[16].lock) +#define CheckpointerCommLock (&MainLWLockArray[17].lock) +#define TwoPhaseStateLock (&MainLWLockArray[18].lock) +#define TablespaceCreateLock (&MainLWLockArray[19].lock) +#define BtreeVacuumLock (&MainLWLockArray[20].lock) +#define AddinShmemInitLock (&MainLWLockArray[21].lock) +#define AutovacuumLock (&MainLWLockArray[22].lock) +#define AutovacuumScheduleLock (&MainLWLockArray[23].lock) +#define SyncScanLock (&MainLWLockArray[24].lock) +#define RelationMappingLock (&MainLWLockArray[25].lock) +#define NotifySLRULock (&MainLWLockArray[26].lock) +#define NotifyQueueLock (&MainLWLockArray[27].lock) +#define SerializableXactHashLock (&MainLWLockArray[28].lock) +#define SerializableFinishedListLock (&MainLWLockArray[29].lock) +#define SerializablePredicateListLock (&MainLWLockArray[30].lock) +#define SerialSLRULock (&MainLWLockArray[31].lock) +#define SyncRepLock (&MainLWLockArray[32].lock) +#define BackgroundWorkerLock (&MainLWLockArray[33].lock) +#define DynamicSharedMemoryControlLock (&MainLWLockArray[34].lock) +#define AutoFileLock (&MainLWLockArray[35].lock) +#define ReplicationSlotAllocationLock (&MainLWLockArray[36].lock) +#define ReplicationSlotControlLock (&MainLWLockArray[37].lock) +#define CommitTsSLRULock (&MainLWLockArray[38].lock) +#define CommitTsLock (&MainLWLockArray[39].lock) +#define ReplicationOriginLock (&MainLWLockArray[40].lock) +#define MultiXactTruncationLock (&MainLWLockArray[41].lock) +#define OldSnapshotTimeMapLock (&MainLWLockArray[42].lock) +#define LogicalRepWorkerLock (&MainLWLockArray[43].lock) +#define XactTruncationLock (&MainLWLockArray[44].lock) +#define WrapLimitsVacuumLock (&MainLWLockArray[46].lock) +#define NotifyQueueTailLock (&MainLWLockArray[47].lock) + +#define NUM_INDIVIDUAL_LWLOCKS 48 diff --git a/install/include/postgresql/server/storage/md.h b/install/include/postgresql/server/storage/md.h new file mode 100644 index 00000000000..a16235d51fe --- /dev/null +++ b/install/include/postgresql/server/storage/md.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * md.h + * magnetic disk storage manager public interface declarations. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/md.h + * + *------------------------------------------------------------------------- + */ +#ifndef MD_H +#define MD_H + +#include "storage/block.h" +#include "storage/relfilelocator.h" +#include "storage/smgr.h" +#include "storage/sync.h" + +/* md storage manager functionality */ +extern void mdinit(void); +extern void mdopen(SMgrRelation reln); +extern void mdclose(SMgrRelation reln, ForkNumber forknum); +extern void mdcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); +extern bool mdexists(SMgrRelation reln, ForkNumber forknum); +extern void mdunlink(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo); +extern void mdextend(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, const void *buffer, bool skipFsync); +extern void mdzeroextend(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, int nblocks, bool skipFsync); +extern bool mdprefetch(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum); +extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, + void *buffer); +extern void mdwrite(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, const void *buffer, bool skipFsync); +extern void mdwriteback(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, BlockNumber nblocks); +extern BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum); +extern void mdtruncate(SMgrRelation reln, ForkNumber forknum, + BlockNumber old_blocks, BlockNumber nblocks); +extern void mdimmedsync(SMgrRelation reln, ForkNumber forknum); + +extern void ForgetDatabaseSyncRequests(Oid dbid); +extern void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo); + +/* md sync callbacks */ +extern int mdsyncfiletag(const FileTag *ftag, char *path); +extern int mdunlinkfiletag(const FileTag *ftag, char *path); +extern bool mdfiletagmatches(const FileTag *ftag, const FileTag *candidate); + +#endif /* MD_H */ diff --git a/install/include/postgresql/server/storage/off.h b/install/include/postgresql/server/storage/off.h new file mode 100644 index 00000000000..3540308069a --- /dev/null +++ b/install/include/postgresql/server/storage/off.h @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------- + * + * off.h + * POSTGRES disk "offset" definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/off.h + * + *------------------------------------------------------------------------- + */ +#ifndef OFF_H +#define OFF_H + +#include "storage/itemid.h" +/* + * OffsetNumber: + * + * this is a 1-based index into the linp (ItemIdData) array in the + * header of each disk page. + */ +typedef uint16 OffsetNumber; + +#define InvalidOffsetNumber ((OffsetNumber) 0) +#define FirstOffsetNumber ((OffsetNumber) 1) +#define MaxOffsetNumber ((OffsetNumber) (BLCKSZ / sizeof(ItemIdData))) + +/* ---------------- + * support macros + * ---------------- + */ + +/* + * OffsetNumberIsValid + * True iff the offset number is valid. + */ +#define OffsetNumberIsValid(offsetNumber) \ + ((bool) ((offsetNumber != InvalidOffsetNumber) && \ + (offsetNumber <= MaxOffsetNumber))) + +/* + * OffsetNumberNext + * OffsetNumberPrev + * Increments/decrements the argument. These macros look pointless + * but they help us disambiguate the different manipulations on + * OffsetNumbers (e.g., sometimes we subtract one from an + * OffsetNumber to move back, and sometimes we do so to form a + * real C array index). + */ +#define OffsetNumberNext(offsetNumber) \ + ((OffsetNumber) (1 + (offsetNumber))) +#define OffsetNumberPrev(offsetNumber) \ + ((OffsetNumber) (-1 + (offsetNumber))) + +#endif /* OFF_H */ diff --git a/install/include/postgresql/server/storage/pg_sema.h b/install/include/postgresql/server/storage/pg_sema.h new file mode 100644 index 00000000000..3bf03420741 --- /dev/null +++ b/install/include/postgresql/server/storage/pg_sema.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * pg_sema.h + * Platform-independent API for semaphores. + * + * PostgreSQL requires counting semaphores (the kind that keep track of + * multiple unlock operations, and will allow an equal number of subsequent + * lock operations before blocking). The underlying implementation is + * not the same on every platform. This file defines the API that must + * be provided by each port. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/pg_sema.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SEMA_H +#define PG_SEMA_H + +/* + * struct PGSemaphoreData and pointer type PGSemaphore are the data structure + * representing an individual semaphore. The contents of PGSemaphoreData vary + * across implementations and must never be touched by platform-independent + * code; hence, PGSemaphoreData is declared as an opaque struct here. + * + * However, Windows is sufficiently unlike our other ports that it doesn't + * seem worth insisting on ABI compatibility for Windows too. Hence, on + * that platform just define PGSemaphore as HANDLE. + */ +#ifndef USE_WIN32_SEMAPHORES +typedef struct PGSemaphoreData *PGSemaphore; +#else +typedef HANDLE PGSemaphore; +#endif + + +/* Report amount of shared memory needed */ +extern Size PGSemaphoreShmemSize(int maxSemas); + +/* Module initialization (called during postmaster start or shmem reinit) */ +extern void PGReserveSemaphores(int maxSemas); + +/* Allocate a PGSemaphore structure with initial count 1 */ +extern PGSemaphore PGSemaphoreCreate(void); + +/* Reset a previously-initialized PGSemaphore to have count 0 */ +extern void PGSemaphoreReset(PGSemaphore sema); + +/* Lock a semaphore (decrement count), blocking if count would be < 0 */ +extern void PGSemaphoreLock(PGSemaphore sema); + +/* Unlock a semaphore (increment count) */ +extern void PGSemaphoreUnlock(PGSemaphore sema); + +/* Lock a semaphore only if able to do so without blocking */ +extern bool PGSemaphoreTryLock(PGSemaphore sema); + +#endif /* PG_SEMA_H */ diff --git a/install/include/postgresql/server/storage/pg_shmem.h b/install/include/postgresql/server/storage/pg_shmem.h new file mode 100644 index 00000000000..4dd05f156d5 --- /dev/null +++ b/install/include/postgresql/server/storage/pg_shmem.h @@ -0,0 +1,92 @@ +/*------------------------------------------------------------------------- + * + * pg_shmem.h + * Platform-independent API for shared memory support. + * + * Every port is expected to support shared memory with approximately + * SysV-ish semantics; in particular, a memory block is not anonymous + * but has an ID, and we must be able to tell whether there are any + * remaining processes attached to a block of a specified ID. + * + * To simplify life for the SysV implementation, the ID is assumed to + * consist of two unsigned long values (these are key and ID in SysV + * terms). Other platforms may ignore the second value if they need + * only one ID number. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/pg_shmem.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHMEM_H +#define PG_SHMEM_H + +#include "storage/dsm_impl.h" + +typedef struct PGShmemHeader /* standard header for all Postgres shmem */ +{ + int32 magic; /* magic # to identify Postgres segments */ +#define PGShmemMagic 679834894 + pid_t creatorPID; /* PID of creating process (set but unread) */ + Size totalsize; /* total size of segment */ + Size freeoffset; /* offset to first free space */ + dsm_handle dsm_control; /* ID of dynamic shared memory control seg */ + void *index; /* pointer to ShmemIndex table */ +#ifndef WIN32 /* Windows doesn't have useful inode#s */ + dev_t device; /* device data directory is on */ + ino_t inode; /* inode number of data directory */ +#endif +} PGShmemHeader; + +/* GUC variables */ +extern PGDLLIMPORT int shared_memory_type; +extern PGDLLIMPORT int huge_pages; +extern PGDLLIMPORT int huge_page_size; + +/* Possible values for huge_pages */ +typedef enum +{ + HUGE_PAGES_OFF, + HUGE_PAGES_ON, + HUGE_PAGES_TRY +} HugePagesType; + +/* Possible values for shared_memory_type */ +typedef enum +{ + SHMEM_TYPE_WINDOWS, + SHMEM_TYPE_SYSV, + SHMEM_TYPE_MMAP +} PGShmemType; + +#ifndef WIN32 +extern PGDLLIMPORT unsigned long UsedShmemSegID; +#else +extern PGDLLIMPORT HANDLE UsedShmemSegID; +extern PGDLLIMPORT void *ShmemProtectiveRegion; +#endif +extern PGDLLIMPORT void *UsedShmemSegAddr; + +#if !defined(WIN32) && !defined(EXEC_BACKEND) +#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_MMAP +#elif !defined(WIN32) +#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_SYSV +#else +#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_WINDOWS +#endif + +#ifdef EXEC_BACKEND +extern void PGSharedMemoryReAttach(void); +extern void PGSharedMemoryNoReAttach(void); +#endif + +extern PGShmemHeader *PGSharedMemoryCreate(Size size, + PGShmemHeader **shim); +extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2); +extern void PGSharedMemoryDetach(void); +extern void GetHugePageSize(Size *hugepagesize, int *mmap_flags); + +#endif /* PG_SHMEM_H */ diff --git a/install/include/postgresql/server/storage/pmsignal.h b/install/include/postgresql/server/storage/pmsignal.h new file mode 100644 index 00000000000..92dc7646671 --- /dev/null +++ b/install/include/postgresql/server/storage/pmsignal.h @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------- + * + * pmsignal.h + * routines for signaling between the postmaster and its child processes + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/pmsignal.h + * + *------------------------------------------------------------------------- + */ +#ifndef PMSIGNAL_H +#define PMSIGNAL_H + +#include + +#ifdef HAVE_SYS_PRCTL_H +#include "sys/prctl.h" +#endif + +#ifdef HAVE_SYS_PROCCTL_H +#include "sys/procctl.h" +#endif + +/* + * Reasons for signaling the postmaster. We can cope with simultaneous + * signals for different reasons. If the same reason is signaled multiple + * times in quick succession, however, the postmaster is likely to observe + * only one notification of it. This is okay for the present uses. + */ +typedef enum +{ + PMSIGNAL_RECOVERY_STARTED, /* recovery has started */ + PMSIGNAL_BEGIN_HOT_STANDBY, /* begin Hot Standby */ + PMSIGNAL_ROTATE_LOGFILE, /* send SIGUSR1 to syslogger to rotate logfile */ + PMSIGNAL_START_AUTOVAC_LAUNCHER, /* start an autovacuum launcher */ + PMSIGNAL_START_AUTOVAC_WORKER, /* start an autovacuum worker */ + PMSIGNAL_BACKGROUND_WORKER_CHANGE, /* background worker state change */ + PMSIGNAL_START_WALRECEIVER, /* start a walreceiver */ + PMSIGNAL_ADVANCE_STATE_MACHINE, /* advance postmaster's state machine */ + + NUM_PMSIGNALS /* Must be last value of enum! */ +} PMSignalReason; + +/* + * Reasons why the postmaster would send SIGQUIT to its children. + */ +typedef enum +{ + PMQUIT_NOT_SENT = 0, /* postmaster hasn't sent SIGQUIT */ + PMQUIT_FOR_CRASH, /* some other backend bought the farm */ + PMQUIT_FOR_STOP /* immediate stop was commanded */ +} QuitSignalReason; + +/* PMSignalData is an opaque struct, details known only within pmsignal.c */ +typedef struct PMSignalData PMSignalData; + +/* + * prototypes for functions in pmsignal.c + */ +extern Size PMSignalShmemSize(void); +extern void PMSignalShmemInit(void); +extern void SendPostmasterSignal(PMSignalReason reason); +extern bool CheckPostmasterSignal(PMSignalReason reason); +extern void SetQuitSignalReason(QuitSignalReason reason); +extern QuitSignalReason GetQuitSignalReason(void); +extern int AssignPostmasterChildSlot(void); +extern bool ReleasePostmasterChildSlot(int slot); +extern bool IsPostmasterChildWalSender(int slot); +extern void MarkPostmasterChildActive(void); +extern void MarkPostmasterChildInactive(void); +extern void MarkPostmasterChildWalSender(void); +extern bool PostmasterIsAliveInternal(void); +extern void PostmasterDeathSignalInit(void); + + +/* + * Do we have a way to ask for a signal on parent death? + * + * If we do, pmsignal.c will set up a signal handler, that sets a flag when + * the parent dies. Checking the flag first makes PostmasterIsAlive() a lot + * cheaper in usual case that the postmaster is alive. + */ +#if (defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_PDEATHSIG)) || \ + (defined(HAVE_SYS_PROCCTL_H) && defined(PROC_PDEATHSIG_CTL)) +#define USE_POSTMASTER_DEATH_SIGNAL +#endif + +#ifdef USE_POSTMASTER_DEATH_SIGNAL +extern PGDLLIMPORT volatile sig_atomic_t postmaster_possibly_dead; + +static inline bool +PostmasterIsAlive(void) +{ + if (likely(!postmaster_possibly_dead)) + return true; + return PostmasterIsAliveInternal(); +} +#else +#define PostmasterIsAlive() PostmasterIsAliveInternal() +#endif + +#endif /* PMSIGNAL_H */ diff --git a/install/include/postgresql/server/storage/predicate.h b/install/include/postgresql/server/storage/predicate.h new file mode 100644 index 00000000000..cd48afa17b2 --- /dev/null +++ b/install/include/postgresql/server/storage/predicate.h @@ -0,0 +1,87 @@ +/*------------------------------------------------------------------------- + * + * predicate.h + * POSTGRES public predicate locking definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/predicate.h + * + *------------------------------------------------------------------------- + */ +#ifndef PREDICATE_H +#define PREDICATE_H + +#include "storage/lock.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + + +/* + * GUC variables + */ +extern PGDLLIMPORT int max_predicate_locks_per_xact; +extern PGDLLIMPORT int max_predicate_locks_per_relation; +extern PGDLLIMPORT int max_predicate_locks_per_page; + + +/* Number of SLRU buffers to use for Serial SLRU */ +#define NUM_SERIAL_BUFFERS 16 + +/* + * A handle used for sharing SERIALIZABLEXACT objects between the participants + * in a parallel query. + */ +typedef void *SerializableXactHandle; + +/* + * function prototypes + */ + +/* housekeeping for shared memory predicate lock structures */ +extern void InitPredicateLocks(void); +extern Size PredicateLockShmemSize(void); + +extern void CheckPointPredicate(void); + +/* predicate lock reporting */ +extern bool PageIsPredicateLocked(Relation relation, BlockNumber blkno); + +/* predicate lock maintenance */ +extern Snapshot GetSerializableTransactionSnapshot(Snapshot snapshot); +extern void SetSerializableTransactionSnapshot(Snapshot snapshot, + VirtualTransactionId *sourcevxid, + int sourcepid); +extern void RegisterPredicateLockingXid(TransactionId xid); +extern void PredicateLockRelation(Relation relation, Snapshot snapshot); +extern void PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot); +extern void PredicateLockTID(Relation relation, ItemPointer tid, Snapshot snapshot, + TransactionId tuple_xid); +extern void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno); +extern void PredicateLockPageCombine(Relation relation, BlockNumber oldblkno, BlockNumber newblkno); +extern void TransferPredicateLocksToHeapRelation(Relation relation); +extern void ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe); + +/* conflict detection (may also trigger rollback) */ +extern bool CheckForSerializableConflictOutNeeded(Relation relation, Snapshot snapshot); +extern void CheckForSerializableConflictOut(Relation relation, TransactionId xid, Snapshot snapshot); +extern void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno); +extern void CheckTableForSerializableConflictIn(Relation relation); + +/* final rollback checking */ +extern void PreCommit_CheckForSerializationFailure(void); + +/* two-phase commit support */ +extern void AtPrepare_PredicateLocks(void); +extern void PostPrepare_PredicateLocks(TransactionId xid); +extern void PredicateLockTwoPhaseFinish(TransactionId xid, bool isCommit); +extern void predicatelock_twophase_recover(TransactionId xid, uint16 info, + void *recdata, uint32 len); + +/* parallel query support */ +extern SerializableXactHandle ShareSerializableXact(void); +extern void AttachSerializableXact(SerializableXactHandle handle); + +#endif /* PREDICATE_H */ diff --git a/install/include/postgresql/server/storage/predicate_internals.h b/install/include/postgresql/server/storage/predicate_internals.h new file mode 100644 index 00000000000..93f84500bf0 --- /dev/null +++ b/install/include/postgresql/server/storage/predicate_internals.h @@ -0,0 +1,478 @@ +/*------------------------------------------------------------------------- + * + * predicate_internals.h + * POSTGRES internal predicate locking definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/predicate_internals.h + * + *------------------------------------------------------------------------- + */ +#ifndef PREDICATE_INTERNALS_H +#define PREDICATE_INTERNALS_H + +#include "lib/ilist.h" +#include "storage/lock.h" +#include "storage/lwlock.h" + +/* + * Commit number. + */ +typedef uint64 SerCommitSeqNo; + +/* + * Reserved commit sequence numbers: + * - 0 is reserved to indicate a non-existent SLRU entry; it cannot be + * used as a SerCommitSeqNo, even an invalid one + * - InvalidSerCommitSeqNo is used to indicate a transaction that + * hasn't committed yet, so use a number greater than all valid + * ones to make comparison do the expected thing + * - RecoverySerCommitSeqNo is used to refer to transactions that + * happened before a crash/recovery, since we restart the sequence + * at that point. It's earlier than all normal sequence numbers, + * and is only used by recovered prepared transactions + */ +#define InvalidSerCommitSeqNo ((SerCommitSeqNo) PG_UINT64_MAX) +#define RecoverySerCommitSeqNo ((SerCommitSeqNo) 1) +#define FirstNormalSerCommitSeqNo ((SerCommitSeqNo) 2) + +/* + * The SERIALIZABLEXACT struct contains information needed for each + * serializable database transaction to support SSI techniques. + * + * A home-grown list is maintained in shared memory to manage these. + * An entry is used when the serializable transaction acquires a snapshot. + * Unless the transaction is rolled back, this entry must generally remain + * until all concurrent transactions have completed. (There are special + * optimizations for READ ONLY transactions which often allow them to be + * cleaned up earlier.) A transaction which is rolled back is cleaned up + * as soon as possible. + * + * Eligibility for cleanup of committed transactions is generally determined + * by comparing the transaction's finishedBefore field to + * SxactGlobalXmin. + */ +typedef struct SERIALIZABLEXACT +{ + VirtualTransactionId vxid; /* The executing process always has one of + * these. */ + + /* + * We use two numbers to track the order that transactions commit. Before + * commit, a transaction is marked as prepared, and prepareSeqNo is set. + * Shortly after commit, it's marked as committed, and commitSeqNo is set. + * This doesn't give a strict commit order, but these two values together + * are good enough for us, as we can always err on the safe side and + * assume that there's a conflict, if we can't be sure of the exact + * ordering of two commits. + * + * Note that a transaction is marked as prepared for a short period during + * commit processing, even if two-phase commit is not used. But with + * two-phase commit, a transaction can stay in prepared state for some + * time. + */ + SerCommitSeqNo prepareSeqNo; + SerCommitSeqNo commitSeqNo; + + /* these values are not both interesting at the same time */ + union + { + SerCommitSeqNo earliestOutConflictCommit; /* when committed with + * conflict out */ + SerCommitSeqNo lastCommitBeforeSnapshot; /* when not committed or + * no conflict out */ + } SeqNo; + dlist_head outConflicts; /* list of write transactions whose data we + * couldn't read. */ + dlist_head inConflicts; /* list of read transactions which couldn't + * see our write. */ + dlist_head predicateLocks; /* list of associated PREDICATELOCK objects */ + dlist_node finishedLink; /* list link in + * FinishedSerializableTransactions */ + dlist_node xactLink; /* PredXact->activeList/availableList */ + + /* + * perXactPredicateListLock is only used in parallel queries: it protects + * this SERIALIZABLEXACT's predicate lock list against other workers of + * the same session. + */ + LWLock perXactPredicateListLock; + + /* + * for r/o transactions: list of concurrent r/w transactions that we could + * potentially have conflicts with, and vice versa for r/w transactions + */ + dlist_head possibleUnsafeConflicts; + + TransactionId topXid; /* top level xid for the transaction, if one + * exists; else invalid */ + TransactionId finishedBefore; /* invalid means still running; else the + * struct expires when no serializable + * xids are before this. */ + TransactionId xmin; /* the transaction's snapshot xmin */ + uint32 flags; /* OR'd combination of values defined below */ + int pid; /* pid of associated process */ + int pgprocno; /* pgprocno of associated process */ +} SERIALIZABLEXACT; + +#define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */ +#define SXACT_FLAG_PREPARED 0x00000002 /* about to commit */ +#define SXACT_FLAG_ROLLED_BACK 0x00000004 /* already rolled back */ +#define SXACT_FLAG_DOOMED 0x00000008 /* will roll back */ +/* + * The following flag actually means that the flagged transaction has a + * conflict out *to a transaction which committed ahead of it*. It's hard + * to get that into a name of a reasonable length. + */ +#define SXACT_FLAG_CONFLICT_OUT 0x00000010 +#define SXACT_FLAG_READ_ONLY 0x00000020 +#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000040 +#define SXACT_FLAG_RO_SAFE 0x00000080 +#define SXACT_FLAG_RO_UNSAFE 0x00000100 +#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000200 +#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000400 +/* + * The following flag means the transaction has been partially released + * already, but is being preserved because parallel workers might have a + * reference to it. It'll be recycled by the leader at end-of-transaction. + */ +#define SXACT_FLAG_PARTIALLY_RELEASED 0x00000800 + +typedef struct PredXactListData +{ + dlist_head availableList; + dlist_head activeList; + + /* + * These global variables are maintained when registering and cleaning up + * serializable transactions. They must be global across all backends, + * but are not needed outside the predicate.c source file. Protected by + * SerializableXactHashLock. + */ + TransactionId SxactGlobalXmin; /* global xmin for active serializable + * transactions */ + int SxactGlobalXminCount; /* how many active serializable + * transactions have this xmin */ + int WritableSxactCount; /* how many non-read-only serializable + * transactions are active */ + SerCommitSeqNo LastSxactCommitSeqNo; /* a strictly monotonically + * increasing number for commits + * of serializable transactions */ + /* Protected by SerializableXactHashLock. */ + SerCommitSeqNo CanPartialClearThrough; /* can clear predicate locks and + * inConflicts for committed + * transactions through this seq + * no */ + /* Protected by SerializableFinishedListLock. */ + SerCommitSeqNo HavePartialClearedThrough; /* have cleared through this + * seq no */ + SERIALIZABLEXACT *OldCommittedSxact; /* shared copy of dummy sxact */ + + SERIALIZABLEXACT *element; +} PredXactListData; + +typedef struct PredXactListData *PredXactList; + +#define PredXactListDataSize \ + ((Size)MAXALIGN(sizeof(PredXactListData))) + + +/* + * The following types are used to provide lists of rw-conflicts between + * pairs of transactions. Since exactly the same information is needed, + * they are also used to record possible unsafe transaction relationships + * for purposes of identifying safe snapshots for read-only transactions. + * + * When a RWConflictData is not in use to record either type of relationship + * between a pair of transactions, it is kept on an "available" list. The + * outLink field is used for maintaining that list. + */ +typedef struct RWConflictData +{ + dlist_node outLink; /* link for list of conflicts out from a sxact */ + dlist_node inLink; /* link for list of conflicts in to a sxact */ + SERIALIZABLEXACT *sxactOut; + SERIALIZABLEXACT *sxactIn; +} RWConflictData; + +typedef struct RWConflictData *RWConflict; + +#define RWConflictDataSize \ + ((Size)MAXALIGN(sizeof(RWConflictData))) + +typedef struct RWConflictPoolHeaderData +{ + dlist_head availableList; + RWConflict element; +} RWConflictPoolHeaderData; + +typedef struct RWConflictPoolHeaderData *RWConflictPoolHeader; + +#define RWConflictPoolHeaderDataSize \ + ((Size)MAXALIGN(sizeof(RWConflictPoolHeaderData))) + + +/* + * The SERIALIZABLEXIDTAG struct identifies an xid assigned to a serializable + * transaction or any of its subtransactions. + */ +typedef struct SERIALIZABLEXIDTAG +{ + TransactionId xid; +} SERIALIZABLEXIDTAG; + +/* + * The SERIALIZABLEXID struct provides a link from a TransactionId for a + * serializable transaction to the related SERIALIZABLEXACT record, even if + * the transaction has completed and its connection has been closed. + * + * These are created as new top level transaction IDs are first assigned to + * transactions which are participating in predicate locking. This may + * never happen for a particular transaction if it doesn't write anything. + * They are removed with their related serializable transaction objects. + * + * The SubTransGetTopmostTransaction method is used where necessary to get + * from an XID which might be from a subtransaction to the top level XID. + */ +typedef struct SERIALIZABLEXID +{ + /* hash key */ + SERIALIZABLEXIDTAG tag; + + /* data */ + SERIALIZABLEXACT *myXact; /* pointer to the top level transaction data */ +} SERIALIZABLEXID; + + +/* + * The PREDICATELOCKTARGETTAG struct identifies a database object which can + * be the target of predicate locks. + * + * Note that the hash function being used doesn't properly respect tag + * length -- if the length of the structure isn't a multiple of four bytes it + * will go to a four byte boundary past the end of the tag. If you change + * this struct, make sure any slack space is initialized, so that any random + * bytes in the middle or at the end are not included in the hash. + * + * TODO SSI: If we always use the same fields for the same type of value, we + * should rename these. Holding off until it's clear there are no exceptions. + * Since indexes are relations with blocks and tuples, it's looking likely that + * the rename will be possible. If not, we may need to divide the last field + * and use part of it for a target type, so that we know how to interpret the + * data.. + */ +typedef struct PREDICATELOCKTARGETTAG +{ + uint32 locktag_field1; /* a 32-bit ID field */ + uint32 locktag_field2; /* a 32-bit ID field */ + uint32 locktag_field3; /* a 32-bit ID field */ + uint32 locktag_field4; /* a 32-bit ID field */ +} PREDICATELOCKTARGETTAG; + +/* + * The PREDICATELOCKTARGET struct represents a database object on which there + * are predicate locks. + * + * A hash list of these objects is maintained in shared memory. An entry is + * added when a predicate lock is requested on an object which doesn't + * already have one. An entry is removed when the last lock is removed from + * its list. + */ +typedef struct PREDICATELOCKTARGET +{ + /* hash key */ + PREDICATELOCKTARGETTAG tag; /* unique identifier of lockable object */ + + /* data */ + dlist_head predicateLocks; /* list of PREDICATELOCK objects assoc. with + * predicate lock target */ +} PREDICATELOCKTARGET; + + +/* + * The PREDICATELOCKTAG struct identifies an individual predicate lock. + * + * It is the combination of predicate lock target (which is a lockable + * object) and a serializable transaction which has acquired a lock on that + * target. + */ +typedef struct PREDICATELOCKTAG +{ + PREDICATELOCKTARGET *myTarget; + SERIALIZABLEXACT *myXact; +} PREDICATELOCKTAG; + +/* + * The PREDICATELOCK struct represents an individual lock. + * + * An entry can be created here when the related database object is read, or + * by promotion of multiple finer-grained targets. All entries related to a + * serializable transaction are removed when that serializable transaction is + * cleaned up. Entries can also be removed when they are combined into a + * single coarser-grained lock entry. + */ +typedef struct PREDICATELOCK +{ + /* hash key */ + PREDICATELOCKTAG tag; /* unique identifier of lock */ + + /* data */ + dlist_node targetLink; /* list link in PREDICATELOCKTARGET's list of + * predicate locks */ + dlist_node xactLink; /* list link in SERIALIZABLEXACT's list of + * predicate locks */ + SerCommitSeqNo commitSeqNo; /* only used for summarized predicate locks */ +} PREDICATELOCK; + + +/* + * The LOCALPREDICATELOCK struct represents a local copy of data which is + * also present in the PREDICATELOCK table, organized for fast access without + * needing to acquire a LWLock. It is strictly for optimization. + * + * Each serializable transaction creates its own local hash table to hold a + * collection of these. This information is used to determine when a number + * of fine-grained locks should be promoted to a single coarser-grained lock. + * The information is maintained more-or-less in parallel to the + * PREDICATELOCK data, but because this data is not protected by locks and is + * only used in an optimization heuristic, it is allowed to drift in a few + * corner cases where maintaining exact data would be expensive. + * + * The hash table is created when the serializable transaction acquires its + * snapshot, and its memory is released upon completion of the transaction. + */ +typedef struct LOCALPREDICATELOCK +{ + /* hash key */ + PREDICATELOCKTARGETTAG tag; /* unique identifier of lockable object */ + + /* data */ + bool held; /* is lock held, or just its children? */ + int childLocks; /* number of child locks currently held */ +} LOCALPREDICATELOCK; + + +/* + * The types of predicate locks which can be acquired. + */ +typedef enum PredicateLockTargetType +{ + PREDLOCKTAG_RELATION, + PREDLOCKTAG_PAGE, + PREDLOCKTAG_TUPLE + /* TODO SSI: Other types may be needed for index locking */ +} PredicateLockTargetType; + + +/* + * This structure is used to quickly capture a copy of all predicate + * locks. This is currently used only by the pg_lock_status function, + * which in turn is used by the pg_locks view. + */ +typedef struct PredicateLockData +{ + int nelements; + PREDICATELOCKTARGETTAG *locktags; + SERIALIZABLEXACT *xacts; +} PredicateLockData; + + +/* + * These macros define how we map logical IDs of lockable objects into the + * physical fields of PREDICATELOCKTARGETTAG. Use these to set up values, + * rather than accessing the fields directly. Note multiple eval of target! + */ +#define SET_PREDICATELOCKTARGETTAG_RELATION(locktag,dboid,reloid) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (reloid), \ + (locktag).locktag_field3 = InvalidBlockNumber, \ + (locktag).locktag_field4 = InvalidOffsetNumber) + +#define SET_PREDICATELOCKTARGETTAG_PAGE(locktag,dboid,reloid,blocknum) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (reloid), \ + (locktag).locktag_field3 = (blocknum), \ + (locktag).locktag_field4 = InvalidOffsetNumber) + +#define SET_PREDICATELOCKTARGETTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \ + ((locktag).locktag_field1 = (dboid), \ + (locktag).locktag_field2 = (reloid), \ + (locktag).locktag_field3 = (blocknum), \ + (locktag).locktag_field4 = (offnum)) + +#define GET_PREDICATELOCKTARGETTAG_DB(locktag) \ + ((Oid) (locktag).locktag_field1) +#define GET_PREDICATELOCKTARGETTAG_RELATION(locktag) \ + ((Oid) (locktag).locktag_field2) +#define GET_PREDICATELOCKTARGETTAG_PAGE(locktag) \ + ((BlockNumber) (locktag).locktag_field3) +#define GET_PREDICATELOCKTARGETTAG_OFFSET(locktag) \ + ((OffsetNumber) (locktag).locktag_field4) +#define GET_PREDICATELOCKTARGETTAG_TYPE(locktag) \ + (((locktag).locktag_field4 != InvalidOffsetNumber) ? PREDLOCKTAG_TUPLE : \ + (((locktag).locktag_field3 != InvalidBlockNumber) ? PREDLOCKTAG_PAGE : \ + PREDLOCKTAG_RELATION)) + +/* + * Two-phase commit statefile records. There are two types: for each + * transaction, we generate one per-transaction record and a variable + * number of per-predicate-lock records. + */ +typedef enum TwoPhasePredicateRecordType +{ + TWOPHASEPREDICATERECORD_XACT, + TWOPHASEPREDICATERECORD_LOCK +} TwoPhasePredicateRecordType; + +/* + * Per-transaction information to reconstruct a SERIALIZABLEXACT. Not + * much is needed because most of it not meaningful for a recovered + * prepared transaction. + * + * In particular, we do not record the in and out conflict lists for a + * prepared transaction because the associated SERIALIZABLEXACTs will + * not be available after recovery. Instead, we simply record the + * existence of each type of conflict by setting the transaction's + * summary conflict in/out flag. + */ +typedef struct TwoPhasePredicateXactRecord +{ + TransactionId xmin; + uint32 flags; +} TwoPhasePredicateXactRecord; + +/* Per-lock state */ +typedef struct TwoPhasePredicateLockRecord +{ + PREDICATELOCKTARGETTAG target; + uint32 filler; /* to avoid length change in back-patched fix */ +} TwoPhasePredicateLockRecord; + +typedef struct TwoPhasePredicateRecord +{ + TwoPhasePredicateRecordType type; + union + { + TwoPhasePredicateXactRecord xactRecord; + TwoPhasePredicateLockRecord lockRecord; + } data; +} TwoPhasePredicateRecord; + +/* + * Define a macro to use for an "empty" SERIALIZABLEXACT reference. + */ +#define InvalidSerializableXact ((SERIALIZABLEXACT *) NULL) + + +/* + * Function definitions for functions needing awareness of predicate + * locking internals. + */ +extern PredicateLockData *GetPredicateLockStatusData(void); +extern int GetSafeSnapshotBlockingPids(int blocked_pid, + int *output, int output_size); + +#endif /* PREDICATE_INTERNALS_H */ diff --git a/install/include/postgresql/server/storage/proc.h b/install/include/postgresql/server/storage/proc.h new file mode 100644 index 00000000000..cc0d4924ec4 --- /dev/null +++ b/install/include/postgresql/server/storage/proc.h @@ -0,0 +1,542 @@ +/*------------------------------------------------------------------------- + * + * proc.h + * per-process shared memory data structures + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/proc.h + * + *------------------------------------------------------------------------- + */ +#ifndef _PROC_H_ +#define _PROC_H_ + +#include "access/clog.h" +#include "access/xlogdefs.h" +#include "lib/ilist.h" +#include "storage/latch.h" +#include "storage/lock.h" +#include "storage/pg_sema.h" +#include "storage/proclist_types.h" + +/* + * Each backend advertises up to PGPROC_MAX_CACHED_SUBXIDS TransactionIds + * for non-aborted subtransactions of its current top transaction. These + * have to be treated as running XIDs by other backends. + * + * We also keep track of whether the cache overflowed (ie, the transaction has + * generated at least one subtransaction that didn't fit in the cache). + * If none of the caches have overflowed, we can assume that an XID that's not + * listed anywhere in the PGPROC array is not a running transaction. Else we + * have to look at pg_subtrans. + * + * See src/test/isolation/specs/subxid-overflow.spec if you change this. + */ +#define PGPROC_MAX_CACHED_SUBXIDS 64 /* XXX guessed-at value */ + +typedef struct XidCacheStatus { + /* number of cached subxids, never more than PGPROC_MAX_CACHED_SUBXIDS */ + uint8 count; + /* has PGPROC->subxids overflowed */ + bool overflowed; +} XidCacheStatus; + +struct XidCache { + TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]; +}; + +/* + * Flags for PGPROC->statusFlags and PROC_HDR->statusFlags[] + */ +#define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */ +#define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */ +#define PROC_IN_SAFE_IC \ + 0x04 /* currently running CREATE INDEX + * CONCURRENTLY or REINDEX + * CONCURRENTLY on non-expressional, + * non-partial index */ +#define PROC_VACUUM_FOR_WRAPAROUND 0x08 /* set by autovac only */ +#define PROC_IN_LOGICAL_DECODING \ + 0x10 /* currently doing logical + * decoding outside xact */ +#define PROC_AFFECTS_ALL_HORIZONS \ + 0x20 /* this proc's xmin must be + * included in vacuum horizons + * in all databases */ + +/* flags reset at EOXact */ +#define PROC_VACUUM_STATE_MASK (PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND) + +/* + * Xmin-related flags. Make sure any flags that affect how the process' Xmin + * value is interpreted by VACUUM are included here. + */ +#define PROC_XMIN_FLAGS (PROC_IN_VACUUM | PROC_IN_SAFE_IC) + +/* + * We allow a small number of "weak" relation locks (AccessShareLock, + * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure + * rather than the main lock table. This eases contention on the lock + * manager LWLocks. See storage/lmgr/README for additional details. + */ +#define FP_LOCK_SLOTS_PER_BACKEND 16 + +/* + * An invalid pgprocno. Must be larger than the maximum number of PGPROC + * structures we could possibly have. See comments for MAX_BACKENDS. + */ +#define INVALID_PGPROCNO PG_INT32_MAX + +/* + * Flags for PGPROC.delayChkptFlags + * + * These flags can be used to delay the start or completion of a checkpoint + * for short periods. A flag is in effect if the corresponding bit is set in + * the PGPROC of any backend. + * + * For our purposes here, a checkpoint has three phases: (1) determine the + * location to which the redo pointer will be moved, (2) write all the + * data durably to disk, and (3) WAL-log the checkpoint. + * + * Setting DELAY_CHKPT_START prevents the system from moving from phase 1 + * to phase 2. This is useful when we are performing a WAL-logged modification + * of data that will be flushed to disk in phase 2. By setting this flag + * before writing WAL and clearing it after we've both written WAL and + * performed the corresponding modification, we ensure that if the WAL record + * is inserted prior to the new redo point, the corresponding data changes will + * also be flushed to disk before the checkpoint can complete. (In the + * extremely common case where the data being modified is in shared buffers + * and we acquire an exclusive content lock and MarkBufferDirty() on the + * relevant buffers before writing WAL, this mechanism is not needed, because + * phase 2 will block until we release the content lock and then flush the + * modified data to disk. See transam/README and SyncOneBuffer().) + * + * Setting DELAY_CHKPT_COMPLETE prevents the system from moving from phase 2 + * to phase 3. This is useful if we are performing a WAL-logged operation that + * might invalidate buffers, such as relation truncation. In this case, we need + * to ensure that any buffers which were invalidated and thus not flushed by + * the checkpoint are actually destroyed on disk. Replay can cope with a file + * or block that doesn't exist, but not with a block that has the wrong + * contents. + */ +#define DELAY_CHKPT_START (1 << 0) +#define DELAY_CHKPT_COMPLETE (1 << 1) + +typedef enum { + PROC_WAIT_STATUS_OK, + PROC_WAIT_STATUS_WAITING, + PROC_WAIT_STATUS_ERROR, +} ProcWaitStatus; + +/* + * Each backend has a PGPROC struct in shared memory. There is also a list of + * currently-unused PGPROC structs that will be reallocated to new backends. + * + * links: list link for any list the PGPROC is in. When waiting for a lock, + * the PGPROC is linked into that lock's waitProcs queue. A recycled PGPROC + * is linked into ProcGlobal's freeProcs list. + * + * Note: twophase.c also sets up a dummy PGPROC struct for each currently + * prepared transaction. These PGPROCs appear in the ProcArray data structure + * so that the prepared transactions appear to be still running and are + * correctly shown as holding locks. A prepared transaction PGPROC can be + * distinguished from a real one at need by the fact that it has pid == 0. + * The semaphore and lock-activity fields in a prepared-xact PGPROC are unused, + * but its myProcLocks[] lists are valid. + * + * We allow many fields of this struct to be accessed without locks, such as + * delayChkptFlags and isBackgroundWorker. However, keep in mind that writing + * mirrored ones (see below) requires holding ProcArrayLock or XidGenLock in + * at least shared mode, so that pgxactoff does not change concurrently. + * + * Mirrored fields: + * + * Some fields in PGPROC (see "mirrored in ..." comment) are mirrored into an + * element of more densely packed ProcGlobal arrays. These arrays are indexed + * by PGPROC->pgxactoff. Both copies need to be maintained coherently. + * + * NB: The pgxactoff indexed value can *never* be accessed without holding + * locks. + * + * See PROC_HDR for details. + */ +struct PGPROC { + /* proc->links MUST BE FIRST IN STRUCT (see ProcSleep,ProcWakeup,etc) */ + dlist_node links; /* list link if process is in a list */ + dlist_head *procgloballist; /* procglobal list that owns this PGPROC */ + + PGSemaphore sem; /* ONE semaphore to sleep on */ + ProcWaitStatus waitStatus; + + Latch procLatch; /* generic latch for process */ + + + TransactionId xid; /* id of top-level transaction currently being + * executed by this proc, if running and XID + * is assigned; else InvalidTransactionId. + * mirrored in ProcGlobal->xids[pgxactoff] */ + + TransactionId xmin; /* minimal running XID as it was when we were + * starting our xact, excluding LAZY VACUUM: + * vacuum must not remove tuples deleted by + * xid >= xmin ! */ + + LocalTransactionId lxid; /* local id of top-level transaction currently + * being executed by this proc, if running; + * else InvalidLocalTransactionId */ + int pid; /* Backend's process ID; 0 if prepared xact */ + + int pgxactoff; /* offset into various ProcGlobal->arrays with + * data mirrored from this PGPROC */ + + int pgprocno; /* Number of this PGPROC in + * ProcGlobal->allProcs array. This is set + * once by InitProcGlobal(). + * ProcGlobal->allProcs[n].pgprocno == n */ + + /* These fields are zero while a backend is still starting up: */ + BackendId backendId; /* This backend's backend ID (if assigned) */ + Oid databaseId; /* OID of database this backend is using */ + Oid roleId; /* OID of role using this backend */ + + Oid tempNamespaceId; /* OID of temp schema this backend is + * using */ + + bool isBackgroundWorker; /* true if not a regular backend. */ + + /* + * While in hot standby mode, shows that a conflict signal has been sent + * for the current transaction. Set/cleared while holding ProcArrayLock, + * though not required. Accessed without lock, if needed. + */ + bool recoveryConflictPending; + + /* Info about LWLock the process is currently waiting for, if any. */ + uint8 lwWaiting; /* see LWLockWaitState */ + uint8 lwWaitMode; /* lwlock mode being waited for */ + proclist_node lwWaitLink; /* position in LW lock wait list */ + + /* Support for condition variables. */ + proclist_node cvWaitLink; /* position in CV wait list */ + + /* Info about lock the process is currently waiting for, if any. */ + /* waitLock and waitProcLock are NULL if not currently waiting. */ + LOCK *waitLock; /* Lock object we're sleeping on ... */ + PROCLOCK *waitProcLock; /* Per-holder info for awaited lock */ + LOCKMODE waitLockMode; /* type of lock we're waiting for */ + LOCKMASK heldLocks; /* bitmask for lock types already held on this + * lock object by this backend */ + pg_atomic_uint64 waitStart; /* time at which wait for lock acquisition + * started */ + + int delayChkptFlags; /* for DELAY_CHKPT_* flags */ + + uint8 statusFlags; /* this backend's status flags, see PROC_* + * above. mirrored in + * ProcGlobal->statusFlags[pgxactoff] */ + + /* + * Info to allow us to wait for synchronous replication, if needed. + * waitLSN is InvalidXLogRecPtr if not waiting; set only by user backend. + * syncRepState must not be touched except by owning process or WALSender. + * syncRepLinks used only while holding SyncRepLock. + */ + XLogRecPtr waitLSN; /* waiting for this LSN or higher */ + int syncRepState; /* wait state for sync rep */ + dlist_node syncRepLinks; /* list link if process is in syncrep queue */ + + /* + * All PROCLOCK objects for locks held or awaited by this backend are + * linked into one of these lists, according to the partition number of + * their lock. + */ + dlist_head myProcLocks[NUM_LOCK_PARTITIONS]; + + XidCacheStatus subxidStatus; /* mirrored with + * ProcGlobal->subxidStates[i] */ + struct XidCache subxids; /* cache for subtransaction XIDs */ + + /* Support for group XID clearing. */ + /* true, if member of ProcArray group waiting for XID clear */ + bool procArrayGroupMember; + /* next ProcArray group member waiting for XID clear */ + pg_atomic_uint32 procArrayGroupNext; + + /* + * latest transaction id among the transaction's main XID and + * subtransactions + */ + TransactionId procArrayGroupMemberXid; + + uint32 wait_event_info; /* proc's wait information */ + + /* Support for group transaction status update. */ + bool clogGroupMember; /* true, if member of clog group */ + pg_atomic_uint32 clogGroupNext; /* next clog group member */ + TransactionId clogGroupMemberXid; /* transaction id of clog group member */ + XidStatus clogGroupMemberXidStatus; /* transaction status of clog + * group member */ + int clogGroupMemberPage; /* clog page corresponding to + * transaction id of clog group member */ + XLogRecPtr clogGroupMemberLsn; /* WAL location of commit record for clog + * group member */ + + /* Lock manager data, recording fast-path locks taken by this backend. */ + LWLock fpInfoLock; /* protects per-backend fast-path state */ + uint64 fpLockBits; /* lock modes held for each fast-path slot */ + Oid fpRelId[FP_LOCK_SLOTS_PER_BACKEND]; /* slots for rel oids */ + bool fpVXIDLock; /* are we holding a fast-path VXID lock? */ + LocalTransactionId fpLocalTransactionId; /* lxid for fast-path VXID + * lock */ + + /* + * Support for lock groups. Use LockHashPartitionLockByProc on the group + * leader to get the LWLock protecting these fields. + */ + PGPROC *lockGroupLeader; /* lock group leader, if I'm a member */ + dlist_head lockGroupMembers; /* list of members, if I'm a leader */ + dlist_node lockGroupLink; /* my member link, if I'm a member */ + + /* + * spec-2.17 P1.7 — cluster GRD target generation(防 stale BAST/CANCEL + * 误打到复用 procno 的新 backend). InitProcess() atomic fetch_add 1 + * from ClusterGrdShared.next_generation. 0 reserved sentinel(0 = + * uninitialized;真值从 1 开始). + */ + uint64 cluster_grd_generation; + + /* + * spec-2.17 Q10 + I85 — BAST advisory flag. BAST handler 仅标 + * (0 主动 release);naturally 等 canonical LockRelease/LockReleaseAll + * 自然路径 → LOCALLOCK refcount 0 → 7-step state machine release + * path 补发 GES_RELEASE. + */ + bool cluster_grd_bast_pending; + + /* + * spec-4.6 D3 — cooperative holder-rebind barrier ack. This backend + * has rebound ALL its cluster_registered LOCALLOCKs to the current + * accepted epoch for redeclare generation <= this value. Written by + * the owning backend (ProcessInterrupts redeclare pass), read by + * LMON's barrier check. InitProcess seeds it with the CURRENT + * redeclare generation: a backend born after the broadcast holds no + * stale-epoch grants and must not block the barrier. + */ + pg_atomic_uint64 cluster_grd_redeclare_acked; + + /* + * spec-4.6 P0-1 (Fable review) — the epoch this backend's rebind ack + * is coherent with. Written together with cluster_grd_redeclare_acked + * by the redeclare walker (the holder was stamped with this epoch). + * LMON's barrier accepts an ack ONLY when this matches the locked + * episode epoch, so a mid-episode epoch bump cannot let a holder + * rebound under the old epoch satisfy the barrier for the new one. + */ + pg_atomic_uint64 cluster_grd_redeclare_acked_epoch; + + /* + * spec-4.6 D3 — live count of this backend's cluster_registered + * LOCALLOCKs (S5 promote ++ / S6 release --). The rebind barrier + * skips procs with count == 0: they hold nothing to rebind, and + * sinval-registered processes that never run the generic + * ProcessInterrupts path (e.g. the autovacuum launcher) would + * otherwise wedge the barrier forever. + */ + pg_atomic_uint32 cluster_grd_registered_count; + + /* + * spec-3.12 D1 — undo/TT-slot retention horizon. Min CLUSTER-source + * read_scn over this backend's live snapshots (active stack + registered); + * InvalidScn when this backend holds no live cluster snapshot. Published in + * snapmgr (GetSnapshotData / recompute on push/pop/register/unregister) and + * cleared at xact end; cluster_undo_retention_horizon() scans the ProcArray + * for the min of these to gate undo/TT-slot recycle. Atomic because SCN is + * 64-bit and snapmgr updates happen outside ProcArrayLock (mirrors xmin but + * torn-read-safe). + */ + pg_atomic_uint64 cluster_read_scn_atomic; +}; + +/* NOTE: "typedef struct PGPROC PGPROC" appears in storage/lock.h. */ + + +extern PGDLLIMPORT PGPROC *MyProc; + +/* + * There is one ProcGlobal struct for the whole database cluster. + * + * Adding/Removing an entry into the procarray requires holding *both* + * ProcArrayLock and XidGenLock in exclusive mode (in that order). Both are + * needed because the dense arrays (see below) are accessed from + * GetNewTransactionId() and GetSnapshotData(), and we don't want to add + * further contention by both using the same lock. Adding/Removing a procarray + * entry is much less frequent. + * + * Some fields in PGPROC are mirrored into more densely packed arrays (e.g. + * xids), with one entry for each backend. These arrays only contain entries + * for PGPROCs that have been added to the shared array with ProcArrayAdd() + * (in contrast to PGPROC array which has unused PGPROCs interspersed). + * + * The dense arrays are indexed by PGPROC->pgxactoff. Any concurrent + * ProcArrayAdd() / ProcArrayRemove() can lead to pgxactoff of a procarray + * member to change. Therefore it is only safe to use PGPROC->pgxactoff to + * access the dense array while holding either ProcArrayLock or XidGenLock. + * + * As long as a PGPROC is in the procarray, the mirrored values need to be + * maintained in both places in a coherent manner. + * + * The denser separate arrays are beneficial for three main reasons: First, to + * allow for as tight loops accessing the data as possible. Second, to prevent + * updates of frequently changing data (e.g. xmin) from invalidating + * cachelines also containing less frequently changing data (e.g. xid, + * statusFlags). Third to condense frequently accessed data into as few + * cachelines as possible. + * + * There are two main reasons to have the data mirrored between these dense + * arrays and PGPROC. First, as explained above, a PGPROC's array entries can + * only be accessed with either ProcArrayLock or XidGenLock held, whereas the + * PGPROC entries do not require that (obviously there may still be locking + * requirements around the individual field, separate from the concerns + * here). That is particularly important for a backend to efficiently checks + * it own values, which it often can safely do without locking. Second, the + * PGPROC fields allow to avoid unnecessary accesses and modification to the + * dense arrays. A backend's own PGPROC is more likely to be in a local cache, + * whereas the cachelines for the dense array will be modified by other + * backends (often removing it from the cache for other cores/sockets). At + * commit/abort time a check of the PGPROC value can avoid accessing/dirtying + * the corresponding array value. + * + * Basically it makes sense to access the PGPROC variable when checking a + * single backend's data, especially when already looking at the PGPROC for + * other reasons already. It makes sense to look at the "dense" arrays if we + * need to look at many / most entries, because we then benefit from the + * reduced indirection and better cross-process cache-ability. + * + * When entering a PGPROC for 2PC transactions with ProcArrayAdd(), the data + * in the dense arrays is initialized from the PGPROC while it already holds + * ProcArrayLock. + */ +typedef struct PROC_HDR { + /* Array of PGPROC structures (not including dummies for prepared txns) */ + PGPROC *allProcs; + + /* Array mirroring PGPROC.xid for each PGPROC currently in the procarray */ + TransactionId *xids; + + /* + * Array mirroring PGPROC.subxidStatus for each PGPROC currently in the + * procarray. + */ + XidCacheStatus *subxidStates; + + /* + * Array mirroring PGPROC.statusFlags for each PGPROC currently in the + * procarray. + */ + uint8 *statusFlags; + + /* Length of allProcs array */ + uint32 allProcCount; + /* Head of list of free PGPROC structures */ + dlist_head freeProcs; + /* Head of list of autovacuum's free PGPROC structures */ + dlist_head autovacFreeProcs; + /* Head of list of bgworker free PGPROC structures */ + dlist_head bgworkerFreeProcs; + /* Head of list of walsender free PGPROC structures */ + dlist_head walsenderFreeProcs; + /* First pgproc waiting for group XID clear */ + pg_atomic_uint32 procArrayGroupFirst; + /* First pgproc waiting for group transaction status update */ + pg_atomic_uint32 clogGroupFirst; + /* WALWriter process's latch */ + Latch *walwriterLatch; + /* Checkpointer process's latch */ + Latch *checkpointerLatch; + /* Current shared estimate of appropriate spins_per_delay value */ + int spins_per_delay; + /* Buffer id of the buffer that Startup process waits for pin on, or -1 */ + int startupBufferPinWaitBufId; +} PROC_HDR; + +extern PGDLLIMPORT PROC_HDR *ProcGlobal; + +extern PGDLLIMPORT PGPROC *PreparedXactProcs; + +/* Accessor for PGPROC given a pgprocno. */ +#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)]) + +/* + * We set aside some extra PGPROC structures for auxiliary processes, + * ie things that aren't full-fledged backends but need shmem access. + * + * Background writer, checkpointer, WAL writer and archiver run during normal + * operation. Startup process and WAL receiver also consume 2 slots, but WAL + * writer is launched only after startup has exited, so PG-vanilla needs 5. + * + * PGRAC: with --enable-cluster builds we add 7 more aux processes that all + * coexist with WalWriter / BgWriter / Checkpointer at PM_RUN: LMON + * (spec-1.11), LCK (spec-1.12), DIAG (spec-1.13), Cluster Stats + * (spec-1.14), CSSD (spec-2.5), QVOTEC (spec-2.6), LMS (spec-2.18), + * LMD (spec-2.19). Bump the slot reserve to 14 (PG 5 + cluster 8 + 1 slack) + * so we never trip "all AuxiliaryProcs are in use". Stage 2+ adds Sinval + * Broadcaster, Recovery Coordinator, etc. — bump again then. + * + * I11 invariant (spec-2.18 / spec-2.19): NUM_AUXILIARY_PROCS MUST be ≥ + * AuxProcType_Last + PG aux process count. The guard is a REAL + * StaticAssertDecl(NUM_AUXILIARY_PROCS >= NUM_AUXPROCTYPES) in + * auxprocess.c (spec-3.13 β: the spec-2.18 comment promised it but never + * landed it — the 3.13 UndoCleaner append overflowed the aux PGPROC / + * backend-status arrays and segfaulted pgstat_bestart at runtime). + * (L18 startup-time validation family). + */ +#ifdef USE_PGRAC_CLUSTER +#define NUM_AUXILIARY_PROCS 16 /* spec-3.13 D1: +UndoCleanerProcess (was 15 spec-2.38) */ +#else +#define NUM_AUXILIARY_PROCS 5 +#endif + +/* configurable options */ +extern PGDLLIMPORT int DeadlockTimeout; +extern PGDLLIMPORT int StatementTimeout; +extern PGDLLIMPORT int LockTimeout; +extern PGDLLIMPORT int IdleInTransactionSessionTimeout; +extern PGDLLIMPORT int IdleSessionTimeout; +extern PGDLLIMPORT bool log_lock_waits; + + +/* + * Function Prototypes + */ +extern int ProcGlobalSemas(void); +extern Size ProcGlobalShmemSize(void); +extern void InitProcGlobal(void); +extern void InitProcess(void); +extern void InitProcessPhase2(void); +extern void InitAuxiliaryProcess(void); + +extern void SetStartupBufferPinWaitBufId(int bufid); +extern int GetStartupBufferPinWaitBufId(void); + +extern bool HaveNFreeProcs(int n, int *nfree); +extern void ProcReleaseLocks(bool isCommit); + +extern ProcWaitStatus ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable); +extern void ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus); +extern void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock); +extern void CheckDeadLockAlert(void); +extern bool IsWaitingForLock(void); +extern void LockErrorCleanup(void); + +extern void ProcWaitForSignal(uint32 wait_event_info); +extern void ProcSendSignal(int pgprocno); + +extern PGPROC *AuxiliaryPidGetProc(int pid); + +extern void BecomeLockGroupLeader(void); +extern bool BecomeLockGroupMember(PGPROC *leader, int pid); + +#endif /* _PROC_H_ */ diff --git a/install/include/postgresql/server/storage/procarray.h b/install/include/postgresql/server/storage/procarray.h new file mode 100644 index 00000000000..d8cae3ce1c5 --- /dev/null +++ b/install/include/postgresql/server/storage/procarray.h @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------- + * + * procarray.h + * POSTGRES process array definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/procarray.h + * + *------------------------------------------------------------------------- + */ +#ifndef PROCARRAY_H +#define PROCARRAY_H + +#include "storage/lock.h" +#include "storage/standby.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + + +extern Size ProcArrayShmemSize(void); +extern void CreateSharedProcArray(void); +extern void ProcArrayAdd(PGPROC *proc); +extern void ProcArrayRemove(PGPROC *proc, TransactionId latestXid); + +extern void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid); +extern void ProcArrayClearTransaction(PGPROC *proc); + +extern void ProcArrayInitRecovery(TransactionId initializedUptoXID); +extern void ProcArrayApplyRecoveryInfo(RunningTransactions running); +extern void ProcArrayApplyXidAssignment(TransactionId topxid, + int nsubxids, TransactionId *subxids); + +extern void RecordKnownAssignedTransactionIds(TransactionId xid); +extern void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, + int nsubxids, TransactionId *subxids, + TransactionId max_xid); +extern void ExpireAllKnownAssignedTransactionIds(void); +extern void ExpireOldKnownAssignedTransactionIds(TransactionId xid); +extern void KnownAssignedTransactionIdsIdleMaintenance(void); + +extern int GetMaxSnapshotXidCount(void); +extern int GetMaxSnapshotSubxidCount(void); + +extern Snapshot GetSnapshotData(Snapshot snapshot); + +extern bool ProcArrayInstallImportedXmin(TransactionId xmin, + VirtualTransactionId *sourcevxid); +extern bool ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc); + +extern RunningTransactions GetRunningTransactionData(void); + +extern bool TransactionIdIsInProgress(TransactionId xid); +extern bool TransactionIdIsActive(TransactionId xid); +extern TransactionId GetOldestNonRemovableTransactionId(Relation rel); +extern TransactionId GetOldestTransactionIdConsideredRunning(void); +extern TransactionId GetOldestActiveTransactionId(void); +extern TransactionId GetOldestSafeDecodingTransactionId(bool catalogOnly); +extern void GetReplicationHorizons(TransactionId *xmin, TransactionId *catalog_xmin); + +extern VirtualTransactionId *GetVirtualXIDsDelayingChkpt(int *nvxids, int type); +extern bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, + int nvxids, int type); + +extern PGPROC *BackendPidGetProc(int pid); +extern PGPROC *BackendPidGetProcWithLock(int pid); +extern int BackendXidGetPid(TransactionId xid); +extern bool IsBackendPid(int pid); + +extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin, + bool excludeXmin0, bool allDbs, int excludeVacuum, + int *nvxids); +extern VirtualTransactionId *GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid); +extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode); +extern pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, + bool conflictPending); + +extern bool MinimumActiveBackends(int min); +extern int CountDBBackends(Oid databaseid); +extern int CountDBConnections(Oid databaseid); +extern void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending); +extern int CountUserBackends(Oid roleid); +extern bool CountOtherDBBackends(Oid databaseId, + int *nbackends, int *nprepared); +extern void TerminateOtherDBBackends(Oid databaseId); + +extern void XidCacheRemoveRunningXids(TransactionId xid, + int nxids, const TransactionId *xids, + TransactionId latestXid); + +extern void ProcArraySetReplicationSlotXmin(TransactionId xmin, + TransactionId catalog_xmin, bool already_locked); + +extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin, + TransactionId *catalog_xmin); + +#endif /* PROCARRAY_H */ diff --git a/install/include/postgresql/server/storage/proclist.h b/install/include/postgresql/server/storage/proclist.h new file mode 100644 index 00000000000..e7d00e5ce12 --- /dev/null +++ b/install/include/postgresql/server/storage/proclist.h @@ -0,0 +1,219 @@ +/*------------------------------------------------------------------------- + * + * proclist.h + * operations on doubly-linked lists of pgprocnos + * + * The interface is similar to dlist from ilist.h, but uses pgprocno instead + * of pointers. This allows proclist_head to be mapped at different addresses + * in different backends. + * + * See proclist_types.h for the structs that these functions operate on. They + * are separated to break a header dependency cycle with proc.h. + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/storage/proclist.h + *------------------------------------------------------------------------- + */ +#ifndef PROCLIST_H +#define PROCLIST_H + +#include "storage/proc.h" +#include "storage/proclist_types.h" + +/* + * Initialize a proclist. + */ +static inline void +proclist_init(proclist_head *list) +{ + list->head = list->tail = INVALID_PGPROCNO; +} + +/* + * Is the list empty? + */ +static inline bool +proclist_is_empty(const proclist_head *list) +{ + return list->head == INVALID_PGPROCNO; +} + +/* + * Get a pointer to a proclist_node inside a given PGPROC, given a procno and + * the proclist_node field's offset within struct PGPROC. + */ +static inline proclist_node * +proclist_node_get(int procno, size_t node_offset) +{ + char *entry = (char *) GetPGProcByNumber(procno); + + return (proclist_node *) (entry + node_offset); +} + +/* + * Insert a process at the beginning of a list. + */ +static inline void +proclist_push_head_offset(proclist_head *list, int procno, size_t node_offset) +{ + proclist_node *node = proclist_node_get(procno, node_offset); + + Assert(node->next == 0 && node->prev == 0); + + if (list->head == INVALID_PGPROCNO) + { + Assert(list->tail == INVALID_PGPROCNO); + node->next = node->prev = INVALID_PGPROCNO; + list->head = list->tail = procno; + } + else + { + Assert(list->tail != INVALID_PGPROCNO); + Assert(list->head != procno); + Assert(list->tail != procno); + node->next = list->head; + proclist_node_get(node->next, node_offset)->prev = procno; + node->prev = INVALID_PGPROCNO; + list->head = procno; + } +} + +/* + * Insert a process at the end of a list. + */ +static inline void +proclist_push_tail_offset(proclist_head *list, int procno, size_t node_offset) +{ + proclist_node *node = proclist_node_get(procno, node_offset); + + Assert(node->next == 0 && node->prev == 0); + + if (list->tail == INVALID_PGPROCNO) + { + Assert(list->head == INVALID_PGPROCNO); + node->next = node->prev = INVALID_PGPROCNO; + list->head = list->tail = procno; + } + else + { + Assert(list->head != INVALID_PGPROCNO); + Assert(list->head != procno); + Assert(list->tail != procno); + node->prev = list->tail; + proclist_node_get(node->prev, node_offset)->next = procno; + node->next = INVALID_PGPROCNO; + list->tail = procno; + } +} + +/* + * Delete a process from a list --- it must be in the list! + */ +static inline void +proclist_delete_offset(proclist_head *list, int procno, size_t node_offset) +{ + proclist_node *node = proclist_node_get(procno, node_offset); + + Assert(node->next != 0 || node->prev != 0); + + if (node->prev == INVALID_PGPROCNO) + { + Assert(list->head == procno); + list->head = node->next; + } + else + proclist_node_get(node->prev, node_offset)->next = node->next; + + if (node->next == INVALID_PGPROCNO) + { + Assert(list->tail == procno); + list->tail = node->prev; + } + else + proclist_node_get(node->next, node_offset)->prev = node->prev; + + node->next = node->prev = 0; +} + +/* + * Check if a process is currently in a list. It must be known that the + * process is not in any _other_ proclist that uses the same proclist_node, + * so that the only possibilities are that it is in this list or none. + */ +static inline bool +proclist_contains_offset(const proclist_head *list, int procno, + size_t node_offset) +{ + const proclist_node *node = proclist_node_get(procno, node_offset); + + /* If it's not in any list, it's definitely not in this one. */ + if (node->prev == 0 && node->next == 0) + return false; + + /* + * It must, in fact, be in this list. Ideally, in assert-enabled builds, + * we'd verify that. But since this function is typically used while + * holding a spinlock, crawling the whole list is unacceptable. However, + * we can verify matters in O(1) time when the node is a list head or + * tail, and that seems worth doing, since in practice that should often + * be enough to catch mistakes. + */ + Assert(node->prev != INVALID_PGPROCNO || list->head == procno); + Assert(node->next != INVALID_PGPROCNO || list->tail == procno); + + return true; +} + +/* + * Remove and return the first process from a list (there must be one). + */ +static inline PGPROC * +proclist_pop_head_node_offset(proclist_head *list, size_t node_offset) +{ + PGPROC *proc; + + Assert(!proclist_is_empty(list)); + proc = GetPGProcByNumber(list->head); + proclist_delete_offset(list, list->head, node_offset); + return proc; +} + +/* + * Helper macros to avoid repetition of offsetof(PGPROC, ). + * 'link_member' is the name of a proclist_node member in PGPROC. + */ +#define proclist_delete(list, procno, link_member) \ + proclist_delete_offset((list), (procno), offsetof(PGPROC, link_member)) +#define proclist_push_head(list, procno, link_member) \ + proclist_push_head_offset((list), (procno), offsetof(PGPROC, link_member)) +#define proclist_push_tail(list, procno, link_member) \ + proclist_push_tail_offset((list), (procno), offsetof(PGPROC, link_member)) +#define proclist_pop_head_node(list, link_member) \ + proclist_pop_head_node_offset((list), offsetof(PGPROC, link_member)) +#define proclist_contains(list, procno, link_member) \ + proclist_contains_offset((list), (procno), offsetof(PGPROC, link_member)) + +/* + * Iterate through the list pointed at by 'lhead', storing the current + * position in 'iter'. 'link_member' is the name of a proclist_node member in + * PGPROC. Access the current position with iter.cur. + * + * The only list modification allowed while iterating is deleting the current + * node with proclist_delete(list, iter.cur, node_offset). + */ +#define proclist_foreach_modify(iter, lhead, link_member) \ + for (AssertVariableIsOfTypeMacro(iter, proclist_mutable_iter), \ + AssertVariableIsOfTypeMacro(lhead, proclist_head *), \ + (iter).cur = (lhead)->head, \ + (iter).next = (iter).cur == INVALID_PGPROCNO ? INVALID_PGPROCNO : \ + proclist_node_get((iter).cur, \ + offsetof(PGPROC, link_member))->next; \ + (iter).cur != INVALID_PGPROCNO; \ + (iter).cur = (iter).next, \ + (iter).next = (iter).cur == INVALID_PGPROCNO ? INVALID_PGPROCNO : \ + proclist_node_get((iter).cur, \ + offsetof(PGPROC, link_member))->next) + +#endif /* PROCLIST_H */ diff --git a/install/include/postgresql/server/storage/proclist_types.h b/install/include/postgresql/server/storage/proclist_types.h new file mode 100644 index 00000000000..526c3ea6f99 --- /dev/null +++ b/install/include/postgresql/server/storage/proclist_types.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * proclist_types.h + * doubly-linked lists of pgprocnos + * + * See proclist.h for functions that operate on these types. + * + * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/storage/proclist_types.h + *------------------------------------------------------------------------- + */ + +#ifndef PROCLIST_TYPES_H +#define PROCLIST_TYPES_H + +/* + * A node in a doubly-linked list of processes. The link fields contain + * the 0-based PGPROC indexes of the next and previous process, or + * INVALID_PGPROCNO in the next-link of the last node and the prev-link + * of the first node. A node that is currently not in any list + * should have next == prev == 0; this is not a possible state for a node + * that is in a list, because we disallow circularity. + */ +typedef struct proclist_node +{ + int next; /* pgprocno of the next PGPROC */ + int prev; /* pgprocno of the prev PGPROC */ +} proclist_node; + +/* + * Header of a doubly-linked list of PGPROCs, identified by pgprocno. + * An empty list is represented by head == tail == INVALID_PGPROCNO. + */ +typedef struct proclist_head +{ + int head; /* pgprocno of the head PGPROC */ + int tail; /* pgprocno of the tail PGPROC */ +} proclist_head; + +/* + * List iterator allowing some modifications while iterating. + */ +typedef struct proclist_mutable_iter +{ + int cur; /* pgprocno of the current PGPROC */ + int next; /* pgprocno of the next PGPROC */ +} proclist_mutable_iter; + +#endif /* PROCLIST_TYPES_H */ diff --git a/install/include/postgresql/server/storage/procsignal.h b/install/include/postgresql/server/storage/procsignal.h new file mode 100644 index 00000000000..1ca2489030c --- /dev/null +++ b/install/include/postgresql/server/storage/procsignal.h @@ -0,0 +1,124 @@ +/*------------------------------------------------------------------------- + * + * procsignal.h + * Routines for interprocess signaling + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/procsignal.h + * + *------------------------------------------------------------------------- + * + * PGRAC MODIFICATIONS + * Modified by: SqlRush + * Stage: 0.15 + 2.6 + * + * Stage 0.15 (initial): + * Extended ProcSignalReason with PROCSIG_CLUSTER_RECONFIG_START. + * Cluster reasons are appended at the end of the enum, guarded + * by #ifdef USE_PGRAC_CLUSTER, so PG's original 13 numeric + * positions are preserved and --disable-cluster builds remain + * byte-for-byte identical to upstream PG. + * + * Stage 2.6 + 2.28 (voting disk fail-closed + fence-lite): + * Added PROCSIG_CLUSTER_FREEZE_WRITES + PROCSIG_CLUSTER_THAW_ + * WRITES. LMON broadcasts these after observing QVOTEC quorum_state + * transitions; backend handlers set process-local sig_atomic_t flags for + * the spec-2.6 commit gate and the spec-2.28 ProcessInterrupts in-flight + * abort path. + * + * Stage 4.6 (recovery-aware GRD/GES remaster): + * Added PROCSIG_CLUSTER_GRD_REDECLARE. LMON broadcasts it after a + * failure-driven remaster; every live backend walks its OWN + * cluster_registered LOCALLOCKs at CFI and rebinds them to the + * current accepted epoch (cooperative holder rebuild, spec-4.6 D3). + * + * Each cluster reason is dispatched in + * src/backend/storage/ipc/procsignal.c::procsignal_sigusr1_handler + * to a handler — for stages 0.15+ in cluster_signal.c, for + * stage 2.6 inline (calls cluster_freeze_writes_set / _thaw_set + * in cluster_qvotec.c). See docs/cluster-signal-design.md and + * specs/spec-0.15-signal-framework.md / specs/spec-2.6-voting- + * disk-quorum-lite.md §3.2. + * + *------------------------------------------------------------------------- + */ +#ifndef PROCSIGNAL_H +#define PROCSIGNAL_H + +#include "storage/backendid.h" + + +/* + * Reasons for signaling a Postgres child process (a backend or an auxiliary + * process, like checkpointer). We can cope with concurrent signals for different + * reasons. However, if the same reason is signaled multiple times in quick + * succession, the process is likely to observe only one notification of it. + * This is okay for the present uses. + * + * Also, because of race conditions, it's important that all the signals be + * defined so that no harm is done if a process mistakenly receives one. + */ +typedef enum +{ + PROCSIG_CATCHUP_INTERRUPT, /* sinval catchup interrupt */ + PROCSIG_NOTIFY_INTERRUPT, /* listen/notify interrupt */ + PROCSIG_PARALLEL_MESSAGE, /* message from cooperating parallel backend */ + PROCSIG_WALSND_INIT_STOPPING, /* ask walsenders to prepare for shutdown */ + PROCSIG_BARRIER, /* global barrier interrupt */ + PROCSIG_LOG_MEMORY_CONTEXT, /* ask backend to log the memory contexts */ + PROCSIG_PARALLEL_APPLY_MESSAGE, /* Message from parallel apply workers */ + + /* Recovery conflict reasons */ + PROCSIG_RECOVERY_CONFLICT_DATABASE, + PROCSIG_RECOVERY_CONFLICT_TABLESPACE, + PROCSIG_RECOVERY_CONFLICT_LOCK, + PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, + PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT, + PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, + PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, + +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC: cluster ProcSignalReasons (stage 0.15+). + * Appended after PG-native values to preserve the 0..13 numeric + * positions for ABI compatibility. Handlers live in + * src/backend/cluster/cluster_signal.c. See + * docs/cluster-signal-design.md §3 for the full registration + * roster and reservation policy. + */ + PROCSIG_CLUSTER_RECONFIG_START, /* LMON: cluster reconfig starting */ + PROCSIG_CLUSTER_FREEZE_WRITES, /* spec-2.6: qvotec quorum loss → fail-closed */ + PROCSIG_CLUSTER_THAW_WRITES, /* spec-2.6: qvotec quorum recover → resume */ + PROCSIG_CLUSTER_GES_BAST, /* spec-2.17 Q8: BAST advisory notify */ + PROCSIG_CLUSTER_GES_CANCEL, /* spec-2.17 Q9: CANCEL wait/grant */ + PROCSIG_CLUSTER_GRD_REDECLARE, /* spec-4.6 D3: cooperative holder rebind */ +#endif + + NUM_PROCSIGNALS /* Must be last! */ +} ProcSignalReason; + +typedef enum +{ + PROCSIGNAL_BARRIER_SMGRRELEASE /* ask smgr to close files */ +} ProcSignalBarrierType; + +/* + * prototypes for functions in procsignal.c + */ +extern Size ProcSignalShmemSize(void); +extern void ProcSignalShmemInit(void); + +extern void ProcSignalInit(int pss_idx); +extern int SendProcSignal(pid_t pid, ProcSignalReason reason, + BackendId backendId); + +extern uint64 EmitProcSignalBarrier(ProcSignalBarrierType type); +extern void WaitForProcSignalBarrier(uint64 generation); +extern void ProcessProcSignalBarrier(void); + +extern void procsignal_sigusr1_handler(SIGNAL_ARGS); + +#endif /* PROCSIGNAL_H */ diff --git a/install/include/postgresql/server/storage/reinit.h b/install/include/postgresql/server/storage/reinit.h new file mode 100644 index 00000000000..e2bbb5abe9f --- /dev/null +++ b/install/include/postgresql/server/storage/reinit.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * reinit.h + * Reinitialization of unlogged relations + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/reinit.h + * + *------------------------------------------------------------------------- + */ + +#ifndef REINIT_H +#define REINIT_H + +#include "common/relpath.h" + + +extern void ResetUnloggedRelations(int op); +extern bool parse_filename_for_nontemp_relation(const char *name, + int *relnumchars, + ForkNumber *fork); + +#define UNLOGGED_RELATION_CLEANUP 0x0001 +#define UNLOGGED_RELATION_INIT 0x0002 + +#endif /* REINIT_H */ diff --git a/install/include/postgresql/server/storage/relfilelocator.h b/install/include/postgresql/server/storage/relfilelocator.h new file mode 100644 index 00000000000..61cf0169bd7 --- /dev/null +++ b/install/include/postgresql/server/storage/relfilelocator.h @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------- + * + * relfilelocator.h + * Physical access information for relations. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/relfilelocator.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELFILELOCATOR_H +#define RELFILELOCATOR_H + +#include "common/relpath.h" +#include "storage/backendid.h" + +/* + * RelFileLocator must provide all that we need to know to physically access + * a relation, with the exception of the backend ID, which can be provided + * separately. Note, however, that a "physical" relation is comprised of + * multiple files on the filesystem, as each fork is stored as a separate + * file, and each fork can be divided into multiple segments. See md.c. + * + * spcOid identifies the tablespace of the relation. It corresponds to + * pg_tablespace.oid. + * + * dbOid identifies the database of the relation. It is zero for + * "shared" relations (those common to all databases of a cluster). + * Nonzero dbOid values correspond to pg_database.oid. + * + * relNumber identifies the specific relation. relNumber corresponds to + * pg_class.relfilenode (NOT pg_class.oid, because we need to be able + * to assign new physical files to relations in some situations). + * Notice that relNumber is only unique within a database in a particular + * tablespace. + * + * Note: spcOid must be GLOBALTABLESPACE_OID if and only if dbOid is + * zero. We support shared relations only in the "global" tablespace. + * + * Note: in pg_class we allow reltablespace == 0 to denote that the + * relation is stored in its database's "default" tablespace (as + * identified by pg_database.dattablespace). However this shorthand + * is NOT allowed in RelFileLocator structs --- the real tablespace ID + * must be supplied when setting spcOid. + * + * Note: in pg_class, relfilenode can be zero to denote that the relation + * is a "mapped" relation, whose current true filenode number is available + * from relmapper.c. Again, this case is NOT allowed in RelFileLocators. + * + * Note: various places use RelFileLocator in hashtable keys. Therefore, + * there *must not* be any unused padding bytes in this struct. That + * should be safe as long as all the fields are of type Oid. + */ +typedef struct RelFileLocator +{ + Oid spcOid; /* tablespace */ + Oid dbOid; /* database */ + RelFileNumber relNumber; /* relation */ +} RelFileLocator; + +/* + * Augmenting a relfilelocator with the backend ID provides all the information + * we need to locate the physical storage. The backend ID is InvalidBackendId + * for regular relations (those accessible to more than one backend), or the + * owning backend's ID for backend-local relations. Backend-local relations + * are always transient and removed in case of a database crash; they are + * never WAL-logged or fsync'd. + */ +typedef struct RelFileLocatorBackend +{ + RelFileLocator locator; + BackendId backend; +} RelFileLocatorBackend; + +#define RelFileLocatorBackendIsTemp(rlocator) \ + ((rlocator).backend != InvalidBackendId) + +/* + * Note: RelFileLocatorEquals and RelFileLocatorBackendEquals compare relNumber + * first since that is most likely to be different in two unequal + * RelFileLocators. It is probably redundant to compare spcOid if the other + * fields are found equal, but do it anyway to be sure. Likewise for checking + * the backend ID in RelFileLocatorBackendEquals. + */ +#define RelFileLocatorEquals(locator1, locator2) \ + ((locator1).relNumber == (locator2).relNumber && \ + (locator1).dbOid == (locator2).dbOid && \ + (locator1).spcOid == (locator2).spcOid) + +#define RelFileLocatorBackendEquals(locator1, locator2) \ + ((locator1).locator.relNumber == (locator2).locator.relNumber && \ + (locator1).locator.dbOid == (locator2).locator.dbOid && \ + (locator1).backend == (locator2).backend && \ + (locator1).locator.spcOid == (locator2).locator.spcOid) + +#endif /* RELFILELOCATOR_H */ diff --git a/install/include/postgresql/server/storage/s_lock.h b/install/include/postgresql/server/storage/s_lock.h new file mode 100644 index 00000000000..c9fa84cc43c --- /dev/null +++ b/install/include/postgresql/server/storage/s_lock.h @@ -0,0 +1,867 @@ +/*------------------------------------------------------------------------- + * + * s_lock.h + * Hardware-dependent implementation of spinlocks. + * + * NOTE: none of the macros in this file are intended to be called directly. + * Call them through the hardware-independent macros in spin.h. + * + * The following hardware-dependent macros must be provided for each + * supported platform: + * + * void S_INIT_LOCK(slock_t *lock) + * Initialize a spinlock (to the unlocked state). + * + * int S_LOCK(slock_t *lock) + * Acquire a spinlock, waiting if necessary. + * Time out and abort() if unable to acquire the lock in a + * "reasonable" amount of time --- typically ~ 1 minute. + * Should return number of "delays"; see s_lock.c + * + * void S_UNLOCK(slock_t *lock) + * Unlock a previously acquired lock. + * + * bool S_LOCK_FREE(slock_t *lock) + * Tests if the lock is free. Returns true if free, false if locked. + * This does *not* change the state of the lock. + * + * void SPIN_DELAY(void) + * Delay operation to occur inside spinlock wait loop. + * + * Note to implementors: there are default implementations for all these + * macros at the bottom of the file. Check if your platform can use + * these or needs to override them. + * + * Usually, S_LOCK() is implemented in terms of even lower-level macros + * TAS() and TAS_SPIN(): + * + * int TAS(slock_t *lock) + * Atomic test-and-set instruction. Attempt to acquire the lock, + * but do *not* wait. Returns 0 if successful, nonzero if unable + * to acquire the lock. + * + * int TAS_SPIN(slock_t *lock) + * Like TAS(), but this version is used when waiting for a lock + * previously found to be contended. By default, this is the + * same as TAS(), but on some architectures it's better to poll a + * contended lock using an unlocked instruction and retry the + * atomic test-and-set only when it appears free. + * + * TAS() and TAS_SPIN() are NOT part of the API, and should never be called + * directly. + * + * CAUTION: on some platforms TAS() and/or TAS_SPIN() may sometimes report + * failure to acquire a lock even when the lock is not locked. For example, + * on Alpha TAS() will "fail" if interrupted. Therefore a retry loop must + * always be used, even if you are certain the lock is free. + * + * It is the responsibility of these macros to make sure that the compiler + * does not re-order accesses to shared memory to precede the actual lock + * acquisition, or follow the lock release. Prior to PostgreSQL 9.5, this + * was the caller's responsibility, which meant that callers had to use + * volatile-qualified pointers to refer to both the spinlock itself and the + * shared data being accessed within the spinlocked critical section. This + * was notationally awkward, easy to forget (and thus error-prone), and + * prevented some useful compiler optimizations. For these reasons, we + * now require that the macros themselves prevent compiler re-ordering, + * so that the caller doesn't need to take special precautions. + * + * On platforms with weak memory ordering, the TAS(), TAS_SPIN(), and + * S_UNLOCK() macros must further include hardware-level memory fence + * instructions to prevent similar re-ordering at the hardware level. + * TAS() and TAS_SPIN() must guarantee that loads and stores issued after + * the macro are not executed until the lock has been obtained. Conversely, + * S_UNLOCK() must guarantee that loads and stores issued before the macro + * have been executed before the lock is released. + * + * On most supported platforms, TAS() uses a tas() function written + * in assembly language to execute a hardware atomic-test-and-set + * instruction. Equivalent OS-supplied mutex routines could be used too. + * + * If no system-specific TAS() is available (ie, HAVE_SPINLOCKS is not + * defined), then we fall back on an emulation that uses SysV semaphores + * (see spin.c). This emulation will be MUCH MUCH slower than a proper TAS() + * implementation, because of the cost of a kernel call per lock or unlock. + * An old report is that Postgres spends around 40% of its time in semop(2) + * when using the SysV semaphore code. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/s_lock.h + * + *------------------------------------------------------------------------- + */ +#ifndef S_LOCK_H +#define S_LOCK_H + +#ifdef FRONTEND +#error "s_lock.h may not be included from frontend code" +#endif + +#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +/************************************************************************* + * All the gcc inlines + * Gcc consistently defines the CPU as __cpu__. + * Other compilers use __cpu or __cpu__ so we test for both in those cases. + */ + +/*---------- + * Standard gcc asm format (assuming "volatile slock_t *lock"): + + __asm__ __volatile__( + " instruction \n" + " instruction \n" + " instruction \n" +: "=r"(_res), "+m"(*lock) // return register, in/out lock value +: "r"(lock) // lock pointer, in input register +: "memory", "cc"); // show clobbered registers here + + * The output-operands list (after first colon) should always include + * "+m"(*lock), whether or not the asm code actually refers to this + * operand directly. This ensures that gcc believes the value in the + * lock variable is used and set by the asm code. Also, the clobbers + * list (after third colon) should always include "memory"; this prevents + * gcc from thinking it can cache the values of shared-memory fields + * across the asm code. Add "cc" if your asm code changes the condition + * code register, and also list any temp registers the code uses. + *---------- + */ + + +#ifdef __i386__ /* 32-bit i386 */ +#define HAS_TEST_AND_SET + +typedef unsigned char slock_t; + +#define TAS(lock) tas(lock) + +static __inline__ int +tas(volatile slock_t *lock) +{ + slock_t _res = 1; + + /* + * Use a non-locking test before asserting the bus lock. Note that the + * extra test appears to be a small loss on some x86 platforms and a small + * win on others; it's by no means clear that we should keep it. + * + * When this was last tested, we didn't have separate TAS() and TAS_SPIN() + * macros. Nowadays it probably would be better to do a non-locking test + * in TAS_SPIN() but not in TAS(), like on x86_64, but no-one's done the + * testing to verify that. Without some empirical evidence, better to + * leave it alone. + */ + __asm__ __volatile__( + " cmpb $0,%1 \n" + " jne 1f \n" + " lock \n" + " xchgb %0,%1 \n" + "1: \n" +: "+q"(_res), "+m"(*lock) +: /* no inputs */ +: "memory", "cc"); + return (int) _res; +} + +#define SPIN_DELAY() spin_delay() + +static __inline__ void +spin_delay(void) +{ + /* + * This sequence is equivalent to the PAUSE instruction ("rep" is + * ignored by old IA32 processors if the following instruction is + * not a string operation); the IA-32 Architecture Software + * Developer's Manual, Vol. 3, Section 7.7.2 describes why using + * PAUSE in the inner loop of a spin lock is necessary for good + * performance: + * + * The PAUSE instruction improves the performance of IA-32 + * processors supporting Hyper-Threading Technology when + * executing spin-wait loops and other routines where one + * thread is accessing a shared lock or semaphore in a tight + * polling loop. When executing a spin-wait loop, the + * processor can suffer a severe performance penalty when + * exiting the loop because it detects a possible memory order + * violation and flushes the core processor's pipeline. The + * PAUSE instruction provides a hint to the processor that the + * code sequence is a spin-wait loop. The processor uses this + * hint to avoid the memory order violation and prevent the + * pipeline flush. In addition, the PAUSE instruction + * de-pipelines the spin-wait loop to prevent it from + * consuming execution resources excessively. + */ + __asm__ __volatile__( + " rep; nop \n"); +} + +#endif /* __i386__ */ + + +#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */ +#define HAS_TEST_AND_SET + +typedef unsigned char slock_t; + +#define TAS(lock) tas(lock) + +/* + * On Intel EM64T, it's a win to use a non-locking test before the xchg proper, + * but only when spinning. + * + * See also Implementing Scalable Atomic Locks for Multi-Core Intel(tm) EM64T + * and IA32, by Michael Chynoweth and Mary R. Lee. As of this writing, it is + * available at: + * http://software.intel.com/en-us/articles/implementing-scalable-atomic-locks-for-multi-core-intel-em64t-and-ia32-architectures + */ +#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock)) + +static __inline__ int +tas(volatile slock_t *lock) +{ + slock_t _res = 1; + + __asm__ __volatile__( + " lock \n" + " xchgb %0,%1 \n" +: "+q"(_res), "+m"(*lock) +: /* no inputs */ +: "memory", "cc"); + return (int) _res; +} + +#define SPIN_DELAY() spin_delay() + +static __inline__ void +spin_delay(void) +{ + /* + * Adding a PAUSE in the spin delay loop is demonstrably a no-op on + * Opteron, but it may be of some use on EM64T, so we keep it. + */ + __asm__ __volatile__( + " rep; nop \n"); +} + +#endif /* __x86_64__ */ + + +/* + * On ARM and ARM64, we use __sync_lock_test_and_set(int *, int) if available. + * + * We use the int-width variant of the builtin because it works on more chips + * than other widths. + */ +#if defined(__arm__) || defined(__arm) || defined(__aarch64__) +#ifdef HAVE_GCC__SYNC_INT32_TAS +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef int slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +/* + * Using an ISB instruction to delay in spinlock loops appears beneficial on + * high-core-count ARM64 processors. It seems mostly a wash for smaller gear, + * and ISB doesn't exist at all on pre-v7 ARM chips. + */ +#if defined(__aarch64__) + +#define SPIN_DELAY() spin_delay() + +static __inline__ void +spin_delay(void) +{ + __asm__ __volatile__( + " isb; \n"); +} + +#endif /* __aarch64__ */ +#endif /* HAVE_GCC__SYNC_INT32_TAS */ +#endif /* __arm__ || __arm || __aarch64__ */ + + +/* S/390 and S/390x Linux (32- and 64-bit zSeries) */ +#if defined(__s390__) || defined(__s390x__) +#define HAS_TEST_AND_SET + +typedef unsigned int slock_t; + +#define TAS(lock) tas(lock) + +static __inline__ int +tas(volatile slock_t *lock) +{ + int _res = 0; + + __asm__ __volatile__( + " cs %0,%3,0(%2) \n" +: "+d"(_res), "+m"(*lock) +: "a"(lock), "d"(1) +: "memory", "cc"); + return _res; +} + +#endif /* __s390__ || __s390x__ */ + + +#if defined(__sparc__) /* Sparc */ +/* + * Solaris has always run sparc processors in TSO (total store) mode, but + * linux didn't use to and the *BSDs still don't. So, be careful about + * acquire/release semantics. The CPU will treat superfluous members as + * NOPs, so it's just code space. + */ +#define HAS_TEST_AND_SET + +typedef unsigned char slock_t; + +#define TAS(lock) tas(lock) + +static __inline__ int +tas(volatile slock_t *lock) +{ + slock_t _res; + + /* + * See comment in src/backend/port/tas/sunstudio_sparc.s for why this + * uses "ldstub", and that file uses "cas". gcc currently generates + * sparcv7-targeted binaries, so "cas" use isn't possible. + */ + __asm__ __volatile__( + " ldstub [%2], %0 \n" +: "=r"(_res), "+m"(*lock) +: "r"(lock) +: "memory"); +#if defined(__sparcv7) || defined(__sparc_v7__) + /* + * No stbar or membar available, luckily no actually produced hardware + * requires a barrier. + */ +#elif defined(__sparcv8) || defined(__sparc_v8__) + /* stbar is available (and required for both PSO, RMO), membar isn't */ + __asm__ __volatile__ ("stbar \n":::"memory"); +#else + /* + * #LoadStore (RMO) | #LoadLoad (RMO) together are the appropriate acquire + * barrier for sparcv8+ upwards. + */ + __asm__ __volatile__ ("membar #LoadStore | #LoadLoad \n":::"memory"); +#endif + return (int) _res; +} + +#if defined(__sparcv7) || defined(__sparc_v7__) +/* + * No stbar or membar available, luckily no actually produced hardware + * requires a barrier. We fall through to the default gcc definition of + * S_UNLOCK in this case. + */ +#elif defined(__sparcv8) || defined(__sparc_v8__) +/* stbar is available (and required for both PSO, RMO), membar isn't */ +#define S_UNLOCK(lock) \ +do \ +{ \ + __asm__ __volatile__ ("stbar \n":::"memory"); \ + *((volatile slock_t *) (lock)) = 0; \ +} while (0) +#else +/* + * #LoadStore (RMO) | #StoreStore (RMO, PSO) together are the appropriate + * release barrier for sparcv8+ upwards. + */ +#define S_UNLOCK(lock) \ +do \ +{ \ + __asm__ __volatile__ ("membar #LoadStore | #StoreStore \n":::"memory"); \ + *((volatile slock_t *) (lock)) = 0; \ +} while (0) +#endif + +#endif /* __sparc__ */ + + +/* PowerPC */ +#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__) +#define HAS_TEST_AND_SET + +typedef unsigned int slock_t; + +#define TAS(lock) tas(lock) + +/* On PPC, it's a win to use a non-locking test before the lwarx */ +#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock)) + +/* + * The second operand of addi can hold a constant zero or a register number, + * hence constraint "=&b" to avoid allocating r0. "b" stands for "address + * base register"; most operands having this register-or-zero property are + * address bases, e.g. the second operand of lwax. + * + * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002, + * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop. + * But if the spinlock is in ordinary memory, we can use lwsync instead for + * better performance. + * + * Ordinarily, we'd code the branches here using GNU-style local symbols, that + * is "1f" referencing "1:" and so on. But some people run gcc on AIX with + * IBM's assembler as backend, and IBM's assembler doesn't do local symbols. + * So hand-code the branch offsets; fortunately, all PPC instructions are + * exactly 4 bytes each, so it's not too hard to count. + */ +static __inline__ int +tas(volatile slock_t *lock) +{ + slock_t _t; + int _res; + + __asm__ __volatile__( +" lwarx %0,0,%3,1 \n" +" cmpwi %0,0 \n" +" bne $+16 \n" /* branch to li %1,1 */ +" addi %0,%0,1 \n" +" stwcx. %0,0,%3 \n" +" beq $+12 \n" /* branch to lwsync */ +" li %1,1 \n" +" b $+12 \n" /* branch to end of asm sequence */ +" lwsync \n" +" li %1,0 \n" + +: "=&b"(_t), "=r"(_res), "+m"(*lock) +: "r"(lock) +: "memory", "cc"); + return _res; +} + +/* + * PowerPC S_UNLOCK is almost standard but requires a "sync" instruction. + * But we can use lwsync instead for better performance. + */ +#define S_UNLOCK(lock) \ +do \ +{ \ + __asm__ __volatile__ (" lwsync \n" ::: "memory"); \ + *((volatile slock_t *) (lock)) = 0; \ +} while (0) + +#endif /* powerpc */ + + +#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */ +#define HAS_TEST_AND_SET + +typedef unsigned int slock_t; + +#define TAS(lock) tas(lock) + +/* + * Original MIPS-I processors lacked the LL/SC instructions, but if we are + * so unfortunate as to be running on one of those, we expect that the kernel + * will handle the illegal-instruction traps and emulate them for us. On + * anything newer (and really, MIPS-I is extinct) LL/SC is the only sane + * choice because any other synchronization method must involve a kernel + * call. Unfortunately, many toolchains still default to MIPS-I as the + * codegen target; if the symbol __mips shows that that's the case, we + * have to force the assembler to accept LL/SC. + * + * R10000 and up processors require a separate SYNC, which has the same + * issues as LL/SC. + */ +#if __mips < 2 +#define MIPS_SET_MIPS2 " .set mips2 \n" +#else +#define MIPS_SET_MIPS2 +#endif + +static __inline__ int +tas(volatile slock_t *lock) +{ + volatile slock_t *_l = lock; + int _res; + int _tmp; + + __asm__ __volatile__( + " .set push \n" + MIPS_SET_MIPS2 + " .set noreorder \n" + " .set nomacro \n" + " ll %0, %2 \n" + " or %1, %0, 1 \n" + " sc %1, %2 \n" + " xori %1, 1 \n" + " or %0, %0, %1 \n" + " sync \n" + " .set pop " +: "=&r" (_res), "=&r" (_tmp), "+R" (*_l) +: /* no inputs */ +: "memory"); + return _res; +} + +/* MIPS S_UNLOCK is almost standard but requires a "sync" instruction */ +#define S_UNLOCK(lock) \ +do \ +{ \ + __asm__ __volatile__( \ + " .set push \n" \ + MIPS_SET_MIPS2 \ + " .set noreorder \n" \ + " .set nomacro \n" \ + " sync \n" \ + " .set pop " \ +: /* no outputs */ \ +: /* no inputs */ \ +: "memory"); \ + *((volatile slock_t *) (lock)) = 0; \ +} while (0) + +#endif /* __mips__ && !__sgi */ + + +#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC */ +/* + * HP's PA-RISC + * + * Because LDCWX requires a 16-byte-aligned address, we declare slock_t as a + * 16-byte struct. The active word in the struct is whichever has the aligned + * address; the other three words just sit at -1. + */ +#define HAS_TEST_AND_SET + +typedef struct +{ + int sema[4]; +} slock_t; + +#define TAS_ACTIVE_WORD(lock) ((volatile int *) (((uintptr_t) (lock) + 15) & ~15)) + +static __inline__ int +tas(volatile slock_t *lock) +{ + volatile int *lockword = TAS_ACTIVE_WORD(lock); + int lockval; + + /* + * The LDCWX instruction atomically clears the target word and + * returns the previous value. Hence, if the instruction returns + * 0, someone else has already acquired the lock before we tested + * it (i.e., we have failed). + * + * Notice that this means that we actually clear the word to set + * the lock and set the word to clear the lock. This is the + * opposite behavior from the SPARC LDSTUB instruction. For some + * reason everything that H-P does is rather baroque... + * + * For details about the LDCWX instruction, see the "Precision + * Architecture and Instruction Reference Manual" (09740-90014 of June + * 1987), p. 5-38. + */ + __asm__ __volatile__( + " ldcwx 0(0,%2),%0 \n" +: "=r"(lockval), "+m"(*lockword) +: "r"(lockword) +: "memory"); + return (lockval == 0); +} + +#define S_UNLOCK(lock) \ + do { \ + __asm__ __volatile__("" : : : "memory"); \ + *TAS_ACTIVE_WORD(lock) = -1; \ + } while (0) + +#define S_INIT_LOCK(lock) \ + do { \ + volatile slock_t *lock_ = (lock); \ + lock_->sema[0] = -1; \ + lock_->sema[1] = -1; \ + lock_->sema[2] = -1; \ + lock_->sema[3] = -1; \ + } while (0) + +#define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0) + +#endif /* __hppa || __hppa__ */ + + +/* + * If we have no platform-specific knowledge, but we found that the compiler + * provides __sync_lock_test_and_set(), use that. Prefer the int-width + * version over the char-width version if we have both, on the rather dubious + * grounds that that's known to be more likely to work in the ARM ecosystem. + * (But we dealt with ARM above.) + */ +#if !defined(HAS_TEST_AND_SET) + +#if defined(HAVE_GCC__SYNC_INT32_TAS) +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef int slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#elif defined(HAVE_GCC__SYNC_CHAR_TAS) +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef char slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#endif /* HAVE_GCC__SYNC_INT32_TAS */ + +#endif /* !defined(HAS_TEST_AND_SET) */ + + +/* + * Default implementation of S_UNLOCK() for gcc/icc. + * + * Note that this implementation is unsafe for any platform that can reorder + * a memory access (either load or store) after a following store. That + * happens not to be possible on x86 and most legacy architectures (some are + * single-processor!), but many modern systems have weaker memory ordering. + * Those that do must define their own version of S_UNLOCK() rather than + * relying on this one. + */ +#if !defined(S_UNLOCK) +#define S_UNLOCK(lock) \ + do { __asm__ __volatile__("" : : : "memory"); *(lock) = 0; } while (0) +#endif + +#endif /* defined(__GNUC__) || defined(__INTEL_COMPILER) */ + + +/* + * --------------------------------------------------------------------- + * Platforms that use non-gcc inline assembly: + * --------------------------------------------------------------------- + */ + +#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */ + +#if defined(_AIX) /* AIX */ +/* + * AIX (POWER) + */ +#define HAS_TEST_AND_SET + +#include + +typedef int slock_t; + +#define TAS(lock) _check_lock((slock_t *) (lock), 0, 1) +#define S_UNLOCK(lock) _clear_lock((slock_t *) (lock), 0) +#endif /* _AIX */ + + +/* These are in sunstudio_(sparc|x86).s */ + +#if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc)) +#define HAS_TEST_AND_SET + +#if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus) +typedef unsigned int slock_t; +#else +typedef unsigned char slock_t; +#endif + +extern slock_t pg_atomic_cas(volatile slock_t *lock, slock_t with, + slock_t cmp); + +#define TAS(a) (pg_atomic_cas((a), 1, 0) != 0) +#endif + + +#ifdef _MSC_VER +typedef LONG slock_t; + +#define HAS_TEST_AND_SET +#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0)) + +#define SPIN_DELAY() spin_delay() + +/* If using Visual C++ on Win64, inline assembly is unavailable. + * Use a _mm_pause intrinsic instead of rep nop. + */ +#if defined(_WIN64) +static __forceinline void +spin_delay(void) +{ + _mm_pause(); +} +#else +static __forceinline void +spin_delay(void) +{ + /* See comment for gcc code. Same code, MASM syntax */ + __asm rep nop; +} +#endif + +#include +#pragma intrinsic(_ReadWriteBarrier) + +#define S_UNLOCK(lock) \ + do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0) + +#endif + + +#endif /* !defined(HAS_TEST_AND_SET) */ + + +/* Blow up if we didn't have any way to do spinlocks */ +#ifndef HAS_TEST_AND_SET +#error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@lists.postgresql.org. +#endif + + +#else /* !HAVE_SPINLOCKS */ + + +/* + * Fake spinlock implementation using semaphores --- slow and prone + * to fall foul of kernel limits on number of semaphores, so don't use this + * unless you must! The subroutines appear in spin.c. + */ +typedef int slock_t; + +extern bool s_lock_free_sema(volatile slock_t *lock); +extern void s_unlock_sema(volatile slock_t *lock); +extern void s_init_lock_sema(volatile slock_t *lock, bool nested); +extern int tas_sema(volatile slock_t *lock); + +#define S_LOCK_FREE(lock) s_lock_free_sema(lock) +#define S_UNLOCK(lock) s_unlock_sema(lock) +#define S_INIT_LOCK(lock) s_init_lock_sema(lock, false) +#define TAS(lock) tas_sema(lock) + + +#endif /* HAVE_SPINLOCKS */ + + +/* + * Default Definitions - override these above as needed. + */ + +#if !defined(S_LOCK) +#define S_LOCK(lock) \ + (TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0) +#endif /* S_LOCK */ + +#if !defined(S_LOCK_FREE) +#define S_LOCK_FREE(lock) (*(lock) == 0) +#endif /* S_LOCK_FREE */ + +#if !defined(S_UNLOCK) +/* + * Our default implementation of S_UNLOCK is essentially *(lock) = 0. This + * is unsafe if the platform can reorder a memory access (either load or + * store) after a following store; platforms where this is possible must + * define their own S_UNLOCK. But CPU reordering is not the only concern: + * if we simply defined S_UNLOCK() as an inline macro, the compiler might + * reorder instructions from inside the critical section to occur after the + * lock release. Since the compiler probably can't know what the external + * function s_unlock is doing, putting the same logic there should be adequate. + * A sufficiently-smart globally optimizing compiler could break that + * assumption, though, and the cost of a function call for every spinlock + * release may hurt performance significantly, so we use this implementation + * only for platforms where we don't know of a suitable intrinsic. For the + * most part, those are relatively obscure platform/compiler combinations to + * which the PostgreSQL project does not have access. + */ +#define USE_DEFAULT_S_UNLOCK +extern void s_unlock(volatile slock_t *lock); +#define S_UNLOCK(lock) s_unlock(lock) +#endif /* S_UNLOCK */ + +#if !defined(S_INIT_LOCK) +#define S_INIT_LOCK(lock) S_UNLOCK(lock) +#endif /* S_INIT_LOCK */ + +#if !defined(SPIN_DELAY) +#define SPIN_DELAY() ((void) 0) +#endif /* SPIN_DELAY */ + +#if !defined(TAS) +extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or + * s_lock.c */ + +#define TAS(lock) tas(lock) +#endif /* TAS */ + +#if !defined(TAS_SPIN) +#define TAS_SPIN(lock) TAS(lock) +#endif /* TAS_SPIN */ + +extern PGDLLIMPORT slock_t dummy_spinlock; + +/* + * Platform-independent out-of-line support routines + */ +extern int s_lock(volatile slock_t *lock, const char *file, int line, const char *func); + +/* Support for dynamic adjustment of spins_per_delay */ +#define DEFAULT_SPINS_PER_DELAY 100 + +extern void set_spins_per_delay(int shared_spins_per_delay); +extern int update_spins_per_delay(int shared_spins_per_delay); + +/* + * Support for spin delay which is useful in various places where + * spinlock-like procedures take place. + */ +typedef struct +{ + int spins; + int delays; + int cur_delay; + const char *file; + int line; + const char *func; +} SpinDelayStatus; + +static inline void +init_spin_delay(SpinDelayStatus *status, + const char *file, int line, const char *func) +{ + status->spins = 0; + status->delays = 0; + status->cur_delay = 0; + status->file = file; + status->line = line; + status->func = func; +} + +#define init_local_spin_delay(status) init_spin_delay(status, __FILE__, __LINE__, __func__) +extern void perform_spin_delay(SpinDelayStatus *status); +extern void finish_spin_delay(SpinDelayStatus *status); + +#endif /* S_LOCK_H */ diff --git a/install/include/postgresql/server/storage/sharedfileset.h b/install/include/postgresql/server/storage/sharedfileset.h new file mode 100644 index 00000000000..aa6f97f8c70 --- /dev/null +++ b/install/include/postgresql/server/storage/sharedfileset.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * sharedfileset.h + * Shared temporary file management. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/sharedfileset.h + * + *------------------------------------------------------------------------- + */ + +#ifndef SHAREDFILESET_H +#define SHAREDFILESET_H + +#include "storage/dsm.h" +#include "storage/fd.h" +#include "storage/fileset.h" +#include "storage/spin.h" + +/* + * A set of temporary files that can be shared by multiple backends. + */ +typedef struct SharedFileSet +{ + FileSet fs; + slock_t mutex; /* mutex protecting the reference count */ + int refcnt; /* number of attached backends */ +} SharedFileSet; + +extern void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg); +extern void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg); +extern void SharedFileSetDeleteAll(SharedFileSet *fileset); + +#endif diff --git a/install/include/postgresql/server/storage/shm_mq.h b/install/include/postgresql/server/storage/shm_mq.h new file mode 100644 index 00000000000..2e04e418378 --- /dev/null +++ b/install/include/postgresql/server/storage/shm_mq.h @@ -0,0 +1,86 @@ +/*------------------------------------------------------------------------- + * + * shm_mq.h + * single-reader, single-writer shared memory message queue + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/shm_mq.h + * + *------------------------------------------------------------------------- + */ +#ifndef SHM_MQ_H +#define SHM_MQ_H + +#include "postmaster/bgworker.h" +#include "storage/dsm.h" +#include "storage/proc.h" + +/* The queue itself, in shared memory. */ +struct shm_mq; +typedef struct shm_mq shm_mq; + +/* Backend-private state. */ +struct shm_mq_handle; +typedef struct shm_mq_handle shm_mq_handle; + +/* Descriptors for a single write spanning multiple locations. */ +typedef struct +{ + const char *data; + Size len; +} shm_mq_iovec; + +/* Possible results of a send or receive operation. */ +typedef enum +{ + SHM_MQ_SUCCESS, /* Sent or received a message. */ + SHM_MQ_WOULD_BLOCK, /* Not completed; retry later. */ + SHM_MQ_DETACHED /* Other process has detached queue. */ +} shm_mq_result; + +/* + * Primitives to create a queue and set the sender and receiver. + * + * Both the sender and the receiver must be set before any messages are read + * or written, but they need not be set by the same process. Each must be + * set exactly once. + */ +extern shm_mq *shm_mq_create(void *address, Size size); +extern void shm_mq_set_receiver(shm_mq *mq, PGPROC *); +extern void shm_mq_set_sender(shm_mq *mq, PGPROC *); + +/* Accessor methods for sender and receiver. */ +extern PGPROC *shm_mq_get_receiver(shm_mq *); +extern PGPROC *shm_mq_get_sender(shm_mq *); + +/* Set up backend-local queue state. */ +extern shm_mq_handle *shm_mq_attach(shm_mq *mq, dsm_segment *seg, + BackgroundWorkerHandle *handle); + +/* Associate worker handle with shm_mq. */ +extern void shm_mq_set_handle(shm_mq_handle *, BackgroundWorkerHandle *); + +/* Break connection, release handle resources. */ +extern void shm_mq_detach(shm_mq_handle *mqh); + +/* Get the shm_mq from handle. */ +extern shm_mq *shm_mq_get_queue(shm_mq_handle *mqh); + +/* Send or receive messages. */ +extern shm_mq_result shm_mq_send(shm_mq_handle *mqh, + Size nbytes, const void *data, bool nowait, + bool force_flush); +extern shm_mq_result shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, + int iovcnt, bool nowait, bool force_flush); +extern shm_mq_result shm_mq_receive(shm_mq_handle *mqh, + Size *nbytesp, void **datap, bool nowait); + +/* Wait for our counterparty to attach to the queue. */ +extern shm_mq_result shm_mq_wait_for_attach(shm_mq_handle *mqh); + +/* Smallest possible queue. */ +extern PGDLLIMPORT const Size shm_mq_minimum_size; + +#endif /* SHM_MQ_H */ diff --git a/install/include/postgresql/server/storage/shm_toc.h b/install/include/postgresql/server/storage/shm_toc.h new file mode 100644 index 00000000000..7a2f8e99349 --- /dev/null +++ b/install/include/postgresql/server/storage/shm_toc.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------- + * + * shm_toc.h + * shared memory segment table of contents + * + * This is intended to provide a simple way to divide a chunk of shared + * memory (probably dynamic shared memory allocated via dsm_create) into + * a number of regions and keep track of the addresses of those regions or + * key data structures within those regions. This is not intended to + * scale to a large number of keys and will perform poorly if used that + * way; if you need a large number of pointers, store them within some + * other data structure within the segment and only put the pointer to + * the data structure itself in the table of contents. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/shm_toc.h + * + *------------------------------------------------------------------------- + */ +#ifndef SHM_TOC_H +#define SHM_TOC_H + +#include "storage/shmem.h" /* for add_size() */ + +/* shm_toc is an opaque type known only within shm_toc.c */ +typedef struct shm_toc shm_toc; + +extern shm_toc *shm_toc_create(uint64 magic, void *address, Size nbytes); +extern shm_toc *shm_toc_attach(uint64 magic, void *address); +extern void *shm_toc_allocate(shm_toc *toc, Size nbytes); +extern Size shm_toc_freespace(shm_toc *toc); +extern void shm_toc_insert(shm_toc *toc, uint64 key, void *address); +extern void *shm_toc_lookup(shm_toc *toc, uint64 key, bool noError); + +/* + * Tools for estimating how large a chunk of shared memory will be needed + * to store a TOC and its dependent objects. Note: we don't really support + * large numbers of keys, but it's convenient to declare number_of_keys + * as a Size anyway. + */ +typedef struct +{ + Size space_for_chunks; + Size number_of_keys; +} shm_toc_estimator; + +#define shm_toc_initialize_estimator(e) \ + ((e)->space_for_chunks = 0, (e)->number_of_keys = 0) +#define shm_toc_estimate_chunk(e, sz) \ + ((e)->space_for_chunks = add_size((e)->space_for_chunks, BUFFERALIGN(sz))) +#define shm_toc_estimate_keys(e, cnt) \ + ((e)->number_of_keys = add_size((e)->number_of_keys, cnt)) + +extern Size shm_toc_estimate(shm_toc_estimator *e); + +#endif /* SHM_TOC_H */ diff --git a/install/include/postgresql/server/storage/shmem.h b/install/include/postgresql/server/storage/shmem.h new file mode 100644 index 00000000000..0e1fb2006c1 --- /dev/null +++ b/install/include/postgresql/server/storage/shmem.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * shmem.h + * shared memory management structures + * + * Historical note: + * A long time ago, Postgres' shared memory region was allowed to be mapped + * at a different address in each process, and shared memory "pointers" were + * passed around as offsets relative to the start of the shared memory region. + * That is no longer the case: each process must map the shared memory region + * at the same address. This means shared memory pointers can be passed + * around directly between different processes. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/shmem.h + * + *------------------------------------------------------------------------- + */ +#ifndef SHMEM_H +#define SHMEM_H + +#include "utils/hsearch.h" + + +/* shmem.c */ +extern void InitShmemAccess(void *seghdr); +extern void InitShmemAllocation(void); +extern void *ShmemAlloc(Size size); +extern void *ShmemAllocNoError(Size size); +extern void *ShmemAllocUnlocked(Size size); +extern bool ShmemAddrIsValid(const void *addr); +extern void InitShmemIndex(void); +extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size, + HASHCTL *infoP, int hash_flags); +extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr); +extern Size add_size(Size s1, Size s2); +extern Size mul_size(Size s1, Size s2); + +/* ipci.c */ +extern void RequestAddinShmemSpace(Size size); + +/* size constants for the shmem index table */ + /* max size of data structure string name */ +#define SHMEM_INDEX_KEYSIZE (48) + /* estimated size of the shmem index table (not a hard limit) */ +#define SHMEM_INDEX_SIZE (64) + +/* this is a hash bucket in the shmem index table */ +typedef struct +{ + char key[SHMEM_INDEX_KEYSIZE]; /* string name */ + void *location; /* location in shared mem */ + Size size; /* # bytes requested for the structure */ + Size allocated_size; /* # bytes actually allocated */ +} ShmemIndexEnt; + +#endif /* SHMEM_H */ diff --git a/install/include/postgresql/server/storage/sinval.h b/install/include/postgresql/server/storage/sinval.h new file mode 100644 index 00000000000..0721e4d2058 --- /dev/null +++ b/install/include/postgresql/server/storage/sinval.h @@ -0,0 +1,153 @@ +/*------------------------------------------------------------------------- + * + * sinval.h + * POSTGRES shared cache invalidation communication definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/sinval.h + * + *------------------------------------------------------------------------- + */ +#ifndef SINVAL_H +#define SINVAL_H + +#include + +#include "storage/relfilelocator.h" + +/* + * We support several types of shared-invalidation messages: + * * invalidate a specific tuple in a specific catcache + * * invalidate all catcache entries from a given system catalog + * * invalidate a relcache entry for a specific logical relation + * * invalidate all relcache entries + * * invalidate an smgr cache entry for a specific physical relation + * * invalidate the mapped-relation mapping for a given database + * * invalidate any saved snapshot that might be used to scan a given relation + * More types could be added if needed. The message type is identified by + * the first "int8" field of the message struct. Zero or positive means a + * specific-catcache inval message (and also serves as the catcache ID field). + * Negative values identify the other message types, as per codes below. + * + * Catcache inval events are initially driven by detecting tuple inserts, + * updates and deletions in system catalogs (see CacheInvalidateHeapTuple). + * An update can generate two inval events, one for the old tuple and one for + * the new, but this is reduced to one event if the tuple's hash key doesn't + * change. Note that the inval events themselves don't actually say whether + * the tuple is being inserted or deleted. Also, since we transmit only a + * hash key, there is a small risk of unnecessary invalidations due to chance + * matches of hash keys. + * + * Note that some system catalogs have multiple caches on them (with different + * indexes). On detecting a tuple invalidation in such a catalog, separate + * catcache inval messages must be generated for each of its caches, since + * the hash keys will generally be different. + * + * Catcache, relcache, and snapshot invalidations are transactional, and so + * are sent to other backends upon commit. Internally to the generating + * backend, they are also processed at CommandCounterIncrement so that later + * commands in the same transaction see the new state. The generating backend + * also has to process them at abort, to flush out any cache state it's loaded + * from no-longer-valid entries. + * + * smgr and relation mapping invalidations are non-transactional: they are + * sent immediately when the underlying file change is made. + */ + +typedef struct +{ + int8 id; /* cache ID --- must be first */ + Oid dbId; /* database ID, or 0 if a shared relation */ + uint32 hashValue; /* hash value of key for this catcache */ +} SharedInvalCatcacheMsg; + +#define SHAREDINVALCATALOG_ID (-1) + +typedef struct +{ + int8 id; /* type field --- must be first */ + Oid dbId; /* database ID, or 0 if a shared catalog */ + Oid catId; /* ID of catalog whose contents are invalid */ +} SharedInvalCatalogMsg; + +#define SHAREDINVALRELCACHE_ID (-2) + +typedef struct +{ + int8 id; /* type field --- must be first */ + Oid dbId; /* database ID, or 0 if a shared relation */ + Oid relId; /* relation ID, or 0 if whole relcache */ +} SharedInvalRelcacheMsg; + +#define SHAREDINVALSMGR_ID (-3) + +typedef struct +{ + /* note: field layout chosen to pack into 16 bytes */ + int8 id; /* type field --- must be first */ + int8 backend_hi; /* high bits of backend ID, if temprel */ + uint16 backend_lo; /* low bits of backend ID, if temprel */ + RelFileLocator rlocator; /* spcOid, dbOid, relNumber */ +} SharedInvalSmgrMsg; + +#define SHAREDINVALRELMAP_ID (-4) + +typedef struct +{ + int8 id; /* type field --- must be first */ + Oid dbId; /* database ID, or 0 for shared catalogs */ +} SharedInvalRelmapMsg; + +#define SHAREDINVALSNAPSHOT_ID (-5) + +typedef struct +{ + int8 id; /* type field --- must be first */ + Oid dbId; /* database ID, or 0 if a shared relation */ + Oid relId; /* relation ID */ +} SharedInvalSnapshotMsg; + +typedef union +{ + int8 id; /* type field --- must be first */ + SharedInvalCatcacheMsg cc; + SharedInvalCatalogMsg cat; + SharedInvalRelcacheMsg rc; + SharedInvalSmgrMsg sm; + SharedInvalRelmapMsg rm; + SharedInvalSnapshotMsg sn; +} SharedInvalidationMessage; + + +/* Counter of messages processed; don't worry about overflow. */ +extern PGDLLIMPORT uint64 SharedInvalidMessageCounter; + +extern PGDLLIMPORT volatile sig_atomic_t catchupInterruptPending; + +extern void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, + int n); +extern void ReceiveSharedInvalidMessages(void (*invalFunction) (SharedInvalidationMessage *msg), + void (*resetFunction) (void)); + +/* signal handler for catchup events (PROCSIG_CATCHUP_INTERRUPT) */ +extern void HandleCatchupInterrupt(void); + +/* + * enable/disable processing of catchup events directly from signal handler. + * The enable routine first performs processing of any catchup events that + * have occurred since the last disable. + */ +extern void ProcessCatchupInterrupt(void); + +extern int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, + bool *RelcacheInitFileInval); +extern void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, + int nmsgs, bool RelcacheInitFileInval, + Oid dbid, Oid tsid); + +extern void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg); + +#endif /* SINVAL_H */ diff --git a/install/include/postgresql/server/storage/sinvaladt.h b/install/include/postgresql/server/storage/sinvaladt.h new file mode 100644 index 00000000000..1f9eaf206f6 --- /dev/null +++ b/install/include/postgresql/server/storage/sinvaladt.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------- + * + * sinvaladt.h + * POSTGRES shared cache invalidation data manager. + * + * The shared cache invalidation manager is responsible for transmitting + * invalidation messages between backends. Any message sent by any backend + * must be delivered to all already-running backends before it can be + * forgotten. (If we run out of space, we instead deliver a "RESET" + * message to backends that have fallen too far behind.) + * + * The struct type SharedInvalidationMessage, defining the contents of + * a single message, is defined in sinval.h. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/sinvaladt.h + * + *------------------------------------------------------------------------- + */ +#ifndef SINVALADT_H +#define SINVALADT_H + +#include "storage/lock.h" +#include "storage/sinval.h" + +/* + * prototypes for functions in sinvaladt.c + */ +extern Size SInvalShmemSize(void); +extern void CreateSharedInvalidationState(void); +extern void SharedInvalBackendInit(bool sendOnly); +extern PGPROC *BackendIdGetProc(int backendID); +extern void BackendIdGetTransactionIds(int backendID, TransactionId *xid, + TransactionId *xmin, int *nsubxid, + bool *overflowed); + +extern void SIInsertDataEntries(const SharedInvalidationMessage *data, int n); +extern int SIGetDataEntries(SharedInvalidationMessage *data, int datasize); +extern void SICleanupQueue(bool callerHasWriteLock, int minFree); +extern void SIResetAll(void); + +extern LocalTransactionId GetNextLocalTransactionId(void); + +#endif /* SINVALADT_H */ diff --git a/install/include/postgresql/server/storage/smgr.h b/install/include/postgresql/server/storage/smgr.h new file mode 100644 index 00000000000..b9a5b992f35 --- /dev/null +++ b/install/include/postgresql/server/storage/smgr.h @@ -0,0 +1,116 @@ +/*------------------------------------------------------------------------- + * + * smgr.h + * storage manager switch public interface declarations. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/smgr.h + * + *------------------------------------------------------------------------- + */ +#ifndef SMGR_H +#define SMGR_H + +#include "lib/ilist.h" +#include "storage/block.h" +#include "storage/relfilelocator.h" + +/* + * smgr.c maintains a table of SMgrRelation objects, which are essentially + * cached file handles. An SMgrRelation is created (if not already present) + * by smgropen(), and destroyed by smgrclose(). Note that neither of these + * operations imply I/O, they just create or destroy a hashtable entry. + * (But smgrclose() may release associated resources, such as OS-level file + * descriptors.) + * + * An SMgrRelation may have an "owner", which is just a pointer to it from + * somewhere else; smgr.c will clear this pointer if the SMgrRelation is + * closed. We use this to avoid dangling pointers from relcache to smgr + * without having to make the smgr explicitly aware of relcache. There + * can't be more than one "owner" pointer per SMgrRelation, but that's + * all we need. + * + * SMgrRelations that do not have an "owner" are considered to be transient, + * and are deleted at end of transaction. + */ +typedef struct SMgrRelationData +{ + /* rlocator is the hashtable lookup key, so it must be first! */ + RelFileLocatorBackend smgr_rlocator; /* relation physical identifier */ + + /* pointer to owning pointer, or NULL if none */ + struct SMgrRelationData **smgr_owner; + + /* + * The following fields are reset to InvalidBlockNumber upon a cache flush + * event, and hold the last known size for each fork. This information is + * currently only reliable during recovery, since there is no cache + * invalidation for fork extension. + */ + BlockNumber smgr_targblock; /* current insertion target block */ + BlockNumber smgr_cached_nblocks[MAX_FORKNUM + 1]; /* last known size */ + + /* additional public fields may someday exist here */ + + /* + * Fields below here are intended to be private to smgr.c and its + * submodules. Do not touch them from elsewhere. + */ + int smgr_which; /* storage manager selector */ + + /* + * for md.c; per-fork arrays of the number of open segments + * (md_num_open_segs) and the segments themselves (md_seg_fds). + */ + int md_num_open_segs[MAX_FORKNUM + 1]; + struct _MdfdVec *md_seg_fds[MAX_FORKNUM + 1]; + + /* if unowned, list link in list of all unowned SMgrRelations */ + dlist_node node; +} SMgrRelationData; + +typedef SMgrRelationData *SMgrRelation; + +#define SmgrIsTemp(smgr) \ + RelFileLocatorBackendIsTemp((smgr)->smgr_rlocator) + +extern void smgrinit(void); +extern SMgrRelation smgropen(RelFileLocator rlocator, BackendId backend); +extern bool smgrexists(SMgrRelation reln, ForkNumber forknum); +extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln); +extern void smgrclearowner(SMgrRelation *owner, SMgrRelation reln); +extern void smgrclose(SMgrRelation reln); +extern void smgrcloseall(void); +extern void smgrcloserellocator(RelFileLocatorBackend rlocator); +extern void smgrrelease(SMgrRelation reln); +extern void smgrreleaseall(void); +extern void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); +extern void smgrdosyncall(SMgrRelation *rels, int nrels); +extern void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo); +extern void smgrextend(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, const void *buffer, bool skipFsync); +extern void smgrzeroextend(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, int nblocks, bool skipFsync); +extern bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum); +extern void smgrread(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, void *buffer); +extern void smgrwrite(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, const void *buffer, bool skipFsync); +extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, BlockNumber nblocks); +extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum); +extern BlockNumber smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum); +extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, + BlockNumber *nblocks); +extern void smgrtruncate2(SMgrRelation reln, ForkNumber *forknum, int nforks, + BlockNumber *old_nblocks, + BlockNumber *nblocks); +extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum); +extern void AtEOXact_SMgr(void); +extern bool ProcessBarrierSmgrRelease(void); + +#endif /* SMGR_H */ diff --git a/install/include/postgresql/server/storage/spin.h b/install/include/postgresql/server/storage/spin.h new file mode 100644 index 00000000000..5d809cc980c --- /dev/null +++ b/install/include/postgresql/server/storage/spin.h @@ -0,0 +1,77 @@ +/*------------------------------------------------------------------------- + * + * spin.h + * Hardware-independent implementation of spinlocks. + * + * + * The hardware-independent interface to spinlocks is defined by the + * typedef "slock_t" and these macros: + * + * void SpinLockInit(volatile slock_t *lock) + * Initialize a spinlock (to the unlocked state). + * + * void SpinLockAcquire(volatile slock_t *lock) + * Acquire a spinlock, waiting if necessary. + * Time out and abort() if unable to acquire the lock in a + * "reasonable" amount of time --- typically ~ 1 minute. + * + * void SpinLockRelease(volatile slock_t *lock) + * Unlock a previously acquired lock. + * + * bool SpinLockFree(slock_t *lock) + * Tests if the lock is free. Returns true if free, false if locked. + * This does *not* change the state of the lock. + * + * Callers must beware that the macro argument may be evaluated multiple + * times! + * + * Load and store operations in calling code are guaranteed not to be + * reordered with respect to these operations, because they include a + * compiler barrier. (Before PostgreSQL 9.5, callers needed to use a + * volatile qualifier to access data protected by spinlocks.) + * + * Keep in mind the coding rule that spinlocks must not be held for more + * than a few instructions. In particular, we assume it is not possible + * for a CHECK_FOR_INTERRUPTS() to occur while holding a spinlock, and so + * it is not necessary to do HOLD/RESUME_INTERRUPTS() in these macros. + * + * These macros are implemented in terms of hardware-dependent macros + * supplied by s_lock.h. There is not currently any extra functionality + * added by this header, but there has been in the past and may someday + * be again. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/spin.h + * + *------------------------------------------------------------------------- + */ +#ifndef SPIN_H +#define SPIN_H + +#include "storage/s_lock.h" +#ifndef HAVE_SPINLOCKS +#include "storage/pg_sema.h" +#endif + + +#define SpinLockInit(lock) S_INIT_LOCK(lock) + +#define SpinLockAcquire(lock) S_LOCK(lock) + +#define SpinLockRelease(lock) S_UNLOCK(lock) + +#define SpinLockFree(lock) S_LOCK_FREE(lock) + + +extern int SpinlockSemas(void); +extern Size SpinlockSemaSize(void); + +#ifndef HAVE_SPINLOCKS +extern void SpinlockSemaInit(void); +extern PGDLLIMPORT PGSemaphore *SpinlockSemaArray; +#endif + +#endif /* SPIN_H */ diff --git a/install/include/postgresql/server/storage/standby.h b/install/include/postgresql/server/storage/standby.h new file mode 100644 index 00000000000..bb7d90c7ad6 --- /dev/null +++ b/install/include/postgresql/server/storage/standby.h @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------------- + * + * standby.h + * Definitions for hot standby mode. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/standby.h + * + *------------------------------------------------------------------------- + */ +#ifndef STANDBY_H +#define STANDBY_H + +#include "datatype/timestamp.h" +#include "storage/lock.h" +#include "storage/procsignal.h" +#include "storage/relfilelocator.h" +#include "storage/standbydefs.h" + +/* User-settable GUC parameters */ +extern PGDLLIMPORT int max_standby_archive_delay; +extern PGDLLIMPORT int max_standby_streaming_delay; +extern PGDLLIMPORT bool log_recovery_conflict_waits; + +extern void InitRecoveryTransactionEnvironment(void); +extern void ShutdownRecoveryTransactionEnvironment(void); + +extern void ResolveRecoveryConflictWithSnapshot(TransactionId snapshotConflictHorizon, + bool isCatalogRel, + RelFileLocator locator); +extern void ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId snapshotConflictHorizon, + bool isCatalogRel, + RelFileLocator locator); +extern void ResolveRecoveryConflictWithTablespace(Oid tsid); +extern void ResolveRecoveryConflictWithDatabase(Oid dbid); + +extern void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict); +extern void ResolveRecoveryConflictWithBufferPin(void); +extern void CheckRecoveryConflictDeadlock(void); +extern void StandbyDeadLockHandler(void); +extern void StandbyTimeoutHandler(void); +extern void StandbyLockTimeoutHandler(void); +extern void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, + TimestampTz now, VirtualTransactionId *wait_list, + bool still_waiting); + +/* + * Standby Rmgr (RM_STANDBY_ID) + * + * Standby recovery manager exists to perform actions that are required + * to make hot standby work. That includes logging AccessExclusiveLocks taken + * by transactions and running-xacts snapshots. + */ +extern void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid); +extern void StandbyReleaseLockTree(TransactionId xid, + int nsubxids, TransactionId *subxids); +extern void StandbyReleaseAllLocks(void); +extern void StandbyReleaseOldLocks(TransactionId oldxid); + +#define MinSizeOfXactRunningXacts offsetof(xl_running_xacts, xids) + + +/* + * Declarations for GetRunningTransactionData(). Similar to Snapshots, but + * not quite. This has nothing at all to do with visibility on this server, + * so this is completely separate from snapmgr.c and snapmgr.h. + * This data is important for creating the initial snapshot state on a + * standby server. We need lots more information than a normal snapshot, + * hence we use a specific data structure for our needs. This data + * is written to WAL as a separate record immediately after each + * checkpoint. That means that wherever we start a standby from we will + * almost immediately see the data we need to begin executing queries. + */ + +typedef enum +{ + SUBXIDS_IN_ARRAY, /* xids array includes all running subxids */ + SUBXIDS_MISSING, /* snapshot overflowed, subxids are missing */ + SUBXIDS_IN_SUBTRANS, /* subxids are not included in 'xids', but + * pg_subtrans is fully up-to-date */ +} subxids_array_status; + +typedef struct RunningTransactionsData +{ + int xcnt; /* # of xact ids in xids[] */ + int subxcnt; /* # of subxact ids in xids[] */ + subxids_array_status subxid_status; + TransactionId nextXid; /* xid from ShmemVariableCache->nextXid */ + TransactionId oldestRunningXid; /* *not* oldestXmin */ + TransactionId latestCompletedXid; /* so we can set xmax */ + + TransactionId *xids; /* array of (sub)xids still running */ +} RunningTransactionsData; + +typedef RunningTransactionsData *RunningTransactions; + +extern void LogAccessExclusiveLock(Oid dbOid, Oid relOid); +extern void LogAccessExclusiveLockPrepare(void); + +extern XLogRecPtr LogStandbySnapshot(void); +extern void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, + bool relcacheInitFileInval); + +#endif /* STANDBY_H */ diff --git a/install/include/postgresql/server/storage/standbydefs.h b/install/include/postgresql/server/storage/standbydefs.h new file mode 100644 index 00000000000..188e348618a --- /dev/null +++ b/install/include/postgresql/server/storage/standbydefs.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * standbydefs.h + * Frontend exposed definitions for hot standby mode. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/standbydefs.h + * + *------------------------------------------------------------------------- + */ +#ifndef STANDBYDEFS_H +#define STANDBYDEFS_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" +#include "storage/lockdefs.h" +#include "storage/sinval.h" + +/* Recovery handlers for the Standby Rmgr (RM_STANDBY_ID) */ +extern void standby_redo(XLogReaderState *record); +extern void standby_desc(StringInfo buf, XLogReaderState *record); +extern const char *standby_identify(uint8 info); +extern void standby_desc_invalidations(StringInfo buf, + int nmsgs, SharedInvalidationMessage *msgs, + Oid dbId, Oid tsId, + bool relcacheInitFileInval); + +/* + * XLOG message types + */ +#define XLOG_STANDBY_LOCK 0x00 +#define XLOG_RUNNING_XACTS 0x10 +#define XLOG_INVALIDATIONS 0x20 + +typedef struct xl_standby_locks +{ + int nlocks; /* number of entries in locks array */ + xl_standby_lock locks[FLEXIBLE_ARRAY_MEMBER]; +} xl_standby_locks; + +/* + * When we write running xact data to WAL, we use this structure. + */ +typedef struct xl_running_xacts +{ + int xcnt; /* # of xact ids in xids[] */ + int subxcnt; /* # of subxact ids in xids[] */ + bool subxid_overflow; /* snapshot overflowed, subxids missing */ + TransactionId nextXid; /* xid from ShmemVariableCache->nextXid */ + TransactionId oldestRunningXid; /* *not* oldestXmin */ + TransactionId latestCompletedXid; /* so we can set xmax */ + + TransactionId xids[FLEXIBLE_ARRAY_MEMBER]; +} xl_running_xacts; + +/* + * Invalidations for standby, currently only when transactions without an + * assigned xid commit. + */ +typedef struct xl_invalidations +{ + Oid dbId; /* MyDatabaseId */ + Oid tsId; /* MyDatabaseTableSpace */ + bool relcacheInitFileInval; /* invalidate relcache init files */ + int nmsgs; /* number of shared inval msgs */ + SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]; +} xl_invalidations; + +#define MinSizeOfInvalidations offsetof(xl_invalidations, msgs) + +#endif /* STANDBYDEFS_H */ diff --git a/install/include/postgresql/server/storage/sync.h b/install/include/postgresql/server/storage/sync.h new file mode 100644 index 00000000000..cfbcfa6797d --- /dev/null +++ b/install/include/postgresql/server/storage/sync.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------- + * + * sync.h + * File synchronization management code. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/sync.h + * + *------------------------------------------------------------------------- + */ +#ifndef SYNC_H +#define SYNC_H + +#include "storage/relfilelocator.h" + +/* + * Type of sync request. These are used to manage the set of pending + * requests to call a sync handler's sync or unlink functions at the next + * checkpoint. + */ +typedef enum SyncRequestType +{ + SYNC_REQUEST, /* schedule a call of sync function */ + SYNC_UNLINK_REQUEST, /* schedule a call of unlink function */ + SYNC_FORGET_REQUEST, /* forget all calls for a tag */ + SYNC_FILTER_REQUEST /* forget all calls satisfying match fn */ +} SyncRequestType; + +/* + * Which set of functions to use to handle a given request. The values of + * the enumerators must match the indexes of the function table in sync.c. + */ +typedef enum SyncRequestHandler +{ + SYNC_HANDLER_MD = 0, + SYNC_HANDLER_CLOG, + SYNC_HANDLER_COMMIT_TS, + SYNC_HANDLER_MULTIXACT_OFFSET, + SYNC_HANDLER_MULTIXACT_MEMBER, + SYNC_HANDLER_NONE +} SyncRequestHandler; + +/* + * A tag identifying a file. Currently it has the members required for md.c's + * usage, but sync.c has no knowledge of the internal structure, and it is + * liable to change as required by future handlers. + */ +typedef struct FileTag +{ + int16 handler; /* SyncRequestHandler value, saving space */ + int16 forknum; /* ForkNumber, saving space */ + RelFileLocator rlocator; + uint32 segno; +} FileTag; + +extern void InitSync(void); +extern void SyncPreCheckpoint(void); +extern void SyncPostCheckpoint(void); +extern void ProcessSyncRequests(void); +extern void RememberSyncRequest(const FileTag *ftag, SyncRequestType type); +extern bool RegisterSyncRequest(const FileTag *ftag, SyncRequestType type, + bool retryOnError); + +#endif /* SYNC_H */ diff --git a/install/include/postgresql/server/tcop/cmdtag.h b/install/include/postgresql/server/tcop/cmdtag.h new file mode 100644 index 00000000000..1e7514dcff7 --- /dev/null +++ b/install/include/postgresql/server/tcop/cmdtag.h @@ -0,0 +1,63 @@ +/*------------------------------------------------------------------------- + * + * cmdtag.h + * Declarations for commandtag names and enumeration. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/cmdtag.h + * + *------------------------------------------------------------------------- + */ +#ifndef CMDTAG_H +#define CMDTAG_H + +/* buffer size required for command completion tags */ +#define COMPLETION_TAG_BUFSIZE 64 + +#define PG_CMDTAG(tag, name, evtrgok, rwrok, rowcnt) \ + tag, + +typedef enum CommandTag +{ +#include "tcop/cmdtaglist.h" + COMMAND_TAG_NEXTTAG +} CommandTag; + +#undef PG_CMDTAG + +typedef struct QueryCompletion +{ + CommandTag commandTag; + uint64 nprocessed; +} QueryCompletion; + + +static inline void +SetQueryCompletion(QueryCompletion *qc, CommandTag commandTag, + uint64 nprocessed) +{ + qc->commandTag = commandTag; + qc->nprocessed = nprocessed; +} + +static inline void +CopyQueryCompletion(QueryCompletion *dst, const QueryCompletion *src) +{ + dst->commandTag = src->commandTag; + dst->nprocessed = src->nprocessed; +} + + +extern void InitializeQueryCompletion(QueryCompletion *qc); +extern const char *GetCommandTagName(CommandTag commandTag); +extern const char *GetCommandTagNameAndLen(CommandTag commandTag, Size *len); +extern bool command_tag_display_rowcount(CommandTag commandTag); +extern bool command_tag_event_trigger_ok(CommandTag commandTag); +extern bool command_tag_table_rewrite_ok(CommandTag commandTag); +extern CommandTag GetCommandTagEnum(const char *commandname); +extern Size BuildQueryCompletionString(char *buff, const QueryCompletion *qc, + bool nameonly); + +#endif /* CMDTAG_H */ diff --git a/install/include/postgresql/server/tcop/cmdtaglist.h b/install/include/postgresql/server/tcop/cmdtaglist.h new file mode 100644 index 00000000000..e738ac1c097 --- /dev/null +++ b/install/include/postgresql/server/tcop/cmdtaglist.h @@ -0,0 +1,218 @@ +/*---------------------------------------------------------------------- + * + * cmdtaglist.h + * Command tags + * + * The command tag list is kept in its own source file for possible use + * by automatic tools. The exact representation of a command tag is + * determined by the PG_CMDTAG macro, which is not defined in this file; + * it can be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/cmdtaglist.h + * + *---------------------------------------------------------------------- + */ + +/* there is deliberately not an #ifndef CMDTAGLIST_H here */ + +/* + * List of command tags. The entries must be sorted alphabetically on their + * textual name, so that we can bsearch on it; see GetCommandTagEnum(). + */ + +/* symbol name, textual name, event_trigger_ok, table_rewrite_ok, rowcount */ +PG_CMDTAG(CMDTAG_UNKNOWN, "???", false, false, false) +PG_CMDTAG(CMDTAG_ALTER_ACCESS_METHOD, "ALTER ACCESS METHOD", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_AGGREGATE, "ALTER AGGREGATE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_CAST, "ALTER CAST", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_COLLATION, "ALTER COLLATION", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_CONSTRAINT, "ALTER CONSTRAINT", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_CONVERSION, "ALTER CONVERSION", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_DATABASE, "ALTER DATABASE", false, false, false) +PG_CMDTAG(CMDTAG_ALTER_DEFAULT_PRIVILEGES, "ALTER DEFAULT PRIVILEGES", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_DOMAIN, "ALTER DOMAIN", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_EVENT_TRIGGER, "ALTER EVENT TRIGGER", false, false, false) +PG_CMDTAG(CMDTAG_ALTER_EXTENSION, "ALTER EXTENSION", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_FOREIGN_DATA_WRAPPER, "ALTER FOREIGN DATA WRAPPER", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_FOREIGN_TABLE, "ALTER FOREIGN TABLE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_FUNCTION, "ALTER FUNCTION", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_INDEX, "ALTER INDEX", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_LANGUAGE, "ALTER LANGUAGE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_LARGE_OBJECT, "ALTER LARGE OBJECT", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_MATERIALIZED_VIEW, "ALTER MATERIALIZED VIEW", true, true, false) +PG_CMDTAG(CMDTAG_ALTER_OPERATOR, "ALTER OPERATOR", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_OPERATOR_CLASS, "ALTER OPERATOR CLASS", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_OPERATOR_FAMILY, "ALTER OPERATOR FAMILY", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_POLICY, "ALTER POLICY", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_PROCEDURE, "ALTER PROCEDURE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_PUBLICATION, "ALTER PUBLICATION", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_ROLE, "ALTER ROLE", false, false, false) +PG_CMDTAG(CMDTAG_ALTER_ROUTINE, "ALTER ROUTINE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_RULE, "ALTER RULE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_SCHEMA, "ALTER SCHEMA", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_SEQUENCE, "ALTER SEQUENCE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_SERVER, "ALTER SERVER", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_STATISTICS, "ALTER STATISTICS", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_SUBSCRIPTION, "ALTER SUBSCRIPTION", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_SYSTEM, "ALTER SYSTEM", false, false, false) +PG_CMDTAG(CMDTAG_ALTER_TABLE, "ALTER TABLE", true, true, false) +PG_CMDTAG(CMDTAG_ALTER_TABLESPACE, "ALTER TABLESPACE", false, false, false) +PG_CMDTAG(CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION, "ALTER TEXT SEARCH CONFIGURATION", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY, "ALTER TEXT SEARCH DICTIONARY", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_TEXT_SEARCH_PARSER, "ALTER TEXT SEARCH PARSER", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_TEXT_SEARCH_TEMPLATE, "ALTER TEXT SEARCH TEMPLATE", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_TRANSFORM, "ALTER TRANSFORM", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_TRIGGER, "ALTER TRIGGER", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_TYPE, "ALTER TYPE", true, true, false) +PG_CMDTAG(CMDTAG_ALTER_USER_MAPPING, "ALTER USER MAPPING", true, false, false) +PG_CMDTAG(CMDTAG_ALTER_VIEW, "ALTER VIEW", true, false, false) +PG_CMDTAG(CMDTAG_ANALYZE, "ANALYZE", false, false, false) +PG_CMDTAG(CMDTAG_BEGIN, "BEGIN", false, false, false) +PG_CMDTAG(CMDTAG_CALL, "CALL", false, false, false) +PG_CMDTAG(CMDTAG_CHECKPOINT, "CHECKPOINT", false, false, false) +PG_CMDTAG(CMDTAG_CLOSE, "CLOSE", false, false, false) +PG_CMDTAG(CMDTAG_CLOSE_CURSOR, "CLOSE CURSOR", false, false, false) +PG_CMDTAG(CMDTAG_CLOSE_CURSOR_ALL, "CLOSE CURSOR ALL", false, false, false) +PG_CMDTAG(CMDTAG_CLUSTER, "CLUSTER", false, false, false) +PG_CMDTAG(CMDTAG_COMMENT, "COMMENT", true, false, false) +PG_CMDTAG(CMDTAG_COMMIT, "COMMIT", false, false, false) +PG_CMDTAG(CMDTAG_COMMIT_PREPARED, "COMMIT PREPARED", false, false, false) +PG_CMDTAG(CMDTAG_COPY, "COPY", false, false, true) +PG_CMDTAG(CMDTAG_COPY_FROM, "COPY FROM", false, false, false) +PG_CMDTAG(CMDTAG_CREATE_ACCESS_METHOD, "CREATE ACCESS METHOD", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_AGGREGATE, "CREATE AGGREGATE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_CAST, "CREATE CAST", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_COLLATION, "CREATE COLLATION", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_CONSTRAINT, "CREATE CONSTRAINT", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_CONVERSION, "CREATE CONVERSION", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_DATABASE, "CREATE DATABASE", false, false, false) +PG_CMDTAG(CMDTAG_CREATE_DOMAIN, "CREATE DOMAIN", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_EVENT_TRIGGER, "CREATE EVENT TRIGGER", false, false, false) +PG_CMDTAG(CMDTAG_CREATE_EXTENSION, "CREATE EXTENSION", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_FOREIGN_DATA_WRAPPER, "CREATE FOREIGN DATA WRAPPER", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_FOREIGN_TABLE, "CREATE FOREIGN TABLE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_FUNCTION, "CREATE FUNCTION", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_INDEX, "CREATE INDEX", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_LANGUAGE, "CREATE LANGUAGE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_MATERIALIZED_VIEW, "CREATE MATERIALIZED VIEW", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_OPERATOR, "CREATE OPERATOR", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_OPERATOR_CLASS, "CREATE OPERATOR CLASS", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_OPERATOR_FAMILY, "CREATE OPERATOR FAMILY", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_POLICY, "CREATE POLICY", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_PROCEDURE, "CREATE PROCEDURE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_PUBLICATION, "CREATE PUBLICATION", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_ROLE, "CREATE ROLE", false, false, false) +PG_CMDTAG(CMDTAG_CREATE_ROUTINE, "CREATE ROUTINE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_RULE, "CREATE RULE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_SCHEMA, "CREATE SCHEMA", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_SEQUENCE, "CREATE SEQUENCE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_SERVER, "CREATE SERVER", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_STATISTICS, "CREATE STATISTICS", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_SUBSCRIPTION, "CREATE SUBSCRIPTION", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TABLE, "CREATE TABLE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TABLE_AS, "CREATE TABLE AS", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TABLESPACE, "CREATE TABLESPACE", false, false, false) +PG_CMDTAG(CMDTAG_CREATE_TEXT_SEARCH_CONFIGURATION, "CREATE TEXT SEARCH CONFIGURATION", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TEXT_SEARCH_DICTIONARY, "CREATE TEXT SEARCH DICTIONARY", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TEXT_SEARCH_PARSER, "CREATE TEXT SEARCH PARSER", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TEXT_SEARCH_TEMPLATE, "CREATE TEXT SEARCH TEMPLATE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TRANSFORM, "CREATE TRANSFORM", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TRIGGER, "CREATE TRIGGER", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_TYPE, "CREATE TYPE", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_USER_MAPPING, "CREATE USER MAPPING", true, false, false) +PG_CMDTAG(CMDTAG_CREATE_VIEW, "CREATE VIEW", true, false, false) +PG_CMDTAG(CMDTAG_DEALLOCATE, "DEALLOCATE", false, false, false) +PG_CMDTAG(CMDTAG_DEALLOCATE_ALL, "DEALLOCATE ALL", false, false, false) +PG_CMDTAG(CMDTAG_DECLARE_CURSOR, "DECLARE CURSOR", false, false, false) +PG_CMDTAG(CMDTAG_DELETE, "DELETE", false, false, true) +PG_CMDTAG(CMDTAG_DISCARD, "DISCARD", false, false, false) +PG_CMDTAG(CMDTAG_DISCARD_ALL, "DISCARD ALL", false, false, false) +PG_CMDTAG(CMDTAG_DISCARD_PLANS, "DISCARD PLANS", false, false, false) +PG_CMDTAG(CMDTAG_DISCARD_SEQUENCES, "DISCARD SEQUENCES", false, false, false) +PG_CMDTAG(CMDTAG_DISCARD_TEMP, "DISCARD TEMP", false, false, false) +PG_CMDTAG(CMDTAG_DO, "DO", false, false, false) +PG_CMDTAG(CMDTAG_DROP_ACCESS_METHOD, "DROP ACCESS METHOD", true, false, false) +PG_CMDTAG(CMDTAG_DROP_AGGREGATE, "DROP AGGREGATE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_CAST, "DROP CAST", true, false, false) +PG_CMDTAG(CMDTAG_DROP_COLLATION, "DROP COLLATION", true, false, false) +PG_CMDTAG(CMDTAG_DROP_CONSTRAINT, "DROP CONSTRAINT", true, false, false) +PG_CMDTAG(CMDTAG_DROP_CONVERSION, "DROP CONVERSION", true, false, false) +PG_CMDTAG(CMDTAG_DROP_DATABASE, "DROP DATABASE", false, false, false) +PG_CMDTAG(CMDTAG_DROP_DOMAIN, "DROP DOMAIN", true, false, false) +PG_CMDTAG(CMDTAG_DROP_EVENT_TRIGGER, "DROP EVENT TRIGGER", false, false, false) +PG_CMDTAG(CMDTAG_DROP_EXTENSION, "DROP EXTENSION", true, false, false) +PG_CMDTAG(CMDTAG_DROP_FOREIGN_DATA_WRAPPER, "DROP FOREIGN DATA WRAPPER", true, false, false) +PG_CMDTAG(CMDTAG_DROP_FOREIGN_TABLE, "DROP FOREIGN TABLE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_FUNCTION, "DROP FUNCTION", true, false, false) +PG_CMDTAG(CMDTAG_DROP_INDEX, "DROP INDEX", true, false, false) +PG_CMDTAG(CMDTAG_DROP_LANGUAGE, "DROP LANGUAGE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_MATERIALIZED_VIEW, "DROP MATERIALIZED VIEW", true, false, false) +PG_CMDTAG(CMDTAG_DROP_OPERATOR, "DROP OPERATOR", true, false, false) +PG_CMDTAG(CMDTAG_DROP_OPERATOR_CLASS, "DROP OPERATOR CLASS", true, false, false) +PG_CMDTAG(CMDTAG_DROP_OPERATOR_FAMILY, "DROP OPERATOR FAMILY", true, false, false) +PG_CMDTAG(CMDTAG_DROP_OWNED, "DROP OWNED", true, false, false) +PG_CMDTAG(CMDTAG_DROP_POLICY, "DROP POLICY", true, false, false) +PG_CMDTAG(CMDTAG_DROP_PROCEDURE, "DROP PROCEDURE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_PUBLICATION, "DROP PUBLICATION", true, false, false) +PG_CMDTAG(CMDTAG_DROP_ROLE, "DROP ROLE", false, false, false) +PG_CMDTAG(CMDTAG_DROP_ROUTINE, "DROP ROUTINE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_RULE, "DROP RULE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_SCHEMA, "DROP SCHEMA", true, false, false) +PG_CMDTAG(CMDTAG_DROP_SEQUENCE, "DROP SEQUENCE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_SERVER, "DROP SERVER", true, false, false) +PG_CMDTAG(CMDTAG_DROP_STATISTICS, "DROP STATISTICS", true, false, false) +PG_CMDTAG(CMDTAG_DROP_SUBSCRIPTION, "DROP SUBSCRIPTION", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TABLE, "DROP TABLE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TABLESPACE, "DROP TABLESPACE", false, false, false) +PG_CMDTAG(CMDTAG_DROP_TEXT_SEARCH_CONFIGURATION, "DROP TEXT SEARCH CONFIGURATION", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TEXT_SEARCH_DICTIONARY, "DROP TEXT SEARCH DICTIONARY", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TEXT_SEARCH_PARSER, "DROP TEXT SEARCH PARSER", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TEXT_SEARCH_TEMPLATE, "DROP TEXT SEARCH TEMPLATE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TRANSFORM, "DROP TRANSFORM", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TRIGGER, "DROP TRIGGER", true, false, false) +PG_CMDTAG(CMDTAG_DROP_TYPE, "DROP TYPE", true, false, false) +PG_CMDTAG(CMDTAG_DROP_USER_MAPPING, "DROP USER MAPPING", true, false, false) +PG_CMDTAG(CMDTAG_DROP_VIEW, "DROP VIEW", true, false, false) +PG_CMDTAG(CMDTAG_EXECUTE, "EXECUTE", false, false, false) +PG_CMDTAG(CMDTAG_EXPLAIN, "EXPLAIN", false, false, false) +PG_CMDTAG(CMDTAG_FETCH, "FETCH", false, false, true) +PG_CMDTAG(CMDTAG_GRANT, "GRANT", true, false, false) +PG_CMDTAG(CMDTAG_GRANT_ROLE, "GRANT ROLE", false, false, false) +PG_CMDTAG(CMDTAG_IMPORT_FOREIGN_SCHEMA, "IMPORT FOREIGN SCHEMA", true, false, false) +PG_CMDTAG(CMDTAG_INSERT, "INSERT", false, false, true) +PG_CMDTAG(CMDTAG_LISTEN, "LISTEN", false, false, false) +PG_CMDTAG(CMDTAG_LOAD, "LOAD", false, false, false) +PG_CMDTAG(CMDTAG_LOCK_TABLE, "LOCK TABLE", false, false, false) +PG_CMDTAG(CMDTAG_MERGE, "MERGE", false, false, true) +PG_CMDTAG(CMDTAG_MOVE, "MOVE", false, false, true) +PG_CMDTAG(CMDTAG_NOTIFY, "NOTIFY", false, false, false) +PG_CMDTAG(CMDTAG_PREPARE, "PREPARE", false, false, false) +PG_CMDTAG(CMDTAG_PREPARE_TRANSACTION, "PREPARE TRANSACTION", false, false, false) +PG_CMDTAG(CMDTAG_REASSIGN_OWNED, "REASSIGN OWNED", false, false, false) +PG_CMDTAG(CMDTAG_REFRESH_MATERIALIZED_VIEW, "REFRESH MATERIALIZED VIEW", true, false, false) +PG_CMDTAG(CMDTAG_REINDEX, "REINDEX", false, false, false) +PG_CMDTAG(CMDTAG_RELEASE, "RELEASE", false, false, false) +PG_CMDTAG(CMDTAG_RESET, "RESET", false, false, false) +PG_CMDTAG(CMDTAG_REVOKE, "REVOKE", true, false, false) +PG_CMDTAG(CMDTAG_REVOKE_ROLE, "REVOKE ROLE", false, false, false) +PG_CMDTAG(CMDTAG_ROLLBACK, "ROLLBACK", false, false, false) +PG_CMDTAG(CMDTAG_ROLLBACK_PREPARED, "ROLLBACK PREPARED", false, false, false) +PG_CMDTAG(CMDTAG_SAVEPOINT, "SAVEPOINT", false, false, false) +PG_CMDTAG(CMDTAG_SECURITY_LABEL, "SECURITY LABEL", true, false, false) +PG_CMDTAG(CMDTAG_SELECT, "SELECT", false, false, true) +PG_CMDTAG(CMDTAG_SELECT_FOR_KEY_SHARE, "SELECT FOR KEY SHARE", false, false, false) +PG_CMDTAG(CMDTAG_SELECT_FOR_NO_KEY_UPDATE, "SELECT FOR NO KEY UPDATE", false, false, false) +PG_CMDTAG(CMDTAG_SELECT_FOR_SHARE, "SELECT FOR SHARE", false, false, false) +PG_CMDTAG(CMDTAG_SELECT_FOR_UPDATE, "SELECT FOR UPDATE", false, false, false) +PG_CMDTAG(CMDTAG_SELECT_INTO, "SELECT INTO", true, false, false) +PG_CMDTAG(CMDTAG_SET, "SET", false, false, false) +PG_CMDTAG(CMDTAG_SET_CONSTRAINTS, "SET CONSTRAINTS", false, false, false) +PG_CMDTAG(CMDTAG_SHOW, "SHOW", false, false, false) +PG_CMDTAG(CMDTAG_START_TRANSACTION, "START TRANSACTION", false, false, false) +PG_CMDTAG(CMDTAG_TRUNCATE_TABLE, "TRUNCATE TABLE", false, false, false) +PG_CMDTAG(CMDTAG_UNLISTEN, "UNLISTEN", false, false, false) +PG_CMDTAG(CMDTAG_UPDATE, "UPDATE", false, false, true) +PG_CMDTAG(CMDTAG_VACUUM, "VACUUM", false, false, false) diff --git a/install/include/postgresql/server/tcop/deparse_utility.h b/install/include/postgresql/server/tcop/deparse_utility.h new file mode 100644 index 00000000000..b585810b9a6 --- /dev/null +++ b/install/include/postgresql/server/tcop/deparse_utility.h @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------- + * + * deparse_utility.h + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/deparse_utility.h + * + *------------------------------------------------------------------------- + */ +#ifndef DEPARSE_UTILITY_H +#define DEPARSE_UTILITY_H + +#include "access/attnum.h" +#include "catalog/objectaddress.h" +#include "nodes/nodes.h" +#include "utils/aclchk_internal.h" + + +/* + * Support for keeping track of collected commands. + */ +typedef enum CollectedCommandType +{ + SCT_Simple, + SCT_AlterTable, + SCT_Grant, + SCT_AlterOpFamily, + SCT_AlterDefaultPrivileges, + SCT_CreateOpClass, + SCT_AlterTSConfig +} CollectedCommandType; + +/* + * For ALTER TABLE commands, we keep a list of the subcommands therein. + */ +typedef struct CollectedATSubcmd +{ + ObjectAddress address; /* affected column, constraint, index, ... */ + Node *parsetree; +} CollectedATSubcmd; + +typedef struct CollectedCommand +{ + CollectedCommandType type; + + bool in_extension; + Node *parsetree; + + union + { + /* most commands */ + struct + { + ObjectAddress address; + ObjectAddress secondaryObject; + } simple; + + /* ALTER TABLE, and internal uses thereof */ + struct + { + Oid objectId; + Oid classId; + List *subcmds; + } alterTable; + + /* GRANT / REVOKE */ + struct + { + InternalGrant *istmt; + } grant; + + /* ALTER OPERATOR FAMILY */ + struct + { + ObjectAddress address; + List *operators; + List *procedures; + } opfam; + + /* CREATE OPERATOR CLASS */ + struct + { + ObjectAddress address; + List *operators; + List *procedures; + } createopc; + + /* ALTER TEXT SEARCH CONFIGURATION ADD/ALTER/DROP MAPPING */ + struct + { + ObjectAddress address; + Oid *dictIds; + int ndicts; + } atscfg; + + /* ALTER DEFAULT PRIVILEGES */ + struct + { + ObjectType objtype; + } defprivs; + } d; + + struct CollectedCommand *parent; /* when nested */ +} CollectedCommand; + +#endif /* DEPARSE_UTILITY_H */ diff --git a/install/include/postgresql/server/tcop/dest.h b/install/include/postgresql/server/tcop/dest.h new file mode 100644 index 00000000000..a7d86e7abd4 --- /dev/null +++ b/install/include/postgresql/server/tcop/dest.h @@ -0,0 +1,147 @@ +/*------------------------------------------------------------------------- + * + * dest.h + * support for communication destinations + * + * Whenever the backend executes a query that returns tuples, the results + * have to go someplace. For example: + * + * - stdout is the destination only when we are running a + * standalone backend (no postmaster) and are returning results + * back to an interactive user. + * + * - a remote process is the destination when we are + * running a backend with a frontend and the frontend executes + * PQexec() or PQfn(). In this case, the results are sent + * to the frontend via the functions in backend/libpq. + * + * - DestNone is the destination when the system executes + * a query internally. The results are discarded. + * + * dest.c defines three functions that implement destination management: + * + * BeginCommand: initialize the destination at start of command. + * CreateDestReceiver: return a pointer to a struct of destination-specific + * receiver functions. + * EndCommand: clean up the destination at end of command. + * + * BeginCommand/EndCommand are executed once per received SQL query. + * + * CreateDestReceiver returns a receiver object appropriate to the specified + * destination. The executor, as well as utility statements that can return + * tuples, are passed the resulting DestReceiver* pointer. Each executor run + * or utility execution calls the receiver's rStartup method, then the + * receiveSlot method (zero or more times), then the rShutdown method. + * The same receiver object may be re-used multiple times; eventually it is + * destroyed by calling its rDestroy method. + * + * In some cases, receiver objects require additional parameters that must + * be passed to them after calling CreateDestReceiver. Since the set of + * parameters varies for different receiver types, this is not handled by + * this module, but by direct calls from the calling code to receiver type + * specific functions. + * + * The DestReceiver object returned by CreateDestReceiver may be a statically + * allocated object (for destination types that require no local state), + * in which case rDestroy is a no-op. Alternatively it can be a palloc'd + * object that has DestReceiver as its first field and contains additional + * fields (see printtup.c for an example). These additional fields are then + * accessible to the DestReceiver functions by casting the DestReceiver* + * pointer passed to them. The palloc'd object is pfree'd by the rDestroy + * method. Note that the caller of CreateDestReceiver should take care to + * do so in a memory context that is long-lived enough for the receiver + * object not to disappear while still needed. + * + * Special provision: None_Receiver is a permanently available receiver + * object for the DestNone destination. This avoids useless creation/destroy + * calls in portal and cursor manipulations. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/dest.h + * + *------------------------------------------------------------------------- + */ +#ifndef DEST_H +#define DEST_H + +#include "executor/tuptable.h" +#include "tcop/cmdtag.h" + + + + +/* ---------------- + * CommandDest is a simplistic means of identifying the desired + * destination. Someday this will probably need to be improved. + * + * Note: only the values DestNone, DestDebug, DestRemote are legal for the + * global variable whereToSendOutput. The other values may be used + * as the destination for individual commands. + * ---------------- + */ +typedef enum +{ + DestNone, /* results are discarded */ + DestDebug, /* results go to debugging output */ + DestRemote, /* results sent to frontend process */ + DestRemoteExecute, /* sent to frontend, in Execute command */ + DestRemoteSimple, /* sent to frontend, w/no catalog access */ + DestSPI, /* results sent to SPI manager */ + DestTuplestore, /* results sent to Tuplestore */ + DestIntoRel, /* results sent to relation (SELECT INTO) */ + DestCopyOut, /* results sent to COPY TO code */ + DestSQLFunction, /* results sent to SQL-language func mgr */ + DestTransientRel, /* results sent to transient relation */ + DestTupleQueue /* results sent to tuple queue */ +} CommandDest; + +/* ---------------- + * DestReceiver is a base type for destination-specific local state. + * In the simplest cases, there is no state info, just the function + * pointers that the executor must call. + * + * Note: the receiveSlot routine must be passed a slot containing a TupleDesc + * identical to the one given to the rStartup routine. It returns bool where + * a "true" value means "continue processing" and a "false" value means + * "stop early, just as if we'd reached the end of the scan". + * ---------------- + */ +typedef struct _DestReceiver DestReceiver; + +struct _DestReceiver +{ + /* Called for each tuple to be output: */ + bool (*receiveSlot) (TupleTableSlot *slot, + DestReceiver *self); + /* Per-executor-run initialization and shutdown: */ + void (*rStartup) (DestReceiver *self, + int operation, + TupleDesc typeinfo); + void (*rShutdown) (DestReceiver *self); + /* Destroy the receiver object itself (if dynamically allocated) */ + void (*rDestroy) (DestReceiver *self); + /* CommandDest code for this receiver */ + CommandDest mydest; + /* Private fields might appear beyond this point... */ +}; + +extern PGDLLIMPORT DestReceiver *None_Receiver; /* permanent receiver for + * DestNone */ + +/* The primary destination management functions */ + +extern void BeginCommand(CommandTag commandTag, CommandDest dest); +extern DestReceiver *CreateDestReceiver(CommandDest dest); +extern void EndCommand(const QueryCompletion *qc, CommandDest dest, + bool force_undecorated_output); +extern void EndReplicationCommand(const char *commandTag); + +/* Additional functions that go with destination management, more or less. */ + +extern void NullCommand(CommandDest dest); +extern void ReadyForQuery(CommandDest dest); + +#endif /* DEST_H */ diff --git a/install/include/postgresql/server/tcop/fastpath.h b/install/include/postgresql/server/tcop/fastpath.h new file mode 100644 index 00000000000..9d57f79def9 --- /dev/null +++ b/install/include/postgresql/server/tcop/fastpath.h @@ -0,0 +1,20 @@ +/*------------------------------------------------------------------------- + * + * fastpath.h + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/fastpath.h + * + *------------------------------------------------------------------------- + */ +#ifndef FASTPATH_H +#define FASTPATH_H + +#include "lib/stringinfo.h" + +extern void HandleFunctionRequest(StringInfo msgBuf); + +#endif /* FASTPATH_H */ diff --git a/install/include/postgresql/server/tcop/pquery.h b/install/include/postgresql/server/tcop/pquery.h new file mode 100644 index 00000000000..a5e65b98aa3 --- /dev/null +++ b/install/include/postgresql/server/tcop/pquery.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------- + * + * pquery.h + * prototypes for pquery.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/pquery.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQUERY_H +#define PQUERY_H + +#include "nodes/parsenodes.h" +#include "utils/portal.h" + +struct PlannedStmt; /* avoid including plannodes.h here */ + + +extern PGDLLIMPORT Portal ActivePortal; + + +extern PortalStrategy ChoosePortalStrategy(List *stmts); + +extern List *FetchPortalTargetList(Portal portal); + +extern List *FetchStatementTargetList(Node *stmt); + +extern void PortalStart(Portal portal, ParamListInfo params, + int eflags, Snapshot snapshot); + +extern void PortalSetResultFormat(Portal portal, int nFormats, + int16 *formats); + +extern bool PortalRun(Portal portal, long count, bool isTopLevel, + bool run_once, DestReceiver *dest, DestReceiver *altdest, + QueryCompletion *qc); + +extern uint64 PortalRunFetch(Portal portal, + FetchDirection fdirection, + long count, + DestReceiver *dest); + +extern bool PlannedStmtRequiresSnapshot(struct PlannedStmt *pstmt); + +extern void EnsurePortalSnapshotExists(void); + +#endif /* PQUERY_H */ diff --git a/install/include/postgresql/server/tcop/tcopprot.h b/install/include/postgresql/server/tcop/tcopprot.h new file mode 100644 index 00000000000..e529e9f06c2 --- /dev/null +++ b/install/include/postgresql/server/tcop/tcopprot.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------- + * + * tcopprot.h + * prototypes for postgres.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/tcopprot.h + * + *------------------------------------------------------------------------- + */ +#ifndef TCOPPROT_H +#define TCOPPROT_H + +#include "nodes/params.h" +#include "nodes/parsenodes.h" +#include "nodes/plannodes.h" +#include "storage/procsignal.h" +#include "utils/guc.h" +#include "utils/queryenvironment.h" + + +/* Required daylight between max_stack_depth and the kernel limit, in bytes */ +#define STACK_DEPTH_SLOP (512 * 1024L) + +extern PGDLLIMPORT CommandDest whereToSendOutput; +extern PGDLLIMPORT const char *debug_query_string; +extern PGDLLIMPORT int max_stack_depth; +extern PGDLLIMPORT int PostAuthDelay; +extern PGDLLIMPORT int client_connection_check_interval; + +/* GUC-configurable parameters */ + +typedef enum +{ + LOGSTMT_NONE, /* log no statements */ + LOGSTMT_DDL, /* log data definition statements */ + LOGSTMT_MOD, /* log modification statements, plus DDL */ + LOGSTMT_ALL /* log all statements */ +} LogStmtLevel; + +extern PGDLLIMPORT int log_statement; + +/* Flags for restrict_nonsystem_relation_kind value */ +#define RESTRICT_RELKIND_VIEW 0x01 +#define RESTRICT_RELKIND_FOREIGN_TABLE 0x02 + +extern PGDLLIMPORT int restrict_nonsystem_relation_kind; + +extern List *pg_parse_query(const char *query_string); +extern List *pg_rewrite_query(Query *query); +extern List *pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, + const char *query_string, + const Oid *paramTypes, int numParams, + QueryEnvironment *queryEnv); +extern List *pg_analyze_and_rewrite_varparams(RawStmt *parsetree, + const char *query_string, + Oid **paramTypes, + int *numParams, + QueryEnvironment *queryEnv); +extern List *pg_analyze_and_rewrite_withcb(RawStmt *parsetree, + const char *query_string, + ParserSetupHook parserSetup, + void *parserSetupArg, + QueryEnvironment *queryEnv); +extern PlannedStmt *pg_plan_query(Query *querytree, const char *query_string, + int cursorOptions, + ParamListInfo boundParams); +extern List *pg_plan_queries(List *querytrees, const char *query_string, + int cursorOptions, + ParamListInfo boundParams); + +extern void die(SIGNAL_ARGS); +extern void quickdie(SIGNAL_ARGS) pg_attribute_noreturn(); +extern void StatementCancelHandler(SIGNAL_ARGS); +extern void FloatExceptionHandler(SIGNAL_ARGS) pg_attribute_noreturn(); +extern void RecoveryConflictInterrupt(ProcSignalReason reason); /* called from SIGUSR1 + * handler */ +extern void ProcessClientReadInterrupt(bool blocked); +extern void ProcessClientWriteInterrupt(bool blocked); + +extern void process_postgres_switches(int argc, char *argv[], + GucContext ctx, const char **dbname); +extern void PostgresSingleUserMain(int argc, char *argv[], + const char *username) pg_attribute_noreturn(); +extern void PostgresMain(const char *dbname, + const char *username) pg_attribute_noreturn(); +extern long get_stack_depth_rlimit(void); +extern void ResetUsage(void); +extern void ShowUsage(const char *title); +extern int check_log_duration(char *msec_str, bool was_logged); +extern void set_debug_options(int debug_flag, + GucContext context, GucSource source); +extern bool set_plan_disabling_options(const char *arg, + GucContext context, GucSource source); +extern const char *get_stats_option_name(const char *arg); + +#endif /* TCOPPROT_H */ diff --git a/install/include/postgresql/server/tcop/utility.h b/install/include/postgresql/server/tcop/utility.h new file mode 100644 index 00000000000..59e64aea073 --- /dev/null +++ b/install/include/postgresql/server/tcop/utility.h @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------------- + * + * utility.h + * prototypes for utility.c. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tcop/utility.h + * + *------------------------------------------------------------------------- + */ +#ifndef UTILITY_H +#define UTILITY_H + +#include "tcop/cmdtag.h" +#include "tcop/tcopprot.h" + +typedef enum +{ + PROCESS_UTILITY_TOPLEVEL, /* toplevel interactive command */ + PROCESS_UTILITY_QUERY, /* a complete query, but not toplevel */ + PROCESS_UTILITY_QUERY_NONATOMIC, /* a complete query, nonatomic + * execution context */ + PROCESS_UTILITY_SUBCOMMAND /* a portion of a query */ +} ProcessUtilityContext; + +/* Info needed when recursing from ALTER TABLE */ +typedef struct AlterTableUtilityContext +{ + PlannedStmt *pstmt; /* PlannedStmt for outer ALTER TABLE command */ + const char *queryString; /* its query string */ + Oid relid; /* OID of ALTER's target table */ + ParamListInfo params; /* any parameters available to ALTER TABLE */ + QueryEnvironment *queryEnv; /* execution environment for ALTER TABLE */ +} AlterTableUtilityContext; + +/* + * These constants are used to describe the extent to which a particular + * command is read-only. + * + * COMMAND_OK_IN_READ_ONLY_TXN means that the command is permissible even when + * XactReadOnly is set. This bit should be set for commands that don't change + * the state of the database (data or schema) in a way that would affect the + * output of pg_dump. + * + * COMMAND_OK_IN_PARALLEL_MODE means that the command is permissible even + * when in parallel mode. Writing tuples is forbidden, as is anything that + * might confuse cooperating processes. + * + * COMMAND_OK_IN_RECOVERY means that the command is permissible even when in + * recovery. It can't write WAL, nor can it do things that would imperil + * replay of future WAL received from the primary. + */ +#define COMMAND_OK_IN_READ_ONLY_TXN 0x0001 +#define COMMAND_OK_IN_PARALLEL_MODE 0x0002 +#define COMMAND_OK_IN_RECOVERY 0x0004 + +/* + * We say that a command is strictly read-only if it is sufficiently read-only + * for all purposes. For clarity, we also have a constant for commands that are + * in no way read-only. + */ +#define COMMAND_IS_STRICTLY_READ_ONLY \ + (COMMAND_OK_IN_READ_ONLY_TXN | COMMAND_OK_IN_RECOVERY | \ + COMMAND_OK_IN_PARALLEL_MODE) +#define COMMAND_IS_NOT_READ_ONLY 0 + +/* Hook for plugins to get control in ProcessUtility() */ +typedef void (*ProcessUtility_hook_type) (PlannedStmt *pstmt, + const char *queryString, + bool readOnlyTree, + ProcessUtilityContext context, + ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, QueryCompletion *qc); +extern PGDLLIMPORT ProcessUtility_hook_type ProcessUtility_hook; + +extern void ProcessUtility(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, + ProcessUtilityContext context, ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, QueryCompletion *qc); +extern void standard_ProcessUtility(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, + ProcessUtilityContext context, ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, QueryCompletion *qc); + +extern void ProcessUtilityForAlterTable(Node *stmt, + AlterTableUtilityContext *context); + +extern bool UtilityReturnsTuples(Node *parsetree); + +extern TupleDesc UtilityTupleDescriptor(Node *parsetree); + +extern Query *UtilityContainsQuery(Node *parsetree); + +extern CommandTag CreateCommandTag(Node *parsetree); + +static inline const char * +CreateCommandName(Node *parsetree) +{ + return GetCommandTagName(CreateCommandTag(parsetree)); +} + +extern LogStmtLevel GetCommandLogLevel(Node *parsetree); + +extern bool CommandIsReadOnly(PlannedStmt *pstmt); + +#endif /* UTILITY_H */ diff --git a/install/include/postgresql/server/tsearch/dicts/regis.h b/install/include/postgresql/server/tsearch/dicts/regis.h new file mode 100644 index 00000000000..0b817291287 --- /dev/null +++ b/install/include/postgresql/server/tsearch/dicts/regis.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * regis.h + * + * Declarations for fast regex subset, used by ISpell + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/tsearch/dicts/regis.h + * + *------------------------------------------------------------------------- + */ + +#ifndef __REGIS_H__ +#define __REGIS_H__ + +typedef struct RegisNode +{ + uint32 + type:2, + len:16, + unused:14; + struct RegisNode *next; + unsigned char data[FLEXIBLE_ARRAY_MEMBER]; +} RegisNode; + +#define RNHDRSZ (offsetof(RegisNode,data)) + +#define RSF_ONEOF 1 +#define RSF_NONEOF 2 + +typedef struct Regis +{ + RegisNode *node; + uint32 + issuffix:1, + nchar:16, + unused:15; +} Regis; + +extern bool RS_isRegis(const char *str); + +extern void RS_compile(Regis *r, bool issuffix, const char *str); +extern void RS_free(Regis *r); + +/*returns true if matches */ +extern bool RS_execute(Regis *r, char *str); + +#endif diff --git a/install/include/postgresql/server/tsearch/dicts/spell.h b/install/include/postgresql/server/tsearch/dicts/spell.h new file mode 100644 index 00000000000..0763f9ffe7b --- /dev/null +++ b/install/include/postgresql/server/tsearch/dicts/spell.h @@ -0,0 +1,241 @@ +/*------------------------------------------------------------------------- + * + * spell.h + * + * Declarations for ISpell dictionary + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/tsearch/dicts/spell.h + * + *------------------------------------------------------------------------- + */ + +#ifndef __SPELL_H__ +#define __SPELL_H__ + +#include "regex/regex.h" +#include "tsearch/dicts/regis.h" +#include "tsearch/ts_public.h" + +/* + * SPNode and SPNodeData are used to represent prefix tree (Trie) to store + * a words list. + */ +struct SPNode; + +typedef struct +{ + uint32 val:8, + isword:1, + /* Stores compound flags listed below */ + compoundflag:4, + /* Reference to an entry of the AffixData field */ + affix:19; + struct SPNode *node; +} SPNodeData; + +/* + * Names of FF_ are correlated with Hunspell options in affix file + * https://hunspell.github.io/ + */ +#define FF_COMPOUNDONLY 0x01 +#define FF_COMPOUNDBEGIN 0x02 +#define FF_COMPOUNDMIDDLE 0x04 +#define FF_COMPOUNDLAST 0x08 +#define FF_COMPOUNDFLAG ( FF_COMPOUNDBEGIN | FF_COMPOUNDMIDDLE | \ + FF_COMPOUNDLAST ) +#define FF_COMPOUNDFLAGMASK 0x0f + +typedef struct SPNode +{ + uint32 length; + SPNodeData data[FLEXIBLE_ARRAY_MEMBER]; +} SPNode; + +#define SPNHDRSZ (offsetof(SPNode,data)) + +/* + * Represents an entry in a words list. + */ +typedef struct spell_struct +{ + union + { + /* + * flag is filled in by NIImportDictionary(). After + * NISortDictionary(), d is used instead of flag. + */ + char *flag; + /* d is used in mkSPNode() */ + struct + { + /* Reference to an entry of the AffixData field */ + int affix; + /* Length of the word */ + int len; + } d; + } p; + char word[FLEXIBLE_ARRAY_MEMBER]; +} SPELL; + +#define SPELLHDRSZ (offsetof(SPELL, word)) + +/* + * Represents an entry in an affix list. + */ +typedef struct aff_struct +{ + char *flag; + /* FF_SUFFIX or FF_PREFIX */ + uint32 type:1, + flagflags:7, + issimple:1, + isregis:1, + replen:14; + char *find; + char *repl; + union + { + /* + * Arrays of AFFIX are moved and sorted. We'll use a pointer to + * regex_t to keep this struct small, and avoid assuming that regex_t + * is movable. + */ + regex_t *pregex; + Regis regis; + } reg; +} AFFIX; + +/* + * affixes use dictionary flags too + */ +#define FF_COMPOUNDPERMITFLAG 0x10 +#define FF_COMPOUNDFORBIDFLAG 0x20 +#define FF_CROSSPRODUCT 0x40 + +/* + * Don't change the order of these. Initialization sorts by these, + * and expects prefixes to come first after sorting. + */ +#define FF_SUFFIX 1 +#define FF_PREFIX 0 + +/* + * AffixNode and AffixNodeData are used to represent prefix tree (Trie) to store + * an affix list. + */ +struct AffixNode; + +typedef struct +{ + uint32 val:8, + naff:24; + AFFIX **aff; + struct AffixNode *node; +} AffixNodeData; + +typedef struct AffixNode +{ + uint32 isvoid:1, + length:31; + AffixNodeData data[FLEXIBLE_ARRAY_MEMBER]; +} AffixNode; + +#define ANHRDSZ (offsetof(AffixNode, data)) + +typedef struct +{ + char *affix; + int len; + bool issuffix; +} CMPDAffix; + +/* + * Type of encoding affix flags in Hunspell dictionaries + */ +typedef enum +{ + FM_CHAR, /* one character (like ispell) */ + FM_LONG, /* two characters */ + FM_NUM /* number, >= 0 and < 65536 */ +} FlagMode; + +/* + * Structure to store Hunspell options. Flag representation depends on flag + * type. These flags are about support of compound words. + */ +typedef struct CompoundAffixFlag +{ + union + { + /* Flag name if flagMode is FM_CHAR or FM_LONG */ + char *s; + /* Flag name if flagMode is FM_NUM */ + uint32 i; + } flag; + /* we don't have a bsearch_arg version, so, copy FlagMode */ + FlagMode flagMode; + uint32 value; +} CompoundAffixFlag; + +#define FLAGNUM_MAXSIZE (1 << 16) + +typedef struct +{ + int maffixes; + int naffixes; + AFFIX *Affix; + + AffixNode *Suffix; + AffixNode *Prefix; + + SPNode *Dictionary; + /* Array of sets of affixes */ + char **AffixData; + int lenAffixData; + int nAffixData; + bool useFlagAliases; + + CMPDAffix *CompoundAffix; + + bool usecompound; + FlagMode flagMode; + + /* + * All follow fields are actually needed only for initialization + */ + + /* Array of Hunspell options in affix file */ + CompoundAffixFlag *CompoundAffixFlags; + /* number of entries in CompoundAffixFlags array */ + int nCompoundAffixFlag; + /* allocated length of CompoundAffixFlags array */ + int mCompoundAffixFlag; + + /* + * Remaining fields are only used during dictionary construction; they are + * set up by NIStartBuild and cleared by NIFinishBuild. + */ + MemoryContext buildCxt; /* temp context for construction */ + + /* Temporary array of all words in the dict file */ + SPELL **Spell; + int nspell; /* number of valid entries in Spell array */ + int mspell; /* allocated length of Spell array */ + + /* These are used to allocate "compact" data without palloc overhead */ + char *firstfree; /* first free address (always maxaligned) */ + size_t avail; /* free space remaining at firstfree */ +} IspellDict; + +extern TSLexeme *NINormalizeWord(IspellDict *Conf, char *word); + +extern void NIStartBuild(IspellDict *Conf); +extern void NIImportAffixes(IspellDict *Conf, const char *filename); +extern void NIImportDictionary(IspellDict *Conf, const char *filename); +extern void NISortDictionary(IspellDict *Conf); +extern void NISortAffixes(IspellDict *Conf); +extern void NIFinishBuild(IspellDict *Conf); + +#endif diff --git a/install/include/postgresql/server/tsearch/ts_cache.h b/install/include/postgresql/server/tsearch/ts_cache.h new file mode 100644 index 00000000000..d432bd0ace4 --- /dev/null +++ b/install/include/postgresql/server/tsearch/ts_cache.h @@ -0,0 +1,96 @@ +/*------------------------------------------------------------------------- + * + * ts_cache.h + * Tsearch related object caches. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/tsearch/ts_cache.h + * + *------------------------------------------------------------------------- + */ +#ifndef TS_CACHE_H +#define TS_CACHE_H + +#include "fmgr.h" + + +/* + * All TS*CacheEntry structs must share this common header + * (see InvalidateTSCacheCallBack) + */ +typedef struct TSAnyCacheEntry +{ + Oid objId; + bool isvalid; +} TSAnyCacheEntry; + + +typedef struct TSParserCacheEntry +{ + /* prsId is the hash lookup key and MUST BE FIRST */ + Oid prsId; /* OID of the parser */ + bool isvalid; + + Oid startOid; + Oid tokenOid; + Oid endOid; + Oid headlineOid; + Oid lextypeOid; + + /* + * Pre-set-up fmgr call of most needed parser's methods + */ + FmgrInfo prsstart; + FmgrInfo prstoken; + FmgrInfo prsend; + FmgrInfo prsheadline; +} TSParserCacheEntry; + +typedef struct TSDictionaryCacheEntry +{ + /* dictId is the hash lookup key and MUST BE FIRST */ + Oid dictId; + bool isvalid; + + /* most frequent fmgr call */ + Oid lexizeOid; + FmgrInfo lexize; + + MemoryContext dictCtx; /* memory context to store private data */ + void *dictData; +} TSDictionaryCacheEntry; + +typedef struct +{ + int len; + Oid *dictIds; +} ListDictionary; + +typedef struct +{ + /* cfgId is the hash lookup key and MUST BE FIRST */ + Oid cfgId; + bool isvalid; + + Oid prsId; + + int lenmap; + ListDictionary *map; +} TSConfigCacheEntry; + + +/* + * GUC variable for current configuration + */ +extern PGDLLIMPORT char *TSCurrentConfig; + + +extern TSParserCacheEntry *lookup_ts_parser_cache(Oid prsId); +extern TSDictionaryCacheEntry *lookup_ts_dictionary_cache(Oid dictId); +extern TSConfigCacheEntry *lookup_ts_config_cache(Oid cfgId); + +extern Oid getTSCurrentConfig(bool emitError); + +#endif /* TS_CACHE_H */ diff --git a/install/include/postgresql/server/tsearch/ts_locale.h b/install/include/postgresql/server/tsearch/ts_locale.h new file mode 100644 index 00000000000..787ffb165d1 --- /dev/null +++ b/install/include/postgresql/server/tsearch/ts_locale.h @@ -0,0 +1,80 @@ +/*------------------------------------------------------------------------- + * + * ts_locale.h + * locale compatibility layer for tsearch + * + * Copyright (c) 1998-2023, PostgreSQL Global Development Group + * + * src/include/tsearch/ts_locale.h + * + *------------------------------------------------------------------------- + */ +#ifndef __TSLOCALE_H__ +#define __TSLOCALE_H__ + +#include +#include +#include + +#include "lib/stringinfo.h" +#include "mb/pg_wchar.h" +#include "utils/pg_locale.h" + +/* working state for tsearch_readline (should be a local var in caller) */ +typedef struct +{ + FILE *fp; + const char *filename; + int lineno; + StringInfoData buf; /* current input line, in UTF-8 */ + char *curline; /* current input line, in DB's encoding */ + /* curline may be NULL, or equal to buf.data, or a palloc'd string */ + ErrorContextCallback cb; +} tsearch_readline_state; + +#define TOUCHAR(x) (*((const unsigned char *) (x))) + +/* The second argument of t_iseq() must be a plain ASCII character */ +#define t_iseq(x,c) (TOUCHAR(x) == (unsigned char) (c)) + +/* Copy multibyte character of known byte length, return byte length. */ +static inline int +ts_copychar_with_len(void *dest, const void *src, int length) +{ + memcpy(dest, src, length); + return length; +} + +/* Copy multibyte character from null-terminated string, return byte length. */ +static inline int +ts_copychar_cstr(void *dest, const void *src) +{ + return ts_copychar_with_len(dest, src, pg_mblen_cstr((const char *) src)); +} + +/* Historical macro for the above. */ +#define COPYCHAR ts_copychar_cstr + +#define GENERATE_T_ISCLASS_DECL(character_class) \ +extern int t_is##character_class##_with_len(const char *ptr, int len); \ +extern int t_is##character_class##_cstr(const char *ptr); \ +extern int t_is##character_class##_unbounded(const char *ptr); \ +\ +/* deprecated */ \ +extern int t_is##character_class(const char *ptr); + +GENERATE_T_ISCLASS_DECL(alnum); +GENERATE_T_ISCLASS_DECL(alpha); +GENERATE_T_ISCLASS_DECL(digit); +GENERATE_T_ISCLASS_DECL(print); +GENERATE_T_ISCLASS_DECL(space); + +extern char *lowerstr(const char *str); +extern char *lowerstr_with_len(const char *str, int len); + +extern bool tsearch_readline_begin(tsearch_readline_state *stp, + const char *filename); +extern char *tsearch_readline(tsearch_readline_state *stp); +extern void tsearch_readline_end(tsearch_readline_state *stp); + +#endif /* __TSLOCALE_H__ */ diff --git a/install/include/postgresql/server/tsearch/ts_public.h b/install/include/postgresql/server/tsearch/ts_public.h new file mode 100644 index 00000000000..0c9bc1498ef --- /dev/null +++ b/install/include/postgresql/server/tsearch/ts_public.h @@ -0,0 +1,159 @@ +/*------------------------------------------------------------------------- + * + * ts_public.h + * Public interface to various tsearch modules, such as + * parsers and dictionaries. + * + * Copyright (c) 1998-2023, PostgreSQL Global Development Group + * + * src/include/tsearch/ts_public.h + * + *------------------------------------------------------------------------- + */ +#ifndef _PG_TS_PUBLIC_H_ +#define _PG_TS_PUBLIC_H_ + +#include "tsearch/ts_type.h" + +/* + * Parser's framework + */ + +/* + * returning type for prslextype method of parser + */ +typedef struct +{ + int lexid; + char *alias; + char *descr; +} LexDescr; + +/* + * Interface to headline generator (tsparser's prsheadline function) + * + * HeadlineParsedText describes the text that is to be highlighted. + * Some fields are passed from the core code to the prsheadline function, + * while others are output from the prsheadline function. + * + * The principal data is words[], an array of HeadlineWordEntry, + * one entry per token, of length curwords. + * The fields of HeadlineWordEntry are: + * + * in, selected, replace, skip: these flags are initially zero + * and may be set by the prsheadline function. A consecutive group + * of tokens marked "in" form a "fragment" to be output. + * Such tokens may additionally be marked selected, replace, or skip + * to modify how they are shown. (If you set more than one of those + * bits, you get an unspecified one of those behaviors.) + * + * type, len, pos, word: filled by core code to describe the token. + * + * item: if the token matches any operand of the tsquery of interest, + * a pointer to such an operand. (If there are multiple matching + * operands, we generate extra copies of the HeadlineWordEntry to hold + * all the pointers. The extras are marked with repeated = 1 and should + * be ignored except for checking the item pointer.) + */ +typedef struct +{ + uint32 selected:1, /* token is to be highlighted */ + in:1, /* token is part of headline */ + replace:1, /* token is to be replaced with a space */ + repeated:1, /* duplicate entry to hold item pointer */ + skip:1, /* token is to be skipped (not output) */ + unused:3, /* available bits */ + type:8, /* parser's token category */ + len:16; /* length of token */ + WordEntryPos pos; /* position of token */ + char *word; /* text of token (not null-terminated) */ + QueryOperand *item; /* a matching query operand, or NULL if none */ +} HeadlineWordEntry; + +typedef struct +{ + /* Fields filled by core code before calling prsheadline function: */ + HeadlineWordEntry *words; + int32 lenwords; /* allocated length of words[] */ + int32 curwords; /* current number of valid entries */ + int32 vectorpos; /* used by ts_parse.c in filling pos fields */ + + /* The prsheadline function must fill these fields: */ + /* Strings for marking selected tokens and separating fragments: */ + char *startsel; /* palloc'd strings */ + char *stopsel; + char *fragdelim; + int16 startsellen; /* lengths of strings */ + int16 stopsellen; + int16 fragdelimlen; +} HeadlineParsedText; + +/* + * Common useful things for tsearch subsystem + */ +extern char *get_tsearch_config_filename(const char *basename, + const char *extension); + +/* + * Often useful stopword list management + */ +typedef struct +{ + int len; + char **stop; +} StopList; + +extern void readstoplist(const char *fname, StopList *s, + char *(*wordop) (const char *)); +extern bool searchstoplist(StopList *s, char *key); + +/* + * Interface with dictionaries + */ + +/* return struct for any lexize function */ +typedef struct +{ + /*---------- + * Number of current variant of split word. For example the Norwegian + * word 'fotballklubber' has two variants to split: ( fotball, klubb ) + * and ( fot, ball, klubb ). So, dictionary should return: + * + * nvariant lexeme + * 1 fotball + * 1 klubb + * 2 fot + * 2 ball + * 2 klubb + * + * In general, a TSLexeme will be considered to belong to the same split + * variant as the previous one if they have the same nvariant value. + * The exact values don't matter, only changes from one lexeme to next. + *---------- + */ + uint16 nvariant; + + uint16 flags; /* See flag bits below */ + + char *lexeme; /* C string */ +} TSLexeme; + +/* Flag bits that can appear in TSLexeme.flags */ +#define TSL_ADDPOS 0x01 +#define TSL_PREFIX 0x02 +#define TSL_FILTER 0x04 + +/* + * Struct for supporting complex dictionaries like thesaurus. + * 4th argument for dictlexize method is a pointer to this + */ +typedef struct +{ + bool isend; /* in: marks for lexize_info about text end is + * reached */ + bool getnext; /* out: dict wants next lexeme */ + void *private_state; /* internal dict state between calls with + * getnext == true */ +} DictSubState; + +#endif /* _PG_TS_PUBLIC_H_ */ diff --git a/install/include/postgresql/server/tsearch/ts_type.h b/install/include/postgresql/server/tsearch/ts_type.h new file mode 100644 index 00000000000..b076039c1c1 --- /dev/null +++ b/install/include/postgresql/server/tsearch/ts_type.h @@ -0,0 +1,272 @@ +/*------------------------------------------------------------------------- + * + * ts_type.h + * Definitions for the tsvector and tsquery types + * + * Copyright (c) 1998-2023, PostgreSQL Global Development Group + * + * src/include/tsearch/ts_type.h + * + *------------------------------------------------------------------------- + */ +#ifndef _PG_TSTYPE_H_ +#define _PG_TSTYPE_H_ + +#include "fmgr.h" +#include "utils/memutils.h" + + +/* + * TSVector type. + * + * Structure of tsvector datatype: + * 1) standard varlena header + * 2) int32 size - number of lexemes (WordEntry array entries) + * 3) Array of WordEntry - one per lexeme; must be sorted according to + * tsCompareString() (ie, memcmp of lexeme strings). + * WordEntry->pos gives the number of bytes from end of WordEntry + * array to start of lexeme's string, which is of length len. + * 4) Per-lexeme data storage: + * lexeme string (not null-terminated) + * if haspos is true: + * padding byte if necessary to make the position data 2-byte aligned + * uint16 number of positions that follow + * WordEntryPos[] positions + * + * The positions for each lexeme must be sorted. + * + * Note, tsvectorsend/recv believe that sizeof(WordEntry) == 4 + */ + +typedef struct +{ + uint32 + haspos:1, + len:11, /* MAX 2Kb */ + pos:20; /* MAX 1Mb */ +} WordEntry; + +#define MAXSTRLEN ( (1<<11) - 1) +#define MAXSTRPOS ( (1<<20) - 1) + +extern int compareWordEntryPos(const void *a, const void *b); + +/* + * Equivalent to + * typedef struct { + * uint16 + * weight:2, + * pos:14; + * } + */ + +typedef uint16 WordEntryPos; + +typedef struct +{ + uint16 npos; + WordEntryPos pos[FLEXIBLE_ARRAY_MEMBER]; +} WordEntryPosVector; + +/* WordEntryPosVector with exactly 1 entry */ +typedef struct +{ + uint16 npos; + WordEntryPos pos[1]; +} WordEntryPosVector1; + + +#define WEP_GETWEIGHT(x) ( (x) >> 14 ) +#define WEP_GETPOS(x) ( (x) & 0x3fff ) + +#define WEP_SETWEIGHT(x,v) ( (x) = ( (v) << 14 ) | ( (x) & 0x3fff ) ) +#define WEP_SETPOS(x,v) ( (x) = ( (x) & 0xc000 ) | ( (v) & 0x3fff ) ) + +#define MAXENTRYPOS (1<<14) +#define MAXNUMPOS (256) +#define LIMITPOS(x) ( ( (x) >= MAXENTRYPOS ) ? (MAXENTRYPOS-1) : (x) ) + +/* This struct represents a complete tsvector datum */ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 size; + WordEntry entries[FLEXIBLE_ARRAY_MEMBER]; + /* lexemes follow the entries[] array */ +} TSVectorData; + +typedef TSVectorData *TSVector; + +#define DATAHDRSIZE (offsetof(TSVectorData, entries)) +#define CALCDATASIZE(nentries, lenstr) (DATAHDRSIZE + (nentries) * sizeof(WordEntry) + (lenstr) ) + +/* pointer to start of a tsvector's WordEntry array */ +#define ARRPTR(x) ( (x)->entries ) + +/* pointer to start of a tsvector's lexeme storage */ +#define STRPTR(x) ( (char *) &(x)->entries[(x)->size] ) + +#define _POSVECPTR(x, e) ((WordEntryPosVector *)(STRPTR(x) + SHORTALIGN((e)->pos + (e)->len))) +#define POSDATALEN(x,e) ( ( (e)->haspos ) ? (_POSVECPTR(x,e)->npos) : 0 ) +#define POSDATAPTR(x,e) (_POSVECPTR(x,e)->pos) + +/* + * fmgr interface functions + */ + +static inline TSVector +DatumGetTSVector(Datum X) +{ + return (TSVector) PG_DETOAST_DATUM(X); +} + +static inline TSVector +DatumGetTSVectorCopy(Datum X) +{ + return (TSVector) PG_DETOAST_DATUM_COPY(X); +} + +static inline Datum +TSVectorGetDatum(const TSVectorData *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_TSVECTOR(n) DatumGetTSVector(PG_GETARG_DATUM(n)) +#define PG_GETARG_TSVECTOR_COPY(n) DatumGetTSVectorCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_TSVECTOR(x) return TSVectorGetDatum(x) + + +/* + * TSQuery + * + * + */ + +typedef int8 QueryItemType; + +/* Valid values for QueryItemType: */ +#define QI_VAL 1 +#define QI_OPR 2 +#define QI_VALSTOP 3 /* This is only used in an intermediate stack + * representation in parse_tsquery. It's not a + * legal type elsewhere. */ + +/* + * QueryItem is one node in tsquery - operator or operand. + */ +typedef struct +{ + QueryItemType type; /* operand or kind of operator (ts_tokentype) */ + uint8 weight; /* weights of operand to search. It's a + * bitmask of allowed weights. if it =0 then + * any weight are allowed. Weights and bit + * map: A: 1<<3 B: 1<<2 C: 1<<1 D: 1<<0 */ + bool prefix; /* true if it's a prefix search */ + int32 valcrc; /* XXX: pg_crc32 would be a more appropriate + * data type, but we use comparisons to signed + * integers in the code. They would need to be + * changed as well. */ + + /* pointer to text value of operand, must correlate with WordEntry */ + uint32 + length:12, + distance:20; +} QueryOperand; + + +/* + * Legal values for QueryOperator.operator. + */ +#define OP_NOT 1 +#define OP_AND 2 +#define OP_OR 3 +#define OP_PHRASE 4 /* highest code, tsquery_cleanup.c */ +#define OP_COUNT 4 + +extern PGDLLIMPORT const int tsearch_op_priority[OP_COUNT]; + +/* get operation priority by its code */ +#define OP_PRIORITY(x) ( tsearch_op_priority[(x) - 1] ) +/* get QueryOperator priority */ +#define QO_PRIORITY(x) OP_PRIORITY(((QueryOperator *) (x))->oper) + +typedef struct +{ + QueryItemType type; + int8 oper; /* see above */ + int16 distance; /* distance between agrs for OP_PHRASE */ + uint32 left; /* pointer to left operand. Right operand is + * item + 1, left operand is placed + * item+item->left */ +} QueryOperator; + +/* + * Note: TSQuery is 4-bytes aligned, so make sure there's no fields + * inside QueryItem requiring 8-byte alignment, like int64. + */ +typedef union +{ + QueryItemType type; + QueryOperator qoperator; + QueryOperand qoperand; +} QueryItem; + +/* + * Storage: + * (len)(size)(array of QueryItem)(operands as '\0'-terminated c-strings) + */ + +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 size; /* number of QueryItems */ + char data[FLEXIBLE_ARRAY_MEMBER]; /* data starts here */ +} TSQueryData; + +typedef TSQueryData *TSQuery; + +#define HDRSIZETQ ( VARHDRSZ + sizeof(int32) ) + +/* Computes the size of header and all QueryItems. size is the number of + * QueryItems, and lenofoperand is the total length of all operands + */ +#define COMPUTESIZE(size, lenofoperand) ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) ) +#define TSQUERY_TOO_BIG(size, lenofoperand) \ + ((size) > (MaxAllocSize - HDRSIZETQ - (lenofoperand)) / sizeof(QueryItem)) + +/* Returns a pointer to the first QueryItem in a TSQuery */ +#define GETQUERY(x) ((QueryItem*)( (char*)(x)+HDRSIZETQ )) + +/* Returns a pointer to the beginning of operands in a TSQuery */ +#define GETOPERAND(x) ( (char*)GETQUERY(x) + ((TSQuery)(x))->size * sizeof(QueryItem) ) + +/* + * fmgr interface functions + * Note, TSQuery type marked as plain storage, so it can't be toasted + * but PG_DETOAST_DATUM_COPY is used for simplicity + */ + +static inline TSQuery +DatumGetTSQuery(Datum X) +{ + return (TSQuery) DatumGetPointer(X); +} + +static inline TSQuery +DatumGetTSQueryCopy(Datum X) +{ + return (TSQuery) PG_DETOAST_DATUM_COPY(X); +} + +static inline Datum +TSQueryGetDatum(const TSQueryData *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_TSQUERY(n) DatumGetTSQuery(PG_GETARG_DATUM(n)) +#define PG_GETARG_TSQUERY_COPY(n) DatumGetTSQueryCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_TSQUERY(x) return TSQueryGetDatum(x) + +#endif /* _PG_TSTYPE_H_ */ diff --git a/install/include/postgresql/server/tsearch/ts_utils.h b/install/include/postgresql/server/tsearch/ts_utils.h new file mode 100644 index 00000000000..48db1b800a1 --- /dev/null +++ b/install/include/postgresql/server/tsearch/ts_utils.h @@ -0,0 +1,281 @@ +/*------------------------------------------------------------------------- + * + * ts_utils.h + * helper utilities for tsearch + * + * Copyright (c) 1998-2023, PostgreSQL Global Development Group + * + * src/include/tsearch/ts_utils.h + * + *------------------------------------------------------------------------- + */ +#ifndef _PG_TS_UTILS_H_ +#define _PG_TS_UTILS_H_ + +#include "nodes/pg_list.h" +#include "tsearch/ts_public.h" +#include "tsearch/ts_type.h" + +/* + * Common parse definitions for tsvector and tsquery + */ + +/* tsvector parser support. */ + +struct TSVectorParseStateData; /* opaque struct in tsvector_parser.c */ +typedef struct TSVectorParseStateData *TSVectorParseState; + +/* flag bits that can be passed to init_tsvector_parser: */ +#define P_TSV_OPR_IS_DELIM (1 << 0) +#define P_TSV_IS_TSQUERY (1 << 1) +#define P_TSV_IS_WEB (1 << 2) + +extern TSVectorParseState init_tsvector_parser(char *input, int flags, + Node *escontext); +extern void reset_tsvector_parser(TSVectorParseState state, char *input); +extern bool gettoken_tsvector(TSVectorParseState state, + char **strval, int *lenval, + WordEntryPos **pos_ptr, int *poslen, + char **endptr); +extern void close_tsvector_parser(TSVectorParseState state); + +/* phrase operator begins with '<' */ +#define ISOPERATOR(x) (*(x) == '!' || \ + *(x) == '&' || \ + *(x) == '|' || \ + *(x) == '(' || \ + *(x) == ')' || \ + *(x) == '<') + +/* parse_tsquery */ + +struct TSQueryParserStateData; /* private in backend/utils/adt/tsquery.c */ +typedef struct TSQueryParserStateData *TSQueryParserState; + +typedef void (*PushFunction) (Datum opaque, TSQueryParserState state, + char *token, int tokenlen, + int16 tokenweights, /* bitmap as described in + * QueryOperand struct */ + bool prefix); + +/* flag bits that can be passed to parse_tsquery: */ +#define P_TSQ_PLAIN (1 << 0) +#define P_TSQ_WEB (1 << 1) + +extern TSQuery parse_tsquery(char *buf, + PushFunction pushval, + Datum opaque, + int flags, + Node *escontext); + +/* Functions for use by PushFunction implementations */ +extern void pushValue(TSQueryParserState state, + char *strval, int lenval, int16 weight, bool prefix); +extern void pushStop(TSQueryParserState state); +extern void pushOperator(TSQueryParserState state, int8 oper, int16 distance); + +/* + * parse plain text and lexize words + */ +typedef struct +{ + uint16 len; + uint16 nvariant; + union + { + uint16 pos; + + /* + * When apos array is used, apos[0] is the number of elements in the + * array (excluding apos[0]), and alen is the allocated size of the + * array. + */ + uint16 *apos; + } pos; + uint16 flags; /* currently, only TSL_PREFIX */ + char *word; + uint32 alen; +} ParsedWord; + +typedef struct +{ + ParsedWord *words; + int32 lenwords; + int32 curwords; + int32 pos; +} ParsedText; + +extern void parsetext(Oid cfgId, ParsedText *prs, char *buf, int32 buflen); + +/* + * headline framework, flow in common to generate: + * 1 parse text with hlparsetext + * 2 parser-specific function to find part + * 3 generateHeadline to generate result text + */ + +extern void hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, + char *buf, int32 buflen); +extern text *generateHeadline(HeadlineParsedText *prs); + +/* + * TSQuery execution support + * + * TS_execute() executes a tsquery against data that can be represented in + * various forms. The TSExecuteCallback callback function is called to check + * whether a given primitive tsquery value is matched in the data. + */ + +/* TS_execute requires ternary logic to handle NOT with phrase matches */ +typedef enum +{ + TS_NO, /* definitely no match */ + TS_YES, /* definitely does match */ + TS_MAYBE /* can't verify match for lack of pos data */ +} TSTernaryValue; + +/* + * struct ExecPhraseData is passed to a TSExecuteCallback function if we need + * lexeme position data (because of a phrase-match operator in the tsquery). + * The callback should fill in position data when it returns TS_YES (success). + * If it cannot return position data, it should leave "data" unchanged and + * return TS_MAYBE. The caller of TS_execute() must then arrange for a later + * recheck with position data available. + * + * The reported lexeme positions must be sorted and unique. Callers must only + * consult the position bits of the pos array, ie, WEP_GETPOS(data->pos[i]). + * This allows the returned "pos" to point directly to the WordEntryPos + * portion of a tsvector value. If "allocated" is true then the pos array + * is palloc'd workspace and caller may free it when done. + * + * "negate" means that the pos array contains positions where the query does + * not match, rather than positions where it does. "width" is positive when + * the match is wider than one lexeme. Neither of these fields normally need + * to be touched by TSExecuteCallback functions; they are used for + * phrase-search processing within TS_execute. + * + * All fields of the ExecPhraseData struct are initially zeroed by caller. + */ +typedef struct ExecPhraseData +{ + int npos; /* number of positions reported */ + bool allocated; /* pos points to palloc'd data? */ + bool negate; /* positions are where query is NOT matched */ + WordEntryPos *pos; /* ordered, non-duplicate lexeme positions */ + int width; /* width of match in lexemes, less 1 */ +} ExecPhraseData; + +/* + * Signature for TSQuery lexeme check functions + * + * arg: opaque value passed through from caller of TS_execute + * val: lexeme to test for presence of + * data: to be filled with lexeme positions; NULL if position data not needed + * + * Return TS_YES if lexeme is present in data, TS_MAYBE if it might be + * present, TS_NO if it definitely is not present. If data is not NULL, + * it must be filled with lexeme positions if available. If position data + * is not available, leave *data as zeroes and return TS_MAYBE, never TS_YES. + */ +typedef TSTernaryValue (*TSExecuteCallback) (void *arg, QueryOperand *val, + ExecPhraseData *data); + +/* + * Flag bits for TS_execute + */ +#define TS_EXEC_EMPTY (0x00) +/* + * If TS_EXEC_SKIP_NOT is set, then NOT sub-expressions are automatically + * evaluated to be true. This was formerly the default behavior. It's now + * deprecated because it tends to give silly answers, but some applications + * might still have a use for it. + */ +#define TS_EXEC_SKIP_NOT (0x01) +/* + * If TS_EXEC_PHRASE_NO_POS is set, allow OP_PHRASE to be executed lossily + * in the absence of position information: a true result indicates that the + * phrase might be present. Without this flag, OP_PHRASE always returns + * false if lexeme position information is not available. + */ +#define TS_EXEC_PHRASE_NO_POS (0x02) + +extern bool TS_execute(QueryItem *curitem, void *arg, uint32 flags, + TSExecuteCallback chkcond); +extern TSTernaryValue TS_execute_ternary(QueryItem *curitem, void *arg, + uint32 flags, + TSExecuteCallback chkcond); +extern List *TS_execute_locations(QueryItem *curitem, void *arg, + uint32 flags, + TSExecuteCallback chkcond); +extern bool tsquery_requires_match(QueryItem *curitem); + +/* + * to_ts* - text transformation to tsvector, tsquery + */ +extern TSVector make_tsvector(ParsedText *prs); +extern int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix); + +/* + * Possible strategy numbers for indexes + * TSearchStrategyNumber - (tsvector|text) @@ tsquery + * TSearchWithClassStrategyNumber - tsvector @@@ tsquery + */ +#define TSearchStrategyNumber 1 +#define TSearchWithClassStrategyNumber 2 + +/* + * TSQuery Utilities + */ +extern QueryItem *clean_NOT(QueryItem *ptr, int32 *len); +extern TSQuery cleanup_tsquery_stopwords(TSQuery in, bool noisy); + +typedef struct QTNode +{ + QueryItem *valnode; + uint32 flags; + int32 nchild; + char *word; + uint32 sign; + struct QTNode **child; +} QTNode; + +/* bits in QTNode.flags */ +#define QTN_NEEDFREE 0x01 +#define QTN_NOCHANGE 0x02 +#define QTN_WORDFREE 0x04 + +typedef uint64 TSQuerySign; + +#define TSQS_SIGLEN (sizeof(TSQuerySign)*BITS_PER_BYTE) + +static inline Datum +TSQuerySignGetDatum(TSQuerySign X) +{ + return Int64GetDatum((int64) X); +} + +static inline TSQuerySign +DatumGetTSQuerySign(Datum X) +{ + return (TSQuerySign) DatumGetInt64(X); +} + +#define PG_RETURN_TSQUERYSIGN(X) return TSQuerySignGetDatum(X) +#define PG_GETARG_TSQUERYSIGN(n) DatumGetTSQuerySign(PG_GETARG_DATUM(n)) + + +extern QTNode *QT2QTN(QueryItem *in, char *operand); +extern TSQuery QTN2QT(QTNode *in); +extern void QTNFree(QTNode *in); +extern void QTNSort(QTNode *in); +extern void QTNTernary(QTNode *in); +extern void QTNBinary(QTNode *in); +extern int QTNodeCompare(QTNode *an, QTNode *bn); +extern QTNode *QTNCopy(QTNode *in); +extern void QTNClearFlags(QTNode *in, uint32 flags); +extern bool QTNEq(QTNode *a, QTNode *b); +extern TSQuerySign makeTSQuerySign(TSQuery a); +extern QTNode *findsubquery(QTNode *root, QTNode *ex, QTNode *subs, + bool *isfind); + +#endif /* _PG_TS_UTILS_H_ */ diff --git a/install/include/postgresql/server/utils/acl.h b/install/include/postgresql/server/utils/acl.h new file mode 100644 index 00000000000..aba1afa971c --- /dev/null +++ b/install/include/postgresql/server/utils/acl.h @@ -0,0 +1,278 @@ +/*------------------------------------------------------------------------- + * + * acl.h + * Definition of (and support for) access control list data structures. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/acl.h + * + * NOTES + * An ACL array is simply an array of AclItems, representing the union + * of the privileges represented by the individual items. A zero-length + * array represents "no privileges". + * + * The order of items in the array is important as client utilities (in + * particular, pg_dump, though possibly other clients) expect to be able + * to issue GRANTs in the ordering of the items in the array. The reason + * this matters is that GRANTs WITH GRANT OPTION must be before any GRANTs + * which depend on it. This happens naturally in the backend during + * operations as we update ACLs in-place, new items are appended, and + * existing entries are only removed if there's no dependency on them (no + * GRANT can been based on it, or, if there was, those GRANTs are also + * removed). + * + * For backward-compatibility purposes we have to allow null ACL entries + * in system catalogs. A null ACL will be treated as meaning "default + * protection" (i.e., whatever acldefault() returns). + *------------------------------------------------------------------------- + */ +#ifndef ACL_H +#define ACL_H + +#include "access/htup.h" +#include "nodes/parsenodes.h" +#include "parser/parse_node.h" +#include "utils/snapshot.h" + + +/* + * typedef AclMode is declared in parsenodes.h, also the individual privilege + * bit meanings are defined there + */ + +#define ACL_ID_PUBLIC 0 /* placeholder for id in a PUBLIC acl item */ + +/* + * AclItem + * + * Note: must be same size on all platforms, because the size is hardcoded + * in the pg_type.h entry for aclitem. + */ +typedef struct AclItem +{ + Oid ai_grantee; /* ID that this item grants privs to */ + Oid ai_grantor; /* grantor of privs */ + AclMode ai_privs; /* privilege bits */ +} AclItem; + +/* + * The upper 32 bits of the ai_privs field of an AclItem are the grant option + * bits, and the lower 32 bits are the actual privileges. We use "rights" + * to mean the combined grant option and privilege bits fields. + */ +#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0xFFFFFFFF) +#define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 32) & 0xFFFFFFFF) +#define ACLITEM_GET_RIGHTS(item) ((item).ai_privs) + +#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFFFFFF) << 32) +#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 32) & 0xFFFFFFFF) + +#define ACLITEM_SET_PRIVS(item,privs) \ + ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFFFFFF)) | \ + ((AclMode) (privs) & 0xFFFFFFFF)) +#define ACLITEM_SET_GOPTIONS(item,goptions) \ + ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFFFFFF) << 32)) | \ + (((AclMode) (goptions) & 0xFFFFFFFF) << 32)) +#define ACLITEM_SET_RIGHTS(item,rights) \ + ((item).ai_privs = (AclMode) (rights)) + +#define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions) \ + ((item).ai_privs = ((AclMode) (privs) & 0xFFFFFFFF) | \ + (((AclMode) (goptions) & 0xFFFFFFFF) << 32)) + + +#define ACLITEM_ALL_PRIV_BITS ((AclMode) 0xFFFFFFFF) +#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFFFFFF << 32) + +/* + * Definitions for convenient access to Acl (array of AclItem). + * These are standard PostgreSQL arrays, but are restricted to have one + * dimension and no nulls. We also ignore the lower bound when reading, + * and set it to one when writing. + * + * CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all + * other array types). Therefore, be careful to detoast them with the + * macros provided, unless you know for certain that a particular array + * can't have been toasted. + */ + + +/* + * Acl a one-dimensional array of AclItem + */ +typedef struct ArrayType Acl; + +#define ACL_NUM(ACL) (ARR_DIMS(ACL)[0]) +#define ACL_DAT(ACL) ((AclItem *) ARR_DATA_PTR(ACL)) +#define ACL_N_SIZE(N) (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem))) +#define ACL_SIZE(ACL) ARR_SIZE(ACL) + +/* + * fmgr macros for these types + */ +#define DatumGetAclItemP(X) ((AclItem *) DatumGetPointer(X)) +#define PG_GETARG_ACLITEM_P(n) DatumGetAclItemP(PG_GETARG_DATUM(n)) +#define PG_RETURN_ACLITEM_P(x) PG_RETURN_POINTER(x) + +#define DatumGetAclP(X) ((Acl *) PG_DETOAST_DATUM(X)) +#define DatumGetAclPCopy(X) ((Acl *) PG_DETOAST_DATUM_COPY(X)) +#define PG_GETARG_ACL_P(n) DatumGetAclP(PG_GETARG_DATUM(n)) +#define PG_GETARG_ACL_P_COPY(n) DatumGetAclPCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_ACL_P(x) PG_RETURN_POINTER(x) + +/* + * ACL modification opcodes for aclupdate + */ +#define ACL_MODECHG_ADD 1 +#define ACL_MODECHG_DEL 2 +#define ACL_MODECHG_EQL 3 + +/* + * External representations of the privilege bits --- aclitemin/aclitemout + * represent each possible privilege bit with a distinct 1-character code + */ +#define ACL_INSERT_CHR 'a' /* formerly known as "append" */ +#define ACL_SELECT_CHR 'r' /* formerly known as "read" */ +#define ACL_UPDATE_CHR 'w' /* formerly known as "write" */ +#define ACL_DELETE_CHR 'd' +#define ACL_TRUNCATE_CHR 'D' /* super-delete, as it were */ +#define ACL_REFERENCES_CHR 'x' +#define ACL_TRIGGER_CHR 't' +#define ACL_EXECUTE_CHR 'X' +#define ACL_USAGE_CHR 'U' +#define ACL_CREATE_CHR 'C' +#define ACL_CREATE_TEMP_CHR 'T' +#define ACL_CONNECT_CHR 'c' +#define ACL_SET_CHR 's' +#define ACL_ALTER_SYSTEM_CHR 'A' + +/* string holding all privilege code chars, in order by bitmask position */ +#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTcsA" + +/* + * Bitmasks defining "all rights" for each supported object type + */ +#define ACL_ALL_RIGHTS_COLUMN (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES) +#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER) +#define ACL_ALL_RIGHTS_SEQUENCE (ACL_USAGE|ACL_SELECT|ACL_UPDATE) +#define ACL_ALL_RIGHTS_DATABASE (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT) +#define ACL_ALL_RIGHTS_FDW (ACL_USAGE) +#define ACL_ALL_RIGHTS_FOREIGN_SERVER (ACL_USAGE) +#define ACL_ALL_RIGHTS_FUNCTION (ACL_EXECUTE) +#define ACL_ALL_RIGHTS_LANGUAGE (ACL_USAGE) +#define ACL_ALL_RIGHTS_LARGEOBJECT (ACL_SELECT|ACL_UPDATE) +#define ACL_ALL_RIGHTS_PARAMETER_ACL (ACL_SET|ACL_ALTER_SYSTEM) +#define ACL_ALL_RIGHTS_SCHEMA (ACL_USAGE|ACL_CREATE) +#define ACL_ALL_RIGHTS_TABLESPACE (ACL_CREATE) +#define ACL_ALL_RIGHTS_TYPE (ACL_USAGE) + +/* operation codes for pg_*_aclmask */ +typedef enum +{ + ACLMASK_ALL, /* normal case: compute all bits */ + ACLMASK_ANY /* return when result is known nonzero */ +} AclMaskHow; + +/* result codes for pg_*_aclcheck */ +typedef enum +{ + ACLCHECK_OK = 0, + ACLCHECK_NO_PRIV, + ACLCHECK_NOT_OWNER +} AclResult; + + +/* + * routines used internally + */ +extern Acl *acldefault(ObjectType objtype, Oid ownerId); +extern Acl *get_user_default_acl(ObjectType objtype, Oid ownerId, + Oid nsp_oid); +extern void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, + Oid ownerId, Acl *acl); + +extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip, + int modechg, Oid ownerId, DropBehavior behavior); +extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId); +extern Acl *make_empty_acl(void); +extern Acl *aclcopy(const Acl *orig_acl); +extern Acl *aclconcat(const Acl *left_acl, const Acl *right_acl); +extern Acl *aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId); +extern void aclitemsort(Acl *acl); +extern bool aclequal(const Acl *left_acl, const Acl *right_acl); + +extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, + AclMode mask, AclMaskHow how); +extern int aclmembers(const Acl *acl, Oid **roleids); + +extern bool has_privs_of_role(Oid member, Oid role); +extern bool member_can_set_role(Oid member, Oid role); +extern void check_can_set_role(Oid member, Oid role); +extern bool is_member_of_role(Oid member, Oid role); +extern bool is_member_of_role_nosuper(Oid member, Oid role); +extern bool is_admin_of_role(Oid member, Oid role); +extern Oid select_best_admin(Oid member, Oid role); +extern Oid get_role_oid(const char *rolname, bool missing_ok); +extern Oid get_role_oid_or_public(const char *rolname); +extern Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok); +extern void check_rolespec_name(const RoleSpec *role, const char *detail_msg); +extern HeapTuple get_rolespec_tuple(const RoleSpec *role); +extern char *get_rolespec_name(const RoleSpec *role); + +extern void select_best_grantor(Oid roleId, AclMode privileges, + const Acl *acl, Oid ownerId, + Oid *grantorId, AclMode *grantOptions); + +extern void initialize_acl(void); + +/* + * prototypes for functions in aclchk.c + */ +extern void ExecuteGrantStmt(GrantStmt *stmt); +extern void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *stmt); + +extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid); + +extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, + AclMode mask, AclMaskHow how); + +/* generic function */ +extern AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode); + +/* special cases */ +extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, + Oid roleid, AclMode mode); +extern AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, + Oid roleid, AclMode mode, + bool *is_missing); +extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, + AclMode mode, AclMaskHow how); +extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode); +extern AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, + AclMode mode, bool *is_missing); +extern AclResult pg_parameter_aclcheck(const char *name, Oid roleid, + AclMode mode); +extern AclResult pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid, + AclMode mode, Snapshot snapshot); + +extern void aclcheck_error(AclResult aclerr, ObjectType objtype, + const char *objectname); + +extern void aclcheck_error_col(AclResult aclerr, ObjectType objtype, + const char *objectname, const char *colname); + +extern void aclcheck_error_type(AclResult aclerr, Oid typeOid); + +extern void recordExtObjInitPriv(Oid objoid, Oid classoid); +extern void removeExtObjInitPriv(Oid objoid, Oid classoid); + + +/* ownercheck routines just return true (owner) or false (not) */ +extern bool object_ownercheck(Oid classid, Oid objectid, Oid roleid); +extern bool has_createrole_privilege(Oid roleid); +extern bool has_bypassrls_privilege(Oid roleid); + +#endif /* ACL_H */ diff --git a/install/include/postgresql/server/utils/aclchk_internal.h b/install/include/postgresql/server/utils/aclchk_internal.h new file mode 100644 index 00000000000..55af624fb34 --- /dev/null +++ b/install/include/postgresql/server/utils/aclchk_internal.h @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------- + * + * aclchk_internal.h + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/aclchk_internal.h + * + *------------------------------------------------------------------------- + */ +#ifndef ACLCHK_INTERNAL_H +#define ACLCHK_INTERNAL_H + +#include "nodes/parsenodes.h" +#include "nodes/pg_list.h" + +/* + * The information about one Grant/Revoke statement, in internal format: object + * and grantees names have been turned into Oids, the privilege list is an + * AclMode bitmask. If 'privileges' is ACL_NO_RIGHTS (the 0 value) and + * all_privs is true, 'privileges' will be internally set to the right kind of + * ACL_ALL_RIGHTS_*, depending on the object type (NB - this will modify the + * InternalGrant struct!) + * + * Note: 'all_privs' and 'privileges' represent object-level privileges only. + * There might also be column-level privilege specifications, which are + * represented in col_privs (this is a list of untransformed AccessPriv nodes). + * Column privileges are only valid for objtype OBJECT_TABLE. + */ +typedef struct +{ + bool is_grant; + ObjectType objtype; + List *objects; + bool all_privs; + AclMode privileges; + List *col_privs; + List *grantees; + bool grant_option; + DropBehavior behavior; +} InternalGrant; + + +#endif /* ACLCHK_INTERNAL_H */ diff --git a/install/include/postgresql/server/utils/array.h b/install/include/postgresql/server/utils/array.h new file mode 100644 index 00000000000..e6c8d88d9f2 --- /dev/null +++ b/install/include/postgresql/server/utils/array.h @@ -0,0 +1,482 @@ +/*------------------------------------------------------------------------- + * + * array.h + * Declarations for Postgres arrays. + * + * A standard varlena array has the following internal structure: + * - standard varlena header word + * - number of dimensions of the array + * - offset to stored data, or 0 if no nulls bitmap + * - element type OID + * - length of each array axis (C array of int) + * - lower boundary of each dimension (C array of int) + * - bitmap showing locations of nulls (OPTIONAL) + * - whatever is the stored data + * + * The and arrays each have ndim elements. + * + * The may be omitted if the array contains no NULL elements. + * If it is absent, the field is zero and the offset to the + * stored data must be computed on-the-fly. If the bitmap is present, + * is nonzero and is equal to the offset from the array start + * to the first data element (including any alignment padding). The bitmap + * follows the same conventions as tuple null bitmaps, ie, a 1 indicates + * a non-null entry and the LSB of each bitmap byte is used first. + * + * The actual data starts on a MAXALIGN boundary. Individual items in the + * array are aligned as specified by the array element type. They are + * stored in row-major order (last subscript varies most rapidly). + * + * NOTE: it is important that array elements of toastable datatypes NOT be + * toasted, since the tupletoaster won't know they are there. (We could + * support compressed toasted items; only out-of-line items are dangerous. + * However, it seems preferable to store such items uncompressed and allow + * the toaster to compress the whole array as one input.) + * + * + * The OIDVECTOR and INT2VECTOR datatypes are storage-compatible with + * generic arrays, but they support only one-dimensional arrays with no + * nulls (and no null bitmap). They don't support being toasted, either. + * + * There are also some "fixed-length array" datatypes, such as NAME and + * POINT. These are simply a sequence of a fixed number of items each + * of a fixed-length datatype, with no overhead; the item size must be + * a multiple of its alignment requirement, because we do no padding. + * We support subscripting on these types, but array_in() and array_out() + * only work with varlena arrays. + * + * In addition, arrays are a major user of the "expanded object" TOAST + * infrastructure. This allows a varlena array to be converted to a + * separate representation that may include "deconstructed" Datum/isnull + * arrays holding the elements. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/array.h + * + *------------------------------------------------------------------------- + */ +#ifndef ARRAY_H +#define ARRAY_H + +#include "fmgr.h" +#include "utils/expandeddatum.h" + +/* avoid including execnodes.h here */ +struct ExprState; +struct ExprContext; + + +/* + * Maximum number of array subscripts (arbitrary limit) + */ +#define MAXDIM 6 + +/* + * Maximum number of elements in an array. We limit this to at most about a + * quarter billion elements, so that it's not necessary to check for overflow + * in quite so many places --- for instance when palloc'ing Datum arrays. + */ +#define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum))) + +/* + * Arrays are varlena objects, so must meet the varlena convention that + * the first int32 of the object contains the total object size in bytes. + * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though! + * + * CAUTION: if you change the header for ordinary arrays you will also + * need to change the headers for oidvector and int2vector! + */ +typedef struct ArrayType +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int ndim; /* # of dimensions */ + int32 dataoffset; /* offset to data, or 0 if no bitmap */ + Oid elemtype; /* element type OID */ +} ArrayType; + +/* + * An expanded array is contained within a private memory context (as + * all expanded objects must be) and has a control structure as below. + * + * The expanded array might contain a regular "flat" array if that was the + * original input and we've not modified it significantly. Otherwise, the + * contents are represented by Datum/isnull arrays plus dimensionality and + * type information. We could also have both forms, if we've deconstructed + * the original array for access purposes but not yet changed it. For pass- + * by-reference element types, the Datums would point into the flat array in + * this situation. Once we start modifying array elements, new pass-by-ref + * elements are separately palloc'd within the memory context. + */ +#define EA_MAGIC 689375833 /* ID for debugging crosschecks */ + +typedef struct ExpandedArrayHeader +{ + /* Standard header for expanded objects */ + ExpandedObjectHeader hdr; + + /* Magic value identifying an expanded array (for debugging only) */ + int ea_magic; + + /* Dimensionality info (always valid) */ + int ndims; /* # of dimensions */ + int *dims; /* array dimensions */ + int *lbound; /* index lower bounds for each dimension */ + + /* Element type info (always valid) */ + Oid element_type; /* element type OID */ + int16 typlen; /* needed info about element datatype */ + bool typbyval; + char typalign; + + /* + * If we have a Datum-array representation of the array, it's kept here; + * else dvalues/dnulls are NULL. The dvalues and dnulls arrays are always + * palloc'd within the object private context, but may change size from + * time to time. For pass-by-ref element types, dvalues entries might + * point either into the fstartptr..fendptr area, or to separately + * palloc'd chunks. Elements should always be fully detoasted, as they + * are in the standard flat representation. + * + * Even when dvalues is valid, dnulls can be NULL if there are no null + * elements. + */ + Datum *dvalues; /* array of Datums */ + bool *dnulls; /* array of is-null flags for Datums */ + int dvalueslen; /* allocated length of above arrays */ + int nelems; /* number of valid entries in above arrays */ + + /* + * flat_size is the current space requirement for the flat equivalent of + * the expanded array, if known; otherwise it's 0. We store this to make + * consecutive calls of get_flat_size cheap. + */ + Size flat_size; + + /* + * fvalue points to the flat representation if it is valid, else it is + * NULL. If we have or ever had a flat representation then + * fstartptr/fendptr point to the start and end+1 of its data area; this + * is so that we can tell which Datum pointers point into the flat + * representation rather than being pointers to separately palloc'd data. + */ + ArrayType *fvalue; /* must be a fully detoasted array */ + char *fstartptr; /* start of its data area */ + char *fendptr; /* end+1 of its data area */ +} ExpandedArrayHeader; + +/* + * Functions that can handle either a "flat" varlena array or an expanded + * array use this union to work with their input. Don't refer to "flt"; + * instead, cast to ArrayType. This struct nominally requires 8-byte + * alignment on 64-bit, but it's often used for an ArrayType having 4-byte + * alignment. UBSan complains about referencing "flt" in such cases. + */ +typedef union AnyArrayType +{ + ArrayType flt; + ExpandedArrayHeader xpn; +} AnyArrayType; + +/* + * working state for accumArrayResult() and friends + * note that the input must be scalars (legal array elements) + */ +typedef struct ArrayBuildState +{ + MemoryContext mcontext; /* where all the temp stuff is kept */ + Datum *dvalues; /* array of accumulated Datums */ + bool *dnulls; /* array of is-null flags for Datums */ + int alen; /* allocated length of above arrays */ + int nelems; /* number of valid entries in above arrays */ + Oid element_type; /* data type of the Datums */ + int16 typlen; /* needed info about datatype */ + bool typbyval; + char typalign; + bool private_cxt; /* use private memory context */ +} ArrayBuildState; + +/* + * working state for accumArrayResultArr() and friends + * note that the input must be arrays, and the same array type is returned + */ +typedef struct ArrayBuildStateArr +{ + MemoryContext mcontext; /* where all the temp stuff is kept */ + char *data; /* accumulated data */ + bits8 *nullbitmap; /* bitmap of is-null flags, or NULL if none */ + int abytes; /* allocated length of "data" */ + int nbytes; /* number of bytes used so far */ + int aitems; /* allocated length of bitmap (in elements) */ + int nitems; /* total number of elements in result */ + int ndims; /* current dimensions of result */ + int dims[MAXDIM]; + int lbs[MAXDIM]; + Oid array_type; /* data type of the arrays */ + Oid element_type; /* data type of the array elements */ + bool private_cxt; /* use private memory context */ +} ArrayBuildStateArr; + +/* + * working state for accumArrayResultAny() and friends + * these functions handle both cases + */ +typedef struct ArrayBuildStateAny +{ + /* Exactly one of these is not NULL: */ + ArrayBuildState *scalarstate; + ArrayBuildStateArr *arraystate; +} ArrayBuildStateAny; + +/* + * structure to cache type metadata needed for array manipulation + */ +typedef struct ArrayMetaState +{ + Oid element_type; + int16 typlen; + bool typbyval; + char typalign; + char typdelim; + Oid typioparam; + Oid typiofunc; + FmgrInfo proc; +} ArrayMetaState; + +/* + * private state needed by array_map (here because caller must provide it) + */ +typedef struct ArrayMapState +{ + ArrayMetaState inp_extra; + ArrayMetaState ret_extra; +} ArrayMapState; + +/* ArrayIteratorData is private in arrayfuncs.c */ +typedef struct ArrayIteratorData *ArrayIterator; + +/* fmgr macros for regular varlena array objects */ +#define DatumGetArrayTypeP(X) ((ArrayType *) PG_DETOAST_DATUM(X)) +#define DatumGetArrayTypePCopy(X) ((ArrayType *) PG_DETOAST_DATUM_COPY(X)) +#define PG_GETARG_ARRAYTYPE_P(n) DatumGetArrayTypeP(PG_GETARG_DATUM(n)) +#define PG_GETARG_ARRAYTYPE_P_COPY(n) DatumGetArrayTypePCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_ARRAYTYPE_P(x) PG_RETURN_POINTER(x) + +/* fmgr macros for expanded array objects */ +#define PG_GETARG_EXPANDED_ARRAY(n) DatumGetExpandedArray(PG_GETARG_DATUM(n)) +#define PG_GETARG_EXPANDED_ARRAYX(n, metacache) \ + DatumGetExpandedArrayX(PG_GETARG_DATUM(n), metacache) +#define PG_RETURN_EXPANDED_ARRAY(x) PG_RETURN_DATUM(EOHPGetRWDatum(&(x)->hdr)) + +/* fmgr macros for AnyArrayType (ie, get either varlena or expanded form) */ +#define PG_GETARG_ANY_ARRAY_P(n) DatumGetAnyArrayP(PG_GETARG_DATUM(n)) + +/* + * Access macros for varlena array header fields. + * + * ARR_DIMS returns a pointer to an array of array dimensions (number of + * elements along the various array axes). + * + * ARR_LBOUND returns a pointer to an array of array lower bounds. + * + * That is: if the third axis of an array has elements 5 through 8, then + * ARR_DIMS(a)[2] == 4 and ARR_LBOUND(a)[2] == 5. + * + * Unlike C, the default lower bound is 1. + */ +#define ARR_SIZE(a) VARSIZE(a) +#define ARR_NDIM(a) ((a)->ndim) +#define ARR_HASNULL(a) ((a)->dataoffset != 0) +#define ARR_ELEMTYPE(a) ((a)->elemtype) + +#define ARR_DIMS(a) \ + ((int *) (((char *) (a)) + sizeof(ArrayType))) +#define ARR_LBOUND(a) \ + ((int *) (((char *) (a)) + sizeof(ArrayType) + \ + sizeof(int) * ARR_NDIM(a))) + +#define ARR_NULLBITMAP(a) \ + (ARR_HASNULL(a) ? \ + (bits8 *) (((char *) (a)) + sizeof(ArrayType) + \ + 2 * sizeof(int) * ARR_NDIM(a)) \ + : (bits8 *) NULL) + +/* + * The total array header size (in bytes) for an array with the specified + * number of dimensions and total number of items. + */ +#define ARR_OVERHEAD_NONULLS(ndims) \ + MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims)) +#define ARR_OVERHEAD_WITHNULLS(ndims, nitems) \ + MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims) + \ + ((nitems) + 7) / 8) + +#define ARR_DATA_OFFSET(a) \ + (ARR_HASNULL(a) ? (a)->dataoffset : ARR_OVERHEAD_NONULLS(ARR_NDIM(a))) + +/* + * Returns a pointer to the actual array data. + */ +#define ARR_DATA_PTR(a) \ + (((char *) (a)) + ARR_DATA_OFFSET(a)) + +/* + * Macros for working with AnyArrayType inputs. Beware multiple references! + */ +#define AARR_NDIM(a) \ + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.ndims : ARR_NDIM((ArrayType *) (a))) +#define AARR_HASNULL(a) \ + (VARATT_IS_EXPANDED_HEADER(a) ? \ + ((a)->xpn.dvalues != NULL ? (a)->xpn.dnulls != NULL : ARR_HASNULL((a)->xpn.fvalue)) : \ + ARR_HASNULL((ArrayType *) (a))) +#define AARR_ELEMTYPE(a) \ + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.element_type : ARR_ELEMTYPE((ArrayType *) (a))) +#define AARR_DIMS(a) \ + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.dims : ARR_DIMS((ArrayType *) (a))) +#define AARR_LBOUND(a) \ + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.lbound : ARR_LBOUND((ArrayType *) (a))) + + +/* + * GUC parameter + */ +extern PGDLLIMPORT bool Array_nulls; + +/* + * prototypes for functions defined in arrayfuncs.c + */ +extern void CopyArrayEls(ArrayType *array, + Datum *values, + bool *nulls, + int nitems, + int typlen, + bool typbyval, + char typalign, + bool freedata); + +extern Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, + int arraytyplen, int elmlen, bool elmbyval, char elmalign, + bool *isNull); +extern Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, + Datum dataValue, bool isNull, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); +extern Datum array_get_slice(Datum arraydatum, int nSubscripts, + int *upperIndx, int *lowerIndx, + bool *upperProvided, bool *lowerProvided, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); +extern Datum array_set_slice(Datum arraydatum, int nSubscripts, + int *upperIndx, int *lowerIndx, + bool *upperProvided, bool *lowerProvided, + Datum srcArrayDatum, bool isNull, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); + +extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx, + int arraytyplen, int elmlen, bool elmbyval, char elmalign, + bool *isNull); +extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx, + Datum dataValue, bool isNull, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); + +extern Datum array_map(Datum arrayd, + struct ExprState *exprstate, struct ExprContext *econtext, + Oid retType, ArrayMapState *amstate); + +extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, + const bits8 *srcbitmap, int srcoffset, + int nitems); + +extern ArrayType *construct_array(Datum *elems, int nelems, + Oid elmtype, + int elmlen, bool elmbyval, char elmalign); +extern ArrayType *construct_array_builtin(Datum *elems, int nelems, Oid elmtype); +extern ArrayType *construct_md_array(Datum *elems, + bool *nulls, + int ndims, + int *dims, + int *lbs, + Oid elmtype, int elmlen, bool elmbyval, char elmalign); +extern ArrayType *construct_empty_array(Oid elmtype); +extern ExpandedArrayHeader *construct_empty_expanded_array(Oid element_type, + MemoryContext parentcontext, + ArrayMetaState *metacache); +extern void deconstruct_array(ArrayType *array, + Oid elmtype, + int elmlen, bool elmbyval, char elmalign, + Datum **elemsp, bool **nullsp, int *nelemsp); +extern void deconstruct_array_builtin(ArrayType *array, + Oid elmtype, + Datum **elemsp, bool **nullsp, int *nelemsp); +extern bool array_contains_nulls(ArrayType *array); + +extern ArrayBuildState *initArrayResult(Oid element_type, + MemoryContext rcontext, bool subcontext); +extern ArrayBuildState *initArrayResultWithSize(Oid element_type, + MemoryContext rcontext, + bool subcontext, int initsize); +extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate, + Datum dvalue, bool disnull, + Oid element_type, + MemoryContext rcontext); +extern Datum makeArrayResult(ArrayBuildState *astate, + MemoryContext rcontext); +extern Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, + int *dims, int *lbs, MemoryContext rcontext, bool release); + +extern ArrayBuildStateArr *initArrayResultArr(Oid array_type, Oid element_type, + MemoryContext rcontext, bool subcontext); +extern ArrayBuildStateArr *accumArrayResultArr(ArrayBuildStateArr *astate, + Datum dvalue, bool disnull, + Oid array_type, + MemoryContext rcontext); +extern Datum makeArrayResultArr(ArrayBuildStateArr *astate, + MemoryContext rcontext, bool release); + +extern ArrayBuildStateAny *initArrayResultAny(Oid input_type, + MemoryContext rcontext, bool subcontext); +extern ArrayBuildStateAny *accumArrayResultAny(ArrayBuildStateAny *astate, + Datum dvalue, bool disnull, + Oid input_type, + MemoryContext rcontext); +extern Datum makeArrayResultAny(ArrayBuildStateAny *astate, + MemoryContext rcontext, bool release); + +extern ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate); +extern bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull); +extern void array_free_iterator(ArrayIterator iterator); + +/* + * prototypes for functions defined in arrayutils.c + */ + +extern int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx); +extern int ArrayGetOffset0(int n, const int *tup, const int *scale); +extern int ArrayGetNItems(int ndim, const int *dims); +extern int ArrayGetNItemsSafe(int ndim, const int *dims, + struct Node *escontext); +extern void ArrayCheckBounds(int ndim, const int *dims, const int *lb); +extern bool ArrayCheckBoundsSafe(int ndim, const int *dims, const int *lb, + struct Node *escontext); +extern void mda_get_range(int n, int *span, const int *st, const int *endp); +extern void mda_get_prod(int n, const int *range, int *prod); +extern void mda_get_offset_values(int n, int *dist, const int *prod, const int *span); +extern int mda_next_tuple(int n, int *curr, const int *span); +extern int32 *ArrayGetIntegerTypmods(ArrayType *arr, int *n); + +/* + * prototypes for functions defined in array_expanded.c + */ +extern Datum expand_array(Datum arraydatum, MemoryContext parentcontext, + ArrayMetaState *metacache); +extern ExpandedArrayHeader *DatumGetExpandedArray(Datum d); +extern ExpandedArrayHeader *DatumGetExpandedArrayX(Datum d, + ArrayMetaState *metacache); +extern AnyArrayType *DatumGetAnyArrayP(Datum d); +extern void deconstruct_expanded_array(ExpandedArrayHeader *eah); + +#endif /* ARRAY_H */ diff --git a/install/include/postgresql/server/utils/arrayaccess.h b/install/include/postgresql/server/utils/arrayaccess.h new file mode 100644 index 00000000000..fd267d54804 --- /dev/null +++ b/install/include/postgresql/server/utils/arrayaccess.h @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------------- + * + * arrayaccess.h + * Declarations for element-by-element access to Postgres arrays. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/arrayaccess.h + * + *------------------------------------------------------------------------- + */ +#ifndef ARRAYACCESS_H +#define ARRAYACCESS_H + +#include "access/tupmacs.h" +#include "utils/array.h" + + +/* + * Functions for iterating through elements of a flat or expanded array. + * These require a state struct "array_iter iter". + * + * Use "array_iter_setup(&iter, arrayptr);" to prepare to iterate, and + * "datumvar = array_iter_next(&iter, &isnullvar, index, ...);" to fetch + * the next element into datumvar/isnullvar. + * "index" must be the zero-origin element number; we make caller provide + * this since caller is generally counting the elements anyway. Despite + * that, these functions can only fetch elements sequentially. + */ + +typedef struct array_iter +{ + /* datumptr being NULL or not tells if we have flat or expanded array */ + + /* Fields used when we have an expanded array */ + Datum *datumptr; /* Pointer to Datum array */ + bool *isnullptr; /* Pointer to isnull array */ + + /* Fields used when we have a flat array */ + char *dataptr; /* Current spot in the data area */ + bits8 *bitmapptr; /* Current byte of the nulls bitmap, or NULL */ + int bitmask; /* mask for current bit in nulls bitmap */ +} array_iter; + + +static inline void +array_iter_setup(array_iter *it, AnyArrayType *a) +{ + if (VARATT_IS_EXPANDED_HEADER(a)) + { + if (a->xpn.dvalues) + { + it->datumptr = a->xpn.dvalues; + it->isnullptr = a->xpn.dnulls; + /* we must fill all fields to prevent compiler warnings */ + it->dataptr = NULL; + it->bitmapptr = NULL; + } + else + { + /* Work with flat array embedded in the expanded datum */ + it->datumptr = NULL; + it->isnullptr = NULL; + it->dataptr = ARR_DATA_PTR(a->xpn.fvalue); + it->bitmapptr = ARR_NULLBITMAP(a->xpn.fvalue); + } + } + else + { + it->datumptr = NULL; + it->isnullptr = NULL; + it->dataptr = ARR_DATA_PTR((ArrayType *) a); + it->bitmapptr = ARR_NULLBITMAP((ArrayType *) a); + } + it->bitmask = 1; +} + +static inline Datum +array_iter_next(array_iter *it, bool *isnull, int i, + int elmlen, bool elmbyval, char elmalign) +{ + Datum ret; + + if (it->datumptr) + { + ret = it->datumptr[i]; + *isnull = it->isnullptr ? it->isnullptr[i] : false; + } + else + { + if (it->bitmapptr && (*(it->bitmapptr) & it->bitmask) == 0) + { + *isnull = true; + ret = (Datum) 0; + } + else + { + *isnull = false; + ret = fetch_att(it->dataptr, elmbyval, elmlen); + it->dataptr = att_addlength_pointer(it->dataptr, elmlen, + it->dataptr); + it->dataptr = (char *) att_align_nominal(it->dataptr, elmalign); + } + it->bitmask <<= 1; + if (it->bitmask == 0x100) + { + if (it->bitmapptr) + it->bitmapptr++; + it->bitmask = 1; + } + } + + return ret; +} + +#endif /* ARRAYACCESS_H */ diff --git a/install/include/postgresql/server/utils/ascii.h b/install/include/postgresql/server/utils/ascii.h new file mode 100644 index 00000000000..7df024dad39 --- /dev/null +++ b/install/include/postgresql/server/utils/ascii.h @@ -0,0 +1,84 @@ +/*----------------------------------------------------------------------- + * ascii.h + * + * Portions Copyright (c) 1999-2023, PostgreSQL Global Development Group + * + * src/include/utils/ascii.h + * + *----------------------------------------------------------------------- + */ + +#ifndef _ASCII_H_ +#define _ASCII_H_ + +#include "port/simd.h" + +extern void ascii_safe_strlcpy(char *dest, const char *src, size_t destsiz); + +/* + * Verify a chunk of bytes for valid ASCII. + * + * Returns false if the input contains any zero bytes or bytes with the + * high-bit set. Input len must be a multiple of the chunk size (8 or 16). + */ +static inline bool +is_valid_ascii(const unsigned char *s, int len) +{ + const unsigned char *const s_end = s + len; + Vector8 chunk; + Vector8 highbit_cum = vector8_broadcast(0); +#ifdef USE_NO_SIMD + Vector8 zero_cum = vector8_broadcast(0x80); +#endif + + Assert(len % sizeof(chunk) == 0); + + while (s < s_end) + { + vector8_load(&chunk, s); + + /* Capture any zero bytes in this chunk. */ +#ifdef USE_NO_SIMD + + /* + * First, add 0x7f to each byte. This sets the high bit in each byte, + * unless it was a zero. If any resulting high bits are zero, the + * corresponding high bits in the zero accumulator will be cleared. + * + * If none of the bytes in the chunk had the high bit set, the max + * value each byte can have after the addition is 0x7f + 0x7f = 0xfe, + * and we don't need to worry about carrying over to the next byte. If + * any input bytes did have the high bit set, it doesn't matter + * because we check for those separately. + */ + zero_cum &= (chunk + vector8_broadcast(0x7F)); +#else + + /* + * Set all bits in each lane of the highbit accumulator where input + * bytes are zero. + */ + highbit_cum = vector8_or(highbit_cum, + vector8_eq(chunk, vector8_broadcast(0))); +#endif + + /* Capture all set bits in this chunk. */ + highbit_cum = vector8_or(highbit_cum, chunk); + + s += sizeof(chunk); + } + + /* Check if any high bits in the high bit accumulator got set. */ + if (vector8_is_highbit_set(highbit_cum)) + return false; + +#ifdef USE_NO_SIMD + /* Check if any high bits in the zero accumulator got cleared. */ + if (zero_cum != vector8_broadcast(0x80)) + return false; +#endif + + return true; +} + +#endif /* _ASCII_H_ */ diff --git a/install/include/postgresql/server/utils/attoptcache.h b/install/include/postgresql/server/utils/attoptcache.h new file mode 100644 index 00000000000..e4119b6aa28 --- /dev/null +++ b/install/include/postgresql/server/utils/attoptcache.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * attoptcache.h + * Attribute options cache. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/attoptcache.h + * + *------------------------------------------------------------------------- + */ +#ifndef ATTOPTCACHE_H +#define ATTOPTCACHE_H + +/* + * Attribute options. + */ +typedef struct AttributeOpts +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + float8 n_distinct; + float8 n_distinct_inherited; +} AttributeOpts; + +extern AttributeOpts *get_attribute_options(Oid attrelid, int attnum); + +#endif /* ATTOPTCACHE_H */ diff --git a/install/include/postgresql/server/utils/backend_progress.h b/install/include/postgresql/server/utils/backend_progress.h new file mode 100644 index 00000000000..a84752ade99 --- /dev/null +++ b/install/include/postgresql/server/utils/backend_progress.h @@ -0,0 +1,45 @@ +/* ---------- + * backend_progress.h + * Command progress reporting definition. + * + * Note that this file provides the infrastructure for storing a single + * backend's command progress counters, without ascribing meaning to the + * individual fields. See commands/progress.h and system_views.sql for that. + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/utils/backend_progress.h + * ---------- + */ +#ifndef BACKEND_PROGRESS_H +#define BACKEND_PROGRESS_H + + +/* ---------- + * Command type for progress reporting purposes + * ---------- + */ +typedef enum ProgressCommandType +{ + PROGRESS_COMMAND_INVALID, + PROGRESS_COMMAND_VACUUM, + PROGRESS_COMMAND_ANALYZE, + PROGRESS_COMMAND_CLUSTER, + PROGRESS_COMMAND_CREATE_INDEX, + PROGRESS_COMMAND_BASEBACKUP, + PROGRESS_COMMAND_COPY +} ProgressCommandType; + +#define PGSTAT_NUM_PROGRESS_PARAM 20 + + +extern void pgstat_progress_start_command(ProgressCommandType cmdtype, + Oid relid); +extern void pgstat_progress_update_param(int index, int64 val); +extern void pgstat_progress_incr_param(int index, int64 incr); +extern void pgstat_progress_update_multi_param(int nparam, const int *index, + const int64 *val); +extern void pgstat_progress_end_command(void); + + +#endif /* BACKEND_PROGRESS_H */ diff --git a/install/include/postgresql/server/utils/backend_status.h b/install/include/postgresql/server/utils/backend_status.h new file mode 100644 index 00000000000..d51c840dafb --- /dev/null +++ b/install/include/postgresql/server/utils/backend_status.h @@ -0,0 +1,342 @@ +/* ---------- + * backend_status.h + * Definitions related to backend status reporting + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/utils/backend_status.h + * ---------- + */ +#ifndef BACKEND_STATUS_H +#define BACKEND_STATUS_H + +#include "datatype/timestamp.h" +#include "libpq/pqcomm.h" +#include "miscadmin.h" /* for BackendType */ +#include "storage/backendid.h" +#include "utils/backend_progress.h" + + +/* ---------- + * Backend states + * ---------- + */ +typedef enum BackendState +{ + STATE_UNDEFINED, + STATE_IDLE, + STATE_RUNNING, + STATE_IDLEINTRANSACTION, + STATE_FASTPATH, + STATE_IDLEINTRANSACTION_ABORTED, + STATE_DISABLED +} BackendState; + + +/* ---------- + * Shared-memory data structures + * ---------- + */ + +/* + * PgBackendSSLStatus + * + * For each backend, we keep the SSL status in a separate struct, that + * is only filled in if SSL is enabled. + * + * All char arrays must be null-terminated. + */ +typedef struct PgBackendSSLStatus +{ + /* Information about SSL connection */ + int ssl_bits; + char ssl_version[NAMEDATALEN]; + char ssl_cipher[NAMEDATALEN]; + char ssl_client_dn[NAMEDATALEN]; + + /* + * serial number is max "20 octets" per RFC 5280, so this size should be + * fine + */ + char ssl_client_serial[NAMEDATALEN]; + + char ssl_issuer_dn[NAMEDATALEN]; +} PgBackendSSLStatus; + +/* + * PgBackendGSSStatus + * + * For each backend, we keep the GSS status in a separate struct, that + * is only filled in if GSS is enabled. + * + * All char arrays must be null-terminated. + */ +typedef struct PgBackendGSSStatus +{ + /* Information about GSSAPI connection */ + char gss_princ[NAMEDATALEN]; /* GSSAPI Principal used to auth */ + bool gss_auth; /* If GSSAPI authentication was used */ + bool gss_enc; /* If encryption is being used */ + bool gss_delegation; /* If credentials delegated */ + +} PgBackendGSSStatus; + + +/* ---------- + * PgBackendStatus + * + * Each live backend maintains a PgBackendStatus struct in shared memory + * showing its current activity. (The structs are allocated according to + * BackendId, but that is not critical.) Note that this is unrelated to the + * cumulative stats system (i.e. pgstat.c et al). + * + * Each auxiliary process also maintains a PgBackendStatus struct in shared + * memory. + * ---------- + */ +typedef struct PgBackendStatus +{ + /* + * To avoid locking overhead, we use the following protocol: a backend + * increments st_changecount before modifying its entry, and again after + * finishing a modification. A would-be reader should note the value of + * st_changecount, copy the entry into private memory, then check + * st_changecount again. If the value hasn't changed, and if it's even, + * the copy is valid; otherwise start over. This makes updates cheap + * while reads are potentially expensive, but that's the tradeoff we want. + * + * The above protocol needs memory barriers to ensure that the apparent + * order of execution is as it desires. Otherwise, for example, the CPU + * might rearrange the code so that st_changecount is incremented twice + * before the modification on a machine with weak memory ordering. Hence, + * use the macros defined below for manipulating st_changecount, rather + * than touching it directly. + */ + int st_changecount; + + /* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */ + int st_procpid; + + /* Type of backends */ + BackendType st_backendType; + + /* Times when current backend, transaction, and activity started */ + TimestampTz st_proc_start_timestamp; + TimestampTz st_xact_start_timestamp; + TimestampTz st_activity_start_timestamp; + TimestampTz st_state_start_timestamp; + + /* Database OID, owning user's OID, connection client address */ + Oid st_databaseid; + Oid st_userid; + SockAddr st_clientaddr; + char *st_clienthostname; /* MUST be null-terminated */ + + /* Information about SSL connection */ + bool st_ssl; + PgBackendSSLStatus *st_sslstatus; + + /* Information about GSSAPI connection */ + bool st_gss; + PgBackendGSSStatus *st_gssstatus; + + /* current state */ + BackendState st_state; + + /* application name; MUST be null-terminated */ + char *st_appname; + + /* + * Current command string; MUST be null-terminated. Note that this string + * possibly is truncated in the middle of a multi-byte character. As + * activity strings are stored more frequently than read, that allows to + * move the cost of correct truncation to the display side. Use + * pgstat_clip_activity() to truncate correctly. + */ + char *st_activity_raw; + + /* + * Command progress reporting. Any command which wishes can advertise + * that it is running by setting st_progress_command, + * st_progress_command_target, and st_progress_param[]. + * st_progress_command_target should be the OID of the relation which the + * command targets (we assume there's just one, as this is meant for + * utility commands), but the meaning of each element in the + * st_progress_param array is command-specific. + */ + ProgressCommandType st_progress_command; + Oid st_progress_command_target; + int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM]; + + /* query identifier, optionally computed using post_parse_analyze_hook */ + uint64 st_query_id; +} PgBackendStatus; + + +/* + * Macros to load and store st_changecount with appropriate memory barriers. + * + * Use PGSTAT_BEGIN_WRITE_ACTIVITY() before, and PGSTAT_END_WRITE_ACTIVITY() + * after, modifying the current process's PgBackendStatus data. Note that, + * since there is no mechanism for cleaning up st_changecount after an error, + * THESE MACROS FORM A CRITICAL SECTION. Any error between them will be + * promoted to PANIC, causing a database restart to clean up shared memory! + * Hence, keep the critical section as short and straight-line as possible. + * Aside from being safer, that minimizes the window in which readers will + * have to loop. + * + * Reader logic should follow this sketch: + * + * for (;;) + * { + * int before_ct, after_ct; + * + * pgstat_begin_read_activity(beentry, before_ct); + * ... copy beentry data to local memory ... + * pgstat_end_read_activity(beentry, after_ct); + * if (pgstat_read_activity_complete(before_ct, after_ct)) + * break; + * CHECK_FOR_INTERRUPTS(); + * } + * + * For extra safety, we generally use volatile beentry pointers, although + * the memory barriers should theoretically be sufficient. + */ +#define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry) \ + do { \ + START_CRIT_SECTION(); \ + (beentry)->st_changecount++; \ + pg_write_barrier(); \ + } while (0) + +#define PGSTAT_END_WRITE_ACTIVITY(beentry) \ + do { \ + pg_write_barrier(); \ + (beentry)->st_changecount++; \ + Assert(((beentry)->st_changecount & 1) == 0); \ + END_CRIT_SECTION(); \ + } while (0) + +#define pgstat_begin_read_activity(beentry, before_changecount) \ + do { \ + (before_changecount) = (beentry)->st_changecount; \ + pg_read_barrier(); \ + } while (0) + +#define pgstat_end_read_activity(beentry, after_changecount) \ + do { \ + pg_read_barrier(); \ + (after_changecount) = (beentry)->st_changecount; \ + } while (0) + +#define pgstat_read_activity_complete(before_changecount, after_changecount) \ + ((before_changecount) == (after_changecount) && \ + ((before_changecount) & 1) == 0) + + +/* ---------- + * LocalPgBackendStatus + * + * When we build the backend status array, we use LocalPgBackendStatus to be + * able to add new values to the struct when needed without adding new fields + * to the shared memory. It contains the backend status as a first member. + * ---------- + */ +typedef struct LocalPgBackendStatus +{ + /* + * Local version of the backend status entry. + */ + PgBackendStatus backendStatus; + + /* + * The backend ID. For auxiliary processes, this will be set to a value + * greater than MaxBackends (since auxiliary processes do not have proper + * backend IDs). + */ + BackendId backend_id; + + /* + * The xid of the current transaction if available, InvalidTransactionId + * if not. + */ + TransactionId backend_xid; + + /* + * The xmin of the current session if available, InvalidTransactionId if + * not. + */ + TransactionId backend_xmin; + + /* + * Number of cached subtransactions in the current session. + */ + int backend_subxact_count; + + /* + * The number of subtransactions in the current session which exceeded the + * cached subtransaction limit. + */ + bool backend_subxact_overflowed; +} LocalPgBackendStatus; + + +/* ---------- + * GUC parameters + * ---------- + */ +extern PGDLLIMPORT bool pgstat_track_activities; +extern PGDLLIMPORT int pgstat_track_activity_query_size; + + +/* ---------- + * Other global variables + * ---------- + */ +extern PGDLLIMPORT PgBackendStatus *MyBEEntry; + + +/* ---------- + * Functions called from postmaster + * ---------- + */ +extern Size BackendStatusShmemSize(void); +extern void CreateSharedBackendStatus(void); + + +/* ---------- + * Functions called from backends + * ---------- + */ + +/* Initialization functions */ +extern void pgstat_beinit(void); +extern void pgstat_bestart(void); + +extern void pgstat_clear_backend_activity_snapshot(void); + +/* Activity reporting functions */ +extern void pgstat_report_activity(BackendState state, const char *cmd_str); +extern void pgstat_report_query_id(uint64 query_id, bool force); +extern void pgstat_report_tempfile(size_t filesize); +extern void pgstat_report_appname(const char *appname); +extern void pgstat_report_xact_timestamp(TimestampTz tstamp); +extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser); +extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer, + int buflen); +extern uint64 pgstat_get_my_query_id(void); + + +/* ---------- + * Support functions for the SQL-callable functions to + * generate the pgstat* views. + * ---------- + */ +extern int pgstat_fetch_stat_numbackends(void); +extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid); +extern LocalPgBackendStatus *pgstat_get_local_beentry_by_backend_id(BackendId beid); +extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int idx); +extern char *pgstat_clip_activity(const char *raw_activity); + + +#endif /* BACKEND_STATUS_H */ diff --git a/install/include/postgresql/server/utils/builtins.h b/install/include/postgresql/server/utils/builtins.h new file mode 100644 index 00000000000..def8ed25f80 --- /dev/null +++ b/install/include/postgresql/server/utils/builtins.h @@ -0,0 +1,137 @@ +/*------------------------------------------------------------------------- + * + * builtins.h + * Declarations for operations on built-in types. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/builtins.h + * + *------------------------------------------------------------------------- + */ +#ifndef BUILTINS_H +#define BUILTINS_H + +#include "fmgr.h" +#include "nodes/nodes.h" +#include "utils/fmgrprotos.h" + +/* Sign + the most decimal digits an 8-byte number could have */ +#define MAXINT8LEN 20 + +/* bool.c */ +extern bool parse_bool(const char *value, bool *result); +extern bool parse_bool_with_len(const char *value, size_t len, bool *result); + +/* domains.c */ +extern void domain_check(Datum value, bool isnull, Oid domainType, + void **extra, MemoryContext mcxt); +extern int errdatatype(Oid datatypeOid); +extern int errdomainconstraint(Oid datatypeOid, const char *conname); + +/* encode.c */ +extern uint64 hex_encode(const char *src, size_t len, char *dst); +extern uint64 hex_decode(const char *src, size_t len, char *dst); +extern uint64 hex_decode_safe(const char *src, size_t len, char *dst, + Node *escontext); + +/* int.c */ +extern int2vector *buildint2vector(const int16 *int2s, int n); + +/* name.c */ +extern void namestrcpy(Name name, const char *str); +extern int namestrcmp(Name name, const char *str); + +/* numutils.c */ +extern int16 pg_strtoint16(const char *s); +extern int16 pg_strtoint16_safe(const char *s, Node *escontext); +extern int32 pg_strtoint32(const char *s); +extern int32 pg_strtoint32_safe(const char *s, Node *escontext); +extern int64 pg_strtoint64(const char *s); +extern int64 pg_strtoint64_safe(const char *s, Node *escontext); +extern uint32 uint32in_subr(const char *s, char **endloc, + const char *typname, Node *escontext); +extern uint64 uint64in_subr(const char *s, char **endloc, + const char *typname, Node *escontext); +extern int pg_itoa(int16 i, char *a); +extern int pg_ultoa_n(uint32 value, char *a); +extern int pg_ulltoa_n(uint64 value, char *a); +extern int pg_ltoa(int32 value, char *a); +extern int pg_lltoa(int64 value, char *a); +extern char *pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth); +extern char *pg_ultostr(char *str, uint32 value); + +/* oid.c */ +extern oidvector *buildoidvector(const Oid *oids, int n); +extern void check_valid_oidvector(const oidvector *oidArray); +extern Oid oidparse(Node *node); +extern int oid_cmp(const void *p1, const void *p2); + +/* regexp.c */ +extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive, + Oid collation, bool *exact); + +/* ruleutils.c */ +extern PGDLLIMPORT bool quote_all_identifiers; +extern const char *quote_identifier(const char *ident); +extern char *quote_qualified_identifier(const char *qualifier, + const char *ident); +extern void generate_operator_clause(fmStringInfo buf, + const char *leftop, Oid leftoptype, + Oid opoid, + const char *rightop, Oid rightoptype); + +/* varchar.c */ +extern int bpchartruelen(char *s, int len); + +/* popular functions from varlena.c */ +extern text *cstring_to_text(const char *s); +extern text *cstring_to_text_with_len(const char *s, int len); +extern char *text_to_cstring(const text *t); +extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len); + +#define CStringGetTextDatum(s) PointerGetDatum(cstring_to_text(s)) +#define TextDatumGetCString(d) text_to_cstring((text *) DatumGetPointer(d)) + +/* xid.c */ +extern int xidComparator(const void *arg1, const void *arg2); +extern int xidLogicalComparator(const void *arg1, const void *arg2); + +/* inet_cidr_ntop.c */ +extern char *pg_inet_cidr_ntop(int af, const void *src, int bits, + char *dst, size_t size); + +/* inet_net_pton.c */ +extern int pg_inet_net_pton(int af, const char *src, + void *dst, size_t size); + +/* network.c */ +extern double convert_network_to_scalar(Datum value, Oid typid, bool *failure); +extern Datum network_scan_first(Datum in); +extern Datum network_scan_last(Datum in); +extern void clean_ipv6_addr(int addr_family, char *addr); + +/* numeric.c */ +extern Datum numeric_float8_no_overflow(PG_FUNCTION_ARGS); + +/* format_type.c */ + +/* Control flags for format_type_extended */ +#define FORMAT_TYPE_TYPEMOD_GIVEN 0x01 /* typemod defined by caller */ +#define FORMAT_TYPE_ALLOW_INVALID 0x02 /* allow invalid types */ +#define FORMAT_TYPE_FORCE_QUALIFY 0x04 /* force qualification of type */ +#define FORMAT_TYPE_INVALID_AS_NULL 0x08 /* NULL if undefined */ +extern char *format_type_extended(Oid type_oid, int32 typemod, bits16 flags); + +extern char *format_type_be(Oid type_oid); +extern char *format_type_be_qualified(Oid type_oid); +extern char *format_type_with_typemod(Oid type_oid, int32 typemod); + +extern int32 type_maximum_size(Oid type_oid, int32 typemod); + +/* quote.c */ +extern char *quote_literal_cstr(const char *rawstr); + +#endif /* BUILTINS_H */ diff --git a/install/include/postgresql/server/utils/bytea.h b/install/include/postgresql/server/utils/bytea.h new file mode 100644 index 00000000000..166dd0366e6 --- /dev/null +++ b/install/include/postgresql/server/utils/bytea.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * bytea.h + * Declarations for BYTEA data type support. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/bytea.h + * + *------------------------------------------------------------------------- + */ +#ifndef BYTEA_H +#define BYTEA_H + + + +typedef enum +{ + BYTEA_OUTPUT_ESCAPE, + BYTEA_OUTPUT_HEX +} ByteaOutputType; + +extern PGDLLIMPORT int bytea_output; /* ByteaOutputType, but int for GUC + * enum */ + +#endif /* BYTEA_H */ diff --git a/install/include/postgresql/server/utils/cash.h b/install/include/postgresql/server/utils/cash.h new file mode 100644 index 00000000000..55d45fadd48 --- /dev/null +++ b/install/include/postgresql/server/utils/cash.h @@ -0,0 +1,35 @@ +/* + * src/include/utils/cash.h + * + * + * cash.h + * Written by D'Arcy J.M. Cain + * + * Functions to allow input and output of money normally but store + * and handle it as 64 bit integer. + */ + +#ifndef CASH_H +#define CASH_H + +#include "fmgr.h" + +typedef int64 Cash; + +/* Cash is pass-by-reference if and only if int64 is */ +static inline Cash +DatumGetCash(Datum X) +{ + return DatumGetInt64(X); +} + +static inline Datum +CashGetDatum(Cash X) +{ + return Int64GetDatum(X); +} + +#define PG_GETARG_CASH(n) DatumGetCash(PG_GETARG_DATUM(n)) +#define PG_RETURN_CASH(x) return CashGetDatum(x) + +#endif /* CASH_H */ diff --git a/install/include/postgresql/server/utils/catcache.h b/install/include/postgresql/server/utils/catcache.h new file mode 100644 index 00000000000..e12bd608649 --- /dev/null +++ b/install/include/postgresql/server/utils/catcache.h @@ -0,0 +1,238 @@ +/*------------------------------------------------------------------------- + * + * catcache.h + * Low-level catalog cache definitions. + * + * NOTE: every catalog cache must have a corresponding unique index on + * the system table that it caches --- ie, the index must match the keys + * used to do lookups in this cache. All cache fetches are done with + * indexscans (under normal conditions). The index should be unique to + * guarantee that there can only be one matching row for a key combination. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/catcache.h + * + *------------------------------------------------------------------------- + */ +#ifndef CATCACHE_H +#define CATCACHE_H + +#include "access/htup.h" +#include "access/skey.h" +#include "lib/ilist.h" +#include "utils/relcache.h" + +/* + * struct catctup: individual tuple in the cache. + * struct catclist: list of tuples matching a partial key. + * struct catcache: information for managing a cache. + * struct catcacheheader: information for managing all the caches. + */ + +#define CATCACHE_MAXKEYS 4 + + +/* function computing a datum's hash */ +typedef uint32 (*CCHashFN) (Datum datum); + +/* function computing equality of two datums */ +typedef bool (*CCFastEqualFN) (Datum a, Datum b); + +typedef struct catcache +{ + int id; /* cache identifier --- see syscache.h */ + int cc_nbuckets; /* # of hash buckets in this cache */ + TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */ + dlist_head *cc_bucket; /* hash buckets */ + CCHashFN cc_hashfunc[CATCACHE_MAXKEYS]; /* hash function for each key */ + CCFastEqualFN cc_fastequal[CATCACHE_MAXKEYS]; /* fast equal function for + * each key */ + int cc_keyno[CATCACHE_MAXKEYS]; /* AttrNumber of each key */ + dlist_head cc_lists; /* list of CatCList structs */ + int cc_ntup; /* # of tuples currently in this cache */ + int cc_nkeys; /* # of keys (1..CATCACHE_MAXKEYS) */ + const char *cc_relname; /* name of relation the tuples come from */ + Oid cc_reloid; /* OID of relation the tuples come from */ + Oid cc_indexoid; /* OID of index matching cache keys */ + bool cc_relisshared; /* is relation shared across databases? */ + slist_node cc_next; /* list link */ + ScanKeyData cc_skey[CATCACHE_MAXKEYS]; /* precomputed key info for heap + * scans */ + + /* These fields are placed here to avoid ABI breakage in v16 */ + int cc_nlist; /* # of CatCLists currently in this cache */ + int cc_nlbuckets; /* # of CatCList hash buckets in this cache */ + dlist_head *cc_lbucket; /* hash buckets for CatCLists */ + + /* + * Keep these at the end, so that compiling catcache.c with CATCACHE_STATS + * doesn't break ABI for other modules + */ +#ifdef CATCACHE_STATS + long cc_searches; /* total # searches against this cache */ + long cc_hits; /* # of matches against existing entry */ + long cc_neg_hits; /* # of matches against negative entry */ + long cc_newloads; /* # of successful loads of new entry */ + + /* + * cc_searches - (cc_hits + cc_neg_hits + cc_newloads) is number of failed + * searches, each of which will result in loading a negative entry + */ + long cc_invals; /* # of entries invalidated from cache */ + long cc_lsearches; /* total # list-searches */ + long cc_lhits; /* # of matches against existing lists */ +#endif +} CatCache; + + +typedef struct catctup +{ + int ct_magic; /* for identifying CatCTup entries */ +#define CT_MAGIC 0x57261502 + + uint32 hash_value; /* hash value for this tuple's keys */ + + /* + * Lookup keys for the entry. By-reference datums point into the tuple for + * positive cache entries, and are separately allocated for negative ones. + */ + Datum keys[CATCACHE_MAXKEYS]; + + /* + * Each tuple in a cache is a member of a dlist that stores the elements + * of its hash bucket. We keep each dlist in LRU order to speed repeated + * lookups. + */ + dlist_node cache_elem; /* list member of per-bucket list */ + + /* + * A tuple marked "dead" must not be returned by subsequent searches. + * However, it won't be physically deleted from the cache until its + * refcount goes to zero. (If it's a member of a CatCList, the list's + * refcount must go to zero, too; also, remember to mark the list dead at + * the same time the tuple is marked.) + * + * A negative cache entry is an assertion that there is no tuple matching + * a particular key. This is just as useful as a normal entry so far as + * avoiding catalog searches is concerned. Management of positive and + * negative entries is identical. + */ + int refcount; /* number of active references */ + bool dead; /* dead but not yet removed? */ + bool negative; /* negative cache entry? */ + HeapTupleData tuple; /* tuple management header */ + + /* + * The tuple may also be a member of at most one CatCList. (If a single + * catcache is list-searched with varying numbers of keys, we may have to + * make multiple entries for the same tuple because of this restriction. + * Currently, that's not expected to be common, so we accept the potential + * inefficiency.) + */ + struct catclist *c_list; /* containing CatCList, or NULL if none */ + + CatCache *my_cache; /* link to owning catcache */ + /* properly aligned tuple data follows, unless a negative entry */ +} CatCTup; + + +/* + * A CatCList describes the result of a partial search, ie, a search using + * only the first K key columns of an N-key cache. We store the keys used + * into the keys attribute to represent the stored key set. The CatCList + * object contains links to cache entries for all the table rows satisfying + * the partial key. (Note: none of these will be negative cache entries.) + * + * A CatCList is only a member of a per-cache list; we do not currently + * divide them into hash buckets. + * + * A list marked "dead" must not be returned by subsequent searches. + * However, it won't be physically deleted from the cache until its + * refcount goes to zero. (A list should be marked dead if any of its + * member entries are dead.) + * + * If "ordered" is true then the member tuples appear in the order of the + * cache's underlying index. This will be true in normal operation, but + * might not be true during bootstrap or recovery operations. (namespace.c + * is able to save some cycles when it is true.) + */ +typedef struct catclist +{ + int cl_magic; /* for identifying CatCList entries */ +#define CL_MAGIC 0x52765103 + + uint32 hash_value; /* hash value for lookup keys */ + + dlist_node cache_elem; /* list member of per-catcache list */ + + /* + * Lookup keys for the entry, with the first nkeys elements being valid. + * All by-reference are separately allocated. + */ + Datum keys[CATCACHE_MAXKEYS]; + + int refcount; /* number of active references */ + bool dead; /* dead but not yet removed? */ + bool ordered; /* members listed in index order? */ + short nkeys; /* number of lookup keys specified */ + int n_members; /* number of member tuples */ + CatCache *my_cache; /* link to owning catcache */ + CatCTup *members[FLEXIBLE_ARRAY_MEMBER]; /* members */ +} CatCList; + + +typedef struct catcacheheader +{ + slist_head ch_caches; /* head of list of CatCache structs */ + int ch_ntup; /* # of tuples in all caches */ +} CatCacheHeader; + + +/* this extern duplicates utils/memutils.h... */ +extern PGDLLIMPORT MemoryContext CacheMemoryContext; + +extern void CreateCacheMemoryContext(void); + +extern CatCache *InitCatCache(int id, Oid reloid, Oid indexoid, + int nkeys, const int *key, + int nbuckets); +extern void InitCatCachePhase2(CatCache *cache, bool touch_index); + +extern HeapTuple SearchCatCache(CatCache *cache, + Datum v1, Datum v2, Datum v3, Datum v4); +extern HeapTuple SearchCatCache1(CatCache *cache, + Datum v1); +extern HeapTuple SearchCatCache2(CatCache *cache, + Datum v1, Datum v2); +extern HeapTuple SearchCatCache3(CatCache *cache, + Datum v1, Datum v2, Datum v3); +extern HeapTuple SearchCatCache4(CatCache *cache, + Datum v1, Datum v2, Datum v3, Datum v4); +extern void ReleaseCatCache(HeapTuple tuple); + +extern uint32 GetCatCacheHashValue(CatCache *cache, + Datum v1, Datum v2, + Datum v3, Datum v4); + +extern CatCList *SearchCatCacheList(CatCache *cache, int nkeys, + Datum v1, Datum v2, + Datum v3); +extern void ReleaseCatCacheList(CatCList *list); + +extern void ResetCatalogCaches(void); +extern void ResetCatalogCachesExt(bool debug_discard); +extern void CatalogCacheFlushCatalog(Oid catId); +extern void CatCacheInvalidate(CatCache *cache, uint32 hashValue); +extern void PrepareToInvalidateCacheTuple(Relation relation, + HeapTuple tuple, + HeapTuple newtuple, + void (*function) (int, uint32, Oid, void *), + void *context); + +extern void PrintCatCacheLeakWarning(HeapTuple tuple); +extern void PrintCatCacheListLeakWarning(CatCList *list); + +#endif /* CATCACHE_H */ diff --git a/install/include/postgresql/server/utils/combocid.h b/install/include/postgresql/server/utils/combocid.h new file mode 100644 index 00000000000..2b496ee6346 --- /dev/null +++ b/install/include/postgresql/server/utils/combocid.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * combocid.h + * Combo command ID support routines + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/combocid.h + * + *------------------------------------------------------------------------- + */ +#ifndef COMBOCID_H +#define COMBOCID_H + +/* + * HeapTupleHeaderGetCmin and HeapTupleHeaderGetCmax function prototypes + * are in access/htup.h, because that's where the macro definitions that + * those functions replaced used to be. + */ + +extern void AtEOXact_ComboCid(void); +extern void RestoreComboCIDState(char *comboCIDstate); +extern void SerializeComboCIDState(Size maxsize, char *start_address); +extern Size EstimateComboCIDStateSpace(void); + +#endif /* COMBOCID_H */ diff --git a/install/include/postgresql/server/utils/conffiles.h b/install/include/postgresql/server/utils/conffiles.h new file mode 100644 index 00000000000..e3868fbc23d --- /dev/null +++ b/install/include/postgresql/server/utils/conffiles.h @@ -0,0 +1,27 @@ +/*-------------------------------------------------------------------- + * conffiles.h + * + * Utilities related to configuration files. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/conffiles.h + * + *-------------------------------------------------------------------- + */ +#ifndef CONFFILES_H +#define CONFFILES_H + +/* recursion nesting depth for configuration files */ +#define CONF_FILE_START_DEPTH 0 +#define CONF_FILE_MAX_DEPTH 10 + +extern char *AbsoluteConfigLocation(const char *location, + const char *calling_file); +extern char **GetConfFilesInDir(const char *includedir, + const char *calling_file, + int elevel, int *num_filenames, + char **err_msg); + +#endif /* CONFFILES_H */ diff --git a/install/include/postgresql/server/utils/date.h b/install/include/postgresql/server/utils/date.h new file mode 100644 index 00000000000..97e1a021217 --- /dev/null +++ b/install/include/postgresql/server/utils/date.h @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------------- + * + * date.h + * Definitions for the SQL "date" and "time" types. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/date.h + * + *------------------------------------------------------------------------- + */ +#ifndef DATE_H +#define DATE_H + +#include + +#include "datatype/timestamp.h" +#include "fmgr.h" +#include "pgtime.h" + +typedef int32 DateADT; + +typedef int64 TimeADT; + +typedef struct +{ + TimeADT time; /* all time units other than months and years */ + int32 zone; /* numeric time zone, in seconds */ +} TimeTzADT; + +/* + * Infinity and minus infinity must be the max and min values of DateADT. + */ +#define DATEVAL_NOBEGIN ((DateADT) PG_INT32_MIN) +#define DATEVAL_NOEND ((DateADT) PG_INT32_MAX) + +#define DATE_NOBEGIN(j) ((j) = DATEVAL_NOBEGIN) +#define DATE_IS_NOBEGIN(j) ((j) == DATEVAL_NOBEGIN) +#define DATE_NOEND(j) ((j) = DATEVAL_NOEND) +#define DATE_IS_NOEND(j) ((j) == DATEVAL_NOEND) +#define DATE_NOT_FINITE(j) (DATE_IS_NOBEGIN(j) || DATE_IS_NOEND(j)) + +#define MAX_TIME_PRECISION 6 + +/* + * Functions for fmgr-callable functions. + * + * For TimeADT, we make use of the same support routines as for int64. + * Therefore TimeADT is pass-by-reference if and only if int64 is! + */ +static inline DateADT +DatumGetDateADT(Datum X) +{ + return (DateADT) DatumGetInt32(X); +} + +static inline TimeADT +DatumGetTimeADT(Datum X) +{ + return (TimeADT) DatumGetInt64(X); +} + +static inline TimeTzADT * +DatumGetTimeTzADTP(Datum X) +{ + return (TimeTzADT *) DatumGetPointer(X); +} + +static inline Datum +DateADTGetDatum(DateADT X) +{ + return Int32GetDatum(X); +} + +static inline Datum +TimeADTGetDatum(TimeADT X) +{ + return Int64GetDatum(X); +} + +static inline Datum +TimeTzADTPGetDatum(const TimeTzADT *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_DATEADT(n) DatumGetDateADT(PG_GETARG_DATUM(n)) +#define PG_GETARG_TIMEADT(n) DatumGetTimeADT(PG_GETARG_DATUM(n)) +#define PG_GETARG_TIMETZADT_P(n) DatumGetTimeTzADTP(PG_GETARG_DATUM(n)) + +#define PG_RETURN_DATEADT(x) return DateADTGetDatum(x) +#define PG_RETURN_TIMEADT(x) return TimeADTGetDatum(x) +#define PG_RETURN_TIMETZADT_P(x) return TimeTzADTPGetDatum(x) + + +/* date.c */ +extern int32 anytime_typmod_check(bool istz, int32 typmod); +extern double date2timestamp_no_overflow(DateADT dateVal); +extern Timestamp date2timestamp_opt_overflow(DateADT dateVal, int *overflow); +extern TimestampTz date2timestamptz_opt_overflow(DateADT dateVal, int *overflow); +extern int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2); +extern int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2); + +extern void EncodeSpecialDate(DateADT dt, char *str); +extern DateADT GetSQLCurrentDate(void); +extern TimeTzADT *GetSQLCurrentTime(int32 typmod); +extern TimeADT GetSQLLocalTime(int32 typmod); +extern int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec); +extern int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp); +extern int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result); +extern int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result); +extern bool time_overflows(int hour, int min, int sec, fsec_t fsec); +extern bool float_time_overflows(int hour, int min, double sec); +extern void AdjustTimeForTypmod(TimeADT *time, int32 typmod); + +#endif /* DATE_H */ diff --git a/install/include/postgresql/server/utils/datetime.h b/install/include/postgresql/server/utils/datetime.h new file mode 100644 index 00000000000..a871e3223de --- /dev/null +++ b/install/include/postgresql/server/utils/datetime.h @@ -0,0 +1,364 @@ +/*------------------------------------------------------------------------- + * + * datetime.h + * Definitions for date/time support code. + * The support code is shared with other date data types, + * including date, and time. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/datetime.h + * + *------------------------------------------------------------------------- + */ +#ifndef DATETIME_H +#define DATETIME_H + +#include "utils/timestamp.h" + +/* this struct is declared in utils/tzparser.h: */ +struct tzEntry; + + +/* ---------------------------------------------------------------- + * time types + support macros + * + * String definitions for standard time quantities. + * + * These strings are the defaults used to form output time strings. + * Other alternative forms are hardcoded into token tables in datetime.c. + * ---------------------------------------------------------------- + */ + +#define DAGO "ago" +#define DCURRENT "current" +#define EPOCH "epoch" +#define INVALID "invalid" +#define EARLY "-infinity" +#define LATE "infinity" +#define NOW "now" +#define TODAY "today" +#define TOMORROW "tomorrow" +#define YESTERDAY "yesterday" +#define ZULU "zulu" + +#define DMICROSEC "usecond" +#define DMILLISEC "msecond" +#define DSECOND "second" +#define DMINUTE "minute" +#define DHOUR "hour" +#define DDAY "day" +#define DWEEK "week" +#define DMONTH "month" +#define DQUARTER "quarter" +#define DYEAR "year" +#define DDECADE "decade" +#define DCENTURY "century" +#define DMILLENNIUM "millennium" +#define DA_D "ad" +#define DB_C "bc" +#define DTIMEZONE "timezone" + +/* + * Fundamental time field definitions for parsing. + * + * Meridian: am, pm, or 24-hour style. + * Millennium: ad, bc + */ + +#define AM 0 +#define PM 1 +#define HR24 2 + +#define AD 0 +#define BC 1 + +/* + * Field types for time decoding. + * + * Can't have more of these than there are bits in an unsigned int + * since these are turned into bit masks during parsing and decoding. + * + * Furthermore, the values for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND + * must be in the range 0..14 so that the associated bitmasks can fit + * into the left half of an INTERVAL's typmod value. Since those bits + * are stored in typmods, you can't change them without initdb! + */ + +#define RESERV 0 +#define MONTH 1 +#define YEAR 2 +#define DAY 3 +#define JULIAN 4 +#define TZ 5 /* fixed-offset timezone abbreviation */ +#define DTZ 6 /* fixed-offset timezone abbrev, DST */ +#define DYNTZ 7 /* dynamic timezone abbreviation */ +#define IGNORE_DTF 8 +#define AMPM 9 +#define HOUR 10 +#define MINUTE 11 +#define SECOND 12 +#define MILLISECOND 13 +#define MICROSECOND 14 +#define DOY 15 +#define DOW 16 +#define UNITS 17 +#define ADBC 18 +/* these are only for relative dates */ +#define AGO 19 +#define ABS_BEFORE 20 +#define ABS_AFTER 21 +/* generic fields to help with parsing */ +#define ISODATE 22 +#define ISOTIME 23 +/* these are only for parsing intervals */ +#define WEEK 24 +#define DECADE 25 +#define CENTURY 26 +#define MILLENNIUM 27 +/* hack for parsing two-word timezone specs "MET DST" etc */ +#define DTZMOD 28 /* "DST" as a separate word */ +/* reserved for unrecognized string values */ +#define UNKNOWN_FIELD 31 + +/* + * Token field definitions for time parsing and decoding. + * + * Some field type codes (see above) use these as the "value" in datetktbl[]. + * These are also used for bit masks in DecodeDateTime and friends + * so actually restrict them to within [0,31] for now. + * - thomas 97/06/19 + * Not all of these fields are used for masks in DecodeDateTime + * so allow some larger than 31. - thomas 1997-11-17 + * + * Caution: there are undocumented assumptions in the code that most of these + * values are not equal to IGNORE_DTF nor RESERV. Be very careful when + * renumbering values in either of these apparently-independent lists :-( + */ + +#define DTK_NUMBER 0 +#define DTK_STRING 1 + +#define DTK_DATE 2 +#define DTK_TIME 3 +#define DTK_TZ 4 +#define DTK_AGO 5 + +#define DTK_SPECIAL 6 +#define DTK_EARLY 9 +#define DTK_LATE 10 +#define DTK_EPOCH 11 +#define DTK_NOW 12 +#define DTK_YESTERDAY 13 +#define DTK_TODAY 14 +#define DTK_TOMORROW 15 +#define DTK_ZULU 16 + +#define DTK_DELTA 17 +#define DTK_SECOND 18 +#define DTK_MINUTE 19 +#define DTK_HOUR 20 +#define DTK_DAY 21 +#define DTK_WEEK 22 +#define DTK_MONTH 23 +#define DTK_QUARTER 24 +#define DTK_YEAR 25 +#define DTK_DECADE 26 +#define DTK_CENTURY 27 +#define DTK_MILLENNIUM 28 +#define DTK_MILLISEC 29 +#define DTK_MICROSEC 30 +#define DTK_JULIAN 31 + +#define DTK_DOW 32 +#define DTK_DOY 33 +#define DTK_TZ_HOUR 34 +#define DTK_TZ_MINUTE 35 +#define DTK_ISOYEAR 36 +#define DTK_ISODOW 37 + + +/* + * Bit mask definitions for time parsing. + */ + +#define DTK_M(t) (0x01 << (t)) + +/* Convenience: a second, plus any fractional component */ +#define DTK_ALL_SECS_M (DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND)) +#define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY)) +#define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_ALL_SECS_M) + +/* + * Working buffer size for input and output of interval, timestamp, etc. + * Inputs that need more working space will be rejected early. Longer outputs + * will overrun buffers, so this must suffice for all possible output. As of + * this writing, interval_out() needs the most space at ~90 bytes. + */ +#define MAXDATELEN 128 +/* maximum possible number of fields in a date string */ +#define MAXDATEFIELDS 25 +/* only this many chars are stored in datetktbl */ +#define TOKMAXLEN 10 + +/* keep this struct small; it gets used a lot */ +typedef struct +{ + char token[TOKMAXLEN + 1]; /* always NUL-terminated */ + char type; /* see field type codes above */ + int32 value; /* meaning depends on type */ +} datetkn; + +/* one of its uses is in tables of time zone abbreviations */ +typedef struct TimeZoneAbbrevTable +{ + Size tblsize; /* size in bytes of TimeZoneAbbrevTable */ + int numabbrevs; /* number of entries in abbrevs[] array */ + datetkn abbrevs[FLEXIBLE_ARRAY_MEMBER]; + /* DynamicZoneAbbrev(s) may follow the abbrevs[] array */ +} TimeZoneAbbrevTable; + +/* auxiliary data for a dynamic time zone abbreviation (non-fixed-offset) */ +typedef struct DynamicZoneAbbrev +{ + pg_tz *tz; /* NULL if not yet looked up */ + char zone[FLEXIBLE_ARRAY_MEMBER]; /* NUL-terminated zone name */ +} DynamicZoneAbbrev; + + +/* FMODULO() + * Macro to replace modf(), which is broken on some platforms. + * t = input and remainder + * q = integer part + * u = divisor + */ +#define FMODULO(t,q,u) \ +do { \ + (q) = (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \ + if ((q) != 0) (t) -= rint((q) * (u)); \ +} while(0) + +/* TMODULO() + * Like FMODULO(), but work on the timestamp datatype (now always int64). + * We assume that int64 follows the C99 semantics for division (negative + * quotients truncate towards zero). + */ +#define TMODULO(t,q,u) \ +do { \ + (q) = ((t) / (u)); \ + if ((q) != 0) (t) -= ((q) * (u)); \ +} while(0) + +/* + * Date/time validation + * Include check for leap year. + */ + +extern PGDLLIMPORT const char *const months[]; /* months (3-char + * abbreviations) */ +extern PGDLLIMPORT const char *const days[]; /* days (full names) */ +extern PGDLLIMPORT const int day_tab[2][13]; + +/* + * These are the rules for the Gregorian calendar, which was adopted in 1582. + * However, we use this calculation for all prior years as well because the + * SQL standard specifies use of the Gregorian calendar. This prevents the + * date 1500-02-29 from being stored, even though it is valid in the Julian + * calendar. + */ +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + + +/* + * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc) + * return zero or a positive value on success. On failure, they return + * one of these negative code values. DateTimeParseError may be used to + * produce a suitable error report. For some of these codes, + * DateTimeParseError requires additional information, which is carried + * in struct DateTimeErrorExtra. + */ +#define DTERR_BAD_FORMAT (-1) +#define DTERR_FIELD_OVERFLOW (-2) +#define DTERR_MD_FIELD_OVERFLOW (-3) /* triggers hint about DateStyle */ +#define DTERR_INTERVAL_OVERFLOW (-4) +#define DTERR_TZDISP_OVERFLOW (-5) +#define DTERR_BAD_TIMEZONE (-6) +#define DTERR_BAD_ZONE_ABBREV (-7) + +typedef struct DateTimeErrorExtra +{ + /* Needed for DTERR_BAD_TIMEZONE and DTERR_BAD_ZONE_ABBREV: */ + const char *dtee_timezone; /* incorrect time zone name */ + /* Needed for DTERR_BAD_ZONE_ABBREV: */ + const char *dtee_abbrev; /* relevant time zone abbreviation */ +} DateTimeErrorExtra; + +/* Result codes for DecodeTimezoneName() */ +#define TZNAME_FIXED_OFFSET 0 +#define TZNAME_DYNTZ 1 +#define TZNAME_ZONE 2 + + +extern void GetCurrentDateTime(struct pg_tm *tm); +extern void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp); +extern void j2date(int jd, int *year, int *month, int *day); +extern int date2j(int year, int month, int day); + +extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, + char **field, int *ftype, + int maxfields, int *numfields); +extern int DecodeDateTime(char **field, int *ftype, int nf, + int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, + DateTimeErrorExtra *extra); +extern int DecodeTimezone(const char *str, int *tzp); +extern int DecodeTimeOnly(char **field, int *ftype, int nf, + int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, + DateTimeErrorExtra *extra); +extern int DecodeInterval(char **field, int *ftype, int nf, int range, + int *dtype, struct pg_itm_in *itm_in); +extern int DecodeISO8601Interval(char *str, + int *dtype, struct pg_itm_in *itm_in); + +extern void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, + const char *str, const char *datatype, + struct Node *escontext); + +extern int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp); +extern int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp); +extern int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, + pg_tz *tzp, int *isdst); + +extern void EncodeDateOnly(struct pg_tm *tm, int style, char *str); +extern void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str); +extern void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str); +extern void EncodeInterval(struct pg_itm *itm, int style, char *str); +extern void EncodeSpecialTimestamp(Timestamp dt, char *str); + +extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, + struct pg_tm *tm); + +extern int DecodeTimezoneAbbrev(int field, const char *lowtoken, + int *ftype, int *offset, pg_tz **tz, + DateTimeErrorExtra *extra); +extern int DecodeSpecial(int field, const char *lowtoken, int *val); +extern int DecodeUnits(int field, const char *lowtoken, int *val); + +extern int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz); +extern pg_tz *DecodeTimezoneNameToTz(const char *tzname); + +extern int j2day(int date); + +extern struct Node *TemporalSimplify(int32 max_precis, struct Node *node); + +extern bool CheckDateTokenTables(void); + +extern TimeZoneAbbrevTable *ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs, + int n); +extern void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl); + +extern bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, + struct Node *escontext); + +#endif /* DATETIME_H */ diff --git a/install/include/postgresql/server/utils/datum.h b/install/include/postgresql/server/utils/datum.h new file mode 100644 index 00000000000..70a47f33c18 --- /dev/null +++ b/install/include/postgresql/server/utils/datum.h @@ -0,0 +1,76 @@ +/*------------------------------------------------------------------------- + * + * datum.h + * POSTGRES Datum (abstract data type) manipulation routines. + * + * These routines are driven by the 'typbyval' and 'typlen' information, + * which must previously have been obtained by the caller for the datatype + * of the Datum. (We do it this way because in most situations the caller + * can look up the info just once and use it for many per-datum operations.) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/datum.h + * + *------------------------------------------------------------------------- + */ +#ifndef DATUM_H +#define DATUM_H + +/* + * datumGetSize - find the "real" length of a datum + */ +extern Size datumGetSize(Datum value, bool typByVal, int typLen); + +/* + * datumCopy - make a copy of a non-NULL datum. + * + * If the datatype is pass-by-reference, memory is obtained with palloc(). + */ +extern Datum datumCopy(Datum value, bool typByVal, int typLen); + +/* + * datumTransfer - transfer a non-NULL datum into the current memory context. + * + * Differs from datumCopy() in its handling of read-write expanded objects. + */ +extern Datum datumTransfer(Datum value, bool typByVal, int typLen); + +/* + * datumIsEqual + * return true if two datums of the same type are equal, false otherwise. + * + * XXX : See comments in the code for restrictions! + */ +extern bool datumIsEqual(Datum value1, Datum value2, + bool typByVal, int typLen); + +/* + * datum_image_eq + * + * Compares two datums for identical contents, based on byte images. Return + * true if the two datums are equal, false otherwise. + */ +extern bool datum_image_eq(Datum value1, Datum value2, + bool typByVal, int typLen); + +/* + * datum_image_hash + * + * Generates hash value for 'value' based on its bits rather than logical + * value. + */ +extern uint32 datum_image_hash(Datum value, bool typByVal, int typLen); + +/* + * Serialize and restore datums so that we can transfer them to parallel + * workers. + */ +extern Size datumEstimateSpace(Datum value, bool isnull, bool typByVal, + int typLen); +extern void datumSerialize(Datum value, bool isnull, bool typByVal, + int typLen, char **start_address); +extern Datum datumRestore(char **start_address, bool *isnull); + +#endif /* DATUM_H */ diff --git a/install/include/postgresql/server/utils/dsa.h b/install/include/postgresql/server/utils/dsa.h new file mode 100644 index 00000000000..3ce4ee300a5 --- /dev/null +++ b/install/include/postgresql/server/utils/dsa.h @@ -0,0 +1,127 @@ +/*------------------------------------------------------------------------- + * + * dsa.h + * Dynamic shared memory areas. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/utils/dsa.h + * + *------------------------------------------------------------------------- + */ +#ifndef DSA_H +#define DSA_H + +#include "port/atomics.h" +#include "storage/dsm.h" + +/* The opaque type used for an area. */ +struct dsa_area; +typedef struct dsa_area dsa_area; + +/* + * If this system only uses a 32-bit value for size_t, then use the 32-bit + * implementation of DSA. This limits the amount of DSA that can be created + * to something significantly less than the entire 4GB address space because + * the DSA pointer must encode both a segment identifier and an offset, but + * that shouldn't be a significant limitation in practice. + * + * If this system doesn't support atomic operations on 64-bit values, then + * we fall back to 32-bit dsa_pointer for lack of other options. + * + * For testing purposes, USE_SMALL_DSA_POINTER can be defined to force the use + * of 32-bit dsa_pointer even on systems capable of supporting a 64-bit + * dsa_pointer. + */ +#if SIZEOF_SIZE_T == 4 || !defined(PG_HAVE_ATOMIC_U64_SUPPORT) || \ + defined(USE_SMALL_DSA_POINTER) +#define SIZEOF_DSA_POINTER 4 +#else +#define SIZEOF_DSA_POINTER 8 +#endif + +/* + * The type of 'relative pointers' to memory allocated by a dynamic shared + * area. dsa_pointer values can be shared with other processes, but must be + * converted to backend-local pointers before they can be dereferenced. See + * dsa_get_address. Also, an atomic version and appropriately sized atomic + * operations. + */ +#if SIZEOF_DSA_POINTER == 4 +typedef uint32 dsa_pointer; +typedef pg_atomic_uint32 dsa_pointer_atomic; +#define dsa_pointer_atomic_init pg_atomic_init_u32 +#define dsa_pointer_atomic_read pg_atomic_read_u32 +#define dsa_pointer_atomic_write pg_atomic_write_u32 +#define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u32 +#define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u32 +#define DSA_POINTER_FORMAT "%08x" +#else +typedef uint64 dsa_pointer; +typedef pg_atomic_uint64 dsa_pointer_atomic; +#define dsa_pointer_atomic_init pg_atomic_init_u64 +#define dsa_pointer_atomic_read pg_atomic_read_u64 +#define dsa_pointer_atomic_write pg_atomic_write_u64 +#define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u64 +#define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u64 +#define DSA_POINTER_FORMAT "%016" INT64_MODIFIER "x" +#endif + +/* Flags for dsa_allocate_extended. */ +#define DSA_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) */ +#define DSA_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ +#define DSA_ALLOC_ZERO 0x04 /* zero allocated memory */ + +/* A sentinel value for dsa_pointer used to indicate failure to allocate. */ +#define InvalidDsaPointer ((dsa_pointer) 0) + +/* Check if a dsa_pointer value is valid. */ +#define DsaPointerIsValid(x) ((x) != InvalidDsaPointer) + +/* Allocate uninitialized memory with error on out-of-memory. */ +#define dsa_allocate(area, size) \ + dsa_allocate_extended(area, size, 0) + +/* Allocate zero-initialized memory with error on out-of-memory. */ +#define dsa_allocate0(area, size) \ + dsa_allocate_extended(area, size, DSA_ALLOC_ZERO) + +/* + * The type used for dsa_area handles. dsa_handle values can be shared with + * other processes, so that they can attach to them. This provides a way to + * share allocated storage with other processes. + * + * The handle for a dsa_area is currently implemented as the dsm_handle + * for the first DSM segment backing this dynamic storage area, but client + * code shouldn't assume that is true. + */ +typedef dsm_handle dsa_handle; + +/* Sentinel value to use for invalid dsa_handles. */ +#define DSA_HANDLE_INVALID ((dsa_handle) DSM_HANDLE_INVALID) + + +extern dsa_area *dsa_create(int tranche_id); +extern dsa_area *dsa_create_in_place(void *place, size_t size, + int tranche_id, dsm_segment *segment); +extern dsa_area *dsa_attach(dsa_handle handle); +extern dsa_area *dsa_attach_in_place(void *place, dsm_segment *segment); +extern void dsa_release_in_place(void *place); +extern void dsa_on_dsm_detach_release_in_place(dsm_segment *, Datum); +extern void dsa_on_shmem_exit_release_in_place(int, Datum); +extern void dsa_pin_mapping(dsa_area *area); +extern void dsa_detach(dsa_area *area); +extern void dsa_pin(dsa_area *area); +extern void dsa_unpin(dsa_area *area); +extern void dsa_set_size_limit(dsa_area *area, size_t limit); +extern size_t dsa_minimum_size(void); +extern dsa_handle dsa_get_handle(dsa_area *area); +extern dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags); +extern void dsa_free(dsa_area *area, dsa_pointer dp); +extern void *dsa_get_address(dsa_area *area, dsa_pointer dp); +extern void dsa_trim(dsa_area *area); +extern void dsa_dump(dsa_area *area); + +#endif /* DSA_H */ diff --git a/install/include/postgresql/server/utils/dynahash.h b/install/include/postgresql/server/utils/dynahash.h new file mode 100644 index 00000000000..866677abd86 --- /dev/null +++ b/install/include/postgresql/server/utils/dynahash.h @@ -0,0 +1,20 @@ +/*------------------------------------------------------------------------- + * + * dynahash.h + * POSTGRES dynahash.h file definitions + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/utils/dynahash.h + * + *------------------------------------------------------------------------- + */ +#ifndef DYNAHASH_H +#define DYNAHASH_H + +extern int my_log2(long num); + +#endif /* DYNAHASH_H */ diff --git a/install/include/postgresql/server/utils/elog.h b/install/include/postgresql/server/utils/elog.h new file mode 100644 index 00000000000..b3e95044174 --- /dev/null +++ b/install/include/postgresql/server/utils/elog.h @@ -0,0 +1,547 @@ +/*------------------------------------------------------------------------- + * + * elog.h + * POSTGRES error reporting/logging definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/elog.h + * + *------------------------------------------------------------------------- + */ +#ifndef ELOG_H +#define ELOG_H + +#include + +#include "lib/stringinfo.h" + +/* We cannot include nodes.h yet, so forward-declare struct Node */ +struct Node; + + +/* Error level codes */ +#define DEBUG5 10 /* Debugging messages, in categories of + * decreasing detail. */ +#define DEBUG4 11 +#define DEBUG3 12 +#define DEBUG2 13 +#define DEBUG1 14 /* used by GUC debug_* variables */ +#define LOG 15 /* Server operational messages; sent only to + * server log by default. */ +#define LOG_SERVER_ONLY 16 /* Same as LOG for server reporting, but never + * sent to client. */ +#define COMMERROR LOG_SERVER_ONLY /* Client communication problems; same as + * LOG for server reporting, but never + * sent to client. */ +#define INFO 17 /* Messages specifically requested by user (eg + * VACUUM VERBOSE output); always sent to + * client regardless of client_min_messages, + * but by default not sent to server log. */ +#define NOTICE 18 /* Helpful messages to users about query + * operation; sent to client and not to server + * log by default. */ +#define WARNING 19 /* Warnings. NOTICE is for expected messages + * like implicit sequence creation by SERIAL. + * WARNING is for unexpected messages. */ +#define PGWARNING 19 /* Must equal WARNING; see NOTE below. */ +#define WARNING_CLIENT_ONLY 20 /* Warnings to be sent to client as usual, but + * never to the server log. */ +#define ERROR 21 /* user error - abort transaction; return to + * known state */ +#define PGERROR 21 /* Must equal ERROR; see NOTE below. */ +#define FATAL 22 /* fatal error - abort process */ +#define PANIC 23 /* take down the other backends with me */ + +/* + * NOTE: the alternate names PGWARNING and PGERROR are useful for dealing + * with third-party headers that make other definitions of WARNING and/or + * ERROR. One can, for example, re-define ERROR as PGERROR after including + * such a header. + */ + + +/* macros for representing SQLSTATE strings compactly */ +#define PGSIXBIT(ch) (((ch) - '0') & 0x3F) +#define PGUNSIXBIT(val) (((val) & 0x3F) + '0') + +#define MAKE_SQLSTATE(ch1,ch2,ch3,ch4,ch5) \ + (PGSIXBIT(ch1) + (PGSIXBIT(ch2) << 6) + (PGSIXBIT(ch3) << 12) + \ + (PGSIXBIT(ch4) << 18) + (PGSIXBIT(ch5) << 24)) + +/* These macros depend on the fact that '0' becomes a zero in PGSIXBIT */ +#define ERRCODE_TO_CATEGORY(ec) ((ec) & ((1 << 12) - 1)) +#define ERRCODE_IS_CATEGORY(ec) (((ec) & ~((1 << 12) - 1)) == 0) + +/* SQLSTATE codes for errors are defined in a separate file */ +#include "utils/errcodes.h" + +/* + * Provide a way to prevent "errno" from being accidentally used inside an + * elog() or ereport() invocation. Since we know that some operating systems + * define errno as something involving a function call, we'll put a local + * variable of the same name as that function in the local scope to force a + * compile error. On platforms that don't define errno in that way, nothing + * happens, so we get no warning ... but we can live with that as long as it + * happens on some popular platforms. + */ +#if defined(errno) && defined(__linux__) +#define pg_prevent_errno_in_scope() int __errno_location pg_attribute_unused() +#elif defined(errno) && (defined(__darwin__) || defined(__FreeBSD__)) +#define pg_prevent_errno_in_scope() int __error pg_attribute_unused() +#else +#define pg_prevent_errno_in_scope() +#endif + + +/*---------- + * New-style error reporting API: to be used in this way: + * ereport(ERROR, + * errcode(ERRCODE_UNDEFINED_CURSOR), + * errmsg("portal \"%s\" not found", stmt->portalname), + * ... other errxxx() fields as needed ...); + * + * The error level is required, and so is a primary error message (errmsg + * or errmsg_internal). All else is optional. errcode() defaults to + * ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING + * if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is + * NOTICE or below. + * + * Before Postgres v12, extra parentheses were required around the + * list of auxiliary function calls; that's now optional. + * + * ereport_domain() allows a message domain to be specified, for modules that + * wish to use a different message catalog from the backend's. To avoid having + * one copy of the default text domain per .o file, we define it as NULL here + * and have errstart insert the default text domain. Modules can either use + * ereport_domain() directly, or preferably they can override the TEXTDOMAIN + * macro. + * + * When __builtin_constant_p is available and elevel >= ERROR we make a call + * to errstart_cold() instead of errstart(). This version of the function is + * marked with pg_attribute_cold which will coax supporting compilers into + * generating code which is more optimized towards non-ERROR cases. Because + * we use __builtin_constant_p() in the condition, when elevel is not a + * compile-time constant, or if it is, but it's < ERROR, the compiler has no + * need to generate any code for this branch. It can simply call errstart() + * unconditionally. + * + * If elevel >= ERROR, the call will not return; we try to inform the compiler + * of that via pg_unreachable(). However, no useful optimization effect is + * obtained unless the compiler sees elevel as a compile-time constant, else + * we're just adding code bloat. So, if __builtin_constant_p is available, + * use that to cause the second if() to vanish completely for non-constant + * cases. We avoid using a local variable because it's not necessary and + * prevents gcc from making the unreachability deduction at optlevel -O0. + *---------- + */ +#ifdef HAVE__BUILTIN_CONSTANT_P +#define ereport_domain(elevel, domain, ...) \ + do { \ + pg_prevent_errno_in_scope(); \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR ? \ + errstart_cold(elevel, domain) : \ + errstart(elevel, domain)) \ + __VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ + pg_unreachable(); \ + } while(0) +#else /* !HAVE__BUILTIN_CONSTANT_P */ +#define ereport_domain(elevel, domain, ...) \ + do { \ + const int elevel_ = (elevel); \ + pg_prevent_errno_in_scope(); \ + if (errstart(elevel_, domain)) \ + __VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \ + if (elevel_ >= ERROR) \ + pg_unreachable(); \ + } while(0) +#endif /* HAVE__BUILTIN_CONSTANT_P */ + +#define ereport(elevel, ...) \ + ereport_domain(elevel, TEXTDOMAIN, __VA_ARGS__) + +#define TEXTDOMAIN NULL + +extern bool message_level_is_interesting(int elevel); + +extern bool errstart(int elevel, const char *domain); +extern pg_attribute_cold bool errstart_cold(int elevel, const char *domain); +extern void errfinish(const char *filename, int lineno, const char *funcname); + +extern int errcode(int sqlerrcode); + +extern int errcode_for_file_access(void); +extern int errcode_for_socket_access(void); + +extern int errmsg(const char *fmt,...) pg_attribute_printf(1, 2); +extern int errmsg_internal(const char *fmt,...) pg_attribute_printf(1, 2); + +extern int errmsg_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); + +extern int errdetail(const char *fmt,...) pg_attribute_printf(1, 2); +extern int errdetail_internal(const char *fmt,...) pg_attribute_printf(1, 2); + +extern int errdetail_log(const char *fmt,...) pg_attribute_printf(1, 2); + +extern int errdetail_log_plural(const char *fmt_singular, + const char *fmt_plural, + unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); + +extern int errdetail_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); + +extern int errhint(const char *fmt,...) pg_attribute_printf(1, 2); + +extern int errhint_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); + +/* + * errcontext() is typically called in error context callback functions, not + * within an ereport() invocation. The callback function can be in a different + * module than the ereport() call, so the message domain passed in errstart() + * is not usually the correct domain for translating the context message. + * set_errcontext_domain() first sets the domain to be used, and + * errcontext_msg() passes the actual message. + */ +#define errcontext set_errcontext_domain(TEXTDOMAIN), errcontext_msg + +extern int set_errcontext_domain(const char *domain); + +extern int errcontext_msg(const char *fmt,...) pg_attribute_printf(1, 2); + +extern int errhidestmt(bool hide_stmt); +extern int errhidecontext(bool hide_ctx); + +extern int errbacktrace(void); + +extern int errposition(int cursorpos); + +extern int internalerrposition(int cursorpos); +extern int internalerrquery(const char *query); + +extern int err_generic_string(int field, const char *str); + +extern int geterrcode(void); +extern int geterrlevel(void); +extern int geterrposition(void); +extern int getinternalerrposition(void); + + +/*---------- + * Old-style error reporting API: to be used in this way: + * elog(ERROR, "portal \"%s\" not found", stmt->portalname); + *---------- + */ +#define elog(elevel, ...) \ + ereport(elevel, errmsg_internal(__VA_ARGS__)) + + +/*---------- + * Support for reporting "soft" errors that don't require a full transaction + * abort to clean up. This is to be used in this way: + * errsave(context, + * errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + * errmsg("invalid input syntax for type %s: \"%s\"", + * "boolean", in_str), + * ... other errxxx() fields as needed ...); + * + * "context" is a node pointer or NULL, and the remaining auxiliary calls + * provide the same error details as in ereport(). If context is not a + * pointer to an ErrorSaveContext node, then errsave(context, ...) + * behaves identically to ereport(ERROR, ...). If context is a pointer + * to an ErrorSaveContext node, then the information provided by the + * auxiliary calls is stored in the context node and control returns + * normally. The caller of errsave() must then do any required cleanup + * and return control back to its caller. That caller must check the + * ErrorSaveContext node to see whether an error occurred before + * it can trust the function's result to be meaningful. + * + * errsave_domain() allows a message domain to be specified; it is + * precisely analogous to ereport_domain(). + *---------- + */ +#define errsave_domain(context, domain, ...) \ + do { \ + struct Node *context_ = (context); \ + pg_prevent_errno_in_scope(); \ + if (errsave_start(context_, domain)) \ + __VA_ARGS__, errsave_finish(context_, __FILE__, __LINE__, __func__); \ + } while(0) + +#define errsave(context, ...) \ + errsave_domain(context, TEXTDOMAIN, __VA_ARGS__) + +/* + * "ereturn(context, dummy_value, ...);" is exactly the same as + * "errsave(context, ...); return dummy_value;". This saves a bit + * of typing in the common case where a function has no cleanup + * actions to take after reporting a soft error. "dummy_value" + * can be empty if the function returns void. + */ +#define ereturn_domain(context, dummy_value, domain, ...) \ + do { \ + errsave_domain(context, domain, __VA_ARGS__); \ + return dummy_value; \ + } while(0) + +#define ereturn(context, dummy_value, ...) \ + ereturn_domain(context, dummy_value, TEXTDOMAIN, __VA_ARGS__) + +extern bool errsave_start(struct Node *context, const char *domain); +extern void errsave_finish(struct Node *context, + const char *filename, int lineno, + const char *funcname); + + +/* Support for constructing error strings separately from ereport() calls */ + +extern void pre_format_elog_string(int errnumber, const char *domain); +extern char *format_elog_string(const char *fmt,...) pg_attribute_printf(1, 2); + + +/* Support for attaching context information to error reports */ + +typedef struct ErrorContextCallback +{ + struct ErrorContextCallback *previous; + void (*callback) (void *arg); + void *arg; +} ErrorContextCallback; + +extern PGDLLIMPORT ErrorContextCallback *error_context_stack; + + +/*---------- + * API for catching ereport(ERROR) exits. Use these macros like so: + * + * PG_TRY(); + * { + * ... code that might throw ereport(ERROR) ... + * } + * PG_CATCH(); + * { + * ... error recovery code ... + * } + * PG_END_TRY(); + * + * (The braces are not actually necessary, but are recommended so that + * pgindent will indent the construct nicely.) The error recovery code + * can either do PG_RE_THROW to propagate the error outwards, or do a + * (sub)transaction abort. Failure to do so may leave the system in an + * inconsistent state for further processing. + * + * For the common case that the error recovery code and the cleanup in the + * normal code path are identical, the following can be used instead: + * + * PG_TRY(); + * { + * ... code that might throw ereport(ERROR) ... + * } + * PG_FINALLY(); + * { + * ... cleanup code ... + * } + * PG_END_TRY(); + * + * The cleanup code will be run in either case, and any error will be rethrown + * afterwards. + * + * You cannot use both PG_CATCH() and PG_FINALLY() in the same + * PG_TRY()/PG_END_TRY() block. + * + * Note: while the system will correctly propagate any new ereport(ERROR) + * occurring in the recovery section, there is a small limit on the number + * of levels this will work for. It's best to keep the error recovery + * section simple enough that it can't generate any new errors, at least + * not before popping the error stack. + * + * Note: an ereport(FATAL) will not be caught by this construct; control will + * exit straight through proc_exit(). Therefore, do NOT put any cleanup + * of non-process-local resources into the error recovery section, at least + * not without taking thought for what will happen during ereport(FATAL). + * The PG_ENSURE_ERROR_CLEANUP macros provided by storage/ipc.h may be + * helpful in such cases. + * + * Note: if a local variable of the function containing PG_TRY is modified + * in the PG_TRY section and used in the PG_CATCH section, that variable + * must be declared "volatile" for POSIX compliance. This is not mere + * pedantry; we have seen bugs from compilers improperly optimizing code + * away when such a variable was not marked. Beware that gcc's -Wclobbered + * warnings are just about entirely useless for catching such oversights. + * + * Each of these macros accepts an optional argument which can be specified + * to apply a suffix to the variables declared within the macros. This suffix + * can be used to avoid the compiler emitting warnings about shadowed + * variables when compiling with -Wshadow in situations where nested PG_TRY() + * statements are required. The optional suffix may contain any character + * that's allowed in a variable name. The suffix, if specified, must be the + * same within each component macro of the given PG_TRY() statement. + *---------- + */ +#define PG_TRY(...) \ + do { \ + sigjmp_buf *_save_exception_stack##__VA_ARGS__ = PG_exception_stack; \ + ErrorContextCallback *_save_context_stack##__VA_ARGS__ = error_context_stack; \ + sigjmp_buf _local_sigjmp_buf##__VA_ARGS__; \ + bool _do_rethrow##__VA_ARGS__ = false; \ + if (sigsetjmp(_local_sigjmp_buf##__VA_ARGS__, 0) == 0) \ + { \ + PG_exception_stack = &_local_sigjmp_buf##__VA_ARGS__ + +#define PG_CATCH(...) \ + } \ + else \ + { \ + PG_exception_stack = _save_exception_stack##__VA_ARGS__; \ + error_context_stack = _save_context_stack##__VA_ARGS__ + +#define PG_FINALLY(...) \ + } \ + else \ + _do_rethrow##__VA_ARGS__ = true; \ + { \ + PG_exception_stack = _save_exception_stack##__VA_ARGS__; \ + error_context_stack = _save_context_stack##__VA_ARGS__ + +#define PG_END_TRY(...) \ + } \ + if (_do_rethrow##__VA_ARGS__) \ + PG_RE_THROW(); \ + PG_exception_stack = _save_exception_stack##__VA_ARGS__; \ + error_context_stack = _save_context_stack##__VA_ARGS__; \ + } while (0) + +/* + * Some compilers understand pg_attribute_noreturn(); for other compilers, + * insert pg_unreachable() so that the compiler gets the point. + */ +#ifdef HAVE_PG_ATTRIBUTE_NORETURN +#define PG_RE_THROW() \ + pg_re_throw() +#else +#define PG_RE_THROW() \ + (pg_re_throw(), pg_unreachable()) +#endif + +extern PGDLLIMPORT sigjmp_buf *PG_exception_stack; + + +/* Stuff that error handlers might want to use */ + +/* + * ErrorData holds the data accumulated during any one ereport() cycle. + * Any non-NULL pointers must point to palloc'd data. + * (The const pointers are an exception; we assume they point at non-freeable + * constant strings.) + */ +typedef struct ErrorData +{ + int elevel; /* error level */ + bool output_to_server; /* will report to server log? */ + bool output_to_client; /* will report to client? */ + bool hide_stmt; /* true to prevent STATEMENT: inclusion */ + bool hide_ctx; /* true to prevent CONTEXT: inclusion */ + const char *filename; /* __FILE__ of ereport() call */ + int lineno; /* __LINE__ of ereport() call */ + const char *funcname; /* __func__ of ereport() call */ + const char *domain; /* message domain */ + const char *context_domain; /* message domain for context message */ + int sqlerrcode; /* encoded ERRSTATE */ + char *message; /* primary error message (translated) */ + char *detail; /* detail error message */ + char *detail_log; /* detail error message for server log only */ + char *hint; /* hint message */ + char *context; /* context message */ + char *backtrace; /* backtrace */ + const char *message_id; /* primary message's id (original string) */ + char *schema_name; /* name of schema */ + char *table_name; /* name of table */ + char *column_name; /* name of column */ + char *datatype_name; /* name of datatype */ + char *constraint_name; /* name of constraint */ + int cursorpos; /* cursor index into query string */ + int internalpos; /* cursor index into internalquery */ + char *internalquery; /* text of internally-generated query */ + int saved_errno; /* errno at entry */ + + /* context containing associated non-constant strings */ + struct MemoryContextData *assoc_context; +} ErrorData; + +extern void EmitErrorReport(void); +extern ErrorData *CopyErrorData(void); +extern void FreeErrorData(ErrorData *edata); +extern void FlushErrorState(void); +extern void ReThrowError(ErrorData *edata) pg_attribute_noreturn(); +extern void ThrowErrorData(ErrorData *edata); +extern void pg_re_throw(void) pg_attribute_noreturn(); + +extern char *GetErrorContextStack(void); + +/* Hook for intercepting messages before they are sent to the server log */ +typedef void (*emit_log_hook_type) (ErrorData *edata); +extern PGDLLIMPORT emit_log_hook_type emit_log_hook; + + +/* GUC-configurable parameters */ + +typedef enum +{ + PGERROR_TERSE, /* single-line error messages */ + PGERROR_DEFAULT, /* recommended style */ + PGERROR_VERBOSE /* all the facts, ma'am */ +} PGErrorVerbosity; + +extern PGDLLIMPORT int Log_error_verbosity; +extern PGDLLIMPORT char *Log_line_prefix; +extern PGDLLIMPORT int Log_destination; +extern PGDLLIMPORT char *Log_destination_string; +extern PGDLLIMPORT bool syslog_sequence_numbers; +extern PGDLLIMPORT bool syslog_split_messages; + +/* Log destination bitmap */ +#define LOG_DESTINATION_STDERR 1 +#define LOG_DESTINATION_SYSLOG 2 +#define LOG_DESTINATION_EVENTLOG 4 +#define LOG_DESTINATION_CSVLOG 8 +#define LOG_DESTINATION_JSONLOG 16 + +/* Other exported functions */ +extern void log_status_format(StringInfo buf, const char *format, + ErrorData *edata); +extern void DebugFileOpen(void); +extern char *unpack_sql_state(int sql_state); +extern bool in_error_recursion_trouble(void); + +/* Common functions shared across destinations */ +extern void reset_formatted_start_time(void); +extern char *get_formatted_start_time(void); +extern char *get_formatted_log_time(void); +extern const char *get_backend_type_for_log(void); +extern bool check_log_of_query(ErrorData *edata); +extern const char *error_severity(int elevel); +extern void write_pipe_chunks(char *data, int len, int dest); + +/* Destination-specific functions */ +extern void write_csvlog(ErrorData *edata); +extern void write_jsonlog(ErrorData *edata); + +/* + * Write errors to stderr (or by equal means when stderr is + * not available). Used before ereport/elog can be used + * safely (memory context, GUC load etc) + */ +extern void write_stderr(const char *fmt,...) pg_attribute_printf(1, 2); +extern void vwrite_stderr(const char *fmt, va_list ap) pg_attribute_printf(1, 0); + +/* + * Write a message to STDERR using only async-signal-safe functions. This can + * be used to safely emit a message from a signal handler. + */ +extern void write_stderr_signal_safe(const char *fmt); + +#endif /* ELOG_H */ diff --git a/install/include/postgresql/server/utils/errcodes.h b/install/include/postgresql/server/utils/errcodes.h new file mode 100644 index 00000000000..f6834cad1b3 --- /dev/null +++ b/install/include/postgresql/server/utils/errcodes.h @@ -0,0 +1,481 @@ +/* autogenerated from src/backend/utils/errcodes.txt, do not edit */ +/* there is deliberately not an #ifndef ERRCODES_H here */ + +/* Class 00 - Successful Completion */ +#define ERRCODE_SUCCESSFUL_COMPLETION MAKE_SQLSTATE('0','0','0','0','0') + +/* Class 01 - Warning */ +#define ERRCODE_WARNING MAKE_SQLSTATE('0','1','0','0','0') +#define ERRCODE_WARNING_DYNAMIC_RESULT_SETS_RETURNED MAKE_SQLSTATE('0','1','0','0','C') +#define ERRCODE_WARNING_IMPLICIT_ZERO_BIT_PADDING MAKE_SQLSTATE('0','1','0','0','8') +#define ERRCODE_WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION MAKE_SQLSTATE('0','1','0','0','3') +#define ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED MAKE_SQLSTATE('0','1','0','0','7') +#define ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED MAKE_SQLSTATE('0','1','0','0','6') +#define ERRCODE_WARNING_STRING_DATA_RIGHT_TRUNCATION MAKE_SQLSTATE('0','1','0','0','4') +#define ERRCODE_WARNING_DEPRECATED_FEATURE MAKE_SQLSTATE('0','1','P','0','1') + +/* Class 02 - No Data (this is also a warning class per the SQL standard) */ +#define ERRCODE_NO_DATA MAKE_SQLSTATE('0','2','0','0','0') +#define ERRCODE_NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED MAKE_SQLSTATE('0','2','0','0','1') + +/* Class 03 - SQL Statement Not Yet Complete */ +#define ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE MAKE_SQLSTATE('0','3','0','0','0') + +/* Class 08 - Connection Exception */ +#define ERRCODE_CONNECTION_EXCEPTION MAKE_SQLSTATE('0','8','0','0','0') +#define ERRCODE_CONNECTION_DOES_NOT_EXIST MAKE_SQLSTATE('0','8','0','0','3') +#define ERRCODE_CONNECTION_FAILURE MAKE_SQLSTATE('0','8','0','0','6') +#define ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION MAKE_SQLSTATE('0','8','0','0','1') +#define ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION MAKE_SQLSTATE('0','8','0','0','4') +#define ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN MAKE_SQLSTATE('0','8','0','0','7') +#define ERRCODE_PROTOCOL_VIOLATION MAKE_SQLSTATE('0','8','P','0','1') + +/* Class 08 - Connection Exception (pgrac extension) */ +#define ERRCODE_CLUSTER_NODE_UNREACHABLE MAKE_SQLSTATE('0','8','R','0','1') +#define ERRCODE_CLUSTER_NODE_EVICTED MAKE_SQLSTATE('0','8','R','0','2') +#define ERRCODE_CLUSTER_JOIN_FAILED MAKE_SQLSTATE('0','8','R','0','3') +#define ERRCODE_CLUSTER_INTERCONNECT_LOST MAKE_SQLSTATE('0','8','R','0','4') +#define ERRCODE_CLUSTER_PROTOCOL_VERSION_MISMATCH MAKE_SQLSTATE('0','8','R','0','5') + +/* Class 09 - Triggered Action Exception */ +#define ERRCODE_TRIGGERED_ACTION_EXCEPTION MAKE_SQLSTATE('0','9','0','0','0') + +/* Class 0A - Feature Not Supported */ +#define ERRCODE_FEATURE_NOT_SUPPORTED MAKE_SQLSTATE('0','A','0','0','0') + +/* Class 0B - Invalid Transaction Initiation */ +#define ERRCODE_INVALID_TRANSACTION_INITIATION MAKE_SQLSTATE('0','B','0','0','0') + +/* Class 0F - Locator Exception */ +#define ERRCODE_LOCATOR_EXCEPTION MAKE_SQLSTATE('0','F','0','0','0') +#define ERRCODE_L_E_INVALID_SPECIFICATION MAKE_SQLSTATE('0','F','0','0','1') + +/* Class 0L - Invalid Grantor */ +#define ERRCODE_INVALID_GRANTOR MAKE_SQLSTATE('0','L','0','0','0') +#define ERRCODE_INVALID_GRANT_OPERATION MAKE_SQLSTATE('0','L','P','0','1') + +/* Class 0P - Invalid Role Specification */ +#define ERRCODE_INVALID_ROLE_SPECIFICATION MAKE_SQLSTATE('0','P','0','0','0') + +/* Class 0Z - Diagnostics Exception */ +#define ERRCODE_DIAGNOSTICS_EXCEPTION MAKE_SQLSTATE('0','Z','0','0','0') +#define ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER MAKE_SQLSTATE('0','Z','0','0','2') + +/* Class 20 - Case Not Found */ +#define ERRCODE_CASE_NOT_FOUND MAKE_SQLSTATE('2','0','0','0','0') + +/* Class 21 - Cardinality Violation */ +#define ERRCODE_CARDINALITY_VIOLATION MAKE_SQLSTATE('2','1','0','0','0') + +/* Class 22 - Data Exception */ +#define ERRCODE_DATA_EXCEPTION MAKE_SQLSTATE('2','2','0','0','0') +#define ERRCODE_ARRAY_ELEMENT_ERROR MAKE_SQLSTATE('2','2','0','2','E') +#define ERRCODE_ARRAY_SUBSCRIPT_ERROR MAKE_SQLSTATE('2','2','0','2','E') +#define ERRCODE_CHARACTER_NOT_IN_REPERTOIRE MAKE_SQLSTATE('2','2','0','2','1') +#define ERRCODE_DATETIME_FIELD_OVERFLOW MAKE_SQLSTATE('2','2','0','0','8') +#define ERRCODE_DATETIME_VALUE_OUT_OF_RANGE MAKE_SQLSTATE('2','2','0','0','8') +#define ERRCODE_DIVISION_BY_ZERO MAKE_SQLSTATE('2','2','0','1','2') +#define ERRCODE_ERROR_IN_ASSIGNMENT MAKE_SQLSTATE('2','2','0','0','5') +#define ERRCODE_ESCAPE_CHARACTER_CONFLICT MAKE_SQLSTATE('2','2','0','0','B') +#define ERRCODE_INDICATOR_OVERFLOW MAKE_SQLSTATE('2','2','0','2','2') +#define ERRCODE_INTERVAL_FIELD_OVERFLOW MAKE_SQLSTATE('2','2','0','1','5') +#define ERRCODE_INVALID_ARGUMENT_FOR_LOG MAKE_SQLSTATE('2','2','0','1','E') +#define ERRCODE_INVALID_ARGUMENT_FOR_NTILE MAKE_SQLSTATE('2','2','0','1','4') +#define ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE MAKE_SQLSTATE('2','2','0','1','6') +#define ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION MAKE_SQLSTATE('2','2','0','1','F') +#define ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION MAKE_SQLSTATE('2','2','0','1','G') +#define ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST MAKE_SQLSTATE('2','2','0','1','8') +#define ERRCODE_INVALID_DATETIME_FORMAT MAKE_SQLSTATE('2','2','0','0','7') +#define ERRCODE_INVALID_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','0','1','9') +#define ERRCODE_INVALID_ESCAPE_OCTET MAKE_SQLSTATE('2','2','0','0','D') +#define ERRCODE_INVALID_ESCAPE_SEQUENCE MAKE_SQLSTATE('2','2','0','2','5') +#define ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','P','0','6') +#define ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE MAKE_SQLSTATE('2','2','0','1','0') +#define ERRCODE_INVALID_PARAMETER_VALUE MAKE_SQLSTATE('2','2','0','2','3') +#define ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE MAKE_SQLSTATE('2','2','0','1','3') +#define ERRCODE_INVALID_REGULAR_EXPRESSION MAKE_SQLSTATE('2','2','0','1','B') +#define ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE MAKE_SQLSTATE('2','2','0','1','W') +#define ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE MAKE_SQLSTATE('2','2','0','1','X') +#define ERRCODE_INVALID_TABLESAMPLE_ARGUMENT MAKE_SQLSTATE('2','2','0','2','H') +#define ERRCODE_INVALID_TABLESAMPLE_REPEAT MAKE_SQLSTATE('2','2','0','2','G') +#define ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE MAKE_SQLSTATE('2','2','0','0','9') +#define ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','0','0','C') +#define ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH MAKE_SQLSTATE('2','2','0','0','G') +#define ERRCODE_NULL_VALUE_NOT_ALLOWED MAKE_SQLSTATE('2','2','0','0','4') +#define ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER MAKE_SQLSTATE('2','2','0','0','2') +#define ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE MAKE_SQLSTATE('2','2','0','0','3') +#define ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED MAKE_SQLSTATE('2','2','0','0','H') +#define ERRCODE_STRING_DATA_LENGTH_MISMATCH MAKE_SQLSTATE('2','2','0','2','6') +#define ERRCODE_STRING_DATA_RIGHT_TRUNCATION MAKE_SQLSTATE('2','2','0','0','1') +#define ERRCODE_SUBSTRING_ERROR MAKE_SQLSTATE('2','2','0','1','1') +#define ERRCODE_TRIM_ERROR MAKE_SQLSTATE('2','2','0','2','7') +#define ERRCODE_UNTERMINATED_C_STRING MAKE_SQLSTATE('2','2','0','2','4') +#define ERRCODE_ZERO_LENGTH_CHARACTER_STRING MAKE_SQLSTATE('2','2','0','0','F') +#define ERRCODE_FLOATING_POINT_EXCEPTION MAKE_SQLSTATE('2','2','P','0','1') +#define ERRCODE_INVALID_TEXT_REPRESENTATION MAKE_SQLSTATE('2','2','P','0','2') +#define ERRCODE_INVALID_BINARY_REPRESENTATION MAKE_SQLSTATE('2','2','P','0','3') +#define ERRCODE_BAD_COPY_FILE_FORMAT MAKE_SQLSTATE('2','2','P','0','4') +#define ERRCODE_UNTRANSLATABLE_CHARACTER MAKE_SQLSTATE('2','2','P','0','5') +#define ERRCODE_NOT_AN_XML_DOCUMENT MAKE_SQLSTATE('2','2','0','0','L') +#define ERRCODE_INVALID_XML_DOCUMENT MAKE_SQLSTATE('2','2','0','0','M') +#define ERRCODE_INVALID_XML_CONTENT MAKE_SQLSTATE('2','2','0','0','N') +#define ERRCODE_INVALID_XML_COMMENT MAKE_SQLSTATE('2','2','0','0','S') +#define ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION MAKE_SQLSTATE('2','2','0','0','T') +#define ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE MAKE_SQLSTATE('2','2','0','3','0') +#define ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION MAKE_SQLSTATE('2','2','0','3','1') +#define ERRCODE_INVALID_JSON_TEXT MAKE_SQLSTATE('2','2','0','3','2') +#define ERRCODE_INVALID_SQL_JSON_SUBSCRIPT MAKE_SQLSTATE('2','2','0','3','3') +#define ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','4') +#define ERRCODE_NO_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','5') +#define ERRCODE_NON_NUMERIC_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','6') +#define ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT MAKE_SQLSTATE('2','2','0','3','7') +#define ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED MAKE_SQLSTATE('2','2','0','3','8') +#define ERRCODE_SQL_JSON_ARRAY_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','9') +#define ERRCODE_SQL_JSON_MEMBER_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','A') +#define ERRCODE_SQL_JSON_NUMBER_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','B') +#define ERRCODE_SQL_JSON_OBJECT_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','C') +#define ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS MAKE_SQLSTATE('2','2','0','3','D') +#define ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS MAKE_SQLSTATE('2','2','0','3','E') +#define ERRCODE_SQL_JSON_SCALAR_REQUIRED MAKE_SQLSTATE('2','2','0','3','F') +#define ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE MAKE_SQLSTATE('2','2','0','3','G') + +/* Class 23 - Integrity Constraint Violation */ +#define ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('2','3','0','0','0') +#define ERRCODE_RESTRICT_VIOLATION MAKE_SQLSTATE('2','3','0','0','1') +#define ERRCODE_NOT_NULL_VIOLATION MAKE_SQLSTATE('2','3','5','0','2') +#define ERRCODE_FOREIGN_KEY_VIOLATION MAKE_SQLSTATE('2','3','5','0','3') +#define ERRCODE_UNIQUE_VIOLATION MAKE_SQLSTATE('2','3','5','0','5') +#define ERRCODE_CHECK_VIOLATION MAKE_SQLSTATE('2','3','5','1','4') +#define ERRCODE_EXCLUSION_VIOLATION MAKE_SQLSTATE('2','3','P','0','1') + +/* Class 24 - Invalid Cursor State */ +#define ERRCODE_INVALID_CURSOR_STATE MAKE_SQLSTATE('2','4','0','0','0') + +/* Class 25 - Invalid Transaction State */ +#define ERRCODE_INVALID_TRANSACTION_STATE MAKE_SQLSTATE('2','5','0','0','0') +#define ERRCODE_ACTIVE_SQL_TRANSACTION MAKE_SQLSTATE('2','5','0','0','1') +#define ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE MAKE_SQLSTATE('2','5','0','0','2') +#define ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL MAKE_SQLSTATE('2','5','0','0','8') +#define ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','3') +#define ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','4') +#define ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','5') +#define ERRCODE_READ_ONLY_SQL_TRANSACTION MAKE_SQLSTATE('2','5','0','0','6') +#define ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED MAKE_SQLSTATE('2','5','0','0','7') +#define ERRCODE_NO_ACTIVE_SQL_TRANSACTION MAKE_SQLSTATE('2','5','P','0','1') +#define ERRCODE_IN_FAILED_SQL_TRANSACTION MAKE_SQLSTATE('2','5','P','0','2') +#define ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT MAKE_SQLSTATE('2','5','P','0','3') + +/* Class 26 - Invalid SQL Statement Name */ +#define ERRCODE_INVALID_SQL_STATEMENT_NAME MAKE_SQLSTATE('2','6','0','0','0') + +/* Class 27 - Triggered Data Change Violation */ +#define ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION MAKE_SQLSTATE('2','7','0','0','0') + +/* Class 28 - Invalid Authorization Specification */ +#define ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION MAKE_SQLSTATE('2','8','0','0','0') +#define ERRCODE_INVALID_PASSWORD MAKE_SQLSTATE('2','8','P','0','1') + +/* Class 2B - Dependent Privilege Descriptors Still Exist */ +#define ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST MAKE_SQLSTATE('2','B','0','0','0') +#define ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST MAKE_SQLSTATE('2','B','P','0','1') + +/* Class 2D - Invalid Transaction Termination */ +#define ERRCODE_INVALID_TRANSACTION_TERMINATION MAKE_SQLSTATE('2','D','0','0','0') + +/* Class 2F - SQL Routine Exception */ +#define ERRCODE_SQL_ROUTINE_EXCEPTION MAKE_SQLSTATE('2','F','0','0','0') +#define ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT MAKE_SQLSTATE('2','F','0','0','5') +#define ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('2','F','0','0','2') +#define ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED MAKE_SQLSTATE('2','F','0','0','3') +#define ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('2','F','0','0','4') + +/* Class 34 - Invalid Cursor Name */ +#define ERRCODE_INVALID_CURSOR_NAME MAKE_SQLSTATE('3','4','0','0','0') + +/* Class 38 - External Routine Exception */ +#define ERRCODE_EXTERNAL_ROUTINE_EXCEPTION MAKE_SQLSTATE('3','8','0','0','0') +#define ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','1') +#define ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','2') +#define ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED MAKE_SQLSTATE('3','8','0','0','3') +#define ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','4') + +/* Class 39 - External Routine Invocation Exception */ +#define ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION MAKE_SQLSTATE('3','9','0','0','0') +#define ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED MAKE_SQLSTATE('3','9','0','0','1') +#define ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED MAKE_SQLSTATE('3','9','0','0','4') +#define ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','1') +#define ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','2') +#define ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','3') + +/* Class 3B - Savepoint Exception */ +#define ERRCODE_SAVEPOINT_EXCEPTION MAKE_SQLSTATE('3','B','0','0','0') +#define ERRCODE_S_E_INVALID_SPECIFICATION MAKE_SQLSTATE('3','B','0','0','1') + +/* Class 3D - Invalid Catalog Name */ +#define ERRCODE_INVALID_CATALOG_NAME MAKE_SQLSTATE('3','D','0','0','0') + +/* Class 3F - Invalid Schema Name */ +#define ERRCODE_INVALID_SCHEMA_NAME MAKE_SQLSTATE('3','F','0','0','0') + +/* Class 40 - Transaction Rollback */ +#define ERRCODE_TRANSACTION_ROLLBACK MAKE_SQLSTATE('4','0','0','0','0') +#define ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('4','0','0','0','2') +#define ERRCODE_T_R_SERIALIZATION_FAILURE MAKE_SQLSTATE('4','0','0','0','1') +#define ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN MAKE_SQLSTATE('4','0','0','0','3') +#define ERRCODE_T_R_DEADLOCK_DETECTED MAKE_SQLSTATE('4','0','P','0','1') + +/* Class 40 - Transaction Rollback (pgrac extension) */ +#define ERRCODE_CLUSTER_RECONFIG_ABORT MAKE_SQLSTATE('4','0','R','0','1') +#define ERRCODE_CLUSTER_ISOLATION_FAILED MAKE_SQLSTATE('4','0','R','0','2') +#define ERRCODE_CLUSTER_CACHE_FUSION_RETRY MAKE_SQLSTATE('4','0','R','0','3') +#define ERRCODE_CLUSTER_PI_INVALIDATED_RETRY MAKE_SQLSTATE('4','0','R','0','4') + +/* Class 42 - Syntax Error or Access Rule Violation */ +#define ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION MAKE_SQLSTATE('4','2','0','0','0') +#define ERRCODE_SYNTAX_ERROR MAKE_SQLSTATE('4','2','6','0','1') +#define ERRCODE_INSUFFICIENT_PRIVILEGE MAKE_SQLSTATE('4','2','5','0','1') +#define ERRCODE_CANNOT_COERCE MAKE_SQLSTATE('4','2','8','4','6') +#define ERRCODE_GROUPING_ERROR MAKE_SQLSTATE('4','2','8','0','3') +#define ERRCODE_WINDOWING_ERROR MAKE_SQLSTATE('4','2','P','2','0') +#define ERRCODE_INVALID_RECURSION MAKE_SQLSTATE('4','2','P','1','9') +#define ERRCODE_INVALID_FOREIGN_KEY MAKE_SQLSTATE('4','2','8','3','0') +#define ERRCODE_INVALID_NAME MAKE_SQLSTATE('4','2','6','0','2') +#define ERRCODE_NAME_TOO_LONG MAKE_SQLSTATE('4','2','6','2','2') +#define ERRCODE_RESERVED_NAME MAKE_SQLSTATE('4','2','9','3','9') +#define ERRCODE_DATATYPE_MISMATCH MAKE_SQLSTATE('4','2','8','0','4') +#define ERRCODE_INDETERMINATE_DATATYPE MAKE_SQLSTATE('4','2','P','1','8') +#define ERRCODE_COLLATION_MISMATCH MAKE_SQLSTATE('4','2','P','2','1') +#define ERRCODE_INDETERMINATE_COLLATION MAKE_SQLSTATE('4','2','P','2','2') +#define ERRCODE_WRONG_OBJECT_TYPE MAKE_SQLSTATE('4','2','8','0','9') +#define ERRCODE_GENERATED_ALWAYS MAKE_SQLSTATE('4','2','8','C','9') +#define ERRCODE_UNDEFINED_COLUMN MAKE_SQLSTATE('4','2','7','0','3') +#define ERRCODE_UNDEFINED_CURSOR MAKE_SQLSTATE('3','4','0','0','0') +#define ERRCODE_UNDEFINED_DATABASE MAKE_SQLSTATE('3','D','0','0','0') +#define ERRCODE_UNDEFINED_FUNCTION MAKE_SQLSTATE('4','2','8','8','3') +#define ERRCODE_UNDEFINED_PSTATEMENT MAKE_SQLSTATE('2','6','0','0','0') +#define ERRCODE_UNDEFINED_SCHEMA MAKE_SQLSTATE('3','F','0','0','0') +#define ERRCODE_UNDEFINED_TABLE MAKE_SQLSTATE('4','2','P','0','1') +#define ERRCODE_UNDEFINED_PARAMETER MAKE_SQLSTATE('4','2','P','0','2') +#define ERRCODE_UNDEFINED_OBJECT MAKE_SQLSTATE('4','2','7','0','4') +#define ERRCODE_DUPLICATE_COLUMN MAKE_SQLSTATE('4','2','7','0','1') +#define ERRCODE_DUPLICATE_CURSOR MAKE_SQLSTATE('4','2','P','0','3') +#define ERRCODE_DUPLICATE_DATABASE MAKE_SQLSTATE('4','2','P','0','4') +#define ERRCODE_DUPLICATE_FUNCTION MAKE_SQLSTATE('4','2','7','2','3') +#define ERRCODE_DUPLICATE_PSTATEMENT MAKE_SQLSTATE('4','2','P','0','5') +#define ERRCODE_DUPLICATE_SCHEMA MAKE_SQLSTATE('4','2','P','0','6') +#define ERRCODE_DUPLICATE_TABLE MAKE_SQLSTATE('4','2','P','0','7') +#define ERRCODE_DUPLICATE_ALIAS MAKE_SQLSTATE('4','2','7','1','2') +#define ERRCODE_DUPLICATE_OBJECT MAKE_SQLSTATE('4','2','7','1','0') +#define ERRCODE_AMBIGUOUS_COLUMN MAKE_SQLSTATE('4','2','7','0','2') +#define ERRCODE_AMBIGUOUS_FUNCTION MAKE_SQLSTATE('4','2','7','2','5') +#define ERRCODE_AMBIGUOUS_PARAMETER MAKE_SQLSTATE('4','2','P','0','8') +#define ERRCODE_AMBIGUOUS_ALIAS MAKE_SQLSTATE('4','2','P','0','9') +#define ERRCODE_INVALID_COLUMN_REFERENCE MAKE_SQLSTATE('4','2','P','1','0') +#define ERRCODE_INVALID_COLUMN_DEFINITION MAKE_SQLSTATE('4','2','6','1','1') +#define ERRCODE_INVALID_CURSOR_DEFINITION MAKE_SQLSTATE('4','2','P','1','1') +#define ERRCODE_INVALID_DATABASE_DEFINITION MAKE_SQLSTATE('4','2','P','1','2') +#define ERRCODE_INVALID_FUNCTION_DEFINITION MAKE_SQLSTATE('4','2','P','1','3') +#define ERRCODE_INVALID_PSTATEMENT_DEFINITION MAKE_SQLSTATE('4','2','P','1','4') +#define ERRCODE_INVALID_SCHEMA_DEFINITION MAKE_SQLSTATE('4','2','P','1','5') +#define ERRCODE_INVALID_TABLE_DEFINITION MAKE_SQLSTATE('4','2','P','1','6') +#define ERRCODE_INVALID_OBJECT_DEFINITION MAKE_SQLSTATE('4','2','P','1','7') + +/* Class 44 - WITH CHECK OPTION Violation */ +#define ERRCODE_WITH_CHECK_OPTION_VIOLATION MAKE_SQLSTATE('4','4','0','0','0') + +/* Class 53 - Insufficient Resources */ +#define ERRCODE_INSUFFICIENT_RESOURCES MAKE_SQLSTATE('5','3','0','0','0') +#define ERRCODE_DISK_FULL MAKE_SQLSTATE('5','3','1','0','0') +#define ERRCODE_OUT_OF_MEMORY MAKE_SQLSTATE('5','3','2','0','0') +#define ERRCODE_TOO_MANY_CONNECTIONS MAKE_SQLSTATE('5','3','3','0','0') +#define ERRCODE_CONFIGURATION_LIMIT_EXCEEDED MAKE_SQLSTATE('5','3','4','0','0') + +/* Class 53 - Insufficient Resources (pgrac extension) */ +#define ERRCODE_CLUSTER_LMS_QUEUE_FULL MAKE_SQLSTATE('5','3','R','0','1') +#define ERRCODE_CLUSTER_GRD_FULL MAKE_SQLSTATE('5','3','R','0','2') +#define ERRCODE_CLUSTER_UNDO_EXHAUSTED MAKE_SQLSTATE('5','3','R','0','3') +#define ERRCODE_CLUSTER_PI_CHAIN_FULL MAKE_SQLSTATE('5','3','R','0','4') +#define ERRCODE_CLUSTER_CR_CHAIN_FULL MAKE_SQLSTATE('5','3','R','0','5') +#define ERRCODE_CLUSTER_RECOVERY_WORKERS_EXHAUSTED MAKE_SQLSTATE('5','3','R','0','6') +#define ERRCODE_CLUSTER_RECONFIG_QUORUM_LOST MAKE_SQLSTATE('5','3','R','0','7') +#define ERRCODE_CLUSTER_PHASE_TRANSITION_TIMEOUT MAKE_SQLSTATE('5','3','R','0','8') +#define ERRCODE_CLUSTER_PHASE_PRECONDITION_FAILED MAKE_SQLSTATE('5','3','R','0','9') +#define ERRCODE_CLUSTER_LMON_SPAWN_FAILED MAKE_SQLSTATE('5','3','R','0','A') +#define ERRCODE_CLUSTER_LMON_NOT_READY MAKE_SQLSTATE('5','3','R','0','B') +#define ERRCODE_CLUSTER_LCK_SPAWN_FAILED MAKE_SQLSTATE('5','3','R','0','C') +#define ERRCODE_CLUSTER_LCK_NOT_READY MAKE_SQLSTATE('5','3','R','0','D') +#define ERRCODE_CLUSTER_DIAG_SPAWN_FAILED MAKE_SQLSTATE('5','3','R','0','E') +#define ERRCODE_CLUSTER_DIAG_NOT_READY MAKE_SQLSTATE('5','3','R','0','F') +#define ERRCODE_CLUSTER_STATS_SPAWN_FAILED MAKE_SQLSTATE('5','3','R','1','0') +#define ERRCODE_CLUSTER_STATS_NOT_READY MAKE_SQLSTATE('5','3','R','1','1') +#define ERRCODE_CLUSTER_SCN_WRAPAROUND_PANIC MAKE_SQLSTATE('5','3','R','1','2') +#define ERRCODE_CLUSTER_IC_STALE_EPOCH_DROP MAKE_SQLSTATE('5','3','R','2','0') +#define ERRCODE_CLUSTER_IC_CHUNK_REASSEMBLY_TIMEOUT MAKE_SQLSTATE('5','3','R','2','1') +#define ERRCODE_CLUSTER_CSSD_SPAWN_FAILED MAKE_SQLSTATE('5','3','R','3','0') +#define ERRCODE_CLUSTER_CSSD_NOT_READY MAKE_SQLSTATE('5','3','R','3','1') +#define ERRCODE_CLUSTER_CSSD_PEER_SUSPECTED MAKE_SQLSTATE('5','3','R','3','2') +#define ERRCODE_CLUSTER_CSSD_PEER_DEAD MAKE_SQLSTATE('5','3','R','3','3') +#define ERRCODE_CLUSTER_QUORUM_LOST MAKE_SQLSTATE('5','3','R','4','0') +#define ERRCODE_CLUSTER_QUORUM_UNCERTAIN MAKE_SQLSTATE('5','3','R','4','1') +#define ERRCODE_CLUSTER_VOTING_DISK_IO_FAILURE MAKE_SQLSTATE('5','3','R','4','2') +#define ERRCODE_CLUSTER_NODE_ID_COLLISION MAKE_SQLSTATE('5','3','R','4','3') +#define ERRCODE_CLUSTER_QVOTEC_SPAWN_FAILED MAKE_SQLSTATE('5','3','R','4','4') +#define ERRCODE_CLUSTER_QVOTEC_NOT_READY MAKE_SQLSTATE('5','3','R','4','5') +#define ERRCODE_CLUSTER_QUORUM_LOST_BACKEND MAKE_SQLSTATE('5','3','R','5','0') +#define ERRCODE_CLUSTER_WRITE_FENCED MAKE_SQLSTATE('5','3','R','5','1') +#define ERRCODE_CLUSTER_RECONFIG_IN_PROGRESS MAKE_SQLSTATE('5','3','R','6','0') +#define ERRCODE_CLUSTER_GES_TIMEOUT MAKE_SQLSTATE('5','3','R','7','0') +#define ERRCODE_CLUSTER_GES_PENDING_FULL MAKE_SQLSTATE('5','3','R','7','1') +#define ERRCODE_CLUSTER_GES_DEADLOCK MAKE_SQLSTATE('5','3','R','7','2') +#define ERRCODE_CLUSTER_GES_CANCEL_PENDING MAKE_SQLSTATE('5','3','R','7','3') +#define ERRCODE_CLUSTER_GES_ILLEGAL_LOCK_CONVERSION MAKE_SQLSTATE('5','3','R','7','4') +#define ERRCODE_CLUSTER_LMS_UNAVAILABLE MAKE_SQLSTATE('5','3','R','8','0') +#define ERRCODE_CLUSTER_LMD_UNAVAILABLE MAKE_SQLSTATE('5','3','R','8','1') +#define ERRCODE_CLUSTER_LMD_WAIT_EDGE_FULL MAKE_SQLSTATE('5','3','R','8','2') +#define ERRCODE_CLUSTER_NATIVE_LOCK_PROBE_TIMEOUT MAKE_SQLSTATE('5','3','R','8','3') +#define ERRCODE_CLUSTER_GCS_BLOCK_RETRANSMIT_EXHAUSTED MAKE_SQLSTATE('5','3','R','9','0') +#define ERRCODE_CLUSTER_GCS_BLOCK_INVALIDATE_TIMEOUT MAKE_SQLSTATE('5','3','R','9','1') +#define ERRCODE_CLUSTER_GCS_BLOCK_STARVATION_EXHAUSTED MAKE_SQLSTATE('5','3','R','9','2') +#define ERRCODE_CLUSTER_LOST_WRITE_DETECTED MAKE_SQLSTATE('5','3','R','9','3') +#define ERRCODE_CLUSTER_SINVAL_QUEUE_FULL MAKE_SQLSTATE('5','3','R','9','4') +#define ERRCODE_CLUSTER_SINVAL_ACK_TIMEOUT MAKE_SQLSTATE('5','3','R','9','5') +#define ERRCODE_CLUSTER_TT_OVERLAY_FULL MAKE_SQLSTATE('5','3','R','9','6') +#define ERRCODE_CLUSTER_TT_STATUS_UNKNOWN MAKE_SQLSTATE('5','3','R','9','7') +#define ERRCODE_CLUSTER_REMOTE_ROW_LOCK_WAIT_NOT_SUPPORTED MAKE_SQLSTATE('5','3','R','9','8') +#define ERRCODE_CLUSTER_CROSS_NODE_WRITE_CONFLICT MAKE_SQLSTATE('5','3','R','9','H') +#define ERRCODE_CLUSTER_MULTIXACT_LOCK_NOT_SUPPORTED MAKE_SQLSTATE('5','3','R','9','9') +#define ERRCODE_CLUSTER_ITL_SLOT_OVERFLOW MAKE_SQLSTATE('5','3','R','9','A') +#define ERRCODE_PREPARE_TRANSACTION_WITH_CLUSTER_SUBTRANS_STATE MAKE_SQLSTATE('5','3','R','9','B') +#define ERRCODE_CLUSTER_MULTIXACT_MEMBER_OVERLAY_MISS MAKE_SQLSTATE('5','3','R','9','C') +#define ERRCODE_CLUSTER_UNDO_RECORD_INVALID_UBA MAKE_SQLSTATE('5','3','R','9','D') +#define ERRCODE_CLUSTER_UNDO_SEGMENTS_HARD_CAP_REACHED MAKE_SQLSTATE('5','3','R','9','E') +#define ERRCODE_CLUSTER_CR_SNAPSHOT_TOO_OLD MAKE_SQLSTATE('5','3','R','9','F') +#define ERRCODE_CLUSTER_CR_CROSS_INSTANCE_UNSUPPORTED MAKE_SQLSTATE('5','3','R','9','G') +#define ERRCODE_CLUSTER_GRD_SHARD_REMASTERING MAKE_SQLSTATE('5','3','R','9','I') +#define ERRCODE_CLUSTER_GRD_STALE_MASTER_GENERATION MAKE_SQLSTATE('5','3','R','9','J') +#define ERRCODE_CLUSTER_GCS_BLOCK_PATH_NOT_REBUILT MAKE_SQLSTATE('5','3','R','9','K') +#define ERRCODE_CLUSTER_GCS_BLOCK_RESOURCE_RECOVERING MAKE_SQLSTATE('5','3','R','9','L') +#define ERRCODE_CLUSTER_GCS_BLOCK_BEFORE_REDO_BOUNDARY MAKE_SQLSTATE('5','3','R','9','M') +#define ERRCODE_CLUSTER_UNDO_WRITEBACK_BOUNDARY_VIOLATION MAKE_SQLSTATE('5','3','R','9','N') +#define ERRCODE_CLUSTER_CLEAN_PAGE_XFER_UNAVAILABLE MAKE_SQLSTATE('5','3','R','9','X') +#define ERRCODE_CLUSTER_WAL_THREAD_ROUTING_MISMATCH MAKE_SQLSTATE('5','3','R','A','0') +#define ERRCODE_CLUSTER_WAL_THREAD_CLAIM_CONFLICT MAKE_SQLSTATE('5','3','R','A','1') +#define ERRCODE_CLUSTER_WAL_STATE_IO_FAILURE MAKE_SQLSTATE('5','3','R','A','2') +#define ERRCODE_CLUSTER_MERGED_RECOVERY_BLOCKED MAKE_SQLSTATE('5','3','R','A','3') +#define ERRCODE_CLUSTER_THREAD_RECOVERY_BLOCKED MAKE_SQLSTATE('5','3','R','A','4') +#define ERRCODE_CLUSTER_SEQUENCE_ALLOC_UNAVAILABLE MAKE_SQLSTATE('5','3','R','A','5') + +/* Class 54 - Program Limit Exceeded */ +#define ERRCODE_PROGRAM_LIMIT_EXCEEDED MAKE_SQLSTATE('5','4','0','0','0') +#define ERRCODE_STATEMENT_TOO_COMPLEX MAKE_SQLSTATE('5','4','0','0','1') +#define ERRCODE_TOO_MANY_COLUMNS MAKE_SQLSTATE('5','4','0','1','1') +#define ERRCODE_TOO_MANY_ARGUMENTS MAKE_SQLSTATE('5','4','0','2','3') + +/* Class 55 - Object Not In Prerequisite State */ +#define ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE MAKE_SQLSTATE('5','5','0','0','0') +#define ERRCODE_OBJECT_IN_USE MAKE_SQLSTATE('5','5','0','0','6') +#define ERRCODE_CANT_CHANGE_RUNTIME_PARAM MAKE_SQLSTATE('5','5','P','0','2') +#define ERRCODE_LOCK_NOT_AVAILABLE MAKE_SQLSTATE('5','5','P','0','3') +#define ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE MAKE_SQLSTATE('5','5','P','0','4') + +/* Class 55 - Object Not In Prerequisite State (pgrac extension) */ +#define ERRCODE_CLUSTER_PCM_STATE_INVALID MAKE_SQLSTATE('5','5','R','0','1') +#define ERRCODE_CLUSTER_BUFFER_PIN_CONFLICT MAKE_SQLSTATE('5','5','R','0','2') +#define ERRCODE_CLUSTER_LOCK_STARVATION MAKE_SQLSTATE('5','5','R','0','3') +#define ERRCODE_CLUSTER_BUFFER_INVALIDATED MAKE_SQLSTATE('5','5','R','0','4') +#define ERRCODE_CLUSTER_MASTER_CHANGED MAKE_SQLSTATE('5','5','R','0','5') +#define ERRCODE_CLUSTER_BLOCK_MISSING_TEMPORARY MAKE_SQLSTATE('5','5','R','0','6') + +/* Class 57 - Operator Intervention */ +#define ERRCODE_OPERATOR_INTERVENTION MAKE_SQLSTATE('5','7','0','0','0') +#define ERRCODE_QUERY_CANCELED MAKE_SQLSTATE('5','7','0','1','4') +#define ERRCODE_ADMIN_SHUTDOWN MAKE_SQLSTATE('5','7','P','0','1') +#define ERRCODE_CRASH_SHUTDOWN MAKE_SQLSTATE('5','7','P','0','2') +#define ERRCODE_CANNOT_CONNECT_NOW MAKE_SQLSTATE('5','7','P','0','3') +#define ERRCODE_DATABASE_DROPPED MAKE_SQLSTATE('5','7','P','0','4') +#define ERRCODE_IDLE_SESSION_TIMEOUT MAKE_SQLSTATE('5','7','P','0','5') + +/* Class 57 - Operator Intervention (pgrac extension) */ +#define ERRCODE_CLUSTER_FENCE_TRIGGERED MAKE_SQLSTATE('5','7','R','0','2') +#define ERRCODE_CLUSTER_ADMIN_SHUTDOWN MAKE_SQLSTATE('5','7','R','0','3') +#define ERRCODE_CLUSTER_NODE_DRAIN MAKE_SQLSTATE('5','7','R','0','4') +#define ERRCODE_CLUSTER_QUIESCE_ACTIVE MAKE_SQLSTATE('5','7','R','0','5') +#define ERRCODE_CLUSTER_ADG_APPLY_LAG_EXCESSIVE MAKE_SQLSTATE('5','7','R','0','6') + +/* Class 58 - System Error (errors external to PostgreSQL itself) */ +#define ERRCODE_SYSTEM_ERROR MAKE_SQLSTATE('5','8','0','0','0') +#define ERRCODE_IO_ERROR MAKE_SQLSTATE('5','8','0','3','0') +#define ERRCODE_UNDEFINED_FILE MAKE_SQLSTATE('5','8','P','0','1') +#define ERRCODE_DUPLICATE_FILE MAKE_SQLSTATE('5','8','P','0','2') + +/* Class 58 - System Error (pgrac extension) */ +#define ERRCODE_CLUSTER_SHARED_STORAGE_FAILED MAKE_SQLSTATE('5','8','R','0','1') +#define ERRCODE_CLUSTER_HEARTBEAT_LOST MAKE_SQLSTATE('5','8','R','0','2') +#define ERRCODE_CLUSTER_INTERCONNECT_CORRUPTED MAKE_SQLSTATE('5','8','R','0','3') +#define ERRCODE_CLUSTER_MASTER_UNAVAILABLE MAKE_SQLSTATE('5','8','R','0','4') +#define ERRCODE_CLUSTER_SCN_DRIFT_EXCESSIVE MAKE_SQLSTATE('5','8','R','0','5') +#define ERRCODE_CLUSTER_SCN_UNDERFLOW MAKE_SQLSTATE('5','8','R','0','6') +#define ERRCODE_CLUSTER_GRD_INCONSISTENT MAKE_SQLSTATE('5','8','R','0','7') +#define ERRCODE_CLUSTER_TOPOLOGY_INVALID MAKE_SQLSTATE('5','8','R','0','8') +#define ERRCODE_CLUSTER_TT_INCONSISTENT MAKE_SQLSTATE('5','8','R','0','9') +#define ERRCODE_CLUSTER_CATALOG_INCONSISTENT MAKE_SQLSTATE('5','8','R','1','0') +#define ERRCODE_CLUSTER_SINVAL_INCONSISTENT MAKE_SQLSTATE('5','8','R','1','1') +#define ERRCODE_CLUSTER_RECOVERY_FAILED MAKE_SQLSTATE('5','8','R','1','2') +#define ERRCODE_CLUSTER_CONTROLFILE_AUTHORITY_UNAVAILABLE MAKE_SQLSTATE('5','8','R','1','3') + +/* Class 72 - Snapshot Failure */ +#define ERRCODE_SNAPSHOT_TOO_OLD MAKE_SQLSTATE('7','2','0','0','0') + +/* Class 72 - Snapshot Failure (pgrac extension) */ +#define ERRCODE_CLUSTER_SNAPSHOT_TOO_OLD MAKE_SQLSTATE('7','2','R','0','1') +#define ERRCODE_CLUSTER_SNAPSHOT_UNAVAILABLE MAKE_SQLSTATE('7','2','R','0','2') + +/* Class F0 - Configuration File Error */ +#define ERRCODE_CONFIG_FILE_ERROR MAKE_SQLSTATE('F','0','0','0','0') +#define ERRCODE_LOCK_FILE_EXISTS MAKE_SQLSTATE('F','0','0','0','1') + +/* Class HV - Foreign Data Wrapper Error (SQL/MED) */ +#define ERRCODE_FDW_ERROR MAKE_SQLSTATE('H','V','0','0','0') +#define ERRCODE_FDW_COLUMN_NAME_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','5') +#define ERRCODE_FDW_DYNAMIC_PARAMETER_VALUE_NEEDED MAKE_SQLSTATE('H','V','0','0','2') +#define ERRCODE_FDW_FUNCTION_SEQUENCE_ERROR MAKE_SQLSTATE('H','V','0','1','0') +#define ERRCODE_FDW_INCONSISTENT_DESCRIPTOR_INFORMATION MAKE_SQLSTATE('H','V','0','2','1') +#define ERRCODE_FDW_INVALID_ATTRIBUTE_VALUE MAKE_SQLSTATE('H','V','0','2','4') +#define ERRCODE_FDW_INVALID_COLUMN_NAME MAKE_SQLSTATE('H','V','0','0','7') +#define ERRCODE_FDW_INVALID_COLUMN_NUMBER MAKE_SQLSTATE('H','V','0','0','8') +#define ERRCODE_FDW_INVALID_DATA_TYPE MAKE_SQLSTATE('H','V','0','0','4') +#define ERRCODE_FDW_INVALID_DATA_TYPE_DESCRIPTORS MAKE_SQLSTATE('H','V','0','0','6') +#define ERRCODE_FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER MAKE_SQLSTATE('H','V','0','9','1') +#define ERRCODE_FDW_INVALID_HANDLE MAKE_SQLSTATE('H','V','0','0','B') +#define ERRCODE_FDW_INVALID_OPTION_INDEX MAKE_SQLSTATE('H','V','0','0','C') +#define ERRCODE_FDW_INVALID_OPTION_NAME MAKE_SQLSTATE('H','V','0','0','D') +#define ERRCODE_FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH MAKE_SQLSTATE('H','V','0','9','0') +#define ERRCODE_FDW_INVALID_STRING_FORMAT MAKE_SQLSTATE('H','V','0','0','A') +#define ERRCODE_FDW_INVALID_USE_OF_NULL_POINTER MAKE_SQLSTATE('H','V','0','0','9') +#define ERRCODE_FDW_TOO_MANY_HANDLES MAKE_SQLSTATE('H','V','0','1','4') +#define ERRCODE_FDW_OUT_OF_MEMORY MAKE_SQLSTATE('H','V','0','0','1') +#define ERRCODE_FDW_NO_SCHEMAS MAKE_SQLSTATE('H','V','0','0','P') +#define ERRCODE_FDW_OPTION_NAME_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','J') +#define ERRCODE_FDW_REPLY_HANDLE MAKE_SQLSTATE('H','V','0','0','K') +#define ERRCODE_FDW_SCHEMA_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','Q') +#define ERRCODE_FDW_TABLE_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','R') +#define ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION MAKE_SQLSTATE('H','V','0','0','L') +#define ERRCODE_FDW_UNABLE_TO_CREATE_REPLY MAKE_SQLSTATE('H','V','0','0','M') +#define ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION MAKE_SQLSTATE('H','V','0','0','N') + +/* Class P0 - PL/pgSQL Error */ +#define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0','0','0','0') +#define ERRCODE_RAISE_EXCEPTION MAKE_SQLSTATE('P','0','0','0','1') +#define ERRCODE_NO_DATA_FOUND MAKE_SQLSTATE('P','0','0','0','2') +#define ERRCODE_TOO_MANY_ROWS MAKE_SQLSTATE('P','0','0','0','3') +#define ERRCODE_ASSERT_FAILURE MAKE_SQLSTATE('P','0','0','0','4') + +/* Class XX - Internal Error */ +#define ERRCODE_INTERNAL_ERROR MAKE_SQLSTATE('X','X','0','0','0') +#define ERRCODE_DATA_CORRUPTED MAKE_SQLSTATE('X','X','0','0','1') +#define ERRCODE_INDEX_CORRUPTED MAKE_SQLSTATE('X','X','0','0','2') + +/* Class XX - Internal Error (pgrac extension) */ +#define ERRCODE_CLUSTER_ASSERTION_FAILURE MAKE_SQLSTATE('X','X','R','0','1') +#define ERRCODE_CLUSTER_UNEXPECTED_STATE MAKE_SQLSTATE('X','X','R','0','2') +#define ERRCODE_CLUSTER_RELMAPPER_CONFLICT MAKE_SQLSTATE('X','X','R','0','3') diff --git a/install/include/postgresql/server/utils/evtcache.h b/install/include/postgresql/server/utils/evtcache.h new file mode 100644 index 00000000000..d340026518a --- /dev/null +++ b/install/include/postgresql/server/utils/evtcache.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + * + * evtcache.h + * Special-purpose cache for event trigger data. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/utils/evtcache.h + * + *------------------------------------------------------------------------- + */ +#ifndef EVTCACHE_H +#define EVTCACHE_H + +#include "nodes/bitmapset.h" +#include "nodes/pg_list.h" + +typedef enum +{ + EVT_DDLCommandStart, + EVT_DDLCommandEnd, + EVT_SQLDrop, + EVT_TableRewrite +} EventTriggerEvent; + +typedef struct +{ + Oid fnoid; /* function to be called */ + char enabled; /* as SESSION_REPLICATION_ROLE_* */ + Bitmapset *tagset; /* command tags, or NULL if empty */ +} EventTriggerCacheItem; + +extern List *EventCacheLookup(EventTriggerEvent event); + +#endif /* EVTCACHE_H */ diff --git a/install/include/postgresql/server/utils/expandeddatum.h b/install/include/postgresql/server/utils/expandeddatum.h new file mode 100644 index 00000000000..a77bb7e7e9a --- /dev/null +++ b/install/include/postgresql/server/utils/expandeddatum.h @@ -0,0 +1,170 @@ +/*------------------------------------------------------------------------- + * + * expandeddatum.h + * Declarations for access to "expanded" value representations. + * + * Complex data types, particularly container types such as arrays and + * records, usually have on-disk representations that are compact but not + * especially convenient to modify. What's more, when we do modify them, + * having to recopy all the rest of the value can be extremely inefficient. + * Therefore, we provide a notion of an "expanded" representation that is used + * only in memory and is optimized more for computation than storage. + * The format appearing on disk is called the data type's "flattened" + * representation, since it is required to be a contiguous blob of bytes -- + * but the type can have an expanded representation that is not. Data types + * must provide means to translate an expanded representation back to + * flattened form. + * + * An expanded object is meant to survive across multiple operations, but + * not to be enormously long-lived; for example it might be a local variable + * in a PL/pgSQL procedure. So its extra bulk compared to the on-disk format + * is a worthwhile trade-off. + * + * References to expanded objects are a type of TOAST pointer. + * Because of longstanding conventions in Postgres, this means that the + * flattened form of such an object must always be a varlena object. + * Fortunately that's no restriction in practice. + * + * There are actually two kinds of TOAST pointers for expanded objects: + * read-only and read-write pointers. Possession of one of the latter + * authorizes a function to modify the value in-place rather than copying it + * as would normally be required. Functions should always return a read-write + * pointer to any new expanded object they create. Functions that modify an + * argument value in-place must take care that they do not corrupt the old + * value if they fail partway through. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/expandeddatum.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXPANDEDDATUM_H +#define EXPANDEDDATUM_H + +#include "varatt.h" + +/* Size of an EXTERNAL datum that contains a pointer to an expanded object */ +#define EXPANDED_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_expanded)) + +/* + * "Methods" that must be provided for any expanded object. + * + * get_flat_size: compute space needed for flattened representation (total, + * including header). + * + * flatten_into: construct flattened representation in the caller-allocated + * space at *result, of size allocated_size (which will always be the result + * of a preceding get_flat_size call; it's passed for cross-checking). + * + * The flattened representation must be a valid in-line, non-compressed, + * 4-byte-header varlena object. + * + * Note: construction of a heap tuple from an expanded datum calls + * get_flat_size twice, so it's worthwhile to make sure that that doesn't + * incur too much overhead. + */ +typedef Size (*EOM_get_flat_size_method) (ExpandedObjectHeader *eohptr); +typedef void (*EOM_flatten_into_method) (ExpandedObjectHeader *eohptr, + void *result, Size allocated_size); + +/* Struct of function pointers for an expanded object's methods */ +typedef struct ExpandedObjectMethods +{ + EOM_get_flat_size_method get_flat_size; + EOM_flatten_into_method flatten_into; +} ExpandedObjectMethods; + +/* + * Every expanded object must contain this header; typically the header + * is embedded in some larger struct that adds type-specific fields. + * + * It is presumed that the header object and all subsidiary data are stored + * in eoh_context, so that the object can be freed by deleting that context, + * or its storage lifespan can be altered by reparenting the context. + * (In principle the object could own additional resources, such as malloc'd + * storage, and use a memory context reset callback to free them upon reset or + * deletion of eoh_context.) + * + * We set up two TOAST pointers within the standard header, one read-write + * and one read-only. This allows functions to return either kind of pointer + * without making an additional allocation, and in particular without worrying + * whether a separately palloc'd object would have sufficient lifespan. + * But note that these pointers are just a convenience; a pointer object + * appearing somewhere else would still be legal. + * + * The typedef declaration for this appears in postgres.h. + */ +struct ExpandedObjectHeader +{ + /* Phony varlena header */ + int32 vl_len_; /* always EOH_HEADER_MAGIC, see below */ + + /* Pointer to methods required for object type */ + const ExpandedObjectMethods *eoh_methods; + + /* Memory context containing this header and subsidiary data */ + MemoryContext eoh_context; + + /* Standard R/W TOAST pointer for this object is kept here */ + char eoh_rw_ptr[EXPANDED_POINTER_SIZE]; + + /* Standard R/O TOAST pointer for this object is kept here */ + char eoh_ro_ptr[EXPANDED_POINTER_SIZE]; +}; + +/* + * Particularly for read-only functions, it is handy to be able to work with + * either regular "flat" varlena inputs or expanded inputs of the same data + * type. To allow determining which case an argument-fetching function has + * returned, the first int32 of an ExpandedObjectHeader always contains -1 + * (EOH_HEADER_MAGIC to the code). This works since no 4-byte-header varlena + * could have that as its first 4 bytes. Caution: we could not reliably tell + * the difference between an ExpandedObjectHeader and a short-header object + * with this trick. However, it works fine if the argument fetching code + * always returns either a 4-byte-header flat object or an expanded object. + */ +#define EOH_HEADER_MAGIC (-1) +#define VARATT_IS_EXPANDED_HEADER(PTR) \ + (((varattrib_4b *) (PTR))->va_4byte.va_header == (uint32) EOH_HEADER_MAGIC) + +/* + * Generic support functions for expanded objects. + * (More of these might be worth inlining later.) + */ + +static inline Datum +EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr) +{ + return PointerGetDatum(eohptr->eoh_rw_ptr); +} + +static inline Datum +EOHPGetRODatum(const struct ExpandedObjectHeader *eohptr) +{ + return PointerGetDatum(eohptr->eoh_ro_ptr); +} + +/* Does the Datum represent a writable expanded object? */ +#define DatumIsReadWriteExpandedObject(d, isnull, typlen) \ + (((isnull) || (typlen) != -1) ? false : \ + VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d))) + +#define MakeExpandedObjectReadOnly(d, isnull, typlen) \ + (((isnull) || (typlen) != -1) ? (d) : \ + MakeExpandedObjectReadOnlyInternal(d)) + +extern ExpandedObjectHeader *DatumGetEOHP(Datum d); +extern void EOH_init_header(ExpandedObjectHeader *eohptr, + const ExpandedObjectMethods *methods, + MemoryContext obj_context); +extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr); +extern void EOH_flatten_into(ExpandedObjectHeader *eohptr, + void *result, Size allocated_size); +extern Datum MakeExpandedObjectReadOnlyInternal(Datum d); +extern Datum TransferExpandedObject(Datum d, MemoryContext new_parent); +extern void DeleteExpandedObject(Datum d); + +#endif /* EXPANDEDDATUM_H */ diff --git a/install/include/postgresql/server/utils/expandedrecord.h b/install/include/postgresql/server/utils/expandedrecord.h new file mode 100644 index 00000000000..7e7c114b829 --- /dev/null +++ b/install/include/postgresql/server/utils/expandedrecord.h @@ -0,0 +1,241 @@ +/*------------------------------------------------------------------------- + * + * expandedrecord.h + * Declarations for composite expanded objects. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/expandedrecord.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXPANDEDRECORD_H +#define EXPANDEDRECORD_H + +#include "access/htup.h" +#include "access/tupdesc.h" +#include "fmgr.h" +#include "utils/expandeddatum.h" + + +/* + * An expanded record is contained within a private memory context (as + * all expanded objects must be) and has a control structure as below. + * + * The expanded record might contain a regular "flat" tuple if that was the + * original input and we've not modified it. Otherwise, the contents are + * represented by Datum/isnull arrays plus type information. We could also + * have both forms, if we've deconstructed the original tuple for access + * purposes but not yet changed it. For pass-by-reference field types, the + * Datums would point into the flat tuple in this situation. Once we start + * modifying tuple fields, new pass-by-ref fields are separately palloc'd + * within the memory context. + * + * It's possible to build an expanded record that references a "flat" tuple + * stored externally, if the caller can guarantee that that tuple will not + * change for the lifetime of the expanded record. (This frammish is mainly + * meant to avoid unnecessary data copying in trigger functions.) + */ +#define ER_MAGIC 1384727874 /* ID for debugging crosschecks */ + +typedef struct ExpandedRecordHeader +{ + /* Standard header for expanded objects */ + ExpandedObjectHeader hdr; + + /* Magic value identifying an expanded record (for debugging only) */ + int er_magic; + + /* Assorted flag bits */ + int flags; +#define ER_FLAG_FVALUE_VALID 0x0001 /* fvalue is up to date? */ +#define ER_FLAG_FVALUE_ALLOCED 0x0002 /* fvalue is local storage? */ +#define ER_FLAG_DVALUES_VALID 0x0004 /* dvalues/dnulls are up to date? */ +#define ER_FLAG_DVALUES_ALLOCED 0x0008 /* any field values local storage? */ +#define ER_FLAG_HAVE_EXTERNAL 0x0010 /* any field values are external? */ +#define ER_FLAG_TUPDESC_ALLOCED 0x0020 /* tupdesc is local storage? */ +#define ER_FLAG_IS_DOMAIN 0x0040 /* er_decltypeid is domain? */ +#define ER_FLAG_IS_DUMMY 0x0080 /* this header is dummy (see below) */ +/* flag bits that are not to be cleared when replacing tuple data: */ +#define ER_FLAGS_NON_DATA \ + (ER_FLAG_TUPDESC_ALLOCED | ER_FLAG_IS_DOMAIN | ER_FLAG_IS_DUMMY) + + /* Declared type of the record variable (could be a domain type) */ + Oid er_decltypeid; + + /* + * Actual composite type/typmod; never a domain (if ER_FLAG_IS_DOMAIN, + * these identify the composite base type). These will match + * er_tupdesc->tdtypeid/tdtypmod, as well as the header fields of + * composite datums made from or stored in this expanded record. + */ + Oid er_typeid; /* type OID of the composite type */ + int32 er_typmod; /* typmod of the composite type */ + + /* + * Tuple descriptor, if we have one, else NULL. This may point to a + * reference-counted tupdesc originally belonging to the typcache, in + * which case we use a memory context reset callback to release the + * refcount. It can also be locally allocated in this object's private + * context (in which case ER_FLAG_TUPDESC_ALLOCED is set). + */ + TupleDesc er_tupdesc; + + /* + * Unique-within-process identifier for the tupdesc (see typcache.h). This + * field will never be equal to INVALID_TUPLEDESC_IDENTIFIER. + */ + uint64 er_tupdesc_id; + + /* + * If we have a Datum-array representation of the record, it's kept here; + * else ER_FLAG_DVALUES_VALID is not set, and dvalues/dnulls may be NULL + * if they've not yet been allocated. If allocated, the dvalues and + * dnulls arrays are palloc'd within the object private context, and are + * of length matching er_tupdesc->natts. For pass-by-ref field types, + * dvalues entries might point either into the fstartptr..fendptr area, or + * to separately palloc'd chunks. + */ + Datum *dvalues; /* array of Datums */ + bool *dnulls; /* array of is-null flags for Datums */ + int nfields; /* length of above arrays */ + + /* + * flat_size is the current space requirement for the flat equivalent of + * the expanded record, if known; otherwise it's 0. We store this to make + * consecutive calls of get_flat_size cheap. If flat_size is not 0, the + * component values data_len, hoff, and hasnull must be valid too. + */ + Size flat_size; + + Size data_len; /* data len within flat_size */ + int hoff; /* header offset */ + bool hasnull; /* null bitmap needed? */ + + /* + * fvalue points to the flat representation if we have one, else it is + * NULL. If the flat representation is valid (up to date) then + * ER_FLAG_FVALUE_VALID is set. Even if we've outdated the flat + * representation due to changes of user fields, it can still be used to + * fetch system column values. If we have a flat representation then + * fstartptr/fendptr point to the start and end+1 of its data area; this + * is so that we can tell which Datum pointers point into the flat + * representation rather than being pointers to separately palloc'd data. + */ + HeapTuple fvalue; /* might or might not be private storage */ + char *fstartptr; /* start of its data area */ + char *fendptr; /* end+1 of its data area */ + + /* Some operations on the expanded record need a short-lived context */ + MemoryContext er_short_term_cxt; /* short-term memory context */ + + /* Working state for domain checking, used if ER_FLAG_IS_DOMAIN is set */ + struct ExpandedRecordHeader *er_dummy_header; /* dummy record header */ + void *er_domaininfo; /* cache space for domain_check() */ + + /* Callback info (it's active if er_mcb.arg is not NULL) */ + MemoryContextCallback er_mcb; +} ExpandedRecordHeader; + +/* fmgr functions and macros for expanded record objects */ +static inline Datum +ExpandedRecordGetDatum(const ExpandedRecordHeader *erh) +{ + return EOHPGetRWDatum(&erh->hdr); +} + +static inline Datum +ExpandedRecordGetRODatum(const ExpandedRecordHeader *erh) +{ + return EOHPGetRODatum(&erh->hdr); +} + +#define PG_GETARG_EXPANDED_RECORD(n) DatumGetExpandedRecord(PG_GETARG_DATUM(n)) +#define PG_RETURN_EXPANDED_RECORD(x) PG_RETURN_DATUM(ExpandedRecordGetDatum(x)) + +/* assorted other macros */ +#define ExpandedRecordIsEmpty(erh) \ + (((erh)->flags & (ER_FLAG_DVALUES_VALID | ER_FLAG_FVALUE_VALID)) == 0) +#define ExpandedRecordIsDomain(erh) \ + (((erh)->flags & ER_FLAG_IS_DOMAIN) != 0) + +/* this can substitute for TransferExpandedObject() when we already have erh */ +#define TransferExpandedRecord(erh, cxt) \ + MemoryContextSetParent((erh)->hdr.eoh_context, cxt) + +/* information returned by expanded_record_lookup_field() */ +typedef struct ExpandedRecordFieldInfo +{ + int fnumber; /* field's attr number in record */ + Oid ftypeid; /* field's type/typmod info */ + int32 ftypmod; + Oid fcollation; /* field's collation if any */ +} ExpandedRecordFieldInfo; + +/* + * prototypes for functions defined in expandedrecord.c + */ +extern ExpandedRecordHeader *make_expanded_record_from_typeid(Oid type_id, int32 typmod, + MemoryContext parentcontext); +extern ExpandedRecordHeader *make_expanded_record_from_tupdesc(TupleDesc tupdesc, + MemoryContext parentcontext); +extern ExpandedRecordHeader *make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh, + MemoryContext parentcontext); +extern void expanded_record_set_tuple(ExpandedRecordHeader *erh, + HeapTuple tuple, bool copy, bool expand_external); +extern Datum make_expanded_record_from_datum(Datum recorddatum, + MemoryContext parentcontext); +extern TupleDesc expanded_record_fetch_tupdesc(ExpandedRecordHeader *erh); +extern HeapTuple expanded_record_get_tuple(ExpandedRecordHeader *erh); +extern ExpandedRecordHeader *DatumGetExpandedRecord(Datum d); +extern void deconstruct_expanded_record(ExpandedRecordHeader *erh); +extern bool expanded_record_lookup_field(ExpandedRecordHeader *erh, + const char *fieldname, + ExpandedRecordFieldInfo *finfo); +extern Datum expanded_record_fetch_field(ExpandedRecordHeader *erh, int fnumber, + bool *isnull); +extern void expanded_record_set_field_internal(ExpandedRecordHeader *erh, + int fnumber, + Datum newValue, bool isnull, + bool expand_external, + bool check_constraints); +extern void expanded_record_set_fields(ExpandedRecordHeader *erh, + const Datum *newValues, const bool *isnulls, + bool expand_external); + +/* outside code should never call expanded_record_set_field_internal as such */ +#define expanded_record_set_field(erh, fnumber, newValue, isnull, expand_external) \ + expanded_record_set_field_internal(erh, fnumber, newValue, isnull, expand_external, true) + +/* + * Inline-able fast cases. The expanded_record_fetch_xxx functions above + * handle the general cases. + */ + +/* Get the tupdesc for the expanded record's actual type */ +static inline TupleDesc +expanded_record_get_tupdesc(ExpandedRecordHeader *erh) +{ + if (likely(erh->er_tupdesc != NULL)) + return erh->er_tupdesc; + else + return expanded_record_fetch_tupdesc(erh); +} + +/* Get value of record field */ +static inline Datum +expanded_record_get_field(ExpandedRecordHeader *erh, int fnumber, + bool *isnull) +{ + if ((erh->flags & ER_FLAG_DVALUES_VALID) && + likely(fnumber > 0 && fnumber <= erh->nfields)) + { + *isnull = erh->dnulls[fnumber - 1]; + return erh->dvalues[fnumber - 1]; + } + else + return expanded_record_fetch_field(erh, fnumber, isnull); +} + +#endif /* EXPANDEDRECORD_H */ diff --git a/install/include/postgresql/server/utils/float.h b/install/include/postgresql/server/utils/float.h new file mode 100644 index 00000000000..7529899d63c --- /dev/null +++ b/install/include/postgresql/server/utils/float.h @@ -0,0 +1,357 @@ +/*------------------------------------------------------------------------- + * + * float.h + * Definitions for the built-in floating-point types + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/include/utils/float.h + * + *------------------------------------------------------------------------- + */ +#ifndef FLOAT_H +#define FLOAT_H + +#include + +/* X/Open (XSI) requires to provide M_PI, but core POSIX does not */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* Radians per degree, a.k.a. PI / 180 */ +#define RADIANS_PER_DEGREE 0.0174532925199432957692 + +/* Visual C++ etc lacks NAN, and won't accept 0.0/0.0. */ +#if defined(WIN32) && !defined(NAN) +static const uint32 nan[2] = {0xffffffff, 0x7fffffff}; + +#define NAN (*(const float8 *) nan) +#endif + +extern PGDLLIMPORT int extra_float_digits; + +/* + * Utility functions in float.c + */ +extern void float_overflow_error(void) pg_attribute_noreturn(); +extern void float_underflow_error(void) pg_attribute_noreturn(); +extern void float_zero_divide_error(void) pg_attribute_noreturn(); +extern int is_infinite(float8 val); +extern float8 float8in_internal(char *num, char **endptr_p, + const char *type_name, const char *orig_string, + struct Node *escontext); +extern float4 float4in_internal(char *num, char **endptr_p, + const char *type_name, const char *orig_string, + struct Node *escontext); +extern char *float8out_internal(float8 num); +extern int float4_cmp_internal(float4 a, float4 b); +extern int float8_cmp_internal(float8 a, float8 b); + +/* + * Routines to provide reasonably platform-independent handling of + * infinity and NaN + * + * We assume that isinf() and isnan() are available and work per spec. + * (On some platforms, we have to supply our own; see src/port.) However, + * generating an Infinity or NaN in the first place is less well standardized; + * pre-C99 systems tend not to have C99's INFINITY and NaN macros. We + * centralize our workarounds for this here. + */ + +/* + * The funny placements of the two #pragmas is necessary because of a + * long lived bug in the Microsoft compilers. + * See http://support.microsoft.com/kb/120968/en-us for details + */ +#ifdef _MSC_VER +#pragma warning(disable:4756) +#endif +static inline float4 +get_float4_infinity(void) +{ +#ifdef INFINITY + /* C99 standard way */ + return (float4) INFINITY; +#else +#ifdef _MSC_VER +#pragma warning(default:4756) +#endif + + /* + * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the + * largest normal float8. We assume forcing an overflow will get us a + * true infinity. + */ + return (float4) (HUGE_VAL * HUGE_VAL); +#endif +} + +static inline float8 +get_float8_infinity(void) +{ +#ifdef INFINITY + /* C99 standard way */ + return (float8) INFINITY; +#else + + /* + * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the + * largest normal float8. We assume forcing an overflow will get us a + * true infinity. + */ + return (float8) (HUGE_VAL * HUGE_VAL); +#endif +} + +static inline float4 +get_float4_nan(void) +{ +#ifdef NAN + /* C99 standard way */ + return (float4) NAN; +#else + /* Assume we can get a NAN via zero divide */ + return (float4) (0.0 / 0.0); +#endif +} + +static inline float8 +get_float8_nan(void) +{ + /* (float8) NAN doesn't work on some NetBSD/MIPS releases */ +#if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__)) + /* C99 standard way */ + return (float8) NAN; +#else + /* Assume we can get a NaN via zero divide */ + return (float8) (0.0 / 0.0); +#endif +} + +/* + * Floating-point arithmetic with overflow/underflow reported as errors + * + * There isn't any way to check for underflow of addition/subtraction + * because numbers near the underflow value have already been rounded to + * the point where we can't detect that the two values were originally + * different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 == + * 1.4013e-45. + */ + +static inline float4 +float4_pl(const float4 val1, const float4 val2) +{ + float4 result; + + result = val1 + val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + float_overflow_error(); + + return result; +} + +static inline float8 +float8_pl(const float8 val1, const float8 val2) +{ + float8 result; + + result = val1 + val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + float_overflow_error(); + + return result; +} + +static inline float4 +float4_mi(const float4 val1, const float4 val2) +{ + float4 result; + + result = val1 - val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + float_overflow_error(); + + return result; +} + +static inline float8 +float8_mi(const float8 val1, const float8 val2) +{ + float8 result; + + result = val1 - val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + float_overflow_error(); + + return result; +} + +static inline float4 +float4_mul(const float4 val1, const float4 val2) +{ + float4 result; + + result = val1 * val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + float_overflow_error(); + if (unlikely(result == 0.0f) && val1 != 0.0f && val2 != 0.0f) + float_underflow_error(); + + return result; +} + +static inline float8 +float8_mul(const float8 val1, const float8 val2) +{ + float8 result; + + result = val1 * val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + float_overflow_error(); + if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0) + float_underflow_error(); + + return result; +} + +static inline float4 +float4_div(const float4 val1, const float4 val2) +{ + float4 result; + + if (unlikely(val2 == 0.0f) && !isnan(val1)) + float_zero_divide_error(); + result = val1 / val2; + if (unlikely(isinf(result)) && !isinf(val1)) + float_overflow_error(); + if (unlikely(result == 0.0f) && val1 != 0.0f && !isinf(val2)) + float_underflow_error(); + + return result; +} + +static inline float8 +float8_div(const float8 val1, const float8 val2) +{ + float8 result; + + if (unlikely(val2 == 0.0) && !isnan(val1)) + float_zero_divide_error(); + result = val1 / val2; + if (unlikely(isinf(result)) && !isinf(val1)) + float_overflow_error(); + if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2)) + float_underflow_error(); + + return result; +} + +/* + * Routines for NaN-aware comparisons + * + * We consider all NaNs to be equal and larger than any non-NaN. This is + * somewhat arbitrary; the important thing is to have a consistent sort + * order. + */ + +static inline bool +float4_eq(const float4 val1, const float4 val2) +{ + return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2; +} + +static inline bool +float8_eq(const float8 val1, const float8 val2) +{ + return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2; +} + +static inline bool +float4_ne(const float4 val1, const float4 val2) +{ + return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2; +} + +static inline bool +float8_ne(const float8 val1, const float8 val2) +{ + return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2; +} + +static inline bool +float4_lt(const float4 val1, const float4 val2) +{ + return !isnan(val1) && (isnan(val2) || val1 < val2); +} + +static inline bool +float8_lt(const float8 val1, const float8 val2) +{ + return !isnan(val1) && (isnan(val2) || val1 < val2); +} + +static inline bool +float4_le(const float4 val1, const float4 val2) +{ + return isnan(val2) || (!isnan(val1) && val1 <= val2); +} + +static inline bool +float8_le(const float8 val1, const float8 val2) +{ + return isnan(val2) || (!isnan(val1) && val1 <= val2); +} + +static inline bool +float4_gt(const float4 val1, const float4 val2) +{ + return !isnan(val2) && (isnan(val1) || val1 > val2); +} + +static inline bool +float8_gt(const float8 val1, const float8 val2) +{ + return !isnan(val2) && (isnan(val1) || val1 > val2); +} + +static inline bool +float4_ge(const float4 val1, const float4 val2) +{ + return isnan(val1) || (!isnan(val2) && val1 >= val2); +} + +static inline bool +float8_ge(const float8 val1, const float8 val2) +{ + return isnan(val1) || (!isnan(val2) && val1 >= val2); +} + +static inline float4 +float4_min(const float4 val1, const float4 val2) +{ + return float4_lt(val1, val2) ? val1 : val2; +} + +static inline float8 +float8_min(const float8 val1, const float8 val2) +{ + return float8_lt(val1, val2) ? val1 : val2; +} + +static inline float4 +float4_max(const float4 val1, const float4 val2) +{ + return float4_gt(val1, val2) ? val1 : val2; +} + +static inline float8 +float8_max(const float8 val1, const float8 val2) +{ + return float8_gt(val1, val2) ? val1 : val2; +} + +#endif /* FLOAT_H */ diff --git a/install/include/postgresql/server/utils/fmgroids.h b/install/include/postgresql/server/utils/fmgroids.h new file mode 100644 index 00000000000..0ea05d1bdac --- /dev/null +++ b/install/include/postgresql/server/utils/fmgroids.h @@ -0,0 +1,3367 @@ +/*------------------------------------------------------------------------- + * + * fmgroids.h + * Macros that define the OIDs of built-in functions. + * + * These macros can be used to avoid a catalog lookup when a specific + * fmgr-callable function needs to be referenced. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl + * + *------------------------------------------------------------------------- + */ +#ifndef FMGROIDS_H +#define FMGROIDS_H + +/* + * Constant macros for the OIDs of entries in pg_proc. + * + * 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. + */ +#define F_HEAP_TABLEAM_HANDLER 3 +#define F_BYTEAOUT 31 +#define F_CHAROUT 33 +#define F_NAMEIN 34 +#define F_NAMEOUT 35 +#define F_INT2IN 38 +#define F_INT2OUT 39 +#define F_INT2VECTORIN 40 +#define F_INT2VECTOROUT 41 +#define F_INT4IN 42 +#define F_INT4OUT 43 +#define F_REGPROCIN 44 +#define F_REGPROCOUT 45 +#define F_TEXTIN 46 +#define F_TEXTOUT 47 +#define F_TIDIN 48 +#define F_TIDOUT 49 +#define F_XIDIN 50 +#define F_XIDOUT 51 +#define F_CIDIN 52 +#define F_CIDOUT 53 +#define F_OIDVECTORIN 54 +#define F_OIDVECTOROUT 55 +#define F_BOOLLT 56 +#define F_BOOLGT 57 +#define F_BOOLEQ 60 +#define F_CHAREQ 61 +#define F_NAMEEQ 62 +#define F_INT2EQ 63 +#define F_INT2LT 64 +#define F_INT4EQ 65 +#define F_INT4LT 66 +#define F_TEXTEQ 67 +#define F_XIDEQ 68 +#define F_CIDEQ 69 +#define F_CHARNE 70 +#define F_CHARLE 72 +#define F_CHARGT 73 +#define F_CHARGE 74 +#define F_INT4_CHAR 77 +#define F_CHAR_INT4 78 +#define F_NAMEREGEXEQ 79 +#define F_BOOLNE 84 +#define F_PG_DDL_COMMAND_IN 86 +#define F_PG_DDL_COMMAND_OUT 87 +#define F_PG_DDL_COMMAND_RECV 88 +#define F_VERSION 89 +#define F_PG_DDL_COMMAND_SEND 90 +#define F_EQSEL 101 +#define F_NEQSEL 102 +#define F_SCALARLTSEL 103 +#define F_SCALARGTSEL 104 +#define F_EQJOINSEL 105 +#define F_NEQJOINSEL 106 +#define F_SCALARLTJOINSEL 107 +#define F_SCALARGTJOINSEL 108 +#define F_UNKNOWNIN 109 +#define F_UNKNOWNOUT 110 +#define F_BOX_ABOVE_EQ 115 +#define F_BOX_BELOW_EQ 116 +#define F_POINT_IN 117 +#define F_POINT_OUT 118 +#define F_LSEG_IN 119 +#define F_LSEG_OUT 120 +#define F_PATH_IN 121 +#define F_PATH_OUT 122 +#define F_BOX_IN 123 +#define F_BOX_OUT 124 +#define F_BOX_OVERLAP 125 +#define F_BOX_GE 126 +#define F_BOX_GT 127 +#define F_BOX_EQ 128 +#define F_BOX_LT 129 +#define F_BOX_LE 130 +#define F_POINT_ABOVE 131 +#define F_POINT_LEFT 132 +#define F_POINT_RIGHT 133 +#define F_POINT_BELOW 134 +#define F_POINT_EQ 135 +#define F_ON_PB 136 +#define F_ON_PPATH 137 +#define F_BOX_CENTER 138 +#define F_AREASEL 139 +#define F_AREAJOINSEL 140 +#define F_INT4MUL 141 +#define F_INT4NE 144 +#define F_INT2NE 145 +#define F_INT2GT 146 +#define F_INT4GT 147 +#define F_INT2LE 148 +#define F_INT4LE 149 +#define F_INT4GE 150 +#define F_INT2GE 151 +#define F_INT2MUL 152 +#define F_INT2DIV 153 +#define F_INT4DIV 154 +#define F_INT2MOD 155 +#define F_INT4MOD 156 +#define F_TEXTNE 157 +#define F_INT24EQ 158 +#define F_INT42EQ 159 +#define F_INT24LT 160 +#define F_INT42LT 161 +#define F_INT24GT 162 +#define F_INT42GT 163 +#define F_INT24NE 164 +#define F_INT42NE 165 +#define F_INT24LE 166 +#define F_INT42LE 167 +#define F_INT24GE 168 +#define F_INT42GE 169 +#define F_INT24MUL 170 +#define F_INT42MUL 171 +#define F_INT24DIV 172 +#define F_INT42DIV 173 +#define F_INT2PL 176 +#define F_INT4PL 177 +#define F_INT24PL 178 +#define F_INT42PL 179 +#define F_INT2MI 180 +#define F_INT4MI 181 +#define F_INT24MI 182 +#define F_INT42MI 183 +#define F_OIDEQ 184 +#define F_OIDNE 185 +#define F_BOX_SAME 186 +#define F_BOX_CONTAIN 187 +#define F_BOX_LEFT 188 +#define F_BOX_OVERLEFT 189 +#define F_BOX_OVERRIGHT 190 +#define F_BOX_RIGHT 191 +#define F_BOX_CONTAINED 192 +#define F_BOX_CONTAIN_PT 193 +#define F_PG_NODE_TREE_IN 195 +#define F_PG_NODE_TREE_OUT 196 +#define F_PG_NODE_TREE_RECV 197 +#define F_PG_NODE_TREE_SEND 198 +#define F_FLOAT4IN 200 +#define F_FLOAT4OUT 201 +#define F_FLOAT4MUL 202 +#define F_FLOAT4DIV 203 +#define F_FLOAT4PL 204 +#define F_FLOAT4MI 205 +#define F_FLOAT4UM 206 +#define F_FLOAT4ABS 207 +#define F_FLOAT4_ACCUM 208 +#define F_FLOAT4LARGER 209 +#define F_FLOAT4SMALLER 211 +#define F_INT4UM 212 +#define F_INT2UM 213 +#define F_FLOAT8IN 214 +#define F_FLOAT8OUT 215 +#define F_FLOAT8MUL 216 +#define F_FLOAT8DIV 217 +#define F_FLOAT8PL 218 +#define F_FLOAT8MI 219 +#define F_FLOAT8UM 220 +#define F_FLOAT8ABS 221 +#define F_FLOAT8_ACCUM 222 +#define F_FLOAT8LARGER 223 +#define F_FLOAT8SMALLER 224 +#define F_LSEG_CENTER 225 +#define F_POLY_CENTER 227 +#define F_DROUND 228 +#define F_DTRUNC 229 +#define F_DSQRT 230 +#define F_DCBRT 231 +#define F_DPOW 232 +#define F_DEXP 233 +#define F_DLOG1 234 +#define F_FLOAT8_INT2 235 +#define F_FLOAT4_INT2 236 +#define F_INT2_FLOAT8 237 +#define F_INT2_FLOAT4 238 +#define F_LINE_DISTANCE 239 +#define F_NAMEEQTEXT 240 +#define F_NAMELTTEXT 241 +#define F_NAMELETEXT 242 +#define F_NAMEGETEXT 243 +#define F_NAMEGTTEXT 244 +#define F_NAMENETEXT 245 +#define F_BTNAMETEXTCMP 246 +#define F_TEXTEQNAME 247 +#define F_TEXTLTNAME 248 +#define F_TEXTLENAME 249 +#define F_TEXTGENAME 250 +#define F_TEXTGTNAME 251 +#define F_TEXTNENAME 252 +#define F_BTTEXTNAMECMP 253 +#define F_NAMECONCATOID 266 +#define F_TABLE_AM_HANDLER_IN 267 +#define F_TABLE_AM_HANDLER_OUT 268 +#define F_TIMEOFDAY 274 +#define F_PG_NEXTOID 275 +#define F_FLOAT8_COMBINE 276 +#define F_INTER_SL 277 +#define F_INTER_LB 278 +#define F_FLOAT48MUL 279 +#define F_FLOAT48DIV 280 +#define F_FLOAT48PL 281 +#define F_FLOAT48MI 282 +#define F_FLOAT84MUL 283 +#define F_FLOAT84DIV 284 +#define F_FLOAT84PL 285 +#define F_FLOAT84MI 286 +#define F_FLOAT4EQ 287 +#define F_FLOAT4NE 288 +#define F_FLOAT4LT 289 +#define F_FLOAT4LE 290 +#define F_FLOAT4GT 291 +#define F_FLOAT4GE 292 +#define F_FLOAT8EQ 293 +#define F_FLOAT8NE 294 +#define F_FLOAT8LT 295 +#define F_FLOAT8LE 296 +#define F_FLOAT8GT 297 +#define F_FLOAT8GE 298 +#define F_FLOAT48EQ 299 +#define F_FLOAT48NE 300 +#define F_FLOAT48LT 301 +#define F_FLOAT48LE 302 +#define F_FLOAT48GT 303 +#define F_FLOAT48GE 304 +#define F_FLOAT84EQ 305 +#define F_FLOAT84NE 306 +#define F_FLOAT84LT 307 +#define F_FLOAT84LE 308 +#define F_FLOAT84GT 309 +#define F_FLOAT84GE 310 +#define F_FLOAT8_FLOAT4 311 +#define F_FLOAT4_FLOAT8 312 +#define F_INT4_INT2 313 +#define F_INT2_INT4 314 +#define F_PG_JIT_AVAILABLE 315 +#define F_FLOAT8_INT4 316 +#define F_INT4_FLOAT8 317 +#define F_FLOAT4_INT4 318 +#define F_INT4_FLOAT4 319 +#define F_WIDTH_BUCKET_FLOAT8_FLOAT8_FLOAT8_INT4 320 +#define F_JSON_IN 321 +#define F_JSON_OUT 322 +#define F_JSON_RECV 323 +#define F_JSON_SEND 324 +#define F_INDEX_AM_HANDLER_IN 326 +#define F_INDEX_AM_HANDLER_OUT 327 +#define F_HASHMACADDR8 328 +#define F_HASH_ACLITEM 329 +#define F_BTHANDLER 330 +#define F_HASHHANDLER 331 +#define F_GISTHANDLER 332 +#define F_GINHANDLER 333 +#define F_SPGHANDLER 334 +#define F_BRINHANDLER 335 +#define F_SCALARLESEL 336 +#define F_SCALARGESEL 337 +#define F_AMVALIDATE 338 +#define F_POLY_SAME 339 +#define F_POLY_CONTAIN 340 +#define F_POLY_LEFT 341 +#define F_POLY_OVERLEFT 342 +#define F_POLY_OVERRIGHT 343 +#define F_POLY_RIGHT 344 +#define F_POLY_CONTAINED 345 +#define F_POLY_OVERLAP 346 +#define F_POLY_IN 347 +#define F_POLY_OUT 348 +#define F_BTINT2CMP 350 +#define F_BTINT4CMP 351 +#define F_BTFLOAT4CMP 354 +#define F_BTFLOAT8CMP 355 +#define F_BTOIDCMP 356 +#define F_DIST_BP 357 +#define F_BTCHARCMP 358 +#define F_BTNAMECMP 359 +#define F_BTTEXTCMP 360 +#define F_LSEG_DISTANCE 361 +#define F_LSEG_INTERPT 362 +#define F_DIST_PS 363 +#define F_DIST_PB 364 +#define F_DIST_SB 365 +#define F_CLOSE_PS 366 +#define F_CLOSE_PB 367 +#define F_CLOSE_SB 368 +#define F_ON_PS 369 +#define F_PATH_DISTANCE 370 +#define F_DIST_PPATH 371 +#define F_ON_SB 372 +#define F_INTER_SB 373 +#define F_STRING_TO_ARRAY_TEXT_TEXT_TEXT 376 +#define F_CASH_CMP 377 +#define F_ARRAY_APPEND 378 +#define F_ARRAY_PREPEND 379 +#define F_DIST_SP 380 +#define F_DIST_BS 381 +#define F_BTARRAYCMP 382 +#define F_ARRAY_CAT 383 +#define F_ARRAY_TO_STRING_ANYARRAY_TEXT_TEXT 384 +#define F_SCALARLEJOINSEL 386 +#define F_ARRAY_NE 390 +#define F_ARRAY_LT 391 +#define F_ARRAY_GT 392 +#define F_ARRAY_LE 393 +#define F_STRING_TO_ARRAY_TEXT_TEXT 394 +#define F_ARRAY_TO_STRING_ANYARRAY_TEXT 395 +#define F_ARRAY_GE 396 +#define F_SCALARGEJOINSEL 398 +#define F_HASHMACADDR 399 +#define F_HASHTEXT 400 +#define F_TEXT_BPCHAR 401 +#define F_BTOIDVECTORCMP 404 +#define F_TEXT_NAME 406 +#define F_NAME_TEXT 407 +#define F_BPCHAR_NAME 408 +#define F_NAME_BPCHAR 409 +#define F_DIST_PATHP 421 +#define F_HASHINET 422 +#define F_HASHINT4EXTENDED 425 +#define F_HASH_NUMERIC 432 +#define F_MACADDR_IN 436 +#define F_MACADDR_OUT 437 +#define F_NUM_NULLS 438 +#define F_NUM_NONNULLS 440 +#define F_HASHINT2EXTENDED 441 +#define F_HASHINT8EXTENDED 442 +#define F_HASHFLOAT4EXTENDED 443 +#define F_HASHFLOAT8EXTENDED 444 +#define F_HASHOIDEXTENDED 445 +#define F_HASHCHAREXTENDED 446 +#define F_HASHNAMEEXTENDED 447 +#define F_HASHTEXTEXTENDED 448 +#define F_HASHINT2 449 +#define F_HASHINT4 450 +#define F_HASHFLOAT4 451 +#define F_HASHFLOAT8 452 +#define F_HASHOID 453 +#define F_HASHCHAR 454 +#define F_HASHNAME 455 +#define F_HASHVARLENA 456 +#define F_HASHOIDVECTOR 457 +#define F_TEXT_LARGER 458 +#define F_TEXT_SMALLER 459 +#define F_INT8IN 460 +#define F_INT8OUT 461 +#define F_INT8UM 462 +#define F_INT8PL 463 +#define F_INT8MI 464 +#define F_INT8MUL 465 +#define F_INT8DIV 466 +#define F_INT8EQ 467 +#define F_INT8NE 468 +#define F_INT8LT 469 +#define F_INT8GT 470 +#define F_INT8LE 471 +#define F_INT8GE 472 +#define F_INT84EQ 474 +#define F_INT84NE 475 +#define F_INT84LT 476 +#define F_INT84GT 477 +#define F_INT84LE 478 +#define F_INT84GE 479 +#define F_INT4_INT8 480 +#define F_INT8_INT4 481 +#define F_FLOAT8_INT8 482 +#define F_INT8_FLOAT8 483 +#define F_ARRAY_LARGER 515 +#define F_ARRAY_SMALLER 516 +#define F_ABBREV_INET 598 +#define F_ABBREV_CIDR 599 +#define F_SET_MASKLEN_INET_INT4 605 +#define F_OIDVECTORNE 619 +#define F_HASH_ARRAY 626 +#define F_SET_MASKLEN_CIDR_INT4 635 +#define F_PG_INDEXAM_HAS_PROPERTY 636 +#define F_PG_INDEX_HAS_PROPERTY 637 +#define F_PG_INDEX_COLUMN_HAS_PROPERTY 638 +#define F_FLOAT4_INT8 652 +#define F_INT8_FLOAT4 653 +#define F_NAMELT 655 +#define F_NAMELE 656 +#define F_NAMEGT 657 +#define F_NAMEGE 658 +#define F_NAMENE 659 +#define F_BPCHAR_BPCHAR_INT4_BOOL 668 +#define F_VARCHAR_VARCHAR_INT4_BOOL 669 +#define F_PG_INDEXAM_PROGRESS_PHASENAME 676 +#define F_OIDVECTORLT 677 +#define F_OIDVECTORLE 678 +#define F_OIDVECTOREQ 679 +#define F_OIDVECTORGE 680 +#define F_OIDVECTORGT 681 +#define F_NETWORK 683 +#define F_NETMASK 696 +#define F_MASKLEN 697 +#define F_BROADCAST 698 +#define F_HOST 699 +#define F_DIST_LP 702 +#define F_DIST_LS 704 +#define F_GETPGUSERNAME 710 +#define F_FAMILY 711 +#define F_INT2_INT8 714 +#define F_LO_CREATE 715 +#define F_OIDLT 716 +#define F_OIDLE 717 +#define F_OCTET_LENGTH_BYTEA 720 +#define F_GET_BYTE 721 +#define F_SET_BYTE 722 +#define F_GET_BIT_BYTEA_INT8 723 +#define F_SET_BIT_BYTEA_INT8_INT4 724 +#define F_DIST_PL 725 +#define F_DIST_SL 727 +#define F_DIST_CPOLY 728 +#define F_POLY_DISTANCE 729 +#define F_TEXT_INET 730 +#define F_TEXT_LT 740 +#define F_TEXT_LE 741 +#define F_TEXT_GT 742 +#define F_TEXT_GE 743 +#define F_ARRAY_EQ 744 +#define F_CURRENT_USER 745 +#define F_SESSION_USER 746 +#define F_ARRAY_DIMS 747 +#define F_ARRAY_NDIMS 748 +#define F_OVERLAY_BYTEA_BYTEA_INT4_INT4 749 +#define F_ARRAY_IN 750 +#define F_ARRAY_OUT 751 +#define F_OVERLAY_BYTEA_BYTEA_INT4 752 +#define F_TRUNC_MACADDR 753 +#define F_INT8_INT2 754 +#define F_LO_IMPORT_TEXT 764 +#define F_LO_EXPORT 765 +#define F_INT4INC 766 +#define F_LO_IMPORT_TEXT_OID 767 +#define F_INT4LARGER 768 +#define F_INT4SMALLER 769 +#define F_INT2LARGER 770 +#define F_INT2SMALLER 771 +#define F_HASHVARLENAEXTENDED 772 +#define F_HASHOIDVECTOREXTENDED 776 +#define F_HASH_ACLITEM_EXTENDED 777 +#define F_HASHMACADDREXTENDED 778 +#define F_HASHINETEXTENDED 779 +#define F_HASH_NUMERIC_EXTENDED 780 +#define F_HASHMACADDR8EXTENDED 781 +#define F_HASH_ARRAY_EXTENDED 782 +#define F_DIST_POLYC 785 +#define F_PG_CLIENT_ENCODING 810 +#define F_CURRENT_QUERY 817 +#define F_MACADDR_EQ 830 +#define F_MACADDR_LT 831 +#define F_MACADDR_LE 832 +#define F_MACADDR_GT 833 +#define F_MACADDR_GE 834 +#define F_MACADDR_NE 835 +#define F_MACADDR_CMP 836 +#define F_INT82PL 837 +#define F_INT82MI 838 +#define F_INT82MUL 839 +#define F_INT82DIV 840 +#define F_INT28PL 841 +#define F_BTINT8CMP 842 +#define F_CASH_MUL_FLT4 846 +#define F_CASH_DIV_FLT4 847 +#define F_FLT4_MUL_CASH 848 +#define F_POSITION_TEXT_TEXT 849 +#define F_TEXTLIKE 850 +#define F_TEXTNLIKE 851 +#define F_INT48EQ 852 +#define F_INT48NE 853 +#define F_INT48LT 854 +#define F_INT48GT 855 +#define F_INT48LE 856 +#define F_INT48GE 857 +#define F_NAMELIKE 858 +#define F_NAMENLIKE 859 +#define F_BPCHAR_CHAR 860 +#define F_CURRENT_DATABASE 861 +#define F_INT4_MUL_CASH 862 +#define F_INT2_MUL_CASH 863 +#define F_CASH_MUL_INT4 864 +#define F_CASH_DIV_INT4 865 +#define F_CASH_MUL_INT2 866 +#define F_CASH_DIV_INT2 867 +#define F_STRPOS 868 +#define F_LOWER_TEXT 870 +#define F_UPPER_TEXT 871 +#define F_INITCAP 872 +#define F_LPAD_TEXT_INT4_TEXT 873 +#define F_RPAD_TEXT_INT4_TEXT 874 +#define F_LTRIM_TEXT_TEXT 875 +#define F_RTRIM_TEXT_TEXT 876 +#define F_SUBSTR_TEXT_INT4_INT4 877 +#define F_TRANSLATE 878 +#define F_LPAD_TEXT_INT4 879 +#define F_RPAD_TEXT_INT4 880 +#define F_LTRIM_TEXT 881 +#define F_RTRIM_TEXT 882 +#define F_SUBSTR_TEXT_INT4 883 +#define F_BTRIM_TEXT_TEXT 884 +#define F_BTRIM_TEXT 885 +#define F_CASH_IN 886 +#define F_CASH_OUT 887 +#define F_CASH_EQ 888 +#define F_CASH_NE 889 +#define F_CASH_LT 890 +#define F_CASH_LE 891 +#define F_CASH_GT 892 +#define F_CASH_GE 893 +#define F_CASH_PL 894 +#define F_CASH_MI 895 +#define F_CASH_MUL_FLT8 896 +#define F_CASH_DIV_FLT8 897 +#define F_CASHLARGER 898 +#define F_CASHSMALLER 899 +#define F_INET_IN 910 +#define F_INET_OUT 911 +#define F_FLT8_MUL_CASH 919 +#define F_NETWORK_EQ 920 +#define F_NETWORK_LT 921 +#define F_NETWORK_LE 922 +#define F_NETWORK_GT 923 +#define F_NETWORK_GE 924 +#define F_NETWORK_NE 925 +#define F_NETWORK_CMP 926 +#define F_NETWORK_SUB 927 +#define F_NETWORK_SUBEQ 928 +#define F_NETWORK_SUP 929 +#define F_NETWORK_SUPEQ 930 +#define F_CASH_WORDS 935 +#define F_SUBSTRING_TEXT_INT4_INT4 936 +#define F_SUBSTRING_TEXT_INT4 937 +#define F_GENERATE_SERIES_TIMESTAMP_TIMESTAMP_INTERVAL 938 +#define F_GENERATE_SERIES_TIMESTAMPTZ_TIMESTAMPTZ_INTERVAL 939 +#define F_MOD_INT2_INT2 940 +#define F_MOD_INT4_INT4 941 +#define F_INT28MI 942 +#define F_INT28MUL 943 +#define F_CHAR_TEXT 944 +#define F_INT8MOD 945 +#define F_TEXT_CHAR 946 +#define F_MOD_INT8_INT8 947 +#define F_INT28DIV 948 +#define F_HASHINT8 949 +#define F_LO_OPEN 952 +#define F_LO_CLOSE 953 +#define F_LOREAD 954 +#define F_LOWRITE 955 +#define F_LO_LSEEK 956 +#define F_LO_CREAT 957 +#define F_LO_TELL 958 +#define F_ON_PL 959 +#define F_ON_SL 960 +#define F_CLOSE_PL 961 +#define F_LO_UNLINK 964 +#define F_HASHBPCHAREXTENDED 972 +#define F_PATH_INTER 973 +#define F_AREA_BOX 975 +#define F_WIDTH 976 +#define F_HEIGHT 977 +#define F_BOX_DISTANCE 978 +#define F_AREA_PATH 979 +#define F_BOX_INTERSECT 980 +#define F_DIAGONAL 981 +#define F_PATH_N_LT 982 +#define F_PATH_N_GT 983 +#define F_PATH_N_EQ 984 +#define F_PATH_N_LE 985 +#define F_PATH_N_GE 986 +#define F_PATH_LENGTH 987 +#define F_POINT_NE 988 +#define F_POINT_VERT 989 +#define F_POINT_HORIZ 990 +#define F_POINT_DISTANCE 991 +#define F_SLOPE 992 +#define F_LSEG_POINT_POINT 993 +#define F_LSEG_INTERSECT 994 +#define F_LSEG_PARALLEL 995 +#define F_LSEG_PERP 996 +#define F_LSEG_VERTICAL 997 +#define F_LSEG_HORIZONTAL 998 +#define F_LSEG_EQ 999 +#define F_LO_TRUNCATE 1004 +#define F_TEXTLIKE_SUPPORT 1023 +#define F_TEXTICREGEXEQ_SUPPORT 1024 +#define F_TEXTICLIKE_SUPPORT 1025 +#define F_TIMEZONE_INTERVAL_TIMESTAMPTZ 1026 +#define F_GIST_POINT_COMPRESS 1030 +#define F_ACLITEMIN 1031 +#define F_ACLITEMOUT 1032 +#define F_ACLINSERT 1035 +#define F_ACLREMOVE 1036 +#define F_ACLCONTAINS 1037 +#define F_GETDATABASEENCODING 1039 +#define F_BPCHARIN 1044 +#define F_BPCHAROUT 1045 +#define F_VARCHARIN 1046 +#define F_VARCHAROUT 1047 +#define F_BPCHAREQ 1048 +#define F_BPCHARLT 1049 +#define F_BPCHARLE 1050 +#define F_BPCHARGT 1051 +#define F_BPCHARGE 1052 +#define F_BPCHARNE 1053 +#define F_ACLITEMEQ 1062 +#define F_BPCHAR_LARGER 1063 +#define F_BPCHAR_SMALLER 1064 +#define F_PG_PREPARED_XACT 1065 +#define F_GENERATE_SERIES_INT4_INT4_INT4 1066 +#define F_GENERATE_SERIES_INT4_INT4 1067 +#define F_GENERATE_SERIES_INT8_INT8_INT8 1068 +#define F_GENERATE_SERIES_INT8_INT8 1069 +#define F_BPCHARCMP 1078 +#define F_REGCLASS 1079 +#define F_HASHBPCHAR 1080 +#define F_FORMAT_TYPE 1081 +#define F_DATE_IN 1084 +#define F_DATE_OUT 1085 +#define F_DATE_EQ 1086 +#define F_DATE_LT 1087 +#define F_DATE_LE 1088 +#define F_DATE_GT 1089 +#define F_DATE_GE 1090 +#define F_DATE_NE 1091 +#define F_DATE_CMP 1092 +#define F_TIME_LT 1102 +#define F_TIME_LE 1103 +#define F_TIME_GT 1104 +#define F_TIME_GE 1105 +#define F_TIME_NE 1106 +#define F_TIME_CMP 1107 +#define F_PG_STAT_GET_WAL 1136 +#define F_PG_GET_WAL_REPLAY_PAUSE_STATE 1137 +#define F_DATE_LARGER 1138 +#define F_DATE_SMALLER 1139 +#define F_DATE_MI 1140 +#define F_DATE_PLI 1141 +#define F_DATE_MII 1142 +#define F_TIME_IN 1143 +#define F_TIME_OUT 1144 +#define F_TIME_EQ 1145 +#define F_CIRCLE_ADD_PT 1146 +#define F_CIRCLE_SUB_PT 1147 +#define F_CIRCLE_MUL_PT 1148 +#define F_CIRCLE_DIV_PT 1149 +#define F_TIMESTAMPTZ_IN 1150 +#define F_TIMESTAMPTZ_OUT 1151 +#define F_TIMESTAMPTZ_EQ 1152 +#define F_TIMESTAMPTZ_NE 1153 +#define F_TIMESTAMPTZ_LT 1154 +#define F_TIMESTAMPTZ_LE 1155 +#define F_TIMESTAMPTZ_GE 1156 +#define F_TIMESTAMPTZ_GT 1157 +#define F_TO_TIMESTAMP_FLOAT8 1158 +#define F_TIMEZONE_TEXT_TIMESTAMPTZ 1159 +#define F_INTERVAL_IN 1160 +#define F_INTERVAL_OUT 1161 +#define F_INTERVAL_EQ 1162 +#define F_INTERVAL_NE 1163 +#define F_INTERVAL_LT 1164 +#define F_INTERVAL_LE 1165 +#define F_INTERVAL_GE 1166 +#define F_INTERVAL_GT 1167 +#define F_INTERVAL_UM 1168 +#define F_INTERVAL_PL 1169 +#define F_INTERVAL_MI 1170 +#define F_DATE_PART_TEXT_TIMESTAMPTZ 1171 +#define F_DATE_PART_TEXT_INTERVAL 1172 +#define F_NETWORK_SUBSET_SUPPORT 1173 +#define F_TIMESTAMPTZ_DATE 1174 +#define F_JUSTIFY_HOURS 1175 +#define F_TIMESTAMPTZ_DATE_TIME 1176 +#define F_JSONB_PATH_EXISTS_TZ 1177 +#define F_DATE_TIMESTAMPTZ 1178 +#define F_JSONB_PATH_QUERY_TZ 1179 +#define F_JSONB_PATH_QUERY_ARRAY_TZ 1180 +#define F_AGE_XID 1181 +#define F_TIMESTAMPTZ_MI 1188 +#define F_TIMESTAMPTZ_PL_INTERVAL 1189 +#define F_TIMESTAMPTZ_MI_INTERVAL 1190 +#define F_GENERATE_SUBSCRIPTS_ANYARRAY_INT4_BOOL 1191 +#define F_GENERATE_SUBSCRIPTS_ANYARRAY_INT4 1192 +#define F_ARRAY_FILL_ANYELEMENT__INT4 1193 +#define F_LOG10_FLOAT8 1194 +#define F_TIMESTAMPTZ_SMALLER 1195 +#define F_TIMESTAMPTZ_LARGER 1196 +#define F_INTERVAL_SMALLER 1197 +#define F_INTERVAL_LARGER 1198 +#define F_AGE_TIMESTAMPTZ_TIMESTAMPTZ 1199 +#define F_INTERVAL_INTERVAL_INT4 1200 +#define F_OBJ_DESCRIPTION_OID_NAME 1215 +#define F_COL_DESCRIPTION 1216 +#define F_DATE_TRUNC_TEXT_TIMESTAMPTZ 1217 +#define F_DATE_TRUNC_TEXT_INTERVAL 1218 +#define F_INT8INC 1219 +#define F_INT8ABS 1230 +#define F_INT8LARGER 1236 +#define F_INT8SMALLER 1237 +#define F_TEXTICREGEXEQ 1238 +#define F_TEXTICREGEXNE 1239 +#define F_NAMEICREGEXEQ 1240 +#define F_NAMEICREGEXNE 1241 +#define F_BOOLIN 1242 +#define F_BOOLOUT 1243 +#define F_BYTEAIN 1244 +#define F_CHARIN 1245 +#define F_CHARLT 1246 +#define F_UNIQUE_KEY_RECHECK 1250 +#define F_INT4ABS 1251 +#define F_NAMEREGEXNE 1252 +#define F_INT2ABS 1253 +#define F_TEXTREGEXEQ 1254 +#define F_TEXTREGEXNE 1256 +#define F_TEXTLEN 1257 +#define F_TEXTCAT 1258 +#define F_PG_CHAR_TO_ENCODING 1264 +#define F_TIDNE 1265 +#define F_CIDR_IN 1267 +#define F_PARSE_IDENT 1268 +#define F_PG_COLUMN_SIZE 1269 +#define F_OVERLAPS_TIMETZ_TIMETZ_TIMETZ_TIMETZ 1271 +#define F_DATETIME_PL 1272 +#define F_DATE_PART_TEXT_TIMETZ 1273 +#define F_INT84PL 1274 +#define F_INT84MI 1275 +#define F_INT84MUL 1276 +#define F_INT84DIV 1277 +#define F_INT48PL 1278 +#define F_INT48MI 1279 +#define F_INT48MUL 1280 +#define F_INT48DIV 1281 +#define F_QUOTE_IDENT 1282 +#define F_QUOTE_LITERAL_TEXT 1283 +#define F_DATE_TRUNC_TEXT_TIMESTAMPTZ_TEXT 1284 +#define F_QUOTE_LITERAL_ANYELEMENT 1285 +#define F_ARRAY_FILL_ANYELEMENT__INT4__INT4 1286 +#define F_OID 1287 +#define F_INT8_OID 1288 +#define F_QUOTE_NULLABLE_TEXT 1289 +#define F_QUOTE_NULLABLE_ANYELEMENT 1290 +#define F_SUPPRESS_REDUNDANT_UPDATES_TRIGGER 1291 +#define F_TIDEQ 1292 +#define F_UNNEST_ANYMULTIRANGE 1293 +#define F_CURRTID2 1294 +#define F_JUSTIFY_DAYS 1295 +#define F_TIMEDATE_PL 1296 +#define F_DATETIMETZ_PL 1297 +#define F_TIMETZDATE_PL 1298 +#define F_NOW 1299 +#define F_POSITIONSEL 1300 +#define F_POSITIONJOINSEL 1301 +#define F_CONTSEL 1302 +#define F_CONTJOINSEL 1303 +#define F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ 1304 +#define F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_INTERVAL 1305 +#define F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_INTERVAL 1306 +#define F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_TIMESTAMPTZ 1307 +#define F_OVERLAPS_TIME_TIME_TIME_TIME 1308 +#define F_OVERLAPS_TIME_INTERVAL_TIME_INTERVAL 1309 +#define F_OVERLAPS_TIME_TIME_TIME_INTERVAL 1310 +#define F_OVERLAPS_TIME_INTERVAL_TIME_TIME 1311 +#define F_TIMESTAMP_IN 1312 +#define F_TIMESTAMP_OUT 1313 +#define F_TIMESTAMPTZ_CMP 1314 +#define F_INTERVAL_CMP 1315 +#define F_TIME_TIMESTAMP 1316 +#define F_LENGTH_TEXT 1317 +#define F_LENGTH_BPCHAR 1318 +#define F_XIDEQINT4 1319 +#define F_INTERVAL_DIV 1326 +#define F_DLOG10 1339 +#define F_LOG_FLOAT8 1340 +#define F_LN_FLOAT8 1341 +#define F_ROUND_FLOAT8 1342 +#define F_TRUNC_FLOAT8 1343 +#define F_SQRT_FLOAT8 1344 +#define F_CBRT 1345 +#define F_POW_FLOAT8_FLOAT8 1346 +#define F_EXP_FLOAT8 1347 +#define F_OBJ_DESCRIPTION_OID 1348 +#define F_OIDVECTORTYPES 1349 +#define F_TIMETZ_IN 1350 +#define F_TIMETZ_OUT 1351 +#define F_TIMETZ_EQ 1352 +#define F_TIMETZ_NE 1353 +#define F_TIMETZ_LT 1354 +#define F_TIMETZ_LE 1355 +#define F_TIMETZ_GE 1356 +#define F_TIMETZ_GT 1357 +#define F_TIMETZ_CMP 1358 +#define F_TIMESTAMPTZ_DATE_TIMETZ 1359 +#define F_HOSTMASK 1362 +#define F_TEXTREGEXEQ_SUPPORT 1364 +#define F_MAKEACLITEM 1365 +#define F_CHARACTER_LENGTH_BPCHAR 1367 +#define F_POWER_FLOAT8_FLOAT8 1368 +#define F_CHARACTER_LENGTH_TEXT 1369 +#define F_INTERVAL_TIME 1370 +#define F_PG_LOCK_STATUS 1371 +#define F_CHAR_LENGTH_BPCHAR 1372 +#define F_ISFINITE_DATE 1373 +#define F_OCTET_LENGTH_TEXT 1374 +#define F_OCTET_LENGTH_BPCHAR 1375 +#define F_FACTORIAL 1376 +#define F_TIME_LARGER 1377 +#define F_TIME_SMALLER 1378 +#define F_TIMETZ_LARGER 1379 +#define F_TIMETZ_SMALLER 1380 +#define F_CHAR_LENGTH_TEXT 1381 +#define F_DATE_PART_TEXT_DATE 1384 +#define F_DATE_PART_TEXT_TIME 1385 +#define F_AGE_TIMESTAMPTZ 1386 +#define F_PG_GET_CONSTRAINTDEF_OID 1387 +#define F_TIMETZ_TIMESTAMPTZ 1388 +#define F_ISFINITE_TIMESTAMPTZ 1389 +#define F_ISFINITE_INTERVAL 1390 +#define F_PG_STAT_GET_BACKEND_START 1391 +#define F_PG_STAT_GET_BACKEND_CLIENT_ADDR 1392 +#define F_PG_STAT_GET_BACKEND_CLIENT_PORT 1393 +#define F_ABS_FLOAT4 1394 +#define F_ABS_FLOAT8 1395 +#define F_ABS_INT8 1396 +#define F_ABS_INT4 1397 +#define F_ABS_INT2 1398 +#define F_NAME_VARCHAR 1400 +#define F_VARCHAR_NAME 1401 +#define F_CURRENT_SCHEMA 1402 +#define F_CURRENT_SCHEMAS 1403 +#define F_OVERLAY_TEXT_TEXT_INT4_INT4 1404 +#define F_OVERLAY_TEXT_TEXT_INT4 1405 +#define F_ISVERTICAL_POINT_POINT 1406 +#define F_ISHORIZONTAL_POINT_POINT 1407 +#define F_ISPARALLEL_LSEG_LSEG 1408 +#define F_ISPERP_LSEG_LSEG 1409 +#define F_ISVERTICAL_LSEG 1410 +#define F_ISHORIZONTAL_LSEG 1411 +#define F_ISPARALLEL_LINE_LINE 1412 +#define F_ISPERP_LINE_LINE 1413 +#define F_ISVERTICAL_LINE 1414 +#define F_ISHORIZONTAL_LINE 1415 +#define F_POINT_CIRCLE 1416 +#define F_TIME_INTERVAL 1419 +#define F_BOX_POINT_POINT 1421 +#define F_BOX_ADD 1422 +#define F_BOX_SUB 1423 +#define F_BOX_MUL 1424 +#define F_BOX_DIV 1425 +#define F_PATH_CONTAIN_PT 1426 +#define F_CIDR_OUT 1427 +#define F_POLY_CONTAIN_PT 1428 +#define F_PT_CONTAINED_POLY 1429 +#define F_ISCLOSED 1430 +#define F_ISOPEN 1431 +#define F_PATH_NPOINTS 1432 +#define F_PCLOSE 1433 +#define F_POPEN 1434 +#define F_PATH_ADD 1435 +#define F_PATH_ADD_PT 1436 +#define F_PATH_SUB_PT 1437 +#define F_PATH_MUL_PT 1438 +#define F_PATH_DIV_PT 1439 +#define F_POINT_FLOAT8_FLOAT8 1440 +#define F_POINT_ADD 1441 +#define F_POINT_SUB 1442 +#define F_POINT_MUL 1443 +#define F_POINT_DIV 1444 +#define F_POLY_NPOINTS 1445 +#define F_BOX_POLYGON 1446 +#define F_PATH 1447 +#define F_POLYGON_BOX 1448 +#define F_POLYGON_PATH 1449 +#define F_CIRCLE_IN 1450 +#define F_CIRCLE_OUT 1451 +#define F_CIRCLE_SAME 1452 +#define F_CIRCLE_CONTAIN 1453 +#define F_CIRCLE_LEFT 1454 +#define F_CIRCLE_OVERLEFT 1455 +#define F_CIRCLE_OVERRIGHT 1456 +#define F_CIRCLE_RIGHT 1457 +#define F_CIRCLE_CONTAINED 1458 +#define F_CIRCLE_OVERLAP 1459 +#define F_CIRCLE_BELOW 1460 +#define F_CIRCLE_ABOVE 1461 +#define F_CIRCLE_EQ 1462 +#define F_CIRCLE_NE 1463 +#define F_CIRCLE_LT 1464 +#define F_CIRCLE_GT 1465 +#define F_CIRCLE_LE 1466 +#define F_CIRCLE_GE 1467 +#define F_AREA_CIRCLE 1468 +#define F_DIAMETER 1469 +#define F_RADIUS 1470 +#define F_CIRCLE_DISTANCE 1471 +#define F_CIRCLE_CENTER 1472 +#define F_CIRCLE_POINT_FLOAT8 1473 +#define F_CIRCLE_POLYGON 1474 +#define F_POLYGON_INT4_CIRCLE 1475 +#define F_DIST_PC 1476 +#define F_CIRCLE_CONTAIN_PT 1477 +#define F_PT_CONTAINED_CIRCLE 1478 +#define F_CIRCLE_BOX 1479 +#define F_BOX_CIRCLE 1480 +#define F_LOG10_NUMERIC 1481 +#define F_LSEG_NE 1482 +#define F_LSEG_LT 1483 +#define F_LSEG_LE 1484 +#define F_LSEG_GT 1485 +#define F_LSEG_GE 1486 +#define F_LSEG_LENGTH 1487 +#define F_CLOSE_LS 1488 +#define F_CLOSE_LSEG 1489 +#define F_LINE_IN 1490 +#define F_LINE_OUT 1491 +#define F_LINE_EQ 1492 +#define F_LINE 1493 +#define F_LINE_INTERPT 1494 +#define F_LINE_INTERSECT 1495 +#define F_LINE_PARALLEL 1496 +#define F_LINE_PERP 1497 +#define F_LINE_VERTICAL 1498 +#define F_LINE_HORIZONTAL 1499 +#define F_LENGTH_LSEG 1530 +#define F_LENGTH_PATH 1531 +#define F_POINT_LSEG 1532 +#define F_POINT_BOX 1534 +#define F_POINT_POLYGON 1540 +#define F_LSEG_BOX 1541 +#define F_CENTER_BOX 1542 +#define F_CENTER_CIRCLE 1543 +#define F_POLYGON_CIRCLE 1544 +#define F_NPOINTS_PATH 1545 +#define F_NPOINTS_POLYGON 1556 +#define F_BIT_IN 1564 +#define F_BIT_OUT 1565 +#define F_LIKE_TEXT_TEXT 1569 +#define F_NOTLIKE_TEXT_TEXT 1570 +#define F_LIKE_NAME_TEXT 1571 +#define F_NOTLIKE_NAME_TEXT 1572 +#define F_PG_GET_RULEDEF_OID 1573 +#define F_NEXTVAL 1574 +#define F_CURRVAL 1575 +#define F_SETVAL_REGCLASS_INT8 1576 +#define F_VARBIT_IN 1579 +#define F_VARBIT_OUT 1580 +#define F_BITEQ 1581 +#define F_BITNE 1582 +#define F_BITGE 1592 +#define F_BITGT 1593 +#define F_BITLE 1594 +#define F_BITLT 1595 +#define F_BITCMP 1596 +#define F_PG_ENCODING_TO_CHAR 1597 +#define F_RANDOM 1598 +#define F_SETSEED 1599 +#define F_ASIN 1600 +#define F_ACOS 1601 +#define F_ATAN 1602 +#define F_ATAN2 1603 +#define F_SIN 1604 +#define F_COS 1605 +#define F_TAN 1606 +#define F_COT 1607 +#define F_DEGREES 1608 +#define F_RADIANS 1609 +#define F_PI 1610 +#define F_INTERVAL_MUL 1618 +#define F_PG_TYPEOF 1619 +#define F_ASCII 1620 +#define F_CHR 1621 +#define F_REPEAT 1622 +#define F_SIMILAR_ESCAPE 1623 +#define F_MUL_D_INTERVAL 1624 +#define F_BPCHARLIKE 1631 +#define F_BPCHARNLIKE 1632 +#define F_TEXTICLIKE 1633 +#define F_TEXTICNLIKE 1634 +#define F_NAMEICLIKE 1635 +#define F_NAMEICNLIKE 1636 +#define F_LIKE_ESCAPE_TEXT_TEXT 1637 +#define F_OIDGT 1638 +#define F_OIDGE 1639 +#define F_PG_GET_VIEWDEF_TEXT 1640 +#define F_PG_GET_VIEWDEF_OID 1641 +#define F_PG_GET_USERBYID 1642 +#define F_PG_GET_INDEXDEF_OID 1643 +#define F_RI_FKEY_CHECK_INS 1644 +#define F_RI_FKEY_CHECK_UPD 1645 +#define F_RI_FKEY_CASCADE_DEL 1646 +#define F_RI_FKEY_CASCADE_UPD 1647 +#define F_RI_FKEY_RESTRICT_DEL 1648 +#define F_RI_FKEY_RESTRICT_UPD 1649 +#define F_RI_FKEY_SETNULL_DEL 1650 +#define F_RI_FKEY_SETNULL_UPD 1651 +#define F_RI_FKEY_SETDEFAULT_DEL 1652 +#define F_RI_FKEY_SETDEFAULT_UPD 1653 +#define F_RI_FKEY_NOACTION_DEL 1654 +#define F_RI_FKEY_NOACTION_UPD 1655 +#define F_BPCHARICREGEXEQ 1656 +#define F_BPCHARICREGEXNE 1657 +#define F_BPCHARREGEXEQ 1658 +#define F_BPCHARREGEXNE 1659 +#define F_BPCHARICLIKE 1660 +#define F_BPCHARICNLIKE 1661 +#define F_PG_GET_TRIGGERDEF_OID 1662 +#define F_PG_GET_SERIAL_SEQUENCE 1665 +#define F_VARBITEQ 1666 +#define F_VARBITNE 1667 +#define F_VARBITGE 1668 +#define F_VARBITGT 1669 +#define F_VARBITLE 1670 +#define F_VARBITLT 1671 +#define F_VARBITCMP 1672 +#define F_BITAND 1673 +#define F_BITOR 1674 +#define F_BITXOR 1675 +#define F_BITNOT 1676 +#define F_BITSHIFTLEFT 1677 +#define F_BITSHIFTRIGHT 1678 +#define F_BITCAT 1679 +#define F_SUBSTRING_BIT_INT4_INT4 1680 +#define F_LENGTH_BIT 1681 +#define F_OCTET_LENGTH_BIT 1682 +#define F_BIT_INT4_INT4 1683 +#define F_INT4_BIT 1684 +#define F_BIT_BIT_INT4_BOOL 1685 +#define F_PG_GET_KEYWORDS 1686 +#define F_VARBIT 1687 +#define F_TIME_HASH 1688 +#define F_ACLEXPLODE 1689 +#define F_TIME_MI_TIME 1690 +#define F_BOOLLE 1691 +#define F_BOOLGE 1692 +#define F_BTBOOLCMP 1693 +#define F_TIMETZ_HASH 1696 +#define F_INTERVAL_HASH 1697 +#define F_POSITION_BIT_BIT 1698 +#define F_SUBSTRING_BIT_INT4 1699 +#define F_NUMERIC_IN 1701 +#define F_NUMERIC_OUT 1702 +#define F_NUMERIC_NUMERIC_INT4 1703 +#define F_NUMERIC_ABS 1704 +#define F_ABS_NUMERIC 1705 +#define F_SIGN_NUMERIC 1706 +#define F_ROUND_NUMERIC_INT4 1707 +#define F_ROUND_NUMERIC 1708 +#define F_TRUNC_NUMERIC_INT4 1709 +#define F_TRUNC_NUMERIC 1710 +#define F_CEIL_NUMERIC 1711 +#define F_FLOOR_NUMERIC 1712 +#define F_LENGTH_BYTEA_NAME 1713 +#define F_CONVERT_FROM 1714 +#define F_CIDR 1715 +#define F_PG_GET_EXPR_PG_NODE_TREE_OID 1716 +#define F_CONVERT_TO 1717 +#define F_NUMERIC_EQ 1718 +#define F_NUMERIC_NE 1719 +#define F_NUMERIC_GT 1720 +#define F_NUMERIC_GE 1721 +#define F_NUMERIC_LT 1722 +#define F_NUMERIC_LE 1723 +#define F_NUMERIC_ADD 1724 +#define F_NUMERIC_SUB 1725 +#define F_NUMERIC_MUL 1726 +#define F_NUMERIC_DIV 1727 +#define F_MOD_NUMERIC_NUMERIC 1728 +#define F_NUMERIC_MOD 1729 +#define F_SQRT_NUMERIC 1730 +#define F_NUMERIC_SQRT 1731 +#define F_EXP_NUMERIC 1732 +#define F_NUMERIC_EXP 1733 +#define F_LN_NUMERIC 1734 +#define F_NUMERIC_LN 1735 +#define F_LOG_NUMERIC_NUMERIC 1736 +#define F_NUMERIC_LOG 1737 +#define F_POW_NUMERIC_NUMERIC 1738 +#define F_NUMERIC_POWER 1739 +#define F_NUMERIC_INT4 1740 +#define F_LOG_NUMERIC 1741 +#define F_NUMERIC_FLOAT4 1742 +#define F_NUMERIC_FLOAT8 1743 +#define F_INT4_NUMERIC 1744 +#define F_FLOAT4_NUMERIC 1745 +#define F_FLOAT8_NUMERIC 1746 +#define F_TIME_PL_INTERVAL 1747 +#define F_TIME_MI_INTERVAL 1748 +#define F_TIMETZ_PL_INTERVAL 1749 +#define F_TIMETZ_MI_INTERVAL 1750 +#define F_NUMERIC_INC 1764 +#define F_SETVAL_REGCLASS_INT8_BOOL 1765 +#define F_NUMERIC_SMALLER 1766 +#define F_NUMERIC_LARGER 1767 +#define F_TO_CHAR_INTERVAL_TEXT 1768 +#define F_NUMERIC_CMP 1769 +#define F_TO_CHAR_TIMESTAMPTZ_TEXT 1770 +#define F_NUMERIC_UMINUS 1771 +#define F_TO_CHAR_NUMERIC_TEXT 1772 +#define F_TO_CHAR_INT4_TEXT 1773 +#define F_TO_CHAR_INT8_TEXT 1774 +#define F_TO_CHAR_FLOAT4_TEXT 1775 +#define F_TO_CHAR_FLOAT8_TEXT 1776 +#define F_TO_NUMBER 1777 +#define F_TO_TIMESTAMP_TEXT_TEXT 1778 +#define F_INT8_NUMERIC 1779 +#define F_TO_DATE 1780 +#define F_NUMERIC_INT8 1781 +#define F_NUMERIC_INT2 1782 +#define F_INT2_NUMERIC 1783 +#define F_OIDIN 1798 +#define F_OIDOUT 1799 +#define F_BIT_LENGTH_BYTEA 1810 +#define F_BIT_LENGTH_TEXT 1811 +#define F_BIT_LENGTH_BIT 1812 +#define F_CONVERT 1813 +#define F_ICLIKESEL 1814 +#define F_ICNLIKESEL 1815 +#define F_ICLIKEJOINSEL 1816 +#define F_ICNLIKEJOINSEL 1817 +#define F_REGEXEQSEL 1818 +#define F_LIKESEL 1819 +#define F_ICREGEXEQSEL 1820 +#define F_REGEXNESEL 1821 +#define F_NLIKESEL 1822 +#define F_ICREGEXNESEL 1823 +#define F_REGEXEQJOINSEL 1824 +#define F_LIKEJOINSEL 1825 +#define F_ICREGEXEQJOINSEL 1826 +#define F_REGEXNEJOINSEL 1827 +#define F_NLIKEJOINSEL 1828 +#define F_ICREGEXNEJOINSEL 1829 +#define F_FLOAT8_AVG 1830 +#define F_FLOAT8_VAR_SAMP 1831 +#define F_FLOAT8_STDDEV_SAMP 1832 +#define F_NUMERIC_ACCUM 1833 +#define F_INT2_ACCUM 1834 +#define F_INT4_ACCUM 1835 +#define F_INT8_ACCUM 1836 +#define F_NUMERIC_AVG 1837 +#define F_NUMERIC_VAR_SAMP 1838 +#define F_NUMERIC_STDDEV_SAMP 1839 +#define F_INT2_SUM 1840 +#define F_INT4_SUM 1841 +#define F_INT8_SUM 1842 +#define F_INTERVAL_ACCUM 1843 +#define F_INTERVAL_AVG 1844 +#define F_TO_ASCII_TEXT 1845 +#define F_TO_ASCII_TEXT_INT4 1846 +#define F_TO_ASCII_TEXT_NAME 1847 +#define F_INTERVAL_PL_TIME 1848 +#define F_INT28EQ 1850 +#define F_INT28NE 1851 +#define F_INT28LT 1852 +#define F_INT28GT 1853 +#define F_INT28LE 1854 +#define F_INT28GE 1855 +#define F_INT82EQ 1856 +#define F_INT82NE 1857 +#define F_INT82LT 1858 +#define F_INT82GT 1859 +#define F_INT82LE 1860 +#define F_INT82GE 1861 +#define F_INT2AND 1892 +#define F_INT2OR 1893 +#define F_INT2XOR 1894 +#define F_INT2NOT 1895 +#define F_INT2SHL 1896 +#define F_INT2SHR 1897 +#define F_INT4AND 1898 +#define F_INT4OR 1899 +#define F_INT4XOR 1900 +#define F_INT4NOT 1901 +#define F_INT4SHL 1902 +#define F_INT4SHR 1903 +#define F_INT8AND 1904 +#define F_INT8OR 1905 +#define F_INT8XOR 1906 +#define F_INT8NOT 1907 +#define F_INT8SHL 1908 +#define F_INT8SHR 1909 +#define F_INT8UP 1910 +#define F_INT2UP 1911 +#define F_INT4UP 1912 +#define F_FLOAT4UP 1913 +#define F_FLOAT8UP 1914 +#define F_NUMERIC_UPLUS 1915 +#define F_HAS_TABLE_PRIVILEGE_NAME_TEXT_TEXT 1922 +#define F_HAS_TABLE_PRIVILEGE_NAME_OID_TEXT 1923 +#define F_HAS_TABLE_PRIVILEGE_OID_TEXT_TEXT 1924 +#define F_HAS_TABLE_PRIVILEGE_OID_OID_TEXT 1925 +#define F_HAS_TABLE_PRIVILEGE_TEXT_TEXT 1926 +#define F_HAS_TABLE_PRIVILEGE_OID_TEXT 1927 +#define F_PG_STAT_GET_NUMSCANS 1928 +#define F_PG_STAT_GET_TUPLES_RETURNED 1929 +#define F_PG_STAT_GET_TUPLES_FETCHED 1930 +#define F_PG_STAT_GET_TUPLES_INSERTED 1931 +#define F_PG_STAT_GET_TUPLES_UPDATED 1932 +#define F_PG_STAT_GET_TUPLES_DELETED 1933 +#define F_PG_STAT_GET_BLOCKS_FETCHED 1934 +#define F_PG_STAT_GET_BLOCKS_HIT 1935 +#define F_PG_STAT_GET_BACKEND_IDSET 1936 +#define F_PG_STAT_GET_BACKEND_PID 1937 +#define F_PG_STAT_GET_BACKEND_DBID 1938 +#define F_PG_STAT_GET_BACKEND_USERID 1939 +#define F_PG_STAT_GET_BACKEND_ACTIVITY 1940 +#define F_PG_STAT_GET_DB_NUMBACKENDS 1941 +#define F_PG_STAT_GET_DB_XACT_COMMIT 1942 +#define F_PG_STAT_GET_DB_XACT_ROLLBACK 1943 +#define F_PG_STAT_GET_DB_BLOCKS_FETCHED 1944 +#define F_PG_STAT_GET_DB_BLOCKS_HIT 1945 +#define F_ENCODE 1946 +#define F_DECODE 1947 +#define F_BYTEAEQ 1948 +#define F_BYTEALT 1949 +#define F_BYTEALE 1950 +#define F_BYTEAGT 1951 +#define F_BYTEAGE 1952 +#define F_BYTEANE 1953 +#define F_BYTEACMP 1954 +#define F_TIMESTAMP_TIMESTAMP_INT4 1961 +#define F_INT2_AVG_ACCUM 1962 +#define F_INT4_AVG_ACCUM 1963 +#define F_INT8_AVG 1964 +#define F_OIDLARGER 1965 +#define F_OIDSMALLER 1966 +#define F_TIMESTAMPTZ_TIMESTAMPTZ_INT4 1967 +#define F_TIME_TIME_INT4 1968 +#define F_TIMETZ_TIMETZ_INT4 1969 +#define F_PG_STAT_GET_TUPLES_HOT_UPDATED 1972 +#define F_DIV 1973 +#define F_NUMERIC_DIV_TRUNC 1980 +#define F_SIMILAR_TO_ESCAPE_TEXT_TEXT 1986 +#define F_SIMILAR_TO_ESCAPE_TEXT 1987 +#define F_SHOBJ_DESCRIPTION 1993 +#define F_TEXTANYCAT 2003 +#define F_ANYTEXTCAT 2004 +#define F_BYTEALIKE 2005 +#define F_BYTEANLIKE 2006 +#define F_LIKE_BYTEA_BYTEA 2007 +#define F_NOTLIKE_BYTEA_BYTEA 2008 +#define F_LIKE_ESCAPE_BYTEA_BYTEA 2009 +#define F_LENGTH_BYTEA 2010 +#define F_BYTEACAT 2011 +#define F_SUBSTRING_BYTEA_INT4_INT4 2012 +#define F_SUBSTRING_BYTEA_INT4 2013 +#define F_POSITION_BYTEA_BYTEA 2014 +#define F_BTRIM_BYTEA_BYTEA 2015 +#define F_TIME_TIMESTAMPTZ 2019 +#define F_DATE_TRUNC_TEXT_TIMESTAMP 2020 +#define F_DATE_PART_TEXT_TIMESTAMP 2021 +#define F_PG_STAT_GET_ACTIVITY 2022 +#define F_JSONB_PATH_QUERY_FIRST_TZ 2023 +#define F_TIMESTAMP_DATE 2024 +#define F_TIMESTAMP_DATE_TIME 2025 +#define F_PG_BACKEND_PID 2026 +#define F_TIMESTAMP_TIMESTAMPTZ 2027 +#define F_TIMESTAMPTZ_TIMESTAMP 2028 +#define F_DATE_TIMESTAMP 2029 +#define F_JSONB_PATH_MATCH_TZ 2030 +#define F_TIMESTAMP_MI 2031 +#define F_TIMESTAMP_PL_INTERVAL 2032 +#define F_TIMESTAMP_MI_INTERVAL 2033 +#define F_PG_CONF_LOAD_TIME 2034 +#define F_TIMESTAMP_SMALLER 2035 +#define F_TIMESTAMP_LARGER 2036 +#define F_TIMEZONE_TEXT_TIMETZ 2037 +#define F_TIMEZONE_INTERVAL_TIMETZ 2038 +#define F_TIMESTAMP_HASH 2039 +#define F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_TIMESTAMP 2041 +#define F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_INTERVAL 2042 +#define F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_INTERVAL 2043 +#define F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_TIMESTAMP 2044 +#define F_TIMESTAMP_CMP 2045 +#define F_TIME_TIMETZ 2046 +#define F_TIMETZ_TIME 2047 +#define F_ISFINITE_TIMESTAMP 2048 +#define F_TO_CHAR_TIMESTAMP_TEXT 2049 +#define F_MAX_ANYARRAY 2050 +#define F_MIN_ANYARRAY 2051 +#define F_TIMESTAMP_EQ 2052 +#define F_TIMESTAMP_NE 2053 +#define F_TIMESTAMP_LT 2054 +#define F_TIMESTAMP_LE 2055 +#define F_TIMESTAMP_GE 2056 +#define F_TIMESTAMP_GT 2057 +#define F_AGE_TIMESTAMP_TIMESTAMP 2058 +#define F_AGE_TIMESTAMP 2059 +#define F_TIMEZONE_TEXT_TIMESTAMP 2069 +#define F_TIMEZONE_INTERVAL_TIMESTAMP 2070 +#define F_DATE_PL_INTERVAL 2071 +#define F_DATE_MI_INTERVAL 2072 +#define F_SUBSTRING_TEXT_TEXT 2073 +#define F_SUBSTRING_TEXT_TEXT_TEXT 2074 +#define F_BIT_INT8_INT4 2075 +#define F_INT8_BIT 2076 +#define F_CURRENT_SETTING_TEXT 2077 +#define F_SET_CONFIG 2078 +#define F_PG_TABLE_IS_VISIBLE 2079 +#define F_PG_TYPE_IS_VISIBLE 2080 +#define F_PG_FUNCTION_IS_VISIBLE 2081 +#define F_PG_OPERATOR_IS_VISIBLE 2082 +#define F_PG_OPCLASS_IS_VISIBLE 2083 +#define F_PG_SHOW_ALL_SETTINGS 2084 +#define F_SUBSTR_BYTEA_INT4_INT4 2085 +#define F_SUBSTR_BYTEA_INT4 2086 +#define F_REPLACE 2087 +#define F_SPLIT_PART 2088 +#define F_TO_HEX_INT4 2089 +#define F_TO_HEX_INT8 2090 +#define F_ARRAY_LOWER 2091 +#define F_ARRAY_UPPER 2092 +#define F_PG_CONVERSION_IS_VISIBLE 2093 +#define F_PG_STAT_GET_BACKEND_ACTIVITY_START 2094 +#define F_PG_TERMINATE_BACKEND 2096 +#define F_PG_GET_FUNCTIONDEF 2098 +#define F_AVG_INT8 2100 +#define F_AVG_INT4 2101 +#define F_AVG_INT2 2102 +#define F_AVG_NUMERIC 2103 +#define F_AVG_FLOAT4 2104 +#define F_AVG_FLOAT8 2105 +#define F_AVG_INTERVAL 2106 +#define F_SUM_INT8 2107 +#define F_SUM_INT4 2108 +#define F_SUM_INT2 2109 +#define F_SUM_FLOAT4 2110 +#define F_SUM_FLOAT8 2111 +#define F_SUM_MONEY 2112 +#define F_SUM_INTERVAL 2113 +#define F_SUM_NUMERIC 2114 +#define F_MAX_INT8 2115 +#define F_MAX_INT4 2116 +#define F_MAX_INT2 2117 +#define F_MAX_OID 2118 +#define F_MAX_FLOAT4 2119 +#define F_MAX_FLOAT8 2120 +#define F_PG_COLUMN_COMPRESSION 2121 +#define F_MAX_DATE 2122 +#define F_MAX_TIME 2123 +#define F_MAX_TIMETZ 2124 +#define F_MAX_MONEY 2125 +#define F_MAX_TIMESTAMP 2126 +#define F_MAX_TIMESTAMPTZ 2127 +#define F_MAX_INTERVAL 2128 +#define F_MAX_TEXT 2129 +#define F_MAX_NUMERIC 2130 +#define F_MIN_INT8 2131 +#define F_MIN_INT4 2132 +#define F_MIN_INT2 2133 +#define F_MIN_OID 2134 +#define F_MIN_FLOAT4 2135 +#define F_MIN_FLOAT8 2136 +#define F_PG_STAT_FORCE_NEXT_FLUSH 2137 +#define F_MIN_DATE 2138 +#define F_MIN_TIME 2139 +#define F_MIN_TIMETZ 2140 +#define F_MIN_MONEY 2141 +#define F_MIN_TIMESTAMP 2142 +#define F_MIN_TIMESTAMPTZ 2143 +#define F_MIN_INTERVAL 2144 +#define F_MIN_TEXT 2145 +#define F_MIN_NUMERIC 2146 +#define F_COUNT_ANY 2147 +#define F_VARIANCE_INT8 2148 +#define F_VARIANCE_INT4 2149 +#define F_VARIANCE_INT2 2150 +#define F_VARIANCE_FLOAT4 2151 +#define F_VARIANCE_FLOAT8 2152 +#define F_VARIANCE_NUMERIC 2153 +#define F_STDDEV_INT8 2154 +#define F_STDDEV_INT4 2155 +#define F_STDDEV_INT2 2156 +#define F_STDDEV_FLOAT4 2157 +#define F_STDDEV_FLOAT8 2158 +#define F_STDDEV_NUMERIC 2159 +#define F_TEXT_PATTERN_LT 2160 +#define F_TEXT_PATTERN_LE 2161 +#define F_PG_GET_FUNCTION_ARGUMENTS 2162 +#define F_TEXT_PATTERN_GE 2163 +#define F_TEXT_PATTERN_GT 2164 +#define F_PG_GET_FUNCTION_RESULT 2165 +#define F_BTTEXT_PATTERN_CMP 2166 +#define F_CEILING_NUMERIC 2167 +#define F_PG_DATABASE_SIZE_NAME 2168 +#define F_POWER_NUMERIC_NUMERIC 2169 +#define F_WIDTH_BUCKET_NUMERIC_NUMERIC_NUMERIC_INT4 2170 +#define F_PG_CANCEL_BACKEND 2171 +#define F_PG_BACKUP_START 2172 +#define F_BPCHAR_PATTERN_LT 2174 +#define F_BPCHAR_PATTERN_LE 2175 +#define F_ARRAY_LENGTH 2176 +#define F_BPCHAR_PATTERN_GE 2177 +#define F_BPCHAR_PATTERN_GT 2178 +#define F_GIST_POINT_CONSISTENT 2179 +#define F_BTBPCHAR_PATTERN_CMP 2180 +#define F_HAS_SEQUENCE_PRIVILEGE_NAME_TEXT_TEXT 2181 +#define F_HAS_SEQUENCE_PRIVILEGE_NAME_OID_TEXT 2182 +#define F_HAS_SEQUENCE_PRIVILEGE_OID_TEXT_TEXT 2183 +#define F_HAS_SEQUENCE_PRIVILEGE_OID_OID_TEXT 2184 +#define F_HAS_SEQUENCE_PRIVILEGE_TEXT_TEXT 2185 +#define F_HAS_SEQUENCE_PRIVILEGE_OID_TEXT 2186 +#define F_BTINT48CMP 2188 +#define F_BTINT84CMP 2189 +#define F_BTINT24CMP 2190 +#define F_BTINT42CMP 2191 +#define F_BTINT28CMP 2192 +#define F_BTINT82CMP 2193 +#define F_BTFLOAT48CMP 2194 +#define F_BTFLOAT84CMP 2195 +#define F_INET_CLIENT_ADDR 2196 +#define F_INET_CLIENT_PORT 2197 +#define F_INET_SERVER_ADDR 2198 +#define F_INET_SERVER_PORT 2199 +#define F_REGPROCEDUREIN 2212 +#define F_REGPROCEDUREOUT 2213 +#define F_REGOPERIN 2214 +#define F_REGOPEROUT 2215 +#define F_REGOPERATORIN 2216 +#define F_REGOPERATOROUT 2217 +#define F_REGCLASSIN 2218 +#define F_REGCLASSOUT 2219 +#define F_REGTYPEIN 2220 +#define F_REGTYPEOUT 2221 +#define F_PG_STAT_CLEAR_SNAPSHOT 2230 +#define F_PG_GET_FUNCTION_IDENTITY_ARGUMENTS 2232 +#define F_HASHTID 2233 +#define F_HASHTIDEXTENDED 2234 +#define F_BIT_AND_INT2 2236 +#define F_BIT_OR_INT2 2237 +#define F_BIT_AND_INT4 2238 +#define F_BIT_OR_INT4 2239 +#define F_BIT_AND_INT8 2240 +#define F_BIT_OR_INT8 2241 +#define F_BIT_AND_BIT 2242 +#define F_BIT_OR_BIT 2243 +#define F_MAX_BPCHAR 2244 +#define F_MIN_BPCHAR 2245 +#define F_FMGR_INTERNAL_VALIDATOR 2246 +#define F_FMGR_C_VALIDATOR 2247 +#define F_FMGR_SQL_VALIDATOR 2248 +#define F_HAS_DATABASE_PRIVILEGE_NAME_TEXT_TEXT 2250 +#define F_HAS_DATABASE_PRIVILEGE_NAME_OID_TEXT 2251 +#define F_HAS_DATABASE_PRIVILEGE_OID_TEXT_TEXT 2252 +#define F_HAS_DATABASE_PRIVILEGE_OID_OID_TEXT 2253 +#define F_HAS_DATABASE_PRIVILEGE_TEXT_TEXT 2254 +#define F_HAS_DATABASE_PRIVILEGE_OID_TEXT 2255 +#define F_HAS_FUNCTION_PRIVILEGE_NAME_TEXT_TEXT 2256 +#define F_HAS_FUNCTION_PRIVILEGE_NAME_OID_TEXT 2257 +#define F_HAS_FUNCTION_PRIVILEGE_OID_TEXT_TEXT 2258 +#define F_HAS_FUNCTION_PRIVILEGE_OID_OID_TEXT 2259 +#define F_HAS_FUNCTION_PRIVILEGE_TEXT_TEXT 2260 +#define F_HAS_FUNCTION_PRIVILEGE_OID_TEXT 2261 +#define F_HAS_LANGUAGE_PRIVILEGE_NAME_TEXT_TEXT 2262 +#define F_HAS_LANGUAGE_PRIVILEGE_NAME_OID_TEXT 2263 +#define F_HAS_LANGUAGE_PRIVILEGE_OID_TEXT_TEXT 2264 +#define F_HAS_LANGUAGE_PRIVILEGE_OID_OID_TEXT 2265 +#define F_HAS_LANGUAGE_PRIVILEGE_TEXT_TEXT 2266 +#define F_HAS_LANGUAGE_PRIVILEGE_OID_TEXT 2267 +#define F_HAS_SCHEMA_PRIVILEGE_NAME_TEXT_TEXT 2268 +#define F_HAS_SCHEMA_PRIVILEGE_NAME_OID_TEXT 2269 +#define F_HAS_SCHEMA_PRIVILEGE_OID_TEXT_TEXT 2270 +#define F_HAS_SCHEMA_PRIVILEGE_OID_OID_TEXT 2271 +#define F_HAS_SCHEMA_PRIVILEGE_TEXT_TEXT 2272 +#define F_HAS_SCHEMA_PRIVILEGE_OID_TEXT 2273 +#define F_PG_STAT_RESET 2274 +#define F_PG_GET_BACKEND_MEMORY_CONTEXTS 2282 +#define F_REGEXP_REPLACE_TEXT_TEXT_TEXT 2284 +#define F_REGEXP_REPLACE_TEXT_TEXT_TEXT_TEXT 2285 +#define F_PG_TOTAL_RELATION_SIZE 2286 +#define F_PG_SIZE_PRETTY_INT8 2288 +#define F_PG_OPTIONS_TO_TABLE 2289 +#define F_RECORD_IN 2290 +#define F_RECORD_OUT 2291 +#define F_CSTRING_IN 2292 +#define F_CSTRING_OUT 2293 +#define F_ANY_IN 2294 +#define F_ANY_OUT 2295 +#define F_ANYARRAY_IN 2296 +#define F_ANYARRAY_OUT 2297 +#define F_VOID_IN 2298 +#define F_VOID_OUT 2299 +#define F_TRIGGER_IN 2300 +#define F_TRIGGER_OUT 2301 +#define F_LANGUAGE_HANDLER_IN 2302 +#define F_LANGUAGE_HANDLER_OUT 2303 +#define F_INTERNAL_IN 2304 +#define F_INTERNAL_OUT 2305 +#define F_PG_STAT_GET_SLRU 2306 +#define F_PG_STAT_RESET_SLRU 2307 +#define F_CEIL_FLOAT8 2308 +#define F_FLOOR_FLOAT8 2309 +#define F_SIGN_FLOAT8 2310 +#define F_MD5_TEXT 2311 +#define F_ANYELEMENT_IN 2312 +#define F_ANYELEMENT_OUT 2313 +#define F_POSTGRESQL_FDW_VALIDATOR 2316 +#define F_PG_ENCODING_MAX_LENGTH 2319 +#define F_CEILING_FLOAT8 2320 +#define F_MD5_BYTEA 2321 +#define F_PG_TABLESPACE_SIZE_OID 2322 +#define F_PG_TABLESPACE_SIZE_NAME 2323 +#define F_PG_DATABASE_SIZE_OID 2324 +#define F_PG_RELATION_SIZE_REGCLASS 2325 +#define F_UNNEST_ANYARRAY 2331 +#define F_PG_RELATION_SIZE_REGCLASS_TEXT 2332 +#define F_ARRAY_AGG_TRANSFN 2333 +#define F_ARRAY_AGG_FINALFN 2334 +#define F_ARRAY_AGG_ANYNONARRAY 2335 +#define F_DATE_LT_TIMESTAMP 2338 +#define F_DATE_LE_TIMESTAMP 2339 +#define F_DATE_EQ_TIMESTAMP 2340 +#define F_DATE_GT_TIMESTAMP 2341 +#define F_DATE_GE_TIMESTAMP 2342 +#define F_DATE_NE_TIMESTAMP 2343 +#define F_DATE_CMP_TIMESTAMP 2344 +#define F_DATE_LT_TIMESTAMPTZ 2351 +#define F_DATE_LE_TIMESTAMPTZ 2352 +#define F_DATE_EQ_TIMESTAMPTZ 2353 +#define F_DATE_GT_TIMESTAMPTZ 2354 +#define F_DATE_GE_TIMESTAMPTZ 2355 +#define F_DATE_NE_TIMESTAMPTZ 2356 +#define F_DATE_CMP_TIMESTAMPTZ 2357 +#define F_TIMESTAMP_LT_DATE 2364 +#define F_TIMESTAMP_LE_DATE 2365 +#define F_TIMESTAMP_EQ_DATE 2366 +#define F_TIMESTAMP_GT_DATE 2367 +#define F_TIMESTAMP_GE_DATE 2368 +#define F_TIMESTAMP_NE_DATE 2369 +#define F_TIMESTAMP_CMP_DATE 2370 +#define F_TIMESTAMPTZ_LT_DATE 2377 +#define F_TIMESTAMPTZ_LE_DATE 2378 +#define F_TIMESTAMPTZ_EQ_DATE 2379 +#define F_TIMESTAMPTZ_GT_DATE 2380 +#define F_TIMESTAMPTZ_GE_DATE 2381 +#define F_TIMESTAMPTZ_NE_DATE 2382 +#define F_TIMESTAMPTZ_CMP_DATE 2383 +#define F_HAS_TABLESPACE_PRIVILEGE_NAME_TEXT_TEXT 2390 +#define F_HAS_TABLESPACE_PRIVILEGE_NAME_OID_TEXT 2391 +#define F_HAS_TABLESPACE_PRIVILEGE_OID_TEXT_TEXT 2392 +#define F_HAS_TABLESPACE_PRIVILEGE_OID_OID_TEXT 2393 +#define F_HAS_TABLESPACE_PRIVILEGE_TEXT_TEXT 2394 +#define F_HAS_TABLESPACE_PRIVILEGE_OID_TEXT 2395 +#define F_SHELL_IN 2398 +#define F_SHELL_OUT 2399 +#define F_ARRAY_RECV 2400 +#define F_ARRAY_SEND 2401 +#define F_RECORD_RECV 2402 +#define F_RECORD_SEND 2403 +#define F_INT2RECV 2404 +#define F_INT2SEND 2405 +#define F_INT4RECV 2406 +#define F_INT4SEND 2407 +#define F_INT8RECV 2408 +#define F_INT8SEND 2409 +#define F_INT2VECTORRECV 2410 +#define F_INT2VECTORSEND 2411 +#define F_BYTEARECV 2412 +#define F_BYTEASEND 2413 +#define F_TEXTRECV 2414 +#define F_TEXTSEND 2415 +#define F_UNKNOWNRECV 2416 +#define F_UNKNOWNSEND 2417 +#define F_OIDRECV 2418 +#define F_OIDSEND 2419 +#define F_OIDVECTORRECV 2420 +#define F_OIDVECTORSEND 2421 +#define F_NAMERECV 2422 +#define F_NAMESEND 2423 +#define F_FLOAT4RECV 2424 +#define F_FLOAT4SEND 2425 +#define F_FLOAT8RECV 2426 +#define F_FLOAT8SEND 2427 +#define F_POINT_RECV 2428 +#define F_POINT_SEND 2429 +#define F_BPCHARRECV 2430 +#define F_BPCHARSEND 2431 +#define F_VARCHARRECV 2432 +#define F_VARCHARSEND 2433 +#define F_CHARRECV 2434 +#define F_CHARSEND 2435 +#define F_BOOLRECV 2436 +#define F_BOOLSEND 2437 +#define F_TIDRECV 2438 +#define F_TIDSEND 2439 +#define F_XIDRECV 2440 +#define F_XIDSEND 2441 +#define F_CIDRECV 2442 +#define F_CIDSEND 2443 +#define F_REGPROCRECV 2444 +#define F_REGPROCSEND 2445 +#define F_REGPROCEDURERECV 2446 +#define F_REGPROCEDURESEND 2447 +#define F_REGOPERRECV 2448 +#define F_REGOPERSEND 2449 +#define F_REGOPERATORRECV 2450 +#define F_REGOPERATORSEND 2451 +#define F_REGCLASSRECV 2452 +#define F_REGCLASSSEND 2453 +#define F_REGTYPERECV 2454 +#define F_REGTYPESEND 2455 +#define F_BIT_RECV 2456 +#define F_BIT_SEND 2457 +#define F_VARBIT_RECV 2458 +#define F_VARBIT_SEND 2459 +#define F_NUMERIC_RECV 2460 +#define F_NUMERIC_SEND 2461 +#define F_SINH 2462 +#define F_COSH 2463 +#define F_TANH 2464 +#define F_ASINH 2465 +#define F_ACOSH 2466 +#define F_ATANH 2467 +#define F_DATE_RECV 2468 +#define F_DATE_SEND 2469 +#define F_TIME_RECV 2470 +#define F_TIME_SEND 2471 +#define F_TIMETZ_RECV 2472 +#define F_TIMETZ_SEND 2473 +#define F_TIMESTAMP_RECV 2474 +#define F_TIMESTAMP_SEND 2475 +#define F_TIMESTAMPTZ_RECV 2476 +#define F_TIMESTAMPTZ_SEND 2477 +#define F_INTERVAL_RECV 2478 +#define F_INTERVAL_SEND 2479 +#define F_LSEG_RECV 2480 +#define F_LSEG_SEND 2481 +#define F_PATH_RECV 2482 +#define F_PATH_SEND 2483 +#define F_BOX_RECV 2484 +#define F_BOX_SEND 2485 +#define F_POLY_RECV 2486 +#define F_POLY_SEND 2487 +#define F_LINE_RECV 2488 +#define F_LINE_SEND 2489 +#define F_CIRCLE_RECV 2490 +#define F_CIRCLE_SEND 2491 +#define F_CASH_RECV 2492 +#define F_CASH_SEND 2493 +#define F_MACADDR_RECV 2494 +#define F_MACADDR_SEND 2495 +#define F_INET_RECV 2496 +#define F_INET_SEND 2497 +#define F_CIDR_RECV 2498 +#define F_CIDR_SEND 2499 +#define F_CSTRING_RECV 2500 +#define F_CSTRING_SEND 2501 +#define F_ANYARRAY_RECV 2502 +#define F_ANYARRAY_SEND 2503 +#define F_PG_GET_RULEDEF_OID_BOOL 2504 +#define F_PG_GET_VIEWDEF_TEXT_BOOL 2505 +#define F_PG_GET_VIEWDEF_OID_BOOL 2506 +#define F_PG_GET_INDEXDEF_OID_INT4_BOOL 2507 +#define F_PG_GET_CONSTRAINTDEF_OID_BOOL 2508 +#define F_PG_GET_EXPR_PG_NODE_TREE_OID_BOOL 2509 +#define F_PG_PREPARED_STATEMENT 2510 +#define F_PG_CURSOR 2511 +#define F_FLOAT8_VAR_POP 2512 +#define F_FLOAT8_STDDEV_POP 2513 +#define F_NUMERIC_VAR_POP 2514 +#define F_BOOLAND_STATEFUNC 2515 +#define F_BOOLOR_STATEFUNC 2516 +#define F_BOOL_AND 2517 +#define F_BOOL_OR 2518 +#define F_EVERY 2519 +#define F_TIMESTAMP_LT_TIMESTAMPTZ 2520 +#define F_TIMESTAMP_LE_TIMESTAMPTZ 2521 +#define F_TIMESTAMP_EQ_TIMESTAMPTZ 2522 +#define F_TIMESTAMP_GT_TIMESTAMPTZ 2523 +#define F_TIMESTAMP_GE_TIMESTAMPTZ 2524 +#define F_TIMESTAMP_NE_TIMESTAMPTZ 2525 +#define F_TIMESTAMP_CMP_TIMESTAMPTZ 2526 +#define F_TIMESTAMPTZ_LT_TIMESTAMP 2527 +#define F_TIMESTAMPTZ_LE_TIMESTAMP 2528 +#define F_TIMESTAMPTZ_EQ_TIMESTAMP 2529 +#define F_TIMESTAMPTZ_GT_TIMESTAMP 2530 +#define F_TIMESTAMPTZ_GE_TIMESTAMP 2531 +#define F_TIMESTAMPTZ_NE_TIMESTAMP 2532 +#define F_TIMESTAMPTZ_CMP_TIMESTAMP 2533 +#define F_INTERVAL_PL_DATE 2546 +#define F_INTERVAL_PL_TIMETZ 2547 +#define F_INTERVAL_PL_TIMESTAMP 2548 +#define F_INTERVAL_PL_TIMESTAMPTZ 2549 +#define F_INTEGER_PL_DATE 2550 +#define F_PG_TABLESPACE_DATABASES 2556 +#define F_BOOL_INT4 2557 +#define F_INT4_BOOL 2558 +#define F_LASTVAL 2559 +#define F_PG_POSTMASTER_START_TIME 2560 +#define F_PG_BLOCKING_PIDS 2561 +#define F_BOX_BELOW 2562 +#define F_BOX_OVERBELOW 2563 +#define F_BOX_OVERABOVE 2564 +#define F_BOX_ABOVE 2565 +#define F_POLY_BELOW 2566 +#define F_POLY_OVERBELOW 2567 +#define F_POLY_OVERABOVE 2568 +#define F_POLY_ABOVE 2569 +#define F_GIST_BOX_CONSISTENT 2578 +#define F_FLOAT8_JSONB 2580 +#define F_GIST_BOX_PENALTY 2581 +#define F_GIST_BOX_PICKSPLIT 2582 +#define F_GIST_BOX_UNION 2583 +#define F_GIST_BOX_SAME 2584 +#define F_GIST_POLY_CONSISTENT 2585 +#define F_GIST_POLY_COMPRESS 2586 +#define F_CIRCLE_OVERBELOW 2587 +#define F_CIRCLE_OVERABOVE 2588 +#define F_GIST_CIRCLE_CONSISTENT 2591 +#define F_GIST_CIRCLE_COMPRESS 2592 +#define F_NUMERIC_STDDEV_POP 2596 +#define F_DOMAIN_IN 2597 +#define F_DOMAIN_RECV 2598 +#define F_PG_TIMEZONE_ABBREVS 2599 +#define F_XMLEXISTS 2614 +#define F_PG_RELOAD_CONF 2621 +#define F_PG_ROTATE_LOGFILE 2622 +#define F_PG_STAT_FILE_TEXT 2623 +#define F_PG_READ_FILE_TEXT_INT8_INT8 2624 +#define F_PG_LS_DIR_TEXT 2625 +#define F_PG_SLEEP 2626 +#define F_INETNOT 2627 +#define F_INETAND 2628 +#define F_INETOR 2629 +#define F_INETPL 2630 +#define F_INT8PL_INET 2631 +#define F_INETMI_INT8 2632 +#define F_INETMI 2633 +#define F_VAR_SAMP_INT8 2641 +#define F_VAR_SAMP_INT4 2642 +#define F_VAR_SAMP_INT2 2643 +#define F_VAR_SAMP_FLOAT4 2644 +#define F_VAR_SAMP_FLOAT8 2645 +#define F_VAR_SAMP_NUMERIC 2646 +#define F_TRANSACTION_TIMESTAMP 2647 +#define F_STATEMENT_TIMESTAMP 2648 +#define F_CLOCK_TIMESTAMP 2649 +#define F_GIN_CMP_PREFIX 2700 +#define F_PG_HAS_ROLE_NAME_NAME_TEXT 2705 +#define F_PG_HAS_ROLE_NAME_OID_TEXT 2706 +#define F_PG_HAS_ROLE_OID_NAME_TEXT 2707 +#define F_PG_HAS_ROLE_OID_OID_TEXT 2708 +#define F_PG_HAS_ROLE_NAME_TEXT 2709 +#define F_PG_HAS_ROLE_OID_TEXT 2710 +#define F_JUSTIFY_INTERVAL 2711 +#define F_STDDEV_SAMP_INT8 2712 +#define F_STDDEV_SAMP_INT4 2713 +#define F_STDDEV_SAMP_INT2 2714 +#define F_STDDEV_SAMP_FLOAT4 2715 +#define F_STDDEV_SAMP_FLOAT8 2716 +#define F_STDDEV_SAMP_NUMERIC 2717 +#define F_VAR_POP_INT8 2718 +#define F_VAR_POP_INT4 2719 +#define F_VAR_POP_INT2 2720 +#define F_VAR_POP_FLOAT4 2721 +#define F_VAR_POP_FLOAT8 2722 +#define F_VAR_POP_NUMERIC 2723 +#define F_STDDEV_POP_INT8 2724 +#define F_STDDEV_POP_INT4 2725 +#define F_STDDEV_POP_INT2 2726 +#define F_STDDEV_POP_FLOAT4 2727 +#define F_STDDEV_POP_FLOAT8 2728 +#define F_STDDEV_POP_NUMERIC 2729 +#define F_PG_GET_TRIGGERDEF_OID_BOOL 2730 +#define F_ASIND 2731 +#define F_ACOSD 2732 +#define F_ATAND 2733 +#define F_ATAN2D 2734 +#define F_SIND 2735 +#define F_COSD 2736 +#define F_TAND 2737 +#define F_COTD 2738 +#define F_PG_BACKUP_STOP 2739 +#define F_NUMERIC_AVG_SERIALIZE 2740 +#define F_NUMERIC_AVG_DESERIALIZE 2741 +#define F_GINARRAYEXTRACT_ANYARRAY_INTERNAL_INTERNAL 2743 +#define F_GINARRAYCONSISTENT 2744 +#define F_INT8_AVG_ACCUM 2746 +#define F_ARRAYOVERLAP 2747 +#define F_ARRAYCONTAINS 2748 +#define F_ARRAYCONTAINED 2749 +#define F_PG_STAT_GET_DB_TUPLES_RETURNED 2758 +#define F_PG_STAT_GET_DB_TUPLES_FETCHED 2759 +#define F_PG_STAT_GET_DB_TUPLES_INSERTED 2760 +#define F_PG_STAT_GET_DB_TUPLES_UPDATED 2761 +#define F_PG_STAT_GET_DB_TUPLES_DELETED 2762 +#define F_REGEXP_MATCHES_TEXT_TEXT 2763 +#define F_REGEXP_MATCHES_TEXT_TEXT_TEXT 2764 +#define F_REGEXP_SPLIT_TO_TABLE_TEXT_TEXT 2765 +#define F_REGEXP_SPLIT_TO_TABLE_TEXT_TEXT_TEXT 2766 +#define F_REGEXP_SPLIT_TO_ARRAY_TEXT_TEXT 2767 +#define F_REGEXP_SPLIT_TO_ARRAY_TEXT_TEXT_TEXT 2768 +#define F_PG_STAT_GET_BGWRITER_TIMED_CHECKPOINTS 2769 +#define F_PG_STAT_GET_BGWRITER_REQUESTED_CHECKPOINTS 2770 +#define F_PG_STAT_GET_BGWRITER_BUF_WRITTEN_CHECKPOINTS 2771 +#define F_PG_STAT_GET_BGWRITER_BUF_WRITTEN_CLEAN 2772 +#define F_PG_STAT_GET_BGWRITER_MAXWRITTEN_CLEAN 2773 +#define F_GINQUERYARRAYEXTRACT 2774 +#define F_PG_STAT_GET_BUF_WRITTEN_BACKEND 2775 +#define F_ANYNONARRAY_IN 2777 +#define F_ANYNONARRAY_OUT 2778 +#define F_PG_STAT_GET_LAST_VACUUM_TIME 2781 +#define F_PG_STAT_GET_LAST_AUTOVACUUM_TIME 2782 +#define F_PG_STAT_GET_LAST_ANALYZE_TIME 2783 +#define F_PG_STAT_GET_LAST_AUTOANALYZE_TIME 2784 +#define F_INT8_AVG_COMBINE 2785 +#define F_INT8_AVG_SERIALIZE 2786 +#define F_INT8_AVG_DESERIALIZE 2787 +#define F_PG_STAT_GET_BACKEND_WAIT_EVENT_TYPE 2788 +#define F_TIDGT 2790 +#define F_TIDLT 2791 +#define F_TIDGE 2792 +#define F_TIDLE 2793 +#define F_BTTIDCMP 2794 +#define F_TIDLARGER 2795 +#define F_TIDSMALLER 2796 +#define F_MAX_TID 2797 +#define F_MIN_TID 2798 +#define F_COUNT_ 2803 +#define F_INT8INC_ANY 2804 +#define F_INT8INC_FLOAT8_FLOAT8 2805 +#define F_FLOAT8_REGR_ACCUM 2806 +#define F_FLOAT8_REGR_SXX 2807 +#define F_FLOAT8_REGR_SYY 2808 +#define F_FLOAT8_REGR_SXY 2809 +#define F_FLOAT8_REGR_AVGX 2810 +#define F_FLOAT8_REGR_AVGY 2811 +#define F_FLOAT8_REGR_R2 2812 +#define F_FLOAT8_REGR_SLOPE 2813 +#define F_FLOAT8_REGR_INTERCEPT 2814 +#define F_FLOAT8_COVAR_POP 2815 +#define F_FLOAT8_COVAR_SAMP 2816 +#define F_FLOAT8_CORR 2817 +#define F_REGR_COUNT 2818 +#define F_REGR_SXX 2819 +#define F_REGR_SYY 2820 +#define F_REGR_SXY 2821 +#define F_REGR_AVGX 2822 +#define F_REGR_AVGY 2823 +#define F_REGR_R2 2824 +#define F_REGR_SLOPE 2825 +#define F_REGR_INTERCEPT 2826 +#define F_COVAR_POP 2827 +#define F_COVAR_SAMP 2828 +#define F_CORR 2829 +#define F_PG_STAT_GET_DB_BLK_READ_TIME 2844 +#define F_PG_STAT_GET_DB_BLK_WRITE_TIME 2845 +#define F_PG_SWITCH_WAL 2848 +#define F_PG_CURRENT_WAL_LSN 2849 +#define F_PG_WALFILE_NAME_OFFSET 2850 +#define F_PG_WALFILE_NAME 2851 +#define F_PG_CURRENT_WAL_INSERT_LSN 2852 +#define F_PG_STAT_GET_BACKEND_WAIT_EVENT 2853 +#define F_PG_MY_TEMP_SCHEMA 2854 +#define F_PG_IS_OTHER_TEMP_SCHEMA 2855 +#define F_PG_TIMEZONE_NAMES 2856 +#define F_PG_STAT_GET_BACKEND_XACT_START 2857 +#define F_NUMERIC_AVG_ACCUM 2858 +#define F_PG_STAT_GET_BUF_ALLOC 2859 +#define F_PG_STAT_GET_LIVE_TUPLES 2878 +#define F_PG_STAT_GET_DEAD_TUPLES 2879 +#define F_PG_ADVISORY_LOCK_INT8 2880 +#define F_PG_ADVISORY_LOCK_SHARED_INT8 2881 +#define F_PG_TRY_ADVISORY_LOCK_INT8 2882 +#define F_PG_TRY_ADVISORY_LOCK_SHARED_INT8 2883 +#define F_PG_ADVISORY_UNLOCK_INT8 2884 +#define F_PG_ADVISORY_UNLOCK_SHARED_INT8 2885 +#define F_PG_ADVISORY_LOCK_INT4_INT4 2886 +#define F_PG_ADVISORY_LOCK_SHARED_INT4_INT4 2887 +#define F_PG_TRY_ADVISORY_LOCK_INT4_INT4 2888 +#define F_PG_TRY_ADVISORY_LOCK_SHARED_INT4_INT4 2889 +#define F_PG_ADVISORY_UNLOCK_INT4_INT4 2890 +#define F_PG_ADVISORY_UNLOCK_SHARED_INT4_INT4 2891 +#define F_PG_ADVISORY_UNLOCK_ALL 2892 +#define F_XML_IN 2893 +#define F_XML_OUT 2894 +#define F_XMLCOMMENT 2895 +#define F_XML 2896 +#define F_XMLVALIDATE 2897 +#define F_XML_RECV 2898 +#define F_XML_SEND 2899 +#define F_XMLCONCAT2 2900 +#define F_XMLAGG 2901 +#define F_VARBITTYPMODIN 2902 +#define F_INTERVALTYPMODIN 2903 +#define F_INTERVALTYPMODOUT 2904 +#define F_TIMESTAMPTYPMODIN 2905 +#define F_TIMESTAMPTYPMODOUT 2906 +#define F_TIMESTAMPTZTYPMODIN 2907 +#define F_TIMESTAMPTZTYPMODOUT 2908 +#define F_TIMETYPMODIN 2909 +#define F_TIMETYPMODOUT 2910 +#define F_TIMETZTYPMODIN 2911 +#define F_TIMETZTYPMODOUT 2912 +#define F_BPCHARTYPMODIN 2913 +#define F_BPCHARTYPMODOUT 2914 +#define F_VARCHARTYPMODIN 2915 +#define F_VARCHARTYPMODOUT 2916 +#define F_NUMERICTYPMODIN 2917 +#define F_NUMERICTYPMODOUT 2918 +#define F_BITTYPMODIN 2919 +#define F_BITTYPMODOUT 2920 +#define F_VARBITTYPMODOUT 2921 +#define F_TEXT_XML 2922 +#define F_TABLE_TO_XML 2923 +#define F_QUERY_TO_XML 2924 +#define F_CURSOR_TO_XML 2925 +#define F_TABLE_TO_XMLSCHEMA 2926 +#define F_QUERY_TO_XMLSCHEMA 2927 +#define F_CURSOR_TO_XMLSCHEMA 2928 +#define F_TABLE_TO_XML_AND_XMLSCHEMA 2929 +#define F_QUERY_TO_XML_AND_XMLSCHEMA 2930 +#define F_XPATH_TEXT_XML__TEXT 2931 +#define F_XPATH_TEXT_XML 2932 +#define F_SCHEMA_TO_XML 2933 +#define F_SCHEMA_TO_XMLSCHEMA 2934 +#define F_SCHEMA_TO_XML_AND_XMLSCHEMA 2935 +#define F_DATABASE_TO_XML 2936 +#define F_DATABASE_TO_XMLSCHEMA 2937 +#define F_DATABASE_TO_XML_AND_XMLSCHEMA 2938 +#define F_TXID_SNAPSHOT_IN 2939 +#define F_TXID_SNAPSHOT_OUT 2940 +#define F_TXID_SNAPSHOT_RECV 2941 +#define F_TXID_SNAPSHOT_SEND 2942 +#define F_TXID_CURRENT 2943 +#define F_TXID_CURRENT_SNAPSHOT 2944 +#define F_TXID_SNAPSHOT_XMIN 2945 +#define F_TXID_SNAPSHOT_XMAX 2946 +#define F_TXID_SNAPSHOT_XIP 2947 +#define F_TXID_VISIBLE_IN_SNAPSHOT 2948 +#define F_UUID_IN 2952 +#define F_UUID_OUT 2953 +#define F_UUID_LT 2954 +#define F_UUID_LE 2955 +#define F_UUID_EQ 2956 +#define F_UUID_GE 2957 +#define F_UUID_GT 2958 +#define F_UUID_NE 2959 +#define F_UUID_CMP 2960 +#define F_UUID_RECV 2961 +#define F_UUID_SEND 2962 +#define F_UUID_HASH 2963 +#define F_TEXT_BOOL 2971 +#define F_PG_STAT_GET_FUNCTION_CALLS 2978 +#define F_PG_STAT_GET_FUNCTION_TOTAL_TIME 2979 +#define F_PG_STAT_GET_FUNCTION_SELF_TIME 2980 +#define F_RECORD_EQ 2981 +#define F_RECORD_NE 2982 +#define F_RECORD_LT 2983 +#define F_RECORD_GT 2984 +#define F_RECORD_LE 2985 +#define F_RECORD_GE 2986 +#define F_BTRECORDCMP 2987 +#define F_PG_TABLE_SIZE 2997 +#define F_PG_INDEXES_SIZE 2998 +#define F_PG_RELATION_FILENODE 2999 +#define F_HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE_NAME_TEXT_TEXT 3000 +#define F_HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE_NAME_OID_TEXT 3001 +#define F_HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE_OID_TEXT_TEXT 3002 +#define F_HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE_OID_OID_TEXT 3003 +#define F_HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE_TEXT_TEXT 3004 +#define F_HAS_FOREIGN_DATA_WRAPPER_PRIVILEGE_OID_TEXT 3005 +#define F_HAS_SERVER_PRIVILEGE_NAME_TEXT_TEXT 3006 +#define F_HAS_SERVER_PRIVILEGE_NAME_OID_TEXT 3007 +#define F_HAS_SERVER_PRIVILEGE_OID_TEXT_TEXT 3008 +#define F_HAS_SERVER_PRIVILEGE_OID_OID_TEXT 3009 +#define F_HAS_SERVER_PRIVILEGE_TEXT_TEXT 3010 +#define F_HAS_SERVER_PRIVILEGE_OID_TEXT 3011 +#define F_HAS_COLUMN_PRIVILEGE_NAME_TEXT_TEXT_TEXT 3012 +#define F_HAS_COLUMN_PRIVILEGE_NAME_TEXT_INT2_TEXT 3013 +#define F_HAS_COLUMN_PRIVILEGE_NAME_OID_TEXT_TEXT 3014 +#define F_HAS_COLUMN_PRIVILEGE_NAME_OID_INT2_TEXT 3015 +#define F_HAS_COLUMN_PRIVILEGE_OID_TEXT_TEXT_TEXT 3016 +#define F_HAS_COLUMN_PRIVILEGE_OID_TEXT_INT2_TEXT 3017 +#define F_HAS_COLUMN_PRIVILEGE_OID_OID_TEXT_TEXT 3018 +#define F_HAS_COLUMN_PRIVILEGE_OID_OID_INT2_TEXT 3019 +#define F_HAS_COLUMN_PRIVILEGE_TEXT_TEXT_TEXT 3020 +#define F_HAS_COLUMN_PRIVILEGE_TEXT_INT2_TEXT 3021 +#define F_HAS_COLUMN_PRIVILEGE_OID_TEXT_TEXT 3022 +#define F_HAS_COLUMN_PRIVILEGE_OID_INT2_TEXT 3023 +#define F_HAS_ANY_COLUMN_PRIVILEGE_NAME_TEXT_TEXT 3024 +#define F_HAS_ANY_COLUMN_PRIVILEGE_NAME_OID_TEXT 3025 +#define F_HAS_ANY_COLUMN_PRIVILEGE_OID_TEXT_TEXT 3026 +#define F_HAS_ANY_COLUMN_PRIVILEGE_OID_OID_TEXT 3027 +#define F_HAS_ANY_COLUMN_PRIVILEGE_TEXT_TEXT 3028 +#define F_HAS_ANY_COLUMN_PRIVILEGE_OID_TEXT 3029 +#define F_OVERLAY_BIT_BIT_INT4_INT4 3030 +#define F_OVERLAY_BIT_BIT_INT4 3031 +#define F_GET_BIT_BIT_INT4 3032 +#define F_SET_BIT_BIT_INT4_INT4 3033 +#define F_PG_RELATION_FILEPATH 3034 +#define F_PG_LISTENING_CHANNELS 3035 +#define F_PG_NOTIFY 3036 +#define F_PG_STAT_GET_XACT_NUMSCANS 3037 +#define F_PG_STAT_GET_XACT_TUPLES_RETURNED 3038 +#define F_PG_STAT_GET_XACT_TUPLES_FETCHED 3039 +#define F_PG_STAT_GET_XACT_TUPLES_INSERTED 3040 +#define F_PG_STAT_GET_XACT_TUPLES_UPDATED 3041 +#define F_PG_STAT_GET_XACT_TUPLES_DELETED 3042 +#define F_PG_STAT_GET_XACT_TUPLES_HOT_UPDATED 3043 +#define F_PG_STAT_GET_XACT_BLOCKS_FETCHED 3044 +#define F_PG_STAT_GET_XACT_BLOCKS_HIT 3045 +#define F_PG_STAT_GET_XACT_FUNCTION_CALLS 3046 +#define F_PG_STAT_GET_XACT_FUNCTION_TOTAL_TIME 3047 +#define F_PG_STAT_GET_XACT_FUNCTION_SELF_TIME 3048 +#define F_XPATH_EXISTS_TEXT_XML__TEXT 3049 +#define F_XPATH_EXISTS_TEXT_XML 3050 +#define F_XML_IS_WELL_FORMED 3051 +#define F_XML_IS_WELL_FORMED_DOCUMENT 3052 +#define F_XML_IS_WELL_FORMED_CONTENT 3053 +#define F_PG_STAT_GET_VACUUM_COUNT 3054 +#define F_PG_STAT_GET_AUTOVACUUM_COUNT 3055 +#define F_PG_STAT_GET_ANALYZE_COUNT 3056 +#define F_PG_STAT_GET_AUTOANALYZE_COUNT 3057 +#define F_CONCAT 3058 +#define F_CONCAT_WS 3059 +#define F_LEFT 3060 +#define F_RIGHT 3061 +#define F_REVERSE 3062 +#define F_PG_STAT_GET_BUF_FSYNC_BACKEND 3063 +#define F_GIST_POINT_DISTANCE 3064 +#define F_PG_STAT_GET_DB_CONFLICT_TABLESPACE 3065 +#define F_PG_STAT_GET_DB_CONFLICT_LOCK 3066 +#define F_PG_STAT_GET_DB_CONFLICT_SNAPSHOT 3067 +#define F_PG_STAT_GET_DB_CONFLICT_BUFFERPIN 3068 +#define F_PG_STAT_GET_DB_CONFLICT_STARTUP_DEADLOCK 3069 +#define F_PG_STAT_GET_DB_CONFLICT_ALL 3070 +#define F_PG_WAL_REPLAY_PAUSE 3071 +#define F_PG_WAL_REPLAY_RESUME 3072 +#define F_PG_IS_WAL_REPLAY_PAUSED 3073 +#define F_PG_STAT_GET_DB_STAT_RESET_TIME 3074 +#define F_PG_STAT_GET_BGWRITER_STAT_RESET_TIME 3075 +#define F_GINARRAYEXTRACT_ANYARRAY_INTERNAL 3076 +#define F_GIN_EXTRACT_TSVECTOR_TSVECTOR_INTERNAL 3077 +#define F_PG_SEQUENCE_PARAMETERS 3078 +#define F_PG_AVAILABLE_EXTENSIONS 3082 +#define F_PG_AVAILABLE_EXTENSION_VERSIONS 3083 +#define F_PG_EXTENSION_UPDATE_PATHS 3084 +#define F_PG_EXTENSION_CONFIG_DUMP 3086 +#define F_GIN_EXTRACT_TSQUERY_TSQUERY_INTERNAL_INT2_INTERNAL_INTERNAL 3087 +#define F_GIN_TSQUERY_CONSISTENT_INTERNAL_INT2_TSQUERY_INT4_INTERNAL_INTERNAL 3088 +#define F_PG_ADVISORY_XACT_LOCK_INT8 3089 +#define F_PG_ADVISORY_XACT_LOCK_SHARED_INT8 3090 +#define F_PG_TRY_ADVISORY_XACT_LOCK_INT8 3091 +#define F_PG_TRY_ADVISORY_XACT_LOCK_SHARED_INT8 3092 +#define F_PG_ADVISORY_XACT_LOCK_INT4_INT4 3093 +#define F_PG_ADVISORY_XACT_LOCK_SHARED_INT4_INT4 3094 +#define F_PG_TRY_ADVISORY_XACT_LOCK_INT4_INT4 3095 +#define F_PG_TRY_ADVISORY_XACT_LOCK_SHARED_INT4_INT4 3096 +#define F_VARCHAR_SUPPORT 3097 +#define F_PG_CREATE_RESTORE_POINT 3098 +#define F_PG_STAT_GET_WAL_SENDERS 3099 +#define F_ROW_NUMBER 3100 +#define F_RANK_ 3101 +#define F_DENSE_RANK_ 3102 +#define F_PERCENT_RANK_ 3103 +#define F_CUME_DIST_ 3104 +#define F_NTILE 3105 +#define F_LAG_ANYELEMENT 3106 +#define F_LAG_ANYELEMENT_INT4 3107 +#define F_LAG_ANYCOMPATIBLE_INT4_ANYCOMPATIBLE 3108 +#define F_LEAD_ANYELEMENT 3109 +#define F_LEAD_ANYELEMENT_INT4 3110 +#define F_LEAD_ANYCOMPATIBLE_INT4_ANYCOMPATIBLE 3111 +#define F_FIRST_VALUE 3112 +#define F_LAST_VALUE 3113 +#define F_NTH_VALUE 3114 +#define F_FDW_HANDLER_IN 3116 +#define F_FDW_HANDLER_OUT 3117 +#define F_VOID_RECV 3120 +#define F_VOID_SEND 3121 +#define F_BTINT2SORTSUPPORT 3129 +#define F_BTINT4SORTSUPPORT 3130 +#define F_BTINT8SORTSUPPORT 3131 +#define F_BTFLOAT4SORTSUPPORT 3132 +#define F_BTFLOAT8SORTSUPPORT 3133 +#define F_BTOIDSORTSUPPORT 3134 +#define F_BTNAMESORTSUPPORT 3135 +#define F_DATE_SORTSUPPORT 3136 +#define F_TIMESTAMP_SORTSUPPORT 3137 +#define F_HAS_TYPE_PRIVILEGE_NAME_TEXT_TEXT 3138 +#define F_HAS_TYPE_PRIVILEGE_NAME_OID_TEXT 3139 +#define F_HAS_TYPE_PRIVILEGE_OID_TEXT_TEXT 3140 +#define F_HAS_TYPE_PRIVILEGE_OID_OID_TEXT 3141 +#define F_HAS_TYPE_PRIVILEGE_TEXT_TEXT 3142 +#define F_HAS_TYPE_PRIVILEGE_OID_TEXT 3143 +#define F_MACADDR_NOT 3144 +#define F_MACADDR_AND 3145 +#define F_MACADDR_OR 3146 +#define F_PG_STAT_GET_DB_TEMP_FILES 3150 +#define F_PG_STAT_GET_DB_TEMP_BYTES 3151 +#define F_PG_STAT_GET_DB_DEADLOCKS 3152 +#define F_ARRAY_TO_JSON_ANYARRAY 3153 +#define F_ARRAY_TO_JSON_ANYARRAY_BOOL 3154 +#define F_ROW_TO_JSON_RECORD 3155 +#define F_ROW_TO_JSON_RECORD_BOOL 3156 +#define F_NUMERIC_SUPPORT 3157 +#define F_VARBIT_SUPPORT 3158 +#define F_PG_GET_VIEWDEF_OID_INT4 3159 +#define F_PG_STAT_GET_CHECKPOINT_WRITE_TIME 3160 +#define F_PG_STAT_GET_CHECKPOINT_SYNC_TIME 3161 +#define F_PG_COLLATION_FOR 3162 +#define F_PG_TRIGGER_DEPTH 3163 +#define F_PG_WAL_LSN_DIFF 3165 +#define F_PG_SIZE_PRETTY_NUMERIC 3166 +#define F_ARRAY_REMOVE 3167 +#define F_ARRAY_REPLACE 3168 +#define F_RANGESEL 3169 +#define F_LO_LSEEK64 3170 +#define F_LO_TELL64 3171 +#define F_LO_TRUNCATE64 3172 +#define F_JSON_AGG_TRANSFN 3173 +#define F_JSON_AGG_FINALFN 3174 +#define F_JSON_AGG 3175 +#define F_TO_JSON 3176 +#define F_PG_STAT_GET_MOD_SINCE_ANALYZE 3177 +#define F_NUMERIC_SUM 3178 +#define F_CARDINALITY 3179 +#define F_JSON_OBJECT_AGG_TRANSFN 3180 +#define F_RECORD_IMAGE_EQ 3181 +#define F_RECORD_IMAGE_NE 3182 +#define F_RECORD_IMAGE_LT 3183 +#define F_RECORD_IMAGE_GT 3184 +#define F_RECORD_IMAGE_LE 3185 +#define F_RECORD_IMAGE_GE 3186 +#define F_BTRECORDIMAGECMP 3187 +#define F_PG_STAT_GET_ARCHIVER 3195 +#define F_JSON_OBJECT_AGG_FINALFN 3196 +#define F_JSON_OBJECT_AGG 3197 +#define F_JSON_BUILD_ARRAY_ANY 3198 +#define F_JSON_BUILD_ARRAY_ 3199 +#define F_JSON_BUILD_OBJECT_ANY 3200 +#define F_JSON_BUILD_OBJECT_ 3201 +#define F_JSON_OBJECT__TEXT 3202 +#define F_JSON_OBJECT__TEXT__TEXT 3203 +#define F_JSON_TO_RECORD 3204 +#define F_JSON_TO_RECORDSET 3205 +#define F_JSONB_ARRAY_LENGTH 3207 +#define F_JSONB_EACH 3208 +#define F_JSONB_POPULATE_RECORD 3209 +#define F_JSONB_TYPEOF 3210 +#define F_JSONB_OBJECT_FIELD_TEXT 3214 +#define F_JSONB_ARRAY_ELEMENT 3215 +#define F_JSONB_ARRAY_ELEMENT_TEXT 3216 +#define F_JSONB_EXTRACT_PATH 3217 +#define F_WIDTH_BUCKET_ANYCOMPATIBLE_ANYCOMPATIBLEARRAY 3218 +#define F_JSONB_ARRAY_ELEMENTS 3219 +#define F_PG_LSN_IN 3229 +#define F_PG_LSN_OUT 3230 +#define F_PG_LSN_LT 3231 +#define F_PG_LSN_LE 3232 +#define F_PG_LSN_EQ 3233 +#define F_PG_LSN_GE 3234 +#define F_PG_LSN_GT 3235 +#define F_PG_LSN_NE 3236 +#define F_PG_LSN_MI 3237 +#define F_PG_LSN_RECV 3238 +#define F_PG_LSN_SEND 3239 +#define F_PG_LSN_CMP 3251 +#define F_PG_LSN_HASH 3252 +#define F_BTTEXTSORTSUPPORT 3255 +#define F_GENERATE_SERIES_NUMERIC_NUMERIC_NUMERIC 3259 +#define F_GENERATE_SERIES_NUMERIC_NUMERIC 3260 +#define F_JSON_STRIP_NULLS 3261 +#define F_JSONB_STRIP_NULLS 3262 +#define F_JSONB_OBJECT__TEXT 3263 +#define F_JSONB_OBJECT__TEXT__TEXT 3264 +#define F_JSONB_AGG_TRANSFN 3265 +#define F_JSONB_AGG_FINALFN 3266 +#define F_JSONB_AGG 3267 +#define F_JSONB_OBJECT_AGG_TRANSFN 3268 +#define F_JSONB_OBJECT_AGG_FINALFN 3269 +#define F_JSONB_OBJECT_AGG 3270 +#define F_JSONB_BUILD_ARRAY_ANY 3271 +#define F_JSONB_BUILD_ARRAY_ 3272 +#define F_JSONB_BUILD_OBJECT_ANY 3273 +#define F_JSONB_BUILD_OBJECT_ 3274 +#define F_DIST_PPOLY 3275 +#define F_ARRAY_POSITION_ANYCOMPATIBLEARRAY_ANYCOMPATIBLE 3277 +#define F_ARRAY_POSITION_ANYCOMPATIBLEARRAY_ANYCOMPATIBLE_INT4 3278 +#define F_ARRAY_POSITIONS 3279 +#define F_GIST_CIRCLE_DISTANCE 3280 +#define F_SCALE 3281 +#define F_GIST_POINT_FETCH 3282 +#define F_NUMERIC_SORTSUPPORT 3283 +#define F_GIST_POLY_DISTANCE 3288 +#define F_DIST_CPOINT 3290 +#define F_DIST_POLYP 3292 +#define F_PG_READ_FILE_TEXT_INT8_INT8_BOOL 3293 +#define F_CURRENT_SETTING_TEXT_BOOL 3294 +#define F_PG_READ_BINARY_FILE_TEXT_INT8_INT8_BOOL 3295 +#define F_PG_NOTIFICATION_QUEUE_USAGE 3296 +#define F_PG_LS_DIR_TEXT_BOOL_BOOL 3297 +#define F_ROW_SECURITY_ACTIVE_OID 3298 +#define F_ROW_SECURITY_ACTIVE_TEXT 3299 +#define F_UUID_SORTSUPPORT 3300 +#define F_JSONB_CONCAT 3301 +#define F_JSONB_DELETE_JSONB_TEXT 3302 +#define F_JSONB_DELETE_JSONB_INT4 3303 +#define F_JSONB_DELETE_PATH 3304 +#define F_JSONB_SET 3305 +#define F_JSONB_PRETTY 3306 +#define F_PG_STAT_FILE_TEXT_BOOL 3307 +#define F_XIDNEQ 3308 +#define F_XIDNEQINT4 3309 +#define F_TSM_HANDLER_IN 3311 +#define F_TSM_HANDLER_OUT 3312 +#define F_BERNOULLI 3313 +#define F_SYSTEM 3314 +#define F_PG_STAT_GET_WAL_RECEIVER 3317 +#define F_PG_STAT_GET_PROGRESS_INFO 3318 +#define F_TS_FILTER 3319 +#define F_SETWEIGHT_TSVECTOR_CHAR__TEXT 3320 +#define F_TS_DELETE_TSVECTOR_TEXT 3321 +#define F_UNNEST_TSVECTOR 3322 +#define F_TS_DELETE_TSVECTOR__TEXT 3323 +#define F_INT4_AVG_COMBINE 3324 +#define F_INTERVAL_COMBINE 3325 +#define F_TSVECTOR_TO_ARRAY 3326 +#define F_ARRAY_TO_TSVECTOR 3327 +#define F_BPCHAR_SORTSUPPORT 3328 +#define F_PG_SHOW_ALL_FILE_SETTINGS 3329 +#define F_PG_CURRENT_WAL_FLUSH_LSN 3330 +#define F_BYTEA_SORTSUPPORT 3331 +#define F_BTTEXT_PATTERN_SORTSUPPORT 3332 +#define F_BTBPCHAR_PATTERN_SORTSUPPORT 3333 +#define F_PG_SIZE_BYTES 3334 +#define F_NUMERIC_SERIALIZE 3335 +#define F_NUMERIC_DESERIALIZE 3336 +#define F_NUMERIC_AVG_COMBINE 3337 +#define F_NUMERIC_POLY_COMBINE 3338 +#define F_NUMERIC_POLY_SERIALIZE 3339 +#define F_NUMERIC_POLY_DESERIALIZE 3340 +#define F_NUMERIC_COMBINE 3341 +#define F_FLOAT8_REGR_COMBINE 3342 +#define F_JSONB_DELETE_JSONB__TEXT 3343 +#define F_CASH_MUL_INT8 3344 +#define F_CASH_DIV_INT8 3345 +#define F_TXID_CURRENT_IF_ASSIGNED 3348 +#define F_PG_GET_PARTKEYDEF 3352 +#define F_PG_LS_LOGDIR 3353 +#define F_PG_LS_WALDIR 3354 +#define F_PG_NDISTINCT_IN 3355 +#define F_PG_NDISTINCT_OUT 3356 +#define F_PG_NDISTINCT_RECV 3357 +#define F_PG_NDISTINCT_SEND 3358 +#define F_MACADDR_SORTSUPPORT 3359 +#define F_TXID_STATUS 3360 +#define F_PG_SAFE_SNAPSHOT_BLOCKING_PIDS 3376 +#define F_PG_ISOLATION_TEST_SESSION_IS_BLOCKED 3378 +#define F_PG_IDENTIFY_OBJECT_AS_ADDRESS 3382 +#define F_BRIN_MINMAX_OPCINFO 3383 +#define F_BRIN_MINMAX_ADD_VALUE 3384 +#define F_BRIN_MINMAX_CONSISTENT 3385 +#define F_BRIN_MINMAX_UNION 3386 +#define F_INT8_AVG_ACCUM_INV 3387 +#define F_NUMERIC_POLY_SUM 3388 +#define F_NUMERIC_POLY_AVG 3389 +#define F_NUMERIC_POLY_VAR_POP 3390 +#define F_NUMERIC_POLY_VAR_SAMP 3391 +#define F_NUMERIC_POLY_STDDEV_POP 3392 +#define F_NUMERIC_POLY_STDDEV_SAMP 3393 +#define F_REGEXP_MATCH_TEXT_TEXT 3396 +#define F_REGEXP_MATCH_TEXT_TEXT_TEXT 3397 +#define F_INT8_MUL_CASH 3399 +#define F_PG_CONFIG 3400 +#define F_PG_HBA_FILE_RULES 3401 +#define F_PG_STATISTICS_OBJ_IS_VISIBLE 3403 +#define F_PG_DEPENDENCIES_IN 3404 +#define F_PG_DEPENDENCIES_OUT 3405 +#define F_PG_DEPENDENCIES_RECV 3406 +#define F_PG_DEPENDENCIES_SEND 3407 +#define F_PG_GET_PARTITION_CONSTRAINTDEF 3408 +#define F_TIME_HASH_EXTENDED 3409 +#define F_TIMETZ_HASH_EXTENDED 3410 +#define F_TIMESTAMP_HASH_EXTENDED 3411 +#define F_UUID_HASH_EXTENDED 3412 +#define F_PG_LSN_HASH_EXTENDED 3413 +#define F_HASHENUMEXTENDED 3414 +#define F_PG_GET_STATISTICSOBJDEF 3415 +#define F_JSONB_HASH_EXTENDED 3416 +#define F_HASH_RANGE_EXTENDED 3417 +#define F_INTERVAL_HASH_EXTENDED 3418 +#define F_SHA224 3419 +#define F_SHA256 3420 +#define F_SHA384 3421 +#define F_SHA512 3422 +#define F_PG_PARTITION_TREE 3423 +#define F_PG_PARTITION_ROOT 3424 +#define F_PG_PARTITION_ANCESTORS 3425 +#define F_PG_STAT_GET_DB_CHECKSUM_FAILURES 3426 +#define F_PG_MCV_LIST_ITEMS 3427 +#define F_PG_STAT_GET_DB_CHECKSUM_LAST_FAILURE 3428 +#define F_GEN_RANDOM_UUID 3432 +#define F_GTSVECTOR_OPTIONS 3434 +#define F_GIST_POINT_SORTSUPPORT 3435 +#define F_PG_PROMOTE 3436 +#define F_PREFIXSEL 3437 +#define F_PREFIXJOINSEL 3438 +#define F_PG_CONTROL_SYSTEM 3441 +#define F_PG_CONTROL_CHECKPOINT 3442 +#define F_PG_CONTROL_RECOVERY 3443 +#define F_PG_CONTROL_INIT 3444 +#define F_PG_IMPORT_SYSTEM_COLLATIONS 3445 +#define F_MACADDR8_RECV 3446 +#define F_MACADDR8_SEND 3447 +#define F_PG_COLLATION_ACTUAL_VERSION 3448 +#define F_NUMERIC_JSONB 3449 +#define F_INT2_JSONB 3450 +#define F_INT4_JSONB 3451 +#define F_INT8_JSONB 3452 +#define F_FLOAT4_JSONB 3453 +#define F_PG_FILENODE_RELATION 3454 +#define F_LO_FROM_BYTEA 3457 +#define F_LO_GET_OID 3458 +#define F_LO_GET_OID_INT8_INT4 3459 +#define F_LO_PUT 3460 +#define F_MAKE_TIMESTAMP 3461 +#define F_MAKE_TIMESTAMPTZ_INT4_INT4_INT4_INT4_INT4_FLOAT8 3462 +#define F_MAKE_TIMESTAMPTZ_INT4_INT4_INT4_INT4_INT4_FLOAT8_TEXT 3463 +#define F_MAKE_INTERVAL 3464 +#define F_JSONB_ARRAY_ELEMENTS_TEXT 3465 +#define F_SPG_RANGE_QUAD_CONFIG 3469 +#define F_SPG_RANGE_QUAD_CHOOSE 3470 +#define F_SPG_RANGE_QUAD_PICKSPLIT 3471 +#define F_SPG_RANGE_QUAD_INNER_CONSISTENT 3472 +#define F_SPG_RANGE_QUAD_LEAF_CONSISTENT 3473 +#define F_JSONB_POPULATE_RECORDSET 3475 +#define F_TO_REGOPERATOR 3476 +#define F_JSONB_OBJECT_FIELD 3478 +#define F_TO_REGPROCEDURE 3479 +#define F_GIN_COMPARE_JSONB 3480 +#define F_GIN_EXTRACT_JSONB 3482 +#define F_GIN_EXTRACT_JSONB_QUERY 3483 +#define F_GIN_CONSISTENT_JSONB 3484 +#define F_GIN_EXTRACT_JSONB_PATH 3485 +#define F_GIN_EXTRACT_JSONB_QUERY_PATH 3486 +#define F_GIN_CONSISTENT_JSONB_PATH 3487 +#define F_GIN_TRICONSISTENT_JSONB 3488 +#define F_GIN_TRICONSISTENT_JSONB_PATH 3489 +#define F_JSONB_TO_RECORD 3490 +#define F_JSONB_TO_RECORDSET 3491 +#define F_TO_REGOPER 3492 +#define F_TO_REGTYPE 3493 +#define F_TO_REGPROC 3494 +#define F_TO_REGCLASS 3495 +#define F_BOOL_ACCUM 3496 +#define F_BOOL_ACCUM_INV 3497 +#define F_BOOL_ALLTRUE 3498 +#define F_BOOL_ANYTRUE 3499 +#define F_ANYENUM_IN 3504 +#define F_ANYENUM_OUT 3505 +#define F_ENUM_IN 3506 +#define F_ENUM_OUT 3507 +#define F_ENUM_EQ 3508 +#define F_ENUM_NE 3509 +#define F_ENUM_LT 3510 +#define F_ENUM_GT 3511 +#define F_ENUM_LE 3512 +#define F_ENUM_GE 3513 +#define F_ENUM_CMP 3514 +#define F_HASHENUM 3515 +#define F_ENUM_SMALLER 3524 +#define F_ENUM_LARGER 3525 +#define F_MAX_ANYENUM 3526 +#define F_MIN_ANYENUM 3527 +#define F_ENUM_FIRST 3528 +#define F_ENUM_LAST 3529 +#define F_ENUM_RANGE_ANYENUM_ANYENUM 3530 +#define F_ENUM_RANGE_ANYENUM 3531 +#define F_ENUM_RECV 3532 +#define F_ENUM_SEND 3533 +#define F_STRING_AGG_TRANSFN 3535 +#define F_STRING_AGG_FINALFN 3536 +#define F_PG_DESCRIBE_OBJECT 3537 +#define F_STRING_AGG_TEXT_TEXT 3538 +#define F_FORMAT_TEXT_ANY 3539 +#define F_FORMAT_TEXT 3540 +#define F_BYTEA_STRING_AGG_TRANSFN 3543 +#define F_BYTEA_STRING_AGG_FINALFN 3544 +#define F_STRING_AGG_BYTEA_BYTEA 3545 +#define F_INT8DEC 3546 +#define F_INT8DEC_ANY 3547 +#define F_NUMERIC_ACCUM_INV 3548 +#define F_INTERVAL_ACCUM_INV 3549 +#define F_NETWORK_OVERLAP 3551 +#define F_INET_GIST_CONSISTENT 3553 +#define F_INET_GIST_UNION 3554 +#define F_INET_GIST_COMPRESS 3555 +#define F_BOOL_JSONB 3556 +#define F_INET_GIST_PENALTY 3557 +#define F_INET_GIST_PICKSPLIT 3558 +#define F_INET_GIST_SAME 3559 +#define F_NETWORKSEL 3560 +#define F_NETWORKJOINSEL 3561 +#define F_NETWORK_LARGER 3562 +#define F_NETWORK_SMALLER 3563 +#define F_MAX_INET 3564 +#define F_MIN_INET 3565 +#define F_PG_EVENT_TRIGGER_DROPPED_OBJECTS 3566 +#define F_INT2_ACCUM_INV 3567 +#define F_INT4_ACCUM_INV 3568 +#define F_INT8_ACCUM_INV 3569 +#define F_INT2_AVG_ACCUM_INV 3570 +#define F_INT4_AVG_ACCUM_INV 3571 +#define F_INT2INT4_SUM 3572 +#define F_INET_GIST_FETCH 3573 +#define F_PG_LOGICAL_EMIT_MESSAGE_BOOL_TEXT_TEXT 3577 +#define F_PG_LOGICAL_EMIT_MESSAGE_BOOL_TEXT_BYTEA 3578 +#define F_JSONB_INSERT 3579 +#define F_PG_XACT_COMMIT_TIMESTAMP 3581 +#define F_BINARY_UPGRADE_SET_NEXT_PG_TYPE_OID 3582 +#define F_PG_LAST_COMMITTED_XACT 3583 +#define F_BINARY_UPGRADE_SET_NEXT_ARRAY_PG_TYPE_OID 3584 +#define F_BINARY_UPGRADE_SET_NEXT_HEAP_PG_CLASS_OID 3586 +#define F_BINARY_UPGRADE_SET_NEXT_INDEX_PG_CLASS_OID 3587 +#define F_BINARY_UPGRADE_SET_NEXT_TOAST_PG_CLASS_OID 3588 +#define F_BINARY_UPGRADE_SET_NEXT_PG_ENUM_OID 3589 +#define F_BINARY_UPGRADE_SET_NEXT_PG_AUTHID_OID 3590 +#define F_BINARY_UPGRADE_CREATE_EMPTY_EXTENSION 3591 +#define F_EVENT_TRIGGER_IN 3594 +#define F_EVENT_TRIGGER_OUT 3595 +#define F_TSVECTORIN 3610 +#define F_TSVECTOROUT 3611 +#define F_TSQUERYIN 3612 +#define F_TSQUERYOUT 3613 +#define F_TSVECTOR_LT 3616 +#define F_TSVECTOR_LE 3617 +#define F_TSVECTOR_EQ 3618 +#define F_TSVECTOR_NE 3619 +#define F_TSVECTOR_GE 3620 +#define F_TSVECTOR_GT 3621 +#define F_TSVECTOR_CMP 3622 +#define F_STRIP 3623 +#define F_SETWEIGHT_TSVECTOR_CHAR 3624 +#define F_TSVECTOR_CONCAT 3625 +#define F_TS_MATCH_VQ 3634 +#define F_TS_MATCH_QV 3635 +#define F_TSVECTORSEND 3638 +#define F_TSVECTORRECV 3639 +#define F_TSQUERYSEND 3640 +#define F_TSQUERYRECV 3641 +#define F_GTSVECTORIN 3646 +#define F_GTSVECTOROUT 3647 +#define F_GTSVECTOR_COMPRESS 3648 +#define F_GTSVECTOR_DECOMPRESS 3649 +#define F_GTSVECTOR_PICKSPLIT 3650 +#define F_GTSVECTOR_UNION 3651 +#define F_GTSVECTOR_SAME 3652 +#define F_GTSVECTOR_PENALTY 3653 +#define F_GTSVECTOR_CONSISTENT_INTERNAL_TSVECTOR_INT2_OID_INTERNAL 3654 +#define F_GIN_EXTRACT_TSVECTOR_TSVECTOR_INTERNAL_INTERNAL 3656 +#define F_GIN_EXTRACT_TSQUERY_TSVECTOR_INTERNAL_INT2_INTERNAL_INTERNAL_INTERNAL_INTERNAL 3657 +#define F_GIN_TSQUERY_CONSISTENT_INTERNAL_INT2_TSVECTOR_INT4_INTERNAL_INTERNAL_INTERNAL_INTERNAL 3658 +#define F_TSQUERY_LT 3662 +#define F_TSQUERY_LE 3663 +#define F_TSQUERY_EQ 3664 +#define F_TSQUERY_NE 3665 +#define F_TSQUERY_GE 3666 +#define F_TSQUERY_GT 3667 +#define F_TSQUERY_CMP 3668 +#define F_TSQUERY_AND 3669 +#define F_TSQUERY_OR 3670 +#define F_TSQUERY_NOT 3671 +#define F_NUMNODE 3672 +#define F_QUERYTREE 3673 +#define F_TS_REWRITE_TSQUERY_TSQUERY_TSQUERY 3684 +#define F_TS_REWRITE_TSQUERY_TEXT 3685 +#define F_TSMATCHSEL 3686 +#define F_TSMATCHJOINSEL 3687 +#define F_TS_TYPANALYZE 3688 +#define F_TS_STAT_TEXT 3689 +#define F_TS_STAT_TEXT_TEXT 3690 +#define F_TSQ_MCONTAINS 3691 +#define F_TSQ_MCONTAINED 3692 +#define F_GTSQUERY_COMPRESS 3695 +#define F_STARTS_WITH 3696 +#define F_GTSQUERY_PICKSPLIT 3697 +#define F_GTSQUERY_UNION 3698 +#define F_GTSQUERY_SAME 3699 +#define F_GTSQUERY_PENALTY 3700 +#define F_GTSQUERY_CONSISTENT_INTERNAL_TSQUERY_INT2_OID_INTERNAL 3701 +#define F_TS_RANK__FLOAT4_TSVECTOR_TSQUERY_INT4 3703 +#define F_TS_RANK__FLOAT4_TSVECTOR_TSQUERY 3704 +#define F_TS_RANK_TSVECTOR_TSQUERY_INT4 3705 +#define F_TS_RANK_TSVECTOR_TSQUERY 3706 +#define F_TS_RANK_CD__FLOAT4_TSVECTOR_TSQUERY_INT4 3707 +#define F_TS_RANK_CD__FLOAT4_TSVECTOR_TSQUERY 3708 +#define F_TS_RANK_CD_TSVECTOR_TSQUERY_INT4 3709 +#define F_TS_RANK_CD_TSVECTOR_TSQUERY 3710 +#define F_LENGTH_TSVECTOR 3711 +#define F_TS_TOKEN_TYPE_OID 3713 +#define F_TS_TOKEN_TYPE_TEXT 3714 +#define F_TS_PARSE_OID_TEXT 3715 +#define F_TS_PARSE_TEXT_TEXT 3716 +#define F_PRSD_START 3717 +#define F_PRSD_NEXTTOKEN 3718 +#define F_PRSD_END 3719 +#define F_PRSD_HEADLINE 3720 +#define F_PRSD_LEXTYPE 3721 +#define F_TS_LEXIZE 3723 +#define F_GIN_CMP_TSLEXEME 3724 +#define F_DSIMPLE_INIT 3725 +#define F_DSIMPLE_LEXIZE 3726 +#define F_DSYNONYM_INIT 3728 +#define F_DSYNONYM_LEXIZE 3729 +#define F_DISPELL_INIT 3731 +#define F_DISPELL_LEXIZE 3732 +#define F_REGCONFIGIN 3736 +#define F_REGCONFIGOUT 3737 +#define F_REGCONFIGRECV 3738 +#define F_REGCONFIGSEND 3739 +#define F_THESAURUS_INIT 3740 +#define F_THESAURUS_LEXIZE 3741 +#define F_TS_HEADLINE_REGCONFIG_TEXT_TSQUERY_TEXT 3743 +#define F_TS_HEADLINE_REGCONFIG_TEXT_TSQUERY 3744 +#define F_TO_TSVECTOR_REGCONFIG_TEXT 3745 +#define F_TO_TSQUERY_REGCONFIG_TEXT 3746 +#define F_PLAINTO_TSQUERY_REGCONFIG_TEXT 3747 +#define F_TO_TSVECTOR_TEXT 3749 +#define F_TO_TSQUERY_TEXT 3750 +#define F_PLAINTO_TSQUERY_TEXT 3751 +#define F_TSVECTOR_UPDATE_TRIGGER 3752 +#define F_TSVECTOR_UPDATE_TRIGGER_COLUMN 3753 +#define F_TS_HEADLINE_TEXT_TSQUERY_TEXT 3754 +#define F_TS_HEADLINE_TEXT_TSQUERY 3755 +#define F_PG_TS_PARSER_IS_VISIBLE 3756 +#define F_PG_TS_DICT_IS_VISIBLE 3757 +#define F_PG_TS_CONFIG_IS_VISIBLE 3758 +#define F_GET_CURRENT_TS_CONFIG 3759 +#define F_TS_MATCH_TT 3760 +#define F_TS_MATCH_TQ 3761 +#define F_PG_TS_TEMPLATE_IS_VISIBLE 3768 +#define F_REGDICTIONARYIN 3771 +#define F_REGDICTIONARYOUT 3772 +#define F_REGDICTIONARYRECV 3773 +#define F_REGDICTIONARYSEND 3774 +#define F_PG_STAT_RESET_SHARED 3775 +#define F_PG_STAT_RESET_SINGLE_TABLE_COUNTERS 3776 +#define F_PG_STAT_RESET_SINGLE_FUNCTION_COUNTERS 3777 +#define F_PG_TABLESPACE_LOCATION 3778 +#define F_PG_CREATE_PHYSICAL_REPLICATION_SLOT 3779 +#define F_PG_DROP_REPLICATION_SLOT 3780 +#define F_PG_GET_REPLICATION_SLOTS 3781 +#define F_PG_LOGICAL_SLOT_GET_CHANGES 3782 +#define F_PG_LOGICAL_SLOT_GET_BINARY_CHANGES 3783 +#define F_PG_LOGICAL_SLOT_PEEK_CHANGES 3784 +#define F_PG_LOGICAL_SLOT_PEEK_BINARY_CHANGES 3785 +#define F_PG_CREATE_LOGICAL_REPLICATION_SLOT 3786 +#define F_TO_JSONB 3787 +#define F_PG_STAT_GET_SNAPSHOT_TIMESTAMP 3788 +#define F_GIN_CLEAN_PENDING_LIST 3789 +#define F_GTSVECTOR_CONSISTENT_INTERNAL_GTSVECTOR_INT4_OID_INTERNAL 3790 +#define F_GIN_EXTRACT_TSQUERY_TSQUERY_INTERNAL_INT2_INTERNAL_INTERNAL_INTERNAL_INTERNAL 3791 +#define F_GIN_TSQUERY_CONSISTENT_INTERNAL_INT2_TSQUERY_INT4_INTERNAL_INTERNAL_INTERNAL_INTERNAL 3792 +#define F_GTSQUERY_CONSISTENT_INTERNAL_INTERNAL_INT4_OID_INTERNAL 3793 +#define F_INET_SPG_CONFIG 3795 +#define F_INET_SPG_CHOOSE 3796 +#define F_INET_SPG_PICKSPLIT 3797 +#define F_INET_SPG_INNER_CONSISTENT 3798 +#define F_INET_SPG_LEAF_CONSISTENT 3799 +#define F_PG_CURRENT_LOGFILE_ 3800 +#define F_PG_CURRENT_LOGFILE_TEXT 3801 +#define F_JSONB_SEND 3803 +#define F_JSONB_OUT 3804 +#define F_JSONB_RECV 3805 +#define F_JSONB_IN 3806 +#define F_PG_GET_FUNCTION_ARG_DEFAULT 3808 +#define F_PG_EXPORT_SNAPSHOT 3809 +#define F_PG_IS_IN_RECOVERY 3810 +#define F_MONEY_INT4 3811 +#define F_MONEY_INT8 3812 +#define F_PG_COLLATION_IS_VISIBLE 3815 +#define F_ARRAY_TYPANALYZE 3816 +#define F_ARRAYCONTSEL 3817 +#define F_ARRAYCONTJOINSEL 3818 +#define F_PG_GET_MULTIXACT_MEMBERS 3819 +#define F_PG_LAST_WAL_RECEIVE_LSN 3820 +#define F_PG_LAST_WAL_REPLAY_LSN 3821 +#define F_CASH_DIV_CASH 3822 +#define F_NUMERIC_MONEY 3823 +#define F_MONEY_NUMERIC 3824 +#define F_PG_READ_FILE_TEXT 3826 +#define F_PG_READ_BINARY_FILE_TEXT_INT8_INT8 3827 +#define F_PG_READ_BINARY_FILE_TEXT 3828 +#define F_PG_OPFAMILY_IS_VISIBLE 3829 +#define F_PG_LAST_XACT_REPLAY_TIMESTAMP 3830 +#define F_ANYRANGE_IN 3832 +#define F_ANYRANGE_OUT 3833 +#define F_RANGE_IN 3834 +#define F_RANGE_OUT 3835 +#define F_RANGE_RECV 3836 +#define F_RANGE_SEND 3837 +#define F_PG_IDENTIFY_OBJECT 3839 +#define F_INT4RANGE_INT4_INT4 3840 +#define F_INT4RANGE_INT4_INT4_TEXT 3841 +#define F_PG_RELATION_IS_UPDATABLE 3842 +#define F_PG_COLUMN_IS_UPDATABLE 3843 +#define F_NUMRANGE_NUMERIC_NUMERIC 3844 +#define F_NUMRANGE_NUMERIC_NUMERIC_TEXT 3845 +#define F_MAKE_DATE 3846 +#define F_MAKE_TIME 3847 +#define F_LOWER_ANYRANGE 3848 +#define F_UPPER_ANYRANGE 3849 +#define F_ISEMPTY_ANYRANGE 3850 +#define F_LOWER_INC_ANYRANGE 3851 +#define F_UPPER_INC_ANYRANGE 3852 +#define F_LOWER_INF_ANYRANGE 3853 +#define F_UPPER_INF_ANYRANGE 3854 +#define F_RANGE_EQ 3855 +#define F_RANGE_NE 3856 +#define F_RANGE_OVERLAPS 3857 +#define F_RANGE_CONTAINS_ELEM 3858 +#define F_RANGE_CONTAINS 3859 +#define F_ELEM_CONTAINED_BY_RANGE 3860 +#define F_RANGE_CONTAINED_BY 3861 +#define F_RANGE_ADJACENT 3862 +#define F_RANGE_BEFORE 3863 +#define F_RANGE_AFTER 3864 +#define F_RANGE_OVERLEFT 3865 +#define F_RANGE_OVERRIGHT 3866 +#define F_RANGE_UNION 3867 +#define F_RANGE_INTERSECT 3868 +#define F_RANGE_MINUS 3869 +#define F_RANGE_CMP 3870 +#define F_RANGE_LT 3871 +#define F_RANGE_LE 3872 +#define F_RANGE_GE 3873 +#define F_RANGE_GT 3874 +#define F_RANGE_GIST_CONSISTENT 3875 +#define F_RANGE_GIST_UNION 3876 +#define F_PG_REPLICATION_SLOT_ADVANCE 3878 +#define F_RANGE_GIST_PENALTY 3879 +#define F_RANGE_GIST_PICKSPLIT 3880 +#define F_RANGE_GIST_SAME 3881 +#define F_HASH_RANGE 3902 +#define F_INT4RANGE_CANONICAL 3914 +#define F_DATERANGE_CANONICAL 3915 +#define F_RANGE_TYPANALYZE 3916 +#define F_TIMESTAMP_SUPPORT 3917 +#define F_INTERVAL_SUPPORT 3918 +#define F_GINARRAYTRICONSISTENT 3920 +#define F_GIN_TSQUERY_TRICONSISTENT 3921 +#define F_INT4RANGE_SUBDIFF 3922 +#define F_INT8RANGE_SUBDIFF 3923 +#define F_NUMRANGE_SUBDIFF 3924 +#define F_DATERANGE_SUBDIFF 3925 +#define F_INT8RANGE_CANONICAL 3928 +#define F_TSRANGE_SUBDIFF 3929 +#define F_TSTZRANGE_SUBDIFF 3930 +#define F_JSONB_OBJECT_KEYS 3931 +#define F_JSONB_EACH_TEXT 3932 +#define F_TSRANGE_TIMESTAMP_TIMESTAMP 3933 +#define F_TSRANGE_TIMESTAMP_TIMESTAMP_TEXT 3934 +#define F_PG_SLEEP_FOR 3935 +#define F_PG_SLEEP_UNTIL 3936 +#define F_TSTZRANGE_TIMESTAMPTZ_TIMESTAMPTZ 3937 +#define F_TSTZRANGE_TIMESTAMPTZ_TIMESTAMPTZ_TEXT 3938 +#define F_MXID_AGE 3939 +#define F_JSONB_EXTRACT_PATH_TEXT 3940 +#define F_DATERANGE_DATE_DATE 3941 +#define F_DATERANGE_DATE_DATE_TEXT 3942 +#define F_ACLDEFAULT 3943 +#define F_TIME_SUPPORT 3944 +#define F_INT8RANGE_INT8_INT8 3945 +#define F_INT8RANGE_INT8_INT8_TEXT 3946 +#define F_JSON_OBJECT_FIELD 3947 +#define F_JSON_OBJECT_FIELD_TEXT 3948 +#define F_JSON_ARRAY_ELEMENT 3949 +#define F_JSON_ARRAY_ELEMENT_TEXT 3950 +#define F_JSON_EXTRACT_PATH 3951 +#define F_BRIN_SUMMARIZE_NEW_VALUES 3952 +#define F_JSON_EXTRACT_PATH_TEXT 3953 +#define F_PG_GET_OBJECT_ADDRESS 3954 +#define F_JSON_ARRAY_ELEMENTS 3955 +#define F_JSON_ARRAY_LENGTH 3956 +#define F_JSON_OBJECT_KEYS 3957 +#define F_JSON_EACH 3958 +#define F_JSON_EACH_TEXT 3959 +#define F_JSON_POPULATE_RECORD 3960 +#define F_JSON_POPULATE_RECORDSET 3961 +#define F_JSON_TYPEOF 3968 +#define F_JSON_ARRAY_ELEMENTS_TEXT 3969 +#define F_ORDERED_SET_TRANSITION 3970 +#define F_ORDERED_SET_TRANSITION_MULTI 3971 +#define F_PERCENTILE_DISC_FLOAT8_ANYELEMENT 3972 +#define F_PERCENTILE_DISC_FINAL 3973 +#define F_PERCENTILE_CONT_FLOAT8_FLOAT8 3974 +#define F_PERCENTILE_CONT_FLOAT8_FINAL 3975 +#define F_PERCENTILE_CONT_FLOAT8_INTERVAL 3976 +#define F_PERCENTILE_CONT_INTERVAL_FINAL 3977 +#define F_PERCENTILE_DISC__FLOAT8_ANYELEMENT 3978 +#define F_PERCENTILE_DISC_MULTI_FINAL 3979 +#define F_PERCENTILE_CONT__FLOAT8_FLOAT8 3980 +#define F_PERCENTILE_CONT_FLOAT8_MULTI_FINAL 3981 +#define F_PERCENTILE_CONT__FLOAT8_INTERVAL 3982 +#define F_PERCENTILE_CONT_INTERVAL_MULTI_FINAL 3983 +#define F_MODE 3984 +#define F_MODE_FINAL 3985 +#define F_RANK_ANY 3986 +#define F_RANK_FINAL 3987 +#define F_PERCENT_RANK_ANY 3988 +#define F_PERCENT_RANK_FINAL 3989 +#define F_CUME_DIST_ANY 3990 +#define F_CUME_DIST_FINAL 3991 +#define F_DENSE_RANK_ANY 3992 +#define F_DENSE_RANK_FINAL 3993 +#define F_GENERATE_SERIES_INT4_SUPPORT 3994 +#define F_GENERATE_SERIES_INT8_SUPPORT 3995 +#define F_ARRAY_UNNEST_SUPPORT 3996 +#define F_GIST_BOX_DISTANCE 3998 +#define F_BRIN_SUMMARIZE_RANGE 3999 +#define F_JSONPATH_IN 4001 +#define F_JSONPATH_RECV 4002 +#define F_JSONPATH_OUT 4003 +#define F_JSONPATH_SEND 4004 +#define F_JSONB_PATH_EXISTS 4005 +#define F_JSONB_PATH_QUERY 4006 +#define F_JSONB_PATH_QUERY_ARRAY 4007 +#define F_JSONB_PATH_QUERY_FIRST 4008 +#define F_JSONB_PATH_MATCH 4009 +#define F_JSONB_PATH_EXISTS_OPR 4010 +#define F_JSONB_PATH_MATCH_OPR 4011 +#define F_BRIN_DESUMMARIZE_RANGE 4014 +#define F_SPG_QUAD_CONFIG 4018 +#define F_SPG_QUAD_CHOOSE 4019 +#define F_SPG_QUAD_PICKSPLIT 4020 +#define F_SPG_QUAD_INNER_CONSISTENT 4021 +#define F_SPG_QUAD_LEAF_CONSISTENT 4022 +#define F_SPG_KD_CONFIG 4023 +#define F_SPG_KD_CHOOSE 4024 +#define F_SPG_KD_PICKSPLIT 4025 +#define F_SPG_KD_INNER_CONSISTENT 4026 +#define F_SPG_TEXT_CONFIG 4027 +#define F_SPG_TEXT_CHOOSE 4028 +#define F_SPG_TEXT_PICKSPLIT 4029 +#define F_SPG_TEXT_INNER_CONSISTENT 4030 +#define F_SPG_TEXT_LEAF_CONSISTENT 4031 +#define F_PG_SEQUENCE_LAST_VALUE 4032 +#define F_JSONB_NE 4038 +#define F_JSONB_LT 4039 +#define F_JSONB_GT 4040 +#define F_JSONB_LE 4041 +#define F_JSONB_GE 4042 +#define F_JSONB_EQ 4043 +#define F_JSONB_CMP 4044 +#define F_JSONB_HASH 4045 +#define F_JSONB_CONTAINS 4046 +#define F_JSONB_EXISTS 4047 +#define F_JSONB_EXISTS_ANY 4048 +#define F_JSONB_EXISTS_ALL 4049 +#define F_JSONB_CONTAINED 4050 +#define F_ARRAY_AGG_ARRAY_TRANSFN 4051 +#define F_ARRAY_AGG_ARRAY_FINALFN 4052 +#define F_ARRAY_AGG_ANYARRAY 4053 +#define F_RANGE_MERGE_ANYRANGE_ANYRANGE 4057 +#define F_INET_MERGE 4063 +#define F_BOUND_BOX 4067 +#define F_INET_SAME_FAMILY 4071 +#define F_BINARY_UPGRADE_SET_RECORD_INIT_PRIVS 4083 +#define F_REGNAMESPACEIN 4084 +#define F_REGNAMESPACEOUT 4085 +#define F_TO_REGNAMESPACE 4086 +#define F_REGNAMESPACERECV 4087 +#define F_REGNAMESPACESEND 4088 +#define F_BOX_POINT 4091 +#define F_REGROLEOUT 4092 +#define F_TO_REGROLE 4093 +#define F_REGROLERECV 4094 +#define F_REGROLESEND 4095 +#define F_REGROLEIN 4098 +#define F_PG_ROTATE_LOGFILE_OLD 4099 +#define F_PG_READ_FILE_OLD 4100 +#define F_BINARY_UPGRADE_SET_MISSING_VALUE 4101 +#define F_BRIN_INCLUSION_OPCINFO 4105 +#define F_BRIN_INCLUSION_ADD_VALUE 4106 +#define F_BRIN_INCLUSION_CONSISTENT 4107 +#define F_BRIN_INCLUSION_UNION 4108 +#define F_MACADDR8_IN 4110 +#define F_MACADDR8_OUT 4111 +#define F_TRUNC_MACADDR8 4112 +#define F_MACADDR8_EQ 4113 +#define F_MACADDR8_LT 4114 +#define F_MACADDR8_LE 4115 +#define F_MACADDR8_GT 4116 +#define F_MACADDR8_GE 4117 +#define F_MACADDR8_NE 4118 +#define F_MACADDR8_CMP 4119 +#define F_MACADDR8_NOT 4120 +#define F_MACADDR8_AND 4121 +#define F_MACADDR8_OR 4122 +#define F_MACADDR8 4123 +#define F_MACADDR 4124 +#define F_MACADDR8_SET7BIT 4125 +#define F_IN_RANGE_INT8_INT8_INT8_BOOL_BOOL 4126 +#define F_IN_RANGE_INT4_INT4_INT8_BOOL_BOOL 4127 +#define F_IN_RANGE_INT4_INT4_INT4_BOOL_BOOL 4128 +#define F_IN_RANGE_INT4_INT4_INT2_BOOL_BOOL 4129 +#define F_IN_RANGE_INT2_INT2_INT8_BOOL_BOOL 4130 +#define F_IN_RANGE_INT2_INT2_INT4_BOOL_BOOL 4131 +#define F_IN_RANGE_INT2_INT2_INT2_BOOL_BOOL 4132 +#define F_IN_RANGE_DATE_DATE_INTERVAL_BOOL_BOOL 4133 +#define F_IN_RANGE_TIMESTAMP_TIMESTAMP_INTERVAL_BOOL_BOOL 4134 +#define F_IN_RANGE_TIMESTAMPTZ_TIMESTAMPTZ_INTERVAL_BOOL_BOOL 4135 +#define F_IN_RANGE_INTERVAL_INTERVAL_INTERVAL_BOOL_BOOL 4136 +#define F_IN_RANGE_TIME_TIME_INTERVAL_BOOL_BOOL 4137 +#define F_IN_RANGE_TIMETZ_TIMETZ_INTERVAL_BOOL_BOOL 4138 +#define F_IN_RANGE_FLOAT8_FLOAT8_FLOAT8_BOOL_BOOL 4139 +#define F_IN_RANGE_FLOAT4_FLOAT4_FLOAT8_BOOL_BOOL 4140 +#define F_IN_RANGE_NUMERIC_NUMERIC_NUMERIC_BOOL_BOOL 4141 +#define F_PG_LSN_LARGER 4187 +#define F_PG_LSN_SMALLER 4188 +#define F_MAX_PG_LSN 4189 +#define F_MIN_PG_LSN 4190 +#define F_REGCOLLATIONIN 4193 +#define F_REGCOLLATIONOUT 4194 +#define F_TO_REGCOLLATION 4195 +#define F_REGCOLLATIONRECV 4196 +#define F_REGCOLLATIONSEND 4197 +#define F_TS_HEADLINE_REGCONFIG_JSONB_TSQUERY_TEXT 4201 +#define F_TS_HEADLINE_REGCONFIG_JSONB_TSQUERY 4202 +#define F_TS_HEADLINE_JSONB_TSQUERY_TEXT 4203 +#define F_TS_HEADLINE_JSONB_TSQUERY 4204 +#define F_TS_HEADLINE_REGCONFIG_JSON_TSQUERY_TEXT 4205 +#define F_TS_HEADLINE_REGCONFIG_JSON_TSQUERY 4206 +#define F_TS_HEADLINE_JSON_TSQUERY_TEXT 4207 +#define F_TS_HEADLINE_JSON_TSQUERY 4208 +#define F_TO_TSVECTOR_JSONB 4209 +#define F_TO_TSVECTOR_JSON 4210 +#define F_TO_TSVECTOR_REGCONFIG_JSONB 4211 +#define F_TO_TSVECTOR_REGCONFIG_JSON 4212 +#define F_JSONB_TO_TSVECTOR_JSONB_JSONB 4213 +#define F_JSONB_TO_TSVECTOR_REGCONFIG_JSONB_JSONB 4214 +#define F_JSON_TO_TSVECTOR_JSON_JSONB 4215 +#define F_JSON_TO_TSVECTOR_REGCONFIG_JSON_JSONB 4216 +#define F_PG_COPY_PHYSICAL_REPLICATION_SLOT_NAME_NAME_BOOL 4220 +#define F_PG_COPY_PHYSICAL_REPLICATION_SLOT_NAME_NAME 4221 +#define F_PG_COPY_LOGICAL_REPLICATION_SLOT_NAME_NAME_BOOL_NAME 4222 +#define F_PG_COPY_LOGICAL_REPLICATION_SLOT_NAME_NAME_BOOL 4223 +#define F_PG_COPY_LOGICAL_REPLICATION_SLOT_NAME_NAME 4224 +#define F_ANYCOMPATIBLEMULTIRANGE_IN 4226 +#define F_ANYCOMPATIBLEMULTIRANGE_OUT 4227 +#define F_RANGE_MERGE_ANYMULTIRANGE 4228 +#define F_ANYMULTIRANGE_IN 4229 +#define F_ANYMULTIRANGE_OUT 4230 +#define F_MULTIRANGE_IN 4231 +#define F_MULTIRANGE_OUT 4232 +#define F_MULTIRANGE_RECV 4233 +#define F_MULTIRANGE_SEND 4234 +#define F_LOWER_ANYMULTIRANGE 4235 +#define F_UPPER_ANYMULTIRANGE 4236 +#define F_ISEMPTY_ANYMULTIRANGE 4237 +#define F_LOWER_INC_ANYMULTIRANGE 4238 +#define F_UPPER_INC_ANYMULTIRANGE 4239 +#define F_LOWER_INF_ANYMULTIRANGE 4240 +#define F_UPPER_INF_ANYMULTIRANGE 4241 +#define F_MULTIRANGE_TYPANALYZE 4242 +#define F_MULTIRANGESEL 4243 +#define F_MULTIRANGE_EQ 4244 +#define F_MULTIRANGE_NE 4245 +#define F_RANGE_OVERLAPS_MULTIRANGE 4246 +#define F_MULTIRANGE_OVERLAPS_RANGE 4247 +#define F_MULTIRANGE_OVERLAPS_MULTIRANGE 4248 +#define F_MULTIRANGE_CONTAINS_ELEM 4249 +#define F_MULTIRANGE_CONTAINS_RANGE 4250 +#define F_MULTIRANGE_CONTAINS_MULTIRANGE 4251 +#define F_ELEM_CONTAINED_BY_MULTIRANGE 4252 +#define F_RANGE_CONTAINED_BY_MULTIRANGE 4253 +#define F_MULTIRANGE_CONTAINED_BY_MULTIRANGE 4254 +#define F_RANGE_ADJACENT_MULTIRANGE 4255 +#define F_MULTIRANGE_ADJACENT_MULTIRANGE 4256 +#define F_MULTIRANGE_ADJACENT_RANGE 4257 +#define F_RANGE_BEFORE_MULTIRANGE 4258 +#define F_MULTIRANGE_BEFORE_RANGE 4259 +#define F_MULTIRANGE_BEFORE_MULTIRANGE 4260 +#define F_RANGE_AFTER_MULTIRANGE 4261 +#define F_MULTIRANGE_AFTER_RANGE 4262 +#define F_MULTIRANGE_AFTER_MULTIRANGE 4263 +#define F_RANGE_OVERLEFT_MULTIRANGE 4264 +#define F_MULTIRANGE_OVERLEFT_RANGE 4265 +#define F_MULTIRANGE_OVERLEFT_MULTIRANGE 4266 +#define F_RANGE_OVERRIGHT_MULTIRANGE 4267 +#define F_MULTIRANGE_OVERRIGHT_RANGE 4268 +#define F_MULTIRANGE_OVERRIGHT_MULTIRANGE 4269 +#define F_MULTIRANGE_UNION 4270 +#define F_MULTIRANGE_MINUS 4271 +#define F_MULTIRANGE_INTERSECT 4272 +#define F_MULTIRANGE_CMP 4273 +#define F_MULTIRANGE_LT 4274 +#define F_MULTIRANGE_LE 4275 +#define F_MULTIRANGE_GE 4276 +#define F_MULTIRANGE_GT 4277 +#define F_HASH_MULTIRANGE 4278 +#define F_HASH_MULTIRANGE_EXTENDED 4279 +#define F_INT4MULTIRANGE_ 4280 +#define F_INT4MULTIRANGE_INT4RANGE 4281 +#define F_INT4MULTIRANGE__INT4RANGE 4282 +#define F_NUMMULTIRANGE_ 4283 +#define F_NUMMULTIRANGE_NUMRANGE 4284 +#define F_NUMMULTIRANGE__NUMRANGE 4285 +#define F_TSMULTIRANGE_ 4286 +#define F_TSMULTIRANGE_TSRANGE 4287 +#define F_TSMULTIRANGE__TSRANGE 4288 +#define F_TSTZMULTIRANGE_ 4289 +#define F_TSTZMULTIRANGE_TSTZRANGE 4290 +#define F_TSTZMULTIRANGE__TSTZRANGE 4291 +#define F_DATEMULTIRANGE_ 4292 +#define F_DATEMULTIRANGE_DATERANGE 4293 +#define F_DATEMULTIRANGE__DATERANGE 4294 +#define F_INT8MULTIRANGE_ 4295 +#define F_INT8MULTIRANGE_INT8RANGE 4296 +#define F_INT8MULTIRANGE__INT8RANGE 4297 +#define F_MULTIRANGE 4298 +#define F_RANGE_AGG_TRANSFN 4299 +#define F_RANGE_AGG_FINALFN 4300 +#define F_RANGE_AGG_ANYRANGE 4301 +#define F_KOI8R_TO_MIC 4302 +#define F_MIC_TO_KOI8R 4303 +#define F_ISO_TO_MIC 4304 +#define F_MIC_TO_ISO 4305 +#define F_WIN1251_TO_MIC 4306 +#define F_MIC_TO_WIN1251 4307 +#define F_WIN866_TO_MIC 4308 +#define F_MIC_TO_WIN866 4309 +#define F_KOI8R_TO_WIN1251 4310 +#define F_WIN1251_TO_KOI8R 4311 +#define F_KOI8R_TO_WIN866 4312 +#define F_WIN866_TO_KOI8R 4313 +#define F_WIN866_TO_WIN1251 4314 +#define F_WIN1251_TO_WIN866 4315 +#define F_ISO_TO_KOI8R 4316 +#define F_KOI8R_TO_ISO 4317 +#define F_ISO_TO_WIN1251 4318 +#define F_WIN1251_TO_ISO 4319 +#define F_ISO_TO_WIN866 4320 +#define F_WIN866_TO_ISO 4321 +#define F_EUC_CN_TO_MIC 4322 +#define F_MIC_TO_EUC_CN 4323 +#define F_EUC_JP_TO_SJIS 4324 +#define F_SJIS_TO_EUC_JP 4325 +#define F_EUC_JP_TO_MIC 4326 +#define F_SJIS_TO_MIC 4327 +#define F_MIC_TO_EUC_JP 4328 +#define F_MIC_TO_SJIS 4329 +#define F_EUC_KR_TO_MIC 4330 +#define F_MIC_TO_EUC_KR 4331 +#define F_EUC_TW_TO_BIG5 4332 +#define F_BIG5_TO_EUC_TW 4333 +#define F_EUC_TW_TO_MIC 4334 +#define F_BIG5_TO_MIC 4335 +#define F_MIC_TO_EUC_TW 4336 +#define F_MIC_TO_BIG5 4337 +#define F_LATIN2_TO_MIC 4338 +#define F_MIC_TO_LATIN2 4339 +#define F_WIN1250_TO_MIC 4340 +#define F_MIC_TO_WIN1250 4341 +#define F_LATIN2_TO_WIN1250 4342 +#define F_WIN1250_TO_LATIN2 4343 +#define F_LATIN1_TO_MIC 4344 +#define F_MIC_TO_LATIN1 4345 +#define F_LATIN3_TO_MIC 4346 +#define F_MIC_TO_LATIN3 4347 +#define F_LATIN4_TO_MIC 4348 +#define F_MIC_TO_LATIN4 4349 +#define F_NORMALIZE 4350 +#define F_IS_NORMALIZED 4351 +#define F_BIG5_TO_UTF8 4352 +#define F_UTF8_TO_BIG5 4353 +#define F_UTF8_TO_KOI8R 4354 +#define F_KOI8R_TO_UTF8 4355 +#define F_UTF8_TO_KOI8U 4356 +#define F_KOI8U_TO_UTF8 4357 +#define F_UTF8_TO_WIN 4358 +#define F_WIN_TO_UTF8 4359 +#define F_EUC_CN_TO_UTF8 4360 +#define F_UTF8_TO_EUC_CN 4361 +#define F_EUC_JP_TO_UTF8 4362 +#define F_UTF8_TO_EUC_JP 4363 +#define F_EUC_KR_TO_UTF8 4364 +#define F_UTF8_TO_EUC_KR 4365 +#define F_EUC_TW_TO_UTF8 4366 +#define F_UTF8_TO_EUC_TW 4367 +#define F_GB18030_TO_UTF8 4368 +#define F_UTF8_TO_GB18030 4369 +#define F_GBK_TO_UTF8 4370 +#define F_UTF8_TO_GBK 4371 +#define F_UTF8_TO_ISO8859 4372 +#define F_ISO8859_TO_UTF8 4373 +#define F_ISO8859_1_TO_UTF8 4374 +#define F_UTF8_TO_ISO8859_1 4375 +#define F_JOHAB_TO_UTF8 4376 +#define F_UTF8_TO_JOHAB 4377 +#define F_SJIS_TO_UTF8 4378 +#define F_UTF8_TO_SJIS 4379 +#define F_UHC_TO_UTF8 4380 +#define F_UTF8_TO_UHC 4381 +#define F_EUC_JIS_2004_TO_UTF8 4382 +#define F_UTF8_TO_EUC_JIS_2004 4383 +#define F_SHIFT_JIS_2004_TO_UTF8 4384 +#define F_UTF8_TO_SHIFT_JIS_2004 4385 +#define F_EUC_JIS_2004_TO_SHIFT_JIS_2004 4386 +#define F_SHIFT_JIS_2004_TO_EUC_JIS_2004 4387 +#define F_MULTIRANGE_INTERSECT_AGG_TRANSFN 4388 +#define F_RANGE_INTERSECT_AGG_ANYMULTIRANGE 4389 +#define F_BINARY_UPGRADE_SET_NEXT_MULTIRANGE_PG_TYPE_OID 4390 +#define F_BINARY_UPGRADE_SET_NEXT_MULTIRANGE_ARRAY_PG_TYPE_OID 4391 +#define F_RANGE_INTERSECT_AGG_TRANSFN 4401 +#define F_RANGE_INTERSECT_AGG_ANYRANGE 4450 +#define F_RANGE_CONTAINS_MULTIRANGE 4541 +#define F_MULTIRANGE_CONTAINED_BY_RANGE 4542 +#define F_PG_LOG_BACKEND_MEMORY_CONTEXTS 4543 +#define F_BINARY_UPGRADE_SET_NEXT_HEAP_RELFILENODE 4545 +#define F_BINARY_UPGRADE_SET_NEXT_INDEX_RELFILENODE 4546 +#define F_BINARY_UPGRADE_SET_NEXT_TOAST_RELFILENODE 4547 +#define F_BINARY_UPGRADE_SET_NEXT_PG_TABLESPACE_OID 4548 +#define F_PG_EVENT_TRIGGER_TABLE_REWRITE_OID 4566 +#define F_PG_EVENT_TRIGGER_TABLE_REWRITE_REASON 4567 +#define F_PG_EVENT_TRIGGER_DDL_COMMANDS 4568 +#define F_BRIN_BLOOM_OPCINFO 4591 +#define F_BRIN_BLOOM_ADD_VALUE 4592 +#define F_BRIN_BLOOM_CONSISTENT 4593 +#define F_BRIN_BLOOM_UNION 4594 +#define F_BRIN_BLOOM_OPTIONS 4595 +#define F_BRIN_BLOOM_SUMMARY_IN 4596 +#define F_BRIN_BLOOM_SUMMARY_OUT 4597 +#define F_BRIN_BLOOM_SUMMARY_RECV 4598 +#define F_BRIN_BLOOM_SUMMARY_SEND 4599 +#define F_BRIN_MINMAX_MULTI_OPCINFO 4616 +#define F_BRIN_MINMAX_MULTI_ADD_VALUE 4617 +#define F_BRIN_MINMAX_MULTI_CONSISTENT 4618 +#define F_BRIN_MINMAX_MULTI_UNION 4619 +#define F_BRIN_MINMAX_MULTI_OPTIONS 4620 +#define F_BRIN_MINMAX_MULTI_DISTANCE_INT2 4621 +#define F_BRIN_MINMAX_MULTI_DISTANCE_INT4 4622 +#define F_BRIN_MINMAX_MULTI_DISTANCE_INT8 4623 +#define F_BRIN_MINMAX_MULTI_DISTANCE_FLOAT4 4624 +#define F_BRIN_MINMAX_MULTI_DISTANCE_FLOAT8 4625 +#define F_BRIN_MINMAX_MULTI_DISTANCE_NUMERIC 4626 +#define F_BRIN_MINMAX_MULTI_DISTANCE_TID 4627 +#define F_BRIN_MINMAX_MULTI_DISTANCE_UUID 4628 +#define F_BRIN_MINMAX_MULTI_DISTANCE_DATE 4629 +#define F_BRIN_MINMAX_MULTI_DISTANCE_TIME 4630 +#define F_BRIN_MINMAX_MULTI_DISTANCE_INTERVAL 4631 +#define F_BRIN_MINMAX_MULTI_DISTANCE_TIMETZ 4632 +#define F_BRIN_MINMAX_MULTI_DISTANCE_PG_LSN 4633 +#define F_BRIN_MINMAX_MULTI_DISTANCE_MACADDR 4634 +#define F_BRIN_MINMAX_MULTI_DISTANCE_MACADDR8 4635 +#define F_BRIN_MINMAX_MULTI_DISTANCE_INET 4636 +#define F_BRIN_MINMAX_MULTI_DISTANCE_TIMESTAMP 4637 +#define F_BRIN_MINMAX_MULTI_SUMMARY_IN 4638 +#define F_BRIN_MINMAX_MULTI_SUMMARY_OUT 4639 +#define F_BRIN_MINMAX_MULTI_SUMMARY_RECV 4640 +#define F_BRIN_MINMAX_MULTI_SUMMARY_SEND 4641 +#define F_PHRASETO_TSQUERY_TEXT 5001 +#define F_TSQUERY_PHRASE_TSQUERY_TSQUERY 5003 +#define F_TSQUERY_PHRASE_TSQUERY_TSQUERY_INT4 5004 +#define F_PHRASETO_TSQUERY_REGCONFIG_TEXT 5006 +#define F_WEBSEARCH_TO_TSQUERY_REGCONFIG_TEXT 5007 +#define F_WEBSEARCH_TO_TSQUERY_TEXT 5009 +#define F_SPG_BBOX_QUAD_CONFIG 5010 +#define F_SPG_POLY_QUAD_COMPRESS 5011 +#define F_SPG_BOX_QUAD_CONFIG 5012 +#define F_SPG_BOX_QUAD_CHOOSE 5013 +#define F_SPG_BOX_QUAD_PICKSPLIT 5014 +#define F_SPG_BOX_QUAD_INNER_CONSISTENT 5015 +#define F_SPG_BOX_QUAD_LEAF_CONSISTENT 5016 +#define F_PG_MCV_LIST_IN 5018 +#define F_PG_MCV_LIST_OUT 5019 +#define F_PG_MCV_LIST_RECV 5020 +#define F_PG_MCV_LIST_SEND 5021 +#define F_PG_LSN_PLI 5022 +#define F_NUMERIC_PL_PG_LSN 5023 +#define F_PG_LSN_MII 5024 +#define F_SATISFIES_HASH_PARTITION 5028 +#define F_PG_LS_TMPDIR_ 5029 +#define F_PG_LS_TMPDIR_OID 5030 +#define F_PG_LS_ARCHIVE_STATUSDIR 5031 +#define F_NETWORK_SORTSUPPORT 5033 +#define F_XID8LT 5034 +#define F_XID8GT 5035 +#define F_XID8LE 5036 +#define F_XID8GE 5037 +#define F_MATCHINGSEL 5040 +#define F_MATCHINGJOINSEL 5041 +#define F_MIN_SCALE 5042 +#define F_TRIM_SCALE 5043 +#define F_GCD_INT4_INT4 5044 +#define F_GCD_INT8_INT8 5045 +#define F_LCM_INT4_INT4 5046 +#define F_LCM_INT8_INT8 5047 +#define F_GCD_NUMERIC_NUMERIC 5048 +#define F_LCM_NUMERIC_NUMERIC 5049 +#define F_BTVARSTREQUALIMAGE 5050 +#define F_BTEQUALIMAGE 5051 +#define F_PG_GET_SHMEM_ALLOCATIONS 5052 +#define F_PG_STAT_GET_INS_SINCE_VACUUM 5053 +#define F_JSONB_SET_LAX 5054 +#define F_PG_SNAPSHOT_IN 5055 +#define F_PG_SNAPSHOT_OUT 5056 +#define F_PG_SNAPSHOT_RECV 5057 +#define F_PG_SNAPSHOT_SEND 5058 +#define F_PG_CURRENT_XACT_ID 5059 +#define F_PG_CURRENT_XACT_ID_IF_ASSIGNED 5060 +#define F_PG_CURRENT_SNAPSHOT 5061 +#define F_PG_SNAPSHOT_XMIN 5062 +#define F_PG_SNAPSHOT_XMAX 5063 +#define F_PG_SNAPSHOT_XIP 5064 +#define F_PG_VISIBLE_IN_SNAPSHOT 5065 +#define F_PG_XACT_STATUS 5066 +#define F_XID8IN 5070 +#define F_XID 5071 +#define F_XID8OUT 5081 +#define F_XID8RECV 5082 +#define F_XID8SEND 5083 +#define F_XID8EQ 5084 +#define F_XID8NE 5085 +#define F_ANYCOMPATIBLE_IN 5086 +#define F_ANYCOMPATIBLE_OUT 5087 +#define F_ANYCOMPATIBLEARRAY_IN 5088 +#define F_ANYCOMPATIBLEARRAY_OUT 5089 +#define F_ANYCOMPATIBLEARRAY_RECV 5090 +#define F_ANYCOMPATIBLEARRAY_SEND 5091 +#define F_ANYCOMPATIBLENONARRAY_IN 5092 +#define F_ANYCOMPATIBLENONARRAY_OUT 5093 +#define F_ANYCOMPATIBLERANGE_IN 5094 +#define F_ANYCOMPATIBLERANGE_OUT 5095 +#define F_XID8CMP 5096 +#define F_XID8_LARGER 5097 +#define F_XID8_SMALLER 5098 +#define F_MAX_XID8 5099 +#define F_MIN_XID8 5100 +#define F_PG_REPLICATION_ORIGIN_CREATE 6003 +#define F_PG_REPLICATION_ORIGIN_DROP 6004 +#define F_PG_REPLICATION_ORIGIN_OID 6005 +#define F_PG_REPLICATION_ORIGIN_SESSION_SETUP 6006 +#define F_PG_REPLICATION_ORIGIN_SESSION_RESET 6007 +#define F_PG_REPLICATION_ORIGIN_SESSION_IS_SETUP 6008 +#define F_PG_REPLICATION_ORIGIN_SESSION_PROGRESS 6009 +#define F_PG_REPLICATION_ORIGIN_XACT_SETUP 6010 +#define F_PG_REPLICATION_ORIGIN_XACT_RESET 6011 +#define F_PG_REPLICATION_ORIGIN_ADVANCE 6012 +#define F_PG_REPLICATION_ORIGIN_PROGRESS 6013 +#define F_PG_SHOW_REPLICATION_ORIGIN_STATUS 6014 +#define F_JSONB_SUBSCRIPT_HANDLER 6098 +#define F_PG_LSN 6103 +#define F_PG_STAT_GET_BACKEND_SUBXACT 6107 +#define F_PG_STAT_GET_SUBSCRIPTION 6118 +#define F_PG_GET_PUBLICATION_TABLES 6119 +#define F_PG_GET_REPLICA_IDENTITY_INDEX 6120 +#define F_PG_RELATION_IS_PUBLISHABLE 6121 +#define F_MULTIRANGE_GIST_CONSISTENT 6154 +#define F_MULTIRANGE_GIST_COMPRESS 6156 +#define F_PG_GET_CATALOG_FOREIGN_KEYS 6159 +#define F_STRING_TO_TABLE_TEXT_TEXT 6160 +#define F_STRING_TO_TABLE_TEXT_TEXT_TEXT 6161 +#define F_BIT_COUNT_BIT 6162 +#define F_BIT_COUNT_BYTEA 6163 +#define F_BIT_XOR_INT2 6164 +#define F_BIT_XOR_INT4 6165 +#define F_BIT_XOR_INT8 6166 +#define F_BIT_XOR_BIT 6167 +#define F_PG_XACT_COMMIT_TIMESTAMP_ORIGIN 6168 +#define F_PG_STAT_GET_REPLICATION_SLOT 6169 +#define F_PG_STAT_RESET_REPLICATION_SLOT 6170 +#define F_TRIM_ARRAY 6172 +#define F_PG_GET_STATISTICSOBJDEF_EXPRESSIONS 6173 +#define F_PG_GET_STATISTICSOBJDEF_COLUMNS 6174 +#define F_DATE_BIN_INTERVAL_TIMESTAMP_TIMESTAMP 6177 +#define F_DATE_BIN_INTERVAL_TIMESTAMPTZ_TIMESTAMPTZ 6178 +#define F_ARRAY_SUBSCRIPT_HANDLER 6179 +#define F_RAW_ARRAY_SUBSCRIPT_HANDLER 6180 +#define F_TS_DEBUG_REGCONFIG_TEXT 6183 +#define F_TS_DEBUG_TEXT 6184 +#define F_PG_STAT_GET_DB_SESSION_TIME 6185 +#define F_PG_STAT_GET_DB_ACTIVE_TIME 6186 +#define F_PG_STAT_GET_DB_IDLE_IN_TRANSACTION_TIME 6187 +#define F_PG_STAT_GET_DB_SESSIONS 6188 +#define F_PG_STAT_GET_DB_SESSIONS_ABANDONED 6189 +#define F_PG_STAT_GET_DB_SESSIONS_FATAL 6190 +#define F_PG_STAT_GET_DB_SESSIONS_KILLED 6191 +#define F_HASH_RECORD 6192 +#define F_HASH_RECORD_EXTENDED 6193 +#define F_LTRIM_BYTEA_BYTEA 6195 +#define F_RTRIM_BYTEA_BYTEA 6196 +#define F_PG_GET_FUNCTION_SQLBODY 6197 +#define F_UNISTR 6198 +#define F_EXTRACT_TEXT_DATE 6199 +#define F_EXTRACT_TEXT_TIME 6200 +#define F_EXTRACT_TEXT_TIMETZ 6201 +#define F_EXTRACT_TEXT_TIMESTAMP 6202 +#define F_EXTRACT_TEXT_TIMESTAMPTZ 6203 +#define F_EXTRACT_TEXT_INTERVAL 6204 +#define F_HAS_PARAMETER_PRIVILEGE_NAME_TEXT_TEXT 6205 +#define F_HAS_PARAMETER_PRIVILEGE_OID_TEXT_TEXT 6206 +#define F_HAS_PARAMETER_PRIVILEGE_TEXT_TEXT 6207 +#define F_PG_READ_FILE_TEXT_BOOL 6208 +#define F_PG_READ_BINARY_FILE_TEXT_BOOL 6209 +#define F_PG_INPUT_IS_VALID 6210 +#define F_PG_INPUT_ERROR_INFO 6211 +#define F_RANDOM_NORMAL 6212 +#define F_PG_SPLIT_WALFILE_NAME 6213 +#define F_PG_STAT_GET_IO 6214 +#define F_ARRAY_SHUFFLE 6215 +#define F_ARRAY_SAMPLE 6216 +#define F_PG_STAT_GET_TUPLES_NEWPAGE_UPDATED 6217 +#define F_PG_STAT_GET_XACT_TUPLES_NEWPAGE_UPDATED 6218 +#define F_ERF 6219 +#define F_ERFC 6220 +#define F_DATE_ADD_TIMESTAMPTZ_INTERVAL 6221 +#define F_DATE_ADD_TIMESTAMPTZ_INTERVAL_TEXT 6222 +#define F_DATE_SUBTRACT_TIMESTAMPTZ_INTERVAL 6223 +#define F_PG_GET_WAL_RESOURCE_MANAGERS 6224 +#define F_MULTIRANGE_AGG_TRANSFN 6225 +#define F_MULTIRANGE_AGG_FINALFN 6226 +#define F_RANGE_AGG_ANYMULTIRANGE 6227 +#define F_PG_STAT_HAVE_STATS 6230 +#define F_PG_STAT_GET_SUBSCRIPTION_STATS 6231 +#define F_PG_STAT_RESET_SUBSCRIPTION_STATS 6232 +#define F_WINDOW_ROW_NUMBER_SUPPORT 6233 +#define F_WINDOW_RANK_SUPPORT 6234 +#define F_WINDOW_DENSE_RANK_SUPPORT 6235 +#define F_INT8INC_SUPPORT 6236 +#define F_PG_SETTINGS_GET_FLAGS 6240 +#define F_PG_STOP_MAKING_PINNED_OBJECTS 6241 +#define F_TEXT_STARTS_WITH_SUPPORT 6242 +#define F_PG_STAT_GET_RECOVERY_PREFETCH 6248 +#define F_PG_DATABASE_COLLATION_ACTUAL_VERSION 6249 +#define F_PG_IDENT_FILE_MAPPINGS 6250 +#define F_REGEXP_REPLACE_TEXT_TEXT_TEXT_INT4_INT4_TEXT 6251 +#define F_REGEXP_REPLACE_TEXT_TEXT_TEXT_INT4_INT4 6252 +#define F_REGEXP_REPLACE_TEXT_TEXT_TEXT_INT4 6253 +#define F_REGEXP_COUNT_TEXT_TEXT 6254 +#define F_REGEXP_COUNT_TEXT_TEXT_INT4 6255 +#define F_REGEXP_COUNT_TEXT_TEXT_INT4_TEXT 6256 +#define F_REGEXP_INSTR_TEXT_TEXT 6257 +#define F_REGEXP_INSTR_TEXT_TEXT_INT4 6258 +#define F_REGEXP_INSTR_TEXT_TEXT_INT4_INT4 6259 +#define F_REGEXP_INSTR_TEXT_TEXT_INT4_INT4_INT4 6260 +#define F_REGEXP_INSTR_TEXT_TEXT_INT4_INT4_INT4_TEXT 6261 +#define F_REGEXP_INSTR_TEXT_TEXT_INT4_INT4_INT4_TEXT_INT4 6262 +#define F_REGEXP_LIKE_TEXT_TEXT 6263 +#define F_REGEXP_LIKE_TEXT_TEXT_TEXT 6264 +#define F_REGEXP_SUBSTR_TEXT_TEXT 6265 +#define F_REGEXP_SUBSTR_TEXT_TEXT_INT4 6266 +#define F_REGEXP_SUBSTR_TEXT_TEXT_INT4_INT4 6267 +#define F_REGEXP_SUBSTR_TEXT_TEXT_INT4_INT4_TEXT 6268 +#define F_REGEXP_SUBSTR_TEXT_TEXT_INT4_INT4_TEXT_INT4 6269 +#define F_PG_LS_LOGICALSNAPDIR 6270 +#define F_PG_LS_LOGICALMAPDIR 6271 +#define F_PG_LS_REPLSLOTDIR 6272 +#define F_DATE_SUBTRACT_TIMESTAMPTZ_INTERVAL_TEXT 6273 +#define F_GENERATE_SERIES_TIMESTAMPTZ_TIMESTAMPTZ_INTERVAL_TEXT 6274 +#define F_JSON_AGG_STRICT_TRANSFN 6275 +#define F_JSON_AGG_STRICT 6276 +#define F_JSON_OBJECT_AGG_STRICT_TRANSFN 6277 +#define F_JSON_OBJECT_AGG_UNIQUE_TRANSFN 6278 +#define F_JSON_OBJECT_AGG_UNIQUE_STRICT_TRANSFN 6279 +#define F_JSON_OBJECT_AGG_STRICT 6280 +#define F_JSON_OBJECT_AGG_UNIQUE 6281 +#define F_JSON_OBJECT_AGG_UNIQUE_STRICT 6282 +#define F_JSONB_AGG_STRICT_TRANSFN 6283 +#define F_JSONB_AGG_STRICT 6284 +#define F_JSONB_OBJECT_AGG_STRICT_TRANSFN 6285 +#define F_JSONB_OBJECT_AGG_UNIQUE_TRANSFN 6286 +#define F_JSONB_OBJECT_AGG_UNIQUE_STRICT_TRANSFN 6287 +#define F_JSONB_OBJECT_AGG_STRICT 6288 +#define F_JSONB_OBJECT_AGG_UNIQUE 6289 +#define F_JSONB_OBJECT_AGG_UNIQUE_STRICT 6290 +#define F_ANY_VALUE 6291 +#define F_ANY_VALUE_TRANSFN 6292 +#define F_ARRAY_AGG_COMBINE 6293 +#define F_ARRAY_AGG_SERIALIZE 6294 +#define F_ARRAY_AGG_DESERIALIZE 6295 +#define F_ARRAY_AGG_ARRAY_COMBINE 6296 +#define F_ARRAY_AGG_ARRAY_SERIALIZE 6297 +#define F_ARRAY_AGG_ARRAY_DESERIALIZE 6298 +#define F_STRING_AGG_COMBINE 6299 +#define F_STRING_AGG_SERIALIZE 6300 +#define F_STRING_AGG_DESERIALIZE 6301 +#define F_PG_LOG_STANDBY_SNAPSHOT 6305 +#define F_WINDOW_PERCENT_RANK_SUPPORT 6306 +#define F_WINDOW_CUME_DIST_SUPPORT 6307 +#define F_WINDOW_NTILE_SUPPORT 6308 +#define F_PG_STAT_GET_DB_CONFLICT_LOGICALSLOT 6309 +#define F_PG_STAT_GET_LASTSCAN 6310 +#define F_SYSTEM_USER 6311 +#define F_CLUSTER_GET_WAIT_EVENTS 8898 +#define F_CLUSTER_GET_GCLUSTER_WAIT_EVENTS 8899 +#define F_CLUSTER_GET_NODES 8900 +#define F_CLUSTER_IC_MOCK_INJECT 8901 +#define F_CLUSTER_IC_MOCK_DRAIN_OUTBOUND 8902 +#define F_CLUSTER_IC_MOCK_CLEAR_ALL 8903 +#define F_CLUSTER_IC_MOCK_RECV_TEST 8904 +#define F_CLUSTER_INJECT_FAULT 8905 +#define F_CLUSTER_GET_INJECTION_STATE 8906 +#define F_CLUSTER_GET_STAT_NODES 8907 +#define F_CLUSTER_GET_PGSTAT_COUNTERS 8908 +#define F_CLUSTER_DUMP_STATE 8909 +#define F_CLUSTER_SHMEM_DUMP_REGIONS 8910 +#define F_CLUSTER_SCN_ADVANCE 8911 +#define F_CLUSTER_SCN_CURRENT 8912 +#define F_CLUSTER_SCN_OBSERVE 8913 +#define F_CLUSTER_GET_IC_PEERS 8914 +#define F_CLUSTER_GET_IC_MSG_TYPES 8915 +#define F_CLUSTER_GET_CSSD_PEERS 8916 +#define F_CLUSTER_GET_QUORUM_STATE 8917 +#define F_CLUSTER_GET_VOTING_DISKS 8918 +#define F_CLUSTER_GET_FENCE_STATE 8919 +#define F_CLUSTER_GET_RECONFIG_STATE 8920 +#define F_CLUSTER_GET_GRD_SHARDS 8921 +#define F_CLUSTER_GET_GRD_ENTRIES 8922 +#define F_CLUSTER_GET_LMD_STATE 8923 +#define F_PG_CLUSTER_LMD_INJECT_WAIT_EDGE 8924 +#define F_CLUSTER_TEST_INJECT_VISIBILITY_TT_REF 8925 +#define F_CLUSTER_TEST_CLEAR_VISIBILITY_INJECTS 8926 +#define F_CLUSTER_TEST_INJECT_SUBTRANS_SUBCOMMITTED 8927 +#define F_CLUSTER_UNDO_GET_RECORD 8928 +#define F_CLUSTER_UNDO_TEST_FORCE_SEGMENT_END 8929 +#define F_CLUSTER_CR_TEST_CONSTRUCT 8930 +#define F_CLUSTER_CR_TEST_IMAGE 8931 +#define F_CLUSTER_BLOCK_APPLY_REDO_TEST 8932 +#define F_CLUSTER_BLOCK_RECOVERY_RECONSTRUCT_TEST 8933 +#define F_CLUSTER_THREAD_APPLY_REDO_TEST 8934 +#define F_CLUSTER_THREAD_REPLAY_TEST 8935 +#define F_CLUSTER_THREAD_DRIVE_TEST 8936 +#define F_CLUSTER_THREAD_REPLAY_ONE_TEST 8937 +#define F_CLUSTER_THREAD_REPLAY_ONE_AUTO_TEST 8938 +#define F_CLUSTER_THREAD_LOCAL_COMPLETE_TEST 8939 +#define F_CLUSTER_THREAD_GATE_UNFREEZE_TEST 8940 +#define F_CLUSTER_THREAD_VALIDATED_END_TEST 8941 +#define F_CLUSTER_THREAD_REPLAY_SLOT_TEST 8942 +#define F_CLUSTER_THREAD_RECOVERY_WORKER_RUN_TEST 8943 +#define F_CLUSTER_THREAD_RECOVERY_LAUNCH_TEST 8944 +#define F_CLUSTER_THREAD_REPLAY_SLOT_STATE_TEST 8945 +#define F_CLUSTER_RECONFIG_INJECT_DEAD_NODE_TEST 8946 +#define F_CLUSTER_THREAD_CAPABILITY_GATE_TEST 8947 +#define F_PG_CLUSTER_GES_MODE_MATRIX 8948 +#define F_CLUSTER_GES_MODE_COMPAT 8949 +#define F_CLUSTER_GES_MODE_MATCHES_PG 8950 + +#endif /* FMGROIDS_H */ diff --git a/install/include/postgresql/server/utils/fmgrprotos.h b/install/include/postgresql/server/utils/fmgrprotos.h new file mode 100644 index 00000000000..de091899721 --- /dev/null +++ b/install/include/postgresql/server/utils/fmgrprotos.h @@ -0,0 +1,2924 @@ +/*------------------------------------------------------------------------- + * + * fmgrprotos.h + * Prototypes for built-in functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/utils/Gen_fmgrtab.pl + * + *------------------------------------------------------------------------- + */ + +#ifndef FMGRPROTOS_H +#define FMGRPROTOS_H + +#include "fmgr.h" + +extern Datum heap_tableam_handler(PG_FUNCTION_ARGS); +extern Datum byteaout(PG_FUNCTION_ARGS); +extern Datum charout(PG_FUNCTION_ARGS); +extern Datum namein(PG_FUNCTION_ARGS); +extern Datum nameout(PG_FUNCTION_ARGS); +extern Datum int2in(PG_FUNCTION_ARGS); +extern Datum int2out(PG_FUNCTION_ARGS); +extern Datum int2vectorin(PG_FUNCTION_ARGS); +extern Datum int2vectorout(PG_FUNCTION_ARGS); +extern Datum int4in(PG_FUNCTION_ARGS); +extern Datum int4out(PG_FUNCTION_ARGS); +extern Datum regprocin(PG_FUNCTION_ARGS); +extern Datum regprocout(PG_FUNCTION_ARGS); +extern Datum textin(PG_FUNCTION_ARGS); +extern Datum textout(PG_FUNCTION_ARGS); +extern Datum tidin(PG_FUNCTION_ARGS); +extern Datum tidout(PG_FUNCTION_ARGS); +extern Datum xidin(PG_FUNCTION_ARGS); +extern Datum xidout(PG_FUNCTION_ARGS); +extern Datum cidin(PG_FUNCTION_ARGS); +extern Datum cidout(PG_FUNCTION_ARGS); +extern Datum oidvectorin(PG_FUNCTION_ARGS); +extern Datum oidvectorout(PG_FUNCTION_ARGS); +extern Datum boollt(PG_FUNCTION_ARGS); +extern Datum boolgt(PG_FUNCTION_ARGS); +extern Datum booleq(PG_FUNCTION_ARGS); +extern Datum chareq(PG_FUNCTION_ARGS); +extern Datum nameeq(PG_FUNCTION_ARGS); +extern Datum int2eq(PG_FUNCTION_ARGS); +extern Datum int2lt(PG_FUNCTION_ARGS); +extern Datum int4eq(PG_FUNCTION_ARGS); +extern Datum int4lt(PG_FUNCTION_ARGS); +extern Datum texteq(PG_FUNCTION_ARGS); +extern Datum xideq(PG_FUNCTION_ARGS); +extern Datum cideq(PG_FUNCTION_ARGS); +extern Datum charne(PG_FUNCTION_ARGS); +extern Datum charle(PG_FUNCTION_ARGS); +extern Datum chargt(PG_FUNCTION_ARGS); +extern Datum charge(PG_FUNCTION_ARGS); +extern Datum chartoi4(PG_FUNCTION_ARGS); +extern Datum i4tochar(PG_FUNCTION_ARGS); +extern Datum nameregexeq(PG_FUNCTION_ARGS); +extern Datum boolne(PG_FUNCTION_ARGS); +extern Datum pg_ddl_command_in(PG_FUNCTION_ARGS); +extern Datum pg_ddl_command_out(PG_FUNCTION_ARGS); +extern Datum pg_ddl_command_recv(PG_FUNCTION_ARGS); +extern Datum pgsql_version(PG_FUNCTION_ARGS); +extern Datum pg_ddl_command_send(PG_FUNCTION_ARGS); +extern Datum eqsel(PG_FUNCTION_ARGS); +extern Datum neqsel(PG_FUNCTION_ARGS); +extern Datum scalarltsel(PG_FUNCTION_ARGS); +extern Datum scalargtsel(PG_FUNCTION_ARGS); +extern Datum eqjoinsel(PG_FUNCTION_ARGS); +extern Datum neqjoinsel(PG_FUNCTION_ARGS); +extern Datum scalarltjoinsel(PG_FUNCTION_ARGS); +extern Datum scalargtjoinsel(PG_FUNCTION_ARGS); +extern Datum unknownin(PG_FUNCTION_ARGS); +extern Datum unknownout(PG_FUNCTION_ARGS); +extern Datum box_above_eq(PG_FUNCTION_ARGS); +extern Datum box_below_eq(PG_FUNCTION_ARGS); +extern Datum point_in(PG_FUNCTION_ARGS); +extern Datum point_out(PG_FUNCTION_ARGS); +extern Datum lseg_in(PG_FUNCTION_ARGS); +extern Datum lseg_out(PG_FUNCTION_ARGS); +extern Datum path_in(PG_FUNCTION_ARGS); +extern Datum path_out(PG_FUNCTION_ARGS); +extern Datum box_in(PG_FUNCTION_ARGS); +extern Datum box_out(PG_FUNCTION_ARGS); +extern Datum box_overlap(PG_FUNCTION_ARGS); +extern Datum box_ge(PG_FUNCTION_ARGS); +extern Datum box_gt(PG_FUNCTION_ARGS); +extern Datum box_eq(PG_FUNCTION_ARGS); +extern Datum box_lt(PG_FUNCTION_ARGS); +extern Datum box_le(PG_FUNCTION_ARGS); +extern Datum point_above(PG_FUNCTION_ARGS); +extern Datum point_left(PG_FUNCTION_ARGS); +extern Datum point_right(PG_FUNCTION_ARGS); +extern Datum point_below(PG_FUNCTION_ARGS); +extern Datum point_eq(PG_FUNCTION_ARGS); +extern Datum on_pb(PG_FUNCTION_ARGS); +extern Datum on_ppath(PG_FUNCTION_ARGS); +extern Datum box_center(PG_FUNCTION_ARGS); +extern Datum areasel(PG_FUNCTION_ARGS); +extern Datum areajoinsel(PG_FUNCTION_ARGS); +extern Datum int4mul(PG_FUNCTION_ARGS); +extern Datum int4ne(PG_FUNCTION_ARGS); +extern Datum int2ne(PG_FUNCTION_ARGS); +extern Datum int2gt(PG_FUNCTION_ARGS); +extern Datum int4gt(PG_FUNCTION_ARGS); +extern Datum int2le(PG_FUNCTION_ARGS); +extern Datum int4le(PG_FUNCTION_ARGS); +extern Datum int4ge(PG_FUNCTION_ARGS); +extern Datum int2ge(PG_FUNCTION_ARGS); +extern Datum int2mul(PG_FUNCTION_ARGS); +extern Datum int2div(PG_FUNCTION_ARGS); +extern Datum int4div(PG_FUNCTION_ARGS); +extern Datum int2mod(PG_FUNCTION_ARGS); +extern Datum int4mod(PG_FUNCTION_ARGS); +extern Datum textne(PG_FUNCTION_ARGS); +extern Datum int24eq(PG_FUNCTION_ARGS); +extern Datum int42eq(PG_FUNCTION_ARGS); +extern Datum int24lt(PG_FUNCTION_ARGS); +extern Datum int42lt(PG_FUNCTION_ARGS); +extern Datum int24gt(PG_FUNCTION_ARGS); +extern Datum int42gt(PG_FUNCTION_ARGS); +extern Datum int24ne(PG_FUNCTION_ARGS); +extern Datum int42ne(PG_FUNCTION_ARGS); +extern Datum int24le(PG_FUNCTION_ARGS); +extern Datum int42le(PG_FUNCTION_ARGS); +extern Datum int24ge(PG_FUNCTION_ARGS); +extern Datum int42ge(PG_FUNCTION_ARGS); +extern Datum int24mul(PG_FUNCTION_ARGS); +extern Datum int42mul(PG_FUNCTION_ARGS); +extern Datum int24div(PG_FUNCTION_ARGS); +extern Datum int42div(PG_FUNCTION_ARGS); +extern Datum int2pl(PG_FUNCTION_ARGS); +extern Datum int4pl(PG_FUNCTION_ARGS); +extern Datum int24pl(PG_FUNCTION_ARGS); +extern Datum int42pl(PG_FUNCTION_ARGS); +extern Datum int2mi(PG_FUNCTION_ARGS); +extern Datum int4mi(PG_FUNCTION_ARGS); +extern Datum int24mi(PG_FUNCTION_ARGS); +extern Datum int42mi(PG_FUNCTION_ARGS); +extern Datum oideq(PG_FUNCTION_ARGS); +extern Datum oidne(PG_FUNCTION_ARGS); +extern Datum box_same(PG_FUNCTION_ARGS); +extern Datum box_contain(PG_FUNCTION_ARGS); +extern Datum box_left(PG_FUNCTION_ARGS); +extern Datum box_overleft(PG_FUNCTION_ARGS); +extern Datum box_overright(PG_FUNCTION_ARGS); +extern Datum box_right(PG_FUNCTION_ARGS); +extern Datum box_contained(PG_FUNCTION_ARGS); +extern Datum box_contain_pt(PG_FUNCTION_ARGS); +extern Datum pg_node_tree_in(PG_FUNCTION_ARGS); +extern Datum pg_node_tree_out(PG_FUNCTION_ARGS); +extern Datum pg_node_tree_recv(PG_FUNCTION_ARGS); +extern Datum pg_node_tree_send(PG_FUNCTION_ARGS); +extern Datum float4in(PG_FUNCTION_ARGS); +extern Datum float4out(PG_FUNCTION_ARGS); +extern Datum float4mul(PG_FUNCTION_ARGS); +extern Datum float4div(PG_FUNCTION_ARGS); +extern Datum float4pl(PG_FUNCTION_ARGS); +extern Datum float4mi(PG_FUNCTION_ARGS); +extern Datum float4um(PG_FUNCTION_ARGS); +extern Datum float4abs(PG_FUNCTION_ARGS); +extern Datum float4_accum(PG_FUNCTION_ARGS); +extern Datum float4larger(PG_FUNCTION_ARGS); +extern Datum float4smaller(PG_FUNCTION_ARGS); +extern Datum int4um(PG_FUNCTION_ARGS); +extern Datum int2um(PG_FUNCTION_ARGS); +extern Datum float8in(PG_FUNCTION_ARGS); +extern Datum float8out(PG_FUNCTION_ARGS); +extern Datum float8mul(PG_FUNCTION_ARGS); +extern Datum float8div(PG_FUNCTION_ARGS); +extern Datum float8pl(PG_FUNCTION_ARGS); +extern Datum float8mi(PG_FUNCTION_ARGS); +extern Datum float8um(PG_FUNCTION_ARGS); +extern Datum float8abs(PG_FUNCTION_ARGS); +extern Datum float8_accum(PG_FUNCTION_ARGS); +extern Datum float8larger(PG_FUNCTION_ARGS); +extern Datum float8smaller(PG_FUNCTION_ARGS); +extern Datum lseg_center(PG_FUNCTION_ARGS); +extern Datum poly_center(PG_FUNCTION_ARGS); +extern Datum dround(PG_FUNCTION_ARGS); +extern Datum dtrunc(PG_FUNCTION_ARGS); +extern Datum dsqrt(PG_FUNCTION_ARGS); +extern Datum dcbrt(PG_FUNCTION_ARGS); +extern Datum dpow(PG_FUNCTION_ARGS); +extern Datum dexp(PG_FUNCTION_ARGS); +extern Datum dlog1(PG_FUNCTION_ARGS); +extern Datum i2tod(PG_FUNCTION_ARGS); +extern Datum i2tof(PG_FUNCTION_ARGS); +extern Datum dtoi2(PG_FUNCTION_ARGS); +extern Datum ftoi2(PG_FUNCTION_ARGS); +extern Datum line_distance(PG_FUNCTION_ARGS); +extern Datum nameeqtext(PG_FUNCTION_ARGS); +extern Datum namelttext(PG_FUNCTION_ARGS); +extern Datum nameletext(PG_FUNCTION_ARGS); +extern Datum namegetext(PG_FUNCTION_ARGS); +extern Datum namegttext(PG_FUNCTION_ARGS); +extern Datum namenetext(PG_FUNCTION_ARGS); +extern Datum btnametextcmp(PG_FUNCTION_ARGS); +extern Datum texteqname(PG_FUNCTION_ARGS); +extern Datum textltname(PG_FUNCTION_ARGS); +extern Datum textlename(PG_FUNCTION_ARGS); +extern Datum textgename(PG_FUNCTION_ARGS); +extern Datum textgtname(PG_FUNCTION_ARGS); +extern Datum textnename(PG_FUNCTION_ARGS); +extern Datum bttextnamecmp(PG_FUNCTION_ARGS); +extern Datum nameconcatoid(PG_FUNCTION_ARGS); +extern Datum table_am_handler_in(PG_FUNCTION_ARGS); +extern Datum table_am_handler_out(PG_FUNCTION_ARGS); +extern Datum timeofday(PG_FUNCTION_ARGS); +extern Datum pg_nextoid(PG_FUNCTION_ARGS); +extern Datum float8_combine(PG_FUNCTION_ARGS); +extern Datum inter_sl(PG_FUNCTION_ARGS); +extern Datum inter_lb(PG_FUNCTION_ARGS); +extern Datum float48mul(PG_FUNCTION_ARGS); +extern Datum float48div(PG_FUNCTION_ARGS); +extern Datum float48pl(PG_FUNCTION_ARGS); +extern Datum float48mi(PG_FUNCTION_ARGS); +extern Datum float84mul(PG_FUNCTION_ARGS); +extern Datum float84div(PG_FUNCTION_ARGS); +extern Datum float84pl(PG_FUNCTION_ARGS); +extern Datum float84mi(PG_FUNCTION_ARGS); +extern Datum float4eq(PG_FUNCTION_ARGS); +extern Datum float4ne(PG_FUNCTION_ARGS); +extern Datum float4lt(PG_FUNCTION_ARGS); +extern Datum float4le(PG_FUNCTION_ARGS); +extern Datum float4gt(PG_FUNCTION_ARGS); +extern Datum float4ge(PG_FUNCTION_ARGS); +extern Datum float8eq(PG_FUNCTION_ARGS); +extern Datum float8ne(PG_FUNCTION_ARGS); +extern Datum float8lt(PG_FUNCTION_ARGS); +extern Datum float8le(PG_FUNCTION_ARGS); +extern Datum float8gt(PG_FUNCTION_ARGS); +extern Datum float8ge(PG_FUNCTION_ARGS); +extern Datum float48eq(PG_FUNCTION_ARGS); +extern Datum float48ne(PG_FUNCTION_ARGS); +extern Datum float48lt(PG_FUNCTION_ARGS); +extern Datum float48le(PG_FUNCTION_ARGS); +extern Datum float48gt(PG_FUNCTION_ARGS); +extern Datum float48ge(PG_FUNCTION_ARGS); +extern Datum float84eq(PG_FUNCTION_ARGS); +extern Datum float84ne(PG_FUNCTION_ARGS); +extern Datum float84lt(PG_FUNCTION_ARGS); +extern Datum float84le(PG_FUNCTION_ARGS); +extern Datum float84gt(PG_FUNCTION_ARGS); +extern Datum float84ge(PG_FUNCTION_ARGS); +extern Datum ftod(PG_FUNCTION_ARGS); +extern Datum dtof(PG_FUNCTION_ARGS); +extern Datum i2toi4(PG_FUNCTION_ARGS); +extern Datum i4toi2(PG_FUNCTION_ARGS); +extern Datum pg_jit_available(PG_FUNCTION_ARGS); +extern Datum i4tod(PG_FUNCTION_ARGS); +extern Datum dtoi4(PG_FUNCTION_ARGS); +extern Datum i4tof(PG_FUNCTION_ARGS); +extern Datum ftoi4(PG_FUNCTION_ARGS); +extern Datum width_bucket_float8(PG_FUNCTION_ARGS); +extern Datum json_in(PG_FUNCTION_ARGS); +extern Datum json_out(PG_FUNCTION_ARGS); +extern Datum json_recv(PG_FUNCTION_ARGS); +extern Datum json_send(PG_FUNCTION_ARGS); +extern Datum index_am_handler_in(PG_FUNCTION_ARGS); +extern Datum index_am_handler_out(PG_FUNCTION_ARGS); +extern Datum hashmacaddr8(PG_FUNCTION_ARGS); +extern Datum hash_aclitem(PG_FUNCTION_ARGS); +extern Datum bthandler(PG_FUNCTION_ARGS); +extern Datum hashhandler(PG_FUNCTION_ARGS); +extern Datum gisthandler(PG_FUNCTION_ARGS); +extern Datum ginhandler(PG_FUNCTION_ARGS); +extern Datum spghandler(PG_FUNCTION_ARGS); +extern Datum brinhandler(PG_FUNCTION_ARGS); +extern Datum scalarlesel(PG_FUNCTION_ARGS); +extern Datum scalargesel(PG_FUNCTION_ARGS); +extern Datum amvalidate(PG_FUNCTION_ARGS); +extern Datum poly_same(PG_FUNCTION_ARGS); +extern Datum poly_contain(PG_FUNCTION_ARGS); +extern Datum poly_left(PG_FUNCTION_ARGS); +extern Datum poly_overleft(PG_FUNCTION_ARGS); +extern Datum poly_overright(PG_FUNCTION_ARGS); +extern Datum poly_right(PG_FUNCTION_ARGS); +extern Datum poly_contained(PG_FUNCTION_ARGS); +extern Datum poly_overlap(PG_FUNCTION_ARGS); +extern Datum poly_in(PG_FUNCTION_ARGS); +extern Datum poly_out(PG_FUNCTION_ARGS); +extern Datum btint2cmp(PG_FUNCTION_ARGS); +extern Datum btint4cmp(PG_FUNCTION_ARGS); +extern Datum btfloat4cmp(PG_FUNCTION_ARGS); +extern Datum btfloat8cmp(PG_FUNCTION_ARGS); +extern Datum btoidcmp(PG_FUNCTION_ARGS); +extern Datum dist_bp(PG_FUNCTION_ARGS); +extern Datum btcharcmp(PG_FUNCTION_ARGS); +extern Datum btnamecmp(PG_FUNCTION_ARGS); +extern Datum bttextcmp(PG_FUNCTION_ARGS); +extern Datum lseg_distance(PG_FUNCTION_ARGS); +extern Datum lseg_interpt(PG_FUNCTION_ARGS); +extern Datum dist_ps(PG_FUNCTION_ARGS); +extern Datum dist_pb(PG_FUNCTION_ARGS); +extern Datum dist_sb(PG_FUNCTION_ARGS); +extern Datum close_ps(PG_FUNCTION_ARGS); +extern Datum close_pb(PG_FUNCTION_ARGS); +extern Datum close_sb(PG_FUNCTION_ARGS); +extern Datum on_ps(PG_FUNCTION_ARGS); +extern Datum path_distance(PG_FUNCTION_ARGS); +extern Datum dist_ppath(PG_FUNCTION_ARGS); +extern Datum on_sb(PG_FUNCTION_ARGS); +extern Datum inter_sb(PG_FUNCTION_ARGS); +extern Datum text_to_array_null(PG_FUNCTION_ARGS); +extern Datum cash_cmp(PG_FUNCTION_ARGS); +extern Datum array_append(PG_FUNCTION_ARGS); +extern Datum array_prepend(PG_FUNCTION_ARGS); +extern Datum dist_sp(PG_FUNCTION_ARGS); +extern Datum dist_bs(PG_FUNCTION_ARGS); +extern Datum btarraycmp(PG_FUNCTION_ARGS); +extern Datum array_cat(PG_FUNCTION_ARGS); +extern Datum array_to_text_null(PG_FUNCTION_ARGS); +extern Datum scalarlejoinsel(PG_FUNCTION_ARGS); +extern Datum array_ne(PG_FUNCTION_ARGS); +extern Datum array_lt(PG_FUNCTION_ARGS); +extern Datum array_gt(PG_FUNCTION_ARGS); +extern Datum array_le(PG_FUNCTION_ARGS); +extern Datum text_to_array(PG_FUNCTION_ARGS); +extern Datum array_to_text(PG_FUNCTION_ARGS); +extern Datum array_ge(PG_FUNCTION_ARGS); +extern Datum scalargejoinsel(PG_FUNCTION_ARGS); +extern Datum hashmacaddr(PG_FUNCTION_ARGS); +extern Datum hashtext(PG_FUNCTION_ARGS); +extern Datum rtrim1(PG_FUNCTION_ARGS); +extern Datum btoidvectorcmp(PG_FUNCTION_ARGS); +extern Datum name_text(PG_FUNCTION_ARGS); +extern Datum text_name(PG_FUNCTION_ARGS); +extern Datum name_bpchar(PG_FUNCTION_ARGS); +extern Datum bpchar_name(PG_FUNCTION_ARGS); +extern Datum dist_pathp(PG_FUNCTION_ARGS); +extern Datum hashinet(PG_FUNCTION_ARGS); +extern Datum hashint4extended(PG_FUNCTION_ARGS); +extern Datum hash_numeric(PG_FUNCTION_ARGS); +extern Datum macaddr_in(PG_FUNCTION_ARGS); +extern Datum macaddr_out(PG_FUNCTION_ARGS); +extern Datum pg_num_nulls(PG_FUNCTION_ARGS); +extern Datum pg_num_nonnulls(PG_FUNCTION_ARGS); +extern Datum hashint2extended(PG_FUNCTION_ARGS); +extern Datum hashint8extended(PG_FUNCTION_ARGS); +extern Datum hashfloat4extended(PG_FUNCTION_ARGS); +extern Datum hashfloat8extended(PG_FUNCTION_ARGS); +extern Datum hashoidextended(PG_FUNCTION_ARGS); +extern Datum hashcharextended(PG_FUNCTION_ARGS); +extern Datum hashnameextended(PG_FUNCTION_ARGS); +extern Datum hashtextextended(PG_FUNCTION_ARGS); +extern Datum hashint2(PG_FUNCTION_ARGS); +extern Datum hashint4(PG_FUNCTION_ARGS); +extern Datum hashfloat4(PG_FUNCTION_ARGS); +extern Datum hashfloat8(PG_FUNCTION_ARGS); +extern Datum hashoid(PG_FUNCTION_ARGS); +extern Datum hashchar(PG_FUNCTION_ARGS); +extern Datum hashname(PG_FUNCTION_ARGS); +extern Datum hashvarlena(PG_FUNCTION_ARGS); +extern Datum hashoidvector(PG_FUNCTION_ARGS); +extern Datum text_larger(PG_FUNCTION_ARGS); +extern Datum text_smaller(PG_FUNCTION_ARGS); +extern Datum int8in(PG_FUNCTION_ARGS); +extern Datum int8out(PG_FUNCTION_ARGS); +extern Datum int8um(PG_FUNCTION_ARGS); +extern Datum int8pl(PG_FUNCTION_ARGS); +extern Datum int8mi(PG_FUNCTION_ARGS); +extern Datum int8mul(PG_FUNCTION_ARGS); +extern Datum int8div(PG_FUNCTION_ARGS); +extern Datum int8eq(PG_FUNCTION_ARGS); +extern Datum int8ne(PG_FUNCTION_ARGS); +extern Datum int8lt(PG_FUNCTION_ARGS); +extern Datum int8gt(PG_FUNCTION_ARGS); +extern Datum int8le(PG_FUNCTION_ARGS); +extern Datum int8ge(PG_FUNCTION_ARGS); +extern Datum int84eq(PG_FUNCTION_ARGS); +extern Datum int84ne(PG_FUNCTION_ARGS); +extern Datum int84lt(PG_FUNCTION_ARGS); +extern Datum int84gt(PG_FUNCTION_ARGS); +extern Datum int84le(PG_FUNCTION_ARGS); +extern Datum int84ge(PG_FUNCTION_ARGS); +extern Datum int84(PG_FUNCTION_ARGS); +extern Datum int48(PG_FUNCTION_ARGS); +extern Datum i8tod(PG_FUNCTION_ARGS); +extern Datum dtoi8(PG_FUNCTION_ARGS); +extern Datum array_larger(PG_FUNCTION_ARGS); +extern Datum array_smaller(PG_FUNCTION_ARGS); +extern Datum inet_abbrev(PG_FUNCTION_ARGS); +extern Datum cidr_abbrev(PG_FUNCTION_ARGS); +extern Datum inet_set_masklen(PG_FUNCTION_ARGS); +extern Datum oidvectorne(PG_FUNCTION_ARGS); +extern Datum hash_array(PG_FUNCTION_ARGS); +extern Datum cidr_set_masklen(PG_FUNCTION_ARGS); +extern Datum pg_indexam_has_property(PG_FUNCTION_ARGS); +extern Datum pg_index_has_property(PG_FUNCTION_ARGS); +extern Datum pg_index_column_has_property(PG_FUNCTION_ARGS); +extern Datum i8tof(PG_FUNCTION_ARGS); +extern Datum ftoi8(PG_FUNCTION_ARGS); +extern Datum namelt(PG_FUNCTION_ARGS); +extern Datum namele(PG_FUNCTION_ARGS); +extern Datum namegt(PG_FUNCTION_ARGS); +extern Datum namege(PG_FUNCTION_ARGS); +extern Datum namene(PG_FUNCTION_ARGS); +extern Datum bpchar(PG_FUNCTION_ARGS); +extern Datum varchar(PG_FUNCTION_ARGS); +extern Datum pg_indexam_progress_phasename(PG_FUNCTION_ARGS); +extern Datum oidvectorlt(PG_FUNCTION_ARGS); +extern Datum oidvectorle(PG_FUNCTION_ARGS); +extern Datum oidvectoreq(PG_FUNCTION_ARGS); +extern Datum oidvectorge(PG_FUNCTION_ARGS); +extern Datum oidvectorgt(PG_FUNCTION_ARGS); +extern Datum network_network(PG_FUNCTION_ARGS); +extern Datum network_netmask(PG_FUNCTION_ARGS); +extern Datum network_masklen(PG_FUNCTION_ARGS); +extern Datum network_broadcast(PG_FUNCTION_ARGS); +extern Datum network_host(PG_FUNCTION_ARGS); +extern Datum dist_lp(PG_FUNCTION_ARGS); +extern Datum dist_ls(PG_FUNCTION_ARGS); +extern Datum current_user(PG_FUNCTION_ARGS); +extern Datum network_family(PG_FUNCTION_ARGS); +extern Datum int82(PG_FUNCTION_ARGS); +extern Datum be_lo_create(PG_FUNCTION_ARGS); +extern Datum oidlt(PG_FUNCTION_ARGS); +extern Datum oidle(PG_FUNCTION_ARGS); +extern Datum byteaoctetlen(PG_FUNCTION_ARGS); +extern Datum byteaGetByte(PG_FUNCTION_ARGS); +extern Datum byteaSetByte(PG_FUNCTION_ARGS); +extern Datum byteaGetBit(PG_FUNCTION_ARGS); +extern Datum byteaSetBit(PG_FUNCTION_ARGS); +extern Datum dist_pl(PG_FUNCTION_ARGS); +extern Datum dist_sl(PG_FUNCTION_ARGS); +extern Datum dist_cpoly(PG_FUNCTION_ARGS); +extern Datum poly_distance(PG_FUNCTION_ARGS); +extern Datum network_show(PG_FUNCTION_ARGS); +extern Datum text_lt(PG_FUNCTION_ARGS); +extern Datum text_le(PG_FUNCTION_ARGS); +extern Datum text_gt(PG_FUNCTION_ARGS); +extern Datum text_ge(PG_FUNCTION_ARGS); +extern Datum array_eq(PG_FUNCTION_ARGS); +extern Datum session_user(PG_FUNCTION_ARGS); +extern Datum array_dims(PG_FUNCTION_ARGS); +extern Datum array_ndims(PG_FUNCTION_ARGS); +extern Datum byteaoverlay(PG_FUNCTION_ARGS); +extern Datum array_in(PG_FUNCTION_ARGS); +extern Datum array_out(PG_FUNCTION_ARGS); +extern Datum byteaoverlay_no_len(PG_FUNCTION_ARGS); +extern Datum macaddr_trunc(PG_FUNCTION_ARGS); +extern Datum int28(PG_FUNCTION_ARGS); +extern Datum be_lo_import(PG_FUNCTION_ARGS); +extern Datum be_lo_export(PG_FUNCTION_ARGS); +extern Datum int4inc(PG_FUNCTION_ARGS); +extern Datum be_lo_import_with_oid(PG_FUNCTION_ARGS); +extern Datum int4larger(PG_FUNCTION_ARGS); +extern Datum int4smaller(PG_FUNCTION_ARGS); +extern Datum int2larger(PG_FUNCTION_ARGS); +extern Datum int2smaller(PG_FUNCTION_ARGS); +extern Datum hashvarlenaextended(PG_FUNCTION_ARGS); +extern Datum hashoidvectorextended(PG_FUNCTION_ARGS); +extern Datum hash_aclitem_extended(PG_FUNCTION_ARGS); +extern Datum hashmacaddrextended(PG_FUNCTION_ARGS); +extern Datum hashinetextended(PG_FUNCTION_ARGS); +extern Datum hash_numeric_extended(PG_FUNCTION_ARGS); +extern Datum hashmacaddr8extended(PG_FUNCTION_ARGS); +extern Datum hash_array_extended(PG_FUNCTION_ARGS); +extern Datum dist_polyc(PG_FUNCTION_ARGS); +extern Datum pg_client_encoding(PG_FUNCTION_ARGS); +extern Datum current_query(PG_FUNCTION_ARGS); +extern Datum macaddr_eq(PG_FUNCTION_ARGS); +extern Datum macaddr_lt(PG_FUNCTION_ARGS); +extern Datum macaddr_le(PG_FUNCTION_ARGS); +extern Datum macaddr_gt(PG_FUNCTION_ARGS); +extern Datum macaddr_ge(PG_FUNCTION_ARGS); +extern Datum macaddr_ne(PG_FUNCTION_ARGS); +extern Datum macaddr_cmp(PG_FUNCTION_ARGS); +extern Datum int82pl(PG_FUNCTION_ARGS); +extern Datum int82mi(PG_FUNCTION_ARGS); +extern Datum int82mul(PG_FUNCTION_ARGS); +extern Datum int82div(PG_FUNCTION_ARGS); +extern Datum int28pl(PG_FUNCTION_ARGS); +extern Datum btint8cmp(PG_FUNCTION_ARGS); +extern Datum cash_mul_flt4(PG_FUNCTION_ARGS); +extern Datum cash_div_flt4(PG_FUNCTION_ARGS); +extern Datum flt4_mul_cash(PG_FUNCTION_ARGS); +extern Datum textpos(PG_FUNCTION_ARGS); +extern Datum textlike(PG_FUNCTION_ARGS); +extern Datum textnlike(PG_FUNCTION_ARGS); +extern Datum int48eq(PG_FUNCTION_ARGS); +extern Datum int48ne(PG_FUNCTION_ARGS); +extern Datum int48lt(PG_FUNCTION_ARGS); +extern Datum int48gt(PG_FUNCTION_ARGS); +extern Datum int48le(PG_FUNCTION_ARGS); +extern Datum int48ge(PG_FUNCTION_ARGS); +extern Datum namelike(PG_FUNCTION_ARGS); +extern Datum namenlike(PG_FUNCTION_ARGS); +extern Datum char_bpchar(PG_FUNCTION_ARGS); +extern Datum current_database(PG_FUNCTION_ARGS); +extern Datum int4_mul_cash(PG_FUNCTION_ARGS); +extern Datum int2_mul_cash(PG_FUNCTION_ARGS); +extern Datum cash_mul_int4(PG_FUNCTION_ARGS); +extern Datum cash_div_int4(PG_FUNCTION_ARGS); +extern Datum cash_mul_int2(PG_FUNCTION_ARGS); +extern Datum cash_div_int2(PG_FUNCTION_ARGS); +extern Datum lower(PG_FUNCTION_ARGS); +extern Datum upper(PG_FUNCTION_ARGS); +extern Datum initcap(PG_FUNCTION_ARGS); +extern Datum lpad(PG_FUNCTION_ARGS); +extern Datum rpad(PG_FUNCTION_ARGS); +extern Datum ltrim(PG_FUNCTION_ARGS); +extern Datum rtrim(PG_FUNCTION_ARGS); +extern Datum text_substr(PG_FUNCTION_ARGS); +extern Datum translate(PG_FUNCTION_ARGS); +extern Datum ltrim1(PG_FUNCTION_ARGS); +extern Datum text_substr_no_len(PG_FUNCTION_ARGS); +extern Datum btrim(PG_FUNCTION_ARGS); +extern Datum btrim1(PG_FUNCTION_ARGS); +extern Datum cash_in(PG_FUNCTION_ARGS); +extern Datum cash_out(PG_FUNCTION_ARGS); +extern Datum cash_eq(PG_FUNCTION_ARGS); +extern Datum cash_ne(PG_FUNCTION_ARGS); +extern Datum cash_lt(PG_FUNCTION_ARGS); +extern Datum cash_le(PG_FUNCTION_ARGS); +extern Datum cash_gt(PG_FUNCTION_ARGS); +extern Datum cash_ge(PG_FUNCTION_ARGS); +extern Datum cash_pl(PG_FUNCTION_ARGS); +extern Datum cash_mi(PG_FUNCTION_ARGS); +extern Datum cash_mul_flt8(PG_FUNCTION_ARGS); +extern Datum cash_div_flt8(PG_FUNCTION_ARGS); +extern Datum cashlarger(PG_FUNCTION_ARGS); +extern Datum cashsmaller(PG_FUNCTION_ARGS); +extern Datum inet_in(PG_FUNCTION_ARGS); +extern Datum inet_out(PG_FUNCTION_ARGS); +extern Datum flt8_mul_cash(PG_FUNCTION_ARGS); +extern Datum network_eq(PG_FUNCTION_ARGS); +extern Datum network_lt(PG_FUNCTION_ARGS); +extern Datum network_le(PG_FUNCTION_ARGS); +extern Datum network_gt(PG_FUNCTION_ARGS); +extern Datum network_ge(PG_FUNCTION_ARGS); +extern Datum network_ne(PG_FUNCTION_ARGS); +extern Datum network_cmp(PG_FUNCTION_ARGS); +extern Datum network_sub(PG_FUNCTION_ARGS); +extern Datum network_subeq(PG_FUNCTION_ARGS); +extern Datum network_sup(PG_FUNCTION_ARGS); +extern Datum network_supeq(PG_FUNCTION_ARGS); +extern Datum cash_words(PG_FUNCTION_ARGS); +extern Datum generate_series_timestamp(PG_FUNCTION_ARGS); +extern Datum generate_series_timestamptz(PG_FUNCTION_ARGS); +extern Datum int28mi(PG_FUNCTION_ARGS); +extern Datum int28mul(PG_FUNCTION_ARGS); +extern Datum text_char(PG_FUNCTION_ARGS); +extern Datum int8mod(PG_FUNCTION_ARGS); +extern Datum char_text(PG_FUNCTION_ARGS); +extern Datum int28div(PG_FUNCTION_ARGS); +extern Datum hashint8(PG_FUNCTION_ARGS); +extern Datum be_lo_open(PG_FUNCTION_ARGS); +extern Datum be_lo_close(PG_FUNCTION_ARGS); +extern Datum be_loread(PG_FUNCTION_ARGS); +extern Datum be_lowrite(PG_FUNCTION_ARGS); +extern Datum be_lo_lseek(PG_FUNCTION_ARGS); +extern Datum be_lo_creat(PG_FUNCTION_ARGS); +extern Datum be_lo_tell(PG_FUNCTION_ARGS); +extern Datum on_pl(PG_FUNCTION_ARGS); +extern Datum on_sl(PG_FUNCTION_ARGS); +extern Datum close_pl(PG_FUNCTION_ARGS); +extern Datum be_lo_unlink(PG_FUNCTION_ARGS); +extern Datum hashbpcharextended(PG_FUNCTION_ARGS); +extern Datum path_inter(PG_FUNCTION_ARGS); +extern Datum box_area(PG_FUNCTION_ARGS); +extern Datum box_width(PG_FUNCTION_ARGS); +extern Datum box_height(PG_FUNCTION_ARGS); +extern Datum box_distance(PG_FUNCTION_ARGS); +extern Datum path_area(PG_FUNCTION_ARGS); +extern Datum box_intersect(PG_FUNCTION_ARGS); +extern Datum box_diagonal(PG_FUNCTION_ARGS); +extern Datum path_n_lt(PG_FUNCTION_ARGS); +extern Datum path_n_gt(PG_FUNCTION_ARGS); +extern Datum path_n_eq(PG_FUNCTION_ARGS); +extern Datum path_n_le(PG_FUNCTION_ARGS); +extern Datum path_n_ge(PG_FUNCTION_ARGS); +extern Datum path_length(PG_FUNCTION_ARGS); +extern Datum point_ne(PG_FUNCTION_ARGS); +extern Datum point_vert(PG_FUNCTION_ARGS); +extern Datum point_horiz(PG_FUNCTION_ARGS); +extern Datum point_distance(PG_FUNCTION_ARGS); +extern Datum point_slope(PG_FUNCTION_ARGS); +extern Datum lseg_construct(PG_FUNCTION_ARGS); +extern Datum lseg_intersect(PG_FUNCTION_ARGS); +extern Datum lseg_parallel(PG_FUNCTION_ARGS); +extern Datum lseg_perp(PG_FUNCTION_ARGS); +extern Datum lseg_vertical(PG_FUNCTION_ARGS); +extern Datum lseg_horizontal(PG_FUNCTION_ARGS); +extern Datum lseg_eq(PG_FUNCTION_ARGS); +extern Datum be_lo_truncate(PG_FUNCTION_ARGS); +extern Datum textlike_support(PG_FUNCTION_ARGS); +extern Datum texticregexeq_support(PG_FUNCTION_ARGS); +extern Datum texticlike_support(PG_FUNCTION_ARGS); +extern Datum timestamptz_izone(PG_FUNCTION_ARGS); +extern Datum gist_point_compress(PG_FUNCTION_ARGS); +extern Datum aclitemin(PG_FUNCTION_ARGS); +extern Datum aclitemout(PG_FUNCTION_ARGS); +extern Datum aclinsert(PG_FUNCTION_ARGS); +extern Datum aclremove(PG_FUNCTION_ARGS); +extern Datum aclcontains(PG_FUNCTION_ARGS); +extern Datum getdatabaseencoding(PG_FUNCTION_ARGS); +extern Datum bpcharin(PG_FUNCTION_ARGS); +extern Datum bpcharout(PG_FUNCTION_ARGS); +extern Datum varcharin(PG_FUNCTION_ARGS); +extern Datum varcharout(PG_FUNCTION_ARGS); +extern Datum bpchareq(PG_FUNCTION_ARGS); +extern Datum bpcharlt(PG_FUNCTION_ARGS); +extern Datum bpcharle(PG_FUNCTION_ARGS); +extern Datum bpchargt(PG_FUNCTION_ARGS); +extern Datum bpcharge(PG_FUNCTION_ARGS); +extern Datum bpcharne(PG_FUNCTION_ARGS); +extern Datum aclitem_eq(PG_FUNCTION_ARGS); +extern Datum bpchar_larger(PG_FUNCTION_ARGS); +extern Datum bpchar_smaller(PG_FUNCTION_ARGS); +extern Datum pg_prepared_xact(PG_FUNCTION_ARGS); +extern Datum generate_series_step_int4(PG_FUNCTION_ARGS); +extern Datum generate_series_int4(PG_FUNCTION_ARGS); +extern Datum generate_series_step_int8(PG_FUNCTION_ARGS); +extern Datum generate_series_int8(PG_FUNCTION_ARGS); +extern Datum bpcharcmp(PG_FUNCTION_ARGS); +extern Datum text_regclass(PG_FUNCTION_ARGS); +extern Datum hashbpchar(PG_FUNCTION_ARGS); +extern Datum format_type(PG_FUNCTION_ARGS); +extern Datum date_in(PG_FUNCTION_ARGS); +extern Datum date_out(PG_FUNCTION_ARGS); +extern Datum date_eq(PG_FUNCTION_ARGS); +extern Datum date_lt(PG_FUNCTION_ARGS); +extern Datum date_le(PG_FUNCTION_ARGS); +extern Datum date_gt(PG_FUNCTION_ARGS); +extern Datum date_ge(PG_FUNCTION_ARGS); +extern Datum date_ne(PG_FUNCTION_ARGS); +extern Datum date_cmp(PG_FUNCTION_ARGS); +extern Datum time_lt(PG_FUNCTION_ARGS); +extern Datum time_le(PG_FUNCTION_ARGS); +extern Datum time_gt(PG_FUNCTION_ARGS); +extern Datum time_ge(PG_FUNCTION_ARGS); +extern Datum time_ne(PG_FUNCTION_ARGS); +extern Datum time_cmp(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_wal(PG_FUNCTION_ARGS); +extern Datum pg_get_wal_replay_pause_state(PG_FUNCTION_ARGS); +extern Datum date_larger(PG_FUNCTION_ARGS); +extern Datum date_smaller(PG_FUNCTION_ARGS); +extern Datum date_mi(PG_FUNCTION_ARGS); +extern Datum date_pli(PG_FUNCTION_ARGS); +extern Datum date_mii(PG_FUNCTION_ARGS); +extern Datum time_in(PG_FUNCTION_ARGS); +extern Datum time_out(PG_FUNCTION_ARGS); +extern Datum time_eq(PG_FUNCTION_ARGS); +extern Datum circle_add_pt(PG_FUNCTION_ARGS); +extern Datum circle_sub_pt(PG_FUNCTION_ARGS); +extern Datum circle_mul_pt(PG_FUNCTION_ARGS); +extern Datum circle_div_pt(PG_FUNCTION_ARGS); +extern Datum timestamptz_in(PG_FUNCTION_ARGS); +extern Datum timestamptz_out(PG_FUNCTION_ARGS); +extern Datum timestamp_eq(PG_FUNCTION_ARGS); +extern Datum timestamp_ne(PG_FUNCTION_ARGS); +extern Datum timestamp_lt(PG_FUNCTION_ARGS); +extern Datum timestamp_le(PG_FUNCTION_ARGS); +extern Datum timestamp_ge(PG_FUNCTION_ARGS); +extern Datum timestamp_gt(PG_FUNCTION_ARGS); +extern Datum float8_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamptz_zone(PG_FUNCTION_ARGS); +extern Datum interval_in(PG_FUNCTION_ARGS); +extern Datum interval_out(PG_FUNCTION_ARGS); +extern Datum interval_eq(PG_FUNCTION_ARGS); +extern Datum interval_ne(PG_FUNCTION_ARGS); +extern Datum interval_lt(PG_FUNCTION_ARGS); +extern Datum interval_le(PG_FUNCTION_ARGS); +extern Datum interval_ge(PG_FUNCTION_ARGS); +extern Datum interval_gt(PG_FUNCTION_ARGS); +extern Datum interval_um(PG_FUNCTION_ARGS); +extern Datum interval_pl(PG_FUNCTION_ARGS); +extern Datum interval_mi(PG_FUNCTION_ARGS); +extern Datum timestamptz_part(PG_FUNCTION_ARGS); +extern Datum interval_part(PG_FUNCTION_ARGS); +extern Datum network_subset_support(PG_FUNCTION_ARGS); +extern Datum date_timestamptz(PG_FUNCTION_ARGS); +extern Datum interval_justify_hours(PG_FUNCTION_ARGS); +extern Datum jsonb_path_exists_tz(PG_FUNCTION_ARGS); +extern Datum timestamptz_date(PG_FUNCTION_ARGS); +extern Datum jsonb_path_query_tz(PG_FUNCTION_ARGS); +extern Datum jsonb_path_query_array_tz(PG_FUNCTION_ARGS); +extern Datum xid_age(PG_FUNCTION_ARGS); +extern Datum timestamp_mi(PG_FUNCTION_ARGS); +extern Datum timestamptz_pl_interval(PG_FUNCTION_ARGS); +extern Datum timestamptz_mi_interval(PG_FUNCTION_ARGS); +extern Datum generate_subscripts(PG_FUNCTION_ARGS); +extern Datum generate_subscripts_nodir(PG_FUNCTION_ARGS); +extern Datum array_fill(PG_FUNCTION_ARGS); +extern Datum dlog10(PG_FUNCTION_ARGS); +extern Datum timestamp_smaller(PG_FUNCTION_ARGS); +extern Datum timestamp_larger(PG_FUNCTION_ARGS); +extern Datum interval_smaller(PG_FUNCTION_ARGS); +extern Datum interval_larger(PG_FUNCTION_ARGS); +extern Datum timestamptz_age(PG_FUNCTION_ARGS); +extern Datum interval_scale(PG_FUNCTION_ARGS); +extern Datum timestamptz_trunc(PG_FUNCTION_ARGS); +extern Datum interval_trunc(PG_FUNCTION_ARGS); +extern Datum int8inc(PG_FUNCTION_ARGS); +extern Datum int8abs(PG_FUNCTION_ARGS); +extern Datum int8larger(PG_FUNCTION_ARGS); +extern Datum int8smaller(PG_FUNCTION_ARGS); +extern Datum texticregexeq(PG_FUNCTION_ARGS); +extern Datum texticregexne(PG_FUNCTION_ARGS); +extern Datum nameicregexeq(PG_FUNCTION_ARGS); +extern Datum nameicregexne(PG_FUNCTION_ARGS); +extern Datum boolin(PG_FUNCTION_ARGS); +extern Datum boolout(PG_FUNCTION_ARGS); +extern Datum byteain(PG_FUNCTION_ARGS); +extern Datum charin(PG_FUNCTION_ARGS); +extern Datum charlt(PG_FUNCTION_ARGS); +extern Datum unique_key_recheck(PG_FUNCTION_ARGS); +extern Datum int4abs(PG_FUNCTION_ARGS); +extern Datum nameregexne(PG_FUNCTION_ARGS); +extern Datum int2abs(PG_FUNCTION_ARGS); +extern Datum textregexeq(PG_FUNCTION_ARGS); +extern Datum textregexne(PG_FUNCTION_ARGS); +extern Datum textlen(PG_FUNCTION_ARGS); +extern Datum textcat(PG_FUNCTION_ARGS); +extern Datum PG_char_to_encoding(PG_FUNCTION_ARGS); +extern Datum tidne(PG_FUNCTION_ARGS); +extern Datum cidr_in(PG_FUNCTION_ARGS); +extern Datum parse_ident(PG_FUNCTION_ARGS); +extern Datum pg_column_size(PG_FUNCTION_ARGS); +extern Datum overlaps_timetz(PG_FUNCTION_ARGS); +extern Datum datetime_timestamp(PG_FUNCTION_ARGS); +extern Datum timetz_part(PG_FUNCTION_ARGS); +extern Datum int84pl(PG_FUNCTION_ARGS); +extern Datum int84mi(PG_FUNCTION_ARGS); +extern Datum int84mul(PG_FUNCTION_ARGS); +extern Datum int84div(PG_FUNCTION_ARGS); +extern Datum int48pl(PG_FUNCTION_ARGS); +extern Datum int48mi(PG_FUNCTION_ARGS); +extern Datum int48mul(PG_FUNCTION_ARGS); +extern Datum int48div(PG_FUNCTION_ARGS); +extern Datum quote_ident(PG_FUNCTION_ARGS); +extern Datum quote_literal(PG_FUNCTION_ARGS); +extern Datum timestamptz_trunc_zone(PG_FUNCTION_ARGS); +extern Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS); +extern Datum i8tooid(PG_FUNCTION_ARGS); +extern Datum oidtoi8(PG_FUNCTION_ARGS); +extern Datum quote_nullable(PG_FUNCTION_ARGS); +extern Datum suppress_redundant_updates_trigger(PG_FUNCTION_ARGS); +extern Datum tideq(PG_FUNCTION_ARGS); +extern Datum multirange_unnest(PG_FUNCTION_ARGS); +extern Datum currtid_byrelname(PG_FUNCTION_ARGS); +extern Datum interval_justify_days(PG_FUNCTION_ARGS); +extern Datum datetimetz_timestamptz(PG_FUNCTION_ARGS); +extern Datum now(PG_FUNCTION_ARGS); +extern Datum positionsel(PG_FUNCTION_ARGS); +extern Datum positionjoinsel(PG_FUNCTION_ARGS); +extern Datum contsel(PG_FUNCTION_ARGS); +extern Datum contjoinsel(PG_FUNCTION_ARGS); +extern Datum overlaps_timestamp(PG_FUNCTION_ARGS); +extern Datum overlaps_time(PG_FUNCTION_ARGS); +extern Datum timestamp_in(PG_FUNCTION_ARGS); +extern Datum timestamp_out(PG_FUNCTION_ARGS); +extern Datum timestamp_cmp(PG_FUNCTION_ARGS); +extern Datum interval_cmp(PG_FUNCTION_ARGS); +extern Datum timestamp_time(PG_FUNCTION_ARGS); +extern Datum bpcharlen(PG_FUNCTION_ARGS); +extern Datum interval_div(PG_FUNCTION_ARGS); +extern Datum oidvectortypes(PG_FUNCTION_ARGS); +extern Datum timetz_in(PG_FUNCTION_ARGS); +extern Datum timetz_out(PG_FUNCTION_ARGS); +extern Datum timetz_eq(PG_FUNCTION_ARGS); +extern Datum timetz_ne(PG_FUNCTION_ARGS); +extern Datum timetz_lt(PG_FUNCTION_ARGS); +extern Datum timetz_le(PG_FUNCTION_ARGS); +extern Datum timetz_ge(PG_FUNCTION_ARGS); +extern Datum timetz_gt(PG_FUNCTION_ARGS); +extern Datum timetz_cmp(PG_FUNCTION_ARGS); +extern Datum network_hostmask(PG_FUNCTION_ARGS); +extern Datum textregexeq_support(PG_FUNCTION_ARGS); +extern Datum makeaclitem(PG_FUNCTION_ARGS); +extern Datum time_interval(PG_FUNCTION_ARGS); +extern Datum pg_lock_status(PG_FUNCTION_ARGS); +extern Datum date_finite(PG_FUNCTION_ARGS); +extern Datum textoctetlen(PG_FUNCTION_ARGS); +extern Datum bpcharoctetlen(PG_FUNCTION_ARGS); +extern Datum numeric_fac(PG_FUNCTION_ARGS); +extern Datum time_larger(PG_FUNCTION_ARGS); +extern Datum time_smaller(PG_FUNCTION_ARGS); +extern Datum timetz_larger(PG_FUNCTION_ARGS); +extern Datum timetz_smaller(PG_FUNCTION_ARGS); +extern Datum time_part(PG_FUNCTION_ARGS); +extern Datum pg_get_constraintdef(PG_FUNCTION_ARGS); +extern Datum timestamptz_timetz(PG_FUNCTION_ARGS); +extern Datum timestamp_finite(PG_FUNCTION_ARGS); +extern Datum interval_finite(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS); +extern Datum current_schema(PG_FUNCTION_ARGS); +extern Datum current_schemas(PG_FUNCTION_ARGS); +extern Datum textoverlay(PG_FUNCTION_ARGS); +extern Datum textoverlay_no_len(PG_FUNCTION_ARGS); +extern Datum line_parallel(PG_FUNCTION_ARGS); +extern Datum line_perp(PG_FUNCTION_ARGS); +extern Datum line_vertical(PG_FUNCTION_ARGS); +extern Datum line_horizontal(PG_FUNCTION_ARGS); +extern Datum circle_center(PG_FUNCTION_ARGS); +extern Datum interval_time(PG_FUNCTION_ARGS); +extern Datum points_box(PG_FUNCTION_ARGS); +extern Datum box_add(PG_FUNCTION_ARGS); +extern Datum box_sub(PG_FUNCTION_ARGS); +extern Datum box_mul(PG_FUNCTION_ARGS); +extern Datum box_div(PG_FUNCTION_ARGS); +extern Datum cidr_out(PG_FUNCTION_ARGS); +extern Datum poly_contain_pt(PG_FUNCTION_ARGS); +extern Datum pt_contained_poly(PG_FUNCTION_ARGS); +extern Datum path_isclosed(PG_FUNCTION_ARGS); +extern Datum path_isopen(PG_FUNCTION_ARGS); +extern Datum path_npoints(PG_FUNCTION_ARGS); +extern Datum path_close(PG_FUNCTION_ARGS); +extern Datum path_open(PG_FUNCTION_ARGS); +extern Datum path_add(PG_FUNCTION_ARGS); +extern Datum path_add_pt(PG_FUNCTION_ARGS); +extern Datum path_sub_pt(PG_FUNCTION_ARGS); +extern Datum path_mul_pt(PG_FUNCTION_ARGS); +extern Datum path_div_pt(PG_FUNCTION_ARGS); +extern Datum construct_point(PG_FUNCTION_ARGS); +extern Datum point_add(PG_FUNCTION_ARGS); +extern Datum point_sub(PG_FUNCTION_ARGS); +extern Datum point_mul(PG_FUNCTION_ARGS); +extern Datum point_div(PG_FUNCTION_ARGS); +extern Datum poly_npoints(PG_FUNCTION_ARGS); +extern Datum poly_box(PG_FUNCTION_ARGS); +extern Datum poly_path(PG_FUNCTION_ARGS); +extern Datum box_poly(PG_FUNCTION_ARGS); +extern Datum path_poly(PG_FUNCTION_ARGS); +extern Datum circle_in(PG_FUNCTION_ARGS); +extern Datum circle_out(PG_FUNCTION_ARGS); +extern Datum circle_same(PG_FUNCTION_ARGS); +extern Datum circle_contain(PG_FUNCTION_ARGS); +extern Datum circle_left(PG_FUNCTION_ARGS); +extern Datum circle_overleft(PG_FUNCTION_ARGS); +extern Datum circle_overright(PG_FUNCTION_ARGS); +extern Datum circle_right(PG_FUNCTION_ARGS); +extern Datum circle_contained(PG_FUNCTION_ARGS); +extern Datum circle_overlap(PG_FUNCTION_ARGS); +extern Datum circle_below(PG_FUNCTION_ARGS); +extern Datum circle_above(PG_FUNCTION_ARGS); +extern Datum circle_eq(PG_FUNCTION_ARGS); +extern Datum circle_ne(PG_FUNCTION_ARGS); +extern Datum circle_lt(PG_FUNCTION_ARGS); +extern Datum circle_gt(PG_FUNCTION_ARGS); +extern Datum circle_le(PG_FUNCTION_ARGS); +extern Datum circle_ge(PG_FUNCTION_ARGS); +extern Datum circle_area(PG_FUNCTION_ARGS); +extern Datum circle_diameter(PG_FUNCTION_ARGS); +extern Datum circle_radius(PG_FUNCTION_ARGS); +extern Datum circle_distance(PG_FUNCTION_ARGS); +extern Datum cr_circle(PG_FUNCTION_ARGS); +extern Datum poly_circle(PG_FUNCTION_ARGS); +extern Datum circle_poly(PG_FUNCTION_ARGS); +extern Datum dist_pc(PG_FUNCTION_ARGS); +extern Datum circle_contain_pt(PG_FUNCTION_ARGS); +extern Datum pt_contained_circle(PG_FUNCTION_ARGS); +extern Datum box_circle(PG_FUNCTION_ARGS); +extern Datum circle_box(PG_FUNCTION_ARGS); +extern Datum lseg_ne(PG_FUNCTION_ARGS); +extern Datum lseg_lt(PG_FUNCTION_ARGS); +extern Datum lseg_le(PG_FUNCTION_ARGS); +extern Datum lseg_gt(PG_FUNCTION_ARGS); +extern Datum lseg_ge(PG_FUNCTION_ARGS); +extern Datum lseg_length(PG_FUNCTION_ARGS); +extern Datum close_ls(PG_FUNCTION_ARGS); +extern Datum close_lseg(PG_FUNCTION_ARGS); +extern Datum line_in(PG_FUNCTION_ARGS); +extern Datum line_out(PG_FUNCTION_ARGS); +extern Datum line_eq(PG_FUNCTION_ARGS); +extern Datum line_construct_pp(PG_FUNCTION_ARGS); +extern Datum line_interpt(PG_FUNCTION_ARGS); +extern Datum line_intersect(PG_FUNCTION_ARGS); +extern Datum bit_in(PG_FUNCTION_ARGS); +extern Datum bit_out(PG_FUNCTION_ARGS); +extern Datum pg_get_ruledef(PG_FUNCTION_ARGS); +extern Datum nextval_oid(PG_FUNCTION_ARGS); +extern Datum currval_oid(PG_FUNCTION_ARGS); +extern Datum setval_oid(PG_FUNCTION_ARGS); +extern Datum varbit_in(PG_FUNCTION_ARGS); +extern Datum varbit_out(PG_FUNCTION_ARGS); +extern Datum biteq(PG_FUNCTION_ARGS); +extern Datum bitne(PG_FUNCTION_ARGS); +extern Datum bitge(PG_FUNCTION_ARGS); +extern Datum bitgt(PG_FUNCTION_ARGS); +extern Datum bitle(PG_FUNCTION_ARGS); +extern Datum bitlt(PG_FUNCTION_ARGS); +extern Datum bitcmp(PG_FUNCTION_ARGS); +extern Datum PG_encoding_to_char(PG_FUNCTION_ARGS); +extern Datum drandom(PG_FUNCTION_ARGS); +extern Datum setseed(PG_FUNCTION_ARGS); +extern Datum dasin(PG_FUNCTION_ARGS); +extern Datum dacos(PG_FUNCTION_ARGS); +extern Datum datan(PG_FUNCTION_ARGS); +extern Datum datan2(PG_FUNCTION_ARGS); +extern Datum dsin(PG_FUNCTION_ARGS); +extern Datum dcos(PG_FUNCTION_ARGS); +extern Datum dtan(PG_FUNCTION_ARGS); +extern Datum dcot(PG_FUNCTION_ARGS); +extern Datum degrees(PG_FUNCTION_ARGS); +extern Datum radians(PG_FUNCTION_ARGS); +extern Datum dpi(PG_FUNCTION_ARGS); +extern Datum interval_mul(PG_FUNCTION_ARGS); +extern Datum pg_typeof(PG_FUNCTION_ARGS); +extern Datum ascii(PG_FUNCTION_ARGS); +extern Datum chr(PG_FUNCTION_ARGS); +extern Datum repeat(PG_FUNCTION_ARGS); +extern Datum similar_escape(PG_FUNCTION_ARGS); +extern Datum mul_d_interval(PG_FUNCTION_ARGS); +extern Datum texticlike(PG_FUNCTION_ARGS); +extern Datum texticnlike(PG_FUNCTION_ARGS); +extern Datum nameiclike(PG_FUNCTION_ARGS); +extern Datum nameicnlike(PG_FUNCTION_ARGS); +extern Datum like_escape(PG_FUNCTION_ARGS); +extern Datum oidgt(PG_FUNCTION_ARGS); +extern Datum oidge(PG_FUNCTION_ARGS); +extern Datum pg_get_viewdef_name(PG_FUNCTION_ARGS); +extern Datum pg_get_viewdef(PG_FUNCTION_ARGS); +extern Datum pg_get_userbyid(PG_FUNCTION_ARGS); +extern Datum pg_get_indexdef(PG_FUNCTION_ARGS); +extern Datum RI_FKey_check_ins(PG_FUNCTION_ARGS); +extern Datum RI_FKey_check_upd(PG_FUNCTION_ARGS); +extern Datum RI_FKey_cascade_del(PG_FUNCTION_ARGS); +extern Datum RI_FKey_cascade_upd(PG_FUNCTION_ARGS); +extern Datum RI_FKey_restrict_del(PG_FUNCTION_ARGS); +extern Datum RI_FKey_restrict_upd(PG_FUNCTION_ARGS); +extern Datum RI_FKey_setnull_del(PG_FUNCTION_ARGS); +extern Datum RI_FKey_setnull_upd(PG_FUNCTION_ARGS); +extern Datum RI_FKey_setdefault_del(PG_FUNCTION_ARGS); +extern Datum RI_FKey_setdefault_upd(PG_FUNCTION_ARGS); +extern Datum RI_FKey_noaction_del(PG_FUNCTION_ARGS); +extern Datum RI_FKey_noaction_upd(PG_FUNCTION_ARGS); +extern Datum pg_get_triggerdef(PG_FUNCTION_ARGS); +extern Datum pg_get_serial_sequence(PG_FUNCTION_ARGS); +extern Datum bit_and(PG_FUNCTION_ARGS); +extern Datum bit_or(PG_FUNCTION_ARGS); +extern Datum bitxor(PG_FUNCTION_ARGS); +extern Datum bitnot(PG_FUNCTION_ARGS); +extern Datum bitshiftleft(PG_FUNCTION_ARGS); +extern Datum bitshiftright(PG_FUNCTION_ARGS); +extern Datum bitcat(PG_FUNCTION_ARGS); +extern Datum bitsubstr(PG_FUNCTION_ARGS); +extern Datum bitlength(PG_FUNCTION_ARGS); +extern Datum bitoctetlength(PG_FUNCTION_ARGS); +extern Datum bitfromint4(PG_FUNCTION_ARGS); +extern Datum bittoint4(PG_FUNCTION_ARGS); +extern Datum bit(PG_FUNCTION_ARGS); +extern Datum pg_get_keywords(PG_FUNCTION_ARGS); +extern Datum varbit(PG_FUNCTION_ARGS); +extern Datum time_hash(PG_FUNCTION_ARGS); +extern Datum aclexplode(PG_FUNCTION_ARGS); +extern Datum time_mi_time(PG_FUNCTION_ARGS); +extern Datum boolle(PG_FUNCTION_ARGS); +extern Datum boolge(PG_FUNCTION_ARGS); +extern Datum btboolcmp(PG_FUNCTION_ARGS); +extern Datum timetz_hash(PG_FUNCTION_ARGS); +extern Datum interval_hash(PG_FUNCTION_ARGS); +extern Datum bitposition(PG_FUNCTION_ARGS); +extern Datum bitsubstr_no_len(PG_FUNCTION_ARGS); +extern Datum numeric_in(PG_FUNCTION_ARGS); +extern Datum numeric_out(PG_FUNCTION_ARGS); +extern Datum numeric(PG_FUNCTION_ARGS); +extern Datum numeric_abs(PG_FUNCTION_ARGS); +extern Datum numeric_sign(PG_FUNCTION_ARGS); +extern Datum numeric_round(PG_FUNCTION_ARGS); +extern Datum numeric_trunc(PG_FUNCTION_ARGS); +extern Datum numeric_ceil(PG_FUNCTION_ARGS); +extern Datum numeric_floor(PG_FUNCTION_ARGS); +extern Datum length_in_encoding(PG_FUNCTION_ARGS); +extern Datum pg_convert_from(PG_FUNCTION_ARGS); +extern Datum inet_to_cidr(PG_FUNCTION_ARGS); +extern Datum pg_get_expr(PG_FUNCTION_ARGS); +extern Datum pg_convert_to(PG_FUNCTION_ARGS); +extern Datum numeric_eq(PG_FUNCTION_ARGS); +extern Datum numeric_ne(PG_FUNCTION_ARGS); +extern Datum numeric_gt(PG_FUNCTION_ARGS); +extern Datum numeric_ge(PG_FUNCTION_ARGS); +extern Datum numeric_lt(PG_FUNCTION_ARGS); +extern Datum numeric_le(PG_FUNCTION_ARGS); +extern Datum numeric_add(PG_FUNCTION_ARGS); +extern Datum numeric_sub(PG_FUNCTION_ARGS); +extern Datum numeric_mul(PG_FUNCTION_ARGS); +extern Datum numeric_div(PG_FUNCTION_ARGS); +extern Datum numeric_mod(PG_FUNCTION_ARGS); +extern Datum numeric_sqrt(PG_FUNCTION_ARGS); +extern Datum numeric_exp(PG_FUNCTION_ARGS); +extern Datum numeric_ln(PG_FUNCTION_ARGS); +extern Datum numeric_log(PG_FUNCTION_ARGS); +extern Datum numeric_power(PG_FUNCTION_ARGS); +extern Datum int4_numeric(PG_FUNCTION_ARGS); +extern Datum float4_numeric(PG_FUNCTION_ARGS); +extern Datum float8_numeric(PG_FUNCTION_ARGS); +extern Datum numeric_int4(PG_FUNCTION_ARGS); +extern Datum numeric_float4(PG_FUNCTION_ARGS); +extern Datum numeric_float8(PG_FUNCTION_ARGS); +extern Datum time_pl_interval(PG_FUNCTION_ARGS); +extern Datum time_mi_interval(PG_FUNCTION_ARGS); +extern Datum timetz_pl_interval(PG_FUNCTION_ARGS); +extern Datum timetz_mi_interval(PG_FUNCTION_ARGS); +extern Datum numeric_inc(PG_FUNCTION_ARGS); +extern Datum setval3_oid(PG_FUNCTION_ARGS); +extern Datum numeric_smaller(PG_FUNCTION_ARGS); +extern Datum numeric_larger(PG_FUNCTION_ARGS); +extern Datum interval_to_char(PG_FUNCTION_ARGS); +extern Datum numeric_cmp(PG_FUNCTION_ARGS); +extern Datum timestamptz_to_char(PG_FUNCTION_ARGS); +extern Datum numeric_uminus(PG_FUNCTION_ARGS); +extern Datum numeric_to_char(PG_FUNCTION_ARGS); +extern Datum int4_to_char(PG_FUNCTION_ARGS); +extern Datum int8_to_char(PG_FUNCTION_ARGS); +extern Datum float4_to_char(PG_FUNCTION_ARGS); +extern Datum float8_to_char(PG_FUNCTION_ARGS); +extern Datum numeric_to_number(PG_FUNCTION_ARGS); +extern Datum to_timestamp(PG_FUNCTION_ARGS); +extern Datum numeric_int8(PG_FUNCTION_ARGS); +extern Datum to_date(PG_FUNCTION_ARGS); +extern Datum int8_numeric(PG_FUNCTION_ARGS); +extern Datum int2_numeric(PG_FUNCTION_ARGS); +extern Datum numeric_int2(PG_FUNCTION_ARGS); +extern Datum oidin(PG_FUNCTION_ARGS); +extern Datum oidout(PG_FUNCTION_ARGS); +extern Datum pg_convert(PG_FUNCTION_ARGS); +extern Datum iclikesel(PG_FUNCTION_ARGS); +extern Datum icnlikesel(PG_FUNCTION_ARGS); +extern Datum iclikejoinsel(PG_FUNCTION_ARGS); +extern Datum icnlikejoinsel(PG_FUNCTION_ARGS); +extern Datum regexeqsel(PG_FUNCTION_ARGS); +extern Datum likesel(PG_FUNCTION_ARGS); +extern Datum icregexeqsel(PG_FUNCTION_ARGS); +extern Datum regexnesel(PG_FUNCTION_ARGS); +extern Datum nlikesel(PG_FUNCTION_ARGS); +extern Datum icregexnesel(PG_FUNCTION_ARGS); +extern Datum regexeqjoinsel(PG_FUNCTION_ARGS); +extern Datum likejoinsel(PG_FUNCTION_ARGS); +extern Datum icregexeqjoinsel(PG_FUNCTION_ARGS); +extern Datum regexnejoinsel(PG_FUNCTION_ARGS); +extern Datum nlikejoinsel(PG_FUNCTION_ARGS); +extern Datum icregexnejoinsel(PG_FUNCTION_ARGS); +extern Datum float8_avg(PG_FUNCTION_ARGS); +extern Datum float8_var_samp(PG_FUNCTION_ARGS); +extern Datum float8_stddev_samp(PG_FUNCTION_ARGS); +extern Datum numeric_accum(PG_FUNCTION_ARGS); +extern Datum int2_accum(PG_FUNCTION_ARGS); +extern Datum int4_accum(PG_FUNCTION_ARGS); +extern Datum int8_accum(PG_FUNCTION_ARGS); +extern Datum numeric_avg(PG_FUNCTION_ARGS); +extern Datum numeric_var_samp(PG_FUNCTION_ARGS); +extern Datum numeric_stddev_samp(PG_FUNCTION_ARGS); +extern Datum int2_sum(PG_FUNCTION_ARGS); +extern Datum int4_sum(PG_FUNCTION_ARGS); +extern Datum int8_sum(PG_FUNCTION_ARGS); +extern Datum interval_accum(PG_FUNCTION_ARGS); +extern Datum interval_avg(PG_FUNCTION_ARGS); +extern Datum to_ascii_default(PG_FUNCTION_ARGS); +extern Datum to_ascii_enc(PG_FUNCTION_ARGS); +extern Datum to_ascii_encname(PG_FUNCTION_ARGS); +extern Datum int28eq(PG_FUNCTION_ARGS); +extern Datum int28ne(PG_FUNCTION_ARGS); +extern Datum int28lt(PG_FUNCTION_ARGS); +extern Datum int28gt(PG_FUNCTION_ARGS); +extern Datum int28le(PG_FUNCTION_ARGS); +extern Datum int28ge(PG_FUNCTION_ARGS); +extern Datum int82eq(PG_FUNCTION_ARGS); +extern Datum int82ne(PG_FUNCTION_ARGS); +extern Datum int82lt(PG_FUNCTION_ARGS); +extern Datum int82gt(PG_FUNCTION_ARGS); +extern Datum int82le(PG_FUNCTION_ARGS); +extern Datum int82ge(PG_FUNCTION_ARGS); +extern Datum int2and(PG_FUNCTION_ARGS); +extern Datum int2or(PG_FUNCTION_ARGS); +extern Datum int2xor(PG_FUNCTION_ARGS); +extern Datum int2not(PG_FUNCTION_ARGS); +extern Datum int2shl(PG_FUNCTION_ARGS); +extern Datum int2shr(PG_FUNCTION_ARGS); +extern Datum int4and(PG_FUNCTION_ARGS); +extern Datum int4or(PG_FUNCTION_ARGS); +extern Datum int4xor(PG_FUNCTION_ARGS); +extern Datum int4not(PG_FUNCTION_ARGS); +extern Datum int4shl(PG_FUNCTION_ARGS); +extern Datum int4shr(PG_FUNCTION_ARGS); +extern Datum int8and(PG_FUNCTION_ARGS); +extern Datum int8or(PG_FUNCTION_ARGS); +extern Datum int8xor(PG_FUNCTION_ARGS); +extern Datum int8not(PG_FUNCTION_ARGS); +extern Datum int8shl(PG_FUNCTION_ARGS); +extern Datum int8shr(PG_FUNCTION_ARGS); +extern Datum int8up(PG_FUNCTION_ARGS); +extern Datum int2up(PG_FUNCTION_ARGS); +extern Datum int4up(PG_FUNCTION_ARGS); +extern Datum float4up(PG_FUNCTION_ARGS); +extern Datum float8up(PG_FUNCTION_ARGS); +extern Datum numeric_uplus(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_id(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_tuples_updated(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_blocks_hit(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS); +extern Datum binary_encode(PG_FUNCTION_ARGS); +extern Datum binary_decode(PG_FUNCTION_ARGS); +extern Datum byteaeq(PG_FUNCTION_ARGS); +extern Datum bytealt(PG_FUNCTION_ARGS); +extern Datum byteale(PG_FUNCTION_ARGS); +extern Datum byteagt(PG_FUNCTION_ARGS); +extern Datum byteage(PG_FUNCTION_ARGS); +extern Datum byteane(PG_FUNCTION_ARGS); +extern Datum byteacmp(PG_FUNCTION_ARGS); +extern Datum timestamp_scale(PG_FUNCTION_ARGS); +extern Datum int2_avg_accum(PG_FUNCTION_ARGS); +extern Datum int4_avg_accum(PG_FUNCTION_ARGS); +extern Datum int8_avg(PG_FUNCTION_ARGS); +extern Datum oidlarger(PG_FUNCTION_ARGS); +extern Datum oidsmaller(PG_FUNCTION_ARGS); +extern Datum timestamptz_scale(PG_FUNCTION_ARGS); +extern Datum time_scale(PG_FUNCTION_ARGS); +extern Datum timetz_scale(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS); +extern Datum numeric_div_trunc(PG_FUNCTION_ARGS); +extern Datum similar_to_escape_2(PG_FUNCTION_ARGS); +extern Datum similar_to_escape_1(PG_FUNCTION_ARGS); +extern Datum bytealike(PG_FUNCTION_ARGS); +extern Datum byteanlike(PG_FUNCTION_ARGS); +extern Datum like_escape_bytea(PG_FUNCTION_ARGS); +extern Datum byteacat(PG_FUNCTION_ARGS); +extern Datum bytea_substr(PG_FUNCTION_ARGS); +extern Datum bytea_substr_no_len(PG_FUNCTION_ARGS); +extern Datum byteapos(PG_FUNCTION_ARGS); +extern Datum byteatrim(PG_FUNCTION_ARGS); +extern Datum timestamptz_time(PG_FUNCTION_ARGS); +extern Datum timestamp_trunc(PG_FUNCTION_ARGS); +extern Datum timestamp_part(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_activity(PG_FUNCTION_ARGS); +extern Datum jsonb_path_query_first_tz(PG_FUNCTION_ARGS); +extern Datum date_timestamp(PG_FUNCTION_ARGS); +extern Datum pg_backend_pid(PG_FUNCTION_ARGS); +extern Datum timestamptz_timestamp(PG_FUNCTION_ARGS); +extern Datum timestamp_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_date(PG_FUNCTION_ARGS); +extern Datum jsonb_path_match_tz(PG_FUNCTION_ARGS); +extern Datum timestamp_pl_interval(PG_FUNCTION_ARGS); +extern Datum timestamp_mi_interval(PG_FUNCTION_ARGS); +extern Datum pg_conf_load_time(PG_FUNCTION_ARGS); +extern Datum timetz_zone(PG_FUNCTION_ARGS); +extern Datum timetz_izone(PG_FUNCTION_ARGS); +extern Datum timestamp_hash(PG_FUNCTION_ARGS); +extern Datum timetz_time(PG_FUNCTION_ARGS); +extern Datum time_timetz(PG_FUNCTION_ARGS); +extern Datum timestamp_to_char(PG_FUNCTION_ARGS); +extern Datum timestamp_age(PG_FUNCTION_ARGS); +extern Datum timestamp_zone(PG_FUNCTION_ARGS); +extern Datum timestamp_izone(PG_FUNCTION_ARGS); +extern Datum date_pl_interval(PG_FUNCTION_ARGS); +extern Datum date_mi_interval(PG_FUNCTION_ARGS); +extern Datum textregexsubstr(PG_FUNCTION_ARGS); +extern Datum bitfromint8(PG_FUNCTION_ARGS); +extern Datum bittoint8(PG_FUNCTION_ARGS); +extern Datum show_config_by_name(PG_FUNCTION_ARGS); +extern Datum set_config_by_name(PG_FUNCTION_ARGS); +extern Datum pg_table_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_type_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_function_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_operator_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_opclass_is_visible(PG_FUNCTION_ARGS); +extern Datum show_all_settings(PG_FUNCTION_ARGS); +extern Datum replace_text(PG_FUNCTION_ARGS); +extern Datum split_part(PG_FUNCTION_ARGS); +extern Datum to_hex32(PG_FUNCTION_ARGS); +extern Datum to_hex64(PG_FUNCTION_ARGS); +extern Datum array_lower(PG_FUNCTION_ARGS); +extern Datum array_upper(PG_FUNCTION_ARGS); +extern Datum pg_conversion_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS); +extern Datum pg_terminate_backend(PG_FUNCTION_ARGS); +extern Datum pg_get_functiondef(PG_FUNCTION_ARGS); +extern Datum pg_column_compression(PG_FUNCTION_ARGS); +extern Datum pg_stat_force_next_flush(PG_FUNCTION_ARGS); +extern Datum text_pattern_lt(PG_FUNCTION_ARGS); +extern Datum text_pattern_le(PG_FUNCTION_ARGS); +extern Datum pg_get_function_arguments(PG_FUNCTION_ARGS); +extern Datum text_pattern_ge(PG_FUNCTION_ARGS); +extern Datum text_pattern_gt(PG_FUNCTION_ARGS); +extern Datum pg_get_function_result(PG_FUNCTION_ARGS); +extern Datum bttext_pattern_cmp(PG_FUNCTION_ARGS); +extern Datum pg_database_size_name(PG_FUNCTION_ARGS); +extern Datum width_bucket_numeric(PG_FUNCTION_ARGS); +extern Datum pg_cancel_backend(PG_FUNCTION_ARGS); +extern Datum pg_backup_start(PG_FUNCTION_ARGS); +extern Datum bpchar_pattern_lt(PG_FUNCTION_ARGS); +extern Datum bpchar_pattern_le(PG_FUNCTION_ARGS); +extern Datum array_length(PG_FUNCTION_ARGS); +extern Datum bpchar_pattern_ge(PG_FUNCTION_ARGS); +extern Datum bpchar_pattern_gt(PG_FUNCTION_ARGS); +extern Datum gist_point_consistent(PG_FUNCTION_ARGS); +extern Datum btbpchar_pattern_cmp(PG_FUNCTION_ARGS); +extern Datum has_sequence_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_sequence_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_sequence_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_sequence_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_sequence_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_sequence_privilege_id(PG_FUNCTION_ARGS); +extern Datum btint48cmp(PG_FUNCTION_ARGS); +extern Datum btint84cmp(PG_FUNCTION_ARGS); +extern Datum btint24cmp(PG_FUNCTION_ARGS); +extern Datum btint42cmp(PG_FUNCTION_ARGS); +extern Datum btint28cmp(PG_FUNCTION_ARGS); +extern Datum btint82cmp(PG_FUNCTION_ARGS); +extern Datum btfloat48cmp(PG_FUNCTION_ARGS); +extern Datum btfloat84cmp(PG_FUNCTION_ARGS); +extern Datum inet_client_addr(PG_FUNCTION_ARGS); +extern Datum inet_client_port(PG_FUNCTION_ARGS); +extern Datum inet_server_addr(PG_FUNCTION_ARGS); +extern Datum inet_server_port(PG_FUNCTION_ARGS); +extern Datum regprocedurein(PG_FUNCTION_ARGS); +extern Datum regprocedureout(PG_FUNCTION_ARGS); +extern Datum regoperin(PG_FUNCTION_ARGS); +extern Datum regoperout(PG_FUNCTION_ARGS); +extern Datum regoperatorin(PG_FUNCTION_ARGS); +extern Datum regoperatorout(PG_FUNCTION_ARGS); +extern Datum regclassin(PG_FUNCTION_ARGS); +extern Datum regclassout(PG_FUNCTION_ARGS); +extern Datum regtypein(PG_FUNCTION_ARGS); +extern Datum regtypeout(PG_FUNCTION_ARGS); +extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS); +extern Datum pg_get_function_identity_arguments(PG_FUNCTION_ARGS); +extern Datum hashtid(PG_FUNCTION_ARGS); +extern Datum hashtidextended(PG_FUNCTION_ARGS); +extern Datum fmgr_internal_validator(PG_FUNCTION_ARGS); +extern Datum fmgr_c_validator(PG_FUNCTION_ARGS); +extern Datum fmgr_sql_validator(PG_FUNCTION_ARGS); +extern Datum has_database_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_database_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_database_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_database_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_database_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_database_privilege_id(PG_FUNCTION_ARGS); +extern Datum has_function_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_function_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_function_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_function_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_function_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_function_privilege_id(PG_FUNCTION_ARGS); +extern Datum has_language_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_language_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_language_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_language_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_language_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_language_privilege_id(PG_FUNCTION_ARGS); +extern Datum has_schema_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_schema_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_schema_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_schema_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_schema_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_schema_privilege_id(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset(PG_FUNCTION_ARGS); +extern Datum pg_get_backend_memory_contexts(PG_FUNCTION_ARGS); +extern Datum textregexreplace_noopt(PG_FUNCTION_ARGS); +extern Datum textregexreplace(PG_FUNCTION_ARGS); +extern Datum pg_total_relation_size(PG_FUNCTION_ARGS); +extern Datum pg_size_pretty(PG_FUNCTION_ARGS); +extern Datum pg_options_to_table(PG_FUNCTION_ARGS); +extern Datum record_in(PG_FUNCTION_ARGS); +extern Datum record_out(PG_FUNCTION_ARGS); +extern Datum cstring_in(PG_FUNCTION_ARGS); +extern Datum cstring_out(PG_FUNCTION_ARGS); +extern Datum any_in(PG_FUNCTION_ARGS); +extern Datum any_out(PG_FUNCTION_ARGS); +extern Datum anyarray_in(PG_FUNCTION_ARGS); +extern Datum anyarray_out(PG_FUNCTION_ARGS); +extern Datum void_in(PG_FUNCTION_ARGS); +extern Datum void_out(PG_FUNCTION_ARGS); +extern Datum trigger_in(PG_FUNCTION_ARGS); +extern Datum trigger_out(PG_FUNCTION_ARGS); +extern Datum language_handler_in(PG_FUNCTION_ARGS); +extern Datum language_handler_out(PG_FUNCTION_ARGS); +extern Datum internal_in(PG_FUNCTION_ARGS); +extern Datum internal_out(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_slru(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_slru(PG_FUNCTION_ARGS); +extern Datum dceil(PG_FUNCTION_ARGS); +extern Datum dfloor(PG_FUNCTION_ARGS); +extern Datum dsign(PG_FUNCTION_ARGS); +extern Datum md5_text(PG_FUNCTION_ARGS); +extern Datum anyelement_in(PG_FUNCTION_ARGS); +extern Datum anyelement_out(PG_FUNCTION_ARGS); +extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS); +extern Datum pg_encoding_max_length_sql(PG_FUNCTION_ARGS); +extern Datum md5_bytea(PG_FUNCTION_ARGS); +extern Datum pg_tablespace_size_oid(PG_FUNCTION_ARGS); +extern Datum pg_tablespace_size_name(PG_FUNCTION_ARGS); +extern Datum pg_database_size_oid(PG_FUNCTION_ARGS); +extern Datum array_unnest(PG_FUNCTION_ARGS); +extern Datum pg_relation_size(PG_FUNCTION_ARGS); +extern Datum array_agg_transfn(PG_FUNCTION_ARGS); +extern Datum array_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum date_lt_timestamp(PG_FUNCTION_ARGS); +extern Datum date_le_timestamp(PG_FUNCTION_ARGS); +extern Datum date_eq_timestamp(PG_FUNCTION_ARGS); +extern Datum date_gt_timestamp(PG_FUNCTION_ARGS); +extern Datum date_ge_timestamp(PG_FUNCTION_ARGS); +extern Datum date_ne_timestamp(PG_FUNCTION_ARGS); +extern Datum date_cmp_timestamp(PG_FUNCTION_ARGS); +extern Datum date_lt_timestamptz(PG_FUNCTION_ARGS); +extern Datum date_le_timestamptz(PG_FUNCTION_ARGS); +extern Datum date_eq_timestamptz(PG_FUNCTION_ARGS); +extern Datum date_gt_timestamptz(PG_FUNCTION_ARGS); +extern Datum date_ge_timestamptz(PG_FUNCTION_ARGS); +extern Datum date_ne_timestamptz(PG_FUNCTION_ARGS); +extern Datum date_cmp_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_lt_date(PG_FUNCTION_ARGS); +extern Datum timestamp_le_date(PG_FUNCTION_ARGS); +extern Datum timestamp_eq_date(PG_FUNCTION_ARGS); +extern Datum timestamp_gt_date(PG_FUNCTION_ARGS); +extern Datum timestamp_ge_date(PG_FUNCTION_ARGS); +extern Datum timestamp_ne_date(PG_FUNCTION_ARGS); +extern Datum timestamp_cmp_date(PG_FUNCTION_ARGS); +extern Datum timestamptz_lt_date(PG_FUNCTION_ARGS); +extern Datum timestamptz_le_date(PG_FUNCTION_ARGS); +extern Datum timestamptz_eq_date(PG_FUNCTION_ARGS); +extern Datum timestamptz_gt_date(PG_FUNCTION_ARGS); +extern Datum timestamptz_ge_date(PG_FUNCTION_ARGS); +extern Datum timestamptz_ne_date(PG_FUNCTION_ARGS); +extern Datum timestamptz_cmp_date(PG_FUNCTION_ARGS); +extern Datum has_tablespace_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_tablespace_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_tablespace_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_tablespace_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_tablespace_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_tablespace_privilege_id(PG_FUNCTION_ARGS); +extern Datum shell_in(PG_FUNCTION_ARGS); +extern Datum shell_out(PG_FUNCTION_ARGS); +extern Datum array_recv(PG_FUNCTION_ARGS); +extern Datum array_send(PG_FUNCTION_ARGS); +extern Datum record_recv(PG_FUNCTION_ARGS); +extern Datum record_send(PG_FUNCTION_ARGS); +extern Datum int2recv(PG_FUNCTION_ARGS); +extern Datum int2send(PG_FUNCTION_ARGS); +extern Datum int4recv(PG_FUNCTION_ARGS); +extern Datum int4send(PG_FUNCTION_ARGS); +extern Datum int8recv(PG_FUNCTION_ARGS); +extern Datum int8send(PG_FUNCTION_ARGS); +extern Datum int2vectorrecv(PG_FUNCTION_ARGS); +extern Datum int2vectorsend(PG_FUNCTION_ARGS); +extern Datum bytearecv(PG_FUNCTION_ARGS); +extern Datum byteasend(PG_FUNCTION_ARGS); +extern Datum textrecv(PG_FUNCTION_ARGS); +extern Datum textsend(PG_FUNCTION_ARGS); +extern Datum unknownrecv(PG_FUNCTION_ARGS); +extern Datum unknownsend(PG_FUNCTION_ARGS); +extern Datum oidrecv(PG_FUNCTION_ARGS); +extern Datum oidsend(PG_FUNCTION_ARGS); +extern Datum oidvectorrecv(PG_FUNCTION_ARGS); +extern Datum oidvectorsend(PG_FUNCTION_ARGS); +extern Datum namerecv(PG_FUNCTION_ARGS); +extern Datum namesend(PG_FUNCTION_ARGS); +extern Datum float4recv(PG_FUNCTION_ARGS); +extern Datum float4send(PG_FUNCTION_ARGS); +extern Datum float8recv(PG_FUNCTION_ARGS); +extern Datum float8send(PG_FUNCTION_ARGS); +extern Datum point_recv(PG_FUNCTION_ARGS); +extern Datum point_send(PG_FUNCTION_ARGS); +extern Datum bpcharrecv(PG_FUNCTION_ARGS); +extern Datum bpcharsend(PG_FUNCTION_ARGS); +extern Datum varcharrecv(PG_FUNCTION_ARGS); +extern Datum varcharsend(PG_FUNCTION_ARGS); +extern Datum charrecv(PG_FUNCTION_ARGS); +extern Datum charsend(PG_FUNCTION_ARGS); +extern Datum boolrecv(PG_FUNCTION_ARGS); +extern Datum boolsend(PG_FUNCTION_ARGS); +extern Datum tidrecv(PG_FUNCTION_ARGS); +extern Datum tidsend(PG_FUNCTION_ARGS); +extern Datum xidrecv(PG_FUNCTION_ARGS); +extern Datum xidsend(PG_FUNCTION_ARGS); +extern Datum cidrecv(PG_FUNCTION_ARGS); +extern Datum cidsend(PG_FUNCTION_ARGS); +extern Datum regprocrecv(PG_FUNCTION_ARGS); +extern Datum regprocsend(PG_FUNCTION_ARGS); +extern Datum regprocedurerecv(PG_FUNCTION_ARGS); +extern Datum regproceduresend(PG_FUNCTION_ARGS); +extern Datum regoperrecv(PG_FUNCTION_ARGS); +extern Datum regopersend(PG_FUNCTION_ARGS); +extern Datum regoperatorrecv(PG_FUNCTION_ARGS); +extern Datum regoperatorsend(PG_FUNCTION_ARGS); +extern Datum regclassrecv(PG_FUNCTION_ARGS); +extern Datum regclasssend(PG_FUNCTION_ARGS); +extern Datum regtyperecv(PG_FUNCTION_ARGS); +extern Datum regtypesend(PG_FUNCTION_ARGS); +extern Datum bit_recv(PG_FUNCTION_ARGS); +extern Datum bit_send(PG_FUNCTION_ARGS); +extern Datum varbit_recv(PG_FUNCTION_ARGS); +extern Datum varbit_send(PG_FUNCTION_ARGS); +extern Datum numeric_recv(PG_FUNCTION_ARGS); +extern Datum numeric_send(PG_FUNCTION_ARGS); +extern Datum dsinh(PG_FUNCTION_ARGS); +extern Datum dcosh(PG_FUNCTION_ARGS); +extern Datum dtanh(PG_FUNCTION_ARGS); +extern Datum dasinh(PG_FUNCTION_ARGS); +extern Datum dacosh(PG_FUNCTION_ARGS); +extern Datum datanh(PG_FUNCTION_ARGS); +extern Datum date_recv(PG_FUNCTION_ARGS); +extern Datum date_send(PG_FUNCTION_ARGS); +extern Datum time_recv(PG_FUNCTION_ARGS); +extern Datum time_send(PG_FUNCTION_ARGS); +extern Datum timetz_recv(PG_FUNCTION_ARGS); +extern Datum timetz_send(PG_FUNCTION_ARGS); +extern Datum timestamp_recv(PG_FUNCTION_ARGS); +extern Datum timestamp_send(PG_FUNCTION_ARGS); +extern Datum timestamptz_recv(PG_FUNCTION_ARGS); +extern Datum timestamptz_send(PG_FUNCTION_ARGS); +extern Datum interval_recv(PG_FUNCTION_ARGS); +extern Datum interval_send(PG_FUNCTION_ARGS); +extern Datum lseg_recv(PG_FUNCTION_ARGS); +extern Datum lseg_send(PG_FUNCTION_ARGS); +extern Datum path_recv(PG_FUNCTION_ARGS); +extern Datum path_send(PG_FUNCTION_ARGS); +extern Datum box_recv(PG_FUNCTION_ARGS); +extern Datum box_send(PG_FUNCTION_ARGS); +extern Datum poly_recv(PG_FUNCTION_ARGS); +extern Datum poly_send(PG_FUNCTION_ARGS); +extern Datum line_recv(PG_FUNCTION_ARGS); +extern Datum line_send(PG_FUNCTION_ARGS); +extern Datum circle_recv(PG_FUNCTION_ARGS); +extern Datum circle_send(PG_FUNCTION_ARGS); +extern Datum cash_recv(PG_FUNCTION_ARGS); +extern Datum cash_send(PG_FUNCTION_ARGS); +extern Datum macaddr_recv(PG_FUNCTION_ARGS); +extern Datum macaddr_send(PG_FUNCTION_ARGS); +extern Datum inet_recv(PG_FUNCTION_ARGS); +extern Datum inet_send(PG_FUNCTION_ARGS); +extern Datum cidr_recv(PG_FUNCTION_ARGS); +extern Datum cidr_send(PG_FUNCTION_ARGS); +extern Datum cstring_recv(PG_FUNCTION_ARGS); +extern Datum cstring_send(PG_FUNCTION_ARGS); +extern Datum anyarray_recv(PG_FUNCTION_ARGS); +extern Datum anyarray_send(PG_FUNCTION_ARGS); +extern Datum pg_get_ruledef_ext(PG_FUNCTION_ARGS); +extern Datum pg_get_viewdef_name_ext(PG_FUNCTION_ARGS); +extern Datum pg_get_viewdef_ext(PG_FUNCTION_ARGS); +extern Datum pg_get_indexdef_ext(PG_FUNCTION_ARGS); +extern Datum pg_get_constraintdef_ext(PG_FUNCTION_ARGS); +extern Datum pg_get_expr_ext(PG_FUNCTION_ARGS); +extern Datum pg_prepared_statement(PG_FUNCTION_ARGS); +extern Datum pg_cursor(PG_FUNCTION_ARGS); +extern Datum float8_var_pop(PG_FUNCTION_ARGS); +extern Datum float8_stddev_pop(PG_FUNCTION_ARGS); +extern Datum numeric_var_pop(PG_FUNCTION_ARGS); +extern Datum booland_statefunc(PG_FUNCTION_ARGS); +extern Datum boolor_statefunc(PG_FUNCTION_ARGS); +extern Datum timestamp_lt_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_le_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_eq_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_gt_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_ge_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_ne_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamp_cmp_timestamptz(PG_FUNCTION_ARGS); +extern Datum timestamptz_lt_timestamp(PG_FUNCTION_ARGS); +extern Datum timestamptz_le_timestamp(PG_FUNCTION_ARGS); +extern Datum timestamptz_eq_timestamp(PG_FUNCTION_ARGS); +extern Datum timestamptz_gt_timestamp(PG_FUNCTION_ARGS); +extern Datum timestamptz_ge_timestamp(PG_FUNCTION_ARGS); +extern Datum timestamptz_ne_timestamp(PG_FUNCTION_ARGS); +extern Datum timestamptz_cmp_timestamp(PG_FUNCTION_ARGS); +extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS); +extern Datum int4_bool(PG_FUNCTION_ARGS); +extern Datum bool_int4(PG_FUNCTION_ARGS); +extern Datum lastval(PG_FUNCTION_ARGS); +extern Datum pg_postmaster_start_time(PG_FUNCTION_ARGS); +extern Datum pg_blocking_pids(PG_FUNCTION_ARGS); +extern Datum box_below(PG_FUNCTION_ARGS); +extern Datum box_overbelow(PG_FUNCTION_ARGS); +extern Datum box_overabove(PG_FUNCTION_ARGS); +extern Datum box_above(PG_FUNCTION_ARGS); +extern Datum poly_below(PG_FUNCTION_ARGS); +extern Datum poly_overbelow(PG_FUNCTION_ARGS); +extern Datum poly_overabove(PG_FUNCTION_ARGS); +extern Datum poly_above(PG_FUNCTION_ARGS); +extern Datum gist_box_consistent(PG_FUNCTION_ARGS); +extern Datum jsonb_float8(PG_FUNCTION_ARGS); +extern Datum gist_box_penalty(PG_FUNCTION_ARGS); +extern Datum gist_box_picksplit(PG_FUNCTION_ARGS); +extern Datum gist_box_union(PG_FUNCTION_ARGS); +extern Datum gist_box_same(PG_FUNCTION_ARGS); +extern Datum gist_poly_consistent(PG_FUNCTION_ARGS); +extern Datum gist_poly_compress(PG_FUNCTION_ARGS); +extern Datum circle_overbelow(PG_FUNCTION_ARGS); +extern Datum circle_overabove(PG_FUNCTION_ARGS); +extern Datum gist_circle_consistent(PG_FUNCTION_ARGS); +extern Datum gist_circle_compress(PG_FUNCTION_ARGS); +extern Datum numeric_stddev_pop(PG_FUNCTION_ARGS); +extern Datum domain_in(PG_FUNCTION_ARGS); +extern Datum domain_recv(PG_FUNCTION_ARGS); +extern Datum pg_timezone_abbrevs(PG_FUNCTION_ARGS); +extern Datum xmlexists(PG_FUNCTION_ARGS); +extern Datum pg_reload_conf(PG_FUNCTION_ARGS); +extern Datum pg_rotate_logfile_v2(PG_FUNCTION_ARGS); +extern Datum pg_stat_file_1arg(PG_FUNCTION_ARGS); +extern Datum pg_read_file_off_len(PG_FUNCTION_ARGS); +extern Datum pg_ls_dir_1arg(PG_FUNCTION_ARGS); +extern Datum pg_sleep(PG_FUNCTION_ARGS); +extern Datum inetnot(PG_FUNCTION_ARGS); +extern Datum inetand(PG_FUNCTION_ARGS); +extern Datum inetor(PG_FUNCTION_ARGS); +extern Datum inetpl(PG_FUNCTION_ARGS); +extern Datum inetmi_int8(PG_FUNCTION_ARGS); +extern Datum inetmi(PG_FUNCTION_ARGS); +extern Datum statement_timestamp(PG_FUNCTION_ARGS); +extern Datum clock_timestamp(PG_FUNCTION_ARGS); +extern Datum gin_cmp_prefix(PG_FUNCTION_ARGS); +extern Datum pg_has_role_name_name(PG_FUNCTION_ARGS); +extern Datum pg_has_role_name_id(PG_FUNCTION_ARGS); +extern Datum pg_has_role_id_name(PG_FUNCTION_ARGS); +extern Datum pg_has_role_id_id(PG_FUNCTION_ARGS); +extern Datum pg_has_role_name(PG_FUNCTION_ARGS); +extern Datum pg_has_role_id(PG_FUNCTION_ARGS); +extern Datum interval_justify_interval(PG_FUNCTION_ARGS); +extern Datum pg_get_triggerdef_ext(PG_FUNCTION_ARGS); +extern Datum dasind(PG_FUNCTION_ARGS); +extern Datum dacosd(PG_FUNCTION_ARGS); +extern Datum datand(PG_FUNCTION_ARGS); +extern Datum datan2d(PG_FUNCTION_ARGS); +extern Datum dsind(PG_FUNCTION_ARGS); +extern Datum dcosd(PG_FUNCTION_ARGS); +extern Datum dtand(PG_FUNCTION_ARGS); +extern Datum dcotd(PG_FUNCTION_ARGS); +extern Datum pg_backup_stop(PG_FUNCTION_ARGS); +extern Datum numeric_avg_serialize(PG_FUNCTION_ARGS); +extern Datum numeric_avg_deserialize(PG_FUNCTION_ARGS); +extern Datum ginarrayextract(PG_FUNCTION_ARGS); +extern Datum ginarrayconsistent(PG_FUNCTION_ARGS); +extern Datum int8_avg_accum(PG_FUNCTION_ARGS); +extern Datum arrayoverlap(PG_FUNCTION_ARGS); +extern Datum arraycontains(PG_FUNCTION_ARGS); +extern Datum arraycontained(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS); +extern Datum regexp_matches_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_matches(PG_FUNCTION_ARGS); +extern Datum regexp_split_to_table_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_split_to_table(PG_FUNCTION_ARGS); +extern Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_split_to_array(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS); +extern Datum ginqueryarrayextract(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS); +extern Datum anynonarray_in(PG_FUNCTION_ARGS); +extern Datum anynonarray_out(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS); +extern Datum int8_avg_combine(PG_FUNCTION_ARGS); +extern Datum int8_avg_serialize(PG_FUNCTION_ARGS); +extern Datum int8_avg_deserialize(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS); +extern Datum tidgt(PG_FUNCTION_ARGS); +extern Datum tidlt(PG_FUNCTION_ARGS); +extern Datum tidge(PG_FUNCTION_ARGS); +extern Datum tidle(PG_FUNCTION_ARGS); +extern Datum bttidcmp(PG_FUNCTION_ARGS); +extern Datum tidlarger(PG_FUNCTION_ARGS); +extern Datum tidsmaller(PG_FUNCTION_ARGS); +extern Datum int8inc_any(PG_FUNCTION_ARGS); +extern Datum int8inc_float8_float8(PG_FUNCTION_ARGS); +extern Datum float8_regr_accum(PG_FUNCTION_ARGS); +extern Datum float8_regr_sxx(PG_FUNCTION_ARGS); +extern Datum float8_regr_syy(PG_FUNCTION_ARGS); +extern Datum float8_regr_sxy(PG_FUNCTION_ARGS); +extern Datum float8_regr_avgx(PG_FUNCTION_ARGS); +extern Datum float8_regr_avgy(PG_FUNCTION_ARGS); +extern Datum float8_regr_r2(PG_FUNCTION_ARGS); +extern Datum float8_regr_slope(PG_FUNCTION_ARGS); +extern Datum float8_regr_intercept(PG_FUNCTION_ARGS); +extern Datum float8_covar_pop(PG_FUNCTION_ARGS); +extern Datum float8_covar_samp(PG_FUNCTION_ARGS); +extern Datum float8_corr(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_blk_read_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_blk_write_time(PG_FUNCTION_ARGS); +extern Datum pg_switch_wal(PG_FUNCTION_ARGS); +extern Datum pg_current_wal_lsn(PG_FUNCTION_ARGS); +extern Datum pg_walfile_name_offset(PG_FUNCTION_ARGS); +extern Datum pg_walfile_name(PG_FUNCTION_ARGS); +extern Datum pg_current_wal_insert_lsn(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS); +extern Datum pg_my_temp_schema(PG_FUNCTION_ARGS); +extern Datum pg_is_other_temp_schema(PG_FUNCTION_ARGS); +extern Datum pg_timezone_names(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS); +extern Datum numeric_avg_accum(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_live_tuples(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_dead_tuples(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_int8(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_int4(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_shared_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_unlock_all(PG_FUNCTION_ARGS); +extern Datum xml_in(PG_FUNCTION_ARGS); +extern Datum xml_out(PG_FUNCTION_ARGS); +extern Datum xmlcomment(PG_FUNCTION_ARGS); +extern Datum texttoxml(PG_FUNCTION_ARGS); +extern Datum xmlvalidate(PG_FUNCTION_ARGS); +extern Datum xml_recv(PG_FUNCTION_ARGS); +extern Datum xml_send(PG_FUNCTION_ARGS); +extern Datum xmlconcat2(PG_FUNCTION_ARGS); +extern Datum varbittypmodin(PG_FUNCTION_ARGS); +extern Datum intervaltypmodin(PG_FUNCTION_ARGS); +extern Datum intervaltypmodout(PG_FUNCTION_ARGS); +extern Datum timestamptypmodin(PG_FUNCTION_ARGS); +extern Datum timestamptypmodout(PG_FUNCTION_ARGS); +extern Datum timestamptztypmodin(PG_FUNCTION_ARGS); +extern Datum timestamptztypmodout(PG_FUNCTION_ARGS); +extern Datum timetypmodin(PG_FUNCTION_ARGS); +extern Datum timetypmodout(PG_FUNCTION_ARGS); +extern Datum timetztypmodin(PG_FUNCTION_ARGS); +extern Datum timetztypmodout(PG_FUNCTION_ARGS); +extern Datum bpchartypmodin(PG_FUNCTION_ARGS); +extern Datum bpchartypmodout(PG_FUNCTION_ARGS); +extern Datum varchartypmodin(PG_FUNCTION_ARGS); +extern Datum varchartypmodout(PG_FUNCTION_ARGS); +extern Datum numerictypmodin(PG_FUNCTION_ARGS); +extern Datum numerictypmodout(PG_FUNCTION_ARGS); +extern Datum bittypmodin(PG_FUNCTION_ARGS); +extern Datum bittypmodout(PG_FUNCTION_ARGS); +extern Datum varbittypmodout(PG_FUNCTION_ARGS); +extern Datum xmltotext(PG_FUNCTION_ARGS); +extern Datum table_to_xml(PG_FUNCTION_ARGS); +extern Datum query_to_xml(PG_FUNCTION_ARGS); +extern Datum cursor_to_xml(PG_FUNCTION_ARGS); +extern Datum table_to_xmlschema(PG_FUNCTION_ARGS); +extern Datum query_to_xmlschema(PG_FUNCTION_ARGS); +extern Datum cursor_to_xmlschema(PG_FUNCTION_ARGS); +extern Datum table_to_xml_and_xmlschema(PG_FUNCTION_ARGS); +extern Datum query_to_xml_and_xmlschema(PG_FUNCTION_ARGS); +extern Datum xpath(PG_FUNCTION_ARGS); +extern Datum schema_to_xml(PG_FUNCTION_ARGS); +extern Datum schema_to_xmlschema(PG_FUNCTION_ARGS); +extern Datum schema_to_xml_and_xmlschema(PG_FUNCTION_ARGS); +extern Datum database_to_xml(PG_FUNCTION_ARGS); +extern Datum database_to_xmlschema(PG_FUNCTION_ARGS); +extern Datum database_to_xml_and_xmlschema(PG_FUNCTION_ARGS); +extern Datum pg_snapshot_in(PG_FUNCTION_ARGS); +extern Datum pg_snapshot_out(PG_FUNCTION_ARGS); +extern Datum pg_snapshot_recv(PG_FUNCTION_ARGS); +extern Datum pg_snapshot_send(PG_FUNCTION_ARGS); +extern Datum pg_current_xact_id(PG_FUNCTION_ARGS); +extern Datum pg_current_snapshot(PG_FUNCTION_ARGS); +extern Datum pg_snapshot_xmin(PG_FUNCTION_ARGS); +extern Datum pg_snapshot_xmax(PG_FUNCTION_ARGS); +extern Datum pg_snapshot_xip(PG_FUNCTION_ARGS); +extern Datum pg_visible_in_snapshot(PG_FUNCTION_ARGS); +extern Datum uuid_in(PG_FUNCTION_ARGS); +extern Datum uuid_out(PG_FUNCTION_ARGS); +extern Datum uuid_lt(PG_FUNCTION_ARGS); +extern Datum uuid_le(PG_FUNCTION_ARGS); +extern Datum uuid_eq(PG_FUNCTION_ARGS); +extern Datum uuid_ge(PG_FUNCTION_ARGS); +extern Datum uuid_gt(PG_FUNCTION_ARGS); +extern Datum uuid_ne(PG_FUNCTION_ARGS); +extern Datum uuid_cmp(PG_FUNCTION_ARGS); +extern Datum uuid_recv(PG_FUNCTION_ARGS); +extern Datum uuid_send(PG_FUNCTION_ARGS); +extern Datum uuid_hash(PG_FUNCTION_ARGS); +extern Datum booltext(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_function_total_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_function_self_time(PG_FUNCTION_ARGS); +extern Datum record_eq(PG_FUNCTION_ARGS); +extern Datum record_ne(PG_FUNCTION_ARGS); +extern Datum record_lt(PG_FUNCTION_ARGS); +extern Datum record_gt(PG_FUNCTION_ARGS); +extern Datum record_le(PG_FUNCTION_ARGS); +extern Datum record_ge(PG_FUNCTION_ARGS); +extern Datum btrecordcmp(PG_FUNCTION_ARGS); +extern Datum pg_table_size(PG_FUNCTION_ARGS); +extern Datum pg_indexes_size(PG_FUNCTION_ARGS); +extern Datum pg_relation_filenode(PG_FUNCTION_ARGS); +extern Datum has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_foreign_data_wrapper_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_foreign_data_wrapper_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_foreign_data_wrapper_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_foreign_data_wrapper_privilege_id(PG_FUNCTION_ARGS); +extern Datum has_server_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_server_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_server_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_server_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_server_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_server_privilege_id(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_name_name_name(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_name_id_name(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_id_name_name(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_id_name_attnum(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_id_id_name(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_id_id_attnum(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_name_attnum(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_column_privilege_id_attnum(PG_FUNCTION_ARGS); +extern Datum has_any_column_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_any_column_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_any_column_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_any_column_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_any_column_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_any_column_privilege_id(PG_FUNCTION_ARGS); +extern Datum bitoverlay(PG_FUNCTION_ARGS); +extern Datum bitoverlay_no_len(PG_FUNCTION_ARGS); +extern Datum bitgetbit(PG_FUNCTION_ARGS); +extern Datum bitsetbit(PG_FUNCTION_ARGS); +extern Datum pg_relation_filepath(PG_FUNCTION_ARGS); +extern Datum pg_listening_channels(PG_FUNCTION_ARGS); +extern Datum pg_notify(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_function_total_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS); +extern Datum xpath_exists(PG_FUNCTION_ARGS); +extern Datum xml_is_well_formed(PG_FUNCTION_ARGS); +extern Datum xml_is_well_formed_document(PG_FUNCTION_ARGS); +extern Datum xml_is_well_formed_content(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_vacuum_count(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_autovacuum_count(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_analyze_count(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS); +extern Datum text_concat(PG_FUNCTION_ARGS); +extern Datum text_concat_ws(PG_FUNCTION_ARGS); +extern Datum text_left(PG_FUNCTION_ARGS); +extern Datum text_right(PG_FUNCTION_ARGS); +extern Datum text_reverse(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS); +extern Datum gist_point_distance(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_conflict_tablespace(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_conflict_lock(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_conflict_snapshot(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_conflict_bufferpin(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_conflict_startup_deadlock(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS); +extern Datum pg_wal_replay_pause(PG_FUNCTION_ARGS); +extern Datum pg_wal_replay_resume(PG_FUNCTION_ARGS); +extern Datum pg_is_wal_replay_paused(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS); +extern Datum ginarrayextract_2args(PG_FUNCTION_ARGS); +extern Datum gin_extract_tsvector_2args(PG_FUNCTION_ARGS); +extern Datum pg_sequence_parameters(PG_FUNCTION_ARGS); +extern Datum pg_available_extensions(PG_FUNCTION_ARGS); +extern Datum pg_available_extension_versions(PG_FUNCTION_ARGS); +extern Datum pg_extension_update_paths(PG_FUNCTION_ARGS); +extern Datum pg_extension_config_dump(PG_FUNCTION_ARGS); +extern Datum gin_extract_tsquery_5args(PG_FUNCTION_ARGS); +extern Datum gin_tsquery_consistent_6args(PG_FUNCTION_ARGS); +extern Datum pg_advisory_xact_lock_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_xact_lock_int8(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS); +extern Datum pg_advisory_xact_lock_int4(PG_FUNCTION_ARGS); +extern Datum pg_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_xact_lock_int4(PG_FUNCTION_ARGS); +extern Datum pg_try_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS); +extern Datum varchar_support(PG_FUNCTION_ARGS); +extern Datum pg_create_restore_point(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_wal_senders(PG_FUNCTION_ARGS); +extern Datum window_row_number(PG_FUNCTION_ARGS); +extern Datum window_rank(PG_FUNCTION_ARGS); +extern Datum window_dense_rank(PG_FUNCTION_ARGS); +extern Datum window_percent_rank(PG_FUNCTION_ARGS); +extern Datum window_cume_dist(PG_FUNCTION_ARGS); +extern Datum window_ntile(PG_FUNCTION_ARGS); +extern Datum window_lag(PG_FUNCTION_ARGS); +extern Datum window_lag_with_offset(PG_FUNCTION_ARGS); +extern Datum window_lag_with_offset_and_default(PG_FUNCTION_ARGS); +extern Datum window_lead(PG_FUNCTION_ARGS); +extern Datum window_lead_with_offset(PG_FUNCTION_ARGS); +extern Datum window_lead_with_offset_and_default(PG_FUNCTION_ARGS); +extern Datum window_first_value(PG_FUNCTION_ARGS); +extern Datum window_last_value(PG_FUNCTION_ARGS); +extern Datum window_nth_value(PG_FUNCTION_ARGS); +extern Datum fdw_handler_in(PG_FUNCTION_ARGS); +extern Datum fdw_handler_out(PG_FUNCTION_ARGS); +extern Datum void_recv(PG_FUNCTION_ARGS); +extern Datum void_send(PG_FUNCTION_ARGS); +extern Datum btint2sortsupport(PG_FUNCTION_ARGS); +extern Datum btint4sortsupport(PG_FUNCTION_ARGS); +extern Datum btint8sortsupport(PG_FUNCTION_ARGS); +extern Datum btfloat4sortsupport(PG_FUNCTION_ARGS); +extern Datum btfloat8sortsupport(PG_FUNCTION_ARGS); +extern Datum btoidsortsupport(PG_FUNCTION_ARGS); +extern Datum btnamesortsupport(PG_FUNCTION_ARGS); +extern Datum date_sortsupport(PG_FUNCTION_ARGS); +extern Datum timestamp_sortsupport(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_id(PG_FUNCTION_ARGS); +extern Datum macaddr_not(PG_FUNCTION_ARGS); +extern Datum macaddr_and(PG_FUNCTION_ARGS); +extern Datum macaddr_or(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_temp_files(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_temp_bytes(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_deadlocks(PG_FUNCTION_ARGS); +extern Datum array_to_json(PG_FUNCTION_ARGS); +extern Datum array_to_json_pretty(PG_FUNCTION_ARGS); +extern Datum row_to_json(PG_FUNCTION_ARGS); +extern Datum row_to_json_pretty(PG_FUNCTION_ARGS); +extern Datum numeric_support(PG_FUNCTION_ARGS); +extern Datum varbit_support(PG_FUNCTION_ARGS); +extern Datum pg_get_viewdef_wrap(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_checkpoint_write_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_checkpoint_sync_time(PG_FUNCTION_ARGS); +extern Datum pg_collation_for(PG_FUNCTION_ARGS); +extern Datum pg_trigger_depth(PG_FUNCTION_ARGS); +extern Datum pg_wal_lsn_diff(PG_FUNCTION_ARGS); +extern Datum pg_size_pretty_numeric(PG_FUNCTION_ARGS); +extern Datum array_remove(PG_FUNCTION_ARGS); +extern Datum array_replace(PG_FUNCTION_ARGS); +extern Datum rangesel(PG_FUNCTION_ARGS); +extern Datum be_lo_lseek64(PG_FUNCTION_ARGS); +extern Datum be_lo_tell64(PG_FUNCTION_ARGS); +extern Datum be_lo_truncate64(PG_FUNCTION_ARGS); +extern Datum json_agg_transfn(PG_FUNCTION_ARGS); +extern Datum json_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum to_json(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_mod_since_analyze(PG_FUNCTION_ARGS); +extern Datum numeric_sum(PG_FUNCTION_ARGS); +extern Datum array_cardinality(PG_FUNCTION_ARGS); +extern Datum json_object_agg_transfn(PG_FUNCTION_ARGS); +extern Datum record_image_eq(PG_FUNCTION_ARGS); +extern Datum record_image_ne(PG_FUNCTION_ARGS); +extern Datum record_image_lt(PG_FUNCTION_ARGS); +extern Datum record_image_gt(PG_FUNCTION_ARGS); +extern Datum record_image_le(PG_FUNCTION_ARGS); +extern Datum record_image_ge(PG_FUNCTION_ARGS); +extern Datum btrecordimagecmp(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_archiver(PG_FUNCTION_ARGS); +extern Datum json_object_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum json_build_array(PG_FUNCTION_ARGS); +extern Datum json_build_array_noargs(PG_FUNCTION_ARGS); +extern Datum json_build_object(PG_FUNCTION_ARGS); +extern Datum json_build_object_noargs(PG_FUNCTION_ARGS); +extern Datum json_object(PG_FUNCTION_ARGS); +extern Datum json_object_two_arg(PG_FUNCTION_ARGS); +extern Datum json_to_record(PG_FUNCTION_ARGS); +extern Datum json_to_recordset(PG_FUNCTION_ARGS); +extern Datum jsonb_array_length(PG_FUNCTION_ARGS); +extern Datum jsonb_each(PG_FUNCTION_ARGS); +extern Datum jsonb_populate_record(PG_FUNCTION_ARGS); +extern Datum jsonb_typeof(PG_FUNCTION_ARGS); +extern Datum jsonb_object_field_text(PG_FUNCTION_ARGS); +extern Datum jsonb_array_element(PG_FUNCTION_ARGS); +extern Datum jsonb_array_element_text(PG_FUNCTION_ARGS); +extern Datum jsonb_extract_path(PG_FUNCTION_ARGS); +extern Datum width_bucket_array(PG_FUNCTION_ARGS); +extern Datum jsonb_array_elements(PG_FUNCTION_ARGS); +extern Datum pg_lsn_in(PG_FUNCTION_ARGS); +extern Datum pg_lsn_out(PG_FUNCTION_ARGS); +extern Datum pg_lsn_lt(PG_FUNCTION_ARGS); +extern Datum pg_lsn_le(PG_FUNCTION_ARGS); +extern Datum pg_lsn_eq(PG_FUNCTION_ARGS); +extern Datum pg_lsn_ge(PG_FUNCTION_ARGS); +extern Datum pg_lsn_gt(PG_FUNCTION_ARGS); +extern Datum pg_lsn_ne(PG_FUNCTION_ARGS); +extern Datum pg_lsn_mi(PG_FUNCTION_ARGS); +extern Datum pg_lsn_recv(PG_FUNCTION_ARGS); +extern Datum pg_lsn_send(PG_FUNCTION_ARGS); +extern Datum pg_lsn_cmp(PG_FUNCTION_ARGS); +extern Datum pg_lsn_hash(PG_FUNCTION_ARGS); +extern Datum bttextsortsupport(PG_FUNCTION_ARGS); +extern Datum generate_series_step_numeric(PG_FUNCTION_ARGS); +extern Datum generate_series_numeric(PG_FUNCTION_ARGS); +extern Datum json_strip_nulls(PG_FUNCTION_ARGS); +extern Datum jsonb_strip_nulls(PG_FUNCTION_ARGS); +extern Datum jsonb_object(PG_FUNCTION_ARGS); +extern Datum jsonb_object_two_arg(PG_FUNCTION_ARGS); +extern Datum jsonb_agg_transfn(PG_FUNCTION_ARGS); +extern Datum jsonb_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum jsonb_object_agg_transfn(PG_FUNCTION_ARGS); +extern Datum jsonb_object_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum jsonb_build_array(PG_FUNCTION_ARGS); +extern Datum jsonb_build_array_noargs(PG_FUNCTION_ARGS); +extern Datum jsonb_build_object(PG_FUNCTION_ARGS); +extern Datum jsonb_build_object_noargs(PG_FUNCTION_ARGS); +extern Datum dist_ppoly(PG_FUNCTION_ARGS); +extern Datum array_position(PG_FUNCTION_ARGS); +extern Datum array_position_start(PG_FUNCTION_ARGS); +extern Datum array_positions(PG_FUNCTION_ARGS); +extern Datum gist_circle_distance(PG_FUNCTION_ARGS); +extern Datum numeric_scale(PG_FUNCTION_ARGS); +extern Datum gist_point_fetch(PG_FUNCTION_ARGS); +extern Datum numeric_sortsupport(PG_FUNCTION_ARGS); +extern Datum gist_poly_distance(PG_FUNCTION_ARGS); +extern Datum dist_cpoint(PG_FUNCTION_ARGS); +extern Datum dist_polyp(PG_FUNCTION_ARGS); +extern Datum pg_read_file_off_len_missing(PG_FUNCTION_ARGS); +extern Datum show_config_by_name_missing_ok(PG_FUNCTION_ARGS); +extern Datum pg_read_binary_file_off_len_missing(PG_FUNCTION_ARGS); +extern Datum pg_notification_queue_usage(PG_FUNCTION_ARGS); +extern Datum pg_ls_dir(PG_FUNCTION_ARGS); +extern Datum row_security_active(PG_FUNCTION_ARGS); +extern Datum row_security_active_name(PG_FUNCTION_ARGS); +extern Datum uuid_sortsupport(PG_FUNCTION_ARGS); +extern Datum jsonb_concat(PG_FUNCTION_ARGS); +extern Datum jsonb_delete(PG_FUNCTION_ARGS); +extern Datum jsonb_delete_idx(PG_FUNCTION_ARGS); +extern Datum jsonb_delete_path(PG_FUNCTION_ARGS); +extern Datum jsonb_set(PG_FUNCTION_ARGS); +extern Datum jsonb_pretty(PG_FUNCTION_ARGS); +extern Datum pg_stat_file(PG_FUNCTION_ARGS); +extern Datum xidneq(PG_FUNCTION_ARGS); +extern Datum tsm_handler_in(PG_FUNCTION_ARGS); +extern Datum tsm_handler_out(PG_FUNCTION_ARGS); +extern Datum tsm_bernoulli_handler(PG_FUNCTION_ARGS); +extern Datum tsm_system_handler(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_wal_receiver(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_progress_info(PG_FUNCTION_ARGS); +extern Datum tsvector_filter(PG_FUNCTION_ARGS); +extern Datum tsvector_setweight_by_filter(PG_FUNCTION_ARGS); +extern Datum tsvector_delete_str(PG_FUNCTION_ARGS); +extern Datum tsvector_unnest(PG_FUNCTION_ARGS); +extern Datum tsvector_delete_arr(PG_FUNCTION_ARGS); +extern Datum int4_avg_combine(PG_FUNCTION_ARGS); +extern Datum interval_combine(PG_FUNCTION_ARGS); +extern Datum tsvector_to_array(PG_FUNCTION_ARGS); +extern Datum array_to_tsvector(PG_FUNCTION_ARGS); +extern Datum bpchar_sortsupport(PG_FUNCTION_ARGS); +extern Datum show_all_file_settings(PG_FUNCTION_ARGS); +extern Datum pg_current_wal_flush_lsn(PG_FUNCTION_ARGS); +extern Datum bytea_sortsupport(PG_FUNCTION_ARGS); +extern Datum bttext_pattern_sortsupport(PG_FUNCTION_ARGS); +extern Datum btbpchar_pattern_sortsupport(PG_FUNCTION_ARGS); +extern Datum pg_size_bytes(PG_FUNCTION_ARGS); +extern Datum numeric_serialize(PG_FUNCTION_ARGS); +extern Datum numeric_deserialize(PG_FUNCTION_ARGS); +extern Datum numeric_avg_combine(PG_FUNCTION_ARGS); +extern Datum numeric_poly_combine(PG_FUNCTION_ARGS); +extern Datum numeric_poly_serialize(PG_FUNCTION_ARGS); +extern Datum numeric_poly_deserialize(PG_FUNCTION_ARGS); +extern Datum numeric_combine(PG_FUNCTION_ARGS); +extern Datum float8_regr_combine(PG_FUNCTION_ARGS); +extern Datum jsonb_delete_array(PG_FUNCTION_ARGS); +extern Datum cash_mul_int8(PG_FUNCTION_ARGS); +extern Datum cash_div_int8(PG_FUNCTION_ARGS); +extern Datum pg_current_xact_id_if_assigned(PG_FUNCTION_ARGS); +extern Datum pg_get_partkeydef(PG_FUNCTION_ARGS); +extern Datum pg_ls_logdir(PG_FUNCTION_ARGS); +extern Datum pg_ls_waldir(PG_FUNCTION_ARGS); +extern Datum pg_ndistinct_in(PG_FUNCTION_ARGS); +extern Datum pg_ndistinct_out(PG_FUNCTION_ARGS); +extern Datum pg_ndistinct_recv(PG_FUNCTION_ARGS); +extern Datum pg_ndistinct_send(PG_FUNCTION_ARGS); +extern Datum macaddr_sortsupport(PG_FUNCTION_ARGS); +extern Datum pg_xact_status(PG_FUNCTION_ARGS); +extern Datum pg_safe_snapshot_blocking_pids(PG_FUNCTION_ARGS); +extern Datum pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS); +extern Datum pg_identify_object_as_address(PG_FUNCTION_ARGS); +extern Datum brin_minmax_opcinfo(PG_FUNCTION_ARGS); +extern Datum brin_minmax_add_value(PG_FUNCTION_ARGS); +extern Datum brin_minmax_consistent(PG_FUNCTION_ARGS); +extern Datum brin_minmax_union(PG_FUNCTION_ARGS); +extern Datum int8_avg_accum_inv(PG_FUNCTION_ARGS); +extern Datum numeric_poly_sum(PG_FUNCTION_ARGS); +extern Datum numeric_poly_avg(PG_FUNCTION_ARGS); +extern Datum numeric_poly_var_pop(PG_FUNCTION_ARGS); +extern Datum numeric_poly_var_samp(PG_FUNCTION_ARGS); +extern Datum numeric_poly_stddev_pop(PG_FUNCTION_ARGS); +extern Datum numeric_poly_stddev_samp(PG_FUNCTION_ARGS); +extern Datum regexp_match_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_match(PG_FUNCTION_ARGS); +extern Datum int8_mul_cash(PG_FUNCTION_ARGS); +extern Datum pg_config(PG_FUNCTION_ARGS); +extern Datum pg_hba_file_rules(PG_FUNCTION_ARGS); +extern Datum pg_statistics_obj_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_dependencies_in(PG_FUNCTION_ARGS); +extern Datum pg_dependencies_out(PG_FUNCTION_ARGS); +extern Datum pg_dependencies_recv(PG_FUNCTION_ARGS); +extern Datum pg_dependencies_send(PG_FUNCTION_ARGS); +extern Datum pg_get_partition_constraintdef(PG_FUNCTION_ARGS); +extern Datum time_hash_extended(PG_FUNCTION_ARGS); +extern Datum timetz_hash_extended(PG_FUNCTION_ARGS); +extern Datum timestamp_hash_extended(PG_FUNCTION_ARGS); +extern Datum uuid_hash_extended(PG_FUNCTION_ARGS); +extern Datum pg_lsn_hash_extended(PG_FUNCTION_ARGS); +extern Datum hashenumextended(PG_FUNCTION_ARGS); +extern Datum pg_get_statisticsobjdef(PG_FUNCTION_ARGS); +extern Datum jsonb_hash_extended(PG_FUNCTION_ARGS); +extern Datum hash_range_extended(PG_FUNCTION_ARGS); +extern Datum interval_hash_extended(PG_FUNCTION_ARGS); +extern Datum sha224_bytea(PG_FUNCTION_ARGS); +extern Datum sha256_bytea(PG_FUNCTION_ARGS); +extern Datum sha384_bytea(PG_FUNCTION_ARGS); +extern Datum sha512_bytea(PG_FUNCTION_ARGS); +extern Datum pg_partition_tree(PG_FUNCTION_ARGS); +extern Datum pg_partition_root(PG_FUNCTION_ARGS); +extern Datum pg_partition_ancestors(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_checksum_failures(PG_FUNCTION_ARGS); +extern Datum pg_stats_ext_mcvlist_items(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_checksum_last_failure(PG_FUNCTION_ARGS); +extern Datum gen_random_uuid(PG_FUNCTION_ARGS); +extern Datum gtsvector_options(PG_FUNCTION_ARGS); +extern Datum gist_point_sortsupport(PG_FUNCTION_ARGS); +extern Datum pg_promote(PG_FUNCTION_ARGS); +extern Datum prefixsel(PG_FUNCTION_ARGS); +extern Datum prefixjoinsel(PG_FUNCTION_ARGS); +extern Datum pg_control_system(PG_FUNCTION_ARGS); +extern Datum pg_control_checkpoint(PG_FUNCTION_ARGS); +extern Datum pg_control_recovery(PG_FUNCTION_ARGS); +extern Datum pg_control_init(PG_FUNCTION_ARGS); +extern Datum pg_import_system_collations(PG_FUNCTION_ARGS); +extern Datum macaddr8_recv(PG_FUNCTION_ARGS); +extern Datum macaddr8_send(PG_FUNCTION_ARGS); +extern Datum pg_collation_actual_version(PG_FUNCTION_ARGS); +extern Datum jsonb_numeric(PG_FUNCTION_ARGS); +extern Datum jsonb_int2(PG_FUNCTION_ARGS); +extern Datum jsonb_int4(PG_FUNCTION_ARGS); +extern Datum jsonb_int8(PG_FUNCTION_ARGS); +extern Datum jsonb_float4(PG_FUNCTION_ARGS); +extern Datum pg_filenode_relation(PG_FUNCTION_ARGS); +extern Datum be_lo_from_bytea(PG_FUNCTION_ARGS); +extern Datum be_lo_get(PG_FUNCTION_ARGS); +extern Datum be_lo_get_fragment(PG_FUNCTION_ARGS); +extern Datum be_lo_put(PG_FUNCTION_ARGS); +extern Datum make_timestamp(PG_FUNCTION_ARGS); +extern Datum make_timestamptz(PG_FUNCTION_ARGS); +extern Datum make_timestamptz_at_timezone(PG_FUNCTION_ARGS); +extern Datum make_interval(PG_FUNCTION_ARGS); +extern Datum jsonb_array_elements_text(PG_FUNCTION_ARGS); +extern Datum spg_range_quad_config(PG_FUNCTION_ARGS); +extern Datum spg_range_quad_choose(PG_FUNCTION_ARGS); +extern Datum spg_range_quad_picksplit(PG_FUNCTION_ARGS); +extern Datum spg_range_quad_inner_consistent(PG_FUNCTION_ARGS); +extern Datum spg_range_quad_leaf_consistent(PG_FUNCTION_ARGS); +extern Datum jsonb_populate_recordset(PG_FUNCTION_ARGS); +extern Datum to_regoperator(PG_FUNCTION_ARGS); +extern Datum jsonb_object_field(PG_FUNCTION_ARGS); +extern Datum to_regprocedure(PG_FUNCTION_ARGS); +extern Datum gin_compare_jsonb(PG_FUNCTION_ARGS); +extern Datum gin_extract_jsonb(PG_FUNCTION_ARGS); +extern Datum gin_extract_jsonb_query(PG_FUNCTION_ARGS); +extern Datum gin_consistent_jsonb(PG_FUNCTION_ARGS); +extern Datum gin_extract_jsonb_path(PG_FUNCTION_ARGS); +extern Datum gin_extract_jsonb_query_path(PG_FUNCTION_ARGS); +extern Datum gin_consistent_jsonb_path(PG_FUNCTION_ARGS); +extern Datum gin_triconsistent_jsonb(PG_FUNCTION_ARGS); +extern Datum gin_triconsistent_jsonb_path(PG_FUNCTION_ARGS); +extern Datum jsonb_to_record(PG_FUNCTION_ARGS); +extern Datum jsonb_to_recordset(PG_FUNCTION_ARGS); +extern Datum to_regoper(PG_FUNCTION_ARGS); +extern Datum to_regtype(PG_FUNCTION_ARGS); +extern Datum to_regproc(PG_FUNCTION_ARGS); +extern Datum to_regclass(PG_FUNCTION_ARGS); +extern Datum bool_accum(PG_FUNCTION_ARGS); +extern Datum bool_accum_inv(PG_FUNCTION_ARGS); +extern Datum bool_alltrue(PG_FUNCTION_ARGS); +extern Datum bool_anytrue(PG_FUNCTION_ARGS); +extern Datum anyenum_in(PG_FUNCTION_ARGS); +extern Datum anyenum_out(PG_FUNCTION_ARGS); +extern Datum enum_in(PG_FUNCTION_ARGS); +extern Datum enum_out(PG_FUNCTION_ARGS); +extern Datum enum_eq(PG_FUNCTION_ARGS); +extern Datum enum_ne(PG_FUNCTION_ARGS); +extern Datum enum_lt(PG_FUNCTION_ARGS); +extern Datum enum_gt(PG_FUNCTION_ARGS); +extern Datum enum_le(PG_FUNCTION_ARGS); +extern Datum enum_ge(PG_FUNCTION_ARGS); +extern Datum enum_cmp(PG_FUNCTION_ARGS); +extern Datum hashenum(PG_FUNCTION_ARGS); +extern Datum enum_smaller(PG_FUNCTION_ARGS); +extern Datum enum_larger(PG_FUNCTION_ARGS); +extern Datum enum_first(PG_FUNCTION_ARGS); +extern Datum enum_last(PG_FUNCTION_ARGS); +extern Datum enum_range_bounds(PG_FUNCTION_ARGS); +extern Datum enum_range_all(PG_FUNCTION_ARGS); +extern Datum enum_recv(PG_FUNCTION_ARGS); +extern Datum enum_send(PG_FUNCTION_ARGS); +extern Datum string_agg_transfn(PG_FUNCTION_ARGS); +extern Datum string_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum pg_describe_object(PG_FUNCTION_ARGS); +extern Datum text_format(PG_FUNCTION_ARGS); +extern Datum text_format_nv(PG_FUNCTION_ARGS); +extern Datum bytea_string_agg_transfn(PG_FUNCTION_ARGS); +extern Datum bytea_string_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum int8dec(PG_FUNCTION_ARGS); +extern Datum int8dec_any(PG_FUNCTION_ARGS); +extern Datum numeric_accum_inv(PG_FUNCTION_ARGS); +extern Datum interval_accum_inv(PG_FUNCTION_ARGS); +extern Datum network_overlap(PG_FUNCTION_ARGS); +extern Datum inet_gist_consistent(PG_FUNCTION_ARGS); +extern Datum inet_gist_union(PG_FUNCTION_ARGS); +extern Datum inet_gist_compress(PG_FUNCTION_ARGS); +extern Datum jsonb_bool(PG_FUNCTION_ARGS); +extern Datum inet_gist_penalty(PG_FUNCTION_ARGS); +extern Datum inet_gist_picksplit(PG_FUNCTION_ARGS); +extern Datum inet_gist_same(PG_FUNCTION_ARGS); +extern Datum networksel(PG_FUNCTION_ARGS); +extern Datum networkjoinsel(PG_FUNCTION_ARGS); +extern Datum network_larger(PG_FUNCTION_ARGS); +extern Datum network_smaller(PG_FUNCTION_ARGS); +extern Datum pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS); +extern Datum int2_accum_inv(PG_FUNCTION_ARGS); +extern Datum int4_accum_inv(PG_FUNCTION_ARGS); +extern Datum int8_accum_inv(PG_FUNCTION_ARGS); +extern Datum int2_avg_accum_inv(PG_FUNCTION_ARGS); +extern Datum int4_avg_accum_inv(PG_FUNCTION_ARGS); +extern Datum int2int4_sum(PG_FUNCTION_ARGS); +extern Datum inet_gist_fetch(PG_FUNCTION_ARGS); +extern Datum pg_logical_emit_message_text(PG_FUNCTION_ARGS); +extern Datum pg_logical_emit_message_bytea(PG_FUNCTION_ARGS); +extern Datum jsonb_insert(PG_FUNCTION_ARGS); +extern Datum pg_xact_commit_timestamp(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS); +extern Datum pg_last_committed_xact(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS); +extern Datum event_trigger_in(PG_FUNCTION_ARGS); +extern Datum event_trigger_out(PG_FUNCTION_ARGS); +extern Datum tsvectorin(PG_FUNCTION_ARGS); +extern Datum tsvectorout(PG_FUNCTION_ARGS); +extern Datum tsqueryin(PG_FUNCTION_ARGS); +extern Datum tsqueryout(PG_FUNCTION_ARGS); +extern Datum tsvector_lt(PG_FUNCTION_ARGS); +extern Datum tsvector_le(PG_FUNCTION_ARGS); +extern Datum tsvector_eq(PG_FUNCTION_ARGS); +extern Datum tsvector_ne(PG_FUNCTION_ARGS); +extern Datum tsvector_ge(PG_FUNCTION_ARGS); +extern Datum tsvector_gt(PG_FUNCTION_ARGS); +extern Datum tsvector_cmp(PG_FUNCTION_ARGS); +extern Datum tsvector_strip(PG_FUNCTION_ARGS); +extern Datum tsvector_setweight(PG_FUNCTION_ARGS); +extern Datum tsvector_concat(PG_FUNCTION_ARGS); +extern Datum ts_match_vq(PG_FUNCTION_ARGS); +extern Datum ts_match_qv(PG_FUNCTION_ARGS); +extern Datum tsvectorsend(PG_FUNCTION_ARGS); +extern Datum tsvectorrecv(PG_FUNCTION_ARGS); +extern Datum tsquerysend(PG_FUNCTION_ARGS); +extern Datum tsqueryrecv(PG_FUNCTION_ARGS); +extern Datum gtsvectorin(PG_FUNCTION_ARGS); +extern Datum gtsvectorout(PG_FUNCTION_ARGS); +extern Datum gtsvector_compress(PG_FUNCTION_ARGS); +extern Datum gtsvector_decompress(PG_FUNCTION_ARGS); +extern Datum gtsvector_picksplit(PG_FUNCTION_ARGS); +extern Datum gtsvector_union(PG_FUNCTION_ARGS); +extern Datum gtsvector_same(PG_FUNCTION_ARGS); +extern Datum gtsvector_penalty(PG_FUNCTION_ARGS); +extern Datum gtsvector_consistent(PG_FUNCTION_ARGS); +extern Datum gin_extract_tsvector(PG_FUNCTION_ARGS); +extern Datum gin_extract_tsquery(PG_FUNCTION_ARGS); +extern Datum gin_tsquery_consistent(PG_FUNCTION_ARGS); +extern Datum tsquery_lt(PG_FUNCTION_ARGS); +extern Datum tsquery_le(PG_FUNCTION_ARGS); +extern Datum tsquery_eq(PG_FUNCTION_ARGS); +extern Datum tsquery_ne(PG_FUNCTION_ARGS); +extern Datum tsquery_ge(PG_FUNCTION_ARGS); +extern Datum tsquery_gt(PG_FUNCTION_ARGS); +extern Datum tsquery_cmp(PG_FUNCTION_ARGS); +extern Datum tsquery_and(PG_FUNCTION_ARGS); +extern Datum tsquery_or(PG_FUNCTION_ARGS); +extern Datum tsquery_not(PG_FUNCTION_ARGS); +extern Datum tsquery_numnode(PG_FUNCTION_ARGS); +extern Datum tsquerytree(PG_FUNCTION_ARGS); +extern Datum tsquery_rewrite(PG_FUNCTION_ARGS); +extern Datum tsquery_rewrite_query(PG_FUNCTION_ARGS); +extern Datum tsmatchsel(PG_FUNCTION_ARGS); +extern Datum tsmatchjoinsel(PG_FUNCTION_ARGS); +extern Datum ts_typanalyze(PG_FUNCTION_ARGS); +extern Datum ts_stat1(PG_FUNCTION_ARGS); +extern Datum ts_stat2(PG_FUNCTION_ARGS); +extern Datum tsq_mcontains(PG_FUNCTION_ARGS); +extern Datum tsq_mcontained(PG_FUNCTION_ARGS); +extern Datum gtsquery_compress(PG_FUNCTION_ARGS); +extern Datum text_starts_with(PG_FUNCTION_ARGS); +extern Datum gtsquery_picksplit(PG_FUNCTION_ARGS); +extern Datum gtsquery_union(PG_FUNCTION_ARGS); +extern Datum gtsquery_same(PG_FUNCTION_ARGS); +extern Datum gtsquery_penalty(PG_FUNCTION_ARGS); +extern Datum gtsquery_consistent(PG_FUNCTION_ARGS); +extern Datum ts_rank_wttf(PG_FUNCTION_ARGS); +extern Datum ts_rank_wtt(PG_FUNCTION_ARGS); +extern Datum ts_rank_ttf(PG_FUNCTION_ARGS); +extern Datum ts_rank_tt(PG_FUNCTION_ARGS); +extern Datum ts_rankcd_wttf(PG_FUNCTION_ARGS); +extern Datum ts_rankcd_wtt(PG_FUNCTION_ARGS); +extern Datum ts_rankcd_ttf(PG_FUNCTION_ARGS); +extern Datum ts_rankcd_tt(PG_FUNCTION_ARGS); +extern Datum tsvector_length(PG_FUNCTION_ARGS); +extern Datum ts_token_type_byid(PG_FUNCTION_ARGS); +extern Datum ts_token_type_byname(PG_FUNCTION_ARGS); +extern Datum ts_parse_byid(PG_FUNCTION_ARGS); +extern Datum ts_parse_byname(PG_FUNCTION_ARGS); +extern Datum prsd_start(PG_FUNCTION_ARGS); +extern Datum prsd_nexttoken(PG_FUNCTION_ARGS); +extern Datum prsd_end(PG_FUNCTION_ARGS); +extern Datum prsd_headline(PG_FUNCTION_ARGS); +extern Datum prsd_lextype(PG_FUNCTION_ARGS); +extern Datum ts_lexize(PG_FUNCTION_ARGS); +extern Datum gin_cmp_tslexeme(PG_FUNCTION_ARGS); +extern Datum dsimple_init(PG_FUNCTION_ARGS); +extern Datum dsimple_lexize(PG_FUNCTION_ARGS); +extern Datum dsynonym_init(PG_FUNCTION_ARGS); +extern Datum dsynonym_lexize(PG_FUNCTION_ARGS); +extern Datum dispell_init(PG_FUNCTION_ARGS); +extern Datum dispell_lexize(PG_FUNCTION_ARGS); +extern Datum regconfigin(PG_FUNCTION_ARGS); +extern Datum regconfigout(PG_FUNCTION_ARGS); +extern Datum regconfigrecv(PG_FUNCTION_ARGS); +extern Datum regconfigsend(PG_FUNCTION_ARGS); +extern Datum thesaurus_init(PG_FUNCTION_ARGS); +extern Datum thesaurus_lexize(PG_FUNCTION_ARGS); +extern Datum ts_headline_byid_opt(PG_FUNCTION_ARGS); +extern Datum ts_headline_byid(PG_FUNCTION_ARGS); +extern Datum to_tsvector_byid(PG_FUNCTION_ARGS); +extern Datum to_tsquery_byid(PG_FUNCTION_ARGS); +extern Datum plainto_tsquery_byid(PG_FUNCTION_ARGS); +extern Datum to_tsvector(PG_FUNCTION_ARGS); +extern Datum to_tsquery(PG_FUNCTION_ARGS); +extern Datum plainto_tsquery(PG_FUNCTION_ARGS); +extern Datum tsvector_update_trigger_byid(PG_FUNCTION_ARGS); +extern Datum tsvector_update_trigger_bycolumn(PG_FUNCTION_ARGS); +extern Datum ts_headline_opt(PG_FUNCTION_ARGS); +extern Datum ts_headline(PG_FUNCTION_ARGS); +extern Datum pg_ts_parser_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_ts_dict_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_ts_config_is_visible(PG_FUNCTION_ARGS); +extern Datum get_current_ts_config(PG_FUNCTION_ARGS); +extern Datum ts_match_tt(PG_FUNCTION_ARGS); +extern Datum ts_match_tq(PG_FUNCTION_ARGS); +extern Datum pg_ts_template_is_visible(PG_FUNCTION_ARGS); +extern Datum regdictionaryin(PG_FUNCTION_ARGS); +extern Datum regdictionaryout(PG_FUNCTION_ARGS); +extern Datum regdictionaryrecv(PG_FUNCTION_ARGS); +extern Datum regdictionarysend(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS); +extern Datum pg_tablespace_location(PG_FUNCTION_ARGS); +extern Datum pg_create_physical_replication_slot(PG_FUNCTION_ARGS); +extern Datum pg_drop_replication_slot(PG_FUNCTION_ARGS); +extern Datum pg_get_replication_slots(PG_FUNCTION_ARGS); +extern Datum pg_logical_slot_get_changes(PG_FUNCTION_ARGS); +extern Datum pg_logical_slot_get_binary_changes(PG_FUNCTION_ARGS); +extern Datum pg_logical_slot_peek_changes(PG_FUNCTION_ARGS); +extern Datum pg_logical_slot_peek_binary_changes(PG_FUNCTION_ARGS); +extern Datum pg_create_logical_replication_slot(PG_FUNCTION_ARGS); +extern Datum to_jsonb(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_snapshot_timestamp(PG_FUNCTION_ARGS); +extern Datum gin_clean_pending_list(PG_FUNCTION_ARGS); +extern Datum gtsvector_consistent_oldsig(PG_FUNCTION_ARGS); +extern Datum gin_extract_tsquery_oldsig(PG_FUNCTION_ARGS); +extern Datum gin_tsquery_consistent_oldsig(PG_FUNCTION_ARGS); +extern Datum gtsquery_consistent_oldsig(PG_FUNCTION_ARGS); +extern Datum inet_spg_config(PG_FUNCTION_ARGS); +extern Datum inet_spg_choose(PG_FUNCTION_ARGS); +extern Datum inet_spg_picksplit(PG_FUNCTION_ARGS); +extern Datum inet_spg_inner_consistent(PG_FUNCTION_ARGS); +extern Datum inet_spg_leaf_consistent(PG_FUNCTION_ARGS); +extern Datum pg_current_logfile(PG_FUNCTION_ARGS); +extern Datum pg_current_logfile_1arg(PG_FUNCTION_ARGS); +extern Datum jsonb_send(PG_FUNCTION_ARGS); +extern Datum jsonb_out(PG_FUNCTION_ARGS); +extern Datum jsonb_recv(PG_FUNCTION_ARGS); +extern Datum jsonb_in(PG_FUNCTION_ARGS); +extern Datum pg_get_function_arg_default(PG_FUNCTION_ARGS); +extern Datum pg_export_snapshot(PG_FUNCTION_ARGS); +extern Datum pg_is_in_recovery(PG_FUNCTION_ARGS); +extern Datum int4_cash(PG_FUNCTION_ARGS); +extern Datum int8_cash(PG_FUNCTION_ARGS); +extern Datum pg_collation_is_visible(PG_FUNCTION_ARGS); +extern Datum array_typanalyze(PG_FUNCTION_ARGS); +extern Datum arraycontsel(PG_FUNCTION_ARGS); +extern Datum arraycontjoinsel(PG_FUNCTION_ARGS); +extern Datum pg_get_multixact_members(PG_FUNCTION_ARGS); +extern Datum pg_last_wal_receive_lsn(PG_FUNCTION_ARGS); +extern Datum pg_last_wal_replay_lsn(PG_FUNCTION_ARGS); +extern Datum cash_div_cash(PG_FUNCTION_ARGS); +extern Datum cash_numeric(PG_FUNCTION_ARGS); +extern Datum numeric_cash(PG_FUNCTION_ARGS); +extern Datum pg_read_file_all(PG_FUNCTION_ARGS); +extern Datum pg_read_binary_file_off_len(PG_FUNCTION_ARGS); +extern Datum pg_read_binary_file_all(PG_FUNCTION_ARGS); +extern Datum pg_opfamily_is_visible(PG_FUNCTION_ARGS); +extern Datum pg_last_xact_replay_timestamp(PG_FUNCTION_ARGS); +extern Datum anyrange_in(PG_FUNCTION_ARGS); +extern Datum anyrange_out(PG_FUNCTION_ARGS); +extern Datum range_in(PG_FUNCTION_ARGS); +extern Datum range_out(PG_FUNCTION_ARGS); +extern Datum range_recv(PG_FUNCTION_ARGS); +extern Datum range_send(PG_FUNCTION_ARGS); +extern Datum pg_identify_object(PG_FUNCTION_ARGS); +extern Datum range_constructor2(PG_FUNCTION_ARGS); +extern Datum range_constructor3(PG_FUNCTION_ARGS); +extern Datum pg_relation_is_updatable(PG_FUNCTION_ARGS); +extern Datum pg_column_is_updatable(PG_FUNCTION_ARGS); +extern Datum make_date(PG_FUNCTION_ARGS); +extern Datum make_time(PG_FUNCTION_ARGS); +extern Datum range_lower(PG_FUNCTION_ARGS); +extern Datum range_upper(PG_FUNCTION_ARGS); +extern Datum range_empty(PG_FUNCTION_ARGS); +extern Datum range_lower_inc(PG_FUNCTION_ARGS); +extern Datum range_upper_inc(PG_FUNCTION_ARGS); +extern Datum range_lower_inf(PG_FUNCTION_ARGS); +extern Datum range_upper_inf(PG_FUNCTION_ARGS); +extern Datum range_eq(PG_FUNCTION_ARGS); +extern Datum range_ne(PG_FUNCTION_ARGS); +extern Datum range_overlaps(PG_FUNCTION_ARGS); +extern Datum range_contains_elem(PG_FUNCTION_ARGS); +extern Datum range_contains(PG_FUNCTION_ARGS); +extern Datum elem_contained_by_range(PG_FUNCTION_ARGS); +extern Datum range_contained_by(PG_FUNCTION_ARGS); +extern Datum range_adjacent(PG_FUNCTION_ARGS); +extern Datum range_before(PG_FUNCTION_ARGS); +extern Datum range_after(PG_FUNCTION_ARGS); +extern Datum range_overleft(PG_FUNCTION_ARGS); +extern Datum range_overright(PG_FUNCTION_ARGS); +extern Datum range_union(PG_FUNCTION_ARGS); +extern Datum range_intersect(PG_FUNCTION_ARGS); +extern Datum range_minus(PG_FUNCTION_ARGS); +extern Datum range_cmp(PG_FUNCTION_ARGS); +extern Datum range_lt(PG_FUNCTION_ARGS); +extern Datum range_le(PG_FUNCTION_ARGS); +extern Datum range_ge(PG_FUNCTION_ARGS); +extern Datum range_gt(PG_FUNCTION_ARGS); +extern Datum range_gist_consistent(PG_FUNCTION_ARGS); +extern Datum range_gist_union(PG_FUNCTION_ARGS); +extern Datum pg_replication_slot_advance(PG_FUNCTION_ARGS); +extern Datum range_gist_penalty(PG_FUNCTION_ARGS); +extern Datum range_gist_picksplit(PG_FUNCTION_ARGS); +extern Datum range_gist_same(PG_FUNCTION_ARGS); +extern Datum hash_range(PG_FUNCTION_ARGS); +extern Datum int4range_canonical(PG_FUNCTION_ARGS); +extern Datum daterange_canonical(PG_FUNCTION_ARGS); +extern Datum range_typanalyze(PG_FUNCTION_ARGS); +extern Datum timestamp_support(PG_FUNCTION_ARGS); +extern Datum interval_support(PG_FUNCTION_ARGS); +extern Datum ginarraytriconsistent(PG_FUNCTION_ARGS); +extern Datum gin_tsquery_triconsistent(PG_FUNCTION_ARGS); +extern Datum int4range_subdiff(PG_FUNCTION_ARGS); +extern Datum int8range_subdiff(PG_FUNCTION_ARGS); +extern Datum numrange_subdiff(PG_FUNCTION_ARGS); +extern Datum daterange_subdiff(PG_FUNCTION_ARGS); +extern Datum int8range_canonical(PG_FUNCTION_ARGS); +extern Datum tsrange_subdiff(PG_FUNCTION_ARGS); +extern Datum tstzrange_subdiff(PG_FUNCTION_ARGS); +extern Datum jsonb_object_keys(PG_FUNCTION_ARGS); +extern Datum jsonb_each_text(PG_FUNCTION_ARGS); +extern Datum mxid_age(PG_FUNCTION_ARGS); +extern Datum jsonb_extract_path_text(PG_FUNCTION_ARGS); +extern Datum acldefault_sql(PG_FUNCTION_ARGS); +extern Datum time_support(PG_FUNCTION_ARGS); +extern Datum json_object_field(PG_FUNCTION_ARGS); +extern Datum json_object_field_text(PG_FUNCTION_ARGS); +extern Datum json_array_element(PG_FUNCTION_ARGS); +extern Datum json_array_element_text(PG_FUNCTION_ARGS); +extern Datum json_extract_path(PG_FUNCTION_ARGS); +extern Datum brin_summarize_new_values(PG_FUNCTION_ARGS); +extern Datum json_extract_path_text(PG_FUNCTION_ARGS); +extern Datum pg_get_object_address(PG_FUNCTION_ARGS); +extern Datum json_array_elements(PG_FUNCTION_ARGS); +extern Datum json_array_length(PG_FUNCTION_ARGS); +extern Datum json_object_keys(PG_FUNCTION_ARGS); +extern Datum json_each(PG_FUNCTION_ARGS); +extern Datum json_each_text(PG_FUNCTION_ARGS); +extern Datum json_populate_record(PG_FUNCTION_ARGS); +extern Datum json_populate_recordset(PG_FUNCTION_ARGS); +extern Datum json_typeof(PG_FUNCTION_ARGS); +extern Datum json_array_elements_text(PG_FUNCTION_ARGS); +extern Datum ordered_set_transition(PG_FUNCTION_ARGS); +extern Datum ordered_set_transition_multi(PG_FUNCTION_ARGS); +extern Datum percentile_disc_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_float8_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_interval_final(PG_FUNCTION_ARGS); +extern Datum percentile_disc_multi_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_float8_multi_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_interval_multi_final(PG_FUNCTION_ARGS); +extern Datum mode_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_rank_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_percent_rank_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_cume_dist_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_dense_rank_final(PG_FUNCTION_ARGS); +extern Datum generate_series_int4_support(PG_FUNCTION_ARGS); +extern Datum generate_series_int8_support(PG_FUNCTION_ARGS); +extern Datum array_unnest_support(PG_FUNCTION_ARGS); +extern Datum gist_box_distance(PG_FUNCTION_ARGS); +extern Datum brin_summarize_range(PG_FUNCTION_ARGS); +extern Datum jsonpath_in(PG_FUNCTION_ARGS); +extern Datum jsonpath_recv(PG_FUNCTION_ARGS); +extern Datum jsonpath_out(PG_FUNCTION_ARGS); +extern Datum jsonpath_send(PG_FUNCTION_ARGS); +extern Datum jsonb_path_exists(PG_FUNCTION_ARGS); +extern Datum jsonb_path_query(PG_FUNCTION_ARGS); +extern Datum jsonb_path_query_array(PG_FUNCTION_ARGS); +extern Datum jsonb_path_query_first(PG_FUNCTION_ARGS); +extern Datum jsonb_path_match(PG_FUNCTION_ARGS); +extern Datum jsonb_path_exists_opr(PG_FUNCTION_ARGS); +extern Datum jsonb_path_match_opr(PG_FUNCTION_ARGS); +extern Datum brin_desummarize_range(PG_FUNCTION_ARGS); +extern Datum spg_quad_config(PG_FUNCTION_ARGS); +extern Datum spg_quad_choose(PG_FUNCTION_ARGS); +extern Datum spg_quad_picksplit(PG_FUNCTION_ARGS); +extern Datum spg_quad_inner_consistent(PG_FUNCTION_ARGS); +extern Datum spg_quad_leaf_consistent(PG_FUNCTION_ARGS); +extern Datum spg_kd_config(PG_FUNCTION_ARGS); +extern Datum spg_kd_choose(PG_FUNCTION_ARGS); +extern Datum spg_kd_picksplit(PG_FUNCTION_ARGS); +extern Datum spg_kd_inner_consistent(PG_FUNCTION_ARGS); +extern Datum spg_text_config(PG_FUNCTION_ARGS); +extern Datum spg_text_choose(PG_FUNCTION_ARGS); +extern Datum spg_text_picksplit(PG_FUNCTION_ARGS); +extern Datum spg_text_inner_consistent(PG_FUNCTION_ARGS); +extern Datum spg_text_leaf_consistent(PG_FUNCTION_ARGS); +extern Datum pg_sequence_last_value(PG_FUNCTION_ARGS); +extern Datum jsonb_ne(PG_FUNCTION_ARGS); +extern Datum jsonb_lt(PG_FUNCTION_ARGS); +extern Datum jsonb_gt(PG_FUNCTION_ARGS); +extern Datum jsonb_le(PG_FUNCTION_ARGS); +extern Datum jsonb_ge(PG_FUNCTION_ARGS); +extern Datum jsonb_eq(PG_FUNCTION_ARGS); +extern Datum jsonb_cmp(PG_FUNCTION_ARGS); +extern Datum jsonb_hash(PG_FUNCTION_ARGS); +extern Datum jsonb_contains(PG_FUNCTION_ARGS); +extern Datum jsonb_exists(PG_FUNCTION_ARGS); +extern Datum jsonb_exists_any(PG_FUNCTION_ARGS); +extern Datum jsonb_exists_all(PG_FUNCTION_ARGS); +extern Datum jsonb_contained(PG_FUNCTION_ARGS); +extern Datum array_agg_array_transfn(PG_FUNCTION_ARGS); +extern Datum array_agg_array_finalfn(PG_FUNCTION_ARGS); +extern Datum range_merge(PG_FUNCTION_ARGS); +extern Datum inet_merge(PG_FUNCTION_ARGS); +extern Datum boxes_bound_box(PG_FUNCTION_ARGS); +extern Datum inet_same_family(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS); +extern Datum regnamespacein(PG_FUNCTION_ARGS); +extern Datum regnamespaceout(PG_FUNCTION_ARGS); +extern Datum to_regnamespace(PG_FUNCTION_ARGS); +extern Datum regnamespacerecv(PG_FUNCTION_ARGS); +extern Datum regnamespacesend(PG_FUNCTION_ARGS); +extern Datum point_box(PG_FUNCTION_ARGS); +extern Datum regroleout(PG_FUNCTION_ARGS); +extern Datum to_regrole(PG_FUNCTION_ARGS); +extern Datum regrolerecv(PG_FUNCTION_ARGS); +extern Datum regrolesend(PG_FUNCTION_ARGS); +extern Datum regrolein(PG_FUNCTION_ARGS); +extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS); +extern Datum pg_read_file(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_missing_value(PG_FUNCTION_ARGS); +extern Datum brin_inclusion_opcinfo(PG_FUNCTION_ARGS); +extern Datum brin_inclusion_add_value(PG_FUNCTION_ARGS); +extern Datum brin_inclusion_consistent(PG_FUNCTION_ARGS); +extern Datum brin_inclusion_union(PG_FUNCTION_ARGS); +extern Datum macaddr8_in(PG_FUNCTION_ARGS); +extern Datum macaddr8_out(PG_FUNCTION_ARGS); +extern Datum macaddr8_trunc(PG_FUNCTION_ARGS); +extern Datum macaddr8_eq(PG_FUNCTION_ARGS); +extern Datum macaddr8_lt(PG_FUNCTION_ARGS); +extern Datum macaddr8_le(PG_FUNCTION_ARGS); +extern Datum macaddr8_gt(PG_FUNCTION_ARGS); +extern Datum macaddr8_ge(PG_FUNCTION_ARGS); +extern Datum macaddr8_ne(PG_FUNCTION_ARGS); +extern Datum macaddr8_cmp(PG_FUNCTION_ARGS); +extern Datum macaddr8_not(PG_FUNCTION_ARGS); +extern Datum macaddr8_and(PG_FUNCTION_ARGS); +extern Datum macaddr8_or(PG_FUNCTION_ARGS); +extern Datum macaddrtomacaddr8(PG_FUNCTION_ARGS); +extern Datum macaddr8tomacaddr(PG_FUNCTION_ARGS); +extern Datum macaddr8_set7bit(PG_FUNCTION_ARGS); +extern Datum in_range_int8_int8(PG_FUNCTION_ARGS); +extern Datum in_range_int4_int8(PG_FUNCTION_ARGS); +extern Datum in_range_int4_int4(PG_FUNCTION_ARGS); +extern Datum in_range_int4_int2(PG_FUNCTION_ARGS); +extern Datum in_range_int2_int8(PG_FUNCTION_ARGS); +extern Datum in_range_int2_int4(PG_FUNCTION_ARGS); +extern Datum in_range_int2_int2(PG_FUNCTION_ARGS); +extern Datum in_range_date_interval(PG_FUNCTION_ARGS); +extern Datum in_range_timestamp_interval(PG_FUNCTION_ARGS); +extern Datum in_range_timestamptz_interval(PG_FUNCTION_ARGS); +extern Datum in_range_interval_interval(PG_FUNCTION_ARGS); +extern Datum in_range_time_interval(PG_FUNCTION_ARGS); +extern Datum in_range_timetz_interval(PG_FUNCTION_ARGS); +extern Datum in_range_float8_float8(PG_FUNCTION_ARGS); +extern Datum in_range_float4_float8(PG_FUNCTION_ARGS); +extern Datum in_range_numeric_numeric(PG_FUNCTION_ARGS); +extern Datum pg_lsn_larger(PG_FUNCTION_ARGS); +extern Datum pg_lsn_smaller(PG_FUNCTION_ARGS); +extern Datum regcollationin(PG_FUNCTION_ARGS); +extern Datum regcollationout(PG_FUNCTION_ARGS); +extern Datum to_regcollation(PG_FUNCTION_ARGS); +extern Datum regcollationrecv(PG_FUNCTION_ARGS); +extern Datum regcollationsend(PG_FUNCTION_ARGS); +extern Datum ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS); +extern Datum ts_headline_jsonb_byid(PG_FUNCTION_ARGS); +extern Datum ts_headline_jsonb_opt(PG_FUNCTION_ARGS); +extern Datum ts_headline_jsonb(PG_FUNCTION_ARGS); +extern Datum ts_headline_json_byid_opt(PG_FUNCTION_ARGS); +extern Datum ts_headline_json_byid(PG_FUNCTION_ARGS); +extern Datum ts_headline_json_opt(PG_FUNCTION_ARGS); +extern Datum ts_headline_json(PG_FUNCTION_ARGS); +extern Datum jsonb_string_to_tsvector(PG_FUNCTION_ARGS); +extern Datum json_string_to_tsvector(PG_FUNCTION_ARGS); +extern Datum jsonb_string_to_tsvector_byid(PG_FUNCTION_ARGS); +extern Datum json_string_to_tsvector_byid(PG_FUNCTION_ARGS); +extern Datum jsonb_to_tsvector(PG_FUNCTION_ARGS); +extern Datum jsonb_to_tsvector_byid(PG_FUNCTION_ARGS); +extern Datum json_to_tsvector(PG_FUNCTION_ARGS); +extern Datum json_to_tsvector_byid(PG_FUNCTION_ARGS); +extern Datum pg_copy_physical_replication_slot_a(PG_FUNCTION_ARGS); +extern Datum pg_copy_physical_replication_slot_b(PG_FUNCTION_ARGS); +extern Datum pg_copy_logical_replication_slot_a(PG_FUNCTION_ARGS); +extern Datum pg_copy_logical_replication_slot_b(PG_FUNCTION_ARGS); +extern Datum pg_copy_logical_replication_slot_c(PG_FUNCTION_ARGS); +extern Datum anycompatiblemultirange_in(PG_FUNCTION_ARGS); +extern Datum anycompatiblemultirange_out(PG_FUNCTION_ARGS); +extern Datum range_merge_from_multirange(PG_FUNCTION_ARGS); +extern Datum anymultirange_in(PG_FUNCTION_ARGS); +extern Datum anymultirange_out(PG_FUNCTION_ARGS); +extern Datum multirange_in(PG_FUNCTION_ARGS); +extern Datum multirange_out(PG_FUNCTION_ARGS); +extern Datum multirange_recv(PG_FUNCTION_ARGS); +extern Datum multirange_send(PG_FUNCTION_ARGS); +extern Datum multirange_lower(PG_FUNCTION_ARGS); +extern Datum multirange_upper(PG_FUNCTION_ARGS); +extern Datum multirange_empty(PG_FUNCTION_ARGS); +extern Datum multirange_lower_inc(PG_FUNCTION_ARGS); +extern Datum multirange_upper_inc(PG_FUNCTION_ARGS); +extern Datum multirange_lower_inf(PG_FUNCTION_ARGS); +extern Datum multirange_upper_inf(PG_FUNCTION_ARGS); +extern Datum multirange_typanalyze(PG_FUNCTION_ARGS); +extern Datum multirangesel(PG_FUNCTION_ARGS); +extern Datum multirange_eq(PG_FUNCTION_ARGS); +extern Datum multirange_ne(PG_FUNCTION_ARGS); +extern Datum range_overlaps_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_overlaps_range(PG_FUNCTION_ARGS); +extern Datum multirange_overlaps_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_contains_elem(PG_FUNCTION_ARGS); +extern Datum multirange_contains_range(PG_FUNCTION_ARGS); +extern Datum multirange_contains_multirange(PG_FUNCTION_ARGS); +extern Datum elem_contained_by_multirange(PG_FUNCTION_ARGS); +extern Datum range_contained_by_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_contained_by_multirange(PG_FUNCTION_ARGS); +extern Datum range_adjacent_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_adjacent_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_adjacent_range(PG_FUNCTION_ARGS); +extern Datum range_before_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_before_range(PG_FUNCTION_ARGS); +extern Datum multirange_before_multirange(PG_FUNCTION_ARGS); +extern Datum range_after_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_after_range(PG_FUNCTION_ARGS); +extern Datum multirange_after_multirange(PG_FUNCTION_ARGS); +extern Datum range_overleft_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_overleft_range(PG_FUNCTION_ARGS); +extern Datum multirange_overleft_multirange(PG_FUNCTION_ARGS); +extern Datum range_overright_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_overright_range(PG_FUNCTION_ARGS); +extern Datum multirange_overright_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_union(PG_FUNCTION_ARGS); +extern Datum multirange_minus(PG_FUNCTION_ARGS); +extern Datum multirange_intersect(PG_FUNCTION_ARGS); +extern Datum multirange_cmp(PG_FUNCTION_ARGS); +extern Datum multirange_lt(PG_FUNCTION_ARGS); +extern Datum multirange_le(PG_FUNCTION_ARGS); +extern Datum multirange_ge(PG_FUNCTION_ARGS); +extern Datum multirange_gt(PG_FUNCTION_ARGS); +extern Datum hash_multirange(PG_FUNCTION_ARGS); +extern Datum hash_multirange_extended(PG_FUNCTION_ARGS); +extern Datum multirange_constructor0(PG_FUNCTION_ARGS); +extern Datum multirange_constructor1(PG_FUNCTION_ARGS); +extern Datum multirange_constructor2(PG_FUNCTION_ARGS); +extern Datum range_agg_transfn(PG_FUNCTION_ARGS); +extern Datum range_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum unicode_normalize_func(PG_FUNCTION_ARGS); +extern Datum unicode_is_normalized(PG_FUNCTION_ARGS); +extern Datum multirange_intersect_agg_transfn(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_multirange_pg_type_oid(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_multirange_array_pg_type_oid(PG_FUNCTION_ARGS); +extern Datum range_intersect_agg_transfn(PG_FUNCTION_ARGS); +extern Datum range_contains_multirange(PG_FUNCTION_ARGS); +extern Datum multirange_contained_by_range(PG_FUNCTION_ARGS); +extern Datum pg_log_backend_memory_contexts(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_heap_relfilenode(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_index_relfilenode(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_toast_relfilenode(PG_FUNCTION_ARGS); +extern Datum binary_upgrade_set_next_pg_tablespace_oid(PG_FUNCTION_ARGS); +extern Datum pg_event_trigger_table_rewrite_oid(PG_FUNCTION_ARGS); +extern Datum pg_event_trigger_table_rewrite_reason(PG_FUNCTION_ARGS); +extern Datum pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS); +extern Datum brin_bloom_opcinfo(PG_FUNCTION_ARGS); +extern Datum brin_bloom_add_value(PG_FUNCTION_ARGS); +extern Datum brin_bloom_consistent(PG_FUNCTION_ARGS); +extern Datum brin_bloom_union(PG_FUNCTION_ARGS); +extern Datum brin_bloom_options(PG_FUNCTION_ARGS); +extern Datum brin_bloom_summary_in(PG_FUNCTION_ARGS); +extern Datum brin_bloom_summary_out(PG_FUNCTION_ARGS); +extern Datum brin_bloom_summary_recv(PG_FUNCTION_ARGS); +extern Datum brin_bloom_summary_send(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_opcinfo(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_add_value(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_consistent(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_union(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_options(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_int2(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_int4(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_int8(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_float4(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_float8(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_numeric(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_tid(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_uuid(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_date(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_time(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_interval(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_timetz(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_pg_lsn(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_macaddr(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_macaddr8(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_inet(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_distance_timestamp(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_summary_in(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_summary_out(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_summary_recv(PG_FUNCTION_ARGS); +extern Datum brin_minmax_multi_summary_send(PG_FUNCTION_ARGS); +extern Datum phraseto_tsquery(PG_FUNCTION_ARGS); +extern Datum tsquery_phrase(PG_FUNCTION_ARGS); +extern Datum tsquery_phrase_distance(PG_FUNCTION_ARGS); +extern Datum phraseto_tsquery_byid(PG_FUNCTION_ARGS); +extern Datum websearch_to_tsquery_byid(PG_FUNCTION_ARGS); +extern Datum websearch_to_tsquery(PG_FUNCTION_ARGS); +extern Datum spg_bbox_quad_config(PG_FUNCTION_ARGS); +extern Datum spg_poly_quad_compress(PG_FUNCTION_ARGS); +extern Datum spg_box_quad_config(PG_FUNCTION_ARGS); +extern Datum spg_box_quad_choose(PG_FUNCTION_ARGS); +extern Datum spg_box_quad_picksplit(PG_FUNCTION_ARGS); +extern Datum spg_box_quad_inner_consistent(PG_FUNCTION_ARGS); +extern Datum spg_box_quad_leaf_consistent(PG_FUNCTION_ARGS); +extern Datum pg_mcv_list_in(PG_FUNCTION_ARGS); +extern Datum pg_mcv_list_out(PG_FUNCTION_ARGS); +extern Datum pg_mcv_list_recv(PG_FUNCTION_ARGS); +extern Datum pg_mcv_list_send(PG_FUNCTION_ARGS); +extern Datum pg_lsn_pli(PG_FUNCTION_ARGS); +extern Datum pg_lsn_mii(PG_FUNCTION_ARGS); +extern Datum satisfies_hash_partition(PG_FUNCTION_ARGS); +extern Datum pg_ls_tmpdir_noargs(PG_FUNCTION_ARGS); +extern Datum pg_ls_tmpdir_1arg(PG_FUNCTION_ARGS); +extern Datum pg_ls_archive_statusdir(PG_FUNCTION_ARGS); +extern Datum network_sortsupport(PG_FUNCTION_ARGS); +extern Datum xid8lt(PG_FUNCTION_ARGS); +extern Datum xid8gt(PG_FUNCTION_ARGS); +extern Datum xid8le(PG_FUNCTION_ARGS); +extern Datum xid8ge(PG_FUNCTION_ARGS); +extern Datum matchingsel(PG_FUNCTION_ARGS); +extern Datum matchingjoinsel(PG_FUNCTION_ARGS); +extern Datum numeric_min_scale(PG_FUNCTION_ARGS); +extern Datum numeric_trim_scale(PG_FUNCTION_ARGS); +extern Datum int4gcd(PG_FUNCTION_ARGS); +extern Datum int8gcd(PG_FUNCTION_ARGS); +extern Datum int4lcm(PG_FUNCTION_ARGS); +extern Datum int8lcm(PG_FUNCTION_ARGS); +extern Datum numeric_gcd(PG_FUNCTION_ARGS); +extern Datum numeric_lcm(PG_FUNCTION_ARGS); +extern Datum btvarstrequalimage(PG_FUNCTION_ARGS); +extern Datum btequalimage(PG_FUNCTION_ARGS); +extern Datum pg_get_shmem_allocations(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_ins_since_vacuum(PG_FUNCTION_ARGS); +extern Datum jsonb_set_lax(PG_FUNCTION_ARGS); +extern Datum xid8in(PG_FUNCTION_ARGS); +extern Datum xid8toxid(PG_FUNCTION_ARGS); +extern Datum xid8out(PG_FUNCTION_ARGS); +extern Datum xid8recv(PG_FUNCTION_ARGS); +extern Datum xid8send(PG_FUNCTION_ARGS); +extern Datum xid8eq(PG_FUNCTION_ARGS); +extern Datum xid8ne(PG_FUNCTION_ARGS); +extern Datum anycompatible_in(PG_FUNCTION_ARGS); +extern Datum anycompatible_out(PG_FUNCTION_ARGS); +extern Datum anycompatiblearray_in(PG_FUNCTION_ARGS); +extern Datum anycompatiblearray_out(PG_FUNCTION_ARGS); +extern Datum anycompatiblearray_recv(PG_FUNCTION_ARGS); +extern Datum anycompatiblearray_send(PG_FUNCTION_ARGS); +extern Datum anycompatiblenonarray_in(PG_FUNCTION_ARGS); +extern Datum anycompatiblenonarray_out(PG_FUNCTION_ARGS); +extern Datum anycompatiblerange_in(PG_FUNCTION_ARGS); +extern Datum anycompatiblerange_out(PG_FUNCTION_ARGS); +extern Datum xid8cmp(PG_FUNCTION_ARGS); +extern Datum xid8_larger(PG_FUNCTION_ARGS); +extern Datum xid8_smaller(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_create(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_drop(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_oid(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_session_setup(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_session_reset(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_session_is_setup(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_session_progress(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_xact_setup(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_xact_reset(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_advance(PG_FUNCTION_ARGS); +extern Datum pg_replication_origin_progress(PG_FUNCTION_ARGS); +extern Datum pg_show_replication_origin_status(PG_FUNCTION_ARGS); +extern Datum jsonb_subscript_handler(PG_FUNCTION_ARGS); +extern Datum numeric_pg_lsn(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_backend_subxact(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_subscription(PG_FUNCTION_ARGS); +extern Datum pg_get_publication_tables(PG_FUNCTION_ARGS); +extern Datum pg_get_replica_identity_index(PG_FUNCTION_ARGS); +extern Datum pg_relation_is_publishable(PG_FUNCTION_ARGS); +extern Datum multirange_gist_consistent(PG_FUNCTION_ARGS); +extern Datum multirange_gist_compress(PG_FUNCTION_ARGS); +extern Datum pg_get_catalog_foreign_keys(PG_FUNCTION_ARGS); +extern Datum text_to_table(PG_FUNCTION_ARGS); +extern Datum text_to_table_null(PG_FUNCTION_ARGS); +extern Datum bit_bit_count(PG_FUNCTION_ARGS); +extern Datum bytea_bit_count(PG_FUNCTION_ARGS); +extern Datum pg_xact_commit_timestamp_origin(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_replication_slot(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_replication_slot(PG_FUNCTION_ARGS); +extern Datum trim_array(PG_FUNCTION_ARGS); +extern Datum pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS); +extern Datum pg_get_statisticsobjdef_columns(PG_FUNCTION_ARGS); +extern Datum timestamp_bin(PG_FUNCTION_ARGS); +extern Datum timestamptz_bin(PG_FUNCTION_ARGS); +extern Datum array_subscript_handler(PG_FUNCTION_ARGS); +extern Datum raw_array_subscript_handler(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_session_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_active_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_idle_in_transaction_time(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_sessions(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_sessions_abandoned(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_sessions_fatal(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_sessions_killed(PG_FUNCTION_ARGS); +extern Datum hash_record(PG_FUNCTION_ARGS); +extern Datum hash_record_extended(PG_FUNCTION_ARGS); +extern Datum bytealtrim(PG_FUNCTION_ARGS); +extern Datum byteartrim(PG_FUNCTION_ARGS); +extern Datum pg_get_function_sqlbody(PG_FUNCTION_ARGS); +extern Datum unistr(PG_FUNCTION_ARGS); +extern Datum extract_date(PG_FUNCTION_ARGS); +extern Datum extract_time(PG_FUNCTION_ARGS); +extern Datum extract_timetz(PG_FUNCTION_ARGS); +extern Datum extract_timestamp(PG_FUNCTION_ARGS); +extern Datum extract_timestamptz(PG_FUNCTION_ARGS); +extern Datum extract_interval(PG_FUNCTION_ARGS); +extern Datum has_parameter_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_parameter_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_parameter_privilege_name(PG_FUNCTION_ARGS); +extern Datum pg_read_file_all_missing(PG_FUNCTION_ARGS); +extern Datum pg_read_binary_file_all_missing(PG_FUNCTION_ARGS); +extern Datum pg_input_is_valid(PG_FUNCTION_ARGS); +extern Datum pg_input_error_info(PG_FUNCTION_ARGS); +extern Datum drandom_normal(PG_FUNCTION_ARGS); +extern Datum pg_split_walfile_name(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_io(PG_FUNCTION_ARGS); +extern Datum array_shuffle(PG_FUNCTION_ARGS); +extern Datum array_sample(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_tuples_newpage_updated(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xact_tuples_newpage_updated(PG_FUNCTION_ARGS); +extern Datum derf(PG_FUNCTION_ARGS); +extern Datum derfc(PG_FUNCTION_ARGS); +extern Datum timestamptz_pl_interval_at_zone(PG_FUNCTION_ARGS); +extern Datum pg_get_wal_resource_managers(PG_FUNCTION_ARGS); +extern Datum multirange_agg_transfn(PG_FUNCTION_ARGS); +extern Datum pg_stat_have_stats(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_subscription_stats(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_subscription_stats(PG_FUNCTION_ARGS); +extern Datum window_row_number_support(PG_FUNCTION_ARGS); +extern Datum window_rank_support(PG_FUNCTION_ARGS); +extern Datum window_dense_rank_support(PG_FUNCTION_ARGS); +extern Datum int8inc_support(PG_FUNCTION_ARGS); +extern Datum pg_settings_get_flags(PG_FUNCTION_ARGS); +extern Datum pg_stop_making_pinned_objects(PG_FUNCTION_ARGS); +extern Datum text_starts_with_support(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_recovery_prefetch(PG_FUNCTION_ARGS); +extern Datum pg_database_collation_actual_version(PG_FUNCTION_ARGS); +extern Datum pg_ident_file_mappings(PG_FUNCTION_ARGS); +extern Datum textregexreplace_extended(PG_FUNCTION_ARGS); +extern Datum textregexreplace_extended_no_flags(PG_FUNCTION_ARGS); +extern Datum textregexreplace_extended_no_n(PG_FUNCTION_ARGS); +extern Datum regexp_count_no_start(PG_FUNCTION_ARGS); +extern Datum regexp_count_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_count(PG_FUNCTION_ARGS); +extern Datum regexp_instr_no_start(PG_FUNCTION_ARGS); +extern Datum regexp_instr_no_n(PG_FUNCTION_ARGS); +extern Datum regexp_instr_no_endoption(PG_FUNCTION_ARGS); +extern Datum regexp_instr_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_instr_no_subexpr(PG_FUNCTION_ARGS); +extern Datum regexp_instr(PG_FUNCTION_ARGS); +extern Datum regexp_like_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_like(PG_FUNCTION_ARGS); +extern Datum regexp_substr_no_start(PG_FUNCTION_ARGS); +extern Datum regexp_substr_no_n(PG_FUNCTION_ARGS); +extern Datum regexp_substr_no_flags(PG_FUNCTION_ARGS); +extern Datum regexp_substr_no_subexpr(PG_FUNCTION_ARGS); +extern Datum regexp_substr(PG_FUNCTION_ARGS); +extern Datum pg_ls_logicalsnapdir(PG_FUNCTION_ARGS); +extern Datum pg_ls_logicalmapdir(PG_FUNCTION_ARGS); +extern Datum pg_ls_replslotdir(PG_FUNCTION_ARGS); +extern Datum timestamptz_mi_interval_at_zone(PG_FUNCTION_ARGS); +extern Datum generate_series_timestamptz_at_zone(PG_FUNCTION_ARGS); +extern Datum json_agg_strict_transfn(PG_FUNCTION_ARGS); +extern Datum json_object_agg_strict_transfn(PG_FUNCTION_ARGS); +extern Datum json_object_agg_unique_transfn(PG_FUNCTION_ARGS); +extern Datum json_object_agg_unique_strict_transfn(PG_FUNCTION_ARGS); +extern Datum jsonb_agg_strict_transfn(PG_FUNCTION_ARGS); +extern Datum jsonb_object_agg_strict_transfn(PG_FUNCTION_ARGS); +extern Datum jsonb_object_agg_unique_transfn(PG_FUNCTION_ARGS); +extern Datum jsonb_object_agg_unique_strict_transfn(PG_FUNCTION_ARGS); +extern Datum any_value_transfn(PG_FUNCTION_ARGS); +extern Datum array_agg_combine(PG_FUNCTION_ARGS); +extern Datum array_agg_serialize(PG_FUNCTION_ARGS); +extern Datum array_agg_deserialize(PG_FUNCTION_ARGS); +extern Datum array_agg_array_combine(PG_FUNCTION_ARGS); +extern Datum array_agg_array_serialize(PG_FUNCTION_ARGS); +extern Datum array_agg_array_deserialize(PG_FUNCTION_ARGS); +extern Datum string_agg_combine(PG_FUNCTION_ARGS); +extern Datum string_agg_serialize(PG_FUNCTION_ARGS); +extern Datum string_agg_deserialize(PG_FUNCTION_ARGS); +extern Datum pg_log_standby_snapshot(PG_FUNCTION_ARGS); +extern Datum window_percent_rank_support(PG_FUNCTION_ARGS); +extern Datum window_cume_dist_support(PG_FUNCTION_ARGS); +extern Datum window_ntile_support(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_conflict_logicalslot(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_lastscan(PG_FUNCTION_ARGS); +extern Datum system_user(PG_FUNCTION_ARGS); +extern Datum cluster_get_wait_events(PG_FUNCTION_ARGS); +extern Datum cluster_get_gcluster_wait_events(PG_FUNCTION_ARGS); +extern Datum cluster_get_nodes(PG_FUNCTION_ARGS); +extern Datum cluster_ic_mock_inject(PG_FUNCTION_ARGS); +extern Datum cluster_ic_mock_drain_outbound(PG_FUNCTION_ARGS); +extern Datum cluster_ic_mock_clear_all(PG_FUNCTION_ARGS); +extern Datum cluster_ic_mock_recv_test(PG_FUNCTION_ARGS); +extern Datum cluster_inject_fault(PG_FUNCTION_ARGS); +extern Datum cluster_get_injection_state(PG_FUNCTION_ARGS); +extern Datum cluster_get_stat_nodes(PG_FUNCTION_ARGS); +extern Datum cluster_get_pgstat_counters(PG_FUNCTION_ARGS); +extern Datum cluster_dump_state(PG_FUNCTION_ARGS); +extern Datum cluster_shmem_dump_regions(PG_FUNCTION_ARGS); +extern Datum cluster_scn_advance_sql(PG_FUNCTION_ARGS); +extern Datum cluster_scn_current_sql(PG_FUNCTION_ARGS); +extern Datum cluster_scn_observe_sql(PG_FUNCTION_ARGS); +extern Datum cluster_get_ic_peers(PG_FUNCTION_ARGS); +extern Datum cluster_get_ic_msg_types(PG_FUNCTION_ARGS); +extern Datum cluster_get_cssd_peers(PG_FUNCTION_ARGS); +extern Datum cluster_get_quorum_state(PG_FUNCTION_ARGS); +extern Datum cluster_get_voting_disks(PG_FUNCTION_ARGS); +extern Datum cluster_get_fence_state(PG_FUNCTION_ARGS); +extern Datum cluster_get_reconfig_state(PG_FUNCTION_ARGS); +extern Datum cluster_get_grd_shards(PG_FUNCTION_ARGS); +extern Datum cluster_get_grd_entries(PG_FUNCTION_ARGS); +extern Datum cluster_get_lmd_state(PG_FUNCTION_ARGS); +extern Datum pg_cluster_lmd_inject_wait_edge(PG_FUNCTION_ARGS); +extern Datum cluster_test_inject_visibility_tt_ref(PG_FUNCTION_ARGS); +extern Datum cluster_test_clear_visibility_injects(PG_FUNCTION_ARGS); +extern Datum cluster_test_inject_subtrans_subcommitted(PG_FUNCTION_ARGS); +extern Datum cluster_undo_get_record_srf(PG_FUNCTION_ARGS); +extern Datum cluster_undo_test_force_segment_end_srf(PG_FUNCTION_ARGS); +extern Datum cluster_cr_test_construct(PG_FUNCTION_ARGS); +extern Datum cluster_cr_test_image(PG_FUNCTION_ARGS); +extern Datum cluster_block_apply_redo_test(PG_FUNCTION_ARGS); +extern Datum cluster_block_recovery_reconstruct_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_apply_redo_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_replay_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_drive_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_replay_one_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_replay_one_auto_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_local_complete_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_gate_unfreeze_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_validated_end_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_replay_slot_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_recovery_worker_run_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_recovery_launch_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_replay_slot_state_test(PG_FUNCTION_ARGS); +extern Datum cluster_reconfig_inject_dead_node_test(PG_FUNCTION_ARGS); +extern Datum cluster_thread_capability_gate_test(PG_FUNCTION_ARGS); +extern Datum pg_cluster_ges_mode_matrix(PG_FUNCTION_ARGS); +extern Datum cluster_ges_mode_compat(PG_FUNCTION_ARGS); +extern Datum cluster_ges_mode_matches_pg(PG_FUNCTION_ARGS); + +#endif /* FMGRPROTOS_H */ diff --git a/install/include/postgresql/server/utils/fmgrtab.h b/install/include/postgresql/server/utils/fmgrtab.h new file mode 100644 index 00000000000..838ffe3bc1c --- /dev/null +++ b/install/include/postgresql/server/utils/fmgrtab.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * fmgrtab.h + * The function manager's table of internal functions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/fmgrtab.h + * + *------------------------------------------------------------------------- + */ +#ifndef FMGRTAB_H +#define FMGRTAB_H + +#include "access/transam.h" +#include "fmgr.h" + + +/* + * This table stores info about all the built-in functions (ie, functions + * that are compiled into the Postgres executable). + */ + +typedef struct +{ + Oid foid; /* OID of the function */ + short nargs; /* 0..FUNC_MAX_ARGS, or -1 if variable count */ + bool strict; /* T if function is "strict" */ + bool retset; /* T if function returns a set */ + const char *funcName; /* C name of the function */ + PGFunction func; /* pointer to compiled function */ +} FmgrBuiltin; + +extern PGDLLIMPORT const FmgrBuiltin fmgr_builtins[]; + +extern PGDLLIMPORT const int fmgr_nbuiltins; /* number of entries in table */ + +extern PGDLLIMPORT const Oid fmgr_last_builtin_oid; /* highest function OID in + * table */ + +/* + * Mapping from a builtin function's OID to its index in the fmgr_builtins + * array. This is indexed from 0 through fmgr_last_builtin_oid. + */ +#define InvalidOidBuiltinMapping PG_UINT16_MAX +extern PGDLLIMPORT const uint16 fmgr_builtin_oid_index[]; + +#endif /* FMGRTAB_H */ diff --git a/install/include/postgresql/server/utils/formatting.h b/install/include/postgresql/server/utils/formatting.h new file mode 100644 index 00000000000..0cad3a27090 --- /dev/null +++ b/install/include/postgresql/server/utils/formatting.h @@ -0,0 +1,33 @@ +/* ----------------------------------------------------------------------- + * formatting.h + * + * src/include/utils/formatting.h + * + * + * Portions Copyright (c) 1999-2023, PostgreSQL Global Development Group + * + * The PostgreSQL routines for a DateTime/int/float/numeric formatting, + * inspired by the Oracle TO_CHAR() / TO_DATE() / TO_NUMBER() routines. + * + * Karel Zak + * + * ----------------------------------------------------------------------- + */ + +#ifndef _FORMATTING_H_ +#define _FORMATTING_H_ + + +extern char *str_tolower(const char *buff, size_t nbytes, Oid collid); +extern char *str_toupper(const char *buff, size_t nbytes, Oid collid); +extern char *str_initcap(const char *buff, size_t nbytes, Oid collid); + +extern char *asc_tolower(const char *buff, size_t nbytes); +extern char *asc_toupper(const char *buff, size_t nbytes); +extern char *asc_initcap(const char *buff, size_t nbytes); + +extern Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict, + Oid *typid, int32 *typmod, int *tz, + struct Node *escontext); + +#endif diff --git a/install/include/postgresql/server/utils/freepage.h b/install/include/postgresql/server/utils/freepage.h new file mode 100644 index 00000000000..8d1ebb4c47c --- /dev/null +++ b/install/include/postgresql/server/utils/freepage.h @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------- + * + * freepage.h + * Management of page-organized free memory. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/freepage.h + * + *------------------------------------------------------------------------- + */ + +#ifndef FREEPAGE_H +#define FREEPAGE_H + +#include "storage/lwlock.h" +#include "utils/relptr.h" + +/* Forward declarations. */ +typedef struct FreePageSpanLeader FreePageSpanLeader; +typedef struct FreePageBtree FreePageBtree; +typedef struct FreePageManager FreePageManager; + +/* + * PostgreSQL normally uses 8kB pages for most things, but many common + * architecture/operating system pairings use a 4kB page size for memory + * allocation, so we do that here also. + */ +#define FPM_PAGE_SIZE 4096 + +/* + * Each freelist except for the last contains only spans of one particular + * size. Everything larger goes on the last one. In some sense this seems + * like a waste since most allocations are in a few common sizes, but it + * means that small allocations can simply pop the head of the relevant list + * without needing to worry about whether the object we find there is of + * precisely the correct size (because we know it must be). + */ +#define FPM_NUM_FREELISTS 129 + +/* Define relative pointer types. */ +relptr_declare(FreePageBtree, RelptrFreePageBtree); +relptr_declare(FreePageManager, RelptrFreePageManager); +relptr_declare(FreePageSpanLeader, RelptrFreePageSpanLeader); + +/* Everything we need in order to manage free pages (see freepage.c) */ +struct FreePageManager +{ + RelptrFreePageManager self; + RelptrFreePageBtree btree_root; + RelptrFreePageSpanLeader btree_recycle; + unsigned btree_depth; + unsigned btree_recycle_count; + Size singleton_first_page; + Size singleton_npages; + Size contiguous_pages; + bool contiguous_pages_dirty; + RelptrFreePageSpanLeader freelist[FPM_NUM_FREELISTS]; +#ifdef FPM_EXTRA_ASSERTS + /* For debugging only, pages put minus pages gotten. */ + Size free_pages; +#endif +}; + +/* Macros to convert between page numbers (expressed as Size) and pointers. */ +#define fpm_page_to_pointer(base, page) \ + (AssertVariableIsOfTypeMacro(page, Size), \ + (base) + FPM_PAGE_SIZE * (page)) +#define fpm_pointer_to_page(base, ptr) \ + (((Size) (((char *) (ptr)) - (base))) / FPM_PAGE_SIZE) + +/* Macro to convert an allocation size to a number of pages. */ +#define fpm_size_to_pages(sz) \ + (((sz) + FPM_PAGE_SIZE - 1) / FPM_PAGE_SIZE) + +/* Macros to check alignment of absolute and relative pointers. */ +#define fpm_pointer_is_page_aligned(base, ptr) \ + (((Size) (((char *) (ptr)) - (base))) % FPM_PAGE_SIZE == 0) +#define fpm_relptr_is_page_aligned(base, relptr) \ + (relptr_offset(relptr) % FPM_PAGE_SIZE == 0) + +/* Macro to find base address of the segment containing a FreePageManager. */ +#define fpm_segment_base(fpm) \ + (((char *) fpm) - relptr_offset(fpm->self)) + +/* Macro to access a FreePageManager's largest consecutive run of pages. */ +#define fpm_largest(fpm) \ + (fpm->contiguous_pages) + +/* Functions to manipulate the free page map. */ +extern void FreePageManagerInitialize(FreePageManager *fpm, char *base); +extern bool FreePageManagerGet(FreePageManager *fpm, Size npages, + Size *first_page); +extern void FreePageManagerPut(FreePageManager *fpm, Size first_page, + Size npages); +extern char *FreePageManagerDump(FreePageManager *fpm); + +#endif /* FREEPAGE_H */ diff --git a/install/include/postgresql/server/utils/geo_decls.h b/install/include/postgresql/server/utils/geo_decls.h new file mode 100644 index 00000000000..d176f589d4b --- /dev/null +++ b/install/include/postgresql/server/utils/geo_decls.h @@ -0,0 +1,285 @@ +/*------------------------------------------------------------------------- + * + * geo_decls.h - Declarations for various 2D constructs. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/geo_decls.h + * + * XXX These routines were not written by a numerical analyst. + * + * XXX I have made some attempt to flesh out the operators + * and data types. There are still some more to do. - tgl 97/04/19 + * + *------------------------------------------------------------------------- + */ +#ifndef GEO_DECLS_H +#define GEO_DECLS_H + +#include + +#include "fmgr.h" + +/*-------------------------------------------------------------------- + * Useful floating point utilities and constants. + *-------------------------------------------------------------------- + * + * "Fuzzy" floating-point comparisons: values within EPSILON of each other + * are considered equal. Beware of normal reasoning about the behavior of + * these comparisons, since for example FPeq does not behave transitively. + * + * Note that these functions are not NaN-aware and will give FALSE for + * any case involving NaN inputs. + * + * Also note that these will give sane answers for infinite inputs, + * where it's important to avoid computing Inf minus Inf; we do so + * by eliminating equality cases before subtracting. + */ + +#define EPSILON 1.0E-06 + +#ifdef EPSILON +#define FPzero(A) (fabs(A) <= EPSILON) + +static inline bool +FPeq(double A, double B) +{ + return A == B || fabs(A - B) <= EPSILON; +} + +static inline bool +FPne(double A, double B) +{ + return A != B && fabs(A - B) > EPSILON; +} + +static inline bool +FPlt(double A, double B) +{ + return A + EPSILON < B; +} + +static inline bool +FPle(double A, double B) +{ + return A <= B + EPSILON; +} + +static inline bool +FPgt(double A, double B) +{ + return A > B + EPSILON; +} + +static inline bool +FPge(double A, double B) +{ + return A + EPSILON >= B; +} +#else +#define FPzero(A) ((A) == 0) +#define FPeq(A,B) ((A) == (B)) +#define FPne(A,B) ((A) != (B)) +#define FPlt(A,B) ((A) < (B)) +#define FPle(A,B) ((A) <= (B)) +#define FPgt(A,B) ((A) > (B)) +#define FPge(A,B) ((A) >= (B)) +#endif + +#define HYPOT(A, B) pg_hypot(A, B) + +/*--------------------------------------------------------------------- + * Point - (x,y) + *-------------------------------------------------------------------*/ +typedef struct +{ + float8 x, + y; +} Point; + + +/*--------------------------------------------------------------------- + * LSEG - A straight line, specified by endpoints. + *-------------------------------------------------------------------*/ +typedef struct +{ + Point p[2]; +} LSEG; + + +/*--------------------------------------------------------------------- + * PATH - Specified by vertex points. + *-------------------------------------------------------------------*/ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 npts; + int32 closed; /* is this a closed polygon? */ + int32 dummy; /* padding to make it double align */ + Point p[FLEXIBLE_ARRAY_MEMBER]; +} PATH; + + +/*--------------------------------------------------------------------- + * LINE - Specified by its general equation (Ax+By+C=0). + *-------------------------------------------------------------------*/ +typedef struct +{ + float8 A, + B, + C; +} LINE; + + +/*--------------------------------------------------------------------- + * BOX - Specified by two corner points, which are + * sorted to save calculation time later. + *-------------------------------------------------------------------*/ +typedef struct +{ + Point high, + low; /* corner POINTs */ +} BOX; + +/*--------------------------------------------------------------------- + * POLYGON - Specified by an array of doubles defining the points, + * keeping the number of points and the bounding box for + * speed purposes. + *-------------------------------------------------------------------*/ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 npts; + BOX boundbox; + Point p[FLEXIBLE_ARRAY_MEMBER]; +} POLYGON; + +/*--------------------------------------------------------------------- + * CIRCLE - Specified by a center point and radius. + *-------------------------------------------------------------------*/ +typedef struct +{ + Point center; + float8 radius; +} CIRCLE; + +/* + * fmgr interface functions + * + * Path and Polygon are toastable varlena types, the others are just + * fixed-size pass-by-reference types. + */ + +static inline Point * +DatumGetPointP(Datum X) +{ + return (Point *) DatumGetPointer(X); +} +static inline Datum +PointPGetDatum(const Point *X) +{ + return PointerGetDatum(X); +} +#define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n)) +#define PG_RETURN_POINT_P(x) return PointPGetDatum(x) + +static inline LSEG * +DatumGetLsegP(Datum X) +{ + return (LSEG *) DatumGetPointer(X); +} +static inline Datum +LsegPGetDatum(const LSEG *X) +{ + return PointerGetDatum(X); +} +#define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n)) +#define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x) + +static inline PATH * +DatumGetPathP(Datum X) +{ + return (PATH *) PG_DETOAST_DATUM(X); +} +static inline PATH * +DatumGetPathPCopy(Datum X) +{ + return (PATH *) PG_DETOAST_DATUM_COPY(X); +} +static inline Datum +PathPGetDatum(const PATH *X) +{ + return PointerGetDatum(X); +} +#define PG_GETARG_PATH_P(n) DatumGetPathP(PG_GETARG_DATUM(n)) +#define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_PATH_P(x) return PathPGetDatum(x) + +static inline LINE * +DatumGetLineP(Datum X) +{ + return (LINE *) DatumGetPointer(X); +} +static inline Datum +LinePGetDatum(const LINE *X) +{ + return PointerGetDatum(X); +} +#define PG_GETARG_LINE_P(n) DatumGetLineP(PG_GETARG_DATUM(n)) +#define PG_RETURN_LINE_P(x) return LinePGetDatum(x) + +static inline BOX * +DatumGetBoxP(Datum X) +{ + return (BOX *) DatumGetPointer(X); +} +static inline Datum +BoxPGetDatum(const BOX *X) +{ + return PointerGetDatum(X); +} +#define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n)) +#define PG_RETURN_BOX_P(x) return BoxPGetDatum(x) + +static inline POLYGON * +DatumGetPolygonP(Datum X) +{ + return (POLYGON *) PG_DETOAST_DATUM(X); +} +static inline POLYGON * +DatumGetPolygonPCopy(Datum X) +{ + return (POLYGON *) PG_DETOAST_DATUM_COPY(X); +} +static inline Datum +PolygonPGetDatum(const POLYGON *X) +{ + return PointerGetDatum(X); +} +#define PG_GETARG_POLYGON_P(n) DatumGetPolygonP(PG_GETARG_DATUM(n)) +#define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x) + +static inline CIRCLE * +DatumGetCircleP(Datum X) +{ + return (CIRCLE *) DatumGetPointer(X); +} +static inline Datum +CirclePGetDatum(const CIRCLE *X) +{ + return PointerGetDatum(X); +} +#define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n)) +#define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x) + + +/* + * in geo_ops.c + */ + +extern float8 pg_hypot(float8 x, float8 y); + +#endif /* GEO_DECLS_H */ diff --git a/install/include/postgresql/server/utils/guc.h b/install/include/postgresql/server/utils/guc.h new file mode 100644 index 00000000000..3c1f78bb992 --- /dev/null +++ b/install/include/postgresql/server/utils/guc.h @@ -0,0 +1,443 @@ +/*-------------------------------------------------------------------- + * guc.h + * + * External declarations pertaining to Grand Unified Configuration. + * + * Copyright (c) 2000-2023, PostgreSQL Global Development Group + * Written by Peter Eisentraut . + * + * src/include/utils/guc.h + *-------------------------------------------------------------------- + */ +#ifndef GUC_H +#define GUC_H + +#include "nodes/parsenodes.h" +#include "tcop/dest.h" +#include "utils/array.h" + + +/* upper limit for GUC variables measured in kilobytes of memory */ +/* note that various places assume the byte size fits in a "long" variable */ +#if SIZEOF_SIZE_T > 4 && SIZEOF_LONG > 4 +#define MAX_KILOBYTES INT_MAX +#else +#define MAX_KILOBYTES (INT_MAX / 1024) +#endif + +/* + * Automatic configuration file name for ALTER SYSTEM. + * This file will be used to store values of configuration parameters + * set by ALTER SYSTEM command. + */ +#define PG_AUTOCONF_FILENAME "postgresql.auto.conf" + +/* + * Certain options can only be set at certain times. The rules are + * like this: + * + * INTERNAL options cannot be set by the user at all, but only through + * internal processes ("server_version" is an example). These are GUC + * variables only so they can be shown by SHOW, etc. + * + * POSTMASTER options can only be set when the postmaster starts, + * either from the configuration file or the command line. + * + * SIGHUP options can only be set at postmaster startup or by changing + * the configuration file and sending the HUP signal to the postmaster + * or a backend process. (Notice that the signal receipt will not be + * evaluated immediately. The postmaster and the backend check it at a + * certain point in their main loop. It's safer to wait than to read a + * file asynchronously.) + * + * BACKEND and SU_BACKEND options can only be set at postmaster startup, + * from the configuration file, or by client request in the connection + * startup packet (e.g., from libpq's PGOPTIONS variable). SU_BACKEND + * options can be set from the startup packet only when the user is a + * superuser. Furthermore, an already-started backend will ignore changes + * to such an option in the configuration file. The idea is that these + * options are fixed for a given backend once it's started, but they can + * vary across backends. + * + * SUSET options can be set at postmaster startup, with the SIGHUP + * mechanism, or from the startup packet or SQL if you're a superuser. + * + * USERSET options can be set by anyone any time. + */ +typedef enum +{ + PGC_INTERNAL, + PGC_POSTMASTER, + PGC_SIGHUP, + PGC_SU_BACKEND, + PGC_BACKEND, + PGC_SUSET, + PGC_USERSET +} GucContext; + +/* + * The following type records the source of the current setting. A + * new setting can only take effect if the previous setting had the + * same or lower level. (E.g, changing the config file doesn't + * override the postmaster command line.) Tracking the source allows us + * to process sources in any convenient order without affecting results. + * Sources <= PGC_S_OVERRIDE will set the default used by RESET, as well + * as the current value. + * + * PGC_S_INTERACTIVE isn't actually a source value, but is the + * dividing line between "interactive" and "non-interactive" sources for + * error reporting purposes. + * + * PGC_S_TEST is used when testing values to be used later. For example, + * ALTER DATABASE/ROLE tests proposed per-database or per-user defaults this + * way, and CREATE FUNCTION tests proposed function SET clauses this way. + * This is an interactive case, but it needs its own source value because + * some assign hooks need to make different validity checks in this case. + * In particular, references to nonexistent database objects generally + * shouldn't throw hard errors in this case, at most NOTICEs, since the + * objects might exist by the time the setting is used for real. + * + * When setting the value of a non-compile-time-constant PGC_INTERNAL option, + * source == PGC_S_DYNAMIC_DEFAULT should typically be used so that the value + * will show as "default" in pg_settings. If there is a specific reason not + * to want that, use source == PGC_S_OVERRIDE. + * + * NB: see GucSource_Names in guc_tables.c if you change this. + */ +typedef enum +{ + PGC_S_DEFAULT, /* hard-wired default ("boot_val") */ + PGC_S_DYNAMIC_DEFAULT, /* default computed during initialization */ + PGC_S_ENV_VAR, /* postmaster environment variable */ + PGC_S_FILE, /* postgresql.conf */ + PGC_S_ARGV, /* postmaster command line */ + PGC_S_GLOBAL, /* global in-database setting */ + PGC_S_DATABASE, /* per-database setting */ + PGC_S_USER, /* per-user setting */ + PGC_S_DATABASE_USER, /* per-user-and-database setting */ + PGC_S_CLIENT, /* from client connection request */ + PGC_S_OVERRIDE, /* special case to forcibly set default */ + PGC_S_INTERACTIVE, /* dividing line for error reporting */ + PGC_S_TEST, /* test per-database or per-user setting */ + PGC_S_SESSION /* SET command */ +} GucSource; + +/* + * Parsing the configuration file(s) will return a list of name-value pairs + * with source location info. We also abuse this data structure to carry + * error reports about the config files. An entry reporting an error will + * have errmsg != NULL, and might have NULLs for name, value, and/or filename. + * + * If "ignore" is true, don't attempt to apply the item (it might be an error + * report, or an item we determined to be duplicate). "applied" is set true + * if we successfully applied, or could have applied, the setting. + */ +typedef struct ConfigVariable +{ + char *name; + char *value; + char *errmsg; + char *filename; + int sourceline; + bool ignore; + bool applied; + struct ConfigVariable *next; +} ConfigVariable; + +extern bool ParseConfigFile(const char *config_file, bool strict, + const char *calling_file, int calling_lineno, + int depth, int elevel, + ConfigVariable **head_p, ConfigVariable **tail_p); +extern bool ParseConfigFp(FILE *fp, const char *config_file, + int depth, int elevel, + ConfigVariable **head_p, ConfigVariable **tail_p); +extern bool ParseConfigDirectory(const char *includedir, + const char *calling_file, int calling_lineno, + int depth, int elevel, + ConfigVariable **head_p, + ConfigVariable **tail_p); +extern void FreeConfigVariables(ConfigVariable *list); +extern char *DeescapeQuotedString(const char *s); + +/* + * The possible values of an enum variable are specified by an array of + * name-value pairs. The "hidden" flag means the value is accepted but + * won't be displayed when guc.c is asked for a list of acceptable values. + */ +struct config_enum_entry +{ + const char *name; + int val; + bool hidden; +}; + +/* + * Signatures for per-variable check/assign/show hook functions + */ +typedef bool (*GucBoolCheckHook) (bool *newval, void **extra, GucSource source); +typedef bool (*GucIntCheckHook) (int *newval, void **extra, GucSource source); +typedef bool (*GucRealCheckHook) (double *newval, void **extra, GucSource source); +typedef bool (*GucStringCheckHook) (char **newval, void **extra, GucSource source); +typedef bool (*GucEnumCheckHook) (int *newval, void **extra, GucSource source); + +typedef void (*GucBoolAssignHook) (bool newval, void *extra); +typedef void (*GucIntAssignHook) (int newval, void *extra); +typedef void (*GucRealAssignHook) (double newval, void *extra); +typedef void (*GucStringAssignHook) (const char *newval, void *extra); +typedef void (*GucEnumAssignHook) (int newval, void *extra); + +typedef const char *(*GucShowHook) (void); + +/* + * Miscellaneous + */ +typedef enum +{ + /* Types of set_config_option actions */ + GUC_ACTION_SET, /* regular SET command */ + GUC_ACTION_LOCAL, /* SET LOCAL command */ + GUC_ACTION_SAVE /* function SET option, or temp assignment */ +} GucAction; + +#define GUC_QUALIFIER_SEPARATOR '.' + +/* + * Bit values in "flags" of a GUC variable. Note that these don't appear + * on disk, so we can reassign their values freely. + */ +#define GUC_LIST_INPUT 0x000001 /* input can be list format */ +#define GUC_LIST_QUOTE 0x000002 /* double-quote list elements */ +#define GUC_NO_SHOW_ALL 0x000004 /* exclude from SHOW ALL */ +#define GUC_NO_RESET 0x000008 /* disallow RESET and SAVE */ +#define GUC_NO_RESET_ALL 0x000010 /* exclude from RESET ALL */ +#define GUC_EXPLAIN 0x000020 /* include in EXPLAIN */ +#define GUC_REPORT 0x000040 /* auto-report changes to client */ +#define GUC_NOT_IN_SAMPLE 0x000080 /* not in postgresql.conf.sample */ +#define GUC_DISALLOW_IN_FILE 0x000100 /* can't set in postgresql.conf */ +#define GUC_CUSTOM_PLACEHOLDER 0x000200 /* placeholder for custom variable */ +#define GUC_SUPERUSER_ONLY 0x000400 /* show only to superusers */ +#define GUC_IS_NAME 0x000800 /* limit string to NAMEDATALEN-1 */ +#define GUC_NOT_WHILE_SEC_REST 0x001000 /* can't set if security restricted */ +#define GUC_DISALLOW_IN_AUTO_FILE \ + 0x002000 /* can't set in PG_AUTOCONF_FILENAME */ +#define GUC_RUNTIME_COMPUTED 0x004000 /* delay processing in 'postgres -C' */ +#define GUC_ALLOW_IN_PARALLEL 0x008000 /* allow setting in parallel mode */ + +#define GUC_UNIT_KB 0x01000000 /* value is in kilobytes */ +#define GUC_UNIT_BLOCKS 0x02000000 /* value is in blocks */ +#define GUC_UNIT_XBLOCKS 0x03000000 /* value is in xlog blocks */ +#define GUC_UNIT_MB 0x04000000 /* value is in megabytes */ +#define GUC_UNIT_BYTE 0x05000000 /* value is in bytes */ +#define GUC_UNIT_MEMORY 0x0F000000 /* mask for size-related units */ + +#define GUC_UNIT_MS 0x10000000 /* value is in milliseconds */ +#define GUC_UNIT_S 0x20000000 /* value is in seconds */ +#define GUC_UNIT_MIN 0x30000000 /* value is in minutes */ +#define GUC_UNIT_TIME 0x70000000 /* mask for time-related units */ + +#define GUC_UNIT (GUC_UNIT_MEMORY | GUC_UNIT_TIME) + + +/* GUC vars that are actually defined in guc_tables.c, rather than elsewhere */ +extern PGDLLIMPORT bool Debug_print_plan; +extern PGDLLIMPORT bool Debug_print_parse; +extern PGDLLIMPORT bool Debug_print_rewritten; +extern PGDLLIMPORT bool Debug_pretty_print; + +extern PGDLLIMPORT bool log_parser_stats; +extern PGDLLIMPORT bool log_planner_stats; +extern PGDLLIMPORT bool log_executor_stats; +extern PGDLLIMPORT bool log_statement_stats; +extern PGDLLIMPORT bool log_btree_build_stats; + +extern PGDLLIMPORT bool check_function_bodies; +extern PGDLLIMPORT bool session_auth_is_superuser; + +extern PGDLLIMPORT bool log_duration; +extern PGDLLIMPORT int log_parameter_max_length; +extern PGDLLIMPORT int log_parameter_max_length_on_error; +extern PGDLLIMPORT int log_min_error_statement; +extern PGDLLIMPORT int log_min_messages; +extern PGDLLIMPORT int client_min_messages; +extern PGDLLIMPORT int log_min_duration_sample; +extern PGDLLIMPORT int log_min_duration_statement; +extern PGDLLIMPORT int log_temp_files; +extern PGDLLIMPORT double log_statement_sample_rate; +extern PGDLLIMPORT double log_xact_sample_rate; +extern PGDLLIMPORT char *backtrace_functions; + +extern PGDLLIMPORT int temp_file_limit; + +extern PGDLLIMPORT int num_temp_buffers; + +extern PGDLLIMPORT char *cluster_name; +extern PGDLLIMPORT char *ConfigFileName; +extern PGDLLIMPORT char *HbaFileName; +extern PGDLLIMPORT char *IdentFileName; +extern PGDLLIMPORT char *external_pid_file; + +extern PGDLLIMPORT char *application_name; + +extern PGDLLIMPORT int tcp_keepalives_idle; +extern PGDLLIMPORT int tcp_keepalives_interval; +extern PGDLLIMPORT int tcp_keepalives_count; +extern PGDLLIMPORT int tcp_user_timeout; + +#ifdef TRACE_SORT +extern PGDLLIMPORT bool trace_sort; +#endif + +/* + * Functions exported by guc.c + */ +extern void SetConfigOption(const char *name, const char *value, + GucContext context, GucSource source); + +extern void DefineCustomBoolVariable(const char *name, + const char *short_desc, + const char *long_desc, + bool *valueAddr, + bool bootValue, + GucContext context, + int flags, + GucBoolCheckHook check_hook, + GucBoolAssignHook assign_hook, + GucShowHook show_hook) pg_attribute_nonnull(1, 4); + +extern void DefineCustomIntVariable(const char *name, + const char *short_desc, + const char *long_desc, + int *valueAddr, + int bootValue, + int minValue, + int maxValue, + GucContext context, + int flags, + GucIntCheckHook check_hook, + GucIntAssignHook assign_hook, + GucShowHook show_hook) pg_attribute_nonnull(1, 4); + +extern void DefineCustomRealVariable(const char *name, + const char *short_desc, + const char *long_desc, + double *valueAddr, + double bootValue, + double minValue, + double maxValue, + GucContext context, + int flags, + GucRealCheckHook check_hook, + GucRealAssignHook assign_hook, + GucShowHook show_hook) pg_attribute_nonnull(1, 4); + +extern void DefineCustomStringVariable(const char *name, + const char *short_desc, + const char *long_desc, + char **valueAddr, + const char *bootValue, + GucContext context, + int flags, + GucStringCheckHook check_hook, + GucStringAssignHook assign_hook, + GucShowHook show_hook) pg_attribute_nonnull(1, 4); + +extern void DefineCustomEnumVariable(const char *name, + const char *short_desc, + const char *long_desc, + int *valueAddr, + int bootValue, + const struct config_enum_entry *options, + GucContext context, + int flags, + GucEnumCheckHook check_hook, + GucEnumAssignHook assign_hook, + GucShowHook show_hook) pg_attribute_nonnull(1, 4); + +extern void MarkGUCPrefixReserved(const char *className); + +/* old name for MarkGUCPrefixReserved, for backwards compatibility: */ +#define EmitWarningsOnPlaceholders(className) MarkGUCPrefixReserved(className) + +extern const char *GetConfigOption(const char *name, bool missing_ok, + bool restrict_privileged); +extern const char *GetConfigOptionResetString(const char *name); +extern int GetConfigOptionFlags(const char *name, bool missing_ok); +extern void ProcessConfigFile(GucContext context); +extern char *convert_GUC_name_for_parameter_acl(const char *name); +extern bool check_GUC_name_for_parameter_acl(const char *name); +extern void InitializeGUCOptions(void); +extern bool SelectConfigFiles(const char *userDoption, const char *progname); +extern void ResetAllOptions(void); +extern void AtStart_GUC(void); +extern int NewGUCNestLevel(void); +extern void AtEOXact_GUC(bool isCommit, int nestLevel); +extern void BeginReportingGUCOptions(void); +extern void ReportChangedGUCOptions(void); +extern void ParseLongOption(const char *string, char **name, char **value); +extern const char *get_config_unit_name(int flags); +extern bool parse_int(const char *value, int *result, int flags, + const char **hintmsg); +extern bool parse_real(const char *value, double *result, int flags, + const char **hintmsg); +extern int set_config_option(const char *name, const char *value, + GucContext context, GucSource source, + GucAction action, bool changeVal, int elevel, + bool is_reload); +extern int set_config_option_ext(const char *name, const char *value, + GucContext context, GucSource source, + Oid srole, + GucAction action, bool changeVal, int elevel, + bool is_reload); +extern void AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt); +extern char *GetConfigOptionByName(const char *name, const char **varname, + bool missing_ok); + +extern void ProcessGUCArray(ArrayType *array, + GucContext context, GucSource source, GucAction action); +extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value); +extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name); +extern ArrayType *GUCArrayReset(ArrayType *array); + +extern void *guc_malloc(int elevel, size_t size); +extern pg_nodiscard void *guc_realloc(int elevel, void *old, size_t size); +extern char *guc_strdup(int elevel, const char *src); +extern void guc_free(void *ptr); + +#ifdef EXEC_BACKEND +extern void write_nondefault_variables(GucContext context); +extern void read_nondefault_variables(void); +#endif + +/* GUC serialization */ +extern Size EstimateGUCStateSpace(void); +extern void SerializeGUCState(Size maxsize, char *start_address); +extern void RestoreGUCState(void *gucstate); + +/* Functions exported by guc_funcs.c */ +extern void ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel); +extern char *ExtractSetVariableArgs(VariableSetStmt *stmt); +extern void SetPGVariable(const char *name, List *args, bool is_local); +extern void GetPGVariable(const char *name, DestReceiver *dest); +extern TupleDesc GetPGVariableResultDesc(const char *name); + +/* Support for messages reported from GUC check hooks */ + +extern PGDLLIMPORT char *GUC_check_errmsg_string; +extern PGDLLIMPORT char *GUC_check_errdetail_string; +extern PGDLLIMPORT char *GUC_check_errhint_string; + +extern void GUC_check_errcode(int sqlerrcode); + +#define GUC_check_errmsg \ + pre_format_elog_string(errno, TEXTDOMAIN), \ + GUC_check_errmsg_string = format_elog_string + +#define GUC_check_errdetail \ + pre_format_elog_string(errno, TEXTDOMAIN), \ + GUC_check_errdetail_string = format_elog_string + +#define GUC_check_errhint \ + pre_format_elog_string(errno, TEXTDOMAIN), \ + GUC_check_errhint_string = format_elog_string + +#endif /* GUC_H */ diff --git a/install/include/postgresql/server/utils/guc_hooks.h b/install/include/postgresql/server/utils/guc_hooks.h new file mode 100644 index 00000000000..0ea33fede9c --- /dev/null +++ b/install/include/postgresql/server/utils/guc_hooks.h @@ -0,0 +1,166 @@ +/*------------------------------------------------------------------------- + * + * guc_hooks.h + * Declarations of per-variable callback functions used by GUC. + * + * These functions are scattered throughout the system, but we + * declare them all here to avoid having to propagate guc.h into + * a lot of unrelated header files. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/utils/guc_hooks.h + * + *------------------------------------------------------------------------- + */ +#ifndef GUC_HOOKS_H +#define GUC_HOOKS_H 1 + +#include "utils/guc.h" + +/* + * See guc.h for the typedefs that these hook functions should match + * (GucBoolCheckHook and so on). + * + * Please keep the declarations in order by GUC variable name. + */ + +extern bool check_application_name(char **newval, void **extra, + GucSource source); +extern void assign_application_name(const char *newval, void *extra); +extern const char *show_archive_command(void); +extern bool check_autovacuum_max_workers(int *newval, void **extra, + GucSource source); +extern bool check_autovacuum_work_mem(int *newval, void **extra, + GucSource source); +extern bool check_vacuum_buffer_usage_limit(int *newval, void **extra, + GucSource source); +extern bool check_backtrace_functions(char **newval, void **extra, + GucSource source); +extern void assign_backtrace_functions(const char *newval, void *extra); +extern bool check_bonjour(bool *newval, void **extra, GucSource source); +extern bool check_canonical_path(char **newval, void **extra, GucSource source); +extern void assign_checkpoint_completion_target(double newval, void *extra); +extern bool check_client_connection_check_interval(int *newval, void **extra, + GucSource source); +extern bool check_client_encoding(char **newval, void **extra, GucSource source); +extern void assign_client_encoding(const char *newval, void *extra); +extern bool check_cluster_name(char **newval, void **extra, GucSource source); +extern const char *show_data_directory_mode(void); +extern bool check_datestyle(char **newval, void **extra, GucSource source); +extern void assign_datestyle(const char *newval, void *extra); +extern bool check_debug_io_direct(char **newval, void **extra, GucSource source); +extern void assign_debug_io_direct(const char *newval, void *extra); +extern bool check_default_table_access_method(char **newval, void **extra, + GucSource source); +extern bool check_default_tablespace(char **newval, void **extra, + GucSource source); +extern bool check_default_text_search_config(char **newval, void **extra, GucSource source); +extern void assign_default_text_search_config(const char *newval, void *extra); +extern bool check_default_with_oids(bool *newval, void **extra, + GucSource source); +extern bool check_effective_io_concurrency(int *newval, void **extra, + GucSource source); +extern bool check_huge_page_size(int *newval, void **extra, GucSource source); +extern const char *show_in_hot_standby(void); +extern bool check_locale_messages(char **newval, void **extra, GucSource source); +extern void assign_locale_messages(const char *newval, void *extra); +extern bool check_locale_monetary(char **newval, void **extra, GucSource source); +extern void assign_locale_monetary(const char *newval, void *extra); +extern bool check_locale_numeric(char **newval, void **extra, GucSource source); +extern void assign_locale_numeric(const char *newval, void *extra); +extern bool check_locale_time(char **newval, void **extra, GucSource source); +extern void assign_locale_time(const char *newval, void *extra); +extern bool check_log_destination(char **newval, void **extra, + GucSource source); +extern void assign_log_destination(const char *newval, void *extra); +extern const char *show_log_file_mode(void); +extern bool check_log_stats(bool *newval, void **extra, GucSource source); +extern bool check_log_timezone(char **newval, void **extra, GucSource source); +extern void assign_log_timezone(const char *newval, void *extra); +extern const char *show_log_timezone(void); +extern bool check_maintenance_io_concurrency(int *newval, void **extra, + GucSource source); +extern void assign_maintenance_io_concurrency(int newval, void *extra); +extern bool check_max_connections(int *newval, void **extra, GucSource source); +extern bool check_max_wal_senders(int *newval, void **extra, GucSource source); +extern void assign_max_wal_size(int newval, void *extra); +extern bool check_max_worker_processes(int *newval, void **extra, + GucSource source); +extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); +extern void assign_max_stack_depth(int newval, void *extra); +extern bool check_primary_slot_name(char **newval, void **extra, + GucSource source); +extern bool check_random_seed(double *newval, void **extra, GucSource source); +extern void assign_random_seed(double newval, void *extra); +extern const char *show_random_seed(void); +extern bool check_recovery_prefetch(int *new_value, void **extra, + GucSource source); +extern void assign_recovery_prefetch(int new_value, void *extra); +extern bool check_recovery_target(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target(const char *newval, void *extra); +extern bool check_recovery_target_lsn(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_lsn(const char *newval, void *extra); +extern bool check_recovery_target_name(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_name(const char *newval, void *extra); +extern bool check_recovery_target_time(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_time(const char *newval, void *extra); +extern bool check_recovery_target_timeline(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_timeline(const char *newval, void *extra); +extern bool check_recovery_target_xid(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_xid(const char *newval, void *extra); +extern bool check_role(char **newval, void **extra, GucSource source); +extern void assign_role(const char *newval, void *extra); +extern const char *show_role(void); +extern bool check_restrict_nonsystem_relation_kind(char **newval, void **extra, + GucSource source); +extern void assign_restrict_nonsystem_relation_kind(const char *newval, void *extra); +extern bool check_search_path(char **newval, void **extra, GucSource source); +extern void assign_search_path(const char *newval, void *extra); +extern bool check_session_authorization(char **newval, void **extra, GucSource source); +extern void assign_session_authorization(const char *newval, void *extra); +extern void assign_session_replication_role(int newval, void *extra); +extern void assign_stats_fetch_consistency(int newval, void *extra); +extern bool check_ssl(bool *newval, void **extra, GucSource source); +extern bool check_stage_log_stats(bool *newval, void **extra, GucSource source); +extern bool check_synchronous_standby_names(char **newval, void **extra, + GucSource source); +extern void assign_synchronous_standby_names(const char *newval, void *extra); +extern void assign_synchronous_commit(int newval, void *extra); +extern void assign_syslog_facility(int newval, void *extra); +extern void assign_syslog_ident(const char *newval, void *extra); +extern void assign_tcp_keepalives_count(int newval, void *extra); +extern const char *show_tcp_keepalives_count(void); +extern void assign_tcp_keepalives_idle(int newval, void *extra); +extern const char *show_tcp_keepalives_idle(void); +extern void assign_tcp_keepalives_interval(int newval, void *extra); +extern const char *show_tcp_keepalives_interval(void); +extern void assign_tcp_user_timeout(int newval, void *extra); +extern const char *show_tcp_user_timeout(void); +extern bool check_temp_buffers(int *newval, void **extra, GucSource source); +extern bool check_temp_tablespaces(char **newval, void **extra, + GucSource source); +extern void assign_temp_tablespaces(const char *newval, void *extra); +extern bool check_timezone(char **newval, void **extra, GucSource source); +extern void assign_timezone(const char *newval, void *extra); +extern const char *show_timezone(void); +extern bool check_timezone_abbreviations(char **newval, void **extra, + GucSource source); +extern void assign_timezone_abbreviations(const char *newval, void *extra); +extern bool check_transaction_deferrable(bool *newval, void **extra, GucSource source); +extern bool check_transaction_isolation(int *newval, void **extra, GucSource source); +extern bool check_transaction_read_only(bool *newval, void **extra, GucSource source); +extern const char *show_unix_socket_permissions(void); +extern bool check_wal_buffers(int *newval, void **extra, GucSource source); +extern bool check_wal_consistency_checking(char **newval, void **extra, + GucSource source); +extern void assign_wal_consistency_checking(const char *newval, void *extra); +extern void assign_xlog_sync_method(int new_sync_method, void *extra); + +#endif /* GUC_HOOKS_H */ diff --git a/install/include/postgresql/server/utils/guc_tables.h b/install/include/postgresql/server/utils/guc_tables.h new file mode 100644 index 00000000000..ab880cae2c4 --- /dev/null +++ b/install/include/postgresql/server/utils/guc_tables.h @@ -0,0 +1,322 @@ +/*------------------------------------------------------------------------- + * + * guc_tables.h + * Declarations of tables used by GUC. + * + * See src/backend/utils/misc/README for design notes. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/utils/guc_tables.h + * + *------------------------------------------------------------------------- + */ +#ifndef GUC_TABLES_H +#define GUC_TABLES_H 1 + +#include "lib/ilist.h" +#include "utils/guc.h" + +/* + * GUC supports these types of variables: + */ +enum config_type +{ + PGC_BOOL, + PGC_INT, + PGC_REAL, + PGC_STRING, + PGC_ENUM +}; + +union config_var_val +{ + bool boolval; + int intval; + double realval; + char *stringval; + int enumval; +}; + +/* + * The actual value of a GUC variable can include a malloc'd opaque struct + * "extra", which is created by its check_hook and used by its assign_hook. + */ +typedef struct config_var_value +{ + union config_var_val val; + void *extra; +} config_var_value; + +/* + * Groupings to help organize all the run-time options for display. + * Be sure this agrees with the way the options are categorized in config.sgml! + */ +enum config_group +{ + UNGROUPED, /* use for options not shown in pg_settings */ + FILE_LOCATIONS, + CONN_AUTH_SETTINGS, + CONN_AUTH_TCP, + CONN_AUTH_AUTH, + CONN_AUTH_SSL, + RESOURCES_MEM, + RESOURCES_DISK, + RESOURCES_KERNEL, + RESOURCES_VACUUM_DELAY, + RESOURCES_BGWRITER, + RESOURCES_ASYNCHRONOUS, + WAL_SETTINGS, + WAL_CHECKPOINTS, + WAL_ARCHIVING, + WAL_RECOVERY, + WAL_ARCHIVE_RECOVERY, + WAL_RECOVERY_TARGET, + REPLICATION_SENDING, + REPLICATION_PRIMARY, + REPLICATION_STANDBY, + REPLICATION_SUBSCRIBERS, + QUERY_TUNING_METHOD, + QUERY_TUNING_COST, + QUERY_TUNING_GEQO, + QUERY_TUNING_OTHER, + LOGGING_WHERE, + LOGGING_WHEN, + LOGGING_WHAT, + PROCESS_TITLE, + STATS_MONITORING, + STATS_CUMULATIVE, + AUTOVACUUM, + CLIENT_CONN_STATEMENT, + CLIENT_CONN_LOCALE, + CLIENT_CONN_PRELOAD, + CLIENT_CONN_OTHER, + LOCK_MANAGEMENT, + COMPAT_OPTIONS_PREVIOUS, + COMPAT_OPTIONS_CLIENT, + ERROR_HANDLING_OPTIONS, + PRESET_OPTIONS, + CUSTOM_OPTIONS, + DEVELOPER_OPTIONS +}; + +/* + * Stack entry for saving the state a variable had prior to an uncommitted + * transactional change + */ +typedef enum +{ + /* This is almost GucAction, but we need a fourth state for SET+LOCAL */ + GUC_SAVE, /* entry caused by function SET option */ + GUC_SET, /* entry caused by plain SET command */ + GUC_LOCAL, /* entry caused by SET LOCAL command */ + GUC_SET_LOCAL /* entry caused by SET then SET LOCAL */ +} GucStackState; + +typedef struct guc_stack +{ + struct guc_stack *prev; /* previous stack item, if any */ + int nest_level; /* nesting depth at which we made entry */ + GucStackState state; /* see enum above */ + GucSource source; /* source of the prior value */ + /* masked value's source must be PGC_S_SESSION, so no need to store it */ + GucContext scontext; /* context that set the prior value */ + GucContext masked_scontext; /* context that set the masked value */ + Oid srole; /* role that set the prior value */ + Oid masked_srole; /* role that set the masked value */ + config_var_value prior; /* previous value of variable */ + config_var_value masked; /* SET value in a GUC_SET_LOCAL entry */ +} GucStack; + +/* + * Generic fields applicable to all types of variables + * + * The short description should be less than 80 chars in length. Some + * applications may use the long description as well, and will append + * it to the short description. (separated by a newline or '. ') + * + * srole is the role that set the current value, or BOOTSTRAP_SUPERUSERID + * if the value came from an internal source or the config file. Similarly + * for reset_srole (which is usually BOOTSTRAP_SUPERUSERID, but not always). + * + * Variables that are currently of active interest for maintenance + * operations are linked into various lists using the xxx_link fields. + * The link fields are unused/garbage in variables not currently having + * the specified properties. + * + * Note that sourcefile/sourceline are kept here, and not pushed into stacked + * values, although in principle they belong with some stacked value if the + * active value is session- or transaction-local. This is to avoid bloating + * stack entries. We know they are only relevant when source == PGC_S_FILE. + */ +struct config_generic +{ + /* constant fields, must be set correctly in initial value: */ + const char *name; /* name of variable - MUST BE FIRST */ + GucContext context; /* context required to set the variable */ + enum config_group group; /* to help organize variables by function */ + const char *short_desc; /* short desc. of this variable's purpose */ + const char *long_desc; /* long desc. of this variable's purpose */ + int flags; /* flag bits, see guc.h */ + /* variable fields, initialized at runtime: */ + enum config_type vartype; /* type of variable (set only at startup) */ + int status; /* status bits, see below */ + GucSource source; /* source of the current actual value */ + GucSource reset_source; /* source of the reset_value */ + GucContext scontext; /* context that set the current value */ + GucContext reset_scontext; /* context that set the reset value */ + Oid srole; /* role that set the current value */ + Oid reset_srole; /* role that set the reset value */ + GucStack *stack; /* stacked prior values */ + void *extra; /* "extra" pointer for current actual value */ + dlist_node nondef_link; /* list link for variables that have source + * different from PGC_S_DEFAULT */ + slist_node stack_link; /* list link for variables that have non-NULL + * stack */ + slist_node report_link; /* list link for variables that have the + * GUC_NEEDS_REPORT bit set in status */ + char *last_reported; /* if variable is GUC_REPORT, value last sent + * to client (NULL if not yet sent) */ + char *sourcefile; /* file current setting is from (NULL if not + * set in config file) */ + int sourceline; /* line in source file */ +}; + +/* bit values in status field */ +#define GUC_IS_IN_FILE 0x0001 /* found it in config file */ +/* + * Caution: the GUC_IS_IN_FILE bit is transient state for ProcessConfigFile. + * Do not assume that its value represents useful information elsewhere. + */ +#define GUC_PENDING_RESTART 0x0002 /* changed value cannot be applied yet */ +#define GUC_NEEDS_REPORT 0x0004 /* new value must be reported to client */ + + +/* GUC records for specific variable types */ + +struct config_bool +{ + struct config_generic gen; + /* constant fields, must be set correctly in initial value: */ + bool *variable; + bool boot_val; + GucBoolCheckHook check_hook; + GucBoolAssignHook assign_hook; + GucShowHook show_hook; + /* variable fields, initialized at runtime: */ + bool reset_val; + void *reset_extra; +}; + +struct config_int +{ + struct config_generic gen; + /* constant fields, must be set correctly in initial value: */ + int *variable; + int boot_val; + int min; + int max; + GucIntCheckHook check_hook; + GucIntAssignHook assign_hook; + GucShowHook show_hook; + /* variable fields, initialized at runtime: */ + int reset_val; + void *reset_extra; +}; + +struct config_real +{ + struct config_generic gen; + /* constant fields, must be set correctly in initial value: */ + double *variable; + double boot_val; + double min; + double max; + GucRealCheckHook check_hook; + GucRealAssignHook assign_hook; + GucShowHook show_hook; + /* variable fields, initialized at runtime: */ + double reset_val; + void *reset_extra; +}; + +/* + * A note about string GUCs: the boot_val is allowed to be NULL, which leads + * to the reset_val and the actual variable value (*variable) also being NULL. + * However, there is no way to set a NULL value subsequently using + * set_config_option or any other GUC API. Also, GUC APIs such as SHOW will + * display a NULL value as an empty string. Callers that choose to use a NULL + * boot_val should overwrite the setting later in startup, or else be careful + * that NULL doesn't have semantics that are visibly different from an empty + * string. + */ +struct config_string +{ + struct config_generic gen; + /* constant fields, must be set correctly in initial value: */ + char **variable; + const char *boot_val; + GucStringCheckHook check_hook; + GucStringAssignHook assign_hook; + GucShowHook show_hook; + /* variable fields, initialized at runtime: */ + char *reset_val; + void *reset_extra; +}; + +struct config_enum +{ + struct config_generic gen; + /* constant fields, must be set correctly in initial value: */ + int *variable; + int boot_val; + const struct config_enum_entry *options; + GucEnumCheckHook check_hook; + GucEnumAssignHook assign_hook; + GucShowHook show_hook; + /* variable fields, initialized at runtime: */ + int reset_val; + void *reset_extra; +}; + +/* constant tables corresponding to enums above and in guc.h */ +extern PGDLLIMPORT const char *const config_group_names[]; +extern PGDLLIMPORT const char *const config_type_names[]; +extern PGDLLIMPORT const char *const GucContext_Names[]; +extern PGDLLIMPORT const char *const GucSource_Names[]; + +/* data arrays defining all the built-in GUC variables */ +extern PGDLLIMPORT struct config_bool ConfigureNamesBool[]; +extern PGDLLIMPORT struct config_int ConfigureNamesInt[]; +extern PGDLLIMPORT struct config_real ConfigureNamesReal[]; +extern PGDLLIMPORT struct config_string ConfigureNamesString[]; +extern PGDLLIMPORT struct config_enum ConfigureNamesEnum[]; + +/* lookup GUC variables, returning config_generic pointers */ +extern struct config_generic *find_option(const char *name, + bool create_placeholders, + bool skip_errors, + int elevel); +extern struct config_generic **get_explain_guc_options(int *num); + +/* get string value of variable */ +extern char *ShowGUCOption(struct config_generic *record, bool use_units); + +/* get whether or not the GUC variable is visible to current user */ +extern bool ConfigOptionIsVisible(struct config_generic *conf); + +/* get the current set of variables */ +extern struct config_generic **get_guc_variables(int *num_vars); + +extern void build_guc_variables(void); + +/* search in enum options */ +extern const char *config_enum_lookup_by_value(struct config_enum *record, int val); +extern bool config_enum_lookup_by_name(struct config_enum *record, + const char *value, int *retval); +extern char *config_enum_get_options(struct config_enum *record, + const char *prefix, + const char *suffix, + const char *separator); + +#endif /* GUC_TABLES_H */ diff --git a/install/include/postgresql/server/utils/help_config.h b/install/include/postgresql/server/utils/help_config.h new file mode 100644 index 00000000000..e9bc417ca45 --- /dev/null +++ b/install/include/postgresql/server/utils/help_config.h @@ -0,0 +1,17 @@ +/*------------------------------------------------------------------------- + * + * help_config.h + * Interface to the --help-config option of main.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/utils/help_config.h + * + *------------------------------------------------------------------------- + */ +#ifndef HELP_CONFIG_H +#define HELP_CONFIG_H 1 + +extern void GucInfoMain(void) pg_attribute_noreturn(); + +#endif diff --git a/install/include/postgresql/server/utils/hsearch.h b/install/include/postgresql/server/utils/hsearch.h new file mode 100644 index 00000000000..bc3d5efa963 --- /dev/null +++ b/install/include/postgresql/server/utils/hsearch.h @@ -0,0 +1,153 @@ +/*------------------------------------------------------------------------- + * + * hsearch.h + * exported definitions for utils/hash/dynahash.c; see notes therein + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/hsearch.h + * + *------------------------------------------------------------------------- + */ +#ifndef HSEARCH_H +#define HSEARCH_H + + +/* + * Hash functions must have this signature. + */ +typedef uint32 (*HashValueFunc) (const void *key, Size keysize); + +/* + * Key comparison functions must have this signature. Comparison functions + * return zero for match, nonzero for no match. (The comparison function + * definition is designed to allow memcmp() and strncmp() to be used directly + * as key comparison functions.) + */ +typedef int (*HashCompareFunc) (const void *key1, const void *key2, + Size keysize); + +/* + * Key copying functions must have this signature. The return value is not + * used. (The definition is set up to allow memcpy() and strlcpy() to be + * used directly.) + */ +typedef void *(*HashCopyFunc) (void *dest, const void *src, Size keysize); + +/* + * Space allocation function for a hashtable --- designed to match malloc(). + * Note: there is no free function API; can't destroy a hashtable unless you + * use the default allocator. + */ +typedef void *(*HashAllocFunc) (Size request); + +/* + * HASHELEMENT is the private part of a hashtable entry. The caller's data + * follows the HASHELEMENT structure (on a MAXALIGN'd boundary). The hash key + * is expected to be at the start of the caller's hash entry data structure. + */ +typedef struct HASHELEMENT +{ + struct HASHELEMENT *link; /* link to next entry in same bucket */ + uint32 hashvalue; /* hash function result for this entry */ +} HASHELEMENT; + +/* Hash table header struct is an opaque type known only within dynahash.c */ +typedef struct HASHHDR HASHHDR; + +/* Hash table control struct is an opaque type known only within dynahash.c */ +typedef struct HTAB HTAB; + +/* Parameter data structure for hash_create */ +/* Only those fields indicated by hash_flags need be set */ +typedef struct HASHCTL +{ + /* Used if HASH_PARTITION flag is set: */ + long num_partitions; /* # partitions (must be power of 2) */ + /* Used if HASH_SEGMENT flag is set: */ + long ssize; /* segment size */ + /* Used if HASH_DIRSIZE flag is set: */ + long dsize; /* (initial) directory size */ + long max_dsize; /* limit to dsize if dir size is limited */ + /* Used if HASH_ELEM flag is set (which is now required): */ + Size keysize; /* hash key length in bytes */ + Size entrysize; /* total user element size in bytes */ + /* Used if HASH_FUNCTION flag is set: */ + HashValueFunc hash; /* hash function */ + /* Used if HASH_COMPARE flag is set: */ + HashCompareFunc match; /* key comparison function */ + /* Used if HASH_KEYCOPY flag is set: */ + HashCopyFunc keycopy; /* key copying function */ + /* Used if HASH_ALLOC flag is set: */ + HashAllocFunc alloc; /* memory allocator */ + /* Used if HASH_CONTEXT flag is set: */ + MemoryContext hcxt; /* memory context to use for allocations */ + /* Used if HASH_SHARED_MEM flag is set: */ + HASHHDR *hctl; /* location of header in shared mem */ +} HASHCTL; + +/* Flag bits for hash_create; most indicate which parameters are supplied */ +#define HASH_PARTITION 0x0001 /* Hashtable is used w/partitioned locking */ +#define HASH_SEGMENT 0x0002 /* Set segment size */ +#define HASH_DIRSIZE 0x0004 /* Set directory size (initial and max) */ +#define HASH_ELEM 0x0008 /* Set keysize and entrysize (now required!) */ +#define HASH_STRINGS 0x0010 /* Select support functions for string keys */ +#define HASH_BLOBS 0x0020 /* Select support functions for binary keys */ +#define HASH_FUNCTION 0x0040 /* Set user defined hash function */ +#define HASH_COMPARE 0x0080 /* Set user defined comparison function */ +#define HASH_KEYCOPY 0x0100 /* Set user defined key-copying function */ +#define HASH_ALLOC 0x0200 /* Set memory allocator */ +#define HASH_CONTEXT 0x0400 /* Set memory allocation context */ +#define HASH_SHARED_MEM 0x0800 /* Hashtable is in shared memory */ +#define HASH_ATTACH 0x1000 /* Do not initialize hctl */ +#define HASH_FIXED_SIZE 0x2000 /* Initial size is a hard limit */ + +/* max_dsize value to indicate expansible directory */ +#define NO_MAX_DSIZE (-1) + +/* hash_search operations */ +typedef enum +{ + HASH_FIND, + HASH_ENTER, + HASH_REMOVE, + HASH_ENTER_NULL +} HASHACTION; + +/* hash_seq status (should be considered an opaque type by callers) */ +typedef struct +{ + HTAB *hashp; + uint32 curBucket; /* index of current bucket */ + HASHELEMENT *curEntry; /* current entry in bucket */ +} HASH_SEQ_STATUS; + +/* + * prototypes for functions in dynahash.c + */ +extern HTAB *hash_create(const char *tabname, long nelem, + const HASHCTL *info, int flags); +extern void hash_destroy(HTAB *hashp); +extern void hash_stats(const char *where, HTAB *hashp); +extern void *hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, + bool *foundPtr); +extern uint32 get_hash_value(HTAB *hashp, const void *keyPtr); +extern void *hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, + uint32 hashvalue, HASHACTION action, + bool *foundPtr); +extern bool hash_update_hash_key(HTAB *hashp, void *existingEntry, + const void *newKeyPtr); +extern long hash_get_num_entries(HTAB *hashp); +extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp); +extern void *hash_seq_search(HASH_SEQ_STATUS *status); +extern void hash_seq_term(HASH_SEQ_STATUS *status); +extern void hash_freeze(HTAB *hashp); +extern Size hash_estimate_size(long num_entries, Size entrysize); +extern long hash_select_dirsize(long num_entries); +extern Size hash_get_shared_size(HASHCTL *info, int flags); +extern void AtEOXact_HashTables(bool isCommit); +extern void AtEOSubXact_HashTables(bool isCommit, int nestDepth); + +#endif /* HSEARCH_H */ diff --git a/install/include/postgresql/server/utils/index_selfuncs.h b/install/include/postgresql/server/utils/index_selfuncs.h new file mode 100644 index 00000000000..f081a1a326b --- /dev/null +++ b/install/include/postgresql/server/utils/index_selfuncs.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * index_selfuncs.h + * Index cost estimation functions for standard index access methods. + * + * + * Note: this is split out of selfuncs.h mainly to avoid importing all of the + * planner's data structures into the non-planner parts of the index AMs. + * If you make it depend on anything besides access/amapi.h, that's likely + * a mistake. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/index_selfuncs.h + * + *------------------------------------------------------------------------- + */ +#ifndef INDEX_SELFUNCS_H +#define INDEX_SELFUNCS_H + +#include "access/amapi.h" + +/* Functions in selfuncs.c */ +extern void brincostestimate(struct PlannerInfo *root, + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); +extern void btcostestimate(struct PlannerInfo *root, + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); +extern void hashcostestimate(struct PlannerInfo *root, + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); +extern void gistcostestimate(struct PlannerInfo *root, + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); +extern void spgcostestimate(struct PlannerInfo *root, + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); +extern void gincostestimate(struct PlannerInfo *root, + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); + +#endif /* INDEX_SELFUNCS_H */ diff --git a/install/include/postgresql/server/utils/inet.h b/install/include/postgresql/server/utils/inet.h new file mode 100644 index 00000000000..96d9f6a234b --- /dev/null +++ b/install/include/postgresql/server/utils/inet.h @@ -0,0 +1,184 @@ +/*------------------------------------------------------------------------- + * + * inet.h + * Declarations for operations on INET datatypes. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/inet.h + * + *------------------------------------------------------------------------- + */ +#ifndef INET_H +#define INET_H + +#include "fmgr.h" + +/* + * This is the internal storage format for IP addresses + * (both INET and CIDR datatypes): + */ +typedef struct +{ + unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */ + unsigned char bits; /* number of bits in netmask */ + unsigned char ipaddr[16]; /* up to 128 bits of address */ +} inet_struct; + +/* + * We use these values for the "family" field. + * + * Referencing all of the non-AF_INET types to AF_INET lets us work on + * machines which did not have the appropriate address family (like + * inet6 addresses when AF_INET6 wasn't present) but didn't cause a + * dump/reload requirement. Pre-7.4 databases used AF_INET for the family + * type on disk. + */ +#define PGSQL_AF_INET (AF_INET + 0) +#define PGSQL_AF_INET6 (AF_INET + 1) + +/* + * Both INET and CIDR addresses are represented within Postgres as varlena + * objects, ie, there is a varlena header in front of the struct type + * depicted above. This struct depicts what we actually have in memory + * in "uncompressed" cases. Note that since the maximum data size is only + * 18 bytes, INET/CIDR will invariably be stored into tuples using the + * 1-byte-header varlena format. However, we have to be prepared to cope + * with the 4-byte-header format too, because various code may helpfully + * try to "decompress" 1-byte-header datums. + */ +typedef struct +{ + char vl_len_[4]; /* Do not touch this field directly! */ + inet_struct inet_data; +} inet; + +/* + * Access macros. We use VARDATA_ANY so that we can process short-header + * varlena values without detoasting them. This requires a trick: + * VARDATA_ANY assumes the varlena header is already filled in, which is + * not the case when constructing a new value (until SET_INET_VARSIZE is + * called, which we typically can't do till the end). Therefore, we + * always initialize the newly-allocated value to zeroes (using palloc0). + * A zero length word will look like the not-1-byte case to VARDATA_ANY, + * and so we correctly construct an uncompressed value. + * + * Note that ip_addrsize(), ip_maxbits(), and SET_INET_VARSIZE() require + * the family field to be set correctly. + */ +#define ip_family(inetptr) \ + (((inet_struct *) VARDATA_ANY(inetptr))->family) + +#define ip_bits(inetptr) \ + (((inet_struct *) VARDATA_ANY(inetptr))->bits) + +#define ip_addr(inetptr) \ + (((inet_struct *) VARDATA_ANY(inetptr))->ipaddr) + +#define ip_addrsize(inetptr) \ + (ip_family(inetptr) == PGSQL_AF_INET ? 4 : 16) + +#define ip_maxbits(inetptr) \ + (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128) + +#define SET_INET_VARSIZE(dst) \ + SET_VARSIZE(dst, VARHDRSZ + offsetof(inet_struct, ipaddr) + \ + ip_addrsize(dst)) + + +/* + * This is the internal storage format for MAC addresses: + */ +typedef struct macaddr +{ + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; +} macaddr; + +/* + * This is the internal storage format for MAC8 addresses: + */ +typedef struct macaddr8 +{ + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} macaddr8; + +/* + * fmgr interface macros + */ +static inline inet * +DatumGetInetPP(Datum X) +{ + return (inet *) PG_DETOAST_DATUM_PACKED(X); +} + +static inline Datum +InetPGetDatum(const inet *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n)) +#define PG_RETURN_INET_P(x) return InetPGetDatum(x) + +/* obsolescent variants */ +static inline inet * +DatumGetInetP(Datum X) +{ + return (inet *) PG_DETOAST_DATUM(X); +} +#define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n)) + +/* macaddr is a fixed-length pass-by-reference datatype */ +static inline macaddr * +DatumGetMacaddrP(Datum X) +{ + return (macaddr *) DatumGetPointer(X); +} + +static inline Datum +MacaddrPGetDatum(const macaddr *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n)) +#define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x) + +/* macaddr8 is a fixed-length pass-by-reference datatype */ +static inline macaddr8 * +DatumGetMacaddr8P(Datum X) +{ + return (macaddr8 *) DatumGetPointer(X); +} + +static inline Datum +Macaddr8PGetDatum(const macaddr8 *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_MACADDR8_P(n) DatumGetMacaddr8P(PG_GETARG_DATUM(n)) +#define PG_RETURN_MACADDR8_P(x) return Macaddr8PGetDatum(x) + +/* + * Support functions in network.c + */ +extern inet *cidr_set_masklen_internal(const inet *src, int bits); +extern int bitncmp(const unsigned char *l, const unsigned char *r, int n); +extern int bitncommon(const unsigned char *l, const unsigned char *r, int n); + +#endif /* INET_H */ diff --git a/install/include/postgresql/server/utils/inval.h b/install/include/postgresql/server/utils/inval.h new file mode 100644 index 00000000000..ae4eb65bc59 --- /dev/null +++ b/install/include/postgresql/server/utils/inval.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * inval.h + * POSTGRES cache invalidation dispatcher definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/inval.h + * + *------------------------------------------------------------------------- + */ +#ifndef INVAL_H +#define INVAL_H + +#include "access/htup.h" +#include "storage/relfilelocator.h" +#include "utils/relcache.h" + +extern PGDLLIMPORT int debug_discard_caches; + +typedef void (*SyscacheCallbackFunction) (Datum arg, int cacheid, uint32 hashvalue); +typedef void (*RelcacheCallbackFunction) (Datum arg, Oid relid); + + +extern void AcceptInvalidationMessages(void); + +extern void AtEOXact_Inval(bool isCommit); + +extern void PreInplace_Inval(void); +extern void AtInplace_Inval(void); +extern void ForgetInplace_Inval(void); + +extern void AtEOSubXact_Inval(bool isCommit); + +extern void PostPrepare_Inval(void); + +extern void CommandEndInvalidationMessages(void); + +extern void CacheInvalidateHeapTuple(Relation relation, + HeapTuple tuple, + HeapTuple newtuple); +extern void CacheInvalidateHeapTupleInplace(Relation relation, + HeapTuple key_equivalent_tuple); + +extern void CacheInvalidateCatalog(Oid catalogId); + +extern void CacheInvalidateRelcache(Relation relation); + +extern void CacheInvalidateRelcacheAll(void); + +extern void CacheInvalidateRelcacheByTuple(HeapTuple classTuple); + +extern void CacheInvalidateRelcacheByRelid(Oid relid); + +extern void CacheInvalidateSmgr(RelFileLocatorBackend rlocator); + +extern void CacheInvalidateRelmap(Oid databaseId); + +extern void CacheRegisterSyscacheCallback(int cacheid, + SyscacheCallbackFunction func, + Datum arg); + +extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, + Datum arg); + +extern void CallSyscacheCallbacks(int cacheid, uint32 hashvalue); + +extern void InvalidateSystemCaches(void); +extern void InvalidateSystemCachesExtended(bool debug_discard); + +extern void LogLogicalInvalidations(void); +#endif /* INVAL_H */ diff --git a/install/include/postgresql/server/utils/json.h b/install/include/postgresql/server/utils/json.h new file mode 100644 index 00000000000..35a9a5545d8 --- /dev/null +++ b/install/include/postgresql/server/utils/json.h @@ -0,0 +1,31 @@ +/*------------------------------------------------------------------------- + * + * json.h + * Declarations for JSON data type support. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/json.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSON_H +#define JSON_H + +#include "lib/stringinfo.h" + +/* functions in json.c */ +extern void escape_json(StringInfo buf, const char *str); +extern char *JsonEncodeDateTime(char *buf, Datum value, Oid typid, + const int *tzp); +extern bool to_json_is_immutable(Oid typoid); +extern Datum json_build_object_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null, + bool unique_keys); +extern Datum json_build_array_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null); +extern bool json_validate(text *json, bool check_unique_keys, bool throw_error); + +#endif /* JSON_H */ diff --git a/install/include/postgresql/server/utils/jsonb.h b/install/include/postgresql/server/utils/jsonb.h new file mode 100644 index 00000000000..649a1644f24 --- /dev/null +++ b/install/include/postgresql/server/utils/jsonb.h @@ -0,0 +1,439 @@ +/*------------------------------------------------------------------------- + * + * jsonb.h + * Declarations for jsonb data type support. + * + * Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/utils/jsonb.h + * + *------------------------------------------------------------------------- + */ +#ifndef __JSONB_H__ +#define __JSONB_H__ + +#include "lib/stringinfo.h" +#include "utils/array.h" +#include "utils/numeric.h" + +/* Tokens used when sequentially processing a jsonb value */ +typedef enum +{ + WJB_DONE, + WJB_KEY, + WJB_VALUE, + WJB_ELEM, + WJB_BEGIN_ARRAY, + WJB_END_ARRAY, + WJB_BEGIN_OBJECT, + WJB_END_OBJECT +} JsonbIteratorToken; + +/* Strategy numbers for GIN index opclasses */ +#define JsonbContainsStrategyNumber 7 +#define JsonbExistsStrategyNumber 9 +#define JsonbExistsAnyStrategyNumber 10 +#define JsonbExistsAllStrategyNumber 11 +#define JsonbJsonpathExistsStrategyNumber 15 +#define JsonbJsonpathPredicateStrategyNumber 16 + + +/* + * In the standard jsonb_ops GIN opclass for jsonb, we choose to index both + * keys and values. The storage format is text. The first byte of the text + * string distinguishes whether this is a key (always a string), null value, + * boolean value, numeric value, or string value. However, array elements + * that are strings are marked as though they were keys; this imprecision + * supports the definition of the "exists" operator, which treats array + * elements like keys. The remainder of the text string is empty for a null + * value, "t" or "f" for a boolean value, a normalized print representation of + * a numeric value, or the text of a string value. However, if the length of + * this text representation would exceed JGIN_MAXLENGTH bytes, we instead hash + * the text representation and store an 8-hex-digit representation of the + * uint32 hash value, marking the prefix byte with an additional bit to + * distinguish that this has happened. Hashing long strings saves space and + * ensures that we won't overrun the maximum entry length for a GIN index. + * (But JGIN_MAXLENGTH is quite a bit shorter than GIN's limit. It's chosen + * to ensure that the on-disk text datum will have a short varlena header.) + * Note that when any hashed item appears in a query, we must recheck index + * matches against the heap tuple; currently, this costs nothing because we + * must always recheck for other reasons. + */ +#define JGINFLAG_KEY 0x01 /* key (or string array element) */ +#define JGINFLAG_NULL 0x02 /* null value */ +#define JGINFLAG_BOOL 0x03 /* boolean value */ +#define JGINFLAG_NUM 0x04 /* numeric value */ +#define JGINFLAG_STR 0x05 /* string value (if not an array element) */ +#define JGINFLAG_HASHED 0x10 /* OR'd into flag if value was hashed */ +#define JGIN_MAXLENGTH 125 /* max length of text part before hashing */ + +typedef struct JsonbPair JsonbPair; +typedef struct JsonbValue JsonbValue; + +/* + * Jsonbs are varlena objects, so must meet the varlena convention that the + * first int32 of the object contains the total object size in bytes. Be sure + * to use VARSIZE() and SET_VARSIZE() to access it, though! + * + * Jsonb is the on-disk representation, in contrast to the in-memory JsonbValue + * representation. Often, JsonbValues are just shims through which a Jsonb + * buffer is accessed, but they can also be deep copied and passed around. + * + * Jsonb is a tree structure. Each node in the tree consists of a JEntry + * header and a variable-length content (possibly of zero size). The JEntry + * header indicates what kind of a node it is, e.g. a string or an array, + * and provides the length of its variable-length portion. + * + * The JEntry and the content of a node are not stored physically together. + * Instead, the container array or object has an array that holds the JEntrys + * of all the child nodes, followed by their variable-length portions. + * + * The root node is an exception; it has no parent array or object that could + * hold its JEntry. Hence, no JEntry header is stored for the root node. It + * is implicitly known that the root node must be an array or an object, + * so we can get away without the type indicator as long as we can distinguish + * the two. For that purpose, both an array and an object begin with a uint32 + * header field, which contains an JB_FOBJECT or JB_FARRAY flag. When a naked + * scalar value needs to be stored as a Jsonb value, what we actually store is + * an array with one element, with the flags in the array's header field set + * to JB_FSCALAR | JB_FARRAY. + * + * Overall, the Jsonb struct requires 4-bytes alignment. Within the struct, + * the variable-length portion of some node types is aligned to a 4-byte + * boundary, while others are not. When alignment is needed, the padding is + * in the beginning of the node that requires it. For example, if a numeric + * node is stored after a string node, so that the numeric node begins at + * offset 3, the variable-length portion of the numeric node will begin with + * one padding byte so that the actual numeric data is 4-byte aligned. + */ + +/* + * JEntry format. + * + * The least significant 28 bits store either the data length of the entry, + * or its end+1 offset from the start of the variable-length portion of the + * containing object. The next three bits store the type of the entry, and + * the high-order bit tells whether the least significant bits store a length + * or an offset. + * + * The reason for the offset-or-length complication is to compromise between + * access speed and data compressibility. In the initial design each JEntry + * always stored an offset, but this resulted in JEntry arrays with horrible + * compressibility properties, so that TOAST compression of a JSONB did not + * work well. Storing only lengths would greatly improve compressibility, + * but it makes random access into large arrays expensive (O(N) not O(1)). + * So what we do is store an offset in every JB_OFFSET_STRIDE'th JEntry and + * a length in the rest. This results in reasonably compressible data (as + * long as the stride isn't too small). We may have to examine as many as + * JB_OFFSET_STRIDE JEntrys in order to find out the offset or length of any + * given item, but that's still O(1) no matter how large the container is. + * + * We could avoid eating a flag bit for this purpose if we were to store + * the stride in the container header, or if we were willing to treat the + * stride as an unchangeable constant. Neither of those options is very + * attractive though. + */ +typedef uint32 JEntry; + +#define JENTRY_OFFLENMASK 0x0FFFFFFF +#define JENTRY_TYPEMASK 0x70000000 +#define JENTRY_HAS_OFF 0x80000000 + +/* values stored in the type bits */ +#define JENTRY_ISSTRING 0x00000000 +#define JENTRY_ISNUMERIC 0x10000000 +#define JENTRY_ISBOOL_FALSE 0x20000000 +#define JENTRY_ISBOOL_TRUE 0x30000000 +#define JENTRY_ISNULL 0x40000000 +#define JENTRY_ISCONTAINER 0x50000000 /* array or object */ + +/* Access macros. Note possible multiple evaluations */ +#define JBE_OFFLENFLD(je_) ((je_) & JENTRY_OFFLENMASK) +#define JBE_HAS_OFF(je_) (((je_) & JENTRY_HAS_OFF) != 0) +#define JBE_ISSTRING(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISSTRING) +#define JBE_ISNUMERIC(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNUMERIC) +#define JBE_ISCONTAINER(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISCONTAINER) +#define JBE_ISNULL(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNULL) +#define JBE_ISBOOL_TRUE(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_TRUE) +#define JBE_ISBOOL_FALSE(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_FALSE) +#define JBE_ISBOOL(je_) (JBE_ISBOOL_TRUE(je_) || JBE_ISBOOL_FALSE(je_)) + +/* Macro for advancing an offset variable to the next JEntry */ +#define JBE_ADVANCE_OFFSET(offset, je) \ + do { \ + JEntry je_ = (je); \ + if (JBE_HAS_OFF(je_)) \ + (offset) = JBE_OFFLENFLD(je_); \ + else \ + (offset) += JBE_OFFLENFLD(je_); \ + } while(0) + +/* + * We store an offset, not a length, every JB_OFFSET_STRIDE children. + * Caution: this macro should only be referenced when creating a JSONB + * value. When examining an existing value, pay attention to the HAS_OFF + * bits instead. This allows changes in the offset-placement heuristic + * without breaking on-disk compatibility. + */ +#define JB_OFFSET_STRIDE 32 + +/* + * A jsonb array or object node, within a Jsonb Datum. + * + * An array has one child for each element, stored in array order. + * + * An object has two children for each key/value pair. The keys all appear + * first, in key sort order; then the values appear, in an order matching the + * key order. This arrangement keeps the keys compact in memory, making a + * search for a particular key more cache-friendly. + */ +typedef struct JsonbContainer +{ + uint32 header; /* number of elements or key/value pairs, and + * flags */ + JEntry children[FLEXIBLE_ARRAY_MEMBER]; + + /* the data for each child node follows. */ +} JsonbContainer; + +/* flags for the header-field in JsonbContainer */ +#define JB_CMASK 0x0FFFFFFF /* mask for count field */ +#define JB_FSCALAR 0x10000000 /* flag bits */ +#define JB_FOBJECT 0x20000000 +#define JB_FARRAY 0x40000000 + +/* convenience macros for accessing a JsonbContainer struct */ +#define JsonContainerSize(jc) ((jc)->header & JB_CMASK) +#define JsonContainerIsScalar(jc) (((jc)->header & JB_FSCALAR) != 0) +#define JsonContainerIsObject(jc) (((jc)->header & JB_FOBJECT) != 0) +#define JsonContainerIsArray(jc) (((jc)->header & JB_FARRAY) != 0) + +/* The top-level on-disk format for a jsonb datum. */ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + JsonbContainer root; +} Jsonb; + +/* convenience macros for accessing the root container in a Jsonb datum */ +#define JB_ROOT_COUNT(jbp_) (*(uint32 *) VARDATA(jbp_) & JB_CMASK) +#define JB_ROOT_IS_SCALAR(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FSCALAR) != 0) +#define JB_ROOT_IS_OBJECT(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FOBJECT) != 0) +#define JB_ROOT_IS_ARRAY(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FARRAY) != 0) + + +enum jbvType +{ + /* Scalar types */ + jbvNull = 0x0, + jbvString, + jbvNumeric, + jbvBool, + /* Composite types */ + jbvArray = 0x10, + jbvObject, + /* Binary (i.e. struct Jsonb) jbvArray/jbvObject */ + jbvBinary, + + /* + * Virtual types. + * + * These types are used only for in-memory JSON processing and serialized + * into JSON strings when outputted to json/jsonb. + */ + jbvDatetime = 0x20, +}; + +/* + * JsonbValue: In-memory representation of Jsonb. This is a convenient + * deserialized representation, that can easily support using the "val" + * union across underlying types during manipulation. The Jsonb on-disk + * representation has various alignment considerations. + */ +struct JsonbValue +{ + enum jbvType type; /* Influences sort order */ + + union + { + Numeric numeric; + bool boolean; + struct + { + int len; + char *val; /* Not necessarily null-terminated */ + } string; /* String primitive type */ + + struct + { + int nElems; + JsonbValue *elems; + bool rawScalar; /* Top-level "raw scalar" array? */ + } array; /* Array container type */ + + struct + { + int nPairs; /* 1 pair, 2 elements */ + JsonbPair *pairs; + } object; /* Associative container type */ + + struct + { + int len; + JsonbContainer *data; + } binary; /* Array or object, in on-disk format */ + + struct + { + Datum value; + Oid typid; + int32 typmod; + int tz; /* Numeric time zone, in seconds, for + * TimestampTz data type */ + } datetime; + } val; +}; + +#define IsAJsonbScalar(jsonbval) (((jsonbval)->type >= jbvNull && \ + (jsonbval)->type <= jbvBool) || \ + (jsonbval)->type == jbvDatetime) + +/* + * Key/value pair within an Object. + * + * This struct type is only used briefly while constructing a Jsonb; it is + * *not* the on-disk representation. + * + * Pairs with duplicate keys are de-duplicated. We store the originally + * observed pair ordering for the purpose of removing duplicates in a + * well-defined way (which is "last observed wins"). + */ +struct JsonbPair +{ + JsonbValue key; /* Must be a jbvString */ + JsonbValue value; /* May be of any type */ + uint32 order; /* Pair's index in original sequence */ +}; + +/* Conversion state used when parsing Jsonb from text, or for type coercion */ +typedef struct JsonbParseState +{ + JsonbValue contVal; + Size size; + struct JsonbParseState *next; + bool unique_keys; /* Check object key uniqueness */ + bool skip_nulls; /* Skip null object fields */ +} JsonbParseState; + +/* + * JsonbIterator holds details of the type for each iteration. It also stores a + * Jsonb varlena buffer, which can be directly accessed in some contexts. + */ +typedef enum +{ + JBI_ARRAY_START, + JBI_ARRAY_ELEM, + JBI_OBJECT_START, + JBI_OBJECT_KEY, + JBI_OBJECT_VALUE +} JsonbIterState; + +typedef struct JsonbIterator +{ + /* Container being iterated */ + JsonbContainer *container; + uint32 nElems; /* Number of elements in children array (will + * be nPairs for objects) */ + bool isScalar; /* Pseudo-array scalar value? */ + JEntry *children; /* JEntrys for child nodes */ + /* Data proper. This points to the beginning of the variable-length data */ + char *dataProper; + + /* Current item in buffer (up to nElems) */ + int curIndex; + + /* Data offset corresponding to current item */ + uint32 curDataOffset; + + /* + * If the container is an object, we want to return keys and values + * alternately; so curDataOffset points to the current key, and + * curValueOffset points to the current value. + */ + uint32 curValueOffset; + + /* Private state */ + JsonbIterState state; + + struct JsonbIterator *parent; +} JsonbIterator; + + +/* Convenience macros */ +static inline Jsonb * +DatumGetJsonbP(Datum d) +{ + return (Jsonb *) PG_DETOAST_DATUM(d); +} + +static inline Jsonb * +DatumGetJsonbPCopy(Datum d) +{ + return (Jsonb *) PG_DETOAST_DATUM_COPY(d); +} + +static inline Datum +JsonbPGetDatum(const Jsonb *p) +{ + return PointerGetDatum(p); +} + +#define PG_GETARG_JSONB_P(x) DatumGetJsonbP(PG_GETARG_DATUM(x)) +#define PG_GETARG_JSONB_P_COPY(x) DatumGetJsonbPCopy(PG_GETARG_DATUM(x)) +#define PG_RETURN_JSONB_P(x) PG_RETURN_POINTER(x) + +/* Support functions */ +extern uint32 getJsonbOffset(const JsonbContainer *jc, int index); +extern uint32 getJsonbLength(const JsonbContainer *jc, int index); +extern int compareJsonbContainers(JsonbContainer *a, JsonbContainer *b); +extern JsonbValue *findJsonbValueFromContainer(JsonbContainer *container, + uint32 flags, + JsonbValue *key); +extern JsonbValue *getKeyJsonValueFromContainer(JsonbContainer *container, + const char *keyVal, int keyLen, + JsonbValue *res); +extern JsonbValue *getIthJsonbValueFromContainer(JsonbContainer *container, + uint32 i); +extern JsonbValue *pushJsonbValue(JsonbParseState **pstate, + JsonbIteratorToken seq, JsonbValue *jbval); +extern JsonbIterator *JsonbIteratorInit(JsonbContainer *container); +extern JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, + bool skipNested); +extern void JsonbToJsonbValue(Jsonb *jsonb, JsonbValue *val); +extern Jsonb *JsonbValueToJsonb(JsonbValue *val); +extern bool JsonbDeepContains(JsonbIterator **val, + JsonbIterator **mContained); +extern void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash); +extern void JsonbHashScalarValueExtended(const JsonbValue *scalarVal, + uint64 *hash, uint64 seed); + +/* jsonb.c support functions */ +extern char *JsonbToCString(StringInfo out, JsonbContainer *in, + int estimated_len); +extern char *JsonbToCStringIndent(StringInfo out, JsonbContainer *in, + int estimated_len); +extern bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res); +extern const char *JsonbTypeName(JsonbValue *val); + +extern Datum jsonb_set_element(Jsonb *jb, Datum *path, int path_len, + JsonbValue *newval); +extern Datum jsonb_get_element(Jsonb *jb, Datum *path, int npath, + bool *isnull, bool as_text); +extern bool to_jsonb_is_immutable(Oid typoid); +extern Datum jsonb_build_object_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null, + bool unique_keys); +extern Datum jsonb_build_array_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null); + +#endif /* __JSONB_H__ */ diff --git a/install/include/postgresql/server/utils/jsonfuncs.h b/install/include/postgresql/server/utils/jsonfuncs.h new file mode 100644 index 00000000000..a85203d4a4b --- /dev/null +++ b/install/include/postgresql/server/utils/jsonfuncs.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------- + * + * jsonfuncs.h + * Functions to process JSON data types. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/jsonfuncs.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSONFUNCS_H +#define JSONFUNCS_H + +#include "common/jsonapi.h" +#include "utils/jsonb.h" + +/* + * Flag types for iterate_json(b)_values to specify what elements from a + * json(b) document we want to iterate. + */ +typedef enum JsonToIndex +{ + jtiKey = 0x01, + jtiString = 0x02, + jtiNumeric = 0x04, + jtiBool = 0x08, + jtiAll = jtiKey | jtiString | jtiNumeric | jtiBool +} JsonToIndex; + +/* an action that will be applied to each value in iterate_json(b)_values functions */ +typedef void (*JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len); + +/* an action that will be applied to each value in transform_json(b)_values functions */ +typedef text *(*JsonTransformStringValuesAction) (void *state, char *elem_value, int elem_len); + +/* build a JsonLexContext from a text datum */ +extern JsonLexContext *makeJsonLexContext(text *json, bool need_escapes); + +/* try to parse json, and errsave(escontext) on failure */ +extern bool pg_parse_json_or_errsave(JsonLexContext *lex, JsonSemAction *sem, + struct Node *escontext); + +#define pg_parse_json_or_ereport(lex, sem) \ + (void) pg_parse_json_or_errsave(lex, sem, NULL) + +/* save an error during json lexing or parsing */ +extern void json_errsave_error(JsonParseErrorType error, JsonLexContext *lex, + struct Node *escontext); + +/* get first JSON token */ +extern JsonTokenType json_get_first_token(text *json, bool throw_error); + +extern uint32 parse_jsonb_index_flags(Jsonb *jb); +extern void iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state, + JsonIterateStringValuesAction action); +extern void iterate_json_values(text *json, uint32 flags, void *action_state, + JsonIterateStringValuesAction action); +extern Jsonb *transform_jsonb_string_values(Jsonb *jsonb, void *action_state, + JsonTransformStringValuesAction transform_action); +extern text *transform_json_string_values(text *json, void *action_state, + JsonTransformStringValuesAction transform_action); + +#endif diff --git a/install/include/postgresql/server/utils/jsonpath.h b/install/include/postgresql/server/utils/jsonpath.h new file mode 100644 index 00000000000..f0181e045f7 --- /dev/null +++ b/install/include/postgresql/server/utils/jsonpath.h @@ -0,0 +1,264 @@ +/*------------------------------------------------------------------------- + * + * jsonpath.h + * Definitions for jsonpath datatype + * + * Copyright (c) 2019-2023, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/utils/jsonpath.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSONPATH_H +#define JSONPATH_H + +#include "fmgr.h" +#include "nodes/pg_list.h" +#include "utils/jsonb.h" + +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + uint32 header; /* version and flags (see below) */ + char data[FLEXIBLE_ARRAY_MEMBER]; +} JsonPath; + +#define JSONPATH_VERSION (0x01) +#define JSONPATH_LAX (0x80000000) +#define JSONPATH_HDRSZ (offsetof(JsonPath, data)) + +static inline JsonPath * +DatumGetJsonPathP(Datum d) +{ + return (JsonPath *) PG_DETOAST_DATUM(d); +} + +static inline JsonPath * +DatumGetJsonPathPCopy(Datum d) +{ + return (JsonPath *) PG_DETOAST_DATUM_COPY(d); +} + +#define PG_GETARG_JSONPATH_P(x) DatumGetJsonPathP(PG_GETARG_DATUM(x)) +#define PG_GETARG_JSONPATH_P_COPY(x) DatumGetJsonPathPCopy(PG_GETARG_DATUM(x)) +#define PG_RETURN_JSONPATH_P(p) PG_RETURN_POINTER(p) + +#define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool) + +/* + * All node's type of jsonpath expression + */ +typedef enum JsonPathItemType +{ + jpiNull = jbvNull, /* NULL literal */ + jpiString = jbvString, /* string literal */ + jpiNumeric = jbvNumeric, /* numeric literal */ + jpiBool = jbvBool, /* boolean literal: TRUE or FALSE */ + jpiAnd, /* predicate && predicate */ + jpiOr, /* predicate || predicate */ + jpiNot, /* ! predicate */ + jpiIsUnknown, /* (predicate) IS UNKNOWN */ + jpiEqual, /* expr == expr */ + jpiNotEqual, /* expr != expr */ + jpiLess, /* expr < expr */ + jpiGreater, /* expr > expr */ + jpiLessOrEqual, /* expr <= expr */ + jpiGreaterOrEqual, /* expr >= expr */ + jpiAdd, /* expr + expr */ + jpiSub, /* expr - expr */ + jpiMul, /* expr * expr */ + jpiDiv, /* expr / expr */ + jpiMod, /* expr % expr */ + jpiPlus, /* + expr */ + jpiMinus, /* - expr */ + jpiAnyArray, /* [*] */ + jpiAnyKey, /* .* */ + jpiIndexArray, /* [subscript, ...] */ + jpiAny, /* .** */ + jpiKey, /* .key */ + jpiCurrent, /* @ */ + jpiRoot, /* $ */ + jpiVariable, /* $variable */ + jpiFilter, /* ? (predicate) */ + jpiExists, /* EXISTS (expr) predicate */ + jpiType, /* .type() item method */ + jpiSize, /* .size() item method */ + jpiAbs, /* .abs() item method */ + jpiFloor, /* .floor() item method */ + jpiCeiling, /* .ceiling() item method */ + jpiDouble, /* .double() item method */ + jpiDatetime, /* .datetime() item method */ + jpiKeyValue, /* .keyvalue() item method */ + jpiSubscript, /* array subscript: 'expr' or 'expr TO expr' */ + jpiLast, /* LAST array subscript */ + jpiStartsWith, /* STARTS WITH predicate */ + jpiLikeRegex, /* LIKE_REGEX predicate */ +} JsonPathItemType; + +/* XQuery regex mode flags for LIKE_REGEX predicate */ +#define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */ +#define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */ +#define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */ +#define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */ +#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */ + +/* + * Support functions to parse/construct binary value. + * Unlike many other representation of expression the first/main + * node is not an operation but left operand of expression. That + * allows to implement cheap follow-path descending in jsonb + * structure and then execute operator with right operand + */ + +typedef struct JsonPathItem +{ + JsonPathItemType type; + + /* position form base to next node */ + int32 nextPos; + + /* + * pointer into JsonPath value to current node, all positions of current + * are relative to this base + */ + char *base; + + union + { + /* classic operator with two operands: and, or etc */ + struct + { + int32 left; + int32 right; + } args; + + /* any unary operation */ + int32 arg; + + /* storage for jpiIndexArray: indexes of array */ + struct + { + int32 nelems; + struct + { + int32 from; + int32 to; + } *elems; + } array; + + /* jpiAny: levels */ + struct + { + uint32 first; + uint32 last; + } anybounds; + + struct + { + char *data; /* for bool, numeric and string/key */ + int32 datalen; /* filled only for string/key */ + } value; + + struct + { + int32 expr; + char *pattern; + int32 patternlen; + uint32 flags; + } like_regex; + } content; +} JsonPathItem; + +#define jspHasNext(jsp) ((jsp)->nextPos > 0) + +extern void jspInit(JsonPathItem *v, JsonPath *js); +extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos); +extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a); +extern void jspGetArg(JsonPathItem *v, JsonPathItem *a); +extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a); +extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a); +extern Numeric jspGetNumeric(JsonPathItem *v); +extern bool jspGetBool(JsonPathItem *v); +extern char *jspGetString(JsonPathItem *v, int32 *len); +extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, + JsonPathItem *to, int i); + +extern const char *jspOperationName(JsonPathItemType type); + +/* + * Parsing support data structures. + */ + +typedef struct JsonPathParseItem JsonPathParseItem; + +struct JsonPathParseItem +{ + JsonPathItemType type; + JsonPathParseItem *next; /* next in path */ + + union + { + + /* classic operator with two operands: and, or etc */ + struct + { + JsonPathParseItem *left; + JsonPathParseItem *right; + } args; + + /* any unary operation */ + JsonPathParseItem *arg; + + /* storage for jpiIndexArray: indexes of array */ + struct + { + int nelems; + struct + { + JsonPathParseItem *from; + JsonPathParseItem *to; + } *elems; + } array; + + /* jpiAny: levels */ + struct + { + uint32 first; + uint32 last; + } anybounds; + + struct + { + JsonPathParseItem *expr; + char *pattern; /* could not be not null-terminated */ + uint32 patternlen; + uint32 flags; + } like_regex; + + /* scalars */ + Numeric numeric; + bool boolean; + struct + { + uint32 len; + char *val; /* could not be not null-terminated */ + } string; + } value; +}; + +typedef struct JsonPathParseResult +{ + JsonPathParseItem *expr; + bool lax; +} JsonPathParseResult; + +extern JsonPathParseResult *parsejsonpath(const char *str, int len, + struct Node *escontext); + +extern bool jspConvertRegexFlags(uint32 xflags, int *result, + struct Node *escontext); + + +#endif diff --git a/install/include/postgresql/server/utils/logtape.h b/install/include/postgresql/server/utils/logtape.h new file mode 100644 index 00000000000..5420a24ac9b --- /dev/null +++ b/install/include/postgresql/server/utils/logtape.h @@ -0,0 +1,77 @@ +/*------------------------------------------------------------------------- + * + * logtape.h + * Management of "logical tapes" within temporary files. + * + * See logtape.c for explanations. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/logtape.h + * + *------------------------------------------------------------------------- + */ + +#ifndef LOGTAPE_H +#define LOGTAPE_H + +#include "storage/sharedfileset.h" + +/* + * LogicalTapeSet and LogicalTape are opaque types whose details are not + * known outside logtape.c. + */ +typedef struct LogicalTapeSet LogicalTapeSet; +typedef struct LogicalTape LogicalTape; + + +/* + * The approach tuplesort.c takes to parallel external sorts is that workers, + * whose state is almost the same as independent serial sorts, are made to + * produce a final materialized tape of sorted output in all cases. This is + * frozen, just like any case requiring a final materialized tape. However, + * there is one difference, which is that freezing will also export an + * underlying shared fileset BufFile for sharing. Freezing produces TapeShare + * metadata for the worker when this happens, which is passed along through + * shared memory to leader. + * + * The leader process can then pass an array of TapeShare metadata (one per + * worker participant) to LogicalTapeSetCreate(), alongside a handle to a + * shared fileset, which is sufficient to construct a new logical tapeset that + * consists of each of the tapes materialized by workers. + * + * Note that while logtape.c does create an empty leader tape at the end of the + * tapeset in the leader case, it can never be written to due to a restriction + * in the shared buffile infrastructure. + */ +typedef struct TapeShare +{ + /* + * Currently, all the leader process needs is the location of the + * materialized tape's first block. + */ + long firstblocknumber; +} TapeShare; + +/* + * prototypes for functions in logtape.c + */ + +extern LogicalTapeSet *LogicalTapeSetCreate(bool preallocate, + SharedFileSet *fileset, int worker); +extern void LogicalTapeClose(LogicalTape *lt); +extern void LogicalTapeSetClose(LogicalTapeSet *lts); +extern LogicalTape *LogicalTapeCreate(LogicalTapeSet *lts); +extern LogicalTape *LogicalTapeImport(LogicalTapeSet *lts, int worker, TapeShare *shared); +extern void LogicalTapeSetForgetFreeSpace(LogicalTapeSet *lts); +extern size_t LogicalTapeRead(LogicalTape *lt, void *ptr, size_t size); +extern void LogicalTapeWrite(LogicalTape *lt, const void *ptr, size_t size); +extern void LogicalTapeRewindForRead(LogicalTape *lt, size_t buffer_size); +extern void LogicalTapeFreeze(LogicalTape *lt, TapeShare *share); +extern size_t LogicalTapeBackspace(LogicalTape *lt, size_t size); +extern void LogicalTapeSeek(LogicalTape *lt, long blocknum, int offset); +extern void LogicalTapeTell(LogicalTape *lt, long *blocknum, int *offset); +extern long LogicalTapeSetBlocks(LogicalTapeSet *lts); + +#endif /* LOGTAPE_H */ diff --git a/install/include/postgresql/server/utils/lsyscache.h b/install/include/postgresql/server/utils/lsyscache.h new file mode 100644 index 00000000000..4f5418b9728 --- /dev/null +++ b/install/include/postgresql/server/utils/lsyscache.h @@ -0,0 +1,212 @@ +/*------------------------------------------------------------------------- + * + * lsyscache.h + * Convenience routines for common queries in the system catalog cache. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/lsyscache.h + * + *------------------------------------------------------------------------- + */ +#ifndef LSYSCACHE_H +#define LSYSCACHE_H + +#include "access/attnum.h" +#include "access/htup.h" +#include "nodes/pg_list.h" + +/* avoid including subscripting.h here */ +struct SubscriptRoutines; + +/* Result list element for get_op_btree_interpretation */ +typedef struct OpBtreeInterpretation +{ + Oid opfamily_id; /* btree opfamily containing operator */ + int strategy; /* its strategy number */ + Oid oplefttype; /* declared left input datatype */ + Oid oprighttype; /* declared right input datatype */ +} OpBtreeInterpretation; + +/* I/O function selector for get_type_io_data */ +typedef enum IOFuncSelector +{ + IOFunc_input, + IOFunc_output, + IOFunc_receive, + IOFunc_send +} IOFuncSelector; + +/* Flag bits for get_attstatsslot */ +#define ATTSTATSSLOT_VALUES 0x01 +#define ATTSTATSSLOT_NUMBERS 0x02 + +/* Result struct for get_attstatsslot */ +typedef struct AttStatsSlot +{ + /* Always filled: */ + Oid staop; /* Actual staop for the found slot */ + Oid stacoll; /* Actual collation for the found slot */ + /* Filled if ATTSTATSSLOT_VALUES is specified: */ + Oid valuetype; /* Actual datatype of the values */ + Datum *values; /* slot's "values" array, or NULL if none */ + int nvalues; /* length of values[], or 0 */ + /* Filled if ATTSTATSSLOT_NUMBERS is specified: */ + float4 *numbers; /* slot's "numbers" array, or NULL if none */ + int nnumbers; /* length of numbers[], or 0 */ + + /* Remaining fields are private to get_attstatsslot/free_attstatsslot */ + void *values_arr; /* palloc'd values array, if any */ + void *numbers_arr; /* palloc'd numbers array, if any */ +} AttStatsSlot; + +/* Hook for plugins to get control in get_attavgwidth() */ +typedef int32 (*get_attavgwidth_hook_type) (Oid relid, AttrNumber attnum); +extern PGDLLIMPORT get_attavgwidth_hook_type get_attavgwidth_hook; + +extern bool op_in_opfamily(Oid opno, Oid opfamily); +extern int get_op_opfamily_strategy(Oid opno, Oid opfamily); +extern Oid get_op_opfamily_sortfamily(Oid opno, Oid opfamily); +extern void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, + int *strategy, + Oid *lefttype, + Oid *righttype); +extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, + int16 strategy); +extern bool get_ordering_op_properties(Oid opno, + Oid *opfamily, Oid *opcintype, int16 *strategy); +extern Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse); +extern Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type); +extern List *get_mergejoin_opfamilies(Oid opno); +extern bool get_compatible_hash_operators(Oid opno, + Oid *lhs_opno, Oid *rhs_opno); +extern bool get_op_hash_functions(Oid opno, + RegProcedure *lhs_procno, RegProcedure *rhs_procno); +extern List *get_op_btree_interpretation(Oid opno); +extern bool equality_ops_are_compatible(Oid opno1, Oid opno2); +extern bool comparison_ops_are_compatible(Oid opno1, Oid opno2); +extern Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, + int16 procnum); +extern char *get_attname(Oid relid, AttrNumber attnum, bool missing_ok); +extern AttrNumber get_attnum(Oid relid, const char *attname); +extern int get_attstattarget(Oid relid, AttrNumber attnum); +extern char get_attgenerated(Oid relid, AttrNumber attnum); +extern Oid get_atttype(Oid relid, AttrNumber attnum); +extern void get_atttypetypmodcoll(Oid relid, AttrNumber attnum, + Oid *typid, int32 *typmod, Oid *collid); +extern Datum get_attoptions(Oid relid, int16 attnum); +extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok); +extern char *get_collation_name(Oid colloid); +extern bool get_collation_isdeterministic(Oid colloid); +extern char *get_constraint_name(Oid conoid); +extern Oid get_constraint_index(Oid conoid); +extern char *get_language_name(Oid langoid, bool missing_ok); +extern Oid get_opclass_family(Oid opclass); +extern Oid get_opclass_input_type(Oid opclass); +extern bool get_opclass_opfamily_and_input_type(Oid opclass, + Oid *opfamily, Oid *opcintype); +extern RegProcedure get_opcode(Oid opno); +extern char *get_opname(Oid opno); +extern Oid get_op_rettype(Oid opno); +extern void op_input_types(Oid opno, Oid *lefttype, Oid *righttype); +extern bool op_mergejoinable(Oid opno, Oid inputtype); +extern bool op_hashjoinable(Oid opno, Oid inputtype); +extern bool op_strict(Oid opno); +extern char op_volatile(Oid opno); +extern Oid get_commutator(Oid opno); +extern Oid get_negator(Oid opno); +extern RegProcedure get_oprrest(Oid opno); +extern RegProcedure get_oprjoin(Oid opno); +extern char *get_func_name(Oid funcid); +extern Oid get_func_namespace(Oid funcid); +extern Oid get_func_rettype(Oid funcid); +extern int get_func_nargs(Oid funcid); +extern Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs); +extern Oid get_func_variadictype(Oid funcid); +extern bool get_func_retset(Oid funcid); +extern bool func_strict(Oid funcid); +extern char func_volatile(Oid funcid); +extern char func_parallel(Oid funcid); +extern char get_func_prokind(Oid funcid); +extern bool get_func_leakproof(Oid funcid); +extern RegProcedure get_func_support(Oid funcid); +extern Oid get_relname_relid(const char *relname, Oid relnamespace); +extern char *get_rel_name(Oid relid); +extern Oid get_rel_namespace(Oid relid); +extern Oid get_rel_type_id(Oid relid); +extern char get_rel_relkind(Oid relid); +extern bool get_rel_relispartition(Oid relid); +extern Oid get_rel_tablespace(Oid relid); +extern char get_rel_persistence(Oid relid); +extern Oid get_transform_fromsql(Oid typid, Oid langid, List *trftypes); +extern Oid get_transform_tosql(Oid typid, Oid langid, List *trftypes); +extern bool get_typisdefined(Oid typid); +extern int16 get_typlen(Oid typid); +extern bool get_typbyval(Oid typid); +extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval); +extern void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, + char *typalign); +extern Oid getTypeIOParam(HeapTuple typeTuple); +extern void get_type_io_data(Oid typid, + IOFuncSelector which_func, + int16 *typlen, + bool *typbyval, + char *typalign, + char *typdelim, + Oid *typioparam, + Oid *func); +extern char get_typstorage(Oid typid); +extern Node *get_typdefault(Oid typid); +extern char get_typtype(Oid typid); +extern bool type_is_rowtype(Oid typid); +extern bool type_is_enum(Oid typid); +extern bool type_is_range(Oid typid); +extern bool type_is_multirange(Oid typid); +extern void get_type_category_preferred(Oid typid, + char *typcategory, + bool *typispreferred); +extern Oid get_typ_typrelid(Oid typid); +extern Oid get_element_type(Oid typid); +extern Oid get_array_type(Oid typid); +extern Oid get_promoted_array_type(Oid typid); +extern Oid get_base_element_type(Oid typid); +extern void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam); +extern void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena); +extern void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam); +extern void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena); +extern Oid get_typmodin(Oid typid); +extern Oid get_typcollation(Oid typid); +extern bool type_is_collatable(Oid typid); +extern RegProcedure get_typsubscript(Oid typid, Oid *typelemp); +extern const struct SubscriptRoutines *getSubscriptingRoutines(Oid typid, + Oid *typelemp); +extern Oid getBaseType(Oid typid); +extern Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod); +extern int32 get_typavgwidth(Oid typid, int32 typmod); +extern int32 get_attavgwidth(Oid relid, AttrNumber attnum); +extern bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, + int reqkind, Oid reqop, int flags); +extern void free_attstatsslot(AttStatsSlot *sslot); +extern char *get_namespace_name(Oid nspid); +extern char *get_namespace_name_or_temp(Oid nspid); +extern Oid get_range_subtype(Oid rangeOid); +extern Oid get_range_collation(Oid rangeOid); +extern Oid get_range_multirange(Oid rangeOid); +extern Oid get_multirange_range(Oid multirangeOid); +extern Oid get_index_column_opclass(Oid index_oid, int attno); +extern bool get_index_isreplident(Oid index_oid); +extern bool get_index_isvalid(Oid index_oid); +extern bool get_index_isclustered(Oid index_oid); +extern Oid get_publication_oid(const char *pubname, bool missing_ok); +extern char *get_publication_name(Oid pubid, bool missing_ok); +extern Oid get_subscription_oid(const char *subname, bool missing_ok); +extern char *get_subscription_name(Oid subid, bool missing_ok); + +#define type_is_array(typid) (get_element_type(typid) != InvalidOid) +/* type_is_array_domain accepts both plain arrays and domains over arrays */ +#define type_is_array_domain(typid) (get_base_element_type(typid) != InvalidOid) + +#define TypeIsToastable(typid) (get_typstorage(typid) != TYPSTORAGE_PLAIN) + +#endif /* LSYSCACHE_H */ diff --git a/install/include/postgresql/server/utils/memdebug.h b/install/include/postgresql/server/utils/memdebug.h new file mode 100644 index 00000000000..804ed1fbc07 --- /dev/null +++ b/install/include/postgresql/server/utils/memdebug.h @@ -0,0 +1,82 @@ +/*------------------------------------------------------------------------- + * + * memdebug.h + * Memory debugging support. + * + * Currently, this file either wraps or substitutes + * empty definitions for Valgrind client request macros we use. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/memdebug.h + * + *------------------------------------------------------------------------- + */ +#ifndef MEMDEBUG_H +#define MEMDEBUG_H + +#ifdef USE_VALGRIND +#include +#else +#define VALGRIND_CHECK_MEM_IS_DEFINED(addr, size) do {} while (0) +#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed) do {} while (0) +#define VALGRIND_DESTROY_MEMPOOL(context) do {} while (0) +#define VALGRIND_MAKE_MEM_DEFINED(addr, size) do {} while (0) +#define VALGRIND_MAKE_MEM_NOACCESS(addr, size) do {} while (0) +#define VALGRIND_MAKE_MEM_UNDEFINED(addr, size) do {} while (0) +#define VALGRIND_MEMPOOL_ALLOC(context, addr, size) do {} while (0) +#define VALGRIND_MEMPOOL_FREE(context, addr) do {} while (0) +#define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size) do {} while (0) +#endif + + +#ifdef CLOBBER_FREED_MEMORY + +/* Wipe freed memory for debugging purposes */ +static inline void +wipe_mem(void *ptr, size_t size) +{ + VALGRIND_MAKE_MEM_UNDEFINED(ptr, size); + memset(ptr, 0x7F, size); + VALGRIND_MAKE_MEM_NOACCESS(ptr, size); +} + +#endif /* CLOBBER_FREED_MEMORY */ + +#ifdef MEMORY_CONTEXT_CHECKING + +static inline void +set_sentinel(void *base, Size offset) +{ + char *ptr = (char *) base + offset; + + VALGRIND_MAKE_MEM_UNDEFINED(ptr, 1); + *ptr = 0x7E; + VALGRIND_MAKE_MEM_NOACCESS(ptr, 1); +} + +static inline bool +sentinel_ok(const void *base, Size offset) +{ + const char *ptr = (const char *) base + offset; + bool ret; + + VALGRIND_MAKE_MEM_DEFINED(ptr, 1); + ret = *ptr == 0x7E; + VALGRIND_MAKE_MEM_NOACCESS(ptr, 1); + + return ret; +} + +#endif /* MEMORY_CONTEXT_CHECKING */ + +#ifdef RANDOMIZE_ALLOCATED_MEMORY + +void randomize_mem(char *ptr, size_t size); + +#endif /* RANDOMIZE_ALLOCATED_MEMORY */ + + +#endif /* MEMDEBUG_H */ diff --git a/install/include/postgresql/server/utils/memutils.h b/install/include/postgresql/server/utils/memutils.h new file mode 100644 index 00000000000..21640d62a64 --- /dev/null +++ b/install/include/postgresql/server/utils/memutils.h @@ -0,0 +1,185 @@ +/*------------------------------------------------------------------------- + * + * memutils.h + * This file contains declarations for memory allocation utility + * functions. These are functions that are not quite widely used + * enough to justify going in utils/palloc.h, but are still part + * of the API of the memory management subsystem. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/memutils.h + * + *------------------------------------------------------------------------- + */ +#ifndef MEMUTILS_H +#define MEMUTILS_H + +#include "nodes/memnodes.h" + + +/* + * MaxAllocSize, MaxAllocHugeSize + * Quasi-arbitrary limits on size of allocations. + * + * Note: + * There is no guarantee that smaller allocations will succeed, but + * larger requests will be summarily denied. + * + * palloc() enforces MaxAllocSize, chosen to correspond to the limiting size + * of varlena objects under TOAST. See VARSIZE_4B() and related macros in + * postgres.h. Many datatypes assume that any allocatable size can be + * represented in a varlena header. This limit also permits a caller to use + * an "int" variable for an index into or length of an allocation. Callers + * careful to avoid these hazards can access the higher limit with + * MemoryContextAllocHuge(). Both limits permit code to assume that it may + * compute twice an allocation's size without overflow. + */ +#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ + +#define AllocSizeIsValid(size) ((Size) (size) <= MaxAllocSize) + +/* Must be less than SIZE_MAX */ +#define MaxAllocHugeSize (SIZE_MAX / 2) + +#define InvalidAllocSize SIZE_MAX + +#define AllocHugeSizeIsValid(size) ((Size) (size) <= MaxAllocHugeSize) + + +/* + * Standard top-level memory contexts. + * + * Only TopMemoryContext and ErrorContext are initialized by + * MemoryContextInit() itself. + */ +extern PGDLLIMPORT MemoryContext TopMemoryContext; +extern PGDLLIMPORT MemoryContext ErrorContext; +extern PGDLLIMPORT MemoryContext PostmasterContext; +extern PGDLLIMPORT MemoryContext CacheMemoryContext; +extern PGDLLIMPORT MemoryContext MessageContext; +extern PGDLLIMPORT MemoryContext TopTransactionContext; +extern PGDLLIMPORT MemoryContext CurTransactionContext; + +/* This is a transient link to the active portal's memory context: */ +extern PGDLLIMPORT MemoryContext PortalContext; + +/* Backwards compatibility macro */ +#define MemoryContextResetAndDeleteChildren(ctx) MemoryContextReset(ctx) + + +/* + * Memory-context-type-independent functions in mcxt.c + */ +extern void MemoryContextInit(void); +extern void MemoryContextReset(MemoryContext context); +extern void MemoryContextDelete(MemoryContext context); +extern void MemoryContextResetOnly(MemoryContext context); +extern void MemoryContextResetChildren(MemoryContext context); +extern void MemoryContextDeleteChildren(MemoryContext context); +extern void MemoryContextSetIdentifier(MemoryContext context, const char *id); +extern void MemoryContextSetParent(MemoryContext context, + MemoryContext new_parent); +extern MemoryContext GetMemoryChunkContext(void *pointer); +extern Size GetMemoryChunkSpace(void *pointer); +extern MemoryContext MemoryContextGetParent(MemoryContext context); +extern bool MemoryContextIsEmpty(MemoryContext context); +extern Size MemoryContextMemAllocated(MemoryContext context, bool recurse); +extern void MemoryContextStats(MemoryContext context); +extern void MemoryContextStatsDetail(MemoryContext context, int max_children, + bool print_to_stderr); +extern void MemoryContextAllowInCriticalSection(MemoryContext context, + bool allow); + +#ifdef MEMORY_CONTEXT_CHECKING +extern void MemoryContextCheck(MemoryContext context); +#endif + +/* Handy macro for copying and assigning context ID ... but note double eval */ +#define MemoryContextCopyAndSetIdentifier(cxt, id) \ + MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id)) + +extern void HandleLogMemoryContextInterrupt(void); +extern void ProcessLogMemoryContextInterrupt(void); + +/* + * Memory-context-type-specific functions + */ + +/* aset.c */ +extern MemoryContext AllocSetContextCreateInternal(MemoryContext parent, + const char *name, + Size minContextSize, + Size initBlockSize, + Size maxBlockSize); + +/* + * This wrapper macro exists to check for non-constant strings used as context + * names; that's no longer supported. (Use MemoryContextSetIdentifier if you + * want to provide a variable identifier.) + */ +#ifdef HAVE__BUILTIN_CONSTANT_P +#define AllocSetContextCreate(parent, name, ...) \ + (StaticAssertExpr(__builtin_constant_p(name), \ + "memory context names must be constant strings"), \ + AllocSetContextCreateInternal(parent, name, __VA_ARGS__)) +#else +#define AllocSetContextCreate \ + AllocSetContextCreateInternal +#endif + +/* slab.c */ +extern MemoryContext SlabContextCreate(MemoryContext parent, + const char *name, + Size blockSize, + Size chunkSize); + +/* generation.c */ +extern MemoryContext GenerationContextCreate(MemoryContext parent, + const char *name, + Size minContextSize, + Size initBlockSize, + Size maxBlockSize); + +/* + * Recommended default alloc parameters, suitable for "ordinary" contexts + * that might hold quite a lot of data. + */ +#define ALLOCSET_DEFAULT_MINSIZE 0 +#define ALLOCSET_DEFAULT_INITSIZE (8 * 1024) +#define ALLOCSET_DEFAULT_MAXSIZE (8 * 1024 * 1024) +#define ALLOCSET_DEFAULT_SIZES \ + ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE + +/* + * Recommended alloc parameters for "small" contexts that are never expected + * to contain much data (for example, a context to contain a query plan). + */ +#define ALLOCSET_SMALL_MINSIZE 0 +#define ALLOCSET_SMALL_INITSIZE (1 * 1024) +#define ALLOCSET_SMALL_MAXSIZE (8 * 1024) +#define ALLOCSET_SMALL_SIZES \ + ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE + +/* + * Recommended alloc parameters for contexts that should start out small, + * but might sometimes grow big. + */ +#define ALLOCSET_START_SMALL_SIZES \ + ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE + + +/* + * Threshold above which a request in an AllocSet context is certain to be + * allocated separately (and thereby have constant allocation overhead). + * Few callers should be interested in this, but tuplesort/tuplestore need + * to know it. + */ +#define ALLOCSET_SEPARATE_THRESHOLD 8192 + +#define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024) +#define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024) + +#endif /* MEMUTILS_H */ diff --git a/install/include/postgresql/server/utils/memutils_internal.h b/install/include/postgresql/server/utils/memutils_internal.h new file mode 100644 index 00000000000..2d107bbf9d4 --- /dev/null +++ b/install/include/postgresql/server/utils/memutils_internal.h @@ -0,0 +1,136 @@ +/*------------------------------------------------------------------------- + * + * memutils_internal.h + * This file contains declarations for memory allocation utility + * functions for internal use. + * + * + * Portions Copyright (c) 2022-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/memutils_internal.h + * + *------------------------------------------------------------------------- + */ + +#ifndef MEMUTILS_INTERNAL_H +#define MEMUTILS_INTERNAL_H + +#include "utils/memutils.h" + +/* These functions implement the MemoryContext API for AllocSet context. */ +extern void *AllocSetAlloc(MemoryContext context, Size size); +extern void AllocSetFree(void *pointer); +extern void *AllocSetRealloc(void *pointer, Size size); +extern void AllocSetReset(MemoryContext context); +extern void AllocSetDelete(MemoryContext context); +extern MemoryContext AllocSetGetChunkContext(void *pointer); +extern Size AllocSetGetChunkSpace(void *pointer); +extern bool AllocSetIsEmpty(MemoryContext context); +extern void AllocSetStats(MemoryContext context, + MemoryStatsPrintFunc printfunc, void *passthru, + MemoryContextCounters *totals, + bool print_to_stderr); +#ifdef MEMORY_CONTEXT_CHECKING +extern void AllocSetCheck(MemoryContext context); +#endif + +/* These functions implement the MemoryContext API for Generation context. */ +extern void *GenerationAlloc(MemoryContext context, Size size); +extern void GenerationFree(void *pointer); +extern void *GenerationRealloc(void *pointer, Size size); +extern void GenerationReset(MemoryContext context); +extern void GenerationDelete(MemoryContext context); +extern MemoryContext GenerationGetChunkContext(void *pointer); +extern Size GenerationGetChunkSpace(void *pointer); +extern bool GenerationIsEmpty(MemoryContext context); +extern void GenerationStats(MemoryContext context, + MemoryStatsPrintFunc printfunc, void *passthru, + MemoryContextCounters *totals, + bool print_to_stderr); +#ifdef MEMORY_CONTEXT_CHECKING +extern void GenerationCheck(MemoryContext context); +#endif + + +/* These functions implement the MemoryContext API for Slab context. */ +extern void *SlabAlloc(MemoryContext context, Size size); +extern void SlabFree(void *pointer); +extern void *SlabRealloc(void *pointer, Size size); +extern void SlabReset(MemoryContext context); +extern void SlabDelete(MemoryContext context); +extern MemoryContext SlabGetChunkContext(void *pointer); +extern Size SlabGetChunkSpace(void *pointer); +extern bool SlabIsEmpty(MemoryContext context); +extern void SlabStats(MemoryContext context, + MemoryStatsPrintFunc printfunc, void *passthru, + MemoryContextCounters *totals, + bool print_to_stderr); +#ifdef MEMORY_CONTEXT_CHECKING +extern void SlabCheck(MemoryContext context); +#endif + +/* + * These functions support the implementation of palloc_aligned() and are not + * part of a fully-fledged MemoryContext type. + */ +extern void AlignedAllocFree(void *pointer); +extern void *AlignedAllocRealloc(void *pointer, Size size); +extern MemoryContext AlignedAllocGetChunkContext(void *pointer); +extern Size AlignedAllocGetChunkSpace(void *pointer); + +/* + * How many extra bytes do we need to request in order to ensure that we can + * align a pointer to 'alignto'. Since palloc'd pointers are already aligned + * to MAXIMUM_ALIGNOF we can subtract that amount. We also need to make sure + * there is enough space for the redirection MemoryChunk. + */ +#define PallocAlignedExtraBytes(alignto) \ + ((alignto) + (sizeof(MemoryChunk) - MAXIMUM_ALIGNOF)) + +/* + * MemoryContextMethodID + * A unique identifier for each MemoryContext implementation which + * indicates the index into the mcxt_methods[] array. See mcxt.c. + * + * For robust error detection, ensure that MemoryContextMethodID has a value + * for each possible bit-pattern of MEMORY_CONTEXT_METHODID_MASK, and make + * dummy entries for unused IDs in the mcxt_methods[] array. We also try + * to avoid using bit-patterns as valid IDs if they are likely to occur in + * garbage data, or if they could falsely match on chunks that are really from + * malloc not palloc. (We can't tell that for most malloc implementations, + * but it happens that glibc stores flag bits in the same place where we put + * the MemoryContextMethodID, so the possible values are predictable for it.) + */ +typedef enum MemoryContextMethodID +{ + MCTX_UNUSED1_ID, /* 000 occurs in never-used memory */ + MCTX_UNUSED2_ID, /* glibc malloc'd chunks usually match 001 */ + MCTX_UNUSED3_ID, /* glibc malloc'd chunks > 128kB match 010 */ + MCTX_ASET_ID, + MCTX_GENERATION_ID, + MCTX_SLAB_ID, + MCTX_ALIGNED_REDIRECT_ID, + MCTX_UNUSED4_ID /* 111 occurs in wipe_mem'd memory */ +} MemoryContextMethodID; + +/* + * The number of bits that 8-byte memory chunk headers can use to encode the + * MemoryContextMethodID. + */ +#define MEMORY_CONTEXT_METHODID_BITS 3 +#define MEMORY_CONTEXT_METHODID_MASK \ + ((((uint64) 1) << MEMORY_CONTEXT_METHODID_BITS) - 1) + +/* + * This routine handles the context-type-independent part of memory + * context creation. It's intended to be called from context-type- + * specific creation routines, and noplace else. + */ +extern void MemoryContextCreate(MemoryContext node, + NodeTag tag, + MemoryContextMethodID method_id, + MemoryContext parent, + const char *name); + +#endif /* MEMUTILS_INTERNAL_H */ diff --git a/install/include/postgresql/server/utils/memutils_memorychunk.h b/install/include/postgresql/server/utils/memutils_memorychunk.h new file mode 100644 index 00000000000..ffa91131c88 --- /dev/null +++ b/install/include/postgresql/server/utils/memutils_memorychunk.h @@ -0,0 +1,237 @@ +/*------------------------------------------------------------------------- + * + * memutils_memorychunk.h + * Here we define a struct named MemoryChunk which implementations of + * MemoryContexts may use as a header for chunks of memory they allocate. + * + * MemoryChunk provides a lightweight header that a MemoryContext can use to + * store a reference back to the block which the given chunk is allocated on + * and also an additional 30-bits to store another value such as the size of + * the allocated chunk. + * + * Although MemoryChunks are used by each of our MemoryContexts, future + * implementations may choose to implement their own method for storing chunk + * headers. The only requirement is that the header ends with an 8-byte value + * which the least significant 3-bits of are set to the MemoryContextMethodID + * of the given context. + * + * By default, a MemoryChunk is 8 bytes in size, however, when + * MEMORY_CONTEXT_CHECKING is defined the header becomes 16 bytes in size due + * to the additional requested_size field. The MemoryContext may use this + * field for whatever they wish, but it is intended to be used for additional + * checks which are only done in MEMORY_CONTEXT_CHECKING builds. + * + * The MemoryChunk contains a uint64 field named 'hdrmask'. This field is + * used to encode 4 separate pieces of information. Starting with the least + * significant bits of 'hdrmask', the bit space is reserved as follows: + * + * 1. 3-bits to indicate the MemoryContextMethodID as defined by + * MEMORY_CONTEXT_METHODID_MASK + * 2. 1-bit to denote an "external" chunk (see below) + * 3. 30-bits reserved for the MemoryContext to use for anything it + * requires. Most MemoryContext likely want to store the size of the + * chunk here. + * 4. 30-bits for the number of bytes that must be subtracted from the chunk + * to obtain the address of the block that the chunk is stored on. + * + * In some cases, for example when memory allocations become large, it's + * possible fields 3 and 4 above are not large enough to store the values + * required for the chunk. In this case, the MemoryContext can choose to mark + * the chunk as "external" by calling the MemoryChunkSetHdrMaskExternal() + * function. When this is done, fields 3 and 4 are unavailable for use by the + * MemoryContext and it's up to the MemoryContext itself to devise its own + * method for getting the reference to the block. + * + * Interface: + * + * MemoryChunkSetHdrMask: + * Used to set up a non-external MemoryChunk. + * + * MemoryChunkSetHdrMaskExternal: + * Used to set up an externally managed MemoryChunk. + * + * MemoryChunkIsExternal: + * Determine if the given MemoryChunk is externally managed, i.e. + * MemoryChunkSetHdrMaskExternal() was called on the chunk. + * + * MemoryChunkGetValue: + * For non-external chunks, return the stored 30-bit value as it was set + * in the call to MemoryChunkSetHdrMask(). + * + * MemoryChunkGetBlock: + * For non-external chunks, return a pointer to the block as it was set + * in the call to MemoryChunkSetHdrMask(). + * + * Also exports: + * MEMORYCHUNK_MAX_VALUE + * MEMORYCHUNK_MAX_BLOCKOFFSET + * PointerGetMemoryChunk + * MemoryChunkGetPointer + * + * Portions Copyright (c) 2022-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/memutils_memorychunk.h + * + *------------------------------------------------------------------------- + */ + +#ifndef MEMUTILS_MEMORYCHUNK_H +#define MEMUTILS_MEMORYCHUNK_H + +#include "utils/memutils_internal.h" + + /* + * The maximum allowed value that MemoryContexts can store in the value + * field. Must be 1 less than a power of 2. + */ +#define MEMORYCHUNK_MAX_VALUE UINT64CONST(0x3FFFFFFF) + +/* + * The maximum distance in bytes that a MemoryChunk can be offset from the + * block that is storing the chunk. Must be 1 less than a power of 2. + */ +#define MEMORYCHUNK_MAX_BLOCKOFFSET UINT64CONST(0x3FFFFFFF) + +/* define the least significant base-0 bit of each portion of the hdrmask */ +#define MEMORYCHUNK_EXTERNAL_BASEBIT MEMORY_CONTEXT_METHODID_BITS +#define MEMORYCHUNK_VALUE_BASEBIT (MEMORYCHUNK_EXTERNAL_BASEBIT + 1) +#define MEMORYCHUNK_BLOCKOFFSET_BASEBIT (MEMORYCHUNK_VALUE_BASEBIT + 30) + +/* + * A magic number for storing in the free bits of an external chunk. This + * must mask out the bits used for storing the MemoryContextMethodID and the + * external bit. + */ +#define MEMORYCHUNK_MAGIC (UINT64CONST(0xB1A8DB858EB6EFBA) >> \ + MEMORYCHUNK_VALUE_BASEBIT << \ + MEMORYCHUNK_VALUE_BASEBIT) + +typedef struct MemoryChunk +{ +#ifdef MEMORY_CONTEXT_CHECKING + Size requested_size; +#endif + + /* bitfield for storing details about the chunk */ + uint64 hdrmask; /* must be last */ +} MemoryChunk; + +/* Get the MemoryChunk from the pointer */ +#define PointerGetMemoryChunk(p) \ + ((MemoryChunk *) ((char *) (p) - sizeof(MemoryChunk))) +/* Get the pointer from the MemoryChunk */ +#define MemoryChunkGetPointer(c) \ + ((void *) ((char *) (c) + sizeof(MemoryChunk))) + +/* private macros for making the inline functions below more simple */ +#define HdrMaskIsExternal(hdrmask) \ + ((hdrmask) & (((uint64) 1) << MEMORYCHUNK_EXTERNAL_BASEBIT)) +#define HdrMaskGetValue(hdrmask) \ + (((hdrmask) >> MEMORYCHUNK_VALUE_BASEBIT) & MEMORYCHUNK_MAX_VALUE) + +/* + * We should have used up all the bits here, so the compiler is likely to + * optimize out the & MEMORYCHUNK_MAX_BLOCKOFFSET. + */ +#define HdrMaskBlockOffset(hdrmask) \ + (((hdrmask) >> MEMORYCHUNK_BLOCKOFFSET_BASEBIT) & MEMORYCHUNK_MAX_BLOCKOFFSET) + +/* For external chunks only, check the magic number matches */ +#define HdrMaskCheckMagic(hdrmask) \ + (MEMORYCHUNK_MAGIC == \ + ((hdrmask) >> MEMORYCHUNK_VALUE_BASEBIT << MEMORYCHUNK_VALUE_BASEBIT)) +/* + * MemoryChunkSetHdrMask + * Store the given 'block', 'chunk_size' and 'methodid' in the given + * MemoryChunk. + * + * The number of bytes between 'block' and 'chunk' must be <= + * MEMORYCHUNK_MAX_BLOCKOFFSET. + * 'value' must be <= MEMORYCHUNK_MAX_VALUE. + */ +static inline void +MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block, + Size value, MemoryContextMethodID methodid) +{ + Size blockoffset = (char *) chunk - (char *) block; + + Assert((char *) chunk >= (char *) block); + Assert(blockoffset <= MEMORYCHUNK_MAX_BLOCKOFFSET); + Assert(value <= MEMORYCHUNK_MAX_VALUE); + Assert((int) methodid <= MEMORY_CONTEXT_METHODID_MASK); + + chunk->hdrmask = (((uint64) blockoffset) << MEMORYCHUNK_BLOCKOFFSET_BASEBIT) | + (((uint64) value) << MEMORYCHUNK_VALUE_BASEBIT) | + methodid; +} + +/* + * MemoryChunkSetHdrMaskExternal + * Set 'chunk' as an externally managed chunk. Here we only record the + * MemoryContextMethodID and set the external chunk bit. + */ +static inline void +MemoryChunkSetHdrMaskExternal(MemoryChunk *chunk, + MemoryContextMethodID methodid) +{ + Assert((int) methodid <= MEMORY_CONTEXT_METHODID_MASK); + + chunk->hdrmask = MEMORYCHUNK_MAGIC | (((uint64) 1) << MEMORYCHUNK_EXTERNAL_BASEBIT) | + methodid; +} + +/* + * MemoryChunkIsExternal + * Return true if 'chunk' is marked as external. + */ +static inline bool +MemoryChunkIsExternal(MemoryChunk *chunk) +{ + /* + * External chunks should always store MEMORYCHUNK_MAGIC in the upper + * portion of the hdrmask, check that nothing has stomped on that. + */ + Assert(!HdrMaskIsExternal(chunk->hdrmask) || + HdrMaskCheckMagic(chunk->hdrmask)); + + return HdrMaskIsExternal(chunk->hdrmask); +} + +/* + * MemoryChunkGetValue + * For non-external chunks, returns the value field as it was set in + * MemoryChunkSetHdrMask. + */ +static inline Size +MemoryChunkGetValue(MemoryChunk *chunk) +{ + Assert(!HdrMaskIsExternal(chunk->hdrmask)); + + return HdrMaskGetValue(chunk->hdrmask); +} + +/* + * MemoryChunkGetBlock + * For non-external chunks, returns the pointer to the block as was set + * in MemoryChunkSetHdrMask. + */ +static inline void * +MemoryChunkGetBlock(MemoryChunk *chunk) +{ + Assert(!HdrMaskIsExternal(chunk->hdrmask)); + + return (void *) ((char *) chunk - HdrMaskBlockOffset(chunk->hdrmask)); +} + +/* cleanup all internal definitions */ +#undef MEMORYCHUNK_EXTERNAL_BASEBIT +#undef MEMORYCHUNK_VALUE_BASEBIT +#undef MEMORYCHUNK_BLOCKOFFSET_BASEBIT +#undef MEMORYCHUNK_MAGIC +#undef HdrMaskIsExternal +#undef HdrMaskGetValue +#undef HdrMaskBlockOffset +#undef HdrMaskCheckMagic + +#endif /* MEMUTILS_MEMORYCHUNK_H */ diff --git a/install/include/postgresql/server/utils/multirangetypes.h b/install/include/postgresql/server/utils/multirangetypes.h new file mode 100644 index 00000000000..7663d35d56a --- /dev/null +++ b/install/include/postgresql/server/utils/multirangetypes.h @@ -0,0 +1,150 @@ +/*------------------------------------------------------------------------- + * + * multirangetypes.h + * Declarations for Postgres multirange types. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/multirangetypes.h + * + *------------------------------------------------------------------------- + */ +#ifndef MULTIRANGETYPES_H +#define MULTIRANGETYPES_H + +#include "utils/rangetypes.h" +#include "utils/typcache.h" + + +/* + * Multiranges are varlena objects, so must meet the varlena convention that + * the first int32 of the object contains the total object size in bytes. + * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though! + */ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + Oid multirangetypid; /* multirange type's own OID */ + uint32 rangeCount; /* the number of ranges */ + + /* + * Following the count are the range objects themselves, as ShortRangeType + * structs. Note that ranges are varlena too, depending on whether they + * have lower/upper bounds and because even their base types can be + * varlena. So we can't really index into this list. + */ +} MultirangeType; + +/* Use these macros in preference to accessing these fields directly */ +#define MultirangeTypeGetOid(mr) ((mr)->multirangetypid) +#define MultirangeIsEmpty(mr) ((mr)->rangeCount == 0) + +/* + * fmgr functions for multirange type objects + */ +static inline MultirangeType * +DatumGetMultirangeTypeP(Datum X) +{ + return (MultirangeType *) PG_DETOAST_DATUM(X); +} + +static inline MultirangeType * +DatumGetMultirangeTypePCopy(Datum X) +{ + return (MultirangeType *) PG_DETOAST_DATUM_COPY(X); +} + +static inline Datum +MultirangeTypePGetDatum(const MultirangeType *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_MULTIRANGE_P(n) DatumGetMultirangeTypeP(PG_GETARG_DATUM(n)) +#define PG_GETARG_MULTIRANGE_P_COPY(n) DatumGetMultirangeTypePCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_MULTIRANGE_P(x) return MultirangeTypePGetDatum(x) + +/* + * prototypes for functions defined in multirangetypes.c + */ + +/* internal versions of the above */ +extern bool multirange_eq_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2); +extern bool multirange_ne_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2); +extern bool multirange_contains_elem_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr, + Datum val); +extern bool multirange_contains_range_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr, + const RangeType *r); +extern bool range_contains_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr); +extern bool multirange_contains_multirange_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2); +extern bool range_overlaps_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr); +extern bool multirange_overlaps_multirange_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2); +extern bool range_overleft_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr); +extern bool range_overright_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr); +extern bool range_before_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr); +extern bool range_after_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr); +extern bool range_adjacent_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr); +extern bool multirange_before_multirange_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2); +extern MultirangeType *multirange_minus_internal(Oid mltrngtypoid, + TypeCacheEntry *rangetyp, + int32 range_count1, + RangeType **ranges1, + int32 range_count2, + RangeType **ranges2); +extern MultirangeType *multirange_intersect_internal(Oid mltrngtypoid, + TypeCacheEntry *rangetyp, + int32 range_count1, + RangeType **ranges1, + int32 range_count2, + RangeType **ranges2); + +/* assorted support functions */ +extern TypeCacheEntry *multirange_get_typcache(FunctionCallInfo fcinfo, + Oid mltrngtypid); +extern void multirange_deserialize(TypeCacheEntry *rangetyp, + const MultirangeType *multirange, + int32 *range_count, + RangeType ***ranges); +extern MultirangeType *make_multirange(Oid mltrngtypoid, + TypeCacheEntry *rangetyp, + int32 range_count, RangeType **ranges); +extern MultirangeType *make_empty_multirange(Oid mltrngtypoid, + TypeCacheEntry *rangetyp); +extern void multirange_get_bounds(TypeCacheEntry *rangetyp, + const MultirangeType *multirange, + uint32 i, + RangeBound *lower, RangeBound *upper); +extern RangeType *multirange_get_range(TypeCacheEntry *rangetyp, + const MultirangeType *multirange, int i); +extern RangeType *multirange_get_union_range(TypeCacheEntry *rangetyp, + const MultirangeType *mr); + +#endif /* MULTIRANGETYPES_H */ diff --git a/install/include/postgresql/server/utils/numeric.h b/install/include/postgresql/server/utils/numeric.h new file mode 100644 index 00000000000..08e4f8c217d --- /dev/null +++ b/install/include/postgresql/server/utils/numeric.h @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------- + * + * numeric.h + * Definitions for the exact numeric data type of Postgres + * + * Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane. + * + * Copyright (c) 1998-2023, PostgreSQL Global Development Group + * + * src/include/utils/numeric.h + * + *------------------------------------------------------------------------- + */ +#ifndef _PG_NUMERIC_H_ +#define _PG_NUMERIC_H_ + +#include "fmgr.h" + +/* + * Limits on the precision and scale specifiable in a NUMERIC typmod. The + * precision is strictly positive, but the scale may be positive or negative. + * A negative scale implies rounding before the decimal point. + * + * Note that the minimum display scale defined below is zero --- we always + * display all digits before the decimal point, even when the scale is + * negative. + * + * Note that the implementation limits on the precision and display scale of a + * numeric value are much larger --- beware of what you use these for! + */ +#define NUMERIC_MAX_PRECISION 1000 + +#define NUMERIC_MIN_SCALE (-1000) +#define NUMERIC_MAX_SCALE 1000 + +/* + * Internal limits on the scales chosen for calculation results + */ +#define NUMERIC_MAX_DISPLAY_SCALE NUMERIC_MAX_PRECISION +#define NUMERIC_MIN_DISPLAY_SCALE 0 + +#define NUMERIC_MAX_RESULT_SCALE (NUMERIC_MAX_PRECISION * 2) + +/* + * For inherently inexact calculations such as division and square root, + * we try to get at least this many significant digits; the idea is to + * deliver a result no worse than float8 would. + */ +#define NUMERIC_MIN_SIG_DIGITS 16 + +/* The actual contents of Numeric are private to numeric.c */ +struct NumericData; +typedef struct NumericData *Numeric; + +/* + * fmgr interface macros + */ + +static inline Numeric +DatumGetNumeric(Datum X) +{ + return (Numeric) PG_DETOAST_DATUM(X); +} + +static inline Numeric +DatumGetNumericCopy(Datum X) +{ + return (Numeric) PG_DETOAST_DATUM_COPY(X); +} + +static inline Datum +NumericGetDatum(Numeric X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_NUMERIC(n) DatumGetNumeric(PG_GETARG_DATUM(n)) +#define PG_GETARG_NUMERIC_COPY(n) DatumGetNumericCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_NUMERIC(x) return NumericGetDatum(x) + +/* + * Utility functions in numeric.c + */ +extern bool numeric_is_nan(Numeric num); +extern bool numeric_is_inf(Numeric num); +extern int32 numeric_maximum_size(int32 typmod); +extern char *numeric_out_sci(Numeric num, int scale); +extern char *numeric_normalize(Numeric num); + +extern Numeric int64_to_numeric(int64 val); +extern Numeric int64_div_fast_to_numeric(int64 val1, int log10val2); + +extern Numeric numeric_add_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_mul_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_div_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern int32 numeric_int4_opt_error(Numeric num, bool *have_error); + +#endif /* _PG_NUMERIC_H_ */ diff --git a/install/include/postgresql/server/utils/old_snapshot.h b/install/include/postgresql/server/utils/old_snapshot.h new file mode 100644 index 00000000000..f1978a28e1c --- /dev/null +++ b/install/include/postgresql/server/utils/old_snapshot.h @@ -0,0 +1,75 @@ +/*------------------------------------------------------------------------- + * + * old_snapshot.h + * Data structures for 'snapshot too old' + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/utils/old_snapshot.h + * + *------------------------------------------------------------------------- + */ + +#ifndef OLD_SNAPSHOT_H +#define OLD_SNAPSHOT_H + +#include "datatype/timestamp.h" +#include "storage/s_lock.h" + +/* + * 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; + +extern PGDLLIMPORT volatile OldSnapshotControlData *oldSnapshotControl; + +#endif diff --git a/install/include/postgresql/server/utils/palloc.h b/install/include/postgresql/server/utils/palloc.h new file mode 100644 index 00000000000..d1146c12351 --- /dev/null +++ b/install/include/postgresql/server/utils/palloc.h @@ -0,0 +1,165 @@ +/*------------------------------------------------------------------------- + * + * palloc.h + * POSTGRES memory allocator definitions. + * + * This file contains the basic memory allocation interface that is + * needed by almost every backend module. It is included directly by + * postgres.h, so the definitions here are automatically available + * everywhere. Keep it lean! + * + * Memory allocation occurs within "contexts". Every chunk obtained from + * palloc()/MemoryContextAlloc() is allocated within a specific context. + * The entire contents of a context can be freed easily and quickly by + * resetting or deleting the context --- this is both faster and less + * prone to memory-leakage bugs than releasing chunks individually. + * We organize contexts into context trees to allow fine-grain control + * over chunk lifetime while preserving the certainty that we will free + * everything that should be freed. See utils/mmgr/README for more info. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/palloc.h + * + *------------------------------------------------------------------------- + */ +#ifndef PALLOC_H +#define PALLOC_H + +/* + * Type MemoryContextData is declared in nodes/memnodes.h. Most users + * of memory allocation should just treat it as an abstract type, so we + * do not provide the struct contents here. + */ +typedef struct MemoryContextData *MemoryContext; + +/* + * A memory context can have callback functions registered on it. Any such + * function will be called once just before the context is next reset or + * deleted. The MemoryContextCallback struct describing such a callback + * typically would be allocated within the context itself, thereby avoiding + * any need to manage it explicitly (the reset/delete action will free it). + */ +typedef void (*MemoryContextCallbackFunction) (void *arg); + +typedef struct MemoryContextCallback +{ + MemoryContextCallbackFunction func; /* function to call */ + void *arg; /* argument to pass it */ + struct MemoryContextCallback *next; /* next in list of callbacks */ +} MemoryContextCallback; + +/* + * CurrentMemoryContext is the default allocation context for palloc(). + * Avoid accessing it directly! Instead, use MemoryContextSwitchTo() + * to change the setting. + */ +extern PGDLLIMPORT MemoryContext CurrentMemoryContext; + +/* + * Flags for MemoryContextAllocExtended. + */ +#define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) */ +#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ +#define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */ + +/* + * Fundamental memory-allocation operations (more are in utils/memutils.h) + */ +extern void *MemoryContextAlloc(MemoryContext context, Size size); +extern void *MemoryContextAllocZero(MemoryContext context, Size size); +extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); +extern void *MemoryContextAllocExtended(MemoryContext context, + Size size, int flags); +extern void *MemoryContextAllocAligned(MemoryContext context, + Size size, Size alignto, int flags); + +extern void *palloc(Size size); +extern void *palloc0(Size size); +extern void *palloc_extended(Size size, int flags); +extern void *palloc_aligned(Size size, Size alignto, int flags); +extern pg_nodiscard void *repalloc(void *pointer, Size size); +extern pg_nodiscard void *repalloc_extended(void *pointer, + Size size, int flags); +extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size); +extern void pfree(void *pointer); + +/* + * Variants with easier notation and more type safety + */ + +/* + * Allocate space for one object of type "type" + */ +#define palloc_object(type) ((type *) palloc(sizeof(type))) +#define palloc0_object(type) ((type *) palloc0(sizeof(type))) + +/* + * Allocate space for "count" objects of type "type" + */ +#define palloc_array(type, count) ((type *) palloc(sizeof(type) * (count))) +#define palloc0_array(type, count) ((type *) palloc0(sizeof(type) * (count))) + +/* + * Change size of allocation pointed to by "pointer" to have space for "count" + * objects of type "type" + */ +#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count))) +#define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count))) + +/* + * The result of palloc() is always word-aligned, so we can skip testing + * alignment of the pointer when deciding which MemSet variant to use. + * Note that this variant does not offer any advantage, and should not be + * used, unless its "sz" argument is a compile-time constant; therefore, the + * issue that it evaluates the argument multiple times isn't a problem in + * practice. + */ +#define palloc0fast(sz) \ + ( MemSetTest(0, sz) ? \ + MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \ + MemoryContextAllocZero(CurrentMemoryContext, sz) ) + +/* Higher-limit allocators. */ +extern void *MemoryContextAllocHuge(MemoryContext context, Size size); +extern pg_nodiscard void *repalloc_huge(void *pointer, Size size); + +/* + * Although this header file is nominally backend-only, certain frontend + * programs like pg_controldata include it via postgres.h. For some compilers + * it's necessary to hide the inline definition of MemoryContextSwitchTo in + * this scenario; hence the #ifndef FRONTEND. + */ + +#ifndef FRONTEND +static inline MemoryContext +MemoryContextSwitchTo(MemoryContext context) +{ + MemoryContext old = CurrentMemoryContext; + + CurrentMemoryContext = context; + return old; +} +#endif /* FRONTEND */ + +/* Registration of memory context reset/delete callbacks */ +extern void MemoryContextRegisterResetCallback(MemoryContext context, + MemoryContextCallback *cb); + +/* + * These are like standard strdup() except the copied string is + * allocated in a context, not with malloc(). + */ +extern char *MemoryContextStrdup(MemoryContext context, const char *string); +extern char *pstrdup(const char *in); +extern char *pnstrdup(const char *in, Size len); + +extern char *pchomp(const char *in); + +/* sprintf into a palloc'd buffer --- these are in psprintf.c */ +extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2); +extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0); + +#endif /* PALLOC_H */ diff --git a/install/include/postgresql/server/utils/partcache.h b/install/include/postgresql/server/utils/partcache.h new file mode 100644 index 00000000000..eb9bc4b0dcf --- /dev/null +++ b/install/include/postgresql/server/utils/partcache.h @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------------- + * + * partcache.h + * + * Copyright (c) 1996-2023, PostgreSQL Global Development Group + * + * src/include/utils/partcache.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARTCACHE_H +#define PARTCACHE_H + +#include "access/attnum.h" +#include "fmgr.h" +#include "nodes/parsenodes.h" +#include "nodes/pg_list.h" +#include "nodes/primnodes.h" +#include "partitioning/partdefs.h" +#include "utils/relcache.h" + +/* + * Information about the partition key of a relation + */ +typedef struct PartitionKeyData +{ + PartitionStrategy strategy; /* partitioning strategy */ + int16 partnatts; /* number of columns in the partition key */ + AttrNumber *partattrs; /* attribute numbers of columns in the + * partition key or 0 if it's an expr */ + List *partexprs; /* list of expressions in the partitioning + * key, one for each zero-valued partattrs */ + + Oid *partopfamily; /* OIDs of operator families */ + Oid *partopcintype; /* OIDs of opclass declared input data types */ + FmgrInfo *partsupfunc; /* lookup info for support funcs */ + + /* Partitioning collation per attribute */ + Oid *partcollation; + + /* Type information per attribute */ + Oid *parttypid; + int32 *parttypmod; + int16 *parttyplen; + bool *parttypbyval; + char *parttypalign; + Oid *parttypcoll; +} PartitionKeyData; + + +extern PartitionKey RelationGetPartitionKey(Relation rel); +extern List *RelationGetPartitionQual(Relation rel); +extern Expr *get_partition_qual_relid(Oid relid); + +/* + * PartitionKey inquiry functions + */ +static inline int +get_partition_strategy(PartitionKey key) +{ + return key->strategy; +} + +static inline int +get_partition_natts(PartitionKey key) +{ + return key->partnatts; +} + +static inline List * +get_partition_exprs(PartitionKey key) +{ + return key->partexprs; +} + +/* + * PartitionKey inquiry functions - one column + */ +static inline int16 +get_partition_col_attnum(PartitionKey key, int col) +{ + return key->partattrs[col]; +} + +static inline Oid +get_partition_col_typid(PartitionKey key, int col) +{ + return key->parttypid[col]; +} + +static inline int32 +get_partition_col_typmod(PartitionKey key, int col) +{ + return key->parttypmod[col]; +} + +static inline Oid +get_partition_col_collation(PartitionKey key, int col) +{ + return key->partcollation[col]; +} + +#endif /* PARTCACHE_H */ diff --git a/install/include/postgresql/server/utils/pg_crc.h b/install/include/postgresql/server/utils/pg_crc.h new file mode 100644 index 00000000000..a0369c64717 --- /dev/null +++ b/install/include/postgresql/server/utils/pg_crc.h @@ -0,0 +1,107 @@ +/* + * pg_crc.h + * + * PostgreSQL CRC support + * + * See Ross Williams' excellent introduction + * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from + * http://ross.net/crc/ or several other net sites. + * + * We have three slightly different variants of a 32-bit CRC calculation: + * CRC-32C (Castagnoli polynomial), CRC-32 (Ethernet polynomial), and a legacy + * CRC-32 version that uses the lookup table in a funny way. They all consist + * of four macros: + * + * INIT_(crc) + * Initialize a CRC accumulator + * + * COMP_(crc, data, len) + * Accumulate some (more) bytes into a CRC + * + * FIN_(crc) + * Finish a CRC calculation + * + * EQ_(c1, c2) + * Check for equality of two CRCs. + * + * The CRC-32C variant is in port/pg_crc32c.h. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/pg_crc.h + */ +#ifndef PG_CRC_H +#define PG_CRC_H + +typedef uint32 pg_crc32; + +/* + * CRC-32, the same used e.g. in Ethernet. + * + * This is currently only used in ltree and hstore contrib modules. It uses + * the same lookup table as the legacy algorithm below. New code should + * use the Castagnoli version instead. + */ +#define INIT_TRADITIONAL_CRC32(crc) ((crc) = 0xFFFFFFFF) +#define FIN_TRADITIONAL_CRC32(crc) ((crc) ^= 0xFFFFFFFF) +#define COMP_TRADITIONAL_CRC32(crc, data, len) \ + COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32_table) +#define EQ_TRADITIONAL_CRC32(c1, c2) ((c1) == (c2)) + +/* Sarwate's algorithm, for use with a "normal" lookup table */ +#define COMP_CRC32_NORMAL_TABLE(crc, data, len, table) \ +do { \ + const unsigned char *__data = (const unsigned char *) (data); \ + uint32 __len = (len); \ +\ + while (__len-- > 0) \ + { \ + int __tab_index = ((int) (crc) ^ *__data++) & 0xFF; \ + (crc) = table[__tab_index] ^ ((crc) >> 8); \ + } \ +} while (0) + +/* + * The CRC algorithm used for WAL et al in pre-9.5 versions. + * + * This closely resembles the normal CRC-32 algorithm, but is subtly + * different. Using Williams' terms, we use the "normal" table, but with + * "reflected" code. That's bogus, but it was like that for years before + * anyone noticed. It does not correspond to any polynomial in a normal CRC + * algorithm, so it's not clear what the error-detection properties of this + * algorithm actually are. + * + * We still need to carry this around because it is used in a few on-disk + * structures that need to be pg_upgradeable. It should not be used in new + * code. + */ +#define INIT_LEGACY_CRC32(crc) ((crc) = 0xFFFFFFFF) +#define FIN_LEGACY_CRC32(crc) ((crc) ^= 0xFFFFFFFF) +#define COMP_LEGACY_CRC32(crc, data, len) \ + COMP_CRC32_REFLECTED_TABLE(crc, data, len, pg_crc32_table) +#define EQ_LEGACY_CRC32(c1, c2) ((c1) == (c2)) + +/* + * Sarwate's algorithm, for use with a "reflected" lookup table (but in the + * legacy algorithm, we actually use it on a "normal" table, see above) + */ +#define COMP_CRC32_REFLECTED_TABLE(crc, data, len, table) \ +do { \ + const unsigned char *__data = (const unsigned char *) (data); \ + uint32 __len = (len); \ +\ + while (__len-- > 0) \ + { \ + int __tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \ + (crc) = table[__tab_index] ^ ((crc) << 8); \ + } \ +} while (0) + +/* + * Constant table for the CRC-32 polynomials. The same table is used by both + * the normal and traditional variants. + */ +extern PGDLLIMPORT const uint32 pg_crc32_table[256]; + +#endif /* PG_CRC_H */ diff --git a/install/include/postgresql/server/utils/pg_locale.h b/install/include/postgresql/server/utils/pg_locale.h new file mode 100644 index 00000000000..73d3e6e9310 --- /dev/null +++ b/install/include/postgresql/server/utils/pg_locale.h @@ -0,0 +1,140 @@ +/*----------------------------------------------------------------------- + * + * PostgreSQL locale utilities + * + * src/include/utils/pg_locale.h + * + * Copyright (c) 2002-2023, PostgreSQL Global Development Group + * + *----------------------------------------------------------------------- + */ + +#ifndef _PG_LOCALE_ +#define _PG_LOCALE_ + +#if defined(LOCALE_T_IN_XLOCALE) || defined(WCSTOMBS_L_IN_XLOCALE) +#include +#endif +#ifdef USE_ICU +/* only include the C APIs, to avoid errors in cpluspluscheck */ +#undef U_SHOW_CPLUSPLUS_API +#define U_SHOW_CPLUSPLUS_API 0 +#undef U_SHOW_CPLUSPLUS_HEADER_API +#define U_SHOW_CPLUSPLUS_HEADER_API 0 +#include +#endif + +#ifdef USE_ICU +/* + * ucol_strcollUTF8() was introduced in ICU 50, but it is buggy before ICU 53. + * (see + * ) + */ +#if U_ICU_VERSION_MAJOR_NUM >= 53 +#define HAVE_UCOL_STRCOLLUTF8 1 +#else +#undef HAVE_UCOL_STRCOLLUTF8 +#endif +#endif + +/* use for libc locale names */ +#define LOCALE_NAME_BUFLEN 128 + +/* GUC settings */ +extern PGDLLIMPORT char *locale_messages; +extern PGDLLIMPORT char *locale_monetary; +extern PGDLLIMPORT char *locale_numeric; +extern PGDLLIMPORT char *locale_time; +extern PGDLLIMPORT int icu_validation_level; + +/* lc_time localization cache */ +extern PGDLLIMPORT char *localized_abbrev_days[]; +extern PGDLLIMPORT char *localized_full_days[]; +extern PGDLLIMPORT char *localized_abbrev_months[]; +extern PGDLLIMPORT char *localized_full_months[]; + +/* is the databases's LC_CTYPE the C locale? */ +extern PGDLLIMPORT bool database_ctype_is_c; + +extern bool check_locale(int category, const char *locale, char **canonname); +extern char *pg_perm_setlocale(int category, const char *locale); + +extern bool lc_collate_is_c(Oid collation); +extern bool lc_ctype_is_c(Oid collation); + +/* + * Return the POSIX lconv struct (contains number/money formatting + * information) with locale information for all categories. + */ +extern struct lconv *PGLC_localeconv(void); + +extern void cache_locale_time(void); + + +/* + * We define our own wrapper around locale_t so we can keep the same + * function signatures for all builds, while not having to create a + * fake version of the standard type locale_t in the global namespace. + * pg_locale_t is occasionally checked for truth, so make it a pointer. + */ +struct pg_locale_struct +{ + char provider; + bool deterministic; + union + { +#ifdef HAVE_LOCALE_T + locale_t lt; +#endif +#ifdef USE_ICU + struct + { + const char *locale; + UCollator *ucol; + } icu; +#endif + int dummy; /* in case we have neither LOCALE_T nor ICU */ + } info; +}; + +typedef struct pg_locale_struct *pg_locale_t; + +extern PGDLLIMPORT struct pg_locale_struct default_locale; + +extern void make_icu_collator(const char *iculocstr, + const char *icurules, + struct pg_locale_struct *resultp); + +extern bool pg_locale_deterministic(pg_locale_t locale); +extern pg_locale_t pg_newlocale_from_collation(Oid collid); + +extern char *get_collation_actual_version(char collprovider, const char *collcollate); +extern int pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale); +extern int pg_strncoll(const char *arg1, size_t len1, + const char *arg2, size_t len2, pg_locale_t locale); +extern bool pg_strxfrm_enabled(pg_locale_t locale); +extern size_t pg_strxfrm(char *dest, const char *src, size_t destsize, + pg_locale_t locale); +extern size_t pg_strnxfrm(char *dest, size_t destsize, const char *src, + size_t srclen, pg_locale_t locale); +extern bool pg_strxfrm_prefix_enabled(pg_locale_t locale); +extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize, + pg_locale_t locale); +extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src, + size_t srclen, pg_locale_t locale); + +extern void icu_validate_locale(const char *loc_str); +extern char *icu_language_tag(const char *loc_str, int elevel); + +#ifdef USE_ICU +extern int32_t icu_to_uchar(UChar **buff_uchar, const char *buff, size_t nbytes); +extern int32_t icu_from_uchar(char **result, const UChar *buff_uchar, int32_t len_uchar); +#endif + +/* These functions convert from/to libc's wchar_t, *not* pg_wchar_t */ +extern size_t wchar2char(char *to, const wchar_t *from, size_t tolen, + pg_locale_t locale); +extern size_t char2wchar(wchar_t *to, size_t tolen, + const char *from, size_t fromlen, pg_locale_t locale); + +#endif /* _PG_LOCALE_ */ diff --git a/install/include/postgresql/server/utils/pg_lsn.h b/install/include/postgresql/server/utils/pg_lsn.h new file mode 100644 index 00000000000..7bda26b40ac --- /dev/null +++ b/install/include/postgresql/server/utils/pg_lsn.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * pg_lsn.h + * Declarations for operations on log sequence numbers (LSNs) of + * PostgreSQL. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/pg_lsn.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LSN_H +#define PG_LSN_H + +#include "access/xlogdefs.h" +#include "fmgr.h" + +static inline XLogRecPtr +DatumGetLSN(Datum X) +{ + return (XLogRecPtr) DatumGetInt64(X); +} + +static inline Datum +LSNGetDatum(XLogRecPtr X) +{ + return Int64GetDatum((int64) X); +} + +#define PG_GETARG_LSN(n) DatumGetLSN(PG_GETARG_DATUM(n)) +#define PG_RETURN_LSN(x) return LSNGetDatum(x) + +extern XLogRecPtr pg_lsn_in_internal(const char *str, bool *have_error); + +#endif /* PG_LSN_H */ diff --git a/install/include/postgresql/server/utils/pg_rusage.h b/install/include/postgresql/server/utils/pg_rusage.h new file mode 100644 index 00000000000..219ee678856 --- /dev/null +++ b/install/include/postgresql/server/utils/pg_rusage.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * pg_rusage.h + * header file for resource usage measurement support routines + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/pg_rusage.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_RUSAGE_H +#define PG_RUSAGE_H + +#include +#include + + +/* State structure for pg_rusage_init/pg_rusage_show */ +typedef struct PGRUsage +{ + struct timeval tv; + struct rusage ru; +} PGRUsage; + + +extern void pg_rusage_init(PGRUsage *ru0); +extern const char *pg_rusage_show(const PGRUsage *ru0); + +#endif /* PG_RUSAGE_H */ diff --git a/install/include/postgresql/server/utils/pgstat_internal.h b/install/include/postgresql/server/utils/pgstat_internal.h new file mode 100644 index 00000000000..f886ab7f4bc --- /dev/null +++ b/install/include/postgresql/server/utils/pgstat_internal.h @@ -0,0 +1,833 @@ +/* ---------- + * pgstat_internal.h + * + * Definitions for the PostgreSQL cumulative statistics system that should + * only be needed by files implementing statistics support (rather than ones + * reporting / querying stats). + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/utils/pgstat_internal.h + * ---------- + */ +#ifndef PGSTAT_INTERNAL_H +#define PGSTAT_INTERNAL_H + + +#include "common/hashfn.h" +#include "lib/dshash.h" +#include "lib/ilist.h" +#include "pgstat.h" +#include "storage/lwlock.h" +#include "utils/dsa.h" + + +/* + * Types related to shared memory storage of statistics. + * + * Per-object statistics are stored in the "shared stats" hashtable. That + * table's entries (PgStatShared_HashEntry) contain a pointer to the actual stats + * data for the object (the size of the stats data varies depending on the + * kind of stats). The table is keyed by PgStat_HashKey. + * + * Once a backend has a reference to a shared stats entry, it increments the + * entry's refcount. Even after stats data is dropped (e.g., due to a DROP + * TABLE), the entry itself can only be deleted once all references have been + * released. + * + * These refcounts, in combination with a backend local hashtable + * (pgStatEntryRefHash, with entries pointing to PgStat_EntryRef) in front of + * the shared hash table, mean that most stats work can happen without + * touching the shared hash table, reducing contention. + * + * Once there are pending stats updates for a table PgStat_EntryRef->pending + * is allocated to contain a working space for as-of-yet-unapplied stats + * updates. Once the stats are flushed, PgStat_EntryRef->pending is freed. + * + * Each stat kind in the shared hash table has a fixed member + * PgStatShared_Common as the first element. + */ + +/* struct for shared statistics hash entry key. */ +typedef struct PgStat_HashKey +{ + PgStat_Kind kind; /* statistics entry kind */ + Oid dboid; /* database ID. InvalidOid for shared objects. */ + Oid objoid; /* object ID, either table or function. */ +} PgStat_HashKey; + +/* + * Shared statistics hash entry. Doesn't itself contain any stats, but points + * to them (with ->body). That allows the stats entries themselves to be of + * variable size. + */ +typedef struct PgStatShared_HashEntry +{ + PgStat_HashKey key; /* hash key */ + + /* + * If dropped is set, backends need to release their references so that + * the memory for the entry can be freed. No new references may be made + * once marked as dropped. + */ + bool dropped; + + /* + * Refcount managing lifetime of the entry itself (as opposed to the + * dshash entry pointing to it). The stats lifetime has to be separate + * from the hash table entry lifetime because we allow backends to point + * to a stats entry without holding a hash table lock (and some other + * reasons). + * + * As long as the entry is not dropped, 1 is added to the refcount + * representing that the entry should not be dropped. In addition each + * backend that has a reference to the entry needs to increment the + * refcount as long as it does. + * + * May only be incremented / decremented while holding at least a shared + * lock on the dshash partition containing the entry. It needs to be an + * atomic variable because multiple backends can increment the refcount + * with just a shared lock. + * + * When the refcount reaches 0 the entry needs to be freed. + */ + pg_atomic_uint32 refcount; + + /* + * Counter tracking the number of times the entry has been reused. + * + * Set to 0 when the entry is created, and incremented by one each time + * the shared entry is reinitialized with pgstat_reinit_entry(). + * + * May only be incremented / decremented while holding at least a shared + * lock on the dshash partition containing the entry. Like refcount, it + * needs to be an atomic variable because multiple backends can increment + * the generation with just a shared lock. + */ + pg_atomic_uint32 generation; + + /* + * Pointer to shared stats. The stats entry always starts with + * PgStatShared_Common, embedded in a larger struct containing the + * PgStat_Kind specific stats fields. + */ + dsa_pointer body; +} PgStatShared_HashEntry; + +/* + * Common header struct for PgStatShared_*. + */ +typedef struct PgStatShared_Common +{ + uint32 magic; /* just a validity cross-check */ + /* lock protecting stats contents (i.e. data following the header) */ + LWLock lock; +} PgStatShared_Common; + +/* + * A backend local reference to a shared stats entry. As long as at least one + * such reference exists, the shared stats entry will not be released. + * + * If there are pending stats update to the shared stats, these are stored in + * ->pending. + */ +typedef struct PgStat_EntryRef +{ + /* + * Pointer to the PgStatShared_HashEntry entry in the shared stats + * hashtable. + */ + PgStatShared_HashEntry *shared_entry; + + /* + * Pointer to the stats data (i.e. PgStatShared_HashEntry->body), resolved + * as a local pointer, to avoid repeated dsa_get_address() calls. + */ + PgStatShared_Common *shared_stats; + + /* + * Copy of PgStatShared_HashEntry->generation, keeping locally track of + * the shared stats entry "generation" retrieved (number of times reused). + */ + uint32 generation; + + /* + * Pending statistics data that will need to be flushed to shared memory + * stats eventually. Each stats kind utilizing pending data defines what + * format its pending data has and needs to provide a + * PgStat_KindInfo->flush_pending_cb callback to merge pending into shared + * stats. + */ + void *pending; + dlist_node pending_node; /* membership in pgStatPending list */ +} PgStat_EntryRef; + + +/* + * Some stats changes are transactional. To maintain those, a stack of + * PgStat_SubXactStatus entries is maintained, which contain data pertaining + * to the current transaction and its active subtransactions. + */ +typedef struct PgStat_SubXactStatus +{ + int nest_level; /* subtransaction nest level */ + + struct PgStat_SubXactStatus *prev; /* higher-level subxact if any */ + + /* + * Statistics for transactionally dropped objects need to be + * transactionally dropped as well. Collect the stats dropped in the + * current (sub-)transaction and only execute the stats drop when we know + * if the transaction commits/aborts. To handle replicas and crashes, + * stats drops are included in commit / abort records. + */ + dclist_head pending_drops; + + /* + * Tuple insertion/deletion counts for an open transaction can't be + * propagated into PgStat_TableStatus counters until we know if it is + * going to commit or abort. Hence, we keep these counts in per-subxact + * structs that live in TopTransactionContext. This data structure is + * designed on the assumption that subxacts won't usually modify very many + * tables. + */ + PgStat_TableXactStatus *first; /* head of list for this subxact */ +} PgStat_SubXactStatus; + + +/* + * Metadata for a specific kind of statistics. + */ +typedef struct PgStat_KindInfo +{ + /* + * Do a fixed number of stats objects exist for this kind of stats (e.g. + * bgwriter stats) or not (e.g. tables). + */ + bool fixed_amount:1; + + /* + * Can stats of this kind be accessed from another database? Determines + * whether a stats object gets included in stats snapshots. + */ + bool accessed_across_databases:1; + + /* + * For variable-numbered stats: Identified on-disk using a name, rather + * than PgStat_HashKey. Probably only needed for replication slot stats. + */ + bool named_on_disk:1; + + /* + * The size of an entry in the shared stats hash table (pointed to by + * PgStatShared_HashEntry->body). + */ + uint32 shared_size; + + /* + * The offset/size of statistics inside the shared stats entry. Used when + * [de-]serializing statistics to / from disk respectively. Separate from + * shared_size because [de-]serialization may not include in-memory state + * like lwlocks. + */ + uint32 shared_data_off; + uint32 shared_data_len; + + /* + * The size of the pending data for this kind. E.g. how large + * PgStat_EntryRef->pending is. Used for allocations. + * + * 0 signals that an entry of this kind should never have a pending entry. + */ + uint32 pending_size; + + /* + * For variable-numbered stats: flush pending stats. Required if pending + * data is used. + */ + bool (*flush_pending_cb) (PgStat_EntryRef *sr, bool nowait); + + /* + * For variable-numbered stats: delete pending stats. Optional. + */ + void (*delete_pending_cb) (PgStat_EntryRef *sr); + + /* + * For variable-numbered stats: reset the reset timestamp. Optional. + */ + void (*reset_timestamp_cb) (PgStatShared_Common *header, TimestampTz ts); + + /* + * For variable-numbered stats with named_on_disk. Optional. + */ + void (*to_serialized_name) (const PgStat_HashKey *key, + const PgStatShared_Common *header, NameData *name); + bool (*from_serialized_name) (const NameData *name, PgStat_HashKey *key); + + /* + * For fixed-numbered statistics: Reset All. + */ + void (*reset_all_cb) (TimestampTz ts); + + /* + * For fixed-numbered statistics: Build snapshot for entry + */ + void (*snapshot_cb) (void); + + /* name of the kind of stats */ + const char *const name; +} PgStat_KindInfo; + + +/* + * List of SLRU names that we keep stats for. There is no central registry of + * SLRUs, so we use this fixed list instead. The "other" entry is used for + * all SLRUs without an explicit entry (e.g. SLRUs in extensions). + * + * This is only defined here so that SLRU_NUM_ELEMENTS is known for later type + * definitions. + */ +static const char *const slru_names[] = { + "CommitTs", + "MultiXactMember", + "MultiXactOffset", + "Notify", + "Serial", + "Subtrans", + "Xact", + "other" /* has to be last */ +}; + +#define SLRU_NUM_ELEMENTS lengthof(slru_names) + + +/* ---------- + * Types and definitions for different kinds of fixed-amount stats. + * + * Single-writer stats use the changecount mechanism to achieve low-overhead + * writes - they're obviously more performance critical than reads. Check the + * definition of struct PgBackendStatus for some explanation of the + * changecount mechanism. + * + * Because the obvious implementation of resetting single-writer stats isn't + * compatible with that (another backend needs to write), we don't scribble on + * shared stats while resetting. Instead, just record the current counter + * values in a copy of the stats data, which is protected by ->lock. See + * pgstat_fetch_stat_(archiver|bgwriter|checkpointer) for the reader side. + * + * The only exception to that is the stat_reset_timestamp in these structs, + * which is protected by ->lock, because it has to be written by another + * backend while resetting. + * ---------- + */ + +typedef struct PgStatShared_Archiver +{ + /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */ + LWLock lock; + uint32 changecount; + PgStat_ArchiverStats stats; + PgStat_ArchiverStats reset_offset; +} PgStatShared_Archiver; + +typedef struct PgStatShared_BgWriter +{ + /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */ + LWLock lock; + uint32 changecount; + PgStat_BgWriterStats stats; + PgStat_BgWriterStats reset_offset; +} PgStatShared_BgWriter; + +typedef struct PgStatShared_Checkpointer +{ + /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */ + LWLock lock; + uint32 changecount; + PgStat_CheckpointerStats stats; + PgStat_CheckpointerStats reset_offset; +} PgStatShared_Checkpointer; + +/* Shared-memory ready PgStat_IO */ +typedef struct PgStatShared_IO +{ + /* + * locks[i] protects stats.stats[i]. locks[0] also protects + * stats.stat_reset_timestamp. + */ + LWLock locks[BACKEND_NUM_TYPES]; + PgStat_IO stats; +} PgStatShared_IO; + +typedef struct PgStatShared_SLRU +{ + /* lock protects ->stats */ + LWLock lock; + PgStat_SLRUStats stats[SLRU_NUM_ELEMENTS]; +} PgStatShared_SLRU; + +typedef struct PgStatShared_Wal +{ + /* lock protects ->stats */ + LWLock lock; + PgStat_WalStats stats; +} PgStatShared_Wal; + + + +/* ---------- + * Types and definitions for different kinds of variable-amount stats. + * + * Each struct has to start with PgStatShared_Common, containing information + * common across the different types of stats. Kind-specific data follows. + * ---------- + */ + +typedef struct PgStatShared_Database +{ + PgStatShared_Common header; + PgStat_StatDBEntry stats; +} PgStatShared_Database; + +typedef struct PgStatShared_Relation +{ + PgStatShared_Common header; + PgStat_StatTabEntry stats; +} PgStatShared_Relation; + +typedef struct PgStatShared_Function +{ + PgStatShared_Common header; + PgStat_StatFuncEntry stats; +} PgStatShared_Function; + +typedef struct PgStatShared_Subscription +{ + PgStatShared_Common header; + PgStat_StatSubEntry stats; +} PgStatShared_Subscription; + +typedef struct PgStatShared_ReplSlot +{ + PgStatShared_Common header; + PgStat_StatReplSlotEntry stats; +} PgStatShared_ReplSlot; + + +/* + * Central shared memory entry for the cumulative stats system. + * + * Fixed amount stats, the dynamic shared memory hash table for + * non-fixed-amount stats, as well as remaining bits and pieces are all + * reached from here. + */ +typedef struct PgStat_ShmemControl +{ + void *raw_dsa_area; + + /* + * Stats for variable-numbered objects are kept in this shared hash table. + * See comment above PgStat_Kind for details. + */ + dshash_table_handle hash_handle; /* shared dbstat hash */ + + /* Has the stats system already been shut down? Just a debugging check. */ + bool is_shutdown; + + /* + * Whenever statistics for dropped objects could not be freed - because + * backends still have references - the dropping backend calls + * pgstat_request_entry_refs_gc() incrementing this counter. Eventually + * that causes backends to run pgstat_gc_entry_refs(), allowing memory to + * be reclaimed. + */ + pg_atomic_uint64 gc_request_count; + + /* + * Stats data for fixed-numbered objects. + */ + PgStatShared_Archiver archiver; + PgStatShared_BgWriter bgwriter; + PgStatShared_Checkpointer checkpointer; + PgStatShared_IO io; + PgStatShared_SLRU slru; + PgStatShared_Wal wal; +} PgStat_ShmemControl; + + +/* + * Cached statistics snapshot + */ +typedef struct PgStat_Snapshot +{ + PgStat_FetchConsistency mode; + + /* time at which snapshot was taken */ + TimestampTz snapshot_timestamp; + + bool fixed_valid[PGSTAT_NUM_KINDS]; + + PgStat_ArchiverStats archiver; + + PgStat_BgWriterStats bgwriter; + + PgStat_CheckpointerStats checkpointer; + + PgStat_IO io; + + PgStat_SLRUStats slru[SLRU_NUM_ELEMENTS]; + + PgStat_WalStats wal; + + /* to free snapshot in bulk */ + MemoryContext context; + struct pgstat_snapshot_hash *stats; +} PgStat_Snapshot; + + +/* + * Collection of backend-local stats state. + */ +typedef struct PgStat_LocalState +{ + PgStat_ShmemControl *shmem; + dsa_area *dsa; + dshash_table *shared_hash; + + /* the current statistics snapshot */ + PgStat_Snapshot snapshot; +} PgStat_LocalState; + + +/* + * Inline functions defined further below. + */ + +static inline void pgstat_begin_changecount_write(uint32 *cc); +static inline void pgstat_end_changecount_write(uint32 *cc); +static inline uint32 pgstat_begin_changecount_read(uint32 *cc); +static inline bool pgstat_end_changecount_read(uint32 *cc, uint32 cc_before); + +static inline void pgstat_copy_changecounted_stats(void *dst, void *src, size_t len, + uint32 *cc); + +static inline int pgstat_cmp_hash_key(const void *a, const void *b, size_t size, void *arg); +static inline uint32 pgstat_hash_hash_key(const void *d, size_t size, void *arg); +static inline size_t pgstat_get_entry_len(PgStat_Kind kind); +static inline void *pgstat_get_entry_data(PgStat_Kind kind, PgStatShared_Common *entry); + + +/* + * Functions in pgstat.c + */ + +extern const PgStat_KindInfo *pgstat_get_kind_info(PgStat_Kind kind); + +#ifdef USE_ASSERT_CHECKING +extern void pgstat_assert_is_up(void); +#else +#define pgstat_assert_is_up() ((void)true) +#endif + +extern void pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref); +extern PgStat_EntryRef *pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid, bool *created_entry); +extern PgStat_EntryRef *pgstat_fetch_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid); + +extern void *pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, Oid objoid); +extern void pgstat_snapshot_fixed(PgStat_Kind kind); + + +/* + * Functions in pgstat_archiver.c + */ + +extern void pgstat_archiver_reset_all_cb(TimestampTz ts); +extern void pgstat_archiver_snapshot_cb(void); + + +/* + * Functions in pgstat_bgwriter.c + */ + +extern void pgstat_bgwriter_reset_all_cb(TimestampTz ts); +extern void pgstat_bgwriter_snapshot_cb(void); + + +/* + * Functions in pgstat_checkpointer.c + */ + +extern void pgstat_checkpointer_reset_all_cb(TimestampTz ts); +extern void pgstat_checkpointer_snapshot_cb(void); + + +/* + * Functions in pgstat_database.c + */ + +extern void pgstat_report_disconnect(Oid dboid); +extern void pgstat_update_dbstats(TimestampTz ts); +extern void AtEOXact_PgStat_Database(bool isCommit, bool parallel); + +extern PgStat_StatDBEntry *pgstat_prep_database_pending(Oid dboid); +extern void pgstat_reset_database_timestamp(Oid dboid, TimestampTz ts); +extern bool pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); +extern void pgstat_database_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); + + +/* + * Functions in pgstat_function.c + */ + +extern bool pgstat_function_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); + + +/* + * Functions in pgstat_io.c + */ + +extern bool pgstat_flush_io(bool nowait); +extern void pgstat_io_reset_all_cb(TimestampTz ts); +extern void pgstat_io_snapshot_cb(void); + + +/* + * Functions in pgstat_relation.c + */ + +extern void AtEOXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit); +extern void AtEOSubXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit, int nestDepth); +extern void AtPrepare_PgStat_Relations(PgStat_SubXactStatus *xact_state); +extern void PostPrepare_PgStat_Relations(PgStat_SubXactStatus *xact_state); + +extern bool pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); +extern void pgstat_relation_delete_pending_cb(PgStat_EntryRef *entry_ref); + + +/* + * Functions in pgstat_replslot.c + */ + +extern void pgstat_replslot_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); +extern void pgstat_replslot_to_serialized_name_cb(const PgStat_HashKey *key, const PgStatShared_Common *header, NameData *name); +extern bool pgstat_replslot_from_serialized_name_cb(const NameData *name, PgStat_HashKey *key); + + +/* + * Functions in pgstat_shmem.c + */ + +extern void pgstat_attach_shmem(void); +extern void pgstat_detach_shmem(void); + +extern PgStat_EntryRef *pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, Oid objoid, + bool create, bool *created_entry); +extern bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait); +extern bool pgstat_lock_entry_shared(PgStat_EntryRef *entry_ref, bool nowait); +extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref); +extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid); +extern void pgstat_drop_all_entries(void); +extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, Oid objoid, + bool nowait); +extern void pgstat_reset_entry(PgStat_Kind kind, Oid dboid, Oid objoid, TimestampTz ts); +extern void pgstat_reset_entries_of_kind(PgStat_Kind kind, TimestampTz ts); +extern void pgstat_reset_matching_entries(bool (*do_reset) (PgStatShared_HashEntry *, Datum), + Datum match_data, + TimestampTz ts); + +extern void pgstat_request_entry_refs_gc(void); +extern PgStatShared_Common *pgstat_init_entry(PgStat_Kind kind, + PgStatShared_HashEntry *shhashent); + + +/* + * Functions in pgstat_slru.c + */ + +extern bool pgstat_slru_flush(bool nowait); +extern void pgstat_slru_reset_all_cb(TimestampTz ts); +extern void pgstat_slru_snapshot_cb(void); + + +/* + * Functions in pgstat_wal.c + */ + +extern bool pgstat_flush_wal(bool nowait); +extern void pgstat_init_wal(void); +extern bool pgstat_have_pending_wal(void); + +extern void pgstat_wal_reset_all_cb(TimestampTz ts); +extern void pgstat_wal_snapshot_cb(void); + + +/* + * Functions in pgstat_subscription.c + */ + +extern bool pgstat_subscription_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); +extern void pgstat_subscription_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); + + +/* + * Functions in pgstat_xact.c + */ + +extern PgStat_SubXactStatus *pgstat_get_xact_stack_level(int nest_level); +extern void pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, Oid objoid); +extern void pgstat_create_transactional(PgStat_Kind kind, Oid dboid, Oid objoid); + + +/* + * Variables in pgstat.c + */ + +extern PGDLLIMPORT PgStat_LocalState pgStatLocal; + + +/* + * Variables in pgstat_io.c + */ + +extern PGDLLIMPORT bool have_iostats; + + +/* + * Variables in pgstat_slru.c + */ + +extern PGDLLIMPORT bool have_slrustats; + + +/* + * Implementation of inline functions declared above. + */ + +/* + * Helpers for changecount manipulation. See comments around struct + * PgBackendStatus for details. + */ + +static inline void +pgstat_begin_changecount_write(uint32 *cc) +{ + Assert((*cc & 1) == 0); + + START_CRIT_SECTION(); + (*cc)++; + pg_write_barrier(); +} + +static inline void +pgstat_end_changecount_write(uint32 *cc) +{ + Assert((*cc & 1) == 1); + + pg_write_barrier(); + + (*cc)++; + + END_CRIT_SECTION(); +} + +static inline uint32 +pgstat_begin_changecount_read(uint32 *cc) +{ + uint32 before_cc = *cc; + + CHECK_FOR_INTERRUPTS(); + + pg_read_barrier(); + + return before_cc; +} + +/* + * Returns true if the read succeeded, false if it needs to be repeated. + */ +static inline bool +pgstat_end_changecount_read(uint32 *cc, uint32 before_cc) +{ + uint32 after_cc; + + pg_read_barrier(); + + after_cc = *cc; + + /* was a write in progress when we started? */ + if (before_cc & 1) + return false; + + /* did writes start and complete while we read? */ + return before_cc == after_cc; +} + + +/* + * helper function for PgStat_KindInfo->snapshot_cb + * PgStat_KindInfo->reset_all_cb callbacks. + * + * Copies out the specified memory area following change-count protocol. + */ +static inline void +pgstat_copy_changecounted_stats(void *dst, void *src, size_t len, + uint32 *cc) +{ + uint32 cc_before; + + do + { + cc_before = pgstat_begin_changecount_read(cc); + + memcpy(dst, src, len); + } + while (!pgstat_end_changecount_read(cc, cc_before)); +} + +/* helpers for dshash / simplehash hashtables */ +static inline int +pgstat_cmp_hash_key(const void *a, const void *b, size_t size, void *arg) +{ + Assert(size == sizeof(PgStat_HashKey) && arg == NULL); + return memcmp(a, b, sizeof(PgStat_HashKey)); +} + +static inline uint32 +pgstat_hash_hash_key(const void *d, size_t size, void *arg) +{ + const PgStat_HashKey *key = (PgStat_HashKey *) d; + uint32 hash; + + Assert(size == sizeof(PgStat_HashKey) && arg == NULL); + + hash = murmurhash32(key->kind); + hash = hash_combine(hash, murmurhash32(key->dboid)); + hash = hash_combine(hash, murmurhash32(key->objoid)); + + return hash; +} + +/* + * The length of the data portion of a shared memory stats entry (i.e. without + * transient data such as refcounts, lwlocks, ...). + */ +static inline size_t +pgstat_get_entry_len(PgStat_Kind kind) +{ + return pgstat_get_kind_info(kind)->shared_data_len; +} + +/* + * Returns a pointer to the data portion of a shared memory stats entry. + */ +static inline void * +pgstat_get_entry_data(PgStat_Kind kind, PgStatShared_Common *entry) +{ + size_t off = pgstat_get_kind_info(kind)->shared_data_off; + + Assert(off != 0 && off < PG_UINT32_MAX); + + return ((char *) (entry)) + off; +} + +#endif /* PGSTAT_INTERNAL_H */ diff --git a/install/include/postgresql/server/utils/pidfile.h b/install/include/postgresql/server/utils/pidfile.h new file mode 100644 index 00000000000..1393a534f60 --- /dev/null +++ b/install/include/postgresql/server/utils/pidfile.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * pidfile.h + * Declarations describing the data directory lock file (postmaster.pid) + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/pidfile.h + * + *------------------------------------------------------------------------- + */ +#ifndef UTILS_PIDFILE_H +#define UTILS_PIDFILE_H + +/* + * As of Postgres 10, the contents of the data-directory lock file are: + * + * line # + * 1 postmaster PID (or negative of a standalone backend's PID) + * 2 data directory path + * 3 postmaster start timestamp (time_t representation) + * 4 port number + * 5 first Unix socket directory path (empty if none) + * 6 first listen_address (IP address or "*"; empty if no TCP port) + * 7 shared memory key (empty on Windows) + * 8 postmaster status (see values below) + * + * Lines 6 and up are added via AddToDataDirLockFile() after initial file + * creation; also, line 5 is initially empty and is changed after the first + * Unix socket is opened. Onlookers should not assume that lines 4 and up + * are filled in any particular order. + * + * Socket lock file(s), if used, have the same contents as lines 1-5, with + * line 5 being their own directory. + */ +#define LOCK_FILE_LINE_PID 1 +#define LOCK_FILE_LINE_DATA_DIR 2 +#define LOCK_FILE_LINE_START_TIME 3 +#define LOCK_FILE_LINE_PORT 4 +#define LOCK_FILE_LINE_SOCKET_DIR 5 +#define LOCK_FILE_LINE_LISTEN_ADDR 6 +#define LOCK_FILE_LINE_SHMEM_KEY 7 +#define LOCK_FILE_LINE_PM_STATUS 8 + +/* + * The PM_STATUS line may contain one of these values. All these strings + * must be the same length, per comments for AddToDataDirLockFile(). + * We pad with spaces as needed to make that true. + */ +#define PM_STATUS_STARTING "starting" /* still starting up */ +#define PM_STATUS_STOPPING "stopping" /* in shutdown sequence */ +#define PM_STATUS_READY "ready " /* ready for connections */ +#define PM_STATUS_STANDBY "standby " /* up, won't accept connections */ + +#endif /* UTILS_PIDFILE_H */ diff --git a/install/include/postgresql/server/utils/plancache.h b/install/include/postgresql/server/utils/plancache.h new file mode 100644 index 00000000000..a443181d416 --- /dev/null +++ b/install/include/postgresql/server/utils/plancache.h @@ -0,0 +1,236 @@ +/*------------------------------------------------------------------------- + * + * plancache.h + * Plan cache definitions. + * + * See plancache.c for comments. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/plancache.h + * + *------------------------------------------------------------------------- + */ +#ifndef PLANCACHE_H +#define PLANCACHE_H + +#include "access/tupdesc.h" +#include "lib/ilist.h" +#include "nodes/params.h" +#include "tcop/cmdtag.h" +#include "utils/queryenvironment.h" +#include "utils/resowner.h" + + +/* Forward declaration, to avoid including parsenodes.h here */ +struct RawStmt; + +/* possible values for plan_cache_mode */ +typedef enum +{ + PLAN_CACHE_MODE_AUTO, + PLAN_CACHE_MODE_FORCE_GENERIC_PLAN, + PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN +} PlanCacheMode; + +/* GUC parameter */ +extern PGDLLIMPORT int plan_cache_mode; + +#define CACHEDPLANSOURCE_MAGIC 195726186 +#define CACHEDPLAN_MAGIC 953717834 +#define CACHEDEXPR_MAGIC 838275847 + +/* + * CachedPlanSource (which might better have been called CachedQuery) + * represents a SQL query that we expect to use multiple times. It stores + * the query source text, the raw parse tree, and the analyzed-and-rewritten + * query tree, as well as adjunct data. Cache invalidation can happen as a + * result of DDL affecting objects used by the query. In that case we discard + * the analyzed-and-rewritten query tree, and rebuild it when next needed. + * + * An actual execution plan, represented by CachedPlan, is derived from the + * CachedPlanSource when we need to execute the query. The plan could be + * either generic (usable with any set of plan parameters) or custom (for a + * specific set of parameters). plancache.c contains the logic that decides + * which way to do it for any particular execution. If we are using a generic + * cached plan then it is meant to be re-used across multiple executions, so + * callers must always treat CachedPlans as read-only. + * + * Once successfully built and "saved", CachedPlanSources typically live + * for the life of the backend, although they can be dropped explicitly. + * CachedPlans are reference-counted and go away automatically when the last + * reference is dropped. A CachedPlan can outlive the CachedPlanSource it + * was created from. + * + * An "unsaved" CachedPlanSource can be used for generating plans, but it + * lives in transient storage and will not be updated in response to sinval + * events. + * + * CachedPlans made from saved CachedPlanSources are likewise in permanent + * storage, so to avoid memory leaks, the reference-counted references to them + * must be held in permanent data structures or ResourceOwners. CachedPlans + * made from unsaved CachedPlanSources are in children of the caller's + * memory context, so references to them should not be longer-lived than + * that context. (Reference counting is somewhat pro forma in that case, + * though it may be useful if the CachedPlan can be discarded early.) + * + * A CachedPlanSource has two associated memory contexts: one that holds the + * struct itself, the query source text and the raw parse tree, and another + * context that holds the rewritten query tree and associated data. This + * allows the query tree to be discarded easily when it is invalidated. + * + * Some callers wish to use the CachedPlan API even with one-shot queries + * that have no reason to be saved at all. We therefore support a "oneshot" + * variant that does no data copying or invalidation checking. In this case + * there are no separate memory contexts: the CachedPlanSource struct and + * all subsidiary data live in the caller's CurrentMemoryContext, and there + * is no way to free memory short of clearing that entire context. A oneshot + * plan is always treated as unsaved. + * + * Note: the string referenced by commandTag is not subsidiary storage; + * it is assumed to be a compile-time-constant string. As with portals, + * commandTag shall be NULL if and only if the original query string (before + * rewriting) was an empty string. + */ +typedef struct CachedPlanSource +{ + int magic; /* should equal CACHEDPLANSOURCE_MAGIC */ + struct RawStmt *raw_parse_tree; /* output of raw_parser(), or NULL */ + const char *query_string; /* source text of query */ + CommandTag commandTag; /* 'nuff said */ + Oid *param_types; /* array of parameter type OIDs, or NULL */ + int num_params; /* length of param_types array */ + ParserSetupHook parserSetup; /* alternative parameter spec method */ + void *parserSetupArg; + int cursor_options; /* cursor options used for planning */ + bool fixed_result; /* disallow change in result tupdesc? */ + TupleDesc resultDesc; /* result type; NULL = doesn't return tuples */ + MemoryContext context; /* memory context holding all above */ + /* These fields describe the current analyzed-and-rewritten query tree: */ + List *query_list; /* list of Query nodes, or NIL if not valid */ + List *relationOids; /* OIDs of relations the queries depend on */ + List *invalItems; /* other dependencies, as PlanInvalItems */ + struct OverrideSearchPath *search_path; /* search_path used for parsing + * and planning */ + MemoryContext query_context; /* context holding the above, or NULL */ + Oid rewriteRoleId; /* Role ID we did rewriting for */ + bool rewriteRowSecurity; /* row_security used during rewrite */ + bool dependsOnRLS; /* is rewritten query specific to the above? */ + /* If we have a generic plan, this is a reference-counted link to it: */ + struct CachedPlan *gplan; /* generic plan, or NULL if not valid */ + /* Some state flags: */ + bool is_oneshot; /* is it a "oneshot" plan? */ + bool is_complete; /* has CompleteCachedPlan been done? */ + bool is_saved; /* has CachedPlanSource been "saved"? */ + bool is_valid; /* is the query_list currently valid? */ + int generation; /* increments each time we create a plan */ + /* If CachedPlanSource has been saved, it is a member of a global list */ + dlist_node node; /* list link, if is_saved */ + /* State kept to help decide whether to use custom or generic plans: */ + double generic_cost; /* cost of generic plan, or -1 if not known */ + double total_custom_cost; /* total cost of custom plans so far */ + int64 num_custom_plans; /* # of custom plans included in total */ + int64 num_generic_plans; /* # of generic plans */ +} CachedPlanSource; + +/* + * CachedPlan represents an execution plan derived from a CachedPlanSource. + * The reference count includes both the link from the parent CachedPlanSource + * (if any), and any active plan executions, so the plan can be discarded + * exactly when refcount goes to zero. Both the struct itself and the + * subsidiary data live in the context denoted by the context field. + * This makes it easy to free a no-longer-needed cached plan. (However, + * if is_oneshot is true, the context does not belong solely to the CachedPlan + * so no freeing is possible.) + */ +typedef struct CachedPlan +{ + int magic; /* should equal CACHEDPLAN_MAGIC */ + List *stmt_list; /* list of PlannedStmts */ + bool is_oneshot; /* is it a "oneshot" plan? */ + bool is_saved; /* is CachedPlan in a long-lived context? */ + bool is_valid; /* is the stmt_list currently valid? */ + Oid planRoleId; /* Role ID the plan was created for */ + bool dependsOnRole; /* is plan specific to that role? */ + TransactionId saved_xmin; /* if valid, replan when TransactionXmin + * changes from this value */ + int generation; /* parent's generation number for this plan */ + int refcount; /* count of live references to this struct */ + MemoryContext context; /* context containing this CachedPlan */ +} CachedPlan; + +/* + * CachedExpression is a low-overhead mechanism for caching the planned form + * of standalone scalar expressions. While such expressions are not usually + * subject to cache invalidation events, that can happen, for example because + * of replacement of a SQL function that was inlined into the expression. + * The plancache takes care of storing the expression tree and marking it + * invalid if a cache invalidation occurs, but the caller must notice the + * !is_valid status and discard the obsolete expression without reusing it. + * We do not store the original parse tree, only the planned expression; + * this is an optimization based on the assumption that we usually will not + * need to replan for the life of the session. + */ +typedef struct CachedExpression +{ + int magic; /* should equal CACHEDEXPR_MAGIC */ + Node *expr; /* planned form of expression */ + bool is_valid; /* is the expression still valid? */ + /* remaining fields should be treated as private to plancache.c: */ + List *relationOids; /* OIDs of relations the expr depends on */ + List *invalItems; /* other dependencies, as PlanInvalItems */ + MemoryContext context; /* context containing this CachedExpression */ + dlist_node node; /* link in global list of CachedExpressions */ +} CachedExpression; + + +extern void InitPlanCache(void); +extern void ResetPlanCache(void); + +extern CachedPlanSource *CreateCachedPlan(struct RawStmt *raw_parse_tree, + const char *query_string, + CommandTag commandTag); +extern CachedPlanSource *CreateOneShotCachedPlan(struct RawStmt *raw_parse_tree, + const char *query_string, + CommandTag commandTag); +extern void CompleteCachedPlan(CachedPlanSource *plansource, + List *querytree_list, + MemoryContext querytree_context, + Oid *param_types, + int num_params, + ParserSetupHook parserSetup, + void *parserSetupArg, + int cursor_options, + bool fixed_result); + +extern void SaveCachedPlan(CachedPlanSource *plansource); +extern void DropCachedPlan(CachedPlanSource *plansource); + +extern void CachedPlanSetParentContext(CachedPlanSource *plansource, + MemoryContext newcontext); + +extern CachedPlanSource *CopyCachedPlan(CachedPlanSource *plansource); + +extern bool CachedPlanIsValid(CachedPlanSource *plansource); + +extern List *CachedPlanGetTargetList(CachedPlanSource *plansource, + QueryEnvironment *queryEnv); + +extern CachedPlan *GetCachedPlan(CachedPlanSource *plansource, + ParamListInfo boundParams, + ResourceOwner owner, + QueryEnvironment *queryEnv); +extern void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner); + +extern bool CachedPlanAllowsSimpleValidityCheck(CachedPlanSource *plansource, + CachedPlan *plan, + ResourceOwner owner); +extern bool CachedPlanIsSimplyValid(CachedPlanSource *plansource, + CachedPlan *plan, + ResourceOwner owner); + +extern CachedExpression *GetCachedExpression(Node *expr); +extern void FreeCachedExpression(CachedExpression *cexpr); + +#endif /* PLANCACHE_H */ diff --git a/install/include/postgresql/server/utils/portal.h b/install/include/postgresql/server/utils/portal.h new file mode 100644 index 00000000000..c0a1f562030 --- /dev/null +++ b/install/include/postgresql/server/utils/portal.h @@ -0,0 +1,252 @@ +/*------------------------------------------------------------------------- + * + * portal.h + * POSTGRES portal definitions. + * + * A portal is an abstraction which represents the execution state of + * a running or runnable query. Portals support both SQL-level CURSORs + * and protocol-level portals. + * + * Scrolling (nonsequential access) and suspension of execution are allowed + * only for portals that contain a single SELECT-type query. We do not want + * to let the client suspend an update-type query partway through! Because + * the query rewriter does not allow arbitrary ON SELECT rewrite rules, + * only queries that were originally update-type could produce multiple + * plan trees; so the restriction to a single query is not a problem + * in practice. + * + * For SQL cursors, we support three kinds of scroll behavior: + * + * (1) Neither NO SCROLL nor SCROLL was specified: to remain backward + * compatible, we allow backward fetches here, unless it would + * impose additional runtime overhead to do so. + * + * (2) NO SCROLL was specified: don't allow any backward fetches. + * + * (3) SCROLL was specified: allow all kinds of backward fetches, even + * if we need to take a performance hit to do so. (The planner sticks + * a Materialize node atop the query plan if needed.) + * + * Case #1 is converted to #2 or #3 by looking at the query itself and + * determining if scrollability can be supported without additional + * overhead. + * + * Protocol-level portals have no nonsequential-fetch API and so the + * distinction doesn't matter for them. They are always initialized + * to look like NO SCROLL cursors. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/portal.h + * + *------------------------------------------------------------------------- + */ +#ifndef PORTAL_H +#define PORTAL_H + +#include "datatype/timestamp.h" +#include "executor/execdesc.h" +#include "tcop/cmdtag.h" +#include "utils/plancache.h" +#include "utils/resowner.h" + +/* + * We have several execution strategies for Portals, depending on what + * query or queries are to be executed. (Note: in all cases, a Portal + * executes just a single source-SQL query, and thus produces just a + * single result from the user's viewpoint. However, the rule rewriter + * may expand the single source query to zero or many actual queries.) + * + * PORTAL_ONE_SELECT: the portal contains one single SELECT query. We run + * the Executor incrementally as results are demanded. This strategy also + * supports holdable cursors (the Executor results can be dumped into a + * tuplestore for access after transaction completion). + * + * PORTAL_ONE_RETURNING: the portal contains a single INSERT/UPDATE/DELETE + * query with a RETURNING clause (plus possibly auxiliary queries added by + * rule rewriting). On first execution, we run the portal to completion + * and dump the primary query's results into the portal tuplestore; the + * results are then returned to the client as demanded. (We can't support + * suspension of the query partway through, because the AFTER TRIGGER code + * can't cope, and also because we don't want to risk failing to execute + * all the auxiliary queries.) + * + * PORTAL_ONE_MOD_WITH: the portal contains one single SELECT query, but + * it has data-modifying CTEs. This is currently treated the same as the + * PORTAL_ONE_RETURNING case because of the possibility of needing to fire + * triggers. It may act more like PORTAL_ONE_SELECT in future. + * + * PORTAL_UTIL_SELECT: the portal contains a utility statement that returns + * a SELECT-like result (for example, EXPLAIN or SHOW). On first execution, + * we run the statement and dump its results into the portal tuplestore; + * the results are then returned to the client as demanded. + * + * PORTAL_MULTI_QUERY: all other cases. Here, we do not support partial + * execution: the portal's queries will be run to completion on first call. + */ +typedef enum PortalStrategy +{ + PORTAL_ONE_SELECT, + PORTAL_ONE_RETURNING, + PORTAL_ONE_MOD_WITH, + PORTAL_UTIL_SELECT, + PORTAL_MULTI_QUERY +} PortalStrategy; + +/* + * A portal is always in one of these states. It is possible to transit + * from ACTIVE back to READY if the query is not run to completion; + * otherwise we never back up in status. + */ +typedef enum PortalStatus +{ + PORTAL_NEW, /* freshly created */ + PORTAL_DEFINED, /* PortalDefineQuery done */ + PORTAL_READY, /* PortalStart complete, can run it */ + PORTAL_ACTIVE, /* portal is running (can't delete it) */ + PORTAL_DONE, /* portal is finished (don't re-run it) */ + PORTAL_FAILED /* portal got error (can't re-run it) */ +} PortalStatus; + +typedef struct PortalData *Portal; + +typedef struct PortalData +{ + /* Bookkeeping data */ + const char *name; /* portal's name */ + const char *prepStmtName; /* source prepared statement (NULL if none) */ + MemoryContext portalContext; /* subsidiary memory for portal */ + ResourceOwner resowner; /* resources owned by portal */ + void (*cleanup) (Portal portal); /* cleanup hook */ + + /* + * State data for remembering which subtransaction(s) the portal was + * created or used in. If the portal is held over from a previous + * transaction, both subxids are InvalidSubTransactionId. Otherwise, + * createSubid is the creating subxact and activeSubid is the last subxact + * in which we ran the portal. + */ + SubTransactionId createSubid; /* the creating subxact */ + SubTransactionId activeSubid; /* the last subxact with activity */ + int createLevel; /* creating subxact's nesting level */ + + /* The query or queries the portal will execute */ + const char *sourceText; /* text of query (as of 8.4, never NULL) */ + CommandTag commandTag; /* command tag for original query */ + QueryCompletion qc; /* command completion data for executed query */ + List *stmts; /* list of PlannedStmts */ + CachedPlan *cplan; /* CachedPlan, if stmts are from one */ + + ParamListInfo portalParams; /* params to pass to query */ + QueryEnvironment *queryEnv; /* environment for query */ + + /* Features/options */ + PortalStrategy strategy; /* see above */ + int cursorOptions; /* DECLARE CURSOR option bits */ + bool run_once; /* unused */ + + /* Status data */ + PortalStatus status; /* see above */ + bool portalPinned; /* a pinned portal can't be dropped */ + bool autoHeld; /* was automatically converted from pinned to + * held (see HoldPinnedPortals()) */ + + /* If not NULL, Executor is active; call ExecutorEnd eventually: */ + QueryDesc *queryDesc; /* info needed for executor invocation */ + + /* If portal returns tuples, this is their tupdesc: */ + TupleDesc tupDesc; /* descriptor for result tuples */ + /* and these are the format codes to use for the columns: */ + int16 *formats; /* a format code for each column */ + + /* + * Outermost ActiveSnapshot for execution of the portal's queries. For + * all but a few utility commands, we require such a snapshot to exist. + * This ensures that TOAST references in query results can be detoasted, + * and helps to reduce thrashing of the process's exposed xmin. + */ + Snapshot portalSnapshot; /* active snapshot, or NULL if none */ + + /* + * Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING, + * PORTAL_ONE_MOD_WITH, or PORTAL_UTIL_SELECT query. (A cursor held past + * the end of its transaction no longer has any active executor state.) + */ + Tuplestorestate *holdStore; /* store for holdable cursors */ + MemoryContext holdContext; /* memory containing holdStore */ + + /* + * Snapshot under which tuples in the holdStore were read. We must keep a + * reference to this snapshot if there is any possibility that the tuples + * contain TOAST references, because releasing the snapshot could allow + * recently-dead rows to be vacuumed away, along with any toast data + * belonging to them. In the case of a held cursor, we avoid needing to + * keep such a snapshot by forcibly detoasting the data. + */ + Snapshot holdSnapshot; /* registered snapshot, or NULL if none */ + + /* + * atStart, atEnd and portalPos indicate the current cursor position. + * portalPos is zero before the first row, N after fetching N'th row of + * query. After we run off the end, portalPos = # of rows in query, and + * atEnd is true. Note that atStart implies portalPos == 0, but not the + * reverse: we might have backed up only as far as the first row, not to + * the start. Also note that various code inspects atStart and atEnd, but + * only the portal movement routines should touch portalPos. + */ + bool atStart; + bool atEnd; + uint64 portalPos; + + /* Presentation data, primarily used by the pg_cursors system view */ + TimestampTz creation_time; /* time at which this portal was defined */ + bool visible; /* include this portal in pg_cursors? */ +} PortalData; + +/* + * PortalIsValid + * True iff portal is valid. + */ +#define PortalIsValid(p) PointerIsValid(p) + + +/* Prototypes for functions in utils/mmgr/portalmem.c */ +extern void EnablePortalManager(void); +extern bool PreCommit_Portals(bool isPrepare); +extern void AtAbort_Portals(void); +extern void AtCleanup_Portals(void); +extern void PortalErrorCleanup(void); +extern void AtSubCommit_Portals(SubTransactionId mySubid, + SubTransactionId parentSubid, + int parentLevel, + ResourceOwner parentXactOwner); +extern void AtSubAbort_Portals(SubTransactionId mySubid, + SubTransactionId parentSubid, + ResourceOwner myXactOwner, + ResourceOwner parentXactOwner); +extern void AtSubCleanup_Portals(SubTransactionId mySubid); +extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent); +extern Portal CreateNewPortal(void); +extern void PinPortal(Portal portal); +extern void UnpinPortal(Portal portal); +extern void MarkPortalActive(Portal portal); +extern void MarkPortalDone(Portal portal); +extern void MarkPortalFailed(Portal portal); +extern void PortalDrop(Portal portal, bool isTopCommit); +extern Portal GetPortalByName(const char *name); +extern void PortalDefineQuery(Portal portal, + const char *prepStmtName, + const char *sourceText, + CommandTag commandTag, + List *stmts, + CachedPlan *cplan); +extern PlannedStmt *PortalGetPrimaryStmt(Portal portal); +extern void PortalCreateHoldStore(Portal portal); +extern void PortalHashTableDeleteAll(void); +extern bool ThereAreNoReadyPortals(void); +extern void HoldPinnedPortals(void); +extern void ForgetPortalSnapshots(void); + +#endif /* PORTAL_H */ diff --git a/install/include/postgresql/server/utils/probes.h b/install/include/postgresql/server/utils/probes.h new file mode 100644 index 00000000000..f600a965d20 --- /dev/null +++ b/install/include/postgresql/server/utils/probes.h @@ -0,0 +1,114 @@ +#define TRACE_POSTGRESQL_TRANSACTION_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_TRANSACTION_START_ENABLED() (0) +#define TRACE_POSTGRESQL_TRANSACTION_COMMIT(INT1) do {} while (0) +#define TRACE_POSTGRESQL_TRANSACTION_COMMIT_ENABLED() (0) +#define TRACE_POSTGRESQL_TRANSACTION_ABORT(INT1) do {} while (0) +#define TRACE_POSTGRESQL_TRANSACTION_ABORT_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_ACQUIRE(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_ACQUIRE_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_RELEASE(INT1) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_RELEASE_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_WAIT_START(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_WAIT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_WAIT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_ENABLED() (0) +#define TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL_ENABLED() (0) +#define TRACE_POSTGRESQL_LOCK_WAIT_START(INT1, INT2, INT3, INT4, INT5, INT6) do {} while (0) +#define TRACE_POSTGRESQL_LOCK_WAIT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_LOCK_WAIT_DONE(INT1, INT2, INT3, INT4, INT5, INT6) do {} while (0) +#define TRACE_POSTGRESQL_LOCK_WAIT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_PARSE_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_QUERY_PARSE_START_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_PARSE_DONE(INT1) do {} while (0) +#define TRACE_POSTGRESQL_QUERY_PARSE_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_REWRITE_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_QUERY_REWRITE_START_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_REWRITE_DONE(INT1) do {} while (0) +#define TRACE_POSTGRESQL_QUERY_REWRITE_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_PLAN_START() do {} while (0) +#define TRACE_POSTGRESQL_QUERY_PLAN_START_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_PLAN_DONE() do {} while (0) +#define TRACE_POSTGRESQL_QUERY_PLAN_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_EXECUTE_START() do {} while (0) +#define TRACE_POSTGRESQL_QUERY_EXECUTE_START_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_EXECUTE_DONE() do {} while (0) +#define TRACE_POSTGRESQL_QUERY_EXECUTE_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_QUERY_START_ENABLED() (0) +#define TRACE_POSTGRESQL_QUERY_DONE(INT1) do {} while (0) +#define TRACE_POSTGRESQL_QUERY_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_STATEMENT_STATUS(INT1) do {} while (0) +#define TRACE_POSTGRESQL_STATEMENT_STATUS_ENABLED() (0) +#define TRACE_POSTGRESQL_SORT_START(INT1, INT2, INT3, INT4, INT5, INT6) do {} while (0) +#define TRACE_POSTGRESQL_SORT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_SORT_DONE(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_SORT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_READ_START(INT1, INT2, INT3, INT4, INT5, INT6) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_READ_START_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_READ_DONE(INT1, INT2, INT3, INT4, INT5, INT6, INT7) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_READ_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_FLUSH_START(INT1, INT2, INT3, INT4, INT5) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_FLUSH_START_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_FLUSH_DONE(INT1, INT2, INT3, INT4, INT5) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_FLUSH_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_EXTEND_START(INT1, INT2, INT3, INT4, INT5, INT6) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_EXTEND_START_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_EXTEND_DONE(INT1, INT2, INT3, INT4, INT5, INT6, INT7) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_EXTEND_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START() do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE() do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_SYNC_START(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_SYNC_START_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_SYNC_WRITTEN(INT1) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_SYNC_WRITTEN_ENABLED() (0) +#define TRACE_POSTGRESQL_BUFFER_SYNC_DONE(INT1, INT2, INT3) do {} while (0) +#define TRACE_POSTGRESQL_BUFFER_SYNC_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_DEADLOCK_FOUND() do {} while (0) +#define TRACE_POSTGRESQL_DEADLOCK_FOUND_ENABLED() (0) +#define TRACE_POSTGRESQL_CHECKPOINT_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_CHECKPOINT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_CHECKPOINT_DONE(INT1, INT2, INT3, INT4, INT5) do {} while (0) +#define TRACE_POSTGRESQL_CHECKPOINT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_CLOG_CHECKPOINT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(INT1) do {} while (0) +#define TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(INT1) do {} while (0) +#define TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START(INT1) do {} while (0) +#define TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(INT1) do {} while (0) +#define TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_TWOPHASE_CHECKPOINT_START() do {} while (0) +#define TRACE_POSTGRESQL_TWOPHASE_CHECKPOINT_START_ENABLED() (0) +#define TRACE_POSTGRESQL_TWOPHASE_CHECKPOINT_DONE() do {} while (0) +#define TRACE_POSTGRESQL_TWOPHASE_CHECKPOINT_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_SMGR_MD_READ_START(INT1, INT2, INT3, INT4, INT5, INT6) do {} while (0) +#define TRACE_POSTGRESQL_SMGR_MD_READ_START_ENABLED() (0) +#define TRACE_POSTGRESQL_SMGR_MD_READ_DONE(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8) do {} while (0) +#define TRACE_POSTGRESQL_SMGR_MD_READ_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_SMGR_MD_WRITE_START(INT1, INT2, INT3, INT4, INT5, INT6) do {} while (0) +#define TRACE_POSTGRESQL_SMGR_MD_WRITE_START_ENABLED() (0) +#define TRACE_POSTGRESQL_SMGR_MD_WRITE_DONE(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8) do {} while (0) +#define TRACE_POSTGRESQL_SMGR_MD_WRITE_DONE_ENABLED() (0) +#define TRACE_POSTGRESQL_WAL_INSERT(INT1, INT2) do {} while (0) +#define TRACE_POSTGRESQL_WAL_INSERT_ENABLED() (0) +#define TRACE_POSTGRESQL_WAL_SWITCH() do {} while (0) +#define TRACE_POSTGRESQL_WAL_SWITCH_ENABLED() (0) +#define TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START() do {} while (0) +#define TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START_ENABLED() (0) +#define TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE() do {} while (0) +#define TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE_ENABLED() (0) diff --git a/install/include/postgresql/server/utils/ps_status.h b/install/include/postgresql/server/utils/ps_status.h new file mode 100644 index 00000000000..ff5a2b2b8a2 --- /dev/null +++ b/install/include/postgresql/server/utils/ps_status.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * ps_status.h + * + * Declarations for backend/utils/misc/ps_status.c + * + * src/include/utils/ps_status.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PS_STATUS_H +#define PS_STATUS_H + +/* disabled on Windows as the performance overhead can be significant */ +#ifdef WIN32 +#define DEFAULT_UPDATE_PROCESS_TITLE false +#else +#define DEFAULT_UPDATE_PROCESS_TITLE true +#endif + +extern PGDLLIMPORT bool update_process_title; + +extern char **save_ps_display_args(int argc, char **argv); + +extern void init_ps_display(const char *fixed_part); + +extern void set_ps_display_suffix(const char *suffix); + +extern void set_ps_display_remove_suffix(void); + +extern void set_ps_display_with_len(const char *activity, size_t len); + +/* + * set_ps_display + * inlined to allow strlen to be evaluated during compilation when + * passing string constants. + */ +static inline void +set_ps_display(const char *activity) +{ + set_ps_display_with_len(activity, strlen(activity)); +} + +extern const char *get_ps_display(int *displen); + +#endif /* PS_STATUS_H */ diff --git a/install/include/postgresql/server/utils/queryenvironment.h b/install/include/postgresql/server/utils/queryenvironment.h new file mode 100644 index 00000000000..532219ade23 --- /dev/null +++ b/install/include/postgresql/server/utils/queryenvironment.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * queryenvironment.h + * Access to functions to mutate the query environment and retrieve the + * actual data related to entries (if any). + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/queryenvironment.h + * + *------------------------------------------------------------------------- + */ +#ifndef QUERYENVIRONMENT_H +#define QUERYENVIRONMENT_H + +#include "access/tupdesc.h" + + +typedef enum EphemeralNameRelationType +{ + ENR_NAMED_TUPLESTORE /* named tuplestore relation; e.g., deltas */ +} EphemeralNameRelationType; + +/* + * Some ephemeral named relations must match some relation (e.g., trigger + * transition tables), so to properly handle cached plans and DDL, we should + * carry the OID of that relation. In other cases an ENR might be independent + * of any relation which is stored in the system catalogs, so we need to be + * able to directly store the TupleDesc. We never need both. + */ +typedef struct EphemeralNamedRelationMetadataData +{ + char *name; /* name used to identify the relation */ + + /* only one of the next two fields should be used */ + Oid reliddesc; /* oid of relation to get tupdesc */ + TupleDesc tupdesc; /* description of result rows */ + + EphemeralNameRelationType enrtype; /* to identify type of relation */ + double enrtuples; /* estimated number of tuples */ +} EphemeralNamedRelationMetadataData; + +typedef EphemeralNamedRelationMetadataData *EphemeralNamedRelationMetadata; + +/* + * Ephemeral Named Relation data; used for parsing named relations not in the + * catalog, like transition tables in AFTER triggers. + */ +typedef struct EphemeralNamedRelationData +{ + EphemeralNamedRelationMetadataData md; + void *reldata; /* structure for execution-time access to data */ +} EphemeralNamedRelationData; + +typedef EphemeralNamedRelationData *EphemeralNamedRelation; + +/* + * This is an opaque structure outside of queryenvironment.c itself. The + * intention is to be able to change the implementation or add new context + * features without needing to change existing code for use of existing + * features. + */ +typedef struct QueryEnvironment QueryEnvironment; + + +extern QueryEnvironment *create_queryEnv(void); +extern EphemeralNamedRelationMetadata get_visible_ENR_metadata(QueryEnvironment *queryEnv, const char *refname); +extern void register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr); +extern void unregister_ENR(QueryEnvironment *queryEnv, const char *name); +extern EphemeralNamedRelation get_ENR(QueryEnvironment *queryEnv, const char *name); +extern TupleDesc ENRMetadataGetTupDesc(EphemeralNamedRelationMetadata enrmd); + +#endif /* QUERYENVIRONMENT_H */ diff --git a/install/include/postgresql/server/utils/rangetypes.h b/install/include/postgresql/server/utils/rangetypes.h new file mode 100644 index 00000000000..6b420a8618d --- /dev/null +++ b/install/include/postgresql/server/utils/rangetypes.h @@ -0,0 +1,168 @@ +/*------------------------------------------------------------------------- + * + * rangetypes.h + * Declarations for Postgres range types. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/rangetypes.h + * + *------------------------------------------------------------------------- + */ +#ifndef RANGETYPES_H +#define RANGETYPES_H + +#include "utils/typcache.h" + + +/* + * Ranges are varlena objects, so must meet the varlena convention that + * the first int32 of the object contains the total object size in bytes. + * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though! + */ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + Oid rangetypid; /* range type's own OID */ + /* Following the OID are zero to two bound values, then a flags byte */ +} RangeType; + +#define RANGE_EMPTY_LITERAL "empty" + +/* Use this macro in preference to fetching rangetypid field directly */ +#define RangeTypeGetOid(r) ((r)->rangetypid) + +/* A range's flags byte contains these bits: */ +#define RANGE_EMPTY 0x01 /* range is empty */ +#define RANGE_LB_INC 0x02 /* lower bound is inclusive */ +#define RANGE_UB_INC 0x04 /* upper bound is inclusive */ +#define RANGE_LB_INF 0x08 /* lower bound is -infinity */ +#define RANGE_UB_INF 0x10 /* upper bound is +infinity */ +#define RANGE_LB_NULL 0x20 /* lower bound is null (NOT USED) */ +#define RANGE_UB_NULL 0x40 /* upper bound is null (NOT USED) */ +#define RANGE_CONTAIN_EMPTY 0x80 /* marks a GiST internal-page entry whose + * subtree contains some empty ranges */ + +#define RANGE_HAS_LBOUND(flags) (!((flags) & (RANGE_EMPTY | \ + RANGE_LB_NULL | \ + RANGE_LB_INF))) + +#define RANGE_HAS_UBOUND(flags) (!((flags) & (RANGE_EMPTY | \ + RANGE_UB_NULL | \ + RANGE_UB_INF))) + +#define RangeIsEmpty(r) ((range_get_flags(r) & RANGE_EMPTY) != 0) +#define RangeIsOrContainsEmpty(r) \ + ((range_get_flags(r) & (RANGE_EMPTY | RANGE_CONTAIN_EMPTY)) != 0) + + +/* Internal representation of either bound of a range (not what's on disk) */ +typedef struct +{ + Datum val; /* the bound value, if any */ + bool infinite; /* bound is +/- infinity */ + bool inclusive; /* bound is inclusive (vs exclusive) */ + bool lower; /* this is the lower (vs upper) bound */ +} RangeBound; + +/* + * fmgr functions for range type objects + */ +static inline RangeType * +DatumGetRangeTypeP(Datum X) +{ + return (RangeType *) PG_DETOAST_DATUM(X); +} + +static inline RangeType * +DatumGetRangeTypePCopy(Datum X) +{ + return (RangeType *) PG_DETOAST_DATUM_COPY(X); +} + +static inline Datum +RangeTypePGetDatum(const RangeType *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_RANGE_P(n) DatumGetRangeTypeP(PG_GETARG_DATUM(n)) +#define PG_GETARG_RANGE_P_COPY(n) DatumGetRangeTypePCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_RANGE_P(x) return RangeTypePGetDatum(x) + +/* Operator strategy numbers used in the GiST and SP-GiST range opclasses */ +/* Numbers are chosen to match up operator names with existing usages */ +#define RANGESTRAT_BEFORE RTLeftStrategyNumber +#define RANGESTRAT_OVERLEFT RTOverLeftStrategyNumber +#define RANGESTRAT_OVERLAPS RTOverlapStrategyNumber +#define RANGESTRAT_OVERRIGHT RTOverRightStrategyNumber +#define RANGESTRAT_AFTER RTRightStrategyNumber +#define RANGESTRAT_ADJACENT RTSameStrategyNumber +#define RANGESTRAT_CONTAINS RTContainsStrategyNumber +#define RANGESTRAT_CONTAINED_BY RTContainedByStrategyNumber +#define RANGESTRAT_CONTAINS_ELEM RTContainsElemStrategyNumber +#define RANGESTRAT_EQ RTEqualStrategyNumber + +/* + * prototypes for functions defined in rangetypes.c + */ + +extern bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val); + +/* internal versions of the above */ +extern bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); +extern RangeType *range_union_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2, bool strict); +extern RangeType *range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern RangeType *range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2); + +/* assorted support functions */ +extern TypeCacheEntry *range_get_typcache(FunctionCallInfo fcinfo, + Oid rngtypid); +extern RangeType *range_serialize(TypeCacheEntry *typcache, RangeBound *lower, + RangeBound *upper, bool empty, + struct Node *escontext); +extern void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, + RangeBound *lower, RangeBound *upper, + bool *empty); +extern char range_get_flags(const RangeType *range); +extern void range_set_contain_empty(RangeType *range); +extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower, + RangeBound *upper, bool empty, + struct Node *escontext); +extern int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, + const RangeBound *b2); +extern int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, + const RangeBound *b2); +extern int range_compare(const void *key1, const void *key2, void *arg); +extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, + RangeBound boundB); +extern RangeType *make_empty_range(TypeCacheEntry *typcache); +extern bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, + const RangeType *r2, RangeType **output1, + RangeType **output2); + +#endif /* RANGETYPES_H */ diff --git a/install/include/postgresql/server/utils/regproc.h b/install/include/postgresql/server/utils/regproc.h new file mode 100644 index 00000000000..a1f7c6b0cdc --- /dev/null +++ b/install/include/postgresql/server/utils/regproc.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * regproc.h + * Functions for the built-in types regproc, regclass, regtype, etc. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/regproc.h + * + *------------------------------------------------------------------------- + */ +#ifndef REGPROC_H +#define REGPROC_H + +#include "nodes/pg_list.h" + +/* Control flags for format_procedure_extended */ +#define FORMAT_PROC_INVALID_AS_NULL 0x01 /* NULL if undefined */ +#define FORMAT_PROC_FORCE_QUALIFY 0x02 /* force qualification */ +extern char *format_procedure_extended(Oid procedure_oid, bits16 flags); + +/* Control flags for format_operator_extended */ +#define FORMAT_OPERATOR_INVALID_AS_NULL 0x01 /* NULL if undefined */ +#define FORMAT_OPERATOR_FORCE_QUALIFY 0x02 /* force qualification */ +extern char *format_operator_extended(Oid operator_oid, bits16 flags); + +extern List *stringToQualifiedNameList(const char *string, Node *escontext); +extern char *format_procedure(Oid procedure_oid); +extern char *format_procedure_qualified(Oid procedure_oid); +extern void format_procedure_parts(Oid procedure_oid, List **objnames, + List **objargs, bool missing_ok); + +extern char *format_operator(Oid operator_oid); +extern char *format_operator_qualified(Oid operator_oid); +extern void format_operator_parts(Oid operator_oid, List **objnames, + List **objargs, bool missing_ok); + +#endif diff --git a/install/include/postgresql/server/utils/rel.h b/install/include/postgresql/server/utils/rel.h new file mode 100644 index 00000000000..1426a353cd0 --- /dev/null +++ b/install/include/postgresql/server/utils/rel.h @@ -0,0 +1,712 @@ +/*------------------------------------------------------------------------- + * + * rel.h + * POSTGRES relation descriptor (a/k/a relcache entry) definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/rel.h + * + *------------------------------------------------------------------------- + */ +#ifndef REL_H +#define REL_H + +#include "access/tupdesc.h" +#include "access/xlog.h" +#include "catalog/catalog.h" +#include "catalog/pg_class.h" +#include "catalog/pg_index.h" +#include "catalog/pg_publication.h" +#include "nodes/bitmapset.h" +#include "partitioning/partdefs.h" +#include "rewrite/prs2lock.h" +#include "storage/block.h" +#include "storage/relfilelocator.h" +#include "storage/smgr.h" +#include "utils/relcache.h" +#include "utils/reltrigger.h" + + +/* + * LockRelId and LockInfo really belong to lmgr.h, but it's more convenient + * to declare them here so we can have a LockInfoData field in a Relation. + */ + +typedef struct LockRelId +{ + Oid relId; /* a relation identifier */ + Oid dbId; /* a database identifier */ +} LockRelId; + +typedef struct LockInfoData +{ + LockRelId lockRelId; +} LockInfoData; + +typedef LockInfoData *LockInfo; + +/* + * Here are the contents of a relation cache entry. + */ + +typedef struct RelationData +{ + RelFileLocator rd_locator; /* relation physical identifier */ + SMgrRelation rd_smgr; /* cached file handle, or NULL */ + int rd_refcnt; /* reference count */ + BackendId rd_backend; /* owning backend id, if temporary relation */ + bool rd_islocaltemp; /* rel is a temp rel of this session */ + bool rd_isnailed; /* rel is nailed in cache */ + bool rd_isvalid; /* relcache entry is valid */ + bool rd_indexvalid; /* is rd_indexlist valid? (also rd_pkindex and + * rd_replidindex) */ + bool rd_statvalid; /* is rd_statlist valid? */ + + /*---------- + * rd_createSubid is the ID of the highest subtransaction the rel has + * survived into or zero if the rel or its storage was created before the + * current top transaction. (IndexStmt.oldNumber leads to the case of a new + * rel with an old rd_locator.) rd_firstRelfilelocatorSubid is the ID of the + * highest subtransaction an rd_locator change has survived into or zero if + * rd_locator matches the value it had at the start of the current top + * transaction. (Rolling back the subtransaction that + * rd_firstRelfilelocatorSubid denotes would restore rd_locator to the value it + * had at the start of the current top transaction. Rolling back any + * lower subtransaction would not.) Their accuracy is critical to + * RelationNeedsWAL(). + * + * rd_newRelfilelocatorSubid is the ID of the highest subtransaction the + * most-recent relfilenumber change has survived into or zero if not changed + * in the current transaction (or we have forgotten changing it). This + * field is accurate when non-zero, but it can be zero when a relation has + * multiple new relfilenumbers within a single transaction, with one of them + * occurring in a subsequently aborted subtransaction, e.g. + * BEGIN; + * TRUNCATE t; + * SAVEPOINT save; + * TRUNCATE t; + * ROLLBACK TO save; + * -- rd_newRelfilelocatorSubid is now forgotten + * + * If every rd_*Subid field is zero, they are read-only outside + * relcache.c. Files that trigger rd_locator changes by updating + * pg_class.reltablespace and/or pg_class.relfilenode call + * RelationAssumeNewRelfilelocator() to update rd_*Subid. + * + * rd_droppedSubid is the ID of the highest subtransaction that a drop of + * the rel has survived into. In entries visible outside relcache.c, this + * is always zero. + */ + SubTransactionId rd_createSubid; /* rel was created in current xact */ + SubTransactionId rd_newRelfilelocatorSubid; /* highest subxact changing + * rd_locator to current value */ + SubTransactionId rd_firstRelfilelocatorSubid; /* highest subxact + * changing rd_locator to + * any value */ + SubTransactionId rd_droppedSubid; /* dropped with another Subid set */ + + Form_pg_class rd_rel; /* RELATION tuple */ + TupleDesc rd_att; /* tuple descriptor */ + Oid rd_id; /* relation's object id */ + LockInfoData rd_lockInfo; /* lock mgr's info for locking relation */ + RuleLock *rd_rules; /* rewrite rules */ + MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */ + TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */ + /* use "struct" here to avoid needing to include rowsecurity.h: */ + struct RowSecurityDesc *rd_rsdesc; /* row security policies, or NULL */ + + /* data managed by RelationGetFKeyList: */ + List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */ + bool rd_fkeyvalid; /* true if list has been computed */ + + /* data managed by RelationGetPartitionKey: */ + PartitionKey rd_partkey; /* partition key, or NULL */ + MemoryContext rd_partkeycxt; /* private context for rd_partkey, if any */ + + /* data managed by RelationGetPartitionDesc: */ + PartitionDesc rd_partdesc; /* partition descriptor, or NULL */ + MemoryContext rd_pdcxt; /* private context for rd_partdesc, if any */ + + /* Same as above, for partdescs that omit detached partitions */ + PartitionDesc rd_partdesc_nodetached; /* partdesc w/o detached parts */ + MemoryContext rd_pddcxt; /* for rd_partdesc_nodetached, if any */ + + /* + * pg_inherits.xmin of the partition that was excluded in + * rd_partdesc_nodetached. This informs a future user of that partdesc: + * if this value is not in progress for the active snapshot, then the + * partdesc can be used, otherwise they have to build a new one. (This + * matches what find_inheritance_children_extended would do). + */ + TransactionId rd_partdesc_nodetached_xmin; + + /* data managed by RelationGetPartitionQual: */ + List *rd_partcheck; /* partition CHECK quals */ + bool rd_partcheckvalid; /* true if list has been computed */ + MemoryContext rd_partcheckcxt; /* private cxt for rd_partcheck, if any */ + + /* data managed by RelationGetIndexList: */ + List *rd_indexlist; /* list of OIDs of indexes on relation */ + Oid rd_pkindex; /* OID of primary key, if any */ + Oid rd_replidindex; /* OID of replica identity index, if any */ + + /* data managed by RelationGetStatExtList: */ + List *rd_statlist; /* list of OIDs of extended stats */ + + /* data managed by RelationGetIndexAttrBitmap: */ + bool rd_attrsvalid; /* are bitmaps of attrs valid? */ + Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ + Bitmapset *rd_pkattr; /* cols included in primary key */ + Bitmapset *rd_idattr; /* included in replica identity index */ + Bitmapset *rd_hotblockingattr; /* cols blocking HOT update */ + Bitmapset *rd_summarizedattr; /* cols indexed by summarizing indexes */ + + PublicationDesc *rd_pubdesc; /* publication descriptor, or NULL */ + + /* + * rd_options is set whenever rd_rel is loaded into the relcache entry. + * Note that you can NOT look into rd_rel for this data. NULL means "use + * defaults". + */ + bytea *rd_options; /* parsed pg_class.reloptions */ + + /* + * Oid of the handler for this relation. For an index this is a function + * returning IndexAmRoutine, for table like relations a function returning + * TableAmRoutine. This is stored separately from rd_indam, rd_tableam as + * its lookup requires syscache access, but during relcache bootstrap we + * need to be able to initialize rd_tableam without syscache lookups. + */ + Oid rd_amhandler; /* OID of index AM's handler function */ + + /* + * Table access method. + */ + const struct TableAmRoutine *rd_tableam; + + /* These are non-NULL only for an index relation: */ + Form_pg_index rd_index; /* pg_index tuple describing this index */ + /* use "struct" here to avoid needing to include htup.h: */ + struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */ + + /* + * index access support info (used only for an index relation) + * + * Note: only default support procs for each opclass are cached, namely + * those with lefttype and righttype equal to the opclass's opcintype. The + * arrays are indexed by support function number, which is a sufficient + * identifier given that restriction. + */ + MemoryContext rd_indexcxt; /* private memory cxt for this stuff */ + /* use "struct" here to avoid needing to include amapi.h: */ + struct IndexAmRoutine *rd_indam; /* index AM's API struct */ + Oid *rd_opfamily; /* OIDs of op families for each index col */ + Oid *rd_opcintype; /* OIDs of opclass declared input data types */ + RegProcedure *rd_support; /* OIDs of support procedures */ + struct FmgrInfo *rd_supportinfo; /* lookup info for support procedures */ + int16 *rd_indoption; /* per-column AM-specific flags */ + List *rd_indexprs; /* index expression trees, if any */ + List *rd_indpred; /* index predicate tree, if any */ + Oid *rd_exclops; /* OIDs of exclusion operators, if any */ + Oid *rd_exclprocs; /* OIDs of exclusion ops' procs, if any */ + uint16 *rd_exclstrats; /* exclusion ops' strategy numbers, if any */ + Oid *rd_indcollation; /* OIDs of index collations */ + bytea **rd_opcoptions; /* parsed opclass-specific options */ + + /* + * rd_amcache is available for index and table AMs to cache private data + * about the relation. This must be just a cache since it may get reset + * at any time (in particular, it will get reset by a relcache inval + * message for the relation). If used, it must point to a single memory + * chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index + * relation. A relcache reset will include freeing that chunk and setting + * rd_amcache = NULL. + */ + void *rd_amcache; /* available for use by index/table AM */ + + /* + * foreign-table support + * + * rd_fdwroutine must point to a single memory chunk palloc'd in + * CacheMemoryContext. It will be freed and reset to NULL on a relcache + * reset. + */ + + /* use "struct" here to avoid needing to include fdwapi.h: */ + struct FdwRoutine *rd_fdwroutine; /* cached function pointers, or NULL */ + + /* + * Hack for CLUSTER, rewriting ALTER TABLE, etc: when writing a new + * version of a table, we need to make any toast pointers inserted into it + * have the existing toast table's OID, not the OID of the transient toast + * table. If rd_toastoid isn't InvalidOid, it is the OID to place in + * toast pointers inserted into this rel. (Note it's set on the new + * version of the main heap, not the toast table itself.) This also + * causes toast_save_datum() to try to preserve toast value OIDs. + */ + Oid rd_toastoid; /* Real TOAST table's OID, or InvalidOid */ + + bool pgstat_enabled; /* should relation stats be counted */ + /* use "struct" here to avoid needing to include pgstat.h: */ + struct PgStat_TableStatus *pgstat_info; /* statistics collection area */ +} RelationData; + + +/* + * ForeignKeyCacheInfo + * Information the relcache can cache about foreign key constraints + * + * This is basically just an image of relevant columns from pg_constraint. + * We make it a subclass of Node so that copyObject() can be used on a list + * of these, but we also ensure it is a "flat" object without substructure, + * so that list_free_deep() is sufficient to free such a list. + * The per-FK-column arrays can be fixed-size because we allow at most + * INDEX_MAX_KEYS columns in a foreign key constraint. + * + * Currently, we mostly cache fields of interest to the planner, but the set + * of fields has already grown the constraint OID for other uses. + */ +typedef struct ForeignKeyCacheInfo +{ + pg_node_attr(no_equal, no_read, no_query_jumble) + + NodeTag type; + /* oid of the constraint itself */ + Oid conoid; + /* relation constrained by the foreign key */ + Oid conrelid; + /* relation referenced by the foreign key */ + Oid confrelid; + /* number of columns in the foreign key */ + int nkeys; + + /* + * these arrays each have nkeys valid entries: + */ + /* cols in referencing table */ + AttrNumber conkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys)); + /* cols in referenced table */ + AttrNumber confkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys)); + /* PK = FK operator OIDs */ + Oid conpfeqop[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys)); +} ForeignKeyCacheInfo; + + +/* + * StdRdOptions + * Standard contents of rd_options for heaps. + * + * RelationGetFillFactor() and RelationGetTargetPageFreeSpace() can only + * be applied to relations that use this format or a superset for + * private options data. + */ + /* autovacuum-related reloptions. */ +typedef struct AutoVacOpts +{ + bool enabled; + int vacuum_threshold; + int vacuum_ins_threshold; + int analyze_threshold; + int vacuum_cost_limit; + int freeze_min_age; + int freeze_max_age; + int freeze_table_age; + int multixact_freeze_min_age; + int multixact_freeze_max_age; + int multixact_freeze_table_age; + int log_min_duration; + float8 vacuum_cost_delay; + float8 vacuum_scale_factor; + float8 vacuum_ins_scale_factor; + float8 analyze_scale_factor; +} AutoVacOpts; + +/* StdRdOptions->vacuum_index_cleanup values */ +typedef enum StdRdOptIndexCleanup +{ + STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0, + STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF, + STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON +} StdRdOptIndexCleanup; + +typedef struct StdRdOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int fillfactor; /* page fill factor in percent (0..100) */ + int toast_tuple_target; /* target for tuple toasting */ + AutoVacOpts autovacuum; /* autovacuum-related options */ + bool user_catalog_table; /* use as an additional catalog relation */ + int parallel_workers; /* max number of parallel workers */ + StdRdOptIndexCleanup vacuum_index_cleanup; /* controls index vacuuming */ + bool vacuum_truncate; /* enables vacuum to truncate a relation */ +} StdRdOptions; + +#define HEAP_MIN_FILLFACTOR 10 +#define HEAP_DEFAULT_FILLFACTOR 100 + +/* + * RelationGetToastTupleTarget + * Returns the relation's toast_tuple_target. Note multiple eval of argument! + */ +#define RelationGetToastTupleTarget(relation, defaulttarg) \ + ((relation)->rd_options ? \ + ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg)) + +/* + * RelationGetFillFactor + * Returns the relation's fillfactor. Note multiple eval of argument! + */ +#define RelationGetFillFactor(relation, defaultff) \ + ((relation)->rd_options ? \ + ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff)) + +/* + * RelationGetTargetPageUsage + * Returns the relation's desired space usage per page in bytes. + */ +#define RelationGetTargetPageUsage(relation, defaultff) \ + (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100) + +/* + * RelationGetTargetPageFreeSpace + * Returns the relation's desired freespace per page in bytes. + */ +#define RelationGetTargetPageFreeSpace(relation, defaultff) \ + (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100) + +/* + * RelationIsUsedAsCatalogTable + * Returns whether the relation should be treated as a catalog table + * from the pov of logical decoding. Note multiple eval of argument! + */ +#define RelationIsUsedAsCatalogTable(relation) \ + ((relation)->rd_options && \ + ((relation)->rd_rel->relkind == RELKIND_RELATION || \ + (relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \ + ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false) + +/* + * RelationGetParallelWorkers + * Returns the relation's parallel_workers reloption setting. + * Note multiple eval of argument! + */ +#define RelationGetParallelWorkers(relation, defaultpw) \ + ((relation)->rd_options ? \ + ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw)) + +/* ViewOptions->check_option values */ +typedef enum ViewOptCheckOption +{ + VIEW_OPTION_CHECK_OPTION_NOT_SET, + VIEW_OPTION_CHECK_OPTION_LOCAL, + VIEW_OPTION_CHECK_OPTION_CASCADED +} ViewOptCheckOption; + +/* + * ViewOptions + * Contents of rd_options for views + */ +typedef struct ViewOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + bool security_barrier; + bool security_invoker; + ViewOptCheckOption check_option; +} ViewOptions; + +/* + * RelationIsSecurityView + * Returns whether the relation is security view, or not. Note multiple + * eval of argument! + */ +#define RelationIsSecurityView(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ + (relation)->rd_options ? \ + ((ViewOptions *) (relation)->rd_options)->security_barrier : false) + +/* + * RelationHasSecurityInvoker + * Returns true if the relation has the security_invoker property set. + * Note multiple eval of argument! + */ +#define RelationHasSecurityInvoker(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ + (relation)->rd_options ? \ + ((ViewOptions *) (relation)->rd_options)->security_invoker : false) + +/* + * RelationHasCheckOption + * Returns true if the relation is a view defined with either the local + * or the cascaded check option. Note multiple eval of argument! + */ +#define RelationHasCheckOption(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ + (relation)->rd_options && \ + ((ViewOptions *) (relation)->rd_options)->check_option != \ + VIEW_OPTION_CHECK_OPTION_NOT_SET) + +/* + * RelationHasLocalCheckOption + * Returns true if the relation is a view defined with the local check + * option. Note multiple eval of argument! + */ +#define RelationHasLocalCheckOption(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ + (relation)->rd_options && \ + ((ViewOptions *) (relation)->rd_options)->check_option == \ + VIEW_OPTION_CHECK_OPTION_LOCAL) + +/* + * RelationHasCascadedCheckOption + * Returns true if the relation is a view defined with the cascaded check + * option. Note multiple eval of argument! + */ +#define RelationHasCascadedCheckOption(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ + (relation)->rd_options && \ + ((ViewOptions *) (relation)->rd_options)->check_option == \ + VIEW_OPTION_CHECK_OPTION_CASCADED) + +/* + * RelationIsValid + * True iff relation descriptor is valid. + */ +#define RelationIsValid(relation) PointerIsValid(relation) + +#define InvalidRelation ((Relation) NULL) + +/* + * RelationHasReferenceCountZero + * True iff relation reference count is zero. + * + * Note: + * Assumes relation descriptor is valid. + */ +#define RelationHasReferenceCountZero(relation) \ + ((bool)((relation)->rd_refcnt == 0)) + +/* + * RelationGetForm + * Returns pg_class tuple for a relation. + * + * Note: + * Assumes relation descriptor is valid. + */ +#define RelationGetForm(relation) ((relation)->rd_rel) + +/* + * RelationGetRelid + * Returns the OID of the relation + */ +#define RelationGetRelid(relation) ((relation)->rd_id) + +/* + * RelationGetNumberOfAttributes + * Returns the total number of attributes in a relation. + */ +#define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts) + +/* + * IndexRelationGetNumberOfAttributes + * Returns the number of attributes in an index. + */ +#define IndexRelationGetNumberOfAttributes(relation) \ + ((relation)->rd_index->indnatts) + +/* + * IndexRelationGetNumberOfKeyAttributes + * Returns the number of key attributes in an index. + */ +#define IndexRelationGetNumberOfKeyAttributes(relation) \ + ((relation)->rd_index->indnkeyatts) + +/* + * RelationGetDescr + * Returns tuple descriptor for a relation. + */ +#define RelationGetDescr(relation) ((relation)->rd_att) + +/* + * RelationGetRelationName + * Returns the rel's name. + * + * Note that the name is only unique within the containing namespace. + */ +#define RelationGetRelationName(relation) \ + (NameStr((relation)->rd_rel->relname)) + +/* + * RelationGetNamespace + * Returns the rel's namespace OID. + */ +#define RelationGetNamespace(relation) \ + ((relation)->rd_rel->relnamespace) + +/* + * RelationIsMapped + * True if the relation uses the relfilenumber map. Note multiple eval + * of argument! + */ +#define RelationIsMapped(relation) \ + (RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \ + ((relation)->rd_rel->relfilenode == InvalidRelFileNumber)) + +#ifndef FRONTEND +/* + * RelationGetSmgr + * Returns smgr file handle for a relation, opening it if needed. + * + * Very little code is authorized to touch rel->rd_smgr directly. Instead + * use this function to fetch its value. + * + * Note: since a relcache flush can cause the file handle to be closed again, + * it's unwise to hold onto the pointer returned by this function for any + * long period. Recommended practice is to just re-execute RelationGetSmgr + * each time you need to access the SMgrRelation. It's quite cheap in + * comparison to whatever an smgr function is going to do. + */ +static inline SMgrRelation +RelationGetSmgr(Relation rel) +{ + if (unlikely(rel->rd_smgr == NULL)) + smgrsetowner(&(rel->rd_smgr), smgropen(rel->rd_locator, rel->rd_backend)); + return rel->rd_smgr; +} + +/* + * RelationCloseSmgr + * Close the relation at the smgr level, if not already done. + */ +static inline void +RelationCloseSmgr(Relation relation) +{ + if (relation->rd_smgr != NULL) + smgrclose(relation->rd_smgr); + + /* smgrclose should unhook from owner pointer */ + Assert(relation->rd_smgr == NULL); +} +#endif /* !FRONTEND */ + +/* + * RelationGetTargetBlock + * Fetch relation's current insertion target block. + * + * Returns InvalidBlockNumber if there is no current target block. Note + * that the target block status is discarded on any smgr-level invalidation, + * so there's no need to re-open the smgr handle if it's not currently open. + */ +#define RelationGetTargetBlock(relation) \ + ( (relation)->rd_smgr != NULL ? (relation)->rd_smgr->smgr_targblock : InvalidBlockNumber ) + +/* + * RelationSetTargetBlock + * Set relation's current insertion target block. + */ +#define RelationSetTargetBlock(relation, targblock) \ + do { \ + RelationGetSmgr(relation)->smgr_targblock = (targblock); \ + } while (0) + +/* + * RelationIsPermanent + * True if relation is permanent. + */ +#define RelationIsPermanent(relation) \ + ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT) + +/* + * RelationNeedsWAL + * True if relation needs WAL. + * + * Returns false if wal_level = minimal and this relation is created or + * truncated in the current transaction. See "Skipping WAL for New + * RelFileLocator" in src/backend/access/transam/README. + */ +#define RelationNeedsWAL(relation) \ + (RelationIsPermanent(relation) && (XLogIsNeeded() || \ + (relation->rd_createSubid == InvalidSubTransactionId && \ + relation->rd_firstRelfilelocatorSubid == InvalidSubTransactionId))) + +/* + * RelationUsesLocalBuffers + * True if relation's pages are stored in local buffers. + */ +#define RelationUsesLocalBuffers(relation) \ + ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP) + +/* + * RELATION_IS_LOCAL + * If a rel is either temp or newly created in the current transaction, + * it can be assumed to be accessible only to the current backend. + * This is typically used to decide that we can skip acquiring locks. + * + * Beware of multiple eval of argument + */ +#define RELATION_IS_LOCAL(relation) \ + ((relation)->rd_islocaltemp || \ + (relation)->rd_createSubid != InvalidSubTransactionId) + +/* + * RELATION_IS_OTHER_TEMP + * Test for a temporary relation that belongs to some other session. + * + * Beware of multiple eval of argument + */ +#define RELATION_IS_OTHER_TEMP(relation) \ + ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP && \ + !(relation)->rd_islocaltemp) + + +/* + * RelationIsScannable + * Currently can only be false for a materialized view which has not been + * populated by its query. This is likely to get more complicated later, + * so use a macro which looks like a function. + */ +#define RelationIsScannable(relation) ((relation)->rd_rel->relispopulated) + +/* + * RelationIsPopulated + * Currently, we don't physically distinguish the "populated" and + * "scannable" properties of matviews, but that may change later. + * Hence, use the appropriate one of these macros in code tests. + */ +#define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated) + +/* + * RelationIsAccessibleInLogicalDecoding + * True if we need to log enough information to have access via + * decoding snapshot. + */ +#define RelationIsAccessibleInLogicalDecoding(relation) \ + (XLogLogicalInfoActive() && \ + RelationNeedsWAL(relation) && \ + (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation))) + +/* + * RelationIsLogicallyLogged + * True if we need to log enough information to extract the data from the + * WAL stream. + * + * We don't log information for unlogged tables (since they don't WAL log + * anyway), for foreign tables (since they don't WAL log, either), + * and for system tables (their content is hard to make sense of, and + * it would complicate decoding slightly for little gain). Note that we *do* + * log information for user defined catalog tables since they presumably are + * interesting to the user... + */ +#define RelationIsLogicallyLogged(relation) \ + (XLogLogicalInfoActive() && \ + RelationNeedsWAL(relation) && \ + (relation)->rd_rel->relkind != RELKIND_FOREIGN_TABLE && \ + !IsCatalogRelation(relation)) + +/* routines in utils/cache/relcache.c */ +extern void RelationIncrementReferenceCount(Relation rel); +extern void RelationDecrementReferenceCount(Relation rel); + +#endif /* REL_H */ diff --git a/install/include/postgresql/server/utils/relcache.h b/install/include/postgresql/server/utils/relcache.h new file mode 100644 index 00000000000..10a91c986d1 --- /dev/null +++ b/install/include/postgresql/server/utils/relcache.h @@ -0,0 +1,166 @@ +/*------------------------------------------------------------------------- + * + * relcache.h + * Relation descriptor cache definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/relcache.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELCACHE_H +#define RELCACHE_H + +#include "access/tupdesc.h" +#include "common/relpath.h" +#include "nodes/bitmapset.h" + + +/* + * Name of relcache init file(s), used to speed up backend startup + */ +#define RELCACHE_INIT_FILENAME "pg_internal.init" + +typedef struct RelationData *Relation; + +/* ---------------- + * RelationPtr is used in the executor to support index scans + * where we have to keep track of several index relations in an + * array. -cim 9/10/89 + * ---------------- + */ +typedef Relation *RelationPtr; + +/* + * Routines to open (lookup) and close a relcache entry + */ +#ifdef USE_ASSERT_CHECKING +extern void AssertCouldGetRelation(void); +#else +static inline void +AssertCouldGetRelation(void) +{ +} +#endif +extern Relation RelationIdGetRelation(Oid relationId); +extern void RelationClose(Relation relation); + +/* + * Routines to compute/retrieve additional cached information + */ +extern List *RelationGetFKeyList(Relation relation); +extern List *RelationGetIndexList(Relation relation); +extern List *RelationGetStatExtList(Relation relation); +extern Oid RelationGetPrimaryKeyIndex(Relation relation); +extern Oid RelationGetReplicaIndex(Relation relation); +extern List *RelationGetIndexExpressions(Relation relation); +extern List *RelationGetDummyIndexExpressions(Relation relation); +extern List *RelationGetIndexPredicate(Relation relation); +extern Datum *RelationGetIndexRawAttOptions(Relation indexrel); +extern bytea **RelationGetIndexAttOptions(Relation relation, bool copy); + +/* + * Which set of columns to return by RelationGetIndexAttrBitmap. + */ +typedef enum IndexAttrBitmapKind +{ + INDEX_ATTR_BITMAP_KEY, + INDEX_ATTR_BITMAP_PRIMARY_KEY, + INDEX_ATTR_BITMAP_IDENTITY_KEY, + INDEX_ATTR_BITMAP_HOT_BLOCKING, + INDEX_ATTR_BITMAP_SUMMARIZED +} IndexAttrBitmapKind; + +extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation, + IndexAttrBitmapKind attrKind); + +extern Bitmapset *RelationGetIdentityKeyBitmap(Relation relation); + +extern void RelationGetExclusionInfo(Relation indexRelation, + Oid **operators, + Oid **procs, + uint16 **strategies); + +extern void RelationInitIndexAccessInfo(Relation relation); + +/* caller must include pg_publication.h */ +struct PublicationDesc; +extern void RelationBuildPublicationDesc(Relation relation, + struct PublicationDesc *pubdesc); + +extern void RelationInitTableAccessMethod(Relation relation); + +/* + * Routines to support ereport() reports of relation-related errors + */ +extern int errtable(Relation rel); +extern int errtablecol(Relation rel, int attnum); +extern int errtablecolname(Relation rel, const char *colname); +extern int errtableconstraint(Relation rel, const char *conname); + +/* + * Routines for backend startup + */ +extern void RelationCacheInitialize(void); +extern void RelationCacheInitializePhase2(void); +extern void RelationCacheInitializePhase3(void); + +/* + * Routine to create a relcache entry for an about-to-be-created relation + */ +extern Relation RelationBuildLocalRelation(const char *relname, + Oid relnamespace, + TupleDesc tupDesc, + Oid relid, + Oid accessmtd, + RelFileNumber relfilenumber, + Oid reltablespace, + bool shared_relation, + bool mapped_relation, + char relpersistence, + char relkind); + +/* + * Routines to manage assignment of new relfilenumber to a relation + */ +extern void RelationSetNewRelfilenumber(Relation relation, char persistence); +extern void RelationAssumeNewRelfilelocator(Relation relation); + +/* + * Routines for flushing/rebuilding relcache entries in various scenarios + */ +extern void RelationForgetRelation(Oid rid); + +extern void RelationCacheInvalidateEntry(Oid relationId); + +extern void RelationCacheInvalidate(bool debug_discard); + +extern void RelationCloseSmgrByOid(Oid relationId); + +#ifdef USE_ASSERT_CHECKING +extern void AssertPendingSyncs_RelationCache(void); +#else +#define AssertPendingSyncs_RelationCache() do {} while (0) +#endif +extern void AtEOXact_RelationCache(bool isCommit); +extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, + SubTransactionId parentSubid); + +/* + * Routines to help manage rebuilding of relcache init files + */ +extern bool RelationIdIsInInitFile(Oid relationId); +extern void RelationCacheInitFilePreInvalidate(void); +extern void RelationCacheInitFilePostInvalidate(void); +extern void RelationCacheInitFileRemove(void); + +/* should be used only by relcache.c and catcache.c */ +extern PGDLLIMPORT bool criticalRelcachesBuilt; + +/* should be used only by relcache.c and postinit.c */ +extern PGDLLIMPORT bool criticalSharedRelcachesBuilt; + +#endif /* RELCACHE_H */ diff --git a/install/include/postgresql/server/utils/relfilenumbermap.h b/install/include/postgresql/server/utils/relfilenumbermap.h new file mode 100644 index 00000000000..d9b280d3a10 --- /dev/null +++ b/install/include/postgresql/server/utils/relfilenumbermap.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * relfilenumbermap.h + * relfilenumber to oid mapping cache. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/relfilenumbermap.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELFILENUMBERMAP_H +#define RELFILENUMBERMAP_H + +#include "common/relpath.h" + +extern Oid RelidByRelfilenumber(Oid reltablespace, + RelFileNumber relfilenumber); + +#endif /* RELFILENUMBERMAP_H */ diff --git a/install/include/postgresql/server/utils/relmapper.h b/install/include/postgresql/server/utils/relmapper.h new file mode 100644 index 00000000000..5c173bdbb3c --- /dev/null +++ b/install/include/postgresql/server/utils/relmapper.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * relmapper.h + * Catalog-to-filenumber mapping + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/relmapper.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELMAPPER_H +#define RELMAPPER_H + +#include "access/xlogreader.h" +#include "lib/stringinfo.h" + +/* ---------------- + * relmap-related XLOG entries + * ---------------- + */ + +#define XLOG_RELMAP_UPDATE 0x00 + +typedef struct xl_relmap_update +{ + Oid dbid; /* database ID, or 0 for shared map */ + Oid tsid; /* database's tablespace, or pg_global */ + int32 nbytes; /* size of relmap data */ + char data[FLEXIBLE_ARRAY_MEMBER]; +} xl_relmap_update; + +#define MinSizeOfRelmapUpdate offsetof(xl_relmap_update, data) + + +extern RelFileNumber RelationMapOidToFilenumber(Oid relationId, bool shared); + +extern Oid RelationMapFilenumberToOid(RelFileNumber filenumber, bool shared); +extern RelFileNumber RelationMapOidToFilenumberForDatabase(char *dbpath, + Oid relationId); +extern void RelationMapCopy(Oid dbid, Oid tsid, char *srcdbpath, + char *dstdbpath); +extern void RelationMapUpdateMap(Oid relationId, RelFileNumber fileNumber, + bool shared, bool immediate); + +extern void RelationMapRemoveMapping(Oid relationId); + +extern void RelationMapInvalidate(bool shared); +extern void RelationMapInvalidateAll(void); + +extern void AtCCI_RelationMap(void); +extern void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker); +extern void AtPrepare_RelationMap(void); + +extern void CheckPointRelationMap(void); + +extern void RelationMapFinishBootstrap(void); + +extern void RelationMapInitialize(void); +extern void RelationMapInitializePhase2(void); +extern void RelationMapInitializePhase3(void); + +extern Size EstimateRelationMapSpace(void); +extern void SerializeRelationMap(Size maxSize, char *startAddress); +extern void RestoreRelationMap(char *startAddress); + +extern void relmap_redo(XLogReaderState *record); +extern void relmap_desc(StringInfo buf, XLogReaderState *record); +extern const char *relmap_identify(uint8 info); + +#endif /* RELMAPPER_H */ diff --git a/install/include/postgresql/server/utils/relptr.h b/install/include/postgresql/server/utils/relptr.h new file mode 100644 index 00000000000..365cea14b93 --- /dev/null +++ b/install/include/postgresql/server/utils/relptr.h @@ -0,0 +1,93 @@ +/*------------------------------------------------------------------------- + * + * relptr.h + * This file contains basic declarations for relative pointers. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/relptr.h + * + *------------------------------------------------------------------------- + */ + +#ifndef RELPTR_H +#define RELPTR_H + +/* + * Relative pointers are intended to be used when storing an address that may + * be relative either to the base of the process's address space or some + * dynamic shared memory segment mapped therein. + * + * The idea here is that you declare a relative pointer as relptr(type) + * and then use relptr_access to dereference it and relptr_store to change + * it. The use of a union here is a hack, because what's stored in the + * relptr is always a Size, never an actual pointer. But including a pointer + * in the union allows us to use stupid macro tricks to provide some measure + * of type-safety. + */ +#define relptr(type) union { type *relptr_type; Size relptr_off; } + +/* + * pgindent gets confused by declarations that use "relptr(type)" directly, + * so preferred style is to write + * typedef struct ... SomeStruct; + * relptr_declare(SomeStruct, RelptrSomeStruct); + * and then declare pointer variables as "RelptrSomeStruct someptr". + */ +#define relptr_declare(type, relptrtype) \ + typedef relptr(type) relptrtype + +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define relptr_access(base, rp) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + (__typeof__((rp).relptr_type)) ((rp).relptr_off == 0 ? NULL : \ + (base) + (rp).relptr_off - 1)) +#else +/* + * If we don't have __builtin_types_compatible_p, assume we might not have + * __typeof__ either. + */ +#define relptr_access(base, rp) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + (void *) ((rp).relptr_off == 0 ? NULL : (base) + (rp).relptr_off - 1)) +#endif + +#define relptr_is_null(rp) \ + ((rp).relptr_off == 0) + +#define relptr_offset(rp) \ + ((rp).relptr_off - 1) + +/* We use this inline to avoid double eval of "val" in relptr_store */ +static inline Size +relptr_store_eval(char *base, char *val) +{ + if (val == NULL) + return 0; + else + { + Assert(val >= base); + return val - base + 1; + } +} + +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define relptr_store(base, rp, val) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + AssertVariableIsOfTypeMacro(val, __typeof__((rp).relptr_type)), \ + (rp).relptr_off = relptr_store_eval((base), (char *) (val))) +#else +/* + * If we don't have __builtin_types_compatible_p, assume we might not have + * __typeof__ either. + */ +#define relptr_store(base, rp, val) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + (rp).relptr_off = relptr_store_eval((base), (char *) (val))) +#endif + +#define relptr_copy(rp1, rp2) \ + ((rp1).relptr_off = (rp2).relptr_off) + +#endif /* RELPTR_H */ diff --git a/install/include/postgresql/server/utils/reltrigger.h b/install/include/postgresql/server/utils/reltrigger.h new file mode 100644 index 00000000000..df9a2fb690e --- /dev/null +++ b/install/include/postgresql/server/utils/reltrigger.h @@ -0,0 +1,81 @@ +/*------------------------------------------------------------------------- + * + * reltrigger.h + * POSTGRES relation trigger definitions. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/reltrigger.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELTRIGGER_H +#define RELTRIGGER_H + + +/* + * These struct really belongs to trigger.h, but we put it separately so that + * it can be cleanly included in rel.h and other places. + */ + +typedef struct Trigger +{ + Oid tgoid; /* OID of trigger (pg_trigger row) */ + /* Remaining fields are copied from pg_trigger, see pg_trigger.h */ + char *tgname; + Oid tgfoid; + int16 tgtype; + char tgenabled; + bool tgisinternal; + bool tgisclone; + 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; + +typedef struct TriggerDesc +{ + Trigger *triggers; /* array of Trigger structs */ + int numtriggers; /* number of array entries */ + + /* + * These flags indicate whether the array contains at least one of each + * type of trigger. We use these to skip searching the array if not. + */ + bool trig_insert_before_row; + bool trig_insert_after_row; + bool trig_insert_instead_row; + bool trig_insert_before_statement; + bool trig_insert_after_statement; + bool trig_update_before_row; + bool trig_update_after_row; + bool trig_update_instead_row; + bool trig_update_before_statement; + bool trig_update_after_statement; + bool trig_delete_before_row; + bool trig_delete_after_row; + bool trig_delete_instead_row; + bool trig_delete_before_statement; + bool trig_delete_after_statement; + /* there are no row-level truncate triggers */ + bool trig_truncate_before_statement; + bool trig_truncate_after_statement; + /* Is there at least one trigger specifying each transition relation? */ + bool trig_insert_new_table; + bool trig_update_old_table; + bool trig_update_new_table; + bool trig_delete_old_table; +} TriggerDesc; + +#endif /* RELTRIGGER_H */ diff --git a/install/include/postgresql/server/utils/resowner.h b/install/include/postgresql/server/utils/resowner.h new file mode 100644 index 00000000000..cd070b6080e --- /dev/null +++ b/install/include/postgresql/server/utils/resowner.h @@ -0,0 +1,86 @@ +/*------------------------------------------------------------------------- + * + * resowner.h + * POSTGRES resource owner definitions. + * + * Query-lifespan resources are tracked by associating them with + * ResourceOwner objects. This provides a simple mechanism for ensuring + * that such resources are freed at the right time. + * See utils/resowner/README for more info. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/resowner.h + * + *------------------------------------------------------------------------- + */ +#ifndef RESOWNER_H +#define RESOWNER_H + + +/* + * ResourceOwner objects are an opaque data structure known only within + * resowner.c. + */ +typedef struct ResourceOwnerData *ResourceOwner; + + +/* + * Globally known ResourceOwners + */ +extern PGDLLIMPORT ResourceOwner CurrentResourceOwner; +extern PGDLLIMPORT ResourceOwner CurTransactionResourceOwner; +extern PGDLLIMPORT ResourceOwner TopTransactionResourceOwner; +extern PGDLLIMPORT ResourceOwner AuxProcessResourceOwner; + +/* + * Resource releasing is done in three phases: pre-locks, locks, and + * post-locks. The pre-lock phase must release any resources that are + * visible to other backends (such as pinned buffers); this ensures that + * when we release a lock that another backend may be waiting on, it will + * see us as being fully out of our transaction. The post-lock phase + * should be used for backend-internal cleanup. + */ +typedef enum +{ + RESOURCE_RELEASE_BEFORE_LOCKS, + RESOURCE_RELEASE_LOCKS, + RESOURCE_RELEASE_AFTER_LOCKS +} ResourceReleasePhase; + +/* + * Dynamically loaded modules can get control during ResourceOwnerRelease + * by providing a callback of this form. + */ +typedef void (*ResourceReleaseCallback) (ResourceReleasePhase phase, + bool isCommit, + bool isTopLevel, + void *arg); + + +/* + * Functions in resowner.c + */ + +/* generic routines */ +extern ResourceOwner ResourceOwnerCreate(ResourceOwner parent, + const char *name); +extern void ResourceOwnerRelease(ResourceOwner owner, + ResourceReleasePhase phase, + bool isCommit, + bool isTopLevel); +extern void ResourceOwnerReleaseAllPlanCacheRefs(ResourceOwner owner); +extern void ResourceOwnerDelete(ResourceOwner owner); +extern ResourceOwner ResourceOwnerGetParent(ResourceOwner owner); +extern void ResourceOwnerNewParent(ResourceOwner owner, + ResourceOwner newparent); +extern void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, + void *arg); +extern void UnregisterResourceReleaseCallback(ResourceReleaseCallback callback, + void *arg); +extern void CreateAuxProcessResourceOwner(void); +extern void ReleaseAuxProcessResources(bool isCommit); + +#endif /* RESOWNER_H */ diff --git a/install/include/postgresql/server/utils/resowner_private.h b/install/include/postgresql/server/utils/resowner_private.h new file mode 100644 index 00000000000..ae58438ec76 --- /dev/null +++ b/install/include/postgresql/server/utils/resowner_private.h @@ -0,0 +1,117 @@ +/*------------------------------------------------------------------------- + * + * resowner_private.h + * POSTGRES resource owner private definitions. + * + * See utils/resowner/README for more info. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/resowner_private.h + * + *------------------------------------------------------------------------- + */ +#ifndef RESOWNER_PRIVATE_H +#define RESOWNER_PRIVATE_H + +#include "storage/dsm.h" +#include "storage/fd.h" +#include "storage/lock.h" +#include "utils/catcache.h" +#include "utils/plancache.h" +#include "utils/resowner.h" +#include "utils/snapshot.h" + + +/* support for buffer refcount management */ +extern void ResourceOwnerEnlargeBuffers(ResourceOwner owner); +extern void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer); +extern void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer); + +/* support for IO-in-progress management */ +extern void ResourceOwnerEnlargeBufferIOs(ResourceOwner owner); +extern void ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer); +extern void ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer); + +/* support for local lock management */ +extern void ResourceOwnerRememberLock(ResourceOwner owner, LOCALLOCK *locallock); +extern void ResourceOwnerForgetLock(ResourceOwner owner, LOCALLOCK *locallock); + +/* support for catcache refcount management */ +extern void ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner); +extern void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, + HeapTuple tuple); +extern void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, + HeapTuple tuple); +extern void ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner); +extern void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, + CatCList *list); +extern void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, + CatCList *list); + +/* support for relcache refcount management */ +extern void ResourceOwnerEnlargeRelationRefs(ResourceOwner owner); +extern void ResourceOwnerRememberRelationRef(ResourceOwner owner, + Relation rel); +extern void ResourceOwnerForgetRelationRef(ResourceOwner owner, + Relation rel); + +/* support for plancache refcount management */ +extern void ResourceOwnerEnlargePlanCacheRefs(ResourceOwner owner); +extern void ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, + CachedPlan *plan); +extern void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, + CachedPlan *plan); + +/* support for tupledesc refcount management */ +extern void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner); +extern void ResourceOwnerRememberTupleDesc(ResourceOwner owner, + TupleDesc tupdesc); +extern void ResourceOwnerForgetTupleDesc(ResourceOwner owner, + TupleDesc tupdesc); + +/* support for snapshot refcount management */ +extern void ResourceOwnerEnlargeSnapshots(ResourceOwner owner); +extern void ResourceOwnerRememberSnapshot(ResourceOwner owner, + Snapshot snapshot); +extern void ResourceOwnerForgetSnapshot(ResourceOwner owner, + Snapshot snapshot); + +/* support for temporary file management */ +extern void ResourceOwnerEnlargeFiles(ResourceOwner owner); +extern void ResourceOwnerRememberFile(ResourceOwner owner, + File file); +extern void ResourceOwnerForgetFile(ResourceOwner owner, + File file); + +/* support for dynamic shared memory management */ +extern void ResourceOwnerEnlargeDSMs(ResourceOwner owner); +extern void ResourceOwnerRememberDSM(ResourceOwner owner, + dsm_segment *); +extern void ResourceOwnerForgetDSM(ResourceOwner owner, + dsm_segment *); + +/* support for JITContext management */ +extern void ResourceOwnerEnlargeJIT(ResourceOwner owner); +extern void ResourceOwnerRememberJIT(ResourceOwner owner, + Datum handle); +extern void ResourceOwnerForgetJIT(ResourceOwner owner, + Datum handle); + +/* support for cryptohash context management */ +extern void ResourceOwnerEnlargeCryptoHash(ResourceOwner owner); +extern void ResourceOwnerRememberCryptoHash(ResourceOwner owner, + Datum handle); +extern void ResourceOwnerForgetCryptoHash(ResourceOwner owner, + Datum handle); + +/* support for HMAC context management */ +extern void ResourceOwnerEnlargeHMAC(ResourceOwner owner); +extern void ResourceOwnerRememberHMAC(ResourceOwner owner, + Datum handle); +extern void ResourceOwnerForgetHMAC(ResourceOwner owner, + Datum handle); + +#endif /* RESOWNER_PRIVATE_H */ diff --git a/install/include/postgresql/server/utils/rls.h b/install/include/postgresql/server/utils/rls.h new file mode 100644 index 00000000000..1e95f83ef35 --- /dev/null +++ b/install/include/postgresql/server/utils/rls.h @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------- + * + * rls.h + * Header file for Row Level Security (RLS) utility commands to be used + * with the rowsecurity feature. + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/include/utils/rls.h + * + *------------------------------------------------------------------------- + */ +#ifndef RLS_H +#define RLS_H + +/* GUC variable */ +extern PGDLLIMPORT bool row_security; + +/* + * Used by callers of check_enable_rls. + * + * RLS could be completely disabled on the tables involved in the query, + * which is the simple case, or it may depend on the current environment + * (the role which is running the query or the value of the row_security + * GUC), or it might be simply enabled as usual. + * + * If RLS isn't on the table involved then RLS_NONE is returned to indicate + * that we don't need to worry about invalidating the query plan for RLS + * reasons. If RLS is on the table, but we are bypassing it for now, then + * we return RLS_NONE_ENV to indicate that, if the environment changes, + * we need to invalidate and replan. Finally, if RLS should be turned on + * for the query, then we return RLS_ENABLED, which means we also need to + * invalidate if the environment changes. + * + * Note that RLS_ENABLED will also be returned if noError is true + * (indicating that the caller simply want to know if RLS should be applied + * for this user but doesn't want an error thrown if it is; this is used + * by other error cases where we're just trying to decide if data from the + * table should be passed back to the user or not). + */ +enum CheckEnableRlsResult +{ + RLS_NONE, + RLS_NONE_ENV, + RLS_ENABLED +}; + +extern int check_enable_rls(Oid relid, Oid checkAsUser, bool noError); + +#endif /* RLS_H */ diff --git a/install/include/postgresql/server/utils/ruleutils.h b/install/include/postgresql/server/utils/ruleutils.h new file mode 100644 index 00000000000..b006d9d475e --- /dev/null +++ b/install/include/postgresql/server/utils/ruleutils.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + * + * ruleutils.h + * Declarations for ruleutils.c + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/ruleutils.h + * + *------------------------------------------------------------------------- + */ +#ifndef RULEUTILS_H +#define RULEUTILS_H + +#include "nodes/nodes.h" +#include "nodes/parsenodes.h" +#include "nodes/pg_list.h" + +struct Plan; /* avoid including plannodes.h here */ +struct PlannedStmt; + +/* Flags for pg_get_indexdef_columns_extended() */ +#define RULE_INDEXDEF_PRETTY 0x01 +#define RULE_INDEXDEF_KEYS_ONLY 0x02 /* ignore included attributes */ + +extern char *pg_get_indexdef_string(Oid indexrelid); +extern char *pg_get_indexdef_columns(Oid indexrelid, bool pretty); +extern char *pg_get_indexdef_columns_extended(Oid indexrelid, + bits16 flags); +extern char *pg_get_querydef(Query *query, bool pretty); + +extern char *pg_get_partkeydef_columns(Oid relid, bool pretty); +extern char *pg_get_partconstrdef_string(Oid partitionId, char *aliasname); + +extern char *pg_get_constraintdef_command(Oid constraintId); +extern char *deparse_expression(Node *expr, List *dpcontext, + bool forceprefix, bool showimplicit); +extern List *deparse_context_for(const char *aliasname, Oid relid); +extern List *deparse_context_for_plan_tree(struct PlannedStmt *pstmt, + List *rtable_names); +extern List *set_deparse_context_plan(List *dpcontext, + struct Plan *plan, List *ancestors); +extern List *select_rtable_names_for_explain(List *rtable, + Bitmapset *rels_used); +extern char *generate_collation_name(Oid collid); +extern char *generate_opclass_name(Oid opclass); +extern char *get_range_partbound_string(List *bound_datums); + +extern char *pg_get_statisticsobjdef_string(Oid statextid); + +#endif /* RULEUTILS_H */ diff --git a/install/include/postgresql/server/utils/sampling.h b/install/include/postgresql/server/utils/sampling.h new file mode 100644 index 00000000000..e26944887eb --- /dev/null +++ b/install/include/postgresql/server/utils/sampling.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * sampling.h + * definitions for sampling functions + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/sampling.h + * + *------------------------------------------------------------------------- + */ +#ifndef SAMPLING_H +#define SAMPLING_H + +#include "common/pg_prng.h" +#include "storage/block.h" /* for typedef BlockNumber */ + + +/* Random generator for sampling code */ +extern void sampler_random_init_state(uint32 seed, + pg_prng_state *randstate); +extern double sampler_random_fract(pg_prng_state *randstate); + +/* Block sampling methods */ + +/* Data structure for Algorithm S from Knuth 3.4.2 */ +typedef struct +{ + BlockNumber N; /* number of blocks, known in advance */ + int n; /* desired sample size */ + BlockNumber t; /* current block number */ + int m; /* blocks selected so far */ + pg_prng_state randstate; /* random generator state */ +} BlockSamplerData; + +typedef BlockSamplerData *BlockSampler; + +extern BlockNumber BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, + int samplesize, uint32 randseed); +extern bool BlockSampler_HasMore(BlockSampler bs); +extern BlockNumber BlockSampler_Next(BlockSampler bs); + +/* Reservoir sampling methods */ + +typedef struct +{ + double W; + pg_prng_state randstate; /* random generator state */ +} ReservoirStateData; + +typedef ReservoirStateData *ReservoirState; + +extern void reservoir_init_selection_state(ReservoirState rs, int n); +extern double reservoir_get_next_S(ReservoirState rs, double t, int n); + +/* Old API, still in use by assorted FDWs */ +/* For backwards compatibility, these declarations are duplicated in vacuum.h */ + +extern double anl_random_fract(void); +extern double anl_init_selection_state(int n); +extern double anl_get_next_S(double t, int n, double *stateptr); + +#endif /* SAMPLING_H */ diff --git a/install/include/postgresql/server/utils/selfuncs.h b/install/include/postgresql/server/utils/selfuncs.h new file mode 100644 index 00000000000..28d6be59061 --- /dev/null +++ b/install/include/postgresql/server/utils/selfuncs.h @@ -0,0 +1,243 @@ +/*------------------------------------------------------------------------- + * + * selfuncs.h + * Selectivity functions for standard operators, and assorted + * infrastructure for selectivity and cost estimation. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/selfuncs.h + * + *------------------------------------------------------------------------- + */ +#ifndef SELFUNCS_H +#define SELFUNCS_H + +#include "access/htup.h" +#include "fmgr.h" +#include "nodes/pathnodes.h" + + +/* + * Note: the default selectivity estimates are not chosen entirely at random. + * We want them to be small enough to ensure that indexscans will be used if + * available, for typical table densities of ~100 tuples/page. Thus, for + * example, 0.01 is not quite small enough, since that makes it appear that + * nearly all pages will be hit anyway. Also, since we sometimes estimate + * eqsel as 1/num_distinct, we probably want DEFAULT_NUM_DISTINCT to equal + * 1/DEFAULT_EQ_SEL. + */ + +/* default selectivity estimate for equalities such as "A = b" */ +#define DEFAULT_EQ_SEL 0.005 + +/* default selectivity estimate for inequalities such as "A < b" */ +#define DEFAULT_INEQ_SEL 0.3333333333333333 + +/* default selectivity estimate for range inequalities "A > b AND A < c" */ +#define DEFAULT_RANGE_INEQ_SEL 0.005 + +/* default selectivity estimate for multirange inequalities "A > b AND A < c" */ +#define DEFAULT_MULTIRANGE_INEQ_SEL 0.005 + +/* default selectivity estimate for pattern-match operators such as LIKE */ +#define DEFAULT_MATCH_SEL 0.005 + +/* default selectivity estimate for other matching operators */ +#define DEFAULT_MATCHING_SEL 0.010 + +/* default number of distinct values in a table */ +#define DEFAULT_NUM_DISTINCT 200 + +/* default selectivity estimate for boolean and null test nodes */ +#define DEFAULT_UNK_SEL 0.005 +#define DEFAULT_NOT_UNK_SEL (1.0 - DEFAULT_UNK_SEL) + + +/* + * Clamp a computed probability estimate (which may suffer from roundoff or + * estimation errors) to valid range. Argument must be a float variable. + */ +#define CLAMP_PROBABILITY(p) \ + do { \ + if (p < 0.0) \ + p = 0.0; \ + else if (p > 1.0) \ + p = 1.0; \ + } while (0) + +/* + * A set of flags which some selectivity estimation functions can pass back to + * callers to provide further details about some assumptions which were made + * during the estimation. + */ +#define SELFLAG_USED_DEFAULT (1 << 0) /* Estimation fell back on one + * of the DEFAULTs as defined + * above. */ + +typedef struct EstimationInfo +{ + uint32 flags; /* Flags, as defined above to mark special + * properties of the estimation. */ +} EstimationInfo; + +/* Return data from examine_variable and friends */ +typedef struct VariableStatData +{ + Node *var; /* the Var or expression tree */ + RelOptInfo *rel; /* Relation, or NULL if not identifiable */ + HeapTuple statsTuple; /* pg_statistic tuple, or NULL if none */ + /* NB: if statsTuple!=NULL, it must be freed when caller is done */ + void (*freefunc) (HeapTuple tuple); /* how to free statsTuple */ + Oid vartype; /* exposed type of expression */ + Oid atttype; /* actual type (after stripping relabel) */ + int32 atttypmod; /* actual typmod (after stripping relabel) */ + bool isunique; /* matches unique index or DISTINCT clause */ + bool acl_ok; /* true if user has SELECT privilege on all + * rows from the table or column */ +} VariableStatData; + +#define ReleaseVariableStats(vardata) \ + do { \ + if (HeapTupleIsValid((vardata).statsTuple)) \ + (vardata).freefunc((vardata).statsTuple); \ + } while(0) + + +/* + * genericcostestimate is a general-purpose estimator that can be used for + * most index types. In some cases we use genericcostestimate as the base + * code and then incorporate additional index-type-specific knowledge in + * the type-specific calling function. To avoid code duplication, we make + * genericcostestimate return a number of intermediate values as well as + * its preliminary estimates of the output cost values. The GenericCosts + * struct includes all these values. + * + * Callers should initialize all fields of GenericCosts to zero. In addition, + * they can set numIndexTuples to some positive value if they have a better + * than default way of estimating the number of leaf index tuples visited. + */ +typedef struct +{ + /* These are the values the cost estimator must return to the planner */ + Cost indexStartupCost; /* index-related startup cost */ + Cost indexTotalCost; /* total index-related scan cost */ + Selectivity indexSelectivity; /* selectivity of index */ + double indexCorrelation; /* order correlation of index */ + + /* Intermediate values we obtain along the way */ + double numIndexPages; /* number of leaf pages visited */ + double numIndexTuples; /* number of leaf tuples visited */ + double spc_random_page_cost; /* relevant random_page_cost value */ + double num_sa_scans; /* # indexscans from ScalarArrayOpExprs */ +} GenericCosts; + +/* Hooks for plugins to get control when we ask for stats */ +typedef bool (*get_relation_stats_hook_type) (PlannerInfo *root, + RangeTblEntry *rte, + AttrNumber attnum, + VariableStatData *vardata); +extern PGDLLIMPORT get_relation_stats_hook_type get_relation_stats_hook; +typedef bool (*get_index_stats_hook_type) (PlannerInfo *root, + Oid indexOid, + AttrNumber indexattnum, + VariableStatData *vardata); +extern PGDLLIMPORT get_index_stats_hook_type get_index_stats_hook; + +/* Functions in selfuncs.c */ + +extern void examine_variable(PlannerInfo *root, Node *node, int varRelid, + VariableStatData *vardata); +extern bool all_rows_selectable(PlannerInfo *root, Index varno, Bitmapset *varattnos); +extern bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid); +extern bool get_restriction_variable(PlannerInfo *root, List *args, + int varRelid, + VariableStatData *vardata, Node **other, + bool *varonleft); +extern void get_join_variables(PlannerInfo *root, List *args, + SpecialJoinInfo *sjinfo, + VariableStatData *vardata1, + VariableStatData *vardata2, + bool *join_is_reversed); +extern double get_variable_numdistinct(VariableStatData *vardata, + bool *isdefault); +extern double mcv_selectivity(VariableStatData *vardata, + FmgrInfo *opproc, Oid collation, + Datum constval, bool varonleft, + double *sumcommonp); +extern double histogram_selectivity(VariableStatData *vardata, + FmgrInfo *opproc, Oid collation, + Datum constval, bool varonleft, + int min_hist_size, int n_skip, + int *hist_size); +extern double generic_restriction_selectivity(PlannerInfo *root, + Oid oproid, Oid collation, + List *args, int varRelid, + double default_selectivity); +extern double ineq_histogram_selectivity(PlannerInfo *root, + VariableStatData *vardata, + Oid opoid, FmgrInfo *opproc, + bool isgt, bool iseq, + Oid collation, + Datum constval, Oid consttype); +extern double var_eq_const(VariableStatData *vardata, + Oid oproid, Oid collation, + Datum constval, bool constisnull, + bool varonleft, bool negate); +extern double var_eq_non_const(VariableStatData *vardata, + Oid oproid, Oid collation, + Node *other, + bool varonleft, bool negate); + +extern Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid); +extern Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype, + Node *arg, int varRelid, + JoinType jointype, SpecialJoinInfo *sjinfo); +extern Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype, + Node *arg, int varRelid, + JoinType jointype, SpecialJoinInfo *sjinfo); +extern Selectivity scalararraysel(PlannerInfo *root, + ScalarArrayOpExpr *clause, + bool is_join_clause, + int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo); +extern int estimate_array_length(Node *arrayexpr); +extern Selectivity rowcomparesel(PlannerInfo *root, + RowCompareExpr *clause, + int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo); + +extern void mergejoinscansel(PlannerInfo *root, Node *clause, + Oid opfamily, int strategy, bool nulls_first, + Selectivity *leftstart, Selectivity *leftend, + Selectivity *rightstart, Selectivity *rightend); + +extern double estimate_num_groups(PlannerInfo *root, List *groupExprs, + double input_rows, List **pgset, + EstimationInfo *estinfo); + +extern void estimate_hash_bucket_stats(PlannerInfo *root, + Node *hashkey, double nbuckets, + Selectivity *mcv_freq, + Selectivity *bucketsize_frac); +extern double estimate_hashagg_tablesize(PlannerInfo *root, Path *path, + const AggClauseCosts *agg_costs, + double dNumGroups); + +extern List *get_quals_from_indexclauses(List *indexclauses); +extern Cost index_other_operands_eval_cost(PlannerInfo *root, + List *indexquals); +extern List *add_predicate_to_index_quals(IndexOptInfo *index, + List *indexQuals); +extern void genericcostestimate(PlannerInfo *root, IndexPath *path, + double loop_count, + GenericCosts *costs); + +/* Functions in array_selfuncs.c */ + +extern Selectivity scalararraysel_containment(PlannerInfo *root, + Node *leftop, Node *rightop, + Oid elemtype, bool isEquality, bool useOr, + int varRelid); + +#endif /* SELFUNCS_H */ diff --git a/install/include/postgresql/server/utils/sharedtuplestore.h b/install/include/postgresql/server/utils/sharedtuplestore.h new file mode 100644 index 00000000000..c7075ad055d --- /dev/null +++ b/install/include/postgresql/server/utils/sharedtuplestore.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * sharedtuplestore.h + * Simple mechanism for sharing tuples between backends. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/sharedtuplestore.h + * + *------------------------------------------------------------------------- + */ +#ifndef SHAREDTUPLESTORE_H +#define SHAREDTUPLESTORE_H + +#include "access/htup.h" +#include "storage/fd.h" +#include "storage/sharedfileset.h" + +struct SharedTuplestore; +typedef struct SharedTuplestore SharedTuplestore; + +struct SharedTuplestoreAccessor; +typedef struct SharedTuplestoreAccessor SharedTuplestoreAccessor; + +/* + * A flag indicating that the tuplestore will only be scanned once, so backing + * files can be unlinked early. + */ +#define SHARED_TUPLESTORE_SINGLE_PASS 0x01 + +extern size_t sts_estimate(int participants); + +extern SharedTuplestoreAccessor *sts_initialize(SharedTuplestore *sts, + int participants, + int my_participant_number, + size_t meta_data_size, + int flags, + SharedFileSet *fileset, + const char *name); + +extern SharedTuplestoreAccessor *sts_attach(SharedTuplestore *sts, + int my_participant_number, + SharedFileSet *fileset); + +extern void sts_end_write(SharedTuplestoreAccessor *accessor); + +extern void sts_reinitialize(SharedTuplestoreAccessor *accessor); + +extern void sts_begin_parallel_scan(SharedTuplestoreAccessor *accessor); + +extern void sts_end_parallel_scan(SharedTuplestoreAccessor *accessor); + +extern void sts_puttuple(SharedTuplestoreAccessor *accessor, + void *meta_data, + MinimalTuple tuple); + +extern MinimalTuple sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, + void *meta_data); + +#endif /* SHAREDTUPLESTORE_H */ diff --git a/install/include/postgresql/server/utils/snapmgr.h b/install/include/postgresql/server/utils/snapmgr.h new file mode 100644 index 00000000000..da40ca25a4a --- /dev/null +++ b/install/include/postgresql/server/utils/snapmgr.h @@ -0,0 +1,204 @@ +/*------------------------------------------------------------------------- + * + * snapmgr.h + * POSTGRES snapshot manager + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/snapmgr.h + * + *------------------------------------------------------------------------- + */ +#ifndef SNAPMGR_H +#define SNAPMGR_H + +#include "access/transam.h" +#include "utils/relcache.h" +#include "utils/resowner.h" +#include "utils/snapshot.h" + + +/* + * The structure used to map times to TransactionId values for the "snapshot + * too old" feature must have a few entries at the tail to hold old values; + * otherwise the lookup will often fail and the expected early pruning or + * vacuum will not usually occur. It is best if this padding is for a number + * of minutes greater than a thread would normally be stalled, but it's OK if + * early vacuum opportunities are occasionally missed, so there's no need to + * use an extreme value or get too fancy. 10 minutes seems plenty. + */ +#define OLD_SNAPSHOT_PADDING_ENTRIES 10 +#define OLD_SNAPSHOT_TIME_MAP_ENTRIES (old_snapshot_threshold + OLD_SNAPSHOT_PADDING_ENTRIES) + +/* + * Common definition of relation properties that allow early pruning/vacuuming + * when old_snapshot_threshold >= 0. + */ +#define RelationAllowsEarlyPruning(rel) \ +( \ + RelationIsPermanent(rel) && !IsCatalogRelation(rel) \ + && !RelationIsAccessibleInLogicalDecoding(rel) \ +) + +#define EarlyPruningEnabled(rel) (old_snapshot_threshold >= 0 && RelationAllowsEarlyPruning(rel)) + +/* GUC variables */ +extern PGDLLIMPORT int old_snapshot_threshold; + + +extern Size SnapMgrShmemSize(void); +extern void SnapMgrInit(void); +extern TimestampTz GetSnapshotCurrentTimestamp(void); +extern TimestampTz GetOldSnapshotThresholdTimestamp(void); +extern void SnapshotTooOldMagicForTest(void); + +extern PGDLLIMPORT bool FirstSnapshotSet; + +extern PGDLLIMPORT TransactionId TransactionXmin; +extern PGDLLIMPORT TransactionId RecentXmin; + +/* Variables representing various special snapshot semantics */ +extern PGDLLIMPORT SnapshotData SnapshotSelfData; +extern PGDLLIMPORT SnapshotData SnapshotAnyData; +extern PGDLLIMPORT SnapshotData CatalogSnapshotData; + +#define SnapshotSelf (&SnapshotSelfData) +#define SnapshotAny (&SnapshotAnyData) + +/* + * We don't provide a static SnapshotDirty variable because it would be + * non-reentrant. Instead, users of that snapshot type should declare a + * local variable of type SnapshotData, and initialize it with this macro. + */ +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC (spec-3.3 D4 root 1): static SnapshotData init macros must zero + * the cluster tail. Callers commonly declare `SnapshotData s;` on the + * stack (uninitialised garbage) and only invoke Init*Snapshot() to set + * snapshot_type. Without explicit zeroing, cluster_source could randomly + * be == CLUSTER (1) and route a Dirty / NonVacuumable / Toast snapshot + * into the cluster visibility path. Force LOCAL semantics for all + * non-MVCC static snapshots. + */ +#define PGRAC_INIT_SNAPSHOT_LOCAL(snapshotdata) \ + ((snapshotdata).cluster_source = (uint8) SNAPSHOT_SOURCE_LOCAL, \ + (snapshotdata).cluster_snapshot_session_local = 0, \ + (snapshotdata).read_scn = InvalidScn, \ + (snapshotdata).read_epoch = 0, \ + memset((snapshotdata)._pad, 0, sizeof((snapshotdata)._pad))) +#else +#define PGRAC_INIT_SNAPSHOT_LOCAL(snapshotdata) ((void) 0) +#endif + +#define InitDirtySnapshot(snapshotdata) \ + ((snapshotdata).snapshot_type = SNAPSHOT_DIRTY, \ + PGRAC_INIT_SNAPSHOT_LOCAL(snapshotdata)) + +/* + * Similarly, some initialization is required for a NonVacuumable snapshot. + * The caller must supply the visibility cutoff state to use (c.f. + * GlobalVisTestFor()). + */ +#define InitNonVacuumableSnapshot(snapshotdata, vistestp) \ + ((snapshotdata).snapshot_type = SNAPSHOT_NON_VACUUMABLE, \ + (snapshotdata).vistest = (vistestp), \ + PGRAC_INIT_SNAPSHOT_LOCAL(snapshotdata)) + +/* + * Similarly, some initialization is required for SnapshotToast. We need + * to set lsn and whenTaken correctly to support snapshot_too_old. + */ +#define InitToastSnapshot(snapshotdata, l, w) \ + ((snapshotdata).snapshot_type = SNAPSHOT_TOAST, \ + (snapshotdata).lsn = (l), \ + (snapshotdata).whenTaken = (w), \ + PGRAC_INIT_SNAPSHOT_LOCAL(snapshotdata)) + +/* This macro encodes the knowledge of which snapshots are MVCC-safe */ +#define IsMVCCSnapshot(snapshot) \ + ((snapshot)->snapshot_type == SNAPSHOT_MVCC || \ + (snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC) + +#ifndef FRONTEND +static inline bool +OldSnapshotThresholdActive(void) +{ + return old_snapshot_threshold >= 0; +} +#endif + +extern Snapshot GetTransactionSnapshot(void); +extern Snapshot GetLatestSnapshot(void); +extern void SnapshotSetCommandId(CommandId curcid); +extern Snapshot GetOldestSnapshot(void); + +extern Snapshot GetCatalogSnapshot(Oid relid); +extern Snapshot GetNonHistoricCatalogSnapshot(Oid relid); +extern void InvalidateCatalogSnapshot(void); +extern void InvalidateCatalogSnapshotConditionally(void); + +extern void PushActiveSnapshot(Snapshot snapshot); +extern void PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level); +extern void PushCopiedSnapshot(Snapshot snapshot); +extern void UpdateActiveSnapshotCommandId(void); +extern void PopActiveSnapshot(void); +extern Snapshot GetActiveSnapshot(void); +extern bool ActiveSnapshotSet(void); + +extern Snapshot RegisterSnapshot(Snapshot snapshot); +extern void UnregisterSnapshot(Snapshot snapshot); +extern Snapshot RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner); +extern void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner); + +extern void AtSubCommit_Snapshot(int level); +extern void AtSubAbort_Snapshot(int level); +extern void AtEOXact_Snapshot(bool isCommit, bool resetXmin); + +extern void ImportSnapshot(const char *idstr); +extern bool XactHasExportedSnapshots(void); +extern void DeleteAllExportedSnapshotFiles(void); +extern void WaitForOlderSnapshots(TransactionId limitXmin, bool progress); +extern bool ThereAreNoPriorRegisteredSnapshots(void); +extern bool HaveRegisteredOrActiveSnapshot(void); +extern bool TransactionIdLimitedForOldSnapshots(TransactionId recentXmin, + Relation relation, + TransactionId *limit_xid, + TimestampTz *limit_ts); +extern void SetOldSnapshotThresholdTimestamp(TimestampTz ts, TransactionId xlimit); +extern void MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, + TransactionId xmin); + +extern char *ExportSnapshot(Snapshot snapshot); + +/* + * These live in procarray.c because they're intimately linked to the + * procarray contents, but thematically they better fit into snapmgr.h. + */ +typedef struct GlobalVisState GlobalVisState; +extern GlobalVisState *GlobalVisTestFor(Relation rel); +extern bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid); +extern bool GlobalVisTestIsRemovableFullXid(GlobalVisState *state, FullTransactionId fxid); +extern FullTransactionId GlobalVisTestNonRemovableFullHorizon(GlobalVisState *state); +extern TransactionId GlobalVisTestNonRemovableHorizon(GlobalVisState *state); +extern bool GlobalVisCheckRemovableXid(Relation rel, TransactionId xid); +extern bool GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid); + +/* + * Utility functions for implementing visibility routines in table AMs. + */ +extern bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); + +/* Support for catalog timetravel for logical decoding */ +struct HTAB; +extern struct HTAB *HistoricSnapshotGetTupleCids(void); +extern void SetupHistoricSnapshot(Snapshot historic_snapshot, struct HTAB *tuplecids); +extern void TeardownHistoricSnapshot(bool is_error); +extern bool HistoricSnapshotActive(void); + +extern Size EstimateSnapshotSpace(Snapshot snapshot); +extern void SerializeSnapshot(Snapshot snapshot, char *start_address); +extern Snapshot RestoreSnapshot(char *start_address); +extern void RestoreTransactionSnapshot(Snapshot snapshot, void *source_pgproc); + +#endif /* SNAPMGR_H */ diff --git a/install/include/postgresql/server/utils/snapshot.h b/install/include/postgresql/server/utils/snapshot.h new file mode 100644 index 00000000000..d13e7212a2c --- /dev/null +++ b/install/include/postgresql/server/utils/snapshot.h @@ -0,0 +1,298 @@ +/*------------------------------------------------------------------------- + * + * snapshot.h + * POSTGRES snapshot definition + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/snapshot.h + * + *------------------------------------------------------------------------- + * + * PGRAC MODIFICATIONS (spec-3.3 D1): + * Added explicit 24-byte cluster tail to SnapshotData: SCN read_scn (8B) + * + uint64 read_epoch (8B) + uint8 cluster_source (1B) + * + uint8 cluster_snapshot_session_local (1B, spec-3.24 D1) + uint8 _pad[6] + * (7B). Explicit layout prevents hidden 4B padding (R4 P1) and avoids + * uint32 wrap alias on cluster epoch (R9 P2). + * + * New SnapshotSource enum {LOCAL=0, CLUSTER=1}: + * LOCAL - catalog scans, logical decoding, system snapshots; PG-native + * visibility path unchanged. + * CLUSTER- user-facing MVCC snapshots; read_scn / read_epoch carry the + * cluster-wide SCN and epoch at GetSnapshotData() capture + * instant. + * + * Spec: spec-3.3-snapshot-consistency-cross-node.md §1.2 D1 / §2.1. + * See also feature-121 + docs/spec-drafting-lessons.md v1.68 L180/L181. + *------------------------------------------------------------------------- + */ +#ifndef SNAPSHOT_H +#define SNAPSHOT_H + +#include "access/htup.h" +#include "access/xlogdefs.h" +#include "datatype/timestamp.h" +#include "lib/pairingheap.h" +#include "storage/buf.h" + +#ifdef USE_PGRAC_CLUSTER +#include "cluster/cluster_scn.h" /* PGRAC: SCN typedef */ +#endif + + +/* + * The different snapshot types. We use SnapshotData structures to represent + * both "regular" (MVCC) snapshots and "special" snapshots that have non-MVCC + * semantics. The specific semantics of a snapshot are encoded by its type. + * + * The behaviour of each type of snapshot should be documented alongside its + * enum value, best in terms that are not specific to an individual table AM. + * + * The reason the snapshot type rather than a callback as it used to be is + * that that allows to use the same snapshot for different table AMs without + * having one callback per AM. + */ +typedef enum SnapshotType +{ + /*------------------------------------------------------------------------- + * A tuple is visible iff the tuple is valid for the given MVCC snapshot. + * + * Here, we consider the effects of: + * - all transactions committed as of the time of the given snapshot + * - previous commands of this transaction + * + * Does _not_ include: + * - transactions shown as in-progress by the snapshot + * - transactions started after the snapshot was taken + * - changes made by the current command + * ------------------------------------------------------------------------- + */ + SNAPSHOT_MVCC = 0, + + /*------------------------------------------------------------------------- + * A tuple is visible iff the tuple is valid "for itself". + * + * Here, we consider the effects of: + * - all committed transactions (as of the current instant) + * - previous commands of this transaction + * - changes made by the current command + * + * Does _not_ include: + * - in-progress transactions (as of the current instant) + * ------------------------------------------------------------------------- + */ + SNAPSHOT_SELF, + + /* + * Any tuple is visible. + */ + SNAPSHOT_ANY, + + /* + * A tuple is visible iff the tuple is valid as a TOAST row. + */ + SNAPSHOT_TOAST, + + /*------------------------------------------------------------------------- + * A tuple is visible iff the tuple is valid including effects of open + * transactions. + * + * Here, we consider the effects of: + * - all committed and in-progress transactions (as of the current instant) + * - previous commands of this transaction + * - changes made by the current command + * + * This is essentially like SNAPSHOT_SELF as far as effects of the current + * transaction and committed/aborted xacts are concerned. However, it + * also includes the effects of other xacts still in progress. + * + * A special hack is that when a snapshot of this type is used to + * determine tuple visibility, the passed-in snapshot struct is used as an + * output argument to return the xids of concurrent xacts that affected + * the tuple. snapshot->xmin is set to the tuple's xmin if that is + * another transaction that's still in progress; or to + * InvalidTransactionId if the tuple's xmin is committed good, committed + * dead, or my own xact. Similarly for snapshot->xmax and the tuple's + * xmax. If the tuple was inserted speculatively, meaning that the + * inserter might still back down on the insertion without aborting the + * whole transaction, the associated token is also returned in + * snapshot->speculativeToken. See also InitDirtySnapshot(). + * ------------------------------------------------------------------------- + */ + SNAPSHOT_DIRTY, + + /* + * A tuple is visible iff it follows the rules of SNAPSHOT_MVCC, but + * supports being called in timetravel context (for decoding catalog + * contents in the context of logical decoding). + */ + SNAPSHOT_HISTORIC_MVCC, + + /* + * A tuple is visible iff the tuple might be visible to some transaction; + * false if it's surely dead to everyone, i.e., vacuumable. + * + * For visibility checks snapshot->min must have been set up with the xmin + * horizon to use. + */ + SNAPSHOT_NON_VACUUMABLE +} SnapshotType; + +typedef struct SnapshotData *Snapshot; + +#define InvalidSnapshot ((Snapshot) NULL) + +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC: cluster snapshot source enum (spec-3.3 D1). + * + * LOCAL - catalog scans / logical decoding / system snapshots; PG-native + * visibility path unchanged; read_scn/read_epoch are InvalidScn/0. + * CLUSTER- user-facing MVCC snapshots; read_scn/read_epoch carry the + * cluster-wide SCN/epoch at GetSnapshotData() capture instant. + */ +typedef enum SnapshotSource +{ + SNAPSHOT_SOURCE_LOCAL = 0, + SNAPSHOT_SOURCE_CLUSTER = 1 +} SnapshotSource; +#endif + +/* + * Struct representing all kind of possible snapshots. + * + * There are several different kinds of snapshots: + * * Normal MVCC snapshots + * * MVCC snapshots taken during recovery (in Hot-Standby mode) + * * Historic MVCC snapshots used during logical decoding + * * snapshots passed to HeapTupleSatisfiesDirty() + * * snapshots passed to HeapTupleSatisfiesNonVacuumable() + * * snapshots used for SatisfiesAny, Toast, Self where no members are + * accessed. + * + * TODO: It's probably a good idea to split this struct using a NodeTag + * similar to how parser and executor nodes are handled, with one type for + * each different kind of snapshot to avoid overloading the meaning of + * individual fields. + */ +typedef struct SnapshotData +{ + SnapshotType snapshot_type; /* type of snapshot */ + + /* + * The remaining fields are used only for MVCC snapshots, and are normally + * just zeroes in special snapshots. (But xmin and xmax are used + * specially by HeapTupleSatisfiesDirty, and xmin is used specially by + * HeapTupleSatisfiesNonVacuumable.) + * + * An MVCC snapshot can never see the effects of XIDs >= xmax. It can see + * the effects of all older XIDs except those listed in the snapshot. xmin + * is stored as an optimization to avoid needing to search the XID arrays + * for most tuples. + */ + TransactionId xmin; /* all XID < xmin are visible to me */ + TransactionId xmax; /* all XID >= xmax are invisible to me */ + + /* + * For normal MVCC snapshot this contains the all xact IDs that are in + * progress, unless the snapshot was taken during recovery in which case + * it's empty. For historic MVCC snapshots, the meaning is inverted, i.e. + * it contains *committed* transactions between xmin and xmax. + * + * note: all ids in xip[] satisfy xmin <= xip[i] < xmax + */ + TransactionId *xip; + uint32 xcnt; /* # of xact ids in xip[] */ + + /* + * For non-historic MVCC snapshots, this contains subxact IDs that are in + * progress (and other transactions that are in progress if taken during + * recovery). For historic snapshot it contains *all* xids assigned to the + * replayed transaction, including the toplevel xid. + * + * note: all ids in subxip[] are >= xmin, but we don't bother filtering + * out any that are >= xmax + */ + TransactionId *subxip; + int32 subxcnt; /* # of xact ids in subxip[] */ + bool suboverflowed; /* has the subxip array overflowed? */ + + bool takenDuringRecovery; /* recovery-shaped snapshot? */ + bool copied; /* false if it's a static snapshot */ + + CommandId curcid; /* in my xact, CID < curcid are visible */ + + /* + * An extra return value for HeapTupleSatisfiesDirty, not used in MVCC + * snapshots. + */ + uint32 speculativeToken; + + /* + * For SNAPSHOT_NON_VACUUMABLE (and hopefully more in the future) this is + * used to determine whether row could be vacuumed. + */ + struct GlobalVisState *vistest; + + /* + * Book-keeping information, used by the snapshot manager + */ + uint32 active_count; /* refcount on ActiveSnapshot stack */ + uint32 regd_count; /* refcount on RegisteredSnapshots */ + pairingheap_node ph_node; /* link in the RegisteredSnapshots heap */ + + TimestampTz whenTaken; /* timestamp when snapshot was taken */ + XLogRecPtr lsn; /* position in the WAL stream when taken */ + + /* + * The transaction completion count at the time GetSnapshotData() built + * this snapshot. Allows to avoid re-computing static snapshots when no + * transactions completed since the last GetSnapshotData(). + */ + uint64 snapXactCompletionCount; + +#ifdef USE_PGRAC_CLUSTER + /* + * PGRAC (spec-3.3 D1): explicit 24-byte cluster tail. Field order matters + * for ABI stability: SCN (8B aligned) + uint64 (8B aligned) leaves the + * cluster_source byte at offset +16, the spec-3.24 D1 + * cluster_snapshot_session_local byte at +17, and an explicit 6-byte _pad[6] + * to pad out to 24 bytes. NO hidden compiler padding; NO uint32 truncation + * on cluster epoch (R9 P2). All fields zero-initialised on LOCAL paths. + * + * read_scn - cluster_scn_current() snapped at GetSnapshotData() + * (or GetSnapshotDataReuse() refresh path). Compared via + * scn_time_cmp() only; raw `<=` is banned (R1 P0). + * read_epoch - cluster_epoch_get_current() snapped likewise. + * Reconfig bumps epoch; stale snapshots fail-closed. + * cluster_source - SNAPSHOT_SOURCE_LOCAL=0 / CLUSTER=1. + * cluster_snapshot_session_local - spec-3.24 D1: 1 iff this snapshot was + * produced by this backend's GetSnapshotData() path, so the + * local ProcArray matched its creation moment (AD-012 例外 + * 9 row #1). 0 for an imported / restored snapshot (SET + * TRANSACTION SNAPSHOT, or a parallel worker via + * RestoreSnapshot) -- AD-012 row #2, which keeps the SCN/CR + * path even with no peers. Repurposed from a _pad byte (no + * ABI size change); NOT serialized -- a restored snapshot is + * imported by definition (SetTransactionSnapshot clears it). + * _pad[6] - explicit padding, must be zero (asserted by D12). + */ + SCN read_scn; + uint64 read_epoch; + uint8 cluster_source; + uint8 cluster_snapshot_session_local; + uint8 _pad[6]; +#endif +} SnapshotData; + +#ifdef USE_PGRAC_CLUSTER +/* + * PGRAC: D12 cluster_unit checks these offsets; if SnapshotData layout + * changes upstream, these StaticAssertDecl()s catch silent ABI drift. + */ +StaticAssertDecl(sizeof(SCN) == 8, "PGRAC: SCN must be 8 bytes"); +#endif + +#endif /* SNAPSHOT_H */ diff --git a/install/include/postgresql/server/utils/sortsupport.h b/install/include/postgresql/server/utils/sortsupport.h new file mode 100644 index 00000000000..475ed1d5b82 --- /dev/null +++ b/install/include/postgresql/server/utils/sortsupport.h @@ -0,0 +1,391 @@ +/*------------------------------------------------------------------------- + * + * sortsupport.h + * Framework for accelerated sorting. + * + * Traditionally, PostgreSQL has implemented sorting by repeatedly invoking + * an SQL-callable comparison function "cmp(x, y) returns int" on pairs of + * values to be compared, where the comparison function is the BTORDER_PROC + * pg_amproc support function of the appropriate btree index opclass. + * + * This file defines alternative APIs that allow sorting to be performed with + * reduced overhead. To support lower-overhead sorting, a btree opclass may + * provide a BTSORTSUPPORT_PROC pg_amproc entry, which must take a single + * argument of type internal and return void. The argument is actually a + * pointer to a SortSupportData struct, which is defined below. + * + * If provided, the BTSORTSUPPORT function will be called during sort setup, + * and it must initialize the provided struct with pointers to function(s) + * that can be called to perform sorting. This API is defined to allow + * multiple acceleration mechanisms to be supported, but no opclass is + * required to provide all of them. The BTSORTSUPPORT function should + * simply not set any function pointers for mechanisms it doesn't support. + * Opclasses that provide BTSORTSUPPORT and don't provide a comparator + * function will have a shim set up by sort support automatically. However, + * opclasses that support the optional additional abbreviated key capability + * must always provide an authoritative comparator used to tie-break + * inconclusive abbreviated comparisons and also used when aborting + * abbreviation. Furthermore, a converter and abort/costing function must be + * provided. + * + * All sort support functions will be passed the address of the + * SortSupportData struct when called, so they can use it to store + * additional private data as needed. In particular, for collation-aware + * datatypes, the ssup_collation field is set before calling BTSORTSUPPORT + * and is available to all support functions. Additional opclass-dependent + * data can be stored using the ssup_extra field. Any such data + * should be allocated in the ssup_cxt memory context. + * + * Note: since pg_amproc functions are indexed by (lefttype, righttype) + * it is possible to associate a BTSORTSUPPORT function with a cross-type + * comparison. This could sensibly be used to provide a fast comparator + * function for such cases, but probably not any other acceleration method. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/sortsupport.h + * + *------------------------------------------------------------------------- + */ +#ifndef SORTSUPPORT_H +#define SORTSUPPORT_H + +#include "access/attnum.h" +#include "utils/relcache.h" + +typedef struct SortSupportData *SortSupport; + +typedef struct SortSupportData +{ + /* + * These fields are initialized before calling the BTSORTSUPPORT function + * and should not be changed later. + */ + MemoryContext ssup_cxt; /* Context containing sort info */ + Oid ssup_collation; /* Collation to use, or InvalidOid */ + + /* + * Additional sorting parameters; but unlike ssup_collation, these can be + * changed after BTSORTSUPPORT is called, so don't use them in selecting + * sort support functions. + */ + bool ssup_reverse; /* descending-order sort? */ + bool ssup_nulls_first; /* sort nulls first? */ + + /* + * These fields are workspace for callers, and should not be touched by + * opclass-specific functions. + */ + AttrNumber ssup_attno; /* column number to sort */ + + /* + * ssup_extra is zeroed before calling the BTSORTSUPPORT function, and is + * not touched subsequently by callers. + */ + void *ssup_extra; /* Workspace for opclass functions */ + + /* + * Function pointers are zeroed before calling the BTSORTSUPPORT function, + * and must be set by it for any acceleration methods it wants to supply. + * The comparator pointer must be set, others are optional. + */ + + /* + * Comparator function has the same API as the traditional btree + * comparison function, ie, return <0, 0, or >0 according as x is less + * than, equal to, or greater than y. Note that x and y are guaranteed + * not null, and there is no way to return null either. + * + * This may be either the authoritative comparator, or the abbreviated + * comparator. Core code may switch this over the initial preference of + * an opclass support function despite originally indicating abbreviation + * was applicable, by assigning the authoritative comparator back. + */ + int (*comparator) (Datum x, Datum y, SortSupport ssup); + + /* + * "Abbreviated key" infrastructure follows. + * + * All callbacks must be set by sortsupport opclasses that make use of + * this optional additional infrastructure (unless for whatever reasons + * the opclass doesn't proceed with abbreviation, in which case + * abbrev_converter must not be set). + * + * This allows opclass authors to supply a conversion routine, used to + * create an alternative representation of the underlying type (an + * "abbreviated key"). This representation must be pass-by-value and + * typically will use some ad-hoc format that only the opclass has + * knowledge of. An alternative comparator, used only with this + * alternative representation must also be provided (which is assigned to + * "comparator"). This representation is a simple approximation of the + * original Datum. It must be possible to compare datums of this + * representation with each other using the supplied alternative + * comparator, and have any non-zero return value be a reliable proxy for + * what a proper comparison would indicate. Returning zero from the + * alternative comparator does not indicate equality, as with a + * conventional support routine 1, though -- it indicates that it wasn't + * possible to determine how the two abbreviated values compared. A + * proper comparison, using "abbrev_full_comparator"/ + * ApplySortAbbrevFullComparator() is therefore required. In many cases + * this results in most or all comparisons only using the cheap + * alternative comparison func, which is typically implemented as code + * that compiles to just a few CPU instructions. CPU cache miss penalties + * are expensive; to get good overall performance, sort infrastructure + * must heavily weigh cache performance. + * + * Opclass authors must consider the final cardinality of abbreviated keys + * when devising an encoding scheme. It's possible for a strategy to work + * better than an alternative strategy with one usage pattern, while the + * reverse might be true for another usage pattern. All of these factors + * must be considered. + */ + + /* + * "abbreviate" concerns whether or not the abbreviated key optimization + * is applicable in principle (that is, the sortsupport routine needs to + * know if its dealing with a key where an abbreviated representation can + * usefully be packed together. Conventionally, this is the leading + * attribute key). Note, however, that in order to determine that + * abbreviation is not in play, the core code always checks whether or not + * the opclass has set abbrev_converter. This is a one way, one time + * message to the opclass. + */ + bool abbreviate; + + /* + * Converter to abbreviated format, from original representation. Core + * code uses this callback to convert from a pass-by-reference "original" + * Datum to a pass-by-value abbreviated key Datum. Note that original is + * guaranteed NOT NULL, because it doesn't make sense to factor NULLness + * into ad-hoc cost model. + * + * abbrev_converter is tested to see if abbreviation is in play. Core + * code may set it to NULL to indicate abbreviation should not be used + * (which is something sortsupport routines need not concern themselves + * with). However, sortsupport routines must not set it when it is + * immediately established that abbreviation should not proceed (e.g., for + * !abbreviate calls, or due to platform-specific impediments to using + * abbreviation). + */ + Datum (*abbrev_converter) (Datum original, SortSupport ssup); + + /* + * abbrev_abort callback allows clients to verify that the current + * strategy is working out, using a sortsupport routine defined ad-hoc + * cost model. If there is a lot of duplicate abbreviated keys in + * practice, it's useful to be able to abandon the strategy before paying + * too high a cost in conversion (perhaps certain opclass-specific + * adaptations are useful too). + */ + bool (*abbrev_abort) (int memtupcount, SortSupport ssup); + + /* + * Full, authoritative comparator for key that an abbreviated + * representation was generated for, used when an abbreviated comparison + * was inconclusive (by calling ApplySortAbbrevFullComparator()), or used + * to replace "comparator" when core system ultimately decides against + * abbreviation. + */ + int (*abbrev_full_comparator) (Datum x, Datum y, SortSupport ssup); +} SortSupportData; + + +/* + * Apply a sort comparator function and return a 3-way comparison result. + * This takes care of handling reverse-sort and NULLs-ordering properly. + */ +static inline int +ApplySortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { + compare = ssup->comparator(datum1, datum2, ssup); + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} + +static inline int +ApplyUnsignedSortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { + compare = datum1 < datum2 ? -1 : datum1 > datum2 ? 1 : 0; + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} + +#if SIZEOF_DATUM >= 8 +static inline int +ApplySignedSortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { + compare = DatumGetInt64(datum1) < DatumGetInt64(datum2) ? -1 : + DatumGetInt64(datum1) > DatumGetInt64(datum2) ? 1 : 0; + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} +#endif + +static inline int +ApplyInt32SortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { + compare = DatumGetInt32(datum1) < DatumGetInt32(datum2) ? -1 : + DatumGetInt32(datum1) > DatumGetInt32(datum2) ? 1 : 0; + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} + +/* + * Apply a sort comparator function and return a 3-way comparison using full, + * authoritative comparator. This takes care of handling reverse-sort and + * NULLs-ordering properly. + */ +static inline int +ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { + compare = ssup->abbrev_full_comparator(datum1, datum2, ssup); + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} + +/* + * Datum comparison functions that we have specialized sort routines for. + * Datatypes that install these as their comparator or abbreviated comparator + * are eligible for faster sorting. + */ +extern int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup); +#if SIZEOF_DATUM >= 8 +extern int ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup); +#endif +extern int ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup); + +/* Other functions in utils/sort/sortsupport.c */ +extern void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup); +extern void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup); +extern void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, + SortSupport ssup); +extern void PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup); + +#endif /* SORTSUPPORT_H */ diff --git a/install/include/postgresql/server/utils/spccache.h b/install/include/postgresql/server/utils/spccache.h new file mode 100644 index 00000000000..c6c754a2ec4 --- /dev/null +++ b/install/include/postgresql/server/utils/spccache.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * spccache.h + * Tablespace cache. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/spccache.h + * + *------------------------------------------------------------------------- + */ +#ifndef SPCCACHE_H +#define SPCCACHE_H + +extern void get_tablespace_page_costs(Oid spcid, float8 *spc_random_page_cost, + float8 *spc_seq_page_cost); +extern int get_tablespace_io_concurrency(Oid spcid); +extern int get_tablespace_maintenance_io_concurrency(Oid spcid); + +#endif /* SPCCACHE_H */ diff --git a/install/include/postgresql/server/utils/syscache.h b/install/include/postgresql/server/utils/syscache.h new file mode 100644 index 00000000000..34b3b76aa5c --- /dev/null +++ b/install/include/postgresql/server/utils/syscache.h @@ -0,0 +1,234 @@ +/*------------------------------------------------------------------------- + * + * syscache.h + * System catalog cache definitions. + * + * See also lsyscache.h, which provides convenience routines for + * common cache-lookup operations. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/syscache.h + * + *------------------------------------------------------------------------- + */ +#ifndef SYSCACHE_H +#define SYSCACHE_H + +#include "access/attnum.h" +#include "access/htup.h" +/* we intentionally do not include utils/catcache.h here */ + +/* + * SysCache identifiers. + * + * The order of these identifiers must match the order + * of the entries in the array cacheinfo[] in syscache.c. + * Keep them in alphabetical order (renumbering only costs a + * backend rebuild). + */ + +enum SysCacheIdentifier +{ + AGGFNOID = 0, + AMNAME, + AMOID, + AMOPOPID, + AMOPSTRATEGY, + AMPROCNUM, + ATTNAME, + ATTNUM, + AUTHMEMMEMROLE, + AUTHMEMROLEMEM, + AUTHNAME, + AUTHOID, + CASTSOURCETARGET, + CLAAMNAMENSP, + CLAOID, + COLLNAMEENCNSP, + COLLOID, + CONDEFAULT, + CONNAMENSP, + CONSTROID, + CONVOID, + DATABASEOID, + DEFACLROLENSPOBJ, + ENUMOID, + ENUMTYPOIDNAME, + EVENTTRIGGERNAME, + EVENTTRIGGEROID, + FOREIGNDATAWRAPPERNAME, + FOREIGNDATAWRAPPEROID, + FOREIGNSERVERNAME, + FOREIGNSERVEROID, + FOREIGNTABLEREL, + INDEXRELID, + LANGNAME, + LANGOID, + NAMESPACENAME, + NAMESPACEOID, + OPERNAMENSP, + OPEROID, + OPFAMILYAMNAMENSP, + OPFAMILYOID, + PARAMETERACLNAME, + PARAMETERACLOID, + PARTRELID, + PROCNAMEARGSNSP, + PROCOID, + PUBLICATIONNAME, + PUBLICATIONNAMESPACE, + PUBLICATIONNAMESPACEMAP, + PUBLICATIONOID, + PUBLICATIONREL, + PUBLICATIONRELMAP, + RANGEMULTIRANGE, + RANGETYPE, + RELNAMENSP, + RELOID, + REPLORIGIDENT, + REPLORIGNAME, + RULERELNAME, + SEQRELID, + STATEXTDATASTXOID, + STATEXTNAMENSP, + STATEXTOID, + STATRELATTINH, + SUBSCRIPTIONNAME, + SUBSCRIPTIONOID, + SUBSCRIPTIONRELMAP, + TABLESPACEOID, + TRFOID, + TRFTYPELANG, + TSCONFIGMAP, + TSCONFIGNAMENSP, + TSCONFIGOID, + TSDICTNAMENSP, + TSDICTOID, + TSPARSERNAMENSP, + TSPARSEROID, + TSTEMPLATENAMENSP, + TSTEMPLATEOID, + TYPENAMENSP, + TYPEOID, + USERMAPPINGOID, + USERMAPPINGUSERSERVER, + /* intentionally out of alphabetical order, to avoid an ABI break: */ + EXTENSIONOID + +#define SysCacheSize (EXTENSIONOID + 1) +}; + +extern void InitCatalogCache(void); +extern void InitCatalogCachePhase2(void); + +extern HeapTuple SearchSysCache(int cacheId, + Datum key1, Datum key2, Datum key3, Datum key4); + +/* + * The use of argument specific numbers is encouraged. They're faster, and + * insulates the caller from changes in the maximum number of keys. + */ +extern HeapTuple SearchSysCache1(int cacheId, + Datum key1); +extern HeapTuple SearchSysCache2(int cacheId, + Datum key1, Datum key2); +extern HeapTuple SearchSysCache3(int cacheId, + Datum key1, Datum key2, Datum key3); +extern HeapTuple SearchSysCache4(int cacheId, + Datum key1, Datum key2, Datum key3, Datum key4); + +extern void ReleaseSysCache(HeapTuple tuple); + +extern HeapTuple SearchSysCacheLocked1(int cacheId, + Datum key1); + +/* convenience routines */ +extern HeapTuple SearchSysCacheCopy(int cacheId, + Datum key1, Datum key2, Datum key3, Datum key4); +extern HeapTuple SearchSysCacheLockedCopy1(int cacheId, + Datum key1); +extern bool SearchSysCacheExists(int cacheId, + Datum key1, Datum key2, Datum key3, Datum key4); +extern Oid GetSysCacheOid(int cacheId, AttrNumber oidcol, + Datum key1, Datum key2, Datum key3, Datum key4); + +extern HeapTuple SearchSysCacheAttName(Oid relid, const char *attname); +extern HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname); +extern bool SearchSysCacheExistsAttName(Oid relid, const char *attname); + +extern HeapTuple SearchSysCacheAttNum(Oid relid, int16 attnum); +extern HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum); + +extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup, + AttrNumber attributeNumber, bool *isNull); + +extern Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, + AttrNumber attributeNumber); + +extern uint32 GetSysCacheHashValue(int cacheId, + Datum key1, Datum key2, Datum key3, Datum key4); + +/* list-search interface. Users of this must import catcache.h too */ +struct catclist; +extern struct catclist *SearchSysCacheList(int cacheId, int nkeys, + Datum key1, Datum key2, Datum key3); + +extern void SysCacheInvalidate(int cacheId, uint32 hashValue); + +extern bool RelationInvalidatesSnapshotsOnly(Oid relid); +extern bool RelationHasSysCache(Oid relid); +extern bool RelationSupportsSysCache(Oid relid); + +/* + * The use of the macros below rather than direct calls to the corresponding + * functions is encouraged, as it insulates the caller from changes in the + * maximum number of keys. + */ +#define SearchSysCacheCopy1(cacheId, key1) \ + SearchSysCacheCopy(cacheId, key1, 0, 0, 0) +#define SearchSysCacheCopy2(cacheId, key1, key2) \ + SearchSysCacheCopy(cacheId, key1, key2, 0, 0) +#define SearchSysCacheCopy3(cacheId, key1, key2, key3) \ + SearchSysCacheCopy(cacheId, key1, key2, key3, 0) +#define SearchSysCacheCopy4(cacheId, key1, key2, key3, key4) \ + SearchSysCacheCopy(cacheId, key1, key2, key3, key4) + +#define SearchSysCacheExists1(cacheId, key1) \ + SearchSysCacheExists(cacheId, key1, 0, 0, 0) +#define SearchSysCacheExists2(cacheId, key1, key2) \ + SearchSysCacheExists(cacheId, key1, key2, 0, 0) +#define SearchSysCacheExists3(cacheId, key1, key2, key3) \ + SearchSysCacheExists(cacheId, key1, key2, key3, 0) +#define SearchSysCacheExists4(cacheId, key1, key2, key3, key4) \ + SearchSysCacheExists(cacheId, key1, key2, key3, key4) + +#define GetSysCacheOid1(cacheId, oidcol, key1) \ + GetSysCacheOid(cacheId, oidcol, key1, 0, 0, 0) +#define GetSysCacheOid2(cacheId, oidcol, key1, key2) \ + GetSysCacheOid(cacheId, oidcol, key1, key2, 0, 0) +#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3) \ + GetSysCacheOid(cacheId, oidcol, key1, key2, key3, 0) +#define GetSysCacheOid4(cacheId, oidcol, key1, key2, key3, key4) \ + GetSysCacheOid(cacheId, oidcol, key1, key2, key3, key4) + +#define GetSysCacheHashValue1(cacheId, key1) \ + GetSysCacheHashValue(cacheId, key1, 0, 0, 0) +#define GetSysCacheHashValue2(cacheId, key1, key2) \ + GetSysCacheHashValue(cacheId, key1, key2, 0, 0) +#define GetSysCacheHashValue3(cacheId, key1, key2, key3) \ + GetSysCacheHashValue(cacheId, key1, key2, key3, 0) +#define GetSysCacheHashValue4(cacheId, key1, key2, key3, key4) \ + GetSysCacheHashValue(cacheId, key1, key2, key3, key4) + +#define SearchSysCacheList1(cacheId, key1) \ + SearchSysCacheList(cacheId, 1, key1, 0, 0) +#define SearchSysCacheList2(cacheId, key1, key2) \ + SearchSysCacheList(cacheId, 2, key1, key2, 0) +#define SearchSysCacheList3(cacheId, key1, key2, key3) \ + SearchSysCacheList(cacheId, 3, key1, key2, key3) + +#define ReleaseSysCacheList(x) ReleaseCatCacheList(x) + +#endif /* SYSCACHE_H */ diff --git a/install/include/postgresql/server/utils/timeout.h b/install/include/postgresql/server/utils/timeout.h new file mode 100644 index 00000000000..e561a1cde92 --- /dev/null +++ b/install/include/postgresql/server/utils/timeout.h @@ -0,0 +1,95 @@ +/*------------------------------------------------------------------------- + * + * timeout.h + * Routines to multiplex SIGALRM interrupts for multiple timeout reasons. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/timeout.h + * + *------------------------------------------------------------------------- + */ +#ifndef TIMEOUT_H +#define TIMEOUT_H + +#include "datatype/timestamp.h" + +/* + * Identifiers for timeout reasons. Note that in case multiple timeouts + * trigger at the same time, they are serviced in the order of this enum. + */ +typedef enum TimeoutId +{ + /* Predefined timeout reasons */ + STARTUP_PACKET_TIMEOUT, + DEADLOCK_TIMEOUT, + LOCK_TIMEOUT, + STATEMENT_TIMEOUT, + STANDBY_DEADLOCK_TIMEOUT, + STANDBY_TIMEOUT, + STANDBY_LOCK_TIMEOUT, + IDLE_IN_TRANSACTION_SESSION_TIMEOUT, + IDLE_SESSION_TIMEOUT, + IDLE_STATS_UPDATE_TIMEOUT, + CLIENT_CONNECTION_CHECK_TIMEOUT, + STARTUP_PROGRESS_TIMEOUT, + /* First user-definable timeout reason */ + USER_TIMEOUT, + /* Maximum number of timeout reasons */ + MAX_TIMEOUTS = USER_TIMEOUT + 10 +} TimeoutId; + +/* callback function signature */ +typedef void (*timeout_handler_proc) (void); + +/* + * Parameter structure for setting multiple timeouts at once + */ +typedef enum TimeoutType +{ + TMPARAM_AFTER, + TMPARAM_AT, + TMPARAM_EVERY +} TimeoutType; + +typedef struct +{ + TimeoutId id; /* timeout to set */ + TimeoutType type; /* TMPARAM_AFTER or TMPARAM_AT */ + int delay_ms; /* only used for TMPARAM_AFTER/EVERY */ + TimestampTz fin_time; /* only used for TMPARAM_AT */ +} EnableTimeoutParams; + +/* + * Parameter structure for clearing multiple timeouts at once + */ +typedef struct +{ + TimeoutId id; /* timeout to clear */ + bool keep_indicator; /* keep the indicator flag? */ +} DisableTimeoutParams; + +/* timeout setup */ +extern void InitializeTimeouts(void); +extern TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler); +extern void reschedule_timeouts(void); + +/* timeout operation */ +extern void enable_timeout_after(TimeoutId id, int delay_ms); +extern void enable_timeout_every(TimeoutId id, TimestampTz fin_time, + int delay_ms); +extern void enable_timeout_at(TimeoutId id, TimestampTz fin_time); +extern void enable_timeouts(const EnableTimeoutParams *timeouts, int count); +extern void disable_timeout(TimeoutId id, bool keep_indicator); +extern void disable_timeouts(const DisableTimeoutParams *timeouts, int count); +extern void disable_all_timeouts(bool keep_indicators); + +/* accessors */ +extern bool get_timeout_active(TimeoutId id); +extern bool get_timeout_indicator(TimeoutId id, bool reset_indicator); +extern TimestampTz get_timeout_start_time(TimeoutId id); +extern TimestampTz get_timeout_finish_time(TimeoutId id); + +#endif /* TIMEOUT_H */ diff --git a/install/include/postgresql/server/utils/timestamp.h b/install/include/postgresql/server/utils/timestamp.h new file mode 100644 index 00000000000..c4dd96c8c97 --- /dev/null +++ b/install/include/postgresql/server/utils/timestamp.h @@ -0,0 +1,147 @@ +/*------------------------------------------------------------------------- + * + * timestamp.h + * Definitions for the SQL "timestamp" and "interval" types. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/timestamp.h + * + *------------------------------------------------------------------------- + */ +#ifndef TIMESTAMP_H +#define TIMESTAMP_H + +#include "datatype/timestamp.h" +#include "fmgr.h" +#include "pgtime.h" + + +/* + * Functions for fmgr-callable functions. + * + * For Timestamp, we make use of the same support routines as for int64. + * Therefore Timestamp is pass-by-reference if and only if int64 is! + */ +static inline Timestamp +DatumGetTimestamp(Datum X) +{ + return (Timestamp) DatumGetInt64(X); +} + +static inline TimestampTz +DatumGetTimestampTz(Datum X) +{ + return (TimestampTz) DatumGetInt64(X); +} + +static inline Interval * +DatumGetIntervalP(Datum X) +{ + return (Interval *) DatumGetPointer(X); +} + +static inline Datum +TimestampGetDatum(Timestamp X) +{ + return Int64GetDatum(X); +} + +static inline Datum +TimestampTzGetDatum(TimestampTz X) +{ + return Int64GetDatum(X); +} + +static inline Datum +IntervalPGetDatum(const Interval *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_TIMESTAMP(n) DatumGetTimestamp(PG_GETARG_DATUM(n)) +#define PG_GETARG_TIMESTAMPTZ(n) DatumGetTimestampTz(PG_GETARG_DATUM(n)) +#define PG_GETARG_INTERVAL_P(n) DatumGetIntervalP(PG_GETARG_DATUM(n)) + +#define PG_RETURN_TIMESTAMP(x) return TimestampGetDatum(x) +#define PG_RETURN_TIMESTAMPTZ(x) return TimestampTzGetDatum(x) +#define PG_RETURN_INTERVAL_P(x) return IntervalPGetDatum(x) + + +#define TIMESTAMP_MASK(b) (1 << (b)) +#define INTERVAL_MASK(b) (1 << (b)) + +/* Macros to handle packing and unpacking the typmod field for intervals */ +#define INTERVAL_FULL_RANGE (0x7FFF) +#define INTERVAL_RANGE_MASK (0x7FFF) +#define INTERVAL_FULL_PRECISION (0xFFFF) +#define INTERVAL_PRECISION_MASK (0xFFFF) +#define INTERVAL_TYPMOD(p,r) ((((r) & INTERVAL_RANGE_MASK) << 16) | ((p) & INTERVAL_PRECISION_MASK)) +#define INTERVAL_PRECISION(t) ((t) & INTERVAL_PRECISION_MASK) +#define INTERVAL_RANGE(t) (((t) >> 16) & INTERVAL_RANGE_MASK) + +/* Macros for doing timestamp arithmetic without assuming timestamp's units */ +#define TimestampTzPlusMilliseconds(tz,ms) ((tz) + ((ms) * (int64) 1000)) +#define TimestampTzPlusSeconds(tz,s) ((tz) + ((s) * (int64) 1000000)) + + +/* Set at postmaster start */ +extern PGDLLIMPORT TimestampTz PgStartTime; + +/* Set at configuration reload */ +extern PGDLLIMPORT TimestampTz PgReloadTime; + + +/* Internal routines (not fmgr-callable) */ + +extern int32 anytimestamp_typmod_check(bool istz, int32 typmod); + +extern TimestampTz GetCurrentTimestamp(void); +extern TimestampTz GetSQLCurrentTimestamp(int32 typmod); +extern Timestamp GetSQLLocalTimestamp(int32 typmod); +extern void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, + long *secs, int *microsecs); +extern long TimestampDifferenceMilliseconds(TimestampTz start_time, + TimestampTz stop_time); +extern bool TimestampDifferenceExceeds(TimestampTz start_time, + TimestampTz stop_time, + int msec); + +extern TimestampTz time_t_to_timestamptz(pg_time_t tm); +extern pg_time_t timestamptz_to_time_t(TimestampTz t); + +extern const char *timestamptz_to_str(TimestampTz t); + +extern int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result); +extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, + fsec_t *fsec, const char **tzn, pg_tz *attimezone); +extern void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec); + +extern void interval2itm(Interval span, struct pg_itm *itm); +extern int itm2interval(struct pg_itm *itm, Interval *span); +extern int itmin2interval(struct pg_itm_in *itm_in, Interval *span); + +extern Timestamp SetEpochTimestamp(void); +extern void GetEpochTime(struct pg_tm *tm); + +extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2); + +/* timestamp comparison works for timestamptz also */ +#define timestamptz_cmp_internal(dt1,dt2) timestamp_cmp_internal(dt1, dt2) + +extern TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, + int *overflow); +extern int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, + TimestampTz dt2); + +extern int isoweek2j(int year, int week); +extern void isoweek2date(int woy, int *year, int *mon, int *mday); +extern void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday); +extern int date2isoweek(int year, int mon, int mday); +extern int date2isoyear(int year, int mon, int mday); +extern int date2isoyearday(int year, int mon, int mday); + +extern bool TimestampTimestampTzRequiresRewrite(void); + +#endif /* TIMESTAMP_H */ diff --git a/install/include/postgresql/server/utils/tuplesort.h b/install/include/postgresql/server/utils/tuplesort.h new file mode 100644 index 00000000000..af057b6358e --- /dev/null +++ b/install/include/postgresql/server/utils/tuplesort.h @@ -0,0 +1,445 @@ +/*------------------------------------------------------------------------- + * + * tuplesort.h + * Generalized tuple sorting routines. + * + * This module handles sorting of heap tuples, index tuples, or single + * Datums (and could easily support other kinds of sortable objects, + * if necessary). It works efficiently for both small and large amounts + * of data. Small amounts are sorted in-memory using qsort(). Large + * amounts are sorted using temporary files and a standard external sort + * algorithm. Parallel sorts use a variant of this external sort + * algorithm, and are typically only used for large amounts of data. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/tuplesort.h + * + *------------------------------------------------------------------------- + */ +#ifndef TUPLESORT_H +#define TUPLESORT_H + +#include "access/itup.h" +#include "executor/tuptable.h" +#include "storage/dsm.h" +#include "utils/logtape.h" +#include "utils/relcache.h" +#include "utils/sortsupport.h" + + +/* + * Tuplesortstate and Sharedsort are opaque types whose details are not + * known outside tuplesort.c. + */ +typedef struct Tuplesortstate Tuplesortstate; +typedef struct Sharedsort Sharedsort; + +/* + * Tuplesort parallel coordination state, allocated by each participant in + * local memory. Participant caller initializes everything. See usage notes + * below. + */ +typedef struct SortCoordinateData +{ + /* Worker process? If not, must be leader. */ + bool isWorker; + + /* + * Leader-process-passed number of participants known launched (workers + * set this to -1). Includes state within leader needed for it to + * participate as a worker, if any. + */ + int nParticipants; + + /* Private opaque state (points to shared memory) */ + Sharedsort *sharedsort; +} SortCoordinateData; + +typedef struct SortCoordinateData *SortCoordinate; + +/* + * Data structures for reporting sort statistics. Note that + * TuplesortInstrumentation can't contain any pointers because we + * sometimes put it in shared memory. + * + * The parallel-sort infrastructure relies on having a zero TuplesortMethod + * to indicate that a worker never did anything, so we assign zero to + * SORT_TYPE_STILL_IN_PROGRESS. The other values of this enum can be + * OR'ed together to represent a situation where different workers used + * different methods, so we need a separate bit for each one. Keep the + * NUM_TUPLESORTMETHODS constant in sync with the number of bits! + */ +typedef enum +{ + SORT_TYPE_STILL_IN_PROGRESS = 0, + SORT_TYPE_TOP_N_HEAPSORT = 1 << 0, + SORT_TYPE_QUICKSORT = 1 << 1, + SORT_TYPE_EXTERNAL_SORT = 1 << 2, + SORT_TYPE_EXTERNAL_MERGE = 1 << 3 +} TuplesortMethod; + +#define NUM_TUPLESORTMETHODS 4 + +typedef enum +{ + SORT_SPACE_TYPE_DISK, + SORT_SPACE_TYPE_MEMORY +} TuplesortSpaceType; + +/* Bitwise option flags for tuple sorts */ +#define TUPLESORT_NONE 0 + +/* specifies whether non-sequential access to the sort result is required */ +#define TUPLESORT_RANDOMACCESS (1 << 0) + +/* specifies if the tuplesort is able to support bounded sorts */ +#define TUPLESORT_ALLOWBOUNDED (1 << 1) + +typedef struct TuplesortInstrumentation +{ + TuplesortMethod sortMethod; /* sort algorithm used */ + TuplesortSpaceType spaceType; /* type of space spaceUsed represents */ + int64 spaceUsed; /* space consumption, in kB */ +} TuplesortInstrumentation; + +/* + * The objects we actually sort are SortTuple structs. These contain + * a pointer to the tuple proper (might be a MinimalTuple or IndexTuple), + * which is a separate palloc chunk --- we assume it is just one chunk and + * can be freed by a simple pfree() (except during merge, when we use a + * simple slab allocator). SortTuples also contain the tuple's first key + * column in Datum/nullflag format, and a source/input tape number that + * tracks which tape each heap element/slot belongs to during merging. + * + * Storing the first key column lets us save heap_getattr or index_getattr + * calls during tuple comparisons. We could extract and save all the key + * columns not just the first, but this would increase code complexity and + * overhead, and wouldn't actually save any comparison cycles in the common + * case where the first key determines the comparison result. Note that + * for a pass-by-reference datatype, datum1 points into the "tuple" storage. + * + * There is one special case: when the sort support infrastructure provides an + * "abbreviated key" representation, where the key is (typically) a pass by + * value proxy for a pass by reference type. In this case, the abbreviated key + * is stored in datum1 in place of the actual first key column. + * + * When sorting single Datums, the data value is represented directly by + * datum1/isnull1 for pass by value types (or null values). If the datatype is + * pass-by-reference and isnull1 is false, then "tuple" points to a separately + * palloc'd data value, otherwise "tuple" is NULL. The value of datum1 is then + * either the same pointer as "tuple", or is an abbreviated key value as + * described above. Accordingly, "tuple" is always used in preference to + * datum1 as the authoritative value for pass-by-reference cases. + */ +typedef struct +{ + void *tuple; /* the tuple itself */ + Datum datum1; /* value of first key column */ + bool isnull1; /* is first key column NULL? */ + int srctape; /* source tape number */ +} SortTuple; + +typedef int (*SortTupleComparator) (const SortTuple *a, const SortTuple *b, + Tuplesortstate *state); + +/* + * The public part of a Tuple sort operation state. This data structure + * contains the definition of sort-variant-specific interface methods and + * the part of Tuple sort operation state required by their implementations. + */ +typedef struct +{ + /* + * These function pointers decouple the routines that must know what kind + * of tuple we are sorting from the routines that don't need to know it. + * They are set up by the tuplesort_begin_xxx routines. + * + * Function to compare two tuples; result is per qsort() convention, ie: + * <0, 0, >0 according as ab. The API must match + * qsort_arg_comparator. + */ + SortTupleComparator comparetup; + + /* + * Alter datum1 representation in the SortTuple's array back from the + * abbreviated key to the first column value. + */ + void (*removeabbrev) (Tuplesortstate *state, SortTuple *stups, + int count); + + /* + * Function to write a stored tuple onto tape. The representation of the + * tuple on tape need not be the same as it is in memory. + */ + void (*writetup) (Tuplesortstate *state, LogicalTape *tape, + SortTuple *stup); + + /* + * Function to read a stored tuple from tape back into memory. 'len' is + * the already-read length of the stored tuple. The tuple is allocated + * from the slab memory arena, or is palloc'd, see + * tuplesort_readtup_alloc(). + */ + void (*readtup) (Tuplesortstate *state, SortTuple *stup, + LogicalTape *tape, unsigned int len); + + /* + * Function to do some specific release of resources for the sort variant. + * In particular, this function should free everything stored in the "arg" + * field, which wouldn't be cleared on reset of the Tuple sort memory + * contexts. This can be NULL if nothing specific needs to be done. + */ + void (*freestate) (Tuplesortstate *state); + + /* + * The subsequent fields are used in the implementations of the functions + * above. + */ + MemoryContext maincontext; /* memory context for tuple sort metadata that + * persists across multiple batches */ + MemoryContext sortcontext; /* memory context holding most sort data */ + MemoryContext tuplecontext; /* sub-context of sortcontext for tuple data */ + + /* + * Whether SortTuple's datum1 and isnull1 members are maintained by the + * above routines. If not, some sort specializations are disabled. + */ + bool haveDatum1; + + /* + * The sortKeys variable is used by every case other than the hash index + * case; it is set by tuplesort_begin_xxx. tupDesc is only used by the + * MinimalTuple and CLUSTER routines, though. + */ + int nKeys; /* number of columns in sort key */ + SortSupport sortKeys; /* array of length nKeys */ + + /* + * This variable is shared by the single-key MinimalTuple case and the + * Datum case (which both use qsort_ssup()). Otherwise, it's NULL. The + * presence of a value in this field is also checked by various sort + * specialization functions as an optimization when comparing the leading + * key in a tiebreak situation to determine if there are any subsequent + * keys to sort on. + */ + SortSupport onlyKey; + + int sortopt; /* Bitmask of flags used to setup sort */ + + bool tuples; /* Can SortTuple.tuple ever be set? */ + + void *arg; /* Specific information for the sort variant */ +} TuplesortPublic; + +/* Sort parallel code from state for sort__start probes */ +#define PARALLEL_SORT(coordinate) (coordinate == NULL || \ + (coordinate)->sharedsort == NULL ? 0 : \ + (coordinate)->isWorker ? 1 : 2) + +#define TuplesortstateGetPublic(state) ((TuplesortPublic *) state) + +/* When using this macro, beware of double evaluation of len */ +#define LogicalTapeReadExact(tape, ptr, len) \ + do { \ + if (LogicalTapeRead(tape, ptr, len) != (size_t) (len)) \ + elog(ERROR, "unexpected end of data"); \ + } while(0) + +/* + * We provide multiple interfaces to what is essentially the same code, + * since different callers have different data to be sorted and want to + * specify the sort key information differently. There are two APIs for + * sorting HeapTuples and two more for sorting IndexTuples. Yet another + * API supports sorting bare Datums. + * + * Serial sort callers should pass NULL for their coordinate argument. + * + * The "heap" API actually stores/sorts MinimalTuples, which means it doesn't + * preserve the system columns (tuple identity and transaction visibility + * info). The sort keys are specified by column numbers within the tuples + * and sort operator OIDs. We save some cycles by passing and returning the + * tuples in TupleTableSlots, rather than forming actual HeapTuples (which'd + * have to be converted to MinimalTuples). This API works well for sorts + * executed as parts of plan trees. + * + * The "cluster" API stores/sorts full HeapTuples including all visibility + * info. The sort keys are specified by reference to a btree index that is + * defined on the relation to be sorted. Note that putheaptuple/getheaptuple + * go with this API, not the "begin_heap" one! + * + * The "index_btree" API stores/sorts IndexTuples (preserving all their + * header fields). The sort keys are specified by a btree index definition. + * + * The "index_hash" API is similar to index_btree, but the tuples are + * actually sorted by their hash codes not the raw data. + * + * Parallel sort callers are required to coordinate multiple tuplesort states + * in a leader process and one or more worker processes. The leader process + * must launch workers, and have each perform an independent "partial" + * tuplesort, typically fed by the parallel heap interface. The leader later + * produces the final output (internally, it merges runs output by workers). + * + * Callers must do the following to perform a sort in parallel using multiple + * worker processes: + * + * 1. Request tuplesort-private shared memory for n workers. Use + * tuplesort_estimate_shared() to get the required size. + * 2. Have leader process initialize allocated shared memory using + * tuplesort_initialize_shared(). Launch workers. + * 3. Initialize a coordinate argument within both the leader process, and + * for each worker process. This has a pointer to the shared + * tuplesort-private structure, as well as some caller-initialized fields. + * Leader's coordinate argument reliably indicates number of workers + * launched (this is unused by workers). + * 4. Begin a tuplesort using some appropriate tuplesort_begin* routine, + * (passing the coordinate argument) within each worker. The workMem + * arguments need not be identical. All other arguments should match + * exactly, though. + * 5. tuplesort_attach_shared() should be called by all workers. Feed tuples + * to each worker, and call tuplesort_performsort() within each when input + * is exhausted. + * 6. Call tuplesort_end() in each worker process. Worker processes can shut + * down once tuplesort_end() returns. + * 7. Begin a tuplesort in the leader using the same tuplesort_begin* + * routine, passing a leader-appropriate coordinate argument (this can + * happen as early as during step 3, actually, since we only need to know + * the number of workers successfully launched). The leader must now wait + * for workers to finish. Caller must use own mechanism for ensuring that + * next step isn't reached until all workers have called and returned from + * tuplesort_performsort(). (Note that it's okay if workers have already + * also called tuplesort_end() by then.) + * 8. Call tuplesort_performsort() in leader. Consume output using the + * appropriate tuplesort_get* routine. Leader can skip this step if + * tuplesort turns out to be unnecessary. + * 9. Call tuplesort_end() in leader. + * + * This division of labor assumes nothing about how input tuples are produced, + * but does require that caller combine the state of multiple tuplesorts for + * any purpose other than producing the final output. For example, callers + * must consider that tuplesort_get_stats() reports on only one worker's role + * in a sort (or the leader's role), and not statistics for the sort as a + * whole. + * + * Note that callers may use the leader process to sort runs as if it was an + * independent worker process (prior to the process performing a leader sort + * to produce the final sorted output). Doing so only requires a second + * "partial" tuplesort within the leader process, initialized like that of a + * worker process. The steps above don't touch on this directly. The only + * difference is that the tuplesort_attach_shared() call is never needed within + * leader process, because the backend as a whole holds the shared fileset + * reference. A worker Tuplesortstate in leader is expected to do exactly the + * same amount of total initial processing work as a worker process + * Tuplesortstate, since the leader process has nothing else to do before + * workers finish. + * + * Note that only a very small amount of memory will be allocated prior to + * the leader state first consuming input, and that workers will free the + * vast majority of their memory upon returning from tuplesort_performsort(). + * Callers can rely on this to arrange for memory to be used in a way that + * respects a workMem-style budget across an entire parallel sort operation. + * + * Callers are responsible for parallel safety in general. However, they + * can at least rely on there being no parallel safety hazards within + * tuplesort, because tuplesort thinks of the sort as several independent + * sorts whose results are combined. Since, in general, the behavior of + * sort operators is immutable, caller need only worry about the parallel + * safety of whatever the process is through which input tuples are + * generated (typically, caller uses a parallel heap scan). + */ + + +extern Tuplesortstate *tuplesort_begin_common(int workMem, + SortCoordinate coordinate, + int sortopt); +extern void tuplesort_set_bound(Tuplesortstate *state, int64 bound); +extern bool tuplesort_used_bound(Tuplesortstate *state); +extern void tuplesort_puttuple_common(Tuplesortstate *state, + SortTuple *tuple, bool useAbbrev); +extern void tuplesort_performsort(Tuplesortstate *state); +extern bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, + SortTuple *stup); +extern bool tuplesort_skiptuples(Tuplesortstate *state, int64 ntuples, + bool forward); +extern void tuplesort_end(Tuplesortstate *state); +extern void tuplesort_reset(Tuplesortstate *state); + +extern void tuplesort_get_stats(Tuplesortstate *state, + TuplesortInstrumentation *stats); +extern const char *tuplesort_method_name(TuplesortMethod m); +extern const char *tuplesort_space_type_name(TuplesortSpaceType t); + +extern int tuplesort_merge_order(int64 allowedMem); + +extern Size tuplesort_estimate_shared(int nWorkers); +extern void tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, + dsm_segment *seg); +extern void tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg); + +/* + * These routines may only be called if TUPLESORT_RANDOMACCESS was specified + * during tuplesort_begin_*. Additionally backwards scan in gettuple/getdatum + * also require TUPLESORT_RANDOMACCESS. Note that parallel sorts do not + * support random access. + */ +extern void tuplesort_rescan(Tuplesortstate *state); +extern void tuplesort_markpos(Tuplesortstate *state); +extern void tuplesort_restorepos(Tuplesortstate *state); + +extern void *tuplesort_readtup_alloc(Tuplesortstate *state, Size tuplen); + + +/* tuplesortvariants.c */ + +extern Tuplesortstate *tuplesort_begin_heap(TupleDesc tupDesc, + int nkeys, AttrNumber *attNums, + Oid *sortOperators, Oid *sortCollations, + bool *nullsFirstFlags, + int workMem, SortCoordinate coordinate, + int sortopt); +extern Tuplesortstate *tuplesort_begin_cluster(TupleDesc tupDesc, + Relation indexRel, int workMem, + SortCoordinate coordinate, + int sortopt); +extern Tuplesortstate *tuplesort_begin_index_btree(Relation heapRel, + Relation indexRel, + bool enforceUnique, + bool uniqueNullsNotDistinct, + int workMem, SortCoordinate coordinate, + int sortopt); +extern Tuplesortstate *tuplesort_begin_index_hash(Relation heapRel, + Relation indexRel, + uint32 high_mask, + uint32 low_mask, + uint32 max_buckets, + int workMem, SortCoordinate coordinate, + int sortopt); +extern Tuplesortstate *tuplesort_begin_index_gist(Relation heapRel, + Relation indexRel, + int workMem, SortCoordinate coordinate, + int sortopt); +extern Tuplesortstate *tuplesort_begin_datum(Oid datumType, + Oid sortOperator, Oid sortCollation, + bool nullsFirstFlag, + int workMem, SortCoordinate coordinate, + int sortopt); + +extern void tuplesort_puttupleslot(Tuplesortstate *state, + TupleTableSlot *slot); +extern void tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup); +extern void tuplesort_putindextuplevalues(Tuplesortstate *state, + Relation rel, ItemPointer self, + Datum *values, bool *isnull); +extern void tuplesort_putdatum(Tuplesortstate *state, Datum val, + bool isNull); + +extern bool tuplesort_gettupleslot(Tuplesortstate *state, bool forward, + bool copy, TupleTableSlot *slot, Datum *abbrev); +extern HeapTuple tuplesort_getheaptuple(Tuplesortstate *state, bool forward); +extern IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward); +extern bool tuplesort_getdatum(Tuplesortstate *state, bool forward, bool copy, + Datum *val, bool *isNull, Datum *abbrev); + + +#endif /* TUPLESORT_H */ diff --git a/install/include/postgresql/server/utils/tuplestore.h b/install/include/postgresql/server/utils/tuplestore.h new file mode 100644 index 00000000000..36424b80b1b --- /dev/null +++ b/install/include/postgresql/server/utils/tuplestore.h @@ -0,0 +1,91 @@ +/*------------------------------------------------------------------------- + * + * tuplestore.h + * Generalized routines for temporary tuple storage. + * + * This module handles temporary storage of tuples for purposes such + * as Materialize nodes, hashjoin batch files, etc. It is essentially + * a dumbed-down version of tuplesort.c; it does no sorting of tuples + * but can only store and regurgitate a sequence of tuples. However, + * because no sort is required, it is allowed to start reading the sequence + * before it has all been written. This is particularly useful for cursors, + * because it allows random access within the already-scanned portion of + * a query without having to process the underlying scan to completion. + * Also, it is possible to support multiple independent read pointers. + * + * A temporary file is used to handle the data if it exceeds the + * space limit specified by the caller. + * + * Beginning in Postgres 8.2, what is stored is just MinimalTuples; + * callers cannot expect valid system columns in regurgitated tuples. + * Also, we have changed the API to return tuples in TupleTableSlots, + * so that there is a check to prevent attempted access to system columns. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/tuplestore.h + * + *------------------------------------------------------------------------- + */ +#ifndef TUPLESTORE_H +#define TUPLESTORE_H + +#include "executor/tuptable.h" + + +/* Tuplestorestate is an opaque type whose details are not known outside + * tuplestore.c. + */ +typedef struct Tuplestorestate Tuplestorestate; + +/* + * Currently we only need to store MinimalTuples, but it would be easy + * to support the same behavior for IndexTuples and/or bare Datums. + */ + +extern Tuplestorestate *tuplestore_begin_heap(bool randomAccess, + bool interXact, + int maxKBytes); + +extern void tuplestore_set_eflags(Tuplestorestate *state, int eflags); + +extern void tuplestore_puttupleslot(Tuplestorestate *state, + TupleTableSlot *slot); +extern void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple); +extern void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, + Datum *values, bool *isnull); + +/* Backwards compatibility macro */ +#define tuplestore_donestoring(state) ((void) 0) + +extern int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags); + +extern void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr); + +extern void tuplestore_copy_read_pointer(Tuplestorestate *state, + int srcptr, int destptr); + +extern void tuplestore_trim(Tuplestorestate *state); + +extern bool tuplestore_in_memory(Tuplestorestate *state); + +extern bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, + bool copy, TupleTableSlot *slot); + +extern bool tuplestore_advance(Tuplestorestate *state, bool forward); + +extern bool tuplestore_skiptuples(Tuplestorestate *state, + int64 ntuples, bool forward); + +extern int64 tuplestore_tuple_count(Tuplestorestate *state); + +extern bool tuplestore_ateof(Tuplestorestate *state); + +extern void tuplestore_rescan(Tuplestorestate *state); + +extern void tuplestore_clear(Tuplestorestate *state); + +extern void tuplestore_end(Tuplestorestate *state); + +#endif /* TUPLESTORE_H */ diff --git a/install/include/postgresql/server/utils/typcache.h b/install/include/postgresql/server/utils/typcache.h new file mode 100644 index 00000000000..95f3a9ee308 --- /dev/null +++ b/install/include/postgresql/server/utils/typcache.h @@ -0,0 +1,209 @@ +/*------------------------------------------------------------------------- + * + * typcache.h + * Type cache definitions. + * + * The type cache exists to speed lookup of certain information about data + * types that is not directly available from a type's pg_type row. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/typcache.h + * + *------------------------------------------------------------------------- + */ +#ifndef TYPCACHE_H +#define TYPCACHE_H + +#include "access/tupdesc.h" +#include "fmgr.h" +#include "storage/dsm.h" +#include "utils/dsa.h" + + +/* DomainConstraintCache is an opaque struct known only within typcache.c */ +typedef struct DomainConstraintCache DomainConstraintCache; + +/* TypeCacheEnumData is an opaque struct known only within typcache.c */ +struct TypeCacheEnumData; + +typedef struct TypeCacheEntry +{ + /* typeId is the hash lookup key and MUST BE FIRST */ + Oid type_id; /* OID of the data type */ + + uint32 type_id_hash; /* hashed value of the OID */ + + /* some subsidiary information copied from the pg_type row */ + int16 typlen; + bool typbyval; + char typalign; + char typstorage; + char typtype; + Oid typrelid; + Oid typsubscript; + Oid typelem; + Oid typcollation; + + /* + * Information obtained from opfamily entries + * + * These will be InvalidOid if no match could be found, or if the + * information hasn't yet been requested. Also note that for array and + * composite types, typcache.c checks that the contained types are + * comparable or hashable before allowing eq_opr etc to become set. + */ + Oid btree_opf; /* the default btree opclass' family */ + Oid btree_opintype; /* the default btree opclass' opcintype */ + Oid hash_opf; /* the default hash opclass' family */ + Oid hash_opintype; /* the default hash opclass' opcintype */ + Oid eq_opr; /* the equality operator */ + Oid lt_opr; /* the less-than operator */ + Oid gt_opr; /* the greater-than operator */ + Oid cmp_proc; /* the btree comparison function */ + Oid hash_proc; /* the hash calculation function */ + Oid hash_extended_proc; /* the extended hash calculation function */ + + /* + * Pre-set-up fmgr call info for the equality operator, the btree + * comparison function, and the hash calculation function. These are kept + * in the type cache to avoid problems with memory leaks in repeated calls + * to functions such as array_eq, array_cmp, hash_array. There is not + * currently a need to maintain call info for the lt_opr or gt_opr. + */ + FmgrInfo eq_opr_finfo; + FmgrInfo cmp_proc_finfo; + FmgrInfo hash_proc_finfo; + FmgrInfo hash_extended_proc_finfo; + + /* + * Tuple descriptor if it's a composite type (row type). NULL if not + * composite or information hasn't yet been requested. (NOTE: this is a + * reference-counted tupledesc.) + * + * To simplify caching dependent info, tupDesc_identifier is an identifier + * for this tupledesc that is unique for the life of the process, and + * changes anytime the tupledesc does. Zero if not yet determined. + */ + TupleDesc tupDesc; + uint64 tupDesc_identifier; + + /* + * Fields computed when TYPECACHE_RANGE_INFO is requested. Zeroes if not + * a range type or information hasn't yet been requested. Note that + * rng_cmp_proc_finfo could be different from the element type's default + * btree comparison function. + */ + struct TypeCacheEntry *rngelemtype; /* range's element type */ + Oid rng_collation; /* collation for comparisons, if any */ + FmgrInfo rng_cmp_proc_finfo; /* comparison function */ + FmgrInfo rng_canonical_finfo; /* canonicalization function, if any */ + FmgrInfo rng_subdiff_finfo; /* difference function, if any */ + + /* + * Fields computed when TYPECACHE_MULTIRANGE_INFO is required. + */ + struct TypeCacheEntry *rngtype; /* multirange's range underlying type */ + + /* + * Domain's base type and typmod if it's a domain type. Zeroes if not + * domain, or if information hasn't been requested. + */ + Oid domainBaseType; + int32 domainBaseTypmod; + + /* + * Domain constraint data if it's a domain type. NULL if not domain, or + * if domain has no constraints, or if information hasn't been requested. + */ + DomainConstraintCache *domainData; + + /* Private data, for internal use of typcache.c only */ + int flags; /* flags about what we've computed */ + + /* + * Private information about an enum type. NULL if not enum or + * information hasn't been requested. + */ + struct TypeCacheEnumData *enumData; + + /* We also maintain a list of all known domain-type cache entries */ + struct TypeCacheEntry *nextDomain; +} TypeCacheEntry; + +/* Bit flags to indicate which fields a given caller needs to have set */ +#define TYPECACHE_EQ_OPR 0x00001 +#define TYPECACHE_LT_OPR 0x00002 +#define TYPECACHE_GT_OPR 0x00004 +#define TYPECACHE_CMP_PROC 0x00008 +#define TYPECACHE_HASH_PROC 0x00010 +#define TYPECACHE_EQ_OPR_FINFO 0x00020 +#define TYPECACHE_CMP_PROC_FINFO 0x00040 +#define TYPECACHE_HASH_PROC_FINFO 0x00080 +#define TYPECACHE_TUPDESC 0x00100 +#define TYPECACHE_BTREE_OPFAMILY 0x00200 +#define TYPECACHE_HASH_OPFAMILY 0x00400 +#define TYPECACHE_RANGE_INFO 0x00800 +#define TYPECACHE_DOMAIN_BASE_INFO 0x01000 +#define TYPECACHE_DOMAIN_CONSTR_INFO 0x02000 +#define TYPECACHE_HASH_EXTENDED_PROC 0x04000 +#define TYPECACHE_HASH_EXTENDED_PROC_FINFO 0x08000 +#define TYPECACHE_MULTIRANGE_INFO 0x10000 + +/* This value will not equal any valid tupledesc identifier, nor 0 */ +#define INVALID_TUPLEDESC_IDENTIFIER ((uint64) 1) + +/* + * Callers wishing to maintain a long-lived reference to a domain's constraint + * set must store it in one of these. Use InitDomainConstraintRef() and + * UpdateDomainConstraintRef() to manage it. Note: DomainConstraintState is + * considered an executable expression type, so it's defined in execnodes.h. + */ +typedef struct DomainConstraintRef +{ + List *constraints; /* list of DomainConstraintState nodes */ + MemoryContext refctx; /* context holding DomainConstraintRef */ + TypeCacheEntry *tcache; /* typcache entry for domain type */ + bool need_exprstate; /* does caller need check_exprstate? */ + + /* Management data --- treat these fields as private to typcache.c */ + DomainConstraintCache *dcc; /* current constraints, or NULL if none */ + MemoryContextCallback callback; /* used to release refcount when done */ +} DomainConstraintRef; + +typedef struct SharedRecordTypmodRegistry SharedRecordTypmodRegistry; + +extern TypeCacheEntry *lookup_type_cache(Oid type_id, int flags); + +extern void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref, + MemoryContext refctx, bool need_exprstate); + +extern void UpdateDomainConstraintRef(DomainConstraintRef *ref); + +extern bool DomainHasConstraints(Oid type_id); + +extern TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod); + +extern TupleDesc lookup_rowtype_tupdesc_noerror(Oid type_id, int32 typmod, + bool noError); + +extern TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod); + +extern TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, + bool noError); + +extern void assign_record_type_typmod(TupleDesc tupDesc); + +extern uint64 assign_record_type_identifier(Oid type_id, int32 typmod); + +extern int compare_values_of_enum(TypeCacheEntry *tcache, Oid arg1, Oid arg2); + +extern size_t SharedRecordTypmodRegistryEstimate(void); + +extern void SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *, + dsm_segment *segment, dsa_area *area); + +extern void SharedRecordTypmodRegistryAttach(SharedRecordTypmodRegistry *); + +#endif /* TYPCACHE_H */ diff --git a/install/include/postgresql/server/utils/tzparser.h b/install/include/postgresql/server/utils/tzparser.h new file mode 100644 index 00000000000..760785b2bf2 --- /dev/null +++ b/install/include/postgresql/server/utils/tzparser.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * + * tzparser.h + * Timezone offset file parsing definitions. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/tzparser.h + * + *------------------------------------------------------------------------- + */ +#ifndef TZPARSER_H +#define TZPARSER_H + +#include "utils/datetime.h" + +/* + * The result of parsing a timezone configuration file is an array of + * these structs, in order by abbrev. We export this because datetime.c + * needs it. + */ +typedef struct tzEntry +{ + /* the actual data */ + char *abbrev; /* TZ abbreviation (downcased) */ + char *zone; /* zone name if dynamic abbrev, else NULL */ + /* for a dynamic abbreviation, offset/is_dst are not used */ + int offset; /* offset in seconds from UTC */ + bool is_dst; /* true if a DST abbreviation */ + /* source information (for error messages) */ + int lineno; + const char *filename; +} tzEntry; + + +extern TimeZoneAbbrevTable *load_tzoffsets(const char *filename); + +#endif /* TZPARSER_H */ diff --git a/install/include/postgresql/server/utils/usercontext.h b/install/include/postgresql/server/utils/usercontext.h new file mode 100644 index 00000000000..a8195c194de --- /dev/null +++ b/install/include/postgresql/server/utils/usercontext.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * usercontext.h + * Convenience functions for running code as a different database user. + * + *------------------------------------------------------------------------- + */ +#ifndef USERCONTEXT_H +#define USERCONTEXT_H + +/* + * When temporarily changing to run as a different user, this structure + * holds the details needed to restore the original state. + */ +typedef struct UserContext +{ + Oid save_userid; + int save_sec_context; + int save_nestlevel; +} UserContext; + +/* Function prototypes. */ +extern void SwitchToUntrustedUser(Oid userid, UserContext *context); +extern void RestoreUserContext(UserContext *context); + +#endif /* USERCONTEXT_H */ diff --git a/install/include/postgresql/server/utils/uuid.h b/install/include/postgresql/server/utils/uuid.h new file mode 100644 index 00000000000..11177171b2c --- /dev/null +++ b/install/include/postgresql/server/utils/uuid.h @@ -0,0 +1,42 @@ +/*------------------------------------------------------------------------- + * + * uuid.h + * Header file for the "uuid" ADT. In C, we use the name pg_uuid_t, + * to avoid conflicts with any uuid_t type that might be defined by + * the system headers. + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/include/utils/uuid.h + * + *------------------------------------------------------------------------- + */ +#ifndef UUID_H +#define UUID_H + +/* uuid size in bytes */ +#define UUID_LEN 16 + +typedef struct pg_uuid_t +{ + unsigned char data[UUID_LEN]; +} pg_uuid_t; + +/* fmgr interface macros */ +static inline Datum +UUIDPGetDatum(const pg_uuid_t *X) +{ + return PointerGetDatum(X); +} + +#define PG_RETURN_UUID_P(X) return UUIDPGetDatum(X) + +static inline pg_uuid_t * +DatumGetUUIDP(Datum X) +{ + return (pg_uuid_t *) DatumGetPointer(X); +} + +#define PG_GETARG_UUID_P(X) DatumGetUUIDP(PG_GETARG_DATUM(X)) + +#endif /* UUID_H */ diff --git a/install/include/postgresql/server/utils/varbit.h b/install/include/postgresql/server/utils/varbit.h new file mode 100644 index 00000000000..3bb7945ed99 --- /dev/null +++ b/install/include/postgresql/server/utils/varbit.h @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------- + * + * varbit.h + * Functions for the SQL datatypes BIT() and BIT VARYING(). + * + * Code originally contributed by Adriaan Joubert. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/varbit.h + * + *------------------------------------------------------------------------- + */ +#ifndef VARBIT_H +#define VARBIT_H + +#include + +#include "fmgr.h" + +/* + * Modeled on struct varlena from postgres.h, but data type is bits8. + * + * Caution: if bit_len is not a multiple of BITS_PER_BYTE, the low-order + * bits of the last byte of bit_dat[] are unused and MUST be zeroes. + * (This allows bit_cmp() to not bother masking the last byte.) + * Also, there should not be any excess bytes counted in the header length. + */ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 bit_len; /* number of valid bits */ + bits8 bit_dat[FLEXIBLE_ARRAY_MEMBER]; /* bit string, most sig. byte + * first */ +} VarBit; + +/* + * fmgr interface macros + * + * BIT and BIT VARYING are toastable varlena types. They are the same + * as far as representation goes, so we just have one set of macros. + */ +static inline VarBit * +DatumGetVarBitP(Datum X) +{ + return (VarBit *) PG_DETOAST_DATUM(X); +} + +static inline VarBit * +DatumGetVarBitPCopy(Datum X) +{ + return (VarBit *) PG_DETOAST_DATUM_COPY(X); +} + +static inline Datum +VarBitPGetDatum(const VarBit *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_VARBIT_P(n) DatumGetVarBitP(PG_GETARG_DATUM(n)) +#define PG_GETARG_VARBIT_P_COPY(n) DatumGetVarBitPCopy(PG_GETARG_DATUM(n)) +#define PG_RETURN_VARBIT_P(x) return VarBitPGetDatum(x) + +/* Header overhead *in addition to* VARHDRSZ */ +#define VARBITHDRSZ sizeof(int32) +/* Number of bits in this bit string */ +#define VARBITLEN(PTR) (((VarBit *) (PTR))->bit_len) +/* Pointer to the first byte containing bit string data */ +#define VARBITS(PTR) (((VarBit *) (PTR))->bit_dat) +/* Number of bytes in the data section of a bit string */ +#define VARBITBYTES(PTR) (VARSIZE(PTR) - VARHDRSZ - VARBITHDRSZ) +/* Padding of the bit string at the end (in bits) */ +#define VARBITPAD(PTR) (VARBITBYTES(PTR)*BITS_PER_BYTE - VARBITLEN(PTR)) +/* Number of bytes needed to store a bit string of a given length */ +#define VARBITTOTALLEN(BITLEN) (((BITLEN) + BITS_PER_BYTE-1)/BITS_PER_BYTE + \ + VARHDRSZ + VARBITHDRSZ) +/* + * Maximum number of bits. Several code sites assume no overflow from + * computing bitlen + X; VARBITTOTALLEN() has the largest such X. + */ +#define VARBITMAXLEN (INT_MAX - BITS_PER_BYTE + 1) +/* pointer beyond the end of the bit string (like end() in STL containers) */ +#define VARBITEND(PTR) (((bits8 *) (PTR)) + VARSIZE(PTR)) +/* Mask that will cover exactly one byte, i.e. BITS_PER_BYTE bits */ +#define BITMASK 0xFF + +#endif diff --git a/install/include/postgresql/server/utils/varlena.h b/install/include/postgresql/server/utils/varlena.h new file mode 100644 index 00000000000..77f5b247351 --- /dev/null +++ b/install/include/postgresql/server/utils/varlena.h @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * varlena.h + * Functions for the variable-length built-in types. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/varlena.h + * + *------------------------------------------------------------------------- + */ +#ifndef VARLENA_H +#define VARLENA_H + +#include "nodes/pg_list.h" +#include "utils/sortsupport.h" + +extern int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid); +extern void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid); +extern int varstr_levenshtein(const char *source, int slen, + const char *target, int tlen, + int ins_c, int del_c, int sub_c, + bool trusted); +extern int varstr_levenshtein_less_equal(const char *source, int slen, + const char *target, int tlen, + int ins_c, int del_c, int sub_c, + int max_d, bool trusted); +extern List *textToQualifiedNameList(text *textval); +extern bool SplitIdentifierString(char *rawstring, char separator, + List **namelist); +extern bool SplitDirectoriesString(char *rawstring, char separator, + List **namelist); +extern bool SplitGUCList(char *rawstring, char separator, + List **namelist); +extern text *replace_text_regexp(text *src_text, text *pattern_text, + text *replace_text, + int cflags, Oid collation, + int search_start, int n); + +typedef struct ClosestMatchState +{ + const char *source; + int min_d; + int max_d; + const char *match; +} ClosestMatchState; + +extern void initClosestMatch(ClosestMatchState *state, const char *source, int max_d); +extern void updateClosestMatch(ClosestMatchState *state, const char *candidate); +extern const char *getClosestMatch(ClosestMatchState *state); + +#endif diff --git a/install/include/postgresql/server/utils/wait_event.h b/install/include/postgresql/server/utils/wait_event.h new file mode 100644 index 00000000000..9256ad0d84e --- /dev/null +++ b/install/include/postgresql/server/utils/wait_event.h @@ -0,0 +1,639 @@ +/*------------------------------------------------------------------------- + * wait_event.h + * Definitions related to wait event reporting + * + * Copyright (c) 2001-2023, PostgreSQL Global Development Group + * + * src/include/utils/wait_event.h + * ---------- + * + * PGRAC MODIFICATIONS + * Modified by: SqlRush + * Stage: 0.11 / 1.1 + * + * Added the WaitEventCluster enum (now 51 entries spread across + * 11 class IDs 0x10000000..0x1a000000) and pulled in + * cluster/cluster_wait_events.h for the class-ID macros. No PG + * native enum is touched; the cluster enum is independent. + * + * Stage 0.11 registered the original 46 entries across 10 classes + * (GES / PCM / BufferShip / SCN / Reconfig / Recovery / Sinval / + * Interconnect / Undo / ADG). Stage 1.1 extended with the + * Cluster: SharedFs class and 5 events for cluster_shared_fs + * (read / write / extend / truncate / fsync). + * + * Identifiers are registered here; the call sites that emit + * these wait events are wired up in the spec for each owning + * subsystem (GES events in spec-1.X-ges, PCM events in + * spec-2.X-pcm, SharedFs events when stage 6+ wires production + * perf instrumentation, ...). + * + * Related design: + * docs/wait-events-design.md v1.1 §14.1 / §14.2 + * specs/spec-0.11-wait-events-framework.md + * specs/spec-1.1-shared-fs-skeleton.md + * + *------------------------------------------------------------------------- + */ +#ifndef WAIT_EVENT_H +#define WAIT_EVENT_H + +/* PGRAC: pull in cluster wait class IDs (10 PG_WAIT_CLUSTER_* macros). */ +#include "cluster/cluster_wait_events.h" + + +/* ---------- + * Wait Classes + * ---------- + */ +#define PG_WAIT_LWLOCK 0x01000000U +#define PG_WAIT_LOCK 0x03000000U +#define PG_WAIT_BUFFER_PIN 0x04000000U +#define PG_WAIT_ACTIVITY 0x05000000U +#define PG_WAIT_CLIENT 0x06000000U +#define PG_WAIT_EXTENSION 0x07000000U +#define PG_WAIT_IPC 0x08000000U +#define PG_WAIT_TIMEOUT 0x09000000U +#define PG_WAIT_IO 0x0A000000U + +/* ---------- + * Wait Events - Activity + * + * Use this category when a process is waiting because it has no work to do, + * unless the "Client" or "Timeout" category describes the situation better. + * Typically, this should only be used for background processes. + * ---------- + */ +typedef enum { + WAIT_EVENT_ARCHIVER_MAIN = PG_WAIT_ACTIVITY, + WAIT_EVENT_AUTOVACUUM_MAIN, + WAIT_EVENT_BGWRITER_HIBERNATE, + WAIT_EVENT_BGWRITER_MAIN, + WAIT_EVENT_CHECKPOINTER_MAIN, + WAIT_EVENT_LOGICAL_APPLY_MAIN, + WAIT_EVENT_LOGICAL_LAUNCHER_MAIN, + WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN, + WAIT_EVENT_RECOVERY_WAL_STREAM, + WAIT_EVENT_SYSLOGGER_MAIN, + WAIT_EVENT_WAL_RECEIVER_MAIN, + WAIT_EVENT_WAL_SENDER_MAIN, + WAIT_EVENT_WAL_WRITER_MAIN +} WaitEventActivity; + +/* ---------- + * Wait Events - Client + * + * Use this category when a process is waiting to send data to or receive data + * from the frontend process to which it is connected. This is never used for + * a background process, which has no client connection. + * ---------- + */ +typedef enum { + WAIT_EVENT_CLIENT_READ = PG_WAIT_CLIENT, + WAIT_EVENT_CLIENT_WRITE, + WAIT_EVENT_GSS_OPEN_SERVER, + WAIT_EVENT_LIBPQWALRECEIVER_CONNECT, + WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE, + WAIT_EVENT_SSL_OPEN_SERVER, + WAIT_EVENT_WAL_SENDER_WAIT_WAL, + WAIT_EVENT_WAL_SENDER_WRITE_DATA, +} WaitEventClient; + +/* ---------- + * Wait Events - IPC + * + * Use this category when a process cannot complete the work it is doing because + * it is waiting for a notification from another process. + * ---------- + */ +typedef enum { + WAIT_EVENT_APPEND_READY = PG_WAIT_IPC, + WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND, + WAIT_EVENT_ARCHIVE_COMMAND, + WAIT_EVENT_BACKEND_TERMINATION, + WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE, + WAIT_EVENT_BGWORKER_SHUTDOWN, + WAIT_EVENT_BGWORKER_STARTUP, + WAIT_EVENT_BTREE_PAGE, + WAIT_EVENT_BUFFER_IO, + WAIT_EVENT_CHECKPOINT_DONE, + WAIT_EVENT_CHECKPOINT_START, + WAIT_EVENT_EXECUTE_GATHER, + WAIT_EVENT_HASH_BATCH_ALLOCATE, + WAIT_EVENT_HASH_BATCH_ELECT, + WAIT_EVENT_HASH_BATCH_LOAD, + WAIT_EVENT_HASH_BUILD_ALLOCATE, + WAIT_EVENT_HASH_BUILD_ELECT, + WAIT_EVENT_HASH_BUILD_HASH_INNER, + WAIT_EVENT_HASH_BUILD_HASH_OUTER, + WAIT_EVENT_HASH_GROW_BATCHES_DECIDE, + WAIT_EVENT_HASH_GROW_BATCHES_ELECT, + WAIT_EVENT_HASH_GROW_BATCHES_FINISH, + WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE, + WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION, + WAIT_EVENT_HASH_GROW_BUCKETS_ELECT, + WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE, + WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT, + WAIT_EVENT_LOGICAL_APPLY_SEND_DATA, + WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE, + WAIT_EVENT_LOGICAL_SYNC_DATA, + WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE, + WAIT_EVENT_MQ_INTERNAL, + WAIT_EVENT_MQ_PUT_MESSAGE, + WAIT_EVENT_MQ_RECEIVE, + WAIT_EVENT_MQ_SEND, + WAIT_EVENT_PARALLEL_BITMAP_SCAN, + WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN, + WAIT_EVENT_PARALLEL_FINISH, + WAIT_EVENT_PROCARRAY_GROUP_UPDATE, + WAIT_EVENT_PROC_SIGNAL_BARRIER, + WAIT_EVENT_PROMOTE, + WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT, + WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE, + WAIT_EVENT_RECOVERY_END_COMMAND, + WAIT_EVENT_RECOVERY_PAUSE, + WAIT_EVENT_REPLICATION_ORIGIN_DROP, + WAIT_EVENT_REPLICATION_SLOT_DROP, + WAIT_EVENT_RESTORE_COMMAND, + WAIT_EVENT_SAFE_SNAPSHOT, + WAIT_EVENT_SYNC_REP, + WAIT_EVENT_WAL_RECEIVER_EXIT, + WAIT_EVENT_WAL_RECEIVER_WAIT_START, + WAIT_EVENT_XACT_GROUP_UPDATE +} WaitEventIPC; + +/* ---------- + * Wait Events - Timeout + * + * Use this category when a process is waiting for a timeout to expire. + * ---------- + */ +typedef enum { + WAIT_EVENT_BASE_BACKUP_THROTTLE = PG_WAIT_TIMEOUT, + WAIT_EVENT_CHECKPOINT_WRITE_DELAY, + WAIT_EVENT_PG_SLEEP, + WAIT_EVENT_RECOVERY_APPLY_DELAY, + WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL, + WAIT_EVENT_REGISTER_SYNC_REQUEST, + WAIT_EVENT_SPIN_DELAY, + WAIT_EVENT_VACUUM_DELAY, + WAIT_EVENT_VACUUM_TRUNCATE +} WaitEventTimeout; + +/* ---------- + * Wait Events - IO + * + * Use this category when a process is waiting for a IO. + * ---------- + */ +typedef enum { + WAIT_EVENT_BASEBACKUP_READ = PG_WAIT_IO, + WAIT_EVENT_BASEBACKUP_SYNC, + WAIT_EVENT_BASEBACKUP_WRITE, + WAIT_EVENT_BUFFILE_READ, + WAIT_EVENT_BUFFILE_WRITE, + WAIT_EVENT_BUFFILE_TRUNCATE, + WAIT_EVENT_CONTROL_FILE_READ, + WAIT_EVENT_CONTROL_FILE_SYNC, + WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE, + WAIT_EVENT_CONTROL_FILE_WRITE, + WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE, + WAIT_EVENT_COPY_FILE_READ, + WAIT_EVENT_COPY_FILE_WRITE, + WAIT_EVENT_DATA_FILE_EXTEND, + WAIT_EVENT_DATA_FILE_FLUSH, + WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC, + WAIT_EVENT_DATA_FILE_PREFETCH, + WAIT_EVENT_DATA_FILE_READ, + WAIT_EVENT_DATA_FILE_SYNC, + WAIT_EVENT_DATA_FILE_TRUNCATE, + WAIT_EVENT_DATA_FILE_WRITE, + WAIT_EVENT_DSM_ALLOCATE, + WAIT_EVENT_DSM_FILL_ZERO_WRITE, + WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ, + WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC, + WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE, + WAIT_EVENT_LOCK_FILE_CREATE_READ, + WAIT_EVENT_LOCK_FILE_CREATE_SYNC, + WAIT_EVENT_LOCK_FILE_CREATE_WRITE, + WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ, + WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC, + WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC, + WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE, + WAIT_EVENT_LOGICAL_REWRITE_SYNC, + WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE, + WAIT_EVENT_LOGICAL_REWRITE_WRITE, + WAIT_EVENT_RELATION_MAP_READ, + WAIT_EVENT_RELATION_MAP_REPLACE, + WAIT_EVENT_RELATION_MAP_WRITE, + WAIT_EVENT_REORDER_BUFFER_READ, + WAIT_EVENT_REORDER_BUFFER_WRITE, + WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ, + WAIT_EVENT_REPLICATION_SLOT_READ, + WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC, + WAIT_EVENT_REPLICATION_SLOT_SYNC, + WAIT_EVENT_REPLICATION_SLOT_WRITE, + WAIT_EVENT_SLRU_FLUSH_SYNC, + WAIT_EVENT_SLRU_READ, + WAIT_EVENT_SLRU_SYNC, + WAIT_EVENT_SLRU_WRITE, + WAIT_EVENT_SNAPBUILD_READ, + WAIT_EVENT_SNAPBUILD_SYNC, + WAIT_EVENT_SNAPBUILD_WRITE, + WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC, + WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE, + WAIT_EVENT_TIMELINE_HISTORY_READ, + WAIT_EVENT_TIMELINE_HISTORY_SYNC, + WAIT_EVENT_TIMELINE_HISTORY_WRITE, + WAIT_EVENT_TWOPHASE_FILE_READ, + WAIT_EVENT_TWOPHASE_FILE_SYNC, + WAIT_EVENT_TWOPHASE_FILE_WRITE, + WAIT_EVENT_VERSION_FILE_WRITE, + WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ, + WAIT_EVENT_WAL_BOOTSTRAP_SYNC, + WAIT_EVENT_WAL_BOOTSTRAP_WRITE, + WAIT_EVENT_WAL_COPY_READ, + WAIT_EVENT_WAL_COPY_SYNC, + WAIT_EVENT_WAL_COPY_WRITE, + WAIT_EVENT_WAL_INIT_SYNC, + WAIT_EVENT_WAL_INIT_WRITE, + WAIT_EVENT_WAL_READ, + WAIT_EVENT_WAL_SYNC, + WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN, + WAIT_EVENT_WAL_WRITE, + WAIT_EVENT_VERSION_FILE_SYNC +} WaitEventIO; + + +/* ---------- + * Wait Events - Cluster (PGRAC, stage 0.11) + * + * pgrac cluster wait events span 13 categories (10 from stage 0.11 plus + * SharedFs, StartupPhase, and BgProc), each with its own class + * ID in the upper byte (PG_WAIT_CLUSTER_* macros from cluster_wait_events.h). + * Within a category, events are densely packed. See + * docs/wait-events-design.md §3-§12 for per-event semantics and + * specs/spec-0.11-wait-events-framework.md for the registration policy. + * + * Stage 0.11 registers identifiers only; pgstat_report_wait_start() call + * sites land in the spec for each owning subsystem. + * ---------- + */ +typedef enum { + /* Cluster: GES (5+3 events) -- subsystem #8 */ + WAIT_EVENT_GES_ENQUEUE_ACQUIRE = PG_WAIT_CLUSTER_GES, + WAIT_EVENT_GES_ENQUEUE_CONVERT, + WAIT_EVENT_GES_ENQUEUE_RELEASE_ACK, + WAIT_EVENT_GES_MASTER_QUERY, + WAIT_EVENT_GES_LOCAL_FAST_PATH, + /* spec-2.16 D13 (3 NEW per v0.4 Q13 + L2.1): cross-node grant wait + * surfaces. GRANT_WAIT — backend wait latch for GES reply (S4 wait); + * CONVERT_WAIT — caller wait for convert ack; DRAIN — LMON drain + * dirty-list / work queue. */ + WAIT_EVENT_GES_GRANT_WAIT, + WAIT_EVENT_GES_CONVERT_WAIT, + WAIT_EVENT_GES_DRAIN, + /* spec-2.17 D28 NEW 4 wait events. */ + WAIT_EVENT_GES_BAST_WAIT, + WAIT_EVENT_GES_DEADLOCK_PROBE_WAIT, + WAIT_EVENT_GES_CANCEL_DRAIN, + WAIT_EVENT_GES_DEADLOCK_REASSEMBLY_WAIT, + /* spec-5.2 D9: cross-node TX enqueue completion wait (a backend blocked + * on a row lock held by a transaction on another node). */ + WAIT_EVENT_GES_TX_ENQUEUE_WAIT, + + /* Cluster: PCM (14 events: base 6 + spec-2.30 2 + spec-2.31 1 + + * spec-2.32 1 + spec-2.33 4) -- subsystem #6 */ + WAIT_EVENT_PCM_BLOCK_READ_N_S = PG_WAIT_CLUSTER_PCM, + WAIT_EVENT_PCM_BLOCK_READ_N_X, + WAIT_EVENT_PCM_BLOCK_WRITE_S_X, + WAIT_EVENT_PCM_BLOCK_CONVERT_WAIT, + WAIT_EVENT_PCM_BLOCK_DOWNGRADE, + WAIT_EVENT_PCM_ITL_CLEANOUT, + /* PGRAC (spec-2.30 D8): GrdEntry HTAB init at postmaster startup. */ + WAIT_EVENT_PCM_GRD_INIT, + /* PGRAC (spec-2.30 D8): per-entry entry_lock acquire hot path. */ + WAIT_EVENT_PCM_TRANSITION_APPLY, + /* PGRAC (spec-2.31 D6 F3 v0.4): wait_cv ConditionVariableSleep when + * cluster_pcm_lock_acquire sees incompatible holder state. Bufmgr + * content-lock hook contention path; DBA sees backend waiting on + * 'ClusterPcmCompatibleStateWait' in pg_stat_activity. */ + WAIT_EVENT_PCM_COMPATIBLE_STATE_WAIT, + /* PGRAC (spec-2.32 D7): sender waits on outstanding-slot CV for GCS + * reply from master node after sending PGRAC_IC_MSG_GCS_REQUEST. + * Classified under PG_WAIT_CLUSTER_PCM family (semantic: waiting for + * PCM/GCS transition reply, not GES lock acquire). */ + WAIT_EVENT_GCS_REPLY_WAIT, + /* PGRAC (spec-2.33 D9 NEW 4 wait events; block-shipping data plane). + * GCS_BLOCK_SHIP_WAIT — sender backend ConditionVariableTimedSleep on + * outstanding-slot CV waiting for GCS_BLOCK_REPLY (HC85; pg_stat_activity + * shows 'ClusterGCSBlockShipWait'). GCS_BLOCK_REQUEST_DISPATCH / + * GCS_BLOCK_REPLY_DISPATCH — receiver-side cluster_ic dispatch event + * latch (rare, kept symmetric with control plane events). + * GCS_BLOCK_CHECKSUM_FAIL — sender-side recovery / cleanup path after + * HC83 CRC32C mismatch (DBA-visible diagnostic). */ + WAIT_EVENT_GCS_BLOCK_SHIP_WAIT, + WAIT_EVENT_GCS_BLOCK_REQUEST_DISPATCH, + WAIT_EVENT_GCS_BLOCK_REPLY_DISPATCH, + WAIT_EVENT_GCS_BLOCK_CHECKSUM_FAIL, + /* PGRAC (spec-2.34 D7 NEW 2 wait events; reliability hardening). + * GCS_BLOCK_RETRANSMIT_WAIT — sender WaitLatch sleep during exponential + * backoff between retry attempts (visible in pg_stat_activity as + * 'ClusterGCSBlockRetransmitWait'). GCS_BLOCK_EPOCH_STALE_RETRY — + * sender CV wake after DENIED_EPOCH_STALE + re-lookup_master path + * (HC94 lazy retry annotation). */ + WAIT_EVENT_GCS_BLOCK_RETRANSMIT_WAIT, + WAIT_EVENT_GCS_BLOCK_EPOCH_STALE_RETRY, + /* PGRAC (spec-2.36 D8 NEW 3 wait events; CF 3-way protocol). + * GCS_BLOCK_INVALIDATE_BROADCAST — master backend sleep while + * enumerating holders + dispatching INVALIDATE envelopes. + * GCS_BLOCK_INVALIDATE_ACK_WAIT — master backend ConditionVariable + * sleep waiting for INVALIDATE_ACK from all holders in bitmap. + * GCS_BLOCK_STARVATION_RETRY — reader backend sleep between + * DENIED_PENDING_X retry attempts (S barrier backoff). */ + WAIT_EVENT_GCS_BLOCK_INVALIDATE_BROADCAST, + WAIT_EVENT_GCS_BLOCK_INVALIDATE_ACK_WAIT, + WAIT_EVENT_GCS_BLOCK_STARVATION_RETRY, + /* PGRAC (spec-4.7 D1 NEW 1 wait event; GCS/PCM warm recovery). + * GCS_BLOCK_RECOVERING — backend bounded pg_usleep poll (20ms steps, + * CHECK_FOR_INTERRUPTS each step) while a block resource is RECOVERING + * (survivor re-declare / master rebuild after reconfiguration); on timeout + * the acquire fail-closes 53R9L. DBA sees 'ClusterGCSBlockRecovering' in + * pg_stat_activity. */ + WAIT_EVENT_GCS_BLOCK_RECOVERING, + + /* Cluster: BufferShip (5 events) -- subsystem #5 */ + WAIT_EVENT_BUFFER_SHIP_CR_BUILD = PG_WAIT_CLUSTER_BUFFERSHIP, + WAIT_EVENT_BUFFER_SHIP_CR_SEND, + WAIT_EVENT_BUFFER_SHIP_CR_RECEIVE, + WAIT_EVENT_BUFFER_SHIP_CURRENT_SEND, + WAIT_EVENT_BUFFER_SHIP_CURRENT_RECEIVE, + + /* Cluster: SCN (4 events) -- subsystem #7 */ + WAIT_EVENT_SCN_BOC_FLUSH_WAIT = PG_WAIT_CLUSTER_SCN, + WAIT_EVENT_SCN_PIGGYBACK_MERGE, + WAIT_EVENT_SCN_CROSS_NODE_COMPARE, + WAIT_EVENT_SCN_ADVANCE_BROADCAST, + + /* Cluster: Reconfig (5 events) -- #14 / #20 */ + WAIT_EVENT_RECONFIG_GRD_REBUILD = PG_WAIT_CLUSTER_RECONFIG, + WAIT_EVENT_RECONFIG_LOCK_RECOVERY, + WAIT_EVENT_RECONFIG_FENCE_WAIT, + WAIT_EVENT_RECONFIG_MASTER_SELECTION, + WAIT_EVENT_RECONFIG_BARRIER_WAIT, + /* spec-4.6 D4: backend short-wait on a FROZEN/REBUILDING GRD shard + * during failure-driven remaster. Reconfig business class (NOT + * BgProc — see that segment's contract). */ + WAIT_EVENT_CLUSTER_GRD_SHARD_REMASTER, + /* spec-4.12 D4: the reconfig coordinator (LMON) synchronously waits for qvotec + * to write + fdatasync the durable fence marker to a voting-disk majority + * before publishing the reconfig event (core 8.A order). */ + WAIT_EVENT_CLUSTER_WRITE_FENCE_MARKER_WRITE, + + /* Cluster: Recovery (6 events) -- #86; +1 spec-4.11 D5; +1 spec-4.12 D6 */ + WAIT_EVENT_RECOVERY_WAL_FETCH = PG_WAIT_CLUSTER_RECOVERY, + WAIT_EVENT_RECOVERY_KWAY_MERGE, + WAIT_EVENT_RECOVERY_APPLY_PER_THREAD, + WAIT_EVENT_RECOVERY_UNDO_REPLAY, + WAIT_EVENT_RECOVERY_PCM_STATE_RESTORE, + /* spec-4.11 D5 (#84): a survivor online-replaying a dead WAL thread's data + * through to shared storage inside the reconfig freeze window. */ + WAIT_EVENT_CLUSTER_THREAD_RECOVERY, + /* spec-4.12 D6: a recovery / rejoin / startup direct durable read of the + * voting-disk fence markers to verify authority. */ + WAIT_EVENT_CLUSTER_WRITE_FENCE_VERIFY, + + /* Cluster: Sinval (6 events) -- subsystem #9; +3 NEW spec-2.39 D13 */ + WAIT_EVENT_SINVAL_BROADCAST_SEND = PG_WAIT_CLUSTER_SINVAL, + WAIT_EVENT_SINVAL_BROADCAST_RECEIVE, + WAIT_EVENT_SINVAL_INJECT_LOCAL_QUEUE, + WAIT_EVENT_SINVAL_ACK_WAIT, /* spec-2.39 D13: enqueue_and_wait_ack WaitLatch */ + WAIT_EVENT_SINVAL_ACK_SEND, /* spec-2.39 D13: LMON drain ack_outbound + send */ + WAIT_EVENT_SINVAL_ACK_RECEIVE, /* spec-2.39 D13: IC handler ack envelope receive */ + + /* Cluster: Interconnect (5 events + 6 spec-2.2 D8) -- AD-007 */ + WAIT_EVENT_INTERCONNECT_RDMA_SEND = PG_WAIT_CLUSTER_INTERCONNECT, + WAIT_EVENT_INTERCONNECT_RDMA_RECV, + WAIT_EVENT_INTERCONNECT_TCP_FALLBACK, + WAIT_EVENT_INTERCONNECT_TIER_SWITCH, + WAIT_EVENT_INTERCONNECT_CONNECT_RETRY, + /* + * spec-2.2 D8 (2026-05-07) -- Tier 1 TCP transport wait events. + * Per 约束 2 strict semantics: + * ClusterICTcpAccept : listener fd waiting for incoming connection + * ClusterICTcpConnect : active edge nonblocking connect waiting for + * SO_ERROR check via WL_SOCKET_WRITEABLE + * ClusterICTcpRecv : per-peer socket waiting readable -- the + * ONLY socket-recv wait event (HeartbeatWait + * is timer-based, NOT recv) + * ClusterICTcpSend : per-peer socket waiting writeable on + * short / nonblocking write + * ClusterICHeartbeatWait: timer-based wait until next heartbeat tick + * (NOT a socket recv -- distinct from TcpRecv) + * ClusterICReconnect : reconnect backoff sleep after + * connect failure / connection lost + * (NOT a connect-in-progress wait) + * + * WAIT_EVENT_CLUSTER_BGPROC_LMON_MAIN_LOOP (spec-1.11) is RESERVED + * for the LMON IDLE tick path -- per 约束 1 it MUST NOT be reused + * for any of the 6 IC socket waits. + */ + WAIT_EVENT_CLUSTER_IC_TCP_ACCEPT, + WAIT_EVENT_CLUSTER_IC_TCP_CONNECT, + WAIT_EVENT_CLUSTER_IC_TCP_RECV, + WAIT_EVENT_CLUSTER_IC_TCP_SEND, + WAIT_EVENT_CLUSTER_IC_HEARTBEAT_WAIT, + WAIT_EVENT_CLUSTER_IC_RECONNECT, + + /* Cluster: Undo (8 events) -- AD-010; spec-3.9 adds CR_CONSTRUCT; + * spec-3.11 adds TT_DURABLE_IO; spec-3.18 D7 adds BUF_FLUSH + EXTENT_CLAIM */ + WAIT_EVENT_UNDO_REMOTE_READ = PG_WAIT_CLUSTER_UNDO, + WAIT_EVENT_UNDO_TT_LOOKUP_REMOTE, + WAIT_EVENT_UNDO_SEGMENT_FETCH, + WAIT_EVENT_UNDO_RETENTION_WAIT, + WAIT_EVENT_CLUSTER_CR_CONSTRUCT, /* spec-3.9: own-instance CR block construction */ + WAIT_EVENT_UNDO_TT_DURABLE_IO, /* spec-3.11: durable TT slot header I/O */ + WAIT_EVENT_CLUSTER_UNDO_BUF_FLUSH, /* spec-3.18 D7: undo buffer write-back I/O */ + WAIT_EVENT_CLUSTER_UNDO_EXTENT_CLAIM, /* spec-3.18 D7: extent claim autoextend I/O */ + + /* Cluster: ADG (4 events) -- #95 */ + WAIT_EVENT_ADG_MRP_APPLY_WAIT = PG_WAIT_CLUSTER_ADG, + WAIT_EVENT_ADG_WAL_RECEIVE_LAG, + WAIT_EVENT_ADG_READ_SNAPSHOT_WAIT, + WAIT_EVENT_ADG_SCN_SYNC_WAIT, + + /* Cluster: SharedFs (5 events) -- spec-1.1 */ + WAIT_EVENT_CLUSTER_SHARED_FS_READ = PG_WAIT_CLUSTER_SHAREDFS, + WAIT_EVENT_CLUSTER_SHARED_FS_WRITE, + WAIT_EVENT_CLUSTER_SHARED_FS_EXTEND, + WAIT_EVENT_CLUSTER_SHARED_FS_TRUNCATE, + WAIT_EVENT_CLUSTER_SHARED_FS_FSYNC, + + /* Cluster: StartupPhase (5 events) -- spec-1.10 (2026-05-03) */ + WAIT_EVENT_CLUSTER_STARTUP_PHASE_0 = PG_WAIT_CLUSTER_STARTUP_PHASE, + WAIT_EVENT_CLUSTER_STARTUP_PHASE_1, + WAIT_EVENT_CLUSTER_STARTUP_PHASE_2, + WAIT_EVENT_CLUSTER_STARTUP_PHASE_3, + WAIT_EVENT_CLUSTER_STARTUP_PHASE_4, + + /* + * Cluster: BgProc (1 event so far) -- spec-1.11 Sprint B (2026-05-04). + * Class scoped to cluster background-process main-loop / lifecycle / + * liveness waits (LMON, future LCK / DIAG / Cluster Stats). Real + * reconfig / fence / heartbeat / interconnect / GES wait events go + * to their dedicated business class, NOT BgProc. + */ + WAIT_EVENT_CLUSTER_BGPROC_LMON_MAIN_LOOP = PG_WAIT_CLUSTER_BGPROC, + WAIT_EVENT_CLUSTER_BGPROC_LCK_MAIN_LOOP, /* spec-1.12 Sprint B D11 */ + WAIT_EVENT_CLUSTER_BGPROC_DIAG_MAIN_LOOP, /* spec-1.13 D11 */ + WAIT_EVENT_CLUSTER_BGPROC_CLUSTER_STATS_MAIN_LOOP, /* spec-1.14 D11 */ + WAIT_EVENT_CLUSTER_BGPROC_CSSD_MAIN_LOOP, /* spec-2.5 D8 */ + WAIT_EVENT_CLUSTER_BGPROC_QVOTEC_MAIN_LOOP, /* spec-2.6 D11 */ + WAIT_EVENT_CLUSTER_VOTING_DISK_READ, /* spec-2.6 D11 */ + WAIT_EVENT_CLUSTER_VOTING_DISK_WRITE, /* spec-2.6 D11 */ + /* spec-4.1 D7: WAL thread claim file I/O (postmaster startup, once + * per boot; the VotingDisk pattern -- direct file I/O on shared + * storage, not routed through cluster_shared_fs). */ + WAIT_EVENT_CLUSTER_WAL_THREAD_CLAIM_READ, + WAIT_EVENT_CLUSTER_WAL_THREAD_CLAIM_WRITE, + /* spec-4.2 D5: ClusterWalState registry slot/header I/O (startup + + * clean shutdown + cluster_stats periodic refresh). */ + WAIT_EVENT_CLUSTER_WAL_STATE_READ, + WAIT_EVENT_CLUSTER_WAL_STATE_WRITE, + /* spec-2.28 Sprint A Step 4 D9: fence-lite backend interrupt check + * wait event. Backend ProcessInterrupts hook (postgres.c D4) sets + * this wait event briefly while reading + clearing ClusterFenceFreeze + * Pending + ereport(ERROR, 53R50). Sub-microsecond duration in the + * fast path (flag==0 early return);longer when ereport unwinds the + * transaction. Lets pg_stat_activity expose freeze-induced abort + * source distinct from generic ClientRead / WAL classes. */ + WAIT_EVENT_CLUSTER_FENCE_BACKEND_INTERRUPT_CHECK, + /* spec-2.29 Sprint A Step 3 D9: reconfig coordinator LMON tick. + * Wraps cluster_reconfig_lmon_tick body which runs every LMON main + * loop iteration (~100ms). Lets pg_stat_activity attribute LMON + * tick CPU to its dedicated wait class — useful for diagnosing + * "is LMON spinning on reconfig dedup checks". */ + WAIT_EVENT_CLUSTER_BGPROC_LMON_RECONFIG_TICK, + /* spec-2.19 Sprint A Step 4 D12: LMD lifecycle / idle wait events. */ + WAIT_EVENT_CLUSTER_LMD_STARTUP, + WAIT_EVENT_CLUSTER_LMD_SCAN, + WAIT_EVENT_CLUSTER_LMD_IDLE, + /* + * spec-2.20 D12 (v0.3 frozen): 7-step caller-side S4 cross-node wait. + * Backend waits for remote master grant decision after S3 reservation + + * GES_REQUEST send;wake on GES_REPLY arrival or timeout (53R70). + * Local-master fast path (A1) does NOT enter S4_WAIT (no remote IPC). + */ + WAIT_EVENT_CLUSTER_GES_S4_WAIT, + /* + * spec-2.22 D10:LMD coordinator handler processing DEADLOCK_PROBE + * + snapshot_copy + REPORT encode. Production cross-node broadcast + * 推 spec-2.23 BAST 配套;本 spec scope 仅 handler dispatch + payload. + */ + WAIT_EVENT_CLUSTER_LMD_PROBE, + /* + * spec-2.23 D12:cross-node GES reply 5-tuple wait (HC17). Backend + * sleeps on the per-entry ConditionVariable inserted into the + * cluster_ges_reply_wait HTAB before sending a GES_REQUEST/RELEASE + * to a remote master. Wake on GES_REPLY arrival or timeout (53R70). + */ + WAIT_EVENT_CLUSTER_GES_REPLY_WAIT, + /* + * spec-2.23 D12:LMD coordinator REPORT collect. Coordinator scan + * tick polls WaitLatch up to cluster.lmd_probe_collect_timeout_ms + * for N-1 DEADLOCK_REPORTs after broadcasting PROBE. Distinct from + * WAIT_EVENT_CLUSTER_LMD_PROBE which covers the per-receiver + * handler processing path. + */ + WAIT_EVENT_CLUSTER_LMD_PROBE_COLLECT, + /* + * spec-2.25 D11: LMS native-lock probe collector aggregate wait. + * LMS process sleeps on cluster_lms_state->cv while in-flight + * probe slots await N-1 peer replies (HC29 fan-out). Wake on + * reply arrival (recv_reply broadcast) or retry tick. + */ + WAIT_EVENT_CLUSTER_LMS_NATIVE_PROBE_WAIT, + /* + * spec-2.25 D11: peer node scanning local PG lock state during a + * native-lock probe request handler invocation (HC30 scan of + * LockMethodLockHash + LOCK->waitProcs + relation fast-path). + * Distinct from LMS_NATIVE_PROBE_WAIT which covers the LMS + * collector side. + */ + WAIT_EVENT_CLUSTER_NATIVE_PROBE_REPLY_WAIT, + /* spec-3.13 D1: Undo Cleaner main-loop idle wait. */ + WAIT_EVENT_CLUSTER_BGPROC_UNDO_CLEANER_MAIN_LOOP, + /* spec-3.13 D6: cleaner durable-header segment scan I/O. */ + WAIT_EVENT_CLUSTER_UNDO_CLEANER_SEGMENT_SCAN, + /* + * spec-5.4 D9: SQ sequence instance-cache refill. A backend whose + * node-level instance cache is empty sleeps here while it acquires the + * SQ(X) enqueue and waits for the authority to grant the next segment + * (and complete the cross-node boundary writeback) before nextval can + * return. Wake on grant arrival or refill timeout (53R70). + */ + WAIT_EVENT_CLUSTER_SQ_REFILL_WAIT, + /* + * spec-5.6 Dc4b: CF (control-file) enqueue wait. A backend (checkpointer + * during a steady-state checkpoint, or a strong-consistency reader) sleeps + * here while acquiring the singleton CF X/S lock over GES, bounded by + * cluster.cf_enqueue_timeout_ms. Wake on grant arrival or timeout (53R70). + */ + WAIT_EVENT_CLUSTER_CF_ENQUEUE, +} WaitEventCluster; + + +extern const char *pgstat_get_wait_event(uint32 wait_event_info); +extern const char *pgstat_get_wait_event_type(uint32 wait_event_info); +static inline void pgstat_report_wait_start(uint32 wait_event_info); +static inline void pgstat_report_wait_end(void); +extern void pgstat_set_wait_event_storage(uint32 *wait_event_info); +extern void pgstat_reset_wait_event_storage(void); + +extern PGDLLIMPORT uint32 *my_wait_event_info; + + +/* ---------- + * pgstat_report_wait_start() - + * + * Called from places where server process needs to wait. This is called + * to report wait event information. The wait information is stored + * as 4-bytes where first byte represents the wait event class (type of + * wait, for different types of wait, refer WaitClass) and the next + * 3-bytes represent the actual wait event. Currently 2-bytes are used + * for wait event which is sufficient for current usage, 1-byte is + * reserved for future usage. + * + * Historically we used to make this reporting conditional on + * pgstat_track_activities, but the check for that seems to add more cost + * than it saves. + * + * my_wait_event_info initially points to local memory, making it safe to + * call this before MyProc has been initialized. + * ---------- + */ +static inline void +pgstat_report_wait_start(uint32 wait_event_info) +{ + /* + * Since this is a four-byte field which is always read and written as + * four-bytes, updates are atomic. + */ + *(volatile uint32 *)my_wait_event_info = wait_event_info; +} + +/* ---------- + * pgstat_report_wait_end() - + * + * Called to report end of a wait. + * ---------- + */ +static inline void +pgstat_report_wait_end(void) +{ + /* see pgstat_report_wait_start() */ + *(volatile uint32 *)my_wait_event_info = 0; +} + + +#endif /* WAIT_EVENT_H */ diff --git a/install/include/postgresql/server/utils/xid8.h b/install/include/postgresql/server/utils/xid8.h new file mode 100644 index 00000000000..2f5e14baad4 --- /dev/null +++ b/install/include/postgresql/server/utils/xid8.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * xid8.h + * Header file for the "xid8" ADT. + * + * Copyright (c) 2020-2023, PostgreSQL Global Development Group + * + * src/include/utils/xid8.h + * + *------------------------------------------------------------------------- + */ +#ifndef XID8_H +#define XID8_H + +#include "access/transam.h" + +static inline FullTransactionId +DatumGetFullTransactionId(Datum X) +{ + return FullTransactionIdFromU64(DatumGetUInt64(X)); +} + +static inline Datum +FullTransactionIdGetDatum(FullTransactionId X) +{ + return UInt64GetDatum(U64FromFullTransactionId(X)); +} + +#define PG_GETARG_FULLTRANSACTIONID(X) DatumGetFullTransactionId(PG_GETARG_DATUM(X)) +#define PG_RETURN_FULLTRANSACTIONID(X) return FullTransactionIdGetDatum(X) + +#endif /* XID8_H */ diff --git a/install/include/postgresql/server/utils/xml.h b/install/include/postgresql/server/utils/xml.h new file mode 100644 index 00000000000..224f6d75ffd --- /dev/null +++ b/install/include/postgresql/server/utils/xml.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------- + * + * xml.h + * Declarations for XML data type support. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/xml.h + * + *------------------------------------------------------------------------- + */ + +#ifndef XML_H +#define XML_H + +#include "executor/tablefunc.h" +#include "fmgr.h" +#include "nodes/execnodes.h" +#include "nodes/primnodes.h" + +typedef struct varlena xmltype; + +typedef enum +{ + XML_STANDALONE_YES, + XML_STANDALONE_NO, + XML_STANDALONE_NO_VALUE, + XML_STANDALONE_OMITTED +} XmlStandaloneType; + +typedef enum +{ + XMLBINARY_BASE64, + XMLBINARY_HEX +} XmlBinaryType; + +typedef enum +{ + PG_XML_STRICTNESS_LEGACY, /* ignore errors unless function result + * indicates error condition */ + PG_XML_STRICTNESS_WELLFORMED, /* ignore non-parser messages */ + PG_XML_STRICTNESS_ALL /* report all notices/warnings/errors */ +} PgXmlStrictness; + +/* struct PgXmlErrorContext is private to xml.c */ +typedef struct PgXmlErrorContext PgXmlErrorContext; + +static inline xmltype * +DatumGetXmlP(Datum X) +{ + return (xmltype *) PG_DETOAST_DATUM(X); +} + +static inline Datum +XmlPGetDatum(const xmltype *X) +{ + return PointerGetDatum(X); +} + +#define PG_GETARG_XML_P(n) DatumGetXmlP(PG_GETARG_DATUM(n)) +#define PG_RETURN_XML_P(x) PG_RETURN_POINTER(x) + +extern void pg_xml_init_library(void); +extern PgXmlErrorContext *pg_xml_init(PgXmlStrictness strictness); +extern void pg_xml_done(PgXmlErrorContext *errcxt, bool isError); +extern bool pg_xml_error_occurred(PgXmlErrorContext *errcxt); +extern void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, + const char *msg); + +extern xmltype *xmlconcat(List *args); +extern xmltype *xmlelement(XmlExpr *xexpr, + Datum *named_argvalue, bool *named_argnull, + Datum *argvalue, bool *argnull); +extern xmltype *xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace); +extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *result_is_null); +extern xmltype *xmlroot(xmltype *data, text *version, int standalone); +extern bool xml_is_document(xmltype *arg); +extern text *xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, + bool indent); +extern char *escape_xml(const char *str); + +extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period); +extern char *map_xml_name_to_sql_identifier(const char *name); +extern char *map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings); + +extern PGDLLIMPORT int xmlbinary; /* XmlBinaryType, but int for guc enum */ + +extern PGDLLIMPORT int xmloption; /* XmlOptionType, but int for guc enum */ + +extern PGDLLIMPORT const TableFuncRoutine XmlTableRoutine; + +#endif /* XML_H */ diff --git a/install/include/postgresql/server/varatt.h b/install/include/postgresql/server/varatt.h new file mode 100644 index 00000000000..e34870526ba --- /dev/null +++ b/install/include/postgresql/server/varatt.h @@ -0,0 +1,358 @@ +/*------------------------------------------------------------------------- + * + * varatt.h + * variable-length datatypes (TOAST support) + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1995, Regents of the University of California + * + * src/include/varatt.h + * + *------------------------------------------------------------------------- + */ + +#ifndef VARATT_H +#define VARATT_H + +/* + * struct varatt_external is a traditional "TOAST pointer", that is, the + * information needed to fetch a Datum stored out-of-line in a TOAST table. + * The data is compressed if and only if the external size stored in + * va_extinfo is less than va_rawsize - VARHDRSZ. + * + * This struct must not contain any padding, because we sometimes compare + * these pointers using memcmp. + * + * Note that this information is stored unaligned within actual tuples, so + * you need to memcpy from the tuple into a local struct variable before + * you can look at these fields! (The reason we use memcmp is to avoid + * having to do that just to detect equality of two TOAST pointers...) + */ +typedef struct varatt_external +{ + int32 va_rawsize; /* Original data size (includes header) */ + uint32 va_extinfo; /* External saved size (without header) and + * compression method */ + Oid va_valueid; /* Unique ID of value within TOAST table */ + Oid va_toastrelid; /* RelID of TOAST table containing it */ +} varatt_external; + +/* + * These macros define the "saved size" portion of va_extinfo. Its remaining + * two high-order bits identify the compression method. + */ +#define VARLENA_EXTSIZE_BITS 30 +#define VARLENA_EXTSIZE_MASK ((1U << VARLENA_EXTSIZE_BITS) - 1) + +/* + * struct varatt_indirect is a "TOAST pointer" representing an out-of-line + * Datum that's stored in memory, not in an external toast relation. + * The creator of such a Datum is entirely responsible that the referenced + * storage survives for as long as referencing pointer Datums can exist. + * + * Note that just as for struct varatt_external, this struct is stored + * unaligned within any containing tuple. + */ +typedef struct varatt_indirect +{ + struct varlena *pointer; /* Pointer to in-memory varlena */ +} varatt_indirect; + +/* + * struct varatt_expanded is a "TOAST pointer" representing an out-of-line + * Datum that is stored in memory, in some type-specific, not necessarily + * physically contiguous format that is convenient for computation not + * storage. APIs for this, in particular the definition of struct + * ExpandedObjectHeader, are in src/include/utils/expandeddatum.h. + * + * Note that just as for struct varatt_external, this struct is stored + * unaligned within any containing tuple. + */ +typedef struct ExpandedObjectHeader ExpandedObjectHeader; + +typedef struct varatt_expanded +{ + ExpandedObjectHeader *eohptr; +} varatt_expanded; + +/* + * Type tag for the various sorts of "TOAST pointer" datums. The peculiar + * value for VARTAG_ONDISK comes from a requirement for on-disk compatibility + * with a previous notion that the tag field was the pointer datum's length. + */ +typedef enum vartag_external +{ + VARTAG_INDIRECT = 1, + VARTAG_EXPANDED_RO = 2, + VARTAG_EXPANDED_RW = 3, + VARTAG_ONDISK = 18 +} vartag_external; + +/* this test relies on the specific tag values above */ +#define VARTAG_IS_EXPANDED(tag) \ + (((tag) & ~1) == VARTAG_EXPANDED_RO) + +#define VARTAG_SIZE(tag) \ + ((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \ + VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \ + (tag) == VARTAG_ONDISK ? sizeof(varatt_external) : \ + (AssertMacro(false), 0)) + +/* + * These structs describe the header of a varlena object that may have been + * TOASTed. Generally, don't reference these structs directly, but use the + * macros below. + * + * We use separate structs for the aligned and unaligned cases because the + * compiler might otherwise think it could generate code that assumes + * alignment while touching fields of a 1-byte-header varlena. + */ +typedef union +{ + struct /* Normal varlena (4-byte length) */ + { + uint32 va_header; + char va_data[FLEXIBLE_ARRAY_MEMBER]; + } va_4byte; + struct /* Compressed-in-line format */ + { + uint32 va_header; + uint32 va_tcinfo; /* Original data size (excludes header) and + * compression method; see va_extinfo */ + char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Compressed data */ + } va_compressed; +} varattrib_4b; + +typedef struct +{ + uint8 va_header; + char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Data begins here */ +} varattrib_1b; + +/* TOAST pointers are a subset of varattrib_1b with an identifying tag byte */ +typedef struct +{ + uint8 va_header; /* Always 0x80 or 0x01 */ + uint8 va_tag; /* Type of datum */ + char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Type-specific data */ +} varattrib_1b_e; + +/* + * Bit layouts for varlena headers on big-endian machines: + * + * 00xxxxxx 4-byte length word, aligned, uncompressed data (up to 1G) + * 01xxxxxx 4-byte length word, aligned, *compressed* data (up to 1G) + * 10000000 1-byte length word, unaligned, TOAST pointer + * 1xxxxxxx 1-byte length word, unaligned, uncompressed data (up to 126b) + * + * Bit layouts for varlena headers on little-endian machines: + * + * xxxxxx00 4-byte length word, aligned, uncompressed data (up to 1G) + * xxxxxx10 4-byte length word, aligned, *compressed* data (up to 1G) + * 00000001 1-byte length word, unaligned, TOAST pointer + * xxxxxxx1 1-byte length word, unaligned, uncompressed data (up to 126b) + * + * The "xxx" bits are the length field (which includes itself in all cases). + * In the big-endian case we mask to extract the length, in the little-endian + * case we shift. Note that in both cases the flag bits are in the physically + * first byte. Also, it is not possible for a 1-byte length word to be zero; + * this lets us disambiguate alignment padding bytes from the start of an + * unaligned datum. (We now *require* pad bytes to be filled with zero!) + * + * In TOAST pointers the va_tag field (see varattrib_1b_e) is used to discern + * the specific type and length of the pointer datum. + */ + +/* + * Endian-dependent macros. These are considered internal --- use the + * external macros below instead of using these directly. + * + * Note: IS_1B is true for external toast records but VARSIZE_1B will return 0 + * for such records. Hence you should usually check for IS_EXTERNAL before + * checking for IS_1B. + */ + +#ifdef WORDS_BIGENDIAN + +#define VARATT_IS_4B(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0x80) == 0x00) +#define VARATT_IS_4B_U(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0xC0) == 0x00) +#define VARATT_IS_4B_C(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0xC0) == 0x40) +#define VARATT_IS_1B(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0x80) == 0x80) +#define VARATT_IS_1B_E(PTR) \ + ((((varattrib_1b *) (PTR))->va_header) == 0x80) +#define VARATT_NOT_PAD_BYTE(PTR) \ + (*((uint8 *) (PTR)) != 0) + +/* VARSIZE_4B() should only be used on known-aligned data */ +#define VARSIZE_4B(PTR) \ + (((varattrib_4b *) (PTR))->va_4byte.va_header & 0x3FFFFFFF) +#define VARSIZE_1B(PTR) \ + (((varattrib_1b *) (PTR))->va_header & 0x7F) +#define VARTAG_1B_E(PTR) \ + (((varattrib_1b_e *) (PTR))->va_tag) + +#define SET_VARSIZE_4B(PTR,len) \ + (((varattrib_4b *) (PTR))->va_4byte.va_header = (len) & 0x3FFFFFFF) +#define SET_VARSIZE_4B_C(PTR,len) \ + (((varattrib_4b *) (PTR))->va_4byte.va_header = ((len) & 0x3FFFFFFF) | 0x40000000) +#define SET_VARSIZE_1B(PTR,len) \ + (((varattrib_1b *) (PTR))->va_header = (len) | 0x80) +#define SET_VARTAG_1B_E(PTR,tag) \ + (((varattrib_1b_e *) (PTR))->va_header = 0x80, \ + ((varattrib_1b_e *) (PTR))->va_tag = (tag)) + +#else /* !WORDS_BIGENDIAN */ + +#define VARATT_IS_4B(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0x01) == 0x00) +#define VARATT_IS_4B_U(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0x03) == 0x00) +#define VARATT_IS_4B_C(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0x03) == 0x02) +#define VARATT_IS_1B(PTR) \ + ((((varattrib_1b *) (PTR))->va_header & 0x01) == 0x01) +#define VARATT_IS_1B_E(PTR) \ + ((((varattrib_1b *) (PTR))->va_header) == 0x01) +#define VARATT_NOT_PAD_BYTE(PTR) \ + (*((uint8 *) (PTR)) != 0) + +/* VARSIZE_4B() should only be used on known-aligned data */ +#define VARSIZE_4B(PTR) \ + ((((varattrib_4b *) (PTR))->va_4byte.va_header >> 2) & 0x3FFFFFFF) +#define VARSIZE_1B(PTR) \ + ((((varattrib_1b *) (PTR))->va_header >> 1) & 0x7F) +#define VARTAG_1B_E(PTR) \ + (((varattrib_1b_e *) (PTR))->va_tag) + +#define SET_VARSIZE_4B(PTR,len) \ + (((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2)) +#define SET_VARSIZE_4B_C(PTR,len) \ + (((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2) | 0x02) +#define SET_VARSIZE_1B(PTR,len) \ + (((varattrib_1b *) (PTR))->va_header = (((uint8) (len)) << 1) | 0x01) +#define SET_VARTAG_1B_E(PTR,tag) \ + (((varattrib_1b_e *) (PTR))->va_header = 0x01, \ + ((varattrib_1b_e *) (PTR))->va_tag = (tag)) + +#endif /* WORDS_BIGENDIAN */ + +#define VARDATA_4B(PTR) (((varattrib_4b *) (PTR))->va_4byte.va_data) +#define VARDATA_4B_C(PTR) (((varattrib_4b *) (PTR))->va_compressed.va_data) +#define VARDATA_1B(PTR) (((varattrib_1b *) (PTR))->va_data) +#define VARDATA_1B_E(PTR) (((varattrib_1b_e *) (PTR))->va_data) + +/* + * Externally visible TOAST macros begin here. + */ + +#define VARHDRSZ_EXTERNAL offsetof(varattrib_1b_e, va_data) +#define VARHDRSZ_COMPRESSED offsetof(varattrib_4b, va_compressed.va_data) +#define VARHDRSZ_SHORT offsetof(varattrib_1b, va_data) + +#define VARATT_SHORT_MAX 0x7F +#define VARATT_CAN_MAKE_SHORT(PTR) \ + (VARATT_IS_4B_U(PTR) && \ + (VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT) <= VARATT_SHORT_MAX) +#define VARATT_CONVERTED_SHORT_SIZE(PTR) \ + (VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT) + +/* + * In consumers oblivious to data alignment, call PG_DETOAST_DATUM_PACKED(), + * VARDATA_ANY(), VARSIZE_ANY() and VARSIZE_ANY_EXHDR(). Elsewhere, call + * PG_DETOAST_DATUM(), VARDATA() and VARSIZE(). Directly fetching an int16, + * int32 or wider field in the struct representing the datum layout requires + * aligned data. memcpy() is alignment-oblivious, as are most operations on + * datatypes, such as text, whose layout struct contains only char fields. + * + * Code assembling a new datum should call VARDATA() and SET_VARSIZE(). + * (Datums begin life untoasted.) + * + * Other macros here should usually be used only by tuple assembly/disassembly + * code and code that specifically wants to work with still-toasted Datums. + */ +#define VARDATA(PTR) VARDATA_4B(PTR) +#define VARSIZE(PTR) VARSIZE_4B(PTR) + +#define VARSIZE_SHORT(PTR) VARSIZE_1B(PTR) +#define VARDATA_SHORT(PTR) VARDATA_1B(PTR) + +#define VARTAG_EXTERNAL(PTR) VARTAG_1B_E(PTR) +#define VARSIZE_EXTERNAL(PTR) (VARHDRSZ_EXTERNAL + VARTAG_SIZE(VARTAG_EXTERNAL(PTR))) +#define VARDATA_EXTERNAL(PTR) VARDATA_1B_E(PTR) + +#define VARATT_IS_COMPRESSED(PTR) VARATT_IS_4B_C(PTR) +#define VARATT_IS_EXTERNAL(PTR) VARATT_IS_1B_E(PTR) +#define VARATT_IS_EXTERNAL_ONDISK(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_ONDISK) +#define VARATT_IS_EXTERNAL_INDIRECT(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_INDIRECT) +#define VARATT_IS_EXTERNAL_EXPANDED_RO(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXPANDED_RO) +#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXPANDED_RW) +#define VARATT_IS_EXTERNAL_EXPANDED(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR))) +#define VARATT_IS_EXTERNAL_NON_EXPANDED(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && !VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR))) +#define VARATT_IS_SHORT(PTR) VARATT_IS_1B(PTR) +#define VARATT_IS_EXTENDED(PTR) (!VARATT_IS_4B_U(PTR)) + +#define SET_VARSIZE(PTR, len) SET_VARSIZE_4B(PTR, len) +#define SET_VARSIZE_SHORT(PTR, len) SET_VARSIZE_1B(PTR, len) +#define SET_VARSIZE_COMPRESSED(PTR, len) SET_VARSIZE_4B_C(PTR, len) + +#define SET_VARTAG_EXTERNAL(PTR, tag) SET_VARTAG_1B_E(PTR, tag) + +#define VARSIZE_ANY(PTR) \ + (VARATT_IS_1B_E(PTR) ? VARSIZE_EXTERNAL(PTR) : \ + (VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR) : \ + VARSIZE_4B(PTR))) + +/* Size of a varlena data, excluding header */ +#define VARSIZE_ANY_EXHDR(PTR) \ + (VARATT_IS_1B_E(PTR) ? VARSIZE_EXTERNAL(PTR)-VARHDRSZ_EXTERNAL : \ + (VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR)-VARHDRSZ_SHORT : \ + VARSIZE_4B(PTR)-VARHDRSZ)) + +/* caution: this will not work on an external or compressed-in-line Datum */ +/* caution: this will return a possibly unaligned pointer */ +#define VARDATA_ANY(PTR) \ + (VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR)) + +/* Decompressed size and compression method of a compressed-in-line Datum */ +#define VARDATA_COMPRESSED_GET_EXTSIZE(PTR) \ + (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo & VARLENA_EXTSIZE_MASK) +#define VARDATA_COMPRESSED_GET_COMPRESS_METHOD(PTR) \ + (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS) + +/* Same for external Datums; but note argument is a struct varatt_external */ +#define VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) \ + ((toast_pointer).va_extinfo & VARLENA_EXTSIZE_MASK) +#define VARATT_EXTERNAL_GET_COMPRESS_METHOD(toast_pointer) \ + ((toast_pointer).va_extinfo >> VARLENA_EXTSIZE_BITS) + +#define VARATT_EXTERNAL_SET_SIZE_AND_COMPRESS_METHOD(toast_pointer, len, cm) \ + do { \ + Assert((cm) == TOAST_PGLZ_COMPRESSION_ID || \ + (cm) == TOAST_LZ4_COMPRESSION_ID); \ + ((toast_pointer).va_extinfo = \ + (len) | ((uint32) (cm) << VARLENA_EXTSIZE_BITS)); \ + } while (0) + +/* + * Testing whether an externally-stored value is compressed now requires + * comparing size stored in va_extinfo (the actual length of the external data) + * to rawsize (the original uncompressed datum's size). The latter includes + * VARHDRSZ overhead, the former doesn't. We never use compression unless it + * actually saves space, so we expect either equality or less-than. + */ +#define VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \ + (VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) < \ + (toast_pointer).va_rawsize - VARHDRSZ) + +#endif diff --git a/install/include/postgresql/server/windowapi.h b/install/include/postgresql/server/windowapi.h new file mode 100644 index 00000000000..b8c2c565d17 --- /dev/null +++ b/install/include/postgresql/server/windowapi.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * windowapi.h + * API for window functions to extract data from their window + * + * A window function does not receive its arguments in the normal way + * (and therefore the concept of strictness is irrelevant). Instead it + * receives a "WindowObject", which it can fetch with PG_WINDOW_OBJECT() + * (note V1 calling convention must be used). Correct call context can + * be tested with WindowObjectIsValid(). Although argument values are + * not passed, the call is correctly set up so that PG_NARGS() can be + * used and argument type information can be obtained with + * get_fn_expr_argtype(), get_fn_expr_arg_stable(), etc. + * + * Operations on the WindowObject allow the window function to find out + * the current row number, total number of rows in the partition, etc + * and to evaluate its argument expression(s) at various rows in the + * window partition. See the header comments for each WindowObject API + * function in nodeWindowAgg.c for details. + * + * + * Portions Copyright (c) 2000-2023, PostgreSQL Global Development Group + * + * src/include/windowapi.h + * + *------------------------------------------------------------------------- + */ +#ifndef WINDOWAPI_H +#define WINDOWAPI_H + +/* values of "seektype" */ +#define WINDOW_SEEK_CURRENT 0 +#define WINDOW_SEEK_HEAD 1 +#define WINDOW_SEEK_TAIL 2 + +/* this struct is private in nodeWindowAgg.c */ +typedef struct WindowObjectData *WindowObject; + +#define PG_WINDOW_OBJECT() ((WindowObject) fcinfo->context) + +#define WindowObjectIsValid(winobj) \ + ((winobj) != NULL && IsA(winobj, WindowObjectData)) + +extern void *WinGetPartitionLocalMemory(WindowObject winobj, Size sz); + +extern int64 WinGetCurrentPosition(WindowObject winobj); +extern int64 WinGetPartitionRowCount(WindowObject winobj); + +extern void WinSetMarkPosition(WindowObject winobj, int64 markpos); + +extern bool WinRowsArePeers(WindowObject winobj, int64 pos1, int64 pos2); + +extern Datum WinGetFuncArgInPartition(WindowObject winobj, int argno, + int relpos, int seektype, bool set_mark, + bool *isnull, bool *isout); + +extern Datum WinGetFuncArgInFrame(WindowObject winobj, int argno, + int relpos, int seektype, bool set_mark, + bool *isnull, bool *isout); + +extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno, + bool *isnull); + +#endif /* WINDOWAPI_H */ diff --git a/install/include/sql3types.h b/install/include/sql3types.h new file mode 100644 index 00000000000..644b616cf87 --- /dev/null +++ b/install/include/sql3types.h @@ -0,0 +1,43 @@ +#ifndef _ECPG_SQL3TYPES_H +#define _ECPG_SQL3TYPES_H + +/* SQL3 dynamic type codes */ + +/* chapter 13.1 table 2: Codes used for SQL data types in Dynamic SQL */ + +enum +{ + SQL3_CHARACTER = 1, + SQL3_NUMERIC, + SQL3_DECIMAL, + SQL3_INTEGER, + SQL3_SMALLINT, + SQL3_FLOAT, + SQL3_REAL, + SQL3_DOUBLE_PRECISION, + SQL3_DATE_TIME_TIMESTAMP, + SQL3_INTERVAL, /* 10 */ + SQL3_CHARACTER_VARYING = 12, + SQL3_ENUMERATED, + SQL3_BIT, + SQL3_BIT_VARYING, + SQL3_BOOLEAN, + SQL3_abstract + /* the rest is xLOB stuff */ +}; + +/* chapter 13.1 table 3: Codes associated with datetime data types in Dynamic SQL */ + +enum +{ + SQL3_DDT_DATE = 1, + SQL3_DDT_TIME, + SQL3_DDT_TIMESTAMP, + SQL3_DDT_TIME_WITH_TIME_ZONE, + SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE, + + SQL3_DDT_ILLEGAL /* not a datetime data type (not part of + * standard) */ +}; + +#endif /* !_ECPG_SQL3TYPES_H */ diff --git a/install/include/sqlca.h b/install/include/sqlca.h new file mode 100644 index 00000000000..c5f107dd33c --- /dev/null +++ b/install/include/sqlca.h @@ -0,0 +1,66 @@ +#ifndef POSTGRES_SQLCA_H +#define POSTGRES_SQLCA_H + +#ifndef PGDLLIMPORT +#if defined(WIN32) || defined(__CYGWIN__) +#define PGDLLIMPORT __declspec (dllimport) +#else +#define PGDLLIMPORT +#endif /* __CYGWIN__ */ +#endif /* PGDLLIMPORT */ + +#define SQLERRMC_LEN 150 + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct sqlca_t +{ + char sqlcaid[8]; + long sqlabc; + long sqlcode; + struct + { + int sqlerrml; + char sqlerrmc[SQLERRMC_LEN]; + } sqlerrm; + char sqlerrp[8]; + long sqlerrd[6]; + /* Element 0: empty */ + /* 1: OID of processed tuple if applicable */ + /* 2: number of rows processed */ + /* after an INSERT, UPDATE or */ + /* DELETE statement */ + /* 3: empty */ + /* 4: empty */ + /* 5: empty */ + char sqlwarn[8]; + /* Element 0: set to 'W' if at least one other is 'W' */ + /* 1: if 'W' at least one character string */ + /* value was truncated when it was */ + /* stored into a host variable. */ + + /* + * 2: if 'W' a (hopefully) non-fatal notice occurred + */ /* 3: empty */ + /* 4: empty */ + /* 5: empty */ + /* 6: empty */ + /* 7: empty */ + + char sqlstate[5]; +}; + +struct sqlca_t *ECPGget_sqlca(void); + +#ifndef POSTGRES_ECPG_INTERNAL +#define sqlca (*ECPGget_sqlca()) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/install/include/sqlda-compat.h b/install/include/sqlda-compat.h new file mode 100644 index 00000000000..7b0ac45c42f --- /dev/null +++ b/install/include/sqlda-compat.h @@ -0,0 +1,47 @@ +/* + * src/interfaces/ecpg/include/sqlda-compat.h + */ + +#ifndef ECPG_SQLDA_COMPAT_H +#define ECPG_SQLDA_COMPAT_H + +struct sqlvar_compat +{ + short sqltype; /* variable type */ + int sqllen; /* length in bytes */ + char *sqldata; /* pointer to data */ + short *sqlind; /* pointer to indicator */ + char *sqlname; /* variable name */ + char *sqlformat; /* reserved for future use */ + short sqlitype; /* ind variable type */ + short sqlilen; /* ind length in bytes */ + char *sqlidata; /* ind data pointer */ + int sqlxid; /* extended id type */ + char *sqltypename; /* extended type name */ + short sqltypelen; /* length of extended type name */ + short sqlownerlen; /* length of owner name */ + short sqlsourcetype; /* source type for distinct of built-ins */ + char *sqlownername; /* owner name */ + int sqlsourceid; /* extended id of source type */ + + /* + * sqlilongdata is new. It supports data that exceeds the 32k limit. + * sqlilen and sqlidata are for backward compatibility and they have + * maximum value of <32K. + */ + char *sqlilongdata; /* for data field beyond 32K */ + int sqlflags; /* for internal use only */ + void *sqlreserved; /* reserved for future use */ +}; + +struct sqlda_compat +{ + short sqld; + struct sqlvar_compat *sqlvar; + char desc_name[19]; /* descriptor name */ + short desc_occ; /* size of sqlda structure */ + struct sqlda_compat *desc_next; /* pointer to next sqlda struct */ + void *reserved; /* reserved for future use */ +}; + +#endif /* ECPG_SQLDA_COMPAT_H */ diff --git a/install/include/sqlda-native.h b/install/include/sqlda-native.h new file mode 100644 index 00000000000..9e73f1f1b11 --- /dev/null +++ b/install/include/sqlda-native.h @@ -0,0 +1,43 @@ +/* + * src/interfaces/ecpg/include/sqlda-native.h + */ + +#ifndef ECPG_SQLDA_NATIVE_H +#define ECPG_SQLDA_NATIVE_H + +/* + * Maximum length for identifiers (e.g. table names, column names, + * function names). Names actually are limited to one fewer byte than this, + * because the length must include a trailing zero byte. + * + * This should be at least as much as NAMEDATALEN of the database the + * applications run against. + */ +#define NAMEDATALEN 64 + +struct sqlname +{ + short length; + char data[NAMEDATALEN]; +}; + +struct sqlvar_struct +{ + short sqltype; + short sqllen; + char *sqldata; + short *sqlind; + struct sqlname sqlname; +}; + +struct sqlda_struct +{ + char sqldaid[8]; + long sqldabc; + short sqln; + short sqld; + struct sqlda_struct *desc_next; + struct sqlvar_struct sqlvar[1]; +}; + +#endif /* ECPG_SQLDA_NATIVE_H */ diff --git a/install/include/sqlda.h b/install/include/sqlda.h new file mode 100644 index 00000000000..d810e739e20 --- /dev/null +++ b/install/include/sqlda.h @@ -0,0 +1,18 @@ +#ifndef ECPG_SQLDA_H +#define ECPG_SQLDA_H + +#ifdef _ECPG_INFORMIX_H + +#include "sqlda-compat.h" +typedef struct sqlvar_compat sqlvar_t; +typedef struct sqlda_compat sqlda_t; + +#else + +#include "sqlda-native.h" +typedef struct sqlvar_struct sqlvar_t; +typedef struct sqlda_struct sqlda_t; + +#endif + +#endif /* ECPG_SQLDA_H */ diff --git a/install/lib/postgresql/pgxs/config/install-sh b/install/lib/postgresql/pgxs/config/install-sh new file mode 100755 index 00000000000..377bb8687ff --- /dev/null +++ b/install/lib/postgresql/pgxs/config/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-11-20.07; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/install/lib/postgresql/pgxs/config/missing b/install/lib/postgresql/pgxs/config/missing new file mode 100755 index 00000000000..6df77e94737 --- /dev/null +++ b/install/lib/postgresql/pgxs/config/missing @@ -0,0 +1,54 @@ +#! /bin/sh + +# config/missing + +# This is *not* the GNU `missing' script, although it is similar in +# concept. You can call it from the makefiles to get consistent +# behavior when certain utility programs are missing. + +case $1 in + flex|bison) + # `missing flex|bison ' + input=$2 + output=$3 + if test -f "$output"; then + echo "\ +*** +WARNING: \`$1' is missing on your system. You should only need it +if you changed the file \`$input'; these changes will not take effect. +You can get $1 from a GNU mirror site. +***" >&2 + echo "touch $output" + touch "$output" + exit 0 + else # ! test -f $output + echo "\ +*** +ERROR: \`$1' is missing on your system. It is needed to create the +file \`$output'. You can either get $1 from a GNU mirror site +or download an official distribution of PostgreSQL, which contains +pre-packaged $1 output. +***" >&2 + exit 1 + fi + ;; + + perl) + # `missing perl' + echo "\ +*** +ERROR: Perl is missing on your system. It is needed unless you are building +from an unmodified official distribution of PostgreSQL. +***" >&2 + exit 1 + ;; + + *) + # `missing something-or-other' + echo "\ +*** +ERROR: \`$1' is missing on your system. +***" >&2 + exit 1 + ;; +esac diff --git a/install/lib/postgresql/pgxs/src/Makefile.global b/install/lib/postgresql/pgxs/src/Makefile.global new file mode 100644 index 00000000000..0fe223b09e7 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/Makefile.global @@ -0,0 +1,1130 @@ +# -*-makefile-*- +# src/Makefile.global.in +# src/Makefile.global. Generated from Makefile.global.in by configure. + +#------------------------------------------------------------------------------ +# All PostgreSQL makefiles include this file and use the variables it sets, +# which in turn are put here by the configure script. There is no need for +# users to edit this file -- if it turns out to be necessary then that's a +# bug. +# +# A makefile that includes this file needs to set the variable `subdir' to +# the relative path from the top to itself and `top_builddir' to the relative +# path from itself to the top before including this file. (The "top" is the +# parent directory of the directory this file is in.) +#------------------------------------------------------------------------------ + + +########################################################################## +# +# Meta configuration + +standard_targets = all install installdirs uninstall distprep clean distclean maintainer-clean coverage check checkprep installcheck init-po update-po +# these targets should recurse even into subdirectories not being built: +standard_always_targets = distprep clean distclean maintainer-clean + +.PHONY: $(standard_targets) install-strip html man installcheck-parallel update-unicode + +# make `all' the default target +all: + +# Delete target files if the command fails after it has +# started to update the file. +.DELETE_ON_ERROR: + +# Never delete any intermediate files automatically. +.SECONDARY: + +# PostgreSQL version number +VERSION = 16.13 +MAJORVERSION = 16 +VERSION_NUM = 160013 + +PACKAGE_URL = https://www.postgresql.org/ + +# Set top_srcdir, srcdir, and VPATH. +ifdef PGXS +top_srcdir = $(top_builddir) + +# If VPATH is set or Makefile is not in current directory we are building +# the extension with VPATH so we set the variable here. +ifdef VPATH +srcdir = $(VPATH) +else +ifeq ($(CURDIR),$(dir $(firstword $(MAKEFILE_LIST)))) +srcdir = . + +else +srcdir = $(dir $(firstword $(MAKEFILE_LIST))) + +endif +endif +else # not PGXS +vpath_build = no +abs_top_builddir = /private/tmp/pgrac-worktrees/linkdb-spec-5.50-cr-profile +abs_top_srcdir = /private/tmp/pgrac-worktrees/linkdb-spec-5.50-cr-profile + +ifneq ($(vpath_build),yes) +top_srcdir = $(top_builddir) +srcdir = . +else # vpath_build = yes +top_srcdir = $(abs_top_srcdir) +srcdir = $(top_srcdir)/$(subdir) + +endif +endif # not PGXS + +vpathsearch = `for f in $(addsuffix /$(1),$(subst :, ,. $(VPATH))); do test -r $$f && echo $$f && break; done` + + +########################################################################## +# +# Installation directories +# +# These are set by the equivalent --xxxdir configure options. We +# append "postgresql" to some of them, if the string does not already +# contain "pgsql" or "postgres", in order to avoid directory clutter. +# +# In a PGXS build, we cannot use the values inserted into Makefile.global +# by configure, since the installation tree may have been relocated. +# Instead get the path values from pg_config. + +ifndef PGXS + +# Note that prefix, exec_prefix, and datarootdir aren't defined in a PGXS build; +# makefiles may only use the derived variables such as bindir. + +prefix := /private/tmp/pgrac-worktrees/linkdb-spec-5.50-cr-profile/install +exec_prefix := ${prefix} +datarootdir := ${prefix}/share + +bindir := ${exec_prefix}/bin + +datadir := ${datarootdir} +ifeq "$(findstring pgsql, $(datadir))" "" +ifeq "$(findstring postgres, $(datadir))" "" +override datadir := $(datadir)/postgresql +endif +endif + +sysconfdir := ${prefix}/etc +ifeq "$(findstring pgsql, $(sysconfdir))" "" +ifeq "$(findstring postgres, $(sysconfdir))" "" +override sysconfdir := $(sysconfdir)/postgresql +endif +endif + +libdir := ${exec_prefix}/lib + +pkglibdir = $(libdir) +ifeq "$(findstring pgsql, $(pkglibdir))" "" +ifeq "$(findstring postgres, $(pkglibdir))" "" +override pkglibdir := $(pkglibdir)/postgresql +endif +endif + +includedir := ${prefix}/include + +pkgincludedir = $(includedir) +ifeq "$(findstring pgsql, $(pkgincludedir))" "" +ifeq "$(findstring postgres, $(pkgincludedir))" "" +override pkgincludedir := $(pkgincludedir)/postgresql +endif +endif + +mandir := ${datarootdir}/man + +docdir := ${datarootdir}/doc/${PACKAGE_TARNAME} +ifeq "$(findstring pgsql, $(docdir))" "" +ifeq "$(findstring postgres, $(docdir))" "" +override docdir := $(docdir)/postgresql +endif +endif + +htmldir := ${docdir} + +localedir := ${datarootdir}/locale + +else # PGXS case + +# Extension makefiles should set PG_CONFIG, but older ones might not +ifndef PG_CONFIG +PG_CONFIG = pg_config +endif + +bindir := $(shell $(PG_CONFIG) --bindir) +datadir := $(shell $(PG_CONFIG) --sharedir) +sysconfdir := $(shell $(PG_CONFIG) --sysconfdir) +libdir := $(shell $(PG_CONFIG) --libdir) +pkglibdir := $(shell $(PG_CONFIG) --pkglibdir) +includedir := $(shell $(PG_CONFIG) --includedir) +pkgincludedir := $(shell $(PG_CONFIG) --pkgincludedir) +mandir := $(shell $(PG_CONFIG) --mandir) +docdir := $(shell $(PG_CONFIG) --docdir) +localedir := $(shell $(PG_CONFIG) --localedir) + +endif # PGXS + +# These derived path variables aren't separately configurable. + +includedir_server = $(pkgincludedir)/server +includedir_internal = $(pkgincludedir)/internal +pgxsdir = $(pkglibdir)/pgxs +bitcodedir = $(pkglibdir)/bitcode + + +########################################################################## +# +# Features +# +# Records the choice of the various --enable-xxx and --with-xxx options. + +with_icu = yes +with_perl = no +with_python = no +with_tcl = no +with_ssl = openssl +with_readline = yes +with_selinux = no +with_systemd = no +with_gssapi = no +with_krb_srvnam = postgres +with_ldap = no +with_libxml = no +with_libxslt = no +with_llvm = no +with_system_tzdata = +with_uuid = no +with_zlib = yes +enable_rpath = yes +enable_nls = no +enable_debug = no +enable_dtrace = no +enable_coverage = no +enable_tap_tests = yes +enable_thread_safety = yes +# PGRAC: cluster build flag (--enable-cluster) +enable_pgrac_cluster = yes + +python_includespec = +python_libdir = +python_libspec = +python_additional_libs = +python_majorversion = +python_version = + +krb_srvtab = + +ICU_CFLAGS = -I/opt/homebrew/opt/icu4c@78/include +ICU_LIBS = -L/opt/homebrew/opt/icu4c@78/lib -licui18n -licuuc + +TCLSH = +TCL_LIBS = +TCL_LIB_SPEC = +TCL_INCLUDE_SPEC = +TCL_SHARED_BUILD = + +PTHREAD_CFLAGS = -pthread -D_REENTRANT -D_THREAD_SAFE +PTHREAD_LIBS = + +LLVM_BINPATH = +CLANG = +BITCODE_CFLAGS = -O2 +BITCODE_CXXFLAGS = -O2 + +########################################################################## +# +# Programs and flags + +# Compilers + +CPP = gcc -E +CPPFLAGS = -isysroot $(PG_SYSROOT) -I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/lz4/include -I/opt/homebrew/opt/zstd/include +PG_SYSROOT = /Library/Developer/CommandLineTools/SDKs/MacOSX26.4.sdk + +override CPPFLAGS += $(ICU_CFLAGS) + +ifdef PGXS +override CPPFLAGS := -I$(includedir_server) -I$(includedir_internal) $(CPPFLAGS) +else # not PGXS +override CPPFLAGS := -I$(top_srcdir)/src/include $(CPPFLAGS) +ifdef VPATH +override CPPFLAGS := -I$(top_builddir)/src/include $(CPPFLAGS) +endif +endif # not PGXS + +CC = gcc +GCC = yes +SUN_STUDIO_CC = no +CXX = g++ +CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Werror=unguarded-availability-new -Wendif-labels -Wmissing-format-attribute -Wcast-function-type -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-unused-command-line-argument -Wno-compound-token-split-by-macro -Wno-format-truncation -Wno-cast-function-type-strict -O2 +CFLAGS_SL = +# *_MODULE are for flags applied to extension libraries +CFLAGS_SL_MODULE = -fvisibility=hidden +CXXFLAGS_SL_MODULE = -fvisibility=hidden -fvisibility-inlines-hidden +CFLAGS_UNROLL_LOOPS = -funroll-loops +CFLAGS_VECTORIZE = -ftree-vectorize +CFLAGS_CRC = +PERMIT_DECLARATION_AFTER_STATEMENT = -Wno-declaration-after-statement +CXXFLAGS = -Wall -Wpointer-arith -Werror=unguarded-availability-new -Wendif-labels -Wmissing-format-attribute -Wcast-function-type -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 + +LLVM_CPPFLAGS = +LLVM_CFLAGS = +LLVM_CXXFLAGS = + +# Kind-of compilers + +BISON = /usr/bin/bison +BISONFLAGS = $(YFLAGS) +FLEX = /usr/bin/flex +FLEXFLAGS = $(LFLAGS) +DTRACE = +DTRACEFLAGS = +ZIC = + +# Linking + +AR = ar +AROPT = crs +LIBS = -lzstd -llz4 -lssl -lcrypto -lz -lreadline -lm +LDAP_LIBS_FE = +LDAP_LIBS_BE = +UUID_LIBS = +LLVM_LIBS= + +# It's critical that within LDFLAGS, all -L switches pointing to build-tree +# directories come before any -L switches pointing to external directories. +# Otherwise it's possible for, e.g., a platform-provided copy of libpq.so +# to get linked in place of the one we've built. Therefore we adopt the +# convention that the first component of LDFLAGS is an extra variable +# LDFLAGS_INTERNAL, and -L and -l switches for PG's own libraries must be +# put into LDFLAGS_INTERNAL, so they will appear ahead of those for external +# libraries. +# +# We need LDFLAGS and LDFLAGS_INTERNAL to be "recursively expanded" variables, +# else adjustments to, e.g., rpathdir don't work right. So we must NOT do +# "LDFLAGS := something" anywhere, ditto for LDFLAGS_INTERNAL. +# These initial assignments must be "=" type, and elsewhere we must only do +# "LDFLAGS += something" or "LDFLAGS_INTERNAL += something". +ifdef PGXS + LDFLAGS_INTERNAL = -L$(libdir) +else + LDFLAGS_INTERNAL = -L$(top_builddir)/src/port -L$(top_builddir)/src/common +endif +LDFLAGS = $(LDFLAGS_INTERNAL) -isysroot $(PG_SYSROOT) -L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/lz4/lib -L/opt/homebrew/opt/zstd/lib -Wl,-dead_strip_dylibs + +LDFLAGS_EX = +LDFLAGS_EX_BE = +# LDFLAGS_SL might have already been assigned by calling makefile +LDFLAGS_SL += +WINDRES = +X = + +# Perl + +ifneq (/usr/bin/perl,) + # quoted to protect pathname with spaces + PERL = '/usr/bin/perl' +else + PERL = $(missing) perl +endif +perl_archlibexp = +perl_privlibexp = +perl_includespec = +perl_embed_ccflags = +perl_embed_ldflags = + +# Miscellaneous + +AWK = awk +LN_S = ln -s +MSGFMT = +MSGFMT_FLAGS = +MSGMERGE = +OPENSSL = /usr/bin/openssl +PYTHON = +TAR = /usr/bin/tar +XGETTEXT = + +GZIP = gzip +BZIP2 = bzip2 +LZ4 = /opt/homebrew/bin/lz4 +ZSTD = /opt/homebrew/bin/zstd + +DOWNLOAD = wget -O $@ --no-use-server-timestamps +#DOWNLOAD = curl -o $@ + + +# Unicode data information + +# Before each major release, update these and run make update-unicode. + +# Pick a release from here: . Note +# that the most recent release listed there is often a pre-release; +# don't pick that one, except for testing. +UNICODE_VERSION = 15.0.0 + +# Pick a release from here: +CLDR_VERSION = 43 + + +# Tree-wide build support + +# Just about every code subdirectory wants to have the generated headers +# available before building, but we don't want parallel makes all trying +# to build the same headers. These rules, together with the recursion rules +# below, ensure that we update the generated headers once, if needed, +# at the top level of any "make all/install/check/installcheck" request. +# If a particular subdirectory knows this isn't needed in itself or its +# children, it can set NO_GENERATED_HEADERS. + +all install check installcheck: submake-generated-headers + +.PHONY: submake-generated-headers + +submake-generated-headers: +ifndef NO_GENERATED_HEADERS +ifeq ($(MAKELEVEL),0) + $(MAKE) -C $(top_builddir)/src/backend generated-headers +endif +endif + + +# Testing + +# In much the same way as above, these rules ensure that we build a temp +# install tree just once in any recursive "make check". The additional test +# on abs_top_builddir prevents doing anything foolish to the root directory. + +check: temp-install + +.PHONY: temp-install + +temp-install: | submake-generated-headers +ifndef NO_TEMP_INSTALL +ifneq ($(abs_top_builddir),) +ifeq ($(MAKELEVEL),0) + rm -rf '$(abs_top_builddir)'/tmp_install + $(MKDIR_P) '$(abs_top_builddir)'/tmp_install/log + $(MAKE) -C '$(top_builddir)' DESTDIR='$(abs_top_builddir)'/tmp_install install >'$(abs_top_builddir)'/tmp_install/log/install.log 2>&1 + $(MAKE) -j1 $(if $(CHECKPREP_TOP),-C $(CHECKPREP_TOP),) checkprep >>'$(abs_top_builddir)'/tmp_install/log/install.log 2>&1 +endif +endif +endif + +# Tasks to run serially at the end of temp-install. Some EXTRA_INSTALL +# entries appear more than once in the tree, and parallel installs of the same +# file can fail with EEXIST. +checkprep: + $(if $(EXTRA_INSTALL),for extra in $(EXTRA_INSTALL); do $(MAKE) -C '$(top_builddir)'/$$extra DESTDIR='$(abs_top_builddir)'/tmp_install install || exit; done) + +PROVE = /usr/bin/prove +# There are common routines in src/test/perl, and some test suites have +# extra perl modules in their own directory. +PG_PROVE_FLAGS = -I $(top_srcdir)/src/test/perl/ -I $(srcdir) +# User-supplied prove flags such as --verbose can be provided in PROVE_FLAGS. +PROVE_FLAGS = + +# prepend to path if already set, else just set it +define add_to_path +$(1)="$(if $($(1)),$(2):$$$(1),$(2))" +endef + +# platform-specific environment variable to set shared library path +# individual ports can override this later, this is the default name +ld_library_path_var = LD_LIBRARY_PATH + +# with_temp_install_extra is for individual ports to define if they +# need something more here. If not defined then the expansion does +# nothing. +with_temp_install = \ + PATH="$(abs_top_builddir)/tmp_install$(bindir):$(CURDIR):$$PATH" \ + $(call add_to_path,$(strip $(ld_library_path_var)),$(abs_top_builddir)/tmp_install$(libdir)) \ + $(with_temp_install_extra) + +ifeq ($(enable_tap_tests),yes) + +ifndef PGXS +define prove_installcheck +echo "# +++ tap install-check in $(subdir) +++" && \ +rm -rf '$(CURDIR)'/tmp_check && \ +$(MKDIR_P) '$(CURDIR)'/tmp_check && \ +cd $(srcdir) && \ + TESTLOGDIR='$(CURDIR)/tmp_check/log' \ + TESTDATADIR='$(CURDIR)/tmp_check' \ + PATH="$(bindir):$(CURDIR):$$PATH" \ + PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' \ + PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' \ + $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) +endef +else # PGXS case +define prove_installcheck +echo "# +++ tap install-check in $(subdir) +++" && \ +rm -rf '$(CURDIR)'/tmp_check && \ +$(MKDIR_P) '$(CURDIR)'/tmp_check && \ +cd $(srcdir) && \ + TESTLOGDIR='$(CURDIR)/tmp_check/log' \ + TESTDATADIR='$(CURDIR)/tmp_check' \ + PATH="$(bindir):$(CURDIR):$$PATH" \ + PGPORT='6$(DEF_PGPORT)' \ + PG_REGRESS='$(top_builddir)/src/test/regress/pg_regress' \ + $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) +endef +endif # PGXS + +define prove_check +echo "# +++ tap check in $(subdir) +++" && \ +rm -rf '$(CURDIR)'/tmp_check && \ +$(MKDIR_P) '$(CURDIR)'/tmp_check && \ +cd $(srcdir) && \ + TESTLOGDIR='$(CURDIR)/tmp_check/log' \ + TESTDATADIR='$(CURDIR)/tmp_check' \ + $(with_temp_install) \ + PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' \ + PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' \ + $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) +endef + +else +prove_installcheck = @echo "TAP tests not enabled. Try configuring with --enable-tap-tests" +prove_check = $(prove_installcheck) +endif + +# Installation. + +install_bin = /usr/bin/install -c +install_sh = $(SHELL) $(top_srcdir)/config/install-sh -c +INSTALL = $(if $(use_install_sh),$(install_sh),$(if $(install_bin),$(install_bin),$(install_sh))) + +INSTALL_SCRIPT_MODE = 755 +INSTALL_DATA_MODE = 644 +INSTALL_PROGRAM = $(INSTALL_PROGRAM_ENV) $(INSTALL) $(INSTALL_STRIP_FLAG) +INSTALL_SCRIPT = $(INSTALL) -m $(INSTALL_SCRIPT_MODE) +INSTALL_DATA = $(INSTALL) -m $(INSTALL_DATA_MODE) +INSTALL_STLIB = $(INSTALL_STLIB_ENV) $(INSTALL_DATA) $(INSTALL_STRIP_FLAG) +INSTALL_SHLIB = $(INSTALL_SHLIB_ENV) $(INSTALL) $(INSTALL_SHLIB_OPTS) $(INSTALL_STRIP_FLAG) +# Override in Makefile.port if necessary +INSTALL_SHLIB_OPTS = -m 755 + +MKDIR_P = ${SHELL} ${top_srcdir}/config/install-sh -c -d + +missing = $(SHELL) $(top_srcdir)/config/missing + +STRIP = strip -x +STRIP_STATIC_LIB = strip -x +STRIP_SHARED_LIB = strip -x + +# Documentation + +DBTOEPUB = +FOP = +XMLLINT = /usr/bin/xmllint +XSLTPROC = /usr/bin/xsltproc + +# Code coverage + +GCOV = +LCOV = +GENHTML = + +# Feature settings + +DEF_PGPORT = 5432 +WANTED_LANGUAGES = + + +########################################################################## +# +# Additional platform-specific settings +# + +# Name of the "template" +PORTNAME= darwin + +build_os = darwin25.4.0 + +host_tuple = aarch64-apple-darwin25.4.0 +host_os = darwin25.4.0 +host_cpu = aarch64 + +# Backend stack size limit has to be hard-wired on Windows (it's in bytes) +WIN32_STACK_RLIMIT=4194304 + +DLSUFFIX = .dylib + +# Pull in platform-specific magic +include $(top_builddir)/src/Makefile.port + +# Set up rpath if enabled. By default it will point to our libdir, +# but individual Makefiles can force other rpath paths if needed. +rpathdir = $(libdir) + +ifeq ($(enable_rpath), yes) +LDFLAGS += $(rpath) +endif + +# Show the DLSUFFIX to build scripts (e.g. buildfarm) +.PHONY: show_dl_suffix +show_dl_suffix: + @echo $(DLSUFFIX) + + +########################################################################## +# +# Some variables needed to find some client interfaces + +ifdef PGXS +# some contribs assumes headers and libs are in the source tree... +libpq_srcdir = $(includedir) +libpq_builddir = $(libdir) +else +libpq_srcdir = $(top_srcdir)/src/interfaces/libpq +libpq_builddir = $(top_builddir)/src/interfaces/libpq +endif + +# How to link to libpq. (This macro may be used as-is by backend extensions. +# Client-side code should go through libpq_pgport or libpq_pgport_shlib, +# instead.) +libpq = -L$(libpq_builddir) -lpq + +# libpq_pgport is for use by client executables (not libraries) that use libpq. +# We want clients to pull symbols from the non-shared libraries libpgport +# and libpgcommon rather than pulling some libpgport symbols from libpq just +# because libpq uses those functions too. This makes applications less +# dependent on changes in libpq's usage of pgport. To do this we link to +# pgport before libpq. This does cause duplicate -lpgport's to appear +# on client link lines, since that also appears in $(LIBS). On platforms +# where we have symbol export control for libpq, the whole exercise is +# unnecessary because libpq won't expose any of these symbols. Currently, +# only macOS warns about duplicate library references, so we only suppress +# the duplicates on macOS. +ifeq ($(PORTNAME),darwin) +libpq_pgport = $(libpq) +else ifdef PGXS +libpq_pgport = -L$(libdir) -lpgcommon -lpgport $(libpq) +else +libpq_pgport = -L$(top_builddir)/src/common -lpgcommon -L$(top_builddir)/src/port -lpgport $(libpq) +endif + +# libpq_pgport_shlib is the same idea, but for use in client shared libraries. +# We need those clients to use the shlib variants. (Ideally, users of this +# macro would strip libpgport and libpgcommon from $(LIBS), but no harm is +# done if they don't, since they will have satisfied all their references +# from these libraries.) +ifdef PGXS +libpq_pgport_shlib = -L$(libdir) -lpgcommon_shlib -lpgport_shlib $(libpq) +else +libpq_pgport_shlib = -L$(top_builddir)/src/common -lpgcommon_shlib -L$(top_builddir)/src/port -lpgport_shlib $(libpq) +endif + +# Cygwin seems to need ldap libraries to be mentioned here, too +ifeq ($(PORTNAME),cygwin) +libpq_pgport += $(LDAP_LIBS_FE) +endif + + +########################################################################## +# +# Commonly used submake targets + +submake-libpq: | submake-generated-headers + $(MAKE) -C $(libpq_builddir) all + +submake-libpgport: | submake-generated-headers + $(MAKE) -C $(top_builddir)/src/port all + $(MAKE) -C $(top_builddir)/src/common all + +submake-libpgfeutils: | submake-generated-headers + $(MAKE) -C $(top_builddir)/src/port all + $(MAKE) -C $(top_builddir)/src/common all + $(MAKE) -C $(top_builddir)/src/fe_utils all + +.PHONY: submake-libpq submake-libpgport submake-libpgfeutils + + +########################################################################## +# +# Testing support + +ifneq ($(USE_MODULE_DB),) + PL_TESTDB = pl_regression_$(NAME) + ifneq ($(MODULE_big),) + CONTRIB_TESTDB=contrib_regression_$(MODULE_big) + ISOLATION_TESTDB=isolation_regression_$(MODULE_big) + else + ifneq ($(MODULES),) + CONTRIB_TESTDB=contrib_regression_$(word 1,$(MODULES)) + ISOLATION_TESTDB=isolation_regression_$(word 1,$(MODULES)) + else + CONTRIB_TESTDB=contrib_regression_$(word 1,$(REGRESS)) + ISOLATION_TESTDB=isolation_regression_$(word 1,$(ISOLATION)) + endif + endif +else + PL_TESTDB = pl_regression + CONTRIB_TESTDB = contrib_regression + ISOLATION_TESTDB = isolation_regression +endif + +ifdef NO_LOCALE +NOLOCALE += --no-locale +endif + +# file with extra config for temp build +TEMP_CONF = +ifdef TEMP_CONFIG +TEMP_CONF += --temp-config=$(TEMP_CONFIG) +endif + +pg_regress_locale_flags = $(if $(ENCODING),--encoding=$(ENCODING)) $(NOLOCALE) +pg_regress_clean_files = results/ regression.diffs regression.out tmp_check/ tmp_check_iso/ log/ output_iso/ + +pg_regress_check = \ + echo "\# +++ regress check in $(subdir) +++" && \ + $(with_temp_install) \ + $(top_builddir)/src/test/regress/pg_regress \ + --temp-instance=./tmp_check \ + --inputdir=$(srcdir) \ + --bindir= \ + $(TEMP_CONF) \ + $(pg_regress_locale_flags) $(EXTRA_REGRESS_OPTS) +pg_regress_installcheck = \ + echo "\# +++ regress install-check in $(subdir) +++" && \ + $(top_builddir)/src/test/regress/pg_regress \ + --inputdir=$(srcdir) \ + --bindir='$(bindir)' \ + $(pg_regress_locale_flags) $(EXTRA_REGRESS_OPTS) + +pg_isolation_regress_check = \ + echo "\# +++ isolation check in $(subdir) +++" && \ + $(with_temp_install) \ + $(top_builddir)/src/test/isolation/pg_isolation_regress \ + --temp-instance=./tmp_check_iso \ + --inputdir=$(srcdir) --outputdir=output_iso \ + --bindir= \ + $(TEMP_CONF) \ + $(pg_regress_locale_flags) $(EXTRA_REGRESS_OPTS) +pg_isolation_regress_installcheck = \ + echo "\# +++ isolation install-check in $(subdir) +++" && \ + $(top_builddir)/src/test/isolation/pg_isolation_regress \ + --inputdir=$(srcdir) --outputdir=output_iso \ + --bindir='$(bindir)' \ + $(pg_regress_locale_flags) $(EXTRA_REGRESS_OPTS) + +########################################################################## +# +# Customization +# +# This includes your local customizations if Makefile.custom exists +# in the source directory. This file doesn't exist in the original +# distribution so that it doesn't get overwritten when you upgrade. +# +# NOTE: Makefile.custom is from the pre-Autoconf days of PostgreSQL. +# You are liable to shoot yourself in the foot if you use it without +# knowing exactly what you're doing. The preferred (and more +# reliable) method is to communicate what you want to do to the +# configure script, and leave the makefiles alone. + +-include $(top_srcdir)/src/Makefile.custom + +ifneq ($(CUSTOM_INSTALL),) +INSTALL= $(CUSTOM_INSTALL) +endif + +ifneq ($(CUSTOM_CC),) + CC= $(CUSTOM_CC) +endif + +ifneq ($(CUSTOM_COPT),) + COPT= $(CUSTOM_COPT) +endif + +# +# These variables are meant to be set in the environment of "make" +# to add flags to whatever configure picked. Unlike the ones above, +# they are documented. +# +ifdef COPT + CFLAGS += $(COPT) + LDFLAGS += $(COPT) +endif + +ifdef PROFILE + CFLAGS += $(PROFILE) + LDFLAGS += $(PROFILE) +endif + + +########################################################################## +# +# substitute implementations of C library routines (see src/port/) +# note we already included -L.../src/port in LDFLAGS above + +LIBOBJS = ${LIBOBJDIR}explicit_bzero$U.o ${LIBOBJDIR}pthread_barrier_wait$U.o + +# files needed for the chosen CRC-32C implementation +PG_CRC32C_OBJS = pg_crc32c_armv8.o + +LIBS := -lpgcommon -lpgport $(LIBS) + +# to make ws2_32.lib the last library +ifeq ($(PORTNAME),win32) +LIBS += -lws2_32 +endif + +# Not really standard libc functions, used by the backend. +TAS = + + +########################################################################## +# +# Global targets and rules + +%.c: %.l +ifdef FLEX + $(FLEX) $(if $(FLEX_NO_BACKUP),-b) $(FLEXFLAGS) -o'$@' $< + @$(if $(FLEX_NO_BACKUP),if [ `wc -l &2; exit 1; fi) + $(if $(FLEX_FIX_WARNING),$(PERL) $(top_srcdir)/src/tools/fix-old-flex-code.pl '$@') +else + @$(missing) flex $< '$@' +endif + +%.c: %.y + $(if $(BISON_CHECK_CMD),$(BISON_CHECK_CMD)) +ifdef BISON + $(BISON) $(BISONFLAGS) -o $@ $< +else + @$(missing) bison $< $@ +endif + +%.i: %.c + $(CPP) $(CPPFLAGS) -o $@ $< + +%.gz: % + $(GZIP) --best -c $< >$@ + +%.bz2: % + $(BZIP2) -c $< >$@ + +# Direct builds of foo.c -> foo are disabled to avoid generating +# *.dSYM junk on Macs. All builds should normally go through the +# foo.c -> foo.o -> foo steps. This also ensures that dependency +# tracking (see below) is used. +%: %.c + +# Replace gmake's default rule for linking a single .o file to produce an +# executable. The main point here is to put LDFLAGS after the .o file, +# since we put -l switches into LDFLAGS and those are order-sensitive. +# In addition, include CFLAGS and LDFLAGS_EX per project conventions. +%: %.o + $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) + +ifndef PGXS + +# Remake Makefile.global from Makefile.global.in if the latter +# changed. In order to trigger this rule, the including file must +# write `include $(top_builddir)/src/Makefile.global', not some +# shortcut thereof. +$(top_builddir)/src/Makefile.global: $(top_srcdir)/src/Makefile.global.in $(top_builddir)/config.status + cd $(top_builddir) && ./config.status src/Makefile.global + +# Remake pg_config.h from pg_config.h.in if the latter changed. +# config.status will not change the timestamp on pg_config.h if it +# doesn't change, so as to avoid recompiling the entire tree +# unnecessarily. Therefore we make config.status update a timestamp file +# stamp-h every time it runs, so that we don't trigger this rule every time. +# (We do trigger the null rule for stamp-h to pg_config.h every time; so it's +# important for that rule to be empty!) +# +# Of course you need to turn on dependency tracking to get any +# dependencies on pg_config.h. +$(top_builddir)/src/include/pg_config.h: $(top_builddir)/src/include/stamp-h ; + +$(top_builddir)/src/include/stamp-h: $(top_srcdir)/src/include/pg_config.h.in $(top_builddir)/config.status + cd $(top_builddir) && ./config.status src/include/pg_config.h + +# Also remake pg_config_ext.h from pg_config_ext.h.in, same logic as above. +$(top_builddir)/src/include/pg_config_ext.h: $(top_builddir)/src/include/stamp-ext-h ; + +$(top_builddir)/src/include/stamp-ext-h: $(top_srcdir)/src/include/pg_config_ext.h.in $(top_builddir)/config.status + cd $(top_builddir) && ./config.status src/include/pg_config_ext.h + +# Also remake ecpg_config.h from ecpg_config.h.in if the latter changed, same +# logic as above. +$(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/interfaces/ecpg/include/stamp-h ; + + $(top_builddir)/src/interfaces/ecpg/include/stamp-h: $(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h.in $(top_builddir)/config.status + cd $(top_builddir) && ./config.status src/interfaces/ecpg/include/ecpg_config.h + +# When configure changes, rerun configure with the same options as +# last time. To change configure, you need to run autoconf manually. +$(top_builddir)/config.status: $(top_srcdir)/configure + cd $(top_builddir) && ./config.status --recheck + +endif # not PGXS + + +install-strip: +# install-strip always uses install-sh, so that strip options can be +# passed. + $(MAKE) use_install_sh=yes \ + INSTALL_PROGRAM_ENV="STRIPPROG='$(STRIP)'" \ + INSTALL_STLIB_ENV="STRIPPROG='$(STRIP_STATIC_LIB)'" \ + INSTALL_SHLIB_ENV="STRIPPROG='$(STRIP_SHARED_LIB)'" \ + INSTALL_STRIP_FLAG=-s \ + install + + +########################################################################## +# +# Recursive make support +# ---------------------- +# Instead of recursing through subdirectories with a for loop or +# repeated $(MAKE) -C whatever calls, this is a little smarter: it +# allows parallel make across directories and lets make -k and -q work +# correctly. + +# We need the ability to export target-specific variables, which was +# added in GNU make 3.81. That also happens to be the version +# where the .FEATURES variable was introduced, so this is a simple check. +ifndef .FEATURES +$(error GNU make 3.81 or newer is required. You are using version $(MAKE_VERSION)) +endif + +# This function is only for internal use below. It should be called +# using $(eval). It will set up a target so that it recurses into a +# given subdirectory. For the tree-wide all/install/check/installcheck cases, +# ensure we do our one-time tasks before recursing (see targets above). +# Note that to avoid a nasty bug in make 3.80, +# this function was written to not use any complicated constructs (like +# multiple targets on a line) and also not contain any lines that expand +# to more than about 200 bytes. This is why we make it apply to just one +# subdirectory at a time, rather than to a list of subdirectories. +# $1: target name, e.g., all +# $2: subdir name +# $3: target to run in subdir, usually same as $1 +define _create_recursive_target +.PHONY: $(1)-$(2)-recurse +$(1): $(1)-$(2)-recurse +$(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install) + $$(MAKE) -C $(2) $(3) +endef +# Note that the use of $$ on the last line above is important; we want +# $(MAKE) to be evaluated when the rule is run, not when the $(eval) is run +# to create the rule. This is necessary to get make -q working. + +# Call this function in a makefile that needs to recurse into subdirectories. +# In the normal case all arguments can be defaulted. +# $1: targets to make recursive (defaults to list of standard targets) +# $2: list of subdirs (defaults to SUBDIRS variable) +# $3: target to run in subdir (defaults to current element of $1) +recurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(foreach subdir,$(if $2,$2,$(SUBDIRS)),$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target)))))) + +# If a makefile's list of SUBDIRS varies depending on configuration, then +# any subdirectories excluded from SUBDIRS should instead be added to +# ALWAYS_SUBDIRS, and then it must call recurse_always as well as recurse. +# This ensures that distprep, distclean, etc will apply to all subdirectories. +# In the normal case all arguments will be defaulted. +# $1: targets to make recursive (defaults to standard_always_targets) +# $2: list of subdirs (defaults to ALWAYS_SUBDIRS variable) +# $3: target to run in subdir (defaults to current element of $1) +recurse_always = $(foreach target,$(if $1,$1,$(standard_always_targets)),$(foreach subdir,$(if $2,$2,$(ALWAYS_SUBDIRS)),$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target)))))) + + +########################################################################## +# +# Automatic dependency generation +# ------------------------------- +# When we configure with --enable-depend then we override the default +# compilation rule with the magic below. While or after creating the +# actual output file we also create a dependency list for the .c file. +# Next time we invoke make we will have top-notch information about +# whether this file needs to be updated. The dependency files are kept +# in the .deps subdirectory of each directory. + +autodepend = + +ifeq ($(autodepend), yes) + +ifndef COMPILE.c +COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c +endif + +ifndef COMPILE.cc +COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c +endif + +DEPDIR = .deps + +ifeq ($(GCC), yes) + +# GCC allows us to create object and dependency file in one invocation. +%.o : %.c + @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi + $(COMPILE.c) -o $@ $< -MMD -MP -MF $(DEPDIR)/$(*F).Po + +%.o : %.cpp + @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi + $(COMPILE.cc) -o $@ $< -MMD -MP -MF $(DEPDIR)/$(*F).Po + +endif # GCC + +# Include all the dependency files generated for the current +# directory. Note that make would complain if include was called with +# no arguments. +Po_files := $(wildcard $(DEPDIR)/*.Po) +ifneq (,$(Po_files)) +include $(Po_files) +endif + +# hook for clean-up +clean distclean maintainer-clean: clean-deps + +.PHONY: clean-deps +clean-deps: + @rm -rf $(DEPDIR) + +endif # autodepend + + +########################################################################## +# +# Native language support + +ifeq ($(enable_nls), yes) +ifneq (,$(wildcard $(srcdir)/nls.mk)) + +include $(top_srcdir)/src/nls-global.mk + +endif # nls.mk +endif # enable_nls + + +########################################################################## +# +# Coverage + +# Explanation of involved files: +# foo.c source file +# foo.o object file +# foo.gcno gcov graph (a.k.a. "notes") file, created at compile time +# (by gcc -ftest-coverage) +# foo.gcda gcov data file, created when the program is run (for +# programs compiled with gcc -fprofile-arcs) +# foo.c.gcov gcov output file with coverage information, created by +# gcov from foo.gcda (by "make coverage") +# foo.c.gcov.out stdout captured when foo.c.gcov is created, mildly +# interesting +# lcov_test.info +# lcov tracefile, built from gcda files in one directory, +# later collected by "make coverage-html" +# lcov_base.info +# tracefile for zero counters for every file, so that +# even files that are not touched by tests are counted +# for the overall coverage rate + +ifeq ($(enable_coverage), yes) + +# make coverage -- text output + +local_gcda_files = $(wildcard *.gcda) + +coverage: $(local_gcda_files:.gcda=.c.gcov) + +%.c.gcov: %.gcda + $(GCOV) -b -f -p -o . $(GCOVFLAGS) $*.c >$*.c.gcov.out + +# make coverage-html -- HTML output via lcov + +.PHONY: coverage-html +coverage-html: coverage-html-stamp + +GENHTML_FLAGS = -q --legend +GENHTML_TITLE = PostgreSQL $(VERSION) + +coverage-html-stamp: lcov_base.info lcov_test.info + rm -rf coverage + $(GENHTML) $(GENHTML_FLAGS) -o coverage --title='$(GENHTML_TITLE)' --num-spaces=4 $(if $(filter no,$(vpath_build)),--prefix='$(abs_top_srcdir)') $^ + touch $@ + +LCOV += --gcov-tool $(GCOV) +LCOVFLAGS = -q --no-external + +all_gcno_files = $(shell find . -name '*.gcno' -print) + +lcov_base.info: $(all_gcno_files) + $(LCOV) $(LCOVFLAGS) -c -i -d . -d $(srcdir) -o $@ + +all_gcda_files = $(shell find . -name '*.gcda' -print) + +lcov_test.info: $(all_gcda_files) + $(LCOV) $(LCOVFLAGS) -c -d . -d $(srcdir) -o $@ + + +# hook for clean-up +clean distclean maintainer-clean: clean-coverage + +.PHONY: clean-coverage +clean-coverage: + rm -rf coverage coverage-html-stamp + rm -f *.gcda *.gcno lcov*.info *.gcov .*.gcov *.gcov.out + + +# User-callable target to reset counts between test runs +coverage-clean: + rm -f `find . -name '*.gcda' -print` + +endif # enable_coverage + +########################################################################## +# +# LLVM support +# + +ifndef COMPILE.c.bc +# -Wno-ignored-attributes added so gnu_printf doesn't trigger +# warnings, when the main binary is compiled with C. +COMPILE.c.bc = $(CLANG) -Wno-ignored-attributes $(BITCODE_CFLAGS) $(CPPFLAGS) -flto=thin -emit-llvm -c +endif + +ifndef COMPILE.cxx.bc +COMPILE.cxx.bc = $(CLANG) -xc++ -Wno-ignored-attributes $(BITCODE_CXXFLAGS) $(CPPFLAGS) -flto=thin -emit-llvm -c +endif + +%.bc : %.c + $(COMPILE.c.bc) -o $@ $< + +%.bc : %.cpp + $(COMPILE.cxx.bc) -o $@ $< + +# Install LLVM bitcode module (for JITing). +# +# The arguments are: +# $(1) name of the module (e.g. an extension's name or postgres for core code) +# $(2) source objects, with .o suffix +# +# The many INSTALL_DATA invocations aren't particularly fast, it'd be +# good if we could coalesce them, but I didn't find a good way. +# +# Note: blank line at end of macro is necessary to let it be used in foreach +define install_llvm_module +$(MKDIR_P) '$(DESTDIR)${bitcodedir}/$(1)' +$(MKDIR_P) $(sort $(dir $(addprefix '$(DESTDIR)${bitcodedir}'/$(1)/, $(2)))) +$(foreach obj, ${2}, $(INSTALL_DATA) $(patsubst %.o,%.bc, $(obj)) '$(DESTDIR)${bitcodedir}'/$(1)/$(dir $(obj)) +) +cd '$(DESTDIR)${bitcodedir}' && $(LLVM_BINPATH)/llvm-lto -thinlto -thinlto-action=thinlink -o $(1).index.bc $(addprefix $(1)/,$(patsubst %.o,%.bc, $(2))) + +endef + +# Uninstall LLVM bitcode module. +# +# The arguments are: +# $(1) name of the module (e.g. an extension's name or postgres for core code) +# +# This intentionally doesn't use the explicit installed file list, +# seems too likely to change regularly. +define uninstall_llvm_module +rm -rf '$(DESTDIR)${bitcodedir}/$(1)/' +rm -f '$(DESTDIR)${bitcodedir}/$(1).index.bc' + +endef diff --git a/install/lib/postgresql/pgxs/src/Makefile.port b/install/lib/postgresql/pgxs/src/Makefile.port new file mode 100644 index 00000000000..7095f66e25c --- /dev/null +++ b/install/lib/postgresql/pgxs/src/Makefile.port @@ -0,0 +1,12 @@ +# env var name to use in place of LD_LIBRARY_PATH +ld_library_path_var = DYLD_LIBRARY_PATH + +ifdef PGXS + BE_DLLLIBS = -bundle_loader $(bindir)/postgres +else + BE_DLLLIBS = -bundle_loader $(top_builddir)/src/backend/postgres +endif + +# Rule for building a shared library from a single .o file +%$(DLSUFFIX): %.o + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -bundle $(BE_DLLLIBS) -o $@ diff --git a/install/lib/postgresql/pgxs/src/Makefile.shlib b/install/lib/postgresql/pgxs/src/Makefile.shlib new file mode 100644 index 00000000000..f94d59d1c59 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/Makefile.shlib @@ -0,0 +1,460 @@ +#------------------------------------------------------------------------- +# +# Makefile.shlib +# Common rules for building shared libraries +# +# Copyright (c) 1998, Regents of the University of California +# +# IDENTIFICATION +# src/Makefile.shlib +# +#------------------------------------------------------------------------- + +# This file should be included by any Postgres module Makefile that +# wants to build a shared library (if possible for the current +# platform). A static library is also built from the same object +# files. Only one library can be built per makefile. +# +# Before including this file, the module Makefile must define these +# variables: +# +# NAME Name of library to build (no suffix nor "lib" prefix) +# OBJS List of object files to include in library +# SHLIB_LINK Stuff to append to library's link command +# (typically, -L and -l switches for external libraries) +# SHLIB_LINK_INTERNAL -L and -l switches for Postgres-supplied libraries +# SHLIB_PREREQS Order-only prerequisites for library build target +# SHLIB_EXPORTS (optional) Name of file containing list of symbols to +# export, in the format "function_name number" +# +# Don't use SHLIB_LINK for references to files in the build tree, or the +# wrong things will happen --- use SHLIB_LINK_INTERNAL for those! +# +# When building a shared library, the following version information +# must also be set. It should be omitted when building a dynamically +# loadable module. +# +# SO_MAJOR_VERSION Major version number to use for shared library +# SO_MINOR_VERSION Minor version number to use for shared library +# (If you want a patchlevel, include it in SO_MINOR_VERSION, e.g., "6.2".) +# +# The module Makefile must also include +# $(top_builddir)/src/Makefile.global before including this file. +# (Makefile.global sets PORTNAME and other needed symbols.) +# +# This makefile provides the following (phony) targets: +# +# all-lib build the static and shared (if applicable) libraries +# install-lib install the libraries into $(libdir) +# installdirs-lib create installation directory $(libdir) +# uninstall-lib remove the libraries from $(libdir) +# clean-lib delete the static and shared libraries from the build dir +# +# Typically you would add `all-lib' to the `all' target so that `make all' +# builds the libraries. In the most simple case it would look like this: +# +# all: all-lib +# +# Similarly, the install rule might look like +# +# install: install-lib +# +# plus any additional things you want to install. Et cetera. +# +# Got that? Look at src/interfaces/libpq/Makefile for an example. +# + + +COMPILER = $(CC) $(CFLAGS) +LINK.static = $(AR) $(AROPT) + +LDFLAGS_INTERNAL += $(SHLIB_LINK_INTERNAL) + + + +ifdef SO_MAJOR_VERSION +# Default library naming convention used by the majority of platforms +shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION) +shlib_major = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION) +shlib_bare = lib$(NAME)$(DLSUFFIX) +# Testing the soname variable is a reliable way to determine whether a +# linkable library is being built. +soname = $(shlib_major) +pkgconfigdir = $(libdir)/pkgconfig +else +# Naming convention for dynamically loadable modules +shlib = $(NAME)$(DLSUFFIX) +endif +stlib = lib$(NAME).a + +ifndef soname +# additional flags for backend modules +SHLIB_LINK += $(BE_DLLLIBS) +endif + +# For each platform we support shared libraries on, set shlib to the +# name of the library (if default above is not right), set +# LINK.shared to the command to link the library, +# and adjust SHLIB_LINK if necessary. + +# Try to keep the sections in some kind of order, folks... + +override CFLAGS += $(CFLAGS_SL) +override CXXFLAGS += $(CFLAGS_SL) +ifdef SO_MAJOR_VERSION +# libraries ought to use this to refer to versioned gettext domain names +override CPPFLAGS += -DSO_MAJOR_VERSION=$(SO_MAJOR_VERSION) +endif + +ifeq ($(PORTNAME), aix) + LINK.shared = $(COMPILER) + ifdef SO_MAJOR_VERSION + shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION) + endif + haslibarule = yes + # $(exports_file) is also usable as an import file + exports_file = lib$(NAME).exp + BUILD.exports = ( echo '\#! $(shlib)'; $(AWK) '/^[^\#]/ {printf "%s\n",$$1}' $< ) > $@ + ifneq (,$(SHLIB_EXPORTS)) + LINK.shared += -Wl,-bE:$(exports_file) + endif +endif + +ifeq ($(PORTNAME), darwin) + ifdef soname + # linkable library + ifneq ($(SO_MAJOR_VERSION), 0) + version_link = -compatibility_version $(SO_MAJOR_VERSION) -current_version $(SO_MAJOR_VERSION).$(SO_MINOR_VERSION) + endif + LINK.shared = $(COMPILER) -dynamiclib -install_name '$(libdir)/lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)' $(version_link) $(exported_symbols_list) + shlib = lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX) + shlib_major = lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX) + else + # loadable module + LINK.shared = $(COMPILER) -bundle + endif + BUILD.exports = $(AWK) '/^[^\#]/ {printf "_%s\n",$$1}' $< >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + exported_symbols_list = -exported_symbols_list $(exports_file) + endif +endif + +ifeq ($(PORTNAME), openbsd) + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-x,-soname,$(soname) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,--version-script=$(exports_file) + endif + SHLIB_LINK += -lc +endif + +ifeq ($(PORTNAME), freebsd) + ifdef SO_MAJOR_VERSION + shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION) + endif + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-x,-soname,$(soname) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,--version-script=$(exports_file) + endif +endif + +ifeq ($(PORTNAME), netbsd) + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-x,-soname,$(soname) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,--version-script=$(exports_file) + endif +endif + +ifeq ($(PORTNAME), linux) + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-soname,$(soname) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,--version-script=$(exports_file) + endif +endif + +ifeq ($(PORTNAME), solaris) + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-soname,$(soname) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,-M$(exports_file) + endif +endif + +ifeq ($(PORTNAME), cygwin) + LINK.shared = $(CC) -shared + ifdef SO_MAJOR_VERSION + shlib = cyg$(NAME)$(DLSUFFIX) + endif + haslibarule = yes +endif + +ifeq ($(PORTNAME), win32) + ifdef SO_MAJOR_VERSION + shlib = lib$(NAME)$(DLSUFFIX) + endif + haslibarule = yes +endif + + +# If the shared library doesn't have an export file, mark all symbols not +# explicitly exported using PGDLLEXPORT as hidden. We can't pass these flags +# when building a library with explicit exports, as the symbols would be +# hidden before the linker script / exported symbol list takes effect. +# +# This is duplicated in pgxs.mk for MODULES style libraries. +ifeq ($(SHLIB_EXPORTS),) + # LDFLAGS_SL addition not strictly needed, CFLAGS used everywhere, but ... + override LDFLAGS_SL += $(CFLAGS_SL_MODULE) + override CFLAGS += $(CFLAGS_SL_MODULE) + override CXXFLAGS += $(CXXFLAGS_SL_MODULE) +endif + + +## +## BUILD +## + +.PHONY: all-lib all-static-lib all-shared-lib + +all-lib: all-shared-lib +ifdef soname +# no static library when building a dynamically loadable module +all-lib: all-static-lib +all-lib: lib$(NAME).pc +endif + +all-static-lib: $(stlib) + +all-shared-lib: $(shlib) + +# In this rule, "touch $@" works around a problem on some platforms wherein +# ar updates the library file's mod time with a value calculated to +# seconds precision. If the filesystem has sub-second timestamps, this can +# cause the library file to appear older than its input files, triggering +# parallel-make problems. +ifndef haslibarule +$(stlib): $(OBJS) | $(SHLIB_PREREQS) + rm -f $@ + $(LINK.static) $@ $^ + touch $@ +endif #haslibarule + +# AIX wraps shared libraries inside a static library, can be used both +# for static and shared linking +ifeq ($(PORTNAME), aix) +$(stlib): $(shlib) + rm -f $(stlib) + $(AR) $(AROPT) $(stlib) $(shlib) +endif # aix + +ifeq (,$(filter cygwin win32,$(PORTNAME))) + +# Normal case +$(shlib): $(OBJS) | $(SHLIB_PREREQS) + $(LINK.shared) -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) +ifdef shlib_major +# If we're using major and minor versions, then make a symlink to major-version-only. +ifneq ($(shlib), $(shlib_major)) + rm -f $(shlib_major) + $(LN_S) $(shlib) $(shlib_major) +endif +# Make sure we have a link to a name without any version numbers +ifneq ($(shlib), $(shlib_bare)) +# except on AIX, where that's not a thing +ifneq ($(PORTNAME), aix) + rm -f $(shlib_bare) + $(LN_S) $(shlib) $(shlib_bare) +endif # aix +endif # shlib_bare +endif # shlib_major + +# Where possible, restrict the symbols exported by the library to just the +# official list, so as to avoid unintentional ABI changes. On recent macOS +# this also quiets multiply-defined-symbol warnings in programs that use +# libpgport along with libpq. +ifneq (,$(SHLIB_EXPORTS)) +ifdef BUILD.exports +$(shlib): $(exports_file) + +$(exports_file): $(SHLIB_EXPORTS) + $(BUILD.exports) +endif +endif + +else # PORTNAME == cygwin || PORTNAME == win32 + +ifeq ($(PORTNAME), cygwin) + +# Cygwin case + +$(shlib): $(OBJS) | $(SHLIB_PREREQS) + $(CC) $(CFLAGS) -shared -o $@ -Wl,--out-implib=$(stlib) $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) $(LDAP_LIBS_BE) + +# see notes in src/backend/parser/Makefile about use of this type of rule +$(stlib): $(shlib) + touch $@ + +else + +# Win32 case + +# See notes in src/backend/parser/Makefile about the following two rules +$(stlib): $(shlib) + touch $@ + +# XXX A backend that loads a module linked with libgcc_s_dw2-1.dll will exit +# uncleanly, hence -static-libgcc. (Last verified with MinGW-w64 compilers +# from i686-4.9.1-release-win32-dwarf-rt_v3-rev1.) Shared libgcc has better +# support for C++/Java exceptions; while core PostgreSQL does not use them, it +# would be nice to support shared libgcc for the benefit of extensions. +# +# If SHLIB_EXPORTS is set, the rules below will build a .def file from that. +# Else we just use --export-all-symbols. +ifeq (,$(SHLIB_EXPORTS)) +$(shlib): $(OBJS) | $(SHLIB_PREREQS) + $(CC) $(CFLAGS) -shared -static-libgcc -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--export-all-symbols -Wl,--out-implib=$(stlib) +else +DLL_DEFFILE = lib$(NAME)dll.def + +$(shlib): $(OBJS) $(DLL_DEFFILE) | $(SHLIB_PREREQS) + $(CC) $(CFLAGS) -shared -static-libgcc -o $@ $(OBJS) $(DLL_DEFFILE) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--out-implib=$(stlib) + +UC_NAME = $(shell echo $(NAME) | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') + +$(DLL_DEFFILE): $(SHLIB_EXPORTS) + echo 'LIBRARY LIB$(UC_NAME).dll' >$@ + echo 'EXPORTS' >>$@ + sed -e '/^#/d' -e 's/^\(.*[ ]\)\([0-9][0-9]*\)/ \1@ \2/' $< >>$@ +endif + +endif # PORTNAME == cygwin +endif # PORTNAME == cygwin || PORTNAME == win32 + + +%.pc: $(MAKEFILE_LIST) + echo 'prefix=$(prefix)' >$@ + echo 'exec_prefix=$(patsubst $(prefix),$${prefix},$(exec_prefix))' >>$@ + echo 'libdir=$(patsubst $(exec_prefix)/%,$${exec_prefix}/%,$(libdir))' >>$@ + echo 'includedir=$(patsubst $(prefix)/%,$${prefix}/%,$(includedir))' >>$@ + echo >>$@ + echo 'Name: lib$(NAME)' >>$@ + echo 'Description: PostgreSQL lib$(NAME) library' >>$@ + echo 'URL: $(PACKAGE_URL)' >>$@ + echo 'Version: $(VERSION)' >>$@ + echo 'Requires: ' >>$@ + echo 'Requires.private: $(PKG_CONFIG_REQUIRES_PRIVATE)' >>$@ + echo 'Cflags: -I$${includedir}' >>$@ + echo 'Libs: -L$${libdir} -l$(NAME)' >>$@ +# Record -L flags that the user might have passed in to the PostgreSQL +# build to locate third-party libraries (e.g., ldap, ssl). Filter out +# those that point inside the build or source tree. Use sort to +# remove duplicates. Also record the -l flags necessary for static +# linking, but not those already covered by Requires.private. + echo 'Libs.private: $(sort $(filter-out -L.% -L$(top_srcdir)/%,$(filter -L%,$(LDFLAGS) $(SHLIB_LINK)))) $(filter-out $(PKG_CONFIG_REQUIRES_PRIVATE:lib%=-l%),$(filter -l%,$(SHLIB_LINK_INTERNAL:%_shlib=%) $(SHLIB_LINK)))' >>$@ + + +## +## INSTALL +## + +.PHONY: install-lib install-lib-static install-lib-shared installdirs-lib +install-lib: install-lib-shared +ifdef soname +install-lib: install-lib-static +install-lib: install-lib-pc +endif + +install-lib-pc: lib$(NAME).pc installdirs-lib + $(INSTALL_DATA) $< '$(DESTDIR)$(pkgconfigdir)/lib$(NAME).pc' + +install-lib-static: $(stlib) installdirs-lib + $(INSTALL_STLIB) $< '$(DESTDIR)$(libdir)/$(stlib)' + +install-lib-shared: $(shlib) installdirs-lib +ifdef soname +# we don't install $(shlib) on AIX +# (see http://archives.postgresql.org/message-id/52EF20B2E3209443BC37736D00C3C1380A6E79FE@EXADV1.host.magwien.gv.at) +ifneq ($(PORTNAME), aix) + $(INSTALL_SHLIB) $< '$(DESTDIR)$(libdir)/$(shlib)' +ifneq ($(PORTNAME), cygwin) +ifneq ($(PORTNAME), win32) +ifneq ($(shlib), $(shlib_major)) + cd '$(DESTDIR)$(libdir)' && \ + rm -f $(shlib_major) && \ + $(LN_S) $(shlib) $(shlib_major) +endif +ifneq ($(shlib), $(shlib_bare)) + cd '$(DESTDIR)$(libdir)' && \ + rm -f $(shlib_bare) && \ + $(LN_S) $(shlib) $(shlib_bare) +endif +endif # not win32 +endif # not cygwin +endif # not aix +ifneq (,$(findstring $(PORTNAME),win32 cygwin)) + $(INSTALL_SHLIB) $< '$(DESTDIR)$(bindir)/$(shlib)' +endif +else # no soname + $(INSTALL_SHLIB) $< '$(DESTDIR)$(pkglibdir)/$(shlib)' +endif + + +installdirs-lib: +ifdef soname + $(MKDIR_P) '$(DESTDIR)$(libdir)' '$(DESTDIR)$(pkgconfigdir)' $(if $(findstring $(PORTNAME),win32 cygwin),'$(DESTDIR)$(bindir)') +else + $(MKDIR_P) '$(DESTDIR)$(pkglibdir)' +endif + + +## +## UNINSTALL +## + +.PHONY: uninstall-lib +uninstall-lib: +ifdef soname + rm -f '$(DESTDIR)$(libdir)/$(stlib)' + rm -f '$(DESTDIR)$(libdir)/$(shlib_bare)' \ + '$(DESTDIR)$(libdir)/$(shlib_major)' \ + '$(DESTDIR)$(libdir)/$(shlib)' $(if $(findstring $(PORTNAME),win32 cygwin),'$(DESTDIR)$(bindir)/$(shlib)') \ + '$(DESTDIR)$(pkgconfigdir)/lib$(NAME).pc' +else # no soname + rm -f '$(DESTDIR)$(pkglibdir)/$(shlib)' +endif # no soname + + +## +## CLEAN +## + +.PHONY: clean-lib +clean-lib: + rm -f $(shlib) $(shlib_bare) $(shlib_major) $(stlib) $(exports_file) lib$(NAME).pc +ifneq (,$(DLL_DEFFILE)) + rm -f $(DLL_DEFFILE) +endif diff --git a/install/lib/postgresql/pgxs/src/makefiles/pgxs.mk b/install/lib/postgresql/pgxs/src/makefiles/pgxs.mk new file mode 100644 index 00000000000..7ba8d5bc980 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/makefiles/pgxs.mk @@ -0,0 +1,479 @@ +# PGXS: PostgreSQL extensions makefile + +# src/makefiles/pgxs.mk + +# This file contains generic rules to build many kinds of simple +# extension modules. You only need to set a few variables and include +# this file, the rest will be done here. +# +# Use the following layout for your Makefile: +# +# [variable assignments, see below] +# +# PG_CONFIG = pg_config +# PGXS := $(shell $(PG_CONFIG) --pgxs) +# include $(PGXS) +# +# [custom rules, rarely necessary] +# +# 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 -- name of extension (there must be a $EXTENSION.control file) +# 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 into $PREFIX/share/tsearch_data +# DOCS -- random files to install under $PREFIX/doc/$MODULEDIR +# 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 +# HEADERS -- files to install into $(includedir_server)/$MODULEDIR/$MODULE_big +# HEADERS_built -- as above but built first (but NOT cleaned) +# HEADERS_$(MODULE) -- files to install into +# $(includedir_server)/$MODULEDIR/$MODULE; the value of $MODULE must be +# listed in MODULES or MODULE_big +# HEADERS_built_$(MODULE) -- as above but built first (also NOT cleaned) +# REGRESS -- list of regression test cases (without suffix) +# REGRESS_OPTS -- additional switches to pass to pg_regress +# TAP_TESTS -- switch to enable TAP tests +# ISOLATION -- list of isolation test cases +# ISOLATION_OPTS -- additional switches to pass to pg_isolation_regress +# 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 +# PG_LIBS_INTERNAL -- same, for references to libraries within build tree +# SHLIB_LINK -- will be added to MODULE_big link line +# SHLIB_LINK_INTERNAL -- same, for references to libraries within build tree +# 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) +# +# Better look at some of the existing uses for examples... + +ifndef PGXS +ifndef NO_PGXS +$(error pgxs error: makefile variable PGXS or NO_PGXS must be set) +endif +endif + + +ifdef PGXS + +# External extensions must assume generated headers are available +NO_GENERATED_HEADERS=yes +# The temp-install rule won't work, either +NO_TEMP_INSTALL=yes + +# We assume that we are in src/makefiles/, so top is ... +top_builddir := $(dir $(PGXS))../.. +include $(top_builddir)/src/Makefile.global + +# These might be set in Makefile.global, but if they were not found +# during the build of PostgreSQL, supply default values so that users +# of pgxs can use the variables. +ifeq ($(BISON),) +BISON = bison +endif +ifeq ($(FLEX),) +FLEX = flex +endif + +endif # PGXS + + +override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) + +# See equivalent block in Makefile.shlib +ifdef MODULES +override LDFLAGS_SL += $(CFLAGS_SL_MODULE) +override CFLAGS += $(CFLAGS_SL) $(CFLAGS_SL_MODULE) +override CXXFLAGS += $(CFLAGS_SL) $(CXXFLAGS_SL_MODULE) +endif + +ifdef MODULEDIR +datamoduledir := $(MODULEDIR) +docmoduledir := $(MODULEDIR) +incmoduledir := $(MODULEDIR) +else +ifdef EXTENSION +datamoduledir := extension +docmoduledir := extension +incmoduledir := extension +else +datamoduledir := contrib +docmoduledir := contrib +incmoduledir := contrib +endif +endif + +ifdef PG_CPPFLAGS +override CPPFLAGS := $(PG_CPPFLAGS) $(CPPFLAGS) +endif +ifdef PG_CFLAGS +override CFLAGS := $(CFLAGS) $(PG_CFLAGS) +endif +ifdef PG_CXXFLAGS +override CXXFLAGS := $(CXXFLAGS) $(PG_CXXFLAGS) +endif +ifdef PG_LDFLAGS +override LDFLAGS := $(PG_LDFLAGS) $(LDFLAGS) +endif + +# logic for HEADERS_* stuff + +# get list of all names used with or without built_ prefix +# note that use of HEADERS_built_foo will get both "foo" and "built_foo", +# we cope with that later when filtering this list against MODULES. +# If someone wants to name a module "built_foo", they can do that and it +# works, but if they have MODULES = foo built_foo then they will need to +# force building of all headers and use HEADERS_built_foo and +# HEADERS_built_built_foo. +HEADER_alldirs := $(patsubst HEADERS_%,%,$(filter HEADERS_%, $(.VARIABLES))) +HEADER_alldirs += $(patsubst HEADERS_built_%,%,$(filter HEADERS_built_%, $(.VARIABLES))) + +# collect all names of built headers to use as a dependency +HEADER_allbuilt := + +ifdef MODULE_big + +# we can unconditionally add $(MODULE_big) here, because we will strip it +# back out below if it turns out not to actually define any headers. +HEADER_dirs := $(MODULE_big) +HEADER_unbuilt_$(MODULE_big) = $(HEADERS) +HEADER_built_$(MODULE_big) = $(HEADERS_built) +HEADER_allbuilt += $(HEADERS_built) +# treat "built" as an exclusion below as well as "built_foo" +HEADER_xdirs := built built_$(MODULE_big) + +else # not MODULE_big, so check MODULES + +# HEADERS is an error in the absence of MODULE_big to provide a dir name +ifdef HEADERS +$(error HEADERS requires MODULE_big to be set) +endif +# make list of modules that have either HEADERS_foo or HEADERS_built_foo +HEADER_dirs := $(foreach m,$(MODULES),$(if $(filter $(m) built_$(m),$(HEADER_alldirs)),$(m))) +# make list of conflicting names to exclude +HEADER_xdirs := $(addprefix built_,$(HEADER_dirs)) + +endif # MODULE_big or MODULES + +# HEADERS_foo requires that "foo" is in MODULES as a sanity check +ifneq (,$(filter-out $(HEADER_dirs) $(HEADER_xdirs),$(HEADER_alldirs))) +$(error $(patsubst %,HEADERS_%,$(filter-out $(HEADER_dirs) $(HEADER_xdirs),$(HEADER_alldirs))) defined with no module) +endif + +# assign HEADER_unbuilt_foo and HEADER_built_foo, but make sure +# that "built" takes precedence in the case of conflict, by removing +# conflicting module names when matching the unbuilt name +$(foreach m,$(filter-out $(HEADER_xdirs),$(HEADER_dirs)),$(eval HEADER_unbuilt_$(m) += $$(HEADERS_$(m)))) +$(foreach m,$(HEADER_dirs),$(eval HEADER_built_$(m) += $$(HEADERS_built_$(m)))) +$(foreach m,$(HEADER_dirs),$(eval HEADER_allbuilt += $$(HEADERS_built_$(m)))) + +# expand out the list of headers for each dir, attaching source prefixes +header_file_list = $(HEADER_built_$(1)) $(addprefix $(srcdir)/,$(HEADER_unbuilt_$(1))) +$(foreach m,$(HEADER_dirs),$(eval HEADER_files_$(m) := $$(call header_file_list,$$(m)))) + +# note that the caller's HEADERS* vars have all been expanded now, and +# later changes will have no effect. + +# remove entries in HEADER_dirs that produced an empty list of files, +# to ensure we don't try and install them +HEADER_dirs := $(foreach m,$(HEADER_dirs),$(if $(strip $(HEADER_files_$(m))),$(m))) + +# Functions for generating install/uninstall commands; the blank lines +# before the "endef" are required, don't lose them +# $(call install_headers,dir,headers) +define install_headers +$(MKDIR_P) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/' +$(INSTALL_DATA) $(2) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/' + +endef +# $(call uninstall_headers,dir,headers) +define uninstall_headers +rm -f $(addprefix '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)'/, $(notdir $(2))) + +endef + +# end of HEADERS_* stuff + + +all: $(PROGRAM) $(DATA_built) $(HEADER_allbuilt) $(SCRIPTS_built) $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .control, $(EXTENSION)) + +ifeq ($(with_llvm), yes) +all: $(addsuffix .bc, $(MODULES)) $(patsubst %.o,%.bc, $(OBJS)) +endif + +ifdef MODULE_big +# shared library parameters +NAME = $(MODULE_big) + +include $(top_srcdir)/src/Makefile.shlib + +all: all-lib +endif # MODULE_big + + +ifndef NO_INSTALL + +install: all installdirs +ifneq (,$(EXTENSION)) + $(INSTALL_DATA) $(addprefix $(srcdir)/, $(addsuffix .control, $(EXTENSION))) '$(DESTDIR)$(datadir)/extension/' +endif # EXTENSION +ifneq (,$(DATA)$(DATA_built)) + $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) $(DATA_built) '$(DESTDIR)$(datadir)/$(datamoduledir)/' +endif # DATA +ifneq (,$(DATA_TSEARCH)) + $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA_TSEARCH)) '$(DESTDIR)$(datadir)/tsearch_data/' +endif # DATA_TSEARCH +ifdef MODULES + $(INSTALL_SHLIB) $(addsuffix $(DLSUFFIX), $(MODULES)) '$(DESTDIR)$(pkglibdir)/' +ifeq ($(with_llvm), yes) + $(foreach mod, $(MODULES), $(call install_llvm_module,$(mod),$(mod).bc)) +endif # with_llvm +endif # MODULES +ifdef DOCS +ifdef docdir + $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DOCS)) '$(DESTDIR)$(docdir)/$(docmoduledir)/' +endif # docdir +endif # DOCS +ifdef PROGRAM + $(INSTALL_PROGRAM) $(PROGRAM)$(X) '$(DESTDIR)$(bindir)' +endif # PROGRAM +ifdef SCRIPTS + $(INSTALL_SCRIPT) $(addprefix $(srcdir)/, $(SCRIPTS)) '$(DESTDIR)$(bindir)/' +endif # SCRIPTS +ifdef SCRIPTS_built + $(INSTALL_SCRIPT) $(SCRIPTS_built) '$(DESTDIR)$(bindir)/' +endif # SCRIPTS_built +ifneq (,$(strip $(HEADER_dirs))) + $(foreach dir,$(HEADER_dirs),$(call install_headers,$(dir),$(HEADER_files_$(dir)))) +endif # HEADERS +ifdef MODULE_big +ifeq ($(with_llvm), yes) + $(call install_llvm_module,$(MODULE_big),$(OBJS)) +endif # with_llvm + +install: install-lib +endif # MODULE_big + + +installdirs: +ifneq (,$(EXTENSION)) + $(MKDIR_P) '$(DESTDIR)$(datadir)/extension' +endif +ifneq (,$(DATA)$(DATA_built)) + $(MKDIR_P) '$(DESTDIR)$(datadir)/$(datamoduledir)' +endif +ifneq (,$(DATA_TSEARCH)) + $(MKDIR_P) '$(DESTDIR)$(datadir)/tsearch_data' +endif +ifneq (,$(MODULES)) + $(MKDIR_P) '$(DESTDIR)$(pkglibdir)' +endif +ifdef DOCS +ifdef docdir + $(MKDIR_P) '$(DESTDIR)$(docdir)/$(docmoduledir)' +endif # docdir +endif # DOCS +ifneq (,$(PROGRAM)$(SCRIPTS)$(SCRIPTS_built)) + $(MKDIR_P) '$(DESTDIR)$(bindir)' +endif + +ifdef MODULE_big +installdirs: installdirs-lib +endif # MODULE_big + + +uninstall: +ifneq (,$(EXTENSION)) + rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(addsuffix .control, $(EXTENSION)))) +endif +ifneq (,$(DATA)$(DATA_built)) + rm -f $(addprefix '$(DESTDIR)$(datadir)/$(datamoduledir)'/, $(notdir $(DATA) $(DATA_built))) +endif +ifneq (,$(DATA_TSEARCH)) + rm -f $(addprefix '$(DESTDIR)$(datadir)/tsearch_data'/, $(notdir $(DATA_TSEARCH))) +endif +ifdef MODULES + rm -f $(addprefix '$(DESTDIR)$(pkglibdir)'/, $(addsuffix $(DLSUFFIX), $(MODULES))) +ifeq ($(with_llvm), yes) + $(foreach mod, $(MODULES), $(call uninstall_llvm_module,$(mod))) +endif # with_llvm +endif # MODULES +ifdef DOCS + rm -f $(addprefix '$(DESTDIR)$(docdir)/$(docmoduledir)'/, $(DOCS)) +endif +ifdef PROGRAM + rm -f '$(DESTDIR)$(bindir)/$(PROGRAM)$(X)' +endif +ifdef SCRIPTS + rm -f $(addprefix '$(DESTDIR)$(bindir)'/, $(SCRIPTS)) +endif +ifdef SCRIPTS_built + rm -f $(addprefix '$(DESTDIR)$(bindir)'/, $(SCRIPTS_built)) +endif +ifneq (,$(strip $(HEADER_dirs))) + $(foreach dir,$(HEADER_dirs),$(call uninstall_headers,$(dir),$(HEADER_files_$(dir)))) +endif # HEADERS + +ifdef MODULE_big +ifeq ($(with_llvm), yes) + $(call uninstall_llvm_module,$(MODULE_big)) +endif # with_llvm + +uninstall: uninstall-lib +endif # MODULE_big + +else # NO_INSTALL + +# Need this so that temp-install builds artifacts not meant for +# installation (Normally, check should depend on all, but we don't do +# that because of parallel make risk (dbf2ec1a1c0).) +install: all + +endif # NO_INSTALL + + +clean: +ifdef MODULES + rm -f $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .o, $(MODULES)) $(if $(PGFILEDESC),$(WIN32RES)) \ + $(addsuffix .bc, $(MODULES)) +endif +ifdef DATA_built + rm -f $(DATA_built) +endif +ifdef SCRIPTS_built + rm -f $(SCRIPTS_built) +endif +ifdef PROGRAM + rm -f $(PROGRAM)$(X) +endif +ifdef OBJS + rm -f $(OBJS) $(patsubst %.o,%.bc, $(OBJS)) +endif +ifdef EXTRA_CLEAN + rm -rf $(EXTRA_CLEAN) +endif +ifdef REGRESS +# things created by various check targets + rm -rf $(pg_regress_clean_files) +ifeq ($(PORTNAME), win) + rm -f regress.def +endif +endif # REGRESS +ifdef TAP_TESTS + rm -rf tmp_check/ +endif +ifdef ISOLATION + rm -rf output_iso/ tmp_check_iso/ +endif + +ifdef MODULE_big +clean: clean-lib +endif + +distclean maintainer-clean: clean + + +ifdef REGRESS + +REGRESS_OPTS += --dbname=$(CONTRIB_TESTDB) + +# When doing a VPATH build, must copy over the data files so that the +# driver script can find them. We have to use an absolute path for +# the targets, because otherwise make will try to locate the missing +# files using VPATH, and will find them in $(srcdir), but the point +# here is that we want to copy them from $(srcdir) to the build +# directory. + +ifdef VPATH +abs_builddir := $(shell pwd) +test_files_src := $(wildcard $(srcdir)/data/*.data) +test_files_build := $(patsubst $(srcdir)/%, $(abs_builddir)/%, $(test_files_src)) + +all: $(test_files_build) +$(test_files_build): $(abs_builddir)/%: $(srcdir)/% + $(MKDIR_P) $(dir $@) + ln -s $< $@ +endif # VPATH +endif # REGRESS + +.PHONY: submake +submake: +ifndef PGXS + $(MAKE) -C $(top_builddir)/src/test/regress pg_regress$(X) + $(MAKE) -C $(top_builddir)/src/test/isolation all +endif + +ifdef ISOLATION +ISOLATION_OPTS += --dbname=$(ISOLATION_TESTDB) +endif + +# Standard rules to run regression tests including multiple test suites. +# Runs against an installed postmaster. +ifndef NO_INSTALLCHECK +installcheck: submake $(REGRESS_PREP) +ifdef REGRESS + $(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS) +endif +ifdef ISOLATION + $(pg_isolation_regress_installcheck) $(ISOLATION_OPTS) $(ISOLATION) +endif +ifdef TAP_TESTS + $(prove_installcheck) +endif +endif # NO_INSTALLCHECK + +# Runs independently of any installation +ifdef PGXS +check: + @echo '"$(MAKE) check" is not supported.' + @echo 'Do "$(MAKE) install", then "$(MAKE) installcheck" instead.' +else +check: submake $(REGRESS_PREP) +ifdef REGRESS + $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS) +endif +ifdef ISOLATION + $(pg_isolation_regress_check) $(ISOLATION_OPTS) $(ISOLATION) +endif +ifdef TAP_TESTS + $(prove_check) +endif +endif # PGXS + +ifndef NO_TEMP_INSTALL +checkprep: EXTRA_INSTALL+=$(subdir) +endif + + +# STANDARD RULES + +ifneq (,$(MODULES)$(MODULE_big)) +%.sql: %.sql.in + sed 's,MODULE_PATHNAME,$$libdir/$*,g' $< >$@ +endif + +ifdef PROGRAM +$(PROGRAM): $(OBJS) + $(CC) $(CFLAGS) $(OBJS) $(PG_LIBS_INTERNAL) $(LDFLAGS) $(LDFLAGS_EX) $(PG_LIBS) $(LIBS) -o $@$(X) +endif diff --git a/install/lib/postgresql/pgxs/src/nls-global.mk b/install/lib/postgresql/pgxs/src/nls-global.mk new file mode 100644 index 00000000000..52ee38f32a9 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/nls-global.mk @@ -0,0 +1,182 @@ +# src/nls-global.mk + +# Common rules for Native Language Support (NLS) +# +# If some subdirectory of the source tree wants to provide NLS, it +# needs to contain a file 'nls.mk' with the following make variable +# assignments: +# +# CATALOG_NAME -- name of the message catalog (xxx.po); probably +# name of the program +# GETTEXT_FILES -- list of source files that contain message strings +# GETTEXT_TRIGGERS -- (optional) list of functions that contain +# translatable strings +# GETTEXT_FLAGS -- (optional) list of gettext --flag arguments to mark +# function arguments that contain C format strings +# (functions must be listed in TRIGGERS and FLAGS) +# +# Also, provide a text file 'po/LINGUAS' with a space-separated list +# of languages that are provided/supported. +# +# That's all, the rest is done here, if --enable-nls was specified. +# +# The only user-visible targets here are 'init-po', to make an initial +# "blank" catalog from program sources, and 'update-po', which is to +# be called if the messages in the program source have changed, in +# order to merge the changes into the existing .po files. + + +# existence checked by Makefile.global; otherwise we won't get here +include $(srcdir)/nls.mk + +AVAIL_LANGUAGES := $(shell cat $(srcdir)/po/LINGUAS) + +# If user specified the languages he wants in --enable-nls=LANGUAGES, +# filter out the rest. Else use all available ones. +ifdef WANTED_LANGUAGES +LANGUAGES = $(filter $(WANTED_LANGUAGES), $(AVAIL_LANGUAGES)) +else +LANGUAGES = $(AVAIL_LANGUAGES) +endif + +PO_FILES = $(addprefix po/, $(addsuffix .po, $(LANGUAGES))) +ALL_PO_FILES = $(addprefix po/, $(addsuffix .po, $(AVAIL_LANGUAGES))) +MO_FILES = $(addprefix po/, $(addsuffix .mo, $(LANGUAGES))) + +ifdef XGETTEXT +XGETTEXT += -ctranslator --copyright-holder='PostgreSQL Global Development Group' --msgid-bugs-address=pgsql-bugs@lists.postgresql.org --no-wrap --sort-by-file --package-name='$(CATALOG_NAME) (PostgreSQL)' --package-version='$(MAJORVERSION)' +endif + +ifdef MSGMERGE +MSGMERGE += --no-wrap --previous --sort-by-file +endif + +# _ is defined in c.h, so it's global +GETTEXT_TRIGGERS += _ +GETTEXT_FLAGS += _:1:pass-c-format + + +# common settings that apply to backend and all backend modules +BACKEND_COMMON_GETTEXT_TRIGGERS = \ + $(FRONTEND_COMMON_GETTEXT_TRIGGERS) \ + errmsg errmsg_plural:1,2 \ + errdetail errdetail_log errdetail_plural:1,2 \ + errhint errhint_plural:1,2 \ + errcontext \ + XactLockTableWait:4 \ + MultiXactIdWait:6 \ + ConditionalMultiXactIdWait:6 +BACKEND_COMMON_GETTEXT_FLAGS = \ + $(FRONTEND_COMMON_GETTEXT_FLAGS) \ + errmsg:1:c-format errmsg_plural:1:c-format errmsg_plural:2:c-format \ + errdetail:1:c-format errdetail_log:1:c-format errdetail_plural:1:c-format errdetail_plural:2:c-format \ + errhint:1:c-format errhint_plural:1:c-format errhint_plural:2:c-format \ + errcontext:1:c-format + +FRONTEND_COMMON_GETTEXT_FILES = $(top_srcdir)/src/common/logging.c + +FRONTEND_COMMON_GETTEXT_TRIGGERS = \ + pg_log_error pg_log_error_detail pg_log_error_hint \ + pg_log_warning pg_log_warning_detail pg_log_warning_hint \ + pg_log_info pg_log_info_detail pg_log_info_hint \ + pg_fatal pg_log_generic:3 pg_log_generic_v:3 + +FRONTEND_COMMON_GETTEXT_FLAGS = \ + pg_log_error:1:c-format pg_log_error_detail:1:c-format pg_log_error_hint:1:c-format \ + pg_log_warning:1:c-format pg_log_warning_detail:1:c-format pg_log_warning_hint:1:c-format \ + pg_log_info:1:c-format pg_log_info_detail:1:c-format pg_log_info_hint:1:c-format \ + pg_fatal:1:c-format pg_log_generic:3:c-format pg_log_generic_v:3:c-format + + +all-po: $(MO_FILES) + +%.mo: %.po + $(MSGFMT) $(MSGFMT_FLAGS) -o $@ $< + +ifeq ($(word 1,$(GETTEXT_FILES)),+) +po/$(CATALOG_NAME).pot: $(word 2, $(GETTEXT_FILES)) $(MAKEFILE_LIST) +ifdef XGETTEXT + $(XGETTEXT) -D $(srcdir) -D . -n $(addprefix -k, $(GETTEXT_TRIGGERS)) $(addprefix --flag=, $(GETTEXT_FLAGS)) -f $< +else + @echo "You don't have 'xgettext'."; exit 1 +endif +else # GETTEXT_FILES +po/$(CATALOG_NAME).pot: $(GETTEXT_FILES) $(MAKEFILE_LIST) +# Change to srcdir explicitly, don't rely on $^. That way we get +# consistent #: file references in the po files. +ifdef XGETTEXT + $(XGETTEXT) -D $(srcdir) -D . -n $(addprefix -k, $(GETTEXT_TRIGGERS)) $(addprefix --flag=, $(GETTEXT_FLAGS)) $(GETTEXT_FILES) +else + @echo "You don't have 'xgettext'."; exit 1 +endif +endif # GETTEXT_FILES + @$(MKDIR_P) $(dir $@) + sed -e '1,18 { s/SOME DESCRIPTIVE TITLE./LANGUAGE message translation file for $(CATALOG_NAME)/;s/PACKAGE/PostgreSQL/g;s/VERSION/$(MAJORVERSION)/g;s/YEAR/'`date +%Y`'/g; }' messages.po >$@ + rm messages.po + + +# catalog name extensions must match behavior of PG_TEXTDOMAIN() in c.h +install-po: all-po installdirs-po +ifneq (,$(LANGUAGES)) + for lang in $(LANGUAGES); do \ + $(INSTALL_DATA) po/$$lang.mo '$(DESTDIR)$(localedir)'/$$lang/LC_MESSAGES/$(CATALOG_NAME)$(SO_MAJOR_VERSION)-$(MAJORVERSION).mo || exit 1; \ + done +endif + +installdirs-po: + $(if $(LANGUAGES),$(MKDIR_P) $(foreach lang, $(LANGUAGES), '$(DESTDIR)$(localedir)'/$(lang)/LC_MESSAGES),:) + +uninstall-po: + $(if $(LANGUAGES),rm -f $(foreach lang, $(LANGUAGES), '$(DESTDIR)$(localedir)'/$(lang)/LC_MESSAGES/$(CATALOG_NAME)$(SO_MAJOR_VERSION)-$(MAJORVERSION).mo),:) + + +clean-po: + $(if $(MO_FILES),rm -f $(MO_FILES)) + @$(if $(wildcard po/*.po.new),rm -f po/*.po.new) + rm -f po/$(CATALOG_NAME).pot + + +init-po: po/$(CATALOG_NAME).pot + + +# For performance reasons, only calculate these when the user actually +# requested update-po or a specific file. +ifneq (,$(filter update-po %.po.new,$(MAKECMDGOALS))) +ifdef PGXS +ALL_LANGUAGES := $(shell find . -name '*.po' -print | sed 's,^.*/\([^/]*\).po$$,\1,' | LC_ALL=C sort -u) +all_compendia := $(shell find . -name '*.po' -print | LC_ALL=C sort) +else +ALL_LANGUAGES := $(shell find $(top_srcdir) -name '*.po' -print | sed 's,^.*/\([^/]*\).po$$,\1,' | LC_ALL=C sort -u) +all_compendia := $(shell find $(top_srcdir) -name '*.po' -print | LC_ALL=C sort) +endif +else +ALL_LANGUAGES = $(AVAIL_LANGUAGES) +all_compendia = FORCE +FORCE: +endif + +ifdef WANTED_LANGUAGES +ALL_LANGUAGES := $(filter $(WANTED_LANGUAGES), $(ALL_LANGUAGES)) +endif + +update-po: $(ALL_LANGUAGES:%=po/%.po.new) + +$(AVAIL_LANGUAGES:%=po/%.po.new): po/%.po.new: po/%.po po/$(CATALOG_NAME).pot $(all_compendia) + $(MSGMERGE) --lang=$* $(word 1, $^) $(word 2,$^) -o $@ $(addprefix --compendium=,$(filter %/$*.po,$(wordlist 3,$(words $^),$^))) + +# For languages not yet available, merge against oneself, to pick +# up translations from the compendia. (Merging against /dev/null +# doesn't work so well; it inserts the headers from the first-named +# compendium.) +po/%.po.new: po/$(CATALOG_NAME).pot $(all_compendia) + $(MSGMERGE) --lang=$* $(word 1,$^) $(word 1,$^) -o $@ $(addprefix --compendium=,$(filter %/$*.po,$(wordlist 2,$(words $^),$^))) + + +all: all-po +install: install-po +installdirs: installdirs-po +uninstall: uninstall-po +clean distclean maintainer-clean: clean-po + +.PHONY: all-po install-po installdirs-po uninstall-po clean-po \ + init-po update-po diff --git a/install/lib/postgresql/pgxs/src/test/isolation/isolationtester b/install/lib/postgresql/pgxs/src/test/isolation/isolationtester new file mode 100755 index 00000000000..bf26c8bb091 Binary files /dev/null and b/install/lib/postgresql/pgxs/src/test/isolation/isolationtester differ diff --git a/install/lib/postgresql/pgxs/src/test/isolation/pg_isolation_regress b/install/lib/postgresql/pgxs/src/test/isolation/pg_isolation_regress new file mode 100755 index 00000000000..8a1ba3f72d8 Binary files /dev/null and b/install/lib/postgresql/pgxs/src/test/isolation/pg_isolation_regress differ diff --git a/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/BackgroundPsql.pm b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/BackgroundPsql.pm new file mode 100644 index 00000000000..59b91358656 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/BackgroundPsql.pm @@ -0,0 +1,369 @@ + +# Copyright (c) 2021-2024, PostgreSQL Global Development Group + +=pod + +=head1 NAME + +PostgreSQL::Test::BackgroundPsql - class for controlling background psql processes + +=head1 SYNOPSIS + + use PostgreSQL::Test::Cluster; + + my $node = PostgreSQL::Test::Cluster->new('mynode'); + + # Create a data directory with initdb + $node->init(); + + # Start the PostgreSQL server + $node->start(); + + # Create and start an interactive psql session + my $isession = $node->interactive_psql('postgres'); + # Apply timeout per query rather than per session + $isession->set_query_timer_restart(); + # Run a query and get the output as seen by psql + my $ret = $isession->query("SELECT 1"); + # Run a backslash command and wait until the prompt returns + $isession->query_until(qr/postgres #/, "\\d foo\n"); + # Close the session and exit psql + $isession->quit; + + # Create and start a background psql session + my $bsession = $node->background_psql('postgres'); + + # Run a query which is guaranteed to not return in case it fails + $bsession->query_safe("SELECT 1"); + # Initiate a command which can be expected to terminate at a later stage + $bsession->query_until(qr/start/, q( + \echo start + CREATE INDEX CONCURRENTLY idx ON t(a); + )); + # Close the session and exit psql + $bsession->quit; + +=head1 DESCRIPTION + +PostgreSQL::Test::BackgroundPsql contains functionality for controlling +a background or interactive psql session operating on a PostgreSQL node +initiated by PostgreSQL::Test::Cluster. + +=cut + +package PostgreSQL::Test::BackgroundPsql; + +use strict; +use warnings FATAL => 'all'; + +use Carp; +use Config; +use IPC::Run; +use PostgreSQL::Test::Utils qw(pump_until); +use Test::More; + +=pod + +=head1 METHODS + +=over + +=item PostgreSQL::Test::BackgroundPsql->new(interactive, @psql_params, timeout, wait) + +Builds a new object of class C for either +an interactive or background session and starts it. If C is +true then a PTY will be attached. C should contain the full +command to run psql with all desired parameters and a complete connection +string. For C sessions, IO::Pty is required. + +This routine will not return until psql has started up and is ready to +consume input. Set B to 0 to return immediately instead. + +=cut + +sub new +{ + my $class = shift; + my ($interactive, $psql_params, $timeout, $wait) = @_; + my $psql = { + 'stdin' => '', + 'stdout' => '', + 'stderr' => '', + 'query_timer_restart' => undef, + 'query_cnt' => 1, + }; + my $run; + + # This constructor should only be called from PostgreSQL::Test::Cluster + my ($package, $file, $line) = caller; + die + "Forbidden caller of constructor: package: $package, file: $file:$line" + unless $package->isa('PostgreSQL::Test::Cluster'); + + $psql->{timeout} = IPC::Run::timeout( + defined($timeout) + ? $timeout + : $PostgreSQL::Test::Utils::timeout_default); + + if ($interactive) + { + $run = IPC::Run::start $psql_params, + '{stdin}, '>pty>', \$psql->{stdout}, '2>', + \$psql->{stderr}, + $psql->{timeout}; + } + else + { + $run = IPC::Run::start $psql_params, + '<', \$psql->{stdin}, '>', \$psql->{stdout}, '2>', \$psql->{stderr}, + $psql->{timeout}; + } + + $psql->{run} = $run; + + my $self = bless $psql, $class; + + $wait = 1 unless defined($wait); + if ($wait) + { + $self->wait_connect(); + } + + return $self; +} + +=pod + +=item $session->wait_connect + +Returns once psql has started up and is ready to consume input. This is called +automatically for clients unless requested otherwise in the constructor. + +=cut + +sub wait_connect +{ + my ($self) = @_; + + # Request some output, and pump until we see it. This means that psql + # connection failures are caught here, relieving callers of the need to + # handle those. (Right now, we have no particularly good handling for + # errors anyway, but that might be added later.) + # + # See query() for details about why/how the banner is used. + my $banner = "background_psql: ready"; + my $banner_match = qr/$banner\r?\n/; + $self->{stdin} .= "\\echo '$banner'\n\\warn '$banner'\n"; + $self->{run}->pump() + until ($self->{stdout} =~ /$banner_match/ + && $self->{stderr} =~ /$banner_match/) + || $self->{timeout}->is_expired; + + note "connect output:\n", + explain { + stdout => $self->{stdout}, + stderr => $self->{stderr}, + }; + + # clear out banners + $self->{stdout} = ''; + $self->{stderr} = ''; + + die "psql startup timed out" if $self->{timeout}->is_expired; +} + +=pod + +=item $session->quit + +Close the session and clean up resources. Each test run must be closed with +C. + +=cut + +sub quit +{ + my ($self) = @_; + + $self->{stdin} .= "\\q\n"; + + return $self->{run}->finish; +} + +=pod + +=item $session->reconnect_and_clear + +Terminate the current session and connect again. + +=cut + +sub reconnect_and_clear +{ + my ($self) = @_; + + # If psql isn't dead already, tell it to quit as \q, when already dead, + # causes IPC::Run to unhelpfully error out with "ack Broken pipe:". + $self->{run}->pump_nb(); + if ($self->{run}->pumpable()) + { + $self->{stdin} .= "\\q\n"; + } + $self->{run}->finish; + + # restart + $self->{run}->run(); + $self->{stdin} = ''; + $self->{stdout} = ''; + + $self->wait_connect(); +} + +=pod + +=item $session->query() + +Executes a query in the current session and returns the output in scalar +context and (output, error) in list context where error is 1 in case there +was output generated on stderr when executing the query. + +=cut + +sub query +{ + my ($self, $query) = @_; + my $ret; + my $output; + my $query_cnt = $self->{query_cnt}++; + + local $Test::Builder::Level = $Test::Builder::Level + 1; + + note "issuing query $query_cnt via background psql: $query"; + + $self->{timeout}->start() if (defined($self->{query_timer_restart})); + + # Feed the query to psql's stdin, followed by \n (so psql processes the + # line), by a ; (so that psql issues the query, if it doesn't include a ; + # itself), and a separator echoed both with \echo and \warn, that we can + # wait on. + # + # To avoid somehow confusing the separator from separately issued queries, + # and to make it easier to debug, we include a per-psql query counter in + # the separator. + # + # We need both \echo (printing to stdout) and \warn (printing to stderr), + # because on windows we can get data on stdout before seeing data on + # stderr (or vice versa), even if psql printed them in the opposite + # order. We therefore wait on both. + # + # In interactive psql we emit \r\n, so we need to allow for that. + # Also, include quotes around the banner string in the \echo and \warn + # commands, not because the string needs quoting but so that $banner_match + # can't match readline's echoing of these commands. + my $banner = "background_psql: QUERY_SEPARATOR $query_cnt:"; + my $banner_match = qr/$banner\r?\n/; + $self->{stdin} .= "$query\n;\n\\echo '$banner'\n\\warn '$banner'\n"; + $self->{run}->pump() + until ($self->{stdout} =~ /$banner_match/ + && $self->{stderr} =~ /$banner_match/) + || $self->{timeout}->is_expired; + + note "results query $query_cnt:\n", + explain { + stdout => $self->{stdout}, + stderr => $self->{stderr}, + }; + + die "psql query timed out" if $self->{timeout}->is_expired; + + # Remove banner from stdout and stderr, our caller doesn't want it. + # Also remove the query output's trailing newline, if present (there + # would not be one if consuming an empty query result). + $banner_match = qr/\r?\n?$banner\r?\n/; + $output = $self->{stdout}; + $output =~ s/$banner_match//; + $self->{stderr} =~ s/$banner_match//; + + # clear out output for the next query + $self->{stdout} = ''; + + $ret = $self->{stderr} eq "" ? 0 : 1; + + return wantarray ? ($output, $ret) : $output; +} + +=pod + +=item $session->query_safe() + +Wrapper around C which errors out if the query failed to execute. +Query failure is determined by it producing output on stderr. + +=cut + +sub query_safe +{ + my ($self, $query) = @_; + + my $ret = $self->query($query); + + if ($self->{stderr} ne "") + { + die "query failed: $self->{stderr}"; + } + + return $ret; +} + +=pod + +=item $session->query_until(until, query) + +Issue C and wait for C appearing in the query output rather than +waiting for query completion. C needs to end with newline and semicolon +(if applicable, interactive psql input may not require it) for psql to process +the input. + +=cut + +sub query_until +{ + my ($self, $until, $query) = @_; + my $ret; + local $Test::Builder::Level = $Test::Builder::Level + 1; + + $self->{timeout}->start() if (defined($self->{query_timer_restart})); + $self->{stdin} .= $query; + + pump_until($self->{run}, $self->{timeout}, \$self->{stdout}, $until); + + die "psql query timed out" if $self->{timeout}->is_expired; + + $ret = $self->{stdout}; + + # clear out output for the next query + $self->{stdout} = ''; + + return $ret; +} + +=pod + +=item $session->set_query_timer_restart() + +Configures the timer to be restarted before each query such that the defined +timeout is valid per query rather than per test run. + +=back + +=cut + +sub set_query_timer_restart +{ + my $self = shift; + + $self->{query_timer_restart} = 1; + return $self->{query_timer_restart}; +} + +1; diff --git a/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/Cluster.pm b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/Cluster.pm new file mode 100644 index 00000000000..9d9490b6b1b --- /dev/null +++ b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/Cluster.pm @@ -0,0 +1,3374 @@ + +# Copyright (c) 2021-2023, PostgreSQL Global Development Group + +=pod + +=head1 NAME + +PostgreSQL::Test::Cluster - class representing PostgreSQL server instance + +=head1 SYNOPSIS + + use PostgreSQL::Test::Cluster; + + my $node = PostgreSQL::Test::Cluster->new('mynode'); + + # Create a data directory with initdb + $node->init(); + + # Start the PostgreSQL server + $node->start(); + + # Add a setting and restart + $node->append_conf('postgresql.conf', 'hot_standby = on'); + $node->restart(); + + # Modify or delete an existing setting + $node->adjust_conf('postgresql.conf', 'max_wal_senders', '10'); + + # get pg_config settings + # all the settings in one string + $pgconfig = $node->config_data; + # all the settings as a map + %config_map = ($node->config_data); + # specified settings + ($incdir, $sharedir) = $node->config_data(qw(--includedir --sharedir)); + + # run a query with psql, like: + # echo 'SELECT 1' | psql -qAXt postgres -v ON_ERROR_STOP=1 + $psql_stdout = $node->safe_psql('postgres', 'SELECT 1'); + + # Run psql with a timeout, capturing stdout and stderr + # as well as the psql exit code. Pass some extra psql + # options. If there's an error from psql raise an exception. + my ($stdout, $stderr, $timed_out); + my $cmdret = $node->psql('postgres', 'SELECT pg_sleep(600)', + stdout => \$stdout, stderr => \$stderr, + timeout => $PostgreSQL::Test::Utils::timeout_default, + timed_out => \$timed_out, + extra_params => ['--single-transaction'], + on_error_die => 1) + print "Sleep timed out" if $timed_out; + + # Similar thing, more convenient in common cases + my ($cmdret, $stdout, $stderr) = + $node->psql('postgres', 'SELECT 1'); + + # run query every second until it returns 't' + # or times out + $node->poll_query_until('postgres', q|SELECT random() < 0.1;|') + or die "timed out"; + + # Do an online pg_basebackup + my $ret = $node->backup('testbackup1'); + + # Take a backup of a running server + my $ret = $node->backup_fs_hot('testbackup2'); + + # Take a backup of a stopped server + $node->stop; + my $ret = $node->backup_fs_cold('testbackup3') + + # Restore it to create a new independent node (not a replica) + my $other_node = PostgreSQL::Test::Cluster->new('mycopy'); + $other_node->init_from_backup($node, 'testbackup'); + $other_node->start; + + # Stop the server + $node->stop('fast'); + + # Find a free, unprivileged TCP port to bind some other service to + my $port = PostgreSQL::Test::Cluster::get_free_port(); + +=head1 DESCRIPTION + +PostgreSQL::Test::Cluster contains a set of routines able to work on a PostgreSQL node, +allowing to start, stop, backup and initialize it with various options. +The set of nodes managed by a given test is also managed by this module. + +In addition to node management, PostgreSQL::Test::Cluster instances have some wrappers +around Test::More functions to run commands with an environment set up to +point to the instance. + +The IPC::Run module is required. + +=cut + +package PostgreSQL::Test::Cluster; + +use strict; +use warnings; + +use Carp; +use Config; +use Fcntl qw(:mode :flock :seek :DEFAULT); +use File::Basename; +use File::Path qw(rmtree mkpath); +use File::Spec; +use File::stat qw(stat); +use File::Temp (); +use IPC::Run; +use PostgreSQL::Version; +use PostgreSQL::Test::RecursiveCopy; +use Socket; +use Test::More; +use PostgreSQL::Test::Utils (); +use PostgreSQL::Test::BackgroundPsql (); +use Time::HiRes qw(usleep); +use Scalar::Util qw(blessed); + +our ($use_tcp, $test_localhost, $test_pghost, $last_host_assigned, + $last_port_assigned, @all_nodes, $died, $portdir); + +# the minimum version we believe to be compatible with this package without +# subclassing. +our $min_compat = 12; + +# list of file reservations made by get_free_port +my @port_reservation_files; + +# We want to choose a server port above the range that servers typically use +# on Unix systems and below the range those systems typically use for ephemeral +# client ports. +# That way we minimize the risk of getting a port collision. These two values +# are chosen to reflect that. We will always choose a port in this range. +my $port_lower_bound = 10200; +my $port_upper_bound = 32767; + +INIT +{ + + # Set PGHOST for backward compatibility. This doesn't work for own_host + # nodes, so prefer to not rely on this when writing new tests. + $use_tcp = !$PostgreSQL::Test::Utils::use_unix_sockets; + $test_localhost = "127.0.0.1"; + $last_host_assigned = 1; + if ($use_tcp) + { + $test_pghost = $test_localhost; + } + else + { + # On windows, replace windows-style \ path separators with / when + # putting socket directories either in postgresql.conf or libpq + # connection strings, otherwise they are interpreted as escapes. + $test_pghost = PostgreSQL::Test::Utils::tempdir_short; + $test_pghost =~ s!\\!/!g if $PostgreSQL::Test::Utils::windows_os; + } + $ENV{PGHOST} = $test_pghost; + $ENV{PGDATABASE} = 'postgres'; + + # Tracking of last port value assigned to accelerate free port lookup. + my $num_ports = $port_upper_bound - $port_lower_bound; + $last_port_assigned = int(rand() * $num_ports) + $port_lower_bound; + + # Set the port lock directory + + # If we're told to use a directory (e.g. from a buildfarm client) + # explicitly, use that + $portdir = $ENV{PG_TEST_PORT_DIR}; + # Otherwise, try to use a directory at the top of the build tree + # or as a last resort use the tmp_check directory + my $build_dir = $ENV{top_builddir} + || $PostgreSQL::Test::Utils::tmp_check; + $portdir ||= "$build_dir/portlock"; + $portdir =~ s!\\!/!g; + # Make sure the directory exists + mkpath($portdir) unless -d $portdir; +} + +=pod + +=head1 METHODS + +=over + +=item $node->port() + +Get the port number assigned to the host. This won't necessarily be a TCP port +open on the local host since we prefer to use unix sockets if possible. + +Use $node->connstr() if you want a connection string. + +=cut + +sub port +{ + my ($self) = @_; + return $self->{_port}; +} + +=pod + +=item $node->host() + +Return the host (like PGHOST) for this instance. May be a UNIX socket path. + +Use $node->connstr() if you want a connection string. + +=cut + +sub host +{ + my ($self) = @_; + return $self->{_host}; +} + +=pod + +=item $node->basedir() + +The directory all the node's files will be within - datadir, archive directory, +backups, etc. + +=cut + +sub basedir +{ + my ($self) = @_; + return $self->{_basedir}; +} + +=pod + +=item $node->name() + +The name assigned to the node at creation time. + +=cut + +sub name +{ + my ($self) = @_; + return $self->{_name}; +} + +=pod + +=item $node->logfile() + +Path to the PostgreSQL log file for this instance. + +=cut + +sub logfile +{ + my ($self) = @_; + return $self->{_logfile}; +} + +=pod + +=item $node->connstr() + +Get a libpq connection string that will establish a connection to +this node. Suitable for passing to psql, DBD::Pg, etc. + +=cut + +sub connstr +{ + my ($self, $dbname) = @_; + my $pgport = $self->port; + my $pghost = $self->host; + if (!defined($dbname)) + { + return "port=$pgport host=$pghost"; + } + + # Escape properly the database string before using it, only + # single quotes and backslashes need to be treated this way. + $dbname =~ s#\\#\\\\#g; + $dbname =~ s#\'#\\\'#g; + + return "port=$pgport host=$pghost dbname='$dbname'"; +} + +=pod + +=item $node->group_access() + +Does the data dir allow group access? + +=cut + +sub group_access +{ + my ($self) = @_; + + my $dir_stat = stat($self->data_dir); + + defined($dir_stat) + or die('unable to stat ' . $self->data_dir); + + return (S_IMODE($dir_stat->mode) == 0750); +} + +=pod + +=item $node->data_dir() + +Returns the path to the data directory. postgresql.conf and pg_hba.conf are +always here. + +=cut + +sub data_dir +{ + my ($self) = @_; + my $res = $self->basedir; + return "$res/pgdata"; +} + +=pod + +=item $node->archive_dir() + +If archiving is enabled, WAL files go here. + +=cut + +sub archive_dir +{ + my ($self) = @_; + my $basedir = $self->basedir; + return "$basedir/archives"; +} + +=pod + +=item $node->backup_dir() + +The output path for backups taken with $node->backup() + +=cut + +sub backup_dir +{ + my ($self) = @_; + my $basedir = $self->basedir; + return "$basedir/backup"; +} + +=pod + +=item $node->install_path() + +The configured install path (if any) for the node. + +=cut + +sub install_path +{ + my ($self) = @_; + return $self->{_install_path}; +} + +=pod + +=item $node->pg_version() + +The version number for the node, from PostgreSQL::Version. + +=cut + +sub pg_version +{ + my ($self) = @_; + return $self->{_pg_version}; +} + +=pod + +=item $node->config_data( option ...) + +Return configuration data from pg_config, using options (if supplied). +The options will be things like '--sharedir'. + +If no options are supplied, return a string in scalar context or a map in +array context. + +If options are supplied, return the list of values. + +=cut + +sub config_data +{ + my ($self, @options) = @_; + local %ENV = $self->_get_env(); + + my ($stdout, $stderr); + my $result = + IPC::Run::run [ $self->installed_command('pg_config'), @options ], + '>', \$stdout, '2>', \$stderr + or die "could not execute pg_config"; + # standardize line endings + $stdout =~ s/\r(?=\n)//g; + # no options, scalar context: just hand back the output + return $stdout unless (wantarray || @options); + chomp($stdout); + # exactly one option: hand back the output (minus LF) + return $stdout if (@options == 1); + my @lines = split(/\n/, $stdout); + # more than one option: hand back the list of values; + return @lines if (@options); + # no options, array context: return a map + my @map; + foreach my $line (@lines) + { + my ($k, $v) = split(/ = /, $line, 2); + push(@map, $k, $v); + } + return @map; +} + +=pod + +=item $node->info() + +Return a string containing human-readable diagnostic information (paths, etc) +about this node. + +=cut + +sub info +{ + my ($self) = @_; + my $_info = ''; + open my $fh, '>', \$_info or die; + print $fh "Name: " . $self->name . "\n"; + print $fh "Version: " . $self->{_pg_version} . "\n" + if $self->{_pg_version}; + print $fh "Data directory: " . $self->data_dir . "\n"; + print $fh "Backup directory: " . $self->backup_dir . "\n"; + print $fh "Archive directory: " . $self->archive_dir . "\n"; + print $fh "Connection string: " . $self->connstr . "\n"; + print $fh "Log file: " . $self->logfile . "\n"; + print $fh "Install Path: ", $self->{_install_path} . "\n" + if $self->{_install_path}; + close $fh or die; + return $_info; +} + +=pod + +=item $node->dump_info() + +Print $node->info() + +=cut + +sub dump_info +{ + my ($self) = @_; + print $self->info; + return; +} + + +# Internal method to set up trusted pg_hba.conf for replication. Not +# documented because you shouldn't use it, it's called automatically if needed. +sub set_replication_conf +{ + my ($self) = @_; + my $pgdata = $self->data_dir; + + $self->host eq $test_pghost + or croak "set_replication_conf only works with the default host"; + + open my $hba, '>>', "$pgdata/pg_hba.conf"; + print $hba + "\n# Allow replication (set up by PostgreSQL::Test::Cluster.pm)\n"; + if ($PostgreSQL::Test::Utils::windows_os + && !$PostgreSQL::Test::Utils::use_unix_sockets) + { + print $hba + "host replication all $test_localhost/32 sspi include_realm=1 map=regress\n"; + } + close $hba; + return; +} + +=pod + +=item $node->init(...) + +Initialize a new cluster for testing. + +Authentication is set up so that only the current OS user can access the +cluster. On Unix, we use Unix domain socket connections, with the socket in +a directory that's only accessible to the current user to ensure that. +On Windows, we use SSPI authentication to ensure the same (by pg_regress +--config-auth). + +WAL archiving can be enabled on this node by passing the keyword parameter +has_archiving => 1. This is disabled by default. + +postgresql.conf can be set up for replication by passing the keyword +parameter allows_streaming => 'logical' or 'physical' (passing 1 will also +suffice for physical replication) depending on type of replication that +should be enabled. This is disabled by default. + +The new node is set up in a fast but unsafe configuration where fsync is +disabled. + +=cut + +sub init +{ + my ($self, %params) = @_; + my $port = $self->port; + my $pgdata = $self->data_dir; + my $host = $self->host; + + local %ENV = $self->_get_env(); + + $params{allows_streaming} = 0 unless defined $params{allows_streaming}; + $params{has_archiving} = 0 unless defined $params{has_archiving}; + + mkdir $self->backup_dir; + mkdir $self->archive_dir; + + PostgreSQL::Test::Utils::system_or_bail('initdb', '-D', $pgdata, '-A', + 'trust', '-N', @{ $params{extra} }); + PostgreSQL::Test::Utils::system_or_bail($ENV{PG_REGRESS}, + '--config-auth', $pgdata, @{ $params{auth_extra} }); + + open my $conf, '>>', "$pgdata/postgresql.conf"; + print $conf "\n# Added by PostgreSQL::Test::Cluster.pm\n"; + print $conf "fsync = off\n"; + print $conf "restart_after_crash = off\n"; + print $conf "log_line_prefix = '%m [%p] %q%a '\n"; + print $conf "log_statement = all\n"; + print $conf "log_replication_commands = on\n"; + print $conf "wal_retrieve_retry_interval = '500ms'\n"; + + # If a setting tends to affect whether tests pass or fail, print it after + # TEMP_CONFIG. Otherwise, print it before TEMP_CONFIG, thereby permitting + # overrides. Settings that merely improve performance or ease debugging + # belong before TEMP_CONFIG. + print $conf PostgreSQL::Test::Utils::slurp_file($ENV{TEMP_CONFIG}) + if defined $ENV{TEMP_CONFIG}; + + if ($params{allows_streaming}) + { + if ($params{allows_streaming} eq "logical") + { + print $conf "wal_level = logical\n"; + } + else + { + print $conf "wal_level = replica\n"; + } + print $conf "max_wal_senders = 10\n"; + print $conf "max_replication_slots = 10\n"; + print $conf "wal_log_hints = on\n"; + print $conf "hot_standby = on\n"; + # conservative settings to ensure we can run multiple postmasters: + print $conf "shared_buffers = 1MB\n"; + print $conf "max_connections = 10\n"; + # limit disk space consumption, too: + print $conf "max_wal_size = 128MB\n"; + } + else + { + print $conf "wal_level = minimal\n"; + print $conf "max_wal_senders = 0\n"; + } + + print $conf "port = $port\n"; + if ($use_tcp) + { + print $conf "unix_socket_directories = ''\n"; + print $conf "listen_addresses = '$host'\n"; + } + else + { + print $conf "unix_socket_directories = '$host'\n"; + print $conf "listen_addresses = ''\n"; + } + close $conf; + + chmod($self->group_access ? 0640 : 0600, "$pgdata/postgresql.conf") + or die("unable to set permissions for $pgdata/postgresql.conf"); + + $self->set_replication_conf if $params{allows_streaming}; + $self->enable_archiving if $params{has_archiving}; + return; +} + +=pod + +=item $node->append_conf(filename, str) + +A shortcut method to append to files like pg_hba.conf and postgresql.conf. + +Does no validation or sanity checking. Does not reload the configuration +after writing. + +A newline is automatically appended to the string. + +=cut + +sub append_conf +{ + my ($self, $filename, $str) = @_; + + my $conffile = $self->data_dir . '/' . $filename; + + PostgreSQL::Test::Utils::append_to_file($conffile, $str . "\n"); + + chmod($self->group_access() ? 0640 : 0600, $conffile) + or die("unable to set permissions for $conffile"); + + return; +} + +=pod + +=item $node->adjust_conf(filename, setting, value, skip_equals) + +Modify the named config file setting with the value. If the value is undefined, +instead delete the setting. If the setting is not present no action is taken. + +This will write "$setting = $value\n" in place of the existing line, +unless skip_equals is true, in which case it will write +"$setting $value\n". If the value needs to be quoted it is the caller's +responsibility to do that. + +=cut + +sub adjust_conf +{ + my ($self, $filename, $setting, $value, $skip_equals) = @_; + + my $conffile = $self->data_dir . '/' . $filename; + + my $contents = PostgreSQL::Test::Utils::slurp_file($conffile); + my @lines = split(/\n/, $contents); + my @result; + my $eq = $skip_equals ? '' : '= '; + foreach my $line (@lines) + { + if ($line !~ /^$setting\W/) + { + push(@result, "$line\n"); + } + elsif (defined $value) + { + push(@result, "$setting $eq$value\n"); + } + } + open my $fh, ">", $conffile + or croak "could not write \"$conffile\": $!"; + print $fh @result; + close $fh; + + chmod($self->group_access() ? 0640 : 0600, $conffile) + or die("unable to set permissions for $conffile"); +} + +=pod + +=item $node->backup(backup_name) + +Create a hot backup with B in subdirectory B of +B<< $node->backup_dir >>, including the WAL. + +By default, WAL files are fetched at the end of the backup, not streamed. +You can adjust that and other things by passing an array of additional +B command line options in the keyword parameter backup_options. + +You'll have to configure a suitable B on the +target server since it isn't done by default. + +=cut + +sub backup +{ + my ($self, $backup_name, %params) = @_; + my $backup_path = $self->backup_dir . '/' . $backup_name; + my $name = $self->name; + + local %ENV = $self->_get_env(); + + print "# Taking pg_basebackup $backup_name from node \"$name\"\n"; + PostgreSQL::Test::Utils::system_or_bail( + 'pg_basebackup', '-D', + $backup_path, '-h', + $self->host, '-p', + $self->port, '--checkpoint', + 'fast', '--no-sync', + @{ $params{backup_options} }); + print "# Backup finished\n"; + return; +} + +=item $node->backup_fs_cold(backup_name) + +Create a backup with a filesystem level copy in subdirectory B of +B<< $node->backup_dir >>, including WAL. The server must be +stopped as no attempt to handle concurrent writes is made. + +Use B or B if you want to back up a running server. + +=cut + +sub backup_fs_cold +{ + my ($self, $backup_name) = @_; + + PostgreSQL::Test::RecursiveCopy::copypath( + $self->data_dir, + $self->backup_dir . '/' . $backup_name, + filterfn => sub { + my $src = shift; + return ($src ne 'log' and $src ne 'postmaster.pid'); + }); + + return; +} + +=pod + +=item $node->init_from_backup(root_node, backup_name) + +Initialize a node from a backup, which may come from this node or a different +node. root_node must be a PostgreSQL::Test::Cluster reference, backup_name the string name +of a backup previously created on that node with $node->backup. + +Does not start the node after initializing it. + +By default, the backup is assumed to be plain format. To restore from +a tar-format backup, pass the name of the tar program to use in the +keyword parameter tar_program. Note that tablespace tar files aren't +handled here. + +Streaming replication can be enabled on this node by passing the keyword +parameter has_streaming => 1. This is disabled by default. + +Restoring WAL segments from archives using restore_command can be enabled +by passing the keyword parameter has_restoring => 1. This is disabled by +default. + +If has_restoring is used, standby mode is used by default. To use +recovery mode instead, pass the keyword parameter standby => 0. + +The backup is copied, leaving the original unmodified. pg_hba.conf is +unconditionally set to enable replication connections. + +=cut + +sub init_from_backup +{ + my ($self, $root_node, $backup_name, %params) = @_; + my $backup_path = $root_node->backup_dir . '/' . $backup_name; + my $host = $self->host; + my $port = $self->port; + my $node_name = $self->name; + my $root_name = $root_node->name; + + $params{has_streaming} = 0 unless defined $params{has_streaming}; + $params{has_restoring} = 0 unless defined $params{has_restoring}; + $params{standby} = 1 unless defined $params{standby}; + + print + "# Initializing node \"$node_name\" from backup \"$backup_name\" of node \"$root_name\"\n"; + croak "Backup \"$backup_name\" does not exist at $backup_path" + unless -d $backup_path; + + mkdir $self->backup_dir; + mkdir $self->archive_dir; + + my $data_path = $self->data_dir; + if (defined $params{tar_program}) + { + mkdir($data_path); + PostgreSQL::Test::Utils::system_or_bail($params{tar_program}, 'xf', + $backup_path . '/base.tar', + '-C', $data_path); + PostgreSQL::Test::Utils::system_or_bail( + $params{tar_program}, 'xf', + $backup_path . '/pg_wal.tar', '-C', + $data_path . '/pg_wal'); + } + else + { + rmdir($data_path); + PostgreSQL::Test::RecursiveCopy::copypath($backup_path, $data_path); + } + chmod(0700, $data_path); + + # Base configuration for this node + $self->append_conf( + 'postgresql.conf', + qq( +port = $port +)); + if ($use_tcp) + { + $self->append_conf('postgresql.conf', "listen_addresses = '$host'"); + } + else + { + $self->append_conf('postgresql.conf', + "unix_socket_directories = '$host'"); + } + $self->enable_streaming($root_node) if $params{has_streaming}; + $self->enable_restoring($root_node, $params{standby}) + if $params{has_restoring}; + return; +} + +=pod + +=item $node->rotate_logfile() + +Switch to a new PostgreSQL log file. This does not alter any running +PostgreSQL process. Subsequent method calls, including pg_ctl invocations, +will use the new name. Return the new name. + +=cut + +sub rotate_logfile +{ + my ($self) = @_; + $self->{_logfile} = sprintf('%s_%d.log', + $self->{_logfile_base}, + ++$self->{_logfile_generation}); + return $self->{_logfile}; +} + +=pod + +=item $node->start(%params) => success_or_failure + +Wrapper for pg_ctl start + +Start the node and wait until it is ready to accept connections. + +=over + +=item fail_ok => 1 + +By default, failure terminates the entire F invocation. If given, +instead return a true or false value to indicate success or failure. + +=back + +=cut + +sub start +{ + my ($self, %params) = @_; + my $port = $self->port; + my $pgdata = $self->data_dir; + my $name = $self->name; + my $ret; + + BAIL_OUT("node \"$name\" is already running") if defined $self->{_pid}; + + print("### Starting node \"$name\"\n"); + + # Temporarily unset PGAPPNAME so that the server doesn't + # inherit it. Otherwise this could affect libpqwalreceiver + # connections in confusing ways. + local %ENV = $self->_get_env(PGAPPNAME => undef); + + # Note: We set the cluster_name here, not in postgresql.conf (in + # sub init) so that it does not get copied to standbys. + # -w is now the default but having it here does no harm and helps + # compatibility with older versions. + $ret = PostgreSQL::Test::Utils::system_log( + 'pg_ctl', '-w', '-D', $self->data_dir, + '-l', $self->logfile, '-o', "--cluster-name=$name", + 'start'); + + if ($ret != 0) + { + print "# pg_ctl start failed; logfile:\n"; + print PostgreSQL::Test::Utils::slurp_file($self->logfile); + + # pg_ctl could have timed out, so check to see if there's a pid file; + # otherwise our END block will fail to shut down the new postmaster. + $self->_update_pid(-1); + + BAIL_OUT("pg_ctl start failed") unless $params{fail_ok}; + return 0; + } + + $self->_update_pid(1); + return 1; +} + +=pod + +=item $node->kill9() + +Send SIGKILL (signal 9) to the postmaster. + +Note: if the node is already known stopped, this does nothing. +However, if we think it's running and it's not, it's important for +this to fail. Otherwise, tests might fail to detect server crashes. + +=cut + +sub kill9 +{ + my ($self) = @_; + my $name = $self->name; + return unless defined $self->{_pid}; + + local %ENV = $self->_get_env(); + + print "### Killing node \"$name\" using signal 9\n"; + kill(9, $self->{_pid}); + $self->{_pid} = undef; + return; +} + +=pod + +=item $node->stop(mode) + +Stop the node using pg_ctl -m $mode and wait for it to stop. + +Note: if the node is already known stopped, this does nothing. +However, if we think it's running and it's not, it's important for +this to fail. Otherwise, tests might fail to detect server crashes. + +With optional extra param fail_ok => 1, returns 0 for failure +instead of bailing out. + +=cut + +sub stop +{ + my ($self, $mode, %params) = @_; + my $pgdata = $self->data_dir; + my $name = $self->name; + my $ret; + + local %ENV = $self->_get_env(); + + $mode = 'fast' unless defined $mode; + return 1 unless defined $self->{_pid}; + + print "### Stopping node \"$name\" using mode $mode\n"; + $ret = PostgreSQL::Test::Utils::system_log('pg_ctl', '-D', $pgdata, + '-m', $mode, 'stop'); + + if ($ret != 0) + { + print "# pg_ctl stop failed: $ret\n"; + + # Check to see if we still have a postmaster or not. + $self->_update_pid(-1); + + BAIL_OUT("pg_ctl stop failed") unless $params{fail_ok}; + return 0; + } + + $self->_update_pid(0); + return 1; +} + +=pod + +=item $node->reload() + +Reload configuration parameters on the node. + +=cut + +sub reload +{ + my ($self) = @_; + my $port = $self->port; + my $pgdata = $self->data_dir; + my $name = $self->name; + + local %ENV = $self->_get_env(); + + print "### Reloading node \"$name\"\n"; + PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, + 'reload'); + return; +} + +=pod + +=item $node->restart() + +Wrapper for pg_ctl restart + +=cut + +sub restart +{ + my ($self) = @_; + my $port = $self->port; + my $pgdata = $self->data_dir; + my $logfile = $self->logfile; + my $name = $self->name; + + local %ENV = $self->_get_env(PGAPPNAME => undef); + + print "### Restarting node \"$name\"\n"; + + # -w is now the default but having it here does no harm and helps + # compatibility with older versions. + PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-w', '-D', $pgdata, + '-l', $logfile, 'restart'); + + $self->_update_pid(1); + return; +} + +=pod + +=item $node->promote() + +Wrapper for pg_ctl promote + +=cut + +sub promote +{ + my ($self) = @_; + my $port = $self->port; + my $pgdata = $self->data_dir; + my $logfile = $self->logfile; + my $name = $self->name; + + local %ENV = $self->_get_env(); + + print "### Promoting node \"$name\"\n"; + PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-l', + $logfile, 'promote'); + return; +} + +=pod + +=item $node->logrotate() + +Wrapper for pg_ctl logrotate + +=cut + +sub logrotate +{ + my ($self) = @_; + my $port = $self->port; + my $pgdata = $self->data_dir; + my $logfile = $self->logfile; + my $name = $self->name; + + local %ENV = $self->_get_env(); + + print "### Rotating log in node \"$name\"\n"; + PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-l', + $logfile, 'logrotate'); + return; +} + +# Internal routine to enable streaming replication on a standby node. +sub enable_streaming +{ + my ($self, $root_node) = @_; + my $root_connstr = $root_node->connstr; + my $name = $self->name; + + print "### Enabling streaming replication for node \"$name\"\n"; + $self->append_conf( + $self->_recovery_file, qq( +primary_conninfo='$root_connstr' +)); + $self->set_standby_mode(); + return; +} + +# Internal routine to enable archive recovery command on a standby node +sub enable_restoring +{ + my ($self, $root_node, $standby) = @_; + my $path = $root_node->archive_dir; + my $name = $self->name; + + print "### Enabling WAL restore for node \"$name\"\n"; + + # On Windows, the path specified in the restore command needs to use + # double back-slashes to work properly and to be able to detect properly + # the file targeted by the copy command, so the directory value used + # in this routine, using only one back-slash, need to be properly changed + # first. Paths also need to be double-quoted to prevent failures where + # the path contains spaces. + $path =~ s{\\}{\\\\}g if ($PostgreSQL::Test::Utils::windows_os); + my $copy_command = + $PostgreSQL::Test::Utils::windows_os + ? qq{copy "$path\\\\%f" "%p"} + : qq{cp "$path/%f" "%p"}; + + $self->append_conf( + $self->_recovery_file, qq( +restore_command = '$copy_command' +)); + if ($standby) + { + $self->set_standby_mode(); + } + else + { + $self->set_recovery_mode(); + } + return; +} + +sub _recovery_file { return "postgresql.conf"; } + +=pod + +=item $node->set_recovery_mode() + +Place recovery.signal file. + +=cut + +sub set_recovery_mode +{ + my ($self) = @_; + + $self->append_conf('recovery.signal', ''); + return; +} + +=pod + +=item $node->set_standby_mode() + +Place standby.signal file. + +=cut + +sub set_standby_mode +{ + my ($self) = @_; + + $self->append_conf('standby.signal', ''); + return; +} + +# Internal routine to enable archiving +sub enable_archiving +{ + my ($self) = @_; + my $path = $self->archive_dir; + my $name = $self->name; + + print "### Enabling WAL archiving for node \"$name\"\n"; + + # On Windows, the path specified in the restore command needs to use + # double back-slashes to work properly and to be able to detect properly + # the file targeted by the copy command, so the directory value used + # in this routine, using only one back-slash, need to be properly changed + # first. Paths also need to be double-quoted to prevent failures where + # the path contains spaces. + $path =~ s{\\}{\\\\}g if ($PostgreSQL::Test::Utils::windows_os); + my $copy_command = + $PostgreSQL::Test::Utils::windows_os + ? qq{copy "%p" "$path\\\\%f"} + : qq{cp "%p" "$path/%f"}; + + # Enable archive_mode and archive_command on node + $self->append_conf( + 'postgresql.conf', qq( +archive_mode = on +archive_command = '$copy_command' +)); + return; +} + +# Internal method to update $self->{_pid} +# $is_running = 1: pid file should be there +# $is_running = 0: pid file should NOT be there +# $is_running = -1: we aren't sure +sub _update_pid +{ + my ($self, $is_running) = @_; + my $name = $self->name; + + # If we can open the PID file, read its first line and that's the PID we + # want. + if (open my $pidfile, '<', $self->data_dir . "/postmaster.pid") + { + chomp($self->{_pid} = <$pidfile>); + close $pidfile; + + # If we aren't sure what to expect, validate the PID using kill(). + # This protects against stale PID files left by crashed postmasters. + if ($is_running == -1 && kill(0, $self->{_pid}) == 0) + { + print + "# Stale postmaster.pid file for node \"$name\": PID $self->{_pid} no longer exists\n"; + $self->{_pid} = undef; + return; + } + + print "# Postmaster PID for node \"$name\" is $self->{_pid}\n"; + + # If we found a pidfile when there shouldn't be one, complain. + BAIL_OUT("postmaster.pid unexpectedly present") if $is_running == 0; + return; + } + + $self->{_pid} = undef; + print "# No postmaster PID for node \"$name\"\n"; + + # Complain if we expected to find a pidfile. + BAIL_OUT("postmaster.pid unexpectedly not present") if $is_running == 1; + return; +} + +=pod + +=item PostgreSQL::Test::Cluster->new(node_name, %params) + +Build a new object of class C (or of a subclass, if you have +one), assigning a free port number. Remembers the node, to prevent its port +number from being reused for another node, and to ensure that it gets +shut down when the test script exits. + +=over + +=item port => [1,65535] + +By default, this function assigns a port number to each node. Specify this to +force a particular port number. The caller is responsible for evaluating +potential conflicts and privilege requirements. + +=item own_host => 1 + +By default, all nodes use the same PGHOST value. If specified, generate a +PGHOST specific to this node. This allows multiple nodes to use the same +port. + +=item install_path => '/path/to/postgres/installation' + +Using this parameter is it possible to have nodes pointing to different +installations, for testing different versions together or the same version +with different build parameters. The provided path must be the parent of the +installation's 'bin' and 'lib' directories. In the common case where this is +not provided, Postgres binaries will be found in the caller's PATH. + +=back + +=cut + +sub new +{ + my $class = shift; + my ($name, %params) = @_; + + # Select a port. + my $port; + if (defined $params{port}) + { + $port = $params{port}; + } + else + { + # When selecting a port, we look for an unassigned TCP port number, + # even if we intend to use only Unix-domain sockets. This is clearly + # necessary on $use_tcp (Windows) configurations, and it seems like a + # good idea on Unixen as well. + $port = get_free_port(); + } + + # Select a host. + my $host = $test_pghost; + if ($params{own_host}) + { + if ($use_tcp) + { + $last_host_assigned++; + $last_host_assigned > 254 and BAIL_OUT("too many own_host nodes"); + $host = '127.0.0.' . $last_host_assigned; + } + else + { + $host = "$test_pghost/$name"; # Assume $name =~ /^[-_a-zA-Z0-9]+$/ + mkdir $host; + } + } + + my $testname = basename($0); + $testname =~ s/\.[^.]+$//; + my $node = { + _port => $port, + _host => $host, + _basedir => + "$PostgreSQL::Test::Utils::tmp_check/t_${testname}_${name}_data", + _name => $name, + _logfile_generation => 0, + _logfile_base => + "$PostgreSQL::Test::Utils::log_path/${testname}_${name}", + _logfile => + "$PostgreSQL::Test::Utils::log_path/${testname}_${name}.log" + }; + + if ($params{install_path}) + { + $node->{_install_path} = $params{install_path}; + } + + bless $node, $class; + mkdir $node->{_basedir} + or + BAIL_OUT("could not create data directory \"$node->{_basedir}\": $!"); + + $node->_set_pg_version; + + $node->dump_info; + + my $ver = $node->{_pg_version}; + + # Use a subclass as defined below (or elsewhere) if this version + # isn't fully compatible. Warn if the version is too old and thus we don't + # have a subclass of this class. + if (ref $ver && $ver < $min_compat) + { + my $maj = $ver->major(separator => '_'); + my $subclass = $class . "::V_$maj"; + if ($subclass->isa($class)) + { + bless $node, $subclass; + } + else + { + carp + "PostgreSQL::Test::Cluster isn't fully compatible with version $ver"; + } + } + + # Add node to list of nodes + push(@all_nodes, $node); + + return $node; +} + +# Private routine to run the pg_config binary found in our environment (or in +# our install_path, if we have one), and set the version from it +# +sub _set_pg_version +{ + my ($self) = @_; + my $inst = $self->{_install_path}; + my $pg_config = "pg_config"; + + if (defined $inst) + { + # If the _install_path is invalid, our PATH variables might find an + # unrelated pg_config executable elsewhere. Sanity check the + # directory. + BAIL_OUT("directory not found: $inst") + unless -d $inst; + + # If the directory exists but is not the root of a postgresql + # installation, or if the user configured using + # --bindir=$SOMEWHERE_ELSE, we're not going to find pg_config, so + # complain about that, too. + $pg_config = "$inst/bin/pg_config"; + BAIL_OUT("pg_config not found: $pg_config") + unless -e $pg_config + or ($PostgreSQL::Test::Utils::windows_os and -e "$pg_config.exe"); + BAIL_OUT("pg_config not executable: $pg_config") + unless $PostgreSQL::Test::Utils::windows_os or -x $pg_config; + + # Leave $pg_config install_path qualified, to be sure we get the right + # version information, below, or die trying + } + + local %ENV = $self->_get_env(); + + # We only want the version field + my $version_line = qx{$pg_config --version}; + BAIL_OUT("$pg_config failed: $!") if $?; + + $self->{_pg_version} = PostgreSQL::Version->new($version_line); + + BAIL_OUT("could not parse pg_config --version output: $version_line") + unless defined $self->{_pg_version}; +} + +# Private routine to return a copy of the environment with the PATH and +# (DY)LD_LIBRARY_PATH correctly set when there is an install path set for +# the node. +# +# Routines that call Postgres binaries need to call this routine like this: +# +# local %ENV = $self->_get_env([%extra_settings]); +# +# A copy of the environment is taken and node's host and port settings are +# added as PGHOST and PGPORT, then the extra settings (if any) are applied. +# Any setting in %extra_settings with a value that is undefined is deleted; +# the remainder are set. Then the PATH and (DY)LD_LIBRARY_PATH are adjusted +# if the node's install path is set, and the copy environment is returned. +# +# The install path set in new() needs to be a directory containing +# bin and lib subdirectories as in a standard PostgreSQL installation, so this +# can't be used with installations where the bin and lib directories don't have +# a common parent directory. +sub _get_env +{ + my $self = shift; + my %inst_env = (%ENV, PGHOST => $self->{_host}, PGPORT => $self->{_port}); + # the remaining arguments are modifications to make to the environment + my %mods = (@_); + while (my ($k, $v) = each %mods) + { + if (defined $v) + { + $inst_env{$k} = "$v"; + } + else + { + delete $inst_env{$k}; + } + } + # now fix up the new environment for the install path + my $inst = $self->{_install_path}; + if ($inst) + { + if ($PostgreSQL::Test::Utils::windows_os) + { + # Windows picks up DLLs from the PATH rather than *LD_LIBRARY_PATH + # choose the right path separator + if ($Config{osname} eq 'MSWin32') + { + $inst_env{PATH} = "$inst/bin;$inst/lib;$ENV{PATH}"; + } + else + { + $inst_env{PATH} = "$inst/bin:$inst/lib:$ENV{PATH}"; + } + } + else + { + my $dylib_name = + $Config{osname} eq 'darwin' + ? "DYLD_LIBRARY_PATH" + : "LD_LIBRARY_PATH"; + $inst_env{PATH} = "$inst/bin:$ENV{PATH}"; + if (exists $ENV{$dylib_name}) + { + $inst_env{$dylib_name} = "$inst/lib:$ENV{$dylib_name}"; + } + else + { + $inst_env{$dylib_name} = "$inst/lib"; + } + } + } + return (%inst_env); +} + +# Private routine to get an installation path qualified command. +# +# IPC::Run maintains a cache, %cmd_cache, mapping commands to paths. Tests +# which use nodes spanning more than one postgres installation path need to +# avoid confusing which installation's binaries get run. Setting $ENV{PATH} is +# insufficient, as IPC::Run does not check to see if the path has changed since +# caching a command. +sub installed_command +{ + my ($self, $cmd) = @_; + + # Nodes using alternate installation locations use their installation's + # bin/ directory explicitly + return join('/', $self->{_install_path}, 'bin', $cmd) + if defined $self->{_install_path}; + + # Nodes implicitly using the default installation location rely on IPC::Run + # to find the right binary, which should not cause %cmd_cache confusion, + # because no nodes with other installation paths do it that way. + return $cmd; +} + +=pod + +=item get_free_port() + +Locate an unprivileged (high) TCP port that's not currently bound to +anything. This is used by C, and also by some test cases that need to +start other, non-Postgres servers. + +Ports assigned to existing PostgreSQL::Test::Cluster objects are automatically +excluded, even if those servers are not currently running. + +The port number is reserved so that other concurrent test programs will not +try to use the same port. + +Note: this is not an instance method. As it's not exported it should be +called from outside the module as C. + +=cut + +sub get_free_port +{ + my $found = 0; + my $port = $last_port_assigned; + + while ($found == 0) + { + + # advance $port, wrapping correctly around range end + $port = $port_lower_bound if ++$port > $port_upper_bound; + print "# Checking port $port\n"; + + # Check first that candidate port number is not included in + # the list of already-registered nodes. + $found = 1; + foreach my $node (@all_nodes) + { + $found = 0 if ($node->port == $port); + } + + # Check to see if anything else is listening on this TCP port. + # Seek a port available for all possible listen_addresses values, + # so callers can harness this port for the widest range of purposes. + # The 0.0.0.0 test achieves that for MSYS, which automatically sets + # SO_EXCLUSIVEADDRUSE. Testing 0.0.0.0 is insufficient for Windows + # native Perl (https://stackoverflow.com/a/14388707), so we also + # have to test individual addresses. Doing that for 127.0.0/24 + # addresses other than 127.0.0.1 might fail with EADDRNOTAVAIL on + # non-Linux, non-Windows kernels. + # + # Thus, 0.0.0.0 and individual 127.0.0/24 addresses are tested + # only on Windows and only when TCP usage is requested. + if ($found == 1) + { + foreach my $addr (qw(127.0.0.1), + ($use_tcp && $PostgreSQL::Test::Utils::windows_os) + ? qw(127.0.0.2 127.0.0.3 0.0.0.0) + : ()) + { + if (!can_bind($addr, $port)) + { + $found = 0; + last; + } + } + $found = _reserve_port($port) if $found; + } + } + + print "# Found port $port\n"; + + # Update port for next time + $last_port_assigned = $port; + + return $port; +} + +# Internal routine to check whether a host:port is available to bind +sub can_bind +{ + my ($host, $port) = @_; + my $iaddr = inet_aton($host); + my $paddr = sockaddr_in($port, $iaddr); + my $proto = getprotobyname("tcp"); + + socket(SOCK, PF_INET, SOCK_STREAM, $proto) + or die "socket failed: $!"; + + # As in postmaster, don't use SO_REUSEADDR on Windows + setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) + unless $PostgreSQL::Test::Utils::windows_os; + my $ret = bind(SOCK, $paddr) && listen(SOCK, SOMAXCONN); + close(SOCK); + return $ret; +} + +# Internal routine to reserve a port number +# Returns 1 if successful, 0 if port is already reserved. +sub _reserve_port +{ + my $port = shift; + # open in rw mode so we don't have to reopen it and lose the lock + my $filename = "$portdir/$port.rsv"; + sysopen(my $portfile, $filename, O_RDWR | O_CREAT) + || die "opening port file $filename: $!"; + # take an exclusive lock to avoid concurrent access + flock($portfile, LOCK_EX) || die "locking port file $filename: $!"; + # see if someone else has or had a reservation of this port + my $pid = <$portfile> || "0"; + chomp $pid; + if ($pid + 0 > 0) + { + if (kill 0, $pid) + { + # process exists and is owned by us, so we can't reserve this port + flock($portfile, LOCK_UN); + close($portfile); + return 0; + } + } + # All good, go ahead and reserve the port + seek($portfile, 0, SEEK_SET); + # print the pid with a fixed width so we don't leave any trailing junk + print $portfile sprintf("%10d\n", $$); + flock($portfile, LOCK_UN); + close($portfile); + push(@port_reservation_files, $filename); + return 1; +} + +# Automatically shut down any still-running nodes (in the same order the nodes +# were created in) when the test script exits. +END +{ + + # take care not to change the script's exit value + my $exit_code = $?; + + foreach my $node (@all_nodes) + { + # During unclean termination (which could be a signal or some + # other failure), we're not sure that the status of our nodes + # has been correctly set up already, so try and update it to + # improve our chances of shutting them down. + $node->_update_pid(-1) if $exit_code != 0; + + # If that fails, don't let that foil other nodes' shutdown + $node->teardown_node(fail_ok => 1); + + # skip clean if we are requested to retain the basedir + next if defined $ENV{'PG_TEST_NOCLEAN'}; + + # clean basedir on clean test invocation + $node->clean_node + if $exit_code == 0 && PostgreSQL::Test::Utils::all_tests_passing(); + } + + unlink @port_reservation_files; + + $? = $exit_code; +} + +=pod + +=item $node->teardown_node() + +Do an immediate stop of the node + +Any optional extra parameter is passed to ->stop. + +=cut + +sub teardown_node +{ + my ($self, %params) = @_; + + $self->stop('immediate', %params); + return; +} + +=pod + +=item $node->clean_node() + +Remove the base directory of the node if the node has been stopped. + +=cut + +sub clean_node +{ + my $self = shift; + + rmtree $self->{_basedir} unless defined $self->{_pid}; + return; +} + +=pod + +=item $node->safe_psql($dbname, $sql) => stdout + +Invoke B to run B on B and return its stdout on success. +Die if the SQL produces an error. Runs with B set. + +Takes optional extra params like timeout and timed_out parameters with the same +options as psql. + +=cut + +sub safe_psql +{ + my ($self, $dbname, $sql, %params) = @_; + + local %ENV = $self->_get_env(); + + my ($stdout, $stderr); + + my $ret = $self->psql( + $dbname, $sql, + %params, + stdout => \$stdout, + stderr => \$stderr, + on_error_die => 1, + on_error_stop => 1); + + # psql can emit stderr from NOTICEs etc + if ($stderr ne "") + { + print "#### Begin standard error\n"; + print $stderr; + print "\n#### End standard error\n"; + } + + return $stdout; +} + +=pod + +=item $node->psql($dbname, $sql, %params) => psql_retval + +Invoke B to execute B<$sql> on B<$dbname> and return the return value +from B, which is run with on_error_stop by default so that it will +stop running sql and return 3 if the passed SQL results in an error. + +As a convenience, if B is called in array context it returns an +array containing ($retval, $stdout, $stderr). + +psql is invoked in tuples-only unaligned mode with reading of B<.psqlrc> +disabled. That may be overridden by passing extra psql parameters. + +stdout and stderr are transformed to UNIX line endings if on Windows. Any +trailing newline is removed. + +Dies on failure to invoke psql but not if psql exits with a nonzero +return code (unless on_error_die specified). + +If psql exits because of a signal, an exception is raised. + +=over + +=item stdout => \$stdout + +B, if given, must be a scalar reference to which standard output is +written. If not given, standard output is not redirected and will be printed +unless B is called in array context, in which case it's captured and +returned. + +=item stderr => \$stderr + +Same as B but gets standard error. If the same scalar is passed for +both B and B the results may be interleaved unpredictably. + +=item on_error_stop => 1 + +By default, the B method invokes the B program with ON_ERROR_STOP=1 +set, so SQL execution is stopped at the first error and exit code 3 is +returned. Set B to 0 to ignore errors instead. + +=item on_error_die => 0 + +By default, this method returns psql's result code. Pass on_error_die to +instead die with an informative message. + +=item timeout => 'interval' + +Set a timeout for the psql call as an interval accepted by B +(integer seconds is fine). This method raises an exception on timeout, unless +the B parameter is also given. + +=item timed_out => \$timed_out + +If B is set and this parameter is given, the scalar it references +is set to true if the psql call times out. + +=item connstr => B + +If set, use this as the connection string for the connection to the +backend. + +=item replication => B + +If set, add B to the conninfo string. +Passing the literal value C results in a logical replication +connection. + +=item extra_params => ['--single-transaction'] + +If given, it must be an array reference containing additional parameters to B. + +=back + +e.g. + + my ($stdout, $stderr, $timed_out); + my $cmdret = $node->psql('postgres', 'SELECT pg_sleep(600)', + stdout => \$stdout, stderr => \$stderr, + timeout => $PostgreSQL::Test::Utils::timeout_default, + timed_out => \$timed_out, + extra_params => ['--single-transaction']) + +will set $cmdret to undef and $timed_out to a true value. + + $node->psql('postgres', $sql, on_error_die => 1); + +dies with an informative message if $sql fails. + +=cut + +sub psql +{ + my ($self, $dbname, $sql, %params) = @_; + + local %ENV = $self->_get_env(); + + my $stdout = $params{stdout}; + my $stderr = $params{stderr}; + my $replication = $params{replication}; + my $timeout = undef; + my $timeout_exception = 'psql timed out'; + + # Build the connection string. + my $psql_connstr; + if (defined $params{connstr}) + { + $psql_connstr = $params{connstr}; + } + else + { + $psql_connstr = $self->connstr($dbname); + } + $psql_connstr .= defined $replication ? " replication=$replication" : ""; + + my @psql_params = ( + $self->installed_command('psql'), + '-XAtq', '-d', $psql_connstr, '-f', '-'); + + # If the caller wants an array and hasn't passed stdout/stderr + # references, allocate temporary ones to capture them so we + # can return them. Otherwise we won't redirect them at all. + if (wantarray) + { + if (!defined($stdout)) + { + my $temp_stdout = ""; + $stdout = \$temp_stdout; + } + if (!defined($stderr)) + { + my $temp_stderr = ""; + $stderr = \$temp_stderr; + } + } + + $params{on_error_stop} = 1 unless defined $params{on_error_stop}; + $params{on_error_die} = 0 unless defined $params{on_error_die}; + + push @psql_params, '-v', 'ON_ERROR_STOP=1' if $params{on_error_stop}; + push @psql_params, @{ $params{extra_params} } + if defined $params{extra_params}; + + $timeout = + IPC::Run::timeout($params{timeout}, exception => $timeout_exception) + if (defined($params{timeout})); + + ${ $params{timed_out} } = 0 if defined $params{timed_out}; + + # IPC::Run would otherwise append to existing contents: + $$stdout = "" if ref($stdout); + $$stderr = "" if ref($stderr); + + my $ret; + + # Run psql and capture any possible exceptions. If the exception is + # because of a timeout and the caller requested to handle that, just return + # and set the flag. Otherwise, and for any other exception, rethrow. + # + # For background, see + # https://metacpan.org/release/ETHER/Try-Tiny-0.24/view/lib/Try/Tiny.pm + do + { + local $@; + eval { + my @ipcrun_opts = (\@psql_params, '<', \$sql); + push @ipcrun_opts, '>', $stdout if defined $stdout; + push @ipcrun_opts, '2>', $stderr if defined $stderr; + push @ipcrun_opts, $timeout if defined $timeout; + + IPC::Run::run @ipcrun_opts; + $ret = $?; + }; + my $exc_save = $@; + if ($exc_save) + { + + # IPC::Run::run threw an exception. re-throw unless it's a + # timeout, which we'll handle by testing is_expired + die $exc_save + if (blessed($exc_save) + || $exc_save !~ /^\Q$timeout_exception\E/); + + $ret = undef; + + die "Got timeout exception '$exc_save' but timer not expired?!" + unless $timeout->is_expired; + + if (defined($params{timed_out})) + { + ${ $params{timed_out} } = 1; + } + else + { + die "psql timed out: stderr: '$$stderr'\n" + . "while running '@psql_params'"; + } + } + }; + + if (defined $$stdout) + { + chomp $$stdout; + } + + if (defined $$stderr) + { + chomp $$stderr; + } + + # See http://perldoc.perl.org/perlvar.html#%24CHILD_ERROR + # We don't use IPC::Run::Simple to limit dependencies. + # + # We always die on signal. + my $core = $ret & 128 ? " (core dumped)" : ""; + die "psql exited with signal " + . ($ret & 127) + . "$core: '$$stderr' while running '@psql_params'" + if $ret & 127; + $ret = $ret >> 8; + + if ($ret && $params{on_error_die}) + { + die "psql error: stderr: '$$stderr'\nwhile running '@psql_params'" + if $ret == 1; + die "connection error: '$$stderr'\nwhile running '@psql_params'" + if $ret == 2; + die + "error running SQL: '$$stderr'\nwhile running '@psql_params' with sql '$sql'" + if $ret == 3; + die "psql returns $ret: '$$stderr'\nwhile running '@psql_params'"; + } + + if (wantarray) + { + return ($ret, $$stdout, $$stderr); + } + else + { + return $ret; + } +} + +=pod + +=item $node->background_psql($dbname, %params) => PostgreSQL::Test::BackgroundPsql instance + +Invoke B on B<$dbname> and return a BackgroundPsql object. + +psql is invoked in tuples-only unaligned mode with reading of B<.psqlrc> +disabled. That may be overridden by passing extra psql parameters. + +Dies on failure to invoke psql, or if psql fails to connect. Errors occurring +later are the caller's problem. psql runs with on_error_stop by default so +that it will stop running sql and return 3 if passed SQL results in an error. + +Be sure to "quit" the returned object when done with it. + +=over + +=item on_error_stop => 1 + +By default, the B method invokes the B program with ON_ERROR_STOP=1 +set, so SQL execution is stopped at the first error and exit code 3 is +returned. Set B to 0 to ignore errors instead. + +=item timeout => 'interval' + +Set a timeout for a background psql session. By default, timeout of +$PostgreSQL::Test::Utils::timeout_default is set up. + +=item replication => B + +If set, add B to the conninfo string. +Passing the literal value C results in a logical replication +connection. + +=item extra_params => ['--single-transaction'] + +If given, it must be an array reference containing additional parameters to B. + +=item wait => 1 + +By default, this method will not return until connection has completed (or +failed). Set B to 0 to return immediately instead. (Clients can call the +session's C method manually when needed.) + +=back + +=cut + +sub background_psql +{ + my ($self, $dbname, %params) = @_; + + local %ENV = $self->_get_env(); + + my $replication = $params{replication}; + my $timeout = undef; + + my @psql_params = ( + $self->installed_command('psql'), + '-XAtq', + '-d', + $self->connstr($dbname) + . (defined $replication ? " replication=$replication" : ""), + '-f', + '-'); + + $params{on_error_stop} = 1 unless defined $params{on_error_stop}; + $params{wait} = 1 unless defined $params{wait}; + $timeout = $params{timeout} if defined $params{timeout}; + + push @psql_params, '-v', 'ON_ERROR_STOP=1' if $params{on_error_stop}; + push @psql_params, @{ $params{extra_params} } + if defined $params{extra_params}; + + return PostgreSQL::Test::BackgroundPsql->new(0, \@psql_params, $timeout, + $params{wait}); +} + +=pod + +=item $node->interactive_psql($dbname, %params) => BackgroundPsql instance + +Invoke B on B<$dbname> and return a BackgroundPsql object, which the +caller may use to send interactive input to B. + +A timeout of $PostgreSQL::Test::Utils::timeout_default is set up. + +psql is invoked in tuples-only unaligned mode with reading of B<.psqlrc> +disabled. That may be overridden by passing extra psql parameters. + +Dies on failure to invoke psql, or if psql fails to connect. +Errors occurring later are the caller's problem. + +Be sure to "quit" the returned object when done with it. + +=over + +=item extra_params => ['--single-transaction'] + +If given, it must be an array reference containing additional parameters to B. + +=item history_file => B + +Cause the interactive B session to write its command history to B. +If not given, the history is sent to B. + +=back + +This requires IO::Pty in addition to IPC::Run. + +=cut + +sub interactive_psql +{ + my ($self, $dbname, %params) = @_; + + local %ENV = $self->_get_env(); + + # Since the invoked psql will believe it's interactive, it will use + # readline/libedit if available. We need to adjust some environment + # settings to prevent unwanted side-effects. + + # Developers would not appreciate tests adding a bunch of junk to + # their ~/.psql_history, so redirect readline history somewhere else. + # If the calling script doesn't specify anything, just bit-bucket it. + $ENV{PSQL_HISTORY} = $params{history_file} || '/dev/null'; + + # Another pitfall for developers is that they might have a ~/.inputrc + # file that changes readline's behavior enough to affect the test. + # So ignore any such file. + $ENV{INPUTRC} = '/dev/null'; + + # Unset TERM so that readline/libedit won't use any terminal-dependent + # escape sequences; that leads to way too many cross-version variations + # in the output. + delete $ENV{TERM}; + # Some versions of readline inspect LS_COLORS, so for luck unset that too. + delete $ENV{LS_COLORS}; + + my @psql_params = ( + $self->installed_command('psql'), + '-XAt', '-d', $self->connstr($dbname)); + + push @psql_params, @{ $params{extra_params} } + if defined $params{extra_params}; + + return PostgreSQL::Test::BackgroundPsql->new(1, \@psql_params); +} + +# Common sub of pgbench-invoking interfaces. Makes any requested script files +# and returns pgbench command-line options causing use of those files. +sub _pgbench_make_files +{ + my ($self, $files) = @_; + my @file_opts; + + if (defined $files) + { + + # note: files are ordered for determinism + for my $fn (sort keys %$files) + { + my $filename = $self->basedir . '/' . $fn; + push @file_opts, '-f', $filename; + + # cleanup file weight + $filename =~ s/\@\d+$//; + + #push @filenames, $filename; + # filenames are expected to be unique on a test + if (-e $filename) + { + ok(0, "$filename must not already exist"); + unlink $filename or die "cannot unlink $filename: $!"; + } + PostgreSQL::Test::Utils::append_to_file($filename, $$files{$fn}); + } + } + + return @file_opts; +} + +=pod + +=item $node->pgbench($opts, $stat, $out, $err, $name, $files, @args) + +Invoke B, with parameters and files. + +=over + +=item $opts + +Options as a string to be split on spaces. + +=item $stat + +Expected exit status. + +=item $out + +Reference to a regexp list that must match stdout. + +=item $err + +Reference to a regexp list that must match stderr. + +=item $name + +Name of test for error messages. + +=item $files + +Reference to filename/contents dictionary. + +=item @args + +Further raw options or arguments. + +=back + +=cut + +sub pgbench +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my ($self, $opts, $stat, $out, $err, $name, $files, @args) = @_; + my @cmd = ( + 'pgbench', + split(/\s+/, $opts), + $self->_pgbench_make_files($files), @args); + + $self->command_checks_all(\@cmd, $stat, $out, $err, $name); +} + +=pod + +=item $node->connect_ok($connstr, $test_name, %params) + +Attempt a connection with a custom connection string. This is expected +to succeed. + +=over + +=item sql => B + +If this parameter is set, this query is used for the connection attempt +instead of the default. + +=item expected_stdout => B + +If this regular expression is set, matches it with the output generated. + +=item log_like => [ qr/required message/ ] + +=item log_unlike => [ qr/prohibited message/ ] + +See C. + +=back + +=cut + +sub connect_ok +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($self, $connstr, $test_name, %params) = @_; + + my $sql; + if (defined($params{sql})) + { + $sql = $params{sql}; + } + else + { + $sql = "SELECT \$\$connected with $connstr\$\$"; + } + + my $log_location = -s $self->logfile; + + # Never prompt for a password, any callers of this routine should + # have set up things properly, and this should not block. + my ($ret, $stdout, $stderr) = $self->psql( + 'postgres', + $sql, + extra_params => ['-w'], + connstr => "$connstr", + on_error_stop => 0); + + is($ret, 0, $test_name); + + if (defined($params{expected_stdout})) + { + like($stdout, $params{expected_stdout}, "$test_name: stdout matches"); + } + + is($stderr, "", "$test_name: no stderr"); + + $self->log_check($test_name, $log_location, %params); +} + +=pod + +=item $node->connect_fails($connstr, $test_name, %params) + +Attempt a connection with a custom connection string. This is expected +to fail. + +=over + +=item expected_stderr => B + +If this regular expression is set, matches it with the output generated. + +=item log_like => [ qr/required message/ ] + +=item log_unlike => [ qr/prohibited message/ ] + +See C. + +=back + +=cut + +sub connect_fails +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($self, $connstr, $test_name, %params) = @_; + + my $log_location = -s $self->logfile; + + # Never prompt for a password, any callers of this routine should + # have set up things properly, and this should not block. + my ($ret, $stdout, $stderr) = $self->psql( + 'postgres', + undef, + extra_params => ['-w'], + connstr => "$connstr"); + + isnt($ret, 0, $test_name); + + if (defined($params{expected_stderr})) + { + like($stderr, $params{expected_stderr}, "$test_name: matches"); + } + + $self->log_check($test_name, $log_location, %params); +} + +=pod + +=item $node->poll_query_until($dbname, $query [, $expected ]) + +Run B<$query> repeatedly, until it returns the B<$expected> result +('t', or SQL boolean true, by default). +Continues polling if B returns an error result. +Times out after $PostgreSQL::Test::Utils::timeout_default seconds. +Returns 1 if successful, 0 if timed out. + +=cut + +sub poll_query_until +{ + my ($self, $dbname, $query, $expected) = @_; + + local %ENV = $self->_get_env(); + + $expected = 't' unless defined($expected); # default value + + my $cmd = [ + $self->installed_command('psql'), '-XAt', + '-d', $self->connstr($dbname) + ]; + my ($stdout, $stderr); + my $max_attempts = 10 * $PostgreSQL::Test::Utils::timeout_default; + my $attempts = 0; + + while ($attempts < $max_attempts) + { + my $result = IPC::Run::run $cmd, '<', \$query, + '>', \$stdout, '2>', \$stderr; + + chomp($stdout); + chomp($stderr); + + if ($stdout eq $expected && $stderr eq '') + { + return 1; + } + + # Wait 0.1 second before retrying. + usleep(100_000); + + $attempts++; + } + + # Give up. Print the output from the last attempt, hopefully that's useful + # for debugging. + diag qq(poll_query_until timed out executing this query: +$query +expecting this output: +$expected +last actual query output: +$stdout +with stderr: +$stderr); + return 0; +} + +=pod + +=item $node->command_ok(...) + +Runs a shell command like PostgreSQL::Test::Utils::command_ok, but with PGHOST and PGPORT set +so that the command will default to connecting to this PostgreSQL::Test::Cluster. + +=cut + +sub command_ok +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my $self = shift; + + local %ENV = $self->_get_env(); + + PostgreSQL::Test::Utils::command_ok(@_); + return; +} + +=pod + +=item $node->command_fails(...) + +PostgreSQL::Test::Utils::command_fails with our connection parameters. See command_ok(...) + +=cut + +sub command_fails +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my $self = shift; + + local %ENV = $self->_get_env(); + + PostgreSQL::Test::Utils::command_fails(@_); + return; +} + +=pod + +=item $node->command_like(...) + +PostgreSQL::Test::Utils::command_like with our connection parameters. See command_ok(...) + +=cut + +sub command_like +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my $self = shift; + + local %ENV = $self->_get_env(); + + PostgreSQL::Test::Utils::command_like(@_); + return; +} + +=pod + +=item $node->command_fails_like(...) + +PostgreSQL::Test::Utils::command_fails_like with our connection parameters. See command_ok(...) + +=cut + +sub command_fails_like +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my $self = shift; + + local %ENV = $self->_get_env(); + + PostgreSQL::Test::Utils::command_fails_like(@_); + return; +} + +=pod + +=item $node->command_checks_all(...) + +PostgreSQL::Test::Utils::command_checks_all with our connection parameters. See +command_ok(...) + +=cut + +sub command_checks_all +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my $self = shift; + + local %ENV = $self->_get_env(); + + PostgreSQL::Test::Utils::command_checks_all(@_); + return; +} + +=pod + +=item $node->issues_sql_like(cmd, expected_sql, test_name) + +Run a command on the node, then verify that $expected_sql appears in the +server log file. + +=cut + +sub issues_sql_like +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my ($self, $cmd, $expected_sql, $test_name) = @_; + + local %ENV = $self->_get_env(); + + my $log_location = -s $self->logfile; + + my $result = PostgreSQL::Test::Utils::run_log($cmd); + ok($result, "@$cmd exit code 0"); + my $log = + PostgreSQL::Test::Utils::slurp_file($self->logfile, $log_location); + like($log, $expected_sql, "$test_name: SQL found in server log"); + return; +} + +=pod + +=item $node->log_content() + +Returns the contents of log of the node + +=cut + +sub log_content +{ + my ($self) = @_; + return PostgreSQL::Test::Utils::slurp_file($self->logfile); +} + +=pod + +=item $node->log_check($test_name, $offset, %params) + +Check contents of server logs. + +=over + +=item $test_name + +Name of test for error messages. + +=item $offset + +Offset of the log file. + +=item log_like => [ qr/required message/ ] + +If given, it must be an array reference containing a list of regular +expressions that must match against the server log, using +C. + +=item log_unlike => [ qr/prohibited message/ ] + +If given, it must be an array reference containing a list of regular +expressions that must NOT match against the server log. They will be +passed to C. + +=back + +=cut + +sub log_check +{ + my ($self, $test_name, $offset, %params) = @_; + + my (@log_like, @log_unlike); + if (defined($params{log_like})) + { + @log_like = @{ $params{log_like} }; + } + if (defined($params{log_unlike})) + { + @log_unlike = @{ $params{log_unlike} }; + } + + if (@log_like or @log_unlike) + { + my $log_contents = + PostgreSQL::Test::Utils::slurp_file($self->logfile, $offset); + + while (my $regex = shift @log_like) + { + like($log_contents, $regex, "$test_name: log matches"); + } + while (my $regex = shift @log_unlike) + { + unlike($log_contents, $regex, "$test_name: log does not match"); + } + } +} + +=pod + +=item log_contains(pattern, offset) + +Find pattern in logfile of node after offset byte. + +=cut + +sub log_contains +{ + my ($self, $pattern, $offset) = @_; + + return PostgreSQL::Test::Utils::slurp_file($self->logfile, $offset) =~ + m/$pattern/; +} + +=pod + +=item $node->run_log(...) + +Runs a shell command like PostgreSQL::Test::Utils::run_log, but with connection parameters set +so that the command will default to connecting to this PostgreSQL::Test::Cluster. + +=cut + +sub run_log +{ + my $self = shift; + + local %ENV = $self->_get_env(); + + return PostgreSQL::Test::Utils::run_log(@_); +} + +=pod + +=item $node->lsn(mode) + +Look up WAL locations on the server: + + * insert location (primary only, error on replica) + * write location (primary only, error on replica) + * flush location (primary only, error on replica) + * receive location (always undef on primary) + * replay location (always undef on primary) + +mode must be specified. + +=cut + +sub lsn +{ + my ($self, $mode) = @_; + my %modes = ( + 'insert' => 'pg_current_wal_insert_lsn()', + 'flush' => 'pg_current_wal_flush_lsn()', + 'write' => 'pg_current_wal_lsn()', + 'receive' => 'pg_last_wal_receive_lsn()', + 'replay' => 'pg_last_wal_replay_lsn()'); + + $mode = '' if !defined($mode); + croak "unknown mode for 'lsn': '$mode', valid modes are " + . join(', ', keys %modes) + if !defined($modes{$mode}); + + my $result = $self->safe_psql('postgres', "SELECT $modes{$mode}"); + chomp($result); + if ($result eq '') + { + return; + } + else + { + return $result; + } +} + +=pod + +=item $node->write_wal($tli, $lsn, $segment_size, $data) + +Write some arbitrary data in WAL for the given segment at $lsn (in bytes). +This should be called while the cluster is not running. + +Returns the path of the WAL segment written to. + +=cut + +sub write_wal +{ + my ($self, $tli, $lsn, $segment_size, $data) = @_; + + # Calculate segment number and offset position in segment based on the + # input LSN. + my $segment = $lsn / $segment_size; + my $offset = $lsn % $segment_size; + my $path = + sprintf("%s/pg_wal/%08X%08X%08X", $self->data_dir, $tli, 0, $segment); + + open my $fh, "+<:raw", $path or die "could not open WAL segment $path"; + seek($fh, $offset, SEEK_SET) or die "could not seek WAL segment $path"; + print $fh $data; + close $fh; + + return $path; +} + +=pod + +=item $node->emit_wal($size) + +Emit a WAL record of arbitrary size, using pg_logical_emit_message(). + +Returns the end LSN of the record inserted, in bytes. + +=cut + +sub emit_wal +{ + my ($self, $size) = @_; + + return int( + $self->safe_psql( + 'postgres', + "SELECT pg_logical_emit_message(true, '', repeat('a', $size)) - '0/0'" + )); +} + + +# Private routine returning the current insert LSN of a node, in bytes. +# Used by the routines below in charge of advancing WAL to arbitrary +# positions. The insert LSN is returned in bytes. +sub _get_insert_lsn +{ + my ($self) = @_; + return int( + $self->safe_psql( + 'postgres', "SELECT pg_current_wal_insert_lsn() - '0/0'")); +} + +=pod + +=item $node->advance_wal_out_of_record_splitting_zone($wal_block_size) + +Advance WAL at the end of a page, making sure that we are far away enough +from the end of a page that we could insert a couple of small records. + +This inserts a few records of a fixed size, until the threshold gets close +enough to the end of the WAL page inserting records to. + +Returns the end LSN up to which WAL has advanced, in bytes. + +=cut + +sub advance_wal_out_of_record_splitting_zone +{ + my ($self, $wal_block_size) = @_; + + my $page_threshold = $wal_block_size / 4; + my $end_lsn = $self->_get_insert_lsn(); + my $page_offset = $end_lsn % $wal_block_size; + while ($page_offset >= $wal_block_size - $page_threshold) + { + $self->emit_wal($page_threshold); + $end_lsn = $self->_get_insert_lsn(); + $page_offset = $end_lsn % $wal_block_size; + } + return $end_lsn; +} + +=pod + +=item $node->advance_wal_to_record_splitting_zone($wal_block_size) + +Advance WAL so close to the end of a page that an XLogRecordHeader would not +fit on it. + +Returns the end LSN up to which WAL has advanced, in bytes. + +=cut + +sub advance_wal_to_record_splitting_zone +{ + my ($self, $wal_block_size) = @_; + + # Size of record header. + my $RECORD_HEADER_SIZE = 24; + + my $end_lsn = $self->_get_insert_lsn(); + my $page_offset = $end_lsn % $wal_block_size; + + # Get fairly close to the end of a page in big steps + while ($page_offset <= $wal_block_size - 512) + { + $self->emit_wal($wal_block_size - $page_offset - 256); + $end_lsn = $self->_get_insert_lsn(); + $page_offset = $end_lsn % $wal_block_size; + } + + # Calibrate our message size so that we can get closer 8 bytes at + # a time. + my $message_size = $wal_block_size - 80; + while ($page_offset <= $wal_block_size - $RECORD_HEADER_SIZE) + { + $self->emit_wal($message_size); + $end_lsn = $self->_get_insert_lsn(); + + my $old_offset = $page_offset; + $page_offset = $end_lsn % $wal_block_size; + + # Adjust the message size until it causes 8 bytes changes in + # offset, enough to be able to split a record header. + my $delta = $page_offset - $old_offset; + if ($delta > 8) + { + $message_size -= 8; + } + elsif ($delta <= 0) + { + $message_size += 8; + } + } + return $end_lsn; +} + +=pod + +=item $node->wait_for_catchup(standby_name, mode, target_lsn) + +Wait for the replication connection with application_name standby_name until +its 'mode' replication column in pg_stat_replication equals or passes the +specified or default target_lsn. By default the replay_lsn is waited for, +but 'mode' may be specified to wait for any of sent|write|flush|replay. +The replication connection must be in a streaming state. + +When doing physical replication, the standby is usually identified by +passing its PostgreSQL::Test::Cluster instance. When doing logical +replication, standby_name identifies a subscription. + +When not in recovery, the default value of target_lsn is $node->lsn('write'), +which ensures that the standby has caught up to what has been committed on +the primary. + +When in recovery, the default value of target_lsn is $node->lsn('replay') +instead which ensures that the cascaded standby has caught up to what has been +replayed on the standby. + +If you pass an explicit value of target_lsn, it should almost always be +the primary's write LSN; so this parameter is seldom needed except when +querying some intermediate replication node rather than the primary. + +If there is no active replication connection from this peer, waits until +poll_query_until timeout. + +Requires that the 'postgres' db exists and is accessible. + +This is not a test. It die()s on failure. + +=cut + +sub wait_for_catchup +{ + my ($self, $standby_name, $mode, $target_lsn) = @_; + $mode = defined($mode) ? $mode : 'replay'; + my %valid_modes = + ('sent' => 1, 'write' => 1, 'flush' => 1, 'replay' => 1); + croak "unknown mode $mode for 'wait_for_catchup', valid modes are " + . join(', ', keys(%valid_modes)) + unless exists($valid_modes{$mode}); + + # Allow passing of a PostgreSQL::Test::Cluster instance as shorthand + if (blessed($standby_name) + && $standby_name->isa("PostgreSQL::Test::Cluster")) + { + $standby_name = $standby_name->name; + } + if (!defined($target_lsn)) + { + my $isrecovery = + $self->safe_psql('postgres', "SELECT pg_is_in_recovery()"); + chomp($isrecovery); + if ($isrecovery eq 't') + { + $target_lsn = $self->lsn('replay'); + } + else + { + $target_lsn = $self->lsn('write'); + } + } + print "Waiting for replication conn " + . $standby_name . "'s " + . $mode + . "_lsn to pass " + . $target_lsn . " on " + . $self->name . "\n"; + # Before release 12 walreceiver just set the application name to + # "walreceiver" + my $query = qq[SELECT '$target_lsn' <= ${mode}_lsn AND state = 'streaming' + FROM pg_catalog.pg_stat_replication + WHERE application_name IN ('$standby_name', 'walreceiver')]; + if (!$self->poll_query_until('postgres', $query)) + { + if (PostgreSQL::Test::Utils::has_wal_read_bug) + { + # Mimic having skipped the test file. If >0 tests have run, the + # harness won't accept a skip; otherwise, it won't accept + # done_testing(). Force a nonzero count by running one test. + ok(1, 'dummy test before skip for filesystem bug'); + carp "skip rest: timed out waiting for catchup & filesystem bug"; + done_testing(); + exit 0; + } + else + { + croak "timed out waiting for catchup"; + } + } + print "done\n"; + return; +} + +=pod + +=item $node->wait_for_replay_catchup($standby_name [, $base_node ]) + +Wait for the replication connection with application_name I<$standby_name> +until its B replication column in pg_stat_replication in I<$node> +equals or passes the I<$base_node>'s B. If I<$base_node> is +omitted, the LSN to wait for is obtained from I<$node>. + +The replication connection must be in a streaming state. + +Requires that the 'postgres' db exists and is accessible. + +This is not a test. It die()s on failure. + +=cut + +sub wait_for_replay_catchup +{ + my ($self, $standby_name, $node) = @_; + $node = defined($node) ? $node : $self; + + $self->wait_for_catchup($standby_name, 'replay', $node->lsn('flush')); +} + +=item $node->wait_for_slot_catchup(slot_name, mode, target_lsn) + +Wait for the named replication slot to equal or pass the supplied target_lsn. +The location used is the restart_lsn unless mode is given, in which case it may +be 'restart' or 'confirmed_flush'. + +Requires that the 'postgres' db exists and is accessible. + +This is not a test. It die()s on failure. + +If the slot is not active, will time out after poll_query_until's timeout. + +target_lsn may be any arbitrary lsn, but is typically $primary_node->lsn('insert'). + +Note that for logical slots, restart_lsn is held down by the oldest in-progress tx. + +=cut + +sub wait_for_slot_catchup +{ + my ($self, $slot_name, $mode, $target_lsn) = @_; + $mode = defined($mode) ? $mode : 'restart'; + if (!($mode eq 'restart' || $mode eq 'confirmed_flush')) + { + croak "valid modes are restart, confirmed_flush"; + } + croak 'target lsn must be specified' unless defined($target_lsn); + print "Waiting for replication slot " + . $slot_name . "'s " + . $mode + . "_lsn to pass " + . $target_lsn . " on " + . $self->name . "\n"; + my $query = + qq[SELECT '$target_lsn' <= ${mode}_lsn FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name';]; + $self->poll_query_until('postgres', $query) + or croak "timed out waiting for catchup"; + print "done\n"; + return; +} + +=pod + +=item $node->wait_for_subscription_sync(publisher, subname, dbname) + +Wait for all tables in pg_subscription_rel to complete the initial +synchronization (i.e to be either in 'syncdone' or 'ready' state). + +If the publisher node is given, additionally, check if the subscriber has +caught up to what has been committed on the primary. This is useful to +ensure that the initial data synchronization has been completed after +creating a new subscription. + +If there is no active replication connection from this peer, wait until +poll_query_until timeout. + +This is not a test. It die()s on failure. + +=cut + +sub wait_for_subscription_sync +{ + my ($self, $publisher, $subname, $dbname) = @_; + my $name = $self->name; + + $dbname = defined($dbname) ? $dbname : 'postgres'; + + # Wait for all tables to finish initial sync. + print "Waiting for all subscriptions in \"$name\" to synchronize data\n"; + my $query = + qq[SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');]; + $self->poll_query_until($dbname, $query) + or croak "timed out waiting for subscriber to synchronize data"; + + # Then, wait for the replication to catchup if required. + if (defined($publisher)) + { + croak 'subscription name must be specified' unless defined($subname); + $publisher->wait_for_catchup($subname); + } + + print "done\n"; + return; +} + +=pod + +=item $node->wait_for_log(regexp, offset) + +Waits for the contents of the server log file, starting at the given offset, to +match the supplied regular expression. Checks the entire log if no offset is +given. Times out after $PostgreSQL::Test::Utils::timeout_default seconds. + +If successful, returns the length of the entire log file, in bytes. + +=cut + +sub wait_for_log +{ + my ($self, $regexp, $offset) = @_; + $offset = 0 unless defined $offset; + + my $max_attempts = 10 * $PostgreSQL::Test::Utils::timeout_default; + my $attempts = 0; + + while ($attempts < $max_attempts) + { + my $log = + PostgreSQL::Test::Utils::slurp_file($self->logfile, $offset); + + return $offset + length($log) if ($log =~ m/$regexp/); + + # Wait 0.1 second before retrying. + usleep(100_000); + + $attempts++; + } + + croak "timed out waiting for match: $regexp"; +} + +=pod + +=item $node->query_hash($dbname, $query, @columns) + +Execute $query on $dbname, replacing any appearance of the string __COLUMNS__ +within the query with a comma-separated list of @columns. + +If __COLUMNS__ does not appear in the query, its result columns must EXACTLY +match the order and number (but not necessarily alias) of supplied @columns. + +The query must return zero or one rows. + +Return a hash-ref representation of the results of the query, with any empty +or null results as defined keys with an empty-string value. There is no way +to differentiate between null and empty-string result fields. + +If the query returns zero rows, return a hash with all columns empty. There +is no way to differentiate between zero rows returned and a row with only +null columns. + +=cut + +sub query_hash +{ + my ($self, $dbname, $query, @columns) = @_; + croak 'calls in array context for multi-row results not supported yet' + if (wantarray); + + # Replace __COLUMNS__ if found + substr($query, index($query, '__COLUMNS__'), length('__COLUMNS__')) = + join(', ', @columns) + if index($query, '__COLUMNS__') >= 0; + my $result = $self->safe_psql($dbname, $query); + + # hash slice, see http://stackoverflow.com/a/16755894/398670 . + # + # Fills the hash with empty strings produced by x-operator element + # duplication if result is an empty row + # + my %val; + @val{@columns} = + $result ne '' ? split(qr/\|/, $result, -1) : ('',) x scalar(@columns); + return \%val; +} + +=pod + +=item $node->slot(slot_name) + +Return hash-ref of replication slot data for the named slot, or a hash-ref with +all values '' if not found. Does not differentiate between null and empty string +for fields, no field is ever undef. + +The restart_lsn and confirmed_flush_lsn fields are returned verbatim, and also +as a 2-list of [highword, lowword] integer. Since we rely on Perl 5.14 we can't +"use bigint", it's from 5.20, and we can't assume we have Math::Bigint from CPAN +either. + +=cut + +sub slot +{ + my ($self, $slot_name) = @_; + my @columns = ( + 'plugin', 'slot_type', 'datoid', 'database', + 'active', 'active_pid', 'xmin', 'catalog_xmin', + 'restart_lsn'); + return $self->query_hash( + 'postgres', + "SELECT __COLUMNS__ FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name'", + @columns); +} + +=pod + +=item $node->pg_recvlogical_upto(self, dbname, slot_name, endpos, timeout_secs, ...) + +Invoke pg_recvlogical to read from slot_name on dbname until LSN endpos, which +corresponds to pg_recvlogical --endpos. Gives up after timeout (if nonzero). + +Disallows pg_recvlogical from internally retrying on error by passing --no-loop. + +Plugin options are passed as additional keyword arguments. + +If called in scalar context, returns stdout, and die()s on timeout or nonzero return. + +If called in array context, returns a tuple of (retval, stdout, stderr, timeout). +timeout is the IPC::Run::Timeout object whose is_expired method can be tested +to check for timeout. retval is undef on timeout. + +=cut + +sub pg_recvlogical_upto +{ + my ($self, $dbname, $slot_name, $endpos, $timeout_secs, %plugin_options) + = @_; + + local %ENV = $self->_get_env(); + + my ($stdout, $stderr); + + my $timeout_exception = 'pg_recvlogical timed out'; + + croak 'slot name must be specified' unless defined($slot_name); + croak 'endpos must be specified' unless defined($endpos); + + my @cmd = ( + $self->installed_command('pg_recvlogical'), + '-S', $slot_name, '--dbname', $self->connstr($dbname)); + push @cmd, '--endpos', $endpos; + push @cmd, '-f', '-', '--no-loop', '--start'; + + while (my ($k, $v) = each %plugin_options) + { + croak "= is not permitted to appear in replication option name" + if ($k =~ qr/=/); + push @cmd, "-o", "$k=$v"; + } + + my $timeout; + $timeout = + IPC::Run::timeout($timeout_secs, exception => $timeout_exception) + if $timeout_secs; + my $ret = 0; + + do + { + local $@; + eval { + IPC::Run::run(\@cmd, ">", \$stdout, "2>", \$stderr, $timeout); + $ret = $?; + }; + my $exc_save = $@; + if ($exc_save) + { + + # IPC::Run::run threw an exception. re-throw unless it's a + # timeout, which we'll handle by testing is_expired + die $exc_save + if (blessed($exc_save) || $exc_save !~ qr/$timeout_exception/); + + $ret = undef; + + die "Got timeout exception '$exc_save' but timer not expired?!" + unless $timeout->is_expired; + + die + "$exc_save waiting for endpos $endpos with stdout '$stdout', stderr '$stderr'" + unless wantarray; + } + }; + + if (wantarray) + { + return ($ret, $stdout, $stderr, $timeout); + } + else + { + die + "pg_recvlogical exited with code '$ret', stdout '$stdout' and stderr '$stderr'" + if $ret; + return $stdout; + } +} + +=pod + +=item $node->corrupt_page_checksum(self, file, page_offset) + +Intentionally corrupt the checksum field of one page in a file. +The server must be stopped for this to work reliably. + +The file name should be specified relative to the cluster datadir. +page_offset had better be a multiple of the cluster's block size. + +=cut + +sub corrupt_page_checksum +{ + my ($self, $file, $page_offset) = @_; + my $pgdata = $self->data_dir; + my $pageheader; + + open my $fh, '+<', "$pgdata/$file" or die "open($file) failed: $!"; + binmode $fh; + sysseek($fh, $page_offset, 0) or die "sysseek failed: $!"; + sysread($fh, $pageheader, 24) or die "sysread failed: $!"; + # This inverts the pd_checksum field (only); see struct PageHeaderData + $pageheader ^= "\0\0\0\0\0\0\0\0\xff\xff"; + sysseek($fh, $page_offset, 0) or die "sysseek failed: $!"; + syswrite($fh, $pageheader) or die "syswrite failed: $!"; + close $fh; + + return; +} + +# +# Signal handlers +# +$SIG{TERM} = $SIG{INT} = sub { + die "death by signal"; +}; + +=pod + +=item $node->log_standby_snapshot(self, standby, slot_name) + +Log a standby snapshot on primary once the slot restart_lsn is determined on +the standby. + +=cut + +sub log_standby_snapshot +{ + my ($self, $standby, $slot_name) = @_; + + # Once the slot's restart_lsn is determined, the standby looks for + # xl_running_xacts WAL record from the restart_lsn onwards. First wait + # until the slot restart_lsn is determined. + + $standby->poll_query_until( + 'postgres', qq[ + SELECT restart_lsn IS NOT NULL + FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name' + ]) + or die + "timed out waiting for logical slot to calculate its restart_lsn"; + + # Then arrange for the xl_running_xacts record for which the standby is + # waiting. + $self->safe_psql('postgres', 'SELECT pg_log_standby_snapshot()'); +} + +=pod + +=item $node->create_logical_slot_on_standby(self, primary, slot_name, dbname) + +Create logical replication slot on given standby + +=cut + +sub create_logical_slot_on_standby +{ + my ($self, $primary, $slot_name, $dbname) = @_; + my ($stdout, $stderr); + + my $handle; + + $handle = IPC::Run::start( + [ + 'pg_recvlogical', '-d', + $self->connstr($dbname), '-P', + 'test_decoding', '-S', + $slot_name, '--create-slot' + ], + '>', + \$stdout, + '2>', + \$stderr); + + # Arrange for the xl_running_xacts record for which pg_recvlogical is + # waiting. + $primary->log_standby_snapshot($self, $slot_name); + + $handle->finish(); + + is($self->slot($slot_name)->{'slot_type'}, + 'logical', $slot_name . ' on standby created') + or die "could not create slot" . $slot_name; +} + +=pod + +=back + +=cut + +########################################################################## + +package PostgreSQL::Test::Cluster::V_11 + ; ## no critic (ProhibitMultiplePackages) + +use parent -norequire, qw(PostgreSQL::Test::Cluster); + +# https://www.postgresql.org/docs/11/release-11.html + +# max_wal_senders + superuser_reserved_connections must be < max_connections +# uses recovery.conf + +sub _recovery_file { return "recovery.conf"; } + +sub set_standby_mode +{ + my $self = shift; + $self->append_conf("recovery.conf", "standby_mode = on\n"); +} + +sub init +{ + my ($self, %params) = @_; + $self->SUPER::init(%params); + $self->adjust_conf('postgresql.conf', 'max_wal_senders', + $params{allows_streaming} ? 5 : 0); +} + +########################################################################## + +package PostgreSQL::Test::Cluster::V_10 + ; ## no critic (ProhibitMultiplePackages) + +use parent -norequire, qw(PostgreSQL::Test::Cluster::V_11); + +# https://www.postgresql.org/docs/10/release-10.html + +######################################################################## + +1; diff --git a/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/RecursiveCopy.pm b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/RecursiveCopy.pm new file mode 100644 index 00000000000..15964e62173 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/RecursiveCopy.pm @@ -0,0 +1,157 @@ + +# Copyright (c) 2021-2023, PostgreSQL Global Development Group + +=pod + +=head1 NAME + +PostgreSQL::Test::RecursiveCopy - simple recursive copy implementation + +=head1 SYNOPSIS + +use PostgreSQL::Test::RecursiveCopy; + +PostgreSQL::Test::RecursiveCopy::copypath($from, $to, filterfn => sub { return 1; }); +PostgreSQL::Test::RecursiveCopy::copypath($from, $to); + +=cut + +package PostgreSQL::Test::RecursiveCopy; + +use strict; +use warnings; + +use Carp; +use File::Basename; +use File::Copy; + +=pod + +=head1 DESCRIPTION + +=head2 copypath($from, $to, %params) + +Recursively copy all files and directories from $from to $to. +Does not preserve file metadata (e.g., permissions). + +Only regular files and subdirectories are copied. Trying to copy other types +of directory entries raises an exception. + +Raises an exception if a file would be overwritten, the source directory can't +be read, or any I/O operation fails. However, we silently ignore ENOENT on +open, because when copying from a live database it's possible for a file/dir +to be deleted after we see its directory entry but before we can open it. + +Always returns true. + +If the B parameter is given, it must be a subroutine reference. +This subroutine will be called for each entry in the source directory with its +relative path as only parameter; if the subroutine returns true the entry is +copied, otherwise the file is skipped. + +On failure the target directory may be in some incomplete state; no cleanup is +attempted. + +=head1 EXAMPLES + + PostgreSQL::Test::RecursiveCopy::copypath('/some/path', '/empty/dir', + filterfn => sub { + # omit log/ and contents + my $src = shift; + return $src ne 'log'; + } + ); + +=cut + +sub copypath +{ + my ($base_src_dir, $base_dest_dir, %params) = @_; + my $filterfn; + + if (defined $params{filterfn}) + { + croak "if specified, filterfn must be a subroutine reference" + unless defined(ref $params{filterfn}) + and (ref $params{filterfn} eq 'CODE'); + + $filterfn = $params{filterfn}; + } + else + { + $filterfn = sub { return 1; }; + } + + # Complain if original path is bogus, because _copypath_recurse won't. + croak "\"$base_src_dir\" does not exist" if !-e $base_src_dir; + + # Start recursive copy from current directory + return _copypath_recurse($base_src_dir, $base_dest_dir, "", $filterfn); +} + +# Recursive private guts of copypath +sub _copypath_recurse +{ + my ($base_src_dir, $base_dest_dir, $curr_path, $filterfn) = @_; + my $srcpath = "$base_src_dir/$curr_path"; + my $destpath = "$base_dest_dir/$curr_path"; + + # invoke the filter and skip all further operation if it returns false + return 1 unless &$filterfn($curr_path); + + # Check for symlink -- needed only on source dir + # (note: this will fall through quietly if file is already gone) + croak "Cannot operate on symlink \"$srcpath\"" if -l $srcpath; + + # Abort if destination path already exists. Should we allow directories + # to exist already? + croak "Destination path \"$destpath\" already exists" if -e $destpath; + + # If this source path is a file, simply copy it to destination with the + # same name and we're done. + if (-f $srcpath) + { + my $fh; + unless (open($fh, '<', $srcpath)) + { + return 1 if ($!{ENOENT}); + die "open($srcpath) failed: $!"; + } + copy($fh, $destpath) + or die "copy $srcpath -> $destpath failed: $!"; + close $fh; + return 1; + } + + # If it's a directory, create it on dest and recurse into it. + if (-d $srcpath) + { + my $directory; + unless (opendir($directory, $srcpath)) + { + return 1 if ($!{ENOENT}); + die "opendir($srcpath) failed: $!"; + } + + mkdir($destpath) or die "mkdir($destpath) failed: $!"; + + while (my $entry = readdir($directory)) + { + next if ($entry eq '.' or $entry eq '..'); + _copypath_recurse($base_src_dir, $base_dest_dir, + $curr_path eq '' ? $entry : "$curr_path/$entry", $filterfn) + or die "copypath $srcpath/$entry -> $destpath/$entry failed"; + } + + closedir($directory); + return 1; + } + + # If it disappeared from sight, that's OK. + return 1 if !-e $srcpath; + + # Else it's some weird file type; complain. + croak "Source path \"$srcpath\" is not a regular file or directory"; +} + +1; diff --git a/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/SimpleTee.pm b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/SimpleTee.pm new file mode 100644 index 00000000000..82099bf5036 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/SimpleTee.pm @@ -0,0 +1,63 @@ + +# Copyright (c) 2021-2023, PostgreSQL Global Development Group + +# A simple 'tee' implementation, using perl tie. +# +# Whenever you print to the handle, it gets forwarded to a list of +# handles. The list of output filehandles is passed to the constructor. +# +# This is similar to IO::Tee, but only used for output. Only the PRINT +# method is currently implemented; that's all we need. We don't want to +# depend on IO::Tee just for this. + +# The package is enhanced to add timestamp and elapsed time decorations to +# the log file traces sent through this interface from Test::More functions +# (ok, is, note, diag etc.). Elapsed time is shown as the time since the last +# log trace. + +package PostgreSQL::Test::SimpleTee; +use strict; +use warnings; + +use Time::HiRes qw(time); + +my $last_time; + +BEGIN { $last_time = time; } + +sub _time_str +{ + my $tm = time; + my $diff = $tm - $last_time; + $last_time = $tm; + my ($sec, $min, $hour) = localtime($tm); + my $msec = int(1000 * ($tm - int($tm))); + return sprintf("[%.2d:%.2d:%.2d.%.3d](%.3fs) ", + $hour, $min, $sec, $msec, $diff); +} + +sub TIEHANDLE +{ + my $self = shift; + return bless \@_, $self; +} + +sub PRINT +{ + my $self = shift; + my $ok = 1; + # The first file argument passed to tiehandle in PostgreSQL::Test::Utils is + # the original stdout, which is what PROVE sees. Additional decorations + # confuse it, so only put out the time string on files after the first. + my $skip = 1; + my $ts = _time_str; + for my $fh (@$self) + { + print $fh ($skip ? "" : $ts), @_ or $ok = 0; + $fh->flush or $ok = 0; + $skip = 0; + } + return $ok; +} + +1; diff --git a/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/Utils.pm b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/Utils.pm new file mode 100644 index 00000000000..d66fe1cf453 --- /dev/null +++ b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test/Utils.pm @@ -0,0 +1,1074 @@ + +# Copyright (c) 2021-2023, PostgreSQL Global Development Group + +=pod + +=head1 NAME + +PostgreSQL::Test::Utils - helper module for writing PostgreSQL's C tests. + +=head1 SYNOPSIS + + use PostgreSQL::Test::Utils; + + # Test basic output of a command + program_help_ok('initdb'); + program_version_ok('initdb'); + program_options_handling_ok('initdb'); + + # Test option combinations + command_fails(['initdb', '--invalid-option'], + 'command fails with invalid option'); + my $tempdir = PostgreSQL::Test::Utils::tempdir; + command_ok('initdb', '-D', $tempdir); + + # Miscellanea + print "on Windows" if $PostgreSQL::Test::Utils::windows_os; + ok(check_mode_recursive($stream_dir, 0700, 0600), + "check stream dir permissions"); + PostgreSQL::Test::Utils::system_log('pg_ctl', 'kill', 'QUIT', $slow_pid); + +=head1 DESCRIPTION + +C contains a set of routines dedicated to environment setup for +a PostgreSQL regression test run and includes some low-level routines +aimed at controlling command execution, logging and test functions. + +=cut + +# This module should never depend on any other PostgreSQL regression test +# modules. + +package PostgreSQL::Test::Utils; + +use strict; +use warnings; + +use Carp; +use Config; +use Cwd; +use Exporter 'import'; +use Fcntl qw(:mode :seek); +use File::Basename; +use File::Find; +use File::Spec; +use File::stat qw(stat); +use File::Temp (); +use IPC::Run; +use POSIX qw(locale_h); +use PostgreSQL::Test::SimpleTee; + +# We need a version of Test::More recent enough to support subtests +use Test::More 0.98; + +our @EXPORT = qw( + generate_ascii_string + slurp_dir + slurp_file + append_to_file + string_replace_file + check_mode_recursive + chmod_recursive + check_pg_config + dir_symlink + scan_server_header + system_or_bail + system_log + run_log + run_command + pump_until + + command_ok + command_fails + command_exit_is + program_help_ok + program_version_ok + program_options_handling_ok + command_like + command_like_safe + command_fails_like + command_checks_all + + $windows_os + $is_msys2 + $use_unix_sockets +); + +our ($windows_os, $is_msys2, $use_unix_sockets, $timeout_default, + $tmp_check, $log_path, $test_logfile); + +BEGIN +{ + + # Set to untranslated messages, to be able to compare program output + # with expected strings. + delete $ENV{LANGUAGE}; + delete $ENV{LC_ALL}; + $ENV{LC_MESSAGES} = 'C'; + setlocale(LC_ALL, ""); + + # This list should be kept in sync with pg_regress.c. + my @envkeys = qw ( + PGCHANNELBINDING + PGCLIENTENCODING + PGCONNECT_TIMEOUT + PGDATA + PGDATABASE + PGGSSDELEGATION + PGGSSENCMODE + PGGSSLIB + PGHOSTADDR + PGKRBSRVNAME + PGPASSFILE + PGPASSWORD + PGREQUIREPEER + PGREQUIRESSL + PGSERVICE + PGSERVICEFILE + PGSSLCERT + PGSSLCRL + PGSSLCRLDIR + PGSSLKEY + PGSSLMAXPROTOCOLVERSION + PGSSLMINPROTOCOLVERSION + PGSSLMODE + PGSSLROOTCERT + PGSSLSNI + PGTARGETSESSIONATTRS + PGUSER + PGPORT + PGHOST + PG_COLOR + ); + delete @ENV{@envkeys}; + + $ENV{PGAPPNAME} = basename($0); + + # Must be set early + $windows_os = $Config{osname} eq 'MSWin32' || $Config{osname} eq 'msys'; + # Check if this environment is MSYS2. + $is_msys2 = + $windows_os + && -x '/usr/bin/uname' + && `uname -or` =~ /^[2-9].*Msys/; + + if ($windows_os) + { + require Win32API::File; + Win32API::File->import(qw(createFile OsFHandleOpen CloseHandle)); + } + + # Specifies whether to use Unix sockets for test setups. On + # Windows we don't use them by default since it's not universally + # supported, but it can be overridden if desired. + $use_unix_sockets = + (!$windows_os || defined $ENV{PG_TEST_USE_UNIX_SOCKETS}); + + $timeout_default = $ENV{PG_TEST_TIMEOUT_DEFAULT}; + $timeout_default = 180 + if not defined $timeout_default or $timeout_default eq ''; +} + +=pod + +=head1 EXPORTED VARIABLES + +=over + +=item C<$windows_os> + +Set to true when running under Windows, except on Cygwin. + +=item C<$is_msys2> + +Set to true when running under MSYS2. + +=back + +=cut + +INIT +{ + + # Return EPIPE instead of killing the process with SIGPIPE. An affected + # test may still fail, but it's more likely to report useful facts. + $SIG{PIPE} = 'IGNORE'; + + # Determine output directories, and create them. The base paths are the + # TESTDATADIR / TESTLOGDIR environment variables, which are normally set + # by the invoking Makefile. + $tmp_check = $ENV{TESTDATADIR} ? "$ENV{TESTDATADIR}" : "tmp_check"; + $log_path = $ENV{TESTLOGDIR} ? "$ENV{TESTLOGDIR}" : "log"; + + mkdir $tmp_check; + mkdir $log_path; + + # Open the test log file, whose name depends on the test name. + $test_logfile = basename($0); + $test_logfile =~ s/\.[^.]+$//; + $test_logfile = "$log_path/regress_log_$test_logfile"; + open my $testlog, '>', $test_logfile + or die "could not open STDOUT to logfile \"$test_logfile\": $!"; + + # Hijack STDOUT and STDERR to the log file + open(my $orig_stdout, '>&', \*STDOUT); + open(my $orig_stderr, '>&', \*STDERR); + open(STDOUT, '>&', $testlog); + open(STDERR, '>&', $testlog); + + # The test output (ok ...) needs to be printed to the original STDOUT so + # that the 'prove' program can parse it, and display it to the user in + # real time. But also copy it to the log file, to provide more context + # in the log. + my $builder = Test::More->builder; + my $fh = $builder->output; + tie *$fh, "PostgreSQL::Test::SimpleTee", $orig_stdout, $testlog; + $fh = $builder->failure_output; + tie *$fh, "PostgreSQL::Test::SimpleTee", $orig_stderr, $testlog; + + # Enable auto-flushing for all the file handles. Stderr and stdout are + # redirected to the same file, and buffering causes the lines to appear + # in the log in confusing order. + autoflush STDOUT 1; + autoflush STDERR 1; + autoflush $testlog 1; +} + +END +{ + + # Test files have several ways of causing prove_check to fail: + # 1. Exit with a non-zero status. + # 2. Call ok(0) or similar, indicating that a constituent test failed. + # 3. Deviate from the planned number of tests. + # + # Preserve temporary directories after (1) and after (2). + $File::Temp::KEEP_ALL = 1 unless $? == 0 && all_tests_passing(); +} + +=pod + +=head1 ROUTINES + +=over + +=item all_tests_passing() + +Return 1 if all the tests run so far have passed. Otherwise, return 0. + +=cut + +sub all_tests_passing +{ + foreach my $status (Test::More->builder->summary) + { + return 0 unless $status; + } + return 1; +} + +=pod + +=item tempdir(prefix) + +Securely create a temporary directory inside C<$tmp_check>, like C, +and return its name. The directory will be removed automatically at the +end of the tests, unless the environment variable PG_TEST_NOCLEAN is provided. + +If C is given, the new directory is templated as C<${prefix}_XXXX>. +Otherwise the template is C. + +=cut + +sub tempdir +{ + my ($prefix) = @_; + $prefix = "tmp_test" unless defined $prefix; + return File::Temp::tempdir( + $prefix . '_XXXX', + DIR => $tmp_check, + CLEANUP => not defined $ENV{'PG_TEST_NOCLEAN'}); +} + +=pod + +=item tempdir_short() + +As above, but the directory is outside the build tree so that it has a short +name, to avoid path length issues. + +=cut + +sub tempdir_short +{ + + return File::Temp::tempdir( + CLEANUP => not defined $ENV{'PG_TEST_NOCLEAN'}); +} + +=pod + +=item has_wal_read_bug() + +Returns true if $tmp_check is subject to a sparc64+ext4 bug that causes WAL +readers to see zeros if another process simultaneously wrote the same offsets. +Consult this in tests that fail frequently on affected configurations. The +bug has made streaming standbys fail to advance, reporting corrupt WAL. It +has made COMMIT PREPARED fail with "could not read two-phase state from WAL". +Non-WAL PostgreSQL reads haven't been affected, likely because those readers +and writers have buffering systems in common. See +https://postgr.es/m/20220116210241.GC756210@rfd.leadboat.com for details. + +=cut + +sub has_wal_read_bug +{ + return + $Config{osname} eq 'linux' + && $Config{archname} =~ /^sparc/ + && !run_log([ qw(df -x ext4), $tmp_check ], '>', '/dev/null', '2>&1'); +} + +=pod + +=item system_log(@cmd) + +Run (via C) the command passed as argument; the return +value is passed through. + +=cut + +sub system_log +{ + print("# Running: " . join(" ", @_) . "\n"); + return system(@_); +} + +=pod + +=item system_or_bail(@cmd) + +Run (via C) the command passed as argument, and returns +if the command is successful. +On failure, abandon further tests and exit the program. + +=cut + +sub system_or_bail +{ + if (system_log(@_) != 0) + { + if ($? == -1) + { + BAIL_OUT( + sprintf( + "failed to execute command \"%s\": $!", join(" ", @_))); + } + elsif ($? & 127) + { + BAIL_OUT( + sprintf( + "command \"%s\" died with signal %d", + join(" ", @_), + $? & 127)); + } + else + { + BAIL_OUT( + sprintf( + "command \"%s\" exited with value %d", + join(" ", @_), + $? >> 8)); + } + } +} + +=pod + +=item run_log(@cmd) + +Run the given command via C, noting it in the log. +The return value from the command is passed through. + +=cut + +sub run_log +{ + print("# Running: " . join(" ", @{ $_[0] }) . "\n"); + return IPC::Run::run(@_); +} + +=pod + +=item run_command(cmd) + +Run (via C) the command passed as argument. +The return value from the command is ignored. +The return value is C<($stdout, $stderr)>. + +=cut + +sub run_command +{ + my ($cmd) = @_; + my ($stdout, $stderr); + my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr; + chomp($stdout); + chomp($stderr); + return ($stdout, $stderr); +} + +=pod + +=item pump_until(proc, timeout, stream, until) + +Pump until string is matched on the specified stream, or timeout occurs. + +=cut + +sub pump_until +{ + my ($proc, $timeout, $stream, $until) = @_; + $proc->pump_nb(); + while (1) + { + last if $$stream =~ /$until/; + if ($timeout->is_expired) + { + diag( + "pump_until: timeout expired when searching for \"$until\" with stream: \"$$stream\"" + ); + return 0; + } + if (not $proc->pumpable()) + { + diag( + "pump_until: process terminated unexpectedly when searching for \"$until\" with stream: \"$$stream\"" + ); + return 0; + } + $proc->pump(); + } + return 1; +} + +=pod + +=item generate_ascii_string(from_char, to_char) + +Generate a string made of the given range of ASCII characters. + +=cut + +sub generate_ascii_string +{ + my ($from_char, $to_char) = @_; + my $res; + + for my $i ($from_char .. $to_char) + { + $res .= sprintf("%c", $i); + } + return $res; +} + +=pod + +=item slurp_dir(dir) + +Return the complete list of entries in the specified directory. + +=cut + +sub slurp_dir +{ + my ($dir) = @_; + opendir(my $dh, $dir) + or croak "could not opendir \"$dir\": $!"; + my @direntries = readdir $dh; + closedir $dh; + return @direntries; +} + +=pod + +=item slurp_file(filename [, $offset]) + +Return the full contents of the specified file, beginning from an +offset position if specified. + +=cut + +sub slurp_file +{ + my ($filename, $offset) = @_; + local $/; + my $contents; + my $fh; + + # On windows open file using win32 APIs, to allow us to set the + # FILE_SHARE_DELETE flag ("d" below), otherwise other accesses to the file + # may fail. + if ($Config{osname} ne 'MSWin32') + { + open($fh, '<', $filename) + or croak "could not read \"$filename\": $!"; + } + else + { + my $fHandle = createFile($filename, "r", "rwd") + or croak "could not open \"$filename\": $^E"; + OsFHandleOpen($fh = IO::Handle->new(), $fHandle, 'r') + or croak "could not read \"$filename\": $^E\n"; + } + + if (defined($offset)) + { + seek($fh, $offset, SEEK_SET) + or croak "could not seek \"$filename\": $!"; + } + + $contents = <$fh>; + close $fh; + + return $contents; +} + +=pod + +=item append_to_file(filename, str) + +Append a string at the end of a given file. (Note: no newline is appended at +end of file.) + +=cut + +sub append_to_file +{ + my ($filename, $str) = @_; + open my $fh, ">>", $filename + or croak "could not write \"$filename\": $!"; + print $fh $str; + close $fh; + return; +} + +=pod + +=item string_replace_file(filename, find, replace) + +Find and replace string of a given file. + +=cut + +sub string_replace_file +{ + my ($filename, $find, $replace) = @_; + open(my $in, '<', $filename); + my $content = ''; + while (<$in>) + { + $_ =~ s/$find/$replace/; + $content = $content . $_; + } + close $in; + open(my $out, '>', $filename); + print $out $content; + close($out); + + return; +} + +=pod + +=item check_mode_recursive(dir, expected_dir_mode, expected_file_mode, ignore_list) + +Check that all file/dir modes in a directory match the expected values, +ignoring files in C (basename only). + +=cut + +sub check_mode_recursive +{ + my ($dir, $expected_dir_mode, $expected_file_mode, $ignore_list) = @_; + + # Result defaults to true + my $result = 1; + + find( + { + follow_fast => 1, + wanted => sub { + # Is file in the ignore list? + foreach my $ignore ($ignore_list ? @{$ignore_list} : []) + { + if ("$dir/$ignore" eq $File::Find::name) + { + return; + } + } + + # Allow ENOENT. A running server can delete files, such as + # those in pg_stat. Other stat() failures are fatal. + my $file_stat = stat($File::Find::name); + unless (defined($file_stat)) + { + my $is_ENOENT = $!{ENOENT}; + my $msg = "unable to stat $File::Find::name: $!"; + if ($is_ENOENT) + { + warn $msg; + return; + } + else + { + die $msg; + } + } + + my $file_mode = S_IMODE($file_stat->mode); + + # Is this a file? + if (S_ISREG($file_stat->mode)) + { + if ($file_mode != $expected_file_mode) + { + print( + *STDERR, + sprintf("$File::Find::name mode must be %04o\n", + $expected_file_mode)); + + $result = 0; + return; + } + } + + # Else a directory? + elsif (S_ISDIR($file_stat->mode)) + { + if ($file_mode != $expected_dir_mode) + { + print( + *STDERR, + sprintf("$File::Find::name mode must be %04o\n", + $expected_dir_mode)); + + $result = 0; + return; + } + } + + # Else something we can't handle + else + { + die "unknown file type for $File::Find::name"; + } + } + }, + $dir); + + return $result; +} + +=pod + +=item chmod_recursive(dir, dir_mode, file_mode) + +C recursively each file and directory within the given directory. + +=cut + +sub chmod_recursive +{ + my ($dir, $dir_mode, $file_mode) = @_; + + find( + { + follow_fast => 1, + wanted => sub { + my $file_stat = stat($File::Find::name); + + if (defined($file_stat)) + { + chmod( + S_ISDIR($file_stat->mode) ? $dir_mode : $file_mode, + $File::Find::name + ) or die "unable to chmod $File::Find::name"; + } + } + }, + $dir); + return; +} + +=pod + +=item scan_server_header(header_path, regexp) + +Returns an array that stores all the matches of the given regular expression +within the PostgreSQL installation's C. This can be used to +retrieve specific value patterns from the installation's header files. + +=cut + +sub scan_server_header +{ + my ($header_path, $regexp) = @_; + + my ($stdout, $stderr); + my $result = IPC::Run::run [ 'pg_config', '--includedir-server' ], '>', + \$stdout, '2>', \$stderr + or die "could not execute pg_config"; + chomp($stdout); + $stdout =~ s/\r$//; + + open my $header_h, '<', "$stdout/$header_path" or die "$!"; + + my @match = undef; + while (<$header_h>) + { + my $line = $_; + + if (@match = $line =~ /^$regexp/) + { + last; + } + } + + close $header_h; + die "could not find match in header $header_path\n" + unless @match; + return @match; +} + +=pod + +=item check_pg_config(regexp) + +Return the number of matches of the given regular expression +within the installation's C. + +=cut + +sub check_pg_config +{ + my ($regexp) = @_; + my ($stdout, $stderr); + my $result = IPC::Run::run [ 'pg_config', '--includedir' ], '>', + \$stdout, '2>', \$stderr + or die "could not execute pg_config"; + chomp($stdout); + $stdout =~ s/\r$//; + + open my $pg_config_h, '<', "$stdout/pg_config.h" or die "$!"; + my $match = (grep { /^$regexp/ } <$pg_config_h>); + close $pg_config_h; + return $match; +} + +=pod + +=item dir_symlink(oldname, newname) + +Portably create a symlink for a directory. On Windows this creates a junction +point. Elsewhere it just calls perl's builtin symlink. + +=cut + +sub dir_symlink +{ + my $oldname = shift; + my $newname = shift; + if ($windows_os) + { + $oldname =~ s,/,\\,g; + $newname =~ s,/,\\,g; + my $cmd = qq{mklink /j "$newname" "$oldname"}; + if ($Config{osname} eq 'msys') + { + # need some indirection on msys + $cmd = qq{echo '$cmd' | \$COMSPEC /Q}; + } + system($cmd); + } + else + { + symlink $oldname, $newname; + } + die "No $newname" unless -e $newname; +} + +=pod + +=back + +=head1 Test::More-LIKE METHODS + +=over + +=item command_ok(cmd, test_name) + +Check that the command runs (via C) successfully. + +=cut + +sub command_ok +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd, $test_name) = @_; + my $result = run_log($cmd); + ok($result, $test_name); + return; +} + +=pod + +=item command_fails(cmd, test_name) + +Check that the command fails (when run via C). + +=cut + +sub command_fails +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd, $test_name) = @_; + my $result = run_log($cmd); + ok(!$result, $test_name); + return; +} + +=pod + +=item command_exit_is(cmd, expected, test_name) + +Check that the command exit code matches the expected exit code. + +=cut + +sub command_exit_is +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd, $expected, $test_name) = @_; + print("# Running: " . join(" ", @{$cmd}) . "\n"); + my $h = IPC::Run::start $cmd; + $h->finish(); + + # Normally, if the child called exit(N), IPC::Run::result() returns N. On + # Windows, with IPC::Run v20220807.0 and earlier, full_results() is the + # method that returns N (https://github.com/toddr/IPC-Run/issues/161). + my $result = + ($Config{osname} eq "MSWin32" && $IPC::Run::VERSION <= 20220807.0) + ? ($h->full_results)[0] + : $h->result(0); + is($result, $expected, $test_name); + return; +} + +=pod + +=item program_help_ok(cmd) + +Check that the command supports the C<--help> option. + +=cut + +sub program_help_ok +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd) = @_; + my ($stdout, $stderr); + print("# Running: $cmd --help\n"); + my $result = IPC::Run::run [ $cmd, '--help' ], '>', \$stdout, '2>', + \$stderr; + ok($result, "$cmd --help exit code 0"); + isnt($stdout, '', "$cmd --help goes to stdout"); + is($stderr, '', "$cmd --help nothing to stderr"); + return; +} + +=pod + +=item program_version_ok(cmd) + +Check that the command supports the C<--version> option. + +=cut + +sub program_version_ok +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd) = @_; + my ($stdout, $stderr); + print("# Running: $cmd --version\n"); + my $result = IPC::Run::run [ $cmd, '--version' ], '>', \$stdout, '2>', + \$stderr; + ok($result, "$cmd --version exit code 0"); + isnt($stdout, '', "$cmd --version goes to stdout"); + is($stderr, '', "$cmd --version nothing to stderr"); + return; +} + +=pod + +=item program_options_handling_ok(cmd) + +Check that a command with an invalid option returns a non-zero +exit code and error message. + +=cut + +sub program_options_handling_ok +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd) = @_; + my ($stdout, $stderr); + print("# Running: $cmd --not-a-valid-option\n"); + my $result = IPC::Run::run [ $cmd, '--not-a-valid-option' ], '>', + \$stdout, + '2>', \$stderr; + ok(!$result, "$cmd with invalid option nonzero exit code"); + isnt($stderr, '', "$cmd with invalid option prints error message"); + return; +} + +=pod + +=item command_like(cmd, expected_stdout, test_name) + +Check that the command runs successfully and the output +matches the given regular expression. + +=cut + +sub command_like +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd, $expected_stdout, $test_name) = @_; + my ($stdout, $stderr); + print("# Running: " . join(" ", @{$cmd}) . "\n"); + my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr; + ok($result, "$test_name: exit code 0"); + is($stderr, '', "$test_name: no stderr"); + like($stdout, $expected_stdout, "$test_name: matches"); + return; +} + +=pod + +=item command_like_safe(cmd, expected_stdout, test_name) + +Check that the command runs successfully and the output +matches the given regular expression. Doesn't assume that the +output files are closed. + +=cut + +sub command_like_safe +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + # Doesn't rely on detecting end of file on the file descriptors, + # which can fail, causing the process to hang, notably on Msys + # when used with 'pg_ctl start' + my ($cmd, $expected_stdout, $test_name) = @_; + my ($stdout, $stderr); + my $stdoutfile = File::Temp->new(); + my $stderrfile = File::Temp->new(); + print("# Running: " . join(" ", @{$cmd}) . "\n"); + my $result = IPC::Run::run $cmd, '>', $stdoutfile, '2>', $stderrfile; + $stdout = slurp_file($stdoutfile); + $stderr = slurp_file($stderrfile); + ok($result, "$test_name: exit code 0"); + is($stderr, '', "$test_name: no stderr"); + like($stdout, $expected_stdout, "$test_name: matches"); + return; +} + +=pod + +=item command_fails_like(cmd, expected_stderr, test_name) + +Check that the command fails and the error message matches +the given regular expression. + +=cut + +sub command_fails_like +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd, $expected_stderr, $test_name) = @_; + my ($stdout, $stderr); + print("# Running: " . join(" ", @{$cmd}) . "\n"); + my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr; + ok(!$result, "$test_name: exit code not 0"); + like($stderr, $expected_stderr, "$test_name: matches"); + return; +} + +=pod + +=item command_checks_all(cmd, ret, out, err, test_name) + +Run a command and check its status and outputs. +Arguments: + +=over + +=item C: Array reference of command and arguments to run + +=item C: Expected exit code + +=item C: Expected stdout from command + +=item C: Expected stderr from command + +=item C: test name + +=back + +=cut + +sub command_checks_all +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my ($cmd, $expected_ret, $out, $err, $test_name) = @_; + + # run command + my ($stdout, $stderr); + print("# Running: " . join(" ", @{$cmd}) . "\n"); + IPC::Run::run($cmd, '>', \$stdout, '2>', \$stderr); + + # See http://perldoc.perl.org/perlvar.html#%24CHILD_ERROR + my $ret = $?; + die "command exited with signal " . ($ret & 127) + if $ret & 127; + $ret = $ret >> 8; + + # check status + ok($ret == $expected_ret, + "$test_name status (got $ret vs expected $expected_ret)"); + + # check stdout + for my $re (@$out) + { + like($stdout, $re, "$test_name stdout /$re/"); + } + + # check stderr + for my $re (@$err) + { + like($stderr, $re, "$test_name stderr /$re/"); + } + + return; +} + +=pod + +=back + +=cut + +1; diff --git a/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Version.pm b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Version.pm new file mode 100644 index 00000000000..3705c1bdafc --- /dev/null +++ b/install/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Version.pm @@ -0,0 +1,167 @@ +############################################################################ +# +# PostgreSQL/Version.pm +# +# Module encapsulating Postgres Version numbers +# +# Copyright (c) 2021-2023, PostgreSQL Global Development Group +# +############################################################################ + +=pod + +=head1 NAME + +PostgreSQL::Version - class representing PostgreSQL version numbers + +=head1 SYNOPSIS + + use PostgreSQL::Version; + + my $version = PostgreSQL::Version->new($version_arg); + + # compare two versions + my $bool = $version1 <= $version2; + + # or compare with a number + $bool = $version < 12; + + # or with a string + $bool = $version lt "13.1"; + + # interpolate in a string + my $stringyval = "version: $version"; + + # get the major version + my $maj = $version->major; + +=head1 DESCRIPTION + +PostgreSQL::Version encapsulates Postgres version numbers, providing parsing +of common version formats and comparison operations. + +=cut + +package PostgreSQL::Version; + +use strict; +use warnings; + +use Scalar::Util qw(blessed); + +use overload + '<=>' => \&_version_cmp, + 'cmp' => \&_version_cmp, + '""' => \&_stringify; + +=pod + +=head1 METHODS + +=over + +=item PostgreSQL::Version->new($version) + +Create a new PostgreSQL::Version instance. + +The argument can be a number like 12, or a string like '12.2' or the output +of a Postgres command like `psql --version` or `pg_config --version`; + +=back + +=cut + +sub new +{ + my $class = shift; + my $arg = shift; + + chomp $arg; + + # Accept standard formats, in case caller has handed us the output of a + # postgres command line tool + my $devel; + ($arg, $devel) = ($1, $2) + if ( + $arg =~ m!^ # beginning of line + (?:\(?PostgreSQL\)?\s)? # ignore PostgreSQL marker + (\d+(?:\.\d+)*) # version number, dotted notation + (devel|(?:alpha|beta|rc)\d+)? # dev marker - see version_stamp.pl + !x); + + # Split into an array + my @numbers = split(/\./, $arg); + + # Treat development versions as having a minor/micro version one less than + # the first released version of that branch. + push @numbers, -1 if ($devel); + + $devel ||= ""; + + return bless { str => "$arg$devel", num => \@numbers }, $class; +} + +# Routine which compares the _pg_version_array obtained for the two +# arguments and returns -1, 0, or 1, allowing comparison between two +# PostgreSQL::Version objects or a PostgreSQL::Version and a version string or number. +# +# If the second argument is not a blessed object we call the constructor +# to make one. +# +# Because we're overloading '<=>' and 'cmp' this function supplies us with +# all the comparison operators ('<' and friends, 'gt' and friends) +# +sub _version_cmp +{ + my ($a, $b, $swapped) = @_; + + $b = __PACKAGE__->new($b) unless blessed($b); + + ($a, $b) = ($b, $a) if $swapped; + + my ($an, $bn) = ($a->{num}, $b->{num}); + + for (my $idx = 0;; $idx++) + { + return 0 + if ($idx >= @$an && $idx >= @$bn); + # treat a missing number as 0 + my ($anum, $bnum) = ($an->[$idx] || 0, $bn->[$idx] || 0); + return $anum <=> $bnum + if ($anum <=> $bnum); + } +} + +# Render the version number using the saved string. +sub _stringify +{ + my $self = shift; + return $self->{str}; +} + +=pod + +=over + +=item major([separator => 'char']) + +Returns the major version. For versions before 10 the parts are separated by +a dot unless the separator argument is given. + +=back + +=cut + +sub major +{ + my ($self, %params) = @_; + my $result = $self->{num}->[0]; + if ($result + 0 < 10) + { + my $sep = $params{separator} || '.'; + $result .= "$sep$self->{num}->[1]"; + } + return $result; +} + +1; diff --git a/install/lib/postgresql/pgxs/src/test/regress/pg_regress b/install/lib/postgresql/pgxs/src/test/regress/pg_regress new file mode 100755 index 00000000000..4f7870f4d9f Binary files /dev/null and b/install/lib/postgresql/pgxs/src/test/regress/pg_regress differ diff --git a/install/share/postgresql/errcodes.txt b/install/share/postgresql/errcodes.txt new file mode 100644 index 00000000000..2d3800120bc --- /dev/null +++ b/install/share/postgresql/errcodes.txt @@ -0,0 +1,913 @@ +# +# errcodes.txt +# PostgreSQL error codes +# +# Copyright (c) 2003-2023, 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 +# the same contents. +# The files generated from this one are: +# +# src/include/utils/errcodes.h +# macros defining errcode constants to be used in the rest of the source +# +# src/pl/plpgsql/src/plerrcodes.h +# a list of PL/pgSQL condition names and their SQLSTATE codes +# +# src/pl/tcl/pltclerrcodes.h +# the same, for PL/Tcl +# +# doc/src/sgml/errcodes-table.sgml +# a SGML table of error codes for inclusion in the documentation +# +# The format of this file is one error code per line, with the following +# whitespace-separated fields: +# +# sqlstate E/W/S errcode_macro_name spec_name +# +# where sqlstate is a five-character string following the SQLSTATE conventions, +# the second field indicates if the code means an error, a warning or success, +# errcode_macro_name is the C macro name starting with ERRCODE that will be put +# in errcodes.h, and spec_name is a lowercase, underscore-separated name that +# will be used as the PL/pgSQL condition name and will also be included in the +# SGML list. The last field is optional, if not present the PL/pgSQL condition +# and the SGML entry will not be generated. +# +# Empty lines and lines starting with a hash are comments. +# +# There are also special lines in the format of: +# +# Section: section description +# +# that is, lines starting with the string "Section:". They are used to delimit +# error classes as defined in the SQL spec, and are necessary for SGML output. +# +# +# SQLSTATE codes for errors. +# +# The SQL99 code set is rather impoverished, especially in the area of +# syntactical and semantic errors. We have borrowed codes from IBM's DB2 +# and invented our own codes to develop a useful code set. +# +# When adding a new code, make sure it is placed in the most appropriate +# class (the first two characters of the code value identify the class). +# The listing is organized by class to make this prominent. +# +# Each class should have a generic '000' subclass. However, +# the generic '000' subclass code should be used for an error only +# when there is not a more-specific subclass code defined. +# +# The SQL spec requires that all the elements of a SQLSTATE code be +# either digits or upper-case ASCII characters. +# +# Classes that begin with 0-4 or A-H are defined by the +# standard. Within such a class, subclass values defined by the +# standard must begin with 0-4 or A-H. To define a new error code, +# ensure that it is either in an "implementation-defined class" (it +# begins with 5-9 or I-Z), or its subclass falls outside the range of +# error codes that could be present in future versions of the +# standard (i.e. the subclass value begins with 5-9 or I-Z). +# +# The convention is that new error codes defined by PostgreSQL in a +# class defined by the standard have a subclass value that begins +# with 'P'. In addition, error codes defined by PostgreSQL clients +# (such as ecpg) have a class value that begins with 'Y'. +# +# PGRAC MODIFICATIONS +# Modified by: SqlRush +# Stage: 0.12 +# +# Added 45 cluster error codes spanning 8 PG classes (08, 40, 53, +# 55, 57, 58, 72, XX). All pgrac codes use the 'R' subclass +# character (third position of the SQLSTATE), which is reserved +# here as the pgrac namespace and never conflicts with the standard +# ('0'-'4', 'A'-'H'), with PG-defined codes ('P' subclass), or with +# PG client codes ('Y' class). +# +# Each PG class containing pgrac codes is followed by a separate +# "(pgrac extension)" sub-section so that the SGML doc generator +# groups pgrac codes immediately after the matching PG class. +# +# Stage 0.12 only registers the codes; ereport() call sites land in +# the spec for each owning subsystem (Stage 1+). +# +# Related design: +# docs/error-codes-design.md v1.1 §3 / §7.3 +# specs/spec-0.12-error-codes-framework.md + +Section: Class 00 - Successful Completion + +00000 S ERRCODE_SUCCESSFUL_COMPLETION successful_completion + +Section: Class 01 - Warning + +# do not use this class for failure conditions +01000 W ERRCODE_WARNING warning +0100C W ERRCODE_WARNING_DYNAMIC_RESULT_SETS_RETURNED dynamic_result_sets_returned +01008 W ERRCODE_WARNING_IMPLICIT_ZERO_BIT_PADDING implicit_zero_bit_padding +01003 W ERRCODE_WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION null_value_eliminated_in_set_function +01007 W ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED privilege_not_granted +01006 W ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED privilege_not_revoked +01004 W ERRCODE_WARNING_STRING_DATA_RIGHT_TRUNCATION string_data_right_truncation +01P01 W ERRCODE_WARNING_DEPRECATED_FEATURE deprecated_feature + +Section: Class 02 - No Data (this is also a warning class per the SQL standard) + +# do not use this class for failure conditions +02000 W ERRCODE_NO_DATA no_data +02001 W ERRCODE_NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED no_additional_dynamic_result_sets_returned + +Section: Class 03 - SQL Statement Not Yet Complete + +03000 E ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE sql_statement_not_yet_complete + +Section: Class 08 - Connection Exception + +08000 E ERRCODE_CONNECTION_EXCEPTION connection_exception +08003 E ERRCODE_CONNECTION_DOES_NOT_EXIST connection_does_not_exist +08006 E ERRCODE_CONNECTION_FAILURE connection_failure +08001 E ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION sqlclient_unable_to_establish_sqlconnection +08004 E ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION sqlserver_rejected_establishment_of_sqlconnection +08007 E ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN transaction_resolution_unknown +08P01 E ERRCODE_PROTOCOL_VIOLATION protocol_violation + +Section: Class 08 - Connection Exception (pgrac extension) + +08R01 E ERRCODE_CLUSTER_NODE_UNREACHABLE cluster_node_unreachable +08R02 E ERRCODE_CLUSTER_NODE_EVICTED cluster_node_evicted +08R03 E ERRCODE_CLUSTER_JOIN_FAILED cluster_join_failed +08R04 E ERRCODE_CLUSTER_INTERCONNECT_LOST cluster_interconnect_lost +08R05 E ERRCODE_CLUSTER_PROTOCOL_VERSION_MISMATCH cluster_protocol_version_mismatch + +Section: Class 09 - Triggered Action Exception + +09000 E ERRCODE_TRIGGERED_ACTION_EXCEPTION triggered_action_exception + +Section: Class 0A - Feature Not Supported + +0A000 E ERRCODE_FEATURE_NOT_SUPPORTED feature_not_supported + +Section: Class 0B - Invalid Transaction Initiation + +0B000 E ERRCODE_INVALID_TRANSACTION_INITIATION invalid_transaction_initiation + +Section: Class 0F - Locator Exception + +0F000 E ERRCODE_LOCATOR_EXCEPTION locator_exception +0F001 E ERRCODE_L_E_INVALID_SPECIFICATION invalid_locator_specification + +Section: Class 0L - Invalid Grantor + +0L000 E ERRCODE_INVALID_GRANTOR invalid_grantor +0LP01 E ERRCODE_INVALID_GRANT_OPERATION invalid_grant_operation + +Section: Class 0P - Invalid Role Specification + +0P000 E ERRCODE_INVALID_ROLE_SPECIFICATION invalid_role_specification + +Section: Class 0Z - Diagnostics Exception + +0Z000 E ERRCODE_DIAGNOSTICS_EXCEPTION diagnostics_exception +0Z002 E ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER stacked_diagnostics_accessed_without_active_handler + +Section: Class 20 - Case Not Found + +20000 E ERRCODE_CASE_NOT_FOUND case_not_found + +Section: Class 21 - Cardinality Violation + +# this means something returned the wrong number of rows +21000 E ERRCODE_CARDINALITY_VIOLATION cardinality_violation + +Section: Class 22 - Data Exception + +22000 E ERRCODE_DATA_EXCEPTION data_exception +2202E E ERRCODE_ARRAY_ELEMENT_ERROR +# SQL99's actual definition of "array element error" is subscript error +2202E E ERRCODE_ARRAY_SUBSCRIPT_ERROR array_subscript_error +22021 E ERRCODE_CHARACTER_NOT_IN_REPERTOIRE character_not_in_repertoire +22008 E ERRCODE_DATETIME_FIELD_OVERFLOW datetime_field_overflow +22008 E ERRCODE_DATETIME_VALUE_OUT_OF_RANGE +22012 E ERRCODE_DIVISION_BY_ZERO division_by_zero +22005 E ERRCODE_ERROR_IN_ASSIGNMENT error_in_assignment +2200B E ERRCODE_ESCAPE_CHARACTER_CONFLICT escape_character_conflict +22022 E ERRCODE_INDICATOR_OVERFLOW indicator_overflow +22015 E ERRCODE_INTERVAL_FIELD_OVERFLOW interval_field_overflow +2201E E ERRCODE_INVALID_ARGUMENT_FOR_LOG invalid_argument_for_logarithm +22014 E ERRCODE_INVALID_ARGUMENT_FOR_NTILE invalid_argument_for_ntile_function +22016 E ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE invalid_argument_for_nth_value_function +2201F E ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION invalid_argument_for_power_function +2201G E ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION invalid_argument_for_width_bucket_function +22018 E ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST invalid_character_value_for_cast +22007 E ERRCODE_INVALID_DATETIME_FORMAT invalid_datetime_format +22019 E ERRCODE_INVALID_ESCAPE_CHARACTER invalid_escape_character +2200D E ERRCODE_INVALID_ESCAPE_OCTET invalid_escape_octet +22025 E ERRCODE_INVALID_ESCAPE_SEQUENCE invalid_escape_sequence +22P06 E ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER nonstandard_use_of_escape_character +22010 E ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE invalid_indicator_parameter_value +22023 E ERRCODE_INVALID_PARAMETER_VALUE invalid_parameter_value +22013 E ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE invalid_preceding_or_following_size +2201B E ERRCODE_INVALID_REGULAR_EXPRESSION invalid_regular_expression +2201W E ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE invalid_row_count_in_limit_clause +2201X E ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE invalid_row_count_in_result_offset_clause +2202H E ERRCODE_INVALID_TABLESAMPLE_ARGUMENT invalid_tablesample_argument +2202G E ERRCODE_INVALID_TABLESAMPLE_REPEAT invalid_tablesample_repeat +22009 E ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE invalid_time_zone_displacement_value +2200C E ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER invalid_use_of_escape_character +2200G E ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH most_specific_type_mismatch +22004 E ERRCODE_NULL_VALUE_NOT_ALLOWED null_value_not_allowed +22002 E ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER null_value_no_indicator_parameter +22003 E ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE numeric_value_out_of_range +2200H E ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED sequence_generator_limit_exceeded +22026 E ERRCODE_STRING_DATA_LENGTH_MISMATCH string_data_length_mismatch +22001 E ERRCODE_STRING_DATA_RIGHT_TRUNCATION string_data_right_truncation +22011 E ERRCODE_SUBSTRING_ERROR substring_error +22027 E ERRCODE_TRIM_ERROR trim_error +22024 E ERRCODE_UNTERMINATED_C_STRING unterminated_c_string +2200F E ERRCODE_ZERO_LENGTH_CHARACTER_STRING zero_length_character_string +22P01 E ERRCODE_FLOATING_POINT_EXCEPTION floating_point_exception +22P02 E ERRCODE_INVALID_TEXT_REPRESENTATION invalid_text_representation +22P03 E ERRCODE_INVALID_BINARY_REPRESENTATION invalid_binary_representation +22P04 E ERRCODE_BAD_COPY_FILE_FORMAT bad_copy_file_format +22P05 E ERRCODE_UNTRANSLATABLE_CHARACTER untranslatable_character +2200L E ERRCODE_NOT_AN_XML_DOCUMENT not_an_xml_document +2200M E ERRCODE_INVALID_XML_DOCUMENT invalid_xml_document +2200N E ERRCODE_INVALID_XML_CONTENT invalid_xml_content +2200S E ERRCODE_INVALID_XML_COMMENT invalid_xml_comment +2200T E ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION invalid_xml_processing_instruction +22030 E ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE duplicate_json_object_key_value +22031 E ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION invalid_argument_for_sql_json_datetime_function +22032 E ERRCODE_INVALID_JSON_TEXT invalid_json_text +22033 E ERRCODE_INVALID_SQL_JSON_SUBSCRIPT invalid_sql_json_subscript +22034 E ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM more_than_one_sql_json_item +22035 E ERRCODE_NO_SQL_JSON_ITEM no_sql_json_item +22036 E ERRCODE_NON_NUMERIC_SQL_JSON_ITEM non_numeric_sql_json_item +22037 E ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT non_unique_keys_in_a_json_object +22038 E ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED singleton_sql_json_item_required +22039 E ERRCODE_SQL_JSON_ARRAY_NOT_FOUND sql_json_array_not_found +2203A E ERRCODE_SQL_JSON_MEMBER_NOT_FOUND sql_json_member_not_found +2203B E ERRCODE_SQL_JSON_NUMBER_NOT_FOUND sql_json_number_not_found +2203C E ERRCODE_SQL_JSON_OBJECT_NOT_FOUND sql_json_object_not_found +2203D E ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS too_many_json_array_elements +2203E E ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS too_many_json_object_members +2203F E ERRCODE_SQL_JSON_SCALAR_REQUIRED sql_json_scalar_required +2203G E ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE sql_json_item_cannot_be_cast_to_target_type + +Section: Class 23 - Integrity Constraint Violation + +23000 E ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION integrity_constraint_violation +23001 E ERRCODE_RESTRICT_VIOLATION restrict_violation +23502 E ERRCODE_NOT_NULL_VIOLATION not_null_violation +23503 E ERRCODE_FOREIGN_KEY_VIOLATION foreign_key_violation +23505 E ERRCODE_UNIQUE_VIOLATION unique_violation +23514 E ERRCODE_CHECK_VIOLATION check_violation +23P01 E ERRCODE_EXCLUSION_VIOLATION exclusion_violation + +Section: Class 24 - Invalid Cursor State + +24000 E ERRCODE_INVALID_CURSOR_STATE invalid_cursor_state + +Section: Class 25 - Invalid Transaction State + +25000 E ERRCODE_INVALID_TRANSACTION_STATE invalid_transaction_state +25001 E ERRCODE_ACTIVE_SQL_TRANSACTION active_sql_transaction +25002 E ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE branch_transaction_already_active +25008 E ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL held_cursor_requires_same_isolation_level +25003 E ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION inappropriate_access_mode_for_branch_transaction +25004 E ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION inappropriate_isolation_level_for_branch_transaction +25005 E ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION no_active_sql_transaction_for_branch_transaction +25006 E ERRCODE_READ_ONLY_SQL_TRANSACTION read_only_sql_transaction +25007 E ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED schema_and_data_statement_mixing_not_supported +25P01 E ERRCODE_NO_ACTIVE_SQL_TRANSACTION no_active_sql_transaction +25P02 E ERRCODE_IN_FAILED_SQL_TRANSACTION in_failed_sql_transaction +25P03 E ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT idle_in_transaction_session_timeout + +Section: Class 26 - Invalid SQL Statement Name + +# (we take this to mean prepared statements +26000 E ERRCODE_INVALID_SQL_STATEMENT_NAME invalid_sql_statement_name + +Section: Class 27 - Triggered Data Change Violation + +27000 E ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION triggered_data_change_violation + +Section: Class 28 - Invalid Authorization Specification + +28000 E ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION invalid_authorization_specification +28P01 E ERRCODE_INVALID_PASSWORD invalid_password + +Section: Class 2B - Dependent Privilege Descriptors Still Exist + +2B000 E ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST dependent_privilege_descriptors_still_exist +2BP01 E ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST dependent_objects_still_exist + +Section: Class 2D - Invalid Transaction Termination + +2D000 E ERRCODE_INVALID_TRANSACTION_TERMINATION invalid_transaction_termination + +Section: Class 2F - SQL Routine Exception + +2F000 E ERRCODE_SQL_ROUTINE_EXCEPTION sql_routine_exception +2F005 E ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT function_executed_no_return_statement +2F002 E ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED modifying_sql_data_not_permitted +2F003 E ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED prohibited_sql_statement_attempted +2F004 E ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED reading_sql_data_not_permitted + +Section: Class 34 - Invalid Cursor Name + +34000 E ERRCODE_INVALID_CURSOR_NAME invalid_cursor_name + +Section: Class 38 - External Routine Exception + +38000 E ERRCODE_EXTERNAL_ROUTINE_EXCEPTION external_routine_exception +38001 E ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED containing_sql_not_permitted +38002 E ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED modifying_sql_data_not_permitted +38003 E ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED prohibited_sql_statement_attempted +38004 E ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED reading_sql_data_not_permitted + +Section: Class 39 - External Routine Invocation Exception + +39000 E ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION external_routine_invocation_exception +39001 E ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED invalid_sqlstate_returned +39004 E ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED null_value_not_allowed +39P01 E ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED trigger_protocol_violated +39P02 E ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED srf_protocol_violated +39P03 E ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED event_trigger_protocol_violated + +Section: Class 3B - Savepoint Exception + +3B000 E ERRCODE_SAVEPOINT_EXCEPTION savepoint_exception +3B001 E ERRCODE_S_E_INVALID_SPECIFICATION invalid_savepoint_specification + +Section: Class 3D - Invalid Catalog Name + +3D000 E ERRCODE_INVALID_CATALOG_NAME invalid_catalog_name + +Section: Class 3F - Invalid Schema Name + +3F000 E ERRCODE_INVALID_SCHEMA_NAME invalid_schema_name + +Section: Class 40 - Transaction Rollback + +40000 E ERRCODE_TRANSACTION_ROLLBACK transaction_rollback +40002 E ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION transaction_integrity_constraint_violation +40001 E ERRCODE_T_R_SERIALIZATION_FAILURE serialization_failure +40003 E ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN statement_completion_unknown +40P01 E ERRCODE_T_R_DEADLOCK_DETECTED deadlock_detected + +Section: Class 40 - Transaction Rollback (pgrac extension) + +40R01 E ERRCODE_CLUSTER_RECONFIG_ABORT cluster_reconfig_abort +40R02 E ERRCODE_CLUSTER_ISOLATION_FAILED cluster_isolation_failed +40R03 E ERRCODE_CLUSTER_CACHE_FUSION_RETRY cluster_cache_fusion_retry +40R04 E ERRCODE_CLUSTER_PI_INVALIDATED_RETRY cluster_pi_invalidated_retry + +Section: Class 42 - Syntax Error or Access Rule Violation + +42000 E ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION syntax_error_or_access_rule_violation +# never use the above; use one of these two if no specific code exists: +42601 E ERRCODE_SYNTAX_ERROR syntax_error +42501 E ERRCODE_INSUFFICIENT_PRIVILEGE insufficient_privilege +42846 E ERRCODE_CANNOT_COERCE cannot_coerce +42803 E ERRCODE_GROUPING_ERROR grouping_error +42P20 E ERRCODE_WINDOWING_ERROR windowing_error +42P19 E ERRCODE_INVALID_RECURSION invalid_recursion +42830 E ERRCODE_INVALID_FOREIGN_KEY invalid_foreign_key +42602 E ERRCODE_INVALID_NAME invalid_name +42622 E ERRCODE_NAME_TOO_LONG name_too_long +42939 E ERRCODE_RESERVED_NAME reserved_name +42804 E ERRCODE_DATATYPE_MISMATCH datatype_mismatch +42P18 E ERRCODE_INDETERMINATE_DATATYPE indeterminate_datatype +42P21 E ERRCODE_COLLATION_MISMATCH collation_mismatch +42P22 E ERRCODE_INDETERMINATE_COLLATION indeterminate_collation +42809 E ERRCODE_WRONG_OBJECT_TYPE wrong_object_type +428C9 E ERRCODE_GENERATED_ALWAYS generated_always + +# Note: for ERRCODE purposes, we divide namable objects into these categories: +# databases, schemas, prepared statements, cursors, tables, columns, +# functions (including operators), and all else (lumped as "objects"). +# (The first four categories are mandated by the existence of separate +# SQLSTATE classes for them in the spec; in this file, however, we group +# the ERRCODE names with all the rest under class 42.) Parameters are +# sort-of-named objects and get their own ERRCODE. +# +# The same breakdown is used for "duplicate" and "ambiguous" complaints, +# as well as complaints associated with incorrect declarations. + +42703 E ERRCODE_UNDEFINED_COLUMN undefined_column +34000 E ERRCODE_UNDEFINED_CURSOR +3D000 E ERRCODE_UNDEFINED_DATABASE +42883 E ERRCODE_UNDEFINED_FUNCTION undefined_function +26000 E ERRCODE_UNDEFINED_PSTATEMENT +3F000 E ERRCODE_UNDEFINED_SCHEMA +42P01 E ERRCODE_UNDEFINED_TABLE undefined_table +42P02 E ERRCODE_UNDEFINED_PARAMETER undefined_parameter +42704 E ERRCODE_UNDEFINED_OBJECT undefined_object +42701 E ERRCODE_DUPLICATE_COLUMN duplicate_column +42P03 E ERRCODE_DUPLICATE_CURSOR duplicate_cursor +42P04 E ERRCODE_DUPLICATE_DATABASE duplicate_database +42723 E ERRCODE_DUPLICATE_FUNCTION duplicate_function +42P05 E ERRCODE_DUPLICATE_PSTATEMENT duplicate_prepared_statement +42P06 E ERRCODE_DUPLICATE_SCHEMA duplicate_schema +42P07 E ERRCODE_DUPLICATE_TABLE duplicate_table +42712 E ERRCODE_DUPLICATE_ALIAS duplicate_alias +42710 E ERRCODE_DUPLICATE_OBJECT duplicate_object +42702 E ERRCODE_AMBIGUOUS_COLUMN ambiguous_column +42725 E ERRCODE_AMBIGUOUS_FUNCTION ambiguous_function +42P08 E ERRCODE_AMBIGUOUS_PARAMETER ambiguous_parameter +42P09 E ERRCODE_AMBIGUOUS_ALIAS ambiguous_alias +42P10 E ERRCODE_INVALID_COLUMN_REFERENCE invalid_column_reference +42611 E ERRCODE_INVALID_COLUMN_DEFINITION invalid_column_definition +42P11 E ERRCODE_INVALID_CURSOR_DEFINITION invalid_cursor_definition +42P12 E ERRCODE_INVALID_DATABASE_DEFINITION invalid_database_definition +42P13 E ERRCODE_INVALID_FUNCTION_DEFINITION invalid_function_definition +42P14 E ERRCODE_INVALID_PSTATEMENT_DEFINITION invalid_prepared_statement_definition +42P15 E ERRCODE_INVALID_SCHEMA_DEFINITION invalid_schema_definition +42P16 E ERRCODE_INVALID_TABLE_DEFINITION invalid_table_definition +42P17 E ERRCODE_INVALID_OBJECT_DEFINITION invalid_object_definition + +Section: Class 44 - WITH CHECK OPTION Violation + +44000 E ERRCODE_WITH_CHECK_OPTION_VIOLATION with_check_option_violation + +Section: Class 53 - Insufficient Resources + +# (PostgreSQL-specific error class) +53000 E ERRCODE_INSUFFICIENT_RESOURCES insufficient_resources +53100 E ERRCODE_DISK_FULL disk_full +53200 E ERRCODE_OUT_OF_MEMORY out_of_memory +53300 E ERRCODE_TOO_MANY_CONNECTIONS too_many_connections +53400 E ERRCODE_CONFIGURATION_LIMIT_EXCEEDED configuration_limit_exceeded + +Section: Class 53 - Insufficient Resources (pgrac extension) + +53R01 E ERRCODE_CLUSTER_LMS_QUEUE_FULL cluster_lms_queue_full +53R02 E ERRCODE_CLUSTER_GRD_FULL cluster_grd_full +53R03 E ERRCODE_CLUSTER_UNDO_EXHAUSTED cluster_undo_exhausted +53R04 E ERRCODE_CLUSTER_PI_CHAIN_FULL cluster_pi_chain_full +53R05 E ERRCODE_CLUSTER_CR_CHAIN_FULL cluster_cr_chain_full +53R06 E ERRCODE_CLUSTER_RECOVERY_WORKERS_EXHAUSTED cluster_recovery_workers_exhausted +53R07 E ERRCODE_CLUSTER_RECONFIG_QUORUM_LOST cluster_reconfig_quorum_lost +53R08 E ERRCODE_CLUSTER_PHASE_TRANSITION_TIMEOUT cluster_phase_transition_timeout +53R09 E ERRCODE_CLUSTER_PHASE_PRECONDITION_FAILED cluster_phase_precondition_failed +53R0A E ERRCODE_CLUSTER_LMON_SPAWN_FAILED cluster_lmon_spawn_failed +53R0B E ERRCODE_CLUSTER_LMON_NOT_READY cluster_lmon_not_ready +53R0C E ERRCODE_CLUSTER_LCK_SPAWN_FAILED cluster_lck_spawn_failed +53R0D E ERRCODE_CLUSTER_LCK_NOT_READY cluster_lck_not_ready +53R0E E ERRCODE_CLUSTER_DIAG_SPAWN_FAILED cluster_diag_spawn_failed +53R0F E ERRCODE_CLUSTER_DIAG_NOT_READY cluster_diag_not_ready +53R10 E ERRCODE_CLUSTER_STATS_SPAWN_FAILED cluster_stats_spawn_failed +53R11 E ERRCODE_CLUSTER_STATS_NOT_READY cluster_stats_not_ready +53R12 E ERRCODE_CLUSTER_SCN_WRAPAROUND_PANIC cluster_scn_wraparound_panic +53R20 E ERRCODE_CLUSTER_IC_STALE_EPOCH_DROP cluster_ic_stale_epoch_drop +53R21 E ERRCODE_CLUSTER_IC_CHUNK_REASSEMBLY_TIMEOUT cluster_ic_chunk_reassembly_timeout +53R30 E ERRCODE_CLUSTER_CSSD_SPAWN_FAILED cluster_cssd_spawn_failed +53R31 E ERRCODE_CLUSTER_CSSD_NOT_READY cluster_cssd_not_ready +53R32 E ERRCODE_CLUSTER_CSSD_PEER_SUSPECTED cluster_cssd_peer_suspected +53R33 E ERRCODE_CLUSTER_CSSD_PEER_DEAD cluster_cssd_peer_dead + +# spec-2.6 Sprint A Step 3 D13 hoisted forward — voting disk quorum +# 4 NEW SQLSTATE under 53R namespace (53R40-43). 53 = INSUFFICIENT +# RESOURCES PG-defined class;R = pgrac extension subclass;40-49 = +# quorum / fail-closed (NEW). 53R40 NOT alias to 40001 SerializationFailure +# per Q5 v0.2 — client retry pattern is fundamentally different. +53R40 E ERRCODE_CLUSTER_QUORUM_LOST cluster_quorum_lost +53R41 E ERRCODE_CLUSTER_QUORUM_UNCERTAIN cluster_quorum_uncertain +53R42 E ERRCODE_CLUSTER_VOTING_DISK_IO_FAILURE cluster_voting_disk_io_failure +53R43 E ERRCODE_CLUSTER_NODE_ID_COLLISION cluster_node_id_collision +53R44 E ERRCODE_CLUSTER_QVOTEC_SPAWN_FAILED cluster_qvotec_spawn_failed +53R45 E ERRCODE_CLUSTER_QVOTEC_NOT_READY cluster_qvotec_not_ready + +# spec-2.28 Sprint A Step 2 D4 (D8 partial) — fence-lite in-flight tx +# abort path. 53R50 ≠ 53R40 by design (Q4 user approve): 53R40 is +# CommitTransaction commit-gate path (spec-2.6 v0.14.1+); 53R50 is +# ProcessInterrupts in-flight ProcSignal abort path (spec-2.28 §3.7 +# C4 read-clear-then-decide). Distinct error codes let log analysis + +# client retry logic distinguish "tx start blocked at commit" vs "tx +# aborted mid-flight by fence broadcast". 53R51-59 reserved for +# future fence / backend fail-closed variants. +53R50 E ERRCODE_CLUSTER_QUORUM_LOST_BACKEND cluster_quorum_lost_backend + +# spec-4.12 D5 — cooperative write-fence hot-path reject. A shared-storage +# write (cluster_smgr create/unlink/extend/zeroextend/write/truncate) was +# refused because this node failed the write-fence token: stale epoch / +# expired lease / self-fenced. Non-critical-section callers get this +# catchable ERROR (recovery PG_TRY harness downgrades it to BLOCKED); +# critical-section callers PANIC instead (cannot ERROR). +53R51 E ERRCODE_CLUSTER_WRITE_FENCED cluster_write_fenced + +# spec-2.29 D8 — retry-safe backend abort for in-flight membership +# reconfig / epoch transition. 53R60 is intentionally separate from +# 53R40 commit-boundary quorum loss and 53R50 fence/quorum-loss backend +# abort so clients can pick distinct retry policy. +53R60 E ERRCODE_CLUSTER_RECONFIG_IN_PROGRESS cluster_reconfig_in_progress + +# spec-2.16 D14: GES cross-node grant timeout / pending HTAB full +# 53R70 fires when backend wait exceeds cluster.ges_request_timeout_ms +# (v0.5 P1.5 effective_timeout helper). 53R71 fires when pending HTAB +# capacity is reached (spec-2.16 v0.4 P1.7 caller-side). +53R70 E ERRCODE_CLUSTER_GES_TIMEOUT cluster_ges_timeout +53R71 E ERRCODE_CLUSTER_GES_PENDING_FULL cluster_ges_pending_full + +# spec-2.17 D29: cross-node deadlock + pending CANCEL semantics +# 53R72 fires when cross-node deadlock detector selects this backend as +# victim (P2.2 deterministic age-based tuple). 53R73 fires when backend +#退出 WaitOnLock 时 reservation 已 insert 但 holder 未 promote(P1.4 v0.6 — +# pending vs granted CANCEL 路径独立)。 +53R72 E ERRCODE_CLUSTER_GES_DEADLOCK cluster_ges_deadlock +53R73 E ERRCODE_CLUSTER_GES_CANCEL_PENDING cluster_ges_cancel_pending + +# spec-5.3 D4: illegal GES lock conversion. 53R74 fires when the +# opcode-2 CONVERT state machine (TM table-lock S->X upgrade, the first +# live convert consumer) is asked for a non-partial-order conversion +# (LATERAL / incomparable modes) or against a (node,procno,current_mode) +# holder the master has no record of. The master replies REJECT with +# GES_REJECT_REASON_ILLEGAL_CONVERT and the requester maps it here. +53R74 E ERRCODE_CLUSTER_GES_ILLEGAL_LOCK_CONVERSION cluster_ges_illegal_lock_conversion + +# spec-2.20 D12 (v0.3 frozen): LMS unavailable fail-closed (mirror 53R81). +# Raised by spec-2.20 7-step caller-side gate when cluster.lms_enabled=on +# but cluster_lms_is_ready() returns false (LMS state != READY). +# Caller naturally retries / rolls back (PG canonical retry pattern). +53R80 E ERRCODE_CLUSTER_LMS_UNAVAILABLE cluster_lms_unavailable + +# spec-2.19 D12: LMD unavailable fail-closed (HC1 / v0.2 P1.3) +# 53R81 fires when backend caller-side deadlock detection path needs LMD +# ownership (cluster.lmd_enabled = on) but cluster_lmd_is_ready() returns +# false — i.e. LMD state is NOT_STARTED / STARTING / DRAINING / STOPPED / +# CRASHED. enabled=off → caller-side legacy path (PGC_POSTMASTER restart +# only). Backend recovers via natural retry / rollback (类 spec-2.16 53R70 +# cluster_ges_timeout pattern;L116 / L120 family). +53R81 E ERRCODE_CLUSTER_LMD_UNAVAILABLE cluster_lmd_unavailable + +# spec-2.22 D11 (HC12 fail-closed): LMD wait-for graph edge table full. +# Caller submitting wait edge sees false return from +# cluster_lmd_submit_wait_edge_real() — wait edges invisible to PG-native +# deadlock detector,so falling back to PG local deadlock_timeout would be +# blind wait (severely disallowed,esp. once cluster.ges_request_timeout_ms +# = -1 spec-2.26 ships). Caller走 S7 cleanup + ereport(53R82). +53R82 E ERRCODE_CLUSTER_LMD_WAIT_EDGE_FULL cluster_lmd_wait_edge_full + +# spec-2.25 D10 (HC32 fail-closed): per-node native-lock probe retry budget +# exhausted before all peer nodes responded CLEAR. LMS aggregates probe replies +# (3-state CLEAR/HOLDER_CONFLICT/WAITER_CONFLICT) over N-1 peers; any non-CLEAR +# or timeout defers grant and retries every cluster.lms_native_lock_probe_retry_interval_ms. +# Cumulative retry_count >= cluster.lms_native_lock_probe_retry_budget (default +# 60 ≈ 30s) → caller ereport(53R83); client retries the failing DDL or aborts. +53R83 E ERRCODE_CLUSTER_NATIVE_LOCK_PROBE_TIMEOUT cluster_native_lock_probe_timeout + +# spec-2.34 D9 (HC98): GCS block reliability hardening retransmit budget +# exhaustion. Sender exhausts cluster.gcs_block_retransmit_max_retries +# (default 4 retries, 100/200/400/800 ms exponential backoff) without a +# valid reply → caller ereport(53R90). Distinct from ERRCODE_QUERY_CANCELED +# so ops can distinguish GCS reliability failure from backend cancellation. +53R90 E ERRCODE_CLUSTER_GCS_BLOCK_RETRANSMIT_EXHAUSTED cluster_gcs_block_retransmit_exhausted + +# spec-2.36 D8 (HC116): GCS block 3-way invalidate broadcast ack collection +# timeout. Master could not collect INVALIDATE_ACK msg_type 18 from all S/X +# holders enumerated from s_holders_bitmap within retransmit budget; master +# replies DENIED_INVALIDATE_TIMEOUT to original X requester; sender backend +# maps reply status 11 to ereport(53R91). +53R91 E ERRCODE_CLUSTER_GCS_BLOCK_INVALIDATE_TIMEOUT cluster_gcs_block_invalidate_timeout + +# spec-2.36 D8 (HC117): reader starvation guard retry budget exhaustion. +# Reader backend sees DENIED_PENDING_X (HC117 S barrier) and exponential- +# backoffs per cluster.gcs_block_starvation_max_retries (default 8 retries, +# 100 × 2^attempt ms); budget exhausted → ereport(53R92) so reader's +# upper-layer transaction can retry or abort. +53R92 E ERRCODE_CLUSTER_GCS_BLOCK_STARVATION_EXHAUSTED cluster_gcs_block_starvation_exhausted + +# spec-2.37 D11 (HC129/HC131): PI watermark + lost-write detection. +# Master direct ship 自校 OR holder forward validate 发现 shipped block. +# page_lsn < GrdEntry.pi_watermark_lsn (master) 或 GcsBlockForwardPayload. +# expected_pi_watermark_lsn (holder),reply.status = DENIED_LOST_WRITE = 12. +# Sender HC131 仅映射:无论 master 自校 OR holder 校 失败,sender 收到该 +# status → ereport(53R93) terminal denial. Lost-write 是 data integrity +# issue,不 retry 掩盖;business 必须重新读 or 上层 retry whole statement. +53R93 E ERRCODE_CLUSTER_LOST_WRITE_DETECTED cluster_lost_write_detected + +# spec-2.38 D8 (HC134): SI Broadcaster outbound queue full fail-closed. +# Caller of cluster_sinval_enqueue_batch() receives false return (queue at +# capacity); spec-2.39 production DDL hook path will ereport(53R94) to +# abort the DDL transaction. Inbound queue full takes a different fail- +# safe path (SIResetAll on SI Broadcaster aux process), not 53R94. +53R94 E ERRCODE_CLUSTER_SINVAL_QUEUE_FULL cluster_sinval_queue_full + +# PGRAC spec-2.39 D11: ERRCODE_CLUSTER_SINVAL_ACK_TIMEOUT — DDL commit hook +# called cluster_sinval_enqueue_and_wait_ack and one or more declared+CSSD- +# ALIVE peers未 ACK within cluster.sinval_ack_timeout_ms (default 5s). WARN +# path only (DDL already committed locally + WAL flushed, no rollback). +# Sender bumps ack_timeout_count;DBA monitors via pg_stat_cluster_counters. +53R95 E ERRCODE_CLUSTER_SINVAL_ACK_TIMEOUT cluster_sinval_ack_timeout + +# spec-3.1 D6 evict fail defensive (placeholder; not currently reachable). +53R96 E ERRCODE_CLUSTER_TT_OVERLAY_FULL cluster_tt_overlay_full + +# spec-3.2 D5 — HeapTupleSatisfiesMVCC cluster path lookup miss. Caller +# decides retry / abort. L177 fail-fast no wait policy enforces this is +# raised synchronously without waiting on wire propagation. +53R97 E ERRCODE_CLUSTER_TT_STATUS_UNKNOWN cluster_tt_status_unknown + +# spec-3.4d Q1 (v0.2 F1+F3 P0): heap_lock_tuple / HeapTupleSatisfiesUpdate +# detects remote ACTIVE row lock (via raw_xmax ITL scan + exact-key TT +# lookup) and caller's wait_policy == LockWaitBlock. Cross-node block-wait +# is not supported in spec-3.4d; errhint forward-links to spec-5.2 GES TX. +# LockWaitSkip -> TM_WouldBlock (no ERROR); LockWaitError -> existing +# ERRCODE_LOCK_NOT_AVAILABLE. L199 NEW lesson — remote ACTIVE must fail +# closed, never silent PG-native fallback. +53R98 E ERRCODE_CLUSTER_REMOTE_ROW_LOCK_WAIT_NOT_SUPPORTED cluster_remote_row_lock_wait_not_supported +53R9H E ERRCODE_CLUSTER_CROSS_NODE_WRITE_CONFLICT cluster_cross_node_write_conflict + +# spec-3.4d Q5 (v0.2 F4 P1): heap_lock_tuple peer mode + final xmax (after +# compute_new_xmax_infomask) is a MultiXact. MULTIXACT cross-node row lock +# support is deferred to spec-3.5+. cluster_multixact_lock_reject_count +# counter is incremented. +53R99 E ERRCODE_CLUSTER_MULTIXACT_LOCK_NOT_SUPPORTED cluster_multixact_lock_not_supported + +# spec-3.4d Q5 (v0.2 F7 P1): heap_lock_tuple peer mode cannot allocate ITL +# slot (8 slot shared with data ITL is full). Distinct from 53R94 +# cluster_sinval_queue_full (sinval semantics). cluster_itl_overflow_lock_count +# counter is incremented. Raise INITRANS or wait for spec-3.5+ split capacity. +53R9A E ERRCODE_CLUSTER_ITL_SLOT_OVERFLOW cluster_itl_slot_overflow + +# spec-3.5 HW1 P0 fail-closed guard: PREPARE TRANSACTION 不允许 carry +# active cluster SUBTRANS state. 本 spec 不实现 COMMIT PREPARED final +# emit; 允许 prepare 后会留 cross-node `SUBCOMMITTED → parent unknown` +# correctness bug. errhint forward-link 独立 2PC spec. +53R9B E ERRCODE_PREPARE_TRANSACTION_WITH_CLUSTER_SUBTRANS_STATE prepare_transaction_with_cluster_subtrans_state + +# spec-3.6 v0.3: reader sees remote MultiXact xmax but cluster overlay +# lookup miss / overflow / authoritative UNKNOWN. Per L199 cross-node +# fall-through → fail-closed (NOT PG-native SLRU fallback). errhint +# directs caller retry after origin re-emit; on-demand re-emit 推 +# spec-3.6b/3.7. IN_PROGRESS authoritative state NOT in this class +# (per OBS-1 truth table: 走 VISIBLE 路径). +53R9C E ERRCODE_CLUSTER_MULTIXACT_MEMBER_OVERLAY_MISS cluster_multixact_member_overlay_miss + +# spec-3.7 v0.3 D10: cluster undo record allocator failure (multi-branch +# triggers per §3.2 + Q9): segment exhaustion / oversize payload / UBA +# decode fail / segment_id out of range / block_num exceeds segment_size_blocks +# / undo block slot-dir index 越界 / undo block durable flush failure. DML +# 4 op emit must ereport BEFORE START_CRIT_SECTION (per §3.3 I1 + I3 invariants). +53R9D E ERRCODE_CLUSTER_UNDO_RECORD_INVALID_UBA cluster_undo_record_invalid_uba + +# spec-3.8 v0.3 D10: autoextend hard cap reached (区别 53R9D record-level +# fail). Trigger: cluster_undo_segment_extend_or_create() detects pool +# size >= cluster.undo_segments_max_per_instance (default 256 = encoding +# limit). errhint: "Increase cluster.undo_segments_max_per_instance up +# to 256, or wait for spec-3.12 cleaner to recycle COMMITTED segments". +# Counter cluster_undo_segment_hard_cap_fail_count bump. +53R9E E ERRCODE_CLUSTER_UNDO_SEGMENTS_HARD_CAP_REACHED cluster_undo_segments_hard_cap_reached + +# spec-3.9 D6: own-instance CR block construction cannot reconstruct the +# snapshot-visible version at read_scn because the undo chain reaches a +# recycled / retention-exceeded segment. Aligned with Oracle ORA-01555 +# "snapshot too old". Raised by cluster_cr_construct_block() chain walker; +# counter cluster_cr_snapshot_too_old_count bump. NEVER silent-fail to +# tuple invisible (spec-3.9 I-fail-1). +53R9F E ERRCODE_CLUSTER_CR_SNAPSHOT_TOO_OLD cluster_cr_snapshot_too_old + +# spec-3.9 D6: CR chain walker encountered a cross-instance UBA +# (record.origin_node_id != local node). spec-3.9 supports own-instance +# CR only; cross-instance CR is Stage 4 (Cache Fusion CR coordinator). +# counter cluster_cr_cross_instance_unsupported_count bump. +53R9G E ERRCODE_CLUSTER_CR_CROSS_INSTANCE_UNSUPPORTED cluster_cr_cross_instance_unsupported + +# spec-4.6 D4: request landed on a GRD shard that is FROZEN/REBUILDING +# during failure-driven remaster and the short wait +# (cluster.grd_remaster_wait_ms) expired, or the holder-rebuild barrier +# failed/timed out (fail-closed; the shard is never half-opened). +# Application retry semantics like serialization_failure. +53R9I E ERRCODE_CLUSTER_GRD_SHARD_REMASTERING cluster_grd_shard_remastering + +# spec-4.6 D4: request/reply carried a stale routing generation (old +# epoch / old master after a remaster). Dropped + retried against the +# current master; never served by the dead/old master. +53R9J E ERRCODE_CLUSTER_GRD_STALE_MASTER_GENERATION cluster_grd_stale_master_generation + +# spec-4.6 D4 / L12: block-level (GCS/PCM) access to a remastered shard +# before Stage-4.7 block-state rebuild exists. The GES logical-lock +# layer is rebuilt by 4.6, but PCM/dirty-block state is NOT; fail-closed +# instead of serving stale block state through the new master map. +53R9K E ERRCODE_CLUSTER_GCS_BLOCK_PATH_NOT_REBUILT cluster_gcs_block_path_not_rebuilt + +# spec-4.7 D1/D4: GCS/PCM block-protocol warm recovery. 53R9K (above) +# is narrowed (spec-4.7 P1#4) to the legacy/permanent "no recovery path" +# guard; the normal failure-driven recovery path now flows +# 53R9L (RECOVERING: survivor re-declare / master rebuild in progress) +# -> 53R9M (redo boundary not yet reached: the dead instance's merged WAL +# has not been recovered to a consistent point, so serving the block +# would risk a stale shared page) -> NORMAL. Both are retryable +# (ERRCODE_T_R_* family); the request path fail-closes with the exact +# code per state (P1#4 — never "53R9K OR 53R9L"). +53R9L E ERRCODE_CLUSTER_GCS_BLOCK_RESOURCE_RECOVERING cluster_gcs_block_resource_recovering +53R9M E ERRCODE_CLUSTER_GCS_BLOCK_BEFORE_REDO_BOUNDARY cluster_gcs_block_before_redo_boundary + +# spec-4.8ab D1: undo/TT/ITL checkpoint-writeback boundary contract. A +# detected boundary violation fail-closes here (8.A) — PANIC inside a critical +# section, else this ERROR; never silent. The data-loss violations are +# WAL-before-data (an undo block written back with block_lsn > the durable +# flush LSN) and checkpoint-coverage (a PRE-redo dirty undo block left +# unflushed at checkpoint completion — recovery starts at redo and would not +# replay it). NB: block_lsn > redo is NOT a violation (recovery replays a +# post-redo block from WAL). 53R9H is already CROSS_NODE_WRITE_CONFLICT and +# 53R9A..M are allocated, so N is the next free slot in the 53R9 family. +53R9N E ERRCODE_CLUSTER_UNDO_WRITEBACK_BOUNDARY_VIOLATION cluster_undo_writeback_boundary_violation + +# spec-5.2a D6: clean-page X-transfer enabler terminal fail-closed. A clean +# (sequence) page X-transfer could not complete safely and there is no proven- +# safe fallback: a 3-node third-party master clean transfer (out of the 2-node +# narrow scope), or the X holder transiently could not relinquish a clean page +# (pinned / re-dirtied) so it kept its X. Retryable — the requester retries the +# transaction (Rule 8.A: never an optimistic grant, never a stale read). 53R9N +# is the previous slot; X is chosen by spec to mark the clean-X-transfer band. +53R9X E ERRCODE_CLUSTER_CLEAN_PAGE_XFER_UNAVAILABLE cluster_clean_page_xfer_unavailable + +# spec-4.1 D7: per-thread WAL routing startup validation (53RA0+ opens +# the Stage-4 WAL/recovery band; 53R70/71 belong to GES). 53RA0 fires +# at postmaster startup when cluster.wal_threads_dir is configured but +# the configuration is contradictory (cluster.enabled=off, or +# cluster.node_id unset), the thread directory is missing, or +# $PGDATA/pg_wal does not resolve to /thread_ for +# this node (mis-linked symlink / wrong mount). Fail-closed: startup is +# refused; never a silent fallback to the flat pg_wal layout. +53RA0 E ERRCODE_CLUSTER_WAL_THREAD_ROUTING_MISMATCH cluster_wal_thread_routing_mismatch + +# spec-4.1 D7: the thread claim file (pgrac_thread.claim, written once +# on first validated startup) guards a thread directory against a +# DIFFERENT node writing into it. 53RA1 fires at postmaster startup +# when the claim belongs to another node_id / thread_id, is corrupt +# (bad magic / version / CRC), or cannot be created (O_EXCL or fsync +# failure). Never auto-rebuilt: operator confirms ownership and removes +# the file manually (errhint carries the procedure). +53RA1 E ERRCODE_CLUSTER_WAL_THREAD_CLAIM_CONFLICT cluster_wal_thread_claim_conflict + +# spec-4.2 D5: ClusterWalState registry (pgrac_wal_state on the shared +# WAL root) I/O or corruption failure. Fires at postmaster startup when +# the registry header cannot be created/validated or the own slot ACTIVE +# publish fails (startup-grade fail-closed), and at clean shutdown when +# the STOPPED publish fails. Periodic cluster_stats refreshes are +# best-effort and never raise this (LOG-once + counter instead). +53RA2 E ERRCODE_CLUSTER_WAL_STATE_IO_FAILURE cluster_wal_state_io_failure +# spec-4.5: merged k-way SCN recovery refused (cold-crash engage gate; +# plan UNKNOWN, stream not OK, missing checkpoint_redo_lsn, fpw history, +# or an unclassifiable foreign record). Fail-closed -- never silently +# fall back to single-stream recovery (would skip a peer's committed WAL). +53RA3 E ERRCODE_CLUSTER_MERGED_RECOVERY_BLOCKED cluster_merged_recovery_blocked +# spec-4.11: online single-thread recovery refused. A survivor cannot +# safely online-replay a dead thread's WAL data to shared storage within +# the reconfig freeze window (missing WAL segment, indeterminate target +# LSN, full_page_writes was off, insufficient checkpoint history, +# incomplete undo/TT authority, a cross-node merge contradiction, or an +# rmgr not in the online apply matrix). Result-returning fail-closed: +# the dead thread's resources stay frozen (never serve a possibly stale +# page); the survivor is NOT crashed unless +# cluster.thread_recovery_on_unrecoverable=panic. +53RA4 E ERRCODE_CLUSTER_THREAD_RECOVERY_BLOCKED cluster_thread_recovery_blocked +# spec-5.4: SQ sequence allocation could not be proven unique, so nextval +# fails closed rather than risk a cross-node duplicate. Fires when the +# authority cannot durably confirm a segment (refill WAL unconfirmed), the +# boundary writeback to a reachable node failed/was unreachable, the SQ +# resource generation no longer matches (drop/recreate ABA), or a master +# failover left the durable allocation boundary unrecoverable. Distinct +# from 53R70 (refill wait timeout): this is a stronger correctness signal, +# not a transient timeout. +53RA5 E ERRCODE_CLUSTER_SEQUENCE_ALLOC_UNAVAILABLE cluster_sequence_alloc_unavailable + +Section: Class 54 - Program Limit Exceeded + +# this is for wired-in limits, not resource exhaustion problems (class borrowed from DB2) +54000 E ERRCODE_PROGRAM_LIMIT_EXCEEDED program_limit_exceeded +54001 E ERRCODE_STATEMENT_TOO_COMPLEX statement_too_complex +54011 E ERRCODE_TOO_MANY_COLUMNS too_many_columns +54023 E ERRCODE_TOO_MANY_ARGUMENTS too_many_arguments + +Section: Class 55 - Object Not In Prerequisite State + +# (class borrowed from DB2) +55000 E ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE object_not_in_prerequisite_state +55006 E ERRCODE_OBJECT_IN_USE object_in_use +55P02 E ERRCODE_CANT_CHANGE_RUNTIME_PARAM cant_change_runtime_param +55P03 E ERRCODE_LOCK_NOT_AVAILABLE lock_not_available +55P04 E ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE unsafe_new_enum_value_usage + +Section: Class 55 - Object Not In Prerequisite State (pgrac extension) + +55R01 E ERRCODE_CLUSTER_PCM_STATE_INVALID cluster_pcm_state_invalid +55R02 E ERRCODE_CLUSTER_BUFFER_PIN_CONFLICT cluster_buffer_pin_conflict +55R03 E ERRCODE_CLUSTER_LOCK_STARVATION cluster_lock_starvation +55R04 E ERRCODE_CLUSTER_BUFFER_INVALIDATED cluster_buffer_invalidated +55R05 E ERRCODE_CLUSTER_MASTER_CHANGED cluster_master_changed +55R06 E ERRCODE_CLUSTER_BLOCK_MISSING_TEMPORARY cluster_block_missing_temporary + +Section: Class 57 - Operator Intervention + +# (class borrowed from DB2) +57000 E ERRCODE_OPERATOR_INTERVENTION operator_intervention +57014 E ERRCODE_QUERY_CANCELED query_canceled +57P01 E ERRCODE_ADMIN_SHUTDOWN admin_shutdown +57P02 E ERRCODE_CRASH_SHUTDOWN crash_shutdown +57P03 E ERRCODE_CANNOT_CONNECT_NOW cannot_connect_now +57P04 E ERRCODE_DATABASE_DROPPED database_dropped +57P05 E ERRCODE_IDLE_SESSION_TIMEOUT idle_session_timeout + +Section: Class 57 - Operator Intervention (pgrac extension) + +57R02 E ERRCODE_CLUSTER_FENCE_TRIGGERED cluster_fence_triggered +57R03 E ERRCODE_CLUSTER_ADMIN_SHUTDOWN cluster_admin_shutdown +57R04 E ERRCODE_CLUSTER_NODE_DRAIN cluster_node_drain +57R05 E ERRCODE_CLUSTER_QUIESCE_ACTIVE cluster_quiesce_active +57R06 E ERRCODE_CLUSTER_ADG_APPLY_LAG_EXCESSIVE cluster_adg_apply_lag_excessive + +Section: Class 58 - System Error (errors external to PostgreSQL itself) + +# (class borrowed from DB2) +58000 E ERRCODE_SYSTEM_ERROR system_error +58030 E ERRCODE_IO_ERROR io_error +58P01 E ERRCODE_UNDEFINED_FILE undefined_file +58P02 E ERRCODE_DUPLICATE_FILE duplicate_file + +Section: Class 58 - System Error (pgrac extension) + +58R01 E ERRCODE_CLUSTER_SHARED_STORAGE_FAILED cluster_shared_storage_failed +58R02 E ERRCODE_CLUSTER_HEARTBEAT_LOST cluster_heartbeat_lost +58R03 E ERRCODE_CLUSTER_INTERCONNECT_CORRUPTED cluster_interconnect_corrupted +58R04 E ERRCODE_CLUSTER_MASTER_UNAVAILABLE cluster_master_unavailable +58R05 E ERRCODE_CLUSTER_SCN_DRIFT_EXCESSIVE cluster_scn_drift_excessive +58R06 E ERRCODE_CLUSTER_SCN_UNDERFLOW cluster_scn_underflow +58R07 E ERRCODE_CLUSTER_GRD_INCONSISTENT cluster_grd_inconsistent +58R08 E ERRCODE_CLUSTER_TOPOLOGY_INVALID cluster_topology_invalid +58R09 E ERRCODE_CLUSTER_TT_INCONSISTENT cluster_tt_inconsistent +58R10 E ERRCODE_CLUSTER_CATALOG_INCONSISTENT cluster_catalog_inconsistent +58R11 E ERRCODE_CLUSTER_SINVAL_INCONSISTENT cluster_sinval_inconsistent +58R12 E ERRCODE_CLUSTER_RECOVERY_FAILED cluster_recovery_failed +58R13 E ERRCODE_CLUSTER_CONTROLFILE_AUTHORITY_UNAVAILABLE cluster_controlfile_authority_unavailable + +Section: Class 72 - Snapshot Failure +# (class borrowed from Oracle) +72000 E ERRCODE_SNAPSHOT_TOO_OLD snapshot_too_old + +Section: Class 72 - Snapshot Failure (pgrac extension) + +72R01 E ERRCODE_CLUSTER_SNAPSHOT_TOO_OLD cluster_snapshot_too_old +72R02 E ERRCODE_CLUSTER_SNAPSHOT_UNAVAILABLE cluster_snapshot_unavailable + +Section: Class F0 - Configuration File Error + +# (PostgreSQL-specific error class) +F0000 E ERRCODE_CONFIG_FILE_ERROR config_file_error +F0001 E ERRCODE_LOCK_FILE_EXISTS lock_file_exists + +Section: Class HV - Foreign Data Wrapper Error (SQL/MED) + +# (SQL/MED-specific error class) +HV000 E ERRCODE_FDW_ERROR fdw_error +HV005 E ERRCODE_FDW_COLUMN_NAME_NOT_FOUND fdw_column_name_not_found +HV002 E ERRCODE_FDW_DYNAMIC_PARAMETER_VALUE_NEEDED fdw_dynamic_parameter_value_needed +HV010 E ERRCODE_FDW_FUNCTION_SEQUENCE_ERROR fdw_function_sequence_error +HV021 E ERRCODE_FDW_INCONSISTENT_DESCRIPTOR_INFORMATION fdw_inconsistent_descriptor_information +HV024 E ERRCODE_FDW_INVALID_ATTRIBUTE_VALUE fdw_invalid_attribute_value +HV007 E ERRCODE_FDW_INVALID_COLUMN_NAME fdw_invalid_column_name +HV008 E ERRCODE_FDW_INVALID_COLUMN_NUMBER fdw_invalid_column_number +HV004 E ERRCODE_FDW_INVALID_DATA_TYPE fdw_invalid_data_type +HV006 E ERRCODE_FDW_INVALID_DATA_TYPE_DESCRIPTORS fdw_invalid_data_type_descriptors +HV091 E ERRCODE_FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER fdw_invalid_descriptor_field_identifier +HV00B E ERRCODE_FDW_INVALID_HANDLE fdw_invalid_handle +HV00C E ERRCODE_FDW_INVALID_OPTION_INDEX fdw_invalid_option_index +HV00D E ERRCODE_FDW_INVALID_OPTION_NAME fdw_invalid_option_name +HV090 E ERRCODE_FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH fdw_invalid_string_length_or_buffer_length +HV00A E ERRCODE_FDW_INVALID_STRING_FORMAT fdw_invalid_string_format +HV009 E ERRCODE_FDW_INVALID_USE_OF_NULL_POINTER fdw_invalid_use_of_null_pointer +HV014 E ERRCODE_FDW_TOO_MANY_HANDLES fdw_too_many_handles +HV001 E ERRCODE_FDW_OUT_OF_MEMORY fdw_out_of_memory +HV00P E ERRCODE_FDW_NO_SCHEMAS fdw_no_schemas +HV00J E ERRCODE_FDW_OPTION_NAME_NOT_FOUND fdw_option_name_not_found +HV00K E ERRCODE_FDW_REPLY_HANDLE fdw_reply_handle +HV00Q E ERRCODE_FDW_SCHEMA_NOT_FOUND fdw_schema_not_found +HV00R E ERRCODE_FDW_TABLE_NOT_FOUND fdw_table_not_found +HV00L E ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION fdw_unable_to_create_execution +HV00M E ERRCODE_FDW_UNABLE_TO_CREATE_REPLY fdw_unable_to_create_reply +HV00N E ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION fdw_unable_to_establish_connection + +Section: Class P0 - PL/pgSQL Error + +# (PostgreSQL-specific error class) +P0000 E ERRCODE_PLPGSQL_ERROR plpgsql_error +P0001 E ERRCODE_RAISE_EXCEPTION raise_exception +P0002 E ERRCODE_NO_DATA_FOUND no_data_found +P0003 E ERRCODE_TOO_MANY_ROWS too_many_rows +P0004 E ERRCODE_ASSERT_FAILURE assert_failure + +Section: Class XX - Internal Error + +# this is for "can't-happen" conditions and software bugs (PostgreSQL-specific error class) +XX000 E ERRCODE_INTERNAL_ERROR internal_error +XX001 E ERRCODE_DATA_CORRUPTED data_corrupted +XX002 E ERRCODE_INDEX_CORRUPTED index_corrupted + +Section: Class XX - Internal Error (pgrac extension) + +XXR01 E ERRCODE_CLUSTER_ASSERTION_FAILURE cluster_assertion_failure +XXR02 E ERRCODE_CLUSTER_UNEXPECTED_STATE cluster_unexpected_state +XXR03 E ERRCODE_CLUSTER_RELMAPPER_CONFLICT cluster_relmapper_conflict diff --git a/install/share/postgresql/extension/plpgsql--1.0.sql b/install/share/postgresql/extension/plpgsql--1.0.sql new file mode 100644 index 00000000000..6e5b990fccc --- /dev/null +++ b/install/share/postgresql/extension/plpgsql--1.0.sql @@ -0,0 +1,20 @@ +/* src/pl/plpgsql/src/plpgsql--1.0.sql */ + +CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler + LANGUAGE c AS 'MODULE_PATHNAME'; + +CREATE FUNCTION plpgsql_inline_handler(internal) RETURNS void + STRICT LANGUAGE c AS 'MODULE_PATHNAME'; + +CREATE FUNCTION plpgsql_validator(oid) RETURNS void + STRICT LANGUAGE c AS 'MODULE_PATHNAME'; + +CREATE TRUSTED LANGUAGE plpgsql + HANDLER plpgsql_call_handler + INLINE plpgsql_inline_handler + VALIDATOR plpgsql_validator; + +-- The language object, but not the functions, can be owned by a non-superuser. +ALTER LANGUAGE plpgsql OWNER TO @extowner@; + +COMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language'; diff --git a/install/share/postgresql/extension/plpgsql.control b/install/share/postgresql/extension/plpgsql.control new file mode 100644 index 00000000000..42e764bf36b --- /dev/null +++ b/install/share/postgresql/extension/plpgsql.control @@ -0,0 +1,8 @@ +# plpgsql extension +comment = 'PL/pgSQL procedural language' +default_version = '1.0' +module_pathname = '$libdir/plpgsql' +relocatable = false +schema = pg_catalog +superuser = true +trusted = true diff --git a/install/share/postgresql/fix-CVE-2024-4317.sql b/install/share/postgresql/fix-CVE-2024-4317.sql new file mode 100644 index 00000000000..b24eba9a354 --- /dev/null +++ b/install/share/postgresql/fix-CVE-2024-4317.sql @@ -0,0 +1,117 @@ +/* + * fix-CVE-2024-4317.sql + * + * Copyright (c) 2024, PostgreSQL Global Development Group + * + * src/backend/catalog/fix-CVE-2024-4317.sql + * + * This file should be run in every database in the cluster to address + * CVE-2024-4317. + */ + +SET search_path = pg_catalog; + +CREATE OR REPLACE VIEW pg_stats_ext 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, + ( SELECT array_agg(a.attname ORDER BY a.attnum) + FROM unnest(s.stxkeys) k + 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.stxdinherit AS inherited, + sd.stxdndistinct AS n_distinct, + sd.stxddependencies AS dependencies, + m.most_common_vals, + m.most_common_val_nulls, + m.most_common_freqs, + m.most_common_base_freqs + FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid) + 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) + LEFT JOIN LATERAL + ( SELECT array_agg(values) AS most_common_vals, + array_agg(nulls) AS most_common_val_nulls, + array_agg(frequency) AS most_common_freqs, + array_agg(base_frequency) AS most_common_base_freqs + FROM pg_mcv_list_items(sd.stxdmcv) + ) m ON sd.stxdmcv IS NOT NULL + WHERE pg_has_role(c.relowner, 'USAGE') + AND (c.relrowsecurity = false OR NOT row_security_active(c.oid)); + +CREATE OR REPLACE 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, + sd.stxdinherit AS inherited, + (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) + WHERE pg_has_role(c.relowner, 'USAGE') + AND (c.relrowsecurity = false OR NOT row_security_active(c.oid)); diff --git a/install/share/postgresql/information_schema.sql b/install/share/postgresql/information_schema.sql new file mode 100644 index 00000000000..8bcd42467a1 --- /dev/null +++ b/install/share/postgresql/information_schema.sql @@ -0,0 +1,3037 @@ +/* + * SQL Information Schema + * as defined in ISO/IEC 9075-11:2023 + * + * Copyright (c) 2003-2023, PostgreSQL Global Development Group + * + * src/backend/catalog/information_schema.sql + * + * 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. + */ + +/* + * Note: Generally, the definitions in this file should be ordered + * according to the clause numbers in the SQL standard, which is also the + * alphabetical order. In some cases it is convenient or necessary to + * define one information schema view by using another one; in that case, + * put the referencing view at the very end and leave a note where it + * should have been put. + */ + + +/* + * 6.2 + * INFORMATION_SCHEMA schema + */ + +CREATE SCHEMA information_schema; +GRANT USAGE ON SCHEMA information_schema TO PUBLIC; +SET search_path TO information_schema; + + +/* + * A few supporting functions first ... + */ + +/* Expand any 1-D array into a set with integers 1..N */ +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 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)'; + +/* Given an index's OID and an underlying-table column number, return the + * column's position in the index (NULL if not there) */ +CREATE FUNCTION _pg_index_position(oid, smallint) RETURNS int + LANGUAGE sql STRICT STABLE +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 +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 +RETURN CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END; + +-- these functions encapsulate knowledge about the encoding of typmod: + +CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT +RETURN + CASE WHEN $2 = -1 /* default typmod */ + THEN null + WHEN $1 IN (1042, 1043) /* char, varchar */ + THEN $2 - 4 + WHEN $1 IN (1560, 1562) /* bit, varbit */ + THEN $2 + ELSE null + END; + +CREATE FUNCTION _pg_char_octet_length(typid oid, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT +RETURN + CASE WHEN $1 IN (25, 1042, 1043) /* text, char, varchar */ + THEN CASE WHEN $2 = -1 /* default typmod */ + THEN CAST(2^30 AS integer) + ELSE information_schema._pg_char_max_length($1, $2) * + pg_catalog.pg_encoding_max_length((SELECT encoding FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database())) + END + ELSE null + END; + +CREATE FUNCTION _pg_numeric_precision(typid oid, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT +RETURN + CASE $1 + WHEN 21 /*int2*/ THEN 16 + WHEN 23 /*int4*/ THEN 32 + WHEN 20 /*int8*/ THEN 64 + WHEN 1700 /*numeric*/ THEN + CASE WHEN $2 = -1 + THEN null + ELSE (($2 - 4) >> 16) & 0xFFFF + END + WHEN 700 /*float4*/ THEN 24 /*FLT_MANT_DIG*/ + WHEN 701 /*float8*/ THEN 53 /*DBL_MANT_DIG*/ + ELSE null + END; + +CREATE FUNCTION _pg_numeric_precision_radix(typid oid, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT +RETURN + CASE WHEN $1 IN (21, 23, 20, 700, 701) THEN 2 + WHEN $1 IN (1700) THEN 10 + ELSE null + END; + +CREATE FUNCTION _pg_numeric_scale(typid oid, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT +RETURN + CASE WHEN $1 IN (21, 23, 20) THEN 0 + WHEN $1 IN (1700) THEN + CASE WHEN $2 = -1 + THEN null + ELSE ($2 - 4) & 0xFFFF + END + ELSE null + END; + +CREATE FUNCTION _pg_datetime_precision(typid oid, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT +RETURN + CASE WHEN $1 IN (1082) /* date */ + THEN 0 + WHEN $1 IN (1083, 1114, 1184, 1266) /* time, timestamp, same + tz */ + THEN CASE WHEN $2 < 0 THEN 6 ELSE $2 END + WHEN $1 IN (1186) /* interval */ + THEN CASE WHEN $2 < 0 OR $2 & 0xFFFF = 0xFFFF THEN 6 ELSE $2 & 0xFFFF END + ELSE null + END; + +CREATE FUNCTION _pg_interval_type(typid oid, mod int4) RETURNS text + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT +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; + + +-- 6.3 INFORMATION_SCHEMA_CATALOG_NAME view appears later. + + +/* + * 6.4 + * CARDINAL_NUMBER domain + */ + +CREATE DOMAIN cardinal_number AS integer + CONSTRAINT cardinal_number_domain_check CHECK (value >= 0); + + +/* + * 6.5 + * CHARACTER_DATA domain + */ + +CREATE DOMAIN character_data AS character varying COLLATE "C"; + + +/* + * 6.6 + * SQL_IDENTIFIER domain + */ + +CREATE DOMAIN sql_identifier AS name; + + +/* + * 6.3 + * INFORMATION_SCHEMA_CATALOG_NAME view + */ + +CREATE VIEW information_schema_catalog_name AS + SELECT CAST(current_database() AS sql_identifier) AS catalog_name; + +GRANT SELECT ON information_schema_catalog_name TO PUBLIC; + + +/* + * 6.7 + * TIME_STAMP domain + */ + +CREATE DOMAIN time_stamp AS timestamp(2) with time zone + DEFAULT current_timestamp(2); + +/* + * 6.8 + * YES_OR_NO domain + */ + +CREATE DOMAIN yes_or_no AS character varying(3) COLLATE "C" + CONSTRAINT yes_or_no_check CHECK (value IN ('YES', 'NO')); + + +-- 6.9 ADMINISTRABLE_ROLE_AUTHORIZATIONS view appears later. + + +/* + * 6.10 + * APPLICABLE_ROLES view + */ + +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 (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'); + +GRANT SELECT ON applicable_roles TO PUBLIC; + + +/* + * 6.9 + * ADMINISTRABLE_ROLE_AUTHORIZATIONS view + */ + +CREATE VIEW administrable_role_authorizations AS + SELECT * + FROM applicable_roles + WHERE is_grantable = 'YES'; + +GRANT SELECT ON administrable_role_authorizations TO PUBLIC; + + +/* + * 6.11 + * ASSERTIONS view + */ + +-- feature not supported + + +/* + * 6.12 + * ATTRIBUTES view + */ + +CREATE VIEW attributes AS + SELECT CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(nc.nspname AS sql_identifier) AS udt_schema, + CAST(c.relname AS sql_identifier) AS udt_name, + CAST(a.attname AS sql_identifier) AS attribute_name, + CAST(a.attnum AS cardinal_number) AS ordinal_position, + CAST(pg_get_expr(ad.adbin, ad.adrelid) AS character_data) AS attribute_default, + CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END + AS yes_or_no) + AS is_nullable, -- This column was apparently removed between SQL:2003 and SQL:2008. + + CAST( + CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY' + WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, null) + ELSE 'USER-DEFINED' END + AS character_data) + AS data_type, + + CAST( + _pg_char_max_length(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS character_maximum_length, + + CAST( + _pg_char_octet_length(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS character_octet_length, + + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(null AS sql_identifier) AS character_set_name, + + CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog, + CAST(nco.nspname AS sql_identifier) AS collation_schema, + CAST(co.collname AS sql_identifier) AS collation_name, + + CAST( + _pg_numeric_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS numeric_precision, + + CAST( + _pg_numeric_precision_radix(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS numeric_precision_radix, + + CAST( + _pg_numeric_scale(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS numeric_scale, + + CAST( + _pg_datetime_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS datetime_precision, + + CAST( + _pg_interval_type(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS character_data) + AS interval_type, + CAST(null AS cardinal_number) AS interval_precision, + + CAST(current_database() AS sql_identifier) AS attribute_udt_catalog, + CAST(nt.nspname AS sql_identifier) AS attribute_udt_schema, + CAST(t.typname AS sql_identifier) AS attribute_udt_name, + + CAST(null AS sql_identifier) AS scope_catalog, + CAST(null AS sql_identifier) AS scope_schema, + CAST(null AS sql_identifier) AS scope_name, + + CAST(null AS cardinal_number) AS maximum_cardinality, + CAST(a.attnum AS sql_identifier) AS dtd_identifier, + CAST('NO' AS yes_or_no) AS is_derived_reference_attribute + + FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum) + JOIN (pg_class c JOIN pg_namespace nc ON (c.relnamespace = nc.oid)) ON a.attrelid = c.oid + JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON a.atttypid = t.oid + LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid)) + ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default') + + WHERE a.attnum > 0 AND NOT a.attisdropped + AND c.relkind IN ('c') + AND (pg_has_role(c.relowner, 'USAGE') + OR has_type_privilege(c.reltype, 'USAGE')); + +GRANT SELECT ON attributes TO PUBLIC; + + +/* + * 6.13 + * CHARACTER_SETS view + */ + +CREATE VIEW character_sets AS + SELECT CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(getdatabaseencoding() AS sql_identifier) AS character_set_name, + CAST(CASE WHEN getdatabaseencoding() = 'UTF8' THEN 'UCS' ELSE getdatabaseencoding() END AS sql_identifier) AS character_repertoire, + CAST(getdatabaseencoding() AS sql_identifier) AS form_of_use, + CAST(current_database() AS sql_identifier) AS default_collate_catalog, + CAST(nc.nspname AS sql_identifier) AS default_collate_schema, + CAST(c.collname AS sql_identifier) AS default_collate_name + FROM pg_database d + LEFT JOIN (pg_collation c JOIN pg_namespace nc ON (c.collnamespace = nc.oid)) + ON (datcollate = collcollate AND datctype = collctype) + WHERE d.datname = current_database() + ORDER BY char_length(c.collname) DESC, c.collname ASC -- prefer full/canonical name + LIMIT 1; + +GRANT SELECT ON character_sets TO PUBLIC; + + +/* + * 6.14 + * CHECK_CONSTRAINT_ROUTINE_USAGE view + */ + +CREATE VIEW check_constraint_routine_usage AS + 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, + CAST(np.nspname AS sql_identifier) AS specific_schema, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name + FROM pg_namespace nc, pg_constraint c, pg_depend d, pg_proc p, pg_namespace np + WHERE nc.oid = c.connamespace + AND c.contype = 'c' + AND c.oid = d.objid + AND d.classid = 'pg_catalog.pg_constraint'::regclass + AND d.refobjid = p.oid + AND d.refclassid = 'pg_catalog.pg_proc'::regclass + AND p.pronamespace = np.oid + AND pg_has_role(p.proowner, 'USAGE'); + +GRANT SELECT ON check_constraint_routine_usage TO PUBLIC; + + +/* + * 6.15 + * CHECK_CONSTRAINTS view + */ + +CREATE VIEW check_constraints AS + SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog, + CAST(rs.nspname AS sql_identifier) AS constraint_schema, + CAST(con.conname AS sql_identifier) AS constraint_name, + CAST(substring(pg_get_constraintdef(con.oid) from 7) AS character_data) + AS check_clause + FROM pg_constraint con + LEFT OUTER JOIN pg_namespace rs ON (rs.oid = con.connamespace) + LEFT OUTER JOIN pg_class c ON (c.oid = con.conrelid) + LEFT OUTER JOIN pg_type t ON (t.oid = con.contypid) + WHERE pg_has_role(coalesce(c.relowner, t.typowner), 'USAGE') + AND con.contype = 'c' + + UNION + -- not-null constraints + + SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog, + CAST(n.nspname AS sql_identifier) AS constraint_schema, + CAST(CAST(n.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX + CAST(a.attname || ' IS NOT NULL' AS character_data) + AS check_clause + FROM pg_namespace n, pg_class r, pg_attribute a + WHERE n.oid = r.relnamespace + AND r.oid = a.attrelid + AND a.attnum > 0 + AND NOT a.attisdropped + AND a.attnotnull + AND r.relkind IN ('r', 'p') + AND pg_has_role(r.relowner, 'USAGE'); + +GRANT SELECT ON check_constraints TO PUBLIC; + + +/* + * 6.16 + * COLLATIONS view + */ + +CREATE VIEW collations AS + SELECT CAST(current_database() AS sql_identifier) AS collation_catalog, + CAST(nc.nspname AS sql_identifier) AS collation_schema, + CAST(c.collname AS sql_identifier) AS collation_name, + CAST('NO PAD' AS character_data) AS pad_attribute + FROM pg_collation c, pg_namespace nc + WHERE c.collnamespace = nc.oid + AND collencoding IN (-1, (SELECT encoding FROM pg_database WHERE datname = current_database())); + +GRANT SELECT ON collations TO PUBLIC; + + +/* + * 6.17 + * COLLATION_CHARACTER_SET_APPLICABILITY view + */ + +CREATE VIEW collation_character_set_applicability AS + SELECT CAST(current_database() AS sql_identifier) AS collation_catalog, + CAST(nc.nspname AS sql_identifier) AS collation_schema, + CAST(c.collname AS sql_identifier) AS collation_name, + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(getdatabaseencoding() AS sql_identifier) AS character_set_name + FROM pg_collation c, pg_namespace nc + WHERE c.collnamespace = nc.oid + AND collencoding IN (-1, (SELECT encoding FROM pg_database WHERE datname = current_database())); + +GRANT SELECT ON collation_character_set_applicability TO PUBLIC; + + +/* + * 6.18 + * COLUMN_COLUMN_USAGE view + */ + +CREATE VIEW column_column_usage AS + 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, + CAST(ad.attname AS sql_identifier) AS dependent_column + + FROM pg_namespace n, pg_class c, pg_depend d, + pg_attribute ac, pg_attribute ad, pg_attrdef atd + + WHERE n.oid = c.relnamespace + AND c.oid = ac.attrelid + AND c.oid = ad.attrelid + AND ac.attnum <> ad.attnum + AND ad.attrelid = atd.adrelid + AND ad.attnum = atd.adnum + AND d.classid = 'pg_catalog.pg_attrdef'::regclass + AND d.refclassid = 'pg_catalog.pg_class'::regclass + AND d.objid = atd.oid + AND d.refobjid = ac.attrelid + AND d.refobjsubid = ac.attnum + AND ad.attgenerated <> '' + AND pg_has_role(c.relowner, 'USAGE'); + +GRANT SELECT ON column_column_usage TO PUBLIC; + + +/* + * 6.19 + * COLUMN_DOMAIN_USAGE view + */ + +CREATE VIEW column_domain_usage AS + SELECT CAST(current_database() AS sql_identifier) AS domain_catalog, + CAST(nt.nspname AS sql_identifier) AS domain_schema, + CAST(t.typname AS sql_identifier) AS domain_name, + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nc.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + CAST(a.attname AS sql_identifier) AS column_name + + FROM pg_type t, pg_namespace nt, pg_class c, pg_namespace nc, + pg_attribute a + + WHERE t.typnamespace = nt.oid + AND c.relnamespace = nc.oid + AND a.attrelid = c.oid + AND a.atttypid = t.oid + AND t.typtype = 'd' + AND c.relkind IN ('r', 'v', 'f', 'p') + AND a.attnum > 0 + AND NOT a.attisdropped + AND pg_has_role(t.typowner, 'USAGE'); + +GRANT SELECT ON column_domain_usage TO PUBLIC; + + +/* + * 6.20 + * COLUMN_PRIVILEGES + */ + +CREATE VIEW column_privileges AS + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nc.nspname AS sql_identifier) AS table_schema, + CAST(x.relname AS sql_identifier) AS table_name, + CAST(x.attname AS sql_identifier) AS column_name, + CAST(x.prtype AS character_data) AS privilege_type, + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(x.grantee, x.relowner, 'USAGE') + OR x.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable + + FROM ( + SELECT pr_c.grantor, + pr_c.grantee, + attname, + relname, + relnamespace, + pr_c.prtype, + pr_c.grantable, + pr_c.relowner + FROM (SELECT oid, relname, relnamespace, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* + FROM pg_class + WHERE relkind IN ('r', 'v', 'f', 'p') + ) pr_c (oid, relname, relnamespace, relowner, grantor, grantee, prtype, grantable), + pg_attribute a + WHERE a.attrelid = pr_c.oid + AND a.attnum > 0 + AND NOT a.attisdropped + UNION + SELECT pr_a.grantor, + pr_a.grantee, + attname, + relname, + relnamespace, + pr_a.prtype, + pr_a.grantable, + c.relowner + FROM (SELECT attrelid, attname, (aclexplode(coalesce(attacl, acldefault('c', relowner)))).* + FROM pg_attribute a JOIN pg_class cc ON (a.attrelid = cc.oid) + WHERE attnum > 0 + AND NOT attisdropped + ) pr_a (attrelid, attname, grantor, grantee, prtype, grantable), + pg_class c + WHERE pr_a.attrelid = c.oid + AND relkind IN ('r', 'v', 'f', 'p') + ) x, + pg_namespace nc, + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE x.relnamespace = nc.oid + AND x.grantee = grantee.oid + AND x.grantor = u_grantor.oid + AND x.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'REFERENCES') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC'); + +GRANT SELECT ON column_privileges TO PUBLIC; + + +/* + * 6.21 + * COLUMN_UDT_USAGE view + */ + +CREATE VIEW column_udt_usage AS + SELECT CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(coalesce(nbt.nspname, nt.nspname) AS sql_identifier) AS udt_schema, + CAST(coalesce(bt.typname, t.typname) AS sql_identifier) AS udt_name, + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nc.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + CAST(a.attname AS sql_identifier) AS column_name + + FROM pg_attribute a, pg_class c, pg_namespace nc, + (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) + LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid)) + ON (t.typtype = 'd' AND t.typbasetype = bt.oid) + + WHERE a.attrelid = c.oid + AND a.atttypid = t.oid + AND nc.oid = c.relnamespace + AND a.attnum > 0 AND NOT a.attisdropped + AND c.relkind in ('r', 'v', 'f', 'p') + AND pg_has_role(coalesce(bt.typowner, t.typowner), 'USAGE'); + +GRANT SELECT ON column_udt_usage TO PUBLIC; + + +/* + * 6.22 + * COLUMNS view + */ + +CREATE VIEW columns AS + SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nc.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + CAST(a.attname AS sql_identifier) AS column_name, + CAST(a.attnum AS cardinal_number) AS ordinal_position, + CAST(CASE WHEN a.attgenerated = '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS character_data) AS column_default, + CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END + AS yes_or_no) + AS is_nullable, + + CAST( + CASE WHEN t.typtype = 'd' THEN + CASE WHEN bt.typelem <> 0 AND bt.typlen = -1 THEN 'ARRAY' + WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, null) + ELSE 'USER-DEFINED' END + ELSE + CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY' + WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, null) + ELSE 'USER-DEFINED' END + END + AS character_data) + AS data_type, + + CAST( + _pg_char_max_length(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS character_maximum_length, + + CAST( + _pg_char_octet_length(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS character_octet_length, + + CAST( + _pg_numeric_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS numeric_precision, + + CAST( + _pg_numeric_precision_radix(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS numeric_precision_radix, + + CAST( + _pg_numeric_scale(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS numeric_scale, + + CAST( + _pg_datetime_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS cardinal_number) + AS datetime_precision, + + CAST( + _pg_interval_type(_pg_truetypid(a, t), _pg_truetypmod(a, t)) + AS character_data) + AS interval_type, + CAST(null AS cardinal_number) AS interval_precision, + + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(null AS sql_identifier) AS character_set_name, + + CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog, + CAST(nco.nspname AS sql_identifier) AS collation_schema, + CAST(co.collname AS sql_identifier) AS collation_name, + + CAST(CASE WHEN t.typtype = 'd' THEN current_database() ELSE null END + AS sql_identifier) AS domain_catalog, + CAST(CASE WHEN t.typtype = 'd' THEN nt.nspname ELSE null END + AS sql_identifier) AS domain_schema, + CAST(CASE WHEN t.typtype = 'd' THEN t.typname ELSE null END + AS sql_identifier) AS domain_name, + + CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(coalesce(nbt.nspname, nt.nspname) AS sql_identifier) AS udt_schema, + CAST(coalesce(bt.typname, t.typname) AS sql_identifier) AS udt_name, + + CAST(null AS sql_identifier) AS scope_catalog, + CAST(null AS sql_identifier) AS scope_schema, + CAST(null AS sql_identifier) AS scope_name, + + CAST(null AS cardinal_number) AS maximum_cardinality, + CAST(a.attnum AS sql_identifier) AS dtd_identifier, + CAST('NO' AS yes_or_no) AS is_self_referencing, + + CAST(CASE WHEN a.attidentity IN ('a', 'd') THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_identity, + CAST(CASE a.attidentity WHEN 'a' THEN 'ALWAYS' WHEN 'd' THEN 'BY DEFAULT' END AS character_data) AS identity_generation, + CAST(seq.seqstart AS character_data) AS identity_start, + CAST(seq.seqincrement AS character_data) AS identity_increment, + CAST(seq.seqmax AS character_data) AS identity_maximum, + CAST(seq.seqmin AS character_data) AS identity_minimum, + CAST(CASE WHEN seq.seqcycle THEN 'YES' ELSE 'NO' END AS yes_or_no) AS identity_cycle, + + CAST(CASE WHEN a.attgenerated <> '' THEN 'ALWAYS' ELSE 'NEVER' END AS character_data) AS is_generated, + CAST(CASE WHEN a.attgenerated <> '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS character_data) AS generation_expression, + + CAST(CASE WHEN c.relkind IN ('r', 'p') OR + (c.relkind IN ('v', 'f') AND + pg_column_is_updatable(c.oid, a.attnum, false)) + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_updatable + + FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum) + JOIN (pg_class c JOIN pg_namespace nc ON (c.relnamespace = nc.oid)) ON a.attrelid = c.oid + JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON a.atttypid = t.oid + LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid)) + ON (t.typtype = 'd' AND t.typbasetype = bt.oid) + LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid)) + ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default') + LEFT JOIN (pg_depend dep JOIN pg_sequence seq ON (dep.classid = 'pg_class'::regclass AND dep.objid = seq.seqrelid AND dep.deptype = 'i')) + ON (dep.refclassid = 'pg_class'::regclass AND dep.refobjid = c.oid AND dep.refobjsubid = a.attnum) + + WHERE (NOT pg_is_other_temp_schema(nc.oid)) + + AND a.attnum > 0 AND NOT a.attisdropped + AND c.relkind IN ('r', 'v', 'f', 'p') + + AND (pg_has_role(c.relowner, 'USAGE') + OR has_column_privilege(c.oid, a.attnum, + 'SELECT, INSERT, UPDATE, REFERENCES')); + +GRANT SELECT ON columns TO PUBLIC; + + +/* + * 6.23 + * CONSTRAINT_COLUMN_USAGE view + */ + +CREATE VIEW constraint_column_usage AS + SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(tblschema AS sql_identifier) AS table_schema, + CAST(tblname AS sql_identifier) AS table_name, + CAST(colname AS sql_identifier) AS column_name, + CAST(current_database() AS sql_identifier) AS constraint_catalog, + CAST(cstrschema AS sql_identifier) AS constraint_schema, + CAST(cstrname AS sql_identifier) AS constraint_name + + FROM ( + /* check constraints */ + SELECT DISTINCT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname + FROM pg_namespace nr, pg_class r, pg_attribute a, pg_depend d, pg_namespace nc, pg_constraint c + WHERE nr.oid = r.relnamespace + AND r.oid = a.attrelid + AND d.refclassid = 'pg_catalog.pg_class'::regclass + AND d.refobjid = r.oid + AND d.refobjsubid = a.attnum + AND d.classid = 'pg_catalog.pg_constraint'::regclass + AND d.objid = c.oid + AND c.connamespace = nc.oid + AND c.contype = 'c' + AND r.relkind IN ('r', 'p') + AND NOT a.attisdropped + + UNION ALL + + /* unique/primary key/foreign key constraints */ + SELECT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname + FROM pg_namespace nr, pg_class r, pg_attribute a, pg_namespace nc, + pg_constraint c + WHERE nr.oid = r.relnamespace + AND r.oid = a.attrelid + AND nc.oid = c.connamespace + AND r.oid = CASE c.contype WHEN 'f' THEN c.confrelid ELSE c.conrelid END + AND a.attnum = ANY (CASE c.contype WHEN 'f' THEN c.confkey ELSE c.conkey END) + AND NOT a.attisdropped + AND c.contype IN ('p', 'u', 'f') + AND r.relkind IN ('r', 'p') + + ) AS x (tblschema, tblname, tblowner, colname, cstrschema, cstrname) + + WHERE pg_has_role(x.tblowner, 'USAGE'); + +GRANT SELECT ON constraint_column_usage TO PUBLIC; + + +/* + * 6.24 + * CONSTRAINT_PERIOD_USAGE view + */ + +-- feature not supported + + +/* + * 6.25 + * CONSTRAINT_TABLE_USAGE view + */ + +CREATE VIEW constraint_table_usage AS + SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nr.nspname AS sql_identifier) AS table_schema, + CAST(r.relname AS sql_identifier) AS table_name, + 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 + + FROM pg_constraint c, pg_namespace nc, + pg_class r, pg_namespace nr + + WHERE c.connamespace = nc.oid AND r.relnamespace = nr.oid + AND ( (c.contype = 'f' AND c.confrelid = r.oid) + OR (c.contype IN ('p', 'u') AND c.conrelid = r.oid) ) + AND r.relkind IN ('r', 'p') + AND pg_has_role(r.relowner, 'USAGE'); + +GRANT SELECT ON constraint_table_usage TO PUBLIC; + + +-- 6.26 DATA_TYPE_PRIVILEGES view appears later. + + +/* + * 6.27 + * DIRECT_SUPERTABLES view + */ + +-- feature not supported + + +/* + * 6.28 + * DIRECT_SUPERTYPES view + */ + +-- feature not supported + + +/* + * 6.29 + * DOMAIN_CONSTRAINTS view + */ + +CREATE VIEW domain_constraints AS + SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog, + CAST(rs.nspname AS sql_identifier) AS constraint_schema, + CAST(con.conname AS sql_identifier) AS constraint_name, + CAST(current_database() AS sql_identifier) AS domain_catalog, + CAST(n.nspname AS sql_identifier) AS domain_schema, + CAST(t.typname AS sql_identifier) AS domain_name, + CAST(CASE WHEN condeferrable THEN 'YES' ELSE 'NO' END + AS yes_or_no) AS is_deferrable, + CAST(CASE WHEN condeferred THEN 'YES' ELSE 'NO' END + AS yes_or_no) AS initially_deferred + FROM pg_namespace rs, pg_namespace n, pg_constraint con, pg_type t + WHERE rs.oid = con.connamespace + AND n.oid = t.typnamespace + AND t.oid = con.contypid + AND (pg_has_role(t.typowner, 'USAGE') + OR has_type_privilege(t.oid, 'USAGE')); + +GRANT SELECT ON domain_constraints TO PUBLIC; + + +/* + * DOMAIN_UDT_USAGE view + * apparently removed in SQL:2003 + */ + +CREATE VIEW domain_udt_usage AS + SELECT CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(nbt.nspname AS sql_identifier) AS udt_schema, + CAST(bt.typname AS sql_identifier) AS udt_name, + CAST(current_database() AS sql_identifier) AS domain_catalog, + CAST(nt.nspname AS sql_identifier) AS domain_schema, + CAST(t.typname AS sql_identifier) AS domain_name + + FROM pg_type t, pg_namespace nt, + pg_type bt, pg_namespace nbt + + WHERE t.typnamespace = nt.oid + AND t.typbasetype = bt.oid + AND bt.typnamespace = nbt.oid + AND t.typtype = 'd' + AND pg_has_role(bt.typowner, 'USAGE'); + +GRANT SELECT ON domain_udt_usage TO PUBLIC; + + +/* + * 6.30 + * DOMAINS view + */ + +CREATE VIEW domains AS + SELECT CAST(current_database() AS sql_identifier) AS domain_catalog, + CAST(nt.nspname AS sql_identifier) AS domain_schema, + CAST(t.typname AS sql_identifier) AS domain_name, + + CAST( + CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY' + WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, null) + ELSE 'USER-DEFINED' END + AS character_data) + AS data_type, + + CAST( + _pg_char_max_length(t.typbasetype, t.typtypmod) + AS cardinal_number) + AS character_maximum_length, + + CAST( + _pg_char_octet_length(t.typbasetype, t.typtypmod) + AS cardinal_number) + AS character_octet_length, + + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(null AS sql_identifier) AS character_set_name, + + CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog, + CAST(nco.nspname AS sql_identifier) AS collation_schema, + CAST(co.collname AS sql_identifier) AS collation_name, + + CAST( + _pg_numeric_precision(t.typbasetype, t.typtypmod) + AS cardinal_number) + AS numeric_precision, + + CAST( + _pg_numeric_precision_radix(t.typbasetype, t.typtypmod) + AS cardinal_number) + AS numeric_precision_radix, + + CAST( + _pg_numeric_scale(t.typbasetype, t.typtypmod) + AS cardinal_number) + AS numeric_scale, + + CAST( + _pg_datetime_precision(t.typbasetype, t.typtypmod) + AS cardinal_number) + AS datetime_precision, + + CAST( + _pg_interval_type(t.typbasetype, t.typtypmod) + AS character_data) + AS interval_type, + CAST(null AS cardinal_number) AS interval_precision, + + CAST(t.typdefault AS character_data) AS domain_default, + + CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(nbt.nspname AS sql_identifier) AS udt_schema, + CAST(bt.typname AS sql_identifier) AS udt_name, + + CAST(null AS sql_identifier) AS scope_catalog, + CAST(null AS sql_identifier) AS scope_schema, + CAST(null AS sql_identifier) AS scope_name, + + CAST(null AS cardinal_number) AS maximum_cardinality, + CAST(1 AS sql_identifier) AS dtd_identifier + + FROM (pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid) + JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) + ON (t.typbasetype = bt.oid AND t.typtype = 'd') + LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid)) + ON t.typcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default') + + WHERE (pg_has_role(t.typowner, 'USAGE') + OR has_type_privilege(t.oid, 'USAGE')); + +GRANT SELECT ON domains TO PUBLIC; + + +-- 6.31 ELEMENT_TYPES view appears later. + + +/* + * 6.32 + * ENABLED_ROLES view + */ + +CREATE VIEW enabled_roles AS + SELECT CAST(a.rolname AS sql_identifier) AS role_name + FROM pg_authid a + WHERE pg_has_role(a.oid, 'USAGE'); + +GRANT SELECT ON enabled_roles TO PUBLIC; + + +/* + * 6.33 + * FIELDS view + */ + +-- feature not supported + + +/* + * 6.34 + * KEY_COLUMN_USAGE view + */ + +CREATE VIEW key_column_usage AS + SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog, + CAST(nc_nspname AS sql_identifier) AS constraint_schema, + CAST(conname AS sql_identifier) AS constraint_name, + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nr_nspname AS sql_identifier) AS table_schema, + CAST(relname AS sql_identifier) AS table_name, + CAST(a.attname AS sql_identifier) AS column_name, + CAST((ss.x).n AS cardinal_number) AS ordinal_position, + CAST(CASE WHEN contype = 'f' THEN + _pg_index_position(ss.conindid, ss.confkey[(ss.x).n]) + ELSE NULL + END AS cardinal_number) + AS position_in_unique_constraint + FROM pg_attribute a, + (SELECT r.oid AS roid, r.relname, r.relowner, + nc.nspname AS nc_nspname, nr.nspname AS nr_nspname, + c.oid AS coid, c.conname, c.contype, c.conindid, + c.confkey, c.confrelid, + _pg_expandarray(c.conkey) AS x + FROM pg_namespace nr, pg_class r, pg_namespace nc, + pg_constraint c + WHERE nr.oid = r.relnamespace + AND r.oid = c.conrelid + AND nc.oid = c.connamespace + AND c.contype IN ('p', 'u', 'f') + AND r.relkind IN ('r', 'p') + AND (NOT pg_is_other_temp_schema(nr.oid)) ) AS ss + WHERE ss.roid = a.attrelid + AND a.attnum = (ss.x).x + AND NOT a.attisdropped + AND (pg_has_role(relowner, 'USAGE') + OR has_column_privilege(roid, a.attnum, + 'SELECT, INSERT, UPDATE, REFERENCES')); + +GRANT SELECT ON key_column_usage TO PUBLIC; + + +/* + * 6.35 + * KEY_PERIOD_USAGE view + */ + +-- feature not supported + + +/* + * 6.36 + * METHOD_SPECIFICATION_PARAMETERS view + */ + +-- feature not supported + + +/* + * 6.37 + * METHOD_SPECIFICATIONS view + */ + +-- feature not supported + + +/* + * 6.38 + * PARAMETERS view + */ + +CREATE VIEW parameters AS + SELECT CAST(current_database() AS sql_identifier) AS specific_catalog, + CAST(n_nspname AS sql_identifier) AS specific_schema, + CAST(nameconcatoid(proname, p_oid) AS sql_identifier) AS specific_name, + CAST((ss.x).n AS cardinal_number) AS ordinal_position, + CAST( + CASE WHEN proargmodes IS NULL THEN 'IN' + WHEN proargmodes[(ss.x).n] = 'i' THEN 'IN' + WHEN proargmodes[(ss.x).n] = 'o' THEN 'OUT' + WHEN proargmodes[(ss.x).n] = 'b' THEN 'INOUT' + WHEN proargmodes[(ss.x).n] = 'v' THEN 'IN' + WHEN proargmodes[(ss.x).n] = 't' THEN 'OUT' + END AS character_data) AS parameter_mode, + CAST('NO' AS yes_or_no) AS is_result, + CAST('NO' AS yes_or_no) AS as_locator, + CAST(NULLIF(proargnames[(ss.x).n], '') AS sql_identifier) AS parameter_name, + CAST( + CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY' + WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null) + ELSE 'USER-DEFINED' END AS character_data) + AS data_type, + CAST(null AS cardinal_number) AS character_maximum_length, + CAST(null AS cardinal_number) AS character_octet_length, + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(null AS sql_identifier) AS character_set_name, + CAST(null AS sql_identifier) AS collation_catalog, + CAST(null AS sql_identifier) AS collation_schema, + CAST(null AS sql_identifier) AS collation_name, + CAST(null AS cardinal_number) AS numeric_precision, + CAST(null AS cardinal_number) AS numeric_precision_radix, + CAST(null AS cardinal_number) AS numeric_scale, + CAST(null AS cardinal_number) AS datetime_precision, + CAST(null AS character_data) AS interval_type, + CAST(null AS cardinal_number) AS interval_precision, + CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(nt.nspname AS sql_identifier) AS udt_schema, + CAST(t.typname AS sql_identifier) AS udt_name, + CAST(null AS sql_identifier) AS scope_catalog, + CAST(null AS sql_identifier) AS scope_schema, + CAST(null AS sql_identifier) AS scope_name, + CAST(null AS cardinal_number) AS maximum_cardinality, + CAST((ss.x).n AS sql_identifier) AS dtd_identifier, + CAST( + CASE WHEN pg_has_role(proowner, 'USAGE') + THEN pg_get_function_arg_default(p_oid, (ss.x).n) + ELSE NULL END + AS character_data) AS parameter_default + + FROM pg_type t, pg_namespace nt, + (SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proowner, + p.proargnames, p.proargmodes, + _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x + FROM pg_namespace n, pg_proc p + WHERE n.oid = p.pronamespace + AND (pg_has_role(p.proowner, 'USAGE') OR + has_function_privilege(p.oid, 'EXECUTE'))) AS ss + WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid; + +GRANT SELECT ON parameters TO PUBLIC; + + +/* + * 6.39 + * PERIODS view + */ + +-- feature not supported + + +/* + * 6.40 + * PRIVATE_PARAMETERS view + */ + +-- feature not supported + + +/* + * 6.41 + * REFERENCED_TYPES view + */ + +-- feature not supported + + +/* + * 6.42 + * REFERENTIAL_CONSTRAINTS view + */ + +CREATE VIEW referential_constraints AS + SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog, + CAST(ncon.nspname AS sql_identifier) AS constraint_schema, + CAST(con.conname AS sql_identifier) AS constraint_name, + CAST( + CASE WHEN npkc.nspname IS NULL THEN NULL + ELSE current_database() END + AS sql_identifier) AS unique_constraint_catalog, + CAST(npkc.nspname AS sql_identifier) AS unique_constraint_schema, + CAST(pkc.conname AS sql_identifier) AS unique_constraint_name, + + CAST( + CASE con.confmatchtype WHEN 'f' THEN 'FULL' + WHEN 'p' THEN 'PARTIAL' + WHEN 's' THEN 'NONE' END + AS character_data) AS match_option, + + CAST( + CASE con.confupdtype WHEN 'c' THEN 'CASCADE' + WHEN 'n' THEN 'SET NULL' + WHEN 'd' THEN 'SET DEFAULT' + WHEN 'r' THEN 'RESTRICT' + WHEN 'a' THEN 'NO ACTION' END + AS character_data) AS update_rule, + + CAST( + CASE con.confdeltype WHEN 'c' THEN 'CASCADE' + WHEN 'n' THEN 'SET NULL' + WHEN 'd' THEN 'SET DEFAULT' + WHEN 'r' THEN 'RESTRICT' + WHEN 'a' THEN 'NO ACTION' END + AS character_data) AS delete_rule + + FROM (pg_namespace ncon + INNER JOIN pg_constraint con ON ncon.oid = con.connamespace + INNER JOIN pg_class c ON con.conrelid = c.oid AND con.contype = 'f') + LEFT JOIN pg_depend d1 -- find constraint's dependency on an index + ON d1.objid = con.oid AND d1.classid = 'pg_constraint'::regclass + AND d1.refclassid = 'pg_class'::regclass AND d1.refobjsubid = 0 + LEFT JOIN pg_depend d2 -- find pkey/unique constraint for that index + ON d2.refclassid = 'pg_constraint'::regclass + AND d2.classid = 'pg_class'::regclass + AND d2.objid = d1.refobjid AND d2.objsubid = 0 + AND d2.deptype = 'i' + LEFT JOIN pg_constraint pkc ON pkc.oid = d2.refobjid + AND pkc.contype IN ('p', 'u') + AND pkc.conrelid = con.confrelid + LEFT JOIN pg_namespace npkc ON pkc.connamespace = npkc.oid + + WHERE pg_has_role(c.relowner, 'USAGE') + -- SELECT privilege omitted, per SQL standard + OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') ; + +GRANT SELECT ON referential_constraints TO PUBLIC; + + +/* + * 6.43 + * ROLE_COLUMN_GRANTS view + */ + +CREATE VIEW role_column_grants AS + SELECT grantor, + grantee, + table_catalog, + table_schema, + table_name, + column_name, + privilege_type, + is_grantable + FROM column_privileges + WHERE grantor IN (SELECT role_name FROM enabled_roles) + OR grantee IN (SELECT role_name FROM enabled_roles); + +GRANT SELECT ON role_column_grants TO PUBLIC; + + +-- 6.44 ROLE_ROUTINE_GRANTS view is based on 6.51 ROUTINE_PRIVILEGES and is defined there instead. + + +-- 6.45 ROLE_TABLE_GRANTS view is based on 6.64 TABLE_PRIVILEGES and is defined there instead. + + +/* + * 6.46 + * ROLE_TABLE_METHOD_GRANTS view + */ + +-- feature not supported + + + +-- 6.47 ROLE_USAGE_GRANTS view is based on 6.76 USAGE_PRIVILEGES and is defined there instead. + + +-- 6.48 ROLE_UDT_GRANTS view is based on 6.75 UDT_PRIVILEGES and is defined there instead. + + +/* + * 6.49 + * ROUTINE_COLUMN_USAGE view + */ + +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; + + +/* + * 6.50 + * ROUTINE_PERIOD_USAGE view + */ + +-- feature not supported + + +/* + * 6.51 + * ROUTINE_PRIVILEGES view + */ + +CREATE VIEW routine_privileges AS + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS specific_catalog, + CAST(n.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(n.nspname AS sql_identifier) AS routine_schema, + CAST(p.proname AS sql_identifier) AS routine_name, + CAST('EXECUTE' AS character_data) AS privilege_type, + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, p.proowner, 'USAGE') + OR p.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable + + FROM ( + SELECT oid, proname, proowner, pronamespace, (aclexplode(coalesce(proacl, acldefault('f', proowner)))).* FROM pg_proc + ) p (oid, proname, proowner, pronamespace, grantor, grantee, prtype, grantable), + pg_namespace n, + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE p.pronamespace = n.oid + AND grantee.oid = p.grantee + AND u_grantor.oid = p.grantor + AND p.prtype IN ('EXECUTE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC'); + +GRANT SELECT ON routine_privileges TO PUBLIC; + + +/* + * 6.43 + * ROLE_ROUTINE_GRANTS view + */ + +CREATE VIEW role_routine_grants AS + SELECT grantor, + grantee, + specific_catalog, + specific_schema, + specific_name, + routine_catalog, + routine_schema, + routine_name, + privilege_type, + is_grantable + FROM routine_privileges + WHERE grantor IN (SELECT role_name FROM enabled_roles) + OR grantee IN (SELECT role_name FROM enabled_roles); + +GRANT SELECT ON role_routine_grants TO PUBLIC; + + +/* + * 6.52 + * ROUTINE_ROUTINE_USAGE view + */ + +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; + + +/* + * 6.53 + * ROUTINE_SEQUENCE_USAGE view + */ + +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; + + +/* + * 6.54 + * ROUTINE_TABLE_USAGE view + */ + +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; + + +/* + * 6.55 + * ROUTINES view + */ + +CREATE VIEW routines AS + SELECT CAST(current_database() AS sql_identifier) AS specific_catalog, + CAST(n.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(n.nspname AS sql_identifier) AS routine_schema, + CAST(p.proname AS sql_identifier) AS routine_name, + CAST(CASE p.prokind WHEN 'f' THEN 'FUNCTION' WHEN 'p' THEN 'PROCEDURE' END + AS character_data) AS routine_type, + CAST(null AS sql_identifier) AS module_catalog, + CAST(null AS sql_identifier) AS module_schema, + CAST(null AS sql_identifier) AS module_name, + CAST(null AS sql_identifier) AS udt_catalog, + CAST(null AS sql_identifier) AS udt_schema, + CAST(null AS sql_identifier) AS udt_name, + + CAST( + CASE WHEN p.prokind = 'p' THEN NULL + WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY' + WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null) + ELSE 'USER-DEFINED' END AS character_data) + AS data_type, + CAST(null AS cardinal_number) AS character_maximum_length, + CAST(null AS cardinal_number) AS character_octet_length, + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(null AS sql_identifier) AS character_set_name, + CAST(null AS sql_identifier) AS collation_catalog, + CAST(null AS sql_identifier) AS collation_schema, + CAST(null AS sql_identifier) AS collation_name, + CAST(null AS cardinal_number) AS numeric_precision, + CAST(null AS cardinal_number) AS numeric_precision_radix, + CAST(null AS cardinal_number) AS numeric_scale, + CAST(null AS cardinal_number) AS datetime_precision, + CAST(null AS character_data) AS interval_type, + CAST(null AS cardinal_number) AS interval_precision, + CAST(CASE WHEN nt.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS type_udt_catalog, + CAST(nt.nspname AS sql_identifier) AS type_udt_schema, + CAST(t.typname AS sql_identifier) AS type_udt_name, + CAST(null AS sql_identifier) AS scope_catalog, + CAST(null AS sql_identifier) AS scope_schema, + CAST(null AS sql_identifier) AS scope_name, + CAST(null AS cardinal_number) AS maximum_cardinality, + CAST(CASE WHEN p.prokind <> 'p' THEN 0 END AS sql_identifier) AS dtd_identifier, + + CAST(CASE WHEN l.lanname = 'sql' THEN 'SQL' ELSE 'EXTERNAL' END AS character_data) + AS routine_body, + CAST( + CASE WHEN pg_has_role(p.proowner, 'USAGE') THEN p.prosrc ELSE null END + AS character_data) AS routine_definition, + CAST( + CASE WHEN l.lanname = 'c' THEN p.prosrc ELSE null END + AS character_data) AS external_name, + CAST(upper(l.lanname) AS character_data) AS external_language, + + CAST('GENERAL' AS character_data) AS parameter_style, + CAST(CASE WHEN p.provolatile = 'i' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_deterministic, + CAST('MODIFIES' AS character_data) AS sql_data_access, + CAST(CASE WHEN p.prokind <> 'p' THEN + CASE WHEN p.proisstrict THEN 'YES' ELSE 'NO' END END AS yes_or_no) AS is_null_call, + CAST(null AS character_data) AS sql_path, + CAST('YES' AS yes_or_no) AS schema_level_routine, + CAST(0 AS cardinal_number) AS max_dynamic_result_sets, + CAST(null AS yes_or_no) AS is_user_defined_cast, + CAST(null AS yes_or_no) AS is_implicitly_invocable, + CAST(CASE WHEN p.prosecdef THEN 'DEFINER' ELSE 'INVOKER' END AS character_data) AS security_type, + CAST(null AS sql_identifier) AS to_sql_specific_catalog, + CAST(null AS sql_identifier) AS to_sql_specific_schema, + CAST(null AS sql_identifier) AS to_sql_specific_name, + CAST('NO' AS yes_or_no) AS as_locator, + CAST(null AS time_stamp) AS created, + CAST(null AS time_stamp) AS last_altered, + CAST(null AS yes_or_no) AS new_savepoint_level, + CAST('NO' AS yes_or_no) AS is_udt_dependent, + + CAST(null AS character_data) AS result_cast_from_data_type, + CAST(null AS yes_or_no) AS result_cast_as_locator, + CAST(null AS cardinal_number) AS result_cast_char_max_length, + CAST(null AS cardinal_number) AS result_cast_char_octet_length, + CAST(null AS sql_identifier) AS result_cast_char_set_catalog, + CAST(null AS sql_identifier) AS result_cast_char_set_schema, + CAST(null AS sql_identifier) AS result_cast_char_set_name, + CAST(null AS sql_identifier) AS result_cast_collation_catalog, + CAST(null AS sql_identifier) AS result_cast_collation_schema, + CAST(null AS sql_identifier) AS result_cast_collation_name, + CAST(null AS cardinal_number) AS result_cast_numeric_precision, + CAST(null AS cardinal_number) AS result_cast_numeric_precision_radix, + CAST(null AS cardinal_number) AS result_cast_numeric_scale, + CAST(null AS cardinal_number) AS result_cast_datetime_precision, + CAST(null AS character_data) AS result_cast_interval_type, + CAST(null AS cardinal_number) AS result_cast_interval_precision, + CAST(null AS sql_identifier) AS result_cast_type_udt_catalog, + CAST(null AS sql_identifier) AS result_cast_type_udt_schema, + CAST(null AS sql_identifier) AS result_cast_type_udt_name, + CAST(null AS sql_identifier) AS result_cast_scope_catalog, + CAST(null AS sql_identifier) AS result_cast_scope_schema, + CAST(null AS sql_identifier) AS result_cast_scope_name, + CAST(null AS cardinal_number) AS result_cast_maximum_cardinality, + CAST(null AS sql_identifier) AS result_cast_dtd_identifier + + FROM (pg_namespace n + JOIN pg_proc p ON n.oid = p.pronamespace + JOIN pg_language l ON p.prolang = l.oid) + LEFT JOIN + (pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid) + ON p.prorettype = t.oid AND p.prokind <> 'p' + + WHERE (pg_has_role(p.proowner, 'USAGE') + OR has_function_privilege(p.oid, 'EXECUTE')); + +GRANT SELECT ON routines TO PUBLIC; + + +/* + * 6.56 + * SCHEMATA view + */ + +CREATE VIEW schemata AS + SELECT CAST(current_database() AS sql_identifier) AS catalog_name, + CAST(n.nspname AS sql_identifier) AS schema_name, + CAST(u.rolname AS sql_identifier) AS schema_owner, + CAST(null AS sql_identifier) AS default_character_set_catalog, + CAST(null AS sql_identifier) AS default_character_set_schema, + CAST(null AS sql_identifier) AS default_character_set_name, + CAST(null AS character_data) AS sql_path + FROM pg_namespace n, pg_authid u + WHERE n.nspowner = u.oid + AND (pg_has_role(n.nspowner, 'USAGE') + OR has_schema_privilege(n.oid, 'CREATE, USAGE')); + +GRANT SELECT ON schemata TO PUBLIC; + + +/* + * 6.57 + * SEQUENCES view + */ + +CREATE VIEW sequences AS + SELECT CAST(current_database() AS sql_identifier) AS sequence_catalog, + CAST(nc.nspname AS sql_identifier) AS sequence_schema, + CAST(c.relname AS sql_identifier) AS sequence_name, + CAST(format_type(s.seqtypid, null) AS character_data) AS data_type, + CAST(_pg_numeric_precision(s.seqtypid, -1) AS cardinal_number) AS numeric_precision, + CAST(2 AS cardinal_number) AS numeric_precision_radix, + CAST(0 AS cardinal_number) AS numeric_scale, + CAST(s.seqstart AS character_data) AS start_value, + CAST(s.seqmin AS character_data) AS minimum_value, + CAST(s.seqmax AS character_data) AS maximum_value, + CAST(s.seqincrement AS character_data) AS increment, + CAST(CASE WHEN s.seqcycle THEN 'YES' ELSE 'NO' END AS yes_or_no) AS cycle_option + FROM pg_namespace nc, pg_class c, pg_sequence s + WHERE c.relnamespace = nc.oid + AND c.relkind = 'S' + AND NOT EXISTS (SELECT 1 FROM pg_depend WHERE classid = 'pg_class'::regclass AND objid = c.oid AND deptype = 'i') + AND (NOT pg_is_other_temp_schema(nc.oid)) + AND c.oid = s.seqrelid + AND (pg_has_role(c.relowner, 'USAGE') + OR has_sequence_privilege(c.oid, 'SELECT, UPDATE, USAGE') ); + +GRANT SELECT ON sequences TO PUBLIC; + + +/* + * 6.58 + * SQL_FEATURES table + */ + +CREATE TABLE sql_features ( + feature_id character_data, + feature_name character_data, + sub_feature_id character_data, + sub_feature_name character_data, + is_supported yes_or_no, + is_verified_by character_data, + comments character_data +); + +-- Will be filled with external data by initdb. + +GRANT SELECT ON sql_features TO PUBLIC; + + +/* + * 6.59 + * SQL_IMPLEMENTATION_INFO table + */ + +CREATE TABLE sql_implementation_info ( + implementation_info_id character_data, + implementation_info_name character_data, + integer_value cardinal_number, + character_value character_data, + comments character_data +); + +INSERT INTO sql_implementation_info VALUES ('10003', 'CATALOG NAME', NULL, 'Y', NULL); +INSERT INTO sql_implementation_info VALUES ('10004', 'COLLATING SEQUENCE', NULL, (SELECT default_collate_name FROM character_sets), NULL); +INSERT INTO sql_implementation_info VALUES ('23', 'CURSOR COMMIT BEHAVIOR', 1, NULL, 'close cursors and retain prepared statements'); +INSERT INTO sql_implementation_info VALUES ('2', 'DATA SOURCE NAME', NULL, '', NULL); +INSERT INTO sql_implementation_info VALUES ('17', 'DBMS NAME', NULL, (select trim(trailing ' ' from substring(version() from '^[^0-9]*'))), NULL); +INSERT INTO sql_implementation_info VALUES ('18', 'DBMS VERSION', NULL, '???', NULL); -- filled by initdb +INSERT INTO sql_implementation_info VALUES ('26', 'DEFAULT TRANSACTION ISOLATION', 2, NULL, 'READ COMMITTED; user-settable'); +INSERT INTO sql_implementation_info VALUES ('28', 'IDENTIFIER CASE', 3, NULL, 'stored in mixed case - case sensitive'); +INSERT INTO sql_implementation_info VALUES ('85', 'NULL COLLATION', 0, NULL, 'nulls higher than non-nulls'); +INSERT INTO sql_implementation_info VALUES ('13', 'SERVER NAME', NULL, '', NULL); +INSERT INTO sql_implementation_info VALUES ('94', 'SPECIAL CHARACTERS', NULL, '', 'all non-ASCII characters allowed'); +INSERT INTO sql_implementation_info VALUES ('46', 'TRANSACTION CAPABLE', 2, NULL, 'both DML and DDL'); + +GRANT SELECT ON sql_implementation_info TO PUBLIC; + + +/* + * 6.60 + * SQL_PARTS table + */ + +CREATE TABLE sql_parts ( + feature_id character_data, + feature_name character_data, + is_supported yes_or_no, + is_verified_by character_data, + comments character_data +); + +INSERT INTO sql_parts VALUES ('1', 'Framework (SQL/Framework)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('2', 'Foundation (SQL/Foundation)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('3', 'Call-Level Interface (SQL/CLI)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('4', 'Persistent Stored Modules (SQL/PSM)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('9', 'Management of External Data (SQL/MED)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('10', 'Object Language Bindings (SQL/OLB)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('11', 'Information and Definition Schema (SQL/Schemata)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('13', 'Routines and Types Using the Java Programming Language (SQL/JRT)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('14', 'XML-Related Specifications (SQL/XML)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('15', 'Multi-Dimensional Arrays (SQL/MDA)', 'NO', NULL, ''); +INSERT INTO sql_parts VALUES ('16', 'Property Graph Queries (SQL/PGQ)', 'NO', NULL, ''); + + +/* + * 6.61 + * SQL_SIZING table + */ + +CREATE TABLE sql_sizing ( + sizing_id cardinal_number, + sizing_name character_data, + supported_value cardinal_number, + comments character_data +); + +INSERT INTO sql_sizing VALUES (34, 'MAXIMUM CATALOG NAME LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (30, 'MAXIMUM COLUMN NAME LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (97, 'MAXIMUM COLUMNS IN GROUP BY', 0, NULL); +INSERT INTO sql_sizing VALUES (99, 'MAXIMUM COLUMNS IN ORDER BY', 0, NULL); +INSERT INTO sql_sizing VALUES (100, 'MAXIMUM COLUMNS IN SELECT', 1664, NULL); -- match MaxTupleAttributeNumber +INSERT INTO sql_sizing VALUES (101, 'MAXIMUM COLUMNS IN TABLE', 1600, NULL); -- match MaxHeapAttributeNumber +INSERT INTO sql_sizing VALUES (1, 'MAXIMUM CONCURRENT ACTIVITIES', 0, NULL); +INSERT INTO sql_sizing VALUES (31, 'MAXIMUM CURSOR NAME LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (0, 'MAXIMUM DRIVER CONNECTIONS', NULL, NULL); +INSERT INTO sql_sizing VALUES (10005, 'MAXIMUM IDENTIFIER LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (32, 'MAXIMUM SCHEMA NAME LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (20000, 'MAXIMUM STATEMENT OCTETS', 0, NULL); +INSERT INTO sql_sizing VALUES (20001, 'MAXIMUM STATEMENT OCTETS DATA', 0, NULL); +INSERT INTO sql_sizing VALUES (20002, 'MAXIMUM STATEMENT OCTETS SCHEMA', 0, NULL); +INSERT INTO sql_sizing VALUES (35, 'MAXIMUM TABLE NAME LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (106, 'MAXIMUM TABLES IN SELECT', 0, NULL); +INSERT INTO sql_sizing VALUES (107, 'MAXIMUM USER NAME LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (25000, 'MAXIMUM CURRENT DEFAULT TRANSFORM GROUP LENGTH', NULL, NULL); +INSERT INTO sql_sizing VALUES (25001, 'MAXIMUM CURRENT TRANSFORM GROUP LENGTH', NULL, NULL); +INSERT INTO sql_sizing VALUES (25002, 'MAXIMUM CURRENT PATH LENGTH', 0, NULL); +INSERT INTO sql_sizing VALUES (25003, 'MAXIMUM CURRENT ROLE LENGTH', NULL, NULL); +INSERT INTO sql_sizing VALUES (25004, 'MAXIMUM SESSION USER LENGTH', 63, NULL); +INSERT INTO sql_sizing VALUES (25005, 'MAXIMUM SYSTEM USER LENGTH', 63, NULL); + +UPDATE sql_sizing + SET supported_value = (SELECT typlen-1 FROM pg_catalog.pg_type WHERE typname = 'name'), + comments = 'Might be less, depending on character set.' + WHERE supported_value = 63; + +GRANT SELECT ON sql_sizing TO PUBLIC; + + +/* + * 6.62 + * TABLE_CONSTRAINTS view + */ + +CREATE VIEW table_constraints AS + SELECT 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 table_catalog, + CAST(nr.nspname AS sql_identifier) AS table_schema, + CAST(r.relname AS sql_identifier) AS table_name, + CAST( + CASE c.contype WHEN 'c' THEN 'CHECK' + WHEN 'f' THEN 'FOREIGN KEY' + WHEN 'p' THEN 'PRIMARY KEY' + WHEN 'u' THEN 'UNIQUE' END + AS character_data) AS constraint_type, + CAST(CASE WHEN c.condeferrable THEN 'YES' ELSE 'NO' END AS yes_or_no) + AS is_deferrable, + CAST(CASE WHEN c.condeferred THEN 'YES' ELSE 'NO' END AS yes_or_no) + AS initially_deferred, + CAST('YES' AS yes_or_no) AS enforced, + CAST(CASE WHEN c.contype = 'u' + THEN CASE WHEN (SELECT NOT indnullsnotdistinct FROM pg_index WHERE indexrelid = conindid) THEN 'YES' ELSE 'NO' END + END + AS yes_or_no) AS nulls_distinct + + FROM pg_namespace nc, + pg_namespace nr, + pg_constraint c, + pg_class r + + WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace + AND c.conrelid = r.oid + AND c.contype NOT IN ('t', 'x') -- ignore nonstandard constraints + AND r.relkind IN ('r', 'p') + AND (NOT pg_is_other_temp_schema(nr.oid)) + AND (pg_has_role(r.relowner, 'USAGE') + -- SELECT privilege omitted, per SQL standard + OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') ) + + UNION ALL + + -- not-null constraints + + SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog, + CAST(nr.nspname AS sql_identifier) AS constraint_schema, + CAST(CAST(nr.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nr.nspname AS sql_identifier) AS table_schema, + CAST(r.relname AS sql_identifier) AS table_name, + CAST('CHECK' AS character_data) AS constraint_type, + CAST('NO' AS yes_or_no) AS is_deferrable, + CAST('NO' AS yes_or_no) AS initially_deferred, + CAST('YES' AS yes_or_no) AS enforced, + CAST(NULL AS yes_or_no) AS nulls_distinct + + FROM pg_namespace nr, + pg_class r, + pg_attribute a + + WHERE nr.oid = r.relnamespace + AND r.oid = a.attrelid + AND a.attnotnull + AND a.attnum > 0 + AND NOT a.attisdropped + AND r.relkind IN ('r', 'p') + AND (NOT pg_is_other_temp_schema(nr.oid)) + AND (pg_has_role(r.relowner, 'USAGE') + -- SELECT privilege omitted, per SQL standard + OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') ); + +GRANT SELECT ON table_constraints TO PUBLIC; + + +/* + * 6.63 + * TABLE_METHOD_PRIVILEGES view + */ + +-- feature not supported + + +/* + * 6.64 + * TABLE_PRIVILEGES view + */ + +CREATE VIEW table_privileges AS + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nc.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + CAST(c.prtype AS character_data) AS privilege_type, + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, c.relowner, 'USAGE') + OR c.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable, + CAST(CASE WHEN c.prtype = 'SELECT' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS with_hierarchy + + FROM ( + SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class + ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), + pg_namespace nc, + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE c.relnamespace = nc.oid + AND c.relkind IN ('r', 'v', 'f', 'p') + AND c.grantee = grantee.oid + AND c.grantor = u_grantor.oid + AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC'); + +GRANT SELECT ON table_privileges TO PUBLIC; + + +/* + * 6.45 + * ROLE_TABLE_GRANTS view + */ + +CREATE VIEW role_table_grants AS + SELECT grantor, + grantee, + table_catalog, + table_schema, + table_name, + privilege_type, + is_grantable, + with_hierarchy + FROM table_privileges + WHERE grantor IN (SELECT role_name FROM enabled_roles) + OR grantee IN (SELECT role_name FROM enabled_roles); + +GRANT SELECT ON role_table_grants TO PUBLIC; + + +/* + * 6.65 + * TABLES view + */ + +CREATE VIEW tables AS + SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nc.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + + CAST( + CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY' + WHEN c.relkind IN ('r', 'p') THEN 'BASE TABLE' + WHEN c.relkind = 'v' THEN 'VIEW' + WHEN c.relkind = 'f' THEN 'FOREIGN' + ELSE null END + AS character_data) AS table_type, + + CAST(null AS sql_identifier) AS self_referencing_column_name, + CAST(null AS character_data) AS reference_generation, + + CAST(CASE WHEN t.typname IS NOT NULL THEN current_database() ELSE null END AS sql_identifier) AS user_defined_type_catalog, + CAST(nt.nspname AS sql_identifier) AS user_defined_type_schema, + CAST(t.typname AS sql_identifier) AS user_defined_type_name, + + CAST(CASE WHEN c.relkind IN ('r', 'p') OR + (c.relkind IN ('v', 'f') AND + -- 1 << CMD_INSERT + pg_relation_is_updatable(c.oid, false) & 8 = 8) + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_insertable_into, + + CAST(CASE WHEN t.typname IS NOT NULL THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_typed, + CAST(null AS character_data) AS commit_action + + FROM pg_namespace nc JOIN pg_class c ON (nc.oid = c.relnamespace) + LEFT JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON (c.reloftype = t.oid) + + WHERE c.relkind IN ('r', 'v', 'f', 'p') + AND (NOT pg_is_other_temp_schema(nc.oid)) + AND (pg_has_role(c.relowner, 'USAGE') + OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') ); + +GRANT SELECT ON tables TO PUBLIC; + + +/* + * 6.66 + * TRANSFORMS view + */ + +CREATE VIEW transforms AS + SELECT CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(nt.nspname AS sql_identifier) AS udt_schema, + CAST(t.typname AS sql_identifier) AS udt_name, + 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(l.lanname AS sql_identifier) AS group_name, + CAST('FROM SQL' AS character_data) AS transform_type + FROM pg_type t JOIN pg_transform x ON t.oid = x.trftype + JOIN pg_language l ON x.trflang = l.oid + JOIN pg_proc p ON x.trffromsql = p.oid + JOIN pg_namespace nt ON t.typnamespace = nt.oid + JOIN pg_namespace np ON p.pronamespace = np.oid + + UNION + + SELECT CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(nt.nspname AS sql_identifier) AS udt_schema, + CAST(t.typname AS sql_identifier) AS udt_name, + 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(l.lanname AS sql_identifier) AS group_name, + CAST('TO SQL' AS character_data) AS transform_type + FROM pg_type t JOIN pg_transform x ON t.oid = x.trftype + JOIN pg_language l ON x.trflang = l.oid + JOIN pg_proc p ON x.trftosql = p.oid + JOIN pg_namespace nt ON t.typnamespace = nt.oid + JOIN pg_namespace np ON p.pronamespace = np.oid + + ORDER BY udt_catalog, udt_schema, udt_name, group_name, transform_type -- some sensible grouping for interactive use +; + + +/* + * 6.67 + * TRANSLATIONS view + */ + +-- feature not supported + + +/* + * 6.68 + * TRIGGERED_UPDATE_COLUMNS view + */ + +CREATE VIEW triggered_update_columns AS + SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog, + CAST(n.nspname AS sql_identifier) AS trigger_schema, + CAST(t.tgname AS sql_identifier) AS trigger_name, + CAST(current_database() AS sql_identifier) AS event_object_catalog, + CAST(n.nspname AS sql_identifier) AS event_object_schema, + CAST(c.relname AS sql_identifier) AS event_object_table, + CAST(a.attname AS sql_identifier) AS event_object_column + + FROM pg_namespace n, pg_class c, pg_trigger t, + (SELECT tgoid, (ta0.tgat).x AS tgattnum, (ta0.tgat).n AS tgattpos + FROM (SELECT oid AS tgoid, information_schema._pg_expandarray(tgattr) AS tgat FROM pg_trigger) AS ta0) AS ta, + pg_attribute a + + WHERE n.oid = c.relnamespace + AND c.oid = t.tgrelid + AND t.oid = ta.tgoid + AND (a.attrelid, a.attnum) = (t.tgrelid, ta.tgattnum) + AND NOT t.tgisinternal + AND (NOT pg_is_other_temp_schema(n.oid)) + AND (pg_has_role(c.relowner, 'USAGE') + -- SELECT privilege omitted, per SQL standard + OR has_column_privilege(c.oid, a.attnum, 'INSERT, UPDATE, REFERENCES') ); + +GRANT SELECT ON triggered_update_columns TO PUBLIC; + + +/* + * 6.69 + * TRIGGER_COLUMN_USAGE view + */ + +-- not tracked by PostgreSQL + + +/* + * 6.70 + * TRIGGER_PERIOD_USAGE view + */ + +-- feature not supported + + +/* + * 6.71 + * TRIGGER_ROUTINE_USAGE view + */ + +-- not tracked by PostgreSQL + + +/* + * 6.72 + * TRIGGER_SEQUENCE_USAGE view + */ + +-- not tracked by PostgreSQL + + +/* + * 6.73 + * TRIGGER_TABLE_USAGE view + */ + +-- not tracked by PostgreSQL + + +/* + * 6.74 + * TRIGGERS view + */ + +CREATE VIEW triggers AS + SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog, + CAST(n.nspname AS sql_identifier) AS trigger_schema, + CAST(t.tgname AS sql_identifier) AS trigger_name, + CAST(em.text AS character_data) AS event_manipulation, + CAST(current_database() AS sql_identifier) AS event_object_catalog, + CAST(n.nspname AS sql_identifier) AS event_object_schema, + CAST(c.relname AS sql_identifier) AS event_object_table, + CAST( + -- To determine action order, partition by schema, table, + -- event_manipulation (INSERT/DELETE/UPDATE), ROW/STATEMENT (1), + -- BEFORE/AFTER (66), then order by trigger name. It's preferable + -- to partition by view output columns, so that query constraints + -- can be pushed down below the window function. + rank() OVER (PARTITION BY CAST(n.nspname AS sql_identifier), + CAST(c.relname AS sql_identifier), + em.num, + t.tgtype & 1, + t.tgtype & 66 + ORDER BY t.tgname) + AS cardinal_number) AS action_order, + CAST( + CASE WHEN pg_has_role(c.relowner, 'USAGE') + THEN (regexp_match(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE FUNCTION'))[1] + ELSE null END + AS character_data) AS action_condition, + CAST( + substring(pg_get_triggerdef(t.oid) from + position('EXECUTE FUNCTION' in substring(pg_get_triggerdef(t.oid) from 48)) + 47) + AS character_data) AS action_statement, + CAST( + -- hard-wired reference to TRIGGER_TYPE_ROW + CASE t.tgtype & 1 WHEN 1 THEN 'ROW' ELSE 'STATEMENT' END + AS character_data) AS action_orientation, + CAST( + -- hard-wired refs to TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSTEAD + CASE t.tgtype & 66 WHEN 2 THEN 'BEFORE' WHEN 64 THEN 'INSTEAD OF' ELSE 'AFTER' END + AS character_data) AS action_timing, + CAST(tgoldtable AS sql_identifier) AS action_reference_old_table, + CAST(tgnewtable AS sql_identifier) AS action_reference_new_table, + CAST(null AS sql_identifier) AS action_reference_old_row, + CAST(null AS sql_identifier) AS action_reference_new_row, + CAST(null AS time_stamp) AS created + + FROM pg_namespace n, pg_class c, pg_trigger t, + -- hard-wired refs to TRIGGER_TYPE_INSERT, TRIGGER_TYPE_DELETE, + -- TRIGGER_TYPE_UPDATE; we intentionally omit TRIGGER_TYPE_TRUNCATE + (VALUES (4, 'INSERT'), + (8, 'DELETE'), + (16, 'UPDATE')) AS em (num, text) + + WHERE n.oid = c.relnamespace + AND c.oid = t.tgrelid + AND t.tgtype & em.num <> 0 + AND NOT t.tgisinternal + AND (NOT pg_is_other_temp_schema(n.oid)) + AND (pg_has_role(c.relowner, 'USAGE') + -- SELECT privilege omitted, per SQL standard + OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') ); + +GRANT SELECT ON triggers TO PUBLIC; + + +/* + * 6.75 + * UDT_PRIVILEGES view + */ + +CREATE VIEW udt_privileges AS + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(n.nspname AS sql_identifier) AS udt_schema, + CAST(t.typname AS sql_identifier) AS udt_name, + CAST('TYPE USAGE' AS character_data) AS privilege_type, -- sic + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, t.typowner, 'USAGE') + OR t.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable + + FROM ( + SELECT oid, typname, typnamespace, typtype, typowner, (aclexplode(coalesce(typacl, acldefault('T', typowner)))).* FROM pg_type + ) AS t (oid, typname, typnamespace, typtype, typowner, grantor, grantee, prtype, grantable), + pg_namespace n, + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE t.typnamespace = n.oid + AND t.typtype = 'c' + AND t.grantee = grantee.oid + AND t.grantor = u_grantor.oid + AND t.prtype IN ('USAGE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC'); + +GRANT SELECT ON udt_privileges TO PUBLIC; + + +/* + * 6.48 + * ROLE_UDT_GRANTS view + */ + +CREATE VIEW role_udt_grants AS + SELECT grantor, + grantee, + udt_catalog, + udt_schema, + udt_name, + privilege_type, + is_grantable + FROM udt_privileges + WHERE grantor IN (SELECT role_name FROM enabled_roles) + OR grantee IN (SELECT role_name FROM enabled_roles); + +GRANT SELECT ON role_udt_grants TO PUBLIC; + + +/* + * 6.76 + * USAGE_PRIVILEGES view + */ + +CREATE VIEW usage_privileges AS + + /* collations */ + -- Collations have no real privileges, so we represent all collations with implicit usage privilege here. + SELECT CAST(u.rolname AS sql_identifier) AS grantor, + CAST('PUBLIC' AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS object_catalog, + CAST(n.nspname AS sql_identifier) AS object_schema, + CAST(c.collname AS sql_identifier) AS object_name, + CAST('COLLATION' AS character_data) AS object_type, + CAST('USAGE' AS character_data) AS privilege_type, + CAST('NO' AS yes_or_no) AS is_grantable + + FROM pg_authid u, + pg_namespace n, + pg_collation c + + WHERE u.oid = c.collowner + AND c.collnamespace = n.oid + AND collencoding IN (-1, (SELECT encoding FROM pg_database WHERE datname = current_database())) + + UNION ALL + + /* domains */ + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS object_catalog, + CAST(n.nspname AS sql_identifier) AS object_schema, + CAST(t.typname AS sql_identifier) AS object_name, + CAST('DOMAIN' AS character_data) AS object_type, + CAST('USAGE' AS character_data) AS privilege_type, + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, t.typowner, 'USAGE') + OR t.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable + + FROM ( + SELECT oid, typname, typnamespace, typtype, typowner, (aclexplode(coalesce(typacl, acldefault('T', typowner)))).* FROM pg_type + ) AS t (oid, typname, typnamespace, typtype, typowner, grantor, grantee, prtype, grantable), + pg_namespace n, + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE t.typnamespace = n.oid + AND t.typtype = 'd' + AND t.grantee = grantee.oid + AND t.grantor = u_grantor.oid + AND t.prtype IN ('USAGE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC') + + UNION ALL + + /* foreign-data wrappers */ + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS object_catalog, + CAST('' AS sql_identifier) AS object_schema, + CAST(fdw.fdwname AS sql_identifier) AS object_name, + CAST('FOREIGN DATA WRAPPER' AS character_data) AS object_type, + CAST('USAGE' AS character_data) AS privilege_type, + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, fdw.fdwowner, 'USAGE') + OR fdw.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable + + FROM ( + SELECT fdwname, fdwowner, (aclexplode(coalesce(fdwacl, acldefault('F', fdwowner)))).* FROM pg_foreign_data_wrapper + ) AS fdw (fdwname, fdwowner, grantor, grantee, prtype, grantable), + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE u_grantor.oid = fdw.grantor + AND grantee.oid = fdw.grantee + AND fdw.prtype IN ('USAGE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC') + + UNION ALL + + /* foreign servers */ + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS object_catalog, + CAST('' AS sql_identifier) AS object_schema, + CAST(srv.srvname AS sql_identifier) AS object_name, + CAST('FOREIGN SERVER' AS character_data) AS object_type, + CAST('USAGE' AS character_data) AS privilege_type, + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, srv.srvowner, 'USAGE') + OR srv.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable + + FROM ( + SELECT srvname, srvowner, (aclexplode(coalesce(srvacl, acldefault('S', srvowner)))).* FROM pg_foreign_server + ) AS srv (srvname, srvowner, grantor, grantee, prtype, grantable), + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE u_grantor.oid = srv.grantor + AND grantee.oid = srv.grantee + AND srv.prtype IN ('USAGE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC') + + UNION ALL + + /* sequences */ + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, + CAST(current_database() AS sql_identifier) AS object_catalog, + CAST(n.nspname AS sql_identifier) AS object_schema, + CAST(c.relname AS sql_identifier) AS object_name, + CAST('SEQUENCE' AS character_data) AS object_type, + CAST('USAGE' AS character_data) AS privilege_type, + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, c.relowner, 'USAGE') + OR c.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable + + FROM ( + SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class + ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), + pg_namespace n, + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) + + WHERE c.relnamespace = n.oid + AND c.relkind = 'S' + AND c.grantee = grantee.oid + AND c.grantor = u_grantor.oid + AND c.prtype IN ('USAGE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC'); + +GRANT SELECT ON usage_privileges TO PUBLIC; + + +/* + * 6.47 + * ROLE_USAGE_GRANTS view + */ + +CREATE VIEW role_usage_grants AS + SELECT grantor, + grantee, + object_catalog, + object_schema, + object_name, + object_type, + privilege_type, + is_grantable + FROM usage_privileges + WHERE grantor IN (SELECT role_name FROM enabled_roles) + OR grantee IN (SELECT role_name FROM enabled_roles); + +GRANT SELECT ON role_usage_grants TO PUBLIC; + + +/* + * 6.77 + * USER_DEFINED_TYPES view + */ + +CREATE VIEW user_defined_types AS + SELECT CAST(current_database() AS sql_identifier) AS user_defined_type_catalog, + CAST(n.nspname AS sql_identifier) AS user_defined_type_schema, + CAST(c.relname AS sql_identifier) AS user_defined_type_name, + CAST('STRUCTURED' AS character_data) AS user_defined_type_category, + CAST('YES' AS yes_or_no) AS is_instantiable, + CAST(null AS yes_or_no) AS is_final, + CAST(null AS character_data) AS ordering_form, + CAST(null AS character_data) AS ordering_category, + CAST(null AS sql_identifier) AS ordering_routine_catalog, + CAST(null AS sql_identifier) AS ordering_routine_schema, + CAST(null AS sql_identifier) AS ordering_routine_name, + CAST(null AS character_data) AS reference_type, + CAST(null AS character_data) AS data_type, + CAST(null AS cardinal_number) AS character_maximum_length, + CAST(null AS cardinal_number) AS character_octet_length, + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(null AS sql_identifier) AS character_set_name, + CAST(null AS sql_identifier) AS collation_catalog, + CAST(null AS sql_identifier) AS collation_schema, + CAST(null AS sql_identifier) AS collation_name, + CAST(null AS cardinal_number) AS numeric_precision, + CAST(null AS cardinal_number) AS numeric_precision_radix, + CAST(null AS cardinal_number) AS numeric_scale, + CAST(null AS cardinal_number) AS datetime_precision, + CAST(null AS character_data) AS interval_type, + CAST(null AS cardinal_number) AS interval_precision, + CAST(null AS sql_identifier) AS source_dtd_identifier, + CAST(null AS sql_identifier) AS ref_dtd_identifier + + FROM pg_namespace n, pg_class c, pg_type t + + WHERE n.oid = c.relnamespace + AND t.typrelid = c.oid + AND c.relkind = 'c' + AND (pg_has_role(t.typowner, 'USAGE') + OR has_type_privilege(t.oid, 'USAGE')); + +GRANT SELECT ON user_defined_types TO PUBLIC; + + +/* + * 6.78 + * VIEW_COLUMN_USAGE + */ + +CREATE VIEW view_column_usage AS + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS view_catalog, + CAST(nv.nspname AS sql_identifier) AS view_schema, + CAST(v.relname AS sql_identifier) AS view_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 nv, pg_class v, pg_depend dv, + pg_depend dt, pg_class t, pg_namespace nt, + pg_attribute a + + WHERE nv.oid = v.relnamespace + AND v.relkind = 'v' + AND v.oid = dv.refobjid + AND dv.refclassid = 'pg_catalog.pg_class'::regclass + AND dv.classid = 'pg_catalog.pg_rewrite'::regclass + AND dv.deptype = 'i' + AND dv.objid = dt.objid + AND dv.refobjid <> dt.refobjid + AND dt.classid = 'pg_catalog.pg_rewrite'::regclass + AND dt.refclassid = 'pg_catalog.pg_class'::regclass + AND dt.refobjid = t.oid + AND t.relnamespace = nt.oid + AND t.relkind IN ('r', 'v', 'f', 'p') + AND t.oid = a.attrelid + AND dt.refobjsubid = a.attnum + AND pg_has_role(t.relowner, 'USAGE'); + +GRANT SELECT ON view_column_usage TO PUBLIC; + + +/* + * 6.79 + * VIEW_PERIOD_USAGE + */ + +-- feature not supported + + +/* + * 6.80 + * VIEW_ROUTINE_USAGE + */ + +CREATE VIEW view_routine_usage AS + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nv.nspname AS sql_identifier) AS table_schema, + CAST(v.relname AS sql_identifier) AS table_name, + 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 + + FROM pg_namespace nv, pg_class v, pg_depend dv, + pg_depend dp, pg_proc p, pg_namespace np + + WHERE nv.oid = v.relnamespace + AND v.relkind = 'v' + AND v.oid = dv.refobjid + AND dv.refclassid = 'pg_catalog.pg_class'::regclass + AND dv.classid = 'pg_catalog.pg_rewrite'::regclass + AND dv.deptype = 'i' + AND dv.objid = dp.objid + AND dp.classid = 'pg_catalog.pg_rewrite'::regclass + AND dp.refclassid = 'pg_catalog.pg_proc'::regclass + AND dp.refobjid = p.oid + AND p.pronamespace = np.oid + AND pg_has_role(p.proowner, 'USAGE'); + +GRANT SELECT ON view_routine_usage TO PUBLIC; + + +/* + * 6.81 + * VIEW_TABLE_USAGE + */ + +CREATE VIEW view_table_usage AS + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS view_catalog, + CAST(nv.nspname AS sql_identifier) AS view_schema, + CAST(v.relname AS sql_identifier) AS view_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 nv, pg_class v, pg_depend dv, + pg_depend dt, pg_class t, pg_namespace nt + + WHERE nv.oid = v.relnamespace + AND v.relkind = 'v' + AND v.oid = dv.refobjid + AND dv.refclassid = 'pg_catalog.pg_class'::regclass + AND dv.classid = 'pg_catalog.pg_rewrite'::regclass + AND dv.deptype = 'i' + AND dv.objid = dt.objid + AND dv.refobjid <> dt.refobjid + AND dt.classid = 'pg_catalog.pg_rewrite'::regclass + AND dt.refclassid = 'pg_catalog.pg_class'::regclass + AND dt.refobjid = t.oid + AND t.relnamespace = nt.oid + AND t.relkind IN ('r', 'v', 'f', 'p') + AND pg_has_role(t.relowner, 'USAGE'); + +GRANT SELECT ON view_table_usage TO PUBLIC; + + +/* + * 6.82 + * VIEWS view + */ + +CREATE VIEW views AS + SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nc.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + + CAST( + CASE WHEN pg_has_role(c.relowner, 'USAGE') + THEN pg_get_viewdef(c.oid) + ELSE null END + AS character_data) AS view_definition, + + CAST( + CASE WHEN 'check_option=cascaded' = ANY (c.reloptions) + THEN 'CASCADED' + WHEN 'check_option=local' = ANY (c.reloptions) + THEN 'LOCAL' + ELSE 'NONE' END + AS character_data) AS check_option, + + CAST( + -- (1 << CMD_UPDATE) + (1 << CMD_DELETE) + CASE WHEN pg_relation_is_updatable(c.oid, false) & 20 = 20 + THEN 'YES' ELSE 'NO' END + AS yes_or_no) AS is_updatable, + + CAST( + -- 1 << CMD_INSERT + CASE WHEN pg_relation_is_updatable(c.oid, false) & 8 = 8 + THEN 'YES' ELSE 'NO' END + AS yes_or_no) AS is_insertable_into, + + CAST( + -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_UPDATE + CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 81 = 81) + THEN 'YES' ELSE 'NO' END + AS yes_or_no) AS is_trigger_updatable, + + CAST( + -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_DELETE + CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 73 = 73) + THEN 'YES' ELSE 'NO' END + AS yes_or_no) AS is_trigger_deletable, + + CAST( + -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_INSERT + CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 69 = 69) + THEN 'YES' ELSE 'NO' END + AS yes_or_no) AS is_trigger_insertable_into + + FROM pg_namespace nc, pg_class c + + WHERE c.relnamespace = nc.oid + AND c.relkind = 'v' + AND (NOT pg_is_other_temp_schema(nc.oid)) + AND (pg_has_role(c.relowner, 'USAGE') + OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') ); + +GRANT SELECT ON views TO PUBLIC; + + +-- The following views have dependencies that force them to appear out of order. + +/* + * 6.26 + * DATA_TYPE_PRIVILEGES view + */ + +CREATE VIEW data_type_privileges AS + SELECT CAST(current_database() AS sql_identifier) AS object_catalog, + CAST(x.objschema AS sql_identifier) AS object_schema, + CAST(x.objname AS sql_identifier) AS object_name, + CAST(x.objtype AS character_data) AS object_type, + CAST(x.objdtdid AS sql_identifier) AS dtd_identifier + + FROM + ( + SELECT udt_schema, udt_name, 'USER-DEFINED TYPE'::text, dtd_identifier FROM attributes + UNION ALL + SELECT table_schema, table_name, 'TABLE'::text, dtd_identifier FROM columns + UNION ALL + SELECT domain_schema, domain_name, 'DOMAIN'::text, dtd_identifier FROM domains + UNION ALL + SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM parameters + UNION ALL + SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM routines + ) AS x (objschema, objname, objtype, objdtdid); + +GRANT SELECT ON data_type_privileges TO PUBLIC; + + +/* + * 6.31 + * ELEMENT_TYPES view + */ + +CREATE VIEW element_types AS + SELECT CAST(current_database() AS sql_identifier) AS object_catalog, + CAST(n.nspname AS sql_identifier) AS object_schema, + CAST(x.objname AS sql_identifier) AS object_name, + CAST(x.objtype AS character_data) AS object_type, + CAST(x.objdtdid AS sql_identifier) AS collection_type_identifier, + CAST( + CASE WHEN nbt.nspname = 'pg_catalog' THEN format_type(bt.oid, null) + ELSE 'USER-DEFINED' END AS character_data) AS data_type, + + CAST(null AS cardinal_number) AS character_maximum_length, + CAST(null AS cardinal_number) AS character_octet_length, + CAST(null AS sql_identifier) AS character_set_catalog, + CAST(null AS sql_identifier) AS character_set_schema, + CAST(null AS sql_identifier) AS character_set_name, + CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog, + CAST(nco.nspname AS sql_identifier) AS collation_schema, + CAST(co.collname AS sql_identifier) AS collation_name, + CAST(null AS cardinal_number) AS numeric_precision, + CAST(null AS cardinal_number) AS numeric_precision_radix, + CAST(null AS cardinal_number) AS numeric_scale, + CAST(null AS cardinal_number) AS datetime_precision, + CAST(null AS character_data) AS interval_type, + CAST(null AS cardinal_number) AS interval_precision, + + CAST(null AS character_data) AS domain_default, -- XXX maybe a bug in the standard + + CAST(current_database() AS sql_identifier) AS udt_catalog, + CAST(nbt.nspname AS sql_identifier) AS udt_schema, + CAST(bt.typname AS sql_identifier) AS udt_name, + + CAST(null AS sql_identifier) AS scope_catalog, + CAST(null AS sql_identifier) AS scope_schema, + CAST(null AS sql_identifier) AS scope_name, + + CAST(null AS cardinal_number) AS maximum_cardinality, + CAST('a' || CAST(x.objdtdid AS text) AS sql_identifier) AS dtd_identifier + + FROM pg_namespace n, pg_type at, pg_namespace nbt, pg_type bt, + ( + /* columns, attributes */ + SELECT c.relnamespace, CAST(c.relname AS sql_identifier), + CASE WHEN c.relkind = 'c' THEN 'USER-DEFINED TYPE'::text ELSE 'TABLE'::text END, + a.attnum, a.atttypid, a.attcollation + FROM pg_class c, pg_attribute a + WHERE c.oid = a.attrelid + AND c.relkind IN ('r', 'v', 'f', 'c', 'p') + AND attnum > 0 AND NOT attisdropped + + UNION ALL + + /* domains */ + SELECT t.typnamespace, CAST(t.typname AS sql_identifier), + 'DOMAIN'::text, 1, t.typbasetype, t.typcollation + FROM pg_type t + WHERE t.typtype = 'd' + + UNION ALL + + /* parameters */ + SELECT pronamespace, + CAST(nameconcatoid(proname, oid) AS sql_identifier), + 'ROUTINE'::text, (ss.x).n, (ss.x).x, 0 + FROM (SELECT p.pronamespace, p.proname, p.oid, + _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x + FROM pg_proc p) AS ss + + UNION ALL + + /* result types */ + SELECT p.pronamespace, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier), + 'ROUTINE'::text, 0, p.prorettype, 0 + FROM pg_proc p + + ) AS x (objschema, objname, objtype, objdtdid, objtypeid, objcollation) + LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid)) + ON x.objcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default') + + WHERE n.oid = x.objschema + AND at.oid = x.objtypeid + AND (at.typelem <> 0 AND at.typlen = -1) + AND at.typelem = bt.oid + AND nbt.oid = bt.typnamespace + + AND (n.nspname, x.objname, x.objtype, CAST(x.objdtdid AS sql_identifier)) IN + ( SELECT object_schema, object_name, object_type, dtd_identifier + FROM data_type_privileges ); + +GRANT SELECT ON element_types TO PUBLIC; + + +-- SQL/MED views; these use section numbers from part 9 of the standard. + +/* Base view for foreign table columns */ +CREATE VIEW _pg_foreign_table_columns AS + SELECT n.nspname, + c.relname, + a.attname, + a.attfdwoptions + FROM pg_foreign_table t, pg_authid u, pg_namespace n, pg_class c, + pg_attribute a + WHERE u.oid = c.relowner + AND (pg_has_role(c.relowner, 'USAGE') + OR has_column_privilege(c.oid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES')) + AND n.oid = c.relnamespace + AND c.oid = t.ftrelid + AND c.relkind = 'f' + AND a.attrelid = c.oid + AND a.attnum > 0; + +/* + * 24.3 + * COLUMN_OPTIONS view + */ +CREATE VIEW column_options AS + SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(c.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + CAST(c.attname AS sql_identifier) AS column_name, + CAST((pg_options_to_table(c.attfdwoptions)).option_name AS sql_identifier) AS option_name, + CAST((pg_options_to_table(c.attfdwoptions)).option_value AS character_data) AS option_value + FROM _pg_foreign_table_columns c; + +GRANT SELECT ON column_options TO PUBLIC; + + +/* Base view for foreign-data wrappers */ +CREATE VIEW _pg_foreign_data_wrappers AS + SELECT w.oid, + w.fdwowner, + w.fdwoptions, + CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog, + CAST(fdwname AS sql_identifier) AS foreign_data_wrapper_name, + CAST(u.rolname AS sql_identifier) AS authorization_identifier, + CAST('c' AS character_data) AS foreign_data_wrapper_language + FROM pg_foreign_data_wrapper w, pg_authid u + WHERE u.oid = w.fdwowner + AND (pg_has_role(fdwowner, 'USAGE') + OR has_foreign_data_wrapper_privilege(w.oid, 'USAGE')); + + +/* + * 24.5 + * FOREIGN_DATA_WRAPPER_OPTIONS view + */ +CREATE VIEW foreign_data_wrapper_options AS + SELECT foreign_data_wrapper_catalog, + foreign_data_wrapper_name, + CAST((pg_options_to_table(w.fdwoptions)).option_name AS sql_identifier) AS option_name, + CAST((pg_options_to_table(w.fdwoptions)).option_value AS character_data) AS option_value + FROM _pg_foreign_data_wrappers w; + +GRANT SELECT ON foreign_data_wrapper_options TO PUBLIC; + + +/* + * 24.6 + * FOREIGN_DATA_WRAPPERS view + */ +CREATE VIEW foreign_data_wrappers AS + SELECT foreign_data_wrapper_catalog, + foreign_data_wrapper_name, + authorization_identifier, + CAST(NULL AS character_data) AS library_name, + foreign_data_wrapper_language + FROM _pg_foreign_data_wrappers w; + +GRANT SELECT ON foreign_data_wrappers TO PUBLIC; + + +/* Base view for foreign servers */ +CREATE VIEW _pg_foreign_servers AS + SELECT s.oid, + s.srvoptions, + CAST(current_database() AS sql_identifier) AS foreign_server_catalog, + CAST(srvname AS sql_identifier) AS foreign_server_name, + CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog, + CAST(w.fdwname AS sql_identifier) AS foreign_data_wrapper_name, + CAST(srvtype AS character_data) AS foreign_server_type, + CAST(srvversion AS character_data) AS foreign_server_version, + CAST(u.rolname AS sql_identifier) AS authorization_identifier + FROM pg_foreign_server s, pg_foreign_data_wrapper w, pg_authid u + WHERE w.oid = s.srvfdw + AND u.oid = s.srvowner + AND (pg_has_role(s.srvowner, 'USAGE') + OR has_server_privilege(s.oid, 'USAGE')); + + +/* + * 24.7 + * FOREIGN_SERVER_OPTIONS view + */ +CREATE VIEW foreign_server_options AS + SELECT foreign_server_catalog, + foreign_server_name, + CAST((pg_options_to_table(s.srvoptions)).option_name AS sql_identifier) AS option_name, + CAST((pg_options_to_table(s.srvoptions)).option_value AS character_data) AS option_value + FROM _pg_foreign_servers s; + +GRANT SELECT ON TABLE foreign_server_options TO PUBLIC; + + +/* + * 24.8 + * FOREIGN_SERVERS view + */ +CREATE VIEW foreign_servers AS + SELECT foreign_server_catalog, + foreign_server_name, + foreign_data_wrapper_catalog, + foreign_data_wrapper_name, + foreign_server_type, + foreign_server_version, + authorization_identifier + FROM _pg_foreign_servers; + +GRANT SELECT ON foreign_servers TO PUBLIC; + + +/* Base view for foreign tables */ +CREATE VIEW _pg_foreign_tables AS + SELECT + CAST(current_database() AS sql_identifier) AS foreign_table_catalog, + CAST(n.nspname AS sql_identifier) AS foreign_table_schema, + CAST(c.relname AS sql_identifier) AS foreign_table_name, + t.ftoptions AS ftoptions, + CAST(current_database() AS sql_identifier) AS foreign_server_catalog, + CAST(srvname AS sql_identifier) AS foreign_server_name, + CAST(u.rolname AS sql_identifier) AS authorization_identifier + FROM pg_foreign_table t, pg_foreign_server s, pg_foreign_data_wrapper w, + pg_authid u, pg_namespace n, pg_class c + WHERE w.oid = s.srvfdw + AND u.oid = c.relowner + AND (pg_has_role(c.relowner, 'USAGE') + OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') + OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES')) + AND n.oid = c.relnamespace + AND c.oid = t.ftrelid + AND c.relkind = 'f' + AND s.oid = t.ftserver; + + +/* + * 24.9 + * FOREIGN_TABLE_OPTIONS view + */ +CREATE VIEW foreign_table_options AS + SELECT foreign_table_catalog, + foreign_table_schema, + foreign_table_name, + CAST((pg_options_to_table(t.ftoptions)).option_name AS sql_identifier) AS option_name, + CAST((pg_options_to_table(t.ftoptions)).option_value AS character_data) AS option_value + FROM _pg_foreign_tables t; + +GRANT SELECT ON TABLE foreign_table_options TO PUBLIC; + + +/* + * 24.10 + * FOREIGN_TABLES view + */ +CREATE VIEW foreign_tables AS + SELECT foreign_table_catalog, + foreign_table_schema, + foreign_table_name, + foreign_server_catalog, + foreign_server_name + FROM _pg_foreign_tables; + +GRANT SELECT ON foreign_tables TO PUBLIC; + + + +/* Base view for user mappings */ +CREATE VIEW _pg_user_mappings AS + SELECT um.oid, + um.umoptions, + um.umuser, + CAST(COALESCE(u.rolname,'PUBLIC') AS sql_identifier ) AS authorization_identifier, + s.foreign_server_catalog, + s.foreign_server_name, + s.authorization_identifier AS srvowner + FROM pg_user_mapping um LEFT JOIN pg_authid u ON (u.oid = um.umuser), + _pg_foreign_servers s + WHERE s.oid = um.umserver; + + +/* + * 24.13 + * USER_MAPPING_OPTIONS view + */ +CREATE VIEW user_mapping_options AS + SELECT authorization_identifier, + foreign_server_catalog, + foreign_server_name, + CAST(opts.option_name AS sql_identifier) AS option_name, + CAST(CASE WHEN (umuser <> 0 AND authorization_identifier = current_user) + OR (umuser = 0 AND pg_has_role(srvowner, 'USAGE')) + OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) + THEN opts.option_value + ELSE NULL END AS character_data) AS option_value + FROM _pg_user_mappings um, + pg_options_to_table(um.umoptions) opts; + +GRANT SELECT ON user_mapping_options TO PUBLIC; + + +/* + * 24.14 + * USER_MAPPINGS view + */ +CREATE VIEW user_mappings AS + SELECT authorization_identifier, + foreign_server_catalog, + foreign_server_name + FROM _pg_user_mappings; + +GRANT SELECT ON user_mappings TO PUBLIC; diff --git a/install/share/postgresql/pg_hba.conf.sample b/install/share/postgresql/pg_hba.conf.sample new file mode 100644 index 00000000000..bad13497a34 --- /dev/null +++ b/install/share/postgresql/pg_hba.conf.sample @@ -0,0 +1,122 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# ---------------------- +# Authentication Records +# ---------------------- +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# 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, a regular expression (if it starts with a slash (/)) +# or a comma-separated list thereof. The "all" keyword does not match +# "replication". Access to replication must be enabled in a separate +# record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", a +# regular expression (if it starts with a slash (/)) or a comma-separated +# list thereof. In both the DATABASE and USER fields you can also write +# a file name prefixed with "@" to include names from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "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. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# --------------- +# Include Records +# --------------- +# +# This file allows the inclusion of external files or directories holding +# more records, using the following keywords: +# +# include FILE +# include_if_exists FILE +# include_dir DIRECTORY +# +# FILE is the file name to include, and DIR is the directory name containing +# the file(s) to include. Any file in a directory will be loaded if suffixed +# with ".conf". The files of a directory are ordered by name. +# include_if_exists ignores missing files. FILE and DIRECTORY can be +# specified as a relative or an absolute path, and can be double-quoted if +# they contain spaces. +# +# ------------- +# Miscellaneous +# ------------- +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# ---------------------------------- +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + +@authcomment@ + +# TYPE DATABASE USER ADDRESS METHOD + +@remove-line-for-nolocal@# "local" is for Unix domain socket connections only +@remove-line-for-nolocal@local all all @authmethodlocal@ +# IPv4 local connections: +host all all 127.0.0.1/32 @authmethodhost@ +# IPv6 local connections: +host all all ::1/128 @authmethodhost@ +# Allow replication connections from localhost, by a user with the +# replication privilege. +@remove-line-for-nolocal@local replication all @authmethodlocal@ +host replication all 127.0.0.1/32 @authmethodhost@ +host replication all ::1/128 @authmethodhost@ diff --git a/install/share/postgresql/pg_ident.conf.sample b/install/share/postgresql/pg_ident.conf.sample new file mode 100644 index 00000000000..f5225f26cdf --- /dev/null +++ b/install/share/postgresql/pg_ident.conf.sample @@ -0,0 +1,72 @@ +# PostgreSQL User Name Maps +# ========================= +# +# --------------- +# Mapping Records +# --------------- +# +# Refer to the PostgreSQL documentation, chapter "Client +# Authentication" for a complete description. A short synopsis +# follows. +# +# This file controls PostgreSQL user name mapping. It maps external +# user names to their corresponding PostgreSQL user names. Records +# are of the form: +# +# MAPNAME SYSTEM-USERNAME PG-USERNAME +# +# (The uppercase quantities must be replaced by actual values.) +# +# MAPNAME is the (otherwise freely chosen) map name that was used in +# pg_hba.conf. SYSTEM-USERNAME is the detected user name of the +# client. PG-USERNAME is the requested PostgreSQL user name. The +# existence of a record specifies that SYSTEM-USERNAME may connect as +# PG-USERNAME. +# +# If SYSTEM-USERNAME starts with a slash (/), it will be treated as a +# regular expression. Optionally this can contain a capture (a +# parenthesized subexpression). The substring matching the capture +# will be substituted for \1 (backslash-one) if present in +# PG-USERNAME. +# +# PG-USERNAME can be "all", a user name, a group name prefixed with "+", or +# a regular expression (if it starts with a slash (/)). If it is a regular +# expression, the substring matching with \1 has no effect. +# +# Multiple maps may be specified in this file and used by pg_hba.conf. +# +# No map names are defined in the default configuration. If all +# system user names and PostgreSQL user names are the same, you don't +# need anything in this file. +# +# --------------- +# Include Records +# --------------- +# +# This file allows the inclusion of external files or directories holding +# more records, using the following keywords: +# +# include FILE +# include_if_exists FILE +# include_dir DIRECTORY +# +# FILE is the file name to include, and DIR is the directory name containing +# the file(s) to include. Any file in a directory will be loaded if suffixed +# with ".conf". The files of a directory are ordered by name. +# include_if_exists ignores missing files. FILE and DIRECTORY can be +# specified as a relative or an absolute path, and can be double-quoted if +# they contain spaces. +# +# ------------------------------- +# Miscellaneous +# ------------------------------- +# +# This file is read on server startup and when the postmaster receives +# a SIGHUP signal. If you edit the file on a running system, you have +# to SIGHUP the postmaster for the changes to take effect. You can +# use "pg_ctl reload" to do that. + +# Put your actual configuration here +# ---------------------------------- + +# MAPNAME SYSTEM-USERNAME PG-USERNAME diff --git a/install/share/postgresql/pg_service.conf.sample b/install/share/postgresql/pg_service.conf.sample new file mode 100644 index 00000000000..5a1c083538b --- /dev/null +++ b/install/share/postgresql/pg_service.conf.sample @@ -0,0 +1,17 @@ +# +# Connection configuration file +# +# A service is a set of named connection parameters. You may specify +# multiple services in this file. Each starts with a service name in +# brackets. Subsequent lines have connection configuration parameters of +# the pattern "param=value" or LDAP URLs starting with "ldap://" +# to look up such parameters. A sample configuration for postgres is +# included in this file. Lines beginning with '#' are comments. +# +# Copy this to your sysconf directory (typically /usr/local/pgsql/etc) and +# rename it pg_service.conf. +# +# +#[postgres] +#dbname=postgres +#user=postgres diff --git a/install/share/postgresql/postgres.bki b/install/share/postgresql/postgres.bki new file mode 100644 index 00000000000..e8b07cdd422 --- /dev/null +++ b/install/share/postgresql/postgres.bki @@ -0,0 +1,11706 @@ +# PostgreSQL 16 +create pg_proc 1255 bootstrap rowtype_oid 81 + ( + oid = oid , + proname = name , + pronamespace = oid , + proowner = oid , + prolang = oid , + procost = float4 , + prorows = float4 , + provariadic = oid , + prosupport = regproc , + prokind = char , + prosecdef = bool , + proleakproof = bool , + proisstrict = bool , + proretset = bool , + provolatile = char , + proparallel = char , + pronargs = int2 , + pronargdefaults = int2 , + prorettype = oid , + proargtypes = oidvector FORCE NOT NULL , + proallargtypes = _oid , + proargmodes = _char , + proargnames = _text , + proargdefaults = pg_node_tree , + protrftypes = _oid , + prosrc = text FORCE NOT NULL , + probin = text , + prosqlbody = pg_node_tree , + proconfig = _text , + proacl = _aclitem + ) +insert ( 1242 boolin 11 10 12 1 0 0 0 f f f t f i s 1 0 16 2275 _null_ _null_ _null_ _null_ _null_ boolin _null_ _null_ _null_ _null_ ) +insert ( 1243 boolout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 16 _null_ _null_ _null_ _null_ _null_ boolout _null_ _null_ _null_ _null_ ) +insert ( 1244 byteain 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2275 _null_ _null_ _null_ _null_ _null_ byteain _null_ _null_ _null_ _null_ ) +insert ( 31 byteaout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 17 _null_ _null_ _null_ _null_ _null_ byteaout _null_ _null_ _null_ _null_ ) +insert ( 1245 charin 11 10 12 1 0 0 0 f f f t f i s 1 0 18 2275 _null_ _null_ _null_ _null_ _null_ charin _null_ _null_ _null_ _null_ ) +insert ( 33 charout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 18 _null_ _null_ _null_ _null_ _null_ charout _null_ _null_ _null_ _null_ ) +insert ( 34 namein 11 10 12 1 0 0 0 f f f t f i s 1 0 19 2275 _null_ _null_ _null_ _null_ _null_ namein _null_ _null_ _null_ _null_ ) +insert ( 35 nameout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 19 _null_ _null_ _null_ _null_ _null_ nameout _null_ _null_ _null_ _null_ ) +insert ( 38 int2in 11 10 12 1 0 0 0 f f f t f i s 1 0 21 2275 _null_ _null_ _null_ _null_ _null_ int2in _null_ _null_ _null_ _null_ ) +insert ( 39 int2out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 21 _null_ _null_ _null_ _null_ _null_ int2out _null_ _null_ _null_ _null_ ) +insert ( 40 int2vectorin 11 10 12 1 0 0 0 f f f t f i s 1 0 22 2275 _null_ _null_ _null_ _null_ _null_ int2vectorin _null_ _null_ _null_ _null_ ) +insert ( 41 int2vectorout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 22 _null_ _null_ _null_ _null_ _null_ int2vectorout _null_ _null_ _null_ _null_ ) +insert ( 42 int4in 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2275 _null_ _null_ _null_ _null_ _null_ int4in _null_ _null_ _null_ _null_ ) +insert ( 43 int4out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ int4out _null_ _null_ _null_ _null_ ) +insert ( 44 regprocin 11 10 12 1 0 0 0 f f f t f s s 1 0 24 2275 _null_ _null_ _null_ _null_ _null_ regprocin _null_ _null_ _null_ _null_ ) +insert ( 45 regprocout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 24 _null_ _null_ _null_ _null_ _null_ regprocout _null_ _null_ _null_ _null_ ) +insert ( 3494 to_regproc 11 10 12 1 0 0 0 f f f t f s s 1 0 24 25 _null_ _null_ _null_ _null_ _null_ to_regproc _null_ _null_ _null_ _null_ ) +insert ( 3479 to_regprocedure 11 10 12 1 0 0 0 f f f t f s s 1 0 2202 25 _null_ _null_ _null_ _null_ _null_ to_regprocedure _null_ _null_ _null_ _null_ ) +insert ( 46 textin 11 10 12 1 0 0 0 f f f t f i s 1 0 25 2275 _null_ _null_ _null_ _null_ _null_ textin _null_ _null_ _null_ _null_ ) +insert ( 47 textout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 25 _null_ _null_ _null_ _null_ _null_ textout _null_ _null_ _null_ _null_ ) +insert ( 48 tidin 11 10 12 1 0 0 0 f f f t f i s 1 0 27 2275 _null_ _null_ _null_ _null_ _null_ tidin _null_ _null_ _null_ _null_ ) +insert ( 49 tidout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 27 _null_ _null_ _null_ _null_ _null_ tidout _null_ _null_ _null_ _null_ ) +insert ( 50 xidin 11 10 12 1 0 0 0 f f f t f i s 1 0 28 2275 _null_ _null_ _null_ _null_ _null_ xidin _null_ _null_ _null_ _null_ ) +insert ( 51 xidout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 28 _null_ _null_ _null_ _null_ _null_ xidout _null_ _null_ _null_ _null_ ) +insert ( 5070 xid8in 11 10 12 1 0 0 0 f f f t f i s 1 0 5069 2275 _null_ _null_ _null_ _null_ _null_ xid8in _null_ _null_ _null_ _null_ ) +insert ( 5081 xid8out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 5069 _null_ _null_ _null_ _null_ _null_ xid8out _null_ _null_ _null_ _null_ ) +insert ( 5082 xid8recv 11 10 12 1 0 0 0 f f f t f i s 1 0 5069 2281 _null_ _null_ _null_ _null_ _null_ xid8recv _null_ _null_ _null_ _null_ ) +insert ( 5083 xid8send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 5069 _null_ _null_ _null_ _null_ _null_ xid8send _null_ _null_ _null_ _null_ ) +insert ( 52 cidin 11 10 12 1 0 0 0 f f f t f i s 1 0 29 2275 _null_ _null_ _null_ _null_ _null_ cidin _null_ _null_ _null_ _null_ ) +insert ( 53 cidout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 29 _null_ _null_ _null_ _null_ _null_ cidout _null_ _null_ _null_ _null_ ) +insert ( 54 oidvectorin 11 10 12 1 0 0 0 f f f t f i s 1 0 30 2275 _null_ _null_ _null_ _null_ _null_ oidvectorin _null_ _null_ _null_ _null_ ) +insert ( 55 oidvectorout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 30 _null_ _null_ _null_ _null_ _null_ oidvectorout _null_ _null_ _null_ _null_ ) +insert ( 56 boollt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ boollt _null_ _null_ _null_ _null_ ) +insert ( 57 boolgt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ boolgt _null_ _null_ _null_ _null_ ) +insert ( 60 booleq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ booleq _null_ _null_ _null_ _null_ ) +insert ( 61 chareq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '18 18' _null_ _null_ _null_ _null_ _null_ chareq _null_ _null_ _null_ _null_ ) +insert ( 62 nameeq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 19' _null_ _null_ _null_ _null_ _null_ nameeq _null_ _null_ _null_ _null_ ) +insert ( 63 int2eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 21' _null_ _null_ _null_ _null_ _null_ int2eq _null_ _null_ _null_ _null_ ) +insert ( 64 int2lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 21' _null_ _null_ _null_ _null_ _null_ int2lt _null_ _null_ _null_ _null_ ) +insert ( 65 int4eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ int4eq _null_ _null_ _null_ _null_ ) +insert ( 66 int4lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ int4lt _null_ _null_ _null_ _null_ ) +insert ( 67 texteq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ texteq _null_ _null_ _null_ _null_ ) +insert ( 3696 starts_with 11 10 12 1 0 0 6242 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_starts_with _null_ _null_ _null_ _null_ ) +insert ( 6242 text_starts_with_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ text_starts_with_support _null_ _null_ _null_ _null_ ) +insert ( 68 xideq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '28 28' _null_ _null_ _null_ _null_ _null_ xideq _null_ _null_ _null_ _null_ ) +insert ( 3308 xidneq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '28 28' _null_ _null_ _null_ _null_ _null_ xidneq _null_ _null_ _null_ _null_ ) +insert ( 5084 xid8eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8eq _null_ _null_ _null_ _null_ ) +insert ( 5085 xid8ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8ne _null_ _null_ _null_ _null_ ) +insert ( 5034 xid8lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8lt _null_ _null_ _null_ _null_ ) +insert ( 5035 xid8gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8gt _null_ _null_ _null_ _null_ ) +insert ( 5036 xid8le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8le _null_ _null_ _null_ _null_ ) +insert ( 5037 xid8ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8ge _null_ _null_ _null_ _null_ ) +insert ( 5096 xid8cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8cmp _null_ _null_ _null_ _null_ ) +insert ( 5071 xid 11 10 12 1 0 0 0 f f f t f i s 1 0 28 5069 _null_ _null_ _null_ _null_ _null_ xid8toxid _null_ _null_ _null_ _null_ ) +insert ( 5097 xid8_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 5069 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8_larger _null_ _null_ _null_ _null_ ) +insert ( 5098 xid8_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 5069 '5069 5069' _null_ _null_ _null_ _null_ _null_ xid8_smaller _null_ _null_ _null_ _null_ ) +insert ( 69 cideq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '29 29' _null_ _null_ _null_ _null_ _null_ cideq _null_ _null_ _null_ _null_ ) +insert ( 70 charne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '18 18' _null_ _null_ _null_ _null_ _null_ charne _null_ _null_ _null_ _null_ ) +insert ( 1246 charlt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '18 18' _null_ _null_ _null_ _null_ _null_ charlt _null_ _null_ _null_ _null_ ) +insert ( 72 charle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '18 18' _null_ _null_ _null_ _null_ _null_ charle _null_ _null_ _null_ _null_ ) +insert ( 73 chargt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '18 18' _null_ _null_ _null_ _null_ _null_ chargt _null_ _null_ _null_ _null_ ) +insert ( 74 charge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '18 18' _null_ _null_ _null_ _null_ _null_ charge _null_ _null_ _null_ _null_ ) +insert ( 77 int4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 18 _null_ _null_ _null_ _null_ _null_ chartoi4 _null_ _null_ _null_ _null_ ) +insert ( 78 char 11 10 12 1 0 0 0 f f f t f i s 1 0 18 23 _null_ _null_ _null_ _null_ _null_ i4tochar _null_ _null_ _null_ _null_ ) +insert ( 79 nameregexeq 11 10 12 1 0 0 1364 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameregexeq _null_ _null_ _null_ _null_ ) +insert ( 1252 nameregexne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameregexne _null_ _null_ _null_ _null_ ) +insert ( 1254 textregexeq 11 10 12 1 0 0 1364 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ textregexeq _null_ _null_ _null_ _null_ ) +insert ( 1256 textregexne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ textregexne _null_ _null_ _null_ _null_ ) +insert ( 1364 textregexeq_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ textregexeq_support _null_ _null_ _null_ _null_ ) +insert ( 1257 textlen 11 10 12 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ textlen _null_ _null_ _null_ _null_ ) +insert ( 1258 textcat 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ textcat _null_ _null_ _null_ _null_ ) +insert ( 84 boolne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ boolne _null_ _null_ _null_ _null_ ) +insert ( 89 version 11 10 12 1 0 0 0 f f f t f s s 0 0 25 '' _null_ _null_ _null_ _null_ _null_ pgsql_version _null_ _null_ _null_ _null_ ) +insert ( 86 pg_ddl_command_in 11 10 12 1 0 0 0 f f f t f i s 1 0 32 2275 _null_ _null_ _null_ _null_ _null_ pg_ddl_command_in _null_ _null_ _null_ _null_ ) +insert ( 87 pg_ddl_command_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 32 _null_ _null_ _null_ _null_ _null_ pg_ddl_command_out _null_ _null_ _null_ _null_ ) +insert ( 88 pg_ddl_command_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 32 2281 _null_ _null_ _null_ _null_ _null_ pg_ddl_command_recv _null_ _null_ _null_ _null_ ) +insert ( 90 pg_ddl_command_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 32 _null_ _null_ _null_ _null_ _null_ pg_ddl_command_send _null_ _null_ _null_ _null_ ) +insert ( 101 eqsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ eqsel _null_ _null_ _null_ _null_ ) +insert ( 102 neqsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ neqsel _null_ _null_ _null_ _null_ ) +insert ( 103 scalarltsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ scalarltsel _null_ _null_ _null_ _null_ ) +insert ( 104 scalargtsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ scalargtsel _null_ _null_ _null_ _null_ ) +insert ( 105 eqjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ eqjoinsel _null_ _null_ _null_ _null_ ) +insert ( 106 neqjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ neqjoinsel _null_ _null_ _null_ _null_ ) +insert ( 107 scalarltjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ scalarltjoinsel _null_ _null_ _null_ _null_ ) +insert ( 108 scalargtjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ scalargtjoinsel _null_ _null_ _null_ _null_ ) +insert ( 336 scalarlesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ scalarlesel _null_ _null_ _null_ _null_ ) +insert ( 337 scalargesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ scalargesel _null_ _null_ _null_ _null_ ) +insert ( 386 scalarlejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ scalarlejoinsel _null_ _null_ _null_ _null_ ) +insert ( 398 scalargejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ scalargejoinsel _null_ _null_ _null_ _null_ ) +insert ( 109 unknownin 11 10 12 1 0 0 0 f f f t f i s 1 0 705 2275 _null_ _null_ _null_ _null_ _null_ unknownin _null_ _null_ _null_ _null_ ) +insert ( 110 unknownout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 705 _null_ _null_ _null_ _null_ _null_ unknownout _null_ _null_ _null_ _null_ ) +insert ( 115 box_above_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_above_eq _null_ _null_ _null_ _null_ ) +insert ( 116 box_below_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_below_eq _null_ _null_ _null_ _null_ ) +insert ( 117 point_in 11 10 12 1 0 0 0 f f f t f i s 1 0 600 2275 _null_ _null_ _null_ _null_ _null_ point_in _null_ _null_ _null_ _null_ ) +insert ( 118 point_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 600 _null_ _null_ _null_ _null_ _null_ point_out _null_ _null_ _null_ _null_ ) +insert ( 119 lseg_in 11 10 12 1 0 0 0 f f f t f i s 1 0 601 2275 _null_ _null_ _null_ _null_ _null_ lseg_in _null_ _null_ _null_ _null_ ) +insert ( 120 lseg_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 601 _null_ _null_ _null_ _null_ _null_ lseg_out _null_ _null_ _null_ _null_ ) +insert ( 121 path_in 11 10 12 1 0 0 0 f f f t f i s 1 0 602 2275 _null_ _null_ _null_ _null_ _null_ path_in _null_ _null_ _null_ _null_ ) +insert ( 122 path_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 602 _null_ _null_ _null_ _null_ _null_ path_out _null_ _null_ _null_ _null_ ) +insert ( 123 box_in 11 10 12 1 0 0 0 f f f t f i s 1 0 603 2275 _null_ _null_ _null_ _null_ _null_ box_in _null_ _null_ _null_ _null_ ) +insert ( 124 box_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 603 _null_ _null_ _null_ _null_ _null_ box_out _null_ _null_ _null_ _null_ ) +insert ( 125 box_overlap 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_overlap _null_ _null_ _null_ _null_ ) +insert ( 126 box_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_ge _null_ _null_ _null_ _null_ ) +insert ( 127 box_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_gt _null_ _null_ _null_ _null_ ) +insert ( 128 box_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_eq _null_ _null_ _null_ _null_ ) +insert ( 129 box_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_lt _null_ _null_ _null_ _null_ ) +insert ( 130 box_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_le _null_ _null_ _null_ _null_ ) +insert ( 131 point_above 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_above _null_ _null_ _null_ _null_ ) +insert ( 132 point_left 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_left _null_ _null_ _null_ _null_ ) +insert ( 133 point_right 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_right _null_ _null_ _null_ _null_ ) +insert ( 134 point_below 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_below _null_ _null_ _null_ _null_ ) +insert ( 135 point_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_eq _null_ _null_ _null_ _null_ ) +insert ( 136 on_pb 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 603' _null_ _null_ _null_ _null_ _null_ on_pb _null_ _null_ _null_ _null_ ) +insert ( 137 on_ppath 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 602' _null_ _null_ _null_ _null_ _null_ on_ppath _null_ _null_ _null_ _null_ ) +insert ( 138 box_center 11 10 12 1 0 0 0 f f f t f i s 1 0 600 603 _null_ _null_ _null_ _null_ _null_ box_center _null_ _null_ _null_ _null_ ) +insert ( 139 areasel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ areasel _null_ _null_ _null_ _null_ ) +insert ( 140 areajoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ areajoinsel _null_ _null_ _null_ _null_ ) +insert ( 141 int4mul 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4mul _null_ _null_ _null_ _null_ ) +insert ( 144 int4ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ int4ne _null_ _null_ _null_ _null_ ) +insert ( 145 int2ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 21' _null_ _null_ _null_ _null_ _null_ int2ne _null_ _null_ _null_ _null_ ) +insert ( 146 int2gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 21' _null_ _null_ _null_ _null_ _null_ int2gt _null_ _null_ _null_ _null_ ) +insert ( 147 int4gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ int4gt _null_ _null_ _null_ _null_ ) +insert ( 148 int2le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 21' _null_ _null_ _null_ _null_ _null_ int2le _null_ _null_ _null_ _null_ ) +insert ( 149 int4le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ int4le _null_ _null_ _null_ _null_ ) +insert ( 150 int4ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ int4ge _null_ _null_ _null_ _null_ ) +insert ( 151 int2ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 21' _null_ _null_ _null_ _null_ _null_ int2ge _null_ _null_ _null_ _null_ ) +insert ( 152 int2mul 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2mul _null_ _null_ _null_ _null_ ) +insert ( 153 int2div 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2div _null_ _null_ _null_ _null_ ) +insert ( 154 int4div 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4div _null_ _null_ _null_ _null_ ) +insert ( 155 int2mod 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2mod _null_ _null_ _null_ _null_ ) +insert ( 156 int4mod 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4mod _null_ _null_ _null_ _null_ ) +insert ( 157 textne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ textne _null_ _null_ _null_ _null_ ) +insert ( 158 int24eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 23' _null_ _null_ _null_ _null_ _null_ int24eq _null_ _null_ _null_ _null_ ) +insert ( 159 int42eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 21' _null_ _null_ _null_ _null_ _null_ int42eq _null_ _null_ _null_ _null_ ) +insert ( 160 int24lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 23' _null_ _null_ _null_ _null_ _null_ int24lt _null_ _null_ _null_ _null_ ) +insert ( 161 int42lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 21' _null_ _null_ _null_ _null_ _null_ int42lt _null_ _null_ _null_ _null_ ) +insert ( 162 int24gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 23' _null_ _null_ _null_ _null_ _null_ int24gt _null_ _null_ _null_ _null_ ) +insert ( 163 int42gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 21' _null_ _null_ _null_ _null_ _null_ int42gt _null_ _null_ _null_ _null_ ) +insert ( 164 int24ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 23' _null_ _null_ _null_ _null_ _null_ int24ne _null_ _null_ _null_ _null_ ) +insert ( 165 int42ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 21' _null_ _null_ _null_ _null_ _null_ int42ne _null_ _null_ _null_ _null_ ) +insert ( 166 int24le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 23' _null_ _null_ _null_ _null_ _null_ int24le _null_ _null_ _null_ _null_ ) +insert ( 167 int42le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 21' _null_ _null_ _null_ _null_ _null_ int42le _null_ _null_ _null_ _null_ ) +insert ( 168 int24ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 23' _null_ _null_ _null_ _null_ _null_ int24ge _null_ _null_ _null_ _null_ ) +insert ( 169 int42ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 21' _null_ _null_ _null_ _null_ _null_ int42ge _null_ _null_ _null_ _null_ ) +insert ( 170 int24mul 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '21 23' _null_ _null_ _null_ _null_ _null_ int24mul _null_ _null_ _null_ _null_ ) +insert ( 171 int42mul 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 21' _null_ _null_ _null_ _null_ _null_ int42mul _null_ _null_ _null_ _null_ ) +insert ( 172 int24div 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '21 23' _null_ _null_ _null_ _null_ _null_ int24div _null_ _null_ _null_ _null_ ) +insert ( 173 int42div 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 21' _null_ _null_ _null_ _null_ _null_ int42div _null_ _null_ _null_ _null_ ) +insert ( 176 int2pl 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2pl _null_ _null_ _null_ _null_ ) +insert ( 177 int4pl 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4pl _null_ _null_ _null_ _null_ ) +insert ( 178 int24pl 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '21 23' _null_ _null_ _null_ _null_ _null_ int24pl _null_ _null_ _null_ _null_ ) +insert ( 179 int42pl 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 21' _null_ _null_ _null_ _null_ _null_ int42pl _null_ _null_ _null_ _null_ ) +insert ( 180 int2mi 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2mi _null_ _null_ _null_ _null_ ) +insert ( 181 int4mi 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4mi _null_ _null_ _null_ _null_ ) +insert ( 182 int24mi 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '21 23' _null_ _null_ _null_ _null_ _null_ int24mi _null_ _null_ _null_ _null_ ) +insert ( 183 int42mi 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 21' _null_ _null_ _null_ _null_ _null_ int42mi _null_ _null_ _null_ _null_ ) +insert ( 184 oideq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '26 26' _null_ _null_ _null_ _null_ _null_ oideq _null_ _null_ _null_ _null_ ) +insert ( 185 oidne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '26 26' _null_ _null_ _null_ _null_ _null_ oidne _null_ _null_ _null_ _null_ ) +insert ( 186 box_same 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_same _null_ _null_ _null_ _null_ ) +insert ( 187 box_contain 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_contain _null_ _null_ _null_ _null_ ) +insert ( 188 box_left 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_left _null_ _null_ _null_ _null_ ) +insert ( 189 box_overleft 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_overleft _null_ _null_ _null_ _null_ ) +insert ( 190 box_overright 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_overright _null_ _null_ _null_ _null_ ) +insert ( 191 box_right 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_right _null_ _null_ _null_ _null_ ) +insert ( 192 box_contained 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_contained _null_ _null_ _null_ _null_ ) +insert ( 193 box_contain_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 600' _null_ _null_ _null_ _null_ _null_ box_contain_pt _null_ _null_ _null_ _null_ ) +insert ( 195 pg_node_tree_in 11 10 12 1 0 0 0 f f f t f i s 1 0 194 2275 _null_ _null_ _null_ _null_ _null_ pg_node_tree_in _null_ _null_ _null_ _null_ ) +insert ( 196 pg_node_tree_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 194 _null_ _null_ _null_ _null_ _null_ pg_node_tree_out _null_ _null_ _null_ _null_ ) +insert ( 197 pg_node_tree_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 194 2281 _null_ _null_ _null_ _null_ _null_ pg_node_tree_recv _null_ _null_ _null_ _null_ ) +insert ( 198 pg_node_tree_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 194 _null_ _null_ _null_ _null_ _null_ pg_node_tree_send _null_ _null_ _null_ _null_ ) +insert ( 200 float4in 11 10 12 1 0 0 0 f f f t f i s 1 0 700 2275 _null_ _null_ _null_ _null_ _null_ float4in _null_ _null_ _null_ _null_ ) +insert ( 201 float4out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 700 _null_ _null_ _null_ _null_ _null_ float4out _null_ _null_ _null_ _null_ ) +insert ( 202 float4mul 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '700 700' _null_ _null_ _null_ _null_ _null_ float4mul _null_ _null_ _null_ _null_ ) +insert ( 203 float4div 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '700 700' _null_ _null_ _null_ _null_ _null_ float4div _null_ _null_ _null_ _null_ ) +insert ( 204 float4pl 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '700 700' _null_ _null_ _null_ _null_ _null_ float4pl _null_ _null_ _null_ _null_ ) +insert ( 205 float4mi 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '700 700' _null_ _null_ _null_ _null_ _null_ float4mi _null_ _null_ _null_ _null_ ) +insert ( 206 float4um 11 10 12 1 0 0 0 f f f t f i s 1 0 700 700 _null_ _null_ _null_ _null_ _null_ float4um _null_ _null_ _null_ _null_ ) +insert ( 207 float4abs 11 10 12 1 0 0 0 f f f t f i s 1 0 700 700 _null_ _null_ _null_ _null_ _null_ float4abs _null_ _null_ _null_ _null_ ) +insert ( 208 float4_accum 11 10 12 1 0 0 0 f f f t f i s 2 0 1022 '1022 700' _null_ _null_ _null_ _null_ _null_ float4_accum _null_ _null_ _null_ _null_ ) +insert ( 209 float4larger 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '700 700' _null_ _null_ _null_ _null_ _null_ float4larger _null_ _null_ _null_ _null_ ) +insert ( 211 float4smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '700 700' _null_ _null_ _null_ _null_ _null_ float4smaller _null_ _null_ _null_ _null_ ) +insert ( 212 int4um 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ int4um _null_ _null_ _null_ _null_ ) +insert ( 213 int2um 11 10 12 1 0 0 0 f f f t f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ int2um _null_ _null_ _null_ _null_ ) +insert ( 214 float8in 11 10 12 1 0 0 0 f f f t f i s 1 0 701 2275 _null_ _null_ _null_ _null_ _null_ float8in _null_ _null_ _null_ _null_ ) +insert ( 215 float8out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 701 _null_ _null_ _null_ _null_ _null_ float8out _null_ _null_ _null_ _null_ ) +insert ( 216 float8mul 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ float8mul _null_ _null_ _null_ _null_ ) +insert ( 217 float8div 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ float8div _null_ _null_ _null_ _null_ ) +insert ( 218 float8pl 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ float8pl _null_ _null_ _null_ _null_ ) +insert ( 219 float8mi 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ float8mi _null_ _null_ _null_ _null_ ) +insert ( 220 float8um 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ float8um _null_ _null_ _null_ _null_ ) +insert ( 221 float8abs 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ float8abs _null_ _null_ _null_ _null_ ) +insert ( 222 float8_accum 11 10 12 1 0 0 0 f f f t f i s 2 0 1022 '1022 701' _null_ _null_ _null_ _null_ _null_ float8_accum _null_ _null_ _null_ _null_ ) +insert ( 276 float8_combine 11 10 12 1 0 0 0 f f f t f i s 2 0 1022 '1022 1022' _null_ _null_ _null_ _null_ _null_ float8_combine _null_ _null_ _null_ _null_ ) +insert ( 223 float8larger 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ float8larger _null_ _null_ _null_ _null_ ) +insert ( 224 float8smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ float8smaller _null_ _null_ _null_ _null_ ) +insert ( 225 lseg_center 11 10 12 1 0 0 0 f f f t f i s 1 0 600 601 _null_ _null_ _null_ _null_ _null_ lseg_center _null_ _null_ _null_ _null_ ) +insert ( 227 poly_center 11 10 12 1 0 0 0 f f f t f i s 1 0 600 604 _null_ _null_ _null_ _null_ _null_ poly_center _null_ _null_ _null_ _null_ ) +insert ( 228 dround 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dround _null_ _null_ _null_ _null_ ) +insert ( 229 dtrunc 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dtrunc _null_ _null_ _null_ _null_ ) +insert ( 2308 ceil 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dceil _null_ _null_ _null_ _null_ ) +insert ( 2320 ceiling 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dceil _null_ _null_ _null_ _null_ ) +insert ( 2309 floor 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dfloor _null_ _null_ _null_ _null_ ) +insert ( 2310 sign 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dsign _null_ _null_ _null_ _null_ ) +insert ( 230 dsqrt 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dsqrt _null_ _null_ _null_ _null_ ) +insert ( 231 dcbrt 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dcbrt _null_ _null_ _null_ _null_ ) +insert ( 232 dpow 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ dpow _null_ _null_ _null_ _null_ ) +insert ( 233 dexp 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dexp _null_ _null_ _null_ _null_ ) +insert ( 234 dlog1 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dlog1 _null_ _null_ _null_ _null_ ) +insert ( 235 float8 11 10 12 1 0 0 0 f f t t f i s 1 0 701 21 _null_ _null_ _null_ _null_ _null_ i2tod _null_ _null_ _null_ _null_ ) +insert ( 236 float4 11 10 12 1 0 0 0 f f t t f i s 1 0 700 21 _null_ _null_ _null_ _null_ _null_ i2tof _null_ _null_ _null_ _null_ ) +insert ( 237 int2 11 10 12 1 0 0 0 f f f t f i s 1 0 21 701 _null_ _null_ _null_ _null_ _null_ dtoi2 _null_ _null_ _null_ _null_ ) +insert ( 238 int2 11 10 12 1 0 0 0 f f f t f i s 1 0 21 700 _null_ _null_ _null_ _null_ _null_ ftoi2 _null_ _null_ _null_ _null_ ) +insert ( 239 line_distance 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '628 628' _null_ _null_ _null_ _null_ _null_ line_distance _null_ _null_ _null_ _null_ ) +insert ( 240 nameeqtext 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameeqtext _null_ _null_ _null_ _null_ ) +insert ( 241 namelttext 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namelttext _null_ _null_ _null_ _null_ ) +insert ( 242 nameletext 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameletext _null_ _null_ _null_ _null_ ) +insert ( 243 namegetext 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namegetext _null_ _null_ _null_ _null_ ) +insert ( 244 namegttext 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namegttext _null_ _null_ _null_ _null_ ) +insert ( 245 namenetext 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namenetext _null_ _null_ _null_ _null_ ) +insert ( 246 btnametextcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '19 25' _null_ _null_ _null_ _null_ _null_ btnametextcmp _null_ _null_ _null_ _null_ ) +insert ( 247 texteqname 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 19' _null_ _null_ _null_ _null_ _null_ texteqname _null_ _null_ _null_ _null_ ) +insert ( 248 textltname 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 19' _null_ _null_ _null_ _null_ _null_ textltname _null_ _null_ _null_ _null_ ) +insert ( 249 textlename 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 19' _null_ _null_ _null_ _null_ _null_ textlename _null_ _null_ _null_ _null_ ) +insert ( 250 textgename 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 19' _null_ _null_ _null_ _null_ _null_ textgename _null_ _null_ _null_ _null_ ) +insert ( 251 textgtname 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 19' _null_ _null_ _null_ _null_ _null_ textgtname _null_ _null_ _null_ _null_ ) +insert ( 252 textnename 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 19' _null_ _null_ _null_ _null_ _null_ textnename _null_ _null_ _null_ _null_ ) +insert ( 253 bttextnamecmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '25 19' _null_ _null_ _null_ _null_ _null_ bttextnamecmp _null_ _null_ _null_ _null_ ) +insert ( 266 nameconcatoid 11 10 12 1 0 0 0 f f f t f i s 2 0 19 '19 26' _null_ _null_ _null_ _null_ _null_ nameconcatoid _null_ _null_ _null_ _null_ ) +insert ( 274 timeofday 11 10 12 1 0 0 0 f f f t f v s 0 0 25 '' _null_ _null_ _null_ _null_ _null_ timeofday _null_ _null_ _null_ _null_ ) +insert ( 277 inter_sl 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 628' _null_ _null_ _null_ _null_ _null_ inter_sl _null_ _null_ _null_ _null_ ) +insert ( 278 inter_lb 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '628 603' _null_ _null_ _null_ _null_ _null_ inter_lb _null_ _null_ _null_ _null_ ) +insert ( 279 float48mul 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '700 701' _null_ _null_ _null_ _null_ _null_ float48mul _null_ _null_ _null_ _null_ ) +insert ( 280 float48div 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '700 701' _null_ _null_ _null_ _null_ _null_ float48div _null_ _null_ _null_ _null_ ) +insert ( 281 float48pl 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '700 701' _null_ _null_ _null_ _null_ _null_ float48pl _null_ _null_ _null_ _null_ ) +insert ( 282 float48mi 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '700 701' _null_ _null_ _null_ _null_ _null_ float48mi _null_ _null_ _null_ _null_ ) +insert ( 283 float84mul 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 700' _null_ _null_ _null_ _null_ _null_ float84mul _null_ _null_ _null_ _null_ ) +insert ( 284 float84div 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 700' _null_ _null_ _null_ _null_ _null_ float84div _null_ _null_ _null_ _null_ ) +insert ( 285 float84pl 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 700' _null_ _null_ _null_ _null_ _null_ float84pl _null_ _null_ _null_ _null_ ) +insert ( 286 float84mi 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 700' _null_ _null_ _null_ _null_ _null_ float84mi _null_ _null_ _null_ _null_ ) +insert ( 287 float4eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 700' _null_ _null_ _null_ _null_ _null_ float4eq _null_ _null_ _null_ _null_ ) +insert ( 288 float4ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 700' _null_ _null_ _null_ _null_ _null_ float4ne _null_ _null_ _null_ _null_ ) +insert ( 289 float4lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 700' _null_ _null_ _null_ _null_ _null_ float4lt _null_ _null_ _null_ _null_ ) +insert ( 290 float4le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 700' _null_ _null_ _null_ _null_ _null_ float4le _null_ _null_ _null_ _null_ ) +insert ( 291 float4gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 700' _null_ _null_ _null_ _null_ _null_ float4gt _null_ _null_ _null_ _null_ ) +insert ( 292 float4ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 700' _null_ _null_ _null_ _null_ _null_ float4ge _null_ _null_ _null_ _null_ ) +insert ( 293 float8eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 701' _null_ _null_ _null_ _null_ _null_ float8eq _null_ _null_ _null_ _null_ ) +insert ( 294 float8ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 701' _null_ _null_ _null_ _null_ _null_ float8ne _null_ _null_ _null_ _null_ ) +insert ( 295 float8lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 701' _null_ _null_ _null_ _null_ _null_ float8lt _null_ _null_ _null_ _null_ ) +insert ( 296 float8le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 701' _null_ _null_ _null_ _null_ _null_ float8le _null_ _null_ _null_ _null_ ) +insert ( 297 float8gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 701' _null_ _null_ _null_ _null_ _null_ float8gt _null_ _null_ _null_ _null_ ) +insert ( 298 float8ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 701' _null_ _null_ _null_ _null_ _null_ float8ge _null_ _null_ _null_ _null_ ) +insert ( 299 float48eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 701' _null_ _null_ _null_ _null_ _null_ float48eq _null_ _null_ _null_ _null_ ) +insert ( 300 float48ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 701' _null_ _null_ _null_ _null_ _null_ float48ne _null_ _null_ _null_ _null_ ) +insert ( 301 float48lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 701' _null_ _null_ _null_ _null_ _null_ float48lt _null_ _null_ _null_ _null_ ) +insert ( 302 float48le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 701' _null_ _null_ _null_ _null_ _null_ float48le _null_ _null_ _null_ _null_ ) +insert ( 303 float48gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 701' _null_ _null_ _null_ _null_ _null_ float48gt _null_ _null_ _null_ _null_ ) +insert ( 304 float48ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '700 701' _null_ _null_ _null_ _null_ _null_ float48ge _null_ _null_ _null_ _null_ ) +insert ( 305 float84eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 700' _null_ _null_ _null_ _null_ _null_ float84eq _null_ _null_ _null_ _null_ ) +insert ( 306 float84ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 700' _null_ _null_ _null_ _null_ _null_ float84ne _null_ _null_ _null_ _null_ ) +insert ( 307 float84lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 700' _null_ _null_ _null_ _null_ _null_ float84lt _null_ _null_ _null_ _null_ ) +insert ( 308 float84le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 700' _null_ _null_ _null_ _null_ _null_ float84le _null_ _null_ _null_ _null_ ) +insert ( 309 float84gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 700' _null_ _null_ _null_ _null_ _null_ float84gt _null_ _null_ _null_ _null_ ) +insert ( 310 float84ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '701 700' _null_ _null_ _null_ _null_ _null_ float84ge _null_ _null_ _null_ _null_ ) +insert ( 320 width_bucket 11 10 12 1 0 0 0 f f f t f i s 4 0 23 '701 701 701 23' _null_ _null_ _null_ _null_ _null_ width_bucket_float8 _null_ _null_ _null_ _null_ ) +insert ( 311 float8 11 10 12 1 0 0 0 f f t t f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ ftod _null_ _null_ _null_ _null_ ) +insert ( 312 float4 11 10 12 1 0 0 0 f f f t f i s 1 0 700 701 _null_ _null_ _null_ _null_ _null_ dtof _null_ _null_ _null_ _null_ ) +insert ( 313 int4 11 10 12 1 0 0 0 f f t t f i s 1 0 23 21 _null_ _null_ _null_ _null_ _null_ i2toi4 _null_ _null_ _null_ _null_ ) +insert ( 314 int2 11 10 12 1 0 0 0 f f f t f i s 1 0 21 23 _null_ _null_ _null_ _null_ _null_ i4toi2 _null_ _null_ _null_ _null_ ) +insert ( 316 float8 11 10 12 1 0 0 0 f f t t f i s 1 0 701 23 _null_ _null_ _null_ _null_ _null_ i4tod _null_ _null_ _null_ _null_ ) +insert ( 317 int4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 701 _null_ _null_ _null_ _null_ _null_ dtoi4 _null_ _null_ _null_ _null_ ) +insert ( 318 float4 11 10 12 1 0 0 0 f f t t f i s 1 0 700 23 _null_ _null_ _null_ _null_ _null_ i4tof _null_ _null_ _null_ _null_ ) +insert ( 319 int4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 700 _null_ _null_ _null_ _null_ _null_ ftoi4 _null_ _null_ _null_ _null_ ) +insert ( 3 heap_tableam_handler 11 10 12 1 0 0 0 f f f t f v s 1 0 269 2281 _null_ _null_ _null_ _null_ _null_ heap_tableam_handler _null_ _null_ _null_ _null_ ) +insert ( 330 bthandler 11 10 12 1 0 0 0 f f f t f v s 1 0 325 2281 _null_ _null_ _null_ _null_ _null_ bthandler _null_ _null_ _null_ _null_ ) +insert ( 331 hashhandler 11 10 12 1 0 0 0 f f f t f v s 1 0 325 2281 _null_ _null_ _null_ _null_ _null_ hashhandler _null_ _null_ _null_ _null_ ) +insert ( 332 gisthandler 11 10 12 1 0 0 0 f f f t f v s 1 0 325 2281 _null_ _null_ _null_ _null_ _null_ gisthandler _null_ _null_ _null_ _null_ ) +insert ( 333 ginhandler 11 10 12 1 0 0 0 f f f t f v s 1 0 325 2281 _null_ _null_ _null_ _null_ _null_ ginhandler _null_ _null_ _null_ _null_ ) +insert ( 334 spghandler 11 10 12 1 0 0 0 f f f t f v s 1 0 325 2281 _null_ _null_ _null_ _null_ _null_ spghandler _null_ _null_ _null_ _null_ ) +insert ( 335 brinhandler 11 10 12 1 0 0 0 f f f t f v s 1 0 325 2281 _null_ _null_ _null_ _null_ _null_ brinhandler _null_ _null_ _null_ _null_ ) +insert ( 3952 brin_summarize_new_values 11 10 12 1 0 0 0 f f f t f v u 1 0 23 2205 _null_ _null_ _null_ _null_ _null_ brin_summarize_new_values _null_ _null_ _null_ _null_ ) +insert ( 3999 brin_summarize_range 11 10 12 1 0 0 0 f f f t f v u 2 0 23 '2205 20' _null_ _null_ _null_ _null_ _null_ brin_summarize_range _null_ _null_ _null_ _null_ ) +insert ( 4014 brin_desummarize_range 11 10 12 1 0 0 0 f f f t f v u 2 0 2278 '2205 20' _null_ _null_ _null_ _null_ _null_ brin_desummarize_range _null_ _null_ _null_ _null_ ) +insert ( 338 amvalidate 11 10 12 1 0 0 0 f f f t f v s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ amvalidate _null_ _null_ _null_ _null_ ) +insert ( 636 pg_indexam_has_property 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ pg_indexam_has_property _null_ _null_ _null_ _null_ ) +insert ( 637 pg_index_has_property 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '2205 25' _null_ _null_ _null_ _null_ _null_ pg_index_has_property _null_ _null_ _null_ _null_ ) +insert ( 638 pg_index_column_has_property 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '2205 23 25' _null_ _null_ _null_ _null_ _null_ pg_index_column_has_property _null_ _null_ _null_ _null_ ) +insert ( 676 pg_indexam_progress_phasename 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '26 20' _null_ _null_ _null_ _null_ _null_ pg_indexam_progress_phasename _null_ _null_ _null_ _null_ ) +insert ( 339 poly_same 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_same _null_ _null_ _null_ _null_ ) +insert ( 340 poly_contain 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_contain _null_ _null_ _null_ _null_ ) +insert ( 341 poly_left 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_left _null_ _null_ _null_ _null_ ) +insert ( 342 poly_overleft 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_overleft _null_ _null_ _null_ _null_ ) +insert ( 343 poly_overright 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_overright _null_ _null_ _null_ _null_ ) +insert ( 344 poly_right 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_right _null_ _null_ _null_ _null_ ) +insert ( 345 poly_contained 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_contained _null_ _null_ _null_ _null_ ) +insert ( 346 poly_overlap 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_overlap _null_ _null_ _null_ _null_ ) +insert ( 347 poly_in 11 10 12 1 0 0 0 f f f t f i s 1 0 604 2275 _null_ _null_ _null_ _null_ _null_ poly_in _null_ _null_ _null_ _null_ ) +insert ( 348 poly_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 604 _null_ _null_ _null_ _null_ _null_ poly_out _null_ _null_ _null_ _null_ ) +insert ( 350 btint2cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '21 21' _null_ _null_ _null_ _null_ _null_ btint2cmp _null_ _null_ _null_ _null_ ) +insert ( 3129 btint2sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btint2sortsupport _null_ _null_ _null_ _null_ ) +insert ( 351 btint4cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ btint4cmp _null_ _null_ _null_ _null_ ) +insert ( 3130 btint4sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btint4sortsupport _null_ _null_ _null_ _null_ ) +insert ( 842 btint8cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '20 20' _null_ _null_ _null_ _null_ _null_ btint8cmp _null_ _null_ _null_ _null_ ) +insert ( 3131 btint8sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btint8sortsupport _null_ _null_ _null_ _null_ ) +insert ( 354 btfloat4cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '700 700' _null_ _null_ _null_ _null_ _null_ btfloat4cmp _null_ _null_ _null_ _null_ ) +insert ( 3132 btfloat4sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btfloat4sortsupport _null_ _null_ _null_ _null_ ) +insert ( 355 btfloat8cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '701 701' _null_ _null_ _null_ _null_ _null_ btfloat8cmp _null_ _null_ _null_ _null_ ) +insert ( 3133 btfloat8sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btfloat8sortsupport _null_ _null_ _null_ _null_ ) +insert ( 356 btoidcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '26 26' _null_ _null_ _null_ _null_ _null_ btoidcmp _null_ _null_ _null_ _null_ ) +insert ( 3134 btoidsortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btoidsortsupport _null_ _null_ _null_ _null_ ) +insert ( 404 btoidvectorcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '30 30' _null_ _null_ _null_ _null_ _null_ btoidvectorcmp _null_ _null_ _null_ _null_ ) +insert ( 358 btcharcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '18 18' _null_ _null_ _null_ _null_ _null_ btcharcmp _null_ _null_ _null_ _null_ ) +insert ( 359 btnamecmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '19 19' _null_ _null_ _null_ _null_ _null_ btnamecmp _null_ _null_ _null_ _null_ ) +insert ( 3135 btnamesortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btnamesortsupport _null_ _null_ _null_ _null_ ) +insert ( 360 bttextcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ bttextcmp _null_ _null_ _null_ _null_ ) +insert ( 3255 bttextsortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ bttextsortsupport _null_ _null_ _null_ _null_ ) +insert ( 5050 btvarstrequalimage 11 10 12 1 0 0 0 f f f t f i s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ btvarstrequalimage _null_ _null_ _null_ _null_ ) +insert ( 377 cash_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '790 790' _null_ _null_ _null_ _null_ _null_ cash_cmp _null_ _null_ _null_ _null_ ) +insert ( 382 btarraycmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '2277 2277' _null_ _null_ _null_ _null_ _null_ btarraycmp _null_ _null_ _null_ _null_ ) +insert ( 4126 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '20 20 20 16 16' _null_ _null_ _null_ _null_ _null_ in_range_int8_int8 _null_ _null_ _null_ _null_ ) +insert ( 4127 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '23 23 20 16 16' _null_ _null_ _null_ _null_ _null_ in_range_int4_int8 _null_ _null_ _null_ _null_ ) +insert ( 4128 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '23 23 23 16 16' _null_ _null_ _null_ _null_ _null_ in_range_int4_int4 _null_ _null_ _null_ _null_ ) +insert ( 4129 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '23 23 21 16 16' _null_ _null_ _null_ _null_ _null_ in_range_int4_int2 _null_ _null_ _null_ _null_ ) +insert ( 4130 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '21 21 20 16 16' _null_ _null_ _null_ _null_ _null_ in_range_int2_int8 _null_ _null_ _null_ _null_ ) +insert ( 4131 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '21 21 23 16 16' _null_ _null_ _null_ _null_ _null_ in_range_int2_int4 _null_ _null_ _null_ _null_ ) +insert ( 4132 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '21 21 21 16 16' _null_ _null_ _null_ _null_ _null_ in_range_int2_int2 _null_ _null_ _null_ _null_ ) +insert ( 4139 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '701 701 701 16 16' _null_ _null_ _null_ _null_ _null_ in_range_float8_float8 _null_ _null_ _null_ _null_ ) +insert ( 4140 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '700 700 701 16 16' _null_ _null_ _null_ _null_ _null_ in_range_float4_float8 _null_ _null_ _null_ _null_ ) +insert ( 4141 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '1700 1700 1700 16 16' _null_ _null_ _null_ _null_ _null_ in_range_numeric_numeric _null_ _null_ _null_ _null_ ) +insert ( 361 lseg_distance 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_distance _null_ _null_ _null_ _null_ ) +insert ( 362 lseg_interpt 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_interpt _null_ _null_ _null_ _null_ ) +insert ( 363 dist_ps 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 601' _null_ _null_ _null_ _null_ _null_ dist_ps _null_ _null_ _null_ _null_ ) +insert ( 380 dist_sp 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '601 600' _null_ _null_ _null_ _null_ _null_ dist_sp _null_ _null_ _null_ _null_ ) +insert ( 364 dist_pb 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 603' _null_ _null_ _null_ _null_ _null_ dist_pb _null_ _null_ _null_ _null_ ) +insert ( 357 dist_bp 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '603 600' _null_ _null_ _null_ _null_ _null_ dist_bp _null_ _null_ _null_ _null_ ) +insert ( 365 dist_sb 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '601 603' _null_ _null_ _null_ _null_ _null_ dist_sb _null_ _null_ _null_ _null_ ) +insert ( 381 dist_bs 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '603 601' _null_ _null_ _null_ _null_ _null_ dist_bs _null_ _null_ _null_ _null_ ) +insert ( 366 close_ps 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '600 601' _null_ _null_ _null_ _null_ _null_ close_ps _null_ _null_ _null_ _null_ ) +insert ( 367 close_pb 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '600 603' _null_ _null_ _null_ _null_ _null_ close_pb _null_ _null_ _null_ _null_ ) +insert ( 368 close_sb 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '601 603' _null_ _null_ _null_ _null_ _null_ close_sb _null_ _null_ _null_ _null_ ) +insert ( 369 on_ps 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 601' _null_ _null_ _null_ _null_ _null_ on_ps _null_ _null_ _null_ _null_ ) +insert ( 370 path_distance 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '602 602' _null_ _null_ _null_ _null_ _null_ path_distance _null_ _null_ _null_ _null_ ) +insert ( 371 dist_ppath 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 602' _null_ _null_ _null_ _null_ _null_ dist_ppath _null_ _null_ _null_ _null_ ) +insert ( 421 dist_pathp 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '602 600' _null_ _null_ _null_ _null_ _null_ dist_pathp _null_ _null_ _null_ _null_ ) +insert ( 372 on_sb 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 603' _null_ _null_ _null_ _null_ _null_ on_sb _null_ _null_ _null_ _null_ ) +insert ( 373 inter_sb 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 603' _null_ _null_ _null_ _null_ _null_ inter_sb _null_ _null_ _null_ _null_ ) +insert ( 401 text 11 10 12 1 0 0 0 f f f t f i s 1 0 25 1042 _null_ _null_ _null_ _null_ _null_ rtrim1 _null_ _null_ _null_ _null_ ) +insert ( 406 text 11 10 12 1 0 0 0 f f t t f i s 1 0 25 19 _null_ _null_ _null_ _null_ _null_ name_text _null_ _null_ _null_ _null_ ) +insert ( 407 name 11 10 12 1 0 0 0 f f t t f i s 1 0 19 25 _null_ _null_ _null_ _null_ _null_ text_name _null_ _null_ _null_ _null_ ) +insert ( 408 bpchar 11 10 12 1 0 0 0 f f f t f i s 1 0 1042 19 _null_ _null_ _null_ _null_ _null_ name_bpchar _null_ _null_ _null_ _null_ ) +insert ( 409 name 11 10 12 1 0 0 0 f f t t f i s 1 0 19 1042 _null_ _null_ _null_ _null_ _null_ bpchar_name _null_ _null_ _null_ _null_ ) +insert ( 449 hashint2 11 10 12 1 0 0 0 f f f t f i s 1 0 23 21 _null_ _null_ _null_ _null_ _null_ hashint2 _null_ _null_ _null_ _null_ ) +insert ( 441 hashint2extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '21 20' _null_ _null_ _null_ _null_ _null_ hashint2extended _null_ _null_ _null_ _null_ ) +insert ( 450 hashint4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ hashint4 _null_ _null_ _null_ _null_ ) +insert ( 425 hashint4extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '23 20' _null_ _null_ _null_ _null_ _null_ hashint4extended _null_ _null_ _null_ _null_ ) +insert ( 949 hashint8 11 10 12 1 0 0 0 f f f t f i s 1 0 23 20 _null_ _null_ _null_ _null_ _null_ hashint8 _null_ _null_ _null_ _null_ ) +insert ( 442 hashint8extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ hashint8extended _null_ _null_ _null_ _null_ ) +insert ( 451 hashfloat4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 700 _null_ _null_ _null_ _null_ _null_ hashfloat4 _null_ _null_ _null_ _null_ ) +insert ( 443 hashfloat4extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '700 20' _null_ _null_ _null_ _null_ _null_ hashfloat4extended _null_ _null_ _null_ _null_ ) +insert ( 452 hashfloat8 11 10 12 1 0 0 0 f f f t f i s 1 0 23 701 _null_ _null_ _null_ _null_ _null_ hashfloat8 _null_ _null_ _null_ _null_ ) +insert ( 444 hashfloat8extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '701 20' _null_ _null_ _null_ _null_ _null_ hashfloat8extended _null_ _null_ _null_ _null_ ) +insert ( 453 hashoid 11 10 12 1 0 0 0 f f f t f i s 1 0 23 26 _null_ _null_ _null_ _null_ _null_ hashoid _null_ _null_ _null_ _null_ ) +insert ( 445 hashoidextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '26 20' _null_ _null_ _null_ _null_ _null_ hashoidextended _null_ _null_ _null_ _null_ ) +insert ( 454 hashchar 11 10 12 1 0 0 0 f f f t f i s 1 0 23 18 _null_ _null_ _null_ _null_ _null_ hashchar _null_ _null_ _null_ _null_ ) +insert ( 446 hashcharextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '18 20' _null_ _null_ _null_ _null_ _null_ hashcharextended _null_ _null_ _null_ _null_ ) +insert ( 455 hashname 11 10 12 1 0 0 0 f f f t f i s 1 0 23 19 _null_ _null_ _null_ _null_ _null_ hashname _null_ _null_ _null_ _null_ ) +insert ( 447 hashnameextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '19 20' _null_ _null_ _null_ _null_ _null_ hashnameextended _null_ _null_ _null_ _null_ ) +insert ( 400 hashtext 11 10 12 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ hashtext _null_ _null_ _null_ _null_ ) +insert ( 448 hashtextextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '25 20' _null_ _null_ _null_ _null_ _null_ hashtextextended _null_ _null_ _null_ _null_ ) +insert ( 456 hashvarlena 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2281 _null_ _null_ _null_ _null_ _null_ hashvarlena _null_ _null_ _null_ _null_ ) +insert ( 772 hashvarlenaextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '2281 20' _null_ _null_ _null_ _null_ _null_ hashvarlenaextended _null_ _null_ _null_ _null_ ) +insert ( 457 hashoidvector 11 10 12 1 0 0 0 f f f t f i s 1 0 23 30 _null_ _null_ _null_ _null_ _null_ hashoidvector _null_ _null_ _null_ _null_ ) +insert ( 776 hashoidvectorextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '30 20' _null_ _null_ _null_ _null_ _null_ hashoidvectorextended _null_ _null_ _null_ _null_ ) +insert ( 329 hash_aclitem 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1033 _null_ _null_ _null_ _null_ _null_ hash_aclitem _null_ _null_ _null_ _null_ ) +insert ( 777 hash_aclitem_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '1033 20' _null_ _null_ _null_ _null_ _null_ hash_aclitem_extended _null_ _null_ _null_ _null_ ) +insert ( 399 hashmacaddr 11 10 12 1 0 0 0 f f f t f i s 1 0 23 829 _null_ _null_ _null_ _null_ _null_ hashmacaddr _null_ _null_ _null_ _null_ ) +insert ( 778 hashmacaddrextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '829 20' _null_ _null_ _null_ _null_ _null_ hashmacaddrextended _null_ _null_ _null_ _null_ ) +insert ( 422 hashinet 11 10 12 1 0 0 0 f f f t f i s 1 0 23 869 _null_ _null_ _null_ _null_ _null_ hashinet _null_ _null_ _null_ _null_ ) +insert ( 779 hashinetextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '869 20' _null_ _null_ _null_ _null_ _null_ hashinetextended _null_ _null_ _null_ _null_ ) +insert ( 432 hash_numeric 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1700 _null_ _null_ _null_ _null_ _null_ hash_numeric _null_ _null_ _null_ _null_ ) +insert ( 780 hash_numeric_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '1700 20' _null_ _null_ _null_ _null_ _null_ hash_numeric_extended _null_ _null_ _null_ _null_ ) +insert ( 328 hashmacaddr8 11 10 12 1 0 0 0 f f f t f i s 1 0 23 774 _null_ _null_ _null_ _null_ _null_ hashmacaddr8 _null_ _null_ _null_ _null_ ) +insert ( 781 hashmacaddr8extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '774 20' _null_ _null_ _null_ _null_ _null_ hashmacaddr8extended _null_ _null_ _null_ _null_ ) +insert ( 438 num_nulls 11 10 12 1 0 2276 0 f f f f f i s 1 0 23 2276 '{2276}' '{v}' _null_ _null_ _null_ pg_num_nulls _null_ _null_ _null_ _null_ ) +insert ( 440 num_nonnulls 11 10 12 1 0 2276 0 f f f f f i s 1 0 23 2276 '{2276}' '{v}' _null_ _null_ _null_ pg_num_nonnulls _null_ _null_ _null_ _null_ ) +insert ( 458 text_larger 11 10 12 1 0 0 0 f f t t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ text_larger _null_ _null_ _null_ _null_ ) +insert ( 459 text_smaller 11 10 12 1 0 0 0 f f t t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ text_smaller _null_ _null_ _null_ _null_ ) +insert ( 460 int8in 11 10 12 1 0 0 0 f f f t f i s 1 0 20 2275 _null_ _null_ _null_ _null_ _null_ int8in _null_ _null_ _null_ _null_ ) +insert ( 461 int8out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 20 _null_ _null_ _null_ _null_ _null_ int8out _null_ _null_ _null_ _null_ ) +insert ( 462 int8um 11 10 12 1 0 0 0 f f f t f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ int8um _null_ _null_ _null_ _null_ ) +insert ( 463 int8pl 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8pl _null_ _null_ _null_ _null_ ) +insert ( 464 int8mi 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8mi _null_ _null_ _null_ _null_ ) +insert ( 465 int8mul 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8mul _null_ _null_ _null_ _null_ ) +insert ( 466 int8div 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8div _null_ _null_ _null_ _null_ ) +insert ( 467 int8eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 20' _null_ _null_ _null_ _null_ _null_ int8eq _null_ _null_ _null_ _null_ ) +insert ( 468 int8ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 20' _null_ _null_ _null_ _null_ _null_ int8ne _null_ _null_ _null_ _null_ ) +insert ( 469 int8lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 20' _null_ _null_ _null_ _null_ _null_ int8lt _null_ _null_ _null_ _null_ ) +insert ( 470 int8gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 20' _null_ _null_ _null_ _null_ _null_ int8gt _null_ _null_ _null_ _null_ ) +insert ( 471 int8le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 20' _null_ _null_ _null_ _null_ _null_ int8le _null_ _null_ _null_ _null_ ) +insert ( 472 int8ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 20' _null_ _null_ _null_ _null_ _null_ int8ge _null_ _null_ _null_ _null_ ) +insert ( 474 int84eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 23' _null_ _null_ _null_ _null_ _null_ int84eq _null_ _null_ _null_ _null_ ) +insert ( 475 int84ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 23' _null_ _null_ _null_ _null_ _null_ int84ne _null_ _null_ _null_ _null_ ) +insert ( 476 int84lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 23' _null_ _null_ _null_ _null_ _null_ int84lt _null_ _null_ _null_ _null_ ) +insert ( 477 int84gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 23' _null_ _null_ _null_ _null_ _null_ int84gt _null_ _null_ _null_ _null_ ) +insert ( 478 int84le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 23' _null_ _null_ _null_ _null_ _null_ int84le _null_ _null_ _null_ _null_ ) +insert ( 479 int84ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 23' _null_ _null_ _null_ _null_ _null_ int84ge _null_ _null_ _null_ _null_ ) +insert ( 480 int4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 20 _null_ _null_ _null_ _null_ _null_ int84 _null_ _null_ _null_ _null_ ) +insert ( 481 int8 11 10 12 1 0 0 0 f f t t f i s 1 0 20 23 _null_ _null_ _null_ _null_ _null_ int48 _null_ _null_ _null_ _null_ ) +insert ( 482 float8 11 10 12 1 0 0 0 f f t t f i s 1 0 701 20 _null_ _null_ _null_ _null_ _null_ i8tod _null_ _null_ _null_ _null_ ) +insert ( 483 int8 11 10 12 1 0 0 0 f f f t f i s 1 0 20 701 _null_ _null_ _null_ _null_ _null_ dtoi8 _null_ _null_ _null_ _null_ ) +insert ( 626 hash_array 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2277 _null_ _null_ _null_ _null_ _null_ hash_array _null_ _null_ _null_ _null_ ) +insert ( 782 hash_array_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '2277 20' _null_ _null_ _null_ _null_ _null_ hash_array_extended _null_ _null_ _null_ _null_ ) +insert ( 652 float4 11 10 12 1 0 0 0 f f t t f i s 1 0 700 20 _null_ _null_ _null_ _null_ _null_ i8tof _null_ _null_ _null_ _null_ ) +insert ( 653 int8 11 10 12 1 0 0 0 f f f t f i s 1 0 20 700 _null_ _null_ _null_ _null_ _null_ ftoi8 _null_ _null_ _null_ _null_ ) +insert ( 714 int2 11 10 12 1 0 0 0 f f f t f i s 1 0 21 20 _null_ _null_ _null_ _null_ _null_ int82 _null_ _null_ _null_ _null_ ) +insert ( 754 int8 11 10 12 1 0 0 0 f f t t f i s 1 0 20 21 _null_ _null_ _null_ _null_ _null_ int28 _null_ _null_ _null_ _null_ ) +insert ( 655 namelt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 19' _null_ _null_ _null_ _null_ _null_ namelt _null_ _null_ _null_ _null_ ) +insert ( 656 namele 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 19' _null_ _null_ _null_ _null_ _null_ namele _null_ _null_ _null_ _null_ ) +insert ( 657 namegt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 19' _null_ _null_ _null_ _null_ _null_ namegt _null_ _null_ _null_ _null_ ) +insert ( 658 namege 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 19' _null_ _null_ _null_ _null_ _null_ namege _null_ _null_ _null_ _null_ ) +insert ( 659 namene 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '19 19' _null_ _null_ _null_ _null_ _null_ namene _null_ _null_ _null_ _null_ ) +insert ( 668 bpchar 11 10 12 1 0 0 0 f f f t f i s 3 0 1042 '1042 23 16' _null_ _null_ _null_ _null_ _null_ bpchar _null_ _null_ _null_ _null_ ) +insert ( 3097 varchar_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ varchar_support _null_ _null_ _null_ _null_ ) +insert ( 669 varchar 11 10 12 1 0 0 3097 f f f t f i s 3 0 1043 '1043 23 16' _null_ _null_ _null_ _null_ _null_ varchar _null_ _null_ _null_ _null_ ) +insert ( 619 oidvectorne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '30 30' _null_ _null_ _null_ _null_ _null_ oidvectorne _null_ _null_ _null_ _null_ ) +insert ( 677 oidvectorlt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '30 30' _null_ _null_ _null_ _null_ _null_ oidvectorlt _null_ _null_ _null_ _null_ ) +insert ( 678 oidvectorle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '30 30' _null_ _null_ _null_ _null_ _null_ oidvectorle _null_ _null_ _null_ _null_ ) +insert ( 679 oidvectoreq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '30 30' _null_ _null_ _null_ _null_ _null_ oidvectoreq _null_ _null_ _null_ _null_ ) +insert ( 680 oidvectorge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '30 30' _null_ _null_ _null_ _null_ _null_ oidvectorge _null_ _null_ _null_ _null_ ) +insert ( 681 oidvectorgt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '30 30' _null_ _null_ _null_ _null_ _null_ oidvectorgt _null_ _null_ _null_ _null_ ) +insert ( 710 getpgusername 11 10 12 1 0 0 0 f f f t f s s 0 0 19 '' _null_ _null_ _null_ _null_ _null_ current_user _null_ _null_ _null_ _null_ ) +insert ( 716 oidlt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '26 26' _null_ _null_ _null_ _null_ _null_ oidlt _null_ _null_ _null_ _null_ ) +insert ( 717 oidle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '26 26' _null_ _null_ _null_ _null_ _null_ oidle _null_ _null_ _null_ _null_ ) +insert ( 720 octet_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 17 _null_ _null_ _null_ _null_ _null_ byteaoctetlen _null_ _null_ _null_ _null_ ) +insert ( 721 get_byte 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '17 23' _null_ _null_ _null_ _null_ _null_ byteaGetByte _null_ _null_ _null_ _null_ ) +insert ( 722 set_byte 11 10 12 1 0 0 0 f f f t f i s 3 0 17 '17 23 23' _null_ _null_ _null_ _null_ _null_ byteaSetByte _null_ _null_ _null_ _null_ ) +insert ( 723 get_bit 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '17 20' _null_ _null_ _null_ _null_ _null_ byteaGetBit _null_ _null_ _null_ _null_ ) +insert ( 724 set_bit 11 10 12 1 0 0 0 f f f t f i s 3 0 17 '17 20 23' _null_ _null_ _null_ _null_ _null_ byteaSetBit _null_ _null_ _null_ _null_ ) +insert ( 749 overlay 11 10 12 1 0 0 0 f f f t f i s 4 0 17 '17 17 23 23' _null_ _null_ _null_ _null_ _null_ byteaoverlay _null_ _null_ _null_ _null_ ) +insert ( 752 overlay 11 10 12 1 0 0 0 f f f t f i s 3 0 17 '17 17 23' _null_ _null_ _null_ _null_ _null_ byteaoverlay_no_len _null_ _null_ _null_ _null_ ) +insert ( 6163 bit_count 11 10 12 1 0 0 0 f f f t f i s 1 0 20 17 _null_ _null_ _null_ _null_ _null_ bytea_bit_count _null_ _null_ _null_ _null_ ) +insert ( 725 dist_pl 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 628' _null_ _null_ _null_ _null_ _null_ dist_pl _null_ _null_ _null_ _null_ ) +insert ( 702 dist_lp 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '628 600' _null_ _null_ _null_ _null_ _null_ dist_lp _null_ _null_ _null_ _null_ ) +insert ( 727 dist_sl 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '601 628' _null_ _null_ _null_ _null_ _null_ dist_sl _null_ _null_ _null_ _null_ ) +insert ( 704 dist_ls 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '628 601' _null_ _null_ _null_ _null_ _null_ dist_ls _null_ _null_ _null_ _null_ ) +insert ( 728 dist_cpoly 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '718 604' _null_ _null_ _null_ _null_ _null_ dist_cpoly _null_ _null_ _null_ _null_ ) +insert ( 785 dist_polyc 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '604 718' _null_ _null_ _null_ _null_ _null_ dist_polyc _null_ _null_ _null_ _null_ ) +insert ( 729 poly_distance 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '604 604' _null_ _null_ _null_ _null_ _null_ poly_distance _null_ _null_ _null_ _null_ ) +insert ( 3275 dist_ppoly 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 604' _null_ _null_ _null_ _null_ _null_ dist_ppoly _null_ _null_ _null_ _null_ ) +insert ( 3292 dist_polyp 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '604 600' _null_ _null_ _null_ _null_ _null_ dist_polyp _null_ _null_ _null_ _null_ ) +insert ( 3290 dist_cpoint 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '718 600' _null_ _null_ _null_ _null_ _null_ dist_cpoint _null_ _null_ _null_ _null_ ) +insert ( 740 text_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_lt _null_ _null_ _null_ _null_ ) +insert ( 741 text_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_le _null_ _null_ _null_ _null_ ) +insert ( 742 text_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_gt _null_ _null_ _null_ _null_ ) +insert ( 743 text_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_ge _null_ _null_ _null_ _null_ ) +insert ( 745 current_user 11 10 12 1 0 0 0 f f f t f s s 0 0 19 '' _null_ _null_ _null_ _null_ _null_ current_user _null_ _null_ _null_ _null_ ) +insert ( 746 session_user 11 10 12 1 0 0 0 f f f t f s s 0 0 19 '' _null_ _null_ _null_ _null_ _null_ session_user _null_ _null_ _null_ _null_ ) +insert ( 6311 system_user 11 10 12 1 0 0 0 f f f t f s s 0 0 25 '' _null_ _null_ _null_ _null_ _null_ system_user _null_ _null_ _null_ _null_ ) +insert ( 744 array_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_eq _null_ _null_ _null_ _null_ ) +insert ( 390 array_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_ne _null_ _null_ _null_ _null_ ) +insert ( 391 array_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_lt _null_ _null_ _null_ _null_ ) +insert ( 392 array_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_gt _null_ _null_ _null_ _null_ ) +insert ( 393 array_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_le _null_ _null_ _null_ _null_ ) +insert ( 396 array_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_ge _null_ _null_ _null_ _null_ ) +insert ( 747 array_dims 11 10 12 1 0 0 0 f f f t f i s 1 0 25 2277 _null_ _null_ _null_ _null_ _null_ array_dims _null_ _null_ _null_ _null_ ) +insert ( 748 array_ndims 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2277 _null_ _null_ _null_ _null_ _null_ array_ndims _null_ _null_ _null_ _null_ ) +insert ( 750 array_in 11 10 12 1 0 0 0 f f f t f s s 3 0 2277 '2275 26 23' _null_ _null_ _null_ _null_ _null_ array_in _null_ _null_ _null_ _null_ ) +insert ( 751 array_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2277 _null_ _null_ _null_ _null_ _null_ array_out _null_ _null_ _null_ _null_ ) +insert ( 2091 array_lower 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '2277 23' _null_ _null_ _null_ _null_ _null_ array_lower _null_ _null_ _null_ _null_ ) +insert ( 2092 array_upper 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '2277 23' _null_ _null_ _null_ _null_ _null_ array_upper _null_ _null_ _null_ _null_ ) +insert ( 2176 array_length 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '2277 23' _null_ _null_ _null_ _null_ _null_ array_length _null_ _null_ _null_ _null_ ) +insert ( 3179 cardinality 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2277 _null_ _null_ _null_ _null_ _null_ array_cardinality _null_ _null_ _null_ _null_ ) +insert ( 378 array_append 11 10 12 1 0 0 0 f f f f f i s 2 0 5078 '5078 5077' _null_ _null_ _null_ _null_ _null_ array_append _null_ _null_ _null_ _null_ ) +insert ( 379 array_prepend 11 10 12 1 0 0 0 f f f f f i s 2 0 5078 '5077 5078' _null_ _null_ _null_ _null_ _null_ array_prepend _null_ _null_ _null_ _null_ ) +insert ( 383 array_cat 11 10 12 1 0 0 0 f f f f f i s 2 0 5078 '5078 5078' _null_ _null_ _null_ _null_ _null_ array_cat _null_ _null_ _null_ _null_ ) +insert ( 394 string_to_array 11 10 12 1 0 0 0 f f f f f i s 2 0 1009 '25 25' _null_ _null_ _null_ _null_ _null_ text_to_array _null_ _null_ _null_ _null_ ) +insert ( 376 string_to_array 11 10 12 1 0 0 0 f f f f f i s 3 0 1009 '25 25 25' _null_ _null_ _null_ _null_ _null_ text_to_array_null _null_ _null_ _null_ _null_ ) +insert ( 6160 string_to_table 11 10 12 1 1000 0 0 f f f f t i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ text_to_table _null_ _null_ _null_ _null_ ) +insert ( 6161 string_to_table 11 10 12 1 1000 0 0 f f f f t i s 3 0 25 '25 25 25' _null_ _null_ _null_ _null_ _null_ text_to_table_null _null_ _null_ _null_ _null_ ) +insert ( 395 array_to_string 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '2277 25' _null_ _null_ _null_ _null_ _null_ array_to_text _null_ _null_ _null_ _null_ ) +insert ( 384 array_to_string 11 10 12 1 0 0 0 f f f f f s s 3 0 25 '2277 25 25' _null_ _null_ _null_ _null_ _null_ array_to_text_null _null_ _null_ _null_ _null_ ) +insert ( 515 array_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 2277 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_larger _null_ _null_ _null_ _null_ ) +insert ( 516 array_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 2277 '2277 2277' _null_ _null_ _null_ _null_ _null_ array_smaller _null_ _null_ _null_ _null_ ) +insert ( 3277 array_position 11 10 12 1 0 0 0 f f f f f i s 2 0 23 '5078 5077' _null_ _null_ _null_ _null_ _null_ array_position _null_ _null_ _null_ _null_ ) +insert ( 3278 array_position 11 10 12 1 0 0 0 f f f f f i s 3 0 23 '5078 5077 23' _null_ _null_ _null_ _null_ _null_ array_position_start _null_ _null_ _null_ _null_ ) +insert ( 3279 array_positions 11 10 12 1 0 0 0 f f f f f i s 2 0 1007 '5078 5077' _null_ _null_ _null_ _null_ _null_ array_positions _null_ _null_ _null_ _null_ ) +insert ( 1191 generate_subscripts 11 10 12 1 1000 0 0 f f f t t i s 3 0 23 '2277 23 16' _null_ _null_ _null_ _null_ _null_ generate_subscripts _null_ _null_ _null_ _null_ ) +insert ( 1192 generate_subscripts 11 10 12 1 1000 0 0 f f f t t i s 2 0 23 '2277 23' _null_ _null_ _null_ _null_ _null_ generate_subscripts_nodir _null_ _null_ _null_ _null_ ) +insert ( 1193 array_fill 11 10 12 1 0 0 0 f f f f f i s 2 0 2277 '2283 1007' _null_ _null_ _null_ _null_ _null_ array_fill _null_ _null_ _null_ _null_ ) +insert ( 1286 array_fill 11 10 12 1 0 0 0 f f f f f i s 3 0 2277 '2283 1007 1007' _null_ _null_ _null_ _null_ _null_ array_fill_with_lower_bounds _null_ _null_ _null_ _null_ ) +insert ( 2331 unnest 11 10 12 1 100 0 3996 f f f t t i s 1 0 2283 2277 _null_ _null_ _null_ _null_ _null_ array_unnest _null_ _null_ _null_ _null_ ) +insert ( 3996 array_unnest_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ array_unnest_support _null_ _null_ _null_ _null_ ) +insert ( 3167 array_remove 11 10 12 1 0 0 0 f f f f f i s 2 0 5078 '5078 5077' _null_ _null_ _null_ _null_ _null_ array_remove _null_ _null_ _null_ _null_ ) +insert ( 3168 array_replace 11 10 12 1 0 0 0 f f f f f i s 3 0 5078 '5078 5077 5077' _null_ _null_ _null_ _null_ _null_ array_replace _null_ _null_ _null_ _null_ ) +insert ( 2333 array_agg_transfn 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2776' _null_ _null_ _null_ _null_ _null_ array_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 6293 array_agg_combine 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ array_agg_combine _null_ _null_ _null_ _null_ ) +insert ( 6294 array_agg_serialize 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ array_agg_serialize _null_ _null_ _null_ _null_ ) +insert ( 6295 array_agg_deserialize 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '17 2281' _null_ _null_ _null_ _null_ _null_ array_agg_deserialize _null_ _null_ _null_ _null_ ) +insert ( 2334 array_agg_finalfn 11 10 12 1 0 0 0 f f f f f i s 2 0 2277 '2281 2776' _null_ _null_ _null_ _null_ _null_ array_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 2335 array_agg 11 10 12 1 0 0 0 a f f f f i s 1 0 2277 2776 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 4051 array_agg_array_transfn 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2277' _null_ _null_ _null_ _null_ _null_ array_agg_array_transfn _null_ _null_ _null_ _null_ ) +insert ( 6296 array_agg_array_combine 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ array_agg_array_combine _null_ _null_ _null_ _null_ ) +insert ( 6297 array_agg_array_serialize 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ array_agg_array_serialize _null_ _null_ _null_ _null_ ) +insert ( 6298 array_agg_array_deserialize 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '17 2281' _null_ _null_ _null_ _null_ _null_ array_agg_array_deserialize _null_ _null_ _null_ _null_ ) +insert ( 4052 array_agg_array_finalfn 11 10 12 1 0 0 0 f f f f f i s 2 0 2277 '2281 2277' _null_ _null_ _null_ _null_ _null_ array_agg_array_finalfn _null_ _null_ _null_ _null_ ) +insert ( 4053 array_agg 11 10 12 1 0 0 0 a f f f f i s 1 0 2277 2277 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3218 width_bucket 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '5077 5078' _null_ _null_ _null_ _null_ _null_ width_bucket_array _null_ _null_ _null_ _null_ ) +insert ( 6172 trim_array 11 10 12 1 0 0 0 f f f t f i s 2 0 2277 '2277 23' _null_ _null_ _null_ _null_ _null_ trim_array _null_ _null_ _null_ _null_ ) +insert ( 6215 array_shuffle 11 10 12 1 0 0 0 f f f t f v s 1 0 2277 2277 _null_ _null_ _null_ _null_ _null_ array_shuffle _null_ _null_ _null_ _null_ ) +insert ( 6216 array_sample 11 10 12 1 0 0 0 f f f t f v s 2 0 2277 '2277 23' _null_ _null_ _null_ _null_ _null_ array_sample _null_ _null_ _null_ _null_ ) +insert ( 3816 array_typanalyze 11 10 12 1 0 0 0 f f f t f s s 1 0 16 2281 _null_ _null_ _null_ _null_ _null_ array_typanalyze _null_ _null_ _null_ _null_ ) +insert ( 3817 arraycontsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ arraycontsel _null_ _null_ _null_ _null_ ) +insert ( 3818 arraycontjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ arraycontjoinsel _null_ _null_ _null_ _null_ ) +insert ( 764 lo_import 11 10 12 1 0 0 0 f f f t f v u 1 0 26 25 _null_ _null_ _null_ _null_ _null_ be_lo_import _null_ _null_ _null_ _null_ ) +insert ( 767 lo_import 11 10 12 1 0 0 0 f f f t f v u 2 0 26 '25 26' _null_ _null_ _null_ _null_ _null_ be_lo_import_with_oid _null_ _null_ _null_ _null_ ) +insert ( 765 lo_export 11 10 12 1 0 0 0 f f f t f v u 2 0 23 '26 25' _null_ _null_ _null_ _null_ _null_ be_lo_export _null_ _null_ _null_ _null_ ) +insert ( 766 int4inc 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ int4inc _null_ _null_ _null_ _null_ ) +insert ( 768 int4larger 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4larger _null_ _null_ _null_ _null_ ) +insert ( 769 int4smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4smaller _null_ _null_ _null_ _null_ ) +insert ( 770 int2larger 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2larger _null_ _null_ _null_ _null_ ) +insert ( 771 int2smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2smaller _null_ _null_ _null_ _null_ ) +insert ( 846 cash_mul_flt4 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 700' _null_ _null_ _null_ _null_ _null_ cash_mul_flt4 _null_ _null_ _null_ _null_ ) +insert ( 847 cash_div_flt4 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 700' _null_ _null_ _null_ _null_ _null_ cash_div_flt4 _null_ _null_ _null_ _null_ ) +insert ( 848 flt4_mul_cash 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '700 790' _null_ _null_ _null_ _null_ _null_ flt4_mul_cash _null_ _null_ _null_ _null_ ) +insert ( 849 position 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ textpos _null_ _null_ _null_ _null_ ) +insert ( 850 textlike 11 10 12 1 0 0 1023 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ textlike _null_ _null_ _null_ _null_ ) +insert ( 1023 textlike_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ textlike_support _null_ _null_ _null_ _null_ ) +insert ( 851 textnlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ textnlike _null_ _null_ _null_ _null_ ) +insert ( 852 int48eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 20' _null_ _null_ _null_ _null_ _null_ int48eq _null_ _null_ _null_ _null_ ) +insert ( 853 int48ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 20' _null_ _null_ _null_ _null_ _null_ int48ne _null_ _null_ _null_ _null_ ) +insert ( 854 int48lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 20' _null_ _null_ _null_ _null_ _null_ int48lt _null_ _null_ _null_ _null_ ) +insert ( 855 int48gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 20' _null_ _null_ _null_ _null_ _null_ int48gt _null_ _null_ _null_ _null_ ) +insert ( 856 int48le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 20' _null_ _null_ _null_ _null_ _null_ int48le _null_ _null_ _null_ _null_ ) +insert ( 857 int48ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '23 20' _null_ _null_ _null_ _null_ _null_ int48ge _null_ _null_ _null_ _null_ ) +insert ( 858 namelike 11 10 12 1 0 0 1023 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namelike _null_ _null_ _null_ _null_ ) +insert ( 859 namenlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namenlike _null_ _null_ _null_ _null_ ) +insert ( 860 bpchar 11 10 12 1 0 0 0 f f f t f i s 1 0 1042 18 _null_ _null_ _null_ _null_ _null_ char_bpchar _null_ _null_ _null_ _null_ ) +insert ( 861 current_database 11 10 12 1 0 0 0 f f f t f s s 0 0 19 '' _null_ _null_ _null_ _null_ _null_ current_database _null_ _null_ _null_ _null_ ) +insert ( 817 current_query 11 10 12 1 0 0 0 f f f f f v r 0 0 25 '' _null_ _null_ _null_ _null_ _null_ current_query _null_ _null_ _null_ _null_ ) +insert ( 3399 int8_mul_cash 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '20 790' _null_ _null_ _null_ _null_ _null_ int8_mul_cash _null_ _null_ _null_ _null_ ) +insert ( 862 int4_mul_cash 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '23 790' _null_ _null_ _null_ _null_ _null_ int4_mul_cash _null_ _null_ _null_ _null_ ) +insert ( 863 int2_mul_cash 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '21 790' _null_ _null_ _null_ _null_ _null_ int2_mul_cash _null_ _null_ _null_ _null_ ) +insert ( 3344 cash_mul_int8 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 20' _null_ _null_ _null_ _null_ _null_ cash_mul_int8 _null_ _null_ _null_ _null_ ) +insert ( 3345 cash_div_int8 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 20' _null_ _null_ _null_ _null_ _null_ cash_div_int8 _null_ _null_ _null_ _null_ ) +insert ( 864 cash_mul_int4 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 23' _null_ _null_ _null_ _null_ _null_ cash_mul_int4 _null_ _null_ _null_ _null_ ) +insert ( 865 cash_div_int4 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 23' _null_ _null_ _null_ _null_ _null_ cash_div_int4 _null_ _null_ _null_ _null_ ) +insert ( 866 cash_mul_int2 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 21' _null_ _null_ _null_ _null_ _null_ cash_mul_int2 _null_ _null_ _null_ _null_ ) +insert ( 867 cash_div_int2 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 21' _null_ _null_ _null_ _null_ _null_ cash_div_int2 _null_ _null_ _null_ _null_ ) +insert ( 886 cash_in 11 10 12 1 0 0 0 f f f t f s s 1 0 790 2275 _null_ _null_ _null_ _null_ _null_ cash_in _null_ _null_ _null_ _null_ ) +insert ( 887 cash_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 790 _null_ _null_ _null_ _null_ _null_ cash_out _null_ _null_ _null_ _null_ ) +insert ( 888 cash_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '790 790' _null_ _null_ _null_ _null_ _null_ cash_eq _null_ _null_ _null_ _null_ ) +insert ( 889 cash_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '790 790' _null_ _null_ _null_ _null_ _null_ cash_ne _null_ _null_ _null_ _null_ ) +insert ( 890 cash_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '790 790' _null_ _null_ _null_ _null_ _null_ cash_lt _null_ _null_ _null_ _null_ ) +insert ( 891 cash_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '790 790' _null_ _null_ _null_ _null_ _null_ cash_le _null_ _null_ _null_ _null_ ) +insert ( 892 cash_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '790 790' _null_ _null_ _null_ _null_ _null_ cash_gt _null_ _null_ _null_ _null_ ) +insert ( 893 cash_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '790 790' _null_ _null_ _null_ _null_ _null_ cash_ge _null_ _null_ _null_ _null_ ) +insert ( 894 cash_pl 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 790' _null_ _null_ _null_ _null_ _null_ cash_pl _null_ _null_ _null_ _null_ ) +insert ( 895 cash_mi 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 790' _null_ _null_ _null_ _null_ _null_ cash_mi _null_ _null_ _null_ _null_ ) +insert ( 896 cash_mul_flt8 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 701' _null_ _null_ _null_ _null_ _null_ cash_mul_flt8 _null_ _null_ _null_ _null_ ) +insert ( 897 cash_div_flt8 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 701' _null_ _null_ _null_ _null_ _null_ cash_div_flt8 _null_ _null_ _null_ _null_ ) +insert ( 898 cashlarger 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 790' _null_ _null_ _null_ _null_ _null_ cashlarger _null_ _null_ _null_ _null_ ) +insert ( 899 cashsmaller 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '790 790' _null_ _null_ _null_ _null_ _null_ cashsmaller _null_ _null_ _null_ _null_ ) +insert ( 919 flt8_mul_cash 11 10 12 1 0 0 0 f f f t f i s 2 0 790 '701 790' _null_ _null_ _null_ _null_ _null_ flt8_mul_cash _null_ _null_ _null_ _null_ ) +insert ( 935 cash_words 11 10 12 1 0 0 0 f f f t f i s 1 0 25 790 _null_ _null_ _null_ _null_ _null_ cash_words _null_ _null_ _null_ _null_ ) +insert ( 3822 cash_div_cash 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '790 790' _null_ _null_ _null_ _null_ _null_ cash_div_cash _null_ _null_ _null_ _null_ ) +insert ( 3823 numeric 11 10 12 1 0 0 0 f f f t f s s 1 0 1700 790 _null_ _null_ _null_ _null_ _null_ cash_numeric _null_ _null_ _null_ _null_ ) +insert ( 3824 money 11 10 12 1 0 0 0 f f f t f s s 1 0 790 1700 _null_ _null_ _null_ _null_ _null_ numeric_cash _null_ _null_ _null_ _null_ ) +insert ( 3811 money 11 10 12 1 0 0 0 f f f t f s s 1 0 790 23 _null_ _null_ _null_ _null_ _null_ int4_cash _null_ _null_ _null_ _null_ ) +insert ( 3812 money 11 10 12 1 0 0 0 f f f t f s s 1 0 790 20 _null_ _null_ _null_ _null_ _null_ int8_cash _null_ _null_ _null_ _null_ ) +insert ( 940 mod 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2mod _null_ _null_ _null_ _null_ ) +insert ( 941 mod 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4mod _null_ _null_ _null_ _null_ ) +insert ( 945 int8mod 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8mod _null_ _null_ _null_ _null_ ) +insert ( 947 mod 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8mod _null_ _null_ _null_ _null_ ) +insert ( 5044 gcd 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4gcd _null_ _null_ _null_ _null_ ) +insert ( 5045 gcd 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8gcd _null_ _null_ _null_ _null_ ) +insert ( 5046 lcm 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4lcm _null_ _null_ _null_ _null_ ) +insert ( 5047 lcm 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8lcm _null_ _null_ _null_ _null_ ) +insert ( 944 char 11 10 12 1 0 0 0 f f f t f i s 1 0 18 25 _null_ _null_ _null_ _null_ _null_ text_char _null_ _null_ _null_ _null_ ) +insert ( 946 text 11 10 12 1 0 0 0 f f f t f i s 1 0 25 18 _null_ _null_ _null_ _null_ _null_ char_text _null_ _null_ _null_ _null_ ) +insert ( 952 lo_open 11 10 12 1 0 0 0 f f f t f v u 2 0 23 '26 23' _null_ _null_ _null_ _null_ _null_ be_lo_open _null_ _null_ _null_ _null_ ) +insert ( 953 lo_close 11 10 12 1 0 0 0 f f f t f v u 1 0 23 23 _null_ _null_ _null_ _null_ _null_ be_lo_close _null_ _null_ _null_ _null_ ) +insert ( 954 loread 11 10 12 1 0 0 0 f f f t f v u 2 0 17 '23 23' _null_ _null_ _null_ _null_ _null_ be_loread _null_ _null_ _null_ _null_ ) +insert ( 955 lowrite 11 10 12 1 0 0 0 f f f t f v u 2 0 23 '23 17' _null_ _null_ _null_ _null_ _null_ be_lowrite _null_ _null_ _null_ _null_ ) +insert ( 956 lo_lseek 11 10 12 1 0 0 0 f f f t f v u 3 0 23 '23 23 23' _null_ _null_ _null_ _null_ _null_ be_lo_lseek _null_ _null_ _null_ _null_ ) +insert ( 3170 lo_lseek64 11 10 12 1 0 0 0 f f f t f v u 3 0 20 '23 20 23' _null_ _null_ _null_ _null_ _null_ be_lo_lseek64 _null_ _null_ _null_ _null_ ) +insert ( 957 lo_creat 11 10 12 1 0 0 0 f f f t f v u 1 0 26 23 _null_ _null_ _null_ _null_ _null_ be_lo_creat _null_ _null_ _null_ _null_ ) +insert ( 715 lo_create 11 10 12 1 0 0 0 f f f t f v u 1 0 26 26 _null_ _null_ _null_ _null_ _null_ be_lo_create _null_ _null_ _null_ _null_ ) +insert ( 958 lo_tell 11 10 12 1 0 0 0 f f f t f v u 1 0 23 23 _null_ _null_ _null_ _null_ _null_ be_lo_tell _null_ _null_ _null_ _null_ ) +insert ( 3171 lo_tell64 11 10 12 1 0 0 0 f f f t f v u 1 0 20 23 _null_ _null_ _null_ _null_ _null_ be_lo_tell64 _null_ _null_ _null_ _null_ ) +insert ( 1004 lo_truncate 11 10 12 1 0 0 0 f f f t f v u 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ be_lo_truncate _null_ _null_ _null_ _null_ ) +insert ( 3172 lo_truncate64 11 10 12 1 0 0 0 f f f t f v u 2 0 23 '23 20' _null_ _null_ _null_ _null_ _null_ be_lo_truncate64 _null_ _null_ _null_ _null_ ) +insert ( 3457 lo_from_bytea 11 10 12 1 0 0 0 f f f t f v u 2 0 26 '26 17' _null_ _null_ _null_ _null_ _null_ be_lo_from_bytea _null_ _null_ _null_ _null_ ) +insert ( 3458 lo_get 11 10 12 1 0 0 0 f f f t f v u 1 0 17 26 _null_ _null_ _null_ _null_ _null_ be_lo_get _null_ _null_ _null_ _null_ ) +insert ( 3459 lo_get 11 10 12 1 0 0 0 f f f t f v u 3 0 17 '26 20 23' _null_ _null_ _null_ _null_ _null_ be_lo_get_fragment _null_ _null_ _null_ _null_ ) +insert ( 3460 lo_put 11 10 12 1 0 0 0 f f f t f v u 3 0 2278 '26 20 17' _null_ _null_ _null_ _null_ _null_ be_lo_put _null_ _null_ _null_ _null_ ) +insert ( 959 on_pl 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 628' _null_ _null_ _null_ _null_ _null_ on_pl _null_ _null_ _null_ _null_ ) +insert ( 960 on_sl 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 628' _null_ _null_ _null_ _null_ _null_ on_sl _null_ _null_ _null_ _null_ ) +insert ( 961 close_pl 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '600 628' _null_ _null_ _null_ _null_ _null_ close_pl _null_ _null_ _null_ _null_ ) +insert ( 964 lo_unlink 11 10 12 1 0 0 0 f f f t f v u 1 0 23 26 _null_ _null_ _null_ _null_ _null_ be_lo_unlink _null_ _null_ _null_ _null_ ) +insert ( 973 path_inter 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '602 602' _null_ _null_ _null_ _null_ _null_ path_inter _null_ _null_ _null_ _null_ ) +insert ( 975 area 11 10 12 1 0 0 0 f f f t f i s 1 0 701 603 _null_ _null_ _null_ _null_ _null_ box_area _null_ _null_ _null_ _null_ ) +insert ( 976 width 11 10 12 1 0 0 0 f f f t f i s 1 0 701 603 _null_ _null_ _null_ _null_ _null_ box_width _null_ _null_ _null_ _null_ ) +insert ( 977 height 11 10 12 1 0 0 0 f f f t f i s 1 0 701 603 _null_ _null_ _null_ _null_ _null_ box_height _null_ _null_ _null_ _null_ ) +insert ( 978 box_distance 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '603 603' _null_ _null_ _null_ _null_ _null_ box_distance _null_ _null_ _null_ _null_ ) +insert ( 979 area 11 10 12 1 0 0 0 f f f t f i s 1 0 701 602 _null_ _null_ _null_ _null_ _null_ path_area _null_ _null_ _null_ _null_ ) +insert ( 980 box_intersect 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '603 603' _null_ _null_ _null_ _null_ _null_ box_intersect _null_ _null_ _null_ _null_ ) +insert ( 4067 bound_box 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '603 603' _null_ _null_ _null_ _null_ _null_ boxes_bound_box _null_ _null_ _null_ _null_ ) +insert ( 981 diagonal 11 10 12 1 0 0 0 f f f t f i s 1 0 601 603 _null_ _null_ _null_ _null_ _null_ box_diagonal _null_ _null_ _null_ _null_ ) +insert ( 982 path_n_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '602 602' _null_ _null_ _null_ _null_ _null_ path_n_lt _null_ _null_ _null_ _null_ ) +insert ( 983 path_n_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '602 602' _null_ _null_ _null_ _null_ _null_ path_n_gt _null_ _null_ _null_ _null_ ) +insert ( 984 path_n_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '602 602' _null_ _null_ _null_ _null_ _null_ path_n_eq _null_ _null_ _null_ _null_ ) +insert ( 985 path_n_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '602 602' _null_ _null_ _null_ _null_ _null_ path_n_le _null_ _null_ _null_ _null_ ) +insert ( 986 path_n_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '602 602' _null_ _null_ _null_ _null_ _null_ path_n_ge _null_ _null_ _null_ _null_ ) +insert ( 987 path_length 11 10 12 1 0 0 0 f f f t f i s 1 0 701 602 _null_ _null_ _null_ _null_ _null_ path_length _null_ _null_ _null_ _null_ ) +insert ( 988 point_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_ne _null_ _null_ _null_ _null_ ) +insert ( 989 point_vert 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_vert _null_ _null_ _null_ _null_ ) +insert ( 990 point_horiz 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_horiz _null_ _null_ _null_ _null_ ) +insert ( 991 point_distance 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 600' _null_ _null_ _null_ _null_ _null_ point_distance _null_ _null_ _null_ _null_ ) +insert ( 992 slope 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 600' _null_ _null_ _null_ _null_ _null_ point_slope _null_ _null_ _null_ _null_ ) +insert ( 993 lseg 11 10 12 1 0 0 0 f f f t f i s 2 0 601 '600 600' _null_ _null_ _null_ _null_ _null_ lseg_construct _null_ _null_ _null_ _null_ ) +insert ( 994 lseg_intersect 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_intersect _null_ _null_ _null_ _null_ ) +insert ( 995 lseg_parallel 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_parallel _null_ _null_ _null_ _null_ ) +insert ( 996 lseg_perp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_perp _null_ _null_ _null_ _null_ ) +insert ( 997 lseg_vertical 11 10 12 1 0 0 0 f f f t f i s 1 0 16 601 _null_ _null_ _null_ _null_ _null_ lseg_vertical _null_ _null_ _null_ _null_ ) +insert ( 998 lseg_horizontal 11 10 12 1 0 0 0 f f f t f i s 1 0 16 601 _null_ _null_ _null_ _null_ _null_ lseg_horizontal _null_ _null_ _null_ _null_ ) +insert ( 999 lseg_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_eq _null_ _null_ _null_ _null_ ) +insert ( 1026 timezone 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1186 1184' _null_ _null_ _null_ _null_ _null_ timestamptz_izone _null_ _null_ _null_ _null_ ) +insert ( 1031 aclitemin 11 10 12 1 0 0 0 f f f t f s s 1 0 1033 2275 _null_ _null_ _null_ _null_ _null_ aclitemin _null_ _null_ _null_ _null_ ) +insert ( 1032 aclitemout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 1033 _null_ _null_ _null_ _null_ _null_ aclitemout _null_ _null_ _null_ _null_ ) +insert ( 1035 aclinsert 11 10 12 1 0 0 0 f f f t f i s 2 0 1034 '1034 1033' _null_ _null_ _null_ _null_ _null_ aclinsert _null_ _null_ _null_ _null_ ) +insert ( 1036 aclremove 11 10 12 1 0 0 0 f f f t f i s 2 0 1034 '1034 1033' _null_ _null_ _null_ _null_ _null_ aclremove _null_ _null_ _null_ _null_ ) +insert ( 1037 aclcontains 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1034 1033' _null_ _null_ _null_ _null_ _null_ aclcontains _null_ _null_ _null_ _null_ ) +insert ( 1062 aclitemeq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1033 1033' _null_ _null_ _null_ _null_ _null_ aclitem_eq _null_ _null_ _null_ _null_ ) +insert ( 1365 makeaclitem 11 10 12 1 0 0 0 f f f t f i s 4 0 1033 '26 26 25 16' _null_ _null_ _null_ _null_ _null_ makeaclitem _null_ _null_ _null_ _null_ ) +insert ( 3943 acldefault 11 10 12 1 0 0 0 f f f t f i s 2 0 1034 '18 26' _null_ _null_ _null_ _null_ _null_ acldefault_sql _null_ _null_ _null_ _null_ ) +insert ( 1689 aclexplode 11 10 12 1 10 0 0 f f f t t s s 1 0 2249 1034 '{1034,26,26,25,16}' '{i,o,o,o,o}' '{acl,grantor,grantee,privilege_type,is_grantable}' _null_ _null_ aclexplode _null_ _null_ _null_ _null_ ) +insert ( 1044 bpcharin 11 10 12 1 0 0 0 f f f t f i s 3 0 1042 '2275 26 23' _null_ _null_ _null_ _null_ _null_ bpcharin _null_ _null_ _null_ _null_ ) +insert ( 1045 bpcharout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 1042 _null_ _null_ _null_ _null_ _null_ bpcharout _null_ _null_ _null_ _null_ ) +insert ( 2913 bpchartypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ bpchartypmodin _null_ _null_ _null_ _null_ ) +insert ( 2914 bpchartypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ bpchartypmodout _null_ _null_ _null_ _null_ ) +insert ( 1046 varcharin 11 10 12 1 0 0 0 f f f t f i s 3 0 1043 '2275 26 23' _null_ _null_ _null_ _null_ _null_ varcharin _null_ _null_ _null_ _null_ ) +insert ( 1047 varcharout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 1043 _null_ _null_ _null_ _null_ _null_ varcharout _null_ _null_ _null_ _null_ ) +insert ( 2915 varchartypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ varchartypmodin _null_ _null_ _null_ _null_ ) +insert ( 2916 varchartypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ varchartypmodout _null_ _null_ _null_ _null_ ) +insert ( 1048 bpchareq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchareq _null_ _null_ _null_ _null_ ) +insert ( 1049 bpcharlt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpcharlt _null_ _null_ _null_ _null_ ) +insert ( 1050 bpcharle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpcharle _null_ _null_ _null_ _null_ ) +insert ( 1051 bpchargt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchargt _null_ _null_ _null_ _null_ ) +insert ( 1052 bpcharge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpcharge _null_ _null_ _null_ _null_ ) +insert ( 1053 bpcharne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpcharne _null_ _null_ _null_ _null_ ) +insert ( 1063 bpchar_larger 11 10 12 1 0 0 0 f f t t f i s 2 0 1042 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchar_larger _null_ _null_ _null_ _null_ ) +insert ( 1064 bpchar_smaller 11 10 12 1 0 0 0 f f t t f i s 2 0 1042 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchar_smaller _null_ _null_ _null_ _null_ ) +insert ( 1078 bpcharcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpcharcmp _null_ _null_ _null_ _null_ ) +insert ( 3328 bpchar_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ bpchar_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 1080 hashbpchar 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1042 _null_ _null_ _null_ _null_ _null_ hashbpchar _null_ _null_ _null_ _null_ ) +insert ( 972 hashbpcharextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '1042 20' _null_ _null_ _null_ _null_ _null_ hashbpcharextended _null_ _null_ _null_ _null_ ) +insert ( 1081 format_type 11 10 12 1 0 0 0 f f f f f s s 2 0 25 '26 23' _null_ _null_ _null_ _null_ _null_ format_type _null_ _null_ _null_ _null_ ) +insert ( 1084 date_in 11 10 12 1 0 0 0 f f f t f s s 1 0 1082 2275 _null_ _null_ _null_ _null_ _null_ date_in _null_ _null_ _null_ _null_ ) +insert ( 1085 date_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 1082 _null_ _null_ _null_ _null_ _null_ date_out _null_ _null_ _null_ _null_ ) +insert ( 1086 date_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_eq _null_ _null_ _null_ _null_ ) +insert ( 1087 date_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_lt _null_ _null_ _null_ _null_ ) +insert ( 1088 date_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_le _null_ _null_ _null_ _null_ ) +insert ( 1089 date_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_gt _null_ _null_ _null_ _null_ ) +insert ( 1090 date_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_ge _null_ _null_ _null_ _null_ ) +insert ( 1091 date_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_ne _null_ _null_ _null_ _null_ ) +insert ( 1092 date_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_cmp _null_ _null_ _null_ _null_ ) +insert ( 3136 date_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ date_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 4133 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '1082 1082 1186 16 16' _null_ _null_ _null_ _null_ _null_ in_range_date_interval _null_ _null_ _null_ _null_ ) +insert ( 1102 time_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_lt _null_ _null_ _null_ _null_ ) +insert ( 1103 time_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_le _null_ _null_ _null_ _null_ ) +insert ( 1104 time_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_gt _null_ _null_ _null_ _null_ ) +insert ( 1105 time_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_ge _null_ _null_ _null_ _null_ ) +insert ( 1106 time_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_ne _null_ _null_ _null_ _null_ ) +insert ( 1107 time_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_cmp _null_ _null_ _null_ _null_ ) +insert ( 1138 date_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 1082 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_larger _null_ _null_ _null_ _null_ ) +insert ( 1139 date_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 1082 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_smaller _null_ _null_ _null_ _null_ ) +insert ( 1140 date_mi 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '1082 1082' _null_ _null_ _null_ _null_ _null_ date_mi _null_ _null_ _null_ _null_ ) +insert ( 1141 date_pli 11 10 12 1 0 0 0 f f f t f i s 2 0 1082 '1082 23' _null_ _null_ _null_ _null_ _null_ date_pli _null_ _null_ _null_ _null_ ) +insert ( 1142 date_mii 11 10 12 1 0 0 0 f f f t f i s 2 0 1082 '1082 23' _null_ _null_ _null_ _null_ _null_ date_mii _null_ _null_ _null_ _null_ ) +insert ( 1143 time_in 11 10 12 1 0 0 0 f f f t f s s 3 0 1083 '2275 26 23' _null_ _null_ _null_ _null_ _null_ time_in _null_ _null_ _null_ _null_ ) +insert ( 1144 time_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 1083 _null_ _null_ _null_ _null_ _null_ time_out _null_ _null_ _null_ _null_ ) +insert ( 2909 timetypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ timetypmodin _null_ _null_ _null_ _null_ ) +insert ( 2910 timetypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ timetypmodout _null_ _null_ _null_ _null_ ) +insert ( 1145 time_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_eq _null_ _null_ _null_ _null_ ) +insert ( 1146 circle_add_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 718 '718 600' _null_ _null_ _null_ _null_ _null_ circle_add_pt _null_ _null_ _null_ _null_ ) +insert ( 1147 circle_sub_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 718 '718 600' _null_ _null_ _null_ _null_ _null_ circle_sub_pt _null_ _null_ _null_ _null_ ) +insert ( 1148 circle_mul_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 718 '718 600' _null_ _null_ _null_ _null_ _null_ circle_mul_pt _null_ _null_ _null_ _null_ ) +insert ( 1149 circle_div_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 718 '718 600' _null_ _null_ _null_ _null_ _null_ circle_div_pt _null_ _null_ _null_ _null_ ) +insert ( 1150 timestamptz_in 11 10 12 1 0 0 0 f f f t f s s 3 0 1184 '2275 26 23' _null_ _null_ _null_ _null_ _null_ timestamptz_in _null_ _null_ _null_ _null_ ) +insert ( 1151 timestamptz_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 1184 _null_ _null_ _null_ _null_ _null_ timestamptz_out _null_ _null_ _null_ _null_ ) +insert ( 2907 timestamptztypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ timestamptztypmodin _null_ _null_ _null_ _null_ ) +insert ( 2908 timestamptztypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ timestamptztypmodout _null_ _null_ _null_ _null_ ) +insert ( 1152 timestamptz_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_eq _null_ _null_ _null_ _null_ ) +insert ( 1153 timestamptz_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_ne _null_ _null_ _null_ _null_ ) +insert ( 1154 timestamptz_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_lt _null_ _null_ _null_ _null_ ) +insert ( 1155 timestamptz_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_le _null_ _null_ _null_ _null_ ) +insert ( 1156 timestamptz_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_ge _null_ _null_ _null_ _null_ ) +insert ( 1157 timestamptz_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_gt _null_ _null_ _null_ _null_ ) +insert ( 1158 to_timestamp 11 10 12 1 0 0 0 f f f t f i s 1 0 1184 701 _null_ _null_ _null_ _null_ _null_ float8_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 1159 timezone 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '25 1184' _null_ _null_ _null_ _null_ _null_ timestamptz_zone _null_ _null_ _null_ _null_ ) +insert ( 1160 interval_in 11 10 12 1 0 0 0 f f f t f s s 3 0 1186 '2275 26 23' _null_ _null_ _null_ _null_ _null_ interval_in _null_ _null_ _null_ _null_ ) +insert ( 1161 interval_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 1186 _null_ _null_ _null_ _null_ _null_ interval_out _null_ _null_ _null_ _null_ ) +insert ( 2903 intervaltypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ intervaltypmodin _null_ _null_ _null_ _null_ ) +insert ( 2904 intervaltypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ intervaltypmodout _null_ _null_ _null_ _null_ ) +insert ( 1162 interval_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_eq _null_ _null_ _null_ _null_ ) +insert ( 1163 interval_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_ne _null_ _null_ _null_ _null_ ) +insert ( 1164 interval_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_lt _null_ _null_ _null_ _null_ ) +insert ( 1165 interval_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_le _null_ _null_ _null_ _null_ ) +insert ( 1166 interval_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_ge _null_ _null_ _null_ _null_ ) +insert ( 1167 interval_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_gt _null_ _null_ _null_ _null_ ) +insert ( 1168 interval_um 11 10 12 1 0 0 0 f f f t f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ interval_um _null_ _null_ _null_ _null_ ) +insert ( 1169 interval_pl 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_pl _null_ _null_ _null_ _null_ ) +insert ( 1170 interval_mi 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_mi _null_ _null_ _null_ _null_ ) +insert ( 1171 date_part 11 10 12 1 0 0 0 f f f t f s s 2 0 701 '25 1184' _null_ _null_ _null_ _null_ _null_ timestamptz_part _null_ _null_ _null_ _null_ ) +insert ( 6203 extract 11 10 12 1 0 0 0 f f f t f s s 2 0 1700 '25 1184' _null_ _null_ _null_ _null_ _null_ extract_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 1172 date_part 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '25 1186' _null_ _null_ _null_ _null_ _null_ interval_part _null_ _null_ _null_ _null_ ) +insert ( 6204 extract 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '25 1186' _null_ _null_ _null_ _null_ _null_ extract_interval _null_ _null_ _null_ _null_ ) +insert ( 1174 timestamptz 11 10 12 1 0 0 0 f f f t f s s 1 0 1184 1082 _null_ _null_ _null_ _null_ _null_ date_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2711 justify_interval 11 10 12 1 0 0 0 f f f t f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ interval_justify_interval _null_ _null_ _null_ _null_ ) +insert ( 1175 justify_hours 11 10 12 1 0 0 0 f f f t f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ interval_justify_hours _null_ _null_ _null_ _null_ ) +insert ( 1295 justify_days 11 10 12 1 0 0 0 f f f t f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ interval_justify_days _null_ _null_ _null_ _null_ ) +insert ( 1176 timestamptz 11 10 14 1 0 0 0 f f f t f s s 2 0 1184 '1082 1083' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1178 date 11 10 12 1 0 0 0 f f f t f s s 1 0 1082 1184 _null_ _null_ _null_ _null_ _null_ timestamptz_date _null_ _null_ _null_ _null_ ) +insert ( 1181 age 11 10 12 1 0 0 0 f f f t f s r 1 0 23 28 _null_ _null_ _null_ _null_ _null_ xid_age _null_ _null_ _null_ _null_ ) +insert ( 3939 mxid_age 11 10 12 1 0 0 0 f f f t f s s 1 0 23 28 _null_ _null_ _null_ _null_ _null_ mxid_age _null_ _null_ _null_ _null_ ) +insert ( 1188 timestamptz_mi 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_mi _null_ _null_ _null_ _null_ ) +insert ( 1189 timestamptz_pl_interval 11 10 12 1 0 0 0 f f f t f s s 2 0 1184 '1184 1186' _null_ _null_ _null_ _null_ _null_ timestamptz_pl_interval _null_ _null_ _null_ _null_ ) +insert ( 6221 date_add 11 10 12 1 0 0 0 f f f t f s s 2 0 1184 '1184 1186' _null_ _null_ _null_ _null_ _null_ timestamptz_pl_interval _null_ _null_ _null_ _null_ ) +insert ( 6222 date_add 11 10 12 1 0 0 0 f f f t f i s 3 0 1184 '1184 1186 25' _null_ _null_ _null_ _null_ _null_ timestamptz_pl_interval_at_zone _null_ _null_ _null_ _null_ ) +insert ( 1190 timestamptz_mi_interval 11 10 12 1 0 0 0 f f f t f s s 2 0 1184 '1184 1186' _null_ _null_ _null_ _null_ _null_ timestamptz_mi_interval _null_ _null_ _null_ _null_ ) +insert ( 6223 date_subtract 11 10 12 1 0 0 0 f f f t f s s 2 0 1184 '1184 1186' _null_ _null_ _null_ _null_ _null_ timestamptz_mi_interval _null_ _null_ _null_ _null_ ) +insert ( 6273 date_subtract 11 10 12 1 0 0 0 f f f t f i s 3 0 1184 '1184 1186 25' _null_ _null_ _null_ _null_ _null_ timestamptz_mi_interval_at_zone _null_ _null_ _null_ _null_ ) +insert ( 1195 timestamptz_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 1184 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_smaller _null_ _null_ _null_ _null_ ) +insert ( 1196 timestamptz_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 1184 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_larger _null_ _null_ _null_ _null_ ) +insert ( 1197 interval_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_smaller _null_ _null_ _null_ _null_ ) +insert ( 1198 interval_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_larger _null_ _null_ _null_ _null_ ) +insert ( 1199 age 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamptz_age _null_ _null_ _null_ _null_ ) +insert ( 3918 interval_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ interval_support _null_ _null_ _null_ _null_ ) +insert ( 1200 interval 11 10 12 1 0 0 3918 f f f t f i s 2 0 1186 '1186 23' _null_ _null_ _null_ _null_ _null_ interval_scale _null_ _null_ _null_ _null_ ) +insert ( 1215 obj_description 11 10 14 100 0 0 0 f f f t f s s 2 0 25 '26 19' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1216 col_description 11 10 14 100 0 0 0 f f f t f s s 2 0 25 '26 23' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1993 shobj_description 11 10 14 100 0 0 0 f f f t f s s 2 0 25 '26 19' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1217 date_trunc 11 10 12 1 0 0 0 f f f t f s s 2 0 1184 '25 1184' _null_ _null_ _null_ _null_ _null_ timestamptz_trunc _null_ _null_ _null_ _null_ ) +insert ( 1284 date_trunc 11 10 12 1 0 0 0 f f f t f i s 3 0 1184 '25 1184 25' _null_ _null_ _null_ _null_ _null_ timestamptz_trunc_zone _null_ _null_ _null_ _null_ ) +insert ( 1218 date_trunc 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '25 1186' _null_ _null_ _null_ _null_ _null_ interval_trunc _null_ _null_ _null_ _null_ ) +insert ( 1219 int8inc 11 10 12 1 0 0 0 f f f t f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ int8inc _null_ _null_ _null_ _null_ ) +insert ( 3546 int8dec 11 10 12 1 0 0 0 f f f t f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ int8dec _null_ _null_ _null_ _null_ ) +insert ( 2804 int8inc_any 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 2276' _null_ _null_ _null_ _null_ _null_ int8inc_any _null_ _null_ _null_ _null_ ) +insert ( 3547 int8dec_any 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 2276' _null_ _null_ _null_ _null_ _null_ int8dec_any _null_ _null_ _null_ _null_ ) +insert ( 1230 int8abs 11 10 12 1 0 0 0 f f f t f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ int8abs _null_ _null_ _null_ _null_ ) +insert ( 1236 int8larger 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8larger _null_ _null_ _null_ _null_ ) +insert ( 1237 int8smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8smaller _null_ _null_ _null_ _null_ ) +insert ( 1238 texticregexeq 11 10 12 1 0 0 1024 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ texticregexeq _null_ _null_ _null_ _null_ ) +insert ( 1024 texticregexeq_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ texticregexeq_support _null_ _null_ _null_ _null_ ) +insert ( 1239 texticregexne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ texticregexne _null_ _null_ _null_ _null_ ) +insert ( 1240 nameicregexeq 11 10 12 1 0 0 1024 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameicregexeq _null_ _null_ _null_ _null_ ) +insert ( 1241 nameicregexne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameicregexne _null_ _null_ _null_ _null_ ) +insert ( 1251 int4abs 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ int4abs _null_ _null_ _null_ _null_ ) +insert ( 1253 int2abs 11 10 12 1 0 0 0 f f f t f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ int2abs _null_ _null_ _null_ _null_ ) +insert ( 1271 overlaps 11 10 12 1 0 0 0 f f f f f i s 4 0 16 '1266 1266 1266 1266' _null_ _null_ _null_ _null_ _null_ overlaps_timetz _null_ _null_ _null_ _null_ ) +insert ( 1272 datetime_pl 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1082 1083' _null_ _null_ _null_ _null_ _null_ datetime_timestamp _null_ _null_ _null_ _null_ ) +insert ( 1273 date_part 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '25 1266' _null_ _null_ _null_ _null_ _null_ timetz_part _null_ _null_ _null_ _null_ ) +insert ( 6201 extract 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '25 1266' _null_ _null_ _null_ _null_ _null_ extract_timetz _null_ _null_ _null_ _null_ ) +insert ( 1274 int84pl 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 23' _null_ _null_ _null_ _null_ _null_ int84pl _null_ _null_ _null_ _null_ ) +insert ( 1275 int84mi 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 23' _null_ _null_ _null_ _null_ _null_ int84mi _null_ _null_ _null_ _null_ ) +insert ( 1276 int84mul 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 23' _null_ _null_ _null_ _null_ _null_ int84mul _null_ _null_ _null_ _null_ ) +insert ( 1277 int84div 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 23' _null_ _null_ _null_ _null_ _null_ int84div _null_ _null_ _null_ _null_ ) +insert ( 1278 int48pl 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '23 20' _null_ _null_ _null_ _null_ _null_ int48pl _null_ _null_ _null_ _null_ ) +insert ( 1279 int48mi 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '23 20' _null_ _null_ _null_ _null_ _null_ int48mi _null_ _null_ _null_ _null_ ) +insert ( 1280 int48mul 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '23 20' _null_ _null_ _null_ _null_ _null_ int48mul _null_ _null_ _null_ _null_ ) +insert ( 1281 int48div 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '23 20' _null_ _null_ _null_ _null_ _null_ int48div _null_ _null_ _null_ _null_ ) +insert ( 837 int82pl 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 21' _null_ _null_ _null_ _null_ _null_ int82pl _null_ _null_ _null_ _null_ ) +insert ( 838 int82mi 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 21' _null_ _null_ _null_ _null_ _null_ int82mi _null_ _null_ _null_ _null_ ) +insert ( 839 int82mul 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 21' _null_ _null_ _null_ _null_ _null_ int82mul _null_ _null_ _null_ _null_ ) +insert ( 840 int82div 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 21' _null_ _null_ _null_ _null_ _null_ int82div _null_ _null_ _null_ _null_ ) +insert ( 841 int28pl 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '21 20' _null_ _null_ _null_ _null_ _null_ int28pl _null_ _null_ _null_ _null_ ) +insert ( 942 int28mi 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '21 20' _null_ _null_ _null_ _null_ _null_ int28mi _null_ _null_ _null_ _null_ ) +insert ( 943 int28mul 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '21 20' _null_ _null_ _null_ _null_ _null_ int28mul _null_ _null_ _null_ _null_ ) +insert ( 948 int28div 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '21 20' _null_ _null_ _null_ _null_ _null_ int28div _null_ _null_ _null_ _null_ ) +insert ( 1287 oid 11 10 12 1 0 0 0 f f f t f i s 1 0 26 20 _null_ _null_ _null_ _null_ _null_ i8tooid _null_ _null_ _null_ _null_ ) +insert ( 1288 int8 11 10 12 1 0 0 0 f f t t f i s 1 0 20 26 _null_ _null_ _null_ _null_ _null_ oidtoi8 _null_ _null_ _null_ _null_ ) +insert ( 1291 suppress_redundant_updates_trigger 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ suppress_redundant_updates_trigger _null_ _null_ _null_ _null_ ) +insert ( 1292 tideq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '27 27' _null_ _null_ _null_ _null_ _null_ tideq _null_ _null_ _null_ _null_ ) +insert ( 1294 currtid2 11 10 12 1 0 0 0 f f f t f v u 2 0 27 '25 27' _null_ _null_ _null_ _null_ _null_ currtid_byrelname _null_ _null_ _null_ _null_ ) +insert ( 1265 tidne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '27 27' _null_ _null_ _null_ _null_ _null_ tidne _null_ _null_ _null_ _null_ ) +insert ( 2790 tidgt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '27 27' _null_ _null_ _null_ _null_ _null_ tidgt _null_ _null_ _null_ _null_ ) +insert ( 2791 tidlt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '27 27' _null_ _null_ _null_ _null_ _null_ tidlt _null_ _null_ _null_ _null_ ) +insert ( 2792 tidge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '27 27' _null_ _null_ _null_ _null_ _null_ tidge _null_ _null_ _null_ _null_ ) +insert ( 2793 tidle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '27 27' _null_ _null_ _null_ _null_ _null_ tidle _null_ _null_ _null_ _null_ ) +insert ( 2794 bttidcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '27 27' _null_ _null_ _null_ _null_ _null_ bttidcmp _null_ _null_ _null_ _null_ ) +insert ( 2795 tidlarger 11 10 12 1 0 0 0 f f f t f i s 2 0 27 '27 27' _null_ _null_ _null_ _null_ _null_ tidlarger _null_ _null_ _null_ _null_ ) +insert ( 2796 tidsmaller 11 10 12 1 0 0 0 f f f t f i s 2 0 27 '27 27' _null_ _null_ _null_ _null_ _null_ tidsmaller _null_ _null_ _null_ _null_ ) +insert ( 2233 hashtid 11 10 12 1 0 0 0 f f f t f i s 1 0 23 27 _null_ _null_ _null_ _null_ _null_ hashtid _null_ _null_ _null_ _null_ ) +insert ( 2234 hashtidextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '27 20' _null_ _null_ _null_ _null_ _null_ hashtidextended _null_ _null_ _null_ _null_ ) +insert ( 1296 timedate_pl 11 10 14 1 0 0 0 f f f t f i s 2 0 1114 '1083 1082' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1297 datetimetz_pl 11 10 12 1 0 0 0 f f f t f i s 2 0 1184 '1082 1266' _null_ _null_ _null_ _null_ _null_ datetimetz_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 1298 timetzdate_pl 11 10 14 1 0 0 0 f f f t f i s 2 0 1184 '1266 1082' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1299 now 11 10 12 1 0 0 0 f f f t f s s 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ now _null_ _null_ _null_ _null_ ) +insert ( 2647 transaction_timestamp 11 10 12 1 0 0 0 f f f t f s s 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ now _null_ _null_ _null_ _null_ ) +insert ( 2648 statement_timestamp 11 10 12 1 0 0 0 f f f t f s s 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ statement_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2649 clock_timestamp 11 10 12 1 0 0 0 f f f t f v s 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ clock_timestamp _null_ _null_ _null_ _null_ ) +insert ( 1300 positionsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ positionsel _null_ _null_ _null_ _null_ ) +insert ( 1301 positionjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ positionjoinsel _null_ _null_ _null_ _null_ ) +insert ( 1302 contsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ contsel _null_ _null_ _null_ _null_ ) +insert ( 1303 contjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ contjoinsel _null_ _null_ _null_ _null_ ) +insert ( 1304 overlaps 11 10 12 1 0 0 0 f f f f f i s 4 0 16 '1184 1184 1184 1184' _null_ _null_ _null_ _null_ _null_ overlaps_timestamp _null_ _null_ _null_ _null_ ) +insert ( 1305 overlaps 11 10 14 1 0 0 0 f f f f f s s 4 0 16 '1184 1186 1184 1186' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1306 overlaps 11 10 14 1 0 0 0 f f f f f s s 4 0 16 '1184 1184 1184 1186' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1307 overlaps 11 10 14 1 0 0 0 f f f f f s s 4 0 16 '1184 1186 1184 1184' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1308 overlaps 11 10 12 1 0 0 0 f f f f f i s 4 0 16 '1083 1083 1083 1083' _null_ _null_ _null_ _null_ _null_ overlaps_time _null_ _null_ _null_ _null_ ) +insert ( 1309 overlaps 11 10 14 1 0 0 0 f f f f f i s 4 0 16 '1083 1186 1083 1186' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1310 overlaps 11 10 14 1 0 0 0 f f f f f i s 4 0 16 '1083 1083 1083 1186' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1311 overlaps 11 10 14 1 0 0 0 f f f f f i s 4 0 16 '1083 1186 1083 1083' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1312 timestamp_in 11 10 12 1 0 0 0 f f f t f s s 3 0 1114 '2275 26 23' _null_ _null_ _null_ _null_ _null_ timestamp_in _null_ _null_ _null_ _null_ ) +insert ( 1313 timestamp_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 1114 _null_ _null_ _null_ _null_ _null_ timestamp_out _null_ _null_ _null_ _null_ ) +insert ( 2905 timestamptypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ timestamptypmodin _null_ _null_ _null_ _null_ ) +insert ( 2906 timestamptypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ timestamptypmodout _null_ _null_ _null_ _null_ ) +insert ( 1314 timestamptz_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1184 1184' _null_ _null_ _null_ _null_ _null_ timestamp_cmp _null_ _null_ _null_ _null_ ) +insert ( 1315 interval_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1186 1186' _null_ _null_ _null_ _null_ _null_ interval_cmp _null_ _null_ _null_ _null_ ) +insert ( 1316 time 11 10 12 1 0 0 0 f f f t f i s 1 0 1083 1114 _null_ _null_ _null_ _null_ _null_ timestamp_time _null_ _null_ _null_ _null_ ) +insert ( 1317 length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ textlen _null_ _null_ _null_ _null_ ) +insert ( 1318 length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1042 _null_ _null_ _null_ _null_ _null_ bpcharlen _null_ _null_ _null_ _null_ ) +insert ( 1319 xideqint4 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '28 23' _null_ _null_ _null_ _null_ _null_ xideq _null_ _null_ _null_ _null_ ) +insert ( 3309 xidneqint4 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '28 23' _null_ _null_ _null_ _null_ _null_ xidneq _null_ _null_ _null_ _null_ ) +insert ( 1326 interval_div 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1186 701' _null_ _null_ _null_ _null_ _null_ interval_div _null_ _null_ _null_ _null_ ) +insert ( 1339 dlog10 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dlog10 _null_ _null_ _null_ _null_ ) +insert ( 1340 log 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dlog10 _null_ _null_ _null_ _null_ ) +insert ( 1194 log10 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dlog10 _null_ _null_ _null_ _null_ ) +insert ( 1341 ln 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dlog1 _null_ _null_ _null_ _null_ ) +insert ( 1342 round 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dround _null_ _null_ _null_ _null_ ) +insert ( 1343 trunc 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dtrunc _null_ _null_ _null_ _null_ ) +insert ( 1344 sqrt 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dsqrt _null_ _null_ _null_ _null_ ) +insert ( 1345 cbrt 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dcbrt _null_ _null_ _null_ _null_ ) +insert ( 1346 pow 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ dpow _null_ _null_ _null_ _null_ ) +insert ( 1368 power 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ dpow _null_ _null_ _null_ _null_ ) +insert ( 1347 exp 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dexp _null_ _null_ _null_ _null_ ) +insert ( 1348 obj_description 11 10 14 100 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1349 oidvectortypes 11 10 12 1 0 0 0 f f f t f s s 1 0 25 30 _null_ _null_ _null_ _null_ _null_ oidvectortypes _null_ _null_ _null_ _null_ ) +insert ( 1350 timetz_in 11 10 12 1 0 0 0 f f f t f s s 3 0 1266 '2275 26 23' _null_ _null_ _null_ _null_ _null_ timetz_in _null_ _null_ _null_ _null_ ) +insert ( 1351 timetz_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 1266 _null_ _null_ _null_ _null_ _null_ timetz_out _null_ _null_ _null_ _null_ ) +insert ( 2911 timetztypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ timetztypmodin _null_ _null_ _null_ _null_ ) +insert ( 2912 timetztypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ timetztypmodout _null_ _null_ _null_ _null_ ) +insert ( 1352 timetz_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_eq _null_ _null_ _null_ _null_ ) +insert ( 1353 timetz_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_ne _null_ _null_ _null_ _null_ ) +insert ( 1354 timetz_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_lt _null_ _null_ _null_ _null_ ) +insert ( 1355 timetz_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_le _null_ _null_ _null_ _null_ ) +insert ( 1356 timetz_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_ge _null_ _null_ _null_ _null_ ) +insert ( 1357 timetz_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_gt _null_ _null_ _null_ _null_ ) +insert ( 1358 timetz_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_cmp _null_ _null_ _null_ _null_ ) +insert ( 1359 timestamptz 11 10 12 1 0 0 0 f f f t f i s 2 0 1184 '1082 1266' _null_ _null_ _null_ _null_ _null_ datetimetz_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 1367 character_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1042 _null_ _null_ _null_ _null_ _null_ bpcharlen _null_ _null_ _null_ _null_ ) +insert ( 1369 character_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ textlen _null_ _null_ _null_ _null_ ) +insert ( 1370 interval 11 10 12 1 0 0 0 f f t t f i s 1 0 1186 1083 _null_ _null_ _null_ _null_ _null_ time_interval _null_ _null_ _null_ _null_ ) +insert ( 1372 char_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1042 _null_ _null_ _null_ _null_ _null_ bpcharlen _null_ _null_ _null_ _null_ ) +insert ( 1374 octet_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ textoctetlen _null_ _null_ _null_ _null_ ) +insert ( 1375 octet_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1042 _null_ _null_ _null_ _null_ _null_ bpcharoctetlen _null_ _null_ _null_ _null_ ) +insert ( 1377 time_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 1083 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_larger _null_ _null_ _null_ _null_ ) +insert ( 1378 time_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 1083 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_smaller _null_ _null_ _null_ _null_ ) +insert ( 1379 timetz_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 1266 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_larger _null_ _null_ _null_ _null_ ) +insert ( 1380 timetz_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 1266 '1266 1266' _null_ _null_ _null_ _null_ _null_ timetz_smaller _null_ _null_ _null_ _null_ ) +insert ( 1381 char_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ textlen _null_ _null_ _null_ _null_ ) +insert ( 1384 date_part 11 10 14 1 0 0 0 f f f t f i s 2 0 701 '25 1082' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 6199 extract 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '25 1082' _null_ _null_ _null_ _null_ _null_ extract_date _null_ _null_ _null_ _null_ ) +insert ( 1385 date_part 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '25 1083' _null_ _null_ _null_ _null_ _null_ time_part _null_ _null_ _null_ _null_ ) +insert ( 6200 extract 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '25 1083' _null_ _null_ _null_ _null_ _null_ extract_time _null_ _null_ _null_ _null_ ) +insert ( 1386 age 11 10 14 1 0 0 0 f f f t f s s 1 0 1186 1184 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1388 timetz 11 10 12 1 0 0 0 f f f t f s s 1 0 1266 1184 _null_ _null_ _null_ _null_ _null_ timestamptz_timetz _null_ _null_ _null_ _null_ ) +insert ( 1373 isfinite 11 10 12 1 0 0 0 f f f t f i s 1 0 16 1082 _null_ _null_ _null_ _null_ _null_ date_finite _null_ _null_ _null_ _null_ ) +insert ( 1389 isfinite 11 10 12 1 0 0 0 f f f t f i s 1 0 16 1184 _null_ _null_ _null_ _null_ _null_ timestamp_finite _null_ _null_ _null_ _null_ ) +insert ( 1390 isfinite 11 10 12 1 0 0 0 f f f t f i s 1 0 16 1186 _null_ _null_ _null_ _null_ _null_ interval_finite _null_ _null_ _null_ _null_ ) +insert ( 1376 factorial 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ numeric_fac _null_ _null_ _null_ _null_ ) +insert ( 1394 abs 11 10 12 1 0 0 0 f f f t f i s 1 0 700 700 _null_ _null_ _null_ _null_ _null_ float4abs _null_ _null_ _null_ _null_ ) +insert ( 1395 abs 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ float8abs _null_ _null_ _null_ _null_ ) +insert ( 1396 abs 11 10 12 1 0 0 0 f f f t f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ int8abs _null_ _null_ _null_ _null_ ) +insert ( 1397 abs 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ int4abs _null_ _null_ _null_ _null_ ) +insert ( 1398 abs 11 10 12 1 0 0 0 f f f t f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ int2abs _null_ _null_ _null_ _null_ ) +insert ( 1400 name 11 10 12 1 0 0 0 f f t t f i s 1 0 19 1043 _null_ _null_ _null_ _null_ _null_ text_name _null_ _null_ _null_ _null_ ) +insert ( 1401 varchar 11 10 12 1 0 0 0 f f t t f i s 1 0 1043 19 _null_ _null_ _null_ _null_ _null_ name_text _null_ _null_ _null_ _null_ ) +insert ( 1402 current_schema 11 10 12 1 0 0 0 f f f t f s u 0 0 19 '' _null_ _null_ _null_ _null_ _null_ current_schema _null_ _null_ _null_ _null_ ) +insert ( 1403 current_schemas 11 10 12 1 0 0 0 f f f t f s u 1 0 1003 16 _null_ _null_ _null_ _null_ _null_ current_schemas _null_ _null_ _null_ _null_ ) +insert ( 1404 overlay 11 10 12 1 0 0 0 f f f t f i s 4 0 25 '25 25 23 23' _null_ _null_ _null_ _null_ _null_ textoverlay _null_ _null_ _null_ _null_ ) +insert ( 1405 overlay 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 25 23' _null_ _null_ _null_ _null_ _null_ textoverlay_no_len _null_ _null_ _null_ _null_ ) +insert ( 1406 isvertical 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_vert _null_ _null_ _null_ _null_ ) +insert ( 1407 ishorizontal 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 600' _null_ _null_ _null_ _null_ _null_ point_horiz _null_ _null_ _null_ _null_ ) +insert ( 1408 isparallel 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_parallel _null_ _null_ _null_ _null_ ) +insert ( 1409 isperp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_perp _null_ _null_ _null_ _null_ ) +insert ( 1410 isvertical 11 10 12 1 0 0 0 f f f t f i s 1 0 16 601 _null_ _null_ _null_ _null_ _null_ lseg_vertical _null_ _null_ _null_ _null_ ) +insert ( 1411 ishorizontal 11 10 12 1 0 0 0 f f f t f i s 1 0 16 601 _null_ _null_ _null_ _null_ _null_ lseg_horizontal _null_ _null_ _null_ _null_ ) +insert ( 1412 isparallel 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '628 628' _null_ _null_ _null_ _null_ _null_ line_parallel _null_ _null_ _null_ _null_ ) +insert ( 1413 isperp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '628 628' _null_ _null_ _null_ _null_ _null_ line_perp _null_ _null_ _null_ _null_ ) +insert ( 1414 isvertical 11 10 12 1 0 0 0 f f f t f i s 1 0 16 628 _null_ _null_ _null_ _null_ _null_ line_vertical _null_ _null_ _null_ _null_ ) +insert ( 1415 ishorizontal 11 10 12 1 0 0 0 f f f t f i s 1 0 16 628 _null_ _null_ _null_ _null_ _null_ line_horizontal _null_ _null_ _null_ _null_ ) +insert ( 1416 point 11 10 12 1 0 0 0 f f f t f i s 1 0 600 718 _null_ _null_ _null_ _null_ _null_ circle_center _null_ _null_ _null_ _null_ ) +insert ( 1419 time 11 10 12 1 0 0 0 f f f t f i s 1 0 1083 1186 _null_ _null_ _null_ _null_ _null_ interval_time _null_ _null_ _null_ _null_ ) +insert ( 1421 box 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '600 600' _null_ _null_ _null_ _null_ _null_ points_box _null_ _null_ _null_ _null_ ) +insert ( 1422 box_add 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '603 600' _null_ _null_ _null_ _null_ _null_ box_add _null_ _null_ _null_ _null_ ) +insert ( 1423 box_sub 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '603 600' _null_ _null_ _null_ _null_ _null_ box_sub _null_ _null_ _null_ _null_ ) +insert ( 1424 box_mul 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '603 600' _null_ _null_ _null_ _null_ _null_ box_mul _null_ _null_ _null_ _null_ ) +insert ( 1425 box_div 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '603 600' _null_ _null_ _null_ _null_ _null_ box_div _null_ _null_ _null_ _null_ ) +insert ( 1426 path_contain_pt 11 10 14 1 0 0 0 f f f t f i s 2 0 16 '602 600' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1428 poly_contain_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 600' _null_ _null_ _null_ _null_ _null_ poly_contain_pt _null_ _null_ _null_ _null_ ) +insert ( 1429 pt_contained_poly 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 604' _null_ _null_ _null_ _null_ _null_ pt_contained_poly _null_ _null_ _null_ _null_ ) +insert ( 1430 isclosed 11 10 12 1 0 0 0 f f f t f i s 1 0 16 602 _null_ _null_ _null_ _null_ _null_ path_isclosed _null_ _null_ _null_ _null_ ) +insert ( 1431 isopen 11 10 12 1 0 0 0 f f f t f i s 1 0 16 602 _null_ _null_ _null_ _null_ _null_ path_isopen _null_ _null_ _null_ _null_ ) +insert ( 1432 path_npoints 11 10 12 1 0 0 0 f f f t f i s 1 0 23 602 _null_ _null_ _null_ _null_ _null_ path_npoints _null_ _null_ _null_ _null_ ) +insert ( 1433 pclose 11 10 12 1 0 0 0 f f f t f i s 1 0 602 602 _null_ _null_ _null_ _null_ _null_ path_close _null_ _null_ _null_ _null_ ) +insert ( 1434 popen 11 10 12 1 0 0 0 f f f t f i s 1 0 602 602 _null_ _null_ _null_ _null_ _null_ path_open _null_ _null_ _null_ _null_ ) +insert ( 1435 path_add 11 10 12 1 0 0 0 f f f t f i s 2 0 602 '602 602' _null_ _null_ _null_ _null_ _null_ path_add _null_ _null_ _null_ _null_ ) +insert ( 1436 path_add_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 602 '602 600' _null_ _null_ _null_ _null_ _null_ path_add_pt _null_ _null_ _null_ _null_ ) +insert ( 1437 path_sub_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 602 '602 600' _null_ _null_ _null_ _null_ _null_ path_sub_pt _null_ _null_ _null_ _null_ ) +insert ( 1438 path_mul_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 602 '602 600' _null_ _null_ _null_ _null_ _null_ path_mul_pt _null_ _null_ _null_ _null_ ) +insert ( 1439 path_div_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 602 '602 600' _null_ _null_ _null_ _null_ _null_ path_div_pt _null_ _null_ _null_ _null_ ) +insert ( 1440 point 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '701 701' _null_ _null_ _null_ _null_ _null_ construct_point _null_ _null_ _null_ _null_ ) +insert ( 1441 point_add 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '600 600' _null_ _null_ _null_ _null_ _null_ point_add _null_ _null_ _null_ _null_ ) +insert ( 1442 point_sub 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '600 600' _null_ _null_ _null_ _null_ _null_ point_sub _null_ _null_ _null_ _null_ ) +insert ( 1443 point_mul 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '600 600' _null_ _null_ _null_ _null_ _null_ point_mul _null_ _null_ _null_ _null_ ) +insert ( 1444 point_div 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '600 600' _null_ _null_ _null_ _null_ _null_ point_div _null_ _null_ _null_ _null_ ) +insert ( 1445 poly_npoints 11 10 12 1 0 0 0 f f f t f i s 1 0 23 604 _null_ _null_ _null_ _null_ _null_ poly_npoints _null_ _null_ _null_ _null_ ) +insert ( 1446 box 11 10 12 1 0 0 0 f f f t f i s 1 0 603 604 _null_ _null_ _null_ _null_ _null_ poly_box _null_ _null_ _null_ _null_ ) +insert ( 1447 path 11 10 12 1 0 0 0 f f f t f i s 1 0 602 604 _null_ _null_ _null_ _null_ _null_ poly_path _null_ _null_ _null_ _null_ ) +insert ( 1448 polygon 11 10 12 1 0 0 0 f f f t f i s 1 0 604 603 _null_ _null_ _null_ _null_ _null_ box_poly _null_ _null_ _null_ _null_ ) +insert ( 1449 polygon 11 10 12 1 0 0 0 f f f t f i s 1 0 604 602 _null_ _null_ _null_ _null_ _null_ path_poly _null_ _null_ _null_ _null_ ) +insert ( 1450 circle_in 11 10 12 1 0 0 0 f f f t f i s 1 0 718 2275 _null_ _null_ _null_ _null_ _null_ circle_in _null_ _null_ _null_ _null_ ) +insert ( 1451 circle_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 718 _null_ _null_ _null_ _null_ _null_ circle_out _null_ _null_ _null_ _null_ ) +insert ( 1452 circle_same 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_same _null_ _null_ _null_ _null_ ) +insert ( 1453 circle_contain 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_contain _null_ _null_ _null_ _null_ ) +insert ( 1454 circle_left 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_left _null_ _null_ _null_ _null_ ) +insert ( 1455 circle_overleft 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_overleft _null_ _null_ _null_ _null_ ) +insert ( 1456 circle_overright 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_overright _null_ _null_ _null_ _null_ ) +insert ( 1457 circle_right 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_right _null_ _null_ _null_ _null_ ) +insert ( 1458 circle_contained 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_contained _null_ _null_ _null_ _null_ ) +insert ( 1459 circle_overlap 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_overlap _null_ _null_ _null_ _null_ ) +insert ( 1460 circle_below 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_below _null_ _null_ _null_ _null_ ) +insert ( 1461 circle_above 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_above _null_ _null_ _null_ _null_ ) +insert ( 1462 circle_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_eq _null_ _null_ _null_ _null_ ) +insert ( 1463 circle_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_ne _null_ _null_ _null_ _null_ ) +insert ( 1464 circle_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_lt _null_ _null_ _null_ _null_ ) +insert ( 1465 circle_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_gt _null_ _null_ _null_ _null_ ) +insert ( 1466 circle_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_le _null_ _null_ _null_ _null_ ) +insert ( 1467 circle_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_ge _null_ _null_ _null_ _null_ ) +insert ( 1468 area 11 10 12 1 0 0 0 f f f t f i s 1 0 701 718 _null_ _null_ _null_ _null_ _null_ circle_area _null_ _null_ _null_ _null_ ) +insert ( 1469 diameter 11 10 12 1 0 0 0 f f f t f i s 1 0 701 718 _null_ _null_ _null_ _null_ _null_ circle_diameter _null_ _null_ _null_ _null_ ) +insert ( 1470 radius 11 10 12 1 0 0 0 f f f t f i s 1 0 701 718 _null_ _null_ _null_ _null_ _null_ circle_radius _null_ _null_ _null_ _null_ ) +insert ( 1471 circle_distance 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '718 718' _null_ _null_ _null_ _null_ _null_ circle_distance _null_ _null_ _null_ _null_ ) +insert ( 1472 circle_center 11 10 12 1 0 0 0 f f f t f i s 1 0 600 718 _null_ _null_ _null_ _null_ _null_ circle_center _null_ _null_ _null_ _null_ ) +insert ( 1473 circle 11 10 12 1 0 0 0 f f f t f i s 2 0 718 '600 701' _null_ _null_ _null_ _null_ _null_ cr_circle _null_ _null_ _null_ _null_ ) +insert ( 1474 circle 11 10 12 1 0 0 0 f f f t f i s 1 0 718 604 _null_ _null_ _null_ _null_ _null_ poly_circle _null_ _null_ _null_ _null_ ) +insert ( 1475 polygon 11 10 12 1 0 0 0 f f f t f i s 2 0 604 '23 718' _null_ _null_ _null_ _null_ _null_ circle_poly _null_ _null_ _null_ _null_ ) +insert ( 1476 dist_pc 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '600 718' _null_ _null_ _null_ _null_ _null_ dist_pc _null_ _null_ _null_ _null_ ) +insert ( 1477 circle_contain_pt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 600' _null_ _null_ _null_ _null_ _null_ circle_contain_pt _null_ _null_ _null_ _null_ ) +insert ( 1478 pt_contained_circle 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '600 718' _null_ _null_ _null_ _null_ _null_ pt_contained_circle _null_ _null_ _null_ _null_ ) +insert ( 4091 box 11 10 12 1 0 0 0 f f f t f i s 1 0 603 600 _null_ _null_ _null_ _null_ _null_ point_box _null_ _null_ _null_ _null_ ) +insert ( 1479 circle 11 10 12 1 0 0 0 f f f t f i s 1 0 718 603 _null_ _null_ _null_ _null_ _null_ box_circle _null_ _null_ _null_ _null_ ) +insert ( 1480 box 11 10 12 1 0 0 0 f f f t f i s 1 0 603 718 _null_ _null_ _null_ _null_ _null_ circle_box _null_ _null_ _null_ _null_ ) +insert ( 1482 lseg_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_ne _null_ _null_ _null_ _null_ ) +insert ( 1483 lseg_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_lt _null_ _null_ _null_ _null_ ) +insert ( 1484 lseg_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_le _null_ _null_ _null_ _null_ ) +insert ( 1485 lseg_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_gt _null_ _null_ _null_ _null_ ) +insert ( 1486 lseg_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '601 601' _null_ _null_ _null_ _null_ _null_ lseg_ge _null_ _null_ _null_ _null_ ) +insert ( 1487 lseg_length 11 10 12 1 0 0 0 f f f t f i s 1 0 701 601 _null_ _null_ _null_ _null_ _null_ lseg_length _null_ _null_ _null_ _null_ ) +insert ( 1488 close_ls 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '628 601' _null_ _null_ _null_ _null_ _null_ close_ls _null_ _null_ _null_ _null_ ) +insert ( 1489 close_lseg 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '601 601' _null_ _null_ _null_ _null_ _null_ close_lseg _null_ _null_ _null_ _null_ ) +insert ( 1490 line_in 11 10 12 1 0 0 0 f f f t f i s 1 0 628 2275 _null_ _null_ _null_ _null_ _null_ line_in _null_ _null_ _null_ _null_ ) +insert ( 1491 line_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 628 _null_ _null_ _null_ _null_ _null_ line_out _null_ _null_ _null_ _null_ ) +insert ( 1492 line_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '628 628' _null_ _null_ _null_ _null_ _null_ line_eq _null_ _null_ _null_ _null_ ) +insert ( 1493 line 11 10 12 1 0 0 0 f f f t f i s 2 0 628 '600 600' _null_ _null_ _null_ _null_ _null_ line_construct_pp _null_ _null_ _null_ _null_ ) +insert ( 1494 line_interpt 11 10 12 1 0 0 0 f f f t f i s 2 0 600 '628 628' _null_ _null_ _null_ _null_ _null_ line_interpt _null_ _null_ _null_ _null_ ) +insert ( 1495 line_intersect 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '628 628' _null_ _null_ _null_ _null_ _null_ line_intersect _null_ _null_ _null_ _null_ ) +insert ( 1496 line_parallel 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '628 628' _null_ _null_ _null_ _null_ _null_ line_parallel _null_ _null_ _null_ _null_ ) +insert ( 1497 line_perp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '628 628' _null_ _null_ _null_ _null_ _null_ line_perp _null_ _null_ _null_ _null_ ) +insert ( 1498 line_vertical 11 10 12 1 0 0 0 f f f t f i s 1 0 16 628 _null_ _null_ _null_ _null_ _null_ line_vertical _null_ _null_ _null_ _null_ ) +insert ( 1499 line_horizontal 11 10 12 1 0 0 0 f f f t f i s 1 0 16 628 _null_ _null_ _null_ _null_ _null_ line_horizontal _null_ _null_ _null_ _null_ ) +insert ( 1530 length 11 10 12 1 0 0 0 f f f t f i s 1 0 701 601 _null_ _null_ _null_ _null_ _null_ lseg_length _null_ _null_ _null_ _null_ ) +insert ( 1531 length 11 10 12 1 0 0 0 f f f t f i s 1 0 701 602 _null_ _null_ _null_ _null_ _null_ path_length _null_ _null_ _null_ _null_ ) +insert ( 1532 point 11 10 12 1 0 0 0 f f f t f i s 1 0 600 601 _null_ _null_ _null_ _null_ _null_ lseg_center _null_ _null_ _null_ _null_ ) +insert ( 1534 point 11 10 12 1 0 0 0 f f f t f i s 1 0 600 603 _null_ _null_ _null_ _null_ _null_ box_center _null_ _null_ _null_ _null_ ) +insert ( 1540 point 11 10 12 1 0 0 0 f f f t f i s 1 0 600 604 _null_ _null_ _null_ _null_ _null_ poly_center _null_ _null_ _null_ _null_ ) +insert ( 1541 lseg 11 10 12 1 0 0 0 f f f t f i s 1 0 601 603 _null_ _null_ _null_ _null_ _null_ box_diagonal _null_ _null_ _null_ _null_ ) +insert ( 1542 center 11 10 12 1 0 0 0 f f f t f i s 1 0 600 603 _null_ _null_ _null_ _null_ _null_ box_center _null_ _null_ _null_ _null_ ) +insert ( 1543 center 11 10 12 1 0 0 0 f f f t f i s 1 0 600 718 _null_ _null_ _null_ _null_ _null_ circle_center _null_ _null_ _null_ _null_ ) +insert ( 1544 polygon 11 10 14 1 0 0 0 f f f t f i s 1 0 604 718 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1545 npoints 11 10 12 1 0 0 0 f f f t f i s 1 0 23 602 _null_ _null_ _null_ _null_ _null_ path_npoints _null_ _null_ _null_ _null_ ) +insert ( 1556 npoints 11 10 12 1 0 0 0 f f f t f i s 1 0 23 604 _null_ _null_ _null_ _null_ _null_ poly_npoints _null_ _null_ _null_ _null_ ) +insert ( 1564 bit_in 11 10 12 1 0 0 0 f f f t f i s 3 0 1560 '2275 26 23' _null_ _null_ _null_ _null_ _null_ bit_in _null_ _null_ _null_ _null_ ) +insert ( 1565 bit_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 1560 _null_ _null_ _null_ _null_ _null_ bit_out _null_ _null_ _null_ _null_ ) +insert ( 2919 bittypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ bittypmodin _null_ _null_ _null_ _null_ ) +insert ( 2920 bittypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ bittypmodout _null_ _null_ _null_ _null_ ) +insert ( 1569 like 11 10 12 1 0 0 1023 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ textlike _null_ _null_ _null_ _null_ ) +insert ( 1570 notlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ textnlike _null_ _null_ _null_ _null_ ) +insert ( 1571 like 11 10 12 1 0 0 1023 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namelike _null_ _null_ _null_ _null_ ) +insert ( 1572 notlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ namenlike _null_ _null_ _null_ _null_ ) +insert ( 1574 nextval 11 10 12 1 0 0 0 f f f t f v u 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ nextval_oid _null_ _null_ _null_ _null_ ) +insert ( 1575 currval 11 10 12 1 0 0 0 f f f t f v u 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ currval_oid _null_ _null_ _null_ _null_ ) +insert ( 1576 setval 11 10 12 1 0 0 0 f f f t f v u 2 0 20 '2205 20' _null_ _null_ _null_ _null_ _null_ setval_oid _null_ _null_ _null_ _null_ ) +insert ( 1765 setval 11 10 12 1 0 0 0 f f f t f v u 3 0 20 '2205 20 16' _null_ _null_ _null_ _null_ _null_ setval3_oid _null_ _null_ _null_ _null_ ) +insert ( 3078 pg_sequence_parameters 11 10 12 1 0 0 0 f f f t f s s 1 0 2249 26 '{26,20,20,20,20,16,20,26}' '{i,o,o,o,o,o,o,o}' '{sequence_oid,start_value,minimum_value,maximum_value,increment,cycle_option,cache_size,data_type}' _null_ _null_ pg_sequence_parameters _null_ _null_ _null_ _null_ ) +insert ( 4032 pg_sequence_last_value 11 10 12 1 0 0 0 f f f t f v u 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ pg_sequence_last_value _null_ _null_ _null_ _null_ ) +insert ( 275 pg_nextoid 11 10 12 1 0 0 0 f f f t f v u 3 0 26 '2205 19 2205' _null_ _null_ _null_ _null_ _null_ pg_nextoid _null_ _null_ _null_ _null_ ) +insert ( 6241 pg_stop_making_pinned_objects 11 10 12 1 0 0 0 f f f t f v u 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_stop_making_pinned_objects _null_ _null_ _null_ _null_ ) +insert ( 1579 varbit_in 11 10 12 1 0 0 0 f f f t f i s 3 0 1562 '2275 26 23' _null_ _null_ _null_ _null_ _null_ varbit_in _null_ _null_ _null_ _null_ ) +insert ( 1580 varbit_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 1562 _null_ _null_ _null_ _null_ _null_ varbit_out _null_ _null_ _null_ _null_ ) +insert ( 2902 varbittypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ varbittypmodin _null_ _null_ _null_ _null_ ) +insert ( 2921 varbittypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ varbittypmodout _null_ _null_ _null_ _null_ ) +insert ( 1581 biteq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1560 1560' _null_ _null_ _null_ _null_ _null_ biteq _null_ _null_ _null_ _null_ ) +insert ( 1582 bitne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitne _null_ _null_ _null_ _null_ ) +insert ( 1592 bitge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitge _null_ _null_ _null_ _null_ ) +insert ( 1593 bitgt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitgt _null_ _null_ _null_ _null_ ) +insert ( 1594 bitle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitle _null_ _null_ _null_ _null_ ) +insert ( 1595 bitlt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitlt _null_ _null_ _null_ _null_ ) +insert ( 1596 bitcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitcmp _null_ _null_ _null_ _null_ ) +insert ( 1598 random 11 10 12 1 0 0 0 f f f t f v r 0 0 701 '' _null_ _null_ _null_ _null_ _null_ drandom _null_ _null_ _null_ _null_ ) +insert ( 6212 random_normal 11 10 12 1 0 0 0 f f f t f v r 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ drandom_normal _null_ _null_ _null_ _null_ ) +insert ( 1599 setseed 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 701 _null_ _null_ _null_ _null_ _null_ setseed _null_ _null_ _null_ _null_ ) +insert ( 1600 asin 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dasin _null_ _null_ _null_ _null_ ) +insert ( 1601 acos 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dacos _null_ _null_ _null_ _null_ ) +insert ( 1602 atan 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ datan _null_ _null_ _null_ _null_ ) +insert ( 1603 atan2 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ datan2 _null_ _null_ _null_ _null_ ) +insert ( 1604 sin 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dsin _null_ _null_ _null_ _null_ ) +insert ( 1605 cos 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dcos _null_ _null_ _null_ _null_ ) +insert ( 1606 tan 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dtan _null_ _null_ _null_ _null_ ) +insert ( 1607 cot 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dcot _null_ _null_ _null_ _null_ ) +insert ( 2731 asind 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dasind _null_ _null_ _null_ _null_ ) +insert ( 2732 acosd 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dacosd _null_ _null_ _null_ _null_ ) +insert ( 2733 atand 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ datand _null_ _null_ _null_ _null_ ) +insert ( 2734 atan2d 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ datan2d _null_ _null_ _null_ _null_ ) +insert ( 2735 sind 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dsind _null_ _null_ _null_ _null_ ) +insert ( 2736 cosd 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dcosd _null_ _null_ _null_ _null_ ) +insert ( 2737 tand 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dtand _null_ _null_ _null_ _null_ ) +insert ( 2738 cotd 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dcotd _null_ _null_ _null_ _null_ ) +insert ( 1608 degrees 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ degrees _null_ _null_ _null_ _null_ ) +insert ( 1609 radians 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ radians _null_ _null_ _null_ _null_ ) +insert ( 1610 pi 11 10 12 1 0 0 0 f f f t f i s 0 0 701 '' _null_ _null_ _null_ _null_ _null_ dpi _null_ _null_ _null_ _null_ ) +insert ( 2462 sinh 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dsinh _null_ _null_ _null_ _null_ ) +insert ( 2463 cosh 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dcosh _null_ _null_ _null_ _null_ ) +insert ( 2464 tanh 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dtanh _null_ _null_ _null_ _null_ ) +insert ( 2465 asinh 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dasinh _null_ _null_ _null_ _null_ ) +insert ( 2466 acosh 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ dacosh _null_ _null_ _null_ _null_ ) +insert ( 2467 atanh 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ datanh _null_ _null_ _null_ _null_ ) +insert ( 6219 erf 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ derf _null_ _null_ _null_ _null_ ) +insert ( 6220 erfc 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ derfc _null_ _null_ _null_ _null_ ) +insert ( 1618 interval_mul 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1186 701' _null_ _null_ _null_ _null_ _null_ interval_mul _null_ _null_ _null_ _null_ ) +insert ( 1620 ascii 11 10 12 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ ascii _null_ _null_ _null_ _null_ ) +insert ( 1621 chr 11 10 12 1 0 0 0 f f f t f i s 1 0 25 23 _null_ _null_ _null_ _null_ _null_ chr _null_ _null_ _null_ _null_ ) +insert ( 1622 repeat 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ repeat _null_ _null_ _null_ _null_ ) +insert ( 1623 similar_escape 11 10 12 1 0 0 0 f f f f f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ similar_escape _null_ _null_ _null_ _null_ ) +insert ( 1986 similar_to_escape 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ similar_to_escape_2 _null_ _null_ _null_ _null_ ) +insert ( 1987 similar_to_escape 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ similar_to_escape_1 _null_ _null_ _null_ _null_ ) +insert ( 1624 mul_d_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '701 1186' _null_ _null_ _null_ _null_ _null_ mul_d_interval _null_ _null_ _null_ _null_ ) +insert ( 1631 bpcharlike 11 10 12 1 0 0 1023 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ textlike _null_ _null_ _null_ _null_ ) +insert ( 1632 bpcharnlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ textnlike _null_ _null_ _null_ _null_ ) +insert ( 1633 texticlike 11 10 12 1 0 0 1025 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ texticlike _null_ _null_ _null_ _null_ ) +insert ( 1025 texticlike_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ texticlike_support _null_ _null_ _null_ _null_ ) +insert ( 1634 texticnlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ texticnlike _null_ _null_ _null_ _null_ ) +insert ( 1635 nameiclike 11 10 12 1 0 0 1025 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameiclike _null_ _null_ _null_ _null_ ) +insert ( 1636 nameicnlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ nameicnlike _null_ _null_ _null_ _null_ ) +insert ( 1637 like_escape 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ like_escape _null_ _null_ _null_ _null_ ) +insert ( 1656 bpcharicregexeq 11 10 12 1 0 0 1024 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ texticregexeq _null_ _null_ _null_ _null_ ) +insert ( 1657 bpcharicregexne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ texticregexne _null_ _null_ _null_ _null_ ) +insert ( 1658 bpcharregexeq 11 10 12 1 0 0 1364 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ textregexeq _null_ _null_ _null_ _null_ ) +insert ( 1659 bpcharregexne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ textregexne _null_ _null_ _null_ _null_ ) +insert ( 1660 bpchariclike 11 10 12 1 0 0 1025 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ texticlike _null_ _null_ _null_ _null_ ) +insert ( 1661 bpcharicnlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1042 25' _null_ _null_ _null_ _null_ _null_ texticnlike _null_ _null_ _null_ _null_ ) +insert ( 868 strpos 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ textpos _null_ _null_ _null_ _null_ ) +insert ( 870 lower 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ lower _null_ _null_ _null_ _null_ ) +insert ( 871 upper 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ upper _null_ _null_ _null_ _null_ ) +insert ( 872 initcap 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ initcap _null_ _null_ _null_ _null_ ) +insert ( 873 lpad 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 23 25' _null_ _null_ _null_ _null_ _null_ lpad _null_ _null_ _null_ _null_ ) +insert ( 874 rpad 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 23 25' _null_ _null_ _null_ _null_ _null_ rpad _null_ _null_ _null_ _null_ ) +insert ( 875 ltrim 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ ltrim _null_ _null_ _null_ _null_ ) +insert ( 876 rtrim 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ rtrim _null_ _null_ _null_ _null_ ) +insert ( 877 substr 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 23 23' _null_ _null_ _null_ _null_ _null_ text_substr _null_ _null_ _null_ _null_ ) +insert ( 878 translate 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 25 25' _null_ _null_ _null_ _null_ _null_ translate _null_ _null_ _null_ _null_ ) +insert ( 879 lpad 11 10 14 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 880 rpad 11 10 14 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 881 ltrim 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ ltrim1 _null_ _null_ _null_ _null_ ) +insert ( 882 rtrim 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ rtrim1 _null_ _null_ _null_ _null_ ) +insert ( 883 substr 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ text_substr_no_len _null_ _null_ _null_ _null_ ) +insert ( 884 btrim 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ btrim _null_ _null_ _null_ _null_ ) +insert ( 885 btrim 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ btrim1 _null_ _null_ _null_ _null_ ) +insert ( 936 substring 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 23 23' _null_ _null_ _null_ _null_ _null_ text_substr _null_ _null_ _null_ _null_ ) +insert ( 937 substring 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ text_substr_no_len _null_ _null_ _null_ _null_ ) +insert ( 2087 replace 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 25 25' _null_ _null_ _null_ _null_ _null_ replace_text _null_ _null_ _null_ _null_ ) +insert ( 2284 regexp_replace 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 25 25' _null_ _null_ _null_ _null_ _null_ textregexreplace_noopt _null_ _null_ _null_ _null_ ) +insert ( 2285 regexp_replace 11 10 12 1 0 0 0 f f f t f i s 4 0 25 '25 25 25 25' _null_ _null_ _null_ _null_ _null_ textregexreplace _null_ _null_ _null_ _null_ ) +insert ( 6251 regexp_replace 11 10 12 1 0 0 0 f f f t f i s 6 0 25 '25 25 25 23 23 25' _null_ _null_ _null_ _null_ _null_ textregexreplace_extended _null_ _null_ _null_ _null_ ) +insert ( 6252 regexp_replace 11 10 12 1 0 0 0 f f f t f i s 5 0 25 '25 25 25 23 23' _null_ _null_ _null_ _null_ _null_ textregexreplace_extended_no_flags _null_ _null_ _null_ _null_ ) +insert ( 6253 regexp_replace 11 10 12 1 0 0 0 f f f t f i s 4 0 25 '25 25 25 23' _null_ _null_ _null_ _null_ _null_ textregexreplace_extended_no_n _null_ _null_ _null_ _null_ ) +insert ( 3396 regexp_match 11 10 12 1 0 0 0 f f f t f i s 2 0 1009 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_match_no_flags _null_ _null_ _null_ _null_ ) +insert ( 3397 regexp_match 11 10 12 1 0 0 0 f f f t f i s 3 0 1009 '25 25 25' _null_ _null_ _null_ _null_ _null_ regexp_match _null_ _null_ _null_ _null_ ) +insert ( 2763 regexp_matches 11 10 12 1 1 0 0 f f f t t i s 2 0 1009 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_matches_no_flags _null_ _null_ _null_ _null_ ) +insert ( 2764 regexp_matches 11 10 12 1 10 0 0 f f f t t i s 3 0 1009 '25 25 25' _null_ _null_ _null_ _null_ _null_ regexp_matches _null_ _null_ _null_ _null_ ) +insert ( 6254 regexp_count 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_count_no_start _null_ _null_ _null_ _null_ ) +insert ( 6255 regexp_count 11 10 12 1 0 0 0 f f f t f i s 3 0 23 '25 25 23' _null_ _null_ _null_ _null_ _null_ regexp_count_no_flags _null_ _null_ _null_ _null_ ) +insert ( 6256 regexp_count 11 10 12 1 0 0 0 f f f t f i s 4 0 23 '25 25 23 25' _null_ _null_ _null_ _null_ _null_ regexp_count _null_ _null_ _null_ _null_ ) +insert ( 6257 regexp_instr 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_instr_no_start _null_ _null_ _null_ _null_ ) +insert ( 6258 regexp_instr 11 10 12 1 0 0 0 f f f t f i s 3 0 23 '25 25 23' _null_ _null_ _null_ _null_ _null_ regexp_instr_no_n _null_ _null_ _null_ _null_ ) +insert ( 6259 regexp_instr 11 10 12 1 0 0 0 f f f t f i s 4 0 23 '25 25 23 23' _null_ _null_ _null_ _null_ _null_ regexp_instr_no_endoption _null_ _null_ _null_ _null_ ) +insert ( 6260 regexp_instr 11 10 12 1 0 0 0 f f f t f i s 5 0 23 '25 25 23 23 23' _null_ _null_ _null_ _null_ _null_ regexp_instr_no_flags _null_ _null_ _null_ _null_ ) +insert ( 6261 regexp_instr 11 10 12 1 0 0 0 f f f t f i s 6 0 23 '25 25 23 23 23 25' _null_ _null_ _null_ _null_ _null_ regexp_instr_no_subexpr _null_ _null_ _null_ _null_ ) +insert ( 6262 regexp_instr 11 10 12 1 0 0 0 f f f t f i s 7 0 23 '25 25 23 23 23 25 23' _null_ _null_ _null_ _null_ _null_ regexp_instr _null_ _null_ _null_ _null_ ) +insert ( 6263 regexp_like 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_like_no_flags _null_ _null_ _null_ _null_ ) +insert ( 6264 regexp_like 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '25 25 25' _null_ _null_ _null_ _null_ _null_ regexp_like _null_ _null_ _null_ _null_ ) +insert ( 6265 regexp_substr 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_substr_no_start _null_ _null_ _null_ _null_ ) +insert ( 6266 regexp_substr 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 25 23' _null_ _null_ _null_ _null_ _null_ regexp_substr_no_n _null_ _null_ _null_ _null_ ) +insert ( 6267 regexp_substr 11 10 12 1 0 0 0 f f f t f i s 4 0 25 '25 25 23 23' _null_ _null_ _null_ _null_ _null_ regexp_substr_no_flags _null_ _null_ _null_ _null_ ) +insert ( 6268 regexp_substr 11 10 12 1 0 0 0 f f f t f i s 5 0 25 '25 25 23 23 25' _null_ _null_ _null_ _null_ _null_ regexp_substr_no_subexpr _null_ _null_ _null_ _null_ ) +insert ( 6269 regexp_substr 11 10 12 1 0 0 0 f f f t f i s 6 0 25 '25 25 23 23 25 23' _null_ _null_ _null_ _null_ _null_ regexp_substr _null_ _null_ _null_ _null_ ) +insert ( 2088 split_part 11 10 12 1 0 0 0 f f f t f i s 3 0 25 '25 25 23' _null_ _null_ _null_ _null_ _null_ split_part _null_ _null_ _null_ _null_ ) +insert ( 2765 regexp_split_to_table 11 10 12 1 1000 0 0 f f f t t i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_split_to_table_no_flags _null_ _null_ _null_ _null_ ) +insert ( 2766 regexp_split_to_table 11 10 12 1 1000 0 0 f f f t t i s 3 0 25 '25 25 25' _null_ _null_ _null_ _null_ _null_ regexp_split_to_table _null_ _null_ _null_ _null_ ) +insert ( 2767 regexp_split_to_array 11 10 12 1 0 0 0 f f f t f i s 2 0 1009 '25 25' _null_ _null_ _null_ _null_ _null_ regexp_split_to_array_no_flags _null_ _null_ _null_ _null_ ) +insert ( 2768 regexp_split_to_array 11 10 12 1 0 0 0 f f f t f i s 3 0 1009 '25 25 25' _null_ _null_ _null_ _null_ _null_ regexp_split_to_array _null_ _null_ _null_ _null_ ) +insert ( 2089 to_hex 11 10 12 1 0 0 0 f f f t f i s 1 0 25 23 _null_ _null_ _null_ _null_ _null_ to_hex32 _null_ _null_ _null_ _null_ ) +insert ( 2090 to_hex 11 10 12 1 0 0 0 f f f t f i s 1 0 25 20 _null_ _null_ _null_ _null_ _null_ to_hex64 _null_ _null_ _null_ _null_ ) +insert ( 1039 getdatabaseencoding 11 10 12 1 0 0 0 f f f t f s s 0 0 19 '' _null_ _null_ _null_ _null_ _null_ getdatabaseencoding _null_ _null_ _null_ _null_ ) +insert ( 810 pg_client_encoding 11 10 12 1 0 0 0 f f f t f s s 0 0 19 '' _null_ _null_ _null_ _null_ _null_ pg_client_encoding _null_ _null_ _null_ _null_ ) +insert ( 1713 length 11 10 12 1 0 0 0 f f f t f s s 2 0 23 '17 19' _null_ _null_ _null_ _null_ _null_ length_in_encoding _null_ _null_ _null_ _null_ ) +insert ( 1714 convert_from 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '17 19' _null_ _null_ _null_ _null_ _null_ pg_convert_from _null_ _null_ _null_ _null_ ) +insert ( 1717 convert_to 11 10 12 1 0 0 0 f f f t f s s 2 0 17 '25 19' _null_ _null_ _null_ _null_ _null_ pg_convert_to _null_ _null_ _null_ _null_ ) +insert ( 1813 convert 11 10 12 1 0 0 0 f f f t f s s 3 0 17 '17 19 19' _null_ _null_ _null_ _null_ _null_ pg_convert _null_ _null_ _null_ _null_ ) +insert ( 1264 pg_char_to_encoding 11 10 12 1 0 0 0 f f f t f s s 1 0 23 19 _null_ _null_ _null_ _null_ _null_ PG_char_to_encoding _null_ _null_ _null_ _null_ ) +insert ( 1597 pg_encoding_to_char 11 10 12 1 0 0 0 f f f t f s s 1 0 19 23 _null_ _null_ _null_ _null_ _null_ PG_encoding_to_char _null_ _null_ _null_ _null_ ) +insert ( 2319 pg_encoding_max_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ pg_encoding_max_length_sql _null_ _null_ _null_ _null_ ) +insert ( 1638 oidgt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '26 26' _null_ _null_ _null_ _null_ _null_ oidgt _null_ _null_ _null_ _null_ ) +insert ( 1639 oidge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '26 26' _null_ _null_ _null_ _null_ _null_ oidge _null_ _null_ _null_ _null_ ) +insert ( 1573 pg_get_ruledef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_ruledef _null_ _null_ _null_ _null_ ) +insert ( 1640 pg_get_viewdef 11 10 12 1 0 0 0 f f f t f s r 1 0 25 25 _null_ _null_ _null_ _null_ _null_ pg_get_viewdef_name _null_ _null_ _null_ _null_ ) +insert ( 1641 pg_get_viewdef 11 10 12 1 0 0 0 f f f t f s r 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_viewdef _null_ _null_ _null_ _null_ ) +insert ( 1642 pg_get_userbyid 11 10 12 1 0 0 0 f f f t f s s 1 0 19 26 _null_ _null_ _null_ _null_ _null_ pg_get_userbyid _null_ _null_ _null_ _null_ ) +insert ( 1643 pg_get_indexdef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_indexdef _null_ _null_ _null_ _null_ ) +insert ( 3415 pg_get_statisticsobjdef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_statisticsobjdef _null_ _null_ _null_ _null_ ) +insert ( 6174 pg_get_statisticsobjdef_columns 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_statisticsobjdef_columns _null_ _null_ _null_ _null_ ) +insert ( 6173 pg_get_statisticsobjdef_expressions 11 10 12 1 0 0 0 f f f t f s s 1 0 1009 26 _null_ _null_ _null_ _null_ _null_ pg_get_statisticsobjdef_expressions _null_ _null_ _null_ _null_ ) +insert ( 3352 pg_get_partkeydef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_partkeydef _null_ _null_ _null_ _null_ ) +insert ( 3408 pg_get_partition_constraintdef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_partition_constraintdef _null_ _null_ _null_ _null_ ) +insert ( 1662 pg_get_triggerdef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_triggerdef _null_ _null_ _null_ _null_ ) +insert ( 1387 pg_get_constraintdef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_constraintdef _null_ _null_ _null_ _null_ ) +insert ( 1716 pg_get_expr 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '194 26' _null_ _null_ _null_ _null_ _null_ pg_get_expr _null_ _null_ _null_ _null_ ) +insert ( 1665 pg_get_serial_sequence 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ pg_get_serial_sequence _null_ _null_ _null_ _null_ ) +insert ( 2098 pg_get_functiondef 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_functiondef _null_ _null_ _null_ _null_ ) +insert ( 2162 pg_get_function_arguments 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_function_arguments _null_ _null_ _null_ _null_ ) +insert ( 2232 pg_get_function_identity_arguments 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_function_identity_arguments _null_ _null_ _null_ _null_ ) +insert ( 2165 pg_get_function_result 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_function_result _null_ _null_ _null_ _null_ ) +insert ( 3808 pg_get_function_arg_default 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '26 23' _null_ _null_ _null_ _null_ _null_ pg_get_function_arg_default _null_ _null_ _null_ _null_ ) +insert ( 6197 pg_get_function_sqlbody 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_get_function_sqlbody _null_ _null_ _null_ _null_ ) +insert ( 1686 pg_get_keywords 11 10 12 10 500 0 0 f f f t t s s 0 0 2249 '' '{25,18,16,25,25}' '{o,o,o,o,o}' '{word,catcode,barelabel,catdesc,baredesc}' _null_ _null_ pg_get_keywords _null_ _null_ _null_ _null_ ) +insert ( 6159 pg_get_catalog_foreign_keys 11 10 12 10 250 0 0 f f f t t s s 0 0 2249 '' '{2205,1009,2205,1009,16,16}' '{o,o,o,o,o,o}' '{fktable,fkcols,pktable,pkcols,is_array,is_opt}' _null_ _null_ pg_get_catalog_foreign_keys _null_ _null_ _null_ _null_ ) +insert ( 2289 pg_options_to_table 11 10 12 1 3 0 0 f f f t t s s 1 0 2249 1009 '{1009,25,25}' '{i,o,o}' '{options_array,option_name,option_value}' _null_ _null_ pg_options_to_table _null_ _null_ _null_ _null_ ) +insert ( 1619 pg_typeof 11 10 12 1 0 0 0 f f f f f s s 1 0 2206 2276 _null_ _null_ _null_ _null_ _null_ pg_typeof _null_ _null_ _null_ _null_ ) +insert ( 3162 pg_collation_for 11 10 12 1 0 0 0 f f f f f s s 1 0 25 2276 _null_ _null_ _null_ _null_ _null_ pg_collation_for _null_ _null_ _null_ _null_ ) +insert ( 3842 pg_relation_is_updatable 11 10 12 10 0 0 0 f f f t f s s 2 0 23 '2205 16' _null_ _null_ _null_ _null_ _null_ pg_relation_is_updatable _null_ _null_ _null_ _null_ ) +insert ( 3843 pg_column_is_updatable 11 10 12 10 0 0 0 f f f t f s s 3 0 16 '2205 21 16' _null_ _null_ _null_ _null_ _null_ pg_column_is_updatable _null_ _null_ _null_ _null_ ) +insert ( 6120 pg_get_replica_identity_index 11 10 12 10 0 0 0 f f f t f s s 1 0 2205 2205 _null_ _null_ _null_ _null_ _null_ pg_get_replica_identity_index _null_ _null_ _null_ _null_ ) +insert ( 1250 unique_key_recheck 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ unique_key_recheck _null_ _null_ _null_ _null_ ) +insert ( 1644 RI_FKey_check_ins 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_check_ins _null_ _null_ _null_ _null_ ) +insert ( 1645 RI_FKey_check_upd 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_check_upd _null_ _null_ _null_ _null_ ) +insert ( 1646 RI_FKey_cascade_del 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_cascade_del _null_ _null_ _null_ _null_ ) +insert ( 1647 RI_FKey_cascade_upd 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_cascade_upd _null_ _null_ _null_ _null_ ) +insert ( 1648 RI_FKey_restrict_del 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_restrict_del _null_ _null_ _null_ _null_ ) +insert ( 1649 RI_FKey_restrict_upd 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_restrict_upd _null_ _null_ _null_ _null_ ) +insert ( 1650 RI_FKey_setnull_del 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_setnull_del _null_ _null_ _null_ _null_ ) +insert ( 1651 RI_FKey_setnull_upd 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_setnull_upd _null_ _null_ _null_ _null_ ) +insert ( 1652 RI_FKey_setdefault_del 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_setdefault_del _null_ _null_ _null_ _null_ ) +insert ( 1653 RI_FKey_setdefault_upd 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_setdefault_upd _null_ _null_ _null_ _null_ ) +insert ( 1654 RI_FKey_noaction_del 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_noaction_del _null_ _null_ _null_ _null_ ) +insert ( 1655 RI_FKey_noaction_upd 11 10 12 1 0 0 0 f f f t f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ RI_FKey_noaction_upd _null_ _null_ _null_ _null_ ) +insert ( 1666 varbiteq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1562 1562' _null_ _null_ _null_ _null_ _null_ biteq _null_ _null_ _null_ _null_ ) +insert ( 1667 varbitne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1562 1562' _null_ _null_ _null_ _null_ _null_ bitne _null_ _null_ _null_ _null_ ) +insert ( 1668 varbitge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1562 1562' _null_ _null_ _null_ _null_ _null_ bitge _null_ _null_ _null_ _null_ ) +insert ( 1669 varbitgt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1562 1562' _null_ _null_ _null_ _null_ _null_ bitgt _null_ _null_ _null_ _null_ ) +insert ( 1670 varbitle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1562 1562' _null_ _null_ _null_ _null_ _null_ bitle _null_ _null_ _null_ _null_ ) +insert ( 1671 varbitlt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1562 1562' _null_ _null_ _null_ _null_ _null_ bitlt _null_ _null_ _null_ _null_ ) +insert ( 1672 varbitcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1562 1562' _null_ _null_ _null_ _null_ _null_ bitcmp _null_ _null_ _null_ _null_ ) +insert ( 1673 bitand 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '1560 1560' _null_ _null_ _null_ _null_ _null_ bit_and _null_ _null_ _null_ _null_ ) +insert ( 1674 bitor 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '1560 1560' _null_ _null_ _null_ _null_ _null_ bit_or _null_ _null_ _null_ _null_ ) +insert ( 1675 bitxor 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitxor _null_ _null_ _null_ _null_ ) +insert ( 1676 bitnot 11 10 12 1 0 0 0 f f f t f i s 1 0 1560 1560 _null_ _null_ _null_ _null_ _null_ bitnot _null_ _null_ _null_ _null_ ) +insert ( 1677 bitshiftleft 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '1560 23' _null_ _null_ _null_ _null_ _null_ bitshiftleft _null_ _null_ _null_ _null_ ) +insert ( 1678 bitshiftright 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '1560 23' _null_ _null_ _null_ _null_ _null_ bitshiftright _null_ _null_ _null_ _null_ ) +insert ( 1679 bitcat 11 10 12 1 0 0 0 f f f t f i s 2 0 1562 '1562 1562' _null_ _null_ _null_ _null_ _null_ bitcat _null_ _null_ _null_ _null_ ) +insert ( 1680 substring 11 10 12 1 0 0 0 f f f t f i s 3 0 1560 '1560 23 23' _null_ _null_ _null_ _null_ _null_ bitsubstr _null_ _null_ _null_ _null_ ) +insert ( 1681 length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1560 _null_ _null_ _null_ _null_ _null_ bitlength _null_ _null_ _null_ _null_ ) +insert ( 1682 octet_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1560 _null_ _null_ _null_ _null_ _null_ bitoctetlength _null_ _null_ _null_ _null_ ) +insert ( 1683 bit 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '23 23' _null_ _null_ _null_ _null_ _null_ bitfromint4 _null_ _null_ _null_ _null_ ) +insert ( 1684 int4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1560 _null_ _null_ _null_ _null_ _null_ bittoint4 _null_ _null_ _null_ _null_ ) +insert ( 1685 bit 11 10 12 1 0 0 0 f f f t f i s 3 0 1560 '1560 23 16' _null_ _null_ _null_ _null_ _null_ bit _null_ _null_ _null_ _null_ ) +insert ( 3158 varbit_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ varbit_support _null_ _null_ _null_ _null_ ) +insert ( 1687 varbit 11 10 12 1 0 0 3158 f f f t f i s 3 0 1562 '1562 23 16' _null_ _null_ _null_ _null_ _null_ varbit _null_ _null_ _null_ _null_ ) +insert ( 1698 position 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '1560 1560' _null_ _null_ _null_ _null_ _null_ bitposition _null_ _null_ _null_ _null_ ) +insert ( 1699 substring 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '1560 23' _null_ _null_ _null_ _null_ _null_ bitsubstr_no_len _null_ _null_ _null_ _null_ ) +insert ( 3030 overlay 11 10 12 1 0 0 0 f f f t f i s 4 0 1560 '1560 1560 23 23' _null_ _null_ _null_ _null_ _null_ bitoverlay _null_ _null_ _null_ _null_ ) +insert ( 3031 overlay 11 10 12 1 0 0 0 f f f t f i s 3 0 1560 '1560 1560 23' _null_ _null_ _null_ _null_ _null_ bitoverlay_no_len _null_ _null_ _null_ _null_ ) +insert ( 3032 get_bit 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '1560 23' _null_ _null_ _null_ _null_ _null_ bitgetbit _null_ _null_ _null_ _null_ ) +insert ( 3033 set_bit 11 10 12 1 0 0 0 f f f t f i s 3 0 1560 '1560 23 23' _null_ _null_ _null_ _null_ _null_ bitsetbit _null_ _null_ _null_ _null_ ) +insert ( 6162 bit_count 11 10 12 1 0 0 0 f f f t f i s 1 0 20 1560 _null_ _null_ _null_ _null_ _null_ bit_bit_count _null_ _null_ _null_ _null_ ) +insert ( 436 macaddr_in 11 10 12 1 0 0 0 f f f t f i s 1 0 829 2275 _null_ _null_ _null_ _null_ _null_ macaddr_in _null_ _null_ _null_ _null_ ) +insert ( 437 macaddr_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 829 _null_ _null_ _null_ _null_ _null_ macaddr_out _null_ _null_ _null_ _null_ ) +insert ( 753 trunc 11 10 12 1 0 0 0 f f f t f i s 1 0 829 829 _null_ _null_ _null_ _null_ _null_ macaddr_trunc _null_ _null_ _null_ _null_ ) +insert ( 830 macaddr_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_eq _null_ _null_ _null_ _null_ ) +insert ( 831 macaddr_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_lt _null_ _null_ _null_ _null_ ) +insert ( 832 macaddr_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_le _null_ _null_ _null_ _null_ ) +insert ( 833 macaddr_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_gt _null_ _null_ _null_ _null_ ) +insert ( 834 macaddr_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_ge _null_ _null_ _null_ _null_ ) +insert ( 835 macaddr_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_ne _null_ _null_ _null_ _null_ ) +insert ( 836 macaddr_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_cmp _null_ _null_ _null_ _null_ ) +insert ( 3144 macaddr_not 11 10 12 1 0 0 0 f f f t f i s 1 0 829 829 _null_ _null_ _null_ _null_ _null_ macaddr_not _null_ _null_ _null_ _null_ ) +insert ( 3145 macaddr_and 11 10 12 1 0 0 0 f f f t f i s 2 0 829 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_and _null_ _null_ _null_ _null_ ) +insert ( 3146 macaddr_or 11 10 12 1 0 0 0 f f f t f i s 2 0 829 '829 829' _null_ _null_ _null_ _null_ _null_ macaddr_or _null_ _null_ _null_ _null_ ) +insert ( 3359 macaddr_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ macaddr_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 4110 macaddr8_in 11 10 12 1 0 0 0 f f f t f i s 1 0 774 2275 _null_ _null_ _null_ _null_ _null_ macaddr8_in _null_ _null_ _null_ _null_ ) +insert ( 4111 macaddr8_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 774 _null_ _null_ _null_ _null_ _null_ macaddr8_out _null_ _null_ _null_ _null_ ) +insert ( 4112 trunc 11 10 12 1 0 0 0 f f f t f i s 1 0 774 774 _null_ _null_ _null_ _null_ _null_ macaddr8_trunc _null_ _null_ _null_ _null_ ) +insert ( 4113 macaddr8_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_eq _null_ _null_ _null_ _null_ ) +insert ( 4114 macaddr8_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_lt _null_ _null_ _null_ _null_ ) +insert ( 4115 macaddr8_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_le _null_ _null_ _null_ _null_ ) +insert ( 4116 macaddr8_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_gt _null_ _null_ _null_ _null_ ) +insert ( 4117 macaddr8_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_ge _null_ _null_ _null_ _null_ ) +insert ( 4118 macaddr8_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_ne _null_ _null_ _null_ _null_ ) +insert ( 4119 macaddr8_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_cmp _null_ _null_ _null_ _null_ ) +insert ( 4120 macaddr8_not 11 10 12 1 0 0 0 f f f t f i s 1 0 774 774 _null_ _null_ _null_ _null_ _null_ macaddr8_not _null_ _null_ _null_ _null_ ) +insert ( 4121 macaddr8_and 11 10 12 1 0 0 0 f f f t f i s 2 0 774 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_and _null_ _null_ _null_ _null_ ) +insert ( 4122 macaddr8_or 11 10 12 1 0 0 0 f f f t f i s 2 0 774 '774 774' _null_ _null_ _null_ _null_ _null_ macaddr8_or _null_ _null_ _null_ _null_ ) +insert ( 4123 macaddr8 11 10 12 1 0 0 0 f f t t f i s 1 0 774 829 _null_ _null_ _null_ _null_ _null_ macaddrtomacaddr8 _null_ _null_ _null_ _null_ ) +insert ( 4124 macaddr 11 10 12 1 0 0 0 f f f t f i s 1 0 829 774 _null_ _null_ _null_ _null_ _null_ macaddr8tomacaddr _null_ _null_ _null_ _null_ ) +insert ( 4125 macaddr8_set7bit 11 10 12 1 0 0 0 f f f t f i s 1 0 774 774 _null_ _null_ _null_ _null_ _null_ macaddr8_set7bit _null_ _null_ _null_ _null_ ) +insert ( 910 inet_in 11 10 12 1 0 0 0 f f f t f i s 1 0 869 2275 _null_ _null_ _null_ _null_ _null_ inet_in _null_ _null_ _null_ _null_ ) +insert ( 911 inet_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 869 _null_ _null_ _null_ _null_ _null_ inet_out _null_ _null_ _null_ _null_ ) +insert ( 1267 cidr_in 11 10 12 1 0 0 0 f f f t f i s 1 0 650 2275 _null_ _null_ _null_ _null_ _null_ cidr_in _null_ _null_ _null_ _null_ ) +insert ( 1427 cidr_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 650 _null_ _null_ _null_ _null_ _null_ cidr_out _null_ _null_ _null_ _null_ ) +insert ( 920 network_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_eq _null_ _null_ _null_ _null_ ) +insert ( 921 network_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_lt _null_ _null_ _null_ _null_ ) +insert ( 922 network_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_le _null_ _null_ _null_ _null_ ) +insert ( 923 network_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_gt _null_ _null_ _null_ _null_ ) +insert ( 924 network_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_ge _null_ _null_ _null_ _null_ ) +insert ( 925 network_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_ne _null_ _null_ _null_ _null_ ) +insert ( 3562 network_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '869 869' _null_ _null_ _null_ _null_ _null_ network_larger _null_ _null_ _null_ _null_ ) +insert ( 3563 network_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '869 869' _null_ _null_ _null_ _null_ _null_ network_smaller _null_ _null_ _null_ _null_ ) +insert ( 926 network_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '869 869' _null_ _null_ _null_ _null_ _null_ network_cmp _null_ _null_ _null_ _null_ ) +insert ( 927 network_sub 11 10 12 1 0 0 1173 f f f t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_sub _null_ _null_ _null_ _null_ ) +insert ( 928 network_subeq 11 10 12 1 0 0 1173 f f f t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_subeq _null_ _null_ _null_ _null_ ) +insert ( 929 network_sup 11 10 12 1 0 0 1173 f f f t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_sup _null_ _null_ _null_ _null_ ) +insert ( 930 network_supeq 11 10 12 1 0 0 1173 f f f t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_supeq _null_ _null_ _null_ _null_ ) +insert ( 1173 network_subset_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ network_subset_support _null_ _null_ _null_ _null_ ) +insert ( 3551 network_overlap 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ network_overlap _null_ _null_ _null_ _null_ ) +insert ( 5033 network_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ network_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 598 abbrev 11 10 12 1 0 0 0 f f f t f i s 1 0 25 869 _null_ _null_ _null_ _null_ _null_ inet_abbrev _null_ _null_ _null_ _null_ ) +insert ( 599 abbrev 11 10 12 1 0 0 0 f f f t f i s 1 0 25 650 _null_ _null_ _null_ _null_ _null_ cidr_abbrev _null_ _null_ _null_ _null_ ) +insert ( 605 set_masklen 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '869 23' _null_ _null_ _null_ _null_ _null_ inet_set_masklen _null_ _null_ _null_ _null_ ) +insert ( 635 set_masklen 11 10 12 1 0 0 0 f f f t f i s 2 0 650 '650 23' _null_ _null_ _null_ _null_ _null_ cidr_set_masklen _null_ _null_ _null_ _null_ ) +insert ( 711 family 11 10 12 1 0 0 0 f f f t f i s 1 0 23 869 _null_ _null_ _null_ _null_ _null_ network_family _null_ _null_ _null_ _null_ ) +insert ( 683 network 11 10 12 1 0 0 0 f f f t f i s 1 0 650 869 _null_ _null_ _null_ _null_ _null_ network_network _null_ _null_ _null_ _null_ ) +insert ( 696 netmask 11 10 12 1 0 0 0 f f f t f i s 1 0 869 869 _null_ _null_ _null_ _null_ _null_ network_netmask _null_ _null_ _null_ _null_ ) +insert ( 697 masklen 11 10 12 1 0 0 0 f f f t f i s 1 0 23 869 _null_ _null_ _null_ _null_ _null_ network_masklen _null_ _null_ _null_ _null_ ) +insert ( 698 broadcast 11 10 12 1 0 0 0 f f f t f i s 1 0 869 869 _null_ _null_ _null_ _null_ _null_ network_broadcast _null_ _null_ _null_ _null_ ) +insert ( 699 host 11 10 12 1 0 0 0 f f f t f i s 1 0 25 869 _null_ _null_ _null_ _null_ _null_ network_host _null_ _null_ _null_ _null_ ) +insert ( 730 text 11 10 12 1 0 0 0 f f f t f i s 1 0 25 869 _null_ _null_ _null_ _null_ _null_ network_show _null_ _null_ _null_ _null_ ) +insert ( 1362 hostmask 11 10 12 1 0 0 0 f f f t f i s 1 0 869 869 _null_ _null_ _null_ _null_ _null_ network_hostmask _null_ _null_ _null_ _null_ ) +insert ( 1715 cidr 11 10 12 1 0 0 0 f f f t f i s 1 0 650 869 _null_ _null_ _null_ _null_ _null_ inet_to_cidr _null_ _null_ _null_ _null_ ) +insert ( 2196 inet_client_addr 11 10 12 1 0 0 0 f f f f f s r 0 0 869 '' _null_ _null_ _null_ _null_ _null_ inet_client_addr _null_ _null_ _null_ _null_ ) +insert ( 2197 inet_client_port 11 10 12 1 0 0 0 f f f f f s r 0 0 23 '' _null_ _null_ _null_ _null_ _null_ inet_client_port _null_ _null_ _null_ _null_ ) +insert ( 2198 inet_server_addr 11 10 12 1 0 0 0 f f f f f s r 0 0 869 '' _null_ _null_ _null_ _null_ _null_ inet_server_addr _null_ _null_ _null_ _null_ ) +insert ( 2199 inet_server_port 11 10 12 1 0 0 0 f f f f f s r 0 0 23 '' _null_ _null_ _null_ _null_ _null_ inet_server_port _null_ _null_ _null_ _null_ ) +insert ( 2627 inetnot 11 10 12 1 0 0 0 f f f t f i s 1 0 869 869 _null_ _null_ _null_ _null_ _null_ inetnot _null_ _null_ _null_ _null_ ) +insert ( 2628 inetand 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '869 869' _null_ _null_ _null_ _null_ _null_ inetand _null_ _null_ _null_ _null_ ) +insert ( 2629 inetor 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '869 869' _null_ _null_ _null_ _null_ _null_ inetor _null_ _null_ _null_ _null_ ) +insert ( 2630 inetpl 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '869 20' _null_ _null_ _null_ _null_ _null_ inetpl _null_ _null_ _null_ _null_ ) +insert ( 2631 int8pl_inet 11 10 14 1 0 0 0 f f f t f i s 2 0 869 '20 869' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2632 inetmi_int8 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '869 20' _null_ _null_ _null_ _null_ _null_ inetmi_int8 _null_ _null_ _null_ _null_ ) +insert ( 2633 inetmi 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '869 869' _null_ _null_ _null_ _null_ _null_ inetmi _null_ _null_ _null_ _null_ ) +insert ( 4071 inet_same_family 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '869 869' _null_ _null_ _null_ _null_ _null_ inet_same_family _null_ _null_ _null_ _null_ ) +insert ( 4063 inet_merge 11 10 12 1 0 0 0 f f f t f i s 2 0 650 '869 869' _null_ _null_ _null_ _null_ _null_ inet_merge _null_ _null_ _null_ _null_ ) +insert ( 3553 inet_gist_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 869 21 26 2281' _null_ _null_ _null_ _null_ _null_ inet_gist_consistent _null_ _null_ _null_ _null_ ) +insert ( 3554 inet_gist_union 11 10 12 1 0 0 0 f f f t f i s 2 0 869 '2281 2281' _null_ _null_ _null_ _null_ _null_ inet_gist_union _null_ _null_ _null_ _null_ ) +insert ( 3555 inet_gist_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ inet_gist_compress _null_ _null_ _null_ _null_ ) +insert ( 3573 inet_gist_fetch 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ inet_gist_fetch _null_ _null_ _null_ _null_ ) +insert ( 3557 inet_gist_penalty 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ inet_gist_penalty _null_ _null_ _null_ _null_ ) +insert ( 3558 inet_gist_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ inet_gist_picksplit _null_ _null_ _null_ _null_ ) +insert ( 3559 inet_gist_same 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '869 869 2281' _null_ _null_ _null_ _null_ _null_ inet_gist_same _null_ _null_ _null_ _null_ ) +insert ( 3795 inet_spg_config 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ inet_spg_config _null_ _null_ _null_ _null_ ) +insert ( 3796 inet_spg_choose 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ inet_spg_choose _null_ _null_ _null_ _null_ ) +insert ( 3797 inet_spg_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ inet_spg_picksplit _null_ _null_ _null_ _null_ ) +insert ( 3798 inet_spg_inner_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ inet_spg_inner_consistent _null_ _null_ _null_ _null_ ) +insert ( 3799 inet_spg_leaf_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2281 2281' _null_ _null_ _null_ _null_ _null_ inet_spg_leaf_consistent _null_ _null_ _null_ _null_ ) +insert ( 3560 networksel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ networksel _null_ _null_ _null_ _null_ ) +insert ( 3561 networkjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ networkjoinsel _null_ _null_ _null_ _null_ ) +insert ( 1690 time_mi_time 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1083 1083' _null_ _null_ _null_ _null_ _null_ time_mi_time _null_ _null_ _null_ _null_ ) +insert ( 1691 boolle 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ boolle _null_ _null_ _null_ _null_ ) +insert ( 1692 boolge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ boolge _null_ _null_ _null_ _null_ ) +insert ( 1693 btboolcmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '16 16' _null_ _null_ _null_ _null_ _null_ btboolcmp _null_ _null_ _null_ _null_ ) +insert ( 1688 time_hash 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1083 _null_ _null_ _null_ _null_ _null_ time_hash _null_ _null_ _null_ _null_ ) +insert ( 3409 time_hash_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '1083 20' _null_ _null_ _null_ _null_ _null_ time_hash_extended _null_ _null_ _null_ _null_ ) +insert ( 1696 timetz_hash 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1266 _null_ _null_ _null_ _null_ _null_ timetz_hash _null_ _null_ _null_ _null_ ) +insert ( 3410 timetz_hash_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '1266 20' _null_ _null_ _null_ _null_ _null_ timetz_hash_extended _null_ _null_ _null_ _null_ ) +insert ( 1697 interval_hash 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1186 _null_ _null_ _null_ _null_ _null_ interval_hash _null_ _null_ _null_ _null_ ) +insert ( 3418 interval_hash_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '1186 20' _null_ _null_ _null_ _null_ _null_ interval_hash_extended _null_ _null_ _null_ _null_ ) +insert ( 1701 numeric_in 11 10 12 1 0 0 0 f f f t f i s 3 0 1700 '2275 26 23' _null_ _null_ _null_ _null_ _null_ numeric_in _null_ _null_ _null_ _null_ ) +insert ( 1702 numeric_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 1700 _null_ _null_ _null_ _null_ _null_ numeric_out _null_ _null_ _null_ _null_ ) +insert ( 2917 numerictypmodin 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1263 _null_ _null_ _null_ _null_ _null_ numerictypmodin _null_ _null_ _null_ _null_ ) +insert ( 2918 numerictypmodout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 23 _null_ _null_ _null_ _null_ _null_ numerictypmodout _null_ _null_ _null_ _null_ ) +insert ( 3157 numeric_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ numeric_support _null_ _null_ _null_ _null_ ) +insert ( 1703 numeric 11 10 12 1 0 0 3157 f f f t f i s 2 0 1700 '1700 23' _null_ _null_ _null_ _null_ _null_ numeric _null_ _null_ _null_ _null_ ) +insert ( 1704 numeric_abs 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_abs _null_ _null_ _null_ _null_ ) +insert ( 1705 abs 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_abs _null_ _null_ _null_ _null_ ) +insert ( 1706 sign 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_sign _null_ _null_ _null_ _null_ ) +insert ( 1707 round 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 23' _null_ _null_ _null_ _null_ _null_ numeric_round _null_ _null_ _null_ _null_ ) +insert ( 1708 round 11 10 14 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1709 trunc 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 23' _null_ _null_ _null_ _null_ _null_ numeric_trunc _null_ _null_ _null_ _null_ ) +insert ( 1710 trunc 11 10 14 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1711 ceil 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_ceil _null_ _null_ _null_ _null_ ) +insert ( 2167 ceiling 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_ceil _null_ _null_ _null_ _null_ ) +insert ( 1712 floor 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_floor _null_ _null_ _null_ _null_ ) +insert ( 1718 numeric_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_eq _null_ _null_ _null_ _null_ ) +insert ( 1719 numeric_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_ne _null_ _null_ _null_ _null_ ) +insert ( 1720 numeric_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_gt _null_ _null_ _null_ _null_ ) +insert ( 1721 numeric_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_ge _null_ _null_ _null_ _null_ ) +insert ( 1722 numeric_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_lt _null_ _null_ _null_ _null_ ) +insert ( 1723 numeric_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_le _null_ _null_ _null_ _null_ ) +insert ( 1724 numeric_add 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_add _null_ _null_ _null_ _null_ ) +insert ( 1725 numeric_sub 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_sub _null_ _null_ _null_ _null_ ) +insert ( 1726 numeric_mul 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_mul _null_ _null_ _null_ _null_ ) +insert ( 1727 numeric_div 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_div _null_ _null_ _null_ _null_ ) +insert ( 1728 mod 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_mod _null_ _null_ _null_ _null_ ) +insert ( 1729 numeric_mod 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_mod _null_ _null_ _null_ _null_ ) +insert ( 5048 gcd 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_gcd _null_ _null_ _null_ _null_ ) +insert ( 5049 lcm 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_lcm _null_ _null_ _null_ _null_ ) +insert ( 1730 sqrt 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_sqrt _null_ _null_ _null_ _null_ ) +insert ( 1731 numeric_sqrt 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_sqrt _null_ _null_ _null_ _null_ ) +insert ( 1732 exp 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_exp _null_ _null_ _null_ _null_ ) +insert ( 1733 numeric_exp 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_exp _null_ _null_ _null_ _null_ ) +insert ( 1734 ln 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_ln _null_ _null_ _null_ _null_ ) +insert ( 1735 numeric_ln 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_ln _null_ _null_ _null_ _null_ ) +insert ( 1736 log 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_log _null_ _null_ _null_ _null_ ) +insert ( 1737 numeric_log 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_log _null_ _null_ _null_ _null_ ) +insert ( 1738 pow 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_power _null_ _null_ _null_ _null_ ) +insert ( 2169 power 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_power _null_ _null_ _null_ _null_ ) +insert ( 1739 numeric_power 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_power _null_ _null_ _null_ _null_ ) +insert ( 3281 scale 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1700 _null_ _null_ _null_ _null_ _null_ numeric_scale _null_ _null_ _null_ _null_ ) +insert ( 5042 min_scale 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1700 _null_ _null_ _null_ _null_ _null_ numeric_min_scale _null_ _null_ _null_ _null_ ) +insert ( 5043 trim_scale 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_trim_scale _null_ _null_ _null_ _null_ ) +insert ( 1740 numeric 11 10 12 1 0 0 0 f f t t f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ int4_numeric _null_ _null_ _null_ _null_ ) +insert ( 1741 log 11 10 14 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1481 log10 11 10 14 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1742 numeric 11 10 12 1 0 0 0 f f t t f i s 1 0 1700 700 _null_ _null_ _null_ _null_ _null_ float4_numeric _null_ _null_ _null_ _null_ ) +insert ( 1743 numeric 11 10 12 1 0 0 0 f f t t f i s 1 0 1700 701 _null_ _null_ _null_ _null_ _null_ float8_numeric _null_ _null_ _null_ _null_ ) +insert ( 1744 int4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1700 _null_ _null_ _null_ _null_ _null_ numeric_int4 _null_ _null_ _null_ _null_ ) +insert ( 1745 float4 11 10 12 1 0 0 0 f f f t f i s 1 0 700 1700 _null_ _null_ _null_ _null_ _null_ numeric_float4 _null_ _null_ _null_ _null_ ) +insert ( 1746 float8 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1700 _null_ _null_ _null_ _null_ _null_ numeric_float8 _null_ _null_ _null_ _null_ ) +insert ( 1973 div 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_div_trunc _null_ _null_ _null_ _null_ ) +insert ( 1980 numeric_div_trunc 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_div_trunc _null_ _null_ _null_ _null_ ) +insert ( 2170 width_bucket 11 10 12 1 0 0 0 f f f t f i s 4 0 23 '1700 1700 1700 23' _null_ _null_ _null_ _null_ _null_ width_bucket_numeric _null_ _null_ _null_ _null_ ) +insert ( 1747 time_pl_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1083 '1083 1186' _null_ _null_ _null_ _null_ _null_ time_pl_interval _null_ _null_ _null_ _null_ ) +insert ( 1748 time_mi_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1083 '1083 1186' _null_ _null_ _null_ _null_ _null_ time_mi_interval _null_ _null_ _null_ _null_ ) +insert ( 1749 timetz_pl_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1266 '1266 1186' _null_ _null_ _null_ _null_ _null_ timetz_pl_interval _null_ _null_ _null_ _null_ ) +insert ( 1750 timetz_mi_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1266 '1266 1186' _null_ _null_ _null_ _null_ _null_ timetz_mi_interval _null_ _null_ _null_ _null_ ) +insert ( 1764 numeric_inc 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_inc _null_ _null_ _null_ _null_ ) +insert ( 1766 numeric_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_smaller _null_ _null_ _null_ _null_ ) +insert ( 1767 numeric_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_larger _null_ _null_ _null_ _null_ ) +insert ( 1769 numeric_cmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '1700 1700' _null_ _null_ _null_ _null_ _null_ numeric_cmp _null_ _null_ _null_ _null_ ) +insert ( 3283 numeric_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ numeric_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 1771 numeric_uminus 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_uminus _null_ _null_ _null_ _null_ ) +insert ( 1779 int8 11 10 12 1 0 0 0 f f f t f i s 1 0 20 1700 _null_ _null_ _null_ _null_ _null_ numeric_int8 _null_ _null_ _null_ _null_ ) +insert ( 1781 numeric 11 10 12 1 0 0 0 f f t t f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ int8_numeric _null_ _null_ _null_ _null_ ) +insert ( 1782 numeric 11 10 12 1 0 0 0 f f t t f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ int2_numeric _null_ _null_ _null_ _null_ ) +insert ( 1783 int2 11 10 12 1 0 0 0 f f f t f i s 1 0 21 1700 _null_ _null_ _null_ _null_ _null_ numeric_int2 _null_ _null_ _null_ _null_ ) +insert ( 6103 pg_lsn 11 10 12 1 0 0 0 f f f t f i s 1 0 3220 1700 _null_ _null_ _null_ _null_ _null_ numeric_pg_lsn _null_ _null_ _null_ _null_ ) +insert ( 3556 bool 11 10 12 1 0 0 0 f f f t f i s 1 0 16 3802 _null_ _null_ _null_ _null_ _null_ jsonb_bool _null_ _null_ _null_ _null_ ) +insert ( 3449 numeric 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 3802 _null_ _null_ _null_ _null_ _null_ jsonb_numeric _null_ _null_ _null_ _null_ ) +insert ( 3450 int2 11 10 12 1 0 0 0 f f f t f i s 1 0 21 3802 _null_ _null_ _null_ _null_ _null_ jsonb_int2 _null_ _null_ _null_ _null_ ) +insert ( 3451 int4 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3802 _null_ _null_ _null_ _null_ _null_ jsonb_int4 _null_ _null_ _null_ _null_ ) +insert ( 3452 int8 11 10 12 1 0 0 0 f f f t f i s 1 0 20 3802 _null_ _null_ _null_ _null_ _null_ jsonb_int8 _null_ _null_ _null_ _null_ ) +insert ( 3453 float4 11 10 12 1 0 0 0 f f f t f i s 1 0 700 3802 _null_ _null_ _null_ _null_ _null_ jsonb_float4 _null_ _null_ _null_ _null_ ) +insert ( 2580 float8 11 10 12 1 0 0 0 f f f t f i s 1 0 701 3802 _null_ _null_ _null_ _null_ _null_ jsonb_float8 _null_ _null_ _null_ _null_ ) +insert ( 1770 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '1184 25' _null_ _null_ _null_ _null_ _null_ timestamptz_to_char _null_ _null_ _null_ _null_ ) +insert ( 1772 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '1700 25' _null_ _null_ _null_ _null_ _null_ numeric_to_char _null_ _null_ _null_ _null_ ) +insert ( 1773 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '23 25' _null_ _null_ _null_ _null_ _null_ int4_to_char _null_ _null_ _null_ _null_ ) +insert ( 1774 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '20 25' _null_ _null_ _null_ _null_ _null_ int8_to_char _null_ _null_ _null_ _null_ ) +insert ( 1775 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '700 25' _null_ _null_ _null_ _null_ _null_ float4_to_char _null_ _null_ _null_ _null_ ) +insert ( 1776 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '701 25' _null_ _null_ _null_ _null_ _null_ float8_to_char _null_ _null_ _null_ _null_ ) +insert ( 1777 to_number 11 10 12 1 0 0 0 f f f t f s s 2 0 1700 '25 25' _null_ _null_ _null_ _null_ _null_ numeric_to_number _null_ _null_ _null_ _null_ ) +insert ( 1778 to_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 1184 '25 25' _null_ _null_ _null_ _null_ _null_ to_timestamp _null_ _null_ _null_ _null_ ) +insert ( 1780 to_date 11 10 12 1 0 0 0 f f f t f s s 2 0 1082 '25 25' _null_ _null_ _null_ _null_ _null_ to_date _null_ _null_ _null_ _null_ ) +insert ( 1768 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '1186 25' _null_ _null_ _null_ _null_ _null_ interval_to_char _null_ _null_ _null_ _null_ ) +insert ( 1282 quote_ident 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ quote_ident _null_ _null_ _null_ _null_ ) +insert ( 1283 quote_literal 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ quote_literal _null_ _null_ _null_ _null_ ) +insert ( 1285 quote_literal 11 10 14 1 0 0 0 f f f t f s s 1 0 25 2283 _null_ _null_ _null_ _null_ _null_ 'select pg_catalog.quote_literal($1::pg_catalog.text)' _null_ _null_ _null_ _null_ ) +insert ( 1289 quote_nullable 11 10 12 1 0 0 0 f f f f f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ quote_nullable _null_ _null_ _null_ _null_ ) +insert ( 1290 quote_nullable 11 10 14 1 0 0 0 f f f f f s s 1 0 25 2283 _null_ _null_ _null_ _null_ _null_ 'select pg_catalog.quote_nullable($1::pg_catalog.text)' _null_ _null_ _null_ _null_ ) +insert ( 1798 oidin 11 10 12 1 0 0 0 f f f t f i s 1 0 26 2275 _null_ _null_ _null_ _null_ _null_ oidin _null_ _null_ _null_ _null_ ) +insert ( 1799 oidout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 26 _null_ _null_ _null_ _null_ _null_ oidout _null_ _null_ _null_ _null_ ) +insert ( 3058 concat 11 10 12 1 0 2276 0 f f f f f s s 1 0 25 2276 '{2276}' '{v}' _null_ _null_ _null_ text_concat _null_ _null_ _null_ _null_ ) +insert ( 3059 concat_ws 11 10 12 1 0 2276 0 f f f f f s s 2 0 25 '25 2276' '{25,2276}' '{i,v}' _null_ _null_ _null_ text_concat_ws _null_ _null_ _null_ _null_ ) +insert ( 3060 left 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ text_left _null_ _null_ _null_ _null_ ) +insert ( 3061 right 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ text_right _null_ _null_ _null_ _null_ ) +insert ( 3062 reverse 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ text_reverse _null_ _null_ _null_ _null_ ) +insert ( 3539 format 11 10 12 1 0 2276 0 f f f f f s s 2 0 25 '25 2276' '{25,2276}' '{i,v}' _null_ _null_ _null_ text_format _null_ _null_ _null_ _null_ ) +insert ( 3540 format 11 10 12 1 0 0 0 f f f f f s s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ text_format_nv _null_ _null_ _null_ _null_ ) +insert ( 1810 bit_length 11 10 14 1 0 0 0 f f f t f i s 1 0 23 17 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1811 bit_length 11 10 14 1 0 0 0 f f f t f i s 1 0 23 25 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1812 bit_length 11 10 14 1 0 0 0 f f f t f i s 1 0 23 1560 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1814 iclikesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ iclikesel _null_ _null_ _null_ _null_ ) +insert ( 1815 icnlikesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ icnlikesel _null_ _null_ _null_ _null_ ) +insert ( 1816 iclikejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ iclikejoinsel _null_ _null_ _null_ _null_ ) +insert ( 1817 icnlikejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ icnlikejoinsel _null_ _null_ _null_ _null_ ) +insert ( 1818 regexeqsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ regexeqsel _null_ _null_ _null_ _null_ ) +insert ( 1819 likesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ likesel _null_ _null_ _null_ _null_ ) +insert ( 1820 icregexeqsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ icregexeqsel _null_ _null_ _null_ _null_ ) +insert ( 1821 regexnesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ regexnesel _null_ _null_ _null_ _null_ ) +insert ( 1822 nlikesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ nlikesel _null_ _null_ _null_ _null_ ) +insert ( 1823 icregexnesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ icregexnesel _null_ _null_ _null_ _null_ ) +insert ( 1824 regexeqjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ regexeqjoinsel _null_ _null_ _null_ _null_ ) +insert ( 1825 likejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ likejoinsel _null_ _null_ _null_ _null_ ) +insert ( 1826 icregexeqjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ icregexeqjoinsel _null_ _null_ _null_ _null_ ) +insert ( 1827 regexnejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ regexnejoinsel _null_ _null_ _null_ _null_ ) +insert ( 1828 nlikejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ nlikejoinsel _null_ _null_ _null_ _null_ ) +insert ( 1829 icregexnejoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ icregexnejoinsel _null_ _null_ _null_ _null_ ) +insert ( 3437 prefixsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ prefixsel _null_ _null_ _null_ _null_ ) +insert ( 3438 prefixjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ prefixjoinsel _null_ _null_ _null_ _null_ ) +insert ( 1830 float8_avg 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_avg _null_ _null_ _null_ _null_ ) +insert ( 2512 float8_var_pop 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_var_pop _null_ _null_ _null_ _null_ ) +insert ( 1831 float8_var_samp 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_var_samp _null_ _null_ _null_ _null_ ) +insert ( 2513 float8_stddev_pop 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_stddev_pop _null_ _null_ _null_ _null_ ) +insert ( 1832 float8_stddev_samp 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_stddev_samp _null_ _null_ _null_ _null_ ) +insert ( 1833 numeric_accum 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 1700' _null_ _null_ _null_ _null_ _null_ numeric_accum _null_ _null_ _null_ _null_ ) +insert ( 3341 numeric_combine 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ numeric_combine _null_ _null_ _null_ _null_ ) +insert ( 2858 numeric_avg_accum 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 1700' _null_ _null_ _null_ _null_ _null_ numeric_avg_accum _null_ _null_ _null_ _null_ ) +insert ( 3337 numeric_avg_combine 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ numeric_avg_combine _null_ _null_ _null_ _null_ ) +insert ( 2740 numeric_avg_serialize 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ numeric_avg_serialize _null_ _null_ _null_ _null_ ) +insert ( 2741 numeric_avg_deserialize 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '17 2281' _null_ _null_ _null_ _null_ _null_ numeric_avg_deserialize _null_ _null_ _null_ _null_ ) +insert ( 3335 numeric_serialize 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ numeric_serialize _null_ _null_ _null_ _null_ ) +insert ( 3336 numeric_deserialize 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '17 2281' _null_ _null_ _null_ _null_ _null_ numeric_deserialize _null_ _null_ _null_ _null_ ) +insert ( 3548 numeric_accum_inv 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 1700' _null_ _null_ _null_ _null_ _null_ numeric_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 1834 int2_accum 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 21' _null_ _null_ _null_ _null_ _null_ int2_accum _null_ _null_ _null_ _null_ ) +insert ( 1835 int4_accum 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 23' _null_ _null_ _null_ _null_ _null_ int4_accum _null_ _null_ _null_ _null_ ) +insert ( 1836 int8_accum 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 20' _null_ _null_ _null_ _null_ _null_ int8_accum _null_ _null_ _null_ _null_ ) +insert ( 3338 numeric_poly_combine 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ numeric_poly_combine _null_ _null_ _null_ _null_ ) +insert ( 3339 numeric_poly_serialize 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ numeric_poly_serialize _null_ _null_ _null_ _null_ ) +insert ( 3340 numeric_poly_deserialize 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '17 2281' _null_ _null_ _null_ _null_ _null_ numeric_poly_deserialize _null_ _null_ _null_ _null_ ) +insert ( 2746 int8_avg_accum 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 20' _null_ _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ _null_ ) +insert ( 3567 int2_accum_inv 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 21' _null_ _null_ _null_ _null_ _null_ int2_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 3568 int4_accum_inv 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 23' _null_ _null_ _null_ _null_ _null_ int4_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 3569 int8_accum_inv 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 20' _null_ _null_ _null_ _null_ _null_ int8_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 3387 int8_avg_accum_inv 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 20' _null_ _null_ _null_ _null_ _null_ int8_avg_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 2785 int8_avg_combine 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ int8_avg_combine _null_ _null_ _null_ _null_ ) +insert ( 2786 int8_avg_serialize 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ int8_avg_serialize _null_ _null_ _null_ _null_ ) +insert ( 2787 int8_avg_deserialize 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '17 2281' _null_ _null_ _null_ _null_ _null_ int8_avg_deserialize _null_ _null_ _null_ _null_ ) +insert ( 3324 int4_avg_combine 11 10 12 1 0 0 0 f f f t f i s 2 0 1016 '1016 1016' _null_ _null_ _null_ _null_ _null_ int4_avg_combine _null_ _null_ _null_ _null_ ) +insert ( 3178 numeric_sum 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_sum _null_ _null_ _null_ _null_ ) +insert ( 1837 numeric_avg 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_avg _null_ _null_ _null_ _null_ ) +insert ( 2514 numeric_var_pop 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_var_pop _null_ _null_ _null_ _null_ ) +insert ( 1838 numeric_var_samp 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_var_samp _null_ _null_ _null_ _null_ ) +insert ( 2596 numeric_stddev_pop 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_stddev_pop _null_ _null_ _null_ _null_ ) +insert ( 1839 numeric_stddev_samp 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_stddev_samp _null_ _null_ _null_ _null_ ) +insert ( 1840 int2_sum 11 10 12 1 0 0 0 f f f f f i s 2 0 20 '20 21' _null_ _null_ _null_ _null_ _null_ int2_sum _null_ _null_ _null_ _null_ ) +insert ( 1841 int4_sum 11 10 12 1 0 0 0 f f f f f i s 2 0 20 '20 23' _null_ _null_ _null_ _null_ _null_ int4_sum _null_ _null_ _null_ _null_ ) +insert ( 1842 int8_sum 11 10 12 1 0 0 0 f f f f f i s 2 0 1700 '1700 20' _null_ _null_ _null_ _null_ _null_ int8_sum _null_ _null_ _null_ _null_ ) +insert ( 3388 numeric_poly_sum 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_poly_sum _null_ _null_ _null_ _null_ ) +insert ( 3389 numeric_poly_avg 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_poly_avg _null_ _null_ _null_ _null_ ) +insert ( 3390 numeric_poly_var_pop 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_poly_var_pop _null_ _null_ _null_ _null_ ) +insert ( 3391 numeric_poly_var_samp 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_poly_var_samp _null_ _null_ _null_ _null_ ) +insert ( 3392 numeric_poly_stddev_pop 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_poly_stddev_pop _null_ _null_ _null_ _null_ ) +insert ( 3393 numeric_poly_stddev_samp 11 10 12 1 0 0 0 f f f f f i s 1 0 1700 2281 _null_ _null_ _null_ _null_ _null_ numeric_poly_stddev_samp _null_ _null_ _null_ _null_ ) +insert ( 1843 interval_accum 11 10 12 1 0 0 0 f f f t f i s 2 0 1187 '1187 1186' _null_ _null_ _null_ _null_ _null_ interval_accum _null_ _null_ _null_ _null_ ) +insert ( 3325 interval_combine 11 10 12 1 0 0 0 f f f t f i s 2 0 1187 '1187 1187' _null_ _null_ _null_ _null_ _null_ interval_combine _null_ _null_ _null_ _null_ ) +insert ( 3549 interval_accum_inv 11 10 12 1 0 0 0 f f f t f i s 2 0 1187 '1187 1186' _null_ _null_ _null_ _null_ _null_ interval_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 1844 interval_avg 11 10 12 1 0 0 0 f f f t f i s 1 0 1186 1187 _null_ _null_ _null_ _null_ _null_ interval_avg _null_ _null_ _null_ _null_ ) +insert ( 1962 int2_avg_accum 11 10 12 1 0 0 0 f f f t f i s 2 0 1016 '1016 21' _null_ _null_ _null_ _null_ _null_ int2_avg_accum _null_ _null_ _null_ _null_ ) +insert ( 1963 int4_avg_accum 11 10 12 1 0 0 0 f f f t f i s 2 0 1016 '1016 23' _null_ _null_ _null_ _null_ _null_ int4_avg_accum _null_ _null_ _null_ _null_ ) +insert ( 3570 int2_avg_accum_inv 11 10 12 1 0 0 0 f f f t f i s 2 0 1016 '1016 21' _null_ _null_ _null_ _null_ _null_ int2_avg_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 3571 int4_avg_accum_inv 11 10 12 1 0 0 0 f f f t f i s 2 0 1016 '1016 23' _null_ _null_ _null_ _null_ _null_ int4_avg_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 1964 int8_avg 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1016 _null_ _null_ _null_ _null_ _null_ int8_avg _null_ _null_ _null_ _null_ ) +insert ( 3572 int2int4_sum 11 10 12 1 0 0 0 f f f t f i s 1 0 20 1016 _null_ _null_ _null_ _null_ _null_ int2int4_sum _null_ _null_ _null_ _null_ ) +insert ( 2805 int8inc_float8_float8 11 10 12 1 0 0 0 f f f t f i s 3 0 20 '20 701 701' _null_ _null_ _null_ _null_ _null_ int8inc_float8_float8 _null_ _null_ _null_ _null_ ) +insert ( 2806 float8_regr_accum 11 10 12 1 0 0 0 f f f t f i s 3 0 1022 '1022 701 701' _null_ _null_ _null_ _null_ _null_ float8_regr_accum _null_ _null_ _null_ _null_ ) +insert ( 3342 float8_regr_combine 11 10 12 1 0 0 0 f f f t f i s 2 0 1022 '1022 1022' _null_ _null_ _null_ _null_ _null_ float8_regr_combine _null_ _null_ _null_ _null_ ) +insert ( 2807 float8_regr_sxx 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_sxx _null_ _null_ _null_ _null_ ) +insert ( 2808 float8_regr_syy 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_syy _null_ _null_ _null_ _null_ ) +insert ( 2809 float8_regr_sxy 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_sxy _null_ _null_ _null_ _null_ ) +insert ( 2810 float8_regr_avgx 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_avgx _null_ _null_ _null_ _null_ ) +insert ( 2811 float8_regr_avgy 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_avgy _null_ _null_ _null_ _null_ ) +insert ( 2812 float8_regr_r2 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_r2 _null_ _null_ _null_ _null_ ) +insert ( 2813 float8_regr_slope 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_slope _null_ _null_ _null_ _null_ ) +insert ( 2814 float8_regr_intercept 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_regr_intercept _null_ _null_ _null_ _null_ ) +insert ( 2815 float8_covar_pop 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_covar_pop _null_ _null_ _null_ _null_ ) +insert ( 2816 float8_covar_samp 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_covar_samp _null_ _null_ _null_ _null_ ) +insert ( 2817 float8_corr 11 10 12 1 0 0 0 f f f t f i s 1 0 701 1022 _null_ _null_ _null_ _null_ _null_ float8_corr _null_ _null_ _null_ _null_ ) +insert ( 3535 string_agg_transfn 11 10 12 1 0 0 0 f f f f f i s 3 0 2281 '2281 25 25' _null_ _null_ _null_ _null_ _null_ string_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 6299 string_agg_combine 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ string_agg_combine _null_ _null_ _null_ _null_ ) +insert ( 6300 string_agg_serialize 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ string_agg_serialize _null_ _null_ _null_ _null_ ) +insert ( 6301 string_agg_deserialize 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '17 2281' _null_ _null_ _null_ _null_ _null_ string_agg_deserialize _null_ _null_ _null_ _null_ ) +insert ( 3536 string_agg_finalfn 11 10 12 1 0 0 0 f f f f f i s 1 0 25 2281 _null_ _null_ _null_ _null_ _null_ string_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 3538 string_agg 11 10 12 1 0 0 0 a f f f f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3543 bytea_string_agg_transfn 11 10 12 1 0 0 0 f f f f f i s 3 0 2281 '2281 17 17' _null_ _null_ _null_ _null_ _null_ bytea_string_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 3544 bytea_string_agg_finalfn 11 10 12 1 0 0 0 f f f f f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ bytea_string_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 3545 string_agg 11 10 12 1 0 0 0 a f f f f i s 2 0 17 '17 17' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 1845 to_ascii 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ to_ascii_default _null_ _null_ _null_ _null_ ) +insert ( 1846 to_ascii 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 23' _null_ _null_ _null_ _null_ _null_ to_ascii_enc _null_ _null_ _null_ _null_ ) +insert ( 1847 to_ascii 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 19' _null_ _null_ _null_ _null_ _null_ to_ascii_encname _null_ _null_ _null_ _null_ ) +insert ( 1848 interval_pl_time 11 10 14 1 0 0 0 f f f t f i s 2 0 1083 '1186 1083' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 1850 int28eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 20' _null_ _null_ _null_ _null_ _null_ int28eq _null_ _null_ _null_ _null_ ) +insert ( 1851 int28ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 20' _null_ _null_ _null_ _null_ _null_ int28ne _null_ _null_ _null_ _null_ ) +insert ( 1852 int28lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 20' _null_ _null_ _null_ _null_ _null_ int28lt _null_ _null_ _null_ _null_ ) +insert ( 1853 int28gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 20' _null_ _null_ _null_ _null_ _null_ int28gt _null_ _null_ _null_ _null_ ) +insert ( 1854 int28le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 20' _null_ _null_ _null_ _null_ _null_ int28le _null_ _null_ _null_ _null_ ) +insert ( 1855 int28ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '21 20' _null_ _null_ _null_ _null_ _null_ int28ge _null_ _null_ _null_ _null_ ) +insert ( 1856 int82eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 21' _null_ _null_ _null_ _null_ _null_ int82eq _null_ _null_ _null_ _null_ ) +insert ( 1857 int82ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 21' _null_ _null_ _null_ _null_ _null_ int82ne _null_ _null_ _null_ _null_ ) +insert ( 1858 int82lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 21' _null_ _null_ _null_ _null_ _null_ int82lt _null_ _null_ _null_ _null_ ) +insert ( 1859 int82gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 21' _null_ _null_ _null_ _null_ _null_ int82gt _null_ _null_ _null_ _null_ ) +insert ( 1860 int82le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 21' _null_ _null_ _null_ _null_ _null_ int82le _null_ _null_ _null_ _null_ ) +insert ( 1861 int82ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '20 21' _null_ _null_ _null_ _null_ _null_ int82ge _null_ _null_ _null_ _null_ ) +insert ( 1892 int2and 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2and _null_ _null_ _null_ _null_ ) +insert ( 1893 int2or 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2or _null_ _null_ _null_ _null_ ) +insert ( 1894 int2xor 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 21' _null_ _null_ _null_ _null_ _null_ int2xor _null_ _null_ _null_ _null_ ) +insert ( 1895 int2not 11 10 12 1 0 0 0 f f f t f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ int2not _null_ _null_ _null_ _null_ ) +insert ( 1896 int2shl 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 23' _null_ _null_ _null_ _null_ _null_ int2shl _null_ _null_ _null_ _null_ ) +insert ( 1897 int2shr 11 10 12 1 0 0 0 f f f t f i s 2 0 21 '21 23' _null_ _null_ _null_ _null_ _null_ int2shr _null_ _null_ _null_ _null_ ) +insert ( 1898 int4and 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4and _null_ _null_ _null_ _null_ ) +insert ( 1899 int4or 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4or _null_ _null_ _null_ _null_ ) +insert ( 1900 int4xor 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4xor _null_ _null_ _null_ _null_ ) +insert ( 1901 int4not 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ int4not _null_ _null_ _null_ _null_ ) +insert ( 1902 int4shl 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4shl _null_ _null_ _null_ _null_ ) +insert ( 1903 int4shr 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ int4shr _null_ _null_ _null_ _null_ ) +insert ( 1904 int8and 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8and _null_ _null_ _null_ _null_ ) +insert ( 1905 int8or 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8or _null_ _null_ _null_ _null_ ) +insert ( 1906 int8xor 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ int8xor _null_ _null_ _null_ _null_ ) +insert ( 1907 int8not 11 10 12 1 0 0 0 f f f t f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ int8not _null_ _null_ _null_ _null_ ) +insert ( 1908 int8shl 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 23' _null_ _null_ _null_ _null_ _null_ int8shl _null_ _null_ _null_ _null_ ) +insert ( 1909 int8shr 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '20 23' _null_ _null_ _null_ _null_ _null_ int8shr _null_ _null_ _null_ _null_ ) +insert ( 1910 int8up 11 10 12 1 0 0 0 f f f t f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ int8up _null_ _null_ _null_ _null_ ) +insert ( 1911 int2up 11 10 12 1 0 0 0 f f f t f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ int2up _null_ _null_ _null_ _null_ ) +insert ( 1912 int4up 11 10 12 1 0 0 0 f f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ int4up _null_ _null_ _null_ _null_ ) +insert ( 1913 float4up 11 10 12 1 0 0 0 f f f t f i s 1 0 700 700 _null_ _null_ _null_ _null_ _null_ float4up _null_ _null_ _null_ _null_ ) +insert ( 1914 float8up 11 10 12 1 0 0 0 f f f t f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ float8up _null_ _null_ _null_ _null_ ) +insert ( 1915 numeric_uplus 11 10 12 1 0 0 0 f f f t f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ numeric_uplus _null_ _null_ _null_ _null_ ) +insert ( 1922 has_table_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_table_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 1923 has_table_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_table_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 1924 has_table_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_table_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 1925 has_table_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_table_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 1926 has_table_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_table_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 1927 has_table_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_table_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 2181 has_sequence_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_sequence_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 2182 has_sequence_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_sequence_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 2183 has_sequence_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_sequence_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 2184 has_sequence_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_sequence_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 2185 has_sequence_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_sequence_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 2186 has_sequence_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_sequence_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 3012 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '19 25 25 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_name_name_name _null_ _null_ _null_ _null_ ) +insert ( 3013 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '19 25 21 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_name_name_attnum _null_ _null_ _null_ _null_ ) +insert ( 3014 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '19 26 25 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_name_id_name _null_ _null_ _null_ _null_ ) +insert ( 3015 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '19 26 21 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_name_id_attnum _null_ _null_ _null_ _null_ ) +insert ( 3016 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '26 25 25 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_id_name_name _null_ _null_ _null_ _null_ ) +insert ( 3017 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '26 25 21 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_id_name_attnum _null_ _null_ _null_ _null_ ) +insert ( 3018 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '26 26 25 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_id_id_name _null_ _null_ _null_ _null_ ) +insert ( 3019 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '26 26 21 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_id_id_attnum _null_ _null_ _null_ _null_ ) +insert ( 3020 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '25 25 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 3021 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '25 21 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_name_attnum _null_ _null_ _null_ _null_ ) +insert ( 3022 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 3023 has_column_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 21 25' _null_ _null_ _null_ _null_ _null_ has_column_privilege_id_attnum _null_ _null_ _null_ _null_ ) +insert ( 3024 has_any_column_privilege 11 10 12 10 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_any_column_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 3025 has_any_column_privilege 11 10 12 10 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_any_column_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 3026 has_any_column_privilege 11 10 12 10 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_any_column_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 3027 has_any_column_privilege 11 10 12 10 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_any_column_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 3028 has_any_column_privilege 11 10 12 10 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_any_column_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 3029 has_any_column_privilege 11 10 12 10 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_any_column_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 3355 pg_ndistinct_in 11 10 12 1 0 0 0 f f f t f i s 1 0 3361 2275 _null_ _null_ _null_ _null_ _null_ pg_ndistinct_in _null_ _null_ _null_ _null_ ) +insert ( 3356 pg_ndistinct_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3361 _null_ _null_ _null_ _null_ _null_ pg_ndistinct_out _null_ _null_ _null_ _null_ ) +insert ( 3357 pg_ndistinct_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 3361 2281 _null_ _null_ _null_ _null_ _null_ pg_ndistinct_recv _null_ _null_ _null_ _null_ ) +insert ( 3358 pg_ndistinct_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 3361 _null_ _null_ _null_ _null_ _null_ pg_ndistinct_send _null_ _null_ _null_ _null_ ) +insert ( 3404 pg_dependencies_in 11 10 12 1 0 0 0 f f f t f i s 1 0 3402 2275 _null_ _null_ _null_ _null_ _null_ pg_dependencies_in _null_ _null_ _null_ _null_ ) +insert ( 3405 pg_dependencies_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3402 _null_ _null_ _null_ _null_ _null_ pg_dependencies_out _null_ _null_ _null_ _null_ ) +insert ( 3406 pg_dependencies_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 3402 2281 _null_ _null_ _null_ _null_ _null_ pg_dependencies_recv _null_ _null_ _null_ _null_ ) +insert ( 3407 pg_dependencies_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 3402 _null_ _null_ _null_ _null_ _null_ pg_dependencies_send _null_ _null_ _null_ _null_ ) +insert ( 5018 pg_mcv_list_in 11 10 12 1 0 0 0 f f f t f i s 1 0 5017 2275 _null_ _null_ _null_ _null_ _null_ pg_mcv_list_in _null_ _null_ _null_ _null_ ) +insert ( 5019 pg_mcv_list_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 5017 _null_ _null_ _null_ _null_ _null_ pg_mcv_list_out _null_ _null_ _null_ _null_ ) +insert ( 5020 pg_mcv_list_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 5017 2281 _null_ _null_ _null_ _null_ _null_ pg_mcv_list_recv _null_ _null_ _null_ _null_ ) +insert ( 5021 pg_mcv_list_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 5017 _null_ _null_ _null_ _null_ _null_ pg_mcv_list_send _null_ _null_ _null_ _null_ ) +insert ( 3427 pg_mcv_list_items 11 10 12 1 1000 0 0 f f f t t s s 1 0 2249 5017 '{5017,23,1009,1000,701,701}' '{i,o,o,o,o,o}' '{mcv_list,index,values,nulls,frequency,base_frequency}' _null_ _null_ pg_stats_ext_mcvlist_items _null_ _null_ _null_ _null_ ) +insert ( 1928 pg_stat_get_numscans 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_numscans _null_ _null_ _null_ _null_ ) +insert ( 6310 pg_stat_get_lastscan 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_lastscan _null_ _null_ _null_ _null_ ) +insert ( 1929 pg_stat_get_tuples_returned 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_tuples_returned _null_ _null_ _null_ _null_ ) +insert ( 1930 pg_stat_get_tuples_fetched 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_tuples_fetched _null_ _null_ _null_ _null_ ) +insert ( 1931 pg_stat_get_tuples_inserted 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_tuples_inserted _null_ _null_ _null_ _null_ ) +insert ( 1932 pg_stat_get_tuples_updated 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_tuples_updated _null_ _null_ _null_ _null_ ) +insert ( 1933 pg_stat_get_tuples_deleted 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_tuples_deleted _null_ _null_ _null_ _null_ ) +insert ( 1972 pg_stat_get_tuples_hot_updated 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_tuples_hot_updated _null_ _null_ _null_ _null_ ) +insert ( 6217 pg_stat_get_tuples_newpage_updated 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_tuples_newpage_updated _null_ _null_ _null_ _null_ ) +insert ( 2878 pg_stat_get_live_tuples 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_live_tuples _null_ _null_ _null_ _null_ ) +insert ( 2879 pg_stat_get_dead_tuples 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_dead_tuples _null_ _null_ _null_ _null_ ) +insert ( 3177 pg_stat_get_mod_since_analyze 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_mod_since_analyze _null_ _null_ _null_ _null_ ) +insert ( 5053 pg_stat_get_ins_since_vacuum 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_ins_since_vacuum _null_ _null_ _null_ _null_ ) +insert ( 1934 pg_stat_get_blocks_fetched 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_blocks_fetched _null_ _null_ _null_ _null_ ) +insert ( 1935 pg_stat_get_blocks_hit 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_blocks_hit _null_ _null_ _null_ _null_ ) +insert ( 2781 pg_stat_get_last_vacuum_time 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_last_vacuum_time _null_ _null_ _null_ _null_ ) +insert ( 2782 pg_stat_get_last_autovacuum_time 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_last_autovacuum_time _null_ _null_ _null_ _null_ ) +insert ( 2783 pg_stat_get_last_analyze_time 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_last_analyze_time _null_ _null_ _null_ _null_ ) +insert ( 2784 pg_stat_get_last_autoanalyze_time 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_last_autoanalyze_time _null_ _null_ _null_ _null_ ) +insert ( 3054 pg_stat_get_vacuum_count 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_vacuum_count _null_ _null_ _null_ _null_ ) +insert ( 3055 pg_stat_get_autovacuum_count 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_autovacuum_count _null_ _null_ _null_ _null_ ) +insert ( 3056 pg_stat_get_analyze_count 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_analyze_count _null_ _null_ _null_ _null_ ) +insert ( 3057 pg_stat_get_autoanalyze_count 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_autoanalyze_count _null_ _null_ _null_ _null_ ) +insert ( 1936 pg_stat_get_backend_idset 11 10 12 1 100 0 0 f f f t t s r 0 0 23 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_idset _null_ _null_ _null_ _null_ ) +insert ( 2022 pg_stat_get_activity 11 10 12 1 100 0 0 f f f f t s r 1 0 2249 23 '{23,26,23,26,25,25,25,25,25,1184,1184,1184,1184,869,25,23,28,28,25,16,25,25,23,25,1700,25,16,25,16,16,23,20}' '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}' _null_ _null_ pg_stat_get_activity _null_ _null_ _null_ _null_ ) +insert ( 3318 pg_stat_get_progress_info 11 10 12 1 100 0 0 f f f t t s r 1 0 2249 25 '{25,23,26,26,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20}' '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{cmdtype,pid,datid,relid,param1,param2,param3,param4,param5,param6,param7,param8,param9,param10,param11,param12,param13,param14,param15,param16,param17,param18,param19,param20}' _null_ _null_ pg_stat_get_progress_info _null_ _null_ _null_ _null_ ) +insert ( 3099 pg_stat_get_wal_senders 11 10 12 1 10 0 0 f f f f t s r 0 0 2249 '' '{23,25,3220,3220,3220,3220,1186,1186,1186,23,25,1184}' '{o,o,o,o,o,o,o,o,o,o,o,o}' '{pid,state,sent_lsn,write_lsn,flush_lsn,replay_lsn,write_lag,flush_lag,replay_lag,sync_priority,sync_state,reply_time}' _null_ _null_ pg_stat_get_wal_senders _null_ _null_ _null_ _null_ ) +insert ( 3317 pg_stat_get_wal_receiver 11 10 12 1 0 0 0 f f f f f s r 0 0 2249 '' '{23,25,3220,23,3220,3220,23,1184,1184,3220,1184,25,25,23,25}' '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{pid,status,receive_start_lsn,receive_start_tli,written_lsn,flushed_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,sender_host,sender_port,conninfo}' _null_ _null_ pg_stat_get_wal_receiver _null_ _null_ _null_ _null_ ) +insert ( 6169 pg_stat_get_replication_slot 11 10 12 1 0 0 0 f f f t f s r 1 0 2249 25 '{25,25,20,20,20,20,20,20,20,20,1184}' '{i,o,o,o,o,o,o,o,o,o,o}' '{slot_name,slot_name,spill_txns,spill_count,spill_bytes,stream_txns,stream_count,stream_bytes,total_txns,total_bytes,stats_reset}' _null_ _null_ pg_stat_get_replication_slot _null_ _null_ _null_ _null_ ) +insert ( 6230 pg_stat_have_stats 11 10 12 1 0 0 0 f f f t f v r 3 0 16 '25 26 26' _null_ _null_ _null_ _null_ _null_ pg_stat_have_stats _null_ _null_ _null_ _null_ ) +insert ( 6231 pg_stat_get_subscription_stats 11 10 12 1 0 0 0 f f f t f s r 1 0 2249 26 '{26,26,20,20,1184}' '{i,o,o,o,o}' '{subid,subid,apply_error_count,sync_error_count,stats_reset}' _null_ _null_ pg_stat_get_subscription_stats _null_ _null_ _null_ _null_ ) +insert ( 6118 pg_stat_get_subscription 11 10 12 1 10 0 0 f f f f t s r 1 0 2249 26 '{26,26,26,23,23,3220,1184,1184,3220,1184}' '{i,o,o,o,o,o,o,o,o,o}' '{subid,subid,relid,pid,leader_pid,received_lsn,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time}' _null_ _null_ pg_stat_get_subscription _null_ _null_ _null_ _null_ ) +insert ( 2026 pg_backend_pid 11 10 12 1 0 0 0 f f f t f s r 0 0 23 '' _null_ _null_ _null_ _null_ _null_ pg_backend_pid _null_ _null_ _null_ _null_ ) +insert ( 1937 pg_stat_get_backend_pid 11 10 12 1 0 0 0 f f f t f s r 1 0 23 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_pid _null_ _null_ _null_ _null_ ) +insert ( 1938 pg_stat_get_backend_dbid 11 10 12 1 0 0 0 f f f t f s r 1 0 26 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_dbid _null_ _null_ _null_ _null_ ) +insert ( 6107 pg_stat_get_backend_subxact 11 10 12 1 0 0 0 f f f t f s r 1 0 2249 23 '{23,23,16}' '{i,o,o}' '{bid,subxact_count,subxact_overflowed}' _null_ _null_ pg_stat_get_backend_subxact _null_ _null_ _null_ _null_ ) +insert ( 1939 pg_stat_get_backend_userid 11 10 12 1 0 0 0 f f f t f s r 1 0 26 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_userid _null_ _null_ _null_ _null_ ) +insert ( 1940 pg_stat_get_backend_activity 11 10 12 1 0 0 0 f f f t f s r 1 0 25 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_activity _null_ _null_ _null_ _null_ ) +insert ( 2788 pg_stat_get_backend_wait_event_type 11 10 12 1 0 0 0 f f f t f s r 1 0 25 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_wait_event_type _null_ _null_ _null_ _null_ ) +insert ( 2853 pg_stat_get_backend_wait_event 11 10 12 1 0 0 0 f f f t f s r 1 0 25 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_wait_event _null_ _null_ _null_ _null_ ) +insert ( 2094 pg_stat_get_backend_activity_start 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_activity_start _null_ _null_ _null_ _null_ ) +insert ( 2857 pg_stat_get_backend_xact_start 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_xact_start _null_ _null_ _null_ _null_ ) +insert ( 1391 pg_stat_get_backend_start 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_start _null_ _null_ _null_ _null_ ) +insert ( 1392 pg_stat_get_backend_client_addr 11 10 12 1 0 0 0 f f f t f s r 1 0 869 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_client_addr _null_ _null_ _null_ _null_ ) +insert ( 1393 pg_stat_get_backend_client_port 11 10 12 1 0 0 0 f f f t f s r 1 0 23 23 _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_client_port _null_ _null_ _null_ _null_ ) +insert ( 1941 pg_stat_get_db_numbackends 11 10 12 1 0 0 0 f f f t f s r 1 0 23 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_numbackends _null_ _null_ _null_ _null_ ) +insert ( 1942 pg_stat_get_db_xact_commit 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_xact_commit _null_ _null_ _null_ _null_ ) +insert ( 1943 pg_stat_get_db_xact_rollback 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_xact_rollback _null_ _null_ _null_ _null_ ) +insert ( 1944 pg_stat_get_db_blocks_fetched 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_blocks_fetched _null_ _null_ _null_ _null_ ) +insert ( 1945 pg_stat_get_db_blocks_hit 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_blocks_hit _null_ _null_ _null_ _null_ ) +insert ( 2758 pg_stat_get_db_tuples_returned 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_tuples_returned _null_ _null_ _null_ _null_ ) +insert ( 2759 pg_stat_get_db_tuples_fetched 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_tuples_fetched _null_ _null_ _null_ _null_ ) +insert ( 2760 pg_stat_get_db_tuples_inserted 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_tuples_inserted _null_ _null_ _null_ _null_ ) +insert ( 2761 pg_stat_get_db_tuples_updated 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_tuples_updated _null_ _null_ _null_ _null_ ) +insert ( 2762 pg_stat_get_db_tuples_deleted 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_tuples_deleted _null_ _null_ _null_ _null_ ) +insert ( 3065 pg_stat_get_db_conflict_tablespace 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_tablespace _null_ _null_ _null_ _null_ ) +insert ( 3066 pg_stat_get_db_conflict_lock 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_lock _null_ _null_ _null_ _null_ ) +insert ( 3067 pg_stat_get_db_conflict_snapshot 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_snapshot _null_ _null_ _null_ _null_ ) +insert ( 6309 pg_stat_get_db_conflict_logicalslot 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_logicalslot _null_ _null_ _null_ _null_ ) +insert ( 3068 pg_stat_get_db_conflict_bufferpin 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_bufferpin _null_ _null_ _null_ _null_ ) +insert ( 3069 pg_stat_get_db_conflict_startup_deadlock 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_startup_deadlock _null_ _null_ _null_ _null_ ) +insert ( 3070 pg_stat_get_db_conflict_all 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_all _null_ _null_ _null_ _null_ ) +insert ( 3152 pg_stat_get_db_deadlocks 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_deadlocks _null_ _null_ _null_ _null_ ) +insert ( 3426 pg_stat_get_db_checksum_failures 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_checksum_failures _null_ _null_ _null_ _null_ ) +insert ( 3428 pg_stat_get_db_checksum_last_failure 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_checksum_last_failure _null_ _null_ _null_ _null_ ) +insert ( 3074 pg_stat_get_db_stat_reset_time 11 10 12 1 0 0 0 f f f t f s r 1 0 1184 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_stat_reset_time _null_ _null_ _null_ _null_ ) +insert ( 3150 pg_stat_get_db_temp_files 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_temp_files _null_ _null_ _null_ _null_ ) +insert ( 3151 pg_stat_get_db_temp_bytes 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_temp_bytes _null_ _null_ _null_ _null_ ) +insert ( 2844 pg_stat_get_db_blk_read_time 11 10 12 1 0 0 0 f f f t f s r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_blk_read_time _null_ _null_ _null_ _null_ ) +insert ( 2845 pg_stat_get_db_blk_write_time 11 10 12 1 0 0 0 f f f t f s r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_blk_write_time _null_ _null_ _null_ _null_ ) +insert ( 6185 pg_stat_get_db_session_time 11 10 12 1 0 0 0 f f f t f s r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_session_time _null_ _null_ _null_ _null_ ) +insert ( 6186 pg_stat_get_db_active_time 11 10 12 1 0 0 0 f f f t f s r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_active_time _null_ _null_ _null_ _null_ ) +insert ( 6187 pg_stat_get_db_idle_in_transaction_time 11 10 12 1 0 0 0 f f f t f s r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_idle_in_transaction_time _null_ _null_ _null_ _null_ ) +insert ( 6188 pg_stat_get_db_sessions 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_sessions _null_ _null_ _null_ _null_ ) +insert ( 6189 pg_stat_get_db_sessions_abandoned 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_sessions_abandoned _null_ _null_ _null_ _null_ ) +insert ( 6190 pg_stat_get_db_sessions_fatal 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_sessions_fatal _null_ _null_ _null_ _null_ ) +insert ( 6191 pg_stat_get_db_sessions_killed 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_db_sessions_killed _null_ _null_ _null_ _null_ ) +insert ( 3195 pg_stat_get_archiver 11 10 12 1 0 0 0 f f f f f s r 0 0 2249 '' '{20,25,1184,20,25,1184,1184}' '{o,o,o,o,o,o,o}' '{archived_count,last_archived_wal,last_archived_time,failed_count,last_failed_wal,last_failed_time,stats_reset}' _null_ _null_ pg_stat_get_archiver _null_ _null_ _null_ _null_ ) +insert ( 2769 pg_stat_get_bgwriter_timed_checkpoints 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_timed_checkpoints _null_ _null_ _null_ _null_ ) +insert ( 2770 pg_stat_get_bgwriter_requested_checkpoints 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_requested_checkpoints _null_ _null_ _null_ _null_ ) +insert ( 2771 pg_stat_get_bgwriter_buf_written_checkpoints 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_buf_written_checkpoints _null_ _null_ _null_ _null_ ) +insert ( 2772 pg_stat_get_bgwriter_buf_written_clean 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_buf_written_clean _null_ _null_ _null_ _null_ ) +insert ( 2773 pg_stat_get_bgwriter_maxwritten_clean 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_maxwritten_clean _null_ _null_ _null_ _null_ ) +insert ( 3075 pg_stat_get_bgwriter_stat_reset_time 11 10 12 1 0 0 0 f f f t f s r 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_stat_reset_time _null_ _null_ _null_ _null_ ) +insert ( 3160 pg_stat_get_checkpoint_write_time 11 10 12 1 0 0 0 f f f t f s r 0 0 701 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_checkpoint_write_time _null_ _null_ _null_ _null_ ) +insert ( 3161 pg_stat_get_checkpoint_sync_time 11 10 12 1 0 0 0 f f f t f s r 0 0 701 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_checkpoint_sync_time _null_ _null_ _null_ _null_ ) +insert ( 2775 pg_stat_get_buf_written_backend 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_buf_written_backend _null_ _null_ _null_ _null_ ) +insert ( 3063 pg_stat_get_buf_fsync_backend 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_buf_fsync_backend _null_ _null_ _null_ _null_ ) +insert ( 2859 pg_stat_get_buf_alloc 11 10 12 1 0 0 0 f f f t f s r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_buf_alloc _null_ _null_ _null_ _null_ ) +insert ( 6214 pg_stat_get_io 11 10 12 1 30 0 0 f f f t t v r 0 0 2249 '' '{25,25,25,20,701,20,701,20,701,20,701,20,20,20,20,20,701,1184}' '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{backend_type,object,context,reads,read_time,writes,write_time,writebacks,writeback_time,extends,extend_time,op_bytes,hits,evictions,reuses,fsyncs,fsync_time,stats_reset}' _null_ _null_ pg_stat_get_io _null_ _null_ _null_ _null_ ) +insert ( 1136 pg_stat_get_wal 11 10 12 1 0 0 0 f f f f f s r 0 0 2249 '' '{20,20,1700,20,20,20,701,701,1184}' '{o,o,o,o,o,o,o,o,o}' '{wal_records,wal_fpi,wal_bytes,wal_buffers_full,wal_write,wal_sync,wal_write_time,wal_sync_time,stats_reset}' _null_ _null_ pg_stat_get_wal _null_ _null_ _null_ _null_ ) +insert ( 6248 pg_stat_get_recovery_prefetch 11 10 12 1 1 0 0 f f f t t v s 0 0 2249 '' '{1184,20,20,20,20,20,20,23,23,23}' '{o,o,o,o,o,o,o,o,o,o}' '{stats_reset,prefetch,hit,skip_init,skip_new,skip_fpw,skip_rep,wal_distance,block_distance,io_depth}' _null_ _null_ pg_stat_get_recovery_prefetch _null_ _null_ _null_ _null_ ) +insert ( 2306 pg_stat_get_slru 11 10 12 1 100 0 0 f f f f t s r 0 0 2249 '' '{25,20,20,20,20,20,20,20,1184}' '{o,o,o,o,o,o,o,o,o}' '{name,blks_zeroed,blks_hit,blks_read,blks_written,blks_exists,flushes,truncates,stats_reset}' _null_ _null_ pg_stat_get_slru _null_ _null_ _null_ _null_ ) +insert ( 2978 pg_stat_get_function_calls 11 10 12 1 0 0 0 f f f t f s r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_function_calls _null_ _null_ _null_ _null_ ) +insert ( 2979 pg_stat_get_function_total_time 11 10 12 1 0 0 0 f f f t f s r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_function_total_time _null_ _null_ _null_ _null_ ) +insert ( 2980 pg_stat_get_function_self_time 11 10 12 1 0 0 0 f f f t f s r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_function_self_time _null_ _null_ _null_ _null_ ) +insert ( 3037 pg_stat_get_xact_numscans 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_numscans _null_ _null_ _null_ _null_ ) +insert ( 3038 pg_stat_get_xact_tuples_returned 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_tuples_returned _null_ _null_ _null_ _null_ ) +insert ( 3039 pg_stat_get_xact_tuples_fetched 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_tuples_fetched _null_ _null_ _null_ _null_ ) +insert ( 3040 pg_stat_get_xact_tuples_inserted 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_tuples_inserted _null_ _null_ _null_ _null_ ) +insert ( 3041 pg_stat_get_xact_tuples_updated 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_tuples_updated _null_ _null_ _null_ _null_ ) +insert ( 3042 pg_stat_get_xact_tuples_deleted 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_tuples_deleted _null_ _null_ _null_ _null_ ) +insert ( 3043 pg_stat_get_xact_tuples_hot_updated 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_tuples_hot_updated _null_ _null_ _null_ _null_ ) +insert ( 6218 pg_stat_get_xact_tuples_newpage_updated 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_tuples_newpage_updated _null_ _null_ _null_ _null_ ) +insert ( 3044 pg_stat_get_xact_blocks_fetched 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_blocks_fetched _null_ _null_ _null_ _null_ ) +insert ( 3045 pg_stat_get_xact_blocks_hit 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_blocks_hit _null_ _null_ _null_ _null_ ) +insert ( 3046 pg_stat_get_xact_function_calls 11 10 12 1 0 0 0 f f f t f v r 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_function_calls _null_ _null_ _null_ _null_ ) +insert ( 3047 pg_stat_get_xact_function_total_time 11 10 12 1 0 0 0 f f f t f v r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_function_total_time _null_ _null_ _null_ _null_ ) +insert ( 3048 pg_stat_get_xact_function_self_time 11 10 12 1 0 0 0 f f f t f v r 1 0 701 26 _null_ _null_ _null_ _null_ _null_ pg_stat_get_xact_function_self_time _null_ _null_ _null_ _null_ ) +insert ( 3788 pg_stat_get_snapshot_timestamp 11 10 12 1 0 0 0 f f f t f s r 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ pg_stat_get_snapshot_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2230 pg_stat_clear_snapshot 11 10 12 1 0 0 0 f f f f f v r 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_stat_clear_snapshot _null_ _null_ _null_ _null_ ) +insert ( 2137 pg_stat_force_next_flush 11 10 12 1 0 0 0 f f f f f v r 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_stat_force_next_flush _null_ _null_ _null_ _null_ ) +insert ( 2274 pg_stat_reset 11 10 12 1 0 0 0 f f f f f v s 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_stat_reset _null_ _null_ _null_ _null_ ) +insert ( 3775 pg_stat_reset_shared 11 10 12 1 0 0 0 f f f t f v s 1 0 2278 25 _null_ _null_ _null_ _null_ _null_ pg_stat_reset_shared _null_ _null_ _null_ _null_ ) +insert ( 3776 pg_stat_reset_single_table_counters 11 10 12 1 0 0 0 f f f t f v s 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ pg_stat_reset_single_table_counters _null_ _null_ _null_ _null_ ) +insert ( 3777 pg_stat_reset_single_function_counters 11 10 12 1 0 0 0 f f f t f v s 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ pg_stat_reset_single_function_counters _null_ _null_ _null_ _null_ ) +insert ( 2307 pg_stat_reset_slru 11 10 12 1 0 0 0 f f f f f v s 1 0 2278 25 _null_ _null_ _null_ _null_ _null_ pg_stat_reset_slru _null_ _null_ _null_ _null_ ) +insert ( 6170 pg_stat_reset_replication_slot 11 10 12 1 0 0 0 f f f f f v s 1 0 2278 25 _null_ _null_ _null_ _null_ _null_ pg_stat_reset_replication_slot _null_ _null_ _null_ _null_ ) +insert ( 6232 pg_stat_reset_subscription_stats 11 10 12 1 0 0 0 f f f f f v s 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ pg_stat_reset_subscription_stats _null_ _null_ _null_ _null_ ) +insert ( 3163 pg_trigger_depth 11 10 12 1 0 0 0 f f f t f s r 0 0 23 '' _null_ _null_ _null_ _null_ _null_ pg_trigger_depth _null_ _null_ _null_ _null_ ) +insert ( 3778 pg_tablespace_location 11 10 12 1 0 0 0 f f f t f s s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_tablespace_location _null_ _null_ _null_ _null_ ) +insert ( 1946 encode 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '17 25' _null_ _null_ _null_ _null_ _null_ binary_encode _null_ _null_ _null_ _null_ ) +insert ( 1947 decode 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '25 25' _null_ _null_ _null_ _null_ _null_ binary_decode _null_ _null_ _null_ _null_ ) +insert ( 1948 byteaeq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ byteaeq _null_ _null_ _null_ _null_ ) +insert ( 1949 bytealt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ bytealt _null_ _null_ _null_ _null_ ) +insert ( 1950 byteale 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ byteale _null_ _null_ _null_ _null_ ) +insert ( 1951 byteagt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ byteagt _null_ _null_ _null_ _null_ ) +insert ( 1952 byteage 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ byteage _null_ _null_ _null_ _null_ ) +insert ( 1953 byteane 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ byteane _null_ _null_ _null_ _null_ ) +insert ( 1954 byteacmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '17 17' _null_ _null_ _null_ _null_ _null_ byteacmp _null_ _null_ _null_ _null_ ) +insert ( 3331 bytea_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ bytea_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 3917 timestamp_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ timestamp_support _null_ _null_ _null_ _null_ ) +insert ( 3944 time_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ time_support _null_ _null_ _null_ _null_ ) +insert ( 1961 timestamp 11 10 12 1 0 0 3917 f f f t f i s 2 0 1114 '1114 23' _null_ _null_ _null_ _null_ _null_ timestamp_scale _null_ _null_ _null_ _null_ ) +insert ( 1965 oidlarger 11 10 12 1 0 0 0 f f f t f i s 2 0 26 '26 26' _null_ _null_ _null_ _null_ _null_ oidlarger _null_ _null_ _null_ _null_ ) +insert ( 1966 oidsmaller 11 10 12 1 0 0 0 f f f t f i s 2 0 26 '26 26' _null_ _null_ _null_ _null_ _null_ oidsmaller _null_ _null_ _null_ _null_ ) +insert ( 1967 timestamptz 11 10 12 1 0 0 3917 f f f t f i s 2 0 1184 '1184 23' _null_ _null_ _null_ _null_ _null_ timestamptz_scale _null_ _null_ _null_ _null_ ) +insert ( 1968 time 11 10 12 1 0 0 3944 f f f t f i s 2 0 1083 '1083 23' _null_ _null_ _null_ _null_ _null_ time_scale _null_ _null_ _null_ _null_ ) +insert ( 1969 timetz 11 10 12 1 0 0 3944 f f f t f i s 2 0 1266 '1266 23' _null_ _null_ _null_ _null_ _null_ timetz_scale _null_ _null_ _null_ _null_ ) +insert ( 2003 textanycat 11 10 14 1 0 0 0 f f f t f s s 2 0 25 '25 2776' _null_ _null_ _null_ _null_ _null_ 'select $1 operator(pg_catalog.||) $2::pg_catalog.text' _null_ _null_ _null_ _null_ ) +insert ( 2004 anytextcat 11 10 14 1 0 0 0 f f f t f s s 2 0 25 '2776 25' _null_ _null_ _null_ _null_ _null_ 'select $1::pg_catalog.text operator(pg_catalog.||) $2' _null_ _null_ _null_ _null_ ) +insert ( 2005 bytealike 11 10 12 1 0 0 1023 f f f t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ bytealike _null_ _null_ _null_ _null_ ) +insert ( 2006 byteanlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ byteanlike _null_ _null_ _null_ _null_ ) +insert ( 2007 like 11 10 12 1 0 0 1023 f f f t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ bytealike _null_ _null_ _null_ _null_ ) +insert ( 2008 notlike 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '17 17' _null_ _null_ _null_ _null_ _null_ byteanlike _null_ _null_ _null_ _null_ ) +insert ( 2009 like_escape 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '17 17' _null_ _null_ _null_ _null_ _null_ like_escape_bytea _null_ _null_ _null_ _null_ ) +insert ( 2010 length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 17 _null_ _null_ _null_ _null_ _null_ byteaoctetlen _null_ _null_ _null_ _null_ ) +insert ( 2011 byteacat 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '17 17' _null_ _null_ _null_ _null_ _null_ byteacat _null_ _null_ _null_ _null_ ) +insert ( 2012 substring 11 10 12 1 0 0 0 f f f t f i s 3 0 17 '17 23 23' _null_ _null_ _null_ _null_ _null_ bytea_substr _null_ _null_ _null_ _null_ ) +insert ( 2013 substring 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '17 23' _null_ _null_ _null_ _null_ _null_ bytea_substr_no_len _null_ _null_ _null_ _null_ ) +insert ( 2085 substr 11 10 12 1 0 0 0 f f f t f i s 3 0 17 '17 23 23' _null_ _null_ _null_ _null_ _null_ bytea_substr _null_ _null_ _null_ _null_ ) +insert ( 2086 substr 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '17 23' _null_ _null_ _null_ _null_ _null_ bytea_substr_no_len _null_ _null_ _null_ _null_ ) +insert ( 2014 position 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '17 17' _null_ _null_ _null_ _null_ _null_ byteapos _null_ _null_ _null_ _null_ ) +insert ( 2015 btrim 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '17 17' _null_ _null_ _null_ _null_ _null_ byteatrim _null_ _null_ _null_ _null_ ) +insert ( 6195 ltrim 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '17 17' _null_ _null_ _null_ _null_ _null_ bytealtrim _null_ _null_ _null_ _null_ ) +insert ( 6196 rtrim 11 10 12 1 0 0 0 f f f t f i s 2 0 17 '17 17' _null_ _null_ _null_ _null_ _null_ byteartrim _null_ _null_ _null_ _null_ ) +insert ( 2019 time 11 10 12 1 0 0 0 f f f t f s s 1 0 1083 1184 _null_ _null_ _null_ _null_ _null_ timestamptz_time _null_ _null_ _null_ _null_ ) +insert ( 2020 date_trunc 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '25 1114' _null_ _null_ _null_ _null_ _null_ timestamp_trunc _null_ _null_ _null_ _null_ ) +insert ( 6177 date_bin 11 10 12 1 0 0 0 f f f t f i s 3 0 1114 '1186 1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_bin _null_ _null_ _null_ _null_ ) +insert ( 6178 date_bin 11 10 12 1 0 0 0 f f f t f i s 3 0 1184 '1186 1184 1184' _null_ _null_ _null_ _null_ _null_ timestamptz_bin _null_ _null_ _null_ _null_ ) +insert ( 2021 date_part 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '25 1114' _null_ _null_ _null_ _null_ _null_ timestamp_part _null_ _null_ _null_ _null_ ) +insert ( 6202 extract 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '25 1114' _null_ _null_ _null_ _null_ _null_ extract_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2024 timestamp 11 10 12 1 0 0 0 f f f t f i s 1 0 1114 1082 _null_ _null_ _null_ _null_ _null_ date_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2025 timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1082 1083' _null_ _null_ _null_ _null_ _null_ datetime_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2027 timestamp 11 10 12 1 0 0 0 f f f t f s s 1 0 1114 1184 _null_ _null_ _null_ _null_ _null_ timestamptz_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2028 timestamptz 11 10 12 1 0 0 0 f f f t f s s 1 0 1184 1114 _null_ _null_ _null_ _null_ _null_ timestamp_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2029 date 11 10 12 1 0 0 0 f f f t f i s 1 0 1082 1114 _null_ _null_ _null_ _null_ _null_ timestamp_date _null_ _null_ _null_ _null_ ) +insert ( 2031 timestamp_mi 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_mi _null_ _null_ _null_ _null_ ) +insert ( 2032 timestamp_pl_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1114 1186' _null_ _null_ _null_ _null_ _null_ timestamp_pl_interval _null_ _null_ _null_ _null_ ) +insert ( 2033 timestamp_mi_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1114 1186' _null_ _null_ _null_ _null_ _null_ timestamp_mi_interval _null_ _null_ _null_ _null_ ) +insert ( 2035 timestamp_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_smaller _null_ _null_ _null_ _null_ ) +insert ( 2036 timestamp_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_larger _null_ _null_ _null_ _null_ ) +insert ( 2037 timezone 11 10 12 1 0 0 0 f f f t f s s 2 0 1266 '25 1266' _null_ _null_ _null_ _null_ _null_ timetz_zone _null_ _null_ _null_ _null_ ) +insert ( 2038 timezone 11 10 12 1 0 0 0 f f f t f i s 2 0 1266 '1186 1266' _null_ _null_ _null_ _null_ _null_ timetz_izone _null_ _null_ _null_ _null_ ) +insert ( 2039 timestamp_hash 11 10 12 1 0 0 0 f f f t f i s 1 0 23 1114 _null_ _null_ _null_ _null_ _null_ timestamp_hash _null_ _null_ _null_ _null_ ) +insert ( 3411 timestamp_hash_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '1114 20' _null_ _null_ _null_ _null_ _null_ timestamp_hash_extended _null_ _null_ _null_ _null_ ) +insert ( 2041 overlaps 11 10 12 1 0 0 0 f f f f f i s 4 0 16 '1114 1114 1114 1114' _null_ _null_ _null_ _null_ _null_ overlaps_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2042 overlaps 11 10 14 1 0 0 0 f f f f f i s 4 0 16 '1114 1186 1114 1186' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2043 overlaps 11 10 14 1 0 0 0 f f f f f i s 4 0 16 '1114 1114 1114 1186' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2044 overlaps 11 10 14 1 0 0 0 f f f f f i s 4 0 16 '1114 1186 1114 1114' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2045 timestamp_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_cmp _null_ _null_ _null_ _null_ ) +insert ( 3137 timestamp_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ timestamp_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 4134 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '1114 1114 1186 16 16' _null_ _null_ _null_ _null_ _null_ in_range_timestamp_interval _null_ _null_ _null_ _null_ ) +insert ( 4135 in_range 11 10 12 1 0 0 0 f f f t f s s 5 0 16 '1184 1184 1186 16 16' _null_ _null_ _null_ _null_ _null_ in_range_timestamptz_interval _null_ _null_ _null_ _null_ ) +insert ( 4136 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '1186 1186 1186 16 16' _null_ _null_ _null_ _null_ _null_ in_range_interval_interval _null_ _null_ _null_ _null_ ) +insert ( 4137 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '1083 1083 1186 16 16' _null_ _null_ _null_ _null_ _null_ in_range_time_interval _null_ _null_ _null_ _null_ ) +insert ( 4138 in_range 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '1266 1266 1186 16 16' _null_ _null_ _null_ _null_ _null_ in_range_timetz_interval _null_ _null_ _null_ _null_ ) +insert ( 2046 time 11 10 12 1 0 0 0 f f f t f i s 1 0 1083 1266 _null_ _null_ _null_ _null_ _null_ timetz_time _null_ _null_ _null_ _null_ ) +insert ( 2047 timetz 11 10 12 1 0 0 0 f f f t f s s 1 0 1266 1083 _null_ _null_ _null_ _null_ _null_ time_timetz _null_ _null_ _null_ _null_ ) +insert ( 2048 isfinite 11 10 12 1 0 0 0 f f f t f i s 1 0 16 1114 _null_ _null_ _null_ _null_ _null_ timestamp_finite _null_ _null_ _null_ _null_ ) +insert ( 2049 to_char 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '1114 25' _null_ _null_ _null_ _null_ _null_ timestamp_to_char _null_ _null_ _null_ _null_ ) +insert ( 2052 timestamp_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_eq _null_ _null_ _null_ _null_ ) +insert ( 2053 timestamp_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_ne _null_ _null_ _null_ _null_ ) +insert ( 2054 timestamp_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_lt _null_ _null_ _null_ _null_ ) +insert ( 2055 timestamp_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_le _null_ _null_ _null_ _null_ ) +insert ( 2056 timestamp_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_ge _null_ _null_ _null_ _null_ ) +insert ( 2057 timestamp_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_gt _null_ _null_ _null_ _null_ ) +insert ( 2058 age 11 10 12 1 0 0 0 f f f t f i s 2 0 1186 '1114 1114' _null_ _null_ _null_ _null_ _null_ timestamp_age _null_ _null_ _null_ _null_ ) +insert ( 2059 age 11 10 14 1 0 0 0 f f f t f s s 1 0 1186 1114 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2069 timezone 11 10 12 1 0 0 0 f f f t f i s 2 0 1184 '25 1114' _null_ _null_ _null_ _null_ _null_ timestamp_zone _null_ _null_ _null_ _null_ ) +insert ( 2070 timezone 11 10 12 1 0 0 0 f f f t f i s 2 0 1184 '1186 1114' _null_ _null_ _null_ _null_ _null_ timestamp_izone _null_ _null_ _null_ _null_ ) +insert ( 2071 date_pl_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1082 1186' _null_ _null_ _null_ _null_ _null_ date_pl_interval _null_ _null_ _null_ _null_ ) +insert ( 2072 date_mi_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 1114 '1082 1186' _null_ _null_ _null_ _null_ _null_ date_mi_interval _null_ _null_ _null_ _null_ ) +insert ( 2073 substring 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ textregexsubstr _null_ _null_ _null_ _null_ ) +insert ( 2074 substring 11 10 14 1 0 0 0 f f f t f i s 3 0 25 '25 25 25' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2075 bit 11 10 12 1 0 0 0 f f f t f i s 2 0 1560 '20 23' _null_ _null_ _null_ _null_ _null_ bitfromint8 _null_ _null_ _null_ _null_ ) +insert ( 2076 int8 11 10 12 1 0 0 0 f f f t f i s 1 0 20 1560 _null_ _null_ _null_ _null_ _null_ bittoint8 _null_ _null_ _null_ _null_ ) +insert ( 2077 current_setting 11 10 12 1 0 0 0 f f f t f s s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ show_config_by_name _null_ _null_ _null_ _null_ ) +insert ( 3294 current_setting 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '25 16' _null_ _null_ _null_ _null_ _null_ show_config_by_name_missing_ok _null_ _null_ _null_ _null_ ) +insert ( 2078 set_config 11 10 12 1 0 0 0 f f f f f v u 3 0 25 '25 25 16' _null_ _null_ _null_ _null_ _null_ set_config_by_name _null_ _null_ _null_ _null_ ) +insert ( 2084 pg_show_all_settings 11 10 12 1 1000 0 0 f f f t t s s 0 0 2249 '' '{25,25,25,25,25,25,25,25,25,25,25,1009,25,25,25,23,16}' '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{name,setting,unit,category,short_desc,extra_desc,context,vartype,source,min_val,max_val,enumvals,boot_val,reset_val,sourcefile,sourceline,pending_restart}' _null_ _null_ show_all_settings _null_ _null_ _null_ _null_ ) +insert ( 6240 pg_settings_get_flags 11 10 12 1 0 0 0 f f f t f s s 1 0 1009 25 _null_ _null_ _null_ _null_ _null_ pg_settings_get_flags _null_ _null_ _null_ _null_ ) +insert ( 3329 pg_show_all_file_settings 11 10 12 1 1000 0 0 f f f t t v s 0 0 2249 '' '{25,23,23,25,25,16,25}' '{o,o,o,o,o,o,o}' '{sourcefile,sourceline,seqno,name,setting,applied,error}' _null_ _null_ show_all_file_settings _null_ _null_ _null_ _null_ ) +insert ( 3401 pg_hba_file_rules 11 10 12 1 1000 0 0 f f f t t v s 0 0 2249 '' '{23,25,23,25,1009,1009,25,25,25,1009,25}' '{o,o,o,o,o,o,o,o,o,o,o}' '{rule_number,file_name,line_number,type,database,user_name,address,netmask,auth_method,options,error}' _null_ _null_ pg_hba_file_rules _null_ _null_ _null_ _null_ ) +insert ( 6250 pg_ident_file_mappings 11 10 12 1 1000 0 0 f f f t t v s 0 0 2249 '' '{23,25,23,25,25,25,25}' '{o,o,o,o,o,o,o}' '{map_number,file_name,line_number,map_name,sys_name,pg_username,error}' _null_ _null_ pg_ident_file_mappings _null_ _null_ _null_ _null_ ) +insert ( 1371 pg_lock_status 11 10 12 1 1000 0 0 f f f t t v s 0 0 2249 '' '{25,26,26,23,21,25,28,26,26,21,25,23,25,16,16,1184}' '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{locktype,database,relation,page,tuple,virtualxid,transactionid,classid,objid,objsubid,virtualtransaction,pid,mode,granted,fastpath,waitstart}' _null_ _null_ pg_lock_status _null_ _null_ _null_ _null_ ) +insert ( 2561 pg_blocking_pids 11 10 12 1 0 0 0 f f f t f v s 1 0 1007 23 _null_ _null_ _null_ _null_ _null_ pg_blocking_pids _null_ _null_ _null_ _null_ ) +insert ( 3376 pg_safe_snapshot_blocking_pids 11 10 12 1 0 0 0 f f f t f v s 1 0 1007 23 _null_ _null_ _null_ _null_ _null_ pg_safe_snapshot_blocking_pids _null_ _null_ _null_ _null_ ) +insert ( 3378 pg_isolation_test_session_is_blocked 11 10 12 1 0 0 0 f f f t f v s 2 0 16 '23 1007' _null_ _null_ _null_ _null_ _null_ pg_isolation_test_session_is_blocked _null_ _null_ _null_ _null_ ) +insert ( 1065 pg_prepared_xact 11 10 12 1 1000 0 0 f f f t t v s 0 0 2249 '' '{28,25,1184,26,26}' '{o,o,o,o,o}' '{transaction,gid,prepared,ownerid,dbid}' _null_ _null_ pg_prepared_xact _null_ _null_ _null_ _null_ ) +insert ( 3819 pg_get_multixact_members 11 10 12 1 1000 0 0 f f f t t v s 1 0 2249 28 '{28,28,25}' '{i,o,o}' '{multixid,xid,mode}' _null_ _null_ pg_get_multixact_members _null_ _null_ _null_ _null_ ) +insert ( 3581 pg_xact_commit_timestamp 11 10 12 1 0 0 0 f f f t f v s 1 0 1184 28 _null_ _null_ _null_ _null_ _null_ pg_xact_commit_timestamp _null_ _null_ _null_ _null_ ) +insert ( 6168 pg_xact_commit_timestamp_origin 11 10 12 1 0 0 0 f f f t f v s 1 0 2249 28 '{28,1184,26}' '{i,o,o}' '{xid,timestamp,roident}' _null_ _null_ pg_xact_commit_timestamp_origin _null_ _null_ _null_ _null_ ) +insert ( 3583 pg_last_committed_xact 11 10 12 1 0 0 0 f f f t f v s 0 0 2249 '' '{28,1184,26}' '{o,o,o}' '{xid,timestamp,roident}' _null_ _null_ pg_last_committed_xact _null_ _null_ _null_ _null_ ) +insert ( 3537 pg_describe_object 11 10 12 1 0 0 0 f f f t f s s 3 0 25 '26 26 23' _null_ _null_ _null_ _null_ _null_ pg_describe_object _null_ _null_ _null_ _null_ ) +insert ( 3839 pg_identify_object 11 10 12 1 0 0 0 f f f t f s s 3 0 2249 '26 26 23' '{26,26,23,25,25,25,25}' '{i,i,i,o,o,o,o}' '{classid,objid,objsubid,type,schema,name,identity}' _null_ _null_ pg_identify_object _null_ _null_ _null_ _null_ ) +insert ( 3382 pg_identify_object_as_address 11 10 12 1 0 0 0 f f f t f s s 3 0 2249 '26 26 23' '{26,26,23,25,1009,1009}' '{i,i,i,o,o,o}' '{classid,objid,objsubid,type,object_names,object_args}' _null_ _null_ pg_identify_object_as_address _null_ _null_ _null_ _null_ ) +insert ( 3954 pg_get_object_address 11 10 12 1 0 0 0 f f f t f s s 3 0 2249 '25 1009 1009' '{25,1009,1009,26,26,23}' '{i,i,i,o,o,o}' '{type,object_names,object_args,classid,objid,objsubid}' _null_ _null_ pg_get_object_address _null_ _null_ _null_ _null_ ) +insert ( 2079 pg_table_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_table_is_visible _null_ _null_ _null_ _null_ ) +insert ( 2080 pg_type_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_type_is_visible _null_ _null_ _null_ _null_ ) +insert ( 2081 pg_function_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_function_is_visible _null_ _null_ _null_ _null_ ) +insert ( 2082 pg_operator_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_operator_is_visible _null_ _null_ _null_ _null_ ) +insert ( 2083 pg_opclass_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_opclass_is_visible _null_ _null_ _null_ _null_ ) +insert ( 3829 pg_opfamily_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_opfamily_is_visible _null_ _null_ _null_ _null_ ) +insert ( 2093 pg_conversion_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_conversion_is_visible _null_ _null_ _null_ _null_ ) +insert ( 3403 pg_statistics_obj_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_statistics_obj_is_visible _null_ _null_ _null_ _null_ ) +insert ( 3756 pg_ts_parser_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_ts_parser_is_visible _null_ _null_ _null_ _null_ ) +insert ( 3757 pg_ts_dict_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_ts_dict_is_visible _null_ _null_ _null_ _null_ ) +insert ( 3768 pg_ts_template_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_ts_template_is_visible _null_ _null_ _null_ _null_ ) +insert ( 3758 pg_ts_config_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_ts_config_is_visible _null_ _null_ _null_ _null_ ) +insert ( 3815 pg_collation_is_visible 11 10 12 10 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_collation_is_visible _null_ _null_ _null_ _null_ ) +insert ( 2854 pg_my_temp_schema 11 10 12 1 0 0 0 f f f t f s r 0 0 26 '' _null_ _null_ _null_ _null_ _null_ pg_my_temp_schema _null_ _null_ _null_ _null_ ) +insert ( 2855 pg_is_other_temp_schema 11 10 12 1 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ pg_is_other_temp_schema _null_ _null_ _null_ _null_ ) +insert ( 2171 pg_cancel_backend 11 10 12 1 0 0 0 f f f t f v s 1 0 16 23 _null_ _null_ _null_ _null_ _null_ pg_cancel_backend _null_ _null_ _null_ _null_ ) +insert ( 2096 pg_terminate_backend 11 10 12 1 0 0 0 f f f t f v s 2 0 16 '23 20' _null_ _null_ '{pid,timeout}' _null_ _null_ pg_terminate_backend _null_ _null_ _null_ _null_ ) +insert ( 2172 pg_backup_start 11 10 12 1 0 0 0 f f f t f v r 2 0 3220 '25 16' _null_ _null_ _null_ _null_ _null_ pg_backup_start _null_ _null_ _null_ _null_ ) +insert ( 2739 pg_backup_stop 11 10 12 1 0 0 0 f f f t f v r 1 0 2249 16 '{16,3220,25,25}' '{i,o,o,o}' '{wait_for_archive,lsn,labelfile,spcmapfile}' _null_ _null_ pg_backup_stop _null_ _null_ _null_ _null_ ) +insert ( 3436 pg_promote 11 10 12 1 0 0 0 f f f t f v s 2 0 16 '16 23' _null_ _null_ '{wait,wait_seconds}' _null_ _null_ pg_promote _null_ _null_ _null_ _null_ ) +insert ( 2848 pg_switch_wal 11 10 12 1 0 0 0 f f f t f v s 0 0 3220 '' _null_ _null_ _null_ _null_ _null_ pg_switch_wal _null_ _null_ _null_ _null_ ) +insert ( 6305 pg_log_standby_snapshot 11 10 12 1 0 0 0 f f f t f v s 0 0 3220 '' _null_ _null_ _null_ _null_ _null_ pg_log_standby_snapshot _null_ _null_ _null_ _null_ ) +insert ( 3098 pg_create_restore_point 11 10 12 1 0 0 0 f f f t f v s 1 0 3220 25 _null_ _null_ _null_ _null_ _null_ pg_create_restore_point _null_ _null_ _null_ _null_ ) +insert ( 2849 pg_current_wal_lsn 11 10 12 1 0 0 0 f f f t f v s 0 0 3220 '' _null_ _null_ _null_ _null_ _null_ pg_current_wal_lsn _null_ _null_ _null_ _null_ ) +insert ( 2852 pg_current_wal_insert_lsn 11 10 12 1 0 0 0 f f f t f v s 0 0 3220 '' _null_ _null_ _null_ _null_ _null_ pg_current_wal_insert_lsn _null_ _null_ _null_ _null_ ) +insert ( 3330 pg_current_wal_flush_lsn 11 10 12 1 0 0 0 f f f t f v s 0 0 3220 '' _null_ _null_ _null_ _null_ _null_ pg_current_wal_flush_lsn _null_ _null_ _null_ _null_ ) +insert ( 2850 pg_walfile_name_offset 11 10 12 1 0 0 0 f f f t f i s 1 0 2249 3220 '{3220,25,23}' '{i,o,o}' '{lsn,file_name,file_offset}' _null_ _null_ pg_walfile_name_offset _null_ _null_ _null_ _null_ ) +insert ( 2851 pg_walfile_name 11 10 12 1 0 0 0 f f f t f i s 1 0 25 3220 _null_ _null_ _null_ _null_ _null_ pg_walfile_name _null_ _null_ _null_ _null_ ) +insert ( 6213 pg_split_walfile_name 11 10 12 1 0 0 0 f f f t f s s 1 0 2249 25 '{25,1700,20}' '{i,o,o}' '{file_name,segment_number,timeline_id}' _null_ _null_ pg_split_walfile_name _null_ _null_ _null_ _null_ ) +insert ( 3165 pg_wal_lsn_diff 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_wal_lsn_diff _null_ _null_ _null_ _null_ ) +insert ( 3809 pg_export_snapshot 11 10 12 1 0 0 0 f f f t f v u 0 0 25 '' _null_ _null_ _null_ _null_ _null_ pg_export_snapshot _null_ _null_ _null_ _null_ ) +insert ( 3810 pg_is_in_recovery 11 10 12 1 0 0 0 f f f t f v s 0 0 16 '' _null_ _null_ _null_ _null_ _null_ pg_is_in_recovery _null_ _null_ _null_ _null_ ) +insert ( 3820 pg_last_wal_receive_lsn 11 10 12 1 0 0 0 f f f t f v s 0 0 3220 '' _null_ _null_ _null_ _null_ _null_ pg_last_wal_receive_lsn _null_ _null_ _null_ _null_ ) +insert ( 3821 pg_last_wal_replay_lsn 11 10 12 1 0 0 0 f f f t f v s 0 0 3220 '' _null_ _null_ _null_ _null_ _null_ pg_last_wal_replay_lsn _null_ _null_ _null_ _null_ ) +insert ( 3830 pg_last_xact_replay_timestamp 11 10 12 1 0 0 0 f f f t f v s 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ pg_last_xact_replay_timestamp _null_ _null_ _null_ _null_ ) +insert ( 3071 pg_wal_replay_pause 11 10 12 1 0 0 0 f f f t f v s 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_wal_replay_pause _null_ _null_ _null_ _null_ ) +insert ( 3072 pg_wal_replay_resume 11 10 12 1 0 0 0 f f f t f v s 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_wal_replay_resume _null_ _null_ _null_ _null_ ) +insert ( 3073 pg_is_wal_replay_paused 11 10 12 1 0 0 0 f f f t f v s 0 0 16 '' _null_ _null_ _null_ _null_ _null_ pg_is_wal_replay_paused _null_ _null_ _null_ _null_ ) +insert ( 1137 pg_get_wal_replay_pause_state 11 10 12 1 0 0 0 f f f t f v s 0 0 25 '' _null_ _null_ _null_ _null_ _null_ pg_get_wal_replay_pause_state _null_ _null_ _null_ _null_ ) +insert ( 6224 pg_get_wal_resource_managers 11 10 12 1 50 0 0 f f f t t v s 0 0 2249 '' '{23,25,16}' '{o,o,o}' '{rm_id, rm_name, rm_builtin}' _null_ _null_ pg_get_wal_resource_managers _null_ _null_ _null_ _null_ ) +insert ( 2621 pg_reload_conf 11 10 12 1 0 0 0 f f f t f v s 0 0 16 '' _null_ _null_ _null_ _null_ _null_ pg_reload_conf _null_ _null_ _null_ _null_ ) +insert ( 2622 pg_rotate_logfile 11 10 12 1 0 0 0 f f f t f v s 0 0 16 '' _null_ _null_ _null_ _null_ _null_ pg_rotate_logfile_v2 _null_ _null_ _null_ _null_ ) +insert ( 4099 pg_rotate_logfile_old 11 10 12 1 0 0 0 f f f t f v s 0 0 16 '' _null_ _null_ _null_ _null_ _null_ pg_rotate_logfile _null_ _null_ _null_ _null_ ) +insert ( 3800 pg_current_logfile 11 10 12 1 0 0 0 f f f f f v s 0 0 25 '' _null_ _null_ _null_ _null_ _null_ pg_current_logfile _null_ _null_ _null_ _null_ ) +insert ( 3801 pg_current_logfile 11 10 12 1 0 0 0 f f f f f v s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ pg_current_logfile_1arg _null_ _null_ _null_ _null_ ) +insert ( 2623 pg_stat_file 11 10 12 1 0 0 0 f f f t f v s 1 0 2249 25 '{25,20,1184,1184,1184,1184,16}' '{i,o,o,o,o,o,o}' '{filename,size,access,modification,change,creation,isdir}' _null_ _null_ pg_stat_file_1arg _null_ _null_ _null_ _null_ ) +insert ( 3307 pg_stat_file 11 10 12 1 0 0 0 f f f t f v s 2 0 2249 '25 16' '{25,16,20,1184,1184,1184,1184,16}' '{i,i,o,o,o,o,o,o}' '{filename,missing_ok,size,access,modification,change,creation,isdir}' _null_ _null_ pg_stat_file _null_ _null_ _null_ _null_ ) +insert ( 2624 pg_read_file 11 10 12 1 0 0 0 f f f t f v s 3 0 25 '25 20 20' _null_ _null_ _null_ _null_ _null_ pg_read_file_off_len _null_ _null_ _null_ _null_ ) +insert ( 3293 pg_read_file 11 10 12 1 0 0 0 f f f t f v s 4 0 25 '25 20 20 16' _null_ _null_ _null_ _null_ _null_ pg_read_file_off_len_missing _null_ _null_ _null_ _null_ ) +insert ( 4100 pg_read_file_old 11 10 12 1 0 0 0 f f f t f v s 3 0 25 '25 20 20' _null_ _null_ _null_ _null_ _null_ pg_read_file _null_ _null_ _null_ _null_ ) +insert ( 3826 pg_read_file 11 10 12 1 0 0 0 f f f t f v s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ pg_read_file_all _null_ _null_ _null_ _null_ ) +insert ( 6208 pg_read_file 11 10 12 1 0 0 0 f f f t f v s 2 0 25 '25 16' _null_ _null_ _null_ _null_ _null_ pg_read_file_all_missing _null_ _null_ _null_ _null_ ) +insert ( 3827 pg_read_binary_file 11 10 12 1 0 0 0 f f f t f v s 3 0 17 '25 20 20' _null_ _null_ _null_ _null_ _null_ pg_read_binary_file_off_len _null_ _null_ _null_ _null_ ) +insert ( 3295 pg_read_binary_file 11 10 12 1 0 0 0 f f f t f v s 4 0 17 '25 20 20 16' _null_ _null_ _null_ _null_ _null_ pg_read_binary_file_off_len_missing _null_ _null_ _null_ _null_ ) +insert ( 3828 pg_read_binary_file 11 10 12 1 0 0 0 f f f t f v s 1 0 17 25 _null_ _null_ _null_ _null_ _null_ pg_read_binary_file_all _null_ _null_ _null_ _null_ ) +insert ( 6209 pg_read_binary_file 11 10 12 1 0 0 0 f f f t f v s 2 0 17 '25 16' _null_ _null_ _null_ _null_ _null_ pg_read_binary_file_all_missing _null_ _null_ _null_ _null_ ) +insert ( 2625 pg_ls_dir 11 10 12 1 1000 0 0 f f f t t v s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ pg_ls_dir_1arg _null_ _null_ _null_ _null_ ) +insert ( 3297 pg_ls_dir 11 10 12 1 1000 0 0 f f f t t v s 3 0 25 '25 16 16' _null_ _null_ _null_ _null_ _null_ pg_ls_dir _null_ _null_ _null_ _null_ ) +insert ( 2626 pg_sleep 11 10 12 1 0 0 0 f f f t f v s 1 0 2278 701 _null_ _null_ _null_ _null_ _null_ pg_sleep _null_ _null_ _null_ _null_ ) +insert ( 3935 pg_sleep_for 11 10 14 1 0 0 0 f f f t f v s 1 0 2278 1186 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 3936 pg_sleep_until 11 10 14 1 0 0 0 f f f t f v s 1 0 2278 1184 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 315 pg_jit_available 11 10 12 1 0 0 0 f f f t f v s 0 0 16 '' _null_ _null_ _null_ _null_ _null_ pg_jit_available _null_ _null_ _null_ _null_ ) +insert ( 2971 text 11 10 12 1 0 0 0 f f f t f i s 1 0 25 16 _null_ _null_ _null_ _null_ _null_ booltext _null_ _null_ _null_ _null_ ) +insert ( 2100 avg 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2101 avg 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2102 avg 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2103 avg 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2104 avg 11 10 12 1 0 0 0 a f f f f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2105 avg 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2106 avg 11 10 12 1 0 0 0 a f f f f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2107 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2108 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 20 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2109 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 20 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2110 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 700 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2111 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2112 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 790 790 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2113 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2114 sum 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2115 max 11 10 12 1 0 0 0 a f f f f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2116 max 11 10 12 1 0 0 0 a f f f f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2117 max 11 10 12 1 0 0 0 a f f f f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2118 max 11 10 12 1 0 0 0 a f f f f i s 1 0 26 26 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2119 max 11 10 12 1 0 0 0 a f f f f i s 1 0 700 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2120 max 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2122 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1082 1082 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2123 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1083 1083 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2124 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1266 1266 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2125 max 11 10 12 1 0 0 0 a f f f f i s 1 0 790 790 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2126 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1114 1114 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2127 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1184 1184 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2128 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2129 max 11 10 12 1 0 0 0 a f f f f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2130 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2050 max 11 10 12 1 0 0 0 a f f f f i s 1 0 2277 2277 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2244 max 11 10 12 1 0 0 0 a f f f f i s 1 0 1042 1042 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2797 max 11 10 12 1 0 0 0 a f f f f i s 1 0 27 27 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3564 max 11 10 12 1 0 0 0 a f f f f i s 1 0 869 869 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 4189 max 11 10 12 1 0 0 0 a f f f f i s 1 0 3220 3220 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 5099 max 11 10 12 1 0 0 0 a f f f f i s 1 0 5069 5069 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2131 min 11 10 12 1 0 0 0 a f f f f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2132 min 11 10 12 1 0 0 0 a f f f f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2133 min 11 10 12 1 0 0 0 a f f f f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2134 min 11 10 12 1 0 0 0 a f f f f i s 1 0 26 26 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2135 min 11 10 12 1 0 0 0 a f f f f i s 1 0 700 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2136 min 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2138 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1082 1082 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2139 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1083 1083 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2140 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1266 1266 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2141 min 11 10 12 1 0 0 0 a f f f f i s 1 0 790 790 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2142 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1114 1114 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2143 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1184 1184 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2144 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1186 1186 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2145 min 11 10 12 1 0 0 0 a f f f f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2146 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2051 min 11 10 12 1 0 0 0 a f f f f i s 1 0 2277 2277 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2245 min 11 10 12 1 0 0 0 a f f f f i s 1 0 1042 1042 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2798 min 11 10 12 1 0 0 0 a f f f f i s 1 0 27 27 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3565 min 11 10 12 1 0 0 0 a f f f f i s 1 0 869 869 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 4190 min 11 10 12 1 0 0 0 a f f f f i s 1 0 3220 3220 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 5100 min 11 10 12 1 0 0 0 a f f f f i s 1 0 5069 5069 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2147 count 11 10 12 1 0 0 6236 a f f f f i s 1 0 20 2276 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2803 count 11 10 12 1 0 0 6236 a f f f f i s 0 0 20 '' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6236 int8inc_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ int8inc_support _null_ _null_ _null_ _null_ ) +insert ( 2718 var_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2719 var_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2720 var_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2721 var_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2722 var_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2723 var_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2641 var_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2642 var_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2643 var_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2644 var_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2645 var_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2646 var_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2148 variance 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2149 variance 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2150 variance 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2151 variance 11 10 12 1 0 0 0 a f f f f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2152 variance 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2153 variance 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2724 stddev_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2725 stddev_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2726 stddev_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2727 stddev_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2728 stddev_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2729 stddev_pop 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2712 stddev_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2713 stddev_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2714 stddev_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2715 stddev_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2716 stddev_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2717 stddev_samp 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2154 stddev 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2155 stddev 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2156 stddev 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2157 stddev 11 10 12 1 0 0 0 a f f f f i s 1 0 701 700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2158 stddev 11 10 12 1 0 0 0 a f f f f i s 1 0 701 701 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2159 stddev 11 10 12 1 0 0 0 a f f f f i s 1 0 1700 1700 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2818 regr_count 11 10 12 1 0 0 0 a f f f f i s 2 0 20 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2819 regr_sxx 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2820 regr_syy 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2821 regr_sxy 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2822 regr_avgx 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2823 regr_avgy 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2824 regr_r2 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2825 regr_slope 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2826 regr_intercept 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2827 covar_pop 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2828 covar_samp 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2829 corr 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2160 text_pattern_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_pattern_lt _null_ _null_ _null_ _null_ ) +insert ( 2161 text_pattern_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_pattern_le _null_ _null_ _null_ _null_ ) +insert ( 2163 text_pattern_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_pattern_ge _null_ _null_ _null_ _null_ ) +insert ( 2164 text_pattern_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ text_pattern_gt _null_ _null_ _null_ _null_ ) +insert ( 2166 bttext_pattern_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ bttext_pattern_cmp _null_ _null_ _null_ _null_ ) +insert ( 3332 bttext_pattern_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ bttext_pattern_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 2174 bpchar_pattern_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchar_pattern_lt _null_ _null_ _null_ _null_ ) +insert ( 2175 bpchar_pattern_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchar_pattern_le _null_ _null_ _null_ _null_ ) +insert ( 2177 bpchar_pattern_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchar_pattern_ge _null_ _null_ _null_ _null_ ) +insert ( 2178 bpchar_pattern_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '1042 1042' _null_ _null_ _null_ _null_ _null_ bpchar_pattern_gt _null_ _null_ _null_ _null_ ) +insert ( 2180 btbpchar_pattern_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '1042 1042' _null_ _null_ _null_ _null_ _null_ btbpchar_pattern_cmp _null_ _null_ _null_ _null_ ) +insert ( 3333 btbpchar_pattern_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ btbpchar_pattern_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 2188 btint48cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '23 20' _null_ _null_ _null_ _null_ _null_ btint48cmp _null_ _null_ _null_ _null_ ) +insert ( 2189 btint84cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '20 23' _null_ _null_ _null_ _null_ _null_ btint84cmp _null_ _null_ _null_ _null_ ) +insert ( 2190 btint24cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '21 23' _null_ _null_ _null_ _null_ _null_ btint24cmp _null_ _null_ _null_ _null_ ) +insert ( 2191 btint42cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '23 21' _null_ _null_ _null_ _null_ _null_ btint42cmp _null_ _null_ _null_ _null_ ) +insert ( 2192 btint28cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '21 20' _null_ _null_ _null_ _null_ _null_ btint28cmp _null_ _null_ _null_ _null_ ) +insert ( 2193 btint82cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '20 21' _null_ _null_ _null_ _null_ _null_ btint82cmp _null_ _null_ _null_ _null_ ) +insert ( 2194 btfloat48cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '700 701' _null_ _null_ _null_ _null_ _null_ btfloat48cmp _null_ _null_ _null_ _null_ ) +insert ( 2195 btfloat84cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '701 700' _null_ _null_ _null_ _null_ _null_ btfloat84cmp _null_ _null_ _null_ _null_ ) +insert ( 2212 regprocedurein 11 10 12 1 0 0 0 f f f t f s s 1 0 2202 2275 _null_ _null_ _null_ _null_ _null_ regprocedurein _null_ _null_ _null_ _null_ ) +insert ( 2213 regprocedureout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2202 _null_ _null_ _null_ _null_ _null_ regprocedureout _null_ _null_ _null_ _null_ ) +insert ( 2214 regoperin 11 10 12 1 0 0 0 f f f t f s s 1 0 2203 2275 _null_ _null_ _null_ _null_ _null_ regoperin _null_ _null_ _null_ _null_ ) +insert ( 2215 regoperout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2203 _null_ _null_ _null_ _null_ _null_ regoperout _null_ _null_ _null_ _null_ ) +insert ( 3492 to_regoper 11 10 12 1 0 0 0 f f f t f s s 1 0 2203 25 _null_ _null_ _null_ _null_ _null_ to_regoper _null_ _null_ _null_ _null_ ) +insert ( 3476 to_regoperator 11 10 12 1 0 0 0 f f f t f s s 1 0 2204 25 _null_ _null_ _null_ _null_ _null_ to_regoperator _null_ _null_ _null_ _null_ ) +insert ( 2216 regoperatorin 11 10 12 1 0 0 0 f f f t f s s 1 0 2204 2275 _null_ _null_ _null_ _null_ _null_ regoperatorin _null_ _null_ _null_ _null_ ) +insert ( 2217 regoperatorout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2204 _null_ _null_ _null_ _null_ _null_ regoperatorout _null_ _null_ _null_ _null_ ) +insert ( 2218 regclassin 11 10 12 1 0 0 0 f f f t f s s 1 0 2205 2275 _null_ _null_ _null_ _null_ _null_ regclassin _null_ _null_ _null_ _null_ ) +insert ( 2219 regclassout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2205 _null_ _null_ _null_ _null_ _null_ regclassout _null_ _null_ _null_ _null_ ) +insert ( 3495 to_regclass 11 10 12 1 0 0 0 f f f t f s s 1 0 2205 25 _null_ _null_ _null_ _null_ _null_ to_regclass _null_ _null_ _null_ _null_ ) +insert ( 4193 regcollationin 11 10 12 1 0 0 0 f f f t f s s 1 0 4191 2275 _null_ _null_ _null_ _null_ _null_ regcollationin _null_ _null_ _null_ _null_ ) +insert ( 4194 regcollationout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 4191 _null_ _null_ _null_ _null_ _null_ regcollationout _null_ _null_ _null_ _null_ ) +insert ( 4195 to_regcollation 11 10 12 1 0 0 0 f f f t f s s 1 0 4191 25 _null_ _null_ _null_ _null_ _null_ to_regcollation _null_ _null_ _null_ _null_ ) +insert ( 2220 regtypein 11 10 12 1 0 0 0 f f f t f s s 1 0 2206 2275 _null_ _null_ _null_ _null_ _null_ regtypein _null_ _null_ _null_ _null_ ) +insert ( 2221 regtypeout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2206 _null_ _null_ _null_ _null_ _null_ regtypeout _null_ _null_ _null_ _null_ ) +insert ( 3493 to_regtype 11 10 12 1 0 0 0 f f f t f s s 1 0 2206 25 _null_ _null_ _null_ _null_ _null_ to_regtype _null_ _null_ _null_ _null_ ) +insert ( 1079 regclass 11 10 12 1 0 0 0 f f f t f s s 1 0 2205 25 _null_ _null_ _null_ _null_ _null_ text_regclass _null_ _null_ _null_ _null_ ) +insert ( 4098 regrolein 11 10 12 1 0 0 0 f f f t f s s 1 0 4096 2275 _null_ _null_ _null_ _null_ _null_ regrolein _null_ _null_ _null_ _null_ ) +insert ( 4092 regroleout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 4096 _null_ _null_ _null_ _null_ _null_ regroleout _null_ _null_ _null_ _null_ ) +insert ( 4093 to_regrole 11 10 12 1 0 0 0 f f f t f s s 1 0 4096 25 _null_ _null_ _null_ _null_ _null_ to_regrole _null_ _null_ _null_ _null_ ) +insert ( 4084 regnamespacein 11 10 12 1 0 0 0 f f f t f s s 1 0 4089 2275 _null_ _null_ _null_ _null_ _null_ regnamespacein _null_ _null_ _null_ _null_ ) +insert ( 4085 regnamespaceout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 4089 _null_ _null_ _null_ _null_ _null_ regnamespaceout _null_ _null_ _null_ _null_ ) +insert ( 4086 to_regnamespace 11 10 12 1 0 0 0 f f f t f s s 1 0 4089 25 _null_ _null_ _null_ _null_ _null_ to_regnamespace _null_ _null_ _null_ _null_ ) +insert ( 6210 pg_input_is_valid 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ pg_input_is_valid _null_ _null_ _null_ _null_ ) +insert ( 6211 pg_input_error_info 11 10 12 1 0 0 0 f f f t f s s 2 0 2249 '25 25' '{25,25,25,25,25,25}' '{i,i,o,o,o,o}' '{value,type_name,message,detail,hint,sql_error_code}' _null_ _null_ pg_input_error_info _null_ _null_ _null_ _null_ ) +insert ( 1268 parse_ident 11 10 12 1 0 0 0 f f f t f i s 2 0 1009 '25 16' _null_ _null_ '{str,strict}' _null_ _null_ parse_ident _null_ _null_ _null_ _null_ ) +insert ( 2246 fmgr_internal_validator 11 10 12 1 0 0 0 f f f t f s s 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ fmgr_internal_validator _null_ _null_ _null_ _null_ ) +insert ( 2247 fmgr_c_validator 11 10 12 1 0 0 0 f f f t f s s 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ fmgr_c_validator _null_ _null_ _null_ _null_ ) +insert ( 2248 fmgr_sql_validator 11 10 12 1 0 0 0 f f f t f s s 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ fmgr_sql_validator _null_ _null_ _null_ _null_ ) +insert ( 2250 has_database_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_database_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 2251 has_database_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_database_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 2252 has_database_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_database_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 2253 has_database_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_database_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 2254 has_database_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_database_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 2255 has_database_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_database_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 2256 has_function_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_function_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 2257 has_function_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_function_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 2258 has_function_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_function_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 2259 has_function_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_function_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 2260 has_function_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_function_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 2261 has_function_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_function_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 2262 has_language_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_language_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 2263 has_language_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_language_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 2264 has_language_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_language_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 2265 has_language_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_language_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 2266 has_language_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_language_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 2267 has_language_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_language_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 2268 has_schema_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_schema_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 2269 has_schema_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_schema_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 2270 has_schema_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_schema_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 2271 has_schema_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_schema_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 2272 has_schema_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_schema_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 2273 has_schema_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_schema_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 2390 has_tablespace_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_tablespace_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 2391 has_tablespace_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_tablespace_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 2392 has_tablespace_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_tablespace_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 2393 has_tablespace_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_tablespace_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 2394 has_tablespace_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_tablespace_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 2395 has_tablespace_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_tablespace_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 3000 has_foreign_data_wrapper_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_foreign_data_wrapper_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 3001 has_foreign_data_wrapper_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_foreign_data_wrapper_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 3002 has_foreign_data_wrapper_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_foreign_data_wrapper_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 3003 has_foreign_data_wrapper_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_foreign_data_wrapper_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 3004 has_foreign_data_wrapper_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_foreign_data_wrapper_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 3005 has_foreign_data_wrapper_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_foreign_data_wrapper_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 3006 has_server_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_server_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 3007 has_server_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_server_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 3008 has_server_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_server_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 3009 has_server_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_server_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 3010 has_server_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_server_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 3011 has_server_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_server_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 3138 has_type_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_type_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 3139 has_type_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ has_type_privilege_name_id _null_ _null_ _null_ _null_ ) +insert ( 3140 has_type_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_type_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 3141 has_type_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ has_type_privilege_id_id _null_ _null_ _null_ _null_ ) +insert ( 3142 has_type_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_type_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 3143 has_type_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ has_type_privilege_id _null_ _null_ _null_ _null_ ) +insert ( 6205 has_parameter_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 25 25' _null_ _null_ _null_ _null_ _null_ has_parameter_privilege_name_name _null_ _null_ _null_ _null_ ) +insert ( 6206 has_parameter_privilege 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 25 25' _null_ _null_ _null_ _null_ _null_ has_parameter_privilege_id_name _null_ _null_ _null_ _null_ ) +insert ( 6207 has_parameter_privilege 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ has_parameter_privilege_name _null_ _null_ _null_ _null_ ) +insert ( 2705 pg_has_role 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 19 25' _null_ _null_ _null_ _null_ _null_ pg_has_role_name_name _null_ _null_ _null_ _null_ ) +insert ( 2706 pg_has_role 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '19 26 25' _null_ _null_ _null_ _null_ _null_ pg_has_role_name_id _null_ _null_ _null_ _null_ ) +insert ( 2707 pg_has_role 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 19 25' _null_ _null_ _null_ _null_ _null_ pg_has_role_id_name _null_ _null_ _null_ _null_ ) +insert ( 2708 pg_has_role 11 10 12 1 0 0 0 f f f t f s s 3 0 16 '26 26 25' _null_ _null_ _null_ _null_ _null_ pg_has_role_id_id _null_ _null_ _null_ _null_ ) +insert ( 2709 pg_has_role 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '19 25' _null_ _null_ _null_ _null_ _null_ pg_has_role_name _null_ _null_ _null_ _null_ ) +insert ( 2710 pg_has_role 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '26 25' _null_ _null_ _null_ _null_ _null_ pg_has_role_id _null_ _null_ _null_ _null_ ) +insert ( 1269 pg_column_size 11 10 12 1 0 0 0 f f f t f s s 1 0 23 2276 _null_ _null_ _null_ _null_ _null_ pg_column_size _null_ _null_ _null_ _null_ ) +insert ( 2121 pg_column_compression 11 10 12 1 0 0 0 f f f t f s s 1 0 25 2276 _null_ _null_ _null_ _null_ _null_ pg_column_compression _null_ _null_ _null_ _null_ ) +insert ( 2322 pg_tablespace_size 11 10 12 1 0 0 0 f f f t f v s 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_tablespace_size_oid _null_ _null_ _null_ _null_ ) +insert ( 2323 pg_tablespace_size 11 10 12 1 0 0 0 f f f t f v s 1 0 20 19 _null_ _null_ _null_ _null_ _null_ pg_tablespace_size_name _null_ _null_ _null_ _null_ ) +insert ( 2324 pg_database_size 11 10 12 1 0 0 0 f f f t f v s 1 0 20 26 _null_ _null_ _null_ _null_ _null_ pg_database_size_oid _null_ _null_ _null_ _null_ ) +insert ( 2168 pg_database_size 11 10 12 1 0 0 0 f f f t f v s 1 0 20 19 _null_ _null_ _null_ _null_ _null_ pg_database_size_name _null_ _null_ _null_ _null_ ) +insert ( 2325 pg_relation_size 11 10 14 1 0 0 0 f f f t f v s 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2332 pg_relation_size 11 10 12 1 0 0 0 f f f t f v s 2 0 20 '2205 25' _null_ _null_ _null_ _null_ _null_ pg_relation_size _null_ _null_ _null_ _null_ ) +insert ( 2286 pg_total_relation_size 11 10 12 1 0 0 0 f f f t f v s 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ pg_total_relation_size _null_ _null_ _null_ _null_ ) +insert ( 2288 pg_size_pretty 11 10 12 1 0 0 0 f f f t f i s 1 0 25 20 _null_ _null_ _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ _null_ ) +insert ( 3166 pg_size_pretty 11 10 12 1 0 0 0 f f f t f i s 1 0 25 1700 _null_ _null_ _null_ _null_ _null_ pg_size_pretty_numeric _null_ _null_ _null_ _null_ ) +insert ( 3334 pg_size_bytes 11 10 12 1 0 0 0 f f f t f i s 1 0 20 25 _null_ _null_ _null_ _null_ _null_ pg_size_bytes _null_ _null_ _null_ _null_ ) +insert ( 2997 pg_table_size 11 10 12 1 0 0 0 f f f t f v s 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ pg_table_size _null_ _null_ _null_ _null_ ) +insert ( 2998 pg_indexes_size 11 10 12 1 0 0 0 f f f t f v s 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ pg_indexes_size _null_ _null_ _null_ _null_ ) +insert ( 2999 pg_relation_filenode 11 10 12 1 0 0 0 f f f t f s s 1 0 26 2205 _null_ _null_ _null_ _null_ _null_ pg_relation_filenode _null_ _null_ _null_ _null_ ) +insert ( 3454 pg_filenode_relation 11 10 12 1 0 0 0 f f f t f s s 2 0 2205 '26 26' _null_ _null_ _null_ _null_ _null_ pg_filenode_relation _null_ _null_ _null_ _null_ ) +insert ( 3034 pg_relation_filepath 11 10 12 1 0 0 0 f f f t f s s 1 0 25 2205 _null_ _null_ _null_ _null_ _null_ pg_relation_filepath _null_ _null_ _null_ _null_ ) +insert ( 2316 postgresql_fdw_validator 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1009 26' _null_ _null_ _null_ _null_ _null_ postgresql_fdw_validator _null_ _null_ _null_ _null_ ) +insert ( 2290 record_in 11 10 12 1 0 0 0 f f f t f s s 3 0 2249 '2275 26 23' _null_ _null_ _null_ _null_ _null_ record_in _null_ _null_ _null_ _null_ ) +insert ( 2291 record_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2249 _null_ _null_ _null_ _null_ _null_ record_out _null_ _null_ _null_ _null_ ) +insert ( 2292 cstring_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2275 _null_ _null_ _null_ _null_ _null_ cstring_in _null_ _null_ _null_ _null_ ) +insert ( 2293 cstring_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2275 _null_ _null_ _null_ _null_ _null_ cstring_out _null_ _null_ _null_ _null_ ) +insert ( 2294 any_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2276 2275 _null_ _null_ _null_ _null_ _null_ any_in _null_ _null_ _null_ _null_ ) +insert ( 2295 any_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2276 _null_ _null_ _null_ _null_ _null_ any_out _null_ _null_ _null_ _null_ ) +insert ( 2296 anyarray_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2277 2275 _null_ _null_ _null_ _null_ _null_ anyarray_in _null_ _null_ _null_ _null_ ) +insert ( 2297 anyarray_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2277 _null_ _null_ _null_ _null_ _null_ anyarray_out _null_ _null_ _null_ _null_ ) +insert ( 2298 void_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2275 _null_ _null_ _null_ _null_ _null_ void_in _null_ _null_ _null_ _null_ ) +insert ( 2299 void_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2278 _null_ _null_ _null_ _null_ _null_ void_out _null_ _null_ _null_ _null_ ) +insert ( 2300 trigger_in 11 10 12 1 0 0 0 f f f f f i s 1 0 2279 2275 _null_ _null_ _null_ _null_ _null_ trigger_in _null_ _null_ _null_ _null_ ) +insert ( 2301 trigger_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2279 _null_ _null_ _null_ _null_ _null_ trigger_out _null_ _null_ _null_ _null_ ) +insert ( 3594 event_trigger_in 11 10 12 1 0 0 0 f f f f f i s 1 0 3838 2275 _null_ _null_ _null_ _null_ _null_ event_trigger_in _null_ _null_ _null_ _null_ ) +insert ( 3595 event_trigger_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3838 _null_ _null_ _null_ _null_ _null_ event_trigger_out _null_ _null_ _null_ _null_ ) +insert ( 2302 language_handler_in 11 10 12 1 0 0 0 f f f f f i s 1 0 2280 2275 _null_ _null_ _null_ _null_ _null_ language_handler_in _null_ _null_ _null_ _null_ ) +insert ( 2303 language_handler_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2280 _null_ _null_ _null_ _null_ _null_ language_handler_out _null_ _null_ _null_ _null_ ) +insert ( 2304 internal_in 11 10 12 1 0 0 0 f f f f f i s 1 0 2281 2275 _null_ _null_ _null_ _null_ _null_ internal_in _null_ _null_ _null_ _null_ ) +insert ( 2305 internal_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2281 _null_ _null_ _null_ _null_ _null_ internal_out _null_ _null_ _null_ _null_ ) +insert ( 2312 anyelement_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2283 2275 _null_ _null_ _null_ _null_ _null_ anyelement_in _null_ _null_ _null_ _null_ ) +insert ( 2313 anyelement_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2283 _null_ _null_ _null_ _null_ _null_ anyelement_out _null_ _null_ _null_ _null_ ) +insert ( 2398 shell_in 11 10 12 1 0 0 0 f f f f f i s 1 0 2278 2275 _null_ _null_ _null_ _null_ _null_ shell_in _null_ _null_ _null_ _null_ ) +insert ( 2399 shell_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2278 _null_ _null_ _null_ _null_ _null_ shell_out _null_ _null_ _null_ _null_ ) +insert ( 2597 domain_in 11 10 12 1 0 0 0 f f f f f s s 3 0 2276 '2275 26 23' _null_ _null_ _null_ _null_ _null_ domain_in _null_ _null_ _null_ _null_ ) +insert ( 2598 domain_recv 11 10 12 1 0 0 0 f f f f f s s 3 0 2276 '2281 26 23' _null_ _null_ _null_ _null_ _null_ domain_recv _null_ _null_ _null_ _null_ ) +insert ( 2777 anynonarray_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2776 2275 _null_ _null_ _null_ _null_ _null_ anynonarray_in _null_ _null_ _null_ _null_ ) +insert ( 2778 anynonarray_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2776 _null_ _null_ _null_ _null_ _null_ anynonarray_out _null_ _null_ _null_ _null_ ) +insert ( 3116 fdw_handler_in 11 10 12 1 0 0 0 f f f f f i s 1 0 3115 2275 _null_ _null_ _null_ _null_ _null_ fdw_handler_in _null_ _null_ _null_ _null_ ) +insert ( 3117 fdw_handler_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3115 _null_ _null_ _null_ _null_ _null_ fdw_handler_out _null_ _null_ _null_ _null_ ) +insert ( 326 index_am_handler_in 11 10 12 1 0 0 0 f f f f f i s 1 0 325 2275 _null_ _null_ _null_ _null_ _null_ index_am_handler_in _null_ _null_ _null_ _null_ ) +insert ( 327 index_am_handler_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 325 _null_ _null_ _null_ _null_ _null_ index_am_handler_out _null_ _null_ _null_ _null_ ) +insert ( 3311 tsm_handler_in 11 10 12 1 0 0 0 f f f f f i s 1 0 3310 2275 _null_ _null_ _null_ _null_ _null_ tsm_handler_in _null_ _null_ _null_ _null_ ) +insert ( 3312 tsm_handler_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3310 _null_ _null_ _null_ _null_ _null_ tsm_handler_out _null_ _null_ _null_ _null_ ) +insert ( 267 table_am_handler_in 11 10 12 1 0 0 0 f f f f f i s 1 0 269 2275 _null_ _null_ _null_ _null_ _null_ table_am_handler_in _null_ _null_ _null_ _null_ ) +insert ( 268 table_am_handler_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 269 _null_ _null_ _null_ _null_ _null_ table_am_handler_out _null_ _null_ _null_ _null_ ) +insert ( 5086 anycompatible_in 11 10 12 1 0 0 0 f f f t f i s 1 0 5077 2275 _null_ _null_ _null_ _null_ _null_ anycompatible_in _null_ _null_ _null_ _null_ ) +insert ( 5087 anycompatible_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 5077 _null_ _null_ _null_ _null_ _null_ anycompatible_out _null_ _null_ _null_ _null_ ) +insert ( 5088 anycompatiblearray_in 11 10 12 1 0 0 0 f f f t f i s 1 0 5078 2275 _null_ _null_ _null_ _null_ _null_ anycompatiblearray_in _null_ _null_ _null_ _null_ ) +insert ( 5089 anycompatiblearray_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 5078 _null_ _null_ _null_ _null_ _null_ anycompatiblearray_out _null_ _null_ _null_ _null_ ) +insert ( 5090 anycompatiblearray_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 5078 2281 _null_ _null_ _null_ _null_ _null_ anycompatiblearray_recv _null_ _null_ _null_ _null_ ) +insert ( 5091 anycompatiblearray_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 5078 _null_ _null_ _null_ _null_ _null_ anycompatiblearray_send _null_ _null_ _null_ _null_ ) +insert ( 5092 anycompatiblenonarray_in 11 10 12 1 0 0 0 f f f t f i s 1 0 5079 2275 _null_ _null_ _null_ _null_ _null_ anycompatiblenonarray_in _null_ _null_ _null_ _null_ ) +insert ( 5093 anycompatiblenonarray_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 5079 _null_ _null_ _null_ _null_ _null_ anycompatiblenonarray_out _null_ _null_ _null_ _null_ ) +insert ( 5094 anycompatiblerange_in 11 10 12 1 0 0 0 f f f t f s s 3 0 5080 '2275 26 23' _null_ _null_ _null_ _null_ _null_ anycompatiblerange_in _null_ _null_ _null_ _null_ ) +insert ( 5095 anycompatiblerange_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 5080 _null_ _null_ _null_ _null_ _null_ anycompatiblerange_out _null_ _null_ _null_ _null_ ) +insert ( 4226 anycompatiblemultirange_in 11 10 12 1 0 0 0 f f f t f s s 3 0 4538 '2275 26 23' _null_ _null_ _null_ _null_ _null_ anycompatiblemultirange_in _null_ _null_ _null_ _null_ ) +insert ( 4227 anycompatiblemultirange_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 4538 _null_ _null_ _null_ _null_ _null_ anycompatiblemultirange_out _null_ _null_ _null_ _null_ ) +insert ( 3313 bernoulli 11 10 12 1 0 0 0 f f f t f v s 1 0 3310 2281 _null_ _null_ _null_ _null_ _null_ tsm_bernoulli_handler _null_ _null_ _null_ _null_ ) +insert ( 3314 system 11 10 12 1 0 0 0 f f f t f v s 1 0 3310 2281 _null_ _null_ _null_ _null_ _null_ tsm_system_handler _null_ _null_ _null_ _null_ ) +insert ( 2311 md5 11 10 12 1 0 0 0 f f t t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ md5_text _null_ _null_ _null_ _null_ ) +insert ( 2321 md5 11 10 12 1 0 0 0 f f t t f i s 1 0 25 17 _null_ _null_ _null_ _null_ _null_ md5_bytea _null_ _null_ _null_ _null_ ) +insert ( 3419 sha224 11 10 12 1 0 0 0 f f t t f i s 1 0 17 17 _null_ _null_ _null_ _null_ _null_ sha224_bytea _null_ _null_ _null_ _null_ ) +insert ( 3420 sha256 11 10 12 1 0 0 0 f f t t f i s 1 0 17 17 _null_ _null_ _null_ _null_ _null_ sha256_bytea _null_ _null_ _null_ _null_ ) +insert ( 3421 sha384 11 10 12 1 0 0 0 f f t t f i s 1 0 17 17 _null_ _null_ _null_ _null_ _null_ sha384_bytea _null_ _null_ _null_ _null_ ) +insert ( 3422 sha512 11 10 12 1 0 0 0 f f t t f i s 1 0 17 17 _null_ _null_ _null_ _null_ _null_ sha512_bytea _null_ _null_ _null_ _null_ ) +insert ( 2338 date_lt_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1082 1114' _null_ _null_ _null_ _null_ _null_ date_lt_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2339 date_le_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1082 1114' _null_ _null_ _null_ _null_ _null_ date_le_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2340 date_eq_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1082 1114' _null_ _null_ _null_ _null_ _null_ date_eq_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2341 date_gt_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1082 1114' _null_ _null_ _null_ _null_ _null_ date_gt_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2342 date_ge_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1082 1114' _null_ _null_ _null_ _null_ _null_ date_ge_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2343 date_ne_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1082 1114' _null_ _null_ _null_ _null_ _null_ date_ne_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2344 date_cmp_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '1082 1114' _null_ _null_ _null_ _null_ _null_ date_cmp_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2351 date_lt_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1082 1184' _null_ _null_ _null_ _null_ _null_ date_lt_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2352 date_le_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1082 1184' _null_ _null_ _null_ _null_ _null_ date_le_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2353 date_eq_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1082 1184' _null_ _null_ _null_ _null_ _null_ date_eq_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2354 date_gt_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1082 1184' _null_ _null_ _null_ _null_ _null_ date_gt_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2355 date_ge_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1082 1184' _null_ _null_ _null_ _null_ _null_ date_ge_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2356 date_ne_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1082 1184' _null_ _null_ _null_ _null_ _null_ date_ne_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2357 date_cmp_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 23 '1082 1184' _null_ _null_ _null_ _null_ _null_ date_cmp_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2364 timestamp_lt_date 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1114 1082' _null_ _null_ _null_ _null_ _null_ timestamp_lt_date _null_ _null_ _null_ _null_ ) +insert ( 2365 timestamp_le_date 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1114 1082' _null_ _null_ _null_ _null_ _null_ timestamp_le_date _null_ _null_ _null_ _null_ ) +insert ( 2366 timestamp_eq_date 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1114 1082' _null_ _null_ _null_ _null_ _null_ timestamp_eq_date _null_ _null_ _null_ _null_ ) +insert ( 2367 timestamp_gt_date 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1114 1082' _null_ _null_ _null_ _null_ _null_ timestamp_gt_date _null_ _null_ _null_ _null_ ) +insert ( 2368 timestamp_ge_date 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1114 1082' _null_ _null_ _null_ _null_ _null_ timestamp_ge_date _null_ _null_ _null_ _null_ ) +insert ( 2369 timestamp_ne_date 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '1114 1082' _null_ _null_ _null_ _null_ _null_ timestamp_ne_date _null_ _null_ _null_ _null_ ) +insert ( 2370 timestamp_cmp_date 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '1114 1082' _null_ _null_ _null_ _null_ _null_ timestamp_cmp_date _null_ _null_ _null_ _null_ ) +insert ( 2377 timestamptz_lt_date 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1082' _null_ _null_ _null_ _null_ _null_ timestamptz_lt_date _null_ _null_ _null_ _null_ ) +insert ( 2378 timestamptz_le_date 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1082' _null_ _null_ _null_ _null_ _null_ timestamptz_le_date _null_ _null_ _null_ _null_ ) +insert ( 2379 timestamptz_eq_date 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1082' _null_ _null_ _null_ _null_ _null_ timestamptz_eq_date _null_ _null_ _null_ _null_ ) +insert ( 2380 timestamptz_gt_date 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1082' _null_ _null_ _null_ _null_ _null_ timestamptz_gt_date _null_ _null_ _null_ _null_ ) +insert ( 2381 timestamptz_ge_date 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1082' _null_ _null_ _null_ _null_ _null_ timestamptz_ge_date _null_ _null_ _null_ _null_ ) +insert ( 2382 timestamptz_ne_date 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1082' _null_ _null_ _null_ _null_ _null_ timestamptz_ne_date _null_ _null_ _null_ _null_ ) +insert ( 2383 timestamptz_cmp_date 11 10 12 1 0 0 0 f f f t f s s 2 0 23 '1184 1082' _null_ _null_ _null_ _null_ _null_ timestamptz_cmp_date _null_ _null_ _null_ _null_ ) +insert ( 2520 timestamp_lt_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1114 1184' _null_ _null_ _null_ _null_ _null_ timestamp_lt_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2521 timestamp_le_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1114 1184' _null_ _null_ _null_ _null_ _null_ timestamp_le_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2522 timestamp_eq_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1114 1184' _null_ _null_ _null_ _null_ _null_ timestamp_eq_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2523 timestamp_gt_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1114 1184' _null_ _null_ _null_ _null_ _null_ timestamp_gt_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2524 timestamp_ge_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1114 1184' _null_ _null_ _null_ _null_ _null_ timestamp_ge_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2525 timestamp_ne_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1114 1184' _null_ _null_ _null_ _null_ _null_ timestamp_ne_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2526 timestamp_cmp_timestamptz 11 10 12 1 0 0 0 f f f t f s s 2 0 23 '1114 1184' _null_ _null_ _null_ _null_ _null_ timestamp_cmp_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 2527 timestamptz_lt_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1114' _null_ _null_ _null_ _null_ _null_ timestamptz_lt_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2528 timestamptz_le_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1114' _null_ _null_ _null_ _null_ _null_ timestamptz_le_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2529 timestamptz_eq_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1114' _null_ _null_ _null_ _null_ _null_ timestamptz_eq_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2530 timestamptz_gt_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1114' _null_ _null_ _null_ _null_ _null_ timestamptz_gt_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2531 timestamptz_ge_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1114' _null_ _null_ _null_ _null_ _null_ timestamptz_ge_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2532 timestamptz_ne_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '1184 1114' _null_ _null_ _null_ _null_ _null_ timestamptz_ne_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2533 timestamptz_cmp_timestamp 11 10 12 1 0 0 0 f f f t f s s 2 0 23 '1184 1114' _null_ _null_ _null_ _null_ _null_ timestamptz_cmp_timestamp _null_ _null_ _null_ _null_ ) +insert ( 2400 array_recv 11 10 12 1 0 0 0 f f f t f s s 3 0 2277 '2281 26 23' _null_ _null_ _null_ _null_ _null_ array_recv _null_ _null_ _null_ _null_ ) +insert ( 2401 array_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 2277 _null_ _null_ _null_ _null_ _null_ array_send _null_ _null_ _null_ _null_ ) +insert ( 2402 record_recv 11 10 12 1 0 0 0 f f f t f s s 3 0 2249 '2281 26 23' _null_ _null_ _null_ _null_ _null_ record_recv _null_ _null_ _null_ _null_ ) +insert ( 2403 record_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 2249 _null_ _null_ _null_ _null_ _null_ record_send _null_ _null_ _null_ _null_ ) +insert ( 2404 int2recv 11 10 12 1 0 0 0 f f f t f i s 1 0 21 2281 _null_ _null_ _null_ _null_ _null_ int2recv _null_ _null_ _null_ _null_ ) +insert ( 2405 int2send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 21 _null_ _null_ _null_ _null_ _null_ int2send _null_ _null_ _null_ _null_ ) +insert ( 2406 int4recv 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2281 _null_ _null_ _null_ _null_ _null_ int4recv _null_ _null_ _null_ _null_ ) +insert ( 2407 int4send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 23 _null_ _null_ _null_ _null_ _null_ int4send _null_ _null_ _null_ _null_ ) +insert ( 2408 int8recv 11 10 12 1 0 0 0 f f f t f i s 1 0 20 2281 _null_ _null_ _null_ _null_ _null_ int8recv _null_ _null_ _null_ _null_ ) +insert ( 2409 int8send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 20 _null_ _null_ _null_ _null_ _null_ int8send _null_ _null_ _null_ _null_ ) +insert ( 2410 int2vectorrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 22 2281 _null_ _null_ _null_ _null_ _null_ int2vectorrecv _null_ _null_ _null_ _null_ ) +insert ( 2411 int2vectorsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 22 _null_ _null_ _null_ _null_ _null_ int2vectorsend _null_ _null_ _null_ _null_ ) +insert ( 2412 bytearecv 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2281 _null_ _null_ _null_ _null_ _null_ bytearecv _null_ _null_ _null_ _null_ ) +insert ( 2413 byteasend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 17 _null_ _null_ _null_ _null_ _null_ byteasend _null_ _null_ _null_ _null_ ) +insert ( 2414 textrecv 11 10 12 1 0 0 0 f f f t f s s 1 0 25 2281 _null_ _null_ _null_ _null_ _null_ textrecv _null_ _null_ _null_ _null_ ) +insert ( 2415 textsend 11 10 12 1 0 0 0 f f f t f s s 1 0 17 25 _null_ _null_ _null_ _null_ _null_ textsend _null_ _null_ _null_ _null_ ) +insert ( 2416 unknownrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 705 2281 _null_ _null_ _null_ _null_ _null_ unknownrecv _null_ _null_ _null_ _null_ ) +insert ( 2417 unknownsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 705 _null_ _null_ _null_ _null_ _null_ unknownsend _null_ _null_ _null_ _null_ ) +insert ( 2418 oidrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 26 2281 _null_ _null_ _null_ _null_ _null_ oidrecv _null_ _null_ _null_ _null_ ) +insert ( 2419 oidsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 26 _null_ _null_ _null_ _null_ _null_ oidsend _null_ _null_ _null_ _null_ ) +insert ( 2420 oidvectorrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 30 2281 _null_ _null_ _null_ _null_ _null_ oidvectorrecv _null_ _null_ _null_ _null_ ) +insert ( 2421 oidvectorsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 30 _null_ _null_ _null_ _null_ _null_ oidvectorsend _null_ _null_ _null_ _null_ ) +insert ( 2422 namerecv 11 10 12 1 0 0 0 f f f t f s s 1 0 19 2281 _null_ _null_ _null_ _null_ _null_ namerecv _null_ _null_ _null_ _null_ ) +insert ( 2423 namesend 11 10 12 1 0 0 0 f f f t f s s 1 0 17 19 _null_ _null_ _null_ _null_ _null_ namesend _null_ _null_ _null_ _null_ ) +insert ( 2424 float4recv 11 10 12 1 0 0 0 f f f t f i s 1 0 700 2281 _null_ _null_ _null_ _null_ _null_ float4recv _null_ _null_ _null_ _null_ ) +insert ( 2425 float4send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 700 _null_ _null_ _null_ _null_ _null_ float4send _null_ _null_ _null_ _null_ ) +insert ( 2426 float8recv 11 10 12 1 0 0 0 f f f t f i s 1 0 701 2281 _null_ _null_ _null_ _null_ _null_ float8recv _null_ _null_ _null_ _null_ ) +insert ( 2427 float8send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 701 _null_ _null_ _null_ _null_ _null_ float8send _null_ _null_ _null_ _null_ ) +insert ( 2428 point_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 600 2281 _null_ _null_ _null_ _null_ _null_ point_recv _null_ _null_ _null_ _null_ ) +insert ( 2429 point_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 600 _null_ _null_ _null_ _null_ _null_ point_send _null_ _null_ _null_ _null_ ) +insert ( 2430 bpcharrecv 11 10 12 1 0 0 0 f f f t f s s 3 0 1042 '2281 26 23' _null_ _null_ _null_ _null_ _null_ bpcharrecv _null_ _null_ _null_ _null_ ) +insert ( 2431 bpcharsend 11 10 12 1 0 0 0 f f f t f s s 1 0 17 1042 _null_ _null_ _null_ _null_ _null_ bpcharsend _null_ _null_ _null_ _null_ ) +insert ( 2432 varcharrecv 11 10 12 1 0 0 0 f f f t f s s 3 0 1043 '2281 26 23' _null_ _null_ _null_ _null_ _null_ varcharrecv _null_ _null_ _null_ _null_ ) +insert ( 2433 varcharsend 11 10 12 1 0 0 0 f f f t f s s 1 0 17 1043 _null_ _null_ _null_ _null_ _null_ varcharsend _null_ _null_ _null_ _null_ ) +insert ( 2434 charrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 18 2281 _null_ _null_ _null_ _null_ _null_ charrecv _null_ _null_ _null_ _null_ ) +insert ( 2435 charsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 18 _null_ _null_ _null_ _null_ _null_ charsend _null_ _null_ _null_ _null_ ) +insert ( 2436 boolrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 16 2281 _null_ _null_ _null_ _null_ _null_ boolrecv _null_ _null_ _null_ _null_ ) +insert ( 2437 boolsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 16 _null_ _null_ _null_ _null_ _null_ boolsend _null_ _null_ _null_ _null_ ) +insert ( 2438 tidrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 27 2281 _null_ _null_ _null_ _null_ _null_ tidrecv _null_ _null_ _null_ _null_ ) +insert ( 2439 tidsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 27 _null_ _null_ _null_ _null_ _null_ tidsend _null_ _null_ _null_ _null_ ) +insert ( 2440 xidrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 28 2281 _null_ _null_ _null_ _null_ _null_ xidrecv _null_ _null_ _null_ _null_ ) +insert ( 2441 xidsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 28 _null_ _null_ _null_ _null_ _null_ xidsend _null_ _null_ _null_ _null_ ) +insert ( 2442 cidrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 29 2281 _null_ _null_ _null_ _null_ _null_ cidrecv _null_ _null_ _null_ _null_ ) +insert ( 2443 cidsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 29 _null_ _null_ _null_ _null_ _null_ cidsend _null_ _null_ _null_ _null_ ) +insert ( 2444 regprocrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 24 2281 _null_ _null_ _null_ _null_ _null_ regprocrecv _null_ _null_ _null_ _null_ ) +insert ( 2445 regprocsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 24 _null_ _null_ _null_ _null_ _null_ regprocsend _null_ _null_ _null_ _null_ ) +insert ( 2446 regprocedurerecv 11 10 12 1 0 0 0 f f f t f i s 1 0 2202 2281 _null_ _null_ _null_ _null_ _null_ regprocedurerecv _null_ _null_ _null_ _null_ ) +insert ( 2447 regproceduresend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2202 _null_ _null_ _null_ _null_ _null_ regproceduresend _null_ _null_ _null_ _null_ ) +insert ( 2448 regoperrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 2203 2281 _null_ _null_ _null_ _null_ _null_ regoperrecv _null_ _null_ _null_ _null_ ) +insert ( 2449 regopersend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2203 _null_ _null_ _null_ _null_ _null_ regopersend _null_ _null_ _null_ _null_ ) +insert ( 2450 regoperatorrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 2204 2281 _null_ _null_ _null_ _null_ _null_ regoperatorrecv _null_ _null_ _null_ _null_ ) +insert ( 2451 regoperatorsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2204 _null_ _null_ _null_ _null_ _null_ regoperatorsend _null_ _null_ _null_ _null_ ) +insert ( 2452 regclassrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 2205 2281 _null_ _null_ _null_ _null_ _null_ regclassrecv _null_ _null_ _null_ _null_ ) +insert ( 2453 regclasssend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2205 _null_ _null_ _null_ _null_ _null_ regclasssend _null_ _null_ _null_ _null_ ) +insert ( 4196 regcollationrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 4191 2281 _null_ _null_ _null_ _null_ _null_ regcollationrecv _null_ _null_ _null_ _null_ ) +insert ( 4197 regcollationsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 4191 _null_ _null_ _null_ _null_ _null_ regcollationsend _null_ _null_ _null_ _null_ ) +insert ( 2454 regtyperecv 11 10 12 1 0 0 0 f f f t f i s 1 0 2206 2281 _null_ _null_ _null_ _null_ _null_ regtyperecv _null_ _null_ _null_ _null_ ) +insert ( 2455 regtypesend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2206 _null_ _null_ _null_ _null_ _null_ regtypesend _null_ _null_ _null_ _null_ ) +insert ( 4094 regrolerecv 11 10 12 1 0 0 0 f f f t f i s 1 0 4096 2281 _null_ _null_ _null_ _null_ _null_ regrolerecv _null_ _null_ _null_ _null_ ) +insert ( 4095 regrolesend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 4096 _null_ _null_ _null_ _null_ _null_ regrolesend _null_ _null_ _null_ _null_ ) +insert ( 4087 regnamespacerecv 11 10 12 1 0 0 0 f f f t f i s 1 0 4089 2281 _null_ _null_ _null_ _null_ _null_ regnamespacerecv _null_ _null_ _null_ _null_ ) +insert ( 4088 regnamespacesend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 4089 _null_ _null_ _null_ _null_ _null_ regnamespacesend _null_ _null_ _null_ _null_ ) +insert ( 2456 bit_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1560 '2281 26 23' _null_ _null_ _null_ _null_ _null_ bit_recv _null_ _null_ _null_ _null_ ) +insert ( 2457 bit_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1560 _null_ _null_ _null_ _null_ _null_ bit_send _null_ _null_ _null_ _null_ ) +insert ( 2458 varbit_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1562 '2281 26 23' _null_ _null_ _null_ _null_ _null_ varbit_recv _null_ _null_ _null_ _null_ ) +insert ( 2459 varbit_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1562 _null_ _null_ _null_ _null_ _null_ varbit_send _null_ _null_ _null_ _null_ ) +insert ( 2460 numeric_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1700 '2281 26 23' _null_ _null_ _null_ _null_ _null_ numeric_recv _null_ _null_ _null_ _null_ ) +insert ( 2461 numeric_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1700 _null_ _null_ _null_ _null_ _null_ numeric_send _null_ _null_ _null_ _null_ ) +insert ( 2468 date_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 1082 2281 _null_ _null_ _null_ _null_ _null_ date_recv _null_ _null_ _null_ _null_ ) +insert ( 2469 date_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1082 _null_ _null_ _null_ _null_ _null_ date_send _null_ _null_ _null_ _null_ ) +insert ( 2470 time_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1083 '2281 26 23' _null_ _null_ _null_ _null_ _null_ time_recv _null_ _null_ _null_ _null_ ) +insert ( 2471 time_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1083 _null_ _null_ _null_ _null_ _null_ time_send _null_ _null_ _null_ _null_ ) +insert ( 2472 timetz_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1266 '2281 26 23' _null_ _null_ _null_ _null_ _null_ timetz_recv _null_ _null_ _null_ _null_ ) +insert ( 2473 timetz_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1266 _null_ _null_ _null_ _null_ _null_ timetz_send _null_ _null_ _null_ _null_ ) +insert ( 2474 timestamp_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1114 '2281 26 23' _null_ _null_ _null_ _null_ _null_ timestamp_recv _null_ _null_ _null_ _null_ ) +insert ( 2475 timestamp_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1114 _null_ _null_ _null_ _null_ _null_ timestamp_send _null_ _null_ _null_ _null_ ) +insert ( 2476 timestamptz_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1184 '2281 26 23' _null_ _null_ _null_ _null_ _null_ timestamptz_recv _null_ _null_ _null_ _null_ ) +insert ( 2477 timestamptz_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1184 _null_ _null_ _null_ _null_ _null_ timestamptz_send _null_ _null_ _null_ _null_ ) +insert ( 2478 interval_recv 11 10 12 1 0 0 0 f f f t f i s 3 0 1186 '2281 26 23' _null_ _null_ _null_ _null_ _null_ interval_recv _null_ _null_ _null_ _null_ ) +insert ( 2479 interval_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 1186 _null_ _null_ _null_ _null_ _null_ interval_send _null_ _null_ _null_ _null_ ) +insert ( 2480 lseg_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 601 2281 _null_ _null_ _null_ _null_ _null_ lseg_recv _null_ _null_ _null_ _null_ ) +insert ( 2481 lseg_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 601 _null_ _null_ _null_ _null_ _null_ lseg_send _null_ _null_ _null_ _null_ ) +insert ( 2482 path_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 602 2281 _null_ _null_ _null_ _null_ _null_ path_recv _null_ _null_ _null_ _null_ ) +insert ( 2483 path_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 602 _null_ _null_ _null_ _null_ _null_ path_send _null_ _null_ _null_ _null_ ) +insert ( 2484 box_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 603 2281 _null_ _null_ _null_ _null_ _null_ box_recv _null_ _null_ _null_ _null_ ) +insert ( 2485 box_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 603 _null_ _null_ _null_ _null_ _null_ box_send _null_ _null_ _null_ _null_ ) +insert ( 2486 poly_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 604 2281 _null_ _null_ _null_ _null_ _null_ poly_recv _null_ _null_ _null_ _null_ ) +insert ( 2487 poly_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 604 _null_ _null_ _null_ _null_ _null_ poly_send _null_ _null_ _null_ _null_ ) +insert ( 2488 line_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 628 2281 _null_ _null_ _null_ _null_ _null_ line_recv _null_ _null_ _null_ _null_ ) +insert ( 2489 line_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 628 _null_ _null_ _null_ _null_ _null_ line_send _null_ _null_ _null_ _null_ ) +insert ( 2490 circle_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 718 2281 _null_ _null_ _null_ _null_ _null_ circle_recv _null_ _null_ _null_ _null_ ) +insert ( 2491 circle_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 718 _null_ _null_ _null_ _null_ _null_ circle_send _null_ _null_ _null_ _null_ ) +insert ( 2492 cash_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 790 2281 _null_ _null_ _null_ _null_ _null_ cash_recv _null_ _null_ _null_ _null_ ) +insert ( 2493 cash_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 790 _null_ _null_ _null_ _null_ _null_ cash_send _null_ _null_ _null_ _null_ ) +insert ( 2494 macaddr_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 829 2281 _null_ _null_ _null_ _null_ _null_ macaddr_recv _null_ _null_ _null_ _null_ ) +insert ( 2495 macaddr_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 829 _null_ _null_ _null_ _null_ _null_ macaddr_send _null_ _null_ _null_ _null_ ) +insert ( 2496 inet_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 869 2281 _null_ _null_ _null_ _null_ _null_ inet_recv _null_ _null_ _null_ _null_ ) +insert ( 2497 inet_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 869 _null_ _null_ _null_ _null_ _null_ inet_send _null_ _null_ _null_ _null_ ) +insert ( 2498 cidr_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 650 2281 _null_ _null_ _null_ _null_ _null_ cidr_recv _null_ _null_ _null_ _null_ ) +insert ( 2499 cidr_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 650 _null_ _null_ _null_ _null_ _null_ cidr_send _null_ _null_ _null_ _null_ ) +insert ( 2500 cstring_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 2281 _null_ _null_ _null_ _null_ _null_ cstring_recv _null_ _null_ _null_ _null_ ) +insert ( 2501 cstring_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 2275 _null_ _null_ _null_ _null_ _null_ cstring_send _null_ _null_ _null_ _null_ ) +insert ( 2502 anyarray_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 2277 2281 _null_ _null_ _null_ _null_ _null_ anyarray_recv _null_ _null_ _null_ _null_ ) +insert ( 2503 anyarray_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 2277 _null_ _null_ _null_ _null_ _null_ anyarray_send _null_ _null_ _null_ _null_ ) +insert ( 3120 void_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ void_recv _null_ _null_ _null_ _null_ ) +insert ( 3121 void_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2278 _null_ _null_ _null_ _null_ _null_ void_send _null_ _null_ _null_ _null_ ) +insert ( 3446 macaddr8_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 774 2281 _null_ _null_ _null_ _null_ _null_ macaddr8_recv _null_ _null_ _null_ _null_ ) +insert ( 3447 macaddr8_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 774 _null_ _null_ _null_ _null_ _null_ macaddr8_send _null_ _null_ _null_ _null_ ) +insert ( 2504 pg_get_ruledef 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '26 16' _null_ _null_ _null_ _null_ _null_ pg_get_ruledef_ext _null_ _null_ _null_ _null_ ) +insert ( 2505 pg_get_viewdef 11 10 12 1 0 0 0 f f f t f s r 2 0 25 '25 16' _null_ _null_ _null_ _null_ _null_ pg_get_viewdef_name_ext _null_ _null_ _null_ _null_ ) +insert ( 2506 pg_get_viewdef 11 10 12 1 0 0 0 f f f t f s r 2 0 25 '26 16' _null_ _null_ _null_ _null_ _null_ pg_get_viewdef_ext _null_ _null_ _null_ _null_ ) +insert ( 3159 pg_get_viewdef 11 10 12 1 0 0 0 f f f t f s r 2 0 25 '26 23' _null_ _null_ _null_ _null_ _null_ pg_get_viewdef_wrap _null_ _null_ _null_ _null_ ) +insert ( 2507 pg_get_indexdef 11 10 12 1 0 0 0 f f f t f s s 3 0 25 '26 23 16' _null_ _null_ _null_ _null_ _null_ pg_get_indexdef_ext _null_ _null_ _null_ _null_ ) +insert ( 2508 pg_get_constraintdef 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '26 16' _null_ _null_ _null_ _null_ _null_ pg_get_constraintdef_ext _null_ _null_ _null_ _null_ ) +insert ( 2509 pg_get_expr 11 10 12 1 0 0 0 f f f t f s s 3 0 25 '194 26 16' _null_ _null_ _null_ _null_ _null_ pg_get_expr_ext _null_ _null_ _null_ _null_ ) +insert ( 2510 pg_prepared_statement 11 10 12 1 1000 0 0 f f f t t s r 0 0 2249 '' '{25,25,1184,2211,2211,16,20,20}' '{o,o,o,o,o,o,o,o}' '{name,statement,prepare_time,parameter_types,result_types,from_sql,generic_plans,custom_plans}' _null_ _null_ pg_prepared_statement _null_ _null_ _null_ _null_ ) +insert ( 2511 pg_cursor 11 10 12 1 1000 0 0 f f f t t s r 0 0 2249 '' '{25,25,16,16,16,1184}' '{o,o,o,o,o,o}' '{name,statement,is_holdable,is_binary,is_scrollable,creation_time}' _null_ _null_ pg_cursor _null_ _null_ _null_ _null_ ) +insert ( 2599 pg_timezone_abbrevs 11 10 12 1 1000 0 0 f f f t t s s 0 0 2249 '' '{25,1186,16}' '{o,o,o}' '{abbrev,utc_offset,is_dst}' _null_ _null_ pg_timezone_abbrevs _null_ _null_ _null_ _null_ ) +insert ( 2856 pg_timezone_names 11 10 12 1 1000 0 0 f f f t t s s 0 0 2249 '' '{25,25,1186,16}' '{o,o,o,o}' '{name,abbrev,utc_offset,is_dst}' _null_ _null_ pg_timezone_names _null_ _null_ _null_ _null_ ) +insert ( 2730 pg_get_triggerdef 11 10 12 1 0 0 0 f f f t f s s 2 0 25 '26 16' _null_ _null_ _null_ _null_ _null_ pg_get_triggerdef_ext _null_ _null_ _null_ _null_ ) +insert ( 3035 pg_listening_channels 11 10 12 1 10 0 0 f f f t t s r 0 0 25 '' _null_ _null_ _null_ _null_ _null_ pg_listening_channels _null_ _null_ _null_ _null_ ) +insert ( 3036 pg_notify 11 10 12 1 0 0 0 f f f f f v r 2 0 2278 '25 25' _null_ _null_ _null_ _null_ _null_ pg_notify _null_ _null_ _null_ _null_ ) +insert ( 3296 pg_notification_queue_usage 11 10 12 1 0 0 0 f f f t f v r 0 0 701 '' _null_ _null_ _null_ _null_ _null_ pg_notification_queue_usage _null_ _null_ _null_ _null_ ) +insert ( 5052 pg_get_shmem_allocations 11 10 12 1 50 0 0 f f f t t v s 0 0 2249 '' '{25,20,20,20}' '{o,o,o,o}' '{name,off,size,allocated_size}' _null_ _null_ pg_get_shmem_allocations _null_ _null_ _null_ _null_ ) +insert ( 2282 pg_get_backend_memory_contexts 11 10 12 1 100 0 0 f f f t t v r 0 0 2249 '' '{25,25,25,23,20,20,20,20,20}' '{o,o,o,o,o,o,o,o,o}' '{name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}' _null_ _null_ pg_get_backend_memory_contexts _null_ _null_ _null_ _null_ ) +insert ( 4543 pg_log_backend_memory_contexts 11 10 12 1 0 0 0 f f f t f v s 1 0 16 23 _null_ _null_ _null_ _null_ _null_ pg_log_backend_memory_contexts _null_ _null_ _null_ _null_ ) +insert ( 1066 generate_series 11 10 12 1 1000 0 3994 f f f t t i s 3 0 23 '23 23 23' _null_ _null_ _null_ _null_ _null_ generate_series_step_int4 _null_ _null_ _null_ _null_ ) +insert ( 1067 generate_series 11 10 12 1 1000 0 3994 f f f t t i s 2 0 23 '23 23' _null_ _null_ _null_ _null_ _null_ generate_series_int4 _null_ _null_ _null_ _null_ ) +insert ( 3994 generate_series_int4_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ generate_series_int4_support _null_ _null_ _null_ _null_ ) +insert ( 1068 generate_series 11 10 12 1 1000 0 3995 f f f t t i s 3 0 20 '20 20 20' _null_ _null_ _null_ _null_ _null_ generate_series_step_int8 _null_ _null_ _null_ _null_ ) +insert ( 1069 generate_series 11 10 12 1 1000 0 3995 f f f t t i s 2 0 20 '20 20' _null_ _null_ _null_ _null_ _null_ generate_series_int8 _null_ _null_ _null_ _null_ ) +insert ( 3995 generate_series_int8_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ generate_series_int8_support _null_ _null_ _null_ _null_ ) +insert ( 3259 generate_series 11 10 12 1 1000 0 0 f f f t t i s 3 0 1700 '1700 1700 1700' _null_ _null_ _null_ _null_ _null_ generate_series_step_numeric _null_ _null_ _null_ _null_ ) +insert ( 3260 generate_series 11 10 12 1 1000 0 0 f f f t t i s 2 0 1700 '1700 1700' _null_ _null_ _null_ _null_ _null_ generate_series_numeric _null_ _null_ _null_ _null_ ) +insert ( 938 generate_series 11 10 12 1 1000 0 0 f f f t t i s 3 0 1114 '1114 1114 1186' _null_ _null_ _null_ _null_ _null_ generate_series_timestamp _null_ _null_ _null_ _null_ ) +insert ( 939 generate_series 11 10 12 1 1000 0 0 f f f t t s s 3 0 1184 '1184 1184 1186' _null_ _null_ _null_ _null_ _null_ generate_series_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 6274 generate_series 11 10 12 1 1000 0 0 f f f t t i s 4 0 1184 '1184 1184 1186 25' _null_ _null_ _null_ _null_ _null_ generate_series_timestamptz_at_zone _null_ _null_ _null_ _null_ ) +insert ( 2515 booland_statefunc 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ booland_statefunc _null_ _null_ _null_ _null_ ) +insert ( 2516 boolor_statefunc 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '16 16' _null_ _null_ _null_ _null_ _null_ boolor_statefunc _null_ _null_ _null_ _null_ ) +insert ( 3496 bool_accum 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 16' _null_ _null_ _null_ _null_ _null_ bool_accum _null_ _null_ _null_ _null_ ) +insert ( 3497 bool_accum_inv 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 16' _null_ _null_ _null_ _null_ _null_ bool_accum_inv _null_ _null_ _null_ _null_ ) +insert ( 3498 bool_alltrue 11 10 12 1 0 0 0 f f f t f i s 1 0 16 2281 _null_ _null_ _null_ _null_ _null_ bool_alltrue _null_ _null_ _null_ _null_ ) +insert ( 3499 bool_anytrue 11 10 12 1 0 0 0 f f f t f i s 1 0 16 2281 _null_ _null_ _null_ _null_ _null_ bool_anytrue _null_ _null_ _null_ _null_ ) +insert ( 2517 bool_and 11 10 12 1 0 0 0 a f f f f i s 1 0 16 16 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2518 bool_or 11 10 12 1 0 0 0 a f f f f i s 1 0 16 16 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2519 every 11 10 12 1 0 0 0 a f f f f i s 1 0 16 16 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2236 bit_and 11 10 12 1 0 0 0 a f f f f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2237 bit_or 11 10 12 1 0 0 0 a f f f f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6164 bit_xor 11 10 12 1 0 0 0 a f f f f i s 1 0 21 21 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2238 bit_and 11 10 12 1 0 0 0 a f f f f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2239 bit_or 11 10 12 1 0 0 0 a f f f f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6165 bit_xor 11 10 12 1 0 0 0 a f f f f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2240 bit_and 11 10 12 1 0 0 0 a f f f f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2241 bit_or 11 10 12 1 0 0 0 a f f f f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6166 bit_xor 11 10 12 1 0 0 0 a f f f f i s 1 0 20 20 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2242 bit_and 11 10 12 1 0 0 0 a f f f f i s 1 0 1560 1560 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2243 bit_or 11 10 12 1 0 0 0 a f f f f i s 1 0 1560 1560 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6167 bit_xor 11 10 12 1 0 0 0 a f f f f i s 1 0 1560 1560 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2546 interval_pl_date 11 10 14 1 0 0 0 f f f t f i s 2 0 1114 '1186 1082' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2547 interval_pl_timetz 11 10 14 1 0 0 0 f f f t f i s 2 0 1266 '1186 1266' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2548 interval_pl_timestamp 11 10 14 1 0 0 0 f f f t f i s 2 0 1114 '1186 1114' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2549 interval_pl_timestamptz 11 10 14 1 0 0 0 f f f t f s s 2 0 1184 '1186 1184' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2550 integer_pl_date 11 10 14 1 0 0 0 f f f t f i s 2 0 1082 '23 1082' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2556 pg_tablespace_databases 11 10 12 1 1000 0 0 f f f t t s s 1 0 26 26 _null_ _null_ _null_ _null_ _null_ pg_tablespace_databases _null_ _null_ _null_ _null_ ) +insert ( 2557 bool 11 10 12 1 0 0 0 f f t t f i s 1 0 16 23 _null_ _null_ _null_ _null_ _null_ int4_bool _null_ _null_ _null_ _null_ ) +insert ( 2558 int4 11 10 12 1 0 0 0 f f t t f i s 1 0 23 16 _null_ _null_ _null_ _null_ _null_ bool_int4 _null_ _null_ _null_ _null_ ) +insert ( 2559 lastval 11 10 12 1 0 0 0 f f f t f v u 0 0 20 '' _null_ _null_ _null_ _null_ _null_ lastval _null_ _null_ _null_ _null_ ) +insert ( 2560 pg_postmaster_start_time 11 10 12 1 0 0 0 f f f t f s s 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ pg_postmaster_start_time _null_ _null_ _null_ _null_ ) +insert ( 2034 pg_conf_load_time 11 10 12 1 0 0 0 f f f t f s r 0 0 1184 '' _null_ _null_ _null_ _null_ _null_ pg_conf_load_time _null_ _null_ _null_ _null_ ) +insert ( 2562 box_below 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_below _null_ _null_ _null_ _null_ ) +insert ( 2563 box_overbelow 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_overbelow _null_ _null_ _null_ _null_ ) +insert ( 2564 box_overabove 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_overabove _null_ _null_ _null_ _null_ ) +insert ( 2565 box_above 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '603 603' _null_ _null_ _null_ _null_ _null_ box_above _null_ _null_ _null_ _null_ ) +insert ( 2566 poly_below 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_below _null_ _null_ _null_ _null_ ) +insert ( 2567 poly_overbelow 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_overbelow _null_ _null_ _null_ _null_ ) +insert ( 2568 poly_overabove 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_overabove _null_ _null_ _null_ _null_ ) +insert ( 2569 poly_above 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '604 604' _null_ _null_ _null_ _null_ _null_ poly_above _null_ _null_ _null_ _null_ ) +insert ( 2587 circle_overbelow 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_overbelow _null_ _null_ _null_ _null_ ) +insert ( 2588 circle_overabove 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '718 718' _null_ _null_ _null_ _null_ _null_ circle_overabove _null_ _null_ _null_ _null_ ) +insert ( 2578 gist_box_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 603 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_box_consistent _null_ _null_ _null_ _null_ ) +insert ( 2581 gist_box_penalty 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gist_box_penalty _null_ _null_ _null_ _null_ ) +insert ( 2582 gist_box_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ gist_box_picksplit _null_ _null_ _null_ _null_ ) +insert ( 2583 gist_box_union 11 10 12 1 0 0 0 f f f t f i s 2 0 603 '2281 2281' _null_ _null_ _null_ _null_ _null_ gist_box_union _null_ _null_ _null_ _null_ ) +insert ( 2584 gist_box_same 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '603 603 2281' _null_ _null_ _null_ _null_ _null_ gist_box_same _null_ _null_ _null_ _null_ ) +insert ( 3998 gist_box_distance 11 10 12 1 0 0 0 f f f t f i s 5 0 701 '2281 603 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_box_distance _null_ _null_ _null_ _null_ ) +insert ( 2585 gist_poly_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 604 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_poly_consistent _null_ _null_ _null_ _null_ ) +insert ( 2586 gist_poly_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ gist_poly_compress _null_ _null_ _null_ _null_ ) +insert ( 2591 gist_circle_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 718 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_circle_consistent _null_ _null_ _null_ _null_ ) +insert ( 2592 gist_circle_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ gist_circle_compress _null_ _null_ _null_ _null_ ) +insert ( 1030 gist_point_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ gist_point_compress _null_ _null_ _null_ _null_ ) +insert ( 3282 gist_point_fetch 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ gist_point_fetch _null_ _null_ _null_ _null_ ) +insert ( 2179 gist_point_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 600 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_point_consistent _null_ _null_ _null_ _null_ ) +insert ( 3064 gist_point_distance 11 10 12 1 0 0 0 f f f t f i s 5 0 701 '2281 600 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_point_distance _null_ _null_ _null_ _null_ ) +insert ( 3280 gist_circle_distance 11 10 12 1 0 0 0 f f f t f i s 5 0 701 '2281 718 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_circle_distance _null_ _null_ _null_ _null_ ) +insert ( 3288 gist_poly_distance 11 10 12 1 0 0 0 f f f t f i s 5 0 701 '2281 604 21 26 2281' _null_ _null_ _null_ _null_ _null_ gist_poly_distance _null_ _null_ _null_ _null_ ) +insert ( 3435 gist_point_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ gist_point_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 2743 ginarrayextract 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2277 2281 2281' _null_ _null_ _null_ _null_ _null_ ginarrayextract _null_ _null_ _null_ _null_ ) +insert ( 2774 ginqueryarrayextract 11 10 12 1 0 0 0 f f f t f i s 7 0 2281 '2277 2281 21 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ ginqueryarrayextract _null_ _null_ _null_ _null_ ) +insert ( 2744 ginarrayconsistent 11 10 12 1 0 0 0 f f f t f i s 8 0 16 '2281 21 2277 23 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ ginarrayconsistent _null_ _null_ _null_ _null_ ) +insert ( 3920 ginarraytriconsistent 11 10 12 1 0 0 0 f f f t f i s 7 0 18 '2281 21 2277 23 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ ginarraytriconsistent _null_ _null_ _null_ _null_ ) +insert ( 3076 ginarrayextract 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '2277 2281' _null_ _null_ _null_ _null_ _null_ ginarrayextract_2args _null_ _null_ _null_ _null_ ) +insert ( 2747 arrayoverlap 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ arrayoverlap _null_ _null_ _null_ _null_ ) +insert ( 2748 arraycontains 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ arraycontains _null_ _null_ _null_ _null_ ) +insert ( 2749 arraycontained 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2277 2277' _null_ _null_ _null_ _null_ _null_ arraycontained _null_ _null_ _null_ _null_ ) +insert ( 3383 brin_minmax_opcinfo 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ brin_minmax_opcinfo _null_ _null_ _null_ _null_ ) +insert ( 3384 brin_minmax_add_value 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_add_value _null_ _null_ _null_ _null_ ) +insert ( 3385 brin_minmax_consistent 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_consistent _null_ _null_ _null_ _null_ ) +insert ( 3386 brin_minmax_union 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_union _null_ _null_ _null_ _null_ ) +insert ( 4616 brin_minmax_multi_opcinfo 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_opcinfo _null_ _null_ _null_ _null_ ) +insert ( 4617 brin_minmax_multi_add_value 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_add_value _null_ _null_ _null_ _null_ ) +insert ( 4618 brin_minmax_multi_consistent 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '2281 2281 2281 23' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_consistent _null_ _null_ _null_ _null_ ) +insert ( 4619 brin_minmax_multi_union 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_union _null_ _null_ _null_ _null_ ) +insert ( 4620 brin_minmax_multi_options 11 10 12 1 0 0 0 f f f f f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_options _null_ _null_ _null_ _null_ ) +insert ( 4621 brin_minmax_multi_distance_int2 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_int2 _null_ _null_ _null_ _null_ ) +insert ( 4622 brin_minmax_multi_distance_int4 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_int4 _null_ _null_ _null_ _null_ ) +insert ( 4623 brin_minmax_multi_distance_int8 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_int8 _null_ _null_ _null_ _null_ ) +insert ( 4624 brin_minmax_multi_distance_float4 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_float4 _null_ _null_ _null_ _null_ ) +insert ( 4625 brin_minmax_multi_distance_float8 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_float8 _null_ _null_ _null_ _null_ ) +insert ( 4626 brin_minmax_multi_distance_numeric 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_numeric _null_ _null_ _null_ _null_ ) +insert ( 4627 brin_minmax_multi_distance_tid 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_tid _null_ _null_ _null_ _null_ ) +insert ( 4628 brin_minmax_multi_distance_uuid 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_uuid _null_ _null_ _null_ _null_ ) +insert ( 4629 brin_minmax_multi_distance_date 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_date _null_ _null_ _null_ _null_ ) +insert ( 4630 brin_minmax_multi_distance_time 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_time _null_ _null_ _null_ _null_ ) +insert ( 4631 brin_minmax_multi_distance_interval 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_interval _null_ _null_ _null_ _null_ ) +insert ( 4632 brin_minmax_multi_distance_timetz 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_timetz _null_ _null_ _null_ _null_ ) +insert ( 4633 brin_minmax_multi_distance_pg_lsn 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_pg_lsn _null_ _null_ _null_ _null_ ) +insert ( 4634 brin_minmax_multi_distance_macaddr 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_macaddr _null_ _null_ _null_ _null_ ) +insert ( 4635 brin_minmax_multi_distance_macaddr8 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_macaddr8 _null_ _null_ _null_ _null_ ) +insert ( 4636 brin_minmax_multi_distance_inet 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_inet _null_ _null_ _null_ _null_ ) +insert ( 4637 brin_minmax_multi_distance_timestamp 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '2281 2281' _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_distance_timestamp _null_ _null_ _null_ _null_ ) +insert ( 4105 brin_inclusion_opcinfo 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ brin_inclusion_opcinfo _null_ _null_ _null_ _null_ ) +insert ( 4106 brin_inclusion_add_value 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_inclusion_add_value _null_ _null_ _null_ _null_ ) +insert ( 4107 brin_inclusion_consistent 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_inclusion_consistent _null_ _null_ _null_ _null_ ) +insert ( 4108 brin_inclusion_union 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_inclusion_union _null_ _null_ _null_ _null_ ) +insert ( 4591 brin_bloom_opcinfo 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ brin_bloom_opcinfo _null_ _null_ _null_ _null_ ) +insert ( 4592 brin_bloom_add_value 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_bloom_add_value _null_ _null_ _null_ _null_ ) +insert ( 4593 brin_bloom_consistent 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '2281 2281 2281 23' _null_ _null_ _null_ _null_ _null_ brin_bloom_consistent _null_ _null_ _null_ _null_ ) +insert ( 4594 brin_bloom_union 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ brin_bloom_union _null_ _null_ _null_ _null_ ) +insert ( 4595 brin_bloom_options 11 10 12 1 0 0 0 f f f f f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ brin_bloom_options _null_ _null_ _null_ _null_ ) +insert ( 2880 pg_advisory_lock 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 20 _null_ _null_ _null_ _null_ _null_ pg_advisory_lock_int8 _null_ _null_ _null_ _null_ ) +insert ( 3089 pg_advisory_xact_lock 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 20 _null_ _null_ _null_ _null_ _null_ pg_advisory_xact_lock_int8 _null_ _null_ _null_ _null_ ) +insert ( 2881 pg_advisory_lock_shared 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 20 _null_ _null_ _null_ _null_ _null_ pg_advisory_lock_shared_int8 _null_ _null_ _null_ _null_ ) +insert ( 3090 pg_advisory_xact_lock_shared 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 20 _null_ _null_ _null_ _null_ _null_ pg_advisory_xact_lock_shared_int8 _null_ _null_ _null_ _null_ ) +insert ( 2882 pg_try_advisory_lock 11 10 12 1 0 0 0 f f f t f v r 1 0 16 20 _null_ _null_ _null_ _null_ _null_ pg_try_advisory_lock_int8 _null_ _null_ _null_ _null_ ) +insert ( 3091 pg_try_advisory_xact_lock 11 10 12 1 0 0 0 f f f t f v r 1 0 16 20 _null_ _null_ _null_ _null_ _null_ pg_try_advisory_xact_lock_int8 _null_ _null_ _null_ _null_ ) +insert ( 2883 pg_try_advisory_lock_shared 11 10 12 1 0 0 0 f f f t f v r 1 0 16 20 _null_ _null_ _null_ _null_ _null_ pg_try_advisory_lock_shared_int8 _null_ _null_ _null_ _null_ ) +insert ( 3092 pg_try_advisory_xact_lock_shared 11 10 12 1 0 0 0 f f f t f v r 1 0 16 20 _null_ _null_ _null_ _null_ _null_ pg_try_advisory_xact_lock_shared_int8 _null_ _null_ _null_ _null_ ) +insert ( 2884 pg_advisory_unlock 11 10 12 1 0 0 0 f f f t f v r 1 0 16 20 _null_ _null_ _null_ _null_ _null_ pg_advisory_unlock_int8 _null_ _null_ _null_ _null_ ) +insert ( 2885 pg_advisory_unlock_shared 11 10 12 1 0 0 0 f f f t f v r 1 0 16 20 _null_ _null_ _null_ _null_ _null_ pg_advisory_unlock_shared_int8 _null_ _null_ _null_ _null_ ) +insert ( 2886 pg_advisory_lock 11 10 12 1 0 0 0 f f f t f v r 2 0 2278 '23 23' _null_ _null_ _null_ _null_ _null_ pg_advisory_lock_int4 _null_ _null_ _null_ _null_ ) +insert ( 3093 pg_advisory_xact_lock 11 10 12 1 0 0 0 f f f t f v r 2 0 2278 '23 23' _null_ _null_ _null_ _null_ _null_ pg_advisory_xact_lock_int4 _null_ _null_ _null_ _null_ ) +insert ( 2887 pg_advisory_lock_shared 11 10 12 1 0 0 0 f f f t f v r 2 0 2278 '23 23' _null_ _null_ _null_ _null_ _null_ pg_advisory_lock_shared_int4 _null_ _null_ _null_ _null_ ) +insert ( 3094 pg_advisory_xact_lock_shared 11 10 12 1 0 0 0 f f f t f v r 2 0 2278 '23 23' _null_ _null_ _null_ _null_ _null_ pg_advisory_xact_lock_shared_int4 _null_ _null_ _null_ _null_ ) +insert ( 2888 pg_try_advisory_lock 11 10 12 1 0 0 0 f f f t f v r 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ pg_try_advisory_lock_int4 _null_ _null_ _null_ _null_ ) +insert ( 3095 pg_try_advisory_xact_lock 11 10 12 1 0 0 0 f f f t f v r 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ pg_try_advisory_xact_lock_int4 _null_ _null_ _null_ _null_ ) +insert ( 2889 pg_try_advisory_lock_shared 11 10 12 1 0 0 0 f f f t f v r 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ pg_try_advisory_lock_shared_int4 _null_ _null_ _null_ _null_ ) +insert ( 3096 pg_try_advisory_xact_lock_shared 11 10 12 1 0 0 0 f f f t f v r 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ pg_try_advisory_xact_lock_shared_int4 _null_ _null_ _null_ _null_ ) +insert ( 2890 pg_advisory_unlock 11 10 12 1 0 0 0 f f f t f v r 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ pg_advisory_unlock_int4 _null_ _null_ _null_ _null_ ) +insert ( 2891 pg_advisory_unlock_shared 11 10 12 1 0 0 0 f f f t f v r 2 0 16 '23 23' _null_ _null_ _null_ _null_ _null_ pg_advisory_unlock_shared_int4 _null_ _null_ _null_ _null_ ) +insert ( 2892 pg_advisory_unlock_all 11 10 12 1 0 0 0 f f f t f v r 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_advisory_unlock_all _null_ _null_ _null_ _null_ ) +insert ( 2893 xml_in 11 10 12 1 0 0 0 f f f t f s s 1 0 142 2275 _null_ _null_ _null_ _null_ _null_ xml_in _null_ _null_ _null_ _null_ ) +insert ( 2894 xml_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 142 _null_ _null_ _null_ _null_ _null_ xml_out _null_ _null_ _null_ _null_ ) +insert ( 2895 xmlcomment 11 10 12 1 0 0 0 f f f t f i s 1 0 142 25 _null_ _null_ _null_ _null_ _null_ xmlcomment _null_ _null_ _null_ _null_ ) +insert ( 2896 xml 11 10 12 1 0 0 0 f f f t f s s 1 0 142 25 _null_ _null_ _null_ _null_ _null_ texttoxml _null_ _null_ _null_ _null_ ) +insert ( 2897 xmlvalidate 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '142 25' _null_ _null_ _null_ _null_ _null_ xmlvalidate _null_ _null_ _null_ _null_ ) +insert ( 2898 xml_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 142 2281 _null_ _null_ _null_ _null_ _null_ xml_recv _null_ _null_ _null_ _null_ ) +insert ( 2899 xml_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 142 _null_ _null_ _null_ _null_ _null_ xml_send _null_ _null_ _null_ _null_ ) +insert ( 2900 xmlconcat2 11 10 12 1 0 0 0 f f f f f i s 2 0 142 '142 142' _null_ _null_ _null_ _null_ _null_ xmlconcat2 _null_ _null_ _null_ _null_ ) +insert ( 2901 xmlagg 11 10 12 1 0 0 0 a f f f f i s 1 0 142 142 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 2922 text 11 10 12 1 0 0 0 f f f t f i s 1 0 25 142 _null_ _null_ _null_ _null_ _null_ xmltotext _null_ _null_ _null_ _null_ ) +insert ( 2923 table_to_xml 11 10 12 100 0 0 0 f f f t f s r 4 0 142 '2205 16 16 25' _null_ _null_ '{tbl,nulls,tableforest,targetns}' _null_ _null_ table_to_xml _null_ _null_ _null_ _null_ ) +insert ( 2924 query_to_xml 11 10 12 100 0 0 0 f f f t f v u 4 0 142 '25 16 16 25' _null_ _null_ '{query,nulls,tableforest,targetns}' _null_ _null_ query_to_xml _null_ _null_ _null_ _null_ ) +insert ( 2925 cursor_to_xml 11 10 12 100 0 0 0 f f f t f v u 5 0 142 '1790 23 16 16 25' _null_ _null_ '{cursor,count,nulls,tableforest,targetns}' _null_ _null_ cursor_to_xml _null_ _null_ _null_ _null_ ) +insert ( 2926 table_to_xmlschema 11 10 12 100 0 0 0 f f f t f s r 4 0 142 '2205 16 16 25' _null_ _null_ '{tbl,nulls,tableforest,targetns}' _null_ _null_ table_to_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2927 query_to_xmlschema 11 10 12 100 0 0 0 f f f t f v u 4 0 142 '25 16 16 25' _null_ _null_ '{query,nulls,tableforest,targetns}' _null_ _null_ query_to_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2928 cursor_to_xmlschema 11 10 12 100 0 0 0 f f f t f v u 4 0 142 '1790 16 16 25' _null_ _null_ '{cursor,nulls,tableforest,targetns}' _null_ _null_ cursor_to_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2929 table_to_xml_and_xmlschema 11 10 12 100 0 0 0 f f f t f s r 4 0 142 '2205 16 16 25' _null_ _null_ '{tbl,nulls,tableforest,targetns}' _null_ _null_ table_to_xml_and_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2930 query_to_xml_and_xmlschema 11 10 12 100 0 0 0 f f f t f v u 4 0 142 '25 16 16 25' _null_ _null_ '{query,nulls,tableforest,targetns}' _null_ _null_ query_to_xml_and_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2933 schema_to_xml 11 10 12 100 0 0 0 f f f t f s r 4 0 142 '19 16 16 25' _null_ _null_ '{schema,nulls,tableforest,targetns}' _null_ _null_ schema_to_xml _null_ _null_ _null_ _null_ ) +insert ( 2934 schema_to_xmlschema 11 10 12 100 0 0 0 f f f t f s r 4 0 142 '19 16 16 25' _null_ _null_ '{schema,nulls,tableforest,targetns}' _null_ _null_ schema_to_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2935 schema_to_xml_and_xmlschema 11 10 12 100 0 0 0 f f f t f s r 4 0 142 '19 16 16 25' _null_ _null_ '{schema,nulls,tableforest,targetns}' _null_ _null_ schema_to_xml_and_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2936 database_to_xml 11 10 12 100 0 0 0 f f f t f s r 3 0 142 '16 16 25' _null_ _null_ '{nulls,tableforest,targetns}' _null_ _null_ database_to_xml _null_ _null_ _null_ _null_ ) +insert ( 2937 database_to_xmlschema 11 10 12 100 0 0 0 f f f t f s r 3 0 142 '16 16 25' _null_ _null_ '{nulls,tableforest,targetns}' _null_ _null_ database_to_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2938 database_to_xml_and_xmlschema 11 10 12 100 0 0 0 f f f t f s r 3 0 142 '16 16 25' _null_ _null_ '{nulls,tableforest,targetns}' _null_ _null_ database_to_xml_and_xmlschema _null_ _null_ _null_ _null_ ) +insert ( 2931 xpath 11 10 12 1 0 0 0 f f f t f i s 3 0 143 '25 142 1009' _null_ _null_ _null_ _null_ _null_ xpath _null_ _null_ _null_ _null_ ) +insert ( 2932 xpath 11 10 14 1 0 0 0 f f f t f i s 2 0 143 '25 142' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 2614 xmlexists 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 142' _null_ _null_ _null_ _null_ _null_ xmlexists _null_ _null_ _null_ _null_ ) +insert ( 3049 xpath_exists 11 10 12 1 0 0 0 f f f t f i s 3 0 16 '25 142 1009' _null_ _null_ _null_ _null_ _null_ xpath_exists _null_ _null_ _null_ _null_ ) +insert ( 3050 xpath_exists 11 10 14 1 0 0 0 f f f t f i s 2 0 16 '25 142' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 3051 xml_is_well_formed 11 10 12 1 0 0 0 f f f t f s s 1 0 16 25 _null_ _null_ _null_ _null_ _null_ xml_is_well_formed _null_ _null_ _null_ _null_ ) +insert ( 3052 xml_is_well_formed_document 11 10 12 1 0 0 0 f f f t f i s 1 0 16 25 _null_ _null_ _null_ _null_ _null_ xml_is_well_formed_document _null_ _null_ _null_ _null_ ) +insert ( 3053 xml_is_well_formed_content 11 10 12 1 0 0 0 f f f t f i s 1 0 16 25 _null_ _null_ _null_ _null_ _null_ xml_is_well_formed_content _null_ _null_ _null_ _null_ ) +insert ( 321 json_in 11 10 12 1 0 0 0 f f f t f i s 1 0 114 2275 _null_ _null_ _null_ _null_ _null_ json_in _null_ _null_ _null_ _null_ ) +insert ( 322 json_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 114 _null_ _null_ _null_ _null_ _null_ json_out _null_ _null_ _null_ _null_ ) +insert ( 323 json_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 114 2281 _null_ _null_ _null_ _null_ _null_ json_recv _null_ _null_ _null_ _null_ ) +insert ( 324 json_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 114 _null_ _null_ _null_ _null_ _null_ json_send _null_ _null_ _null_ _null_ ) +insert ( 3153 array_to_json 11 10 12 1 0 0 0 f f f t f s s 1 0 114 2277 _null_ _null_ _null_ _null_ _null_ array_to_json _null_ _null_ _null_ _null_ ) +insert ( 3154 array_to_json 11 10 12 1 0 0 0 f f f t f s s 2 0 114 '2277 16' _null_ _null_ _null_ _null_ _null_ array_to_json_pretty _null_ _null_ _null_ _null_ ) +insert ( 3155 row_to_json 11 10 12 1 0 0 0 f f f t f s s 1 0 114 2249 _null_ _null_ _null_ _null_ _null_ row_to_json _null_ _null_ _null_ _null_ ) +insert ( 3156 row_to_json 11 10 12 1 0 0 0 f f f t f s s 2 0 114 '2249 16' _null_ _null_ _null_ _null_ _null_ row_to_json_pretty _null_ _null_ _null_ _null_ ) +insert ( 3173 json_agg_transfn 11 10 12 1 0 0 0 f f f f f s s 2 0 2281 '2281 2283' _null_ _null_ _null_ _null_ _null_ json_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 6275 json_agg_strict_transfn 11 10 12 1 0 0 0 f f f f f s s 2 0 2281 '2281 2283' _null_ _null_ _null_ _null_ _null_ json_agg_strict_transfn _null_ _null_ _null_ _null_ ) +insert ( 3174 json_agg_finalfn 11 10 12 1 0 0 0 f f f f f i s 1 0 114 2281 _null_ _null_ _null_ _null_ _null_ json_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 3175 json_agg 11 10 12 1 0 0 0 a f f f f s s 1 0 114 2283 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6276 json_agg_strict 11 10 12 1 0 0 0 a f f f f s s 1 0 114 2283 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3180 json_object_agg_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ json_object_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 6277 json_object_agg_strict_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ json_object_agg_strict_transfn _null_ _null_ _null_ _null_ ) +insert ( 6278 json_object_agg_unique_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ json_object_agg_unique_transfn _null_ _null_ _null_ _null_ ) +insert ( 6279 json_object_agg_unique_strict_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ json_object_agg_unique_strict_transfn _null_ _null_ _null_ _null_ ) +insert ( 3196 json_object_agg_finalfn 11 10 12 1 0 0 0 f f f f f i s 1 0 114 2281 _null_ _null_ _null_ _null_ _null_ json_object_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 3197 json_object_agg 11 10 12 1 0 0 0 a f f f f s s 2 0 114 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6280 json_object_agg_strict 11 10 12 1 0 0 0 a f f f f s s 2 0 114 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6281 json_object_agg_unique 11 10 12 1 0 0 0 a f f f f s s 2 0 114 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6282 json_object_agg_unique_strict 11 10 12 1 0 0 0 a f f f f s s 2 0 114 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3198 json_build_array 11 10 12 1 0 2276 0 f f f f f s s 1 0 114 2276 '{2276}' '{v}' _null_ _null_ _null_ json_build_array _null_ _null_ _null_ _null_ ) +insert ( 3199 json_build_array 11 10 12 1 0 0 0 f f f f f s s 0 0 114 '' _null_ _null_ _null_ _null_ _null_ json_build_array_noargs _null_ _null_ _null_ _null_ ) +insert ( 3200 json_build_object 11 10 12 1 0 2276 0 f f f f f s s 1 0 114 2276 '{2276}' '{v}' _null_ _null_ _null_ json_build_object _null_ _null_ _null_ _null_ ) +insert ( 3201 json_build_object 11 10 12 1 0 0 0 f f f f f s s 0 0 114 '' _null_ _null_ _null_ _null_ _null_ json_build_object_noargs _null_ _null_ _null_ _null_ ) +insert ( 3202 json_object 11 10 12 1 0 0 0 f f f t f i s 1 0 114 1009 _null_ _null_ _null_ _null_ _null_ json_object _null_ _null_ _null_ _null_ ) +insert ( 3203 json_object 11 10 12 1 0 0 0 f f f t f i s 2 0 114 '1009 1009' _null_ _null_ _null_ _null_ _null_ json_object_two_arg _null_ _null_ _null_ _null_ ) +insert ( 3176 to_json 11 10 12 1 0 0 0 f f f t f s s 1 0 114 2283 _null_ _null_ _null_ _null_ _null_ to_json _null_ _null_ _null_ _null_ ) +insert ( 3261 json_strip_nulls 11 10 12 1 0 0 0 f f f t f i s 1 0 114 114 _null_ _null_ _null_ _null_ _null_ json_strip_nulls _null_ _null_ _null_ _null_ ) +insert ( 3947 json_object_field 11 10 12 1 0 0 0 f f f t f i s 2 0 114 '114 25' _null_ _null_ '{from_json, field_name}' _null_ _null_ json_object_field _null_ _null_ _null_ _null_ ) +insert ( 3948 json_object_field_text 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '114 25' _null_ _null_ '{from_json, field_name}' _null_ _null_ json_object_field_text _null_ _null_ _null_ _null_ ) +insert ( 3949 json_array_element 11 10 12 1 0 0 0 f f f t f i s 2 0 114 '114 23' _null_ _null_ '{from_json, element_index}' _null_ _null_ json_array_element _null_ _null_ _null_ _null_ ) +insert ( 3950 json_array_element_text 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '114 23' _null_ _null_ '{from_json, element_index}' _null_ _null_ json_array_element_text _null_ _null_ _null_ _null_ ) +insert ( 3951 json_extract_path 11 10 12 1 0 25 0 f f f t f i s 2 0 114 '114 1009' '{114,1009}' '{i,v}' '{from_json,path_elems}' _null_ _null_ json_extract_path _null_ _null_ _null_ _null_ ) +insert ( 3953 json_extract_path_text 11 10 12 1 0 25 0 f f f t f i s 2 0 25 '114 1009' '{114,1009}' '{i,v}' '{from_json,path_elems}' _null_ _null_ json_extract_path_text _null_ _null_ _null_ _null_ ) +insert ( 3955 json_array_elements 11 10 12 1 100 0 0 f f f t t i s 1 0 114 114 '{114,114}' '{i,o}' '{from_json,value}' _null_ _null_ json_array_elements _null_ _null_ _null_ _null_ ) +insert ( 3969 json_array_elements_text 11 10 12 1 100 0 0 f f f t t i s 1 0 25 114 '{114,25}' '{i,o}' '{from_json,value}' _null_ _null_ json_array_elements_text _null_ _null_ _null_ _null_ ) +insert ( 3956 json_array_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 114 _null_ _null_ _null_ _null_ _null_ json_array_length _null_ _null_ _null_ _null_ ) +insert ( 3957 json_object_keys 11 10 12 1 100 0 0 f f f t t i s 1 0 25 114 _null_ _null_ _null_ _null_ _null_ json_object_keys _null_ _null_ _null_ _null_ ) +insert ( 3958 json_each 11 10 12 1 100 0 0 f f f t t i s 1 0 2249 114 '{114,25,114}' '{i,o,o}' '{from_json,key,value}' _null_ _null_ json_each _null_ _null_ _null_ _null_ ) +insert ( 3959 json_each_text 11 10 12 1 100 0 0 f f f t t i s 1 0 2249 114 '{114,25,25}' '{i,o,o}' '{from_json,key,value}' _null_ _null_ json_each_text _null_ _null_ _null_ _null_ ) +insert ( 3960 json_populate_record 11 10 12 1 0 0 0 f f f f f s s 3 0 2283 '2283 114 16' _null_ _null_ _null_ _null_ _null_ json_populate_record _null_ _null_ _null_ _null_ ) +insert ( 3961 json_populate_recordset 11 10 12 1 100 0 0 f f f f t s s 3 0 2283 '2283 114 16' _null_ _null_ _null_ _null_ _null_ json_populate_recordset _null_ _null_ _null_ _null_ ) +insert ( 3204 json_to_record 11 10 12 1 0 0 0 f f f t f s s 1 0 2249 114 _null_ _null_ _null_ _null_ _null_ json_to_record _null_ _null_ _null_ _null_ ) +insert ( 3205 json_to_recordset 11 10 12 1 100 0 0 f f f f t s s 1 0 2249 114 _null_ _null_ _null_ _null_ _null_ json_to_recordset _null_ _null_ _null_ _null_ ) +insert ( 3968 json_typeof 11 10 12 1 0 0 0 f f f t f i s 1 0 25 114 _null_ _null_ _null_ _null_ _null_ json_typeof _null_ _null_ _null_ _null_ ) +insert ( 2952 uuid_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2950 2275 _null_ _null_ _null_ _null_ _null_ uuid_in _null_ _null_ _null_ _null_ ) +insert ( 2953 uuid_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2950 _null_ _null_ _null_ _null_ _null_ uuid_out _null_ _null_ _null_ _null_ ) +insert ( 2954 uuid_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '2950 2950' _null_ _null_ _null_ _null_ _null_ uuid_lt _null_ _null_ _null_ _null_ ) +insert ( 2955 uuid_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '2950 2950' _null_ _null_ _null_ _null_ _null_ uuid_le _null_ _null_ _null_ _null_ ) +insert ( 2956 uuid_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '2950 2950' _null_ _null_ _null_ _null_ _null_ uuid_eq _null_ _null_ _null_ _null_ ) +insert ( 2957 uuid_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '2950 2950' _null_ _null_ _null_ _null_ _null_ uuid_ge _null_ _null_ _null_ _null_ ) +insert ( 2958 uuid_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '2950 2950' _null_ _null_ _null_ _null_ _null_ uuid_gt _null_ _null_ _null_ _null_ ) +insert ( 2959 uuid_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '2950 2950' _null_ _null_ _null_ _null_ _null_ uuid_ne _null_ _null_ _null_ _null_ ) +insert ( 2960 uuid_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '2950 2950' _null_ _null_ _null_ _null_ _null_ uuid_cmp _null_ _null_ _null_ _null_ ) +insert ( 3300 uuid_sortsupport 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ uuid_sortsupport _null_ _null_ _null_ _null_ ) +insert ( 2961 uuid_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 2950 2281 _null_ _null_ _null_ _null_ _null_ uuid_recv _null_ _null_ _null_ _null_ ) +insert ( 2962 uuid_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2950 _null_ _null_ _null_ _null_ _null_ uuid_send _null_ _null_ _null_ _null_ ) +insert ( 2963 uuid_hash 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2950 _null_ _null_ _null_ _null_ _null_ uuid_hash _null_ _null_ _null_ _null_ ) +insert ( 3412 uuid_hash_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '2950 20' _null_ _null_ _null_ _null_ _null_ uuid_hash_extended _null_ _null_ _null_ _null_ ) +insert ( 3432 gen_random_uuid 11 10 12 1 0 0 0 f f t t f v s 0 0 2950 '' _null_ _null_ _null_ _null_ _null_ gen_random_uuid _null_ _null_ _null_ _null_ ) +insert ( 3229 pg_lsn_in 11 10 12 1 0 0 0 f f f t f i s 1 0 3220 2275 _null_ _null_ _null_ _null_ _null_ pg_lsn_in _null_ _null_ _null_ _null_ ) +insert ( 3230 pg_lsn_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3220 _null_ _null_ _null_ _null_ _null_ pg_lsn_out _null_ _null_ _null_ _null_ ) +insert ( 3231 pg_lsn_lt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_lt _null_ _null_ _null_ _null_ ) +insert ( 3232 pg_lsn_le 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_le _null_ _null_ _null_ _null_ ) +insert ( 3233 pg_lsn_eq 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_eq _null_ _null_ _null_ _null_ ) +insert ( 3234 pg_lsn_ge 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_ge _null_ _null_ _null_ _null_ ) +insert ( 3235 pg_lsn_gt 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_gt _null_ _null_ _null_ _null_ ) +insert ( 3236 pg_lsn_ne 11 10 12 1 0 0 0 f f t t f i s 2 0 16 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_ne _null_ _null_ _null_ _null_ ) +insert ( 3237 pg_lsn_mi 11 10 12 1 0 0 0 f f f t f i s 2 0 1700 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_mi _null_ _null_ _null_ _null_ ) +insert ( 3238 pg_lsn_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 3220 2281 _null_ _null_ _null_ _null_ _null_ pg_lsn_recv _null_ _null_ _null_ _null_ ) +insert ( 3239 pg_lsn_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 3220 _null_ _null_ _null_ _null_ _null_ pg_lsn_send _null_ _null_ _null_ _null_ ) +insert ( 3251 pg_lsn_cmp 11 10 12 1 0 0 0 f f t t f i s 2 0 23 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_cmp _null_ _null_ _null_ _null_ ) +insert ( 3252 pg_lsn_hash 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3220 _null_ _null_ _null_ _null_ _null_ pg_lsn_hash _null_ _null_ _null_ _null_ ) +insert ( 3413 pg_lsn_hash_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '3220 20' _null_ _null_ _null_ _null_ _null_ pg_lsn_hash_extended _null_ _null_ _null_ _null_ ) +insert ( 4187 pg_lsn_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 3220 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_larger _null_ _null_ _null_ _null_ ) +insert ( 4188 pg_lsn_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 3220 '3220 3220' _null_ _null_ _null_ _null_ _null_ pg_lsn_smaller _null_ _null_ _null_ _null_ ) +insert ( 5022 pg_lsn_pli 11 10 12 1 0 0 0 f f f t f i s 2 0 3220 '3220 1700' _null_ _null_ _null_ _null_ _null_ pg_lsn_pli _null_ _null_ _null_ _null_ ) +insert ( 5023 numeric_pl_pg_lsn 11 10 14 1 0 0 0 f f f t f i s 2 0 3220 '1700 3220' _null_ _null_ _null_ _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 5024 pg_lsn_mii 11 10 12 1 0 0 0 f f f t f i s 2 0 3220 '3220 1700' _null_ _null_ _null_ _null_ _null_ pg_lsn_mii _null_ _null_ _null_ _null_ ) +insert ( 3504 anyenum_in 11 10 12 1 0 0 0 f f f t f i s 1 0 3500 2275 _null_ _null_ _null_ _null_ _null_ anyenum_in _null_ _null_ _null_ _null_ ) +insert ( 3505 anyenum_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 3500 _null_ _null_ _null_ _null_ _null_ anyenum_out _null_ _null_ _null_ _null_ ) +insert ( 3506 enum_in 11 10 12 1 0 0 0 f f f t f s s 2 0 3500 '2275 26' _null_ _null_ _null_ _null_ _null_ enum_in _null_ _null_ _null_ _null_ ) +insert ( 3507 enum_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 3500 _null_ _null_ _null_ _null_ _null_ enum_out _null_ _null_ _null_ _null_ ) +insert ( 3508 enum_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_eq _null_ _null_ _null_ _null_ ) +insert ( 3509 enum_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_ne _null_ _null_ _null_ _null_ ) +insert ( 3510 enum_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_lt _null_ _null_ _null_ _null_ ) +insert ( 3511 enum_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_gt _null_ _null_ _null_ _null_ ) +insert ( 3512 enum_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_le _null_ _null_ _null_ _null_ ) +insert ( 3513 enum_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_ge _null_ _null_ _null_ _null_ ) +insert ( 3514 enum_cmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_cmp _null_ _null_ _null_ _null_ ) +insert ( 3515 hashenum 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3500 _null_ _null_ _null_ _null_ _null_ hashenum _null_ _null_ _null_ _null_ ) +insert ( 3414 hashenumextended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '3500 20' _null_ _null_ _null_ _null_ _null_ hashenumextended _null_ _null_ _null_ _null_ ) +insert ( 3524 enum_smaller 11 10 12 1 0 0 0 f f f t f i s 2 0 3500 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_smaller _null_ _null_ _null_ _null_ ) +insert ( 3525 enum_larger 11 10 12 1 0 0 0 f f f t f i s 2 0 3500 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_larger _null_ _null_ _null_ _null_ ) +insert ( 3526 max 11 10 12 1 0 0 0 a f f f f i s 1 0 3500 3500 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3527 min 11 10 12 1 0 0 0 a f f f f i s 1 0 3500 3500 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3528 enum_first 11 10 12 1 0 0 0 f f f f f s s 1 0 3500 3500 _null_ _null_ _null_ _null_ _null_ enum_first _null_ _null_ _null_ _null_ ) +insert ( 3529 enum_last 11 10 12 1 0 0 0 f f f f f s s 1 0 3500 3500 _null_ _null_ _null_ _null_ _null_ enum_last _null_ _null_ _null_ _null_ ) +insert ( 3530 enum_range 11 10 12 1 0 0 0 f f f f f s s 2 0 2277 '3500 3500' _null_ _null_ _null_ _null_ _null_ enum_range_bounds _null_ _null_ _null_ _null_ ) +insert ( 3531 enum_range 11 10 12 1 0 0 0 f f f f f s s 1 0 2277 3500 _null_ _null_ _null_ _null_ _null_ enum_range_all _null_ _null_ _null_ _null_ ) +insert ( 3532 enum_recv 11 10 12 1 0 0 0 f f f t f s s 2 0 3500 '2281 26' _null_ _null_ _null_ _null_ _null_ enum_recv _null_ _null_ _null_ _null_ ) +insert ( 3533 enum_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 3500 _null_ _null_ _null_ _null_ _null_ enum_send _null_ _null_ _null_ _null_ ) +insert ( 3610 tsvectorin 11 10 12 1 0 0 0 f f f t f i s 1 0 3614 2275 _null_ _null_ _null_ _null_ _null_ tsvectorin _null_ _null_ _null_ _null_ ) +insert ( 3639 tsvectorrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 3614 2281 _null_ _null_ _null_ _null_ _null_ tsvectorrecv _null_ _null_ _null_ _null_ ) +insert ( 3611 tsvectorout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3614 _null_ _null_ _null_ _null_ _null_ tsvectorout _null_ _null_ _null_ _null_ ) +insert ( 3638 tsvectorsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 3614 _null_ _null_ _null_ _null_ _null_ tsvectorsend _null_ _null_ _null_ _null_ ) +insert ( 3612 tsqueryin 11 10 12 1 0 0 0 f f f t f i s 1 0 3615 2275 _null_ _null_ _null_ _null_ _null_ tsqueryin _null_ _null_ _null_ _null_ ) +insert ( 3641 tsqueryrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 3615 2281 _null_ _null_ _null_ _null_ _null_ tsqueryrecv _null_ _null_ _null_ _null_ ) +insert ( 3613 tsqueryout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3615 _null_ _null_ _null_ _null_ _null_ tsqueryout _null_ _null_ _null_ _null_ ) +insert ( 3640 tsquerysend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 3615 _null_ _null_ _null_ _null_ _null_ tsquerysend _null_ _null_ _null_ _null_ ) +insert ( 3646 gtsvectorin 11 10 12 1 0 0 0 f f f t f i s 1 0 3642 2275 _null_ _null_ _null_ _null_ _null_ gtsvectorin _null_ _null_ _null_ _null_ ) +insert ( 3647 gtsvectorout 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3642 _null_ _null_ _null_ _null_ _null_ gtsvectorout _null_ _null_ _null_ _null_ ) +insert ( 3616 tsvector_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_lt _null_ _null_ _null_ _null_ ) +insert ( 3617 tsvector_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_le _null_ _null_ _null_ _null_ ) +insert ( 3618 tsvector_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_eq _null_ _null_ _null_ _null_ ) +insert ( 3619 tsvector_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_ne _null_ _null_ _null_ _null_ ) +insert ( 3620 tsvector_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_ge _null_ _null_ _null_ _null_ ) +insert ( 3621 tsvector_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_gt _null_ _null_ _null_ _null_ ) +insert ( 3622 tsvector_cmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_cmp _null_ _null_ _null_ _null_ ) +insert ( 3711 length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3614 _null_ _null_ _null_ _null_ _null_ tsvector_length _null_ _null_ _null_ _null_ ) +insert ( 3623 strip 11 10 12 1 0 0 0 f f f t f i s 1 0 3614 3614 _null_ _null_ _null_ _null_ _null_ tsvector_strip _null_ _null_ _null_ _null_ ) +insert ( 3624 setweight 11 10 12 1 0 0 0 f f f t f i s 2 0 3614 '3614 18' _null_ _null_ _null_ _null_ _null_ tsvector_setweight _null_ _null_ _null_ _null_ ) +insert ( 3320 setweight 11 10 12 1 0 0 0 f f f t f i s 3 0 3614 '3614 18 1009' _null_ _null_ _null_ _null_ _null_ tsvector_setweight_by_filter _null_ _null_ _null_ _null_ ) +insert ( 3625 tsvector_concat 11 10 12 1 0 0 0 f f f t f i s 2 0 3614 '3614 3614' _null_ _null_ _null_ _null_ _null_ tsvector_concat _null_ _null_ _null_ _null_ ) +insert ( 3321 ts_delete 11 10 12 1 0 0 0 f f f t f i s 2 0 3614 '3614 25' _null_ _null_ _null_ _null_ _null_ tsvector_delete_str _null_ _null_ _null_ _null_ ) +insert ( 3323 ts_delete 11 10 12 1 0 0 0 f f f t f i s 2 0 3614 '3614 1009' _null_ _null_ _null_ _null_ _null_ tsvector_delete_arr _null_ _null_ _null_ _null_ ) +insert ( 3322 unnest 11 10 12 1 10 0 0 f f f t t i s 1 0 2249 3614 '{3614,25,1005,1009}' '{i,o,o,o}' '{tsvector,lexeme,positions,weights}' _null_ _null_ tsvector_unnest _null_ _null_ _null_ _null_ ) +insert ( 3326 tsvector_to_array 11 10 12 1 0 0 0 f f f t f i s 1 0 1009 3614 _null_ _null_ _null_ _null_ _null_ tsvector_to_array _null_ _null_ _null_ _null_ ) +insert ( 3327 array_to_tsvector 11 10 12 1 0 0 0 f f f t f i s 1 0 3614 1009 _null_ _null_ _null_ _null_ _null_ array_to_tsvector _null_ _null_ _null_ _null_ ) +insert ( 3319 ts_filter 11 10 12 1 0 0 0 f f f t f i s 2 0 3614 '3614 1002' _null_ _null_ _null_ _null_ _null_ tsvector_filter _null_ _null_ _null_ _null_ ) +insert ( 3634 ts_match_vq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3614 3615' _null_ _null_ _null_ _null_ _null_ ts_match_vq _null_ _null_ _null_ _null_ ) +insert ( 3635 ts_match_qv 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3614' _null_ _null_ _null_ _null_ _null_ ts_match_qv _null_ _null_ _null_ _null_ ) +insert ( 3760 ts_match_tt 11 10 12 100 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ ts_match_tt _null_ _null_ _null_ _null_ ) +insert ( 3761 ts_match_tq 11 10 12 100 0 0 0 f f f t f s s 2 0 16 '25 3615' _null_ _null_ _null_ _null_ _null_ ts_match_tq _null_ _null_ _null_ _null_ ) +insert ( 3648 gtsvector_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ gtsvector_compress _null_ _null_ _null_ _null_ ) +insert ( 3649 gtsvector_decompress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ gtsvector_decompress _null_ _null_ _null_ _null_ ) +insert ( 3650 gtsvector_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ gtsvector_picksplit _null_ _null_ _null_ _null_ ) +insert ( 3651 gtsvector_union 11 10 12 1 0 0 0 f f f t f i s 2 0 3642 '2281 2281' _null_ _null_ _null_ _null_ _null_ gtsvector_union _null_ _null_ _null_ _null_ ) +insert ( 3652 gtsvector_same 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '3642 3642 2281' _null_ _null_ _null_ _null_ _null_ gtsvector_same _null_ _null_ _null_ _null_ ) +insert ( 3653 gtsvector_penalty 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gtsvector_penalty _null_ _null_ _null_ _null_ ) +insert ( 3654 gtsvector_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 3614 21 26 2281' _null_ _null_ _null_ _null_ _null_ gtsvector_consistent _null_ _null_ _null_ _null_ ) +insert ( 3790 gtsvector_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 3642 23 26 2281' _null_ _null_ _null_ _null_ _null_ gtsvector_consistent_oldsig _null_ _null_ _null_ _null_ ) +insert ( 3434 gtsvector_options 11 10 12 1 0 0 0 f f f f f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ gtsvector_options _null_ _null_ _null_ _null_ ) +insert ( 3656 gin_extract_tsvector 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '3614 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_tsvector _null_ _null_ _null_ _null_ ) +insert ( 3657 gin_extract_tsquery 11 10 12 1 0 0 0 f f f t f i s 7 0 2281 '3614 2281 21 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_tsquery _null_ _null_ _null_ _null_ ) +insert ( 3658 gin_tsquery_consistent 11 10 12 1 0 0 0 f f f t f i s 8 0 16 '2281 21 3614 23 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_tsquery_consistent _null_ _null_ _null_ _null_ ) +insert ( 3921 gin_tsquery_triconsistent 11 10 12 1 0 0 0 f f f t f i s 7 0 18 '2281 21 3614 23 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_tsquery_triconsistent _null_ _null_ _null_ _null_ ) +insert ( 3724 gin_cmp_tslexeme 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ gin_cmp_tslexeme _null_ _null_ _null_ _null_ ) +insert ( 2700 gin_cmp_prefix 11 10 12 1 0 0 0 f f f t f i s 4 0 23 '25 25 21 2281' _null_ _null_ _null_ _null_ _null_ gin_cmp_prefix _null_ _null_ _null_ _null_ ) +insert ( 3077 gin_extract_tsvector 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '3614 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_tsvector_2args _null_ _null_ _null_ _null_ ) +insert ( 3087 gin_extract_tsquery 11 10 12 1 0 0 0 f f f t f i s 5 0 2281 '3615 2281 21 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_tsquery_5args _null_ _null_ _null_ _null_ ) +insert ( 3088 gin_tsquery_consistent 11 10 12 1 0 0 0 f f f t f i s 6 0 16 '2281 21 3615 23 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_tsquery_consistent_6args _null_ _null_ _null_ _null_ ) +insert ( 3791 gin_extract_tsquery 11 10 12 1 0 0 0 f f f t f i s 7 0 2281 '3615 2281 21 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_tsquery_oldsig _null_ _null_ _null_ _null_ ) +insert ( 3792 gin_tsquery_consistent 11 10 12 1 0 0 0 f f f t f i s 8 0 16 '2281 21 3615 23 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_tsquery_consistent_oldsig _null_ _null_ _null_ _null_ ) +insert ( 3789 gin_clean_pending_list 11 10 12 1 0 0 0 f f f t f v u 1 0 20 2205 _null_ _null_ _null_ _null_ _null_ gin_clean_pending_list _null_ _null_ _null_ _null_ ) +insert ( 3662 tsquery_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_lt _null_ _null_ _null_ _null_ ) +insert ( 3663 tsquery_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_le _null_ _null_ _null_ _null_ ) +insert ( 3664 tsquery_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_eq _null_ _null_ _null_ _null_ ) +insert ( 3665 tsquery_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_ne _null_ _null_ _null_ _null_ ) +insert ( 3666 tsquery_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_ge _null_ _null_ _null_ _null_ ) +insert ( 3667 tsquery_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_gt _null_ _null_ _null_ _null_ ) +insert ( 3668 tsquery_cmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_cmp _null_ _null_ _null_ _null_ ) +insert ( 3669 tsquery_and 11 10 12 1 0 0 0 f f f t f i s 2 0 3615 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_and _null_ _null_ _null_ _null_ ) +insert ( 3670 tsquery_or 11 10 12 1 0 0 0 f f f t f i s 2 0 3615 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_or _null_ _null_ _null_ _null_ ) +insert ( 5003 tsquery_phrase 11 10 12 1 0 0 0 f f f t f i s 2 0 3615 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_phrase _null_ _null_ _null_ _null_ ) +insert ( 5004 tsquery_phrase 11 10 12 1 0 0 0 f f f t f i s 3 0 3615 '3615 3615 23' _null_ _null_ _null_ _null_ _null_ tsquery_phrase_distance _null_ _null_ _null_ _null_ ) +insert ( 3671 tsquery_not 11 10 12 1 0 0 0 f f f t f i s 1 0 3615 3615 _null_ _null_ _null_ _null_ _null_ tsquery_not _null_ _null_ _null_ _null_ ) +insert ( 3691 tsq_mcontains 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsq_mcontains _null_ _null_ _null_ _null_ ) +insert ( 3692 tsq_mcontained 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3615 3615' _null_ _null_ _null_ _null_ _null_ tsq_mcontained _null_ _null_ _null_ _null_ ) +insert ( 3672 numnode 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3615 _null_ _null_ _null_ _null_ _null_ tsquery_numnode _null_ _null_ _null_ _null_ ) +insert ( 3673 querytree 11 10 12 1 0 0 0 f f f t f i s 1 0 25 3615 _null_ _null_ _null_ _null_ _null_ tsquerytree _null_ _null_ _null_ _null_ ) +insert ( 3684 ts_rewrite 11 10 12 1 0 0 0 f f f t f i s 3 0 3615 '3615 3615 3615' _null_ _null_ _null_ _null_ _null_ tsquery_rewrite _null_ _null_ _null_ _null_ ) +insert ( 3685 ts_rewrite 11 10 12 100 0 0 0 f f f t f v u 2 0 3615 '3615 25' _null_ _null_ _null_ _null_ _null_ tsquery_rewrite_query _null_ _null_ _null_ _null_ ) +insert ( 3695 gtsquery_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ gtsquery_compress _null_ _null_ _null_ _null_ ) +insert ( 3697 gtsquery_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ gtsquery_picksplit _null_ _null_ _null_ _null_ ) +insert ( 3698 gtsquery_union 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '2281 2281' _null_ _null_ _null_ _null_ _null_ gtsquery_union _null_ _null_ _null_ _null_ ) +insert ( 3699 gtsquery_same 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '20 20 2281' _null_ _null_ _null_ _null_ _null_ gtsquery_same _null_ _null_ _null_ _null_ ) +insert ( 3700 gtsquery_penalty 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gtsquery_penalty _null_ _null_ _null_ _null_ ) +insert ( 3701 gtsquery_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 3615 21 26 2281' _null_ _null_ _null_ _null_ _null_ gtsquery_consistent _null_ _null_ _null_ _null_ ) +insert ( 3793 gtsquery_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 2281 23 26 2281' _null_ _null_ _null_ _null_ _null_ gtsquery_consistent_oldsig _null_ _null_ _null_ _null_ ) +insert ( 3686 tsmatchsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ tsmatchsel _null_ _null_ _null_ _null_ ) +insert ( 3687 tsmatchjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ tsmatchjoinsel _null_ _null_ _null_ _null_ ) +insert ( 3688 ts_typanalyze 11 10 12 1 0 0 0 f f f t f s s 1 0 16 2281 _null_ _null_ _null_ _null_ _null_ ts_typanalyze _null_ _null_ _null_ _null_ ) +insert ( 3689 ts_stat 11 10 12 10 10000 0 0 f f f t t v u 1 0 2249 25 '{25,25,23,23}' '{i,o,o,o}' '{query,word,ndoc,nentry}' _null_ _null_ ts_stat1 _null_ _null_ _null_ _null_ ) +insert ( 3690 ts_stat 11 10 12 10 10000 0 0 f f f t t v u 2 0 2249 '25 25' '{25,25,25,23,23}' '{i,i,o,o,o}' '{query,weights,word,ndoc,nentry}' _null_ _null_ ts_stat2 _null_ _null_ _null_ _null_ ) +insert ( 3703 ts_rank 11 10 12 1 0 0 0 f f f t f i s 4 0 700 '1021 3614 3615 23' _null_ _null_ _null_ _null_ _null_ ts_rank_wttf _null_ _null_ _null_ _null_ ) +insert ( 3704 ts_rank 11 10 12 1 0 0 0 f f f t f i s 3 0 700 '1021 3614 3615' _null_ _null_ _null_ _null_ _null_ ts_rank_wtt _null_ _null_ _null_ _null_ ) +insert ( 3705 ts_rank 11 10 12 1 0 0 0 f f f t f i s 3 0 700 '3614 3615 23' _null_ _null_ _null_ _null_ _null_ ts_rank_ttf _null_ _null_ _null_ _null_ ) +insert ( 3706 ts_rank 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '3614 3615' _null_ _null_ _null_ _null_ _null_ ts_rank_tt _null_ _null_ _null_ _null_ ) +insert ( 3707 ts_rank_cd 11 10 12 1 0 0 0 f f f t f i s 4 0 700 '1021 3614 3615 23' _null_ _null_ _null_ _null_ _null_ ts_rankcd_wttf _null_ _null_ _null_ _null_ ) +insert ( 3708 ts_rank_cd 11 10 12 1 0 0 0 f f f t f i s 3 0 700 '1021 3614 3615' _null_ _null_ _null_ _null_ _null_ ts_rankcd_wtt _null_ _null_ _null_ _null_ ) +insert ( 3709 ts_rank_cd 11 10 12 1 0 0 0 f f f t f i s 3 0 700 '3614 3615 23' _null_ _null_ _null_ _null_ _null_ ts_rankcd_ttf _null_ _null_ _null_ _null_ ) +insert ( 3710 ts_rank_cd 11 10 12 1 0 0 0 f f f t f i s 2 0 700 '3614 3615' _null_ _null_ _null_ _null_ _null_ ts_rankcd_tt _null_ _null_ _null_ _null_ ) +insert ( 3713 ts_token_type 11 10 12 1 16 0 0 f f f t t i s 1 0 2249 26 '{26,23,25,25}' '{i,o,o,o}' '{parser_oid,tokid,alias,description}' _null_ _null_ ts_token_type_byid _null_ _null_ _null_ _null_ ) +insert ( 3714 ts_token_type 11 10 12 1 16 0 0 f f f t t s s 1 0 2249 25 '{25,23,25,25}' '{i,o,o,o}' '{parser_name,tokid,alias,description}' _null_ _null_ ts_token_type_byname _null_ _null_ _null_ _null_ ) +insert ( 3715 ts_parse 11 10 12 1 1000 0 0 f f f t t i s 2 0 2249 '26 25' '{26,25,23,25}' '{i,i,o,o}' '{parser_oid,txt,tokid,token}' _null_ _null_ ts_parse_byid _null_ _null_ _null_ _null_ ) +insert ( 3716 ts_parse 11 10 12 1 1000 0 0 f f f t t s s 2 0 2249 '25 25' '{25,25,23,25}' '{i,i,o,o}' '{parser_name,txt,tokid,token}' _null_ _null_ ts_parse_byname _null_ _null_ _null_ _null_ ) +insert ( 3717 prsd_start 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '2281 23' _null_ _null_ _null_ _null_ _null_ prsd_start _null_ _null_ _null_ _null_ ) +insert ( 3718 prsd_nexttoken 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ prsd_nexttoken _null_ _null_ _null_ _null_ ) +insert ( 3719 prsd_end 11 10 12 1 0 0 0 f f f t f i s 1 0 2278 2281 _null_ _null_ _null_ _null_ _null_ prsd_end _null_ _null_ _null_ _null_ ) +insert ( 3720 prsd_headline 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2281 2281 3615' _null_ _null_ _null_ _null_ _null_ prsd_headline _null_ _null_ _null_ _null_ ) +insert ( 3721 prsd_lextype 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ prsd_lextype _null_ _null_ _null_ _null_ ) +insert ( 3723 ts_lexize 11 10 12 1 0 0 0 f f f t f i s 2 0 1009 '3769 25' _null_ _null_ _null_ _null_ _null_ ts_lexize _null_ _null_ _null_ _null_ ) +insert ( 6183 ts_debug 11 10 14 1 1000 0 0 f f f t t s s 2 0 2249 '3734 25' '{3734,25,25,25,25,3770,3769,1009}' '{i,i,o,o,o,o,o,o}' '{config,document,alias,description,token,dictionaries,dictionary,lexemes}' _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 6184 ts_debug 11 10 14 1 1000 0 0 f f f t t s s 1 0 2249 25 '{25,25,25,25,3770,3769,1009}' '{i,o,o,o,o,o,o}' '{document,alias,description,token,dictionaries,dictionary,lexemes}' _null_ _null_ 'see system_functions.sql' _null_ _null_ _null_ _null_ ) +insert ( 3725 dsimple_init 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ dsimple_init _null_ _null_ _null_ _null_ ) +insert ( 3726 dsimple_lexize 11 10 12 1 0 0 0 f f f t f i s 4 0 2281 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ dsimple_lexize _null_ _null_ _null_ _null_ ) +insert ( 3728 dsynonym_init 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ dsynonym_init _null_ _null_ _null_ _null_ ) +insert ( 3729 dsynonym_lexize 11 10 12 1 0 0 0 f f f t f i s 4 0 2281 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ dsynonym_lexize _null_ _null_ _null_ _null_ ) +insert ( 3731 dispell_init 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ dispell_init _null_ _null_ _null_ _null_ ) +insert ( 3732 dispell_lexize 11 10 12 1 0 0 0 f f f t f i s 4 0 2281 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ dispell_lexize _null_ _null_ _null_ _null_ ) +insert ( 3740 thesaurus_init 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ thesaurus_init _null_ _null_ _null_ _null_ ) +insert ( 3741 thesaurus_lexize 11 10 12 1 0 0 0 f f f t f i s 4 0 2281 '2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ thesaurus_lexize _null_ _null_ _null_ _null_ ) +insert ( 3743 ts_headline 11 10 12 100 0 0 0 f f f t f i s 4 0 25 '3734 25 3615 25' _null_ _null_ _null_ _null_ _null_ ts_headline_byid_opt _null_ _null_ _null_ _null_ ) +insert ( 3744 ts_headline 11 10 12 100 0 0 0 f f f t f i s 3 0 25 '3734 25 3615' _null_ _null_ _null_ _null_ _null_ ts_headline_byid _null_ _null_ _null_ _null_ ) +insert ( 3754 ts_headline 11 10 12 100 0 0 0 f f f t f s s 3 0 25 '25 3615 25' _null_ _null_ _null_ _null_ _null_ ts_headline_opt _null_ _null_ _null_ _null_ ) +insert ( 3755 ts_headline 11 10 12 100 0 0 0 f f f t f s s 2 0 25 '25 3615' _null_ _null_ _null_ _null_ _null_ ts_headline _null_ _null_ _null_ _null_ ) +insert ( 4201 ts_headline 11 10 12 100 0 0 0 f f f t f i s 4 0 3802 '3734 3802 3615 25' _null_ _null_ _null_ _null_ _null_ ts_headline_jsonb_byid_opt _null_ _null_ _null_ _null_ ) +insert ( 4202 ts_headline 11 10 12 100 0 0 0 f f f t f i s 3 0 3802 '3734 3802 3615' _null_ _null_ _null_ _null_ _null_ ts_headline_jsonb_byid _null_ _null_ _null_ _null_ ) +insert ( 4203 ts_headline 11 10 12 100 0 0 0 f f f t f s s 3 0 3802 '3802 3615 25' _null_ _null_ _null_ _null_ _null_ ts_headline_jsonb_opt _null_ _null_ _null_ _null_ ) +insert ( 4204 ts_headline 11 10 12 100 0 0 0 f f f t f s s 2 0 3802 '3802 3615' _null_ _null_ _null_ _null_ _null_ ts_headline_jsonb _null_ _null_ _null_ _null_ ) +insert ( 4205 ts_headline 11 10 12 100 0 0 0 f f f t f i s 4 0 114 '3734 114 3615 25' _null_ _null_ _null_ _null_ _null_ ts_headline_json_byid_opt _null_ _null_ _null_ _null_ ) +insert ( 4206 ts_headline 11 10 12 100 0 0 0 f f f t f i s 3 0 114 '3734 114 3615' _null_ _null_ _null_ _null_ _null_ ts_headline_json_byid _null_ _null_ _null_ _null_ ) +insert ( 4207 ts_headline 11 10 12 100 0 0 0 f f f t f s s 3 0 114 '114 3615 25' _null_ _null_ _null_ _null_ _null_ ts_headline_json_opt _null_ _null_ _null_ _null_ ) +insert ( 4208 ts_headline 11 10 12 100 0 0 0 f f f t f s s 2 0 114 '114 3615' _null_ _null_ _null_ _null_ _null_ ts_headline_json _null_ _null_ _null_ _null_ ) +insert ( 3745 to_tsvector 11 10 12 100 0 0 0 f f f t f i s 2 0 3614 '3734 25' _null_ _null_ _null_ _null_ _null_ to_tsvector_byid _null_ _null_ _null_ _null_ ) +insert ( 3746 to_tsquery 11 10 12 100 0 0 0 f f f t f i s 2 0 3615 '3734 25' _null_ _null_ _null_ _null_ _null_ to_tsquery_byid _null_ _null_ _null_ _null_ ) +insert ( 3747 plainto_tsquery 11 10 12 100 0 0 0 f f f t f i s 2 0 3615 '3734 25' _null_ _null_ _null_ _null_ _null_ plainto_tsquery_byid _null_ _null_ _null_ _null_ ) +insert ( 5006 phraseto_tsquery 11 10 12 100 0 0 0 f f f t f i s 2 0 3615 '3734 25' _null_ _null_ _null_ _null_ _null_ phraseto_tsquery_byid _null_ _null_ _null_ _null_ ) +insert ( 5007 websearch_to_tsquery 11 10 12 100 0 0 0 f f f t f i s 2 0 3615 '3734 25' _null_ _null_ _null_ _null_ _null_ websearch_to_tsquery_byid _null_ _null_ _null_ _null_ ) +insert ( 3749 to_tsvector 11 10 12 100 0 0 0 f f f t f s s 1 0 3614 25 _null_ _null_ _null_ _null_ _null_ to_tsvector _null_ _null_ _null_ _null_ ) +insert ( 3750 to_tsquery 11 10 12 100 0 0 0 f f f t f s s 1 0 3615 25 _null_ _null_ _null_ _null_ _null_ to_tsquery _null_ _null_ _null_ _null_ ) +insert ( 3751 plainto_tsquery 11 10 12 100 0 0 0 f f f t f s s 1 0 3615 25 _null_ _null_ _null_ _null_ _null_ plainto_tsquery _null_ _null_ _null_ _null_ ) +insert ( 5001 phraseto_tsquery 11 10 12 100 0 0 0 f f f t f s s 1 0 3615 25 _null_ _null_ _null_ _null_ _null_ phraseto_tsquery _null_ _null_ _null_ _null_ ) +insert ( 5009 websearch_to_tsquery 11 10 12 100 0 0 0 f f f t f s s 1 0 3615 25 _null_ _null_ _null_ _null_ _null_ websearch_to_tsquery _null_ _null_ _null_ _null_ ) +insert ( 4209 to_tsvector 11 10 12 100 0 0 0 f f f t f s s 1 0 3614 3802 _null_ _null_ _null_ _null_ _null_ jsonb_string_to_tsvector _null_ _null_ _null_ _null_ ) +insert ( 4213 jsonb_to_tsvector 11 10 12 100 0 0 0 f f f t f s s 2 0 3614 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_to_tsvector _null_ _null_ _null_ _null_ ) +insert ( 4210 to_tsvector 11 10 12 100 0 0 0 f f f t f s s 1 0 3614 114 _null_ _null_ _null_ _null_ _null_ json_string_to_tsvector _null_ _null_ _null_ _null_ ) +insert ( 4215 json_to_tsvector 11 10 12 100 0 0 0 f f f t f s s 2 0 3614 '114 3802' _null_ _null_ _null_ _null_ _null_ json_to_tsvector _null_ _null_ _null_ _null_ ) +insert ( 4211 to_tsvector 11 10 12 100 0 0 0 f f f t f i s 2 0 3614 '3734 3802' _null_ _null_ _null_ _null_ _null_ jsonb_string_to_tsvector_byid _null_ _null_ _null_ _null_ ) +insert ( 4214 jsonb_to_tsvector 11 10 12 100 0 0 0 f f f t f i s 3 0 3614 '3734 3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_to_tsvector_byid _null_ _null_ _null_ _null_ ) +insert ( 4212 to_tsvector 11 10 12 100 0 0 0 f f f t f i s 2 0 3614 '3734 114' _null_ _null_ _null_ _null_ _null_ json_string_to_tsvector_byid _null_ _null_ _null_ _null_ ) +insert ( 4216 json_to_tsvector 11 10 12 100 0 0 0 f f f t f i s 3 0 3614 '3734 114 3802' _null_ _null_ _null_ _null_ _null_ json_to_tsvector_byid _null_ _null_ _null_ _null_ ) +insert ( 3752 tsvector_update_trigger 11 10 12 1 0 0 0 f f f f f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ tsvector_update_trigger_byid _null_ _null_ _null_ _null_ ) +insert ( 3753 tsvector_update_trigger_column 11 10 12 1 0 0 0 f f f f f v s 0 0 2279 '' _null_ _null_ _null_ _null_ _null_ tsvector_update_trigger_bycolumn _null_ _null_ _null_ _null_ ) +insert ( 3759 get_current_ts_config 11 10 12 1 0 0 0 f f f t f s s 0 0 3734 '' _null_ _null_ _null_ _null_ _null_ get_current_ts_config _null_ _null_ _null_ _null_ ) +insert ( 3736 regconfigin 11 10 12 1 0 0 0 f f f t f s s 1 0 3734 2275 _null_ _null_ _null_ _null_ _null_ regconfigin _null_ _null_ _null_ _null_ ) +insert ( 3737 regconfigout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 3734 _null_ _null_ _null_ _null_ _null_ regconfigout _null_ _null_ _null_ _null_ ) +insert ( 3738 regconfigrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 3734 2281 _null_ _null_ _null_ _null_ _null_ regconfigrecv _null_ _null_ _null_ _null_ ) +insert ( 3739 regconfigsend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 3734 _null_ _null_ _null_ _null_ _null_ regconfigsend _null_ _null_ _null_ _null_ ) +insert ( 3771 regdictionaryin 11 10 12 1 0 0 0 f f f t f s s 1 0 3769 2275 _null_ _null_ _null_ _null_ _null_ regdictionaryin _null_ _null_ _null_ _null_ ) +insert ( 3772 regdictionaryout 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 3769 _null_ _null_ _null_ _null_ _null_ regdictionaryout _null_ _null_ _null_ _null_ ) +insert ( 3773 regdictionaryrecv 11 10 12 1 0 0 0 f f f t f i s 1 0 3769 2281 _null_ _null_ _null_ _null_ _null_ regdictionaryrecv _null_ _null_ _null_ _null_ ) +insert ( 3774 regdictionarysend 11 10 12 1 0 0 0 f f f t f i s 1 0 17 3769 _null_ _null_ _null_ _null_ _null_ regdictionarysend _null_ _null_ _null_ _null_ ) +insert ( 3806 jsonb_in 11 10 12 1 0 0 0 f f f t f i s 1 0 3802 2275 _null_ _null_ _null_ _null_ _null_ jsonb_in _null_ _null_ _null_ _null_ ) +insert ( 3805 jsonb_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 3802 2281 _null_ _null_ _null_ _null_ _null_ jsonb_recv _null_ _null_ _null_ _null_ ) +insert ( 3804 jsonb_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 3802 _null_ _null_ _null_ _null_ _null_ jsonb_out _null_ _null_ _null_ _null_ ) +insert ( 3803 jsonb_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 3802 _null_ _null_ _null_ _null_ _null_ jsonb_send _null_ _null_ _null_ _null_ ) +insert ( 3263 jsonb_object 11 10 12 1 0 0 0 f f f t f i s 1 0 3802 1009 _null_ _null_ _null_ _null_ _null_ jsonb_object _null_ _null_ _null_ _null_ ) +insert ( 3264 jsonb_object 11 10 12 1 0 0 0 f f f t f i s 2 0 3802 '1009 1009' _null_ _null_ _null_ _null_ _null_ jsonb_object_two_arg _null_ _null_ _null_ _null_ ) +insert ( 3787 to_jsonb 11 10 12 1 0 0 0 f f f t f s s 1 0 3802 2283 _null_ _null_ _null_ _null_ _null_ to_jsonb _null_ _null_ _null_ _null_ ) +insert ( 3265 jsonb_agg_transfn 11 10 12 1 0 0 0 f f f f f s s 2 0 2281 '2281 2283' _null_ _null_ _null_ _null_ _null_ jsonb_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 6283 jsonb_agg_strict_transfn 11 10 12 1 0 0 0 f f f f f s s 2 0 2281 '2281 2283' _null_ _null_ _null_ _null_ _null_ jsonb_agg_strict_transfn _null_ _null_ _null_ _null_ ) +insert ( 3266 jsonb_agg_finalfn 11 10 12 1 0 0 0 f f f f f s s 1 0 3802 2281 _null_ _null_ _null_ _null_ _null_ jsonb_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 3267 jsonb_agg 11 10 12 1 0 0 0 a f f f f s s 1 0 3802 2283 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6284 jsonb_agg_strict 11 10 12 1 0 0 0 a f f f f s s 1 0 3802 2283 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3268 jsonb_object_agg_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ jsonb_object_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 6285 jsonb_object_agg_strict_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ jsonb_object_agg_strict_transfn _null_ _null_ _null_ _null_ ) +insert ( 6286 jsonb_object_agg_unique_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ jsonb_object_agg_unique_transfn _null_ _null_ _null_ _null_ ) +insert ( 6287 jsonb_object_agg_unique_strict_transfn 11 10 12 1 0 0 0 f f f f f s s 3 0 2281 '2281 2276 2276' _null_ _null_ _null_ _null_ _null_ jsonb_object_agg_unique_strict_transfn _null_ _null_ _null_ _null_ ) +insert ( 3269 jsonb_object_agg_finalfn 11 10 12 1 0 0 0 f f f f f s s 1 0 3802 2281 _null_ _null_ _null_ _null_ _null_ jsonb_object_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 3270 jsonb_object_agg 11 10 12 1 0 0 0 a f f f f i s 2 0 3802 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6288 jsonb_object_agg_strict 11 10 12 1 0 0 0 a f f f f i s 2 0 3802 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6289 jsonb_object_agg_unique 11 10 12 1 0 0 0 a f f f f i s 2 0 3802 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6290 jsonb_object_agg_unique_strict 11 10 12 1 0 0 0 a f f f f i s 2 0 3802 '2276 2276' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3271 jsonb_build_array 11 10 12 1 0 2276 0 f f f f f s s 1 0 3802 2276 '{2276}' '{v}' _null_ _null_ _null_ jsonb_build_array _null_ _null_ _null_ _null_ ) +insert ( 3272 jsonb_build_array 11 10 12 1 0 0 0 f f f f f s s 0 0 3802 '' _null_ _null_ _null_ _null_ _null_ jsonb_build_array_noargs _null_ _null_ _null_ _null_ ) +insert ( 3273 jsonb_build_object 11 10 12 1 0 2276 0 f f f f f s s 1 0 3802 2276 '{2276}' '{v}' _null_ _null_ _null_ jsonb_build_object _null_ _null_ _null_ _null_ ) +insert ( 3274 jsonb_build_object 11 10 12 1 0 0 0 f f f f f s s 0 0 3802 '' _null_ _null_ _null_ _null_ _null_ jsonb_build_object_noargs _null_ _null_ _null_ _null_ ) +insert ( 3262 jsonb_strip_nulls 11 10 12 1 0 0 0 f f f t f i s 1 0 3802 3802 _null_ _null_ _null_ _null_ _null_ jsonb_strip_nulls _null_ _null_ _null_ _null_ ) +insert ( 3478 jsonb_object_field 11 10 12 1 0 0 0 f f f t f i s 2 0 3802 '3802 25' _null_ _null_ '{from_json, field_name}' _null_ _null_ jsonb_object_field _null_ _null_ _null_ _null_ ) +insert ( 3214 jsonb_object_field_text 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '3802 25' _null_ _null_ '{from_json, field_name}' _null_ _null_ jsonb_object_field_text _null_ _null_ _null_ _null_ ) +insert ( 3215 jsonb_array_element 11 10 12 1 0 0 0 f f f t f i s 2 0 3802 '3802 23' _null_ _null_ '{from_json, element_index}' _null_ _null_ jsonb_array_element _null_ _null_ _null_ _null_ ) +insert ( 3216 jsonb_array_element_text 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '3802 23' _null_ _null_ '{from_json, element_index}' _null_ _null_ jsonb_array_element_text _null_ _null_ _null_ _null_ ) +insert ( 3217 jsonb_extract_path 11 10 12 1 0 25 0 f f f t f i s 2 0 3802 '3802 1009' '{3802,1009}' '{i,v}' '{from_json,path_elems}' _null_ _null_ jsonb_extract_path _null_ _null_ _null_ _null_ ) +insert ( 3940 jsonb_extract_path_text 11 10 12 1 0 25 0 f f f t f i s 2 0 25 '3802 1009' '{3802,1009}' '{i,v}' '{from_json,path_elems}' _null_ _null_ jsonb_extract_path_text _null_ _null_ _null_ _null_ ) +insert ( 3219 jsonb_array_elements 11 10 12 1 100 0 0 f f f t t i s 1 0 3802 3802 '{3802,3802}' '{i,o}' '{from_json,value}' _null_ _null_ jsonb_array_elements _null_ _null_ _null_ _null_ ) +insert ( 3465 jsonb_array_elements_text 11 10 12 1 100 0 0 f f f t t i s 1 0 25 3802 '{3802,25}' '{i,o}' '{from_json,value}' _null_ _null_ jsonb_array_elements_text _null_ _null_ _null_ _null_ ) +insert ( 3207 jsonb_array_length 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3802 _null_ _null_ _null_ _null_ _null_ jsonb_array_length _null_ _null_ _null_ _null_ ) +insert ( 3931 jsonb_object_keys 11 10 12 1 100 0 0 f f f t t i s 1 0 25 3802 _null_ _null_ _null_ _null_ _null_ jsonb_object_keys _null_ _null_ _null_ _null_ ) +insert ( 3208 jsonb_each 11 10 12 1 100 0 0 f f f t t i s 1 0 2249 3802 '{3802,25,3802}' '{i,o,o}' '{from_json,key,value}' _null_ _null_ jsonb_each _null_ _null_ _null_ _null_ ) +insert ( 3932 jsonb_each_text 11 10 12 1 100 0 0 f f f t t i s 1 0 2249 3802 '{3802,25,25}' '{i,o,o}' '{from_json,key,value}' _null_ _null_ jsonb_each_text _null_ _null_ _null_ _null_ ) +insert ( 3209 jsonb_populate_record 11 10 12 1 0 0 0 f f f f f s s 2 0 2283 '2283 3802' _null_ _null_ _null_ _null_ _null_ jsonb_populate_record _null_ _null_ _null_ _null_ ) +insert ( 3475 jsonb_populate_recordset 11 10 12 1 100 0 0 f f f f t s s 2 0 2283 '2283 3802' _null_ _null_ _null_ _null_ _null_ jsonb_populate_recordset _null_ _null_ _null_ _null_ ) +insert ( 3490 jsonb_to_record 11 10 12 1 0 0 0 f f f t f s s 1 0 2249 3802 _null_ _null_ _null_ _null_ _null_ jsonb_to_record _null_ _null_ _null_ _null_ ) +insert ( 3491 jsonb_to_recordset 11 10 12 1 100 0 0 f f f f t s s 1 0 2249 3802 _null_ _null_ _null_ _null_ _null_ jsonb_to_recordset _null_ _null_ _null_ _null_ ) +insert ( 3210 jsonb_typeof 11 10 12 1 0 0 0 f f f t f i s 1 0 25 3802 _null_ _null_ _null_ _null_ _null_ jsonb_typeof _null_ _null_ _null_ _null_ ) +insert ( 4038 jsonb_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_ne _null_ _null_ _null_ _null_ ) +insert ( 4039 jsonb_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_lt _null_ _null_ _null_ _null_ ) +insert ( 4040 jsonb_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_gt _null_ _null_ _null_ _null_ ) +insert ( 4041 jsonb_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_le _null_ _null_ _null_ _null_ ) +insert ( 4042 jsonb_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_ge _null_ _null_ _null_ _null_ ) +insert ( 4043 jsonb_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_eq _null_ _null_ _null_ _null_ ) +insert ( 4044 jsonb_cmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_cmp _null_ _null_ _null_ _null_ ) +insert ( 4045 jsonb_hash 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3802 _null_ _null_ _null_ _null_ _null_ jsonb_hash _null_ _null_ _null_ _null_ ) +insert ( 3416 jsonb_hash_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '3802 20' _null_ _null_ _null_ _null_ _null_ jsonb_hash_extended _null_ _null_ _null_ _null_ ) +insert ( 4046 jsonb_contains 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_contains _null_ _null_ _null_ _null_ ) +insert ( 4047 jsonb_exists 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 25' _null_ _null_ _null_ _null_ _null_ jsonb_exists _null_ _null_ _null_ _null_ ) +insert ( 4048 jsonb_exists_any 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 1009' _null_ _null_ _null_ _null_ _null_ jsonb_exists_any _null_ _null_ _null_ _null_ ) +insert ( 4049 jsonb_exists_all 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 1009' _null_ _null_ _null_ _null_ _null_ jsonb_exists_all _null_ _null_ _null_ _null_ ) +insert ( 4050 jsonb_contained 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_contained _null_ _null_ _null_ _null_ ) +insert ( 3480 gin_compare_jsonb 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '25 25' _null_ _null_ _null_ _null_ _null_ gin_compare_jsonb _null_ _null_ _null_ _null_ ) +insert ( 3482 gin_extract_jsonb 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '3802 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_jsonb _null_ _null_ _null_ _null_ ) +insert ( 3483 gin_extract_jsonb_query 11 10 12 1 0 0 0 f f f t f i s 7 0 2281 '3802 2281 21 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_jsonb_query _null_ _null_ _null_ _null_ ) +insert ( 3484 gin_consistent_jsonb 11 10 12 1 0 0 0 f f f t f i s 8 0 16 '2281 21 3802 23 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_consistent_jsonb _null_ _null_ _null_ _null_ ) +insert ( 3488 gin_triconsistent_jsonb 11 10 12 1 0 0 0 f f f t f i s 7 0 18 '2281 21 3802 23 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_triconsistent_jsonb _null_ _null_ _null_ _null_ ) +insert ( 3485 gin_extract_jsonb_path 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '3802 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_jsonb_path _null_ _null_ _null_ _null_ ) +insert ( 3486 gin_extract_jsonb_query_path 11 10 12 1 0 0 0 f f f t f i s 7 0 2281 '3802 2281 21 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_extract_jsonb_query_path _null_ _null_ _null_ _null_ ) +insert ( 3487 gin_consistent_jsonb_path 11 10 12 1 0 0 0 f f f t f i s 8 0 16 '2281 21 3802 23 2281 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_consistent_jsonb_path _null_ _null_ _null_ _null_ ) +insert ( 3489 gin_triconsistent_jsonb_path 11 10 12 1 0 0 0 f f f t f i s 7 0 18 '2281 21 3802 23 2281 2281 2281' _null_ _null_ _null_ _null_ _null_ gin_triconsistent_jsonb_path _null_ _null_ _null_ _null_ ) +insert ( 3301 jsonb_concat 11 10 12 1 0 0 0 f f f t f i s 2 0 3802 '3802 3802' _null_ _null_ _null_ _null_ _null_ jsonb_concat _null_ _null_ _null_ _null_ ) +insert ( 3302 jsonb_delete 11 10 12 1 0 0 0 f f f t f i s 2 0 3802 '3802 25' _null_ _null_ _null_ _null_ _null_ jsonb_delete _null_ _null_ _null_ _null_ ) +insert ( 3303 jsonb_delete 11 10 12 1 0 0 0 f f f t f i s 2 0 3802 '3802 23' _null_ _null_ _null_ _null_ _null_ jsonb_delete_idx _null_ _null_ _null_ _null_ ) +insert ( 3343 jsonb_delete 11 10 12 1 0 25 0 f f f t f i s 2 0 3802 '3802 1009' '{3802,1009}' '{i,v}' '{from_json,path_elems}' _null_ _null_ jsonb_delete_array _null_ _null_ _null_ _null_ ) +insert ( 3304 jsonb_delete_path 11 10 12 1 0 0 0 f f f t f i s 2 0 3802 '3802 1009' _null_ _null_ _null_ _null_ _null_ jsonb_delete_path _null_ _null_ _null_ _null_ ) +insert ( 5054 jsonb_set_lax 11 10 12 1 0 0 0 f f f f f i s 5 0 3802 '3802 1009 3802 16 25' _null_ _null_ _null_ _null_ _null_ jsonb_set_lax _null_ _null_ _null_ _null_ ) +insert ( 3305 jsonb_set 11 10 12 1 0 0 0 f f f t f i s 4 0 3802 '3802 1009 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_set _null_ _null_ _null_ _null_ ) +insert ( 3306 jsonb_pretty 11 10 12 1 0 0 0 f f f t f i s 1 0 25 3802 _null_ _null_ _null_ _null_ _null_ jsonb_pretty _null_ _null_ _null_ _null_ ) +insert ( 3579 jsonb_insert 11 10 12 1 0 0 0 f f f t f i s 4 0 3802 '3802 1009 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_insert _null_ _null_ _null_ _null_ ) +insert ( 4001 jsonpath_in 11 10 12 1 0 0 0 f f f t f i s 1 0 4072 2275 _null_ _null_ _null_ _null_ _null_ jsonpath_in _null_ _null_ _null_ _null_ ) +insert ( 4002 jsonpath_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 4072 2281 _null_ _null_ _null_ _null_ _null_ jsonpath_recv _null_ _null_ _null_ _null_ ) +insert ( 4003 jsonpath_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 4072 _null_ _null_ _null_ _null_ _null_ jsonpath_out _null_ _null_ _null_ _null_ ) +insert ( 4004 jsonpath_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 4072 _null_ _null_ _null_ _null_ _null_ jsonpath_send _null_ _null_ _null_ _null_ ) +insert ( 4005 jsonb_path_exists 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_exists _null_ _null_ _null_ _null_ ) +insert ( 4006 jsonb_path_query 11 10 12 1 1000 0 0 f f f t t i s 4 0 3802 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_query _null_ _null_ _null_ _null_ ) +insert ( 4007 jsonb_path_query_array 11 10 12 1 0 0 0 f f f t f i s 4 0 3802 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_query_array _null_ _null_ _null_ _null_ ) +insert ( 4008 jsonb_path_query_first 11 10 12 1 0 0 0 f f f t f i s 4 0 3802 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_query_first _null_ _null_ _null_ _null_ ) +insert ( 4009 jsonb_path_match 11 10 12 1 0 0 0 f f f t f i s 4 0 16 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_match _null_ _null_ _null_ _null_ ) +insert ( 1177 jsonb_path_exists_tz 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_exists_tz _null_ _null_ _null_ _null_ ) +insert ( 1179 jsonb_path_query_tz 11 10 12 1 1000 0 0 f f f t t s s 4 0 3802 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_query_tz _null_ _null_ _null_ _null_ ) +insert ( 1180 jsonb_path_query_array_tz 11 10 12 1 0 0 0 f f f t f s s 4 0 3802 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_query_array_tz _null_ _null_ _null_ _null_ ) +insert ( 2023 jsonb_path_query_first_tz 11 10 12 1 0 0 0 f f f t f s s 4 0 3802 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_query_first_tz _null_ _null_ _null_ _null_ ) +insert ( 2030 jsonb_path_match_tz 11 10 12 1 0 0 0 f f f t f s s 4 0 16 '3802 4072 3802 16' _null_ _null_ _null_ _null_ _null_ jsonb_path_match_tz _null_ _null_ _null_ _null_ ) +insert ( 4010 jsonb_path_exists_opr 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 4072' _null_ _null_ _null_ _null_ _null_ jsonb_path_exists_opr _null_ _null_ _null_ _null_ ) +insert ( 4011 jsonb_path_match_opr 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3802 4072' _null_ _null_ _null_ _null_ _null_ jsonb_path_match_opr _null_ _null_ _null_ _null_ ) +insert ( 2939 txid_snapshot_in 11 10 12 1 0 0 0 f f f t f i s 1 0 2970 2275 _null_ _null_ _null_ _null_ _null_ pg_snapshot_in _null_ _null_ _null_ _null_ ) +insert ( 2940 txid_snapshot_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 2970 _null_ _null_ _null_ _null_ _null_ pg_snapshot_out _null_ _null_ _null_ _null_ ) +insert ( 2941 txid_snapshot_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 2970 2281 _null_ _null_ _null_ _null_ _null_ pg_snapshot_recv _null_ _null_ _null_ _null_ ) +insert ( 2942 txid_snapshot_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 2970 _null_ _null_ _null_ _null_ _null_ pg_snapshot_send _null_ _null_ _null_ _null_ ) +insert ( 2943 txid_current 11 10 12 1 0 0 0 f f f t f s u 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_current_xact_id _null_ _null_ _null_ _null_ ) +insert ( 3348 txid_current_if_assigned 11 10 12 1 0 0 0 f f f t f s u 0 0 20 '' _null_ _null_ _null_ _null_ _null_ pg_current_xact_id_if_assigned _null_ _null_ _null_ _null_ ) +insert ( 2944 txid_current_snapshot 11 10 12 1 0 0 0 f f f t f s s 0 0 2970 '' _null_ _null_ _null_ _null_ _null_ pg_current_snapshot _null_ _null_ _null_ _null_ ) +insert ( 2945 txid_snapshot_xmin 11 10 12 1 0 0 0 f f f t f i s 1 0 20 2970 _null_ _null_ _null_ _null_ _null_ pg_snapshot_xmin _null_ _null_ _null_ _null_ ) +insert ( 2946 txid_snapshot_xmax 11 10 12 1 0 0 0 f f f t f i s 1 0 20 2970 _null_ _null_ _null_ _null_ _null_ pg_snapshot_xmax _null_ _null_ _null_ _null_ ) +insert ( 2947 txid_snapshot_xip 11 10 12 1 50 0 0 f f f t t i s 1 0 20 2970 _null_ _null_ _null_ _null_ _null_ pg_snapshot_xip _null_ _null_ _null_ _null_ ) +insert ( 2948 txid_visible_in_snapshot 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '20 2970' _null_ _null_ _null_ _null_ _null_ pg_visible_in_snapshot _null_ _null_ _null_ _null_ ) +insert ( 3360 txid_status 11 10 12 1 0 0 0 f f f t f v s 1 0 25 20 _null_ _null_ _null_ _null_ _null_ pg_xact_status _null_ _null_ _null_ _null_ ) +insert ( 5055 pg_snapshot_in 11 10 12 1 0 0 0 f f f t f i s 1 0 5038 2275 _null_ _null_ _null_ _null_ _null_ pg_snapshot_in _null_ _null_ _null_ _null_ ) +insert ( 5056 pg_snapshot_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 5038 _null_ _null_ _null_ _null_ _null_ pg_snapshot_out _null_ _null_ _null_ _null_ ) +insert ( 5057 pg_snapshot_recv 11 10 12 1 0 0 0 f f f t f i s 1 0 5038 2281 _null_ _null_ _null_ _null_ _null_ pg_snapshot_recv _null_ _null_ _null_ _null_ ) +insert ( 5058 pg_snapshot_send 11 10 12 1 0 0 0 f f f t f i s 1 0 17 5038 _null_ _null_ _null_ _null_ _null_ pg_snapshot_send _null_ _null_ _null_ _null_ ) +insert ( 5061 pg_current_snapshot 11 10 12 1 0 0 0 f f f t f s s 0 0 5038 '' _null_ _null_ _null_ _null_ _null_ pg_current_snapshot _null_ _null_ _null_ _null_ ) +insert ( 5062 pg_snapshot_xmin 11 10 12 1 0 0 0 f f f t f i s 1 0 5069 5038 _null_ _null_ _null_ _null_ _null_ pg_snapshot_xmin _null_ _null_ _null_ _null_ ) +insert ( 5063 pg_snapshot_xmax 11 10 12 1 0 0 0 f f f t f i s 1 0 5069 5038 _null_ _null_ _null_ _null_ _null_ pg_snapshot_xmax _null_ _null_ _null_ _null_ ) +insert ( 5064 pg_snapshot_xip 11 10 12 1 50 0 0 f f f t t i s 1 0 5069 5038 _null_ _null_ _null_ _null_ _null_ pg_snapshot_xip _null_ _null_ _null_ _null_ ) +insert ( 5065 pg_visible_in_snapshot 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '5069 5038' _null_ _null_ _null_ _null_ _null_ pg_visible_in_snapshot _null_ _null_ _null_ _null_ ) +insert ( 5059 pg_current_xact_id 11 10 12 1 0 0 0 f f f t f s u 0 0 5069 '' _null_ _null_ _null_ _null_ _null_ pg_current_xact_id _null_ _null_ _null_ _null_ ) +insert ( 5060 pg_current_xact_id_if_assigned 11 10 12 1 0 0 0 f f f t f s u 0 0 5069 '' _null_ _null_ _null_ _null_ _null_ pg_current_xact_id_if_assigned _null_ _null_ _null_ _null_ ) +insert ( 5066 pg_xact_status 11 10 12 1 0 0 0 f f f t f v s 1 0 25 5069 _null_ _null_ _null_ _null_ _null_ pg_xact_status _null_ _null_ _null_ _null_ ) +insert ( 2981 record_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_eq _null_ _null_ _null_ _null_ ) +insert ( 2982 record_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_ne _null_ _null_ _null_ _null_ ) +insert ( 2983 record_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_lt _null_ _null_ _null_ _null_ ) +insert ( 2984 record_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_gt _null_ _null_ _null_ _null_ ) +insert ( 2985 record_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_le _null_ _null_ _null_ _null_ ) +insert ( 2986 record_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_ge _null_ _null_ _null_ _null_ ) +insert ( 2987 btrecordcmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '2249 2249' _null_ _null_ _null_ _null_ _null_ btrecordcmp _null_ _null_ _null_ _null_ ) +insert ( 6192 hash_record 11 10 12 1 0 0 0 f f f t f i s 1 0 23 2249 _null_ _null_ _null_ _null_ _null_ hash_record _null_ _null_ _null_ _null_ ) +insert ( 6193 hash_record_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '2249 20' _null_ _null_ _null_ _null_ _null_ hash_record_extended _null_ _null_ _null_ _null_ ) +insert ( 3181 record_image_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_image_eq _null_ _null_ _null_ _null_ ) +insert ( 3182 record_image_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_image_ne _null_ _null_ _null_ _null_ ) +insert ( 3183 record_image_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_image_lt _null_ _null_ _null_ _null_ ) +insert ( 3184 record_image_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_image_gt _null_ _null_ _null_ _null_ ) +insert ( 3185 record_image_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_image_le _null_ _null_ _null_ _null_ ) +insert ( 3186 record_image_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2249 2249' _null_ _null_ _null_ _null_ _null_ record_image_ge _null_ _null_ _null_ _null_ ) +insert ( 3187 btrecordimagecmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '2249 2249' _null_ _null_ _null_ _null_ _null_ btrecordimagecmp _null_ _null_ _null_ _null_ ) +insert ( 5051 btequalimage 11 10 12 1 0 0 0 f f f t f i s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ btequalimage _null_ _null_ _null_ _null_ ) +insert ( 3082 pg_available_extensions 11 10 12 10 100 0 0 f f f t t s s 0 0 2249 '' '{19,25,25}' '{o,o,o}' '{name,default_version,comment}' _null_ _null_ pg_available_extensions _null_ _null_ _null_ _null_ ) +insert ( 3083 pg_available_extension_versions 11 10 12 10 100 0 0 f f f t t s s 0 0 2249 '' '{19,25,16,16,16,19,1003,25}' '{o,o,o,o,o,o,o,o}' '{name,version,superuser,trusted,relocatable,schema,requires,comment}' _null_ _null_ pg_available_extension_versions _null_ _null_ _null_ _null_ ) +insert ( 3084 pg_extension_update_paths 11 10 12 10 100 0 0 f f f t t s s 1 0 2249 19 '{19,25,25,25}' '{i,o,o,o}' '{name,source,target,path}' _null_ _null_ pg_extension_update_paths _null_ _null_ _null_ _null_ ) +insert ( 3086 pg_extension_config_dump 11 10 12 1 0 0 0 f f f t f v u 2 0 2278 '2205 25' _null_ _null_ _null_ _null_ _null_ pg_extension_config_dump _null_ _null_ _null_ _null_ ) +insert ( 3100 row_number 11 10 12 1 0 0 6233 w f f f f i s 0 0 20 '' _null_ _null_ _null_ _null_ _null_ window_row_number _null_ _null_ _null_ _null_ ) +insert ( 6233 window_row_number_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ window_row_number_support _null_ _null_ _null_ _null_ ) +insert ( 3101 rank 11 10 12 1 0 0 6234 w f f f f i s 0 0 20 '' _null_ _null_ _null_ _null_ _null_ window_rank _null_ _null_ _null_ _null_ ) +insert ( 6234 window_rank_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ window_rank_support _null_ _null_ _null_ _null_ ) +insert ( 3102 dense_rank 11 10 12 1 0 0 6235 w f f f f i s 0 0 20 '' _null_ _null_ _null_ _null_ _null_ window_dense_rank _null_ _null_ _null_ _null_ ) +insert ( 6235 window_dense_rank_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ window_dense_rank_support _null_ _null_ _null_ _null_ ) +insert ( 3103 percent_rank 11 10 12 1 0 0 6306 w f f f f i s 0 0 701 '' _null_ _null_ _null_ _null_ _null_ window_percent_rank _null_ _null_ _null_ _null_ ) +insert ( 6306 window_percent_rank_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ window_percent_rank_support _null_ _null_ _null_ _null_ ) +insert ( 3104 cume_dist 11 10 12 1 0 0 6307 w f f f f i s 0 0 701 '' _null_ _null_ _null_ _null_ _null_ window_cume_dist _null_ _null_ _null_ _null_ ) +insert ( 6307 window_cume_dist_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ window_cume_dist_support _null_ _null_ _null_ _null_ ) +insert ( 3105 ntile 11 10 12 1 0 0 6308 w f f t f i s 1 0 23 23 _null_ _null_ _null_ _null_ _null_ window_ntile _null_ _null_ _null_ _null_ ) +insert ( 6308 window_ntile_support 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ window_ntile_support _null_ _null_ _null_ _null_ ) +insert ( 3106 lag 11 10 12 1 0 0 0 w f f t f i s 1 0 2283 2283 _null_ _null_ _null_ _null_ _null_ window_lag _null_ _null_ _null_ _null_ ) +insert ( 3107 lag 11 10 12 1 0 0 0 w f f t f i s 2 0 2283 '2283 23' _null_ _null_ _null_ _null_ _null_ window_lag_with_offset _null_ _null_ _null_ _null_ ) +insert ( 3108 lag 11 10 12 1 0 0 0 w f f t f i s 3 0 5077 '5077 23 5077' _null_ _null_ _null_ _null_ _null_ window_lag_with_offset_and_default _null_ _null_ _null_ _null_ ) +insert ( 3109 lead 11 10 12 1 0 0 0 w f f t f i s 1 0 2283 2283 _null_ _null_ _null_ _null_ _null_ window_lead _null_ _null_ _null_ _null_ ) +insert ( 3110 lead 11 10 12 1 0 0 0 w f f t f i s 2 0 2283 '2283 23' _null_ _null_ _null_ _null_ _null_ window_lead_with_offset _null_ _null_ _null_ _null_ ) +insert ( 3111 lead 11 10 12 1 0 0 0 w f f t f i s 3 0 5077 '5077 23 5077' _null_ _null_ _null_ _null_ _null_ window_lead_with_offset_and_default _null_ _null_ _null_ _null_ ) +insert ( 3112 first_value 11 10 12 1 0 0 0 w f f t f i s 1 0 2283 2283 _null_ _null_ _null_ _null_ _null_ window_first_value _null_ _null_ _null_ _null_ ) +insert ( 3113 last_value 11 10 12 1 0 0 0 w f f t f i s 1 0 2283 2283 _null_ _null_ _null_ _null_ _null_ window_last_value _null_ _null_ _null_ _null_ ) +insert ( 3114 nth_value 11 10 12 1 0 0 0 w f f t f i s 2 0 2283 '2283 23' _null_ _null_ _null_ _null_ _null_ window_nth_value _null_ _null_ _null_ _null_ ) +insert ( 3832 anyrange_in 11 10 12 1 0 0 0 f f f t f s s 3 0 3831 '2275 26 23' _null_ _null_ _null_ _null_ _null_ anyrange_in _null_ _null_ _null_ _null_ ) +insert ( 3833 anyrange_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 3831 _null_ _null_ _null_ _null_ _null_ anyrange_out _null_ _null_ _null_ _null_ ) +insert ( 3834 range_in 11 10 12 1 0 0 0 f f f t f s s 3 0 3831 '2275 26 23' _null_ _null_ _null_ _null_ _null_ range_in _null_ _null_ _null_ _null_ ) +insert ( 3835 range_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 3831 _null_ _null_ _null_ _null_ _null_ range_out _null_ _null_ _null_ _null_ ) +insert ( 3836 range_recv 11 10 12 1 0 0 0 f f f t f s s 3 0 3831 '2281 26 23' _null_ _null_ _null_ _null_ _null_ range_recv _null_ _null_ _null_ _null_ ) +insert ( 3837 range_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 3831 _null_ _null_ _null_ _null_ _null_ range_send _null_ _null_ _null_ _null_ ) +insert ( 3848 lower 11 10 12 1 0 0 0 f f f t f i s 1 0 2283 3831 _null_ _null_ _null_ _null_ _null_ range_lower _null_ _null_ _null_ _null_ ) +insert ( 3849 upper 11 10 12 1 0 0 0 f f f t f i s 1 0 2283 3831 _null_ _null_ _null_ _null_ _null_ range_upper _null_ _null_ _null_ _null_ ) +insert ( 3850 isempty 11 10 12 1 0 0 0 f f f t f i s 1 0 16 3831 _null_ _null_ _null_ _null_ _null_ range_empty _null_ _null_ _null_ _null_ ) +insert ( 3851 lower_inc 11 10 12 1 0 0 0 f f f t f i s 1 0 16 3831 _null_ _null_ _null_ _null_ _null_ range_lower_inc _null_ _null_ _null_ _null_ ) +insert ( 3852 upper_inc 11 10 12 1 0 0 0 f f f t f i s 1 0 16 3831 _null_ _null_ _null_ _null_ _null_ range_upper_inc _null_ _null_ _null_ _null_ ) +insert ( 3853 lower_inf 11 10 12 1 0 0 0 f f f t f i s 1 0 16 3831 _null_ _null_ _null_ _null_ _null_ range_lower_inf _null_ _null_ _null_ _null_ ) +insert ( 3854 upper_inf 11 10 12 1 0 0 0 f f f t f i s 1 0 16 3831 _null_ _null_ _null_ _null_ _null_ range_upper_inf _null_ _null_ _null_ _null_ ) +insert ( 3855 range_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_eq _null_ _null_ _null_ _null_ ) +insert ( 3856 range_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_ne _null_ _null_ _null_ _null_ ) +insert ( 3857 range_overlaps 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_overlaps _null_ _null_ _null_ _null_ ) +insert ( 3858 range_contains_elem 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 2283' _null_ _null_ _null_ _null_ _null_ range_contains_elem _null_ _null_ _null_ _null_ ) +insert ( 3859 range_contains 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_contains _null_ _null_ _null_ _null_ ) +insert ( 3860 elem_contained_by_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2283 3831' _null_ _null_ _null_ _null_ _null_ elem_contained_by_range _null_ _null_ _null_ _null_ ) +insert ( 3861 range_contained_by 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_contained_by _null_ _null_ _null_ _null_ ) +insert ( 3862 range_adjacent 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_adjacent _null_ _null_ _null_ _null_ ) +insert ( 3863 range_before 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_before _null_ _null_ _null_ _null_ ) +insert ( 3864 range_after 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_after _null_ _null_ _null_ _null_ ) +insert ( 3865 range_overleft 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_overleft _null_ _null_ _null_ _null_ ) +insert ( 3866 range_overright 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_overright _null_ _null_ _null_ _null_ ) +insert ( 3867 range_union 11 10 12 1 0 0 0 f f f t f i s 2 0 3831 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_union _null_ _null_ _null_ _null_ ) +insert ( 4057 range_merge 11 10 12 1 0 0 0 f f f t f i s 2 0 3831 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_merge _null_ _null_ _null_ _null_ ) +insert ( 4228 range_merge 11 10 12 1 0 0 0 f f f t f i s 1 0 3831 4537 _null_ _null_ _null_ _null_ _null_ range_merge_from_multirange _null_ _null_ _null_ _null_ ) +insert ( 3868 range_intersect 11 10 12 1 0 0 0 f f f t f i s 2 0 3831 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_intersect _null_ _null_ _null_ _null_ ) +insert ( 3869 range_minus 11 10 12 1 0 0 0 f f f t f i s 2 0 3831 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_minus _null_ _null_ _null_ _null_ ) +insert ( 3870 range_cmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_cmp _null_ _null_ _null_ _null_ ) +insert ( 3871 range_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_lt _null_ _null_ _null_ _null_ ) +insert ( 3872 range_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_le _null_ _null_ _null_ _null_ ) +insert ( 3873 range_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_ge _null_ _null_ _null_ _null_ ) +insert ( 3874 range_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_gt _null_ _null_ _null_ _null_ ) +insert ( 3875 range_gist_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 3831 21 26 2281' _null_ _null_ _null_ _null_ _null_ range_gist_consistent _null_ _null_ _null_ _null_ ) +insert ( 3876 range_gist_union 11 10 12 1 0 0 0 f f f t f i s 2 0 3831 '2281 2281' _null_ _null_ _null_ _null_ _null_ range_gist_union _null_ _null_ _null_ _null_ ) +insert ( 3879 range_gist_penalty 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '2281 2281 2281' _null_ _null_ _null_ _null_ _null_ range_gist_penalty _null_ _null_ _null_ _null_ ) +insert ( 3880 range_gist_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2281 '2281 2281' _null_ _null_ _null_ _null_ _null_ range_gist_picksplit _null_ _null_ _null_ _null_ ) +insert ( 3881 range_gist_same 11 10 12 1 0 0 0 f f f t f i s 3 0 2281 '3831 3831 2281' _null_ _null_ _null_ _null_ _null_ range_gist_same _null_ _null_ _null_ _null_ ) +insert ( 6154 multirange_gist_consistent 11 10 12 1 0 0 0 f f f t f i s 5 0 16 '2281 4537 21 26 2281' _null_ _null_ _null_ _null_ _null_ multirange_gist_consistent _null_ _null_ _null_ _null_ ) +insert ( 6156 multirange_gist_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ multirange_gist_compress _null_ _null_ _null_ _null_ ) +insert ( 3902 hash_range 11 10 12 1 0 0 0 f f f t f i s 1 0 23 3831 _null_ _null_ _null_ _null_ _null_ hash_range _null_ _null_ _null_ _null_ ) +insert ( 3417 hash_range_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '3831 20' _null_ _null_ _null_ _null_ _null_ hash_range_extended _null_ _null_ _null_ _null_ ) +insert ( 3916 range_typanalyze 11 10 12 1 0 0 0 f f f t f s s 1 0 16 2281 _null_ _null_ _null_ _null_ _null_ range_typanalyze _null_ _null_ _null_ _null_ ) +insert ( 3169 rangesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ rangesel _null_ _null_ _null_ _null_ ) +insert ( 4401 range_intersect_agg_transfn 11 10 12 1 0 0 0 f f f t f i s 2 0 3831 '3831 3831' _null_ _null_ _null_ _null_ _null_ range_intersect_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 4450 range_intersect_agg 11 10 12 1 0 0 0 a f f f f i s 1 0 3831 3831 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3914 int4range_canonical 11 10 12 1 0 0 0 f f f t f i s 1 0 3904 3904 _null_ _null_ _null_ _null_ _null_ int4range_canonical _null_ _null_ _null_ _null_ ) +insert ( 3928 int8range_canonical 11 10 12 1 0 0 0 f f f t f i s 1 0 3926 3926 _null_ _null_ _null_ _null_ _null_ int8range_canonical _null_ _null_ _null_ _null_ ) +insert ( 3915 daterange_canonical 11 10 12 1 0 0 0 f f f t f i s 1 0 3912 3912 _null_ _null_ _null_ _null_ _null_ daterange_canonical _null_ _null_ _null_ _null_ ) +insert ( 3922 int4range_subdiff 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '23 23' _null_ _null_ _null_ _null_ _null_ int4range_subdiff _null_ _null_ _null_ _null_ ) +insert ( 3923 int8range_subdiff 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '20 20' _null_ _null_ _null_ _null_ _null_ int8range_subdiff _null_ _null_ _null_ _null_ ) +insert ( 3924 numrange_subdiff 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '1700 1700' _null_ _null_ _null_ _null_ _null_ numrange_subdiff _null_ _null_ _null_ _null_ ) +insert ( 3925 daterange_subdiff 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '1082 1082' _null_ _null_ _null_ _null_ _null_ daterange_subdiff _null_ _null_ _null_ _null_ ) +insert ( 3929 tsrange_subdiff 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '1114 1114' _null_ _null_ _null_ _null_ _null_ tsrange_subdiff _null_ _null_ _null_ _null_ ) +insert ( 3930 tstzrange_subdiff 11 10 12 1 0 0 0 f f f t f i s 2 0 701 '1184 1184' _null_ _null_ _null_ _null_ _null_ tstzrange_subdiff _null_ _null_ _null_ _null_ ) +insert ( 3840 int4range 11 10 12 1 0 0 0 f f f f f i s 2 0 3904 '23 23' _null_ _null_ _null_ _null_ _null_ range_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 3841 int4range 11 10 12 1 0 0 0 f f f f f i s 3 0 3904 '23 23 25' _null_ _null_ _null_ _null_ _null_ range_constructor3 _null_ _null_ _null_ _null_ ) +insert ( 3844 numrange 11 10 12 1 0 0 0 f f f f f i s 2 0 3906 '1700 1700' _null_ _null_ _null_ _null_ _null_ range_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 3845 numrange 11 10 12 1 0 0 0 f f f f f i s 3 0 3906 '1700 1700 25' _null_ _null_ _null_ _null_ _null_ range_constructor3 _null_ _null_ _null_ _null_ ) +insert ( 3933 tsrange 11 10 12 1 0 0 0 f f f f f i s 2 0 3908 '1114 1114' _null_ _null_ _null_ _null_ _null_ range_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 3934 tsrange 11 10 12 1 0 0 0 f f f f f i s 3 0 3908 '1114 1114 25' _null_ _null_ _null_ _null_ _null_ range_constructor3 _null_ _null_ _null_ _null_ ) +insert ( 3937 tstzrange 11 10 12 1 0 0 0 f f f f f i s 2 0 3910 '1184 1184' _null_ _null_ _null_ _null_ _null_ range_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 3938 tstzrange 11 10 12 1 0 0 0 f f f f f i s 3 0 3910 '1184 1184 25' _null_ _null_ _null_ _null_ _null_ range_constructor3 _null_ _null_ _null_ _null_ ) +insert ( 3941 daterange 11 10 12 1 0 0 0 f f f f f i s 2 0 3912 '1082 1082' _null_ _null_ _null_ _null_ _null_ range_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 3942 daterange 11 10 12 1 0 0 0 f f f f f i s 3 0 3912 '1082 1082 25' _null_ _null_ _null_ _null_ _null_ range_constructor3 _null_ _null_ _null_ _null_ ) +insert ( 3945 int8range 11 10 12 1 0 0 0 f f f f f i s 2 0 3926 '20 20' _null_ _null_ _null_ _null_ _null_ range_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 3946 int8range 11 10 12 1 0 0 0 f f f f f i s 3 0 3926 '20 20 25' _null_ _null_ _null_ _null_ _null_ range_constructor3 _null_ _null_ _null_ _null_ ) +insert ( 4229 anymultirange_in 11 10 12 1 0 0 0 f f f t f s s 3 0 4537 '2275 26 23' _null_ _null_ _null_ _null_ _null_ anymultirange_in _null_ _null_ _null_ _null_ ) +insert ( 4230 anymultirange_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 4537 _null_ _null_ _null_ _null_ _null_ anymultirange_out _null_ _null_ _null_ _null_ ) +insert ( 4231 multirange_in 11 10 12 1 0 0 0 f f f t f s s 3 0 4537 '2275 26 23' _null_ _null_ _null_ _null_ _null_ multirange_in _null_ _null_ _null_ _null_ ) +insert ( 4232 multirange_out 11 10 12 1 0 0 0 f f f t f s s 1 0 2275 4537 _null_ _null_ _null_ _null_ _null_ multirange_out _null_ _null_ _null_ _null_ ) +insert ( 4233 multirange_recv 11 10 12 1 0 0 0 f f f t f s s 3 0 4537 '2281 26 23' _null_ _null_ _null_ _null_ _null_ multirange_recv _null_ _null_ _null_ _null_ ) +insert ( 4234 multirange_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 4537 _null_ _null_ _null_ _null_ _null_ multirange_send _null_ _null_ _null_ _null_ ) +insert ( 4235 lower 11 10 12 1 0 0 0 f f f t f i s 1 0 2283 4537 _null_ _null_ _null_ _null_ _null_ multirange_lower _null_ _null_ _null_ _null_ ) +insert ( 4236 upper 11 10 12 1 0 0 0 f f f t f i s 1 0 2283 4537 _null_ _null_ _null_ _null_ _null_ multirange_upper _null_ _null_ _null_ _null_ ) +insert ( 4237 isempty 11 10 12 1 0 0 0 f f f t f i s 1 0 16 4537 _null_ _null_ _null_ _null_ _null_ multirange_empty _null_ _null_ _null_ _null_ ) +insert ( 4238 lower_inc 11 10 12 1 0 0 0 f f f t f i s 1 0 16 4537 _null_ _null_ _null_ _null_ _null_ multirange_lower_inc _null_ _null_ _null_ _null_ ) +insert ( 4239 upper_inc 11 10 12 1 0 0 0 f f f t f i s 1 0 16 4537 _null_ _null_ _null_ _null_ _null_ multirange_upper_inc _null_ _null_ _null_ _null_ ) +insert ( 4240 lower_inf 11 10 12 1 0 0 0 f f f t f i s 1 0 16 4537 _null_ _null_ _null_ _null_ _null_ multirange_lower_inf _null_ _null_ _null_ _null_ ) +insert ( 4241 upper_inf 11 10 12 1 0 0 0 f f f t f i s 1 0 16 4537 _null_ _null_ _null_ _null_ _null_ multirange_upper_inf _null_ _null_ _null_ _null_ ) +insert ( 4242 multirange_typanalyze 11 10 12 1 0 0 0 f f f t f s s 1 0 16 2281 _null_ _null_ _null_ _null_ _null_ multirange_typanalyze _null_ _null_ _null_ _null_ ) +insert ( 4243 multirangesel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ multirangesel _null_ _null_ _null_ _null_ ) +insert ( 4244 multirange_eq 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_eq _null_ _null_ _null_ _null_ ) +insert ( 4245 multirange_ne 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_ne _null_ _null_ _null_ _null_ ) +insert ( 4246 range_overlaps_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_overlaps_multirange _null_ _null_ _null_ _null_ ) +insert ( 4247 multirange_overlaps_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_overlaps_range _null_ _null_ _null_ _null_ ) +insert ( 4248 multirange_overlaps_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_overlaps_multirange _null_ _null_ _null_ _null_ ) +insert ( 4249 multirange_contains_elem 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 2283' _null_ _null_ _null_ _null_ _null_ multirange_contains_elem _null_ _null_ _null_ _null_ ) +insert ( 4250 multirange_contains_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_contains_range _null_ _null_ _null_ _null_ ) +insert ( 4251 multirange_contains_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_contains_multirange _null_ _null_ _null_ _null_ ) +insert ( 4252 elem_contained_by_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2283 4537' _null_ _null_ _null_ _null_ _null_ elem_contained_by_multirange _null_ _null_ _null_ _null_ ) +insert ( 4253 range_contained_by_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_contained_by_multirange _null_ _null_ _null_ _null_ ) +insert ( 4541 range_contains_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_contains_multirange _null_ _null_ _null_ _null_ ) +insert ( 4542 multirange_contained_by_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_contained_by_range _null_ _null_ _null_ _null_ ) +insert ( 4254 multirange_contained_by_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_contained_by_multirange _null_ _null_ _null_ _null_ ) +insert ( 4255 range_adjacent_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_adjacent_multirange _null_ _null_ _null_ _null_ ) +insert ( 4256 multirange_adjacent_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_adjacent_multirange _null_ _null_ _null_ _null_ ) +insert ( 4257 multirange_adjacent_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_adjacent_range _null_ _null_ _null_ _null_ ) +insert ( 4258 range_before_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_before_multirange _null_ _null_ _null_ _null_ ) +insert ( 4259 multirange_before_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_before_range _null_ _null_ _null_ _null_ ) +insert ( 4260 multirange_before_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_before_multirange _null_ _null_ _null_ _null_ ) +insert ( 4261 range_after_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_after_multirange _null_ _null_ _null_ _null_ ) +insert ( 4262 multirange_after_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_after_range _null_ _null_ _null_ _null_ ) +insert ( 4263 multirange_after_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_after_multirange _null_ _null_ _null_ _null_ ) +insert ( 4264 range_overleft_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_overleft_multirange _null_ _null_ _null_ _null_ ) +insert ( 4265 multirange_overleft_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_overleft_range _null_ _null_ _null_ _null_ ) +insert ( 4266 multirange_overleft_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_overleft_multirange _null_ _null_ _null_ _null_ ) +insert ( 4267 range_overright_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '3831 4537' _null_ _null_ _null_ _null_ _null_ range_overright_multirange _null_ _null_ _null_ _null_ ) +insert ( 4268 multirange_overright_range 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 3831' _null_ _null_ _null_ _null_ _null_ multirange_overright_range _null_ _null_ _null_ _null_ ) +insert ( 4269 multirange_overright_multirange 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_overright_multirange _null_ _null_ _null_ _null_ ) +insert ( 4270 multirange_union 11 10 12 1 0 0 0 f f f t f i s 2 0 4537 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_union _null_ _null_ _null_ _null_ ) +insert ( 4271 multirange_minus 11 10 12 1 0 0 0 f f f t f i s 2 0 4537 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_minus _null_ _null_ _null_ _null_ ) +insert ( 4272 multirange_intersect 11 10 12 1 0 0 0 f f f t f i s 2 0 4537 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_intersect _null_ _null_ _null_ _null_ ) +insert ( 4273 multirange_cmp 11 10 12 1 0 0 0 f f f t f i s 2 0 23 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_cmp _null_ _null_ _null_ _null_ ) +insert ( 4274 multirange_lt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_lt _null_ _null_ _null_ _null_ ) +insert ( 4275 multirange_le 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_le _null_ _null_ _null_ _null_ ) +insert ( 4276 multirange_ge 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_ge _null_ _null_ _null_ _null_ ) +insert ( 4277 multirange_gt 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_gt _null_ _null_ _null_ _null_ ) +insert ( 4278 hash_multirange 11 10 12 1 0 0 0 f f f t f i s 1 0 23 4537 _null_ _null_ _null_ _null_ _null_ hash_multirange _null_ _null_ _null_ _null_ ) +insert ( 4279 hash_multirange_extended 11 10 12 1 0 0 0 f f f t f i s 2 0 20 '4537 20' _null_ _null_ _null_ _null_ _null_ hash_multirange_extended _null_ _null_ _null_ _null_ ) +insert ( 4280 int4multirange 11 10 12 1 0 0 0 f f f t f i s 0 0 4451 '' _null_ _null_ _null_ _null_ _null_ multirange_constructor0 _null_ _null_ _null_ _null_ ) +insert ( 4281 int4multirange 11 10 12 1 0 0 0 f f f t f i s 1 0 4451 3904 _null_ _null_ _null_ _null_ _null_ multirange_constructor1 _null_ _null_ _null_ _null_ ) +insert ( 4282 int4multirange 11 10 12 1 0 3904 0 f f f t f i s 1 0 4451 3905 '{3905}' '{v}' _null_ _null_ _null_ multirange_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 4283 nummultirange 11 10 12 1 0 0 0 f f f t f i s 0 0 4532 '' _null_ _null_ _null_ _null_ _null_ multirange_constructor0 _null_ _null_ _null_ _null_ ) +insert ( 4284 nummultirange 11 10 12 1 0 0 0 f f f t f i s 1 0 4532 3906 _null_ _null_ _null_ _null_ _null_ multirange_constructor1 _null_ _null_ _null_ _null_ ) +insert ( 4285 nummultirange 11 10 12 1 0 3906 0 f f f t f i s 1 0 4532 3907 '{3907}' '{v}' _null_ _null_ _null_ multirange_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 4286 tsmultirange 11 10 12 1 0 0 0 f f f t f i s 0 0 4533 '' _null_ _null_ _null_ _null_ _null_ multirange_constructor0 _null_ _null_ _null_ _null_ ) +insert ( 4287 tsmultirange 11 10 12 1 0 0 0 f f f t f i s 1 0 4533 3908 _null_ _null_ _null_ _null_ _null_ multirange_constructor1 _null_ _null_ _null_ _null_ ) +insert ( 4288 tsmultirange 11 10 12 1 0 3908 0 f f f t f i s 1 0 4533 3909 '{3909}' '{v}' _null_ _null_ _null_ multirange_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 4289 tstzmultirange 11 10 12 1 0 0 0 f f f t f i s 0 0 4534 '' _null_ _null_ _null_ _null_ _null_ multirange_constructor0 _null_ _null_ _null_ _null_ ) +insert ( 4290 tstzmultirange 11 10 12 1 0 0 0 f f f t f i s 1 0 4534 3910 _null_ _null_ _null_ _null_ _null_ multirange_constructor1 _null_ _null_ _null_ _null_ ) +insert ( 4291 tstzmultirange 11 10 12 1 0 3910 0 f f f t f i s 1 0 4534 3911 '{3911}' '{v}' _null_ _null_ _null_ multirange_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 4292 datemultirange 11 10 12 1 0 0 0 f f f t f i s 0 0 4535 '' _null_ _null_ _null_ _null_ _null_ multirange_constructor0 _null_ _null_ _null_ _null_ ) +insert ( 4293 datemultirange 11 10 12 1 0 0 0 f f f t f i s 1 0 4535 3912 _null_ _null_ _null_ _null_ _null_ multirange_constructor1 _null_ _null_ _null_ _null_ ) +insert ( 4294 datemultirange 11 10 12 1 0 3912 0 f f f t f i s 1 0 4535 3913 '{3913}' '{v}' _null_ _null_ _null_ multirange_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 4295 int8multirange 11 10 12 1 0 0 0 f f f t f i s 0 0 4536 '' _null_ _null_ _null_ _null_ _null_ multirange_constructor0 _null_ _null_ _null_ _null_ ) +insert ( 4296 int8multirange 11 10 12 1 0 0 0 f f f t f i s 1 0 4536 3926 _null_ _null_ _null_ _null_ _null_ multirange_constructor1 _null_ _null_ _null_ _null_ ) +insert ( 4297 int8multirange 11 10 12 1 0 3926 0 f f f t f i s 1 0 4536 3927 '{3927}' '{v}' _null_ _null_ _null_ multirange_constructor2 _null_ _null_ _null_ _null_ ) +insert ( 4298 multirange 11 10 12 1 0 0 0 f f f t f i s 1 0 4537 3831 _null_ _null_ _null_ _null_ _null_ multirange_constructor1 _null_ _null_ _null_ _null_ ) +insert ( 4299 range_agg_transfn 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 3831' _null_ _null_ _null_ _null_ _null_ range_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 4300 range_agg_finalfn 11 10 12 1 0 0 0 f f f f f i s 2 0 4537 '2281 3831' _null_ _null_ _null_ _null_ _null_ range_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 4301 range_agg 11 10 12 1 0 0 0 a f f f f i s 1 0 4537 3831 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6225 multirange_agg_transfn 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 4537' _null_ _null_ _null_ _null_ _null_ multirange_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 6226 multirange_agg_finalfn 11 10 12 1 0 0 0 f f f f f i s 2 0 4537 '2281 4537' _null_ _null_ _null_ _null_ _null_ range_agg_finalfn _null_ _null_ _null_ _null_ ) +insert ( 6227 range_agg 11 10 12 1 0 0 0 a f f f f i s 1 0 4537 4537 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 4388 multirange_intersect_agg_transfn 11 10 12 1 0 0 0 f f f t f i s 2 0 4537 '4537 4537' _null_ _null_ _null_ _null_ _null_ multirange_intersect_agg_transfn _null_ _null_ _null_ _null_ ) +insert ( 4389 range_intersect_agg 11 10 12 1 0 0 0 a f f f f i s 1 0 4537 4537 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 1293 unnest 11 10 12 1 100 0 0 f f f t t i s 1 0 3831 4537 _null_ _null_ _null_ _null_ _null_ multirange_unnest _null_ _null_ _null_ _null_ ) +insert ( 3846 make_date 11 10 12 1 0 0 0 f f f t f i s 3 0 1082 '23 23 23' _null_ _null_ '{year,month,day}' _null_ _null_ make_date _null_ _null_ _null_ _null_ ) +insert ( 3847 make_time 11 10 12 1 0 0 0 f f f t f i s 3 0 1083 '23 23 701' _null_ _null_ '{hour,min,sec}' _null_ _null_ make_time _null_ _null_ _null_ _null_ ) +insert ( 3461 make_timestamp 11 10 12 1 0 0 0 f f f t f i s 6 0 1114 '23 23 23 23 23 701' _null_ _null_ '{year,month,mday,hour,min,sec}' _null_ _null_ make_timestamp _null_ _null_ _null_ _null_ ) +insert ( 3462 make_timestamptz 11 10 12 1 0 0 0 f f f t f s s 6 0 1184 '23 23 23 23 23 701' _null_ _null_ '{year,month,mday,hour,min,sec}' _null_ _null_ make_timestamptz _null_ _null_ _null_ _null_ ) +insert ( 3463 make_timestamptz 11 10 12 1 0 0 0 f f f t f s s 7 0 1184 '23 23 23 23 23 701 25' _null_ _null_ '{year,month,mday,hour,min,sec,timezone}' _null_ _null_ make_timestamptz_at_timezone _null_ _null_ _null_ _null_ ) +insert ( 3464 make_interval 11 10 12 1 0 0 0 f f f t f i s 7 0 1186 '23 23 23 23 23 23 701' _null_ _null_ '{years,months,weeks,days,hours,mins,secs}' _null_ _null_ make_interval _null_ _null_ _null_ _null_ ) +insert ( 4018 spg_quad_config 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_quad_config _null_ _null_ _null_ _null_ ) +insert ( 4019 spg_quad_choose 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_quad_choose _null_ _null_ _null_ _null_ ) +insert ( 4020 spg_quad_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_quad_picksplit _null_ _null_ _null_ _null_ ) +insert ( 4021 spg_quad_inner_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_quad_inner_consistent _null_ _null_ _null_ _null_ ) +insert ( 4022 spg_quad_leaf_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_quad_leaf_consistent _null_ _null_ _null_ _null_ ) +insert ( 4023 spg_kd_config 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_kd_config _null_ _null_ _null_ _null_ ) +insert ( 4024 spg_kd_choose 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_kd_choose _null_ _null_ _null_ _null_ ) +insert ( 4025 spg_kd_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_kd_picksplit _null_ _null_ _null_ _null_ ) +insert ( 4026 spg_kd_inner_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_kd_inner_consistent _null_ _null_ _null_ _null_ ) +insert ( 4027 spg_text_config 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_text_config _null_ _null_ _null_ _null_ ) +insert ( 4028 spg_text_choose 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_text_choose _null_ _null_ _null_ _null_ ) +insert ( 4029 spg_text_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_text_picksplit _null_ _null_ _null_ _null_ ) +insert ( 4030 spg_text_inner_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_text_inner_consistent _null_ _null_ _null_ _null_ ) +insert ( 4031 spg_text_leaf_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_text_leaf_consistent _null_ _null_ _null_ _null_ ) +insert ( 3469 spg_range_quad_config 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_range_quad_config _null_ _null_ _null_ _null_ ) +insert ( 3470 spg_range_quad_choose 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_range_quad_choose _null_ _null_ _null_ _null_ ) +insert ( 3471 spg_range_quad_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_range_quad_picksplit _null_ _null_ _null_ _null_ ) +insert ( 3472 spg_range_quad_inner_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_range_quad_inner_consistent _null_ _null_ _null_ _null_ ) +insert ( 3473 spg_range_quad_leaf_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_range_quad_leaf_consistent _null_ _null_ _null_ _null_ ) +insert ( 5012 spg_box_quad_config 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_box_quad_config _null_ _null_ _null_ _null_ ) +insert ( 5013 spg_box_quad_choose 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_box_quad_choose _null_ _null_ _null_ _null_ ) +insert ( 5014 spg_box_quad_picksplit 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_box_quad_picksplit _null_ _null_ _null_ _null_ ) +insert ( 5015 spg_box_quad_inner_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_box_quad_inner_consistent _null_ _null_ _null_ _null_ ) +insert ( 5016 spg_box_quad_leaf_consistent 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_box_quad_leaf_consistent _null_ _null_ _null_ _null_ ) +insert ( 5010 spg_bbox_quad_config 11 10 12 1 0 0 0 f f f t f i s 2 0 2278 '2281 2281' _null_ _null_ _null_ _null_ _null_ spg_bbox_quad_config _null_ _null_ _null_ _null_ ) +insert ( 5011 spg_poly_quad_compress 11 10 12 1 0 0 0 f f f t f i s 1 0 603 604 _null_ _null_ _null_ _null_ _null_ spg_poly_quad_compress _null_ _null_ _null_ _null_ ) +insert ( 3779 pg_create_physical_replication_slot 11 10 12 1 0 0 0 f f f t f v u 3 0 2249 '19 16 16' '{19,16,16,19,3220}' '{i,i,i,o,o}' '{slot_name,immediately_reserve,temporary,slot_name,lsn}' _null_ _null_ pg_create_physical_replication_slot _null_ _null_ _null_ _null_ ) +insert ( 4220 pg_copy_physical_replication_slot 11 10 12 1 0 0 0 f f f t f v u 3 0 2249 '19 19 16' '{19,19,16,19,3220}' '{i,i,i,o,o}' '{src_slot_name,dst_slot_name,temporary,slot_name,lsn}' _null_ _null_ pg_copy_physical_replication_slot_a _null_ _null_ _null_ _null_ ) +insert ( 4221 pg_copy_physical_replication_slot 11 10 12 1 0 0 0 f f f t f v u 2 0 2249 '19 19' '{19,19,19,3220}' '{i,i,o,o}' '{src_slot_name,dst_slot_name,slot_name,lsn}' _null_ _null_ pg_copy_physical_replication_slot_b _null_ _null_ _null_ _null_ ) +insert ( 3780 pg_drop_replication_slot 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 19 _null_ _null_ _null_ _null_ _null_ pg_drop_replication_slot _null_ _null_ _null_ _null_ ) +insert ( 3781 pg_get_replication_slots 11 10 12 1 10 0 0 f f f f t s s 0 0 2249 '' '{19,19,25,26,16,16,23,28,28,3220,3220,25,20,16,16}' '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{slot_name,plugin,slot_type,datoid,temporary,active,active_pid,xmin,catalog_xmin,restart_lsn,confirmed_flush_lsn,wal_status,safe_wal_size,two_phase,conflicting}' _null_ _null_ pg_get_replication_slots _null_ _null_ _null_ _null_ ) +insert ( 3786 pg_create_logical_replication_slot 11 10 12 1 0 0 0 f f f t f v u 4 0 2249 '19 19 16 16' '{19,19,16,16,19,3220}' '{i,i,i,i,o,o}' '{slot_name,plugin,temporary,twophase,slot_name,lsn}' _null_ _null_ pg_create_logical_replication_slot _null_ _null_ _null_ _null_ ) +insert ( 4222 pg_copy_logical_replication_slot 11 10 12 1 0 0 0 f f f t f v u 4 0 2249 '19 19 16 19' '{19,19,16,19,19,3220}' '{i,i,i,i,o,o}' '{src_slot_name,dst_slot_name,temporary,plugin,slot_name,lsn}' _null_ _null_ pg_copy_logical_replication_slot_a _null_ _null_ _null_ _null_ ) +insert ( 4223 pg_copy_logical_replication_slot 11 10 12 1 0 0 0 f f f t f v u 3 0 2249 '19 19 16' '{19,19,16,19,3220}' '{i,i,i,o,o}' '{src_slot_name,dst_slot_name,temporary,slot_name,lsn}' _null_ _null_ pg_copy_logical_replication_slot_b _null_ _null_ _null_ _null_ ) +insert ( 4224 pg_copy_logical_replication_slot 11 10 12 1 0 0 0 f f f t f v u 2 0 2249 '19 19' '{19,19,19,3220}' '{i,i,o,o}' '{src_slot_name,dst_slot_name,slot_name,lsn}' _null_ _null_ pg_copy_logical_replication_slot_c _null_ _null_ _null_ _null_ ) +insert ( 3782 pg_logical_slot_get_changes 11 10 12 1000 1000 25 0 f f f f t v u 4 0 2249 '19 3220 23 1009' '{19,3220,23,1009,3220,28,25}' '{i,i,i,v,o,o,o}' '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}' _null_ _null_ pg_logical_slot_get_changes _null_ _null_ _null_ _null_ ) +insert ( 3783 pg_logical_slot_get_binary_changes 11 10 12 1000 1000 25 0 f f f f t v u 4 0 2249 '19 3220 23 1009' '{19,3220,23,1009,3220,28,17}' '{i,i,i,v,o,o,o}' '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}' _null_ _null_ pg_logical_slot_get_binary_changes _null_ _null_ _null_ _null_ ) +insert ( 3784 pg_logical_slot_peek_changes 11 10 12 1000 1000 25 0 f f f f t v u 4 0 2249 '19 3220 23 1009' '{19,3220,23,1009,3220,28,25}' '{i,i,i,v,o,o,o}' '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}' _null_ _null_ pg_logical_slot_peek_changes _null_ _null_ _null_ _null_ ) +insert ( 3785 pg_logical_slot_peek_binary_changes 11 10 12 1000 1000 25 0 f f f f t v u 4 0 2249 '19 3220 23 1009' '{19,3220,23,1009,3220,28,17}' '{i,i,i,v,o,o,o}' '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}' _null_ _null_ pg_logical_slot_peek_binary_changes _null_ _null_ _null_ _null_ ) +insert ( 3878 pg_replication_slot_advance 11 10 12 1 0 0 0 f f f t f v u 2 0 2249 '19 3220' '{19,3220,19,3220}' '{i,i,o,o}' '{slot_name,upto_lsn,slot_name,end_lsn}' _null_ _null_ pg_replication_slot_advance _null_ _null_ _null_ _null_ ) +insert ( 3577 pg_logical_emit_message 11 10 12 1 0 0 0 f f f t f v u 3 0 3220 '16 25 25' _null_ _null_ _null_ _null_ _null_ pg_logical_emit_message_text _null_ _null_ _null_ _null_ ) +insert ( 3578 pg_logical_emit_message 11 10 12 1 0 0 0 f f f t f v u 3 0 3220 '16 25 17' _null_ _null_ _null_ _null_ _null_ pg_logical_emit_message_bytea _null_ _null_ _null_ _null_ ) +insert ( 3566 pg_event_trigger_dropped_objects 11 10 12 10 100 0 0 f f f t t s r 0 0 2249 '' '{26,26,23,16,16,16,25,25,25,25,1009,1009}' '{o,o,o,o,o,o,o,o,o,o,o,o}' '{classid, objid, objsubid, original, normal, is_temporary, object_type, schema_name, object_name, object_identity, address_names, address_args}' _null_ _null_ pg_event_trigger_dropped_objects _null_ _null_ _null_ _null_ ) +insert ( 4566 pg_event_trigger_table_rewrite_oid 11 10 12 1 0 0 0 f f f t f s r 0 0 26 '' '{26}' '{o}' '{oid}' _null_ _null_ pg_event_trigger_table_rewrite_oid _null_ _null_ _null_ _null_ ) +insert ( 4567 pg_event_trigger_table_rewrite_reason 11 10 12 1 0 0 0 f f f t f s r 0 0 23 '' _null_ _null_ _null_ _null_ _null_ pg_event_trigger_table_rewrite_reason _null_ _null_ _null_ _null_ ) +insert ( 4568 pg_event_trigger_ddl_commands 11 10 12 10 100 0 0 f f f t t s r 0 0 2249 '' '{26,26,23,25,25,25,25,16,32}' '{o,o,o,o,o,o,o,o,o}' '{classid, objid, objsubid, command_tag, object_type, schema_name, object_identity, in_extension, command}' _null_ _null_ pg_event_trigger_ddl_commands _null_ _null_ _null_ _null_ ) +insert ( 3970 ordered_set_transition 11 10 12 1 0 0 0 f f f f f i s 2 0 2281 '2281 2276' _null_ _null_ _null_ _null_ _null_ ordered_set_transition _null_ _null_ _null_ _null_ ) +insert ( 3971 ordered_set_transition_multi 11 10 12 1 0 2276 0 f f f f f i s 2 0 2281 '2281 2276' '{2281,2276}' '{i,v}' _null_ _null_ _null_ ordered_set_transition_multi _null_ _null_ _null_ _null_ ) +insert ( 3972 percentile_disc 11 10 12 1 0 0 0 a f f f f i s 2 0 2283 '701 2283' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3973 percentile_disc_final 11 10 12 1 0 0 0 f f f f f i s 3 0 2283 '2281 701 2283' _null_ _null_ _null_ _null_ _null_ percentile_disc_final _null_ _null_ _null_ _null_ ) +insert ( 3974 percentile_cont 11 10 12 1 0 0 0 a f f f f i s 2 0 701 '701 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3975 percentile_cont_float8_final 11 10 12 1 0 0 0 f f f f f i s 2 0 701 '2281 701' _null_ _null_ _null_ _null_ _null_ percentile_cont_float8_final _null_ _null_ _null_ _null_ ) +insert ( 3976 percentile_cont 11 10 12 1 0 0 0 a f f f f i s 2 0 1186 '701 1186' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3977 percentile_cont_interval_final 11 10 12 1 0 0 0 f f f f f i s 2 0 1186 '2281 701' _null_ _null_ _null_ _null_ _null_ percentile_cont_interval_final _null_ _null_ _null_ _null_ ) +insert ( 3978 percentile_disc 11 10 12 1 0 0 0 a f f f f i s 2 0 2277 '1022 2283' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3979 percentile_disc_multi_final 11 10 12 1 0 0 0 f f f f f i s 3 0 2277 '2281 1022 2283' _null_ _null_ _null_ _null_ _null_ percentile_disc_multi_final _null_ _null_ _null_ _null_ ) +insert ( 3980 percentile_cont 11 10 12 1 0 0 0 a f f f f i s 2 0 1022 '1022 701' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3981 percentile_cont_float8_multi_final 11 10 12 1 0 0 0 f f f f f i s 2 0 1022 '2281 1022' _null_ _null_ _null_ _null_ _null_ percentile_cont_float8_multi_final _null_ _null_ _null_ _null_ ) +insert ( 3982 percentile_cont 11 10 12 1 0 0 0 a f f f f i s 2 0 1187 '1022 1186' _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3983 percentile_cont_interval_multi_final 11 10 12 1 0 0 0 f f f f f i s 2 0 1187 '2281 1022' _null_ _null_ _null_ _null_ _null_ percentile_cont_interval_multi_final _null_ _null_ _null_ _null_ ) +insert ( 3984 mode 11 10 12 1 0 0 0 a f f f f i s 1 0 2283 2283 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3985 mode_final 11 10 12 1 0 0 0 f f f f f i s 2 0 2283 '2281 2283' _null_ _null_ _null_ _null_ _null_ mode_final _null_ _null_ _null_ _null_ ) +insert ( 3986 rank 11 10 12 1 0 2276 0 a f f f f i s 1 0 20 2276 '{2276}' '{v}' _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3987 rank_final 11 10 12 1 0 2276 0 f f f f f i s 2 0 20 '2281 2276' '{2281,2276}' '{i,v}' _null_ _null_ _null_ hypothetical_rank_final _null_ _null_ _null_ _null_ ) +insert ( 3988 percent_rank 11 10 12 1 0 2276 0 a f f f f i s 1 0 701 2276 '{2276}' '{v}' _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3989 percent_rank_final 11 10 12 1 0 2276 0 f f f f f i s 2 0 701 '2281 2276' '{2281,2276}' '{i,v}' _null_ _null_ _null_ hypothetical_percent_rank_final _null_ _null_ _null_ _null_ ) +insert ( 3990 cume_dist 11 10 12 1 0 2276 0 a f f f f i s 1 0 701 2276 '{2276}' '{v}' _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3991 cume_dist_final 11 10 12 1 0 2276 0 f f f f f i s 2 0 701 '2281 2276' '{2281,2276}' '{i,v}' _null_ _null_ _null_ hypothetical_cume_dist_final _null_ _null_ _null_ _null_ ) +insert ( 3992 dense_rank 11 10 12 1 0 2276 0 a f f f f i s 1 0 20 2276 '{2276}' '{v}' _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 3993 dense_rank_final 11 10 12 1 0 2276 0 f f f f f i s 2 0 20 '2281 2276' '{2281,2276}' '{i,v}' _null_ _null_ _null_ hypothetical_dense_rank_final _null_ _null_ _null_ _null_ ) +insert ( 3582 binary_upgrade_set_next_pg_type_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_pg_type_oid _null_ _null_ _null_ _null_ ) +insert ( 3584 binary_upgrade_set_next_array_pg_type_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_array_pg_type_oid _null_ _null_ _null_ _null_ ) +insert ( 4390 binary_upgrade_set_next_multirange_pg_type_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_multirange_pg_type_oid _null_ _null_ _null_ _null_ ) +insert ( 4391 binary_upgrade_set_next_multirange_array_pg_type_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_multirange_array_pg_type_oid _null_ _null_ _null_ _null_ ) +insert ( 3586 binary_upgrade_set_next_heap_pg_class_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_heap_pg_class_oid _null_ _null_ _null_ _null_ ) +insert ( 3587 binary_upgrade_set_next_index_pg_class_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_index_pg_class_oid _null_ _null_ _null_ _null_ ) +insert ( 3588 binary_upgrade_set_next_toast_pg_class_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_toast_pg_class_oid _null_ _null_ _null_ _null_ ) +insert ( 3589 binary_upgrade_set_next_pg_enum_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_pg_enum_oid _null_ _null_ _null_ _null_ ) +insert ( 3590 binary_upgrade_set_next_pg_authid_oid 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_pg_authid_oid _null_ _null_ _null_ _null_ ) +insert ( 3591 binary_upgrade_create_empty_extension 11 10 12 1 0 0 0 f f f f f v u 7 0 2278 '25 25 16 25 1028 1009 1009' _null_ _null_ _null_ _null_ _null_ binary_upgrade_create_empty_extension _null_ _null_ _null_ _null_ ) +insert ( 4083 binary_upgrade_set_record_init_privs 11 10 12 1 0 0 0 f f f t f v r 1 0 2278 16 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_record_init_privs _null_ _null_ _null_ _null_ ) +insert ( 4101 binary_upgrade_set_missing_value 11 10 12 1 0 0 0 f f f t f v u 3 0 2278 '26 25 25' _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_missing_value _null_ _null_ _null_ _null_ ) +insert ( 4545 binary_upgrade_set_next_heap_relfilenode 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_heap_relfilenode _null_ _null_ _null_ _null_ ) +insert ( 4546 binary_upgrade_set_next_index_relfilenode 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_index_relfilenode _null_ _null_ _null_ _null_ ) +insert ( 4547 binary_upgrade_set_next_toast_relfilenode 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_toast_relfilenode _null_ _null_ _null_ _null_ ) +insert ( 4548 binary_upgrade_set_next_pg_tablespace_oid 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 26 _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_pg_tablespace_oid _null_ _null_ _null_ _null_ ) +insert ( 4302 koi8r_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ koi8r_to_mic '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4303 mic_to_koi8r 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_koi8r '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4304 iso_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ iso_to_mic '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4305 mic_to_iso 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_iso '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4306 win1251_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win1251_to_mic '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4307 mic_to_win1251 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_win1251 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4308 win866_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win866_to_mic '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4309 mic_to_win866 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_win866 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4310 koi8r_to_win1251 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ koi8r_to_win1251 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4311 win1251_to_koi8r 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win1251_to_koi8r '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4312 koi8r_to_win866 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ koi8r_to_win866 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4313 win866_to_koi8r 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win866_to_koi8r '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4314 win866_to_win1251 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win866_to_win1251 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4315 win1251_to_win866 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win1251_to_win866 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4316 iso_to_koi8r 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ iso_to_koi8r '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4317 koi8r_to_iso 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ koi8r_to_iso '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4318 iso_to_win1251 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ iso_to_win1251 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4319 win1251_to_iso 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win1251_to_iso '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4320 iso_to_win866 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ iso_to_win866 '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4321 win866_to_iso 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win866_to_iso '$libdir/cyrillic_and_mic' _null_ _null_ _null_ ) +insert ( 4322 euc_cn_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_cn_to_mic '$libdir/euc_cn_and_mic' _null_ _null_ _null_ ) +insert ( 4323 mic_to_euc_cn 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_euc_cn '$libdir/euc_cn_and_mic' _null_ _null_ _null_ ) +insert ( 4324 euc_jp_to_sjis 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_jp_to_sjis '$libdir/euc_jp_and_sjis' _null_ _null_ _null_ ) +insert ( 4325 sjis_to_euc_jp 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ sjis_to_euc_jp '$libdir/euc_jp_and_sjis' _null_ _null_ _null_ ) +insert ( 4326 euc_jp_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_jp_to_mic '$libdir/euc_jp_and_sjis' _null_ _null_ _null_ ) +insert ( 4327 sjis_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ sjis_to_mic '$libdir/euc_jp_and_sjis' _null_ _null_ _null_ ) +insert ( 4328 mic_to_euc_jp 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_euc_jp '$libdir/euc_jp_and_sjis' _null_ _null_ _null_ ) +insert ( 4329 mic_to_sjis 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_sjis '$libdir/euc_jp_and_sjis' _null_ _null_ _null_ ) +insert ( 4330 euc_kr_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_kr_to_mic '$libdir/euc_kr_and_mic' _null_ _null_ _null_ ) +insert ( 4331 mic_to_euc_kr 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_euc_kr '$libdir/euc_kr_and_mic' _null_ _null_ _null_ ) +insert ( 4332 euc_tw_to_big5 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_tw_to_big5 '$libdir/euc_tw_and_big5' _null_ _null_ _null_ ) +insert ( 4333 big5_to_euc_tw 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ big5_to_euc_tw '$libdir/euc_tw_and_big5' _null_ _null_ _null_ ) +insert ( 4334 euc_tw_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_tw_to_mic '$libdir/euc_tw_and_big5' _null_ _null_ _null_ ) +insert ( 4335 big5_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ big5_to_mic '$libdir/euc_tw_and_big5' _null_ _null_ _null_ ) +insert ( 4336 mic_to_euc_tw 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_euc_tw '$libdir/euc_tw_and_big5' _null_ _null_ _null_ ) +insert ( 4337 mic_to_big5 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_big5 '$libdir/euc_tw_and_big5' _null_ _null_ _null_ ) +insert ( 4338 latin2_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ latin2_to_mic '$libdir/latin2_and_win1250' _null_ _null_ _null_ ) +insert ( 4339 mic_to_latin2 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_latin2 '$libdir/latin2_and_win1250' _null_ _null_ _null_ ) +insert ( 4340 win1250_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win1250_to_mic '$libdir/latin2_and_win1250' _null_ _null_ _null_ ) +insert ( 4341 mic_to_win1250 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_win1250 '$libdir/latin2_and_win1250' _null_ _null_ _null_ ) +insert ( 4342 latin2_to_win1250 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ latin2_to_win1250 '$libdir/latin2_and_win1250' _null_ _null_ _null_ ) +insert ( 4343 win1250_to_latin2 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win1250_to_latin2 '$libdir/latin2_and_win1250' _null_ _null_ _null_ ) +insert ( 4344 latin1_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ latin1_to_mic '$libdir/latin_and_mic' _null_ _null_ _null_ ) +insert ( 4345 mic_to_latin1 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_latin1 '$libdir/latin_and_mic' _null_ _null_ _null_ ) +insert ( 4346 latin3_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ latin3_to_mic '$libdir/latin_and_mic' _null_ _null_ _null_ ) +insert ( 4347 mic_to_latin3 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_latin3 '$libdir/latin_and_mic' _null_ _null_ _null_ ) +insert ( 4348 latin4_to_mic 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ latin4_to_mic '$libdir/latin_and_mic' _null_ _null_ _null_ ) +insert ( 4349 mic_to_latin4 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ mic_to_latin4 '$libdir/latin_and_mic' _null_ _null_ _null_ ) +insert ( 4352 big5_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ big5_to_utf8 '$libdir/utf8_and_big5' _null_ _null_ _null_ ) +insert ( 4353 utf8_to_big5 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_big5 '$libdir/utf8_and_big5' _null_ _null_ _null_ ) +insert ( 4354 utf8_to_koi8r 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_koi8r '$libdir/utf8_and_cyrillic' _null_ _null_ _null_ ) +insert ( 4355 koi8r_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ koi8r_to_utf8 '$libdir/utf8_and_cyrillic' _null_ _null_ _null_ ) +insert ( 4356 utf8_to_koi8u 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_koi8u '$libdir/utf8_and_cyrillic' _null_ _null_ _null_ ) +insert ( 4357 koi8u_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ koi8u_to_utf8 '$libdir/utf8_and_cyrillic' _null_ _null_ _null_ ) +insert ( 4358 utf8_to_win 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_win '$libdir/utf8_and_win' _null_ _null_ _null_ ) +insert ( 4359 win_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ win_to_utf8 '$libdir/utf8_and_win' _null_ _null_ _null_ ) +insert ( 4360 euc_cn_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_cn_to_utf8 '$libdir/utf8_and_euc_cn' _null_ _null_ _null_ ) +insert ( 4361 utf8_to_euc_cn 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_euc_cn '$libdir/utf8_and_euc_cn' _null_ _null_ _null_ ) +insert ( 4362 euc_jp_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_jp_to_utf8 '$libdir/utf8_and_euc_jp' _null_ _null_ _null_ ) +insert ( 4363 utf8_to_euc_jp 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_euc_jp '$libdir/utf8_and_euc_jp' _null_ _null_ _null_ ) +insert ( 4364 euc_kr_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_kr_to_utf8 '$libdir/utf8_and_euc_kr' _null_ _null_ _null_ ) +insert ( 4365 utf8_to_euc_kr 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_euc_kr '$libdir/utf8_and_euc_kr' _null_ _null_ _null_ ) +insert ( 4366 euc_tw_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_tw_to_utf8 '$libdir/utf8_and_euc_tw' _null_ _null_ _null_ ) +insert ( 4367 utf8_to_euc_tw 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_euc_tw '$libdir/utf8_and_euc_tw' _null_ _null_ _null_ ) +insert ( 4368 gb18030_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ gb18030_to_utf8 '$libdir/utf8_and_gb18030' _null_ _null_ _null_ ) +insert ( 4369 utf8_to_gb18030 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_gb18030 '$libdir/utf8_and_gb18030' _null_ _null_ _null_ ) +insert ( 4370 gbk_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ gbk_to_utf8 '$libdir/utf8_and_gbk' _null_ _null_ _null_ ) +insert ( 4371 utf8_to_gbk 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_gbk '$libdir/utf8_and_gbk' _null_ _null_ _null_ ) +insert ( 4372 utf8_to_iso8859 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_iso8859 '$libdir/utf8_and_iso8859' _null_ _null_ _null_ ) +insert ( 4373 iso8859_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ iso8859_to_utf8 '$libdir/utf8_and_iso8859' _null_ _null_ _null_ ) +insert ( 4374 iso8859_1_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ iso8859_1_to_utf8 '$libdir/utf8_and_iso8859_1' _null_ _null_ _null_ ) +insert ( 4375 utf8_to_iso8859_1 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_iso8859_1 '$libdir/utf8_and_iso8859_1' _null_ _null_ _null_ ) +insert ( 4376 johab_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ johab_to_utf8 '$libdir/utf8_and_johab' _null_ _null_ _null_ ) +insert ( 4377 utf8_to_johab 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_johab '$libdir/utf8_and_johab' _null_ _null_ _null_ ) +insert ( 4378 sjis_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ sjis_to_utf8 '$libdir/utf8_and_sjis' _null_ _null_ _null_ ) +insert ( 4379 utf8_to_sjis 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_sjis '$libdir/utf8_and_sjis' _null_ _null_ _null_ ) +insert ( 4380 uhc_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ uhc_to_utf8 '$libdir/utf8_and_uhc' _null_ _null_ _null_ ) +insert ( 4381 utf8_to_uhc 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_uhc '$libdir/utf8_and_uhc' _null_ _null_ _null_ ) +insert ( 4382 euc_jis_2004_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_jis_2004_to_utf8 '$libdir/utf8_and_euc2004' _null_ _null_ _null_ ) +insert ( 4383 utf8_to_euc_jis_2004 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_euc_jis_2004 '$libdir/utf8_and_euc2004' _null_ _null_ _null_ ) +insert ( 4384 shift_jis_2004_to_utf8 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ shift_jis_2004_to_utf8 '$libdir/utf8_and_sjis2004' _null_ _null_ _null_ ) +insert ( 4385 utf8_to_shift_jis_2004 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ utf8_to_shift_jis_2004 '$libdir/utf8_and_sjis2004' _null_ _null_ _null_ ) +insert ( 4386 euc_jis_2004_to_shift_jis_2004 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ euc_jis_2004_to_shift_jis_2004 '$libdir/euc2004_sjis2004' _null_ _null_ _null_ ) +insert ( 4387 shift_jis_2004_to_euc_jis_2004 11 10 13 1 0 0 0 f f f t f i s 6 0 23 '23 23 2275 2281 23 16' _null_ _null_ _null_ _null_ _null_ shift_jis_2004_to_euc_jis_2004 '$libdir/euc2004_sjis2004' _null_ _null_ _null_ ) +insert ( 5040 matchingsel 11 10 12 1 0 0 0 f f f t f s s 4 0 701 '2281 26 2281 23' _null_ _null_ _null_ _null_ _null_ matchingsel _null_ _null_ _null_ _null_ ) +insert ( 5041 matchingjoinsel 11 10 12 1 0 0 0 f f f t f s s 5 0 701 '2281 26 2281 21 2281' _null_ _null_ _null_ _null_ _null_ matchingjoinsel _null_ _null_ _null_ _null_ ) +insert ( 6003 pg_replication_origin_create 11 10 12 1 0 0 0 f f f t f v u 1 0 26 25 _null_ _null_ _null_ _null_ _null_ pg_replication_origin_create _null_ _null_ _null_ _null_ ) +insert ( 6004 pg_replication_origin_drop 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 25 _null_ _null_ _null_ _null_ _null_ pg_replication_origin_drop _null_ _null_ _null_ _null_ ) +insert ( 6005 pg_replication_origin_oid 11 10 12 1 0 0 0 f f f t f s s 1 0 26 25 _null_ _null_ _null_ _null_ _null_ pg_replication_origin_oid _null_ _null_ _null_ _null_ ) +insert ( 6006 pg_replication_origin_session_setup 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 25 _null_ _null_ _null_ _null_ _null_ pg_replication_origin_session_setup _null_ _null_ _null_ _null_ ) +insert ( 6007 pg_replication_origin_session_reset 11 10 12 1 0 0 0 f f f t f v u 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_replication_origin_session_reset _null_ _null_ _null_ _null_ ) +insert ( 6008 pg_replication_origin_session_is_setup 11 10 12 1 0 0 0 f f f t f v r 0 0 16 '' _null_ _null_ _null_ _null_ _null_ pg_replication_origin_session_is_setup _null_ _null_ _null_ _null_ ) +insert ( 6009 pg_replication_origin_session_progress 11 10 12 1 0 0 0 f f f t f v u 1 0 3220 16 _null_ _null_ _null_ _null_ _null_ pg_replication_origin_session_progress _null_ _null_ _null_ _null_ ) +insert ( 6010 pg_replication_origin_xact_setup 11 10 12 1 0 0 0 f f f t f v r 2 0 2278 '3220 1184' _null_ _null_ _null_ _null_ _null_ pg_replication_origin_xact_setup _null_ _null_ _null_ _null_ ) +insert ( 6011 pg_replication_origin_xact_reset 11 10 12 1 0 0 0 f f f t f v r 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ pg_replication_origin_xact_reset _null_ _null_ _null_ _null_ ) +insert ( 6012 pg_replication_origin_advance 11 10 12 1 0 0 0 f f f t f v u 2 0 2278 '25 3220' _null_ _null_ _null_ _null_ _null_ pg_replication_origin_advance _null_ _null_ _null_ _null_ ) +insert ( 6013 pg_replication_origin_progress 11 10 12 1 0 0 0 f f f t f v u 2 0 3220 '25 16' _null_ _null_ _null_ _null_ _null_ pg_replication_origin_progress _null_ _null_ _null_ _null_ ) +insert ( 6014 pg_show_replication_origin_status 11 10 12 1 100 0 0 f f f f t v r 0 0 2249 '' '{26,25,3220,3220}' '{o,o,o,o}' '{local_id, external_id, remote_lsn, local_lsn}' _null_ _null_ pg_show_replication_origin_status _null_ _null_ _null_ _null_ ) +insert ( 6119 pg_get_publication_tables 11 10 12 1 1000 25 0 f f f t t s s 1 0 2249 1009 '{1009,26,26,22,194}' '{v,o,o,o,o}' '{pubname,pubid,relid,attrs,qual}' _null_ _null_ pg_get_publication_tables _null_ _null_ _null_ _null_ ) +insert ( 6121 pg_relation_is_publishable 11 10 12 1 0 0 0 f f f t f s s 1 0 16 2205 _null_ _null_ _null_ _null_ _null_ pg_relation_is_publishable _null_ _null_ _null_ _null_ ) +insert ( 3298 row_security_active 11 10 12 1 0 0 0 f f f t f s s 1 0 16 26 _null_ _null_ _null_ _null_ _null_ row_security_active _null_ _null_ _null_ _null_ ) +insert ( 3299 row_security_active 11 10 12 1 0 0 0 f f f t f s s 1 0 16 25 _null_ _null_ _null_ _null_ _null_ row_security_active_name _null_ _null_ _null_ _null_ ) +insert ( 3400 pg_config 11 10 12 1 23 0 0 f f f t t s r 0 0 2249 '' '{25,25}' '{o,o}' '{name,setting}' _null_ _null_ pg_config _null_ _null_ _null_ _null_ ) +insert ( 3441 pg_control_system 11 10 12 1 0 0 0 f f f t f v s 0 0 2249 '' '{23,23,20,1184}' '{o,o,o,o}' '{pg_control_version,catalog_version_no,system_identifier,pg_control_last_modified}' _null_ _null_ pg_control_system _null_ _null_ _null_ _null_ ) +insert ( 3442 pg_control_checkpoint 11 10 12 1 0 0 0 f f f t f v s 0 0 2249 '' '{3220,3220,25,23,23,16,25,26,28,28,28,26,28,28,26,28,28,1184}' '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,checkpoint_time}' _null_ _null_ pg_control_checkpoint _null_ _null_ _null_ _null_ ) +insert ( 3443 pg_control_recovery 11 10 12 1 0 0 0 f f f t f v s 0 0 2249 '' '{3220,23,3220,3220,16}' '{o,o,o,o,o}' '{min_recovery_end_lsn,min_recovery_end_timeline,backup_start_lsn,backup_end_lsn,end_of_backup_record_required}' _null_ _null_ pg_control_recovery _null_ _null_ _null_ _null_ ) +insert ( 3444 pg_control_init 11 10 12 1 0 0 0 f f f t f v s 0 0 2249 '' '{23,23,23,23,23,23,23,23,23,16,23}' '{o,o,o,o,o,o,o,o,o,o,o}' '{max_data_alignment,database_block_size,blocks_per_segment,wal_block_size,bytes_per_wal_segment,max_identifier_length,max_index_columns,max_toast_chunk_size,large_object_chunk_size,float8_pass_by_value,data_page_checksum_version}' _null_ _null_ pg_control_init _null_ _null_ _null_ _null_ ) +insert ( 6179 array_subscript_handler 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ array_subscript_handler _null_ _null_ _null_ _null_ ) +insert ( 6180 raw_array_subscript_handler 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ raw_array_subscript_handler _null_ _null_ _null_ _null_ ) +insert ( 6098 jsonb_subscript_handler 11 10 12 1 0 0 0 f f f t f i s 1 0 2281 2281 _null_ _null_ _null_ _null_ _null_ jsonb_subscript_handler _null_ _null_ _null_ _null_ ) +insert ( 3445 pg_import_system_collations 11 10 12 100 0 0 0 f f f t f v u 1 0 23 4089 _null_ _null_ _null_ _null_ _null_ pg_import_system_collations _null_ _null_ _null_ _null_ ) +insert ( 3448 pg_collation_actual_version 11 10 12 100 0 0 0 f f f t f v s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_collation_actual_version _null_ _null_ _null_ _null_ ) +insert ( 6249 pg_database_collation_actual_version 11 10 12 100 0 0 0 f f f t f v s 1 0 25 26 _null_ _null_ _null_ _null_ _null_ pg_database_collation_actual_version _null_ _null_ _null_ _null_ ) +insert ( 3353 pg_ls_logdir 11 10 12 10 20 0 0 f f f t t v s 0 0 2249 '' '{25,20,1184}' '{o,o,o}' '{name,size,modification}' _null_ _null_ pg_ls_logdir _null_ _null_ _null_ _null_ ) +insert ( 3354 pg_ls_waldir 11 10 12 10 20 0 0 f f f t t v s 0 0 2249 '' '{25,20,1184}' '{o,o,o}' '{name,size,modification}' _null_ _null_ pg_ls_waldir _null_ _null_ _null_ _null_ ) +insert ( 5031 pg_ls_archive_statusdir 11 10 12 10 20 0 0 f f f t t v s 0 0 2249 '' '{25,20,1184}' '{o,o,o}' '{name,size,modification}' _null_ _null_ pg_ls_archive_statusdir _null_ _null_ _null_ _null_ ) +insert ( 5029 pg_ls_tmpdir 11 10 12 10 20 0 0 f f f t t v s 0 0 2249 '' '{25,20,1184}' '{o,o,o}' '{name,size,modification}' _null_ _null_ pg_ls_tmpdir_noargs _null_ _null_ _null_ _null_ ) +insert ( 5030 pg_ls_tmpdir 11 10 12 10 20 0 0 f f f t t v s 1 0 2249 26 '{26,25,20,1184}' '{i,o,o,o}' '{tablespace,name,size,modification}' _null_ _null_ pg_ls_tmpdir_1arg _null_ _null_ _null_ _null_ ) +insert ( 6270 pg_ls_logicalsnapdir 11 10 12 10 20 0 0 f f f t t v s 0 0 2249 '' '{25,20,1184}' '{o,o,o}' '{name,size,modification}' _null_ _null_ pg_ls_logicalsnapdir _null_ _null_ _null_ _null_ ) +insert ( 6271 pg_ls_logicalmapdir 11 10 12 10 20 0 0 f f f t t v s 0 0 2249 '' '{25,20,1184}' '{o,o,o}' '{name,size,modification}' _null_ _null_ pg_ls_logicalmapdir _null_ _null_ _null_ _null_ ) +insert ( 6272 pg_ls_replslotdir 11 10 12 10 20 0 0 f f f t t v s 1 0 2249 25 '{25,25,20,1184}' '{i,o,o,o}' '{slot_name,name,size,modification}' _null_ _null_ pg_ls_replslotdir _null_ _null_ _null_ _null_ ) +insert ( 5028 satisfies_hash_partition 11 10 12 1 0 2276 0 f f f f f i s 4 0 16 '26 23 23 2276' _null_ '{i,i,i,v}' _null_ _null_ _null_ satisfies_hash_partition _null_ _null_ _null_ _null_ ) +insert ( 3423 pg_partition_tree 11 10 12 1 1000 0 0 f f f t t v s 1 0 2249 2205 '{2205,2205,2205,16,23}' '{i,o,o,o,o}' '{rootrelid,relid,parentrelid,isleaf,level}' _null_ _null_ pg_partition_tree _null_ _null_ _null_ _null_ ) +insert ( 3425 pg_partition_ancestors 11 10 12 1 10 0 0 f f f t t v s 1 0 2205 2205 '{2205,2205}' '{i,o}' '{partitionid,relid}' _null_ _null_ pg_partition_ancestors _null_ _null_ _null_ _null_ ) +insert ( 3424 pg_partition_root 11 10 12 1 0 0 0 f f f t f i s 1 0 2205 2205 _null_ _null_ _null_ _null_ _null_ pg_partition_root _null_ _null_ _null_ _null_ ) +insert ( 4350 normalize 11 10 12 1 0 0 0 f f f t f i s 2 0 25 '25 25' _null_ _null_ _null_ _null_ _null_ unicode_normalize_func _null_ _null_ _null_ _null_ ) +insert ( 4351 is_normalized 11 10 12 1 0 0 0 f f f t f i s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ unicode_is_normalized _null_ _null_ _null_ _null_ ) +insert ( 6198 unistr 11 10 12 1 0 0 0 f f f t f i s 1 0 25 25 _null_ _null_ _null_ _null_ _null_ unistr _null_ _null_ _null_ _null_ ) +insert ( 4596 brin_bloom_summary_in 11 10 12 1 0 0 0 f f f t f i s 1 0 4600 2275 _null_ _null_ _null_ _null_ _null_ brin_bloom_summary_in _null_ _null_ _null_ _null_ ) +insert ( 4597 brin_bloom_summary_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 4600 _null_ _null_ _null_ _null_ _null_ brin_bloom_summary_out _null_ _null_ _null_ _null_ ) +insert ( 4598 brin_bloom_summary_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 4600 2281 _null_ _null_ _null_ _null_ _null_ brin_bloom_summary_recv _null_ _null_ _null_ _null_ ) +insert ( 4599 brin_bloom_summary_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 4600 _null_ _null_ _null_ _null_ _null_ brin_bloom_summary_send _null_ _null_ _null_ _null_ ) +insert ( 4638 brin_minmax_multi_summary_in 11 10 12 1 0 0 0 f f f t f i s 1 0 4601 2275 _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_summary_in _null_ _null_ _null_ _null_ ) +insert ( 4639 brin_minmax_multi_summary_out 11 10 12 1 0 0 0 f f f t f i s 1 0 2275 4601 _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_summary_out _null_ _null_ _null_ _null_ ) +insert ( 4640 brin_minmax_multi_summary_recv 11 10 12 1 0 0 0 f f f t f s s 1 0 4601 2281 _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_summary_recv _null_ _null_ _null_ _null_ ) +insert ( 4641 brin_minmax_multi_summary_send 11 10 12 1 0 0 0 f f f t f s s 1 0 17 4601 _null_ _null_ _null_ _null_ _null_ brin_minmax_multi_summary_send _null_ _null_ _null_ _null_ ) +insert ( 6291 any_value 11 10 12 1 0 0 0 a f f f f i s 1 0 2283 2283 _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ _null_ ) +insert ( 6292 any_value_transfn 11 10 12 1 0 0 0 f f f t f i s 2 0 2283 '2283 2283' _null_ _null_ _null_ _null_ _null_ any_value_transfn _null_ _null_ _null_ _null_ ) +insert ( 8898 cluster_get_wait_events 11 10 12 1 46 0 0 f f f t t s r 0 0 2249 '' '{25,25}' '{o,o}' '{type,name}' _null_ _null_ cluster_get_wait_events _null_ _null_ _null_ _null_ ) +insert ( 8899 cluster_get_gcluster_wait_events 11 10 12 1 46 0 0 f f f t t s r 0 0 2249 '' '{23,25,25}' '{o,o,o}' '{node_id,type,name}' _null_ _null_ cluster_get_gcluster_wait_events _null_ _null_ _null_ _null_ ) +insert ( 8900 cluster_get_nodes 11 10 12 1 16 0 0 f f f t t s r 0 0 2249 '' '{23,25,25,25,25,25,16}' '{o,o,o,o,o,o,o}' '{node_id,hostname,interconnect_addr,public_addr,role,region,is_self}' _null_ _null_ cluster_get_nodes _null_ _null_ _null_ _null_ ) +insert ( 8901 cluster_ic_mock_inject 11 10 12 1 0 0 0 f f f t f v u 2 0 2278 '23 17' _null_ _null_ '{from_node,payload}' _null_ _null_ cluster_ic_mock_inject _null_ _null_ _null_ _null_ ) +insert ( 8902 cluster_ic_mock_drain_outbound 11 10 12 1 8 0 0 f f f t t v u 1 0 2249 23 '{23,23,17}' '{i,o,o}' '{target_node,sender,payload}' _null_ _null_ cluster_ic_mock_drain_outbound _null_ _null_ _null_ _null_ ) +insert ( 8903 cluster_ic_mock_clear_all 11 10 12 1 0 0 0 f f f t f v u 0 0 2278 '' _null_ _null_ _null_ _null_ _null_ cluster_ic_mock_clear_all _null_ _null_ _null_ _null_ ) +insert ( 8904 cluster_ic_mock_recv_test 11 10 12 1 1 0 0 f f f t t v u 0 0 2249 '' '{23,17}' '{o,o}' '{sender,payload}' _null_ _null_ cluster_ic_mock_recv_test _null_ _null_ _null_ _null_ ) +insert ( 8905 cluster_inject_fault 11 10 12 1 0 0 0 f f f t f v u 3 0 16 '25 25 20' _null_ _null_ '{name,fault_type,param}' _null_ _null_ cluster_inject_fault _null_ _null_ _null_ _null_ ) +insert ( 8906 cluster_get_injection_state 11 10 12 1 6 0 0 f f f t t v r 0 0 2249 '' '{25,25,20,20}' '{o,o,o,o}' '{name,fault_type,param,hits}' _null_ _null_ cluster_get_injection_state _null_ _null_ _null_ _null_ ) +insert ( 8907 cluster_get_stat_nodes 11 10 12 1 1 0 0 f f f t t s r 0 0 2249 '' '{23,25,25,1184,25,25}' '{o,o,o,o,o,o}' '{node_id,role,state,startup_time,pgrac_version,pg_version}' _null_ _null_ cluster_get_stat_nodes _null_ _null_ _null_ _null_ ) +insert ( 8908 cluster_get_pgstat_counters 11 10 12 1 8 0 0 f f f t t v r 0 0 2249 '' '{25,20}' '{o,o}' '{name,value}' _null_ _null_ cluster_get_pgstat_counters _null_ _null_ _null_ _null_ ) +insert ( 8909 cluster_dump_state 11 10 12 1 32 0 0 f f f t t s r 0 0 2249 '' '{25,25,25}' '{o,o,o}' '{category,key,value}' _null_ _null_ cluster_dump_state _null_ _null_ _null_ _null_ ) +insert ( 8910 cluster_shmem_dump_regions 11 10 12 1 4 0 0 f f f t t s r 0 0 2249 '' '{25,20,23,25}' '{o,o,o,o}' '{name,size_bytes,lwlock_count,owner_subsys}' _null_ _null_ cluster_shmem_dump_regions _null_ _null_ _null_ _null_ ) +insert ( 8911 cluster_scn_advance 11 10 12 1 0 0 0 f f f t f v u 0 0 20 '' _null_ _null_ _null_ _null_ _null_ cluster_scn_advance_sql _null_ _null_ _null_ _null_ ) +insert ( 8912 cluster_scn_current 11 10 12 1 0 0 0 f f f t f v r 0 0 20 '' _null_ _null_ _null_ _null_ _null_ cluster_scn_current_sql _null_ _null_ _null_ _null_ ) +insert ( 8914 cluster_get_ic_peers 11 10 12 1 8 0 0 f f f t t v r 0 0 2249 '' '{23,25,25,1184,1184,1184,1184,1184,20,20,20,20,20,20,23,23,23,25,25,20,23,20,20}' '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}' '{node_id,state,interconnect_addr,last_connect_at,last_send_at,last_recv_at,last_heartbeat_sent_at,last_heartbeat_recv_at,heartbeat_send_count,heartbeat_recv_count,msg_send_count,msg_recv_count,bytes_send,bytes_recv,reconnect_count,connect_error_count,last_errno,last_error_code,last_error,stale_epoch_drop_count,chunk_reassembly_active,chunk_reassembly_timeout_count,lamport_observe_advance_count}' _null_ _null_ cluster_get_ic_peers _null_ _null_ _null_ _null_ ) +insert ( 8915 cluster_get_ic_msg_types 11 10 12 1 10 0 0 f f f t t s r 0 0 2249 '' '{23,25,20,16,16}' '{o,o,o,o,o}' '{msg_type,name,allowed_producer_mask,broadcast_ok,handler_present}' _null_ _null_ cluster_get_ic_msg_types _null_ _null_ _null_ _null_ ) +insert ( 8913 cluster_scn_observe 11 10 12 1 0 0 0 f f f t f v u 1 0 2278 20 _null_ _null_ '{remote_scn}' _null_ _null_ cluster_scn_observe_sql _null_ _null_ _null_ _null_ ) +insert ( 8916 cluster_get_cssd_peers 11 10 12 1 8 0 0 f f f t t v r 0 0 2249 '' '{23,25,1184,1184,20,20,1184,1184,20}' '{o,o,o,o,o,o,o,o,o}' '{node_id,state,last_heartbeat_send_at,last_heartbeat_recv_at,heartbeat_send_count,heartbeat_recv_count,suspected_since,dead_since,suspected_transitions}' _null_ _null_ cluster_get_cssd_peers _null_ _null_ _null_ _null_ ) +insert ( 8917 cluster_get_quorum_state 11 10 12 1 1 0 0 f f f t t v r 0 0 2249 '' '{16,23,23,23,20,1184,25}' '{o,o,o,o,o,o,o}' '{in_quorum,quorum_size,disks_ok,disks_total,current_epoch_at_boot,last_quorum_loss_at,collision_state}' _null_ _null_ cluster_get_quorum_state _null_ _null_ _null_ _null_ ) +insert ( 8918 cluster_get_voting_disks 11 10 12 1 3 0 0 f f f t t v r 0 0 2249 '' '{25,25,1184,1184,20,20,20}' '{o,o,o,o,o,o,o}' '{path,state,last_read_at,last_write_at,read_count,write_count,io_error_count}' _null_ _null_ cluster_get_voting_disks _null_ _null_ _null_ _null_ ) +insert ( 8919 cluster_get_fence_state 11 10 12 1 1 0 0 f f f t t v r 0 0 2249 '' '{1184,1184,16,23,20,20,20,20}' '{o,o,o,o,o,o,o,o}' '{last_freeze_at,last_thaw_at,self_fence_pending,self_fence_grace_remaining_ms,freeze_broadcast_count,thaw_broadcast_count,self_fence_initiated_count,freeze_signal_received_count}' _null_ _null_ cluster_get_fence_state _null_ _null_ _null_ _null_ ) +insert ( 8920 cluster_get_reconfig_state 11 10 12 1 1 0 0 f f f t t v r 0 0 2249 '' '{20,23,20,20,25,1184,25,20,20}' '{o,o,o,o,o,o,o,o,o}' '{event_id,coordinator_node_id,old_epoch,new_epoch,dead_bitmap,applied_at,observer_role,event_seq,cssd_dead_generation}' _null_ _null_ cluster_get_reconfig_state _null_ _null_ _null_ _null_ ) +insert ( 8921 cluster_get_grd_shards 11 10 12 1 4096 0 0 f f f t t s r 0 0 2249 '' '{23,23,16}' '{o,o,o}' '{shard_id,master_node_id,is_local}' _null_ _null_ cluster_get_grd_shards _null_ _null_ _null_ _null_ ) +insert ( 8922 cluster_get_grd_entries 11 10 12 1 1024 0 0 f f f t t s r 0 0 2249 '' '{23,23,23,23,23,23,23,23,23,23,23}' '{o,o,o,o,o,o,o,o,o,o,o}' '{shard_id,field1,field2,field3,field4,type,lockmethodid,ngranted,nwaiters,nconverts,state_flags}' _null_ _null_ cluster_get_grd_entries _null_ _null_ _null_ _null_ ) +insert ( 8923 cluster_get_lmd_state 11 10 12 1 1 0 0 f f f t t s r 0 0 2249 '' '{23,25,25,1184,1184,20,20,20,20,20}' '{o,o,o,o,o,o,o,o,o,o}' '{pid,state,reason,started_at,ready_at,started_count,edge_submission_count,wake_count,idle_count,error_count}' _null_ _null_ cluster_get_lmd_state _null_ _null_ _null_ _null_ ) +insert ( 8948 pg_cluster_ges_mode_matrix 11 10 12 1 64 0 0 f f f t t s s 0 0 2249 '' '{25,25,16,25,25}' '{o,o,o,o,o}' '{held,wanted,compatible,held_dlm,wanted_dlm}' _null_ _null_ pg_cluster_ges_mode_matrix _null_ _null_ _null_ _null_ ) +insert ( 8949 cluster_ges_mode_compat 11 10 12 1 0 0 0 f f f t f s s 2 0 16 '25 25' _null_ _null_ _null_ _null_ _null_ cluster_ges_mode_compat _null_ _null_ _null_ _null_ ) +insert ( 8950 cluster_ges_mode_matches_pg 11 10 12 1 0 0 0 f f f t f s s 0 0 16 '' _null_ _null_ _null_ _null_ _null_ cluster_ges_mode_matches_pg _null_ _null_ _null_ _null_ ) +insert ( 8924 pg_cluster_lmd_inject_wait_edge 11 10 12 1 0 0 0 f f f t f v r 6 0 16 '23 23 20 23 23 20' _null_ _null_ '{waiter_node,waiter_procno,waiter_request_id,blocker_node,blocker_procno,blocker_request_id}' _null_ _null_ pg_cluster_lmd_inject_wait_edge _null_ _null_ _null_ _null_ ) +insert ( 8925 cluster_test_inject_visibility_tt_ref 11 10 12 1 0 0 0 f f f t f v u 7 0 16 '28 23 23 23 23 20 16' _null_ _null_ '{xid,origin_node_id,undo_segment_id,tt_slot_id,cluster_epoch,commit_scn,is_lock_only}' _null_ _null_ cluster_test_inject_visibility_tt_ref _null_ _null_ _null_ _null_ ) +insert ( 8926 cluster_test_clear_visibility_injects 11 10 12 1 0 0 0 f f f t f v u 0 0 23 '' _null_ _null_ _null_ _null_ _null_ cluster_test_clear_visibility_injects _null_ _null_ _null_ _null_ ) +insert ( 8927 cluster_test_inject_subtrans_subcommitted 11 10 12 1 0 0 0 f f f t f v u 6 0 16 '28 28 23 23 23 23' _null_ _null_ '{child_xid,parent_xid,origin_node_id,undo_segment_id,tt_slot_id,cluster_epoch}' _null_ _null_ cluster_test_inject_subtrans_subcommitted _null_ _null_ _null_ _null_ ) +insert ( 8928 cluster_undo_get_record 11 10 12 1 0 0 0 f f f t f s r 1 0 17 17 _null_ _null_ '{uba}' _null_ _null_ cluster_undo_get_record_srf _null_ _null_ _null_ _null_ ) +insert ( 8929 cluster_undo_test_force_segment_end 11 10 12 1 0 0 0 f f f t f v u 0 0 16 '' _null_ _null_ _null_ _null_ _null_ cluster_undo_test_force_segment_end_srf _null_ _null_ _null_ _null_ ) +insert ( 8930 cluster_cr_test_construct 11 10 12 1 0 0 0 f f f t f v u 4 0 16 '2205 23 23 20' _null_ _null_ '{rel,blockno,itl_idx,read_scn}' _null_ _null_ cluster_cr_test_construct _null_ _null_ _null_ _null_ ) +insert ( 8931 cluster_cr_test_image 11 10 12 1 100 0 0 f f f t t v u 3 0 2249 '2205 23 20' _null_ _null_ '{rel,blockno,read_scn}' _null_ _null_ cluster_cr_test_image _null_ _null_ _null_ _null_ ) +insert ( 8932 cluster_block_apply_redo_test 11 10 12 1 0 0 0 f f f t f v u 5 0 17 '2205 23 20 3220 3220' _null_ _null_ '{rel,forknum,blocknum,start_lsn,end_lsn}' _null_ _null_ cluster_block_apply_redo_test _null_ _null_ _null_ _null_ ) +insert ( 8934 cluster_thread_apply_redo_test 11 10 12 1 0 0 0 f f f f f v u 6 0 17 '2205 23 20 3220 3220 17' _null_ _null_ '{rel,forknum,blocknum,start_lsn,end_lsn,base_page}' _null_ _null_ cluster_thread_apply_redo_test _null_ _null_ _null_ _null_ ) +insert ( 8935 cluster_thread_replay_test 11 10 12 1 0 0 0 f f f f f v u 6 0 25 '3220 3220 2205 23 20 17' _null_ _null_ '{scan_lower,scan_upper,seed_rel,seed_forknum,seed_blocknum,seed_page}' _null_ _null_ cluster_thread_replay_test _null_ _null_ _null_ _null_ ) +insert ( 8936 cluster_thread_drive_test 11 10 12 1 0 0 0 f f f f f v u 3 0 25 '23 3220 3220' _null_ _null_ '{dead_tid,scan_lower,scan_upper}' _null_ _null_ cluster_thread_drive_test _null_ _null_ _null_ _null_ ) +insert ( 8937 cluster_thread_replay_one_test 11 10 12 1 0 0 0 f f f f f v u 3 0 25 '23 3220 3220' _null_ _null_ '{dead_tid,scan_lower,scan_upper}' _null_ _null_ cluster_thread_replay_one_test _null_ _null_ _null_ _null_ ) +insert ( 8938 cluster_thread_replay_one_auto_test 11 10 12 1 0 0 0 f f f f f v u 1 0 25 23 _null_ _null_ '{dead_tid}' _null_ _null_ cluster_thread_replay_one_auto_test _null_ _null_ _null_ _null_ ) +insert ( 8939 cluster_thread_local_complete_test 11 10 12 1 0 0 0 f f f f f v u 2 0 16 '23 3220' _null_ _null_ '{dead_tid,required_lsn}' _null_ _null_ cluster_thread_local_complete_test _null_ _null_ _null_ _null_ ) +insert ( 8940 cluster_thread_gate_unfreeze_test 11 10 12 1 0 0 0 f f f f f v u 1 0 16 23 _null_ _null_ '{dead_tid}' _null_ _null_ cluster_thread_gate_unfreeze_test _null_ _null_ _null_ _null_ ) +insert ( 8941 cluster_thread_validated_end_test 11 10 12 1 0 0 0 f f f f f v u 3 0 25 '23 3220 3220' _null_ _null_ '{dead_tid,scan_lower,validated_min}' _null_ _null_ cluster_thread_validated_end_test _null_ _null_ _null_ _null_ ) +insert ( 8942 cluster_thread_replay_slot_test 11 10 12 1 0 0 0 f f f f f v u 1 0 25 23 _null_ _null_ '{dead_tid}' _null_ _null_ cluster_thread_replay_slot_test _null_ _null_ _null_ _null_ ) +insert ( 8943 cluster_thread_recovery_worker_run_test 11 10 12 1 0 0 0 f f f f f v u 3 0 25 '23 20 16' _null_ _null_ '{dead_tid,epoch_offset,do_mark}' _null_ _null_ cluster_thread_recovery_worker_run_test _null_ _null_ _null_ _null_ ) +insert ( 8944 cluster_thread_recovery_launch_test 11 10 12 1 0 0 0 f f f f f v u 1 0 25 23 _null_ _null_ '{dead_node}' _null_ _null_ cluster_thread_recovery_launch_test _null_ _null_ _null_ _null_ ) +insert ( 8945 cluster_thread_replay_slot_state_test 11 10 12 1 0 0 0 f f f f f v u 1 0 23 23 _null_ _null_ '{dead_tid}' _null_ _null_ cluster_thread_replay_slot_state_test _null_ _null_ _null_ _null_ ) +insert ( 8946 cluster_reconfig_inject_dead_node_test 11 10 12 1 0 0 0 f f f f f v u 1 0 16 23 _null_ _null_ '{dead_node}' _null_ _null_ cluster_reconfig_inject_dead_node_test _null_ _null_ _null_ _null_ ) +insert ( 8947 cluster_thread_capability_gate_test 11 10 12 1 0 0 0 f f f f f v u 1 0 25 23 _null_ _null_ '{scope}' _null_ _null_ cluster_thread_capability_gate_test _null_ _null_ _null_ _null_ ) +insert ( 8933 cluster_block_recovery_reconstruct_test 11 10 12 1 0 0 0 f f f t f v u 5 0 17 '2205 23 20 3220 3220' _null_ _null_ '{rel,forknum,blocknum,scan_lower,scan_upper}' _null_ _null_ cluster_block_recovery_reconstruct_test _null_ _null_ _null_ _null_ ) +close pg_proc +create pg_type 1247 bootstrap rowtype_oid 71 + ( + oid = oid , + typname = name , + typnamespace = oid , + typowner = oid , + typlen = int2 , + typbyval = bool , + typtype = char , + typcategory = char , + typispreferred = bool , + typisdefined = bool , + typdelim = char , + typrelid = oid , + typsubscript = regproc , + typelem = oid , + typarray = oid , + typinput = regproc , + typoutput = regproc , + typreceive = regproc , + typsend = regproc , + typmodin = regproc , + typmodout = regproc , + typanalyze = regproc , + typalign = char , + typstorage = char , + typnotnull = bool , + typbasetype = oid , + typtypmod = int4 , + typndims = int4 , + typcollation = oid , + typdefaultbin = pg_node_tree , + typdefault = text , + typacl = _aclitem + ) +insert ( 16 bool 11 10 1 t b B t t ',' 0 - 0 1000 1242 1243 2436 2437 - - - c p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 17 bytea 11 10 -1 f b U f t ',' 0 - 0 1001 1244 31 2412 2413 - - - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 18 char 11 10 1 t b Z f t ',' 0 - 0 1002 1245 33 2434 2435 - - - c p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 19 name 11 10 NAMEDATALEN f b S f t ',' 0 6180 18 1003 34 35 2422 2423 - - - c p f 0 -1 0 950 _null_ _null_ _null_ ) +insert ( 20 int8 11 10 8 FLOAT8PASSBYVAL b N f t ',' 0 - 0 1016 460 461 2408 2409 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 21 int2 11 10 2 t b N f t ',' 0 - 0 1005 38 39 2404 2405 - - - s p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 22 int2vector 11 10 -1 f b A f t ',' 0 6179 21 1006 40 41 2410 2411 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 23 int4 11 10 4 t b N f t ',' 0 - 0 1007 42 43 2406 2407 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 24 regproc 11 10 4 t b N f t ',' 0 - 0 1008 44 45 2444 2445 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 25 text 11 10 -1 f b S t t ',' 0 - 0 1009 46 47 2414 2415 - - - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 26 oid 11 10 4 t b N t t ',' 0 - 0 1028 1798 1799 2418 2419 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 27 tid 11 10 6 f b U f t ',' 0 - 0 1010 48 49 2438 2439 - - - s p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 28 xid 11 10 4 t b U f t ',' 0 - 0 1011 50 51 2440 2441 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 29 cid 11 10 4 t b U f t ',' 0 - 0 1012 52 53 2442 2443 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 30 oidvector 11 10 -1 f b A f t ',' 0 6179 26 1013 54 55 2420 2421 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 71 pg_type 11 10 -1 f c C f t ',' 1247 - 0 210 2290 2291 2402 2403 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 75 pg_attribute 11 10 -1 f c C f t ',' 1249 - 0 270 2290 2291 2402 2403 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 81 pg_proc 11 10 -1 f c C f t ',' 1255 - 0 272 2290 2291 2402 2403 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 83 pg_class 11 10 -1 f c C f t ',' 1259 - 0 273 2290 2291 2402 2403 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 114 json 11 10 -1 f b U f t ',' 0 - 0 199 321 322 323 324 - - - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 142 xml 11 10 -1 f b U f t ',' 0 - 0 143 2893 2894 2898 2899 - - - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 194 pg_node_tree 11 10 -1 f b Z f t ',' 0 - 0 0 195 196 197 198 - - - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 3361 pg_ndistinct 11 10 -1 f b Z f t ',' 0 - 0 0 3355 3356 3357 3358 - - - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 3402 pg_dependencies 11 10 -1 f b Z f t ',' 0 - 0 0 3404 3405 3406 3407 - - - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 5017 pg_mcv_list 11 10 -1 f b Z f t ',' 0 - 0 0 5018 5019 5020 5021 - - - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 32 pg_ddl_command 11 10 SIZEOF_POINTER t p P f t ',' 0 - 0 0 86 87 88 90 - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 5069 xid8 11 10 8 FLOAT8PASSBYVAL b U f t ',' 0 - 0 271 5070 5081 5082 5083 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 600 point 11 10 16 f b G f t ',' 0 6180 701 1017 117 118 2428 2429 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 601 lseg 11 10 32 f b G f t ',' 0 6180 600 1018 119 120 2480 2481 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 602 path 11 10 -1 f b G f t ',' 0 - 0 1019 121 122 2482 2483 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 603 box 11 10 32 f b G f t ';' 0 6180 600 1020 123 124 2484 2485 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 604 polygon 11 10 -1 f b G f t ',' 0 - 0 1027 347 348 2486 2487 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 628 line 11 10 24 f b G f t ',' 0 6180 701 629 1490 1491 2488 2489 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 700 float4 11 10 4 t b N f t ',' 0 - 0 1021 200 201 2424 2425 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 701 float8 11 10 8 FLOAT8PASSBYVAL b N t t ',' 0 - 0 1022 214 215 2426 2427 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 705 unknown 11 10 -2 f p X f t ',' 0 - 0 0 109 110 2416 2417 - - - c p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 718 circle 11 10 24 f b G f t ',' 0 - 0 719 1450 1451 2490 2491 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 790 money 11 10 8 FLOAT8PASSBYVAL b N f t ',' 0 - 0 791 886 887 2492 2493 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 829 macaddr 11 10 6 f b U f t ',' 0 - 0 1040 436 437 2494 2495 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 869 inet 11 10 -1 f b I t t ',' 0 - 0 1041 910 911 2496 2497 - - - i m f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 650 cidr 11 10 -1 f b I f t ',' 0 - 0 651 1267 1427 2498 2499 - - - i m f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 774 macaddr8 11 10 8 f b U f t ',' 0 - 0 775 4110 4111 3446 3447 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1033 aclitem 11 10 16 f b U f t ',' 0 - 0 1034 1031 1032 - - - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1042 bpchar 11 10 -1 f b S f t ',' 0 - 0 1014 1044 1045 2430 2431 2913 2914 - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 1043 varchar 11 10 -1 f b S f t ',' 0 - 0 1015 1046 1047 2432 2433 2915 2916 - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 1082 date 11 10 4 t b D f t ',' 0 - 0 1182 1084 1085 2468 2469 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1083 time 11 10 8 FLOAT8PASSBYVAL b D f t ',' 0 - 0 1183 1143 1144 2470 2471 2909 2910 - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1114 timestamp 11 10 8 FLOAT8PASSBYVAL b D f t ',' 0 - 0 1115 1312 1313 2474 2475 2905 2906 - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1184 timestamptz 11 10 8 FLOAT8PASSBYVAL b D t t ',' 0 - 0 1185 1150 1151 2476 2477 2907 2908 - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1186 interval 11 10 16 f b T t t ',' 0 - 0 1187 1160 1161 2478 2479 2903 2904 - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1266 timetz 11 10 12 f b D f t ',' 0 - 0 1270 1350 1351 2472 2473 2911 2912 - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1560 bit 11 10 -1 f b V f t ',' 0 - 0 1561 1564 1565 2456 2457 2919 2920 - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1562 varbit 11 10 -1 f b V t t ',' 0 - 0 1563 1579 1580 2458 2459 2902 2921 - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1700 numeric 11 10 -1 f b N f t ',' 0 - 0 1231 1701 1702 2460 2461 2917 2918 - i m f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1790 refcursor 11 10 -1 f b U f t ',' 0 - 0 2201 46 47 2414 2415 - - - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2202 regprocedure 11 10 4 t b N f t ',' 0 - 0 2207 2212 2213 2446 2447 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2203 regoper 11 10 4 t b N f t ',' 0 - 0 2208 2214 2215 2448 2449 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2204 regoperator 11 10 4 t b N f t ',' 0 - 0 2209 2216 2217 2450 2451 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2205 regclass 11 10 4 t b N f t ',' 0 - 0 2210 2218 2219 2452 2453 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4191 regcollation 11 10 4 t b N f t ',' 0 - 0 4192 4193 4194 4196 4197 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2206 regtype 11 10 4 t b N f t ',' 0 - 0 2211 2220 2221 2454 2455 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4096 regrole 11 10 4 t b N f t ',' 0 - 0 4097 4098 4092 4094 4095 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4089 regnamespace 11 10 4 t b N f t ',' 0 - 0 4090 4084 4085 4087 4088 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2950 uuid 11 10 16 f b U f t ',' 0 - 0 2951 2952 2953 2961 2962 - - - c p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3220 pg_lsn 11 10 8 FLOAT8PASSBYVAL b U f t ',' 0 - 0 3221 3229 3230 3238 3239 - - - d p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3614 tsvector 11 10 -1 f b U f t ',' 0 - 0 3643 3610 3611 3639 3638 - - 3688 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3642 gtsvector 11 10 -1 f b U f t ',' 0 - 0 3644 3646 3647 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3615 tsquery 11 10 -1 f b U f t ',' 0 - 0 3645 3612 3613 3641 3640 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3734 regconfig 11 10 4 t b N f t ',' 0 - 0 3735 3736 3737 3738 3739 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3769 regdictionary 11 10 4 t b N f t ',' 0 - 0 3770 3771 3772 3773 3774 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3802 jsonb 11 10 -1 f b U f t ',' 0 6098 0 3807 3806 3804 3805 3803 - - - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4072 jsonpath 11 10 -1 f b U f t ',' 0 - 0 4073 4001 4003 4002 4004 - - - i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2970 txid_snapshot 11 10 -1 f b U f t ',' 0 - 0 2949 2939 2940 2941 2942 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 5038 pg_snapshot 11 10 -1 f b U f t ',' 0 - 0 5039 5055 5056 5057 5058 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3904 int4range 11 10 -1 f r R f t ',' 0 - 0 3905 3834 3835 3836 3837 - - 3916 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3906 numrange 11 10 -1 f r R f t ',' 0 - 0 3907 3834 3835 3836 3837 - - 3916 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3908 tsrange 11 10 -1 f r R f t ',' 0 - 0 3909 3834 3835 3836 3837 - - 3916 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3910 tstzrange 11 10 -1 f r R f t ',' 0 - 0 3911 3834 3835 3836 3837 - - 3916 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3912 daterange 11 10 -1 f r R f t ',' 0 - 0 3913 3834 3835 3836 3837 - - 3916 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3926 int8range 11 10 -1 f r R f t ',' 0 - 0 3927 3834 3835 3836 3837 - - 3916 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4451 int4multirange 11 10 -1 f m R f t ',' 0 - 0 6150 4231 4232 4233 4234 - - 4242 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4532 nummultirange 11 10 -1 f m R f t ',' 0 - 0 6151 4231 4232 4233 4234 - - 4242 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4533 tsmultirange 11 10 -1 f m R f t ',' 0 - 0 6152 4231 4232 4233 4234 - - 4242 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4534 tstzmultirange 11 10 -1 f m R f t ',' 0 - 0 6153 4231 4232 4233 4234 - - 4242 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4535 datemultirange 11 10 -1 f m R f t ',' 0 - 0 6155 4231 4232 4233 4234 - - 4242 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4536 int8multirange 11 10 -1 f m R f t ',' 0 - 0 6157 4231 4232 4233 4234 - - 4242 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2249 record 11 10 -1 f p P f t ',' 0 - 0 2287 2290 2291 2402 2403 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2287 _record 11 10 -1 f p P f t ',' 0 6179 2249 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2275 cstring 11 10 -2 f p P f t ',' 0 - 0 1263 2292 2293 2500 2501 - - - c p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2276 any 11 10 4 t p P f t ',' 0 - 0 0 2294 2295 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2277 anyarray 11 10 -1 f p P f t ',' 0 - 0 0 2296 2297 2502 2503 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2278 void 11 10 4 t p P f t ',' 0 - 0 0 2298 2299 3120 3121 - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2279 trigger 11 10 4 t p P f t ',' 0 - 0 0 2300 2301 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3838 event_trigger 11 10 4 t p P f t ',' 0 - 0 0 3594 3595 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2280 language_handler 11 10 4 t p P f t ',' 0 - 0 0 2302 2303 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2281 internal 11 10 SIZEOF_POINTER t p P f t ',' 0 - 0 0 2304 2305 - - - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2283 anyelement 11 10 4 t p P f t ',' 0 - 0 0 2312 2313 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2776 anynonarray 11 10 4 t p P f t ',' 0 - 0 0 2777 2778 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3500 anyenum 11 10 4 t p P f t ',' 0 - 0 0 3504 3505 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3115 fdw_handler 11 10 4 t p P f t ',' 0 - 0 0 3116 3117 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 325 index_am_handler 11 10 4 t p P f t ',' 0 - 0 0 326 327 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3310 tsm_handler 11 10 4 t p P f t ',' 0 - 0 0 3311 3312 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 269 table_am_handler 11 10 4 t p P f t ',' 0 - 0 0 267 268 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3831 anyrange 11 10 -1 f p P f t ',' 0 - 0 0 3832 3833 - - - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 5077 anycompatible 11 10 4 t p P f t ',' 0 - 0 0 5086 5087 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 5078 anycompatiblearray 11 10 -1 f p P f t ',' 0 - 0 0 5088 5089 5090 5091 - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 5079 anycompatiblenonarray 11 10 4 t p P f t ',' 0 - 0 0 5092 5093 - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 5080 anycompatiblerange 11 10 -1 f p P f t ',' 0 - 0 0 5094 5095 - - - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4537 anymultirange 11 10 -1 f p P f t ',' 0 - 0 0 4229 4230 - - - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4538 anycompatiblemultirange 11 10 -1 f p P f t ',' 0 - 0 0 4226 4227 - - - - - d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4600 pg_brin_bloom_summary 11 10 -1 f b Z f t ',' 0 - 0 0 4596 4597 4598 4599 - - - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 4601 pg_brin_minmax_multi_summary 11 10 -1 f b Z f t ',' 0 - 0 0 4638 4639 4640 4641 - - - i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 1000 _bool 11 10 -1 f b A f t ',' 0 6179 16 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1001 _bytea 11 10 -1 f b A f t ',' 0 6179 17 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1002 _char 11 10 -1 f b A f t ',' 0 6179 18 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1003 _name 11 10 -1 f b A f t ',' 0 6179 19 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 950 _null_ _null_ _null_ ) +insert ( 1016 _int8 11 10 -1 f b A f t ',' 0 6179 20 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1005 _int2 11 10 -1 f b A f t ',' 0 6179 21 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1006 _int2vector 11 10 -1 f b A f t ',' 0 6179 22 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1007 _int4 11 10 -1 f b A f t ',' 0 6179 23 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1008 _regproc 11 10 -1 f b A f t ',' 0 6179 24 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1009 _text 11 10 -1 f b A f t ',' 0 6179 25 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 1028 _oid 11 10 -1 f b A f t ',' 0 6179 26 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1010 _tid 11 10 -1 f b A f t ',' 0 6179 27 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1011 _xid 11 10 -1 f b A f t ',' 0 6179 28 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1012 _cid 11 10 -1 f b A f t ',' 0 6179 29 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1013 _oidvector 11 10 -1 f b A f t ',' 0 6179 30 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 210 _pg_type 11 10 -1 f b A f t ',' 0 6179 71 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 270 _pg_attribute 11 10 -1 f b A f t ',' 0 6179 75 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 272 _pg_proc 11 10 -1 f b A f t ',' 0 6179 81 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 273 _pg_class 11 10 -1 f b A f t ',' 0 6179 83 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 199 _json 11 10 -1 f b A f t ',' 0 6179 114 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 143 _xml 11 10 -1 f b A f t ',' 0 6179 142 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 271 _xid8 11 10 -1 f b A f t ',' 0 6179 5069 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1017 _point 11 10 -1 f b A f t ',' 0 6179 600 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1018 _lseg 11 10 -1 f b A f t ',' 0 6179 601 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1019 _path 11 10 -1 f b A f t ',' 0 6179 602 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1020 _box 11 10 -1 f b A f t ';' 0 6179 603 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1027 _polygon 11 10 -1 f b A f t ',' 0 6179 604 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 629 _line 11 10 -1 f b A f t ',' 0 6179 628 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1021 _float4 11 10 -1 f b A f t ',' 0 6179 700 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1022 _float8 11 10 -1 f b A f t ',' 0 6179 701 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 719 _circle 11 10 -1 f b A f t ',' 0 6179 718 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 791 _money 11 10 -1 f b A f t ',' 0 6179 790 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1040 _macaddr 11 10 -1 f b A f t ',' 0 6179 829 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1041 _inet 11 10 -1 f b A f t ',' 0 6179 869 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 651 _cidr 11 10 -1 f b A f t ',' 0 6179 650 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 775 _macaddr8 11 10 -1 f b A f t ',' 0 6179 774 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1034 _aclitem 11 10 -1 f b A f t ',' 0 6179 1033 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1014 _bpchar 11 10 -1 f b A f t ',' 0 6179 1042 0 750 751 2400 2401 2913 2914 3816 i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 1015 _varchar 11 10 -1 f b A f t ',' 0 6179 1043 0 750 751 2400 2401 2915 2916 3816 i x f 0 -1 0 100 _null_ _null_ _null_ ) +insert ( 1182 _date 11 10 -1 f b A f t ',' 0 6179 1082 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1183 _time 11 10 -1 f b A f t ',' 0 6179 1083 0 750 751 2400 2401 2909 2910 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1115 _timestamp 11 10 -1 f b A f t ',' 0 6179 1114 0 750 751 2400 2401 2905 2906 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1185 _timestamptz 11 10 -1 f b A f t ',' 0 6179 1184 0 750 751 2400 2401 2907 2908 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1187 _interval 11 10 -1 f b A f t ',' 0 6179 1186 0 750 751 2400 2401 2903 2904 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1270 _timetz 11 10 -1 f b A f t ',' 0 6179 1266 0 750 751 2400 2401 2911 2912 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1561 _bit 11 10 -1 f b A f t ',' 0 6179 1560 0 750 751 2400 2401 2919 2920 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1563 _varbit 11 10 -1 f b A f t ',' 0 6179 1562 0 750 751 2400 2401 2902 2921 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1231 _numeric 11 10 -1 f b A f t ',' 0 6179 1700 0 750 751 2400 2401 2917 2918 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2201 _refcursor 11 10 -1 f b A f t ',' 0 6179 1790 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2207 _regprocedure 11 10 -1 f b A f t ',' 0 6179 2202 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2208 _regoper 11 10 -1 f b A f t ',' 0 6179 2203 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2209 _regoperator 11 10 -1 f b A f t ',' 0 6179 2204 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2210 _regclass 11 10 -1 f b A f t ',' 0 6179 2205 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4192 _regcollation 11 10 -1 f b A f t ',' 0 6179 4191 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2211 _regtype 11 10 -1 f b A f t ',' 0 6179 2206 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4097 _regrole 11 10 -1 f b A f t ',' 0 6179 4096 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4090 _regnamespace 11 10 -1 f b A f t ',' 0 6179 4089 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2951 _uuid 11 10 -1 f b A f t ',' 0 6179 2950 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3221 _pg_lsn 11 10 -1 f b A f t ',' 0 6179 3220 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3643 _tsvector 11 10 -1 f b A f t ',' 0 6179 3614 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3644 _gtsvector 11 10 -1 f b A f t ',' 0 6179 3642 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3645 _tsquery 11 10 -1 f b A f t ',' 0 6179 3615 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3735 _regconfig 11 10 -1 f b A f t ',' 0 6179 3734 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3770 _regdictionary 11 10 -1 f b A f t ',' 0 6179 3769 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3807 _jsonb 11 10 -1 f b A f t ',' 0 6179 3802 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 4073 _jsonpath 11 10 -1 f b A f t ',' 0 6179 4072 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 2949 _txid_snapshot 11 10 -1 f b A f t ',' 0 6179 2970 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 5039 _pg_snapshot 11 10 -1 f b A f t ',' 0 6179 5038 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3905 _int4range 11 10 -1 f b A f t ',' 0 6179 3904 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3907 _numrange 11 10 -1 f b A f t ',' 0 6179 3906 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3909 _tsrange 11 10 -1 f b A f t ',' 0 6179 3908 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3911 _tstzrange 11 10 -1 f b A f t ',' 0 6179 3910 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3913 _daterange 11 10 -1 f b A f t ',' 0 6179 3912 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 3927 _int8range 11 10 -1 f b A f t ',' 0 6179 3926 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 6150 _int4multirange 11 10 -1 f b A f t ',' 0 6179 4451 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 6151 _nummultirange 11 10 -1 f b A f t ',' 0 6179 4532 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 6152 _tsmultirange 11 10 -1 f b A f t ',' 0 6179 4533 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 6153 _tstzmultirange 11 10 -1 f b A f t ',' 0 6179 4534 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 6155 _datemultirange 11 10 -1 f b A f t ',' 0 6179 4535 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 6157 _int8multirange 11 10 -1 f b A f t ',' 0 6179 4536 0 750 751 2400 2401 - - 3816 d x f 0 -1 0 0 _null_ _null_ _null_ ) +insert ( 1263 _cstring 11 10 -1 f b A f t ',' 0 6179 2275 0 750 751 2400 2401 - - 3816 i x f 0 -1 0 0 _null_ _null_ _null_ ) +close pg_type +create pg_attribute 1249 bootstrap rowtype_oid 75 + ( + attrelid = oid , + attname = name , + atttypid = oid , + attlen = int2 , + attnum = int2 , + attcacheoff = int4 , + atttypmod = int4 , + attndims = int2 , + attbyval = bool , + attalign = char , + attstorage = char , + attcompression = char , + attnotnull = bool , + atthasdef = bool , + atthasmissing = bool , + attidentity = char , + attgenerated = char , + attisdropped = bool , + attislocal = bool , + attinhcount = int2 , + attstattarget = int2 , + attcollation = oid , + attacl = _aclitem , + attoptions = _text , + attfdwoptions = _text , + attmissingval = anyarray + ) +insert ( 1255 oid 26 4 1 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proname 19 NAMEDATALEN 2 -1 -1 0 f c p '' t f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1255 pronamespace 26 4 3 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proowner 26 4 4 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 prolang 26 4 5 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 procost 700 4 6 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 prorows 700 4 7 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 provariadic 26 4 8 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 prosupport 24 4 9 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 prokind 18 1 10 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 prosecdef 16 1 11 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proleakproof 16 1 12 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proisstrict 16 1 13 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proretset 16 1 14 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 provolatile 18 1 15 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proparallel 18 1 16 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 pronargs 21 2 17 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 pronargdefaults 21 2 18 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 prorettype 26 4 19 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proargtypes 30 -1 20 -1 -1 1 f i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proallargtypes 1028 -1 21 -1 -1 1 f i x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proargmodes 1002 -1 22 -1 -1 1 f i x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 proargnames 1009 -1 23 -1 -1 1 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1255 proargdefaults 194 -1 24 -1 -1 0 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1255 protrftypes 1028 -1 25 -1 -1 1 f i x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 prosrc 25 -1 26 -1 -1 0 f i x '' t f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1255 probin 25 -1 27 -1 -1 0 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1255 prosqlbody 194 -1 28 -1 -1 0 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1255 proconfig 1009 -1 29 -1 -1 1 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1255 proacl 1034 -1 30 -1 -1 1 f d x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 ctid 27 6 -1 -1 -1 0 f s p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 xmin 28 4 -2 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 cmin 29 4 -3 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 xmax 28 4 -4 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 cmax 29 4 -5 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1255 tableoid 26 4 -6 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 oid 26 4 1 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typname 19 NAMEDATALEN 2 -1 -1 0 f c p '' t f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1247 typnamespace 26 4 3 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typowner 26 4 4 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typlen 21 2 5 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typbyval 16 1 6 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typtype 18 1 7 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typcategory 18 1 8 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typispreferred 16 1 9 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typisdefined 16 1 10 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typdelim 18 1 11 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typrelid 26 4 12 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typsubscript 24 4 13 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typelem 26 4 14 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typarray 26 4 15 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typinput 24 4 16 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typoutput 24 4 17 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typreceive 24 4 18 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typsend 24 4 19 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typmodin 24 4 20 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typmodout 24 4 21 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typanalyze 24 4 22 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typalign 18 1 23 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typstorage 18 1 24 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typnotnull 16 1 25 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typbasetype 26 4 26 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typtypmod 23 4 27 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typndims 23 4 28 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typcollation 26 4 29 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 typdefaultbin 194 -1 30 -1 -1 0 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1247 typdefault 25 -1 31 -1 -1 0 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1247 typacl 1034 -1 32 -1 -1 1 f d x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 ctid 27 6 -1 -1 -1 0 f s p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 xmin 28 4 -2 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 cmin 29 4 -3 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 xmax 28 4 -4 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 cmax 29 4 -5 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1247 tableoid 26 4 -6 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attrelid 26 4 1 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attname 19 NAMEDATALEN 2 -1 -1 0 f c p '' t f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1249 atttypid 26 4 3 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attlen 21 2 4 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attnum 21 2 5 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attcacheoff 23 4 6 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 atttypmod 23 4 7 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attndims 21 2 8 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attbyval 16 1 9 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attalign 18 1 10 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attstorage 18 1 11 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attcompression 18 1 12 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attnotnull 16 1 13 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 atthasdef 16 1 14 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 atthasmissing 16 1 15 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attidentity 18 1 16 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attgenerated 18 1 17 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attisdropped 16 1 18 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attislocal 16 1 19 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attinhcount 21 2 20 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attstattarget 21 2 21 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attcollation 26 4 22 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attacl 1034 -1 23 -1 -1 1 f d x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 attoptions 1009 -1 24 -1 -1 1 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1249 attfdwoptions 1009 -1 25 -1 -1 1 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1249 attmissingval 2277 -1 26 -1 -1 0 f d x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 ctid 27 6 -1 -1 -1 0 f s p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 xmin 28 4 -2 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 cmin 29 4 -3 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 xmax 28 4 -4 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 cmax 29 4 -5 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1249 tableoid 26 4 -6 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 oid 26 4 1 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relname 19 NAMEDATALEN 2 -1 -1 0 f c p '' t f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1259 relnamespace 26 4 3 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 reltype 26 4 4 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 reloftype 26 4 5 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relowner 26 4 6 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relam 26 4 7 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relfilenode 26 4 8 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 reltablespace 26 4 9 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relpages 23 4 10 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 reltuples 700 4 11 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relallvisible 23 4 12 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 reltoastrelid 26 4 13 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relhasindex 16 1 14 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relisshared 16 1 15 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relpersistence 18 1 16 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relkind 18 1 17 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relnatts 21 2 18 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relchecks 21 2 19 -1 -1 0 t s p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relhasrules 16 1 20 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relhastriggers 16 1 21 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relhassubclass 16 1 22 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relrowsecurity 16 1 23 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relforcerowsecurity 16 1 24 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relispopulated 16 1 25 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relreplident 18 1 26 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relispartition 16 1 27 -1 -1 0 t c p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relrewrite 26 4 28 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relfrozenxid 28 4 29 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relminmxid 28 4 30 -1 -1 0 t i p '' t f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 relacl 1034 -1 31 -1 -1 1 f d x '' f f f '' '' f t 0 -1 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 reloptions 1009 -1 32 -1 -1 1 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1259 relpartbound 194 -1 33 -1 -1 0 f i x '' f f f '' '' f t 0 -1 950 _null_ _null_ _null_ _null_ ) +insert ( 1259 ctid 27 6 -1 -1 -1 0 f s p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 xmin 28 4 -2 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 cmin 29 4 -3 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 xmax 28 4 -4 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 cmax 29 4 -5 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +insert ( 1259 tableoid 26 4 -6 -1 -1 0 t i p '' t f f '' '' f t 0 0 0 _null_ _null_ _null_ _null_ ) +close pg_attribute +create pg_class 1259 bootstrap rowtype_oid 83 + ( + oid = oid , + relname = name , + relnamespace = oid , + reltype = oid , + reloftype = oid , + relowner = oid , + relam = oid , + relfilenode = oid , + reltablespace = oid , + relpages = int4 , + reltuples = float4 , + relallvisible = int4 , + reltoastrelid = oid , + relhasindex = bool , + relisshared = bool , + relpersistence = char , + relkind = char , + relnatts = int2 , + relchecks = int2 , + relhasrules = bool , + relhastriggers = bool , + relhassubclass = bool , + relrowsecurity = bool , + relforcerowsecurity = bool , + relispopulated = bool , + relreplident = char , + relispartition = bool , + relrewrite = oid , + relfrozenxid = xid , + relminmxid = xid , + relacl = _aclitem , + reloptions = _text , + relpartbound = pg_node_tree + ) +insert ( 1247 pg_type 11 71 0 10 2 0 0 0 -1 0 0 f f p r 32 0 f f f f f t n f 0 3 1 _null_ _null_ _null_ ) +insert ( 1249 pg_attribute 11 75 0 10 2 0 0 0 -1 0 0 f f p r 26 0 f f f f f t n f 0 3 1 _null_ _null_ _null_ ) +insert ( 1255 pg_proc 11 81 0 10 2 0 0 0 -1 0 0 f f p r 30 0 f f f f f t n f 0 3 1 _null_ _null_ _null_ ) +insert ( 1259 pg_class 11 83 0 10 2 0 0 0 -1 0 0 f f p r 33 0 f f f f f t n f 0 3 1 _null_ _null_ _null_ ) +close pg_class +create pg_attrdef 2604 + ( + oid = oid , + adrelid = oid , + adnum = int2 , + adbin = pg_node_tree FORCE NOT NULL + ) +open pg_attrdef +close pg_attrdef +create pg_constraint 2606 + ( + oid = oid , + conname = name , + connamespace = oid , + contype = char , + condeferrable = bool , + condeferred = bool , + convalidated = bool , + conrelid = oid , + contypid = oid , + conindid = oid , + conparentid = oid , + confrelid = oid , + confupdtype = char , + confdeltype = char , + confmatchtype = char , + conislocal = bool , + coninhcount = int2 , + connoinherit = bool , + conkey = _int2 , + confkey = _int2 , + conpfeqop = _oid , + conppeqop = _oid , + conffeqop = _oid , + confdelsetcols = _int2 , + conexclop = _oid , + conbin = pg_node_tree + ) +open pg_constraint +close pg_constraint +create pg_inherits 2611 + ( + inhrelid = oid , + inhparent = oid , + inhseqno = int4 , + inhdetachpending = bool + ) +open pg_inherits +close pg_inherits +create pg_index 2610 + ( + indexrelid = oid , + indrelid = oid , + indnatts = int2 , + indnkeyatts = int2 , + indisunique = bool , + indnullsnotdistinct = bool , + indisprimary = bool , + indisexclusion = bool , + indimmediate = bool , + indisclustered = bool , + indisvalid = bool , + indcheckxmin = bool , + indisready = bool , + indislive = bool , + indisreplident = bool , + indkey = int2vector FORCE NOT NULL , + indcollation = oidvector FORCE NOT NULL , + indclass = oidvector FORCE NOT NULL , + indoption = int2vector FORCE NOT NULL , + indexprs = pg_node_tree , + indpred = pg_node_tree + ) +open pg_index +close pg_index +create pg_operator 2617 + ( + oid = oid , + oprname = name , + oprnamespace = oid , + oprowner = oid , + oprkind = char , + oprcanmerge = bool , + oprcanhash = bool , + oprleft = oid , + oprright = oid , + oprresult = oid , + oprcom = oid , + oprnegate = oid , + oprcode = regproc , + oprrest = regproc , + oprjoin = regproc + ) +open pg_operator +insert ( 15 '=' 11 10 b t t 23 20 16 416 36 852 101 105 ) +insert ( 36 '<>' 11 10 b f f 23 20 16 417 15 853 102 106 ) +insert ( 37 '<' 11 10 b f f 23 20 16 419 82 854 103 107 ) +insert ( 76 '>' 11 10 b f f 23 20 16 418 80 855 104 108 ) +insert ( 80 '<=' 11 10 b f f 23 20 16 430 76 856 336 386 ) +insert ( 82 '>=' 11 10 b f f 23 20 16 420 37 857 337 398 ) +insert ( 58 '<' 11 10 b f f 16 16 16 59 1695 56 103 107 ) +insert ( 59 '>' 11 10 b f f 16 16 16 58 1694 57 104 108 ) +insert ( 85 '<>' 11 10 b f f 16 16 16 85 91 84 102 106 ) +insert ( 91 '=' 11 10 b t t 16 16 16 91 85 60 101 105 ) +insert ( 1694 '<=' 11 10 b f f 16 16 16 1695 59 1691 336 386 ) +insert ( 1695 '>=' 11 10 b f f 16 16 16 1694 58 1692 337 398 ) +insert ( 92 '=' 11 10 b t t 18 18 16 92 630 61 101 105 ) +insert ( 93 '=' 11 10 b t t 19 19 16 93 643 62 101 105 ) +insert ( 94 '=' 11 10 b t t 21 21 16 94 519 63 101 105 ) +insert ( 95 '<' 11 10 b f f 21 21 16 520 524 64 103 107 ) +insert ( 96 '=' 11 10 b t t 23 23 16 96 518 65 101 105 ) +insert ( 97 '<' 11 10 b f f 23 23 16 521 525 66 103 107 ) +insert ( 98 '=' 11 10 b t t 25 25 16 98 531 67 101 105 ) +insert ( 3877 '^@' 11 10 b f f 25 25 16 0 0 3696 3437 3438 ) +insert ( 254 '=' 11 10 b t t 19 25 16 260 259 240 101 105 ) +insert ( 255 '<' 11 10 b f f 19 25 16 264 257 241 103 107 ) +insert ( 256 '<=' 11 10 b f f 19 25 16 263 258 242 336 386 ) +insert ( 257 '>=' 11 10 b f f 19 25 16 262 255 243 337 398 ) +insert ( 258 '>' 11 10 b f f 19 25 16 261 256 244 104 108 ) +insert ( 259 '<>' 11 10 b f f 19 25 16 265 254 245 102 106 ) +insert ( 260 '=' 11 10 b t t 25 19 16 254 265 247 101 105 ) +insert ( 261 '<' 11 10 b f f 25 19 16 258 263 248 103 107 ) +insert ( 262 '<=' 11 10 b f f 25 19 16 257 264 249 336 386 ) +insert ( 263 '>=' 11 10 b f f 25 19 16 256 261 250 337 398 ) +insert ( 264 '>' 11 10 b f f 25 19 16 255 262 251 104 108 ) +insert ( 265 '<>' 11 10 b f f 25 19 16 259 260 252 102 106 ) +insert ( 349 '||' 11 10 b f f 5078 5077 5078 0 0 378 - - ) +insert ( 374 '||' 11 10 b f f 5077 5078 5078 0 0 379 - - ) +insert ( 375 '||' 11 10 b f f 5078 5078 5078 0 0 383 - - ) +insert ( 352 '=' 11 10 b f t 28 28 16 352 3315 68 101 105 ) +insert ( 353 '=' 11 10 b f f 28 23 16 0 3316 1319 101 105 ) +insert ( 3315 '<>' 11 10 b f f 28 28 16 3315 352 3308 102 106 ) +insert ( 3316 '<>' 11 10 b f f 28 23 16 0 353 3309 102 106 ) +insert ( 5068 '=' 11 10 b t t 5069 5069 16 5068 5072 5084 101 105 ) +insert ( 5072 '<>' 11 10 b f f 5069 5069 16 5072 5068 5085 102 106 ) +insert ( 5073 '<' 11 10 b f f 5069 5069 16 5074 5076 5034 103 107 ) +insert ( 5074 '>' 11 10 b f f 5069 5069 16 5073 5075 5035 104 108 ) +insert ( 5075 '<=' 11 10 b f f 5069 5069 16 5076 5074 5036 336 386 ) +insert ( 5076 '>=' 11 10 b f f 5069 5069 16 5075 5073 5037 337 398 ) +insert ( 385 '=' 11 10 b f t 29 29 16 385 0 69 101 105 ) +insert ( 387 '=' 11 10 b t t 27 27 16 387 402 1292 101 105 ) +insert ( 402 '<>' 11 10 b f f 27 27 16 402 387 1265 102 106 ) +insert ( 2799 '<' 11 10 b f f 27 27 16 2800 2802 2791 103 107 ) +insert ( 2800 '>' 11 10 b f f 27 27 16 2799 2801 2790 104 108 ) +insert ( 2801 '<=' 11 10 b f f 27 27 16 2802 2800 2793 336 386 ) +insert ( 2802 '>=' 11 10 b f f 27 27 16 2801 2799 2792 337 398 ) +insert ( 410 '=' 11 10 b t t 20 20 16 410 411 467 101 105 ) +insert ( 411 '<>' 11 10 b f f 20 20 16 411 410 468 102 106 ) +insert ( 412 '<' 11 10 b f f 20 20 16 413 415 469 103 107 ) +insert ( 413 '>' 11 10 b f f 20 20 16 412 414 470 104 108 ) +insert ( 414 '<=' 11 10 b f f 20 20 16 415 413 471 336 386 ) +insert ( 415 '>=' 11 10 b f f 20 20 16 414 412 472 337 398 ) +insert ( 416 '=' 11 10 b t t 20 23 16 15 417 474 101 105 ) +insert ( 417 '<>' 11 10 b f f 20 23 16 36 416 475 102 106 ) +insert ( 418 '<' 11 10 b f f 20 23 16 76 430 476 103 107 ) +insert ( 419 '>' 11 10 b f f 20 23 16 37 420 477 104 108 ) +insert ( 420 '<=' 11 10 b f f 20 23 16 82 419 478 336 386 ) +insert ( 430 '>=' 11 10 b f f 20 23 16 80 418 479 337 398 ) +insert ( 439 '%' 11 10 b f f 20 20 20 0 0 945 - - ) +insert ( 473 '@' 11 10 l f f 0 20 20 0 0 1230 - - ) +insert ( 484 - 11 10 l f f 0 20 20 0 0 462 - - ) +insert ( 485 '<<' 11 10 b f f 604 604 16 0 0 341 1300 1301 ) +insert ( 486 '&<' 11 10 b f f 604 604 16 0 0 342 1300 1301 ) +insert ( 487 '&>' 11 10 b f f 604 604 16 0 0 343 1300 1301 ) +insert ( 488 '>>' 11 10 b f f 604 604 16 0 0 344 1300 1301 ) +insert ( 489 '<@' 11 10 b f f 604 604 16 490 0 345 1302 1303 ) +insert ( 490 '@>' 11 10 b f f 604 604 16 489 0 340 1302 1303 ) +insert ( 491 '~=' 11 10 b f f 604 604 16 491 0 339 101 105 ) +insert ( 492 '&&' 11 10 b f f 604 604 16 492 0 346 139 140 ) +insert ( 493 '<<' 11 10 b f f 603 603 16 0 0 188 1300 1301 ) +insert ( 494 '&<' 11 10 b f f 603 603 16 0 0 189 1300 1301 ) +insert ( 495 '&>' 11 10 b f f 603 603 16 0 0 190 1300 1301 ) +insert ( 496 '>>' 11 10 b f f 603 603 16 0 0 191 1300 1301 ) +insert ( 497 '<@' 11 10 b f f 603 603 16 498 0 192 1302 1303 ) +insert ( 498 '@>' 11 10 b f f 603 603 16 497 0 187 1302 1303 ) +insert ( 499 '~=' 11 10 b f f 603 603 16 499 0 186 101 105 ) +insert ( 500 '&&' 11 10 b f f 603 603 16 500 0 125 139 140 ) +insert ( 501 '>=' 11 10 b f f 603 603 16 505 504 126 139 140 ) +insert ( 502 '>' 11 10 b f f 603 603 16 504 505 127 139 140 ) +insert ( 503 '=' 11 10 b f f 603 603 16 503 0 128 101 105 ) +insert ( 504 '<' 11 10 b f f 603 603 16 502 501 129 139 140 ) +insert ( 505 '<=' 11 10 b f f 603 603 16 501 502 130 139 140 ) +insert ( 506 '>^' 11 10 b f f 600 600 16 0 0 131 1300 1301 ) +insert ( 507 '<<' 11 10 b f f 600 600 16 0 0 132 1300 1301 ) +insert ( 508 '>>' 11 10 b f f 600 600 16 0 0 133 1300 1301 ) +insert ( 509 '<^' 11 10 b f f 600 600 16 0 0 134 1300 1301 ) +insert ( 510 '~=' 11 10 b f f 600 600 16 510 713 135 101 105 ) +insert ( 511 '<@' 11 10 b f f 600 603 16 433 0 136 1302 1303 ) +insert ( 433 '@>' 11 10 b f f 603 600 16 511 0 193 1302 1303 ) +insert ( 512 '<@' 11 10 b f f 600 602 16 755 0 137 - - ) +insert ( 513 '@@' 11 10 l f f 0 603 600 0 0 138 - - ) +insert ( 514 '*' 11 10 b f f 23 23 23 514 0 141 - - ) +insert ( 517 '<->' 11 10 b f f 600 600 701 517 0 991 - - ) +insert ( 518 '<>' 11 10 b f f 23 23 16 518 96 144 102 106 ) +insert ( 519 '<>' 11 10 b f f 21 21 16 519 94 145 102 106 ) +insert ( 520 '>' 11 10 b f f 21 21 16 95 522 146 104 108 ) +insert ( 521 '>' 11 10 b f f 23 23 16 97 523 147 104 108 ) +insert ( 522 '<=' 11 10 b f f 21 21 16 524 520 148 336 386 ) +insert ( 523 '<=' 11 10 b f f 23 23 16 525 521 149 336 386 ) +insert ( 524 '>=' 11 10 b f f 21 21 16 522 95 151 337 398 ) +insert ( 525 '>=' 11 10 b f f 23 23 16 523 97 150 337 398 ) +insert ( 526 '*' 11 10 b f f 21 21 21 526 0 152 - - ) +insert ( 527 '/' 11 10 b f f 21 21 21 0 0 153 - - ) +insert ( 528 '/' 11 10 b f f 23 23 23 0 0 154 - - ) +insert ( 529 '%' 11 10 b f f 21 21 21 0 0 155 - - ) +insert ( 530 '%' 11 10 b f f 23 23 23 0 0 156 - - ) +insert ( 531 '<>' 11 10 b f f 25 25 16 531 98 157 102 106 ) +insert ( 532 '=' 11 10 b t t 21 23 16 533 538 158 101 105 ) +insert ( 533 '=' 11 10 b t t 23 21 16 532 539 159 101 105 ) +insert ( 534 '<' 11 10 b f f 21 23 16 537 542 160 103 107 ) +insert ( 535 '<' 11 10 b f f 23 21 16 536 543 161 103 107 ) +insert ( 536 '>' 11 10 b f f 21 23 16 535 540 162 104 108 ) +insert ( 537 '>' 11 10 b f f 23 21 16 534 541 163 104 108 ) +insert ( 538 '<>' 11 10 b f f 21 23 16 539 532 164 102 106 ) +insert ( 539 '<>' 11 10 b f f 23 21 16 538 533 165 102 106 ) +insert ( 540 '<=' 11 10 b f f 21 23 16 543 536 166 336 386 ) +insert ( 541 '<=' 11 10 b f f 23 21 16 542 537 167 336 386 ) +insert ( 542 '>=' 11 10 b f f 21 23 16 541 534 168 337 398 ) +insert ( 543 '>=' 11 10 b f f 23 21 16 540 535 169 337 398 ) +insert ( 544 '*' 11 10 b f f 21 23 23 545 0 170 - - ) +insert ( 545 '*' 11 10 b f f 23 21 23 544 0 171 - - ) +insert ( 546 '/' 11 10 b f f 21 23 23 0 0 172 - - ) +insert ( 547 '/' 11 10 b f f 23 21 23 0 0 173 - - ) +insert ( 550 '+' 11 10 b f f 21 21 21 550 0 176 - - ) +insert ( 551 '+' 11 10 b f f 23 23 23 551 0 177 - - ) +insert ( 552 '+' 11 10 b f f 21 23 23 553 0 178 - - ) +insert ( 553 '+' 11 10 b f f 23 21 23 552 0 179 - - ) +insert ( 554 - 11 10 b f f 21 21 21 0 0 180 - - ) +insert ( 555 - 11 10 b f f 23 23 23 0 0 181 - - ) +insert ( 556 - 11 10 b f f 21 23 23 0 0 182 - - ) +insert ( 557 - 11 10 b f f 23 21 23 0 0 183 - - ) +insert ( 558 - 11 10 l f f 0 23 23 0 0 212 - - ) +insert ( 559 - 11 10 l f f 0 21 21 0 0 213 - - ) +insert ( 584 - 11 10 l f f 0 700 700 0 0 206 - - ) +insert ( 585 - 11 10 l f f 0 701 701 0 0 220 - - ) +insert ( 586 '+' 11 10 b f f 700 700 700 586 0 204 - - ) +insert ( 587 - 11 10 b f f 700 700 700 0 0 205 - - ) +insert ( 588 '/' 11 10 b f f 700 700 700 0 0 203 - - ) +insert ( 589 '*' 11 10 b f f 700 700 700 589 0 202 - - ) +insert ( 590 '@' 11 10 l f f 0 700 700 0 0 207 - - ) +insert ( 591 '+' 11 10 b f f 701 701 701 591 0 218 - - ) +insert ( 592 - 11 10 b f f 701 701 701 0 0 219 - - ) +insert ( 593 '/' 11 10 b f f 701 701 701 0 0 217 - - ) +insert ( 594 '*' 11 10 b f f 701 701 701 594 0 216 - - ) +insert ( 595 '@' 11 10 l f f 0 701 701 0 0 221 - - ) +insert ( 596 '|/' 11 10 l f f 0 701 701 0 0 230 - - ) +insert ( 597 '||/' 11 10 l f f 0 701 701 0 0 231 - - ) +insert ( 607 '=' 11 10 b t t 26 26 16 607 608 184 101 105 ) +insert ( 608 '<>' 11 10 b f f 26 26 16 608 607 185 102 106 ) +insert ( 609 '<' 11 10 b f f 26 26 16 610 612 716 103 107 ) +insert ( 610 '>' 11 10 b f f 26 26 16 609 611 1638 104 108 ) +insert ( 611 '<=' 11 10 b f f 26 26 16 612 610 717 336 386 ) +insert ( 612 '>=' 11 10 b f f 26 26 16 611 609 1639 337 398 ) +insert ( 644 '<>' 11 10 b f f 30 30 16 644 649 619 102 106 ) +insert ( 645 '<' 11 10 b f f 30 30 16 646 648 677 103 107 ) +insert ( 646 '>' 11 10 b f f 30 30 16 645 647 681 104 108 ) +insert ( 647 '<=' 11 10 b f f 30 30 16 648 646 678 336 386 ) +insert ( 648 '>=' 11 10 b f f 30 30 16 647 645 680 337 398 ) +insert ( 649 '=' 11 10 b t t 30 30 16 649 644 679 101 105 ) +insert ( 613 '<->' 11 10 b f f 600 628 701 760 0 725 - - ) +insert ( 760 '<->' 11 10 b f f 628 600 701 613 0 702 - - ) +insert ( 614 '<->' 11 10 b f f 600 601 701 761 0 363 - - ) +insert ( 761 '<->' 11 10 b f f 601 600 701 614 0 380 - - ) +insert ( 615 '<->' 11 10 b f f 600 603 701 606 0 364 - - ) +insert ( 606 '<->' 11 10 b f f 603 600 701 615 0 357 - - ) +insert ( 616 '<->' 11 10 b f f 601 628 701 762 0 727 - - ) +insert ( 762 '<->' 11 10 b f f 628 601 701 616 0 704 - - ) +insert ( 617 '<->' 11 10 b f f 601 603 701 763 0 365 - - ) +insert ( 763 '<->' 11 10 b f f 603 601 701 617 0 381 - - ) +insert ( 618 '<->' 11 10 b f f 600 602 701 784 0 371 - - ) +insert ( 784 '<->' 11 10 b f f 602 600 701 618 0 421 - - ) +insert ( 620 '=' 11 10 b t t 700 700 16 620 621 287 101 105 ) +insert ( 621 '<>' 11 10 b f f 700 700 16 621 620 288 102 106 ) +insert ( 622 '<' 11 10 b f f 700 700 16 623 625 289 103 107 ) +insert ( 623 '>' 11 10 b f f 700 700 16 622 624 291 104 108 ) +insert ( 624 '<=' 11 10 b f f 700 700 16 625 623 290 336 386 ) +insert ( 625 '>=' 11 10 b f f 700 700 16 624 622 292 337 398 ) +insert ( 630 '<>' 11 10 b f f 18 18 16 630 92 70 102 106 ) +insert ( 631 '<' 11 10 b f f 18 18 16 633 634 1246 103 107 ) +insert ( 632 '<=' 11 10 b f f 18 18 16 634 633 72 336 386 ) +insert ( 633 '>' 11 10 b f f 18 18 16 631 632 73 104 108 ) +insert ( 634 '>=' 11 10 b f f 18 18 16 632 631 74 337 398 ) +insert ( 639 '~' 11 10 b f f 19 25 16 0 640 79 1818 1824 ) +insert ( 640 '!~' 11 10 b f f 19 25 16 0 639 1252 1821 1827 ) +insert ( 641 '~' 11 10 b f f 25 25 16 0 642 1254 1818 1824 ) +insert ( 642 '!~' 11 10 b f f 25 25 16 0 641 1256 1821 1827 ) +insert ( 643 '<>' 11 10 b f f 19 19 16 643 93 659 102 106 ) +insert ( 654 '||' 11 10 b f f 25 25 25 0 0 1258 - - ) +insert ( 660 '<' 11 10 b f f 19 19 16 662 663 655 103 107 ) +insert ( 661 '<=' 11 10 b f f 19 19 16 663 662 656 336 386 ) +insert ( 662 '>' 11 10 b f f 19 19 16 660 661 657 104 108 ) +insert ( 663 '>=' 11 10 b f f 19 19 16 661 660 658 337 398 ) +insert ( 664 '<' 11 10 b f f 25 25 16 666 667 740 103 107 ) +insert ( 665 '<=' 11 10 b f f 25 25 16 667 666 741 336 386 ) +insert ( 666 '>' 11 10 b f f 25 25 16 664 665 742 104 108 ) +insert ( 667 '>=' 11 10 b f f 25 25 16 665 664 743 337 398 ) +insert ( 670 '=' 11 10 b t t 701 701 16 670 671 293 101 105 ) +insert ( 671 '<>' 11 10 b f f 701 701 16 671 670 294 102 106 ) +insert ( 672 '<' 11 10 b f f 701 701 16 674 675 295 103 107 ) +insert ( 673 '<=' 11 10 b f f 701 701 16 675 674 296 336 386 ) +insert ( 674 '>' 11 10 b f f 701 701 16 672 673 297 104 108 ) +insert ( 675 '>=' 11 10 b f f 701 701 16 673 672 298 337 398 ) +insert ( 682 '@' 11 10 l f f 0 21 21 0 0 1253 - - ) +insert ( 684 '+' 11 10 b f f 20 20 20 684 0 463 - - ) +insert ( 685 - 11 10 b f f 20 20 20 0 0 464 - - ) +insert ( 686 '*' 11 10 b f f 20 20 20 686 0 465 - - ) +insert ( 687 '/' 11 10 b f f 20 20 20 0 0 466 - - ) +insert ( 688 '+' 11 10 b f f 20 23 20 692 0 1274 - - ) +insert ( 689 - 11 10 b f f 20 23 20 0 0 1275 - - ) +insert ( 690 '*' 11 10 b f f 20 23 20 694 0 1276 - - ) +insert ( 691 '/' 11 10 b f f 20 23 20 0 0 1277 - - ) +insert ( 692 '+' 11 10 b f f 23 20 20 688 0 1278 - - ) +insert ( 693 - 11 10 b f f 23 20 20 0 0 1279 - - ) +insert ( 694 '*' 11 10 b f f 23 20 20 690 0 1280 - - ) +insert ( 695 '/' 11 10 b f f 23 20 20 0 0 1281 - - ) +insert ( 818 '+' 11 10 b f f 20 21 20 822 0 837 - - ) +insert ( 819 - 11 10 b f f 20 21 20 0 0 838 - - ) +insert ( 820 '*' 11 10 b f f 20 21 20 824 0 839 - - ) +insert ( 821 '/' 11 10 b f f 20 21 20 0 0 840 - - ) +insert ( 822 '+' 11 10 b f f 21 20 20 818 0 841 - - ) +insert ( 823 - 11 10 b f f 21 20 20 0 0 942 - - ) +insert ( 824 '*' 11 10 b f f 21 20 20 820 0 943 - - ) +insert ( 825 '/' 11 10 b f f 21 20 20 0 0 948 - - ) +insert ( 706 '<->' 11 10 b f f 603 603 701 706 0 978 - - ) +insert ( 707 '<->' 11 10 b f f 602 602 701 707 0 370 - - ) +insert ( 708 '<->' 11 10 b f f 628 628 701 708 0 239 - - ) +insert ( 709 '<->' 11 10 b f f 601 601 701 709 0 361 - - ) +insert ( 712 '<->' 11 10 b f f 604 604 701 712 0 729 - - ) +insert ( 713 '<>' 11 10 b f f 600 600 16 713 510 988 102 106 ) +insert ( 731 '+' 11 10 b f f 600 600 600 731 0 1441 - - ) +insert ( 732 - 11 10 b f f 600 600 600 0 0 1442 - - ) +insert ( 733 '*' 11 10 b f f 600 600 600 733 0 1443 - - ) +insert ( 734 '/' 11 10 b f f 600 600 600 0 0 1444 - - ) +insert ( 735 '+' 11 10 b f f 602 602 602 735 0 1435 - - ) +insert ( 736 '+' 11 10 b f f 602 600 602 0 0 1436 - - ) +insert ( 737 - 11 10 b f f 602 600 602 0 0 1437 - - ) +insert ( 738 '*' 11 10 b f f 602 600 602 0 0 1438 - - ) +insert ( 739 '/' 11 10 b f f 602 600 602 0 0 1439 - - ) +insert ( 755 '@>' 11 10 b f f 602 600 16 512 0 1426 - - ) +insert ( 756 '<@' 11 10 b f f 600 604 16 757 0 1429 1302 1303 ) +insert ( 757 '@>' 11 10 b f f 604 600 16 756 0 1428 1302 1303 ) +insert ( 758 '<@' 11 10 b f f 600 718 16 759 0 1478 1302 1303 ) +insert ( 759 '@>' 11 10 b f f 718 600 16 758 0 1477 1302 1303 ) +insert ( 773 '@' 11 10 l f f 0 23 23 0 0 1251 - - ) +insert ( 792 '=' 11 10 b f f 602 602 16 792 0 984 101 105 ) +insert ( 793 '<' 11 10 b f f 602 602 16 794 0 982 - - ) +insert ( 794 '>' 11 10 b f f 602 602 16 793 0 983 - - ) +insert ( 795 '<=' 11 10 b f f 602 602 16 796 0 985 - - ) +insert ( 796 '>=' 11 10 b f f 602 602 16 795 0 986 - - ) +insert ( 797 '#' 11 10 l f f 0 602 23 0 0 1432 - - ) +insert ( 798 '?#' 11 10 b f f 602 602 16 0 0 973 - - ) +insert ( 799 '@-@' 11 10 l f f 0 602 701 0 0 987 - - ) +insert ( 800 '>^' 11 10 b f f 603 603 16 0 0 115 1300 1301 ) +insert ( 801 '<^' 11 10 b f f 603 603 16 0 0 116 1300 1301 ) +insert ( 802 '?#' 11 10 b f f 603 603 16 0 0 125 139 140 ) +insert ( 803 '#' 11 10 b f f 603 603 603 0 0 980 - - ) +insert ( 804 '+' 11 10 b f f 603 600 603 0 0 1422 - - ) +insert ( 805 - 11 10 b f f 603 600 603 0 0 1423 - - ) +insert ( 806 '*' 11 10 b f f 603 600 603 0 0 1424 - - ) +insert ( 807 '/' 11 10 b f f 603 600 603 0 0 1425 - - ) +insert ( 808 '?-' 11 10 b f f 600 600 16 808 0 990 - - ) +insert ( 809 '?|' 11 10 b f f 600 600 16 809 0 989 - - ) +insert ( 843 '*' 11 10 b f f 790 700 790 845 0 846 - - ) +insert ( 844 '/' 11 10 b f f 790 700 790 0 0 847 - - ) +insert ( 845 '*' 11 10 b f f 700 790 790 843 0 848 - - ) +insert ( 900 '=' 11 10 b t f 790 790 16 900 901 888 101 105 ) +insert ( 901 '<>' 11 10 b f f 790 790 16 901 900 889 102 106 ) +insert ( 902 '<' 11 10 b f f 790 790 16 903 905 890 103 107 ) +insert ( 903 '>' 11 10 b f f 790 790 16 902 904 892 104 108 ) +insert ( 904 '<=' 11 10 b f f 790 790 16 905 903 891 336 386 ) +insert ( 905 '>=' 11 10 b f f 790 790 16 904 902 893 337 398 ) +insert ( 906 '+' 11 10 b f f 790 790 790 906 0 894 - - ) +insert ( 907 - 11 10 b f f 790 790 790 0 0 895 - - ) +insert ( 908 '*' 11 10 b f f 790 701 790 916 0 896 - - ) +insert ( 909 '/' 11 10 b f f 790 701 790 0 0 897 - - ) +insert ( 3346 '*' 11 10 b f f 790 20 790 3349 0 3344 - - ) +insert ( 3347 '/' 11 10 b f f 790 20 790 0 0 3345 - - ) +insert ( 912 '*' 11 10 b f f 790 23 790 917 0 864 - - ) +insert ( 913 '/' 11 10 b f f 790 23 790 0 0 865 - - ) +insert ( 914 '*' 11 10 b f f 790 21 790 918 0 866 - - ) +insert ( 915 '/' 11 10 b f f 790 21 790 0 0 867 - - ) +insert ( 916 '*' 11 10 b f f 701 790 790 908 0 919 - - ) +insert ( 3349 '*' 11 10 b f f 20 790 790 3346 0 3399 - - ) +insert ( 917 '*' 11 10 b f f 23 790 790 912 0 862 - - ) +insert ( 918 '*' 11 10 b f f 21 790 790 914 0 863 - - ) +insert ( 3825 '/' 11 10 b f f 790 790 701 0 0 3822 - - ) +insert ( 965 '^' 11 10 b f f 701 701 701 0 0 232 - - ) +insert ( 966 '+' 11 10 b f f 1034 1033 1034 0 0 1035 - - ) +insert ( 967 - 11 10 b f f 1034 1033 1034 0 0 1036 - - ) +insert ( 968 '@>' 11 10 b f f 1034 1033 16 0 0 1037 - - ) +insert ( 974 '=' 11 10 b f t 1033 1033 16 974 0 1062 101 105 ) +insert ( 969 '@@' 11 10 l f f 0 601 600 0 0 225 - - ) +insert ( 971 '@@' 11 10 l f f 0 604 600 0 0 227 - - ) +insert ( 1054 '=' 11 10 b t t 1042 1042 16 1054 1057 1048 101 105 ) +insert ( 1055 '~' 11 10 b f f 1042 25 16 0 1056 1658 1818 1824 ) +insert ( 1056 '!~' 11 10 b f f 1042 25 16 0 1055 1659 1821 1827 ) +insert ( 1057 '<>' 11 10 b f f 1042 1042 16 1057 1054 1053 102 106 ) +insert ( 1058 '<' 11 10 b f f 1042 1042 16 1060 1061 1049 103 107 ) +insert ( 1059 '<=' 11 10 b f f 1042 1042 16 1061 1060 1050 336 386 ) +insert ( 1060 '>' 11 10 b f f 1042 1042 16 1058 1059 1051 104 108 ) +insert ( 1061 '>=' 11 10 b f f 1042 1042 16 1059 1058 1052 337 398 ) +insert ( 1070 '=' 11 10 b t t 2277 2277 16 1070 1071 744 101 105 ) +insert ( 1071 '<>' 11 10 b f f 2277 2277 16 1071 1070 390 102 106 ) +insert ( 1072 '<' 11 10 b f f 2277 2277 16 1073 1075 391 103 107 ) +insert ( 1073 '>' 11 10 b f f 2277 2277 16 1072 1074 392 104 108 ) +insert ( 1074 '<=' 11 10 b f f 2277 2277 16 1075 1073 393 336 386 ) +insert ( 1075 '>=' 11 10 b f f 2277 2277 16 1074 1072 396 337 398 ) +insert ( 1076 '+' 11 10 b f f 1082 1186 1114 2551 0 2071 - - ) +insert ( 1077 - 11 10 b f f 1082 1186 1114 0 0 2072 - - ) +insert ( 1093 '=' 11 10 b t t 1082 1082 16 1093 1094 1086 101 105 ) +insert ( 1094 '<>' 11 10 b f f 1082 1082 16 1094 1093 1091 102 106 ) +insert ( 1095 '<' 11 10 b f f 1082 1082 16 1097 1098 1087 103 107 ) +insert ( 1096 '<=' 11 10 b f f 1082 1082 16 1098 1097 1088 336 386 ) +insert ( 1097 '>' 11 10 b f f 1082 1082 16 1095 1096 1089 104 108 ) +insert ( 1098 '>=' 11 10 b f f 1082 1082 16 1096 1095 1090 337 398 ) +insert ( 1099 - 11 10 b f f 1082 1082 23 0 0 1140 - - ) +insert ( 1100 '+' 11 10 b f f 1082 23 1082 2555 0 1141 - - ) +insert ( 1101 - 11 10 b f f 1082 23 1082 0 0 1142 - - ) +insert ( 1108 '=' 11 10 b t t 1083 1083 16 1108 1109 1145 101 105 ) +insert ( 1109 '<>' 11 10 b f f 1083 1083 16 1109 1108 1106 102 106 ) +insert ( 1110 '<' 11 10 b f f 1083 1083 16 1112 1113 1102 103 107 ) +insert ( 1111 '<=' 11 10 b f f 1083 1083 16 1113 1112 1103 336 386 ) +insert ( 1112 '>' 11 10 b f f 1083 1083 16 1110 1111 1104 104 108 ) +insert ( 1113 '>=' 11 10 b f f 1083 1083 16 1111 1110 1105 337 398 ) +insert ( 1550 '=' 11 10 b t t 1266 1266 16 1550 1551 1352 101 105 ) +insert ( 1551 '<>' 11 10 b f f 1266 1266 16 1551 1550 1353 102 106 ) +insert ( 1552 '<' 11 10 b f f 1266 1266 16 1554 1555 1354 103 107 ) +insert ( 1553 '<=' 11 10 b f f 1266 1266 16 1555 1554 1355 336 386 ) +insert ( 1554 '>' 11 10 b f f 1266 1266 16 1552 1553 1357 104 108 ) +insert ( 1555 '>=' 11 10 b f f 1266 1266 16 1553 1552 1356 337 398 ) +insert ( 1116 '+' 11 10 b f f 700 701 701 1126 0 281 - - ) +insert ( 1117 - 11 10 b f f 700 701 701 0 0 282 - - ) +insert ( 1118 '/' 11 10 b f f 700 701 701 0 0 280 - - ) +insert ( 1119 '*' 11 10 b f f 700 701 701 1129 0 279 - - ) +insert ( 1120 '=' 11 10 b t t 700 701 16 1130 1121 299 101 105 ) +insert ( 1121 '<>' 11 10 b f f 700 701 16 1131 1120 300 102 106 ) +insert ( 1122 '<' 11 10 b f f 700 701 16 1133 1125 301 103 107 ) +insert ( 1123 '>' 11 10 b f f 700 701 16 1132 1124 303 104 108 ) +insert ( 1124 '<=' 11 10 b f f 700 701 16 1135 1123 302 336 386 ) +insert ( 1125 '>=' 11 10 b f f 700 701 16 1134 1122 304 337 398 ) +insert ( 1126 '+' 11 10 b f f 701 700 701 1116 0 285 - - ) +insert ( 1127 - 11 10 b f f 701 700 701 0 0 286 - - ) +insert ( 1128 '/' 11 10 b f f 701 700 701 0 0 284 - - ) +insert ( 1129 '*' 11 10 b f f 701 700 701 1119 0 283 - - ) +insert ( 1130 '=' 11 10 b t t 701 700 16 1120 1131 305 101 105 ) +insert ( 1131 '<>' 11 10 b f f 701 700 16 1121 1130 306 102 106 ) +insert ( 1132 '<' 11 10 b f f 701 700 16 1123 1135 307 103 107 ) +insert ( 1133 '>' 11 10 b f f 701 700 16 1122 1134 309 104 108 ) +insert ( 1134 '<=' 11 10 b f f 701 700 16 1125 1133 308 336 386 ) +insert ( 1135 '>=' 11 10 b f f 701 700 16 1124 1132 310 337 398 ) +insert ( 1207 '~~' 11 10 b f f 19 25 16 0 1208 858 1819 1825 ) +insert ( 1208 '!~~' 11 10 b f f 19 25 16 0 1207 859 1822 1828 ) +insert ( 1209 '~~' 11 10 b f f 25 25 16 0 1210 850 1819 1825 ) +insert ( 1210 '!~~' 11 10 b f f 25 25 16 0 1209 851 1822 1828 ) +insert ( 1211 '~~' 11 10 b f f 1042 25 16 0 1212 1631 1819 1825 ) +insert ( 1212 '!~~' 11 10 b f f 1042 25 16 0 1211 1632 1822 1828 ) +insert ( 1226 '~*' 11 10 b f f 19 25 16 0 1227 1240 1820 1826 ) +insert ( 1227 '!~*' 11 10 b f f 19 25 16 0 1226 1241 1823 1829 ) +insert ( 1228 '~*' 11 10 b f f 25 25 16 0 1229 1238 1820 1826 ) +insert ( 1229 '!~*' 11 10 b f f 25 25 16 0 1228 1239 1823 1829 ) +insert ( 1234 '~*' 11 10 b f f 1042 25 16 0 1235 1656 1820 1826 ) +insert ( 1235 '!~*' 11 10 b f f 1042 25 16 0 1234 1657 1823 1829 ) +insert ( 1320 '=' 11 10 b t t 1184 1184 16 1320 1321 1152 101 105 ) +insert ( 1321 '<>' 11 10 b f f 1184 1184 16 1321 1320 1153 102 106 ) +insert ( 1322 '<' 11 10 b f f 1184 1184 16 1324 1325 1154 103 107 ) +insert ( 1323 '<=' 11 10 b f f 1184 1184 16 1325 1324 1155 336 386 ) +insert ( 1324 '>' 11 10 b f f 1184 1184 16 1322 1323 1157 104 108 ) +insert ( 1325 '>=' 11 10 b f f 1184 1184 16 1323 1322 1156 337 398 ) +insert ( 1327 '+' 11 10 b f f 1184 1186 1184 2554 0 1189 - - ) +insert ( 1328 - 11 10 b f f 1184 1184 1186 0 0 1188 - - ) +insert ( 1329 - 11 10 b f f 1184 1186 1184 0 0 1190 - - ) +insert ( 1330 '=' 11 10 b t t 1186 1186 16 1330 1331 1162 101 105 ) +insert ( 1331 '<>' 11 10 b f f 1186 1186 16 1331 1330 1163 102 106 ) +insert ( 1332 '<' 11 10 b f f 1186 1186 16 1334 1335 1164 103 107 ) +insert ( 1333 '<=' 11 10 b f f 1186 1186 16 1335 1334 1165 336 386 ) +insert ( 1334 '>' 11 10 b f f 1186 1186 16 1332 1333 1167 104 108 ) +insert ( 1335 '>=' 11 10 b f f 1186 1186 16 1333 1332 1166 337 398 ) +insert ( 1336 - 11 10 l f f 0 1186 1186 0 0 1168 - - ) +insert ( 1337 '+' 11 10 b f f 1186 1186 1186 1337 0 1169 - - ) +insert ( 1338 - 11 10 b f f 1186 1186 1186 0 0 1170 - - ) +insert ( 1360 '+' 11 10 b f f 1082 1083 1114 1363 0 1272 - - ) +insert ( 1361 '+' 11 10 b f f 1082 1266 1184 1366 0 1297 - - ) +insert ( 1363 '+' 11 10 b f f 1083 1082 1114 1360 0 1296 - - ) +insert ( 1366 '+' 11 10 b f f 1266 1082 1184 1361 0 1298 - - ) +insert ( 1399 - 11 10 b f f 1083 1083 1186 0 0 1690 - - ) +insert ( 1420 '@@' 11 10 l f f 0 718 600 0 0 1472 - - ) +insert ( 1500 '=' 11 10 b f f 718 718 16 1500 1501 1462 101 105 ) +insert ( 1501 '<>' 11 10 b f f 718 718 16 1501 1500 1463 102 106 ) +insert ( 1502 '<' 11 10 b f f 718 718 16 1503 1505 1464 139 140 ) +insert ( 1503 '>' 11 10 b f f 718 718 16 1502 1504 1465 139 140 ) +insert ( 1504 '<=' 11 10 b f f 718 718 16 1505 1503 1466 139 140 ) +insert ( 1505 '>=' 11 10 b f f 718 718 16 1504 1502 1467 139 140 ) +insert ( 1506 '<<' 11 10 b f f 718 718 16 0 0 1454 1300 1301 ) +insert ( 1507 '&<' 11 10 b f f 718 718 16 0 0 1455 1300 1301 ) +insert ( 1508 '&>' 11 10 b f f 718 718 16 0 0 1456 1300 1301 ) +insert ( 1509 '>>' 11 10 b f f 718 718 16 0 0 1457 1300 1301 ) +insert ( 1510 '<@' 11 10 b f f 718 718 16 1511 0 1458 1302 1303 ) +insert ( 1511 '@>' 11 10 b f f 718 718 16 1510 0 1453 1302 1303 ) +insert ( 1512 '~=' 11 10 b f f 718 718 16 1512 0 1452 101 105 ) +insert ( 1513 '&&' 11 10 b f f 718 718 16 1513 0 1459 139 140 ) +insert ( 1514 '|>>' 11 10 b f f 718 718 16 0 0 1461 1300 1301 ) +insert ( 1515 '<<|' 11 10 b f f 718 718 16 0 0 1460 1300 1301 ) +insert ( 1516 '+' 11 10 b f f 718 600 718 0 0 1146 - - ) +insert ( 1517 - 11 10 b f f 718 600 718 0 0 1147 - - ) +insert ( 1518 '*' 11 10 b f f 718 600 718 0 0 1148 - - ) +insert ( 1519 '/' 11 10 b f f 718 600 718 0 0 1149 - - ) +insert ( 1520 '<->' 11 10 b f f 718 718 701 1520 0 1471 - - ) +insert ( 1521 '#' 11 10 l f f 0 604 23 0 0 1445 - - ) +insert ( 1522 '<->' 11 10 b f f 600 718 701 3291 0 1476 - - ) +insert ( 3291 '<->' 11 10 b f f 718 600 701 1522 0 3290 - - ) +insert ( 3276 '<->' 11 10 b f f 600 604 701 3289 0 3275 - - ) +insert ( 3289 '<->' 11 10 b f f 604 600 701 3276 0 3292 - - ) +insert ( 1523 '<->' 11 10 b f f 718 604 701 1383 0 728 - - ) +insert ( 1383 '<->' 11 10 b f f 604 718 701 1523 0 785 - - ) +insert ( 1525 '?#' 11 10 b f f 601 601 16 1525 0 994 - - ) +insert ( 1526 '?||' 11 10 b f f 601 601 16 1526 0 995 - - ) +insert ( 1527 '?-|' 11 10 b f f 601 601 16 1527 0 996 - - ) +insert ( 1528 '?-' 11 10 l f f 0 601 16 0 0 998 - - ) +insert ( 1529 '?|' 11 10 l f f 0 601 16 0 0 997 - - ) +insert ( 1535 '=' 11 10 b f f 601 601 16 1535 1586 999 101 105 ) +insert ( 1536 '#' 11 10 b f f 601 601 600 1536 0 362 - - ) +insert ( 1537 '?#' 11 10 b f f 601 628 16 0 0 277 - - ) +insert ( 1538 '?#' 11 10 b f f 601 603 16 0 0 373 - - ) +insert ( 1539 '?#' 11 10 b f f 628 603 16 0 0 278 - - ) +insert ( 1546 '<@' 11 10 b f f 600 628 16 0 0 959 - - ) +insert ( 1547 '<@' 11 10 b f f 600 601 16 0 0 369 - - ) +insert ( 1548 '<@' 11 10 b f f 601 628 16 0 0 960 - - ) +insert ( 1549 '<@' 11 10 b f f 601 603 16 0 0 372 - - ) +insert ( 1557 '##' 11 10 b f f 600 628 600 0 0 961 - - ) +insert ( 1558 '##' 11 10 b f f 600 601 600 0 0 366 - - ) +insert ( 1559 '##' 11 10 b f f 600 603 600 0 0 367 - - ) +insert ( 1567 '##' 11 10 b f f 601 603 600 0 0 368 - - ) +insert ( 1577 '##' 11 10 b f f 628 601 600 0 0 1488 - - ) +insert ( 1578 '##' 11 10 b f f 601 601 600 0 0 1489 - - ) +insert ( 1583 '*' 11 10 b f f 1186 701 1186 1584 0 1618 - - ) +insert ( 1584 '*' 11 10 b f f 701 1186 1186 1583 0 1624 - - ) +insert ( 1585 '/' 11 10 b f f 1186 701 1186 0 0 1326 - - ) +insert ( 1586 '<>' 11 10 b f f 601 601 16 1586 1535 1482 102 106 ) +insert ( 1587 '<' 11 10 b f f 601 601 16 1589 1590 1483 - - ) +insert ( 1588 '<=' 11 10 b f f 601 601 16 1590 1589 1484 - - ) +insert ( 1589 '>' 11 10 b f f 601 601 16 1587 1588 1485 - - ) +insert ( 1590 '>=' 11 10 b f f 601 601 16 1588 1587 1486 - - ) +insert ( 1591 '@-@' 11 10 l f f 0 601 701 0 0 1487 - - ) +insert ( 1611 '?#' 11 10 b f f 628 628 16 1611 0 1495 - - ) +insert ( 1612 '?||' 11 10 b f f 628 628 16 1612 0 1496 - - ) +insert ( 1613 '?-|' 11 10 b f f 628 628 16 1613 0 1497 - - ) +insert ( 1614 '?-' 11 10 l f f 0 628 16 0 0 1499 - - ) +insert ( 1615 '?|' 11 10 l f f 0 628 16 0 0 1498 - - ) +insert ( 1616 '=' 11 10 b f f 628 628 16 1616 0 1492 101 105 ) +insert ( 1617 '#' 11 10 b f f 628 628 600 1617 0 1494 - - ) +insert ( 4161 '|>>' 11 10 b f f 600 600 16 0 0 131 1300 1301 ) +insert ( 4162 '<<|' 11 10 b f f 600 600 16 0 0 134 1300 1301 ) +insert ( 1220 '=' 11 10 b t t 829 829 16 1220 1221 830 101 105 ) +insert ( 1221 '<>' 11 10 b f f 829 829 16 1221 1220 835 102 106 ) +insert ( 1222 '<' 11 10 b f f 829 829 16 1224 1225 831 103 107 ) +insert ( 1223 '<=' 11 10 b f f 829 829 16 1225 1224 832 336 386 ) +insert ( 1224 '>' 11 10 b f f 829 829 16 1222 1223 833 104 108 ) +insert ( 1225 '>=' 11 10 b f f 829 829 16 1223 1222 834 337 398 ) +insert ( 3147 '~' 11 10 l f f 0 829 829 0 0 3144 - - ) +insert ( 3148 '&' 11 10 b f f 829 829 829 0 0 3145 - - ) +insert ( 3149 '|' 11 10 b f f 829 829 829 0 0 3146 - - ) +insert ( 3362 '=' 11 10 b t t 774 774 16 3362 3363 4113 101 105 ) +insert ( 3363 '<>' 11 10 b f f 774 774 16 3363 3362 4118 102 106 ) +insert ( 3364 '<' 11 10 b f f 774 774 16 3366 3367 4114 103 107 ) +insert ( 3365 '<=' 11 10 b f f 774 774 16 3367 3366 4115 336 386 ) +insert ( 3366 '>' 11 10 b f f 774 774 16 3364 3365 4116 104 108 ) +insert ( 3367 '>=' 11 10 b f f 774 774 16 3365 3364 4117 337 398 ) +insert ( 3368 '~' 11 10 l f f 0 774 774 0 0 4120 - - ) +insert ( 3369 '&' 11 10 b f f 774 774 774 0 0 4121 - - ) +insert ( 3370 '|' 11 10 b f f 774 774 774 0 0 4122 - - ) +insert ( 1201 '=' 11 10 b t t 869 869 16 1201 1202 920 101 105 ) +insert ( 1202 '<>' 11 10 b f f 869 869 16 1202 1201 925 102 106 ) +insert ( 1203 '<' 11 10 b f f 869 869 16 1205 1206 921 103 107 ) +insert ( 1204 '<=' 11 10 b f f 869 869 16 1206 1205 922 336 386 ) +insert ( 1205 '>' 11 10 b f f 869 869 16 1203 1204 923 104 108 ) +insert ( 1206 '>=' 11 10 b f f 869 869 16 1204 1203 924 337 398 ) +insert ( 931 '<<' 11 10 b f f 869 869 16 933 0 927 3560 3561 ) +insert ( 932 '<<=' 11 10 b f f 869 869 16 934 0 928 3560 3561 ) +insert ( 933 '>>' 11 10 b f f 869 869 16 931 0 929 3560 3561 ) +insert ( 934 '>>=' 11 10 b f f 869 869 16 932 0 930 3560 3561 ) +insert ( 3552 '&&' 11 10 b f f 869 869 16 3552 0 3551 3560 3561 ) +insert ( 2634 '~' 11 10 l f f 0 869 869 0 0 2627 - - ) +insert ( 2635 '&' 11 10 b f f 869 869 869 0 0 2628 - - ) +insert ( 2636 '|' 11 10 b f f 869 869 869 0 0 2629 - - ) +insert ( 2637 '+' 11 10 b f f 869 20 869 2638 0 2630 - - ) +insert ( 2638 '+' 11 10 b f f 20 869 869 2637 0 2631 - - ) +insert ( 2639 - 11 10 b f f 869 20 869 0 0 2632 - - ) +insert ( 2640 - 11 10 b f f 869 869 20 0 0 2633 - - ) +insert ( 1625 '~~*' 11 10 b f f 19 25 16 0 1626 1635 1814 1816 ) +insert ( 1626 '!~~*' 11 10 b f f 19 25 16 0 1625 1636 1815 1817 ) +insert ( 1627 '~~*' 11 10 b f f 25 25 16 0 1628 1633 1814 1816 ) +insert ( 1628 '!~~*' 11 10 b f f 25 25 16 0 1627 1634 1815 1817 ) +insert ( 1629 '~~*' 11 10 b f f 1042 25 16 0 1630 1660 1814 1816 ) +insert ( 1630 '!~~*' 11 10 b f f 1042 25 16 0 1629 1661 1815 1817 ) +insert ( 1751 - 11 10 l f f 0 1700 1700 0 0 1771 - - ) +insert ( 1752 '=' 11 10 b t t 1700 1700 16 1752 1753 1718 101 105 ) +insert ( 1753 '<>' 11 10 b f f 1700 1700 16 1753 1752 1719 102 106 ) +insert ( 1754 '<' 11 10 b f f 1700 1700 16 1756 1757 1722 103 107 ) +insert ( 1755 '<=' 11 10 b f f 1700 1700 16 1757 1756 1723 336 386 ) +insert ( 1756 '>' 11 10 b f f 1700 1700 16 1754 1755 1720 104 108 ) +insert ( 1757 '>=' 11 10 b f f 1700 1700 16 1755 1754 1721 337 398 ) +insert ( 1758 '+' 11 10 b f f 1700 1700 1700 1758 0 1724 - - ) +insert ( 1759 - 11 10 b f f 1700 1700 1700 0 0 1725 - - ) +insert ( 1760 '*' 11 10 b f f 1700 1700 1700 1760 0 1726 - - ) +insert ( 1761 '/' 11 10 b f f 1700 1700 1700 0 0 1727 - - ) +insert ( 1762 '%' 11 10 b f f 1700 1700 1700 0 0 1729 - - ) +insert ( 1038 '^' 11 10 b f f 1700 1700 1700 0 0 1739 - - ) +insert ( 1763 '@' 11 10 l f f 0 1700 1700 0 0 1704 - - ) +insert ( 1784 '=' 11 10 b t f 1560 1560 16 1784 1785 1581 101 105 ) +insert ( 1785 '<>' 11 10 b f f 1560 1560 16 1785 1784 1582 102 106 ) +insert ( 1786 '<' 11 10 b f f 1560 1560 16 1787 1789 1595 103 107 ) +insert ( 1787 '>' 11 10 b f f 1560 1560 16 1786 1788 1593 104 108 ) +insert ( 1788 '<=' 11 10 b f f 1560 1560 16 1789 1787 1594 336 386 ) +insert ( 1789 '>=' 11 10 b f f 1560 1560 16 1788 1786 1592 337 398 ) +insert ( 1791 '&' 11 10 b f f 1560 1560 1560 1791 0 1673 - - ) +insert ( 1792 '|' 11 10 b f f 1560 1560 1560 1792 0 1674 - - ) +insert ( 1793 '#' 11 10 b f f 1560 1560 1560 1793 0 1675 - - ) +insert ( 1794 '~' 11 10 l f f 0 1560 1560 0 0 1676 - - ) +insert ( 1795 '<<' 11 10 b f f 1560 23 1560 0 0 1677 - - ) +insert ( 1796 '>>' 11 10 b f f 1560 23 1560 0 0 1678 - - ) +insert ( 1797 '||' 11 10 b f f 1562 1562 1562 0 0 1679 - - ) +insert ( 1800 '+' 11 10 b f f 1083 1186 1083 1849 0 1747 - - ) +insert ( 1801 - 11 10 b f f 1083 1186 1083 0 0 1748 - - ) +insert ( 1802 '+' 11 10 b f f 1266 1186 1266 2552 0 1749 - - ) +insert ( 1803 - 11 10 b f f 1266 1186 1266 0 0 1750 - - ) +insert ( 1804 '=' 11 10 b t f 1562 1562 16 1804 1805 1666 101 105 ) +insert ( 1805 '<>' 11 10 b f f 1562 1562 16 1805 1804 1667 102 106 ) +insert ( 1806 '<' 11 10 b f f 1562 1562 16 1807 1809 1671 103 107 ) +insert ( 1807 '>' 11 10 b f f 1562 1562 16 1806 1808 1669 104 108 ) +insert ( 1808 '<=' 11 10 b f f 1562 1562 16 1809 1807 1670 336 386 ) +insert ( 1809 '>=' 11 10 b f f 1562 1562 16 1808 1806 1668 337 398 ) +insert ( 1849 '+' 11 10 b f f 1186 1083 1083 1800 0 1848 - - ) +insert ( 1862 '=' 11 10 b t t 21 20 16 1868 1863 1850 101 105 ) +insert ( 1863 '<>' 11 10 b f f 21 20 16 1869 1862 1851 102 106 ) +insert ( 1864 '<' 11 10 b f f 21 20 16 1871 1867 1852 103 107 ) +insert ( 1865 '>' 11 10 b f f 21 20 16 1870 1866 1853 104 108 ) +insert ( 1866 '<=' 11 10 b f f 21 20 16 1873 1865 1854 336 386 ) +insert ( 1867 '>=' 11 10 b f f 21 20 16 1872 1864 1855 337 398 ) +insert ( 1868 '=' 11 10 b t t 20 21 16 1862 1869 1856 101 105 ) +insert ( 1869 '<>' 11 10 b f f 20 21 16 1863 1868 1857 102 106 ) +insert ( 1870 '<' 11 10 b f f 20 21 16 1865 1873 1858 103 107 ) +insert ( 1871 '>' 11 10 b f f 20 21 16 1864 1872 1859 104 108 ) +insert ( 1872 '<=' 11 10 b f f 20 21 16 1867 1871 1860 336 386 ) +insert ( 1873 '>=' 11 10 b f f 20 21 16 1866 1870 1861 337 398 ) +insert ( 1874 '&' 11 10 b f f 21 21 21 1874 0 1892 - - ) +insert ( 1875 '|' 11 10 b f f 21 21 21 1875 0 1893 - - ) +insert ( 1876 '#' 11 10 b f f 21 21 21 1876 0 1894 - - ) +insert ( 1877 '~' 11 10 l f f 0 21 21 0 0 1895 - - ) +insert ( 1878 '<<' 11 10 b f f 21 23 21 0 0 1896 - - ) +insert ( 1879 '>>' 11 10 b f f 21 23 21 0 0 1897 - - ) +insert ( 1880 '&' 11 10 b f f 23 23 23 1880 0 1898 - - ) +insert ( 1881 '|' 11 10 b f f 23 23 23 1881 0 1899 - - ) +insert ( 1882 '#' 11 10 b f f 23 23 23 1882 0 1900 - - ) +insert ( 1883 '~' 11 10 l f f 0 23 23 0 0 1901 - - ) +insert ( 1884 '<<' 11 10 b f f 23 23 23 0 0 1902 - - ) +insert ( 1885 '>>' 11 10 b f f 23 23 23 0 0 1903 - - ) +insert ( 1886 '&' 11 10 b f f 20 20 20 1886 0 1904 - - ) +insert ( 1887 '|' 11 10 b f f 20 20 20 1887 0 1905 - - ) +insert ( 1888 '#' 11 10 b f f 20 20 20 1888 0 1906 - - ) +insert ( 1889 '~' 11 10 l f f 0 20 20 0 0 1907 - - ) +insert ( 1890 '<<' 11 10 b f f 20 23 20 0 0 1908 - - ) +insert ( 1891 '>>' 11 10 b f f 20 23 20 0 0 1909 - - ) +insert ( 1916 '+' 11 10 l f f 0 20 20 0 0 1910 - - ) +insert ( 1917 '+' 11 10 l f f 0 21 21 0 0 1911 - - ) +insert ( 1918 '+' 11 10 l f f 0 23 23 0 0 1912 - - ) +insert ( 1919 '+' 11 10 l f f 0 700 700 0 0 1913 - - ) +insert ( 1920 '+' 11 10 l f f 0 701 701 0 0 1914 - - ) +insert ( 1921 '+' 11 10 l f f 0 1700 1700 0 0 1915 - - ) +insert ( 1955 '=' 11 10 b t t 17 17 16 1955 1956 1948 101 105 ) +insert ( 1956 '<>' 11 10 b f f 17 17 16 1956 1955 1953 102 106 ) +insert ( 1957 '<' 11 10 b f f 17 17 16 1959 1960 1949 103 107 ) +insert ( 1958 '<=' 11 10 b f f 17 17 16 1960 1959 1950 336 386 ) +insert ( 1959 '>' 11 10 b f f 17 17 16 1957 1958 1951 104 108 ) +insert ( 1960 '>=' 11 10 b f f 17 17 16 1958 1957 1952 337 398 ) +insert ( 2016 '~~' 11 10 b f f 17 17 16 0 2017 2005 1819 1825 ) +insert ( 2017 '!~~' 11 10 b f f 17 17 16 0 2016 2006 1822 1828 ) +insert ( 2018 '||' 11 10 b f f 17 17 17 0 0 2011 - - ) +insert ( 2060 '=' 11 10 b t t 1114 1114 16 2060 2061 2052 101 105 ) +insert ( 2061 '<>' 11 10 b f f 1114 1114 16 2061 2060 2053 102 106 ) +insert ( 2062 '<' 11 10 b f f 1114 1114 16 2064 2065 2054 103 107 ) +insert ( 2063 '<=' 11 10 b f f 1114 1114 16 2065 2064 2055 336 386 ) +insert ( 2064 '>' 11 10 b f f 1114 1114 16 2062 2063 2057 104 108 ) +insert ( 2065 '>=' 11 10 b f f 1114 1114 16 2063 2062 2056 337 398 ) +insert ( 2066 '+' 11 10 b f f 1114 1186 1114 2553 0 2032 - - ) +insert ( 2067 - 11 10 b f f 1114 1114 1186 0 0 2031 - - ) +insert ( 2068 - 11 10 b f f 1114 1186 1114 0 0 2033 - - ) +insert ( 2314 '~<~' 11 10 b f f 25 25 16 2318 2317 2160 103 107 ) +insert ( 2315 '~<=~' 11 10 b f f 25 25 16 2317 2318 2161 336 386 ) +insert ( 2317 '~>=~' 11 10 b f f 25 25 16 2315 2314 2163 337 398 ) +insert ( 2318 '~>~' 11 10 b f f 25 25 16 2314 2315 2164 104 108 ) +insert ( 2326 '~<~' 11 10 b f f 1042 1042 16 2330 2329 2174 103 107 ) +insert ( 2327 '~<=~' 11 10 b f f 1042 1042 16 2329 2330 2175 336 386 ) +insert ( 2329 '~>=~' 11 10 b f f 1042 1042 16 2327 2326 2177 337 398 ) +insert ( 2330 '~>~' 11 10 b f f 1042 1042 16 2326 2327 2178 104 108 ) +insert ( 2345 '<' 11 10 b f f 1082 1114 16 2375 2348 2338 103 107 ) +insert ( 2346 '<=' 11 10 b f f 1082 1114 16 2374 2349 2339 336 386 ) +insert ( 2347 '=' 11 10 b t f 1082 1114 16 2373 2350 2340 101 105 ) +insert ( 2348 '>=' 11 10 b f f 1082 1114 16 2372 2345 2342 337 398 ) +insert ( 2349 '>' 11 10 b f f 1082 1114 16 2371 2346 2341 104 108 ) +insert ( 2350 '<>' 11 10 b f f 1082 1114 16 2376 2347 2343 102 106 ) +insert ( 2358 '<' 11 10 b f f 1082 1184 16 2388 2361 2351 103 107 ) +insert ( 2359 '<=' 11 10 b f f 1082 1184 16 2387 2362 2352 336 386 ) +insert ( 2360 '=' 11 10 b t f 1082 1184 16 2386 2363 2353 101 105 ) +insert ( 2361 '>=' 11 10 b f f 1082 1184 16 2385 2358 2355 337 398 ) +insert ( 2362 '>' 11 10 b f f 1082 1184 16 2384 2359 2354 104 108 ) +insert ( 2363 '<>' 11 10 b f f 1082 1184 16 2389 2360 2356 102 106 ) +insert ( 2371 '<' 11 10 b f f 1114 1082 16 2349 2374 2364 103 107 ) +insert ( 2372 '<=' 11 10 b f f 1114 1082 16 2348 2375 2365 336 386 ) +insert ( 2373 '=' 11 10 b t f 1114 1082 16 2347 2376 2366 101 105 ) +insert ( 2374 '>=' 11 10 b f f 1114 1082 16 2346 2371 2368 337 398 ) +insert ( 2375 '>' 11 10 b f f 1114 1082 16 2345 2372 2367 104 108 ) +insert ( 2376 '<>' 11 10 b f f 1114 1082 16 2350 2373 2369 102 106 ) +insert ( 2384 '<' 11 10 b f f 1184 1082 16 2362 2387 2377 103 107 ) +insert ( 2385 '<=' 11 10 b f f 1184 1082 16 2361 2388 2378 336 386 ) +insert ( 2386 '=' 11 10 b t f 1184 1082 16 2360 2389 2379 101 105 ) +insert ( 2387 '>=' 11 10 b f f 1184 1082 16 2359 2384 2381 337 398 ) +insert ( 2388 '>' 11 10 b f f 1184 1082 16 2358 2385 2380 104 108 ) +insert ( 2389 '<>' 11 10 b f f 1184 1082 16 2363 2386 2382 102 106 ) +insert ( 2534 '<' 11 10 b f f 1114 1184 16 2544 2537 2520 103 107 ) +insert ( 2535 '<=' 11 10 b f f 1114 1184 16 2543 2538 2521 336 386 ) +insert ( 2536 '=' 11 10 b t f 1114 1184 16 2542 2539 2522 101 105 ) +insert ( 2537 '>=' 11 10 b f f 1114 1184 16 2541 2534 2524 337 398 ) +insert ( 2538 '>' 11 10 b f f 1114 1184 16 2540 2535 2523 104 108 ) +insert ( 2539 '<>' 11 10 b f f 1114 1184 16 2545 2536 2525 102 106 ) +insert ( 2540 '<' 11 10 b f f 1184 1114 16 2538 2543 2527 103 107 ) +insert ( 2541 '<=' 11 10 b f f 1184 1114 16 2537 2544 2528 336 386 ) +insert ( 2542 '=' 11 10 b t f 1184 1114 16 2536 2545 2529 101 105 ) +insert ( 2543 '>=' 11 10 b f f 1184 1114 16 2535 2540 2531 337 398 ) +insert ( 2544 '>' 11 10 b f f 1184 1114 16 2534 2541 2530 104 108 ) +insert ( 2545 '<>' 11 10 b f f 1184 1114 16 2539 2542 2532 102 106 ) +insert ( 2551 '+' 11 10 b f f 1186 1082 1114 1076 0 2546 - - ) +insert ( 2552 '+' 11 10 b f f 1186 1266 1266 1802 0 2547 - - ) +insert ( 2553 '+' 11 10 b f f 1186 1114 1114 2066 0 2548 - - ) +insert ( 2554 '+' 11 10 b f f 1186 1184 1184 1327 0 2549 - - ) +insert ( 2555 '+' 11 10 b f f 23 1082 1082 1100 0 2550 - - ) +insert ( 2570 '<<|' 11 10 b f f 603 603 16 0 0 2562 1300 1301 ) +insert ( 2571 '&<|' 11 10 b f f 603 603 16 0 0 2563 1300 1301 ) +insert ( 2572 '|&>' 11 10 b f f 603 603 16 0 0 2564 1300 1301 ) +insert ( 2573 '|>>' 11 10 b f f 603 603 16 0 0 2565 1300 1301 ) +insert ( 2574 '<<|' 11 10 b f f 604 604 16 0 0 2566 1300 1301 ) +insert ( 2575 '&<|' 11 10 b f f 604 604 16 0 0 2567 1300 1301 ) +insert ( 2576 '|&>' 11 10 b f f 604 604 16 0 0 2568 1300 1301 ) +insert ( 2577 '|>>' 11 10 b f f 604 604 16 0 0 2569 1300 1301 ) +insert ( 2589 '&<|' 11 10 b f f 718 718 16 0 0 2587 1300 1301 ) +insert ( 2590 '|&>' 11 10 b f f 718 718 16 0 0 2588 1300 1301 ) +insert ( 2750 '&&' 11 10 b f f 2277 2277 16 2750 0 2747 3817 3818 ) +insert ( 2751 '@>' 11 10 b f f 2277 2277 16 2752 0 2748 3817 3818 ) +insert ( 2752 '<@' 11 10 b f f 2277 2277 16 2751 0 2749 3817 3818 ) +insert ( 2779 '||' 11 10 b f f 25 2776 25 0 0 2003 - - ) +insert ( 2780 '||' 11 10 b f f 2776 25 25 0 0 2004 - - ) +insert ( 2972 '=' 11 10 b t t 2950 2950 16 2972 2973 2956 101 105 ) +insert ( 2973 '<>' 11 10 b f f 2950 2950 16 2973 2972 2959 102 106 ) +insert ( 2974 '<' 11 10 b f f 2950 2950 16 2975 2977 2954 103 107 ) +insert ( 2975 '>' 11 10 b f f 2950 2950 16 2974 2976 2958 104 108 ) +insert ( 2976 '<=' 11 10 b f f 2950 2950 16 2977 2975 2955 336 386 ) +insert ( 2977 '>=' 11 10 b f f 2950 2950 16 2976 2974 2957 337 398 ) +insert ( 3222 '=' 11 10 b t t 3220 3220 16 3222 3223 3233 101 105 ) +insert ( 3223 '<>' 11 10 b f f 3220 3220 16 3223 3222 3236 102 106 ) +insert ( 3224 '<' 11 10 b f f 3220 3220 16 3225 3227 3231 103 107 ) +insert ( 3225 '>' 11 10 b f f 3220 3220 16 3224 3226 3235 104 108 ) +insert ( 3226 '<=' 11 10 b f f 3220 3220 16 3227 3225 3232 336 386 ) +insert ( 3227 '>=' 11 10 b f f 3220 3220 16 3226 3224 3234 337 398 ) +insert ( 3228 - 11 10 b f f 3220 3220 1700 0 0 3237 - - ) +insert ( 5025 '+' 11 10 b f f 3220 1700 3220 5026 0 5022 - - ) +insert ( 5026 '+' 11 10 b f f 1700 3220 3220 5025 0 5023 - - ) +insert ( 5027 - 11 10 b f f 3220 1700 3220 0 0 5024 - - ) +insert ( 3516 '=' 11 10 b t t 3500 3500 16 3516 3517 3508 101 105 ) +insert ( 3517 '<>' 11 10 b f f 3500 3500 16 3517 3516 3509 102 106 ) +insert ( 3518 '<' 11 10 b f f 3500 3500 16 3519 3521 3510 103 107 ) +insert ( 3519 '>' 11 10 b f f 3500 3500 16 3518 3520 3511 104 108 ) +insert ( 3520 '<=' 11 10 b f f 3500 3500 16 3521 3519 3512 336 386 ) +insert ( 3521 '>=' 11 10 b f f 3500 3500 16 3520 3518 3513 337 398 ) +insert ( 3627 '<' 11 10 b f f 3614 3614 16 3632 3631 3616 103 107 ) +insert ( 3628 '<=' 11 10 b f f 3614 3614 16 3631 3632 3617 336 386 ) +insert ( 3629 '=' 11 10 b t f 3614 3614 16 3629 3630 3618 101 105 ) +insert ( 3630 '<>' 11 10 b f f 3614 3614 16 3630 3629 3619 102 106 ) +insert ( 3631 '>=' 11 10 b f f 3614 3614 16 3628 3627 3620 337 398 ) +insert ( 3632 '>' 11 10 b f f 3614 3614 16 3627 3628 3621 104 108 ) +insert ( 3633 '||' 11 10 b f f 3614 3614 3614 0 0 3625 - - ) +insert ( 3636 '@@' 11 10 b f f 3614 3615 16 3637 0 3634 3686 3687 ) +insert ( 3637 '@@' 11 10 b f f 3615 3614 16 3636 0 3635 3686 3687 ) +insert ( 3660 '@@@' 11 10 b f f 3614 3615 16 3661 0 3634 3686 3687 ) +insert ( 3661 '@@@' 11 10 b f f 3615 3614 16 3660 0 3635 3686 3687 ) +insert ( 3674 '<' 11 10 b f f 3615 3615 16 3679 3678 3662 103 107 ) +insert ( 3675 '<=' 11 10 b f f 3615 3615 16 3678 3679 3663 336 386 ) +insert ( 3676 '=' 11 10 b t f 3615 3615 16 3676 3677 3664 101 105 ) +insert ( 3677 '<>' 11 10 b f f 3615 3615 16 3677 3676 3665 102 106 ) +insert ( 3678 '>=' 11 10 b f f 3615 3615 16 3675 3674 3666 337 398 ) +insert ( 3679 '>' 11 10 b f f 3615 3615 16 3674 3675 3667 104 108 ) +insert ( 3680 '&&' 11 10 b f f 3615 3615 3615 0 0 3669 - - ) +insert ( 3681 '||' 11 10 b f f 3615 3615 3615 0 0 3670 - - ) +insert ( 5005 '<->' 11 10 b f f 3615 3615 3615 0 0 5003 - - ) +insert ( 3682 '!!' 11 10 l f f 0 3615 3615 0 0 3671 - - ) +insert ( 3693 '@>' 11 10 b f f 3615 3615 16 3694 0 3691 5040 5041 ) +insert ( 3694 '<@' 11 10 b f f 3615 3615 16 3693 0 3692 5040 5041 ) +insert ( 3762 '@@' 11 10 b f f 25 25 16 0 0 3760 5040 5041 ) +insert ( 3763 '@@' 11 10 b f f 25 3615 16 0 0 3761 5040 5041 ) +insert ( 2988 '=' 11 10 b t t 2249 2249 16 2988 2989 2981 101 105 ) +insert ( 2989 '<>' 11 10 b f f 2249 2249 16 2989 2988 2982 102 106 ) +insert ( 2990 '<' 11 10 b f f 2249 2249 16 2991 2993 2983 103 107 ) +insert ( 2991 '>' 11 10 b f f 2249 2249 16 2990 2992 2984 104 108 ) +insert ( 2992 '<=' 11 10 b f f 2249 2249 16 2993 2991 2985 336 386 ) +insert ( 2993 '>=' 11 10 b f f 2249 2249 16 2992 2990 2986 337 398 ) +insert ( 3188 '*=' 11 10 b t f 2249 2249 16 3188 3189 3181 101 105 ) +insert ( 3189 '*<>' 11 10 b f f 2249 2249 16 3189 3188 3182 102 106 ) +insert ( 3190 '*<' 11 10 b f f 2249 2249 16 3191 3193 3183 103 107 ) +insert ( 3191 '*>' 11 10 b f f 2249 2249 16 3190 3192 3184 104 108 ) +insert ( 3192 '*<=' 11 10 b f f 2249 2249 16 3193 3191 3185 336 386 ) +insert ( 3193 '*>=' 11 10 b f f 2249 2249 16 3192 3190 3186 337 398 ) +insert ( 3882 '=' 11 10 b t t 3831 3831 16 3882 3883 3855 101 105 ) +insert ( 3883 '<>' 11 10 b f f 3831 3831 16 3883 3882 3856 102 106 ) +insert ( 3884 '<' 11 10 b f f 3831 3831 16 3887 3886 3871 3169 107 ) +insert ( 3885 '<=' 11 10 b f f 3831 3831 16 3886 3887 3872 3169 386 ) +insert ( 3886 '>=' 11 10 b f f 3831 3831 16 3885 3884 3873 3169 398 ) +insert ( 3887 '>' 11 10 b f f 3831 3831 16 3884 3885 3874 3169 108 ) +insert ( 3888 '&&' 11 10 b f f 3831 3831 16 3888 0 3857 3169 140 ) +insert ( 3889 '@>' 11 10 b f f 3831 2283 16 3891 0 3858 3169 1303 ) +insert ( 3890 '@>' 11 10 b f f 3831 3831 16 3892 0 3859 3169 1303 ) +insert ( 3891 '<@' 11 10 b f f 2283 3831 16 3889 0 3860 3169 1303 ) +insert ( 3892 '<@' 11 10 b f f 3831 3831 16 3890 0 3861 3169 1303 ) +insert ( 3893 '<<' 11 10 b f f 3831 3831 16 3894 0 3863 3169 107 ) +insert ( 3894 '>>' 11 10 b f f 3831 3831 16 3893 0 3864 3169 108 ) +insert ( 3895 '&<' 11 10 b f f 3831 3831 16 0 0 3865 3169 107 ) +insert ( 3896 '&>' 11 10 b f f 3831 3831 16 0 0 3866 3169 108 ) +insert ( 3897 '-|-' 11 10 b f f 3831 3831 16 3897 0 3862 5040 5041 ) +insert ( 3898 '+' 11 10 b f f 3831 3831 3831 3898 0 3867 - - ) +insert ( 3899 - 11 10 b f f 3831 3831 3831 0 0 3869 - - ) +insert ( 3900 '*' 11 10 b f f 3831 3831 3831 3900 0 3868 - - ) +insert ( 3962 '->' 11 10 b f f 114 25 114 0 0 3947 - - ) +insert ( 3963 '->>' 11 10 b f f 114 25 25 0 0 3948 - - ) +insert ( 3964 '->' 11 10 b f f 114 23 114 0 0 3949 - - ) +insert ( 3965 '->>' 11 10 b f f 114 23 25 0 0 3950 - - ) +insert ( 3966 '#>' 11 10 b f f 114 1009 114 0 0 3951 - - ) +insert ( 3967 '#>>' 11 10 b f f 114 1009 25 0 0 3953 - - ) +insert ( 3211 '->' 11 10 b f f 3802 25 3802 0 0 3478 - - ) +insert ( 3477 '->>' 11 10 b f f 3802 25 25 0 0 3214 - - ) +insert ( 3212 '->' 11 10 b f f 3802 23 3802 0 0 3215 - - ) +insert ( 3481 '->>' 11 10 b f f 3802 23 25 0 0 3216 - - ) +insert ( 3213 '#>' 11 10 b f f 3802 1009 3802 0 0 3217 - - ) +insert ( 3206 '#>>' 11 10 b f f 3802 1009 25 0 0 3940 - - ) +insert ( 3240 '=' 11 10 b t t 3802 3802 16 3240 3241 4043 101 105 ) +insert ( 3241 '<>' 11 10 b f f 3802 3802 16 3241 3240 4038 102 106 ) +insert ( 3242 '<' 11 10 b f f 3802 3802 16 3243 3245 4039 103 107 ) +insert ( 3243 '>' 11 10 b f f 3802 3802 16 3242 3244 4040 104 108 ) +insert ( 3244 '<=' 11 10 b f f 3802 3802 16 3245 3243 4041 336 386 ) +insert ( 3245 '>=' 11 10 b f f 3802 3802 16 3244 3242 4042 337 398 ) +insert ( 3246 '@>' 11 10 b f f 3802 3802 16 3250 0 4046 5040 5041 ) +insert ( 3247 '?' 11 10 b f f 3802 25 16 0 0 4047 5040 5041 ) +insert ( 3248 '?|' 11 10 b f f 3802 1009 16 0 0 4048 5040 5041 ) +insert ( 3249 '?&' 11 10 b f f 3802 1009 16 0 0 4049 5040 5041 ) +insert ( 3250 '<@' 11 10 b f f 3802 3802 16 3246 0 4050 5040 5041 ) +insert ( 3284 '||' 11 10 b f f 3802 3802 3802 0 0 3301 - - ) +insert ( 3285 - 11 10 b f f 3802 25 3802 0 0 3302 - - ) +insert ( 3398 - 11 10 b f f 3802 1009 3802 0 0 3343 - - ) +insert ( 3286 - 11 10 b f f 3802 23 3802 0 0 3303 - - ) +insert ( 3287 '#-' 11 10 b f f 3802 1009 3802 0 0 3304 - - ) +insert ( 4012 '@?' 11 10 b f f 3802 4072 16 0 0 4010 5040 5041 ) +insert ( 4013 '@@' 11 10 b f f 3802 4072 16 0 0 4011 5040 5041 ) +insert ( 2860 '=' 11 10 b t t 4537 4537 16 2860 2861 4244 101 105 ) +insert ( 2861 '<>' 11 10 b f f 4537 4537 16 2861 2860 4245 102 106 ) +insert ( 2862 '<' 11 10 b f f 4537 4537 16 2865 2864 4274 4243 107 ) +insert ( 2863 '<=' 11 10 b f f 4537 4537 16 2864 2865 4275 4243 386 ) +insert ( 2864 '>=' 11 10 b f f 4537 4537 16 2863 2862 4276 4243 398 ) +insert ( 2865 '>' 11 10 b f f 4537 4537 16 2862 2863 4277 4243 108 ) +insert ( 2866 '&&' 11 10 b f f 3831 4537 16 2867 0 4246 4243 140 ) +insert ( 2867 '&&' 11 10 b f f 4537 3831 16 2866 0 4247 4243 140 ) +insert ( 2868 '&&' 11 10 b f f 4537 4537 16 2868 0 4248 4243 140 ) +insert ( 2869 '@>' 11 10 b f f 4537 2283 16 2872 0 4249 4243 1303 ) +insert ( 2870 '@>' 11 10 b f f 4537 3831 16 2873 0 4250 4243 1303 ) +insert ( 2871 '@>' 11 10 b f f 4537 4537 16 2874 0 4251 4243 1303 ) +insert ( 2872 '<@' 11 10 b f f 2283 4537 16 2869 0 4252 4243 1303 ) +insert ( 2873 '<@' 11 10 b f f 3831 4537 16 2870 0 4253 4243 1303 ) +insert ( 2874 '<@' 11 10 b f f 4537 4537 16 2871 0 4254 4243 1303 ) +insert ( 4539 '@>' 11 10 b f f 3831 4537 16 4540 0 4541 4243 1303 ) +insert ( 4540 '<@' 11 10 b f f 4537 3831 16 4539 0 4542 4243 1303 ) +insert ( 2875 '&<' 11 10 b f f 3831 4537 16 0 0 4264 4243 107 ) +insert ( 2876 '&<' 11 10 b f f 4537 3831 16 0 0 4265 4243 107 ) +insert ( 2877 '&<' 11 10 b f f 4537 4537 16 0 0 4266 4243 107 ) +insert ( 3585 '&>' 11 10 b f f 3831 4537 16 0 0 4267 4243 108 ) +insert ( 4035 '&>' 11 10 b f f 4537 3831 16 0 0 4268 4243 108 ) +insert ( 4142 '&>' 11 10 b f f 4537 4537 16 0 0 4269 4243 108 ) +insert ( 4179 '-|-' 11 10 b f f 3831 4537 16 4180 0 4255 5040 5041 ) +insert ( 4180 '-|-' 11 10 b f f 4537 3831 16 4179 0 4257 5040 5041 ) +insert ( 4198 '-|-' 11 10 b f f 4537 4537 16 4198 0 4256 5040 5041 ) +insert ( 4392 '+' 11 10 b f f 4537 4537 4537 4392 0 4270 - - ) +insert ( 4393 - 11 10 b f f 4537 4537 4537 0 0 4271 - - ) +insert ( 4394 '*' 11 10 b f f 4537 4537 4537 4394 0 4272 - - ) +insert ( 4395 '<<' 11 10 b f f 3831 4537 16 4399 0 4258 4243 107 ) +insert ( 4396 '<<' 11 10 b f f 4537 3831 16 4398 0 4259 4243 107 ) +insert ( 4397 '<<' 11 10 b f f 4537 4537 16 4400 0 4260 4243 107 ) +insert ( 4398 '>>' 11 10 b f f 3831 4537 16 4396 0 4261 4243 108 ) +insert ( 4399 '>>' 11 10 b f f 4537 3831 16 4395 0 4262 4243 108 ) +insert ( 4400 '>>' 11 10 b f f 4537 4537 16 4397 0 4263 4243 108 ) +close pg_operator +create pg_opfamily 2753 + ( + oid = oid , + opfmethod = oid , + opfname = name , + opfnamespace = oid , + opfowner = oid + ) +open pg_opfamily +insert ( 397 403 array_ops 11 10 ) +insert ( 627 405 array_ops 11 10 ) +insert ( 423 403 bit_ops 11 10 ) +insert ( 424 403 bool_ops 11 10 ) +insert ( 426 403 bpchar_ops 11 10 ) +insert ( 427 405 bpchar_ops 11 10 ) +insert ( 428 403 bytea_ops 11 10 ) +insert ( 429 403 char_ops 11 10 ) +insert ( 431 405 char_ops 11 10 ) +insert ( 434 403 datetime_ops 11 10 ) +insert ( 435 405 date_ops 11 10 ) +insert ( 1970 403 float_ops 11 10 ) +insert ( 1971 405 float_ops 11 10 ) +insert ( 1974 403 network_ops 11 10 ) +insert ( 1975 405 network_ops 11 10 ) +insert ( 3550 783 network_ops 11 10 ) +insert ( 3794 4000 network_ops 11 10 ) +insert ( 1976 403 integer_ops 11 10 ) +insert ( 1977 405 integer_ops 11 10 ) +insert ( 1982 403 interval_ops 11 10 ) +insert ( 1983 405 interval_ops 11 10 ) +insert ( 1984 403 macaddr_ops 11 10 ) +insert ( 1985 405 macaddr_ops 11 10 ) +insert ( 3371 403 macaddr8_ops 11 10 ) +insert ( 3372 405 macaddr8_ops 11 10 ) +insert ( 1988 403 numeric_ops 11 10 ) +insert ( 1998 405 numeric_ops 11 10 ) +insert ( 1989 403 oid_ops 11 10 ) +insert ( 1990 405 oid_ops 11 10 ) +insert ( 1991 403 oidvector_ops 11 10 ) +insert ( 1992 405 oidvector_ops 11 10 ) +insert ( 2994 403 record_ops 11 10 ) +insert ( 6194 405 record_ops 11 10 ) +insert ( 3194 403 record_image_ops 11 10 ) +insert ( 1994 403 text_ops 11 10 ) +insert ( 1995 405 text_ops 11 10 ) +insert ( 1996 403 time_ops 11 10 ) +insert ( 1997 405 time_ops 11 10 ) +insert ( 1999 405 timestamptz_ops 11 10 ) +insert ( 2000 403 timetz_ops 11 10 ) +insert ( 2001 405 timetz_ops 11 10 ) +insert ( 2002 403 varbit_ops 11 10 ) +insert ( 2040 405 timestamp_ops 11 10 ) +insert ( 2095 403 text_pattern_ops 11 10 ) +insert ( 2097 403 bpchar_pattern_ops 11 10 ) +insert ( 2099 403 money_ops 11 10 ) +insert ( 2222 405 bool_ops 11 10 ) +insert ( 2223 405 bytea_ops 11 10 ) +insert ( 2789 403 tid_ops 11 10 ) +insert ( 2225 405 xid_ops 11 10 ) +insert ( 5032 405 xid8_ops 11 10 ) +insert ( 5067 403 xid8_ops 11 10 ) +insert ( 2226 405 cid_ops 11 10 ) +insert ( 2227 405 tid_ops 11 10 ) +insert ( 2229 405 text_pattern_ops 11 10 ) +insert ( 2231 405 bpchar_pattern_ops 11 10 ) +insert ( 2235 405 aclitem_ops 11 10 ) +insert ( 2593 783 box_ops 11 10 ) +insert ( 2594 783 poly_ops 11 10 ) +insert ( 2595 783 circle_ops 11 10 ) +insert ( 1029 783 point_ops 11 10 ) +insert ( 2745 2742 array_ops 11 10 ) +insert ( 2968 403 uuid_ops 11 10 ) +insert ( 2969 405 uuid_ops 11 10 ) +insert ( 3253 403 pg_lsn_ops 11 10 ) +insert ( 3254 405 pg_lsn_ops 11 10 ) +insert ( 3522 403 enum_ops 11 10 ) +insert ( 3523 405 enum_ops 11 10 ) +insert ( 3626 403 tsvector_ops 11 10 ) +insert ( 3655 783 tsvector_ops 11 10 ) +insert ( 3659 2742 tsvector_ops 11 10 ) +insert ( 3683 403 tsquery_ops 11 10 ) +insert ( 3702 783 tsquery_ops 11 10 ) +insert ( 3901 403 range_ops 11 10 ) +insert ( 3903 405 range_ops 11 10 ) +insert ( 3919 783 range_ops 11 10 ) +insert ( 3474 4000 range_ops 11 10 ) +insert ( 4015 4000 quad_point_ops 11 10 ) +insert ( 4016 4000 kd_point_ops 11 10 ) +insert ( 4017 4000 text_ops 11 10 ) +insert ( 4033 403 jsonb_ops 11 10 ) +insert ( 4034 405 jsonb_ops 11 10 ) +insert ( 4036 2742 jsonb_ops 11 10 ) +insert ( 4037 2742 jsonb_path_ops 11 10 ) +insert ( 4054 3580 integer_minmax_ops 11 10 ) +insert ( 4602 3580 integer_minmax_multi_ops 11 10 ) +insert ( 4572 3580 integer_bloom_ops 11 10 ) +insert ( 4055 3580 numeric_minmax_ops 11 10 ) +insert ( 4603 3580 numeric_minmax_multi_ops 11 10 ) +insert ( 4056 3580 text_minmax_ops 11 10 ) +insert ( 4573 3580 text_bloom_ops 11 10 ) +insert ( 4574 3580 numeric_bloom_ops 11 10 ) +insert ( 4058 3580 timetz_minmax_ops 11 10 ) +insert ( 4604 3580 timetz_minmax_multi_ops 11 10 ) +insert ( 4575 3580 timetz_bloom_ops 11 10 ) +insert ( 4059 3580 datetime_minmax_ops 11 10 ) +insert ( 4605 3580 datetime_minmax_multi_ops 11 10 ) +insert ( 4576 3580 datetime_bloom_ops 11 10 ) +insert ( 4062 3580 char_minmax_ops 11 10 ) +insert ( 4577 3580 char_bloom_ops 11 10 ) +insert ( 4064 3580 bytea_minmax_ops 11 10 ) +insert ( 4578 3580 bytea_bloom_ops 11 10 ) +insert ( 4065 3580 name_minmax_ops 11 10 ) +insert ( 4579 3580 name_bloom_ops 11 10 ) +insert ( 4068 3580 oid_minmax_ops 11 10 ) +insert ( 4606 3580 oid_minmax_multi_ops 11 10 ) +insert ( 4580 3580 oid_bloom_ops 11 10 ) +insert ( 4069 3580 tid_minmax_ops 11 10 ) +insert ( 4581 3580 tid_bloom_ops 11 10 ) +insert ( 4607 3580 tid_minmax_multi_ops 11 10 ) +insert ( 4070 3580 float_minmax_ops 11 10 ) +insert ( 4608 3580 float_minmax_multi_ops 11 10 ) +insert ( 4582 3580 float_bloom_ops 11 10 ) +insert ( 4074 3580 macaddr_minmax_ops 11 10 ) +insert ( 4609 3580 macaddr_minmax_multi_ops 11 10 ) +insert ( 4583 3580 macaddr_bloom_ops 11 10 ) +insert ( 4109 3580 macaddr8_minmax_ops 11 10 ) +insert ( 4610 3580 macaddr8_minmax_multi_ops 11 10 ) +insert ( 4584 3580 macaddr8_bloom_ops 11 10 ) +insert ( 4075 3580 network_minmax_ops 11 10 ) +insert ( 4611 3580 network_minmax_multi_ops 11 10 ) +insert ( 4102 3580 network_inclusion_ops 11 10 ) +insert ( 4585 3580 network_bloom_ops 11 10 ) +insert ( 4076 3580 bpchar_minmax_ops 11 10 ) +insert ( 4586 3580 bpchar_bloom_ops 11 10 ) +insert ( 4077 3580 time_minmax_ops 11 10 ) +insert ( 4612 3580 time_minmax_multi_ops 11 10 ) +insert ( 4587 3580 time_bloom_ops 11 10 ) +insert ( 4078 3580 interval_minmax_ops 11 10 ) +insert ( 4613 3580 interval_minmax_multi_ops 11 10 ) +insert ( 4588 3580 interval_bloom_ops 11 10 ) +insert ( 4079 3580 bit_minmax_ops 11 10 ) +insert ( 4080 3580 varbit_minmax_ops 11 10 ) +insert ( 4081 3580 uuid_minmax_ops 11 10 ) +insert ( 4614 3580 uuid_minmax_multi_ops 11 10 ) +insert ( 4589 3580 uuid_bloom_ops 11 10 ) +insert ( 4103 3580 range_inclusion_ops 11 10 ) +insert ( 4082 3580 pg_lsn_minmax_ops 11 10 ) +insert ( 4615 3580 pg_lsn_minmax_multi_ops 11 10 ) +insert ( 4590 3580 pg_lsn_bloom_ops 11 10 ) +insert ( 4104 3580 box_inclusion_ops 11 10 ) +insert ( 5000 4000 box_ops 11 10 ) +insert ( 5008 4000 poly_ops 11 10 ) +insert ( 4199 403 multirange_ops 11 10 ) +insert ( 4225 405 multirange_ops 11 10 ) +insert ( 6158 783 multirange_ops 11 10 ) +close pg_opfamily +create pg_opclass 2616 + ( + oid = oid , + opcmethod = oid , + opcname = name , + opcnamespace = oid , + opcowner = oid , + opcfamily = oid , + opcintype = oid , + opcdefault = bool , + opckeytype = oid + ) +open pg_opclass +insert ( 10000 403 array_ops 11 10 397 2277 t 0 ) +insert ( 10001 405 array_ops 11 10 627 2277 t 0 ) +insert ( 10002 403 bit_ops 11 10 423 1560 t 0 ) +insert ( 10003 403 bool_ops 11 10 424 16 t 0 ) +insert ( 10004 403 bpchar_ops 11 10 426 1042 t 0 ) +insert ( 10005 405 bpchar_ops 11 10 427 1042 t 0 ) +insert ( 10006 403 bytea_ops 11 10 428 17 t 0 ) +insert ( 10007 403 char_ops 11 10 429 18 t 0 ) +insert ( 10008 405 char_ops 11 10 431 18 t 0 ) +insert ( 10009 403 cidr_ops 11 10 1974 869 f 0 ) +insert ( 10010 405 cidr_ops 11 10 1975 869 f 0 ) +insert ( 3122 403 date_ops 11 10 434 1082 t 0 ) +insert ( 10011 405 date_ops 11 10 435 1082 t 0 ) +insert ( 10012 403 float4_ops 11 10 1970 700 t 0 ) +insert ( 10013 405 float4_ops 11 10 1971 700 t 0 ) +insert ( 3123 403 float8_ops 11 10 1970 701 t 0 ) +insert ( 10014 405 float8_ops 11 10 1971 701 t 0 ) +insert ( 10015 403 inet_ops 11 10 1974 869 t 0 ) +insert ( 10016 405 inet_ops 11 10 1975 869 t 0 ) +insert ( 10017 783 inet_ops 11 10 3550 869 f 0 ) +insert ( 10018 4000 inet_ops 11 10 3794 869 t 0 ) +insert ( 1979 403 int2_ops 11 10 1976 21 t 0 ) +insert ( 10019 405 int2_ops 11 10 1977 21 t 0 ) +insert ( 1978 403 int4_ops 11 10 1976 23 t 0 ) +insert ( 10020 405 int4_ops 11 10 1977 23 t 0 ) +insert ( 3124 403 int8_ops 11 10 1976 20 t 0 ) +insert ( 10021 405 int8_ops 11 10 1977 20 t 0 ) +insert ( 10022 403 interval_ops 11 10 1982 1186 t 0 ) +insert ( 10023 405 interval_ops 11 10 1983 1186 t 0 ) +insert ( 10024 403 macaddr_ops 11 10 1984 829 t 0 ) +insert ( 10025 405 macaddr_ops 11 10 1985 829 t 0 ) +insert ( 10026 403 macaddr8_ops 11 10 3371 774 t 0 ) +insert ( 10027 405 macaddr8_ops 11 10 3372 774 t 0 ) +insert ( 10028 403 name_ops 11 10 1994 19 t 2275 ) +insert ( 10029 405 name_ops 11 10 1995 19 t 0 ) +insert ( 3125 403 numeric_ops 11 10 1988 1700 t 0 ) +insert ( 10030 405 numeric_ops 11 10 1998 1700 t 0 ) +insert ( 1981 403 oid_ops 11 10 1989 26 t 0 ) +insert ( 10031 405 oid_ops 11 10 1990 26 t 0 ) +insert ( 10032 403 oidvector_ops 11 10 1991 30 t 0 ) +insert ( 10033 405 oidvector_ops 11 10 1992 30 t 0 ) +insert ( 10034 403 record_ops 11 10 2994 2249 t 0 ) +insert ( 10035 405 record_ops 11 10 6194 2249 t 0 ) +insert ( 10036 403 record_image_ops 11 10 3194 2249 f 0 ) +insert ( 3126 403 text_ops 11 10 1994 25 t 0 ) +insert ( 10037 405 text_ops 11 10 1995 25 t 0 ) +insert ( 10038 403 time_ops 11 10 1996 1083 t 0 ) +insert ( 10039 405 time_ops 11 10 1997 1083 t 0 ) +insert ( 3127 403 timestamptz_ops 11 10 434 1184 t 0 ) +insert ( 10040 405 timestamptz_ops 11 10 1999 1184 t 0 ) +insert ( 10041 403 timetz_ops 11 10 2000 1266 t 0 ) +insert ( 10042 405 timetz_ops 11 10 2001 1266 t 0 ) +insert ( 10043 403 varbit_ops 11 10 2002 1562 t 0 ) +insert ( 10044 403 varchar_ops 11 10 1994 25 f 0 ) +insert ( 10045 405 varchar_ops 11 10 1995 25 f 0 ) +insert ( 3128 403 timestamp_ops 11 10 434 1114 t 0 ) +insert ( 10046 405 timestamp_ops 11 10 2040 1114 t 0 ) +insert ( 4217 403 text_pattern_ops 11 10 2095 25 f 0 ) +insert ( 4218 403 varchar_pattern_ops 11 10 2095 25 f 0 ) +insert ( 4219 403 bpchar_pattern_ops 11 10 2097 1042 f 0 ) +insert ( 10047 403 money_ops 11 10 2099 790 t 0 ) +insert ( 10048 405 bool_ops 11 10 2222 16 t 0 ) +insert ( 10049 405 bytea_ops 11 10 2223 17 t 0 ) +insert ( 10050 403 tid_ops 11 10 2789 27 t 0 ) +insert ( 10051 405 xid_ops 11 10 2225 28 t 0 ) +insert ( 10052 405 xid8_ops 11 10 5032 5069 t 0 ) +insert ( 10053 403 xid8_ops 11 10 5067 5069 t 0 ) +insert ( 10054 405 cid_ops 11 10 2226 29 t 0 ) +insert ( 10055 405 tid_ops 11 10 2227 27 t 0 ) +insert ( 10056 405 text_pattern_ops 11 10 2229 25 f 0 ) +insert ( 10057 405 varchar_pattern_ops 11 10 2229 25 f 0 ) +insert ( 10058 405 bpchar_pattern_ops 11 10 2231 1042 f 0 ) +insert ( 10059 405 aclitem_ops 11 10 2235 1033 t 0 ) +insert ( 10060 783 box_ops 11 10 2593 603 t 0 ) +insert ( 10061 783 point_ops 11 10 1029 600 t 603 ) +insert ( 10062 783 poly_ops 11 10 2594 604 t 603 ) +insert ( 10063 783 circle_ops 11 10 2595 718 t 603 ) +insert ( 10064 2742 array_ops 11 10 2745 2277 t 2283 ) +insert ( 10065 403 uuid_ops 11 10 2968 2950 t 0 ) +insert ( 10066 405 uuid_ops 11 10 2969 2950 t 0 ) +insert ( 10067 403 pg_lsn_ops 11 10 3253 3220 t 0 ) +insert ( 10068 405 pg_lsn_ops 11 10 3254 3220 t 0 ) +insert ( 10069 403 enum_ops 11 10 3522 3500 t 0 ) +insert ( 10070 405 enum_ops 11 10 3523 3500 t 0 ) +insert ( 10071 403 tsvector_ops 11 10 3626 3614 t 0 ) +insert ( 10072 783 tsvector_ops 11 10 3655 3614 t 3642 ) +insert ( 10073 2742 tsvector_ops 11 10 3659 3614 t 25 ) +insert ( 10074 403 tsquery_ops 11 10 3683 3615 t 0 ) +insert ( 10075 783 tsquery_ops 11 10 3702 3615 t 20 ) +insert ( 10076 403 range_ops 11 10 3901 3831 t 0 ) +insert ( 10077 405 range_ops 11 10 3903 3831 t 0 ) +insert ( 10078 783 range_ops 11 10 3919 3831 t 0 ) +insert ( 10079 4000 range_ops 11 10 3474 3831 t 0 ) +insert ( 10080 403 multirange_ops 11 10 4199 4537 t 0 ) +insert ( 10081 405 multirange_ops 11 10 4225 4537 t 0 ) +insert ( 10082 783 multirange_ops 11 10 6158 4537 t 3831 ) +insert ( 10083 4000 box_ops 11 10 5000 603 t 0 ) +insert ( 10084 4000 quad_point_ops 11 10 4015 600 t 0 ) +insert ( 10085 4000 kd_point_ops 11 10 4016 600 f 0 ) +insert ( 10086 4000 text_ops 11 10 4017 25 t 0 ) +insert ( 10087 4000 poly_ops 11 10 5008 604 t 603 ) +insert ( 10088 403 jsonb_ops 11 10 4033 3802 t 0 ) +insert ( 10089 405 jsonb_ops 11 10 4034 3802 t 0 ) +insert ( 10090 2742 jsonb_ops 11 10 4036 3802 t 25 ) +insert ( 10091 2742 jsonb_path_ops 11 10 4037 3802 f 23 ) +insert ( 10092 3580 bytea_minmax_ops 11 10 4064 17 t 17 ) +insert ( 10093 3580 bytea_bloom_ops 11 10 4578 17 f 17 ) +insert ( 10094 3580 char_minmax_ops 11 10 4062 18 t 18 ) +insert ( 10095 3580 char_bloom_ops 11 10 4577 18 f 18 ) +insert ( 10096 3580 name_minmax_ops 11 10 4065 19 t 19 ) +insert ( 10097 3580 name_bloom_ops 11 10 4579 19 f 19 ) +insert ( 10098 3580 int8_minmax_ops 11 10 4054 20 t 20 ) +insert ( 10099 3580 int8_minmax_multi_ops 11 10 4602 20 f 20 ) +insert ( 10100 3580 int8_bloom_ops 11 10 4572 20 f 20 ) +insert ( 10101 3580 int2_minmax_ops 11 10 4054 21 t 21 ) +insert ( 10102 3580 int2_minmax_multi_ops 11 10 4602 21 f 21 ) +insert ( 10103 3580 int2_bloom_ops 11 10 4572 21 f 21 ) +insert ( 10104 3580 int4_minmax_ops 11 10 4054 23 t 23 ) +insert ( 10105 3580 int4_minmax_multi_ops 11 10 4602 23 f 23 ) +insert ( 10106 3580 int4_bloom_ops 11 10 4572 23 f 23 ) +insert ( 10107 3580 text_minmax_ops 11 10 4056 25 t 25 ) +insert ( 10108 3580 text_bloom_ops 11 10 4573 25 f 25 ) +insert ( 10109 3580 oid_minmax_ops 11 10 4068 26 t 26 ) +insert ( 10110 3580 oid_minmax_multi_ops 11 10 4606 26 f 26 ) +insert ( 10111 3580 oid_bloom_ops 11 10 4580 26 f 26 ) +insert ( 10112 3580 tid_minmax_ops 11 10 4069 27 t 27 ) +insert ( 10113 3580 tid_bloom_ops 11 10 4581 27 f 27 ) +insert ( 10114 3580 tid_minmax_multi_ops 11 10 4607 27 f 27 ) +insert ( 10115 3580 float4_minmax_ops 11 10 4070 700 t 700 ) +insert ( 10116 3580 float4_minmax_multi_ops 11 10 4608 700 f 700 ) +insert ( 10117 3580 float4_bloom_ops 11 10 4582 700 f 700 ) +insert ( 10118 3580 float8_minmax_ops 11 10 4070 701 t 701 ) +insert ( 10119 3580 float8_minmax_multi_ops 11 10 4608 701 f 701 ) +insert ( 10120 3580 float8_bloom_ops 11 10 4582 701 f 701 ) +insert ( 10121 3580 macaddr_minmax_ops 11 10 4074 829 t 829 ) +insert ( 10122 3580 macaddr_minmax_multi_ops 11 10 4609 829 f 829 ) +insert ( 10123 3580 macaddr_bloom_ops 11 10 4583 829 f 829 ) +insert ( 10124 3580 macaddr8_minmax_ops 11 10 4109 774 t 774 ) +insert ( 10125 3580 macaddr8_minmax_multi_ops 11 10 4610 774 f 774 ) +insert ( 10126 3580 macaddr8_bloom_ops 11 10 4584 774 f 774 ) +insert ( 10127 3580 inet_minmax_ops 11 10 4075 869 f 869 ) +insert ( 10128 3580 inet_minmax_multi_ops 11 10 4611 869 f 869 ) +insert ( 10129 3580 inet_bloom_ops 11 10 4585 869 f 869 ) +insert ( 10130 3580 inet_inclusion_ops 11 10 4102 869 t 869 ) +insert ( 10131 3580 bpchar_minmax_ops 11 10 4076 1042 t 1042 ) +insert ( 10132 3580 bpchar_bloom_ops 11 10 4586 1042 f 1042 ) +insert ( 10133 3580 time_minmax_ops 11 10 4077 1083 t 1083 ) +insert ( 10134 3580 time_minmax_multi_ops 11 10 4612 1083 f 1083 ) +insert ( 10135 3580 time_bloom_ops 11 10 4587 1083 f 1083 ) +insert ( 10136 3580 date_minmax_ops 11 10 4059 1082 t 1082 ) +insert ( 10137 3580 date_minmax_multi_ops 11 10 4605 1082 f 1082 ) +insert ( 10138 3580 date_bloom_ops 11 10 4576 1082 f 1082 ) +insert ( 10139 3580 timestamp_minmax_ops 11 10 4059 1114 t 1114 ) +insert ( 10140 3580 timestamp_minmax_multi_ops 11 10 4605 1114 f 1114 ) +insert ( 10141 3580 timestamp_bloom_ops 11 10 4576 1114 f 1114 ) +insert ( 10142 3580 timestamptz_minmax_ops 11 10 4059 1184 t 1184 ) +insert ( 10143 3580 timestamptz_minmax_multi_ops 11 10 4605 1184 f 1184 ) +insert ( 10144 3580 timestamptz_bloom_ops 11 10 4576 1184 f 1184 ) +insert ( 10145 3580 interval_minmax_ops 11 10 4078 1186 t 1186 ) +insert ( 10146 3580 interval_minmax_multi_ops 11 10 4613 1186 f 1186 ) +insert ( 10147 3580 interval_bloom_ops 11 10 4588 1186 f 1186 ) +insert ( 10148 3580 timetz_minmax_ops 11 10 4058 1266 t 1266 ) +insert ( 10149 3580 timetz_minmax_multi_ops 11 10 4604 1266 f 1266 ) +insert ( 10150 3580 timetz_bloom_ops 11 10 4575 1266 f 1266 ) +insert ( 10151 3580 bit_minmax_ops 11 10 4079 1560 t 1560 ) +insert ( 10152 3580 varbit_minmax_ops 11 10 4080 1562 t 1562 ) +insert ( 10153 3580 numeric_minmax_ops 11 10 4055 1700 t 1700 ) +insert ( 10154 3580 numeric_minmax_multi_ops 11 10 4603 1700 f 1700 ) +insert ( 10155 3580 numeric_bloom_ops 11 10 4574 1700 f 1700 ) +insert ( 10156 3580 uuid_minmax_ops 11 10 4081 2950 t 2950 ) +insert ( 10157 3580 uuid_minmax_multi_ops 11 10 4614 2950 f 2950 ) +insert ( 10158 3580 uuid_bloom_ops 11 10 4589 2950 f 2950 ) +insert ( 10159 3580 range_inclusion_ops 11 10 4103 3831 t 3831 ) +insert ( 10160 3580 pg_lsn_minmax_ops 11 10 4082 3220 t 3220 ) +insert ( 10161 3580 pg_lsn_minmax_multi_ops 11 10 4615 3220 f 3220 ) +insert ( 10162 3580 pg_lsn_bloom_ops 11 10 4590 3220 f 3220 ) +insert ( 10163 3580 box_inclusion_ops 11 10 4104 603 t 603 ) +close pg_opclass +create pg_am 2601 + ( + oid = oid , + amname = name , + amhandler = regproc , + amtype = char + ) +open pg_am +insert ( 2 heap 3 t ) +insert ( 403 btree 330 i ) +insert ( 405 hash 331 i ) +insert ( 783 gist 332 i ) +insert ( 2742 gin 333 i ) +insert ( 4000 spgist 334 i ) +insert ( 3580 brin 335 i ) +close pg_am +create pg_amop 2602 + ( + oid = oid , + amopfamily = oid , + amoplefttype = oid , + amoprighttype = oid , + amopstrategy = int2 , + amoppurpose = char , + amopopr = oid , + amopmethod = oid , + amopsortfamily = oid + ) +open pg_amop +insert ( 10000 1976 21 21 1 s 95 403 0 ) +insert ( 10001 1976 21 21 2 s 522 403 0 ) +insert ( 10002 1976 21 21 3 s 94 403 0 ) +insert ( 10003 1976 21 21 4 s 524 403 0 ) +insert ( 10004 1976 21 21 5 s 520 403 0 ) +insert ( 10005 1976 21 23 1 s 534 403 0 ) +insert ( 10006 1976 21 23 2 s 540 403 0 ) +insert ( 10007 1976 21 23 3 s 532 403 0 ) +insert ( 10008 1976 21 23 4 s 542 403 0 ) +insert ( 10009 1976 21 23 5 s 536 403 0 ) +insert ( 10010 1976 21 20 1 s 1864 403 0 ) +insert ( 10011 1976 21 20 2 s 1866 403 0 ) +insert ( 10012 1976 21 20 3 s 1862 403 0 ) +insert ( 10013 1976 21 20 4 s 1867 403 0 ) +insert ( 10014 1976 21 20 5 s 1865 403 0 ) +insert ( 10015 1976 23 23 1 s 97 403 0 ) +insert ( 10016 1976 23 23 2 s 523 403 0 ) +insert ( 10017 1976 23 23 3 s 96 403 0 ) +insert ( 10018 1976 23 23 4 s 525 403 0 ) +insert ( 10019 1976 23 23 5 s 521 403 0 ) +insert ( 10020 1976 23 21 1 s 535 403 0 ) +insert ( 10021 1976 23 21 2 s 541 403 0 ) +insert ( 10022 1976 23 21 3 s 533 403 0 ) +insert ( 10023 1976 23 21 4 s 543 403 0 ) +insert ( 10024 1976 23 21 5 s 537 403 0 ) +insert ( 10025 1976 23 20 1 s 37 403 0 ) +insert ( 10026 1976 23 20 2 s 80 403 0 ) +insert ( 10027 1976 23 20 3 s 15 403 0 ) +insert ( 10028 1976 23 20 4 s 82 403 0 ) +insert ( 10029 1976 23 20 5 s 76 403 0 ) +insert ( 10030 1976 20 20 1 s 412 403 0 ) +insert ( 10031 1976 20 20 2 s 414 403 0 ) +insert ( 10032 1976 20 20 3 s 410 403 0 ) +insert ( 10033 1976 20 20 4 s 415 403 0 ) +insert ( 10034 1976 20 20 5 s 413 403 0 ) +insert ( 10035 1976 20 21 1 s 1870 403 0 ) +insert ( 10036 1976 20 21 2 s 1872 403 0 ) +insert ( 10037 1976 20 21 3 s 1868 403 0 ) +insert ( 10038 1976 20 21 4 s 1873 403 0 ) +insert ( 10039 1976 20 21 5 s 1871 403 0 ) +insert ( 10040 1976 20 23 1 s 418 403 0 ) +insert ( 10041 1976 20 23 2 s 420 403 0 ) +insert ( 10042 1976 20 23 3 s 416 403 0 ) +insert ( 10043 1976 20 23 4 s 430 403 0 ) +insert ( 10044 1976 20 23 5 s 419 403 0 ) +insert ( 10045 1989 26 26 1 s 609 403 0 ) +insert ( 10046 1989 26 26 2 s 611 403 0 ) +insert ( 10047 1989 26 26 3 s 607 403 0 ) +insert ( 10048 1989 26 26 4 s 612 403 0 ) +insert ( 10049 1989 26 26 5 s 610 403 0 ) +insert ( 10050 5067 5069 5069 1 s 5073 403 0 ) +insert ( 10051 5067 5069 5069 2 s 5075 403 0 ) +insert ( 10052 5067 5069 5069 3 s 5068 403 0 ) +insert ( 10053 5067 5069 5069 4 s 5076 403 0 ) +insert ( 10054 5067 5069 5069 5 s 5074 403 0 ) +insert ( 10055 2789 27 27 1 s 2799 403 0 ) +insert ( 10056 2789 27 27 2 s 2801 403 0 ) +insert ( 10057 2789 27 27 3 s 387 403 0 ) +insert ( 10058 2789 27 27 4 s 2802 403 0 ) +insert ( 10059 2789 27 27 5 s 2800 403 0 ) +insert ( 10060 1991 30 30 1 s 645 403 0 ) +insert ( 10061 1991 30 30 2 s 647 403 0 ) +insert ( 10062 1991 30 30 3 s 649 403 0 ) +insert ( 10063 1991 30 30 4 s 648 403 0 ) +insert ( 10064 1991 30 30 5 s 646 403 0 ) +insert ( 10065 1970 700 700 1 s 622 403 0 ) +insert ( 10066 1970 700 700 2 s 624 403 0 ) +insert ( 10067 1970 700 700 3 s 620 403 0 ) +insert ( 10068 1970 700 700 4 s 625 403 0 ) +insert ( 10069 1970 700 700 5 s 623 403 0 ) +insert ( 10070 1970 700 701 1 s 1122 403 0 ) +insert ( 10071 1970 700 701 2 s 1124 403 0 ) +insert ( 10072 1970 700 701 3 s 1120 403 0 ) +insert ( 10073 1970 700 701 4 s 1125 403 0 ) +insert ( 10074 1970 700 701 5 s 1123 403 0 ) +insert ( 10075 1970 701 701 1 s 672 403 0 ) +insert ( 10076 1970 701 701 2 s 673 403 0 ) +insert ( 10077 1970 701 701 3 s 670 403 0 ) +insert ( 10078 1970 701 701 4 s 675 403 0 ) +insert ( 10079 1970 701 701 5 s 674 403 0 ) +insert ( 10080 1970 701 700 1 s 1132 403 0 ) +insert ( 10081 1970 701 700 2 s 1134 403 0 ) +insert ( 10082 1970 701 700 3 s 1130 403 0 ) +insert ( 10083 1970 701 700 4 s 1135 403 0 ) +insert ( 10084 1970 701 700 5 s 1133 403 0 ) +insert ( 10085 429 18 18 1 s 631 403 0 ) +insert ( 10086 429 18 18 2 s 632 403 0 ) +insert ( 10087 429 18 18 3 s 92 403 0 ) +insert ( 10088 429 18 18 4 s 634 403 0 ) +insert ( 10089 429 18 18 5 s 633 403 0 ) +insert ( 10090 1994 25 25 1 s 664 403 0 ) +insert ( 10091 1994 25 25 2 s 665 403 0 ) +insert ( 10092 1994 25 25 3 s 98 403 0 ) +insert ( 10093 1994 25 25 4 s 667 403 0 ) +insert ( 10094 1994 25 25 5 s 666 403 0 ) +insert ( 10095 1994 19 19 1 s 660 403 0 ) +insert ( 10096 1994 19 19 2 s 661 403 0 ) +insert ( 10097 1994 19 19 3 s 93 403 0 ) +insert ( 10098 1994 19 19 4 s 663 403 0 ) +insert ( 10099 1994 19 19 5 s 662 403 0 ) +insert ( 10100 1994 19 25 1 s 255 403 0 ) +insert ( 10101 1994 19 25 2 s 256 403 0 ) +insert ( 10102 1994 19 25 3 s 254 403 0 ) +insert ( 10103 1994 19 25 4 s 257 403 0 ) +insert ( 10104 1994 19 25 5 s 258 403 0 ) +insert ( 10105 1994 25 19 1 s 261 403 0 ) +insert ( 10106 1994 25 19 2 s 262 403 0 ) +insert ( 10107 1994 25 19 3 s 260 403 0 ) +insert ( 10108 1994 25 19 4 s 263 403 0 ) +insert ( 10109 1994 25 19 5 s 264 403 0 ) +insert ( 10110 426 1042 1042 1 s 1058 403 0 ) +insert ( 10111 426 1042 1042 2 s 1059 403 0 ) +insert ( 10112 426 1042 1042 3 s 1054 403 0 ) +insert ( 10113 426 1042 1042 4 s 1061 403 0 ) +insert ( 10114 426 1042 1042 5 s 1060 403 0 ) +insert ( 10115 428 17 17 1 s 1957 403 0 ) +insert ( 10116 428 17 17 2 s 1958 403 0 ) +insert ( 10117 428 17 17 3 s 1955 403 0 ) +insert ( 10118 428 17 17 4 s 1960 403 0 ) +insert ( 10119 428 17 17 5 s 1959 403 0 ) +insert ( 10120 434 1082 1082 1 s 1095 403 0 ) +insert ( 10121 434 1082 1082 2 s 1096 403 0 ) +insert ( 10122 434 1082 1082 3 s 1093 403 0 ) +insert ( 10123 434 1082 1082 4 s 1098 403 0 ) +insert ( 10124 434 1082 1082 5 s 1097 403 0 ) +insert ( 10125 434 1082 1114 1 s 2345 403 0 ) +insert ( 10126 434 1082 1114 2 s 2346 403 0 ) +insert ( 10127 434 1082 1114 3 s 2347 403 0 ) +insert ( 10128 434 1082 1114 4 s 2348 403 0 ) +insert ( 10129 434 1082 1114 5 s 2349 403 0 ) +insert ( 10130 434 1082 1184 1 s 2358 403 0 ) +insert ( 10131 434 1082 1184 2 s 2359 403 0 ) +insert ( 10132 434 1082 1184 3 s 2360 403 0 ) +insert ( 10133 434 1082 1184 4 s 2361 403 0 ) +insert ( 10134 434 1082 1184 5 s 2362 403 0 ) +insert ( 10135 434 1114 1114 1 s 2062 403 0 ) +insert ( 10136 434 1114 1114 2 s 2063 403 0 ) +insert ( 10137 434 1114 1114 3 s 2060 403 0 ) +insert ( 10138 434 1114 1114 4 s 2065 403 0 ) +insert ( 10139 434 1114 1114 5 s 2064 403 0 ) +insert ( 10140 434 1114 1082 1 s 2371 403 0 ) +insert ( 10141 434 1114 1082 2 s 2372 403 0 ) +insert ( 10142 434 1114 1082 3 s 2373 403 0 ) +insert ( 10143 434 1114 1082 4 s 2374 403 0 ) +insert ( 10144 434 1114 1082 5 s 2375 403 0 ) +insert ( 10145 434 1114 1184 1 s 2534 403 0 ) +insert ( 10146 434 1114 1184 2 s 2535 403 0 ) +insert ( 10147 434 1114 1184 3 s 2536 403 0 ) +insert ( 10148 434 1114 1184 4 s 2537 403 0 ) +insert ( 10149 434 1114 1184 5 s 2538 403 0 ) +insert ( 10150 434 1184 1184 1 s 1322 403 0 ) +insert ( 10151 434 1184 1184 2 s 1323 403 0 ) +insert ( 10152 434 1184 1184 3 s 1320 403 0 ) +insert ( 10153 434 1184 1184 4 s 1325 403 0 ) +insert ( 10154 434 1184 1184 5 s 1324 403 0 ) +insert ( 10155 434 1184 1082 1 s 2384 403 0 ) +insert ( 10156 434 1184 1082 2 s 2385 403 0 ) +insert ( 10157 434 1184 1082 3 s 2386 403 0 ) +insert ( 10158 434 1184 1082 4 s 2387 403 0 ) +insert ( 10159 434 1184 1082 5 s 2388 403 0 ) +insert ( 10160 434 1184 1114 1 s 2540 403 0 ) +insert ( 10161 434 1184 1114 2 s 2541 403 0 ) +insert ( 10162 434 1184 1114 3 s 2542 403 0 ) +insert ( 10163 434 1184 1114 4 s 2543 403 0 ) +insert ( 10164 434 1184 1114 5 s 2544 403 0 ) +insert ( 10165 1996 1083 1083 1 s 1110 403 0 ) +insert ( 10166 1996 1083 1083 2 s 1111 403 0 ) +insert ( 10167 1996 1083 1083 3 s 1108 403 0 ) +insert ( 10168 1996 1083 1083 4 s 1113 403 0 ) +insert ( 10169 1996 1083 1083 5 s 1112 403 0 ) +insert ( 10170 2000 1266 1266 1 s 1552 403 0 ) +insert ( 10171 2000 1266 1266 2 s 1553 403 0 ) +insert ( 10172 2000 1266 1266 3 s 1550 403 0 ) +insert ( 10173 2000 1266 1266 4 s 1555 403 0 ) +insert ( 10174 2000 1266 1266 5 s 1554 403 0 ) +insert ( 10175 1982 1186 1186 1 s 1332 403 0 ) +insert ( 10176 1982 1186 1186 2 s 1333 403 0 ) +insert ( 10177 1982 1186 1186 3 s 1330 403 0 ) +insert ( 10178 1982 1186 1186 4 s 1335 403 0 ) +insert ( 10179 1982 1186 1186 5 s 1334 403 0 ) +insert ( 10180 1984 829 829 1 s 1222 403 0 ) +insert ( 10181 1984 829 829 2 s 1223 403 0 ) +insert ( 10182 1984 829 829 3 s 1220 403 0 ) +insert ( 10183 1984 829 829 4 s 1225 403 0 ) +insert ( 10184 1984 829 829 5 s 1224 403 0 ) +insert ( 10185 3371 774 774 1 s 3364 403 0 ) +insert ( 10186 3371 774 774 2 s 3365 403 0 ) +insert ( 10187 3371 774 774 3 s 3362 403 0 ) +insert ( 10188 3371 774 774 4 s 3367 403 0 ) +insert ( 10189 3371 774 774 5 s 3366 403 0 ) +insert ( 10190 1974 869 869 1 s 1203 403 0 ) +insert ( 10191 1974 869 869 2 s 1204 403 0 ) +insert ( 10192 1974 869 869 3 s 1201 403 0 ) +insert ( 10193 1974 869 869 4 s 1206 403 0 ) +insert ( 10194 1974 869 869 5 s 1205 403 0 ) +insert ( 10195 1988 1700 1700 1 s 1754 403 0 ) +insert ( 10196 1988 1700 1700 2 s 1755 403 0 ) +insert ( 10197 1988 1700 1700 3 s 1752 403 0 ) +insert ( 10198 1988 1700 1700 4 s 1757 403 0 ) +insert ( 10199 1988 1700 1700 5 s 1756 403 0 ) +insert ( 10200 424 16 16 1 s 58 403 0 ) +insert ( 10201 424 16 16 2 s 1694 403 0 ) +insert ( 10202 424 16 16 3 s 91 403 0 ) +insert ( 10203 424 16 16 4 s 1695 403 0 ) +insert ( 10204 424 16 16 5 s 59 403 0 ) +insert ( 10205 423 1560 1560 1 s 1786 403 0 ) +insert ( 10206 423 1560 1560 2 s 1788 403 0 ) +insert ( 10207 423 1560 1560 3 s 1784 403 0 ) +insert ( 10208 423 1560 1560 4 s 1789 403 0 ) +insert ( 10209 423 1560 1560 5 s 1787 403 0 ) +insert ( 10210 2002 1562 1562 1 s 1806 403 0 ) +insert ( 10211 2002 1562 1562 2 s 1808 403 0 ) +insert ( 10212 2002 1562 1562 3 s 1804 403 0 ) +insert ( 10213 2002 1562 1562 4 s 1809 403 0 ) +insert ( 10214 2002 1562 1562 5 s 1807 403 0 ) +insert ( 10215 2095 25 25 1 s 2314 403 0 ) +insert ( 10216 2095 25 25 2 s 2315 403 0 ) +insert ( 10217 2095 25 25 3 s 98 403 0 ) +insert ( 10218 2095 25 25 4 s 2317 403 0 ) +insert ( 10219 2095 25 25 5 s 2318 403 0 ) +insert ( 10220 2097 1042 1042 1 s 2326 403 0 ) +insert ( 10221 2097 1042 1042 2 s 2327 403 0 ) +insert ( 10222 2097 1042 1042 3 s 1054 403 0 ) +insert ( 10223 2097 1042 1042 4 s 2329 403 0 ) +insert ( 10224 2097 1042 1042 5 s 2330 403 0 ) +insert ( 10225 2099 790 790 1 s 902 403 0 ) +insert ( 10226 2099 790 790 2 s 904 403 0 ) +insert ( 10227 2099 790 790 3 s 900 403 0 ) +insert ( 10228 2099 790 790 4 s 905 403 0 ) +insert ( 10229 2099 790 790 5 s 903 403 0 ) +insert ( 10230 397 2277 2277 1 s 1072 403 0 ) +insert ( 10231 397 2277 2277 2 s 1074 403 0 ) +insert ( 10232 397 2277 2277 3 s 1070 403 0 ) +insert ( 10233 397 2277 2277 4 s 1075 403 0 ) +insert ( 10234 397 2277 2277 5 s 1073 403 0 ) +insert ( 10235 2994 2249 2249 1 s 2990 403 0 ) +insert ( 10236 2994 2249 2249 2 s 2992 403 0 ) +insert ( 10237 2994 2249 2249 3 s 2988 403 0 ) +insert ( 10238 2994 2249 2249 4 s 2993 403 0 ) +insert ( 10239 2994 2249 2249 5 s 2991 403 0 ) +insert ( 10240 3194 2249 2249 1 s 3190 403 0 ) +insert ( 10241 3194 2249 2249 2 s 3192 403 0 ) +insert ( 10242 3194 2249 2249 3 s 3188 403 0 ) +insert ( 10243 3194 2249 2249 4 s 3193 403 0 ) +insert ( 10244 3194 2249 2249 5 s 3191 403 0 ) +insert ( 10245 2968 2950 2950 1 s 2974 403 0 ) +insert ( 10246 2968 2950 2950 2 s 2976 403 0 ) +insert ( 10247 2968 2950 2950 3 s 2972 403 0 ) +insert ( 10248 2968 2950 2950 4 s 2977 403 0 ) +insert ( 10249 2968 2950 2950 5 s 2975 403 0 ) +insert ( 10250 3253 3220 3220 1 s 3224 403 0 ) +insert ( 10251 3253 3220 3220 2 s 3226 403 0 ) +insert ( 10252 3253 3220 3220 3 s 3222 403 0 ) +insert ( 10253 3253 3220 3220 4 s 3227 403 0 ) +insert ( 10254 3253 3220 3220 5 s 3225 403 0 ) +insert ( 10255 427 1042 1042 1 s 1054 405 0 ) +insert ( 10256 431 18 18 1 s 92 405 0 ) +insert ( 10257 435 1082 1082 1 s 1093 405 0 ) +insert ( 10258 1971 700 700 1 s 620 405 0 ) +insert ( 10259 1971 701 701 1 s 670 405 0 ) +insert ( 10260 1971 700 701 1 s 1120 405 0 ) +insert ( 10261 1971 701 700 1 s 1130 405 0 ) +insert ( 10262 1975 869 869 1 s 1201 405 0 ) +insert ( 10263 1977 21 21 1 s 94 405 0 ) +insert ( 10264 1977 23 23 1 s 96 405 0 ) +insert ( 10265 1977 20 20 1 s 410 405 0 ) +insert ( 10266 1977 21 23 1 s 532 405 0 ) +insert ( 10267 1977 21 20 1 s 1862 405 0 ) +insert ( 10268 1977 23 21 1 s 533 405 0 ) +insert ( 10269 1977 23 20 1 s 15 405 0 ) +insert ( 10270 1977 20 21 1 s 1868 405 0 ) +insert ( 10271 1977 20 23 1 s 416 405 0 ) +insert ( 10272 1983 1186 1186 1 s 1330 405 0 ) +insert ( 10273 1985 829 829 1 s 1220 405 0 ) +insert ( 10274 3372 774 774 1 s 3362 405 0 ) +insert ( 10275 1990 26 26 1 s 607 405 0 ) +insert ( 10276 1992 30 30 1 s 649 405 0 ) +insert ( 10277 6194 2249 2249 1 s 2988 405 0 ) +insert ( 10278 1995 25 25 1 s 98 405 0 ) +insert ( 10279 1995 19 19 1 s 93 405 0 ) +insert ( 10280 1995 19 25 1 s 254 405 0 ) +insert ( 10281 1995 25 19 1 s 260 405 0 ) +insert ( 10282 1997 1083 1083 1 s 1108 405 0 ) +insert ( 10283 1999 1184 1184 1 s 1320 405 0 ) +insert ( 10284 2001 1266 1266 1 s 1550 405 0 ) +insert ( 10285 2040 1114 1114 1 s 2060 405 0 ) +insert ( 10286 2222 16 16 1 s 91 405 0 ) +insert ( 10287 2223 17 17 1 s 1955 405 0 ) +insert ( 10288 2225 28 28 1 s 352 405 0 ) +insert ( 10289 5032 5069 5069 1 s 5068 405 0 ) +insert ( 10290 2226 29 29 1 s 385 405 0 ) +insert ( 10291 2227 27 27 1 s 387 405 0 ) +insert ( 10292 2229 25 25 1 s 98 405 0 ) +insert ( 10293 2231 1042 1042 1 s 1054 405 0 ) +insert ( 10294 2235 1033 1033 1 s 974 405 0 ) +insert ( 10295 2969 2950 2950 1 s 2972 405 0 ) +insert ( 10296 3254 3220 3220 1 s 3222 405 0 ) +insert ( 10297 1998 1700 1700 1 s 1752 405 0 ) +insert ( 10298 627 2277 2277 1 s 1070 405 0 ) +insert ( 10299 2593 603 603 1 s 493 783 0 ) +insert ( 10300 2593 603 603 2 s 494 783 0 ) +insert ( 10301 2593 603 603 3 s 500 783 0 ) +insert ( 10302 2593 603 603 4 s 495 783 0 ) +insert ( 10303 2593 603 603 5 s 496 783 0 ) +insert ( 10304 2593 603 603 6 s 499 783 0 ) +insert ( 10305 2593 603 603 7 s 498 783 0 ) +insert ( 10306 2593 603 603 8 s 497 783 0 ) +insert ( 10307 2593 603 603 9 s 2571 783 0 ) +insert ( 10308 2593 603 603 10 s 2570 783 0 ) +insert ( 10309 2593 603 603 11 s 2573 783 0 ) +insert ( 10310 2593 603 603 12 s 2572 783 0 ) +insert ( 10311 2593 603 600 15 o 606 783 1970 ) +insert ( 10312 1029 600 600 11 s 4161 783 0 ) +insert ( 10313 1029 600 600 30 s 506 783 0 ) +insert ( 10314 1029 600 600 1 s 507 783 0 ) +insert ( 10315 1029 600 600 5 s 508 783 0 ) +insert ( 10316 1029 600 600 10 s 4162 783 0 ) +insert ( 10317 1029 600 600 29 s 509 783 0 ) +insert ( 10318 1029 600 600 6 s 510 783 0 ) +insert ( 10319 1029 600 600 15 o 517 783 1970 ) +insert ( 10320 1029 600 603 28 s 511 783 0 ) +insert ( 10321 1029 600 604 48 s 756 783 0 ) +insert ( 10322 1029 600 718 68 s 758 783 0 ) +insert ( 10323 2594 604 604 1 s 485 783 0 ) +insert ( 10324 2594 604 604 2 s 486 783 0 ) +insert ( 10325 2594 604 604 3 s 492 783 0 ) +insert ( 10326 2594 604 604 4 s 487 783 0 ) +insert ( 10327 2594 604 604 5 s 488 783 0 ) +insert ( 10328 2594 604 604 6 s 491 783 0 ) +insert ( 10329 2594 604 604 7 s 490 783 0 ) +insert ( 10330 2594 604 604 8 s 489 783 0 ) +insert ( 10331 2594 604 604 9 s 2575 783 0 ) +insert ( 10332 2594 604 604 10 s 2574 783 0 ) +insert ( 10333 2594 604 604 11 s 2577 783 0 ) +insert ( 10334 2594 604 604 12 s 2576 783 0 ) +insert ( 10335 2594 604 600 15 o 3289 783 1970 ) +insert ( 10336 2595 718 718 1 s 1506 783 0 ) +insert ( 10337 2595 718 718 2 s 1507 783 0 ) +insert ( 10338 2595 718 718 3 s 1513 783 0 ) +insert ( 10339 2595 718 718 4 s 1508 783 0 ) +insert ( 10340 2595 718 718 5 s 1509 783 0 ) +insert ( 10341 2595 718 718 6 s 1512 783 0 ) +insert ( 10342 2595 718 718 7 s 1511 783 0 ) +insert ( 10343 2595 718 718 8 s 1510 783 0 ) +insert ( 10344 2595 718 718 9 s 2589 783 0 ) +insert ( 10345 2595 718 718 10 s 1515 783 0 ) +insert ( 10346 2595 718 718 11 s 1514 783 0 ) +insert ( 10347 2595 718 718 12 s 2590 783 0 ) +insert ( 10348 2595 718 600 15 o 3291 783 1970 ) +insert ( 10349 2745 2277 2277 1 s 2750 2742 0 ) +insert ( 10350 2745 2277 2277 2 s 2751 2742 0 ) +insert ( 10351 2745 2277 2277 3 s 2752 2742 0 ) +insert ( 10352 2745 2277 2277 4 s 1070 2742 0 ) +insert ( 10353 3522 3500 3500 1 s 3518 403 0 ) +insert ( 10354 3522 3500 3500 2 s 3520 403 0 ) +insert ( 10355 3522 3500 3500 3 s 3516 403 0 ) +insert ( 10356 3522 3500 3500 4 s 3521 403 0 ) +insert ( 10357 3522 3500 3500 5 s 3519 403 0 ) +insert ( 10358 3523 3500 3500 1 s 3516 405 0 ) +insert ( 10359 3626 3614 3614 1 s 3627 403 0 ) +insert ( 10360 3626 3614 3614 2 s 3628 403 0 ) +insert ( 10361 3626 3614 3614 3 s 3629 403 0 ) +insert ( 10362 3626 3614 3614 4 s 3631 403 0 ) +insert ( 10363 3626 3614 3614 5 s 3632 403 0 ) +insert ( 10364 3655 3614 3615 1 s 3636 783 0 ) +insert ( 10365 3659 3614 3615 1 s 3636 2742 0 ) +insert ( 10366 3659 3614 3615 2 s 3660 2742 0 ) +insert ( 10367 3683 3615 3615 1 s 3674 403 0 ) +insert ( 10368 3683 3615 3615 2 s 3675 403 0 ) +insert ( 10369 3683 3615 3615 3 s 3676 403 0 ) +insert ( 10370 3683 3615 3615 4 s 3678 403 0 ) +insert ( 10371 3683 3615 3615 5 s 3679 403 0 ) +insert ( 10372 3702 3615 3615 7 s 3693 783 0 ) +insert ( 10373 3702 3615 3615 8 s 3694 783 0 ) +insert ( 10374 3901 3831 3831 1 s 3884 403 0 ) +insert ( 10375 3901 3831 3831 2 s 3885 403 0 ) +insert ( 10376 3901 3831 3831 3 s 3882 403 0 ) +insert ( 10377 3901 3831 3831 4 s 3886 403 0 ) +insert ( 10378 3901 3831 3831 5 s 3887 403 0 ) +insert ( 10379 3903 3831 3831 1 s 3882 405 0 ) +insert ( 10380 3919 3831 3831 1 s 3893 783 0 ) +insert ( 10381 3919 3831 4537 1 s 4395 783 0 ) +insert ( 10382 3919 3831 3831 2 s 3895 783 0 ) +insert ( 10383 3919 3831 4537 2 s 2875 783 0 ) +insert ( 10384 3919 3831 3831 3 s 3888 783 0 ) +insert ( 10385 3919 3831 4537 3 s 2866 783 0 ) +insert ( 10386 3919 3831 3831 4 s 3896 783 0 ) +insert ( 10387 3919 3831 4537 4 s 3585 783 0 ) +insert ( 10388 3919 3831 3831 5 s 3894 783 0 ) +insert ( 10389 3919 3831 4537 5 s 4398 783 0 ) +insert ( 10390 3919 3831 3831 6 s 3897 783 0 ) +insert ( 10391 3919 3831 4537 6 s 4179 783 0 ) +insert ( 10392 3919 3831 3831 7 s 3890 783 0 ) +insert ( 10393 3919 3831 4537 7 s 4539 783 0 ) +insert ( 10394 3919 3831 3831 8 s 3892 783 0 ) +insert ( 10395 3919 3831 4537 8 s 2873 783 0 ) +insert ( 10396 3919 3831 2283 16 s 3889 783 0 ) +insert ( 10397 3919 3831 3831 18 s 3882 783 0 ) +insert ( 10398 6158 4537 4537 1 s 4397 783 0 ) +insert ( 10399 6158 4537 3831 1 s 4396 783 0 ) +insert ( 10400 6158 4537 4537 2 s 2877 783 0 ) +insert ( 10401 6158 4537 3831 2 s 2876 783 0 ) +insert ( 10402 6158 4537 4537 3 s 2868 783 0 ) +insert ( 10403 6158 4537 3831 3 s 2867 783 0 ) +insert ( 10404 6158 4537 4537 4 s 4142 783 0 ) +insert ( 10405 6158 4537 3831 4 s 4035 783 0 ) +insert ( 10406 6158 4537 4537 5 s 4400 783 0 ) +insert ( 10407 6158 4537 3831 5 s 4399 783 0 ) +insert ( 10408 6158 4537 4537 6 s 4198 783 0 ) +insert ( 10409 6158 4537 3831 6 s 4180 783 0 ) +insert ( 10410 6158 4537 4537 7 s 2871 783 0 ) +insert ( 10411 6158 4537 3831 7 s 2870 783 0 ) +insert ( 10412 6158 4537 4537 8 s 2874 783 0 ) +insert ( 10413 6158 4537 3831 8 s 4540 783 0 ) +insert ( 10414 6158 4537 2283 16 s 2869 783 0 ) +insert ( 10415 6158 4537 4537 18 s 2860 783 0 ) +insert ( 10416 4199 4537 4537 1 s 2862 403 0 ) +insert ( 10417 4199 4537 4537 2 s 2863 403 0 ) +insert ( 10418 4199 4537 4537 3 s 2860 403 0 ) +insert ( 10419 4199 4537 4537 4 s 2864 403 0 ) +insert ( 10420 4199 4537 4537 5 s 2865 403 0 ) +insert ( 10421 4225 4537 4537 1 s 2860 405 0 ) +insert ( 10422 4015 600 600 11 s 4161 4000 0 ) +insert ( 10423 4015 600 600 30 s 506 4000 0 ) +insert ( 10424 4015 600 600 1 s 507 4000 0 ) +insert ( 10425 4015 600 600 5 s 508 4000 0 ) +insert ( 10426 4015 600 600 10 s 4162 4000 0 ) +insert ( 10427 4015 600 600 29 s 509 4000 0 ) +insert ( 10428 4015 600 600 6 s 510 4000 0 ) +insert ( 10429 4015 600 603 8 s 511 4000 0 ) +insert ( 10430 4015 600 600 15 o 517 4000 1970 ) +insert ( 10431 4016 600 600 11 s 4161 4000 0 ) +insert ( 10432 4016 600 600 30 s 506 4000 0 ) +insert ( 10433 4016 600 600 1 s 507 4000 0 ) +insert ( 10434 4016 600 600 5 s 508 4000 0 ) +insert ( 10435 4016 600 600 10 s 4162 4000 0 ) +insert ( 10436 4016 600 600 29 s 509 4000 0 ) +insert ( 10437 4016 600 600 6 s 510 4000 0 ) +insert ( 10438 4016 600 603 8 s 511 4000 0 ) +insert ( 10439 4016 600 600 15 o 517 4000 1970 ) +insert ( 10440 4017 25 25 1 s 2314 4000 0 ) +insert ( 10441 4017 25 25 2 s 2315 4000 0 ) +insert ( 10442 4017 25 25 3 s 98 4000 0 ) +insert ( 10443 4017 25 25 4 s 2317 4000 0 ) +insert ( 10444 4017 25 25 5 s 2318 4000 0 ) +insert ( 10445 4017 25 25 11 s 664 4000 0 ) +insert ( 10446 4017 25 25 12 s 665 4000 0 ) +insert ( 10447 4017 25 25 14 s 667 4000 0 ) +insert ( 10448 4017 25 25 15 s 666 4000 0 ) +insert ( 10449 4017 25 25 28 s 3877 4000 0 ) +insert ( 10450 4033 3802 3802 1 s 3242 403 0 ) +insert ( 10451 4033 3802 3802 2 s 3244 403 0 ) +insert ( 10452 4033 3802 3802 3 s 3240 403 0 ) +insert ( 10453 4033 3802 3802 4 s 3245 403 0 ) +insert ( 10454 4033 3802 3802 5 s 3243 403 0 ) +insert ( 10455 4034 3802 3802 1 s 3240 405 0 ) +insert ( 10456 4036 3802 3802 7 s 3246 2742 0 ) +insert ( 10457 4036 3802 25 9 s 3247 2742 0 ) +insert ( 10458 4036 3802 1009 10 s 3248 2742 0 ) +insert ( 10459 4036 3802 1009 11 s 3249 2742 0 ) +insert ( 10460 4036 3802 4072 15 s 4012 2742 0 ) +insert ( 10461 4036 3802 4072 16 s 4013 2742 0 ) +insert ( 10462 4037 3802 3802 7 s 3246 2742 0 ) +insert ( 10463 4037 3802 4072 15 s 4012 2742 0 ) +insert ( 10464 4037 3802 4072 16 s 4013 2742 0 ) +insert ( 10465 3474 3831 3831 1 s 3893 4000 0 ) +insert ( 10466 3474 3831 3831 2 s 3895 4000 0 ) +insert ( 10467 3474 3831 3831 3 s 3888 4000 0 ) +insert ( 10468 3474 3831 3831 4 s 3896 4000 0 ) +insert ( 10469 3474 3831 3831 5 s 3894 4000 0 ) +insert ( 10470 3474 3831 3831 6 s 3897 4000 0 ) +insert ( 10471 3474 3831 3831 7 s 3890 4000 0 ) +insert ( 10472 3474 3831 3831 8 s 3892 4000 0 ) +insert ( 10473 3474 3831 2283 16 s 3889 4000 0 ) +insert ( 10474 3474 3831 3831 18 s 3882 4000 0 ) +insert ( 10475 5000 603 603 1 s 493 4000 0 ) +insert ( 10476 5000 603 603 2 s 494 4000 0 ) +insert ( 10477 5000 603 603 3 s 500 4000 0 ) +insert ( 10478 5000 603 603 4 s 495 4000 0 ) +insert ( 10479 5000 603 603 5 s 496 4000 0 ) +insert ( 10480 5000 603 603 6 s 499 4000 0 ) +insert ( 10481 5000 603 603 7 s 498 4000 0 ) +insert ( 10482 5000 603 603 8 s 497 4000 0 ) +insert ( 10483 5000 603 603 9 s 2571 4000 0 ) +insert ( 10484 5000 603 603 10 s 2570 4000 0 ) +insert ( 10485 5000 603 603 11 s 2573 4000 0 ) +insert ( 10486 5000 603 603 12 s 2572 4000 0 ) +insert ( 10487 5000 603 600 15 o 606 4000 1970 ) +insert ( 10488 5008 604 604 1 s 485 4000 0 ) +insert ( 10489 5008 604 604 2 s 486 4000 0 ) +insert ( 10490 5008 604 604 3 s 492 4000 0 ) +insert ( 10491 5008 604 604 4 s 487 4000 0 ) +insert ( 10492 5008 604 604 5 s 488 4000 0 ) +insert ( 10493 5008 604 604 6 s 491 4000 0 ) +insert ( 10494 5008 604 604 7 s 490 4000 0 ) +insert ( 10495 5008 604 604 8 s 489 4000 0 ) +insert ( 10496 5008 604 604 9 s 2575 4000 0 ) +insert ( 10497 5008 604 604 10 s 2574 4000 0 ) +insert ( 10498 5008 604 604 11 s 2577 4000 0 ) +insert ( 10499 5008 604 604 12 s 2576 4000 0 ) +insert ( 10500 5008 604 600 15 o 3289 4000 1970 ) +insert ( 10501 3550 869 869 3 s 3552 783 0 ) +insert ( 10502 3550 869 869 18 s 1201 783 0 ) +insert ( 10503 3550 869 869 19 s 1202 783 0 ) +insert ( 10504 3550 869 869 20 s 1203 783 0 ) +insert ( 10505 3550 869 869 21 s 1204 783 0 ) +insert ( 10506 3550 869 869 22 s 1205 783 0 ) +insert ( 10507 3550 869 869 23 s 1206 783 0 ) +insert ( 10508 3550 869 869 24 s 931 783 0 ) +insert ( 10509 3550 869 869 25 s 932 783 0 ) +insert ( 10510 3550 869 869 26 s 933 783 0 ) +insert ( 10511 3550 869 869 27 s 934 783 0 ) +insert ( 10512 3794 869 869 3 s 3552 4000 0 ) +insert ( 10513 3794 869 869 18 s 1201 4000 0 ) +insert ( 10514 3794 869 869 19 s 1202 4000 0 ) +insert ( 10515 3794 869 869 20 s 1203 4000 0 ) +insert ( 10516 3794 869 869 21 s 1204 4000 0 ) +insert ( 10517 3794 869 869 22 s 1205 4000 0 ) +insert ( 10518 3794 869 869 23 s 1206 4000 0 ) +insert ( 10519 3794 869 869 24 s 931 4000 0 ) +insert ( 10520 3794 869 869 25 s 932 4000 0 ) +insert ( 10521 3794 869 869 26 s 933 4000 0 ) +insert ( 10522 3794 869 869 27 s 934 4000 0 ) +insert ( 10523 4064 17 17 1 s 1957 3580 0 ) +insert ( 10524 4064 17 17 2 s 1958 3580 0 ) +insert ( 10525 4064 17 17 3 s 1955 3580 0 ) +insert ( 10526 4064 17 17 4 s 1960 3580 0 ) +insert ( 10527 4064 17 17 5 s 1959 3580 0 ) +insert ( 10528 4578 17 17 1 s 1955 3580 0 ) +insert ( 10529 4062 18 18 1 s 631 3580 0 ) +insert ( 10530 4062 18 18 2 s 632 3580 0 ) +insert ( 10531 4062 18 18 3 s 92 3580 0 ) +insert ( 10532 4062 18 18 4 s 634 3580 0 ) +insert ( 10533 4062 18 18 5 s 633 3580 0 ) +insert ( 10534 4577 18 18 1 s 92 3580 0 ) +insert ( 10535 4065 19 19 1 s 660 3580 0 ) +insert ( 10536 4065 19 19 2 s 661 3580 0 ) +insert ( 10537 4065 19 19 3 s 93 3580 0 ) +insert ( 10538 4065 19 19 4 s 663 3580 0 ) +insert ( 10539 4065 19 19 5 s 662 3580 0 ) +insert ( 10540 4579 19 19 1 s 93 3580 0 ) +insert ( 10541 4054 20 20 1 s 412 3580 0 ) +insert ( 10542 4054 20 20 2 s 414 3580 0 ) +insert ( 10543 4054 20 20 3 s 410 3580 0 ) +insert ( 10544 4054 20 20 4 s 415 3580 0 ) +insert ( 10545 4054 20 20 5 s 413 3580 0 ) +insert ( 10546 4054 20 21 1 s 1870 3580 0 ) +insert ( 10547 4054 20 21 2 s 1872 3580 0 ) +insert ( 10548 4054 20 21 3 s 1868 3580 0 ) +insert ( 10549 4054 20 21 4 s 1873 3580 0 ) +insert ( 10550 4054 20 21 5 s 1871 3580 0 ) +insert ( 10551 4054 20 23 1 s 418 3580 0 ) +insert ( 10552 4054 20 23 2 s 420 3580 0 ) +insert ( 10553 4054 20 23 3 s 416 3580 0 ) +insert ( 10554 4054 20 23 4 s 430 3580 0 ) +insert ( 10555 4054 20 23 5 s 419 3580 0 ) +insert ( 10556 4054 21 21 1 s 95 3580 0 ) +insert ( 10557 4054 21 21 2 s 522 3580 0 ) +insert ( 10558 4054 21 21 3 s 94 3580 0 ) +insert ( 10559 4054 21 21 4 s 524 3580 0 ) +insert ( 10560 4054 21 21 5 s 520 3580 0 ) +insert ( 10561 4054 21 20 1 s 1864 3580 0 ) +insert ( 10562 4054 21 20 2 s 1866 3580 0 ) +insert ( 10563 4054 21 20 3 s 1862 3580 0 ) +insert ( 10564 4054 21 20 4 s 1867 3580 0 ) +insert ( 10565 4054 21 20 5 s 1865 3580 0 ) +insert ( 10566 4054 21 23 1 s 534 3580 0 ) +insert ( 10567 4054 21 23 2 s 540 3580 0 ) +insert ( 10568 4054 21 23 3 s 532 3580 0 ) +insert ( 10569 4054 21 23 4 s 542 3580 0 ) +insert ( 10570 4054 21 23 5 s 536 3580 0 ) +insert ( 10571 4054 23 23 1 s 97 3580 0 ) +insert ( 10572 4054 23 23 2 s 523 3580 0 ) +insert ( 10573 4054 23 23 3 s 96 3580 0 ) +insert ( 10574 4054 23 23 4 s 525 3580 0 ) +insert ( 10575 4054 23 23 5 s 521 3580 0 ) +insert ( 10576 4054 23 21 1 s 535 3580 0 ) +insert ( 10577 4054 23 21 2 s 541 3580 0 ) +insert ( 10578 4054 23 21 3 s 533 3580 0 ) +insert ( 10579 4054 23 21 4 s 543 3580 0 ) +insert ( 10580 4054 23 21 5 s 537 3580 0 ) +insert ( 10581 4054 23 20 1 s 37 3580 0 ) +insert ( 10582 4054 23 20 2 s 80 3580 0 ) +insert ( 10583 4054 23 20 3 s 15 3580 0 ) +insert ( 10584 4054 23 20 4 s 82 3580 0 ) +insert ( 10585 4054 23 20 5 s 76 3580 0 ) +insert ( 10586 4602 20 20 1 s 412 3580 0 ) +insert ( 10587 4602 20 20 2 s 414 3580 0 ) +insert ( 10588 4602 20 20 3 s 410 3580 0 ) +insert ( 10589 4602 20 20 4 s 415 3580 0 ) +insert ( 10590 4602 20 20 5 s 413 3580 0 ) +insert ( 10591 4602 20 21 1 s 1870 3580 0 ) +insert ( 10592 4602 20 21 2 s 1872 3580 0 ) +insert ( 10593 4602 20 21 3 s 1868 3580 0 ) +insert ( 10594 4602 20 21 4 s 1873 3580 0 ) +insert ( 10595 4602 20 21 5 s 1871 3580 0 ) +insert ( 10596 4602 20 23 1 s 418 3580 0 ) +insert ( 10597 4602 20 23 2 s 420 3580 0 ) +insert ( 10598 4602 20 23 3 s 416 3580 0 ) +insert ( 10599 4602 20 23 4 s 430 3580 0 ) +insert ( 10600 4602 20 23 5 s 419 3580 0 ) +insert ( 10601 4602 21 21 1 s 95 3580 0 ) +insert ( 10602 4602 21 21 2 s 522 3580 0 ) +insert ( 10603 4602 21 21 3 s 94 3580 0 ) +insert ( 10604 4602 21 21 4 s 524 3580 0 ) +insert ( 10605 4602 21 21 5 s 520 3580 0 ) +insert ( 10606 4602 21 20 1 s 1864 3580 0 ) +insert ( 10607 4602 21 20 2 s 1866 3580 0 ) +insert ( 10608 4602 21 20 3 s 1862 3580 0 ) +insert ( 10609 4602 21 20 4 s 1867 3580 0 ) +insert ( 10610 4602 21 20 5 s 1865 3580 0 ) +insert ( 10611 4602 21 23 1 s 534 3580 0 ) +insert ( 10612 4602 21 23 2 s 540 3580 0 ) +insert ( 10613 4602 21 23 3 s 532 3580 0 ) +insert ( 10614 4602 21 23 4 s 542 3580 0 ) +insert ( 10615 4602 21 23 5 s 536 3580 0 ) +insert ( 10616 4602 23 23 1 s 97 3580 0 ) +insert ( 10617 4602 23 23 2 s 523 3580 0 ) +insert ( 10618 4602 23 23 3 s 96 3580 0 ) +insert ( 10619 4602 23 23 4 s 525 3580 0 ) +insert ( 10620 4602 23 23 5 s 521 3580 0 ) +insert ( 10621 4602 23 21 1 s 535 3580 0 ) +insert ( 10622 4602 23 21 2 s 541 3580 0 ) +insert ( 10623 4602 23 21 3 s 533 3580 0 ) +insert ( 10624 4602 23 21 4 s 543 3580 0 ) +insert ( 10625 4602 23 21 5 s 537 3580 0 ) +insert ( 10626 4602 23 20 1 s 37 3580 0 ) +insert ( 10627 4602 23 20 2 s 80 3580 0 ) +insert ( 10628 4602 23 20 3 s 15 3580 0 ) +insert ( 10629 4602 23 20 4 s 82 3580 0 ) +insert ( 10630 4602 23 20 5 s 76 3580 0 ) +insert ( 10631 4572 20 20 1 s 410 3580 0 ) +insert ( 10632 4572 21 21 1 s 94 3580 0 ) +insert ( 10633 4572 23 23 1 s 96 3580 0 ) +insert ( 10634 4056 25 25 1 s 664 3580 0 ) +insert ( 10635 4056 25 25 2 s 665 3580 0 ) +insert ( 10636 4056 25 25 3 s 98 3580 0 ) +insert ( 10637 4056 25 25 4 s 667 3580 0 ) +insert ( 10638 4056 25 25 5 s 666 3580 0 ) +insert ( 10639 4573 25 25 1 s 98 3580 0 ) +insert ( 10640 4068 26 26 1 s 609 3580 0 ) +insert ( 10641 4068 26 26 2 s 611 3580 0 ) +insert ( 10642 4068 26 26 3 s 607 3580 0 ) +insert ( 10643 4068 26 26 4 s 612 3580 0 ) +insert ( 10644 4068 26 26 5 s 610 3580 0 ) +insert ( 10645 4606 26 26 1 s 609 3580 0 ) +insert ( 10646 4606 26 26 2 s 611 3580 0 ) +insert ( 10647 4606 26 26 3 s 607 3580 0 ) +insert ( 10648 4606 26 26 4 s 612 3580 0 ) +insert ( 10649 4606 26 26 5 s 610 3580 0 ) +insert ( 10650 4580 26 26 1 s 607 3580 0 ) +insert ( 10651 4069 27 27 1 s 2799 3580 0 ) +insert ( 10652 4069 27 27 2 s 2801 3580 0 ) +insert ( 10653 4069 27 27 3 s 387 3580 0 ) +insert ( 10654 4069 27 27 4 s 2802 3580 0 ) +insert ( 10655 4069 27 27 5 s 2800 3580 0 ) +insert ( 10656 4581 27 27 1 s 387 3580 0 ) +insert ( 10657 4607 27 27 1 s 2799 3580 0 ) +insert ( 10658 4607 27 27 2 s 2801 3580 0 ) +insert ( 10659 4607 27 27 3 s 387 3580 0 ) +insert ( 10660 4607 27 27 4 s 2802 3580 0 ) +insert ( 10661 4607 27 27 5 s 2800 3580 0 ) +insert ( 10662 4070 700 700 1 s 622 3580 0 ) +insert ( 10663 4070 700 700 2 s 624 3580 0 ) +insert ( 10664 4070 700 700 3 s 620 3580 0 ) +insert ( 10665 4070 700 700 4 s 625 3580 0 ) +insert ( 10666 4070 700 700 5 s 623 3580 0 ) +insert ( 10667 4070 700 701 1 s 1122 3580 0 ) +insert ( 10668 4070 700 701 2 s 1124 3580 0 ) +insert ( 10669 4070 700 701 3 s 1120 3580 0 ) +insert ( 10670 4070 700 701 4 s 1125 3580 0 ) +insert ( 10671 4070 700 701 5 s 1123 3580 0 ) +insert ( 10672 4070 701 700 1 s 1132 3580 0 ) +insert ( 10673 4070 701 700 2 s 1134 3580 0 ) +insert ( 10674 4070 701 700 3 s 1130 3580 0 ) +insert ( 10675 4070 701 700 4 s 1135 3580 0 ) +insert ( 10676 4070 701 700 5 s 1133 3580 0 ) +insert ( 10677 4070 701 701 1 s 672 3580 0 ) +insert ( 10678 4070 701 701 2 s 673 3580 0 ) +insert ( 10679 4070 701 701 3 s 670 3580 0 ) +insert ( 10680 4070 701 701 4 s 675 3580 0 ) +insert ( 10681 4070 701 701 5 s 674 3580 0 ) +insert ( 10682 4608 700 700 1 s 622 3580 0 ) +insert ( 10683 4608 700 700 2 s 624 3580 0 ) +insert ( 10684 4608 700 700 3 s 620 3580 0 ) +insert ( 10685 4608 700 700 4 s 625 3580 0 ) +insert ( 10686 4608 700 700 5 s 623 3580 0 ) +insert ( 10687 4608 700 701 1 s 1122 3580 0 ) +insert ( 10688 4608 700 701 2 s 1124 3580 0 ) +insert ( 10689 4608 700 701 3 s 1120 3580 0 ) +insert ( 10690 4608 700 701 4 s 1125 3580 0 ) +insert ( 10691 4608 700 701 5 s 1123 3580 0 ) +insert ( 10692 4608 701 700 1 s 1132 3580 0 ) +insert ( 10693 4608 701 700 2 s 1134 3580 0 ) +insert ( 10694 4608 701 700 3 s 1130 3580 0 ) +insert ( 10695 4608 701 700 4 s 1135 3580 0 ) +insert ( 10696 4608 701 700 5 s 1133 3580 0 ) +insert ( 10697 4608 701 701 1 s 672 3580 0 ) +insert ( 10698 4608 701 701 2 s 673 3580 0 ) +insert ( 10699 4608 701 701 3 s 670 3580 0 ) +insert ( 10700 4608 701 701 4 s 675 3580 0 ) +insert ( 10701 4608 701 701 5 s 674 3580 0 ) +insert ( 10702 4582 700 700 1 s 620 3580 0 ) +insert ( 10703 4582 701 701 1 s 670 3580 0 ) +insert ( 10704 4074 829 829 1 s 1222 3580 0 ) +insert ( 10705 4074 829 829 2 s 1223 3580 0 ) +insert ( 10706 4074 829 829 3 s 1220 3580 0 ) +insert ( 10707 4074 829 829 4 s 1225 3580 0 ) +insert ( 10708 4074 829 829 5 s 1224 3580 0 ) +insert ( 10709 4609 829 829 1 s 1222 3580 0 ) +insert ( 10710 4609 829 829 2 s 1223 3580 0 ) +insert ( 10711 4609 829 829 3 s 1220 3580 0 ) +insert ( 10712 4609 829 829 4 s 1225 3580 0 ) +insert ( 10713 4609 829 829 5 s 1224 3580 0 ) +insert ( 10714 4583 829 829 1 s 1220 3580 0 ) +insert ( 10715 4109 774 774 1 s 3364 3580 0 ) +insert ( 10716 4109 774 774 2 s 3365 3580 0 ) +insert ( 10717 4109 774 774 3 s 3362 3580 0 ) +insert ( 10718 4109 774 774 4 s 3367 3580 0 ) +insert ( 10719 4109 774 774 5 s 3366 3580 0 ) +insert ( 10720 4610 774 774 1 s 3364 3580 0 ) +insert ( 10721 4610 774 774 2 s 3365 3580 0 ) +insert ( 10722 4610 774 774 3 s 3362 3580 0 ) +insert ( 10723 4610 774 774 4 s 3367 3580 0 ) +insert ( 10724 4610 774 774 5 s 3366 3580 0 ) +insert ( 10725 4584 774 774 1 s 3362 3580 0 ) +insert ( 10726 4075 869 869 1 s 1203 3580 0 ) +insert ( 10727 4075 869 869 2 s 1204 3580 0 ) +insert ( 10728 4075 869 869 3 s 1201 3580 0 ) +insert ( 10729 4075 869 869 4 s 1206 3580 0 ) +insert ( 10730 4075 869 869 5 s 1205 3580 0 ) +insert ( 10731 4611 869 869 1 s 1203 3580 0 ) +insert ( 10732 4611 869 869 2 s 1204 3580 0 ) +insert ( 10733 4611 869 869 3 s 1201 3580 0 ) +insert ( 10734 4611 869 869 4 s 1206 3580 0 ) +insert ( 10735 4611 869 869 5 s 1205 3580 0 ) +insert ( 10736 4585 869 869 1 s 1201 3580 0 ) +insert ( 10737 4102 869 869 3 s 3552 3580 0 ) +insert ( 10738 4102 869 869 7 s 934 3580 0 ) +insert ( 10739 4102 869 869 8 s 932 3580 0 ) +insert ( 10740 4102 869 869 18 s 1201 3580 0 ) +insert ( 10741 4102 869 869 24 s 933 3580 0 ) +insert ( 10742 4102 869 869 26 s 931 3580 0 ) +insert ( 10743 4076 1042 1042 1 s 1058 3580 0 ) +insert ( 10744 4076 1042 1042 2 s 1059 3580 0 ) +insert ( 10745 4076 1042 1042 3 s 1054 3580 0 ) +insert ( 10746 4076 1042 1042 4 s 1061 3580 0 ) +insert ( 10747 4076 1042 1042 5 s 1060 3580 0 ) +insert ( 10748 4586 1042 1042 1 s 1054 3580 0 ) +insert ( 10749 4077 1083 1083 1 s 1110 3580 0 ) +insert ( 10750 4077 1083 1083 2 s 1111 3580 0 ) +insert ( 10751 4077 1083 1083 3 s 1108 3580 0 ) +insert ( 10752 4077 1083 1083 4 s 1113 3580 0 ) +insert ( 10753 4077 1083 1083 5 s 1112 3580 0 ) +insert ( 10754 4612 1083 1083 1 s 1110 3580 0 ) +insert ( 10755 4612 1083 1083 2 s 1111 3580 0 ) +insert ( 10756 4612 1083 1083 3 s 1108 3580 0 ) +insert ( 10757 4612 1083 1083 4 s 1113 3580 0 ) +insert ( 10758 4612 1083 1083 5 s 1112 3580 0 ) +insert ( 10759 4587 1083 1083 1 s 1108 3580 0 ) +insert ( 10760 4059 1114 1114 1 s 2062 3580 0 ) +insert ( 10761 4059 1114 1114 2 s 2063 3580 0 ) +insert ( 10762 4059 1114 1114 3 s 2060 3580 0 ) +insert ( 10763 4059 1114 1114 4 s 2065 3580 0 ) +insert ( 10764 4059 1114 1114 5 s 2064 3580 0 ) +insert ( 10765 4059 1114 1082 1 s 2371 3580 0 ) +insert ( 10766 4059 1114 1082 2 s 2372 3580 0 ) +insert ( 10767 4059 1114 1082 3 s 2373 3580 0 ) +insert ( 10768 4059 1114 1082 4 s 2374 3580 0 ) +insert ( 10769 4059 1114 1082 5 s 2375 3580 0 ) +insert ( 10770 4059 1114 1184 1 s 2534 3580 0 ) +insert ( 10771 4059 1114 1184 2 s 2535 3580 0 ) +insert ( 10772 4059 1114 1184 3 s 2536 3580 0 ) +insert ( 10773 4059 1114 1184 4 s 2537 3580 0 ) +insert ( 10774 4059 1114 1184 5 s 2538 3580 0 ) +insert ( 10775 4059 1082 1082 1 s 1095 3580 0 ) +insert ( 10776 4059 1082 1082 2 s 1096 3580 0 ) +insert ( 10777 4059 1082 1082 3 s 1093 3580 0 ) +insert ( 10778 4059 1082 1082 4 s 1098 3580 0 ) +insert ( 10779 4059 1082 1082 5 s 1097 3580 0 ) +insert ( 10780 4059 1082 1114 1 s 2345 3580 0 ) +insert ( 10781 4059 1082 1114 2 s 2346 3580 0 ) +insert ( 10782 4059 1082 1114 3 s 2347 3580 0 ) +insert ( 10783 4059 1082 1114 4 s 2348 3580 0 ) +insert ( 10784 4059 1082 1114 5 s 2349 3580 0 ) +insert ( 10785 4059 1082 1184 1 s 2358 3580 0 ) +insert ( 10786 4059 1082 1184 2 s 2359 3580 0 ) +insert ( 10787 4059 1082 1184 3 s 2360 3580 0 ) +insert ( 10788 4059 1082 1184 4 s 2361 3580 0 ) +insert ( 10789 4059 1082 1184 5 s 2362 3580 0 ) +insert ( 10790 4059 1184 1082 1 s 2384 3580 0 ) +insert ( 10791 4059 1184 1082 2 s 2385 3580 0 ) +insert ( 10792 4059 1184 1082 3 s 2386 3580 0 ) +insert ( 10793 4059 1184 1082 4 s 2387 3580 0 ) +insert ( 10794 4059 1184 1082 5 s 2388 3580 0 ) +insert ( 10795 4059 1184 1114 1 s 2540 3580 0 ) +insert ( 10796 4059 1184 1114 2 s 2541 3580 0 ) +insert ( 10797 4059 1184 1114 3 s 2542 3580 0 ) +insert ( 10798 4059 1184 1114 4 s 2543 3580 0 ) +insert ( 10799 4059 1184 1114 5 s 2544 3580 0 ) +insert ( 10800 4059 1184 1184 1 s 1322 3580 0 ) +insert ( 10801 4059 1184 1184 2 s 1323 3580 0 ) +insert ( 10802 4059 1184 1184 3 s 1320 3580 0 ) +insert ( 10803 4059 1184 1184 4 s 1325 3580 0 ) +insert ( 10804 4059 1184 1184 5 s 1324 3580 0 ) +insert ( 10805 4605 1114 1114 1 s 2062 3580 0 ) +insert ( 10806 4605 1114 1114 2 s 2063 3580 0 ) +insert ( 10807 4605 1114 1114 3 s 2060 3580 0 ) +insert ( 10808 4605 1114 1114 4 s 2065 3580 0 ) +insert ( 10809 4605 1114 1114 5 s 2064 3580 0 ) +insert ( 10810 4605 1114 1082 1 s 2371 3580 0 ) +insert ( 10811 4605 1114 1082 2 s 2372 3580 0 ) +insert ( 10812 4605 1114 1082 3 s 2373 3580 0 ) +insert ( 10813 4605 1114 1082 4 s 2374 3580 0 ) +insert ( 10814 4605 1114 1082 5 s 2375 3580 0 ) +insert ( 10815 4605 1114 1184 1 s 2534 3580 0 ) +insert ( 10816 4605 1114 1184 2 s 2535 3580 0 ) +insert ( 10817 4605 1114 1184 3 s 2536 3580 0 ) +insert ( 10818 4605 1114 1184 4 s 2537 3580 0 ) +insert ( 10819 4605 1114 1184 5 s 2538 3580 0 ) +insert ( 10820 4605 1082 1082 1 s 1095 3580 0 ) +insert ( 10821 4605 1082 1082 2 s 1096 3580 0 ) +insert ( 10822 4605 1082 1082 3 s 1093 3580 0 ) +insert ( 10823 4605 1082 1082 4 s 1098 3580 0 ) +insert ( 10824 4605 1082 1082 5 s 1097 3580 0 ) +insert ( 10825 4605 1082 1114 1 s 2345 3580 0 ) +insert ( 10826 4605 1082 1114 2 s 2346 3580 0 ) +insert ( 10827 4605 1082 1114 3 s 2347 3580 0 ) +insert ( 10828 4605 1082 1114 4 s 2348 3580 0 ) +insert ( 10829 4605 1082 1114 5 s 2349 3580 0 ) +insert ( 10830 4605 1082 1184 1 s 2358 3580 0 ) +insert ( 10831 4605 1082 1184 2 s 2359 3580 0 ) +insert ( 10832 4605 1082 1184 3 s 2360 3580 0 ) +insert ( 10833 4605 1082 1184 4 s 2361 3580 0 ) +insert ( 10834 4605 1082 1184 5 s 2362 3580 0 ) +insert ( 10835 4605 1184 1082 1 s 2384 3580 0 ) +insert ( 10836 4605 1184 1082 2 s 2385 3580 0 ) +insert ( 10837 4605 1184 1082 3 s 2386 3580 0 ) +insert ( 10838 4605 1184 1082 4 s 2387 3580 0 ) +insert ( 10839 4605 1184 1082 5 s 2388 3580 0 ) +insert ( 10840 4605 1184 1114 1 s 2540 3580 0 ) +insert ( 10841 4605 1184 1114 2 s 2541 3580 0 ) +insert ( 10842 4605 1184 1114 3 s 2542 3580 0 ) +insert ( 10843 4605 1184 1114 4 s 2543 3580 0 ) +insert ( 10844 4605 1184 1114 5 s 2544 3580 0 ) +insert ( 10845 4605 1184 1184 1 s 1322 3580 0 ) +insert ( 10846 4605 1184 1184 2 s 1323 3580 0 ) +insert ( 10847 4605 1184 1184 3 s 1320 3580 0 ) +insert ( 10848 4605 1184 1184 4 s 1325 3580 0 ) +insert ( 10849 4605 1184 1184 5 s 1324 3580 0 ) +insert ( 10850 4576 1114 1114 1 s 2060 3580 0 ) +insert ( 10851 4576 1082 1082 1 s 1093 3580 0 ) +insert ( 10852 4576 1184 1184 1 s 1320 3580 0 ) +insert ( 10853 4078 1186 1186 1 s 1332 3580 0 ) +insert ( 10854 4078 1186 1186 2 s 1333 3580 0 ) +insert ( 10855 4078 1186 1186 3 s 1330 3580 0 ) +insert ( 10856 4078 1186 1186 4 s 1335 3580 0 ) +insert ( 10857 4078 1186 1186 5 s 1334 3580 0 ) +insert ( 10858 4613 1186 1186 1 s 1332 3580 0 ) +insert ( 10859 4613 1186 1186 2 s 1333 3580 0 ) +insert ( 10860 4613 1186 1186 3 s 1330 3580 0 ) +insert ( 10861 4613 1186 1186 4 s 1335 3580 0 ) +insert ( 10862 4613 1186 1186 5 s 1334 3580 0 ) +insert ( 10863 4588 1186 1186 1 s 1330 3580 0 ) +insert ( 10864 4058 1266 1266 1 s 1552 3580 0 ) +insert ( 10865 4058 1266 1266 2 s 1553 3580 0 ) +insert ( 10866 4058 1266 1266 3 s 1550 3580 0 ) +insert ( 10867 4058 1266 1266 4 s 1555 3580 0 ) +insert ( 10868 4058 1266 1266 5 s 1554 3580 0 ) +insert ( 10869 4604 1266 1266 1 s 1552 3580 0 ) +insert ( 10870 4604 1266 1266 2 s 1553 3580 0 ) +insert ( 10871 4604 1266 1266 3 s 1550 3580 0 ) +insert ( 10872 4604 1266 1266 4 s 1555 3580 0 ) +insert ( 10873 4604 1266 1266 5 s 1554 3580 0 ) +insert ( 10874 4575 1266 1266 1 s 1550 3580 0 ) +insert ( 10875 4079 1560 1560 1 s 1786 3580 0 ) +insert ( 10876 4079 1560 1560 2 s 1788 3580 0 ) +insert ( 10877 4079 1560 1560 3 s 1784 3580 0 ) +insert ( 10878 4079 1560 1560 4 s 1789 3580 0 ) +insert ( 10879 4079 1560 1560 5 s 1787 3580 0 ) +insert ( 10880 4080 1562 1562 1 s 1806 3580 0 ) +insert ( 10881 4080 1562 1562 2 s 1808 3580 0 ) +insert ( 10882 4080 1562 1562 3 s 1804 3580 0 ) +insert ( 10883 4080 1562 1562 4 s 1809 3580 0 ) +insert ( 10884 4080 1562 1562 5 s 1807 3580 0 ) +insert ( 10885 4055 1700 1700 1 s 1754 3580 0 ) +insert ( 10886 4055 1700 1700 2 s 1755 3580 0 ) +insert ( 10887 4055 1700 1700 3 s 1752 3580 0 ) +insert ( 10888 4055 1700 1700 4 s 1757 3580 0 ) +insert ( 10889 4055 1700 1700 5 s 1756 3580 0 ) +insert ( 10890 4603 1700 1700 1 s 1754 3580 0 ) +insert ( 10891 4603 1700 1700 2 s 1755 3580 0 ) +insert ( 10892 4603 1700 1700 3 s 1752 3580 0 ) +insert ( 10893 4603 1700 1700 4 s 1757 3580 0 ) +insert ( 10894 4603 1700 1700 5 s 1756 3580 0 ) +insert ( 10895 4574 1700 1700 1 s 1752 3580 0 ) +insert ( 10896 4081 2950 2950 1 s 2974 3580 0 ) +insert ( 10897 4081 2950 2950 2 s 2976 3580 0 ) +insert ( 10898 4081 2950 2950 3 s 2972 3580 0 ) +insert ( 10899 4081 2950 2950 4 s 2977 3580 0 ) +insert ( 10900 4081 2950 2950 5 s 2975 3580 0 ) +insert ( 10901 4614 2950 2950 1 s 2974 3580 0 ) +insert ( 10902 4614 2950 2950 2 s 2976 3580 0 ) +insert ( 10903 4614 2950 2950 3 s 2972 3580 0 ) +insert ( 10904 4614 2950 2950 4 s 2977 3580 0 ) +insert ( 10905 4614 2950 2950 5 s 2975 3580 0 ) +insert ( 10906 4589 2950 2950 1 s 2972 3580 0 ) +insert ( 10907 4103 3831 3831 1 s 3893 3580 0 ) +insert ( 10908 4103 3831 3831 2 s 3895 3580 0 ) +insert ( 10909 4103 3831 3831 3 s 3888 3580 0 ) +insert ( 10910 4103 3831 3831 4 s 3896 3580 0 ) +insert ( 10911 4103 3831 3831 5 s 3894 3580 0 ) +insert ( 10912 4103 3831 3831 7 s 3890 3580 0 ) +insert ( 10913 4103 3831 3831 8 s 3892 3580 0 ) +insert ( 10914 4103 3831 2283 16 s 3889 3580 0 ) +insert ( 10915 4103 3831 3831 17 s 3897 3580 0 ) +insert ( 10916 4103 3831 3831 18 s 3882 3580 0 ) +insert ( 10917 4103 3831 3831 20 s 3884 3580 0 ) +insert ( 10918 4103 3831 3831 21 s 3885 3580 0 ) +insert ( 10919 4103 3831 3831 22 s 3887 3580 0 ) +insert ( 10920 4103 3831 3831 23 s 3886 3580 0 ) +insert ( 10921 4082 3220 3220 1 s 3224 3580 0 ) +insert ( 10922 4082 3220 3220 2 s 3226 3580 0 ) +insert ( 10923 4082 3220 3220 3 s 3222 3580 0 ) +insert ( 10924 4082 3220 3220 4 s 3227 3580 0 ) +insert ( 10925 4082 3220 3220 5 s 3225 3580 0 ) +insert ( 10926 4615 3220 3220 1 s 3224 3580 0 ) +insert ( 10927 4615 3220 3220 2 s 3226 3580 0 ) +insert ( 10928 4615 3220 3220 3 s 3222 3580 0 ) +insert ( 10929 4615 3220 3220 4 s 3227 3580 0 ) +insert ( 10930 4615 3220 3220 5 s 3225 3580 0 ) +insert ( 10931 4590 3220 3220 1 s 3222 3580 0 ) +insert ( 10932 4104 603 603 1 s 493 3580 0 ) +insert ( 10933 4104 603 603 2 s 494 3580 0 ) +insert ( 10934 4104 603 603 3 s 500 3580 0 ) +insert ( 10935 4104 603 603 4 s 495 3580 0 ) +insert ( 10936 4104 603 603 5 s 496 3580 0 ) +insert ( 10937 4104 603 603 6 s 499 3580 0 ) +insert ( 10938 4104 603 603 7 s 498 3580 0 ) +insert ( 10939 4104 603 603 8 s 497 3580 0 ) +insert ( 10940 4104 603 603 9 s 2571 3580 0 ) +insert ( 10941 4104 603 603 10 s 2570 3580 0 ) +insert ( 10942 4104 603 603 11 s 2573 3580 0 ) +insert ( 10943 4104 603 603 12 s 2572 3580 0 ) +insert ( 10944 4104 603 600 7 s 433 3580 0 ) +close pg_amop +create pg_amproc 2603 + ( + oid = oid , + amprocfamily = oid , + amproclefttype = oid , + amprocrighttype = oid , + amprocnum = int2 , + amproc = regproc + ) +open pg_amproc +insert ( 10000 397 2277 2277 1 382 ) +insert ( 10001 423 1560 1560 1 1596 ) +insert ( 10002 423 1560 1560 4 5051 ) +insert ( 10003 424 16 16 1 1693 ) +insert ( 10004 424 16 16 4 5051 ) +insert ( 10005 426 1042 1042 1 1078 ) +insert ( 10006 426 1042 1042 2 3328 ) +insert ( 10007 426 1042 1042 4 5050 ) +insert ( 10008 428 17 17 1 1954 ) +insert ( 10009 428 17 17 2 3331 ) +insert ( 10010 428 17 17 4 5051 ) +insert ( 10011 429 18 18 1 358 ) +insert ( 10012 429 18 18 4 5051 ) +insert ( 10013 434 1082 1082 1 1092 ) +insert ( 10014 434 1082 1082 2 3136 ) +insert ( 10015 434 1082 1082 4 5051 ) +insert ( 10016 434 1082 1114 1 2344 ) +insert ( 10017 434 1082 1184 1 2357 ) +insert ( 10018 434 1114 1114 1 2045 ) +insert ( 10019 434 1114 1114 2 3137 ) +insert ( 10020 434 1114 1114 4 5051 ) +insert ( 10021 434 1114 1082 1 2370 ) +insert ( 10022 434 1114 1184 1 2526 ) +insert ( 10023 434 1184 1184 1 1314 ) +insert ( 10024 434 1184 1184 2 3137 ) +insert ( 10025 434 1184 1184 4 5051 ) +insert ( 10026 434 1184 1082 1 2383 ) +insert ( 10027 434 1184 1114 1 2533 ) +insert ( 10028 434 1082 1186 3 4133 ) +insert ( 10029 434 1114 1186 3 4134 ) +insert ( 10030 434 1184 1186 3 4135 ) +insert ( 10031 1970 700 700 1 354 ) +insert ( 10032 1970 700 700 2 3132 ) +insert ( 10033 1970 700 701 1 2194 ) +insert ( 10034 1970 701 701 1 355 ) +insert ( 10035 1970 701 701 2 3133 ) +insert ( 10036 1970 701 700 1 2195 ) +insert ( 10037 1970 701 701 3 4139 ) +insert ( 10038 1970 700 701 3 4140 ) +insert ( 10039 1974 869 869 1 926 ) +insert ( 10040 1974 869 869 2 5033 ) +insert ( 10041 1974 869 869 4 5051 ) +insert ( 10042 1976 21 21 1 350 ) +insert ( 10043 1976 21 21 2 3129 ) +insert ( 10044 1976 21 21 4 5051 ) +insert ( 10045 1976 21 23 1 2190 ) +insert ( 10046 1976 21 20 1 2192 ) +insert ( 10047 1976 21 20 3 4130 ) +insert ( 10048 1976 21 23 3 4131 ) +insert ( 10049 1976 21 21 3 4132 ) +insert ( 10050 1976 23 23 1 351 ) +insert ( 10051 1976 23 23 2 3130 ) +insert ( 10052 1976 23 23 4 5051 ) +insert ( 10053 1976 23 20 1 2188 ) +insert ( 10054 1976 23 21 1 2191 ) +insert ( 10055 1976 23 20 3 4127 ) +insert ( 10056 1976 23 23 3 4128 ) +insert ( 10057 1976 23 21 3 4129 ) +insert ( 10058 1976 20 20 1 842 ) +insert ( 10059 1976 20 20 2 3131 ) +insert ( 10060 1976 20 20 4 5051 ) +insert ( 10061 1976 20 23 1 2189 ) +insert ( 10062 1976 20 21 1 2193 ) +insert ( 10063 1976 20 20 3 4126 ) +insert ( 10064 1982 1186 1186 1 1315 ) +insert ( 10065 1982 1186 1186 3 4136 ) +insert ( 10066 1984 829 829 1 836 ) +insert ( 10067 1984 829 829 2 3359 ) +insert ( 10068 1984 829 829 4 5051 ) +insert ( 10069 1988 1700 1700 1 1769 ) +insert ( 10070 1988 1700 1700 2 3283 ) +insert ( 10071 1988 1700 1700 3 4141 ) +insert ( 10072 1989 26 26 1 356 ) +insert ( 10073 1989 26 26 2 3134 ) +insert ( 10074 1989 26 26 4 5051 ) +insert ( 10075 1991 30 30 1 404 ) +insert ( 10076 1991 30 30 4 5051 ) +insert ( 10077 1994 25 25 1 360 ) +insert ( 10078 1994 25 25 2 3255 ) +insert ( 10079 1994 25 25 4 5050 ) +insert ( 10080 1994 19 19 1 359 ) +insert ( 10081 1994 19 19 2 3135 ) +insert ( 10082 1994 19 19 4 5050 ) +insert ( 10083 1994 19 25 1 246 ) +insert ( 10084 1994 25 19 1 253 ) +insert ( 10085 1996 1083 1083 1 1107 ) +insert ( 10086 1996 1083 1083 4 5051 ) +insert ( 10087 1996 1083 1186 3 4137 ) +insert ( 10088 2000 1266 1266 1 1358 ) +insert ( 10089 2000 1266 1266 4 5051 ) +insert ( 10090 2000 1266 1186 3 4138 ) +insert ( 10091 2002 1562 1562 1 1672 ) +insert ( 10092 2002 1562 1562 4 5051 ) +insert ( 10093 2095 25 25 1 2166 ) +insert ( 10094 2095 25 25 2 3332 ) +insert ( 10095 2095 25 25 4 5051 ) +insert ( 10096 2097 1042 1042 1 2180 ) +insert ( 10097 2097 1042 1042 2 3333 ) +insert ( 10098 2097 1042 1042 4 5051 ) +insert ( 10099 2099 790 790 1 377 ) +insert ( 10100 2099 790 790 4 5051 ) +insert ( 10101 2789 27 27 1 2794 ) +insert ( 10102 2789 27 27 4 5051 ) +insert ( 10103 2968 2950 2950 1 2960 ) +insert ( 10104 2968 2950 2950 2 3300 ) +insert ( 10105 2968 2950 2950 4 5051 ) +insert ( 10106 2994 2249 2249 1 2987 ) +insert ( 10107 3194 2249 2249 1 3187 ) +insert ( 10108 3253 3220 3220 1 3251 ) +insert ( 10109 3253 3220 3220 4 5051 ) +insert ( 10110 3371 774 774 1 4119 ) +insert ( 10111 3371 774 774 4 5051 ) +insert ( 10112 3522 3500 3500 1 3514 ) +insert ( 10113 3522 3500 3500 4 5051 ) +insert ( 10114 3626 3614 3614 1 3622 ) +insert ( 10115 3683 3615 3615 1 3668 ) +insert ( 10116 3901 3831 3831 1 3870 ) +insert ( 10117 4199 4537 4537 1 4273 ) +insert ( 10118 4033 3802 3802 1 4044 ) +insert ( 10119 5067 5069 5069 1 5096 ) +insert ( 10120 5067 5069 5069 4 5051 ) +insert ( 10121 427 1042 1042 1 1080 ) +insert ( 10122 427 1042 1042 2 972 ) +insert ( 10123 431 18 18 1 454 ) +insert ( 10124 431 18 18 2 446 ) +insert ( 10125 435 1082 1082 1 450 ) +insert ( 10126 435 1082 1082 2 425 ) +insert ( 10127 627 2277 2277 1 626 ) +insert ( 10128 627 2277 2277 2 782 ) +insert ( 10129 1971 700 700 1 451 ) +insert ( 10130 1971 700 700 2 443 ) +insert ( 10131 1971 701 701 1 452 ) +insert ( 10132 1971 701 701 2 444 ) +insert ( 10133 1975 869 869 1 422 ) +insert ( 10134 1975 869 869 2 779 ) +insert ( 10135 1977 21 21 1 449 ) +insert ( 10136 1977 21 21 2 441 ) +insert ( 10137 1977 23 23 1 450 ) +insert ( 10138 1977 23 23 2 425 ) +insert ( 10139 1977 20 20 1 949 ) +insert ( 10140 1977 20 20 2 442 ) +insert ( 10141 1983 1186 1186 1 1697 ) +insert ( 10142 1983 1186 1186 2 3418 ) +insert ( 10143 1985 829 829 1 399 ) +insert ( 10144 1985 829 829 2 778 ) +insert ( 10145 1990 26 26 1 453 ) +insert ( 10146 1990 26 26 2 445 ) +insert ( 10147 1992 30 30 1 457 ) +insert ( 10148 1992 30 30 2 776 ) +insert ( 10149 1995 25 25 1 400 ) +insert ( 10150 1995 25 25 2 448 ) +insert ( 10151 1995 19 19 1 455 ) +insert ( 10152 1995 19 19 2 447 ) +insert ( 10153 1997 1083 1083 1 1688 ) +insert ( 10154 1997 1083 1083 2 3409 ) +insert ( 10155 1998 1700 1700 1 432 ) +insert ( 10156 1998 1700 1700 2 780 ) +insert ( 10157 1999 1184 1184 1 2039 ) +insert ( 10158 1999 1184 1184 2 3411 ) +insert ( 10159 2001 1266 1266 1 1696 ) +insert ( 10160 2001 1266 1266 2 3410 ) +insert ( 10161 2040 1114 1114 1 2039 ) +insert ( 10162 2040 1114 1114 2 3411 ) +insert ( 10163 2222 16 16 1 454 ) +insert ( 10164 2222 16 16 2 446 ) +insert ( 10165 2223 17 17 1 456 ) +insert ( 10166 2223 17 17 2 772 ) +insert ( 10167 2225 28 28 1 450 ) +insert ( 10168 2225 28 28 2 425 ) +insert ( 10169 5032 5069 5069 1 949 ) +insert ( 10170 5032 5069 5069 2 442 ) +insert ( 10171 2226 29 29 1 450 ) +insert ( 10172 2226 29 29 2 425 ) +insert ( 10173 2227 27 27 1 2233 ) +insert ( 10174 2227 27 27 2 2234 ) +insert ( 10175 2229 25 25 1 400 ) +insert ( 10176 2229 25 25 2 448 ) +insert ( 10177 2231 1042 1042 1 1080 ) +insert ( 10178 2231 1042 1042 2 972 ) +insert ( 10179 2235 1033 1033 1 329 ) +insert ( 10180 2235 1033 1033 2 777 ) +insert ( 10181 2969 2950 2950 1 2963 ) +insert ( 10182 2969 2950 2950 2 3412 ) +insert ( 10183 6194 2249 2249 1 6192 ) +insert ( 10184 6194 2249 2249 2 6193 ) +insert ( 10185 3254 3220 3220 1 3252 ) +insert ( 10186 3254 3220 3220 2 3413 ) +insert ( 10187 3372 774 774 1 328 ) +insert ( 10188 3372 774 774 2 781 ) +insert ( 10189 3523 3500 3500 1 3515 ) +insert ( 10190 3523 3500 3500 2 3414 ) +insert ( 10191 3903 3831 3831 1 3902 ) +insert ( 10192 3903 3831 3831 2 3417 ) +insert ( 10193 4225 4537 4537 1 4278 ) +insert ( 10194 4225 4537 4537 2 4279 ) +insert ( 10195 4034 3802 3802 1 4045 ) +insert ( 10196 4034 3802 3802 2 3416 ) +insert ( 10197 1029 600 600 1 2179 ) +insert ( 10198 1029 600 600 2 2583 ) +insert ( 10199 1029 600 600 3 1030 ) +insert ( 10200 1029 600 600 5 2581 ) +insert ( 10201 1029 600 600 6 2582 ) +insert ( 10202 1029 600 600 7 2584 ) +insert ( 10203 1029 600 600 8 3064 ) +insert ( 10204 1029 600 600 9 3282 ) +insert ( 10205 1029 600 600 11 3435 ) +insert ( 10206 2593 603 603 1 2578 ) +insert ( 10207 2593 603 603 2 2583 ) +insert ( 10208 2593 603 603 5 2581 ) +insert ( 10209 2593 603 603 6 2582 ) +insert ( 10210 2593 603 603 7 2584 ) +insert ( 10211 2593 603 603 8 3998 ) +insert ( 10212 2594 604 604 1 2585 ) +insert ( 10213 2594 604 604 2 2583 ) +insert ( 10214 2594 604 604 3 2586 ) +insert ( 10215 2594 604 604 5 2581 ) +insert ( 10216 2594 604 604 6 2582 ) +insert ( 10217 2594 604 604 7 2584 ) +insert ( 10218 2594 604 604 8 3288 ) +insert ( 10219 2595 718 718 1 2591 ) +insert ( 10220 2595 718 718 2 2583 ) +insert ( 10221 2595 718 718 3 2592 ) +insert ( 10222 2595 718 718 5 2581 ) +insert ( 10223 2595 718 718 6 2582 ) +insert ( 10224 2595 718 718 7 2584 ) +insert ( 10225 2595 718 718 8 3280 ) +insert ( 10226 3655 3614 3614 1 3654 ) +insert ( 10227 3655 3614 3614 2 3651 ) +insert ( 10228 3655 3614 3614 3 3648 ) +insert ( 10229 3655 3614 3614 4 3649 ) +insert ( 10230 3655 3614 3614 5 3653 ) +insert ( 10231 3655 3614 3614 6 3650 ) +insert ( 10232 3655 3614 3614 7 3652 ) +insert ( 10233 3655 3614 3614 10 3434 ) +insert ( 10234 3702 3615 3615 1 3701 ) +insert ( 10235 3702 3615 3615 2 3698 ) +insert ( 10236 3702 3615 3615 3 3695 ) +insert ( 10237 3702 3615 3615 5 3700 ) +insert ( 10238 3702 3615 3615 6 3697 ) +insert ( 10239 3702 3615 3615 7 3699 ) +insert ( 10240 3919 3831 3831 1 3875 ) +insert ( 10241 3919 3831 3831 2 3876 ) +insert ( 10242 3919 3831 3831 5 3879 ) +insert ( 10243 3919 3831 3831 6 3880 ) +insert ( 10244 3919 3831 3831 7 3881 ) +insert ( 10245 3550 869 869 1 3553 ) +insert ( 10246 3550 869 869 2 3554 ) +insert ( 10247 3550 869 869 3 3555 ) +insert ( 10248 3550 869 869 5 3557 ) +insert ( 10249 3550 869 869 6 3558 ) +insert ( 10250 3550 869 869 7 3559 ) +insert ( 10251 3550 869 869 9 3573 ) +insert ( 10252 6158 4537 4537 1 6154 ) +insert ( 10253 6158 4537 4537 2 3876 ) +insert ( 10254 6158 4537 4537 3 6156 ) +insert ( 10255 6158 4537 4537 5 3879 ) +insert ( 10256 6158 4537 4537 6 3880 ) +insert ( 10257 6158 4537 4537 7 3881 ) +insert ( 10258 2745 2277 2277 2 2743 ) +insert ( 10259 2745 2277 2277 3 2774 ) +insert ( 10260 2745 2277 2277 4 2744 ) +insert ( 10261 2745 2277 2277 6 3920 ) +insert ( 10262 3659 3614 3614 1 3724 ) +insert ( 10263 3659 3614 3614 2 3656 ) +insert ( 10264 3659 3614 3614 3 3657 ) +insert ( 10265 3659 3614 3614 4 3658 ) +insert ( 10266 3659 3614 3614 5 2700 ) +insert ( 10267 3659 3614 3614 6 3921 ) +insert ( 10268 4036 3802 3802 1 3480 ) +insert ( 10269 4036 3802 3802 2 3482 ) +insert ( 10270 4036 3802 3802 3 3483 ) +insert ( 10271 4036 3802 3802 4 3484 ) +insert ( 10272 4036 3802 3802 6 3488 ) +insert ( 10273 4037 3802 3802 1 351 ) +insert ( 10274 4037 3802 3802 2 3485 ) +insert ( 10275 4037 3802 3802 3 3486 ) +insert ( 10276 4037 3802 3802 4 3487 ) +insert ( 10277 4037 3802 3802 6 3489 ) +insert ( 10278 3474 3831 3831 1 3469 ) +insert ( 10279 3474 3831 3831 2 3470 ) +insert ( 10280 3474 3831 3831 3 3471 ) +insert ( 10281 3474 3831 3831 4 3472 ) +insert ( 10282 3474 3831 3831 5 3473 ) +insert ( 10283 3794 869 869 1 3795 ) +insert ( 10284 3794 869 869 2 3796 ) +insert ( 10285 3794 869 869 3 3797 ) +insert ( 10286 3794 869 869 4 3798 ) +insert ( 10287 3794 869 869 5 3799 ) +insert ( 10288 4015 600 600 1 4018 ) +insert ( 10289 4015 600 600 2 4019 ) +insert ( 10290 4015 600 600 3 4020 ) +insert ( 10291 4015 600 600 4 4021 ) +insert ( 10292 4015 600 600 5 4022 ) +insert ( 10293 4016 600 600 1 4023 ) +insert ( 10294 4016 600 600 2 4024 ) +insert ( 10295 4016 600 600 3 4025 ) +insert ( 10296 4016 600 600 4 4026 ) +insert ( 10297 4016 600 600 5 4022 ) +insert ( 10298 4017 25 25 1 4027 ) +insert ( 10299 4017 25 25 2 4028 ) +insert ( 10300 4017 25 25 3 4029 ) +insert ( 10301 4017 25 25 4 4030 ) +insert ( 10302 4017 25 25 5 4031 ) +insert ( 10303 5000 603 603 1 5012 ) +insert ( 10304 5000 603 603 2 5013 ) +insert ( 10305 5000 603 603 3 5014 ) +insert ( 10306 5000 603 603 4 5015 ) +insert ( 10307 5000 603 603 5 5016 ) +insert ( 10308 5008 604 604 1 5010 ) +insert ( 10309 5008 604 604 2 5013 ) +insert ( 10310 5008 604 604 3 5014 ) +insert ( 10311 5008 604 604 4 5015 ) +insert ( 10312 5008 604 604 5 5016 ) +insert ( 10313 5008 604 604 6 5011 ) +insert ( 10314 4064 17 17 1 3383 ) +insert ( 10315 4064 17 17 2 3384 ) +insert ( 10316 4064 17 17 3 3385 ) +insert ( 10317 4064 17 17 4 3386 ) +insert ( 10318 4578 17 17 1 4591 ) +insert ( 10319 4578 17 17 2 4592 ) +insert ( 10320 4578 17 17 3 4593 ) +insert ( 10321 4578 17 17 4 4594 ) +insert ( 10322 4578 17 17 5 4595 ) +insert ( 10323 4578 17 17 11 456 ) +insert ( 10324 4062 18 18 1 3383 ) +insert ( 10325 4062 18 18 2 3384 ) +insert ( 10326 4062 18 18 3 3385 ) +insert ( 10327 4062 18 18 4 3386 ) +insert ( 10328 4577 18 18 1 4591 ) +insert ( 10329 4577 18 18 2 4592 ) +insert ( 10330 4577 18 18 3 4593 ) +insert ( 10331 4577 18 18 4 4594 ) +insert ( 10332 4577 18 18 5 4595 ) +insert ( 10333 4577 18 18 11 454 ) +insert ( 10334 4065 19 19 1 3383 ) +insert ( 10335 4065 19 19 2 3384 ) +insert ( 10336 4065 19 19 3 3385 ) +insert ( 10337 4065 19 19 4 3386 ) +insert ( 10338 4579 19 19 1 4591 ) +insert ( 10339 4579 19 19 2 4592 ) +insert ( 10340 4579 19 19 3 4593 ) +insert ( 10341 4579 19 19 4 4594 ) +insert ( 10342 4579 19 19 5 4595 ) +insert ( 10343 4579 19 19 11 455 ) +insert ( 10344 4054 20 20 1 3383 ) +insert ( 10345 4054 20 20 2 3384 ) +insert ( 10346 4054 20 20 3 3385 ) +insert ( 10347 4054 20 20 4 3386 ) +insert ( 10348 4054 21 21 1 3383 ) +insert ( 10349 4054 21 21 2 3384 ) +insert ( 10350 4054 21 21 3 3385 ) +insert ( 10351 4054 21 21 4 3386 ) +insert ( 10352 4054 23 23 1 3383 ) +insert ( 10353 4054 23 23 2 3384 ) +insert ( 10354 4054 23 23 3 3385 ) +insert ( 10355 4054 23 23 4 3386 ) +insert ( 10356 4602 21 21 1 4616 ) +insert ( 10357 4602 21 21 2 4617 ) +insert ( 10358 4602 21 21 3 4618 ) +insert ( 10359 4602 21 21 4 4619 ) +insert ( 10360 4602 21 21 5 4620 ) +insert ( 10361 4602 21 21 11 4621 ) +insert ( 10362 4602 23 23 1 4616 ) +insert ( 10363 4602 23 23 2 4617 ) +insert ( 10364 4602 23 23 3 4618 ) +insert ( 10365 4602 23 23 4 4619 ) +insert ( 10366 4602 23 23 5 4620 ) +insert ( 10367 4602 23 23 11 4622 ) +insert ( 10368 4602 20 20 1 4616 ) +insert ( 10369 4602 20 20 2 4617 ) +insert ( 10370 4602 20 20 3 4618 ) +insert ( 10371 4602 20 20 4 4619 ) +insert ( 10372 4602 20 20 5 4620 ) +insert ( 10373 4602 20 20 11 4623 ) +insert ( 10374 4572 20 20 1 4591 ) +insert ( 10375 4572 20 20 2 4592 ) +insert ( 10376 4572 20 20 3 4593 ) +insert ( 10377 4572 20 20 4 4594 ) +insert ( 10378 4572 20 20 5 4595 ) +insert ( 10379 4572 20 20 11 949 ) +insert ( 10380 4572 21 21 1 4591 ) +insert ( 10381 4572 21 21 2 4592 ) +insert ( 10382 4572 21 21 3 4593 ) +insert ( 10383 4572 21 21 4 4594 ) +insert ( 10384 4572 21 21 5 4595 ) +insert ( 10385 4572 21 21 11 449 ) +insert ( 10386 4572 23 23 1 4591 ) +insert ( 10387 4572 23 23 2 4592 ) +insert ( 10388 4572 23 23 3 4593 ) +insert ( 10389 4572 23 23 4 4594 ) +insert ( 10390 4572 23 23 5 4595 ) +insert ( 10391 4572 23 23 11 450 ) +insert ( 10392 4056 25 25 1 3383 ) +insert ( 10393 4056 25 25 2 3384 ) +insert ( 10394 4056 25 25 3 3385 ) +insert ( 10395 4056 25 25 4 3386 ) +insert ( 10396 4573 25 25 1 4591 ) +insert ( 10397 4573 25 25 2 4592 ) +insert ( 10398 4573 25 25 3 4593 ) +insert ( 10399 4573 25 25 4 4594 ) +insert ( 10400 4573 25 25 5 4595 ) +insert ( 10401 4573 25 25 11 400 ) +insert ( 10402 4068 26 26 1 3383 ) +insert ( 10403 4068 26 26 2 3384 ) +insert ( 10404 4068 26 26 3 3385 ) +insert ( 10405 4068 26 26 4 3386 ) +insert ( 10406 4606 26 26 1 4616 ) +insert ( 10407 4606 26 26 2 4617 ) +insert ( 10408 4606 26 26 3 4618 ) +insert ( 10409 4606 26 26 4 4619 ) +insert ( 10410 4606 26 26 5 4620 ) +insert ( 10411 4606 26 26 11 4622 ) +insert ( 10412 4580 26 26 1 4591 ) +insert ( 10413 4580 26 26 2 4592 ) +insert ( 10414 4580 26 26 3 4593 ) +insert ( 10415 4580 26 26 4 4594 ) +insert ( 10416 4580 26 26 5 4595 ) +insert ( 10417 4580 26 26 11 453 ) +insert ( 10418 4069 27 27 1 3383 ) +insert ( 10419 4069 27 27 2 3384 ) +insert ( 10420 4069 27 27 3 3385 ) +insert ( 10421 4069 27 27 4 3386 ) +insert ( 10422 4581 27 27 1 4591 ) +insert ( 10423 4581 27 27 2 4592 ) +insert ( 10424 4581 27 27 3 4593 ) +insert ( 10425 4581 27 27 4 4594 ) +insert ( 10426 4581 27 27 5 4595 ) +insert ( 10427 4581 27 27 11 2233 ) +insert ( 10428 4607 27 27 1 4616 ) +insert ( 10429 4607 27 27 2 4617 ) +insert ( 10430 4607 27 27 3 4618 ) +insert ( 10431 4607 27 27 4 4619 ) +insert ( 10432 4607 27 27 5 4620 ) +insert ( 10433 4607 27 27 11 4627 ) +insert ( 10434 4070 700 700 1 3383 ) +insert ( 10435 4070 700 700 2 3384 ) +insert ( 10436 4070 700 700 3 3385 ) +insert ( 10437 4070 700 700 4 3386 ) +insert ( 10438 4070 701 701 1 3383 ) +insert ( 10439 4070 701 701 2 3384 ) +insert ( 10440 4070 701 701 3 3385 ) +insert ( 10441 4070 701 701 4 3386 ) +insert ( 10442 4608 700 700 1 4616 ) +insert ( 10443 4608 700 700 2 4617 ) +insert ( 10444 4608 700 700 3 4618 ) +insert ( 10445 4608 700 700 4 4619 ) +insert ( 10446 4608 700 700 5 4620 ) +insert ( 10447 4608 700 700 11 4624 ) +insert ( 10448 4608 701 701 1 4616 ) +insert ( 10449 4608 701 701 2 4617 ) +insert ( 10450 4608 701 701 3 4618 ) +insert ( 10451 4608 701 701 4 4619 ) +insert ( 10452 4608 701 701 5 4620 ) +insert ( 10453 4608 701 701 11 4625 ) +insert ( 10454 4582 700 700 1 4591 ) +insert ( 10455 4582 700 700 2 4592 ) +insert ( 10456 4582 700 700 3 4593 ) +insert ( 10457 4582 700 700 4 4594 ) +insert ( 10458 4582 700 700 5 4595 ) +insert ( 10459 4582 700 700 11 451 ) +insert ( 10460 4582 701 701 1 4591 ) +insert ( 10461 4582 701 701 2 4592 ) +insert ( 10462 4582 701 701 3 4593 ) +insert ( 10463 4582 701 701 4 4594 ) +insert ( 10464 4582 701 701 5 4595 ) +insert ( 10465 4582 701 701 11 452 ) +insert ( 10466 4074 829 829 1 3383 ) +insert ( 10467 4074 829 829 2 3384 ) +insert ( 10468 4074 829 829 3 3385 ) +insert ( 10469 4074 829 829 4 3386 ) +insert ( 10470 4609 829 829 1 4616 ) +insert ( 10471 4609 829 829 2 4617 ) +insert ( 10472 4609 829 829 3 4618 ) +insert ( 10473 4609 829 829 4 4619 ) +insert ( 10474 4609 829 829 5 4620 ) +insert ( 10475 4609 829 829 11 4634 ) +insert ( 10476 4583 829 829 1 4591 ) +insert ( 10477 4583 829 829 2 4592 ) +insert ( 10478 4583 829 829 3 4593 ) +insert ( 10479 4583 829 829 4 4594 ) +insert ( 10480 4583 829 829 5 4595 ) +insert ( 10481 4583 829 829 11 399 ) +insert ( 10482 4109 774 774 1 3383 ) +insert ( 10483 4109 774 774 2 3384 ) +insert ( 10484 4109 774 774 3 3385 ) +insert ( 10485 4109 774 774 4 3386 ) +insert ( 10486 4610 774 774 1 4616 ) +insert ( 10487 4610 774 774 2 4617 ) +insert ( 10488 4610 774 774 3 4618 ) +insert ( 10489 4610 774 774 4 4619 ) +insert ( 10490 4610 774 774 5 4620 ) +insert ( 10491 4610 774 774 11 4635 ) +insert ( 10492 4584 774 774 1 4591 ) +insert ( 10493 4584 774 774 2 4592 ) +insert ( 10494 4584 774 774 3 4593 ) +insert ( 10495 4584 774 774 4 4594 ) +insert ( 10496 4584 774 774 5 4595 ) +insert ( 10497 4584 774 774 11 328 ) +insert ( 10498 4075 869 869 1 3383 ) +insert ( 10499 4075 869 869 2 3384 ) +insert ( 10500 4075 869 869 3 3385 ) +insert ( 10501 4075 869 869 4 3386 ) +insert ( 10502 4611 869 869 1 4616 ) +insert ( 10503 4611 869 869 2 4617 ) +insert ( 10504 4611 869 869 3 4618 ) +insert ( 10505 4611 869 869 4 4619 ) +insert ( 10506 4611 869 869 5 4620 ) +insert ( 10507 4611 869 869 11 4636 ) +insert ( 10508 4585 869 869 1 4591 ) +insert ( 10509 4585 869 869 2 4592 ) +insert ( 10510 4585 869 869 3 4593 ) +insert ( 10511 4585 869 869 4 4594 ) +insert ( 10512 4585 869 869 5 4595 ) +insert ( 10513 4585 869 869 11 422 ) +insert ( 10514 4102 869 869 1 4105 ) +insert ( 10515 4102 869 869 2 4106 ) +insert ( 10516 4102 869 869 3 4107 ) +insert ( 10517 4102 869 869 4 4108 ) +insert ( 10518 4102 869 869 11 4063 ) +insert ( 10519 4102 869 869 12 4071 ) +insert ( 10520 4102 869 869 13 930 ) +insert ( 10521 4076 1042 1042 1 3383 ) +insert ( 10522 4076 1042 1042 2 3384 ) +insert ( 10523 4076 1042 1042 3 3385 ) +insert ( 10524 4076 1042 1042 4 3386 ) +insert ( 10525 4586 1042 1042 1 4591 ) +insert ( 10526 4586 1042 1042 2 4592 ) +insert ( 10527 4586 1042 1042 3 4593 ) +insert ( 10528 4586 1042 1042 4 4594 ) +insert ( 10529 4586 1042 1042 5 4595 ) +insert ( 10530 4586 1042 1042 11 1080 ) +insert ( 10531 4077 1083 1083 1 3383 ) +insert ( 10532 4077 1083 1083 2 3384 ) +insert ( 10533 4077 1083 1083 3 3385 ) +insert ( 10534 4077 1083 1083 4 3386 ) +insert ( 10535 4612 1083 1083 1 4616 ) +insert ( 10536 4612 1083 1083 2 4617 ) +insert ( 10537 4612 1083 1083 3 4618 ) +insert ( 10538 4612 1083 1083 4 4619 ) +insert ( 10539 4612 1083 1083 5 4620 ) +insert ( 10540 4612 1083 1083 11 4630 ) +insert ( 10541 4587 1083 1083 1 4591 ) +insert ( 10542 4587 1083 1083 2 4592 ) +insert ( 10543 4587 1083 1083 3 4593 ) +insert ( 10544 4587 1083 1083 4 4594 ) +insert ( 10545 4587 1083 1083 5 4595 ) +insert ( 10546 4587 1083 1083 11 1688 ) +insert ( 10547 4059 1114 1114 1 3383 ) +insert ( 10548 4059 1114 1114 2 3384 ) +insert ( 10549 4059 1114 1114 3 3385 ) +insert ( 10550 4059 1114 1114 4 3386 ) +insert ( 10551 4059 1184 1184 1 3383 ) +insert ( 10552 4059 1184 1184 2 3384 ) +insert ( 10553 4059 1184 1184 3 3385 ) +insert ( 10554 4059 1184 1184 4 3386 ) +insert ( 10555 4059 1082 1082 1 3383 ) +insert ( 10556 4059 1082 1082 2 3384 ) +insert ( 10557 4059 1082 1082 3 3385 ) +insert ( 10558 4059 1082 1082 4 3386 ) +insert ( 10559 4605 1114 1114 1 4616 ) +insert ( 10560 4605 1114 1114 2 4617 ) +insert ( 10561 4605 1114 1114 3 4618 ) +insert ( 10562 4605 1114 1114 4 4619 ) +insert ( 10563 4605 1114 1114 5 4620 ) +insert ( 10564 4605 1114 1114 11 4637 ) +insert ( 10565 4605 1184 1184 1 4616 ) +insert ( 10566 4605 1184 1184 2 4617 ) +insert ( 10567 4605 1184 1184 3 4618 ) +insert ( 10568 4605 1184 1184 4 4619 ) +insert ( 10569 4605 1184 1184 5 4620 ) +insert ( 10570 4605 1184 1184 11 4637 ) +insert ( 10571 4605 1082 1082 1 4616 ) +insert ( 10572 4605 1082 1082 2 4617 ) +insert ( 10573 4605 1082 1082 3 4618 ) +insert ( 10574 4605 1082 1082 4 4619 ) +insert ( 10575 4605 1082 1082 5 4620 ) +insert ( 10576 4605 1082 1082 11 4629 ) +insert ( 10577 4576 1114 1114 1 4591 ) +insert ( 10578 4576 1114 1114 2 4592 ) +insert ( 10579 4576 1114 1114 3 4593 ) +insert ( 10580 4576 1114 1114 4 4594 ) +insert ( 10581 4576 1114 1114 5 4595 ) +insert ( 10582 4576 1114 1114 11 2039 ) +insert ( 10583 4576 1184 1184 1 4591 ) +insert ( 10584 4576 1184 1184 2 4592 ) +insert ( 10585 4576 1184 1184 3 4593 ) +insert ( 10586 4576 1184 1184 4 4594 ) +insert ( 10587 4576 1184 1184 5 4595 ) +insert ( 10588 4576 1184 1184 11 2039 ) +insert ( 10589 4576 1082 1082 1 4591 ) +insert ( 10590 4576 1082 1082 2 4592 ) +insert ( 10591 4576 1082 1082 3 4593 ) +insert ( 10592 4576 1082 1082 4 4594 ) +insert ( 10593 4576 1082 1082 5 4595 ) +insert ( 10594 4576 1082 1082 11 450 ) +insert ( 10595 4078 1186 1186 1 3383 ) +insert ( 10596 4078 1186 1186 2 3384 ) +insert ( 10597 4078 1186 1186 3 3385 ) +insert ( 10598 4078 1186 1186 4 3386 ) +insert ( 10599 4613 1186 1186 1 4616 ) +insert ( 10600 4613 1186 1186 2 4617 ) +insert ( 10601 4613 1186 1186 3 4618 ) +insert ( 10602 4613 1186 1186 4 4619 ) +insert ( 10603 4613 1186 1186 5 4620 ) +insert ( 10604 4613 1186 1186 11 4631 ) +insert ( 10605 4588 1186 1186 1 4591 ) +insert ( 10606 4588 1186 1186 2 4592 ) +insert ( 10607 4588 1186 1186 3 4593 ) +insert ( 10608 4588 1186 1186 4 4594 ) +insert ( 10609 4588 1186 1186 5 4595 ) +insert ( 10610 4588 1186 1186 11 1697 ) +insert ( 10611 4058 1266 1266 1 3383 ) +insert ( 10612 4058 1266 1266 2 3384 ) +insert ( 10613 4058 1266 1266 3 3385 ) +insert ( 10614 4058 1266 1266 4 3386 ) +insert ( 10615 4604 1266 1266 1 4616 ) +insert ( 10616 4604 1266 1266 2 4617 ) +insert ( 10617 4604 1266 1266 3 4618 ) +insert ( 10618 4604 1266 1266 4 4619 ) +insert ( 10619 4604 1266 1266 5 4620 ) +insert ( 10620 4604 1266 1266 11 4632 ) +insert ( 10621 4575 1266 1266 1 4591 ) +insert ( 10622 4575 1266 1266 2 4592 ) +insert ( 10623 4575 1266 1266 3 4593 ) +insert ( 10624 4575 1266 1266 4 4594 ) +insert ( 10625 4575 1266 1266 5 4595 ) +insert ( 10626 4575 1266 1266 11 1696 ) +insert ( 10627 4079 1560 1560 1 3383 ) +insert ( 10628 4079 1560 1560 2 3384 ) +insert ( 10629 4079 1560 1560 3 3385 ) +insert ( 10630 4079 1560 1560 4 3386 ) +insert ( 10631 4080 1562 1562 1 3383 ) +insert ( 10632 4080 1562 1562 2 3384 ) +insert ( 10633 4080 1562 1562 3 3385 ) +insert ( 10634 4080 1562 1562 4 3386 ) +insert ( 10635 4055 1700 1700 1 3383 ) +insert ( 10636 4055 1700 1700 2 3384 ) +insert ( 10637 4055 1700 1700 3 3385 ) +insert ( 10638 4055 1700 1700 4 3386 ) +insert ( 10639 4603 1700 1700 1 4616 ) +insert ( 10640 4603 1700 1700 2 4617 ) +insert ( 10641 4603 1700 1700 3 4618 ) +insert ( 10642 4603 1700 1700 4 4619 ) +insert ( 10643 4603 1700 1700 5 4620 ) +insert ( 10644 4603 1700 1700 11 4626 ) +insert ( 10645 4574 1700 1700 1 4591 ) +insert ( 10646 4574 1700 1700 2 4592 ) +insert ( 10647 4574 1700 1700 3 4593 ) +insert ( 10648 4574 1700 1700 4 4594 ) +insert ( 10649 4574 1700 1700 5 4595 ) +insert ( 10650 4574 1700 1700 11 432 ) +insert ( 10651 4081 2950 2950 1 3383 ) +insert ( 10652 4081 2950 2950 2 3384 ) +insert ( 10653 4081 2950 2950 3 3385 ) +insert ( 10654 4081 2950 2950 4 3386 ) +insert ( 10655 4614 2950 2950 1 4616 ) +insert ( 10656 4614 2950 2950 2 4617 ) +insert ( 10657 4614 2950 2950 3 4618 ) +insert ( 10658 4614 2950 2950 4 4619 ) +insert ( 10659 4614 2950 2950 5 4620 ) +insert ( 10660 4614 2950 2950 11 4628 ) +insert ( 10661 4589 2950 2950 1 4591 ) +insert ( 10662 4589 2950 2950 2 4592 ) +insert ( 10663 4589 2950 2950 3 4593 ) +insert ( 10664 4589 2950 2950 4 4594 ) +insert ( 10665 4589 2950 2950 5 4595 ) +insert ( 10666 4589 2950 2950 11 2963 ) +insert ( 10667 4103 3831 3831 1 4105 ) +insert ( 10668 4103 3831 3831 2 4106 ) +insert ( 10669 4103 3831 3831 3 4107 ) +insert ( 10670 4103 3831 3831 4 4108 ) +insert ( 10671 4103 3831 3831 11 4057 ) +insert ( 10672 4103 3831 3831 13 3859 ) +insert ( 10673 4103 3831 3831 14 3850 ) +insert ( 10674 4082 3220 3220 1 3383 ) +insert ( 10675 4082 3220 3220 2 3384 ) +insert ( 10676 4082 3220 3220 3 3385 ) +insert ( 10677 4082 3220 3220 4 3386 ) +insert ( 10678 4615 3220 3220 1 4616 ) +insert ( 10679 4615 3220 3220 2 4617 ) +insert ( 10680 4615 3220 3220 3 4618 ) +insert ( 10681 4615 3220 3220 4 4619 ) +insert ( 10682 4615 3220 3220 5 4620 ) +insert ( 10683 4615 3220 3220 11 4633 ) +insert ( 10684 4590 3220 3220 1 4591 ) +insert ( 10685 4590 3220 3220 2 4592 ) +insert ( 10686 4590 3220 3220 3 4593 ) +insert ( 10687 4590 3220 3220 4 4594 ) +insert ( 10688 4590 3220 3220 5 4595 ) +insert ( 10689 4590 3220 3220 11 3252 ) +insert ( 10690 4104 603 603 1 4105 ) +insert ( 10691 4104 603 603 2 4106 ) +insert ( 10692 4104 603 603 3 4107 ) +insert ( 10693 4104 603 603 4 4108 ) +insert ( 10694 4104 603 603 11 4067 ) +insert ( 10695 4104 603 603 13 187 ) +close pg_amproc +create pg_language 2612 + ( + oid = oid , + lanname = name , + lanowner = oid , + lanispl = bool , + lanpltrusted = bool , + lanplcallfoid = oid , + laninline = oid , + lanvalidator = oid , + lanacl = _aclitem + ) +open pg_language +insert ( 12 internal 10 f f 0 0 2246 _null_ ) +insert ( 13 c 10 f f 0 0 2247 _null_ ) +insert ( 14 sql 10 f t 0 0 2248 _null_ ) +close pg_language +create pg_largeobject_metadata 2995 + ( + oid = oid , + lomowner = oid , + lomacl = _aclitem + ) +open pg_largeobject_metadata +close pg_largeobject_metadata +create pg_largeobject 2613 + ( + loid = oid , + pageno = int4 , + data = bytea FORCE NOT NULL + ) +open pg_largeobject +close pg_largeobject +create pg_aggregate 2600 + ( + aggfnoid = regproc , + aggkind = char , + aggnumdirectargs = int2 , + aggtransfn = regproc , + aggfinalfn = regproc , + aggcombinefn = regproc , + aggserialfn = regproc , + aggdeserialfn = regproc , + aggmtransfn = regproc , + aggminvtransfn = regproc , + aggmfinalfn = regproc , + aggfinalextra = bool , + aggmfinalextra = bool , + aggfinalmodify = char , + aggmfinalmodify = char , + aggsortop = oid , + aggtranstype = oid , + aggtransspace = int4 , + aggmtranstype = oid , + aggmtransspace = int4 , + agginitval = text , + aggminitval = text + ) +open pg_aggregate +insert ( 2100 n 0 2746 3389 2785 2786 2787 2746 3387 3389 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2101 n 0 1963 1964 3324 - - 1963 3571 1964 f f r r 0 1016 0 1016 0 '{0,0}' '{0,0}' ) +insert ( 2102 n 0 1962 1964 3324 - - 1962 3570 1964 f f r r 0 1016 0 1016 0 '{0,0}' '{0,0}' ) +insert ( 2103 n 0 2858 1837 3337 2740 2741 2858 3548 1837 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2104 n 0 208 1830 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2105 n 0 222 1830 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2106 n 0 1843 1844 3325 - - 1843 3549 1844 f f r r 0 1187 0 1187 0 '{0 second,0 second}' '{0 second,0 second}' ) +insert ( 2107 n 0 2746 3388 2785 2786 2787 2746 3387 3388 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2108 n 0 1841 - 463 - - 1963 3571 3572 f f r r 0 20 0 1016 0 _null_ '{0,0}' ) +insert ( 2109 n 0 1840 - 463 - - 1962 3570 3572 f f r r 0 20 0 1016 0 _null_ '{0,0}' ) +insert ( 2110 n 0 204 - 204 - - - - - f f r r 0 700 0 0 0 _null_ _null_ ) +insert ( 2111 n 0 218 - 218 - - - - - f f r r 0 701 0 0 0 _null_ _null_ ) +insert ( 2112 n 0 894 - 894 - - 894 895 - f f r r 0 790 0 790 0 _null_ _null_ ) +insert ( 2113 n 0 1169 - 1169 - - 1169 1170 - f f r r 0 1186 0 1186 0 _null_ _null_ ) +insert ( 2114 n 0 2858 3178 3337 2740 2741 2858 3548 3178 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2115 n 0 1236 - 1236 - - - - - f f r r 413 20 0 0 0 _null_ _null_ ) +insert ( 2116 n 0 768 - 768 - - - - - f f r r 521 23 0 0 0 _null_ _null_ ) +insert ( 2117 n 0 770 - 770 - - - - - f f r r 520 21 0 0 0 _null_ _null_ ) +insert ( 2118 n 0 1965 - 1965 - - - - - f f r r 610 26 0 0 0 _null_ _null_ ) +insert ( 2119 n 0 209 - 209 - - - - - f f r r 623 700 0 0 0 _null_ _null_ ) +insert ( 2120 n 0 223 - 223 - - - - - f f r r 674 701 0 0 0 _null_ _null_ ) +insert ( 2122 n 0 1138 - 1138 - - - - - f f r r 1097 1082 0 0 0 _null_ _null_ ) +insert ( 2123 n 0 1377 - 1377 - - - - - f f r r 1112 1083 0 0 0 _null_ _null_ ) +insert ( 2124 n 0 1379 - 1379 - - - - - f f r r 1554 1266 0 0 0 _null_ _null_ ) +insert ( 2125 n 0 898 - 898 - - - - - f f r r 903 790 0 0 0 _null_ _null_ ) +insert ( 2126 n 0 2036 - 2036 - - - - - f f r r 2064 1114 0 0 0 _null_ _null_ ) +insert ( 2127 n 0 1196 - 1196 - - - - - f f r r 1324 1184 0 0 0 _null_ _null_ ) +insert ( 2128 n 0 1198 - 1198 - - - - - f f r r 1334 1186 0 0 0 _null_ _null_ ) +insert ( 2129 n 0 458 - 458 - - - - - f f r r 666 25 0 0 0 _null_ _null_ ) +insert ( 2130 n 0 1767 - 1767 - - - - - f f r r 1756 1700 0 0 0 _null_ _null_ ) +insert ( 2050 n 0 515 - 515 - - - - - f f r r 1073 2277 0 0 0 _null_ _null_ ) +insert ( 2244 n 0 1063 - 1063 - - - - - f f r r 1060 1042 0 0 0 _null_ _null_ ) +insert ( 2797 n 0 2795 - 2795 - - - - - f f r r 2800 27 0 0 0 _null_ _null_ ) +insert ( 3526 n 0 3525 - 3525 - - - - - f f r r 3519 3500 0 0 0 _null_ _null_ ) +insert ( 3564 n 0 3562 - 3562 - - - - - f f r r 1205 869 0 0 0 _null_ _null_ ) +insert ( 4189 n 0 4187 - 4187 - - - - - f f r r 3225 3220 0 0 0 _null_ _null_ ) +insert ( 5099 n 0 5097 - 5097 - - - - - f f r r 5074 5069 0 0 0 _null_ _null_ ) +insert ( 2131 n 0 1237 - 1237 - - - - - f f r r 412 20 0 0 0 _null_ _null_ ) +insert ( 2132 n 0 769 - 769 - - - - - f f r r 97 23 0 0 0 _null_ _null_ ) +insert ( 2133 n 0 771 - 771 - - - - - f f r r 95 21 0 0 0 _null_ _null_ ) +insert ( 2134 n 0 1966 - 1966 - - - - - f f r r 609 26 0 0 0 _null_ _null_ ) +insert ( 2135 n 0 211 - 211 - - - - - f f r r 622 700 0 0 0 _null_ _null_ ) +insert ( 2136 n 0 224 - 224 - - - - - f f r r 672 701 0 0 0 _null_ _null_ ) +insert ( 2138 n 0 1139 - 1139 - - - - - f f r r 1095 1082 0 0 0 _null_ _null_ ) +insert ( 2139 n 0 1378 - 1378 - - - - - f f r r 1110 1083 0 0 0 _null_ _null_ ) +insert ( 2140 n 0 1380 - 1380 - - - - - f f r r 1552 1266 0 0 0 _null_ _null_ ) +insert ( 2141 n 0 899 - 899 - - - - - f f r r 902 790 0 0 0 _null_ _null_ ) +insert ( 2142 n 0 2035 - 2035 - - - - - f f r r 2062 1114 0 0 0 _null_ _null_ ) +insert ( 2143 n 0 1195 - 1195 - - - - - f f r r 1322 1184 0 0 0 _null_ _null_ ) +insert ( 2144 n 0 1197 - 1197 - - - - - f f r r 1332 1186 0 0 0 _null_ _null_ ) +insert ( 2145 n 0 459 - 459 - - - - - f f r r 664 25 0 0 0 _null_ _null_ ) +insert ( 2146 n 0 1766 - 1766 - - - - - f f r r 1754 1700 0 0 0 _null_ _null_ ) +insert ( 2051 n 0 516 - 516 - - - - - f f r r 1072 2277 0 0 0 _null_ _null_ ) +insert ( 2245 n 0 1064 - 1064 - - - - - f f r r 1058 1042 0 0 0 _null_ _null_ ) +insert ( 2798 n 0 2796 - 2796 - - - - - f f r r 2799 27 0 0 0 _null_ _null_ ) +insert ( 3527 n 0 3524 - 3524 - - - - - f f r r 3518 3500 0 0 0 _null_ _null_ ) +insert ( 3565 n 0 3563 - 3563 - - - - - f f r r 1203 869 0 0 0 _null_ _null_ ) +insert ( 4190 n 0 4188 - 4188 - - - - - f f r r 3224 3220 0 0 0 _null_ _null_ ) +insert ( 5100 n 0 5098 - 5098 - - - - - f f r r 5073 5069 0 0 0 _null_ _null_ ) +insert ( 2147 n 0 2804 - 463 - - 2804 3547 - f f r r 0 20 0 20 0 0 0 ) +insert ( 2803 n 0 1219 - 463 - - 1219 3546 - f f r r 0 20 0 20 0 0 0 ) +insert ( 2718 n 0 1836 2514 3341 3335 3336 1836 3569 2514 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2719 n 0 1835 3390 3338 3339 3340 1835 3568 3390 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2720 n 0 1834 3390 3338 3339 3340 1834 3567 3390 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2721 n 0 208 2512 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2722 n 0 222 2512 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2723 n 0 1833 2514 3341 3335 3336 1833 3548 2514 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2641 n 0 1836 1838 3341 3335 3336 1836 3569 1838 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2642 n 0 1835 3391 3338 3339 3340 1835 3568 3391 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2643 n 0 1834 3391 3338 3339 3340 1834 3567 3391 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2644 n 0 208 1831 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2645 n 0 222 1831 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2646 n 0 1833 1838 3341 3335 3336 1833 3548 1838 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2148 n 0 1836 1838 3341 3335 3336 1836 3569 1838 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2149 n 0 1835 3391 3338 3339 3340 1835 3568 3391 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2150 n 0 1834 3391 3338 3339 3340 1834 3567 3391 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2151 n 0 208 1831 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2152 n 0 222 1831 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2153 n 0 1833 1838 3341 3335 3336 1833 3548 1838 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2724 n 0 1836 2596 3341 3335 3336 1836 3569 2596 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2725 n 0 1835 3392 3338 3339 3340 1835 3568 3392 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2726 n 0 1834 3392 3338 3339 3340 1834 3567 3392 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2727 n 0 208 2513 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2728 n 0 222 2513 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2729 n 0 1833 2596 3341 3335 3336 1833 3548 2596 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2712 n 0 1836 1839 3341 3335 3336 1836 3569 1839 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2713 n 0 1835 3393 3338 3339 3340 1835 3568 3393 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2714 n 0 1834 3393 3338 3339 3340 1834 3567 3393 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2715 n 0 208 1832 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2716 n 0 222 1832 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2717 n 0 1833 1839 3341 3335 3336 1833 3548 1839 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2154 n 0 1836 1839 3341 3335 3336 1836 3569 1839 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2155 n 0 1835 3393 3338 3339 3340 1835 3568 3393 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2156 n 0 1834 3393 3338 3339 3340 1834 3567 3393 f f r r 0 2281 48 2281 48 _null_ _null_ ) +insert ( 2157 n 0 208 1832 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2158 n 0 222 1832 276 - - - - - f f r r 0 1022 0 0 0 '{0,0,0}' _null_ ) +insert ( 2159 n 0 1833 1839 3341 3335 3336 1833 3548 1839 f f r r 0 2281 128 2281 128 _null_ _null_ ) +insert ( 2818 n 0 2805 - 463 - - - - - f f r r 0 20 0 0 0 0 _null_ ) +insert ( 2819 n 0 2806 2807 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2820 n 0 2806 2808 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2821 n 0 2806 2809 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2822 n 0 2806 2810 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2823 n 0 2806 2811 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2824 n 0 2806 2812 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2825 n 0 2806 2813 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2826 n 0 2806 2814 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2827 n 0 2806 2815 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2828 n 0 2806 2816 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2829 n 0 2806 2817 3342 - - - - - f f r r 0 1022 0 0 0 '{0,0,0,0,0,0}' _null_ ) +insert ( 2517 n 0 2515 - 2515 - - 3496 3497 3498 f f r r 58 16 0 2281 16 _null_ _null_ ) +insert ( 2518 n 0 2516 - 2516 - - 3496 3497 3499 f f r r 59 16 0 2281 16 _null_ _null_ ) +insert ( 2519 n 0 2515 - 2515 - - 3496 3497 3498 f f r r 58 16 0 2281 16 _null_ _null_ ) +insert ( 2236 n 0 1892 - 1892 - - - - - f f r r 0 21 0 0 0 _null_ _null_ ) +insert ( 2237 n 0 1893 - 1893 - - - - - f f r r 0 21 0 0 0 _null_ _null_ ) +insert ( 6164 n 0 1894 - 1894 - - - - - f f r r 0 21 0 0 0 _null_ _null_ ) +insert ( 2238 n 0 1898 - 1898 - - - - - f f r r 0 23 0 0 0 _null_ _null_ ) +insert ( 2239 n 0 1899 - 1899 - - - - - f f r r 0 23 0 0 0 _null_ _null_ ) +insert ( 6165 n 0 1900 - 1900 - - - - - f f r r 0 23 0 0 0 _null_ _null_ ) +insert ( 2240 n 0 1904 - 1904 - - - - - f f r r 0 20 0 0 0 _null_ _null_ ) +insert ( 2241 n 0 1905 - 1905 - - - - - f f r r 0 20 0 0 0 _null_ _null_ ) +insert ( 6166 n 0 1906 - 1906 - - - - - f f r r 0 20 0 0 0 _null_ _null_ ) +insert ( 2242 n 0 1673 - 1673 - - - - - f f r r 0 1560 0 0 0 _null_ _null_ ) +insert ( 2243 n 0 1674 - 1674 - - - - - f f r r 0 1560 0 0 0 _null_ _null_ ) +insert ( 6167 n 0 1675 - 1675 - - - - - f f r r 0 1560 0 0 0 _null_ _null_ ) +insert ( 2901 n 0 2900 - - - - - - - f f r r 0 142 0 0 0 _null_ _null_ ) +insert ( 2335 n 0 2333 2334 6293 6294 6295 - - - t f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 4053 n 0 4051 4052 6296 6297 6298 - - - t f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 3538 n 0 3535 3536 6299 6300 6301 - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 3545 n 0 3543 3544 6299 6300 6301 - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 4450 n 0 4401 - 4401 - - - - - f f r r 0 3831 0 0 0 _null_ _null_ ) +insert ( 4389 n 0 4388 - 4388 - - - - - f f r r 0 4537 0 0 0 _null_ _null_ ) +insert ( 4301 n 0 4299 4300 - - - - - - t f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6227 n 0 6225 6226 - - - - - - t f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 3175 n 0 3173 3174 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6276 n 0 6275 3174 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 3197 n 0 3180 3196 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6281 n 0 6278 3196 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6280 n 0 6277 3196 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6282 n 0 6279 3196 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 3267 n 0 3265 3266 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6284 n 0 6283 3266 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 3270 n 0 3268 3269 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6289 n 0 6286 3269 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6288 n 0 6285 3269 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 6290 n 0 6287 3269 - - - - - - f f r r 0 2281 0 0 0 _null_ _null_ ) +insert ( 3972 o 1 3970 3973 - - - - - - t f s s 0 2281 0 0 0 _null_ _null_ ) +insert ( 3974 o 1 3970 3975 - - - - - - f f s s 0 2281 0 0 0 _null_ _null_ ) +insert ( 3976 o 1 3970 3977 - - - - - - f f s s 0 2281 0 0 0 _null_ _null_ ) +insert ( 3978 o 1 3970 3979 - - - - - - t f s s 0 2281 0 0 0 _null_ _null_ ) +insert ( 3980 o 1 3970 3981 - - - - - - f f s s 0 2281 0 0 0 _null_ _null_ ) +insert ( 3982 o 1 3970 3983 - - - - - - f f s s 0 2281 0 0 0 _null_ _null_ ) +insert ( 3984 o 0 3970 3985 - - - - - - t f s s 0 2281 0 0 0 _null_ _null_ ) +insert ( 3986 h 1 3971 3987 - - - - - - t f w w 0 2281 0 0 0 _null_ _null_ ) +insert ( 3988 h 1 3971 3989 - - - - - - t f w w 0 2281 0 0 0 _null_ _null_ ) +insert ( 3990 h 1 3971 3991 - - - - - - t f w w 0 2281 0 0 0 _null_ _null_ ) +insert ( 3992 h 1 3971 3993 - - - - - - t f w w 0 2281 0 0 0 _null_ _null_ ) +insert ( 6291 n 0 6292 - 6292 - - - - - f f r r 0 2283 0 0 0 _null_ _null_ ) +close pg_aggregate +create pg_statistic 2619 + ( + starelid = oid , + staattnum = int2 , + stainherit = bool , + stanullfrac = float4 , + stawidth = int4 , + stadistinct = float4 , + stakind1 = int2 , + stakind2 = int2 , + stakind3 = int2 , + stakind4 = int2 , + stakind5 = int2 , + staop1 = oid , + staop2 = oid , + staop3 = oid , + staop4 = oid , + staop5 = oid , + stacoll1 = oid , + stacoll2 = oid , + stacoll3 = oid , + stacoll4 = oid , + stacoll5 = oid , + stanumbers1 = _float4 , + stanumbers2 = _float4 , + stanumbers3 = _float4 , + stanumbers4 = _float4 , + stanumbers5 = _float4 , + stavalues1 = anyarray , + stavalues2 = anyarray , + stavalues3 = anyarray , + stavalues4 = anyarray , + stavalues5 = anyarray + ) +open pg_statistic +close pg_statistic +create pg_statistic_ext 3381 + ( + oid = oid , + stxrelid = oid , + stxname = name , + stxnamespace = oid , + stxowner = oid , + stxstattarget = int4 , + stxkeys = int2vector FORCE NOT NULL , + stxkind = _char FORCE NOT NULL , + stxexprs = pg_node_tree + ) +open pg_statistic_ext +close pg_statistic_ext +create pg_statistic_ext_data 3429 + ( + stxoid = oid , + stxdinherit = bool , + stxdndistinct = pg_ndistinct , + stxddependencies = pg_dependencies , + stxdmcv = pg_mcv_list , + stxdexpr = _pg_statistic + ) +open pg_statistic_ext_data +close pg_statistic_ext_data +create pg_rewrite 2618 + ( + oid = oid , + rulename = name , + ev_class = oid , + ev_type = char , + ev_enabled = char , + is_instead = bool , + ev_qual = pg_node_tree FORCE NOT NULL , + ev_action = pg_node_tree FORCE NOT NULL + ) +open pg_rewrite +close pg_rewrite +create pg_trigger 2620 + ( + oid = oid , + tgrelid = oid , + tgparentid = oid , + tgname = name , + tgfoid = oid , + tgtype = int2 , + tgenabled = char , + tgisinternal = bool , + tgconstrrelid = oid , + tgconstrindid = oid , + tgconstraint = oid , + tgdeferrable = bool , + tginitdeferred = bool , + tgnargs = int2 , + tgattr = int2vector FORCE NOT NULL , + tgargs = bytea FORCE NOT NULL , + tgqual = pg_node_tree , + tgoldtable = name , + tgnewtable = name + ) +open pg_trigger +close pg_trigger +create pg_event_trigger 3466 + ( + oid = oid , + evtname = name , + evtevent = name , + evtowner = oid , + evtfoid = oid , + evtenabled = char , + evttags = _text + ) +open pg_event_trigger +close pg_event_trigger +create pg_description 2609 + ( + objoid = oid , + classoid = oid , + objsubid = int4 , + description = text FORCE NOT NULL + ) +open pg_description +insert ( 1242 1255 0 'I/O' ) +insert ( 1243 1255 0 'I/O' ) +insert ( 1244 1255 0 'I/O' ) +insert ( 31 1255 0 'I/O' ) +insert ( 1245 1255 0 'I/O' ) +insert ( 33 1255 0 'I/O' ) +insert ( 34 1255 0 'I/O' ) +insert ( 35 1255 0 'I/O' ) +insert ( 38 1255 0 'I/O' ) +insert ( 39 1255 0 'I/O' ) +insert ( 40 1255 0 'I/O' ) +insert ( 41 1255 0 'I/O' ) +insert ( 42 1255 0 'I/O' ) +insert ( 43 1255 0 'I/O' ) +insert ( 44 1255 0 'I/O' ) +insert ( 45 1255 0 'I/O' ) +insert ( 3494 1255 0 'convert proname to regproc' ) +insert ( 3479 1255 0 'convert proname to regprocedure' ) +insert ( 46 1255 0 'I/O' ) +insert ( 47 1255 0 'I/O' ) +insert ( 48 1255 0 'I/O' ) +insert ( 49 1255 0 'I/O' ) +insert ( 50 1255 0 'I/O' ) +insert ( 51 1255 0 'I/O' ) +insert ( 5070 1255 0 'I/O' ) +insert ( 5081 1255 0 'I/O' ) +insert ( 5082 1255 0 'I/O' ) +insert ( 5083 1255 0 'I/O' ) +insert ( 52 1255 0 'I/O' ) +insert ( 53 1255 0 'I/O' ) +insert ( 54 1255 0 'I/O' ) +insert ( 55 1255 0 'I/O' ) +insert ( 6242 1255 0 'planner support for text_starts_with' ) +insert ( 5096 1255 0 less-equal-greater ) +insert ( 5071 1255 0 'convert xid8 to xid' ) +insert ( 5097 1255 0 'larger of two' ) +insert ( 5098 1255 0 'smaller of two' ) +insert ( 77 1255 0 'convert char to int4' ) +insert ( 78 1255 0 'convert int4 to char' ) +insert ( 1364 1255 0 'planner support for textregexeq' ) +insert ( 1257 1255 0 length ) +insert ( 89 1255 0 'PostgreSQL version string' ) +insert ( 86 1255 0 'I/O' ) +insert ( 87 1255 0 'I/O' ) +insert ( 88 1255 0 'I/O' ) +insert ( 90 1255 0 'I/O' ) +insert ( 101 1255 0 'restriction selectivity of = and related operators' ) +insert ( 102 1255 0 'restriction selectivity of <> and related operators' ) +insert ( 103 1255 0 'restriction selectivity of < and related operators on scalar datatypes' ) +insert ( 104 1255 0 'restriction selectivity of > and related operators on scalar datatypes' ) +insert ( 105 1255 0 'join selectivity of = and related operators' ) +insert ( 106 1255 0 'join selectivity of <> and related operators' ) +insert ( 107 1255 0 'join selectivity of < and related operators on scalar datatypes' ) +insert ( 108 1255 0 'join selectivity of > and related operators on scalar datatypes' ) +insert ( 336 1255 0 'restriction selectivity of <= and related operators on scalar datatypes' ) +insert ( 337 1255 0 'restriction selectivity of >= and related operators on scalar datatypes' ) +insert ( 386 1255 0 'join selectivity of <= and related operators on scalar datatypes' ) +insert ( 398 1255 0 'join selectivity of >= and related operators on scalar datatypes' ) +insert ( 109 1255 0 'I/O' ) +insert ( 110 1255 0 'I/O' ) +insert ( 117 1255 0 'I/O' ) +insert ( 118 1255 0 'I/O' ) +insert ( 119 1255 0 'I/O' ) +insert ( 120 1255 0 'I/O' ) +insert ( 121 1255 0 'I/O' ) +insert ( 122 1255 0 'I/O' ) +insert ( 123 1255 0 'I/O' ) +insert ( 124 1255 0 'I/O' ) +insert ( 139 1255 0 'restriction selectivity for area-comparison operators' ) +insert ( 140 1255 0 'join selectivity for area-comparison operators' ) +insert ( 195 1255 0 'I/O' ) +insert ( 196 1255 0 'I/O' ) +insert ( 197 1255 0 'I/O' ) +insert ( 198 1255 0 'I/O' ) +insert ( 200 1255 0 'I/O' ) +insert ( 201 1255 0 'I/O' ) +insert ( 208 1255 0 'aggregate transition function' ) +insert ( 209 1255 0 'larger of two' ) +insert ( 211 1255 0 'smaller of two' ) +insert ( 214 1255 0 'I/O' ) +insert ( 215 1255 0 'I/O' ) +insert ( 222 1255 0 'aggregate transition function' ) +insert ( 276 1255 0 'aggregate combine function' ) +insert ( 223 1255 0 'larger of two' ) +insert ( 224 1255 0 'smaller of two' ) +insert ( 228 1255 0 'round to nearest integer' ) +insert ( 229 1255 0 'truncate to integer' ) +insert ( 2308 1255 0 'nearest integer >= value' ) +insert ( 2320 1255 0 'nearest integer >= value' ) +insert ( 2309 1255 0 'nearest integer <= value' ) +insert ( 2310 1255 0 'sign of value' ) +insert ( 233 1255 0 'natural exponential (e^x)' ) +insert ( 234 1255 0 'natural logarithm' ) +insert ( 235 1255 0 'convert int2 to float8' ) +insert ( 236 1255 0 'convert int2 to float4' ) +insert ( 237 1255 0 'convert float8 to int2' ) +insert ( 238 1255 0 'convert float4 to int2' ) +insert ( 246 1255 0 less-equal-greater ) +insert ( 253 1255 0 less-equal-greater ) +insert ( 266 1255 0 'concatenate name and oid' ) +insert ( 274 1255 0 'current date and time - increments during transactions' ) +insert ( 320 1255 0 'bucket number of operand in equal-width histogram' ) +insert ( 311 1255 0 'convert float4 to float8' ) +insert ( 312 1255 0 'convert float8 to float4' ) +insert ( 313 1255 0 'convert int2 to int4' ) +insert ( 314 1255 0 'convert int4 to int2' ) +insert ( 316 1255 0 'convert int4 to float8' ) +insert ( 317 1255 0 'convert float8 to int4' ) +insert ( 318 1255 0 'convert int4 to float4' ) +insert ( 319 1255 0 'convert float4 to int4' ) +insert ( 3 1255 0 'row-oriented heap table access method handler' ) +insert ( 330 1255 0 'btree index access method handler' ) +insert ( 331 1255 0 'hash index access method handler' ) +insert ( 332 1255 0 'gist index access method handler' ) +insert ( 333 1255 0 'gin index access method handler' ) +insert ( 334 1255 0 'spgist index access method handler' ) +insert ( 335 1255 0 'brin index access method handler' ) +insert ( 3952 1255 0 'brin: standalone scan new table pages' ) +insert ( 3999 1255 0 'brin: standalone scan new table pages' ) +insert ( 4014 1255 0 'brin: desummarize page range' ) +insert ( 338 1255 0 'validate an operator class' ) +insert ( 636 1255 0 'test property of an index access method' ) +insert ( 637 1255 0 'test property of an index' ) +insert ( 638 1255 0 'test property of an index column' ) +insert ( 676 1255 0 'return name of given index build phase' ) +insert ( 347 1255 0 'I/O' ) +insert ( 348 1255 0 'I/O' ) +insert ( 350 1255 0 less-equal-greater ) +insert ( 3129 1255 0 'sort support' ) +insert ( 351 1255 0 less-equal-greater ) +insert ( 3130 1255 0 'sort support' ) +insert ( 842 1255 0 less-equal-greater ) +insert ( 3131 1255 0 'sort support' ) +insert ( 354 1255 0 less-equal-greater ) +insert ( 3132 1255 0 'sort support' ) +insert ( 355 1255 0 less-equal-greater ) +insert ( 3133 1255 0 'sort support' ) +insert ( 356 1255 0 less-equal-greater ) +insert ( 3134 1255 0 'sort support' ) +insert ( 404 1255 0 less-equal-greater ) +insert ( 358 1255 0 less-equal-greater ) +insert ( 359 1255 0 less-equal-greater ) +insert ( 3135 1255 0 'sort support' ) +insert ( 360 1255 0 less-equal-greater ) +insert ( 3255 1255 0 'sort support' ) +insert ( 5050 1255 0 'equal image' ) +insert ( 377 1255 0 less-equal-greater ) +insert ( 382 1255 0 less-equal-greater ) +insert ( 4126 1255 0 'window RANGE support' ) +insert ( 4127 1255 0 'window RANGE support' ) +insert ( 4128 1255 0 'window RANGE support' ) +insert ( 4129 1255 0 'window RANGE support' ) +insert ( 4130 1255 0 'window RANGE support' ) +insert ( 4131 1255 0 'window RANGE support' ) +insert ( 4132 1255 0 'window RANGE support' ) +insert ( 4139 1255 0 'window RANGE support' ) +insert ( 4140 1255 0 'window RANGE support' ) +insert ( 4141 1255 0 'window RANGE support' ) +insert ( 401 1255 0 'convert char(n) to text' ) +insert ( 406 1255 0 'convert name to text' ) +insert ( 407 1255 0 'convert text to name' ) +insert ( 408 1255 0 'convert name to char(n)' ) +insert ( 409 1255 0 'convert char(n) to name' ) +insert ( 449 1255 0 hash ) +insert ( 441 1255 0 hash ) +insert ( 450 1255 0 hash ) +insert ( 425 1255 0 hash ) +insert ( 949 1255 0 hash ) +insert ( 442 1255 0 hash ) +insert ( 451 1255 0 hash ) +insert ( 443 1255 0 hash ) +insert ( 452 1255 0 hash ) +insert ( 444 1255 0 hash ) +insert ( 453 1255 0 hash ) +insert ( 445 1255 0 hash ) +insert ( 454 1255 0 hash ) +insert ( 446 1255 0 hash ) +insert ( 455 1255 0 hash ) +insert ( 447 1255 0 hash ) +insert ( 400 1255 0 hash ) +insert ( 448 1255 0 hash ) +insert ( 456 1255 0 hash ) +insert ( 772 1255 0 hash ) +insert ( 457 1255 0 hash ) +insert ( 776 1255 0 hash ) +insert ( 329 1255 0 hash ) +insert ( 777 1255 0 hash ) +insert ( 399 1255 0 hash ) +insert ( 778 1255 0 hash ) +insert ( 422 1255 0 hash ) +insert ( 779 1255 0 hash ) +insert ( 432 1255 0 hash ) +insert ( 780 1255 0 hash ) +insert ( 328 1255 0 hash ) +insert ( 781 1255 0 hash ) +insert ( 438 1255 0 'count the number of NULL arguments' ) +insert ( 440 1255 0 'count the number of non-NULL arguments' ) +insert ( 458 1255 0 'larger of two' ) +insert ( 459 1255 0 'smaller of two' ) +insert ( 460 1255 0 'I/O' ) +insert ( 461 1255 0 'I/O' ) +insert ( 480 1255 0 'convert int8 to int4' ) +insert ( 481 1255 0 'convert int4 to int8' ) +insert ( 482 1255 0 'convert int8 to float8' ) +insert ( 483 1255 0 'convert float8 to int8' ) +insert ( 626 1255 0 hash ) +insert ( 782 1255 0 hash ) +insert ( 652 1255 0 'convert int8 to float4' ) +insert ( 653 1255 0 'convert float4 to int8' ) +insert ( 714 1255 0 'convert int8 to int2' ) +insert ( 754 1255 0 'convert int2 to int8' ) +insert ( 668 1255 0 'adjust char() to typmod length' ) +insert ( 3097 1255 0 'planner support for varchar length coercion' ) +insert ( 669 1255 0 'adjust varchar() to typmod length' ) +insert ( 710 1255 0 'deprecated, use current_user instead' ) +insert ( 720 1255 0 'octet length' ) +insert ( 721 1255 0 'get byte' ) +insert ( 722 1255 0 'set byte' ) +insert ( 723 1255 0 'get bit' ) +insert ( 724 1255 0 'set bit' ) +insert ( 749 1255 0 'substitute portion of string' ) +insert ( 752 1255 0 'substitute portion of string' ) +insert ( 6163 1255 0 'number of set bits' ) +insert ( 745 1255 0 'current user name' ) +insert ( 746 1255 0 'session user name' ) +insert ( 6311 1255 0 'system user name' ) +insert ( 747 1255 0 'array dimensions' ) +insert ( 748 1255 0 'number of array dimensions' ) +insert ( 750 1255 0 'I/O' ) +insert ( 751 1255 0 'I/O' ) +insert ( 2091 1255 0 'array lower dimension' ) +insert ( 2092 1255 0 'array upper dimension' ) +insert ( 2176 1255 0 'array length' ) +insert ( 3179 1255 0 'array cardinality' ) +insert ( 378 1255 0 'append element onto end of array' ) +insert ( 379 1255 0 'prepend element onto front of array' ) +insert ( 394 1255 0 'split delimited text' ) +insert ( 376 1255 0 'split delimited text, with null string' ) +insert ( 6160 1255 0 'split delimited text' ) +insert ( 6161 1255 0 'split delimited text, with null string' ) +insert ( 395 1255 0 'concatenate array elements, using delimiter, into text' ) +insert ( 384 1255 0 'concatenate array elements, using delimiter and null string, into text' ) +insert ( 515 1255 0 'larger of two' ) +insert ( 516 1255 0 'smaller of two' ) +insert ( 3277 1255 0 'returns an offset of value in array' ) +insert ( 3278 1255 0 'returns an offset of value in array with start index' ) +insert ( 3279 1255 0 'returns an array of offsets of some value in array' ) +insert ( 1191 1255 0 'array subscripts generator' ) +insert ( 1192 1255 0 'array subscripts generator' ) +insert ( 1193 1255 0 'array constructor with value' ) +insert ( 1286 1255 0 'array constructor with value' ) +insert ( 2331 1255 0 'expand array to set of rows' ) +insert ( 3996 1255 0 'planner support for array_unnest' ) +insert ( 3167 1255 0 'remove any occurrences of an element from an array' ) +insert ( 3168 1255 0 'replace any occurrences of an element in an array' ) +insert ( 2333 1255 0 'aggregate transition function' ) +insert ( 6293 1255 0 'aggregate combine function' ) +insert ( 6294 1255 0 'aggregate serial function' ) +insert ( 6295 1255 0 'aggregate deserial function' ) +insert ( 2334 1255 0 'aggregate final function' ) +insert ( 2335 1255 0 'concatenate aggregate input into an array' ) +insert ( 4051 1255 0 'aggregate transition function' ) +insert ( 6296 1255 0 'aggregate combine function' ) +insert ( 6297 1255 0 'aggregate serial function' ) +insert ( 6298 1255 0 'aggregate deserial function' ) +insert ( 4052 1255 0 'aggregate final function' ) +insert ( 4053 1255 0 'concatenate aggregate input into an array' ) +insert ( 3218 1255 0 'bucket number of operand given a sorted array of bucket lower bounds' ) +insert ( 6172 1255 0 'remove last N elements of array' ) +insert ( 6215 1255 0 'shuffle array' ) +insert ( 6216 1255 0 'take samples from array' ) +insert ( 3816 1255 0 'array typanalyze' ) +insert ( 3817 1255 0 'restriction selectivity for array-containment operators' ) +insert ( 3818 1255 0 'join selectivity for array-containment operators' ) +insert ( 764 1255 0 'large object import' ) +insert ( 767 1255 0 'large object import' ) +insert ( 765 1255 0 'large object export' ) +insert ( 766 1255 0 increment ) +insert ( 768 1255 0 'larger of two' ) +insert ( 769 1255 0 'smaller of two' ) +insert ( 770 1255 0 'larger of two' ) +insert ( 771 1255 0 'smaller of two' ) +insert ( 849 1255 0 'position of substring' ) +insert ( 1023 1255 0 'planner support for textlike' ) +insert ( 860 1255 0 'convert char to char(n)' ) +insert ( 861 1255 0 'name of the current database' ) +insert ( 817 1255 0 'get the currently executing query' ) +insert ( 886 1255 0 'I/O' ) +insert ( 887 1255 0 'I/O' ) +insert ( 898 1255 0 'larger of two' ) +insert ( 899 1255 0 'smaller of two' ) +insert ( 935 1255 0 'output money amount as words' ) +insert ( 3823 1255 0 'convert money to numeric' ) +insert ( 3824 1255 0 'convert numeric to money' ) +insert ( 3811 1255 0 'convert int4 to money' ) +insert ( 3812 1255 0 'convert int8 to money' ) +insert ( 940 1255 0 modulus ) +insert ( 941 1255 0 modulus ) +insert ( 947 1255 0 modulus ) +insert ( 5044 1255 0 'greatest common divisor' ) +insert ( 5045 1255 0 'greatest common divisor' ) +insert ( 5046 1255 0 'least common multiple' ) +insert ( 5047 1255 0 'least common multiple' ) +insert ( 944 1255 0 'convert text to char' ) +insert ( 946 1255 0 'convert char to text' ) +insert ( 952 1255 0 'large object open' ) +insert ( 953 1255 0 'large object close' ) +insert ( 954 1255 0 'large object read' ) +insert ( 955 1255 0 'large object write' ) +insert ( 956 1255 0 'large object seek' ) +insert ( 3170 1255 0 'large object seek (64 bit)' ) +insert ( 957 1255 0 'large object create' ) +insert ( 715 1255 0 'large object create' ) +insert ( 958 1255 0 'large object position' ) +insert ( 3171 1255 0 'large object position (64 bit)' ) +insert ( 1004 1255 0 'truncate large object' ) +insert ( 3172 1255 0 'truncate large object (64 bit)' ) +insert ( 3457 1255 0 'create new large object with given content' ) +insert ( 3458 1255 0 'read entire large object' ) +insert ( 3459 1255 0 'read large object from offset for length' ) +insert ( 3460 1255 0 'write data at offset' ) +insert ( 964 1255 0 'large object unlink (delete)' ) +insert ( 975 1255 0 'box area' ) +insert ( 976 1255 0 'box width' ) +insert ( 977 1255 0 'box height' ) +insert ( 979 1255 0 'area of a closed path' ) +insert ( 4067 1255 0 'bounding box of two boxes' ) +insert ( 981 1255 0 'box diagonal' ) +insert ( 992 1255 0 'slope between points' ) +insert ( 993 1255 0 'convert points to line segment' ) +insert ( 1026 1255 0 'adjust timestamp to new time zone' ) +insert ( 1031 1255 0 'I/O' ) +insert ( 1032 1255 0 'I/O' ) +insert ( 1035 1255 0 'add/update ACL item' ) +insert ( 1036 1255 0 'remove ACL item' ) +insert ( 1037 1255 0 contains ) +insert ( 1365 1255 0 'make ACL item' ) +insert ( 3943 1255 0 'show hardwired default privileges, primarily for use by the information schema' ) +insert ( 1689 1255 0 'convert ACL item array to table, primarily for use by information schema' ) +insert ( 1044 1255 0 'I/O' ) +insert ( 1045 1255 0 'I/O' ) +insert ( 2913 1255 0 'I/O typmod' ) +insert ( 2914 1255 0 'I/O typmod' ) +insert ( 1046 1255 0 'I/O' ) +insert ( 1047 1255 0 'I/O' ) +insert ( 2915 1255 0 'I/O typmod' ) +insert ( 2916 1255 0 'I/O typmod' ) +insert ( 1063 1255 0 'larger of two' ) +insert ( 1064 1255 0 'smaller of two' ) +insert ( 1078 1255 0 less-equal-greater ) +insert ( 3328 1255 0 'sort support' ) +insert ( 1080 1255 0 hash ) +insert ( 972 1255 0 hash ) +insert ( 1081 1255 0 'format a type oid and atttypmod to canonical SQL' ) +insert ( 1084 1255 0 'I/O' ) +insert ( 1085 1255 0 'I/O' ) +insert ( 1092 1255 0 less-equal-greater ) +insert ( 3136 1255 0 'sort support' ) +insert ( 4133 1255 0 'window RANGE support' ) +insert ( 1107 1255 0 less-equal-greater ) +insert ( 1138 1255 0 'larger of two' ) +insert ( 1139 1255 0 'smaller of two' ) +insert ( 1143 1255 0 'I/O' ) +insert ( 1144 1255 0 'I/O' ) +insert ( 2909 1255 0 'I/O typmod' ) +insert ( 2910 1255 0 'I/O typmod' ) +insert ( 1150 1255 0 'I/O' ) +insert ( 1151 1255 0 'I/O' ) +insert ( 2907 1255 0 'I/O typmod' ) +insert ( 2908 1255 0 'I/O typmod' ) +insert ( 1158 1255 0 'convert UNIX epoch to timestamptz' ) +insert ( 1159 1255 0 'adjust timestamp to new time zone' ) +insert ( 1160 1255 0 'I/O' ) +insert ( 1161 1255 0 'I/O' ) +insert ( 2903 1255 0 'I/O typmod' ) +insert ( 2904 1255 0 'I/O typmod' ) +insert ( 1171 1255 0 'extract field from timestamp with time zone' ) +insert ( 6203 1255 0 'extract field from timestamp with time zone' ) +insert ( 1172 1255 0 'extract field from interval' ) +insert ( 6204 1255 0 'extract field from interval' ) +insert ( 1174 1255 0 'convert date to timestamp with time zone' ) +insert ( 2711 1255 0 'promote groups of 24 hours to numbers of days and promote groups of 30 days to numbers of months' ) +insert ( 1175 1255 0 'promote groups of 24 hours to numbers of days' ) +insert ( 1295 1255 0 'promote groups of 30 days to numbers of months' ) +insert ( 1176 1255 0 'convert date and time to timestamp with time zone' ) +insert ( 1178 1255 0 'convert timestamp with time zone to date' ) +insert ( 1181 1255 0 'age of a transaction ID, in transactions before current transaction' ) +insert ( 3939 1255 0 'age of a multi-transaction ID, in multi-transactions before current multi-transaction' ) +insert ( 6221 1255 0 'add interval to timestamp with time zone' ) +insert ( 6222 1255 0 'add interval to timestamp with time zone in specified time zone' ) +insert ( 6223 1255 0 'subtract interval from timestamp with time zone' ) +insert ( 6273 1255 0 'subtract interval from timestamp with time zone in specified time zone' ) +insert ( 1195 1255 0 'smaller of two' ) +insert ( 1196 1255 0 'larger of two' ) +insert ( 1197 1255 0 'smaller of two' ) +insert ( 1198 1255 0 'larger of two' ) +insert ( 1199 1255 0 'date difference preserving months and years' ) +insert ( 3918 1255 0 'planner support for interval length coercion' ) +insert ( 1200 1255 0 'adjust interval precision' ) +insert ( 1215 1255 0 'get description for object id and catalog name' ) +insert ( 1216 1255 0 'get description for table column' ) +insert ( 1993 1255 0 'get description for object id and shared catalog name' ) +insert ( 1217 1255 0 'truncate timestamp with time zone to specified units' ) +insert ( 1284 1255 0 'truncate timestamp with time zone to specified units in specified time zone' ) +insert ( 1218 1255 0 'truncate interval to specified units' ) +insert ( 1219 1255 0 increment ) +insert ( 3546 1255 0 decrement ) +insert ( 2804 1255 0 'increment, ignores second argument' ) +insert ( 3547 1255 0 'decrement, ignores second argument' ) +insert ( 1236 1255 0 'larger of two' ) +insert ( 1237 1255 0 'smaller of two' ) +insert ( 1024 1255 0 'planner support for texticregexeq' ) +insert ( 1271 1255 0 'intervals overlap?' ) +insert ( 1273 1255 0 'extract field from time with time zone' ) +insert ( 6201 1255 0 'extract field from time with time zone' ) +insert ( 1287 1255 0 'convert int8 to oid' ) +insert ( 1288 1255 0 'convert oid to int8' ) +insert ( 1291 1255 0 'trigger to suppress updates when new and old records match' ) +insert ( 1294 1255 0 'latest tid of a tuple' ) +insert ( 2794 1255 0 less-equal-greater ) +insert ( 2795 1255 0 'larger of two' ) +insert ( 2796 1255 0 'smaller of two' ) +insert ( 2233 1255 0 hash ) +insert ( 2234 1255 0 hash ) +insert ( 1299 1255 0 'current transaction time' ) +insert ( 2647 1255 0 'current transaction time' ) +insert ( 2648 1255 0 'current statement time' ) +insert ( 2649 1255 0 'current clock time' ) +insert ( 1300 1255 0 'restriction selectivity for position-comparison operators' ) +insert ( 1301 1255 0 'join selectivity for position-comparison operators' ) +insert ( 1302 1255 0 'restriction selectivity for containment comparison operators' ) +insert ( 1303 1255 0 'join selectivity for containment comparison operators' ) +insert ( 1304 1255 0 'intervals overlap?' ) +insert ( 1305 1255 0 'intervals overlap?' ) +insert ( 1306 1255 0 'intervals overlap?' ) +insert ( 1307 1255 0 'intervals overlap?' ) +insert ( 1308 1255 0 'intervals overlap?' ) +insert ( 1309 1255 0 'intervals overlap?' ) +insert ( 1310 1255 0 'intervals overlap?' ) +insert ( 1311 1255 0 'intervals overlap?' ) +insert ( 1312 1255 0 'I/O' ) +insert ( 1313 1255 0 'I/O' ) +insert ( 2905 1255 0 'I/O typmod' ) +insert ( 2906 1255 0 'I/O typmod' ) +insert ( 1314 1255 0 less-equal-greater ) +insert ( 1315 1255 0 less-equal-greater ) +insert ( 1316 1255 0 'convert timestamp to time' ) +insert ( 1317 1255 0 length ) +insert ( 1318 1255 0 'character length' ) +insert ( 1339 1255 0 'base 10 logarithm' ) +insert ( 1340 1255 0 'base 10 logarithm' ) +insert ( 1194 1255 0 'base 10 logarithm' ) +insert ( 1341 1255 0 'natural logarithm' ) +insert ( 1342 1255 0 'round to nearest integer' ) +insert ( 1343 1255 0 'truncate to integer' ) +insert ( 1344 1255 0 'square root' ) +insert ( 1345 1255 0 'cube root' ) +insert ( 1346 1255 0 exponentiation ) +insert ( 1368 1255 0 exponentiation ) +insert ( 1347 1255 0 'natural exponential (e^x)' ) +insert ( 1348 1255 0 'deprecated, use two-argument form instead' ) +insert ( 1349 1255 0 'print type names of oidvector field' ) +insert ( 1350 1255 0 'I/O' ) +insert ( 1351 1255 0 'I/O' ) +insert ( 2911 1255 0 'I/O typmod' ) +insert ( 2912 1255 0 'I/O typmod' ) +insert ( 1358 1255 0 less-equal-greater ) +insert ( 1359 1255 0 'convert date and time with time zone to timestamp with time zone' ) +insert ( 1367 1255 0 'character length' ) +insert ( 1369 1255 0 'character length' ) +insert ( 1370 1255 0 'convert time to interval' ) +insert ( 1372 1255 0 'character length' ) +insert ( 1374 1255 0 'octet length' ) +insert ( 1375 1255 0 'octet length' ) +insert ( 1377 1255 0 'larger of two' ) +insert ( 1378 1255 0 'smaller of two' ) +insert ( 1379 1255 0 'larger of two' ) +insert ( 1380 1255 0 'smaller of two' ) +insert ( 1381 1255 0 'character length' ) +insert ( 1384 1255 0 'extract field from date' ) +insert ( 6199 1255 0 'extract field from date' ) +insert ( 1385 1255 0 'extract field from time' ) +insert ( 6200 1255 0 'extract field from time' ) +insert ( 1386 1255 0 'date difference from today preserving months and years' ) +insert ( 1388 1255 0 'convert timestamp with time zone to time with time zone' ) +insert ( 1373 1255 0 'finite date?' ) +insert ( 1389 1255 0 'finite timestamp?' ) +insert ( 1390 1255 0 'finite interval?' ) +insert ( 1376 1255 0 factorial ) +insert ( 1394 1255 0 'absolute value' ) +insert ( 1395 1255 0 'absolute value' ) +insert ( 1396 1255 0 'absolute value' ) +insert ( 1397 1255 0 'absolute value' ) +insert ( 1398 1255 0 'absolute value' ) +insert ( 1400 1255 0 'convert varchar to name' ) +insert ( 1401 1255 0 'convert name to varchar' ) +insert ( 1402 1255 0 'current schema name' ) +insert ( 1403 1255 0 'current schema search list' ) +insert ( 1404 1255 0 'substitute portion of string' ) +insert ( 1405 1255 0 'substitute portion of string' ) +insert ( 1406 1255 0 'vertically aligned' ) +insert ( 1407 1255 0 'horizontally aligned' ) +insert ( 1408 1255 0 parallel ) +insert ( 1409 1255 0 perpendicular ) +insert ( 1410 1255 0 vertical ) +insert ( 1411 1255 0 horizontal ) +insert ( 1412 1255 0 parallel ) +insert ( 1413 1255 0 perpendicular ) +insert ( 1414 1255 0 vertical ) +insert ( 1415 1255 0 horizontal ) +insert ( 1416 1255 0 'center of' ) +insert ( 1419 1255 0 'convert interval to time' ) +insert ( 1421 1255 0 'convert points to box' ) +insert ( 1430 1255 0 'path closed?' ) +insert ( 1431 1255 0 'path open?' ) +insert ( 1433 1255 0 'close path' ) +insert ( 1434 1255 0 'open path' ) +insert ( 1440 1255 0 'convert x, y to point' ) +insert ( 1446 1255 0 'convert polygon to bounding box' ) +insert ( 1447 1255 0 'convert polygon to path' ) +insert ( 1448 1255 0 'convert box to polygon' ) +insert ( 1449 1255 0 'convert path to polygon' ) +insert ( 1450 1255 0 'I/O' ) +insert ( 1451 1255 0 'I/O' ) +insert ( 1468 1255 0 'area of circle' ) +insert ( 1469 1255 0 'diameter of circle' ) +insert ( 1470 1255 0 'radius of circle' ) +insert ( 1473 1255 0 'convert point and radius to circle' ) +insert ( 1474 1255 0 'convert polygon to circle' ) +insert ( 1475 1255 0 'convert vertex count and circle to polygon' ) +insert ( 4091 1255 0 'convert point to empty box' ) +insert ( 1479 1255 0 'convert box to circle' ) +insert ( 1480 1255 0 'convert circle to box' ) +insert ( 1490 1255 0 'I/O' ) +insert ( 1491 1255 0 'I/O' ) +insert ( 1493 1255 0 'construct line from points' ) +insert ( 1530 1255 0 'distance between endpoints' ) +insert ( 1531 1255 0 'sum of path segments' ) +insert ( 1532 1255 0 'center of' ) +insert ( 1534 1255 0 'center of' ) +insert ( 1540 1255 0 'center of' ) +insert ( 1541 1255 0 'diagonal of' ) +insert ( 1542 1255 0 'center of' ) +insert ( 1543 1255 0 'center of' ) +insert ( 1544 1255 0 'convert circle to 12-vertex polygon' ) +insert ( 1545 1255 0 'number of points' ) +insert ( 1556 1255 0 'number of points' ) +insert ( 1564 1255 0 'I/O' ) +insert ( 1565 1255 0 'I/O' ) +insert ( 2919 1255 0 'I/O typmod' ) +insert ( 2920 1255 0 'I/O typmod' ) +insert ( 1569 1255 0 'matches LIKE expression' ) +insert ( 1570 1255 0 'does not match LIKE expression' ) +insert ( 1571 1255 0 'matches LIKE expression' ) +insert ( 1572 1255 0 'does not match LIKE expression' ) +insert ( 1574 1255 0 'sequence next value' ) +insert ( 1575 1255 0 'sequence current value' ) +insert ( 1576 1255 0 'set sequence value' ) +insert ( 1765 1255 0 'set sequence value and is_called status' ) +insert ( 3078 1255 0 'sequence parameters, for use by information schema' ) +insert ( 4032 1255 0 'sequence last value' ) +insert ( 275 1255 0 'return the next oid for a system table' ) +insert ( 6241 1255 0 'stop making pinned objects during initdb' ) +insert ( 1579 1255 0 'I/O' ) +insert ( 1580 1255 0 'I/O' ) +insert ( 2902 1255 0 'I/O typmod' ) +insert ( 2921 1255 0 'I/O typmod' ) +insert ( 1596 1255 0 less-equal-greater ) +insert ( 1598 1255 0 'random value' ) +insert ( 6212 1255 0 'random value from normal distribution' ) +insert ( 1599 1255 0 'set random seed' ) +insert ( 1600 1255 0 arcsine ) +insert ( 1601 1255 0 arccosine ) +insert ( 1602 1255 0 arctangent ) +insert ( 1603 1255 0 'arctangent, two arguments' ) +insert ( 1604 1255 0 sine ) +insert ( 1605 1255 0 cosine ) +insert ( 1606 1255 0 tangent ) +insert ( 1607 1255 0 cotangent ) +insert ( 2731 1255 0 'arcsine, degrees' ) +insert ( 2732 1255 0 'arccosine, degrees' ) +insert ( 2733 1255 0 'arctangent, degrees' ) +insert ( 2734 1255 0 'arctangent, two arguments, degrees' ) +insert ( 2735 1255 0 'sine, degrees' ) +insert ( 2736 1255 0 'cosine, degrees' ) +insert ( 2737 1255 0 'tangent, degrees' ) +insert ( 2738 1255 0 'cotangent, degrees' ) +insert ( 1608 1255 0 'radians to degrees' ) +insert ( 1609 1255 0 'degrees to radians' ) +insert ( 1610 1255 0 PI ) +insert ( 2462 1255 0 'hyperbolic sine' ) +insert ( 2463 1255 0 'hyperbolic cosine' ) +insert ( 2464 1255 0 'hyperbolic tangent' ) +insert ( 2465 1255 0 'inverse hyperbolic sine' ) +insert ( 2466 1255 0 'inverse hyperbolic cosine' ) +insert ( 2467 1255 0 'inverse hyperbolic tangent' ) +insert ( 6219 1255 0 'error function' ) +insert ( 6220 1255 0 'complementary error function' ) +insert ( 1620 1255 0 'convert first char to int4' ) +insert ( 1621 1255 0 'convert int4 to char' ) +insert ( 1622 1255 0 'replicate string n times' ) +insert ( 1623 1255 0 'convert SQL regexp pattern to POSIX style' ) +insert ( 1986 1255 0 'convert SQL regexp pattern to POSIX style' ) +insert ( 1987 1255 0 'convert SQL regexp pattern to POSIX style' ) +insert ( 1025 1255 0 'planner support for texticlike' ) +insert ( 1637 1255 0 'convert LIKE pattern to use backslash escapes' ) +insert ( 868 1255 0 'position of substring' ) +insert ( 870 1255 0 lowercase ) +insert ( 871 1255 0 uppercase ) +insert ( 872 1255 0 'capitalize each word' ) +insert ( 873 1255 0 'left-pad string to length' ) +insert ( 874 1255 0 'right-pad string to length' ) +insert ( 875 1255 0 'trim selected characters from left end of string' ) +insert ( 876 1255 0 'trim selected characters from right end of string' ) +insert ( 877 1255 0 'extract portion of string' ) +insert ( 878 1255 0 'map a set of characters appearing in string' ) +insert ( 879 1255 0 'left-pad string to length' ) +insert ( 880 1255 0 'right-pad string to length' ) +insert ( 881 1255 0 'trim spaces from left end of string' ) +insert ( 882 1255 0 'trim spaces from right end of string' ) +insert ( 883 1255 0 'extract portion of string' ) +insert ( 884 1255 0 'trim selected characters from both ends of string' ) +insert ( 885 1255 0 'trim spaces from both ends of string' ) +insert ( 936 1255 0 'extract portion of string' ) +insert ( 937 1255 0 'extract portion of string' ) +insert ( 2087 1255 0 'replace all occurrences in string of old_substr with new_substr' ) +insert ( 2284 1255 0 'replace text using regexp' ) +insert ( 2285 1255 0 'replace text using regexp' ) +insert ( 6251 1255 0 'replace text using regexp' ) +insert ( 6252 1255 0 'replace text using regexp' ) +insert ( 6253 1255 0 'replace text using regexp' ) +insert ( 3396 1255 0 'find first match for regexp' ) +insert ( 3397 1255 0 'find first match for regexp' ) +insert ( 2763 1255 0 'find match(es) for regexp' ) +insert ( 2764 1255 0 'find match(es) for regexp' ) +insert ( 6254 1255 0 'count regexp matches' ) +insert ( 6255 1255 0 'count regexp matches' ) +insert ( 6256 1255 0 'count regexp matches' ) +insert ( 6257 1255 0 'position of regexp match' ) +insert ( 6258 1255 0 'position of regexp match' ) +insert ( 6259 1255 0 'position of regexp match' ) +insert ( 6260 1255 0 'position of regexp match' ) +insert ( 6261 1255 0 'position of regexp match' ) +insert ( 6262 1255 0 'position of regexp match' ) +insert ( 6263 1255 0 'test for regexp match' ) +insert ( 6264 1255 0 'test for regexp match' ) +insert ( 6265 1255 0 'extract substring that matches regexp' ) +insert ( 6266 1255 0 'extract substring that matches regexp' ) +insert ( 6267 1255 0 'extract substring that matches regexp' ) +insert ( 6268 1255 0 'extract substring that matches regexp' ) +insert ( 6269 1255 0 'extract substring that matches regexp' ) +insert ( 2088 1255 0 'split string by field_sep and return field_num' ) +insert ( 2765 1255 0 'split string by pattern' ) +insert ( 2766 1255 0 'split string by pattern' ) +insert ( 2767 1255 0 'split string by pattern' ) +insert ( 2768 1255 0 'split string by pattern' ) +insert ( 2089 1255 0 'convert int4 number to hex' ) +insert ( 2090 1255 0 'convert int8 number to hex' ) +insert ( 1039 1255 0 'encoding name of current database' ) +insert ( 810 1255 0 'encoding name of current database' ) +insert ( 1713 1255 0 'length of string in specified encoding' ) +insert ( 1714 1255 0 'convert string with specified source encoding name' ) +insert ( 1717 1255 0 'convert string with specified destination encoding name' ) +insert ( 1813 1255 0 'convert string with specified encoding names' ) +insert ( 1264 1255 0 'convert encoding name to encoding id' ) +insert ( 1597 1255 0 'convert encoding id to encoding name' ) +insert ( 2319 1255 0 'maximum octet length of a character in given encoding' ) +insert ( 1573 1255 0 'source text of a rule' ) +insert ( 1640 1255 0 'select statement of a view' ) +insert ( 1641 1255 0 'select statement of a view' ) +insert ( 1642 1255 0 'role name by OID (with fallback)' ) +insert ( 1643 1255 0 'index description' ) +insert ( 3415 1255 0 'extended statistics object description' ) +insert ( 6174 1255 0 'extended statistics columns' ) +insert ( 6173 1255 0 'extended statistics expressions' ) +insert ( 3352 1255 0 'partition key description' ) +insert ( 3408 1255 0 'partition constraint description' ) +insert ( 1662 1255 0 'trigger description' ) +insert ( 1387 1255 0 'constraint description' ) +insert ( 1716 1255 0 'deparse an encoded expression' ) +insert ( 1665 1255 0 'name of sequence for a serial column' ) +insert ( 2098 1255 0 'definition of a function' ) +insert ( 2162 1255 0 'argument list of a function' ) +insert ( 2232 1255 0 'identity argument list of a function' ) +insert ( 2165 1255 0 'result type of a function' ) +insert ( 3808 1255 0 'function argument default' ) +insert ( 6197 1255 0 'function SQL body' ) +insert ( 1686 1255 0 'list of SQL keywords' ) +insert ( 6159 1255 0 'list of catalog foreign key relationships' ) +insert ( 2289 1255 0 'convert generic options array to name/value table' ) +insert ( 1619 1255 0 'type of the argument' ) +insert ( 3162 1255 0 'collation of the argument; implementation of the COLLATION FOR expression' ) +insert ( 3842 1255 0 'is a relation insertable/updatable/deletable' ) +insert ( 3843 1255 0 'is a column updatable' ) +insert ( 6120 1255 0 'oid of replica identity index if any' ) +insert ( 1250 1255 0 'deferred UNIQUE constraint check' ) +insert ( 1644 1255 0 'referential integrity FOREIGN KEY ... REFERENCES' ) +insert ( 1645 1255 0 'referential integrity FOREIGN KEY ... REFERENCES' ) +insert ( 1646 1255 0 'referential integrity ON DELETE CASCADE' ) +insert ( 1647 1255 0 'referential integrity ON UPDATE CASCADE' ) +insert ( 1648 1255 0 'referential integrity ON DELETE RESTRICT' ) +insert ( 1649 1255 0 'referential integrity ON UPDATE RESTRICT' ) +insert ( 1650 1255 0 'referential integrity ON DELETE SET NULL' ) +insert ( 1651 1255 0 'referential integrity ON UPDATE SET NULL' ) +insert ( 1652 1255 0 'referential integrity ON DELETE SET DEFAULT' ) +insert ( 1653 1255 0 'referential integrity ON UPDATE SET DEFAULT' ) +insert ( 1654 1255 0 'referential integrity ON DELETE NO ACTION' ) +insert ( 1655 1255 0 'referential integrity ON UPDATE NO ACTION' ) +insert ( 1672 1255 0 less-equal-greater ) +insert ( 1680 1255 0 'extract portion of bitstring' ) +insert ( 1681 1255 0 'bitstring length' ) +insert ( 1682 1255 0 'octet length' ) +insert ( 1683 1255 0 'convert int4 to bitstring' ) +insert ( 1684 1255 0 'convert bitstring to int4' ) +insert ( 1685 1255 0 'adjust bit() to typmod length' ) +insert ( 3158 1255 0 'planner support for varbit length coercion' ) +insert ( 1687 1255 0 'adjust varbit() to typmod length' ) +insert ( 1698 1255 0 'position of sub-bitstring' ) +insert ( 1699 1255 0 'extract portion of bitstring' ) +insert ( 3030 1255 0 'substitute portion of bitstring' ) +insert ( 3031 1255 0 'substitute portion of bitstring' ) +insert ( 3032 1255 0 'get bit' ) +insert ( 3033 1255 0 'set bit' ) +insert ( 6162 1255 0 'number of set bits' ) +insert ( 436 1255 0 'I/O' ) +insert ( 437 1255 0 'I/O' ) +insert ( 753 1255 0 'MACADDR manufacturer fields' ) +insert ( 836 1255 0 less-equal-greater ) +insert ( 3359 1255 0 'sort support' ) +insert ( 4110 1255 0 'I/O' ) +insert ( 4111 1255 0 'I/O' ) +insert ( 4112 1255 0 'MACADDR8 manufacturer fields' ) +insert ( 4119 1255 0 less-equal-greater ) +insert ( 4123 1255 0 'convert macaddr to macaddr8' ) +insert ( 4124 1255 0 'convert macaddr8 to macaddr' ) +insert ( 4125 1255 0 'set 7th bit in macaddr8' ) +insert ( 910 1255 0 'I/O' ) +insert ( 911 1255 0 'I/O' ) +insert ( 1267 1255 0 'I/O' ) +insert ( 1427 1255 0 'I/O' ) +insert ( 3562 1255 0 'larger of two' ) +insert ( 3563 1255 0 'smaller of two' ) +insert ( 926 1255 0 less-equal-greater ) +insert ( 1173 1255 0 'planner support for network_sub/superset' ) +insert ( 5033 1255 0 'sort support' ) +insert ( 598 1255 0 'abbreviated display of inet value' ) +insert ( 599 1255 0 'abbreviated display of cidr value' ) +insert ( 605 1255 0 'change netmask of inet' ) +insert ( 635 1255 0 'change netmask of cidr' ) +insert ( 711 1255 0 'address family (4 for IPv4, 6 for IPv6)' ) +insert ( 683 1255 0 'network part of address' ) +insert ( 696 1255 0 'netmask of address' ) +insert ( 697 1255 0 'netmask length' ) +insert ( 698 1255 0 'broadcast address of network' ) +insert ( 699 1255 0 'show address octets only' ) +insert ( 730 1255 0 'show all parts of inet/cidr value' ) +insert ( 1362 1255 0 'hostmask of address' ) +insert ( 1715 1255 0 'convert inet to cidr' ) +insert ( 2196 1255 0 'inet address of the client' ) +insert ( 2197 1255 0 'client''s port number for this connection' ) +insert ( 2198 1255 0 'inet address of the server' ) +insert ( 2199 1255 0 'server''s port number for this connection' ) +insert ( 4071 1255 0 'are the addresses from the same family?' ) +insert ( 4063 1255 0 'the smallest network which includes both of the given networks' ) +insert ( 3553 1255 0 'GiST support' ) +insert ( 3554 1255 0 'GiST support' ) +insert ( 3555 1255 0 'GiST support' ) +insert ( 3573 1255 0 'GiST support' ) +insert ( 3557 1255 0 'GiST support' ) +insert ( 3558 1255 0 'GiST support' ) +insert ( 3559 1255 0 'GiST support' ) +insert ( 3795 1255 0 'SP-GiST support' ) +insert ( 3796 1255 0 'SP-GiST support' ) +insert ( 3797 1255 0 'SP-GiST support' ) +insert ( 3798 1255 0 'SP-GiST support' ) +insert ( 3799 1255 0 'SP-GiST support' ) +insert ( 3560 1255 0 'restriction selectivity for network operators' ) +insert ( 3561 1255 0 'join selectivity for network operators' ) +insert ( 1693 1255 0 less-equal-greater ) +insert ( 1688 1255 0 hash ) +insert ( 3409 1255 0 hash ) +insert ( 1696 1255 0 hash ) +insert ( 3410 1255 0 hash ) +insert ( 1697 1255 0 hash ) +insert ( 3418 1255 0 hash ) +insert ( 1701 1255 0 'I/O' ) +insert ( 1702 1255 0 'I/O' ) +insert ( 2917 1255 0 'I/O typmod' ) +insert ( 2918 1255 0 'I/O typmod' ) +insert ( 3157 1255 0 'planner support for numeric length coercion' ) +insert ( 1703 1255 0 'adjust numeric to typmod precision/scale' ) +insert ( 1705 1255 0 'absolute value' ) +insert ( 1706 1255 0 'sign of value' ) +insert ( 1707 1255 0 'value rounded to ''scale''' ) +insert ( 1708 1255 0 'value rounded to ''scale'' of zero' ) +insert ( 1709 1255 0 'value truncated to ''scale''' ) +insert ( 1710 1255 0 'value truncated to ''scale'' of zero' ) +insert ( 1711 1255 0 'nearest integer >= value' ) +insert ( 2167 1255 0 'nearest integer >= value' ) +insert ( 1712 1255 0 'nearest integer <= value' ) +insert ( 1728 1255 0 modulus ) +insert ( 5048 1255 0 'greatest common divisor' ) +insert ( 5049 1255 0 'least common multiple' ) +insert ( 1730 1255 0 'square root' ) +insert ( 1731 1255 0 'square root' ) +insert ( 1732 1255 0 'natural exponential (e^x)' ) +insert ( 1733 1255 0 'natural exponential (e^x)' ) +insert ( 1734 1255 0 'natural logarithm' ) +insert ( 1735 1255 0 'natural logarithm' ) +insert ( 1736 1255 0 'logarithm base m of n' ) +insert ( 1737 1255 0 'logarithm base m of n' ) +insert ( 1738 1255 0 exponentiation ) +insert ( 2169 1255 0 exponentiation ) +insert ( 3281 1255 0 'number of decimal digits in the fractional part' ) +insert ( 5042 1255 0 'minimum scale needed to represent the value' ) +insert ( 5043 1255 0 'numeric with minimum scale needed to represent the value' ) +insert ( 1740 1255 0 'convert int4 to numeric' ) +insert ( 1741 1255 0 'base 10 logarithm' ) +insert ( 1481 1255 0 'base 10 logarithm' ) +insert ( 1742 1255 0 'convert float4 to numeric' ) +insert ( 1743 1255 0 'convert float8 to numeric' ) +insert ( 1744 1255 0 'convert numeric to int4' ) +insert ( 1745 1255 0 'convert numeric to float4' ) +insert ( 1746 1255 0 'convert numeric to float8' ) +insert ( 1973 1255 0 'trunc(x/y)' ) +insert ( 1980 1255 0 'trunc(x/y)' ) +insert ( 2170 1255 0 'bucket number of operand in equal-width histogram' ) +insert ( 1764 1255 0 'increment by one' ) +insert ( 1766 1255 0 'smaller of two' ) +insert ( 1767 1255 0 'larger of two' ) +insert ( 1769 1255 0 less-equal-greater ) +insert ( 3283 1255 0 'sort support' ) +insert ( 1779 1255 0 'convert numeric to int8' ) +insert ( 1781 1255 0 'convert int8 to numeric' ) +insert ( 1782 1255 0 'convert int2 to numeric' ) +insert ( 1783 1255 0 'convert numeric to int2' ) +insert ( 6103 1255 0 'convert numeric to pg_lsn' ) +insert ( 3556 1255 0 'convert jsonb to boolean' ) +insert ( 3449 1255 0 'convert jsonb to numeric' ) +insert ( 3450 1255 0 'convert jsonb to int2' ) +insert ( 3451 1255 0 'convert jsonb to int4' ) +insert ( 3452 1255 0 'convert jsonb to int8' ) +insert ( 3453 1255 0 'convert jsonb to float4' ) +insert ( 2580 1255 0 'convert jsonb to float8' ) +insert ( 1770 1255 0 'format timestamp with time zone to text' ) +insert ( 1772 1255 0 'format numeric to text' ) +insert ( 1773 1255 0 'format int4 to text' ) +insert ( 1774 1255 0 'format int8 to text' ) +insert ( 1775 1255 0 'format float4 to text' ) +insert ( 1776 1255 0 'format float8 to text' ) +insert ( 1777 1255 0 'convert text to numeric' ) +insert ( 1778 1255 0 'convert text to timestamp with time zone' ) +insert ( 1780 1255 0 'convert text to date' ) +insert ( 1768 1255 0 'format interval to text' ) +insert ( 1282 1255 0 'quote an identifier for usage in a querystring' ) +insert ( 1283 1255 0 'quote a literal for usage in a querystring' ) +insert ( 1285 1255 0 'quote a data value for usage in a querystring' ) +insert ( 1289 1255 0 'quote a possibly-null literal for usage in a querystring' ) +insert ( 1290 1255 0 'quote a possibly-null data value for usage in a querystring' ) +insert ( 1798 1255 0 'I/O' ) +insert ( 1799 1255 0 'I/O' ) +insert ( 3058 1255 0 'concatenate values' ) +insert ( 3059 1255 0 'concatenate values with separators' ) +insert ( 3060 1255 0 'extract the first n characters' ) +insert ( 3061 1255 0 'extract the last n characters' ) +insert ( 3062 1255 0 'reverse text' ) +insert ( 3539 1255 0 'format text message' ) +insert ( 3540 1255 0 'format text message' ) +insert ( 1810 1255 0 'length in bits' ) +insert ( 1811 1255 0 'length in bits' ) +insert ( 1812 1255 0 'length in bits' ) +insert ( 1814 1255 0 'restriction selectivity of ILIKE' ) +insert ( 1815 1255 0 'restriction selectivity of NOT ILIKE' ) +insert ( 1816 1255 0 'join selectivity of ILIKE' ) +insert ( 1817 1255 0 'join selectivity of NOT ILIKE' ) +insert ( 1818 1255 0 'restriction selectivity of regex match' ) +insert ( 1819 1255 0 'restriction selectivity of LIKE' ) +insert ( 1820 1255 0 'restriction selectivity of case-insensitive regex match' ) +insert ( 1821 1255 0 'restriction selectivity of regex non-match' ) +insert ( 1822 1255 0 'restriction selectivity of NOT LIKE' ) +insert ( 1823 1255 0 'restriction selectivity of case-insensitive regex non-match' ) +insert ( 1824 1255 0 'join selectivity of regex match' ) +insert ( 1825 1255 0 'join selectivity of LIKE' ) +insert ( 1826 1255 0 'join selectivity of case-insensitive regex match' ) +insert ( 1827 1255 0 'join selectivity of regex non-match' ) +insert ( 1828 1255 0 'join selectivity of NOT LIKE' ) +insert ( 1829 1255 0 'join selectivity of case-insensitive regex non-match' ) +insert ( 3437 1255 0 'restriction selectivity of exact prefix' ) +insert ( 3438 1255 0 'join selectivity of exact prefix' ) +insert ( 1830 1255 0 'aggregate final function' ) +insert ( 2512 1255 0 'aggregate final function' ) +insert ( 1831 1255 0 'aggregate final function' ) +insert ( 2513 1255 0 'aggregate final function' ) +insert ( 1832 1255 0 'aggregate final function' ) +insert ( 1833 1255 0 'aggregate transition function' ) +insert ( 3341 1255 0 'aggregate combine function' ) +insert ( 2858 1255 0 'aggregate transition function' ) +insert ( 3337 1255 0 'aggregate combine function' ) +insert ( 2740 1255 0 'aggregate serial function' ) +insert ( 2741 1255 0 'aggregate deserial function' ) +insert ( 3335 1255 0 'aggregate serial function' ) +insert ( 3336 1255 0 'aggregate deserial function' ) +insert ( 3548 1255 0 'aggregate transition function' ) +insert ( 1834 1255 0 'aggregate transition function' ) +insert ( 1835 1255 0 'aggregate transition function' ) +insert ( 1836 1255 0 'aggregate transition function' ) +insert ( 3338 1255 0 'aggregate combine function' ) +insert ( 3339 1255 0 'aggregate serial function' ) +insert ( 3340 1255 0 'aggregate deserial function' ) +insert ( 2746 1255 0 'aggregate transition function' ) +insert ( 3567 1255 0 'aggregate transition function' ) +insert ( 3568 1255 0 'aggregate transition function' ) +insert ( 3569 1255 0 'aggregate transition function' ) +insert ( 3387 1255 0 'aggregate transition function' ) +insert ( 2785 1255 0 'aggregate combine function' ) +insert ( 2786 1255 0 'aggregate serial function' ) +insert ( 2787 1255 0 'aggregate deserial function' ) +insert ( 3324 1255 0 'aggregate combine function' ) +insert ( 3178 1255 0 'aggregate final function' ) +insert ( 1837 1255 0 'aggregate final function' ) +insert ( 2514 1255 0 'aggregate final function' ) +insert ( 1838 1255 0 'aggregate final function' ) +insert ( 2596 1255 0 'aggregate final function' ) +insert ( 1839 1255 0 'aggregate final function' ) +insert ( 1840 1255 0 'aggregate transition function' ) +insert ( 1841 1255 0 'aggregate transition function' ) +insert ( 1842 1255 0 'aggregate transition function' ) +insert ( 3388 1255 0 'aggregate final function' ) +insert ( 3389 1255 0 'aggregate final function' ) +insert ( 3390 1255 0 'aggregate final function' ) +insert ( 3391 1255 0 'aggregate final function' ) +insert ( 3392 1255 0 'aggregate final function' ) +insert ( 3393 1255 0 'aggregate final function' ) +insert ( 1843 1255 0 'aggregate transition function' ) +insert ( 3325 1255 0 'aggregate combine function' ) +insert ( 3549 1255 0 'aggregate transition function' ) +insert ( 1844 1255 0 'aggregate final function' ) +insert ( 1962 1255 0 'aggregate transition function' ) +insert ( 1963 1255 0 'aggregate transition function' ) +insert ( 3570 1255 0 'aggregate transition function' ) +insert ( 3571 1255 0 'aggregate transition function' ) +insert ( 1964 1255 0 'aggregate final function' ) +insert ( 3572 1255 0 'aggregate final function' ) +insert ( 2805 1255 0 'aggregate transition function' ) +insert ( 2806 1255 0 'aggregate transition function' ) +insert ( 3342 1255 0 'aggregate combine function' ) +insert ( 2807 1255 0 'aggregate final function' ) +insert ( 2808 1255 0 'aggregate final function' ) +insert ( 2809 1255 0 'aggregate final function' ) +insert ( 2810 1255 0 'aggregate final function' ) +insert ( 2811 1255 0 'aggregate final function' ) +insert ( 2812 1255 0 'aggregate final function' ) +insert ( 2813 1255 0 'aggregate final function' ) +insert ( 2814 1255 0 'aggregate final function' ) +insert ( 2815 1255 0 'aggregate final function' ) +insert ( 2816 1255 0 'aggregate final function' ) +insert ( 2817 1255 0 'aggregate final function' ) +insert ( 3535 1255 0 'aggregate transition function' ) +insert ( 6299 1255 0 'aggregate combine function' ) +insert ( 6300 1255 0 'aggregate serial function' ) +insert ( 6301 1255 0 'aggregate deserial function' ) +insert ( 3536 1255 0 'aggregate final function' ) +insert ( 3538 1255 0 'concatenate aggregate input into a string' ) +insert ( 3543 1255 0 'aggregate transition function' ) +insert ( 3544 1255 0 'aggregate final function' ) +insert ( 3545 1255 0 'concatenate aggregate input into a bytea' ) +insert ( 1845 1255 0 'encode text from DB encoding to ASCII text' ) +insert ( 1846 1255 0 'encode text from encoding to ASCII text' ) +insert ( 1847 1255 0 'encode text from encoding to ASCII text' ) +insert ( 1922 1255 0 'user privilege on relation by username, rel name' ) +insert ( 1923 1255 0 'user privilege on relation by username, rel oid' ) +insert ( 1924 1255 0 'user privilege on relation by user oid, rel name' ) +insert ( 1925 1255 0 'user privilege on relation by user oid, rel oid' ) +insert ( 1926 1255 0 'current user privilege on relation by rel name' ) +insert ( 1927 1255 0 'current user privilege on relation by rel oid' ) +insert ( 2181 1255 0 'user privilege on sequence by username, seq name' ) +insert ( 2182 1255 0 'user privilege on sequence by username, seq oid' ) +insert ( 2183 1255 0 'user privilege on sequence by user oid, seq name' ) +insert ( 2184 1255 0 'user privilege on sequence by user oid, seq oid' ) +insert ( 2185 1255 0 'current user privilege on sequence by seq name' ) +insert ( 2186 1255 0 'current user privilege on sequence by seq oid' ) +insert ( 3012 1255 0 'user privilege on column by username, rel name, col name' ) +insert ( 3013 1255 0 'user privilege on column by username, rel name, col attnum' ) +insert ( 3014 1255 0 'user privilege on column by username, rel oid, col name' ) +insert ( 3015 1255 0 'user privilege on column by username, rel oid, col attnum' ) +insert ( 3016 1255 0 'user privilege on column by user oid, rel name, col name' ) +insert ( 3017 1255 0 'user privilege on column by user oid, rel name, col attnum' ) +insert ( 3018 1255 0 'user privilege on column by user oid, rel oid, col name' ) +insert ( 3019 1255 0 'user privilege on column by user oid, rel oid, col attnum' ) +insert ( 3020 1255 0 'current user privilege on column by rel name, col name' ) +insert ( 3021 1255 0 'current user privilege on column by rel name, col attnum' ) +insert ( 3022 1255 0 'current user privilege on column by rel oid, col name' ) +insert ( 3023 1255 0 'current user privilege on column by rel oid, col attnum' ) +insert ( 3024 1255 0 'user privilege on any column by username, rel name' ) +insert ( 3025 1255 0 'user privilege on any column by username, rel oid' ) +insert ( 3026 1255 0 'user privilege on any column by user oid, rel name' ) +insert ( 3027 1255 0 'user privilege on any column by user oid, rel oid' ) +insert ( 3028 1255 0 'current user privilege on any column by rel name' ) +insert ( 3029 1255 0 'current user privilege on any column by rel oid' ) +insert ( 3355 1255 0 'I/O' ) +insert ( 3356 1255 0 'I/O' ) +insert ( 3357 1255 0 'I/O' ) +insert ( 3358 1255 0 'I/O' ) +insert ( 3404 1255 0 'I/O' ) +insert ( 3405 1255 0 'I/O' ) +insert ( 3406 1255 0 'I/O' ) +insert ( 3407 1255 0 'I/O' ) +insert ( 5018 1255 0 'I/O' ) +insert ( 5019 1255 0 'I/O' ) +insert ( 5020 1255 0 'I/O' ) +insert ( 5021 1255 0 'I/O' ) +insert ( 3427 1255 0 'details about MCV list items' ) +insert ( 1928 1255 0 'statistics: number of scans done for table/index' ) +insert ( 6310 1255 0 'statistics: time of the last scan for table/index' ) +insert ( 1929 1255 0 'statistics: number of tuples read by seqscan' ) +insert ( 1930 1255 0 'statistics: number of tuples fetched by idxscan' ) +insert ( 1931 1255 0 'statistics: number of tuples inserted' ) +insert ( 1932 1255 0 'statistics: number of tuples updated' ) +insert ( 1933 1255 0 'statistics: number of tuples deleted' ) +insert ( 1972 1255 0 'statistics: number of tuples hot updated' ) +insert ( 6217 1255 0 'statistics: number of tuples updated onto a new page' ) +insert ( 2878 1255 0 'statistics: number of live tuples' ) +insert ( 2879 1255 0 'statistics: number of dead tuples' ) +insert ( 3177 1255 0 'statistics: number of tuples changed since last analyze' ) +insert ( 5053 1255 0 'statistics: number of tuples inserted since last vacuum' ) +insert ( 1934 1255 0 'statistics: number of blocks fetched' ) +insert ( 1935 1255 0 'statistics: number of blocks found in cache' ) +insert ( 2781 1255 0 'statistics: last manual vacuum time for a table' ) +insert ( 2782 1255 0 'statistics: last auto vacuum time for a table' ) +insert ( 2783 1255 0 'statistics: last manual analyze time for a table' ) +insert ( 2784 1255 0 'statistics: last auto analyze time for a table' ) +insert ( 3054 1255 0 'statistics: number of manual vacuums for a table' ) +insert ( 3055 1255 0 'statistics: number of auto vacuums for a table' ) +insert ( 3056 1255 0 'statistics: number of manual analyzes for a table' ) +insert ( 3057 1255 0 'statistics: number of auto analyzes for a table' ) +insert ( 1936 1255 0 'statistics: currently active backend IDs' ) +insert ( 2022 1255 0 'statistics: information about currently active backends' ) +insert ( 3318 1255 0 'statistics: information about progress of backends running maintenance command' ) +insert ( 3099 1255 0 'statistics: information about currently active replication' ) +insert ( 3317 1255 0 'statistics: information about WAL receiver' ) +insert ( 6169 1255 0 'statistics: information about replication slot' ) +insert ( 6230 1255 0 'statistics: check if a stats object exists' ) +insert ( 6231 1255 0 'statistics: information about subscription stats' ) +insert ( 6118 1255 0 'statistics: information about subscription' ) +insert ( 2026 1255 0 'statistics: current backend PID' ) +insert ( 1937 1255 0 'statistics: PID of backend' ) +insert ( 1938 1255 0 'statistics: database ID of backend' ) +insert ( 6107 1255 0 'statistics: get subtransaction status of backend' ) +insert ( 1939 1255 0 'statistics: user ID of backend' ) +insert ( 1940 1255 0 'statistics: current query of backend' ) +insert ( 2788 1255 0 'statistics: wait event type on which backend is currently waiting' ) +insert ( 2853 1255 0 'statistics: wait event on which backend is currently waiting' ) +insert ( 2094 1255 0 'statistics: start time for current query of backend' ) +insert ( 2857 1255 0 'statistics: start time for backend''s current transaction' ) +insert ( 1391 1255 0 'statistics: start time for current backend session' ) +insert ( 1392 1255 0 'statistics: address of client connected to backend' ) +insert ( 1393 1255 0 'statistics: port number of client connected to backend' ) +insert ( 1941 1255 0 'statistics: number of backends in database' ) +insert ( 1942 1255 0 'statistics: transactions committed' ) +insert ( 1943 1255 0 'statistics: transactions rolled back' ) +insert ( 1944 1255 0 'statistics: blocks fetched for database' ) +insert ( 1945 1255 0 'statistics: blocks found in cache for database' ) +insert ( 2758 1255 0 'statistics: tuples returned for database' ) +insert ( 2759 1255 0 'statistics: tuples fetched for database' ) +insert ( 2760 1255 0 'statistics: tuples inserted in database' ) +insert ( 2761 1255 0 'statistics: tuples updated in database' ) +insert ( 2762 1255 0 'statistics: tuples deleted in database' ) +insert ( 3065 1255 0 'statistics: recovery conflicts in database caused by drop tablespace' ) +insert ( 3066 1255 0 'statistics: recovery conflicts in database caused by relation lock' ) +insert ( 3067 1255 0 'statistics: recovery conflicts in database caused by snapshot expiry' ) +insert ( 6309 1255 0 'statistics: recovery conflicts in database caused by logical replication slot' ) +insert ( 3068 1255 0 'statistics: recovery conflicts in database caused by shared buffer pin' ) +insert ( 3069 1255 0 'statistics: recovery conflicts in database caused by buffer deadlock' ) +insert ( 3070 1255 0 'statistics: recovery conflicts in database' ) +insert ( 3152 1255 0 'statistics: deadlocks detected in database' ) +insert ( 3426 1255 0 'statistics: checksum failures detected in database' ) +insert ( 3428 1255 0 'statistics: when last checksum failure was detected in database' ) +insert ( 3074 1255 0 'statistics: last reset for a database' ) +insert ( 3150 1255 0 'statistics: number of temporary files written' ) +insert ( 3151 1255 0 'statistics: number of bytes in temporary files written' ) +insert ( 2844 1255 0 'statistics: block read time, in milliseconds' ) +insert ( 2845 1255 0 'statistics: block write time, in milliseconds' ) +insert ( 6185 1255 0 'statistics: session time, in milliseconds' ) +insert ( 6186 1255 0 'statistics: session active time, in milliseconds' ) +insert ( 6187 1255 0 'statistics: session idle in transaction time, in milliseconds' ) +insert ( 6188 1255 0 'statistics: total number of sessions' ) +insert ( 6189 1255 0 'statistics: number of sessions disconnected by the client closing the network connection' ) +insert ( 6190 1255 0 'statistics: number of sessions disconnected by fatal errors' ) +insert ( 6191 1255 0 'statistics: number of sessions killed by administrative action' ) +insert ( 3195 1255 0 'statistics: information about WAL archiver' ) +insert ( 2769 1255 0 'statistics: number of timed checkpoints started by the bgwriter' ) +insert ( 2770 1255 0 'statistics: number of backend requested checkpoints started by the bgwriter' ) +insert ( 2771 1255 0 'statistics: number of buffers written by the bgwriter during checkpoints' ) +insert ( 2772 1255 0 'statistics: number of buffers written by the bgwriter for cleaning dirty buffers' ) +insert ( 2773 1255 0 'statistics: number of times the bgwriter stopped processing when it had written too many buffers while cleaning' ) +insert ( 3075 1255 0 'statistics: last reset for the bgwriter' ) +insert ( 3160 1255 0 'statistics: checkpoint time spent writing buffers to disk, in milliseconds' ) +insert ( 3161 1255 0 'statistics: checkpoint time spent synchronizing buffers to disk, in milliseconds' ) +insert ( 2775 1255 0 'statistics: number of buffers written by backends' ) +insert ( 3063 1255 0 'statistics: number of backend buffer writes that did their own fsync' ) +insert ( 2859 1255 0 'statistics: number of buffer allocations' ) +insert ( 6214 1255 0 'statistics: per backend type IO statistics' ) +insert ( 1136 1255 0 'statistics: information about WAL activity' ) +insert ( 6248 1255 0 'statistics: information about WAL prefetching' ) +insert ( 2306 1255 0 'statistics: information about SLRU caches' ) +insert ( 2978 1255 0 'statistics: number of function calls' ) +insert ( 2979 1255 0 'statistics: total execution time of function, in milliseconds' ) +insert ( 2980 1255 0 'statistics: self execution time of function, in milliseconds' ) +insert ( 3037 1255 0 'statistics: number of scans done for table/index in current transaction' ) +insert ( 3038 1255 0 'statistics: number of tuples read by seqscan in current transaction' ) +insert ( 3039 1255 0 'statistics: number of tuples fetched by idxscan in current transaction' ) +insert ( 3040 1255 0 'statistics: number of tuples inserted in current transaction' ) +insert ( 3041 1255 0 'statistics: number of tuples updated in current transaction' ) +insert ( 3042 1255 0 'statistics: number of tuples deleted in current transaction' ) +insert ( 3043 1255 0 'statistics: number of tuples hot updated in current transaction' ) +insert ( 6218 1255 0 'statistics: number of tuples updated onto a new page in current transaction' ) +insert ( 3044 1255 0 'statistics: number of blocks fetched in current transaction' ) +insert ( 3045 1255 0 'statistics: number of blocks found in cache in current transaction' ) +insert ( 3046 1255 0 'statistics: number of function calls in current transaction' ) +insert ( 3047 1255 0 'statistics: total execution time of function in current transaction, in milliseconds' ) +insert ( 3048 1255 0 'statistics: self execution time of function in current transaction, in milliseconds' ) +insert ( 3788 1255 0 'statistics: timestamp of the current statistics snapshot' ) +insert ( 2230 1255 0 'statistics: discard current transaction''s statistics snapshot' ) +insert ( 2137 1255 0 'statistics: force stats to be flushed after the next commit' ) +insert ( 2274 1255 0 'statistics: reset collected statistics for current database' ) +insert ( 3775 1255 0 'statistics: reset collected statistics shared across the cluster' ) +insert ( 3776 1255 0 'statistics: reset collected statistics for a single table or index in the current database or shared across all databases in the cluster' ) +insert ( 3777 1255 0 'statistics: reset collected statistics for a single function in the current database' ) +insert ( 2307 1255 0 'statistics: reset collected statistics for a single SLRU' ) +insert ( 6170 1255 0 'statistics: reset collected statistics for a single replication slot' ) +insert ( 6232 1255 0 'statistics: reset collected statistics for a single subscription' ) +insert ( 3163 1255 0 'current trigger depth' ) +insert ( 3778 1255 0 'tablespace location' ) +insert ( 1946 1255 0 'convert bytea value into some ascii-only text string' ) +insert ( 1947 1255 0 'convert ascii-encoded text string into bytea value' ) +insert ( 1954 1255 0 less-equal-greater ) +insert ( 3331 1255 0 'sort support' ) +insert ( 3917 1255 0 'planner support for timestamp length coercion' ) +insert ( 3944 1255 0 'planner support for time length coercion' ) +insert ( 1961 1255 0 'adjust timestamp precision' ) +insert ( 1965 1255 0 'larger of two' ) +insert ( 1966 1255 0 'smaller of two' ) +insert ( 1967 1255 0 'adjust timestamptz precision' ) +insert ( 1968 1255 0 'adjust time precision' ) +insert ( 1969 1255 0 'adjust time with time zone precision' ) +insert ( 2007 1255 0 'matches LIKE expression' ) +insert ( 2008 1255 0 'does not match LIKE expression' ) +insert ( 2009 1255 0 'convert LIKE pattern to use backslash escapes' ) +insert ( 2010 1255 0 'octet length' ) +insert ( 2012 1255 0 'extract portion of string' ) +insert ( 2013 1255 0 'extract portion of string' ) +insert ( 2085 1255 0 'extract portion of string' ) +insert ( 2086 1255 0 'extract portion of string' ) +insert ( 2014 1255 0 'position of substring' ) +insert ( 2015 1255 0 'trim selected bytes from both ends of string' ) +insert ( 6195 1255 0 'trim selected bytes from left end of string' ) +insert ( 6196 1255 0 'trim selected bytes from right end of string' ) +insert ( 2019 1255 0 'convert timestamp with time zone to time' ) +insert ( 2020 1255 0 'truncate timestamp to specified units' ) +insert ( 6177 1255 0 'bin timestamp into specified interval' ) +insert ( 6178 1255 0 'bin timestamp with time zone into specified interval' ) +insert ( 2021 1255 0 'extract field from timestamp' ) +insert ( 6202 1255 0 'extract field from timestamp' ) +insert ( 2024 1255 0 'convert date to timestamp' ) +insert ( 2025 1255 0 'convert date and time to timestamp' ) +insert ( 2027 1255 0 'convert timestamp with time zone to timestamp' ) +insert ( 2028 1255 0 'convert timestamp to timestamp with time zone' ) +insert ( 2029 1255 0 'convert timestamp to date' ) +insert ( 2035 1255 0 'smaller of two' ) +insert ( 2036 1255 0 'larger of two' ) +insert ( 2037 1255 0 'adjust time with time zone to new zone' ) +insert ( 2038 1255 0 'adjust time with time zone to new zone' ) +insert ( 2039 1255 0 hash ) +insert ( 3411 1255 0 hash ) +insert ( 2041 1255 0 'intervals overlap?' ) +insert ( 2042 1255 0 'intervals overlap?' ) +insert ( 2043 1255 0 'intervals overlap?' ) +insert ( 2044 1255 0 'intervals overlap?' ) +insert ( 2045 1255 0 less-equal-greater ) +insert ( 3137 1255 0 'sort support' ) +insert ( 4134 1255 0 'window RANGE support' ) +insert ( 4135 1255 0 'window RANGE support' ) +insert ( 4136 1255 0 'window RANGE support' ) +insert ( 4137 1255 0 'window RANGE support' ) +insert ( 4138 1255 0 'window RANGE support' ) +insert ( 2046 1255 0 'convert time with time zone to time' ) +insert ( 2047 1255 0 'convert time to time with time zone' ) +insert ( 2048 1255 0 'finite timestamp?' ) +insert ( 2049 1255 0 'format timestamp to text' ) +insert ( 2058 1255 0 'date difference preserving months and years' ) +insert ( 2059 1255 0 'date difference from today preserving months and years' ) +insert ( 2069 1255 0 'adjust timestamp to new time zone' ) +insert ( 2070 1255 0 'adjust timestamp to new time zone' ) +insert ( 2073 1255 0 'extract text matching regular expression' ) +insert ( 2074 1255 0 'extract text matching SQL regular expression' ) +insert ( 2075 1255 0 'convert int8 to bitstring' ) +insert ( 2076 1255 0 'convert bitstring to int8' ) +insert ( 2077 1255 0 'SHOW X as a function' ) +insert ( 3294 1255 0 'SHOW X as a function, optionally no error for missing variable' ) +insert ( 2078 1255 0 'SET X as a function' ) +insert ( 2084 1255 0 'SHOW ALL as a function' ) +insert ( 6240 1255 0 'return flags for specified GUC' ) +insert ( 3329 1255 0 'show config file settings' ) +insert ( 3401 1255 0 'show pg_hba.conf rules' ) +insert ( 6250 1255 0 'show pg_ident.conf mappings' ) +insert ( 1371 1255 0 'view system lock information' ) +insert ( 2561 1255 0 'get array of PIDs of sessions blocking specified backend PID from acquiring a heavyweight lock' ) +insert ( 3376 1255 0 'get array of PIDs of sessions blocking specified backend PID from acquiring a safe snapshot' ) +insert ( 3378 1255 0 'isolationtester support function' ) +insert ( 1065 1255 0 'view two-phase transactions' ) +insert ( 3819 1255 0 'view members of a multixactid' ) +insert ( 3581 1255 0 'get commit timestamp of a transaction' ) +insert ( 6168 1255 0 'get commit timestamp and replication origin of a transaction' ) +insert ( 3583 1255 0 'get transaction Id, commit timestamp and replication origin of latest transaction commit' ) +insert ( 3537 1255 0 'get identification of SQL object' ) +insert ( 3839 1255 0 'get machine-parseable identification of SQL object' ) +insert ( 3382 1255 0 'get identification of SQL object for pg_get_object_address()' ) +insert ( 3954 1255 0 'get OID-based object address from name/args arrays' ) +insert ( 2079 1255 0 'is table visible in search path?' ) +insert ( 2080 1255 0 'is type visible in search path?' ) +insert ( 2081 1255 0 'is function visible in search path?' ) +insert ( 2082 1255 0 'is operator visible in search path?' ) +insert ( 2083 1255 0 'is opclass visible in search path?' ) +insert ( 3829 1255 0 'is opfamily visible in search path?' ) +insert ( 2093 1255 0 'is conversion visible in search path?' ) +insert ( 3403 1255 0 'is statistics object visible in search path?' ) +insert ( 3756 1255 0 'is text search parser visible in search path?' ) +insert ( 3757 1255 0 'is text search dictionary visible in search path?' ) +insert ( 3768 1255 0 'is text search template visible in search path?' ) +insert ( 3758 1255 0 'is text search configuration visible in search path?' ) +insert ( 3815 1255 0 'is collation visible in search path?' ) +insert ( 2854 1255 0 'get OID of current session''s temp schema, if any' ) +insert ( 2855 1255 0 'is schema another session''s temp schema?' ) +insert ( 2171 1255 0 'cancel a server process'' current query' ) +insert ( 2096 1255 0 'terminate a server process' ) +insert ( 2172 1255 0 'prepare for taking an online backup' ) +insert ( 2739 1255 0 'finish taking an online backup' ) +insert ( 3436 1255 0 'promote standby server' ) +insert ( 2848 1255 0 'switch to new wal file' ) +insert ( 6305 1255 0 'log details of the current snapshot to WAL' ) +insert ( 3098 1255 0 'create a named restore point' ) +insert ( 2849 1255 0 'current wal write location' ) +insert ( 2852 1255 0 'current wal insert location' ) +insert ( 3330 1255 0 'current wal flush location' ) +insert ( 2850 1255 0 'wal filename and byte offset, given a wal location' ) +insert ( 2851 1255 0 'wal filename, given a wal location' ) +insert ( 6213 1255 0 'sequence number and timeline ID given a wal filename' ) +insert ( 3165 1255 0 'difference in bytes, given two wal locations' ) +insert ( 3809 1255 0 'export a snapshot' ) +insert ( 3810 1255 0 'true if server is in recovery' ) +insert ( 3820 1255 0 'current wal flush location' ) +insert ( 3821 1255 0 'last wal replay location' ) +insert ( 3830 1255 0 'timestamp of last replay xact' ) +insert ( 3071 1255 0 'pause wal replay' ) +insert ( 3072 1255 0 'resume wal replay, if it was paused' ) +insert ( 3073 1255 0 'true if wal replay is paused' ) +insert ( 1137 1255 0 'get wal replay pause state' ) +insert ( 6224 1255 0 'get resource managers loaded in system' ) +insert ( 2621 1255 0 'reload configuration files' ) +insert ( 2622 1255 0 'rotate log file' ) +insert ( 4099 1255 0 'rotate log file - old version for adminpack 1.0' ) +insert ( 3800 1255 0 'current logging collector file location' ) +insert ( 3801 1255 0 'current logging collector file location' ) +insert ( 2623 1255 0 'get information about file' ) +insert ( 3307 1255 0 'get information about file' ) +insert ( 2624 1255 0 'read text from a file' ) +insert ( 3293 1255 0 'read text from a file' ) +insert ( 4100 1255 0 'read text from a file - old version for adminpack 1.0' ) +insert ( 3826 1255 0 'read text from a file' ) +insert ( 6208 1255 0 'read text from a file' ) +insert ( 3827 1255 0 'read bytea from a file' ) +insert ( 3295 1255 0 'read bytea from a file' ) +insert ( 3828 1255 0 'read bytea from a file' ) +insert ( 6209 1255 0 'read bytea from a file' ) +insert ( 2625 1255 0 'list all files in a directory' ) +insert ( 3297 1255 0 'list all files in a directory' ) +insert ( 2626 1255 0 'sleep for the specified time in seconds' ) +insert ( 3935 1255 0 'sleep for the specified interval' ) +insert ( 3936 1255 0 'sleep until the specified time' ) +insert ( 315 1255 0 'Is JIT compilation available in this session?' ) +insert ( 2971 1255 0 'convert boolean to text' ) +insert ( 2100 1255 0 'the average (arithmetic mean) as numeric of all bigint values' ) +insert ( 2101 1255 0 'the average (arithmetic mean) as numeric of all integer values' ) +insert ( 2102 1255 0 'the average (arithmetic mean) as numeric of all smallint values' ) +insert ( 2103 1255 0 'the average (arithmetic mean) as numeric of all numeric values' ) +insert ( 2104 1255 0 'the average (arithmetic mean) as float8 of all float4 values' ) +insert ( 2105 1255 0 'the average (arithmetic mean) as float8 of all float8 values' ) +insert ( 2106 1255 0 'the average (arithmetic mean) as interval of all interval values' ) +insert ( 2107 1255 0 'sum as numeric across all bigint input values' ) +insert ( 2108 1255 0 'sum as bigint across all integer input values' ) +insert ( 2109 1255 0 'sum as bigint across all smallint input values' ) +insert ( 2110 1255 0 'sum as float4 across all float4 input values' ) +insert ( 2111 1255 0 'sum as float8 across all float8 input values' ) +insert ( 2112 1255 0 'sum as money across all money input values' ) +insert ( 2113 1255 0 'sum as interval across all interval input values' ) +insert ( 2114 1255 0 'sum as numeric across all numeric input values' ) +insert ( 2115 1255 0 'maximum value of all bigint input values' ) +insert ( 2116 1255 0 'maximum value of all integer input values' ) +insert ( 2117 1255 0 'maximum value of all smallint input values' ) +insert ( 2118 1255 0 'maximum value of all oid input values' ) +insert ( 2119 1255 0 'maximum value of all float4 input values' ) +insert ( 2120 1255 0 'maximum value of all float8 input values' ) +insert ( 2122 1255 0 'maximum value of all date input values' ) +insert ( 2123 1255 0 'maximum value of all time input values' ) +insert ( 2124 1255 0 'maximum value of all time with time zone input values' ) +insert ( 2125 1255 0 'maximum value of all money input values' ) +insert ( 2126 1255 0 'maximum value of all timestamp input values' ) +insert ( 2127 1255 0 'maximum value of all timestamp with time zone input values' ) +insert ( 2128 1255 0 'maximum value of all interval input values' ) +insert ( 2129 1255 0 'maximum value of all text input values' ) +insert ( 2130 1255 0 'maximum value of all numeric input values' ) +insert ( 2050 1255 0 'maximum value of all anyarray input values' ) +insert ( 2244 1255 0 'maximum value of all bpchar input values' ) +insert ( 2797 1255 0 'maximum value of all tid input values' ) +insert ( 3564 1255 0 'maximum value of all inet input values' ) +insert ( 4189 1255 0 'maximum value of all pg_lsn input values' ) +insert ( 5099 1255 0 'maximum value of all xid8 input values' ) +insert ( 2131 1255 0 'minimum value of all bigint input values' ) +insert ( 2132 1255 0 'minimum value of all integer input values' ) +insert ( 2133 1255 0 'minimum value of all smallint input values' ) +insert ( 2134 1255 0 'minimum value of all oid input values' ) +insert ( 2135 1255 0 'minimum value of all float4 input values' ) +insert ( 2136 1255 0 'minimum value of all float8 input values' ) +insert ( 2138 1255 0 'minimum value of all date input values' ) +insert ( 2139 1255 0 'minimum value of all time input values' ) +insert ( 2140 1255 0 'minimum value of all time with time zone input values' ) +insert ( 2141 1255 0 'minimum value of all money input values' ) +insert ( 2142 1255 0 'minimum value of all timestamp input values' ) +insert ( 2143 1255 0 'minimum value of all timestamp with time zone input values' ) +insert ( 2144 1255 0 'minimum value of all interval input values' ) +insert ( 2145 1255 0 'minimum value of all text values' ) +insert ( 2146 1255 0 'minimum value of all numeric input values' ) +insert ( 2051 1255 0 'minimum value of all anyarray input values' ) +insert ( 2245 1255 0 'minimum value of all bpchar input values' ) +insert ( 2798 1255 0 'minimum value of all tid input values' ) +insert ( 3565 1255 0 'minimum value of all inet input values' ) +insert ( 4190 1255 0 'minimum value of all pg_lsn input values' ) +insert ( 5100 1255 0 'minimum value of all xid8 input values' ) +insert ( 2147 1255 0 'number of input rows for which the input expression is not null' ) +insert ( 2803 1255 0 'number of input rows' ) +insert ( 6236 1255 0 'planner support for count run condition' ) +insert ( 2718 1255 0 'population variance of bigint input values (square of the population standard deviation)' ) +insert ( 2719 1255 0 'population variance of integer input values (square of the population standard deviation)' ) +insert ( 2720 1255 0 'population variance of smallint input values (square of the population standard deviation)' ) +insert ( 2721 1255 0 'population variance of float4 input values (square of the population standard deviation)' ) +insert ( 2722 1255 0 'population variance of float8 input values (square of the population standard deviation)' ) +insert ( 2723 1255 0 'population variance of numeric input values (square of the population standard deviation)' ) +insert ( 2641 1255 0 'sample variance of bigint input values (square of the sample standard deviation)' ) +insert ( 2642 1255 0 'sample variance of integer input values (square of the sample standard deviation)' ) +insert ( 2643 1255 0 'sample variance of smallint input values (square of the sample standard deviation)' ) +insert ( 2644 1255 0 'sample variance of float4 input values (square of the sample standard deviation)' ) +insert ( 2645 1255 0 'sample variance of float8 input values (square of the sample standard deviation)' ) +insert ( 2646 1255 0 'sample variance of numeric input values (square of the sample standard deviation)' ) +insert ( 2148 1255 0 'historical alias for var_samp' ) +insert ( 2149 1255 0 'historical alias for var_samp' ) +insert ( 2150 1255 0 'historical alias for var_samp' ) +insert ( 2151 1255 0 'historical alias for var_samp' ) +insert ( 2152 1255 0 'historical alias for var_samp' ) +insert ( 2153 1255 0 'historical alias for var_samp' ) +insert ( 2724 1255 0 'population standard deviation of bigint input values' ) +insert ( 2725 1255 0 'population standard deviation of integer input values' ) +insert ( 2726 1255 0 'population standard deviation of smallint input values' ) +insert ( 2727 1255 0 'population standard deviation of float4 input values' ) +insert ( 2728 1255 0 'population standard deviation of float8 input values' ) +insert ( 2729 1255 0 'population standard deviation of numeric input values' ) +insert ( 2712 1255 0 'sample standard deviation of bigint input values' ) +insert ( 2713 1255 0 'sample standard deviation of integer input values' ) +insert ( 2714 1255 0 'sample standard deviation of smallint input values' ) +insert ( 2715 1255 0 'sample standard deviation of float4 input values' ) +insert ( 2716 1255 0 'sample standard deviation of float8 input values' ) +insert ( 2717 1255 0 'sample standard deviation of numeric input values' ) +insert ( 2154 1255 0 'historical alias for stddev_samp' ) +insert ( 2155 1255 0 'historical alias for stddev_samp' ) +insert ( 2156 1255 0 'historical alias for stddev_samp' ) +insert ( 2157 1255 0 'historical alias for stddev_samp' ) +insert ( 2158 1255 0 'historical alias for stddev_samp' ) +insert ( 2159 1255 0 'historical alias for stddev_samp' ) +insert ( 2818 1255 0 'number of input rows in which both expressions are not null' ) +insert ( 2819 1255 0 'sum of squares of the independent variable (sum(X^2) - sum(X)^2/N)' ) +insert ( 2820 1255 0 'sum of squares of the dependent variable (sum(Y^2) - sum(Y)^2/N)' ) +insert ( 2821 1255 0 'sum of products of independent times dependent variable (sum(X*Y) - sum(X) * sum(Y)/N)' ) +insert ( 2822 1255 0 'average of the independent variable (sum(X)/N)' ) +insert ( 2823 1255 0 'average of the dependent variable (sum(Y)/N)' ) +insert ( 2824 1255 0 'square of the correlation coefficient' ) +insert ( 2825 1255 0 'slope of the least-squares-fit linear equation determined by the (X, Y) pairs' ) +insert ( 2826 1255 0 'y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs' ) +insert ( 2827 1255 0 'population covariance' ) +insert ( 2828 1255 0 'sample covariance' ) +insert ( 2829 1255 0 'correlation coefficient' ) +insert ( 2166 1255 0 less-equal-greater ) +insert ( 3332 1255 0 'sort support' ) +insert ( 2180 1255 0 less-equal-greater ) +insert ( 3333 1255 0 'sort support' ) +insert ( 2188 1255 0 less-equal-greater ) +insert ( 2189 1255 0 less-equal-greater ) +insert ( 2190 1255 0 less-equal-greater ) +insert ( 2191 1255 0 less-equal-greater ) +insert ( 2192 1255 0 less-equal-greater ) +insert ( 2193 1255 0 less-equal-greater ) +insert ( 2194 1255 0 less-equal-greater ) +insert ( 2195 1255 0 less-equal-greater ) +insert ( 2212 1255 0 'I/O' ) +insert ( 2213 1255 0 'I/O' ) +insert ( 2214 1255 0 'I/O' ) +insert ( 2215 1255 0 'I/O' ) +insert ( 3492 1255 0 'convert operator name to regoper' ) +insert ( 3476 1255 0 'convert operator name to regoperator' ) +insert ( 2216 1255 0 'I/O' ) +insert ( 2217 1255 0 'I/O' ) +insert ( 2218 1255 0 'I/O' ) +insert ( 2219 1255 0 'I/O' ) +insert ( 3495 1255 0 'convert classname to regclass' ) +insert ( 4193 1255 0 'I/O' ) +insert ( 4194 1255 0 'I/O' ) +insert ( 4195 1255 0 'convert classname to regcollation' ) +insert ( 2220 1255 0 'I/O' ) +insert ( 2221 1255 0 'I/O' ) +insert ( 3493 1255 0 'convert type name to regtype' ) +insert ( 1079 1255 0 'convert text to regclass' ) +insert ( 4098 1255 0 'I/O' ) +insert ( 4092 1255 0 'I/O' ) +insert ( 4093 1255 0 'convert role name to regrole' ) +insert ( 4084 1255 0 'I/O' ) +insert ( 4085 1255 0 'I/O' ) +insert ( 4086 1255 0 'convert namespace name to regnamespace' ) +insert ( 6210 1255 0 'test whether string is valid input for data type' ) +insert ( 6211 1255 0 'get error details if string is not valid input for data type' ) +insert ( 1268 1255 0 'parse qualified identifier to array of identifiers' ) +insert ( 2246 1255 0 '(internal)' ) +insert ( 2247 1255 0 '(internal)' ) +insert ( 2248 1255 0 '(internal)' ) +insert ( 2250 1255 0 'user privilege on database by username, database name' ) +insert ( 2251 1255 0 'user privilege on database by username, database oid' ) +insert ( 2252 1255 0 'user privilege on database by user oid, database name' ) +insert ( 2253 1255 0 'user privilege on database by user oid, database oid' ) +insert ( 2254 1255 0 'current user privilege on database by database name' ) +insert ( 2255 1255 0 'current user privilege on database by database oid' ) +insert ( 2256 1255 0 'user privilege on function by username, function name' ) +insert ( 2257 1255 0 'user privilege on function by username, function oid' ) +insert ( 2258 1255 0 'user privilege on function by user oid, function name' ) +insert ( 2259 1255 0 'user privilege on function by user oid, function oid' ) +insert ( 2260 1255 0 'current user privilege on function by function name' ) +insert ( 2261 1255 0 'current user privilege on function by function oid' ) +insert ( 2262 1255 0 'user privilege on language by username, language name' ) +insert ( 2263 1255 0 'user privilege on language by username, language oid' ) +insert ( 2264 1255 0 'user privilege on language by user oid, language name' ) +insert ( 2265 1255 0 'user privilege on language by user oid, language oid' ) +insert ( 2266 1255 0 'current user privilege on language by language name' ) +insert ( 2267 1255 0 'current user privilege on language by language oid' ) +insert ( 2268 1255 0 'user privilege on schema by username, schema name' ) +insert ( 2269 1255 0 'user privilege on schema by username, schema oid' ) +insert ( 2270 1255 0 'user privilege on schema by user oid, schema name' ) +insert ( 2271 1255 0 'user privilege on schema by user oid, schema oid' ) +insert ( 2272 1255 0 'current user privilege on schema by schema name' ) +insert ( 2273 1255 0 'current user privilege on schema by schema oid' ) +insert ( 2390 1255 0 'user privilege on tablespace by username, tablespace name' ) +insert ( 2391 1255 0 'user privilege on tablespace by username, tablespace oid' ) +insert ( 2392 1255 0 'user privilege on tablespace by user oid, tablespace name' ) +insert ( 2393 1255 0 'user privilege on tablespace by user oid, tablespace oid' ) +insert ( 2394 1255 0 'current user privilege on tablespace by tablespace name' ) +insert ( 2395 1255 0 'current user privilege on tablespace by tablespace oid' ) +insert ( 3000 1255 0 'user privilege on foreign data wrapper by username, foreign data wrapper name' ) +insert ( 3001 1255 0 'user privilege on foreign data wrapper by username, foreign data wrapper oid' ) +insert ( 3002 1255 0 'user privilege on foreign data wrapper by user oid, foreign data wrapper name' ) +insert ( 3003 1255 0 'user privilege on foreign data wrapper by user oid, foreign data wrapper oid' ) +insert ( 3004 1255 0 'current user privilege on foreign data wrapper by foreign data wrapper name' ) +insert ( 3005 1255 0 'current user privilege on foreign data wrapper by foreign data wrapper oid' ) +insert ( 3006 1255 0 'user privilege on server by username, server name' ) +insert ( 3007 1255 0 'user privilege on server by username, server oid' ) +insert ( 3008 1255 0 'user privilege on server by user oid, server name' ) +insert ( 3009 1255 0 'user privilege on server by user oid, server oid' ) +insert ( 3010 1255 0 'current user privilege on server by server name' ) +insert ( 3011 1255 0 'current user privilege on server by server oid' ) +insert ( 3138 1255 0 'user privilege on type by username, type name' ) +insert ( 3139 1255 0 'user privilege on type by username, type oid' ) +insert ( 3140 1255 0 'user privilege on type by user oid, type name' ) +insert ( 3141 1255 0 'user privilege on type by user oid, type oid' ) +insert ( 3142 1255 0 'current user privilege on type by type name' ) +insert ( 3143 1255 0 'current user privilege on type by type oid' ) +insert ( 6205 1255 0 'user privilege on parameter by username, parameter name' ) +insert ( 6206 1255 0 'user privilege on parameter by user oid, parameter name' ) +insert ( 6207 1255 0 'current user privilege on parameter by parameter name' ) +insert ( 2705 1255 0 'user privilege on role by username, role name' ) +insert ( 2706 1255 0 'user privilege on role by username, role oid' ) +insert ( 2707 1255 0 'user privilege on role by user oid, role name' ) +insert ( 2708 1255 0 'user privilege on role by user oid, role oid' ) +insert ( 2709 1255 0 'current user privilege on role by role name' ) +insert ( 2710 1255 0 'current user privilege on role by role oid' ) +insert ( 1269 1255 0 'bytes required to store the value, perhaps with compression' ) +insert ( 2121 1255 0 'compression method for the compressed datum' ) +insert ( 2322 1255 0 'total disk space usage for the specified tablespace' ) +insert ( 2323 1255 0 'total disk space usage for the specified tablespace' ) +insert ( 2324 1255 0 'total disk space usage for the specified database' ) +insert ( 2168 1255 0 'total disk space usage for the specified database' ) +insert ( 2325 1255 0 'disk space usage for the main fork of the specified table or index' ) +insert ( 2332 1255 0 'disk space usage for the specified fork of a table or index' ) +insert ( 2286 1255 0 'total disk space usage for the specified table and associated indexes' ) +insert ( 2288 1255 0 'convert a long int to a human readable text using size units' ) +insert ( 3166 1255 0 'convert a numeric to a human readable text using size units' ) +insert ( 3334 1255 0 'convert a size in human-readable format with size units into bytes' ) +insert ( 2997 1255 0 'disk space usage for the specified table, including TOAST, free space and visibility map' ) +insert ( 2998 1255 0 'disk space usage for all indexes attached to the specified table' ) +insert ( 2999 1255 0 'filenode identifier of relation' ) +insert ( 3454 1255 0 'relation OID for filenode and tablespace' ) +insert ( 3034 1255 0 'file path of relation' ) +insert ( 2316 1255 0 '(internal)' ) +insert ( 2290 1255 0 'I/O' ) +insert ( 2291 1255 0 'I/O' ) +insert ( 2292 1255 0 'I/O' ) +insert ( 2293 1255 0 'I/O' ) +insert ( 2294 1255 0 'I/O' ) +insert ( 2295 1255 0 'I/O' ) +insert ( 2296 1255 0 'I/O' ) +insert ( 2297 1255 0 'I/O' ) +insert ( 2298 1255 0 'I/O' ) +insert ( 2299 1255 0 'I/O' ) +insert ( 2300 1255 0 'I/O' ) +insert ( 2301 1255 0 'I/O' ) +insert ( 3594 1255 0 'I/O' ) +insert ( 3595 1255 0 'I/O' ) +insert ( 2302 1255 0 'I/O' ) +insert ( 2303 1255 0 'I/O' ) +insert ( 2304 1255 0 'I/O' ) +insert ( 2305 1255 0 'I/O' ) +insert ( 2312 1255 0 'I/O' ) +insert ( 2313 1255 0 'I/O' ) +insert ( 2398 1255 0 'I/O' ) +insert ( 2399 1255 0 'I/O' ) +insert ( 2597 1255 0 'I/O' ) +insert ( 2598 1255 0 'I/O' ) +insert ( 2777 1255 0 'I/O' ) +insert ( 2778 1255 0 'I/O' ) +insert ( 3116 1255 0 'I/O' ) +insert ( 3117 1255 0 'I/O' ) +insert ( 326 1255 0 'I/O' ) +insert ( 327 1255 0 'I/O' ) +insert ( 3311 1255 0 'I/O' ) +insert ( 3312 1255 0 'I/O' ) +insert ( 267 1255 0 'I/O' ) +insert ( 268 1255 0 'I/O' ) +insert ( 5086 1255 0 'I/O' ) +insert ( 5087 1255 0 'I/O' ) +insert ( 5088 1255 0 'I/O' ) +insert ( 5089 1255 0 'I/O' ) +insert ( 5090 1255 0 'I/O' ) +insert ( 5091 1255 0 'I/O' ) +insert ( 5092 1255 0 'I/O' ) +insert ( 5093 1255 0 'I/O' ) +insert ( 5094 1255 0 'I/O' ) +insert ( 5095 1255 0 'I/O' ) +insert ( 4226 1255 0 'I/O' ) +insert ( 4227 1255 0 'I/O' ) +insert ( 3313 1255 0 'BERNOULLI tablesample method handler' ) +insert ( 3314 1255 0 'SYSTEM tablesample method handler' ) +insert ( 2311 1255 0 'MD5 hash' ) +insert ( 2321 1255 0 'MD5 hash' ) +insert ( 3419 1255 0 'SHA-224 hash' ) +insert ( 3420 1255 0 'SHA-256 hash' ) +insert ( 3421 1255 0 'SHA-384 hash' ) +insert ( 3422 1255 0 'SHA-512 hash' ) +insert ( 2344 1255 0 less-equal-greater ) +insert ( 2357 1255 0 less-equal-greater ) +insert ( 2370 1255 0 less-equal-greater ) +insert ( 2383 1255 0 less-equal-greater ) +insert ( 2526 1255 0 less-equal-greater ) +insert ( 2533 1255 0 less-equal-greater ) +insert ( 2400 1255 0 'I/O' ) +insert ( 2401 1255 0 'I/O' ) +insert ( 2402 1255 0 'I/O' ) +insert ( 2403 1255 0 'I/O' ) +insert ( 2404 1255 0 'I/O' ) +insert ( 2405 1255 0 'I/O' ) +insert ( 2406 1255 0 'I/O' ) +insert ( 2407 1255 0 'I/O' ) +insert ( 2408 1255 0 'I/O' ) +insert ( 2409 1255 0 'I/O' ) +insert ( 2410 1255 0 'I/O' ) +insert ( 2411 1255 0 'I/O' ) +insert ( 2412 1255 0 'I/O' ) +insert ( 2413 1255 0 'I/O' ) +insert ( 2414 1255 0 'I/O' ) +insert ( 2415 1255 0 'I/O' ) +insert ( 2416 1255 0 'I/O' ) +insert ( 2417 1255 0 'I/O' ) +insert ( 2418 1255 0 'I/O' ) +insert ( 2419 1255 0 'I/O' ) +insert ( 2420 1255 0 'I/O' ) +insert ( 2421 1255 0 'I/O' ) +insert ( 2422 1255 0 'I/O' ) +insert ( 2423 1255 0 'I/O' ) +insert ( 2424 1255 0 'I/O' ) +insert ( 2425 1255 0 'I/O' ) +insert ( 2426 1255 0 'I/O' ) +insert ( 2427 1255 0 'I/O' ) +insert ( 2428 1255 0 'I/O' ) +insert ( 2429 1255 0 'I/O' ) +insert ( 2430 1255 0 'I/O' ) +insert ( 2431 1255 0 'I/O' ) +insert ( 2432 1255 0 'I/O' ) +insert ( 2433 1255 0 'I/O' ) +insert ( 2434 1255 0 'I/O' ) +insert ( 2435 1255 0 'I/O' ) +insert ( 2436 1255 0 'I/O' ) +insert ( 2437 1255 0 'I/O' ) +insert ( 2438 1255 0 'I/O' ) +insert ( 2439 1255 0 'I/O' ) +insert ( 2440 1255 0 'I/O' ) +insert ( 2441 1255 0 'I/O' ) +insert ( 2442 1255 0 'I/O' ) +insert ( 2443 1255 0 'I/O' ) +insert ( 2444 1255 0 'I/O' ) +insert ( 2445 1255 0 'I/O' ) +insert ( 2446 1255 0 'I/O' ) +insert ( 2447 1255 0 'I/O' ) +insert ( 2448 1255 0 'I/O' ) +insert ( 2449 1255 0 'I/O' ) +insert ( 2450 1255 0 'I/O' ) +insert ( 2451 1255 0 'I/O' ) +insert ( 2452 1255 0 'I/O' ) +insert ( 2453 1255 0 'I/O' ) +insert ( 4196 1255 0 'I/O' ) +insert ( 4197 1255 0 'I/O' ) +insert ( 2454 1255 0 'I/O' ) +insert ( 2455 1255 0 'I/O' ) +insert ( 4094 1255 0 'I/O' ) +insert ( 4095 1255 0 'I/O' ) +insert ( 4087 1255 0 'I/O' ) +insert ( 4088 1255 0 'I/O' ) +insert ( 2456 1255 0 'I/O' ) +insert ( 2457 1255 0 'I/O' ) +insert ( 2458 1255 0 'I/O' ) +insert ( 2459 1255 0 'I/O' ) +insert ( 2460 1255 0 'I/O' ) +insert ( 2461 1255 0 'I/O' ) +insert ( 2468 1255 0 'I/O' ) +insert ( 2469 1255 0 'I/O' ) +insert ( 2470 1255 0 'I/O' ) +insert ( 2471 1255 0 'I/O' ) +insert ( 2472 1255 0 'I/O' ) +insert ( 2473 1255 0 'I/O' ) +insert ( 2474 1255 0 'I/O' ) +insert ( 2475 1255 0 'I/O' ) +insert ( 2476 1255 0 'I/O' ) +insert ( 2477 1255 0 'I/O' ) +insert ( 2478 1255 0 'I/O' ) +insert ( 2479 1255 0 'I/O' ) +insert ( 2480 1255 0 'I/O' ) +insert ( 2481 1255 0 'I/O' ) +insert ( 2482 1255 0 'I/O' ) +insert ( 2483 1255 0 'I/O' ) +insert ( 2484 1255 0 'I/O' ) +insert ( 2485 1255 0 'I/O' ) +insert ( 2486 1255 0 'I/O' ) +insert ( 2487 1255 0 'I/O' ) +insert ( 2488 1255 0 'I/O' ) +insert ( 2489 1255 0 'I/O' ) +insert ( 2490 1255 0 'I/O' ) +insert ( 2491 1255 0 'I/O' ) +insert ( 2492 1255 0 'I/O' ) +insert ( 2493 1255 0 'I/O' ) +insert ( 2494 1255 0 'I/O' ) +insert ( 2495 1255 0 'I/O' ) +insert ( 2496 1255 0 'I/O' ) +insert ( 2497 1255 0 'I/O' ) +insert ( 2498 1255 0 'I/O' ) +insert ( 2499 1255 0 'I/O' ) +insert ( 2500 1255 0 'I/O' ) +insert ( 2501 1255 0 'I/O' ) +insert ( 2502 1255 0 'I/O' ) +insert ( 2503 1255 0 'I/O' ) +insert ( 3120 1255 0 'I/O' ) +insert ( 3121 1255 0 'I/O' ) +insert ( 3446 1255 0 'I/O' ) +insert ( 3447 1255 0 'I/O' ) +insert ( 2504 1255 0 'source text of a rule with pretty-print option' ) +insert ( 2505 1255 0 'select statement of a view with pretty-print option' ) +insert ( 2506 1255 0 'select statement of a view with pretty-print option' ) +insert ( 3159 1255 0 'select statement of a view with pretty-printing and specified line wrapping' ) +insert ( 2507 1255 0 'index description (full create statement or single expression) with pretty-print option' ) +insert ( 2508 1255 0 'constraint description with pretty-print option' ) +insert ( 2509 1255 0 'deparse an encoded expression with pretty-print option' ) +insert ( 2510 1255 0 'get the prepared statements for this session' ) +insert ( 2511 1255 0 'get the open cursors for this session' ) +insert ( 2599 1255 0 'get the available time zone abbreviations' ) +insert ( 2856 1255 0 'get the available time zone names' ) +insert ( 2730 1255 0 'trigger description with pretty-print option' ) +insert ( 3035 1255 0 'get the channels that the current backend listens to' ) +insert ( 3036 1255 0 'send a notification event' ) +insert ( 3296 1255 0 'get the fraction of the asynchronous notification queue currently in use' ) +insert ( 5052 1255 0 'allocations from the main shared memory segment' ) +insert ( 2282 1255 0 'information about all memory contexts of local backend' ) +insert ( 4543 1255 0 'log memory contexts of the specified backend' ) +insert ( 1066 1255 0 'non-persistent series generator' ) +insert ( 1067 1255 0 'non-persistent series generator' ) +insert ( 3994 1255 0 'planner support for generate_series' ) +insert ( 1068 1255 0 'non-persistent series generator' ) +insert ( 1069 1255 0 'non-persistent series generator' ) +insert ( 3995 1255 0 'planner support for generate_series' ) +insert ( 3259 1255 0 'non-persistent series generator' ) +insert ( 3260 1255 0 'non-persistent series generator' ) +insert ( 938 1255 0 'non-persistent series generator' ) +insert ( 939 1255 0 'non-persistent series generator' ) +insert ( 6274 1255 0 'non-persistent series generator' ) +insert ( 2515 1255 0 'aggregate transition function' ) +insert ( 2516 1255 0 'aggregate transition function' ) +insert ( 3496 1255 0 'aggregate transition function' ) +insert ( 3497 1255 0 'aggregate transition function' ) +insert ( 3498 1255 0 'aggregate final function' ) +insert ( 3499 1255 0 'aggregate final function' ) +insert ( 2517 1255 0 'boolean-and aggregate' ) +insert ( 2518 1255 0 'boolean-or aggregate' ) +insert ( 2519 1255 0 'boolean-and aggregate' ) +insert ( 2236 1255 0 'bitwise-and smallint aggregate' ) +insert ( 2237 1255 0 'bitwise-or smallint aggregate' ) +insert ( 6164 1255 0 'bitwise-xor smallint aggregate' ) +insert ( 2238 1255 0 'bitwise-and integer aggregate' ) +insert ( 2239 1255 0 'bitwise-or integer aggregate' ) +insert ( 6165 1255 0 'bitwise-xor integer aggregate' ) +insert ( 2240 1255 0 'bitwise-and bigint aggregate' ) +insert ( 2241 1255 0 'bitwise-or bigint aggregate' ) +insert ( 6166 1255 0 'bitwise-xor bigint aggregate' ) +insert ( 2242 1255 0 'bitwise-and bit aggregate' ) +insert ( 2243 1255 0 'bitwise-or bit aggregate' ) +insert ( 6167 1255 0 'bitwise-xor bit aggregate' ) +insert ( 2556 1255 0 'get OIDs of databases in a tablespace' ) +insert ( 2557 1255 0 'convert int4 to boolean' ) +insert ( 2558 1255 0 'convert boolean to int4' ) +insert ( 2559 1255 0 'current value from last used sequence' ) +insert ( 2560 1255 0 'postmaster start time' ) +insert ( 2034 1255 0 'configuration load time' ) +insert ( 2578 1255 0 'GiST support' ) +insert ( 2581 1255 0 'GiST support' ) +insert ( 2582 1255 0 'GiST support' ) +insert ( 2583 1255 0 'GiST support' ) +insert ( 2584 1255 0 'GiST support' ) +insert ( 3998 1255 0 'GiST support' ) +insert ( 2585 1255 0 'GiST support' ) +insert ( 2586 1255 0 'GiST support' ) +insert ( 2591 1255 0 'GiST support' ) +insert ( 2592 1255 0 'GiST support' ) +insert ( 1030 1255 0 'GiST support' ) +insert ( 3282 1255 0 'GiST support' ) +insert ( 2179 1255 0 'GiST support' ) +insert ( 3064 1255 0 'GiST support' ) +insert ( 3280 1255 0 'GiST support' ) +insert ( 3288 1255 0 'GiST support' ) +insert ( 3435 1255 0 'sort support' ) +insert ( 2743 1255 0 'GIN array support' ) +insert ( 2774 1255 0 'GIN array support' ) +insert ( 2744 1255 0 'GIN array support' ) +insert ( 3920 1255 0 'GIN array support' ) +insert ( 3076 1255 0 'GIN array support (obsolete)' ) +insert ( 3383 1255 0 'BRIN minmax support' ) +insert ( 3384 1255 0 'BRIN minmax support' ) +insert ( 3385 1255 0 'BRIN minmax support' ) +insert ( 3386 1255 0 'BRIN minmax support' ) +insert ( 4616 1255 0 'BRIN multi minmax support' ) +insert ( 4617 1255 0 'BRIN multi minmax support' ) +insert ( 4618 1255 0 'BRIN multi minmax support' ) +insert ( 4619 1255 0 'BRIN multi minmax support' ) +insert ( 4620 1255 0 'BRIN multi minmax support' ) +insert ( 4621 1255 0 'BRIN multi minmax int2 distance' ) +insert ( 4622 1255 0 'BRIN multi minmax int4 distance' ) +insert ( 4623 1255 0 'BRIN multi minmax int8 distance' ) +insert ( 4624 1255 0 'BRIN multi minmax float4 distance' ) +insert ( 4625 1255 0 'BRIN multi minmax float8 distance' ) +insert ( 4626 1255 0 'BRIN multi minmax numeric distance' ) +insert ( 4627 1255 0 'BRIN multi minmax tid distance' ) +insert ( 4628 1255 0 'BRIN multi minmax uuid distance' ) +insert ( 4629 1255 0 'BRIN multi minmax date distance' ) +insert ( 4630 1255 0 'BRIN multi minmax time distance' ) +insert ( 4631 1255 0 'BRIN multi minmax interval distance' ) +insert ( 4632 1255 0 'BRIN multi minmax timetz distance' ) +insert ( 4633 1255 0 'BRIN multi minmax pg_lsn distance' ) +insert ( 4634 1255 0 'BRIN multi minmax macaddr distance' ) +insert ( 4635 1255 0 'BRIN multi minmax macaddr8 distance' ) +insert ( 4636 1255 0 'BRIN multi minmax inet distance' ) +insert ( 4637 1255 0 'BRIN multi minmax timestamp distance' ) +insert ( 4105 1255 0 'BRIN inclusion support' ) +insert ( 4106 1255 0 'BRIN inclusion support' ) +insert ( 4107 1255 0 'BRIN inclusion support' ) +insert ( 4108 1255 0 'BRIN inclusion support' ) +insert ( 4591 1255 0 'BRIN bloom support' ) +insert ( 4592 1255 0 'BRIN bloom support' ) +insert ( 4593 1255 0 'BRIN bloom support' ) +insert ( 4594 1255 0 'BRIN bloom support' ) +insert ( 4595 1255 0 'BRIN bloom support' ) +insert ( 2880 1255 0 'obtain exclusive advisory lock' ) +insert ( 3089 1255 0 'obtain exclusive advisory lock' ) +insert ( 2881 1255 0 'obtain shared advisory lock' ) +insert ( 3090 1255 0 'obtain shared advisory lock' ) +insert ( 2882 1255 0 'obtain exclusive advisory lock if available' ) +insert ( 3091 1255 0 'obtain exclusive advisory lock if available' ) +insert ( 2883 1255 0 'obtain shared advisory lock if available' ) +insert ( 3092 1255 0 'obtain shared advisory lock if available' ) +insert ( 2884 1255 0 'release exclusive advisory lock' ) +insert ( 2885 1255 0 'release shared advisory lock' ) +insert ( 2886 1255 0 'obtain exclusive advisory lock' ) +insert ( 3093 1255 0 'obtain exclusive advisory lock' ) +insert ( 2887 1255 0 'obtain shared advisory lock' ) +insert ( 3094 1255 0 'obtain shared advisory lock' ) +insert ( 2888 1255 0 'obtain exclusive advisory lock if available' ) +insert ( 3095 1255 0 'obtain exclusive advisory lock if available' ) +insert ( 2889 1255 0 'obtain shared advisory lock if available' ) +insert ( 3096 1255 0 'obtain shared advisory lock if available' ) +insert ( 2890 1255 0 'release exclusive advisory lock' ) +insert ( 2891 1255 0 'release shared advisory lock' ) +insert ( 2892 1255 0 'release all advisory locks' ) +insert ( 2893 1255 0 'I/O' ) +insert ( 2894 1255 0 'I/O' ) +insert ( 2895 1255 0 'generate XML comment' ) +insert ( 2896 1255 0 'perform a non-validating parse of a character string to produce an XML value' ) +insert ( 2897 1255 0 'validate an XML value' ) +insert ( 2898 1255 0 'I/O' ) +insert ( 2899 1255 0 'I/O' ) +insert ( 2900 1255 0 'aggregate transition function' ) +insert ( 2901 1255 0 'concatenate XML values' ) +insert ( 2922 1255 0 'serialize an XML value to a character string' ) +insert ( 2923 1255 0 'map table contents to XML' ) +insert ( 2924 1255 0 'map query result to XML' ) +insert ( 2925 1255 0 'map rows from cursor to XML' ) +insert ( 2926 1255 0 'map table structure to XML Schema' ) +insert ( 2927 1255 0 'map query result structure to XML Schema' ) +insert ( 2928 1255 0 'map cursor structure to XML Schema' ) +insert ( 2929 1255 0 'map table contents and structure to XML and XML Schema' ) +insert ( 2930 1255 0 'map query result and structure to XML and XML Schema' ) +insert ( 2933 1255 0 'map schema contents to XML' ) +insert ( 2934 1255 0 'map schema structure to XML Schema' ) +insert ( 2935 1255 0 'map schema contents and structure to XML and XML Schema' ) +insert ( 2936 1255 0 'map database contents to XML' ) +insert ( 2937 1255 0 'map database structure to XML Schema' ) +insert ( 2938 1255 0 'map database contents and structure to XML and XML Schema' ) +insert ( 2931 1255 0 'evaluate XPath expression, with namespaces support' ) +insert ( 2932 1255 0 'evaluate XPath expression' ) +insert ( 2614 1255 0 'test XML value against XPath expression' ) +insert ( 3049 1255 0 'test XML value against XPath expression, with namespace support' ) +insert ( 3050 1255 0 'test XML value against XPath expression' ) +insert ( 3051 1255 0 'determine if a string is well formed XML' ) +insert ( 3052 1255 0 'determine if a string is well formed XML document' ) +insert ( 3053 1255 0 'determine if a string is well formed XML content' ) +insert ( 321 1255 0 'I/O' ) +insert ( 322 1255 0 'I/O' ) +insert ( 323 1255 0 'I/O' ) +insert ( 324 1255 0 'I/O' ) +insert ( 3153 1255 0 'map array to json' ) +insert ( 3154 1255 0 'map array to json with optional pretty printing' ) +insert ( 3155 1255 0 'map row to json' ) +insert ( 3156 1255 0 'map row to json with optional pretty printing' ) +insert ( 3173 1255 0 'json aggregate transition function' ) +insert ( 6275 1255 0 'json aggregate transition function' ) +insert ( 3174 1255 0 'json aggregate final function' ) +insert ( 3175 1255 0 'aggregate input into json' ) +insert ( 6276 1255 0 'aggregate input into json' ) +insert ( 3180 1255 0 'json object aggregate transition function' ) +insert ( 6277 1255 0 'json object aggregate transition function' ) +insert ( 6278 1255 0 'json object aggregate transition function' ) +insert ( 6279 1255 0 'json object aggregate transition function' ) +insert ( 3196 1255 0 'json object aggregate final function' ) +insert ( 3197 1255 0 'aggregate input into a json object' ) +insert ( 6280 1255 0 'aggregate non-NULL input into a json object' ) +insert ( 6281 1255 0 'aggregate input into a json object with unique keys' ) +insert ( 6282 1255 0 'aggregate non-NULL input into a json object with unique keys' ) +insert ( 3198 1255 0 'build a json array from any inputs' ) +insert ( 3199 1255 0 'build an empty json array' ) +insert ( 3200 1255 0 'build a json object from pairwise key/value inputs' ) +insert ( 3201 1255 0 'build an empty json object' ) +insert ( 3202 1255 0 'map text array of key value pairs to json object' ) +insert ( 3203 1255 0 'map text arrays of keys and values to json object' ) +insert ( 3176 1255 0 'map input to json' ) +insert ( 3261 1255 0 'remove object fields with null values from json' ) +insert ( 3951 1255 0 'get value from json with path elements' ) +insert ( 3953 1255 0 'get value from json as text with path elements' ) +insert ( 3955 1255 0 'key value pairs of a json object' ) +insert ( 3969 1255 0 'elements of json array' ) +insert ( 3956 1255 0 'length of json array' ) +insert ( 3957 1255 0 'get json object keys' ) +insert ( 3958 1255 0 'key value pairs of a json object' ) +insert ( 3959 1255 0 'key value pairs of a json object' ) +insert ( 3960 1255 0 'get record fields from a json object' ) +insert ( 3961 1255 0 'get set of records with fields from a json array of objects' ) +insert ( 3204 1255 0 'get record fields from a json object' ) +insert ( 3205 1255 0 'get set of records with fields from a json array of objects' ) +insert ( 3968 1255 0 'get the type of a json value' ) +insert ( 2952 1255 0 'I/O' ) +insert ( 2953 1255 0 'I/O' ) +insert ( 2960 1255 0 less-equal-greater ) +insert ( 3300 1255 0 'sort support' ) +insert ( 2961 1255 0 'I/O' ) +insert ( 2962 1255 0 'I/O' ) +insert ( 2963 1255 0 hash ) +insert ( 3412 1255 0 hash ) +insert ( 3432 1255 0 'generate random UUID' ) +insert ( 3229 1255 0 'I/O' ) +insert ( 3230 1255 0 'I/O' ) +insert ( 3238 1255 0 'I/O' ) +insert ( 3239 1255 0 'I/O' ) +insert ( 3251 1255 0 less-equal-greater ) +insert ( 3252 1255 0 hash ) +insert ( 3413 1255 0 hash ) +insert ( 4187 1255 0 'larger of two' ) +insert ( 4188 1255 0 'smaller of two' ) +insert ( 3504 1255 0 'I/O' ) +insert ( 3505 1255 0 'I/O' ) +insert ( 3506 1255 0 'I/O' ) +insert ( 3507 1255 0 'I/O' ) +insert ( 3514 1255 0 less-equal-greater ) +insert ( 3515 1255 0 hash ) +insert ( 3414 1255 0 hash ) +insert ( 3524 1255 0 'smaller of two' ) +insert ( 3525 1255 0 'larger of two' ) +insert ( 3526 1255 0 'maximum value of all enum input values' ) +insert ( 3527 1255 0 'minimum value of all enum input values' ) +insert ( 3528 1255 0 'first value of the input enum type' ) +insert ( 3529 1255 0 'last value of the input enum type' ) +insert ( 3530 1255 0 'range between the two given enum values, as an ordered array' ) +insert ( 3531 1255 0 'range of the given enum type, as an ordered array' ) +insert ( 3532 1255 0 'I/O' ) +insert ( 3533 1255 0 'I/O' ) +insert ( 3610 1255 0 'I/O' ) +insert ( 3639 1255 0 'I/O' ) +insert ( 3611 1255 0 'I/O' ) +insert ( 3638 1255 0 'I/O' ) +insert ( 3612 1255 0 'I/O' ) +insert ( 3641 1255 0 'I/O' ) +insert ( 3613 1255 0 'I/O' ) +insert ( 3640 1255 0 'I/O' ) +insert ( 3646 1255 0 'I/O' ) +insert ( 3647 1255 0 'I/O' ) +insert ( 3622 1255 0 less-equal-greater ) +insert ( 3711 1255 0 'number of lexemes' ) +insert ( 3623 1255 0 'strip position information' ) +insert ( 3624 1255 0 'set given weight for whole tsvector' ) +insert ( 3320 1255 0 'set given weight for given lexemes' ) +insert ( 3321 1255 0 'delete lexeme' ) +insert ( 3323 1255 0 'delete given lexemes' ) +insert ( 3322 1255 0 'expand tsvector to set of rows' ) +insert ( 3326 1255 0 'convert tsvector to array of lexemes' ) +insert ( 3327 1255 0 'build tsvector from array of lexemes' ) +insert ( 3319 1255 0 'delete lexemes that do not have one of the given weights' ) +insert ( 3648 1255 0 'GiST tsvector support' ) +insert ( 3649 1255 0 'GiST tsvector support' ) +insert ( 3650 1255 0 'GiST tsvector support' ) +insert ( 3651 1255 0 'GiST tsvector support' ) +insert ( 3652 1255 0 'GiST tsvector support' ) +insert ( 3653 1255 0 'GiST tsvector support' ) +insert ( 3654 1255 0 'GiST tsvector support' ) +insert ( 3790 1255 0 'GiST tsvector support (obsolete)' ) +insert ( 3434 1255 0 'GiST tsvector support' ) +insert ( 3656 1255 0 'GIN tsvector support' ) +insert ( 3657 1255 0 'GIN tsvector support' ) +insert ( 3658 1255 0 'GIN tsvector support' ) +insert ( 3921 1255 0 'GIN tsvector support' ) +insert ( 3724 1255 0 'GIN tsvector support' ) +insert ( 2700 1255 0 'GIN tsvector support' ) +insert ( 3077 1255 0 'GIN tsvector support (obsolete)' ) +insert ( 3087 1255 0 'GIN tsvector support (obsolete)' ) +insert ( 3088 1255 0 'GIN tsvector support (obsolete)' ) +insert ( 3791 1255 0 'GIN tsvector support (obsolete)' ) +insert ( 3792 1255 0 'GIN tsvector support (obsolete)' ) +insert ( 3789 1255 0 'clean up GIN pending list' ) +insert ( 3668 1255 0 less-equal-greater ) +insert ( 5004 1255 0 'phrase-concatenate with distance' ) +insert ( 3672 1255 0 'number of nodes' ) +insert ( 3673 1255 0 'show real useful query for GiST index' ) +insert ( 3684 1255 0 'rewrite tsquery' ) +insert ( 3685 1255 0 'rewrite tsquery' ) +insert ( 3695 1255 0 'GiST tsquery support' ) +insert ( 3697 1255 0 'GiST tsquery support' ) +insert ( 3698 1255 0 'GiST tsquery support' ) +insert ( 3699 1255 0 'GiST tsquery support' ) +insert ( 3700 1255 0 'GiST tsquery support' ) +insert ( 3701 1255 0 'GiST tsquery support' ) +insert ( 3793 1255 0 'GiST tsquery support (obsolete)' ) +insert ( 3686 1255 0 'restriction selectivity of tsvector @@ tsquery' ) +insert ( 3687 1255 0 'join selectivity of tsvector @@ tsquery' ) +insert ( 3688 1255 0 'tsvector typanalyze' ) +insert ( 3689 1255 0 'statistics of tsvector column' ) +insert ( 3690 1255 0 'statistics of tsvector column' ) +insert ( 3703 1255 0 relevance ) +insert ( 3704 1255 0 relevance ) +insert ( 3705 1255 0 relevance ) +insert ( 3706 1255 0 relevance ) +insert ( 3707 1255 0 relevance ) +insert ( 3708 1255 0 relevance ) +insert ( 3709 1255 0 relevance ) +insert ( 3710 1255 0 relevance ) +insert ( 3713 1255 0 'get parser''s token types' ) +insert ( 3714 1255 0 'get parser''s token types' ) +insert ( 3715 1255 0 'parse text to tokens' ) +insert ( 3716 1255 0 'parse text to tokens' ) +insert ( 3717 1255 0 '(internal)' ) +insert ( 3718 1255 0 '(internal)' ) +insert ( 3719 1255 0 '(internal)' ) +insert ( 3720 1255 0 '(internal)' ) +insert ( 3721 1255 0 '(internal)' ) +insert ( 3723 1255 0 'normalize one word by dictionary' ) +insert ( 6183 1255 0 'debug function for text search configuration' ) +insert ( 6184 1255 0 'debug function for current text search configuration' ) +insert ( 3725 1255 0 '(internal)' ) +insert ( 3726 1255 0 '(internal)' ) +insert ( 3728 1255 0 '(internal)' ) +insert ( 3729 1255 0 '(internal)' ) +insert ( 3731 1255 0 '(internal)' ) +insert ( 3732 1255 0 '(internal)' ) +insert ( 3740 1255 0 '(internal)' ) +insert ( 3741 1255 0 '(internal)' ) +insert ( 3743 1255 0 'generate headline' ) +insert ( 3744 1255 0 'generate headline' ) +insert ( 3754 1255 0 'generate headline' ) +insert ( 3755 1255 0 'generate headline' ) +insert ( 4201 1255 0 'generate headline from jsonb' ) +insert ( 4202 1255 0 'generate headline from jsonb' ) +insert ( 4203 1255 0 'generate headline from jsonb' ) +insert ( 4204 1255 0 'generate headline from jsonb' ) +insert ( 4205 1255 0 'generate headline from json' ) +insert ( 4206 1255 0 'generate headline from json' ) +insert ( 4207 1255 0 'generate headline from json' ) +insert ( 4208 1255 0 'generate headline from json' ) +insert ( 3745 1255 0 'transform to tsvector' ) +insert ( 3746 1255 0 'make tsquery' ) +insert ( 3747 1255 0 'transform to tsquery' ) +insert ( 5006 1255 0 'transform to tsquery' ) +insert ( 5007 1255 0 'transform to tsquery' ) +insert ( 3749 1255 0 'transform to tsvector' ) +insert ( 3750 1255 0 'make tsquery' ) +insert ( 3751 1255 0 'transform to tsquery' ) +insert ( 5001 1255 0 'transform to tsquery' ) +insert ( 5009 1255 0 'transform to tsquery' ) +insert ( 4209 1255 0 'transform string values from jsonb to tsvector' ) +insert ( 4213 1255 0 'transform specified values from jsonb to tsvector' ) +insert ( 4210 1255 0 'transform string values from json to tsvector' ) +insert ( 4215 1255 0 'transform specified values from json to tsvector' ) +insert ( 4211 1255 0 'transform string values from jsonb to tsvector' ) +insert ( 4214 1255 0 'transform specified values from jsonb to tsvector' ) +insert ( 4212 1255 0 'transform string values from json to tsvector' ) +insert ( 4216 1255 0 'transform specified values from json to tsvector' ) +insert ( 3752 1255 0 'trigger for automatic update of tsvector column' ) +insert ( 3753 1255 0 'trigger for automatic update of tsvector column' ) +insert ( 3759 1255 0 'get current tsearch configuration' ) +insert ( 3736 1255 0 'I/O' ) +insert ( 3737 1255 0 'I/O' ) +insert ( 3738 1255 0 'I/O' ) +insert ( 3739 1255 0 'I/O' ) +insert ( 3771 1255 0 'I/O' ) +insert ( 3772 1255 0 'I/O' ) +insert ( 3773 1255 0 'I/O' ) +insert ( 3774 1255 0 'I/O' ) +insert ( 3806 1255 0 'I/O' ) +insert ( 3805 1255 0 'I/O' ) +insert ( 3804 1255 0 'I/O' ) +insert ( 3803 1255 0 'I/O' ) +insert ( 3263 1255 0 'map text array of key value pairs to jsonb object' ) +insert ( 3264 1255 0 'map text array of key value pairs to jsonb object' ) +insert ( 3787 1255 0 'map input to jsonb' ) +insert ( 3265 1255 0 'jsonb aggregate transition function' ) +insert ( 6283 1255 0 'jsonb aggregate transition function' ) +insert ( 3266 1255 0 'jsonb aggregate final function' ) +insert ( 3267 1255 0 'aggregate input into jsonb' ) +insert ( 6284 1255 0 'aggregate input into jsonb skipping nulls' ) +insert ( 3268 1255 0 'jsonb object aggregate transition function' ) +insert ( 6285 1255 0 'jsonb object aggregate transition function' ) +insert ( 6286 1255 0 'jsonb object aggregate transition function' ) +insert ( 6287 1255 0 'jsonb object aggregate transition function' ) +insert ( 3269 1255 0 'jsonb object aggregate final function' ) +insert ( 3270 1255 0 'aggregate inputs into jsonb object' ) +insert ( 6288 1255 0 'aggregate non-NULL inputs into jsonb object' ) +insert ( 6289 1255 0 'aggregate inputs into jsonb object checking key uniqueness' ) +insert ( 6290 1255 0 'aggregate non-NULL inputs into jsonb object checking key uniqueness' ) +insert ( 3271 1255 0 'build a jsonb array from any inputs' ) +insert ( 3272 1255 0 'build an empty jsonb array' ) +insert ( 3273 1255 0 'build a jsonb object from pairwise key/value inputs' ) +insert ( 3274 1255 0 'build an empty jsonb object' ) +insert ( 3262 1255 0 'remove object fields with null values from jsonb' ) +insert ( 3217 1255 0 'get value from jsonb with path elements' ) +insert ( 3940 1255 0 'get value from jsonb as text with path elements' ) +insert ( 3219 1255 0 'elements of a jsonb array' ) +insert ( 3465 1255 0 'elements of jsonb array' ) +insert ( 3207 1255 0 'length of jsonb array' ) +insert ( 3931 1255 0 'get jsonb object keys' ) +insert ( 3208 1255 0 'key value pairs of a jsonb object' ) +insert ( 3932 1255 0 'key value pairs of a jsonb object' ) +insert ( 3209 1255 0 'get record fields from a jsonb object' ) +insert ( 3475 1255 0 'get set of records with fields from a jsonb array of objects' ) +insert ( 3490 1255 0 'get record fields from a jsonb object' ) +insert ( 3491 1255 0 'get set of records with fields from a jsonb array of objects' ) +insert ( 3210 1255 0 'get the type of a jsonb value' ) +insert ( 4044 1255 0 less-equal-greater ) +insert ( 4045 1255 0 hash ) +insert ( 3416 1255 0 hash ) +insert ( 3480 1255 0 'GIN support' ) +insert ( 3482 1255 0 'GIN support' ) +insert ( 3483 1255 0 'GIN support' ) +insert ( 3484 1255 0 'GIN support' ) +insert ( 3488 1255 0 'GIN support' ) +insert ( 3485 1255 0 'GIN support' ) +insert ( 3486 1255 0 'GIN support' ) +insert ( 3487 1255 0 'GIN support' ) +insert ( 3489 1255 0 'GIN support' ) +insert ( 5054 1255 0 'Set part of a jsonb, handle NULL value' ) +insert ( 3305 1255 0 'Set part of a jsonb' ) +insert ( 3306 1255 0 'Indented text from jsonb' ) +insert ( 3579 1255 0 'Insert value into a jsonb' ) +insert ( 4001 1255 0 'I/O' ) +insert ( 4002 1255 0 'I/O' ) +insert ( 4003 1255 0 'I/O' ) +insert ( 4004 1255 0 'I/O' ) +insert ( 4005 1255 0 'jsonpath exists test' ) +insert ( 4006 1255 0 'jsonpath query' ) +insert ( 4007 1255 0 'jsonpath query wrapped into array' ) +insert ( 4008 1255 0 'jsonpath query first item' ) +insert ( 4009 1255 0 'jsonpath match' ) +insert ( 1177 1255 0 'jsonpath exists test with timezone' ) +insert ( 1179 1255 0 'jsonpath query with timezone' ) +insert ( 1180 1255 0 'jsonpath query wrapped into array with timezone' ) +insert ( 2023 1255 0 'jsonpath query first item with timezone' ) +insert ( 2030 1255 0 'jsonpath match with timezone' ) +insert ( 4010 1255 0 'implementation of @? operator' ) +insert ( 4011 1255 0 'implementation of @@ operator' ) +insert ( 2939 1255 0 'I/O' ) +insert ( 2940 1255 0 'I/O' ) +insert ( 2941 1255 0 'I/O' ) +insert ( 2942 1255 0 'I/O' ) +insert ( 2943 1255 0 'get current transaction ID' ) +insert ( 3348 1255 0 'get current transaction ID' ) +insert ( 2944 1255 0 'get current snapshot' ) +insert ( 2945 1255 0 'get xmin of snapshot' ) +insert ( 2946 1255 0 'get xmax of snapshot' ) +insert ( 2947 1255 0 'get set of in-progress txids in snapshot' ) +insert ( 2948 1255 0 'is txid visible in snapshot?' ) +insert ( 3360 1255 0 'commit status of transaction' ) +insert ( 5055 1255 0 'I/O' ) +insert ( 5056 1255 0 'I/O' ) +insert ( 5057 1255 0 'I/O' ) +insert ( 5058 1255 0 'I/O' ) +insert ( 5061 1255 0 'get current snapshot' ) +insert ( 5062 1255 0 'get xmin of snapshot' ) +insert ( 5063 1255 0 'get xmax of snapshot' ) +insert ( 5064 1255 0 'get set of in-progress transactions in snapshot' ) +insert ( 5065 1255 0 'is xid8 visible in snapshot?' ) +insert ( 5059 1255 0 'get current transaction ID' ) +insert ( 5060 1255 0 'get current transaction ID' ) +insert ( 5066 1255 0 'commit status of transaction' ) +insert ( 2987 1255 0 less-equal-greater ) +insert ( 6192 1255 0 hash ) +insert ( 6193 1255 0 hash ) +insert ( 3187 1255 0 'less-equal-greater based on byte images' ) +insert ( 5051 1255 0 'equal image' ) +insert ( 3082 1255 0 'list available extensions' ) +insert ( 3083 1255 0 'list available extension versions' ) +insert ( 3084 1255 0 'list an extension''s version update paths' ) +insert ( 3086 1255 0 'flag an extension''s table contents to be emitted by pg_dump' ) +insert ( 3100 1255 0 'row number within partition' ) +insert ( 6233 1255 0 'planner support for row_number' ) +insert ( 3101 1255 0 'integer rank with gaps' ) +insert ( 6234 1255 0 'planner support for rank' ) +insert ( 3102 1255 0 'integer rank without gaps' ) +insert ( 6235 1255 0 'planner support for dense_rank' ) +insert ( 3103 1255 0 'fractional rank within partition' ) +insert ( 6306 1255 0 'planner support for percent_rank' ) +insert ( 3104 1255 0 'fractional row number within partition' ) +insert ( 6307 1255 0 'planner support for cume_dist' ) +insert ( 3105 1255 0 'split rows into N groups' ) +insert ( 6308 1255 0 'planner support for ntile' ) +insert ( 3106 1255 0 'fetch the preceding row value' ) +insert ( 3107 1255 0 'fetch the Nth preceding row value' ) +insert ( 3108 1255 0 'fetch the Nth preceding row value with default' ) +insert ( 3109 1255 0 'fetch the following row value' ) +insert ( 3110 1255 0 'fetch the Nth following row value' ) +insert ( 3111 1255 0 'fetch the Nth following row value with default' ) +insert ( 3112 1255 0 'fetch the first row value' ) +insert ( 3113 1255 0 'fetch the last row value' ) +insert ( 3114 1255 0 'fetch the Nth row value' ) +insert ( 3832 1255 0 'I/O' ) +insert ( 3833 1255 0 'I/O' ) +insert ( 3834 1255 0 'I/O' ) +insert ( 3835 1255 0 'I/O' ) +insert ( 3836 1255 0 'I/O' ) +insert ( 3837 1255 0 'I/O' ) +insert ( 3848 1255 0 'lower bound of range' ) +insert ( 3849 1255 0 'upper bound of range' ) +insert ( 3850 1255 0 'is the range empty?' ) +insert ( 3851 1255 0 'is the range''s lower bound inclusive?' ) +insert ( 3852 1255 0 'is the range''s upper bound inclusive?' ) +insert ( 3853 1255 0 'is the range''s lower bound infinite?' ) +insert ( 3854 1255 0 'is the range''s upper bound infinite?' ) +insert ( 4057 1255 0 'the smallest range which includes both of the given ranges' ) +insert ( 4228 1255 0 'the smallest range which includes the whole multirange' ) +insert ( 3870 1255 0 less-equal-greater ) +insert ( 3875 1255 0 'GiST support' ) +insert ( 3876 1255 0 'GiST support' ) +insert ( 3879 1255 0 'GiST support' ) +insert ( 3880 1255 0 'GiST support' ) +insert ( 3881 1255 0 'GiST support' ) +insert ( 6154 1255 0 'GiST support' ) +insert ( 6156 1255 0 'GiST support' ) +insert ( 3902 1255 0 'hash a range' ) +insert ( 3417 1255 0 'hash a range' ) +insert ( 3916 1255 0 'range typanalyze' ) +insert ( 3169 1255 0 'restriction selectivity for range operators' ) +insert ( 4401 1255 0 'range aggregate by intersecting' ) +insert ( 4450 1255 0 'range aggregate by intersecting' ) +insert ( 3914 1255 0 'convert an int4 range to canonical form' ) +insert ( 3928 1255 0 'convert an int8 range to canonical form' ) +insert ( 3915 1255 0 'convert a date range to canonical form' ) +insert ( 3922 1255 0 'float8 difference of two int4 values' ) +insert ( 3923 1255 0 'float8 difference of two int8 values' ) +insert ( 3924 1255 0 'float8 difference of two numeric values' ) +insert ( 3925 1255 0 'float8 difference of two date values' ) +insert ( 3929 1255 0 'float8 difference of two timestamp values' ) +insert ( 3930 1255 0 'float8 difference of two timestamp with time zone values' ) +insert ( 3840 1255 0 'int4range constructor' ) +insert ( 3841 1255 0 'int4range constructor' ) +insert ( 3844 1255 0 'numrange constructor' ) +insert ( 3845 1255 0 'numrange constructor' ) +insert ( 3933 1255 0 'tsrange constructor' ) +insert ( 3934 1255 0 'tsrange constructor' ) +insert ( 3937 1255 0 'tstzrange constructor' ) +insert ( 3938 1255 0 'tstzrange constructor' ) +insert ( 3941 1255 0 'daterange constructor' ) +insert ( 3942 1255 0 'daterange constructor' ) +insert ( 3945 1255 0 'int8range constructor' ) +insert ( 3946 1255 0 'int8range constructor' ) +insert ( 4229 1255 0 'I/O' ) +insert ( 4230 1255 0 'I/O' ) +insert ( 4231 1255 0 'I/O' ) +insert ( 4232 1255 0 'I/O' ) +insert ( 4233 1255 0 'I/O' ) +insert ( 4234 1255 0 'I/O' ) +insert ( 4235 1255 0 'lower bound of multirange' ) +insert ( 4236 1255 0 'upper bound of multirange' ) +insert ( 4237 1255 0 'is the multirange empty?' ) +insert ( 4238 1255 0 'is the multirange''s lower bound inclusive?' ) +insert ( 4239 1255 0 'is the multirange''s upper bound inclusive?' ) +insert ( 4240 1255 0 'is the multirange''s lower bound infinite?' ) +insert ( 4241 1255 0 'is the multirange''s upper bound infinite?' ) +insert ( 4242 1255 0 'multirange typanalyze' ) +insert ( 4243 1255 0 'restriction selectivity for multirange operators' ) +insert ( 4273 1255 0 less-equal-greater ) +insert ( 4278 1255 0 'hash a multirange' ) +insert ( 4279 1255 0 'hash a multirange' ) +insert ( 4280 1255 0 'int4multirange constructor' ) +insert ( 4281 1255 0 'int4multirange constructor' ) +insert ( 4282 1255 0 'int4multirange constructor' ) +insert ( 4283 1255 0 'nummultirange constructor' ) +insert ( 4284 1255 0 'nummultirange constructor' ) +insert ( 4285 1255 0 'nummultirange constructor' ) +insert ( 4286 1255 0 'tsmultirange constructor' ) +insert ( 4287 1255 0 'tsmultirange constructor' ) +insert ( 4288 1255 0 'tsmultirange constructor' ) +insert ( 4289 1255 0 'tstzmultirange constructor' ) +insert ( 4290 1255 0 'tstzmultirange constructor' ) +insert ( 4291 1255 0 'tstzmultirange constructor' ) +insert ( 4292 1255 0 'datemultirange constructor' ) +insert ( 4293 1255 0 'datemultirange constructor' ) +insert ( 4294 1255 0 'datemultirange constructor' ) +insert ( 4295 1255 0 'int8multirange constructor' ) +insert ( 4296 1255 0 'int8multirange constructor' ) +insert ( 4297 1255 0 'int8multirange constructor' ) +insert ( 4298 1255 0 'anymultirange cast' ) +insert ( 4299 1255 0 'aggregate transition function' ) +insert ( 4300 1255 0 'aggregate final function' ) +insert ( 4301 1255 0 'combine aggregate input into a multirange' ) +insert ( 6225 1255 0 'aggregate transition function' ) +insert ( 6226 1255 0 'aggregate final function' ) +insert ( 6227 1255 0 'combine aggregate input into a multirange' ) +insert ( 4388 1255 0 'range aggregate by intersecting' ) +insert ( 4389 1255 0 'range aggregate by intersecting' ) +insert ( 1293 1255 0 'expand multirange to set of ranges' ) +insert ( 3846 1255 0 'construct date' ) +insert ( 3847 1255 0 'construct time' ) +insert ( 3461 1255 0 'construct timestamp' ) +insert ( 3462 1255 0 'construct timestamp with time zone' ) +insert ( 3463 1255 0 'construct timestamp with time zone' ) +insert ( 3464 1255 0 'construct interval' ) +insert ( 4018 1255 0 'SP-GiST support for quad tree over point' ) +insert ( 4019 1255 0 'SP-GiST support for quad tree over point' ) +insert ( 4020 1255 0 'SP-GiST support for quad tree over point' ) +insert ( 4021 1255 0 'SP-GiST support for quad tree over point' ) +insert ( 4022 1255 0 'SP-GiST support for quad tree and k-d tree over point' ) +insert ( 4023 1255 0 'SP-GiST support for k-d tree over point' ) +insert ( 4024 1255 0 'SP-GiST support for k-d tree over point' ) +insert ( 4025 1255 0 'SP-GiST support for k-d tree over point' ) +insert ( 4026 1255 0 'SP-GiST support for k-d tree over point' ) +insert ( 4027 1255 0 'SP-GiST support for radix tree over text' ) +insert ( 4028 1255 0 'SP-GiST support for radix tree over text' ) +insert ( 4029 1255 0 'SP-GiST support for radix tree over text' ) +insert ( 4030 1255 0 'SP-GiST support for radix tree over text' ) +insert ( 4031 1255 0 'SP-GiST support for radix tree over text' ) +insert ( 3469 1255 0 'SP-GiST support for quad tree over range' ) +insert ( 3470 1255 0 'SP-GiST support for quad tree over range' ) +insert ( 3471 1255 0 'SP-GiST support for quad tree over range' ) +insert ( 3472 1255 0 'SP-GiST support for quad tree over range' ) +insert ( 3473 1255 0 'SP-GiST support for quad tree over range' ) +insert ( 5012 1255 0 'SP-GiST support for quad tree over box' ) +insert ( 5013 1255 0 'SP-GiST support for quad tree over box' ) +insert ( 5014 1255 0 'SP-GiST support for quad tree over box' ) +insert ( 5015 1255 0 'SP-GiST support for quad tree over box' ) +insert ( 5016 1255 0 'SP-GiST support for quad tree over box' ) +insert ( 5010 1255 0 'SP-GiST support for quad tree over 2-D types represented by their bounding boxes' ) +insert ( 5011 1255 0 'SP-GiST support for quad tree over polygons' ) +insert ( 3779 1255 0 'create a physical replication slot' ) +insert ( 4220 1255 0 'copy a physical replication slot, changing temporality' ) +insert ( 4221 1255 0 'copy a physical replication slot' ) +insert ( 3780 1255 0 'drop a replication slot' ) +insert ( 3781 1255 0 'information about replication slots currently in use' ) +insert ( 3786 1255 0 'set up a logical replication slot' ) +insert ( 4222 1255 0 'copy a logical replication slot, changing temporality and plugin' ) +insert ( 4223 1255 0 'copy a logical replication slot, changing temporality' ) +insert ( 4224 1255 0 'copy a logical replication slot' ) +insert ( 3782 1255 0 'get changes from replication slot' ) +insert ( 3783 1255 0 'get binary changes from replication slot' ) +insert ( 3784 1255 0 'peek at changes from replication slot' ) +insert ( 3785 1255 0 'peek at binary changes from replication slot' ) +insert ( 3878 1255 0 'advance logical replication slot' ) +insert ( 3577 1255 0 'emit a textual logical decoding message' ) +insert ( 3578 1255 0 'emit a binary logical decoding message' ) +insert ( 3566 1255 0 'list objects dropped by the current command' ) +insert ( 4566 1255 0 'return Oid of the table getting rewritten' ) +insert ( 4567 1255 0 'return reason code for table getting rewritten' ) +insert ( 4568 1255 0 'list DDL actions being executed by the current command' ) +insert ( 3970 1255 0 'aggregate transition function' ) +insert ( 3971 1255 0 'aggregate transition function' ) +insert ( 3972 1255 0 'discrete percentile' ) +insert ( 3973 1255 0 'aggregate final function' ) +insert ( 3974 1255 0 'continuous distribution percentile' ) +insert ( 3975 1255 0 'aggregate final function' ) +insert ( 3976 1255 0 'continuous distribution percentile' ) +insert ( 3977 1255 0 'aggregate final function' ) +insert ( 3978 1255 0 'multiple discrete percentiles' ) +insert ( 3979 1255 0 'aggregate final function' ) +insert ( 3980 1255 0 'multiple continuous percentiles' ) +insert ( 3981 1255 0 'aggregate final function' ) +insert ( 3982 1255 0 'multiple continuous percentiles' ) +insert ( 3983 1255 0 'aggregate final function' ) +insert ( 3984 1255 0 'most common value' ) +insert ( 3985 1255 0 'aggregate final function' ) +insert ( 3986 1255 0 'rank of hypothetical row' ) +insert ( 3987 1255 0 'aggregate final function' ) +insert ( 3988 1255 0 'fractional rank of hypothetical row' ) +insert ( 3989 1255 0 'aggregate final function' ) +insert ( 3990 1255 0 'cumulative distribution of hypothetical row' ) +insert ( 3991 1255 0 'aggregate final function' ) +insert ( 3992 1255 0 'rank of hypothetical row without gaps' ) +insert ( 3993 1255 0 'aggregate final function' ) +insert ( 3582 1255 0 'for use by pg_upgrade' ) +insert ( 3584 1255 0 'for use by pg_upgrade' ) +insert ( 4390 1255 0 'for use by pg_upgrade' ) +insert ( 4391 1255 0 'for use by pg_upgrade' ) +insert ( 3586 1255 0 'for use by pg_upgrade' ) +insert ( 3587 1255 0 'for use by pg_upgrade' ) +insert ( 3588 1255 0 'for use by pg_upgrade' ) +insert ( 3589 1255 0 'for use by pg_upgrade' ) +insert ( 3590 1255 0 'for use by pg_upgrade' ) +insert ( 3591 1255 0 'for use by pg_upgrade' ) +insert ( 4083 1255 0 'for use by pg_upgrade' ) +insert ( 4101 1255 0 'for use by pg_upgrade' ) +insert ( 4545 1255 0 'for use by pg_upgrade' ) +insert ( 4546 1255 0 'for use by pg_upgrade' ) +insert ( 4547 1255 0 'for use by pg_upgrade' ) +insert ( 4548 1255 0 'for use by pg_upgrade' ) +insert ( 4302 1255 0 'internal conversion function for KOI8R to MULE_INTERNAL' ) +insert ( 4303 1255 0 'internal conversion function for MULE_INTERNAL to KOI8R' ) +insert ( 4304 1255 0 'internal conversion function for ISO-8859-5 to MULE_INTERNAL' ) +insert ( 4305 1255 0 'internal conversion function for MULE_INTERNAL to ISO-8859-5' ) +insert ( 4306 1255 0 'internal conversion function for WIN1251 to MULE_INTERNAL' ) +insert ( 4307 1255 0 'internal conversion function for MULE_INTERNAL to WIN1251' ) +insert ( 4308 1255 0 'internal conversion function for WIN866 to MULE_INTERNAL' ) +insert ( 4309 1255 0 'internal conversion function for MULE_INTERNAL to WIN866' ) +insert ( 4310 1255 0 'internal conversion function for KOI8R to WIN1251' ) +insert ( 4311 1255 0 'internal conversion function for WIN1251 to KOI8R' ) +insert ( 4312 1255 0 'internal conversion function for KOI8R to WIN866' ) +insert ( 4313 1255 0 'internal conversion function for WIN866 to KOI8R' ) +insert ( 4314 1255 0 'internal conversion function for WIN866 to WIN1251' ) +insert ( 4315 1255 0 'internal conversion function for WIN1251 to WIN866' ) +insert ( 4316 1255 0 'internal conversion function for ISO-8859-5 to KOI8R' ) +insert ( 4317 1255 0 'internal conversion function for KOI8R to ISO-8859-5' ) +insert ( 4318 1255 0 'internal conversion function for ISO-8859-5 to WIN1251' ) +insert ( 4319 1255 0 'internal conversion function for WIN1251 to ISO-8859-5' ) +insert ( 4320 1255 0 'internal conversion function for ISO-8859-5 to WIN866' ) +insert ( 4321 1255 0 'internal conversion function for WIN866 to ISO-8859-5' ) +insert ( 4322 1255 0 'internal conversion function for EUC_CN to MULE_INTERNAL' ) +insert ( 4323 1255 0 'internal conversion function for MULE_INTERNAL to EUC_CN' ) +insert ( 4324 1255 0 'internal conversion function for EUC_JP to SJIS' ) +insert ( 4325 1255 0 'internal conversion function for SJIS to EUC_JP' ) +insert ( 4326 1255 0 'internal conversion function for EUC_JP to MULE_INTERNAL' ) +insert ( 4327 1255 0 'internal conversion function for SJIS to MULE_INTERNAL' ) +insert ( 4328 1255 0 'internal conversion function for MULE_INTERNAL to EUC_JP' ) +insert ( 4329 1255 0 'internal conversion function for MULE_INTERNAL to SJIS' ) +insert ( 4330 1255 0 'internal conversion function for EUC_KR to MULE_INTERNAL' ) +insert ( 4331 1255 0 'internal conversion function for MULE_INTERNAL to EUC_KR' ) +insert ( 4332 1255 0 'internal conversion function for EUC_TW to BIG5' ) +insert ( 4333 1255 0 'internal conversion function for BIG5 to EUC_TW' ) +insert ( 4334 1255 0 'internal conversion function for EUC_TW to MULE_INTERNAL' ) +insert ( 4335 1255 0 'internal conversion function for BIG5 to MULE_INTERNAL' ) +insert ( 4336 1255 0 'internal conversion function for MULE_INTERNAL to EUC_TW' ) +insert ( 4337 1255 0 'internal conversion function for MULE_INTERNAL to BIG5' ) +insert ( 4338 1255 0 'internal conversion function for LATIN2 to MULE_INTERNAL' ) +insert ( 4339 1255 0 'internal conversion function for MULE_INTERNAL to LATIN2' ) +insert ( 4340 1255 0 'internal conversion function for WIN1250 to MULE_INTERNAL' ) +insert ( 4341 1255 0 'internal conversion function for MULE_INTERNAL to WIN1250' ) +insert ( 4342 1255 0 'internal conversion function for LATIN2 to WIN1250' ) +insert ( 4343 1255 0 'internal conversion function for WIN1250 to LATIN2' ) +insert ( 4344 1255 0 'internal conversion function for LATIN1 to MULE_INTERNAL' ) +insert ( 4345 1255 0 'internal conversion function for MULE_INTERNAL to LATIN1' ) +insert ( 4346 1255 0 'internal conversion function for LATIN3 to MULE_INTERNAL' ) +insert ( 4347 1255 0 'internal conversion function for MULE_INTERNAL to LATIN3' ) +insert ( 4348 1255 0 'internal conversion function for LATIN4 to MULE_INTERNAL' ) +insert ( 4349 1255 0 'internal conversion function for MULE_INTERNAL to LATIN4' ) +insert ( 4352 1255 0 'internal conversion function for BIG5 to UTF8' ) +insert ( 4353 1255 0 'internal conversion function for UTF8 to BIG5' ) +insert ( 4354 1255 0 'internal conversion function for UTF8 to KOI8R' ) +insert ( 4355 1255 0 'internal conversion function for KOI8R to UTF8' ) +insert ( 4356 1255 0 'internal conversion function for UTF8 to KOI8U' ) +insert ( 4357 1255 0 'internal conversion function for KOI8U to UTF8' ) +insert ( 4358 1255 0 'internal conversion function for UTF8 to WIN' ) +insert ( 4359 1255 0 'internal conversion function for WIN to UTF8' ) +insert ( 4360 1255 0 'internal conversion function for EUC_CN to UTF8' ) +insert ( 4361 1255 0 'internal conversion function for UTF8 to EUC_CN' ) +insert ( 4362 1255 0 'internal conversion function for EUC_JP to UTF8' ) +insert ( 4363 1255 0 'internal conversion function for UTF8 to EUC_JP' ) +insert ( 4364 1255 0 'internal conversion function for EUC_KR to UTF8' ) +insert ( 4365 1255 0 'internal conversion function for UTF8 to EUC_KR' ) +insert ( 4366 1255 0 'internal conversion function for EUC_TW to UTF8' ) +insert ( 4367 1255 0 'internal conversion function for UTF8 to EUC_TW' ) +insert ( 4368 1255 0 'internal conversion function for GB18030 to UTF8' ) +insert ( 4369 1255 0 'internal conversion function for UTF8 to GB18030' ) +insert ( 4370 1255 0 'internal conversion function for GBK to UTF8' ) +insert ( 4371 1255 0 'internal conversion function for UTF8 to GBK' ) +insert ( 4372 1255 0 'internal conversion function for UTF8 to ISO-8859 2-16' ) +insert ( 4373 1255 0 'internal conversion function for ISO-8859 2-16 to UTF8' ) +insert ( 4374 1255 0 'internal conversion function for LATIN1 to UTF8' ) +insert ( 4375 1255 0 'internal conversion function for UTF8 to LATIN1' ) +insert ( 4376 1255 0 'internal conversion function for JOHAB to UTF8' ) +insert ( 4377 1255 0 'internal conversion function for UTF8 to JOHAB' ) +insert ( 4378 1255 0 'internal conversion function for SJIS to UTF8' ) +insert ( 4379 1255 0 'internal conversion function for UTF8 to SJIS' ) +insert ( 4380 1255 0 'internal conversion function for UHC to UTF8' ) +insert ( 4381 1255 0 'internal conversion function for UTF8 to UHC' ) +insert ( 4382 1255 0 'internal conversion function for EUC_JIS_2004 to UTF8' ) +insert ( 4383 1255 0 'internal conversion function for UTF8 to EUC_JIS_2004' ) +insert ( 4384 1255 0 'internal conversion function for SHIFT_JIS_2004 to UTF8' ) +insert ( 4385 1255 0 'internal conversion function for UTF8 to SHIFT_JIS_2004' ) +insert ( 4386 1255 0 'internal conversion function for EUC_JIS_2004 to SHIFT_JIS_2004' ) +insert ( 4387 1255 0 'internal conversion function for SHIFT_JIS_2004 to EUC_JIS_2004' ) +insert ( 5040 1255 0 'restriction selectivity for generic matching operators' ) +insert ( 5041 1255 0 'join selectivity for generic matching operators' ) +insert ( 6003 1255 0 'create a replication origin' ) +insert ( 6004 1255 0 'drop replication origin identified by its name' ) +insert ( 6005 1255 0 'translate the replication origin''s name to its id' ) +insert ( 6006 1255 0 'configure session to maintain replication progress tracking for the passed in origin' ) +insert ( 6007 1255 0 'teardown configured replication progress tracking' ) +insert ( 6008 1255 0 'is a replication origin configured in this session' ) +insert ( 6009 1255 0 'get the replication progress of the current session' ) +insert ( 6010 1255 0 'setup the transaction''s origin lsn and timestamp' ) +insert ( 6011 1255 0 'reset the transaction''s origin lsn and timestamp' ) +insert ( 6012 1255 0 'advance replication origin to specific location' ) +insert ( 6013 1255 0 'get an individual replication origin''s replication progress' ) +insert ( 6014 1255 0 'get progress for all replication origins' ) +insert ( 6119 1255 0 'get information of the tables that are part of the specified publications' ) +insert ( 6121 1255 0 'returns whether a relation can be part of a publication' ) +insert ( 3298 1255 0 'row security for current context active on table by table oid' ) +insert ( 3299 1255 0 'row security for current context active on table by table name' ) +insert ( 3400 1255 0 'pg_config binary as a function' ) +insert ( 3441 1255 0 'pg_controldata general state information as a function' ) +insert ( 3442 1255 0 'pg_controldata checkpoint state information as a function' ) +insert ( 3443 1255 0 'pg_controldata recovery state information as a function' ) +insert ( 3444 1255 0 'pg_controldata init state information as a function' ) +insert ( 6179 1255 0 'standard array subscripting support' ) +insert ( 6180 1255 0 'raw array subscripting support' ) +insert ( 6098 1255 0 'jsonb subscripting logic' ) +insert ( 3445 1255 0 'import collations from operating system' ) +insert ( 3448 1255 0 'get actual version of collation from operating system' ) +insert ( 6249 1255 0 'get actual version of database collation from operating system' ) +insert ( 3353 1255 0 'list files in the log directory' ) +insert ( 3354 1255 0 'list of files in the WAL directory' ) +insert ( 5031 1255 0 'list of files in the archive_status directory' ) +insert ( 5029 1255 0 'list files in the pgsql_tmp directory' ) +insert ( 5030 1255 0 'list files in the pgsql_tmp directory' ) +insert ( 6270 1255 0 'list of files in the pg_logical/snapshots directory' ) +insert ( 6271 1255 0 'list of files in the pg_logical/mappings directory' ) +insert ( 6272 1255 0 'list of files in the pg_replslot/slot_name directory' ) +insert ( 5028 1255 0 'hash partition CHECK constraint' ) +insert ( 3423 1255 0 'view partition tree tables' ) +insert ( 3425 1255 0 'view ancestors of the partition' ) +insert ( 3424 1255 0 'get top-most partition root parent' ) +insert ( 4350 1255 0 'Unicode normalization' ) +insert ( 4351 1255 0 'check Unicode normalization' ) +insert ( 6198 1255 0 'unescape Unicode characters' ) +insert ( 4596 1255 0 'I/O' ) +insert ( 4597 1255 0 'I/O' ) +insert ( 4598 1255 0 'I/O' ) +insert ( 4599 1255 0 'I/O' ) +insert ( 4638 1255 0 'I/O' ) +insert ( 4639 1255 0 'I/O' ) +insert ( 4640 1255 0 'I/O' ) +insert ( 4641 1255 0 'I/O' ) +insert ( 6291 1255 0 'arbitrary value from among input values' ) +insert ( 6292 1255 0 'aggregate transition function' ) +insert ( 8898 1255 0 'list registered cluster wait events' ) +insert ( 8899 1255 0 'list registered cluster wait events across cluster nodes' ) +insert ( 8900 1255 0 'list cluster nodes from pgrac.conf topology' ) +insert ( 8901 1255 0 'inject a fake inbound message into the mock interconnect queue' ) +insert ( 8902 1255 0 'drain queued outbound mock messages for a target node' ) +insert ( 8903 1255 0 'reset all mock interconnect queues' ) +insert ( 8904 1255 0 'pop one inbound mock message via cluster_ic_recv_bytes' ) +insert ( 8905 1255 0 'arm or disarm a cluster injection point' ) +insert ( 8906 1255 0 'list cluster injection-point arm state and hit counters' ) +insert ( 8907 1255 0 'list cluster nodes with runtime metadata' ) +insert ( 8908 1255 0 'list cluster pgstat atomic counters' ) +insert ( 8909 1255 0 'one-stop diagnostic snapshot of cluster state' ) +insert ( 8910 1255 0 'list registered cluster shmem regions with sizes' ) +insert ( 8911 1255 0 'advance cluster SCN by 1 (superuser-only debug API)' ) +insert ( 8912 1255 0 'read current cluster SCN (encoded uint64)' ) +insert ( 8914 1255 0 'list cluster IC peer connection state + telemetry (spec-2.2 + spec-2.4)' ) +insert ( 8915 1255 0 'list registered cluster IC message types (spec-2.3)' ) +insert ( 8913 1255 0 'observe a remote SCN (single-node 1.15: stat-only; superuser)' ) +insert ( 8916 1255 0 'list CSSD peer state + heartbeat counters (spec-2.5)' ) +insert ( 8917 1255 0 'show current cluster quorum state (spec-2.6)' ) +insert ( 8918 1255 0 'list voting disks declared in cluster.voting_disks (spec-2.6)' ) +insert ( 8919 1255 0 'show fence-lite state (spec-2.28)' ) +insert ( 8920 1255 0 'show reconfig coordinator state (spec-2.29)' ) +insert ( 8921 1255 0 'list GRD shard map: shard_id, master_node_id, is_local (spec-2.14)' ) +insert ( 8922 1255 0 'list cluster_grd entry table snapshot (diagnostic only; not for production hot-path queries) (spec-2.15)' ) +insert ( 8923 1255 0 'show cluster_lmd state + counters (spec-2.19)' ) +insert ( 8948 1255 0 'dump frozen GES 8x8 lock-mode compatibility matrix + DLM aliases' ) +insert ( 8949 1255 0 'GES compatibility of two canonical PG lock-mode names' ) +insert ( 8950 1255 0 'does the frozen GES matrix match the live lock conflict table' ) +insert ( 8924 1255 0 'TEST-ONLY: inject synthetic LMD wait edge (spec-2.22 D16)' ) +insert ( 8925 1255 0 'TEST-ONLY: inject remote TT ref for MVCC visibility fork' ) +insert ( 8926 1255 0 'TEST-ONLY: clear MVCC visibility fork inject table' ) +insert ( 8927 1255 0 'TEST-ONLY: inject SUBCOMMITTED parent chain for SUBTRANS visibility' ) +insert ( 8928 1255 0 'cluster undo record sanity reader (spec-3.7 D8)' ) +insert ( 8929 1255 0 'TEST-ONLY: force undo segment cursor to last block (spec-3.8)' ) +insert ( 8930 1255 0 'TEST-ONLY: construct own-instance CR block image (spec-3.9)' ) +insert ( 8931 1255 0 'TEST-ONLY: CR block image rows as-of read_scn (spec-3.10 v0.6)' ) +insert ( 8932 1255 0 'TEST-ONLY: single-block redo-apply reconstruction over WAL (spec-4.10)' ) +insert ( 8934 1255 0 'TEST-ONLY: LSN-gated online thread-recovery apply over WAL (spec-4.11)' ) +insert ( 8935 1255 0 'TEST-ONLY: online thread-recovery RMW replay over WAL + shared storage (spec-4.11)' ) +insert ( 8936 1255 0 'TEST-ONLY: online thread-recovery data driver over a dead thread WAL (spec-4.11)' ) +insert ( 8937 1255 0 'TEST-ONLY: online thread-recovery orchestrator over an explicit window (spec-4.11)' ) +insert ( 8938 1255 0 'TEST-ONLY: online thread-recovery scope gate + basic window (spec-4.11)' ) +insert ( 8939 1255 0 'TEST-ONLY: online thread-recovery D3 local-complete authority gate (spec-4.11)' ) +insert ( 8940 1255 0 'TEST-ONLY: online thread-recovery D3 reconfig unfreeze gate (spec-4.11)' ) +insert ( 8941 1255 0 'TEST-ONLY: online thread-recovery D4 validated torn-tail boundary (spec-4.11)' ) +insert ( 8942 1255 0 'TEST-ONLY: online thread-recovery 3b-4b replay-state slot round-trip (spec-4.11)' ) +insert ( 8943 1255 0 'TEST-ONLY: online thread-recovery 3b-4b executor worker run (spec-4.11)' ) +insert ( 8944 1255 0 'TEST-ONLY: online thread-recovery 3b-4b lmon launch (spec-4.11)' ) +insert ( 8945 1255 0 'TEST-ONLY: read online thread-recovery 3b-4b replay-state slot (spec-4.11)' ) +insert ( 8946 1255 0 'TEST-ONLY: inject a synthetic dead-node reconfig episode (spec-4.11)' ) +insert ( 8947 1255 0 'TEST-ONLY: drive the online thread-recovery D7 capability gate (spec-4.11)' ) +insert ( 8933 1255 0 'TEST-ONLY: online single-block recovery reconstruction over WAL (spec-4.10)' ) +insert ( 16 1247 0 'boolean, ''true''/''false''' ) +insert ( 17 1247 0 'variable-length string, binary values escaped' ) +insert ( 18 1247 0 'single character' ) +insert ( 19 1247 0 '63-byte type for storing system identifiers' ) +insert ( 20 1247 0 '~18 digit integer, 8-byte storage' ) +insert ( 21 1247 0 '-32 thousand to 32 thousand, 2-byte storage' ) +insert ( 22 1247 0 'array of int2, used in system tables' ) +insert ( 23 1247 0 '-2 billion to 2 billion integer, 4-byte storage' ) +insert ( 24 1247 0 'registered procedure' ) +insert ( 25 1247 0 'variable-length string, no limit specified' ) +insert ( 26 1247 0 'object identifier(oid), maximum 4 billion' ) +insert ( 27 1247 0 '(block, offset), physical location of tuple' ) +insert ( 28 1247 0 'transaction id' ) +insert ( 29 1247 0 'command identifier type, sequence in transaction id' ) +insert ( 30 1247 0 'array of oids, used in system tables' ) +insert ( 114 1247 0 'JSON stored as text' ) +insert ( 142 1247 0 'XML content' ) +insert ( 194 1247 0 'string representing an internal node tree' ) +insert ( 3361 1247 0 'multivariate ndistinct coefficients' ) +insert ( 3402 1247 0 'multivariate dependencies' ) +insert ( 5017 1247 0 'multivariate MCV list' ) +insert ( 32 1247 0 'internal type for passing CollectedCommand' ) +insert ( 5069 1247 0 'full transaction id' ) +insert ( 600 1247 0 'geometric point ''(x, y)''' ) +insert ( 601 1247 0 'geometric line segment ''(pt1,pt2)''' ) +insert ( 602 1247 0 'geometric path ''(pt1,...)''' ) +insert ( 603 1247 0 'geometric box ''(lower left,upper right)''' ) +insert ( 604 1247 0 'geometric polygon ''(pt1,...)''' ) +insert ( 628 1247 0 'geometric line' ) +insert ( 700 1247 0 'single-precision floating point number, 4-byte storage' ) +insert ( 701 1247 0 'double-precision floating point number, 8-byte storage' ) +insert ( 705 1247 0 'pseudo-type representing an undetermined type' ) +insert ( 718 1247 0 'geometric circle ''(center,radius)''' ) +insert ( 790 1247 0 'monetary amounts, $d,ddd.cc' ) +insert ( 829 1247 0 'XX:XX:XX:XX:XX:XX, MAC address' ) +insert ( 869 1247 0 'IP address/netmask, host address, netmask optional' ) +insert ( 650 1247 0 'network IP address/netmask, network address' ) +insert ( 774 1247 0 'XX:XX:XX:XX:XX:XX:XX:XX, MAC address' ) +insert ( 1033 1247 0 'access control list' ) +insert ( 1042 1247 0 'char(length), blank-padded string, fixed storage length' ) +insert ( 1043 1247 0 'varchar(length), non-blank-padded string, variable storage length' ) +insert ( 1082 1247 0 date ) +insert ( 1083 1247 0 'time of day' ) +insert ( 1114 1247 0 'date and time' ) +insert ( 1184 1247 0 'date and time with time zone' ) +insert ( 1186 1247 0 '@ , time interval' ) +insert ( 1266 1247 0 'time of day with time zone' ) +insert ( 1560 1247 0 'fixed-length bit string' ) +insert ( 1562 1247 0 'variable-length bit string' ) +insert ( 1700 1247 0 'numeric(precision, decimal), arbitrary precision number' ) +insert ( 1790 1247 0 'reference to cursor (portal name)' ) +insert ( 2202 1247 0 'registered procedure (with args)' ) +insert ( 2203 1247 0 'registered operator' ) +insert ( 2204 1247 0 'registered operator (with args)' ) +insert ( 2205 1247 0 'registered class' ) +insert ( 4191 1247 0 'registered collation' ) +insert ( 2206 1247 0 'registered type' ) +insert ( 4096 1247 0 'registered role' ) +insert ( 4089 1247 0 'registered namespace' ) +insert ( 2950 1247 0 'UUID datatype' ) +insert ( 3220 1247 0 'PostgreSQL LSN datatype' ) +insert ( 3614 1247 0 'text representation for text search' ) +insert ( 3642 1247 0 'GiST index internal text representation for text search' ) +insert ( 3615 1247 0 'query representation for text search' ) +insert ( 3734 1247 0 'registered text search configuration' ) +insert ( 3769 1247 0 'registered text search dictionary' ) +insert ( 3802 1247 0 'Binary JSON' ) +insert ( 4072 1247 0 'JSON path' ) +insert ( 2970 1247 0 'txid snapshot' ) +insert ( 5038 1247 0 snapshot ) +insert ( 3904 1247 0 'range of integers' ) +insert ( 3906 1247 0 'range of numerics' ) +insert ( 3908 1247 0 'range of timestamps without time zone' ) +insert ( 3910 1247 0 'range of timestamps with time zone' ) +insert ( 3912 1247 0 'range of dates' ) +insert ( 3926 1247 0 'range of bigints' ) +insert ( 4451 1247 0 'multirange of integers' ) +insert ( 4532 1247 0 'multirange of numerics' ) +insert ( 4533 1247 0 'multirange of timestamps without time zone' ) +insert ( 4534 1247 0 'multirange of timestamps with time zone' ) +insert ( 4535 1247 0 'multirange of dates' ) +insert ( 4536 1247 0 'multirange of bigints' ) +insert ( 2249 1247 0 'pseudo-type representing any composite type' ) +insert ( 2275 1247 0 'C-style string' ) +insert ( 2276 1247 0 'pseudo-type representing any type' ) +insert ( 2277 1247 0 'pseudo-type representing a polymorphic array type' ) +insert ( 2278 1247 0 'pseudo-type for the result of a function with no real result' ) +insert ( 2279 1247 0 'pseudo-type for the result of a trigger function' ) +insert ( 3838 1247 0 'pseudo-type for the result of an event trigger function' ) +insert ( 2280 1247 0 'pseudo-type for the result of a language handler function' ) +insert ( 2281 1247 0 'pseudo-type representing an internal data structure' ) +insert ( 2283 1247 0 'pseudo-type representing a polymorphic base type' ) +insert ( 2776 1247 0 'pseudo-type representing a polymorphic base type that is not an array' ) +insert ( 3500 1247 0 'pseudo-type representing a polymorphic base type that is an enum' ) +insert ( 3115 1247 0 'pseudo-type for the result of an FDW handler function' ) +insert ( 325 1247 0 'pseudo-type for the result of an index AM handler function' ) +insert ( 3310 1247 0 'pseudo-type for the result of a tablesample method function' ) +insert ( 3831 1247 0 'pseudo-type representing a range over a polymorphic base type' ) +insert ( 5077 1247 0 'pseudo-type representing a polymorphic common type' ) +insert ( 5078 1247 0 'pseudo-type representing an array of polymorphic common type elements' ) +insert ( 5079 1247 0 'pseudo-type representing a polymorphic common type that is not an array' ) +insert ( 5080 1247 0 'pseudo-type representing a range over a polymorphic common type' ) +insert ( 4537 1247 0 'pseudo-type representing a polymorphic base type that is a multirange' ) +insert ( 4538 1247 0 'pseudo-type representing a multirange over a polymorphic common type' ) +insert ( 4600 1247 0 'BRIN bloom summary' ) +insert ( 4601 1247 0 'BRIN minmax-multi summary' ) +insert ( 15 2617 0 equal ) +insert ( 36 2617 0 'not equal' ) +insert ( 37 2617 0 'less than' ) +insert ( 76 2617 0 'greater than' ) +insert ( 80 2617 0 'less than or equal' ) +insert ( 82 2617 0 'greater than or equal' ) +insert ( 58 2617 0 'less than' ) +insert ( 59 2617 0 'greater than' ) +insert ( 85 2617 0 'not equal' ) +insert ( 91 2617 0 equal ) +insert ( 1694 2617 0 'less than or equal' ) +insert ( 1695 2617 0 'greater than or equal' ) +insert ( 92 2617 0 equal ) +insert ( 93 2617 0 equal ) +insert ( 94 2617 0 equal ) +insert ( 95 2617 0 'less than' ) +insert ( 96 2617 0 equal ) +insert ( 97 2617 0 'less than' ) +insert ( 98 2617 0 equal ) +insert ( 3877 2617 0 'starts with' ) +insert ( 254 2617 0 equal ) +insert ( 255 2617 0 'less than' ) +insert ( 256 2617 0 'less than or equal' ) +insert ( 257 2617 0 'greater than or equal' ) +insert ( 258 2617 0 'greater than' ) +insert ( 259 2617 0 'not equal' ) +insert ( 260 2617 0 equal ) +insert ( 261 2617 0 'less than' ) +insert ( 262 2617 0 'less than or equal' ) +insert ( 263 2617 0 'greater than or equal' ) +insert ( 264 2617 0 'greater than' ) +insert ( 265 2617 0 'not equal' ) +insert ( 349 2617 0 'append element onto end of array' ) +insert ( 374 2617 0 'prepend element onto front of array' ) +insert ( 375 2617 0 concatenate ) +insert ( 352 2617 0 equal ) +insert ( 353 2617 0 equal ) +insert ( 3315 2617 0 'not equal' ) +insert ( 3316 2617 0 'not equal' ) +insert ( 5068 2617 0 equal ) +insert ( 5072 2617 0 'not equal' ) +insert ( 5073 2617 0 'less than' ) +insert ( 5074 2617 0 'greater than' ) +insert ( 5075 2617 0 'less than or equal' ) +insert ( 5076 2617 0 'greater than or equal' ) +insert ( 385 2617 0 equal ) +insert ( 387 2617 0 equal ) +insert ( 402 2617 0 'not equal' ) +insert ( 2799 2617 0 'less than' ) +insert ( 2800 2617 0 'greater than' ) +insert ( 2801 2617 0 'less than or equal' ) +insert ( 2802 2617 0 'greater than or equal' ) +insert ( 410 2617 0 equal ) +insert ( 411 2617 0 'not equal' ) +insert ( 412 2617 0 'less than' ) +insert ( 413 2617 0 'greater than' ) +insert ( 414 2617 0 'less than or equal' ) +insert ( 415 2617 0 'greater than or equal' ) +insert ( 416 2617 0 equal ) +insert ( 417 2617 0 'not equal' ) +insert ( 418 2617 0 'less than' ) +insert ( 419 2617 0 'greater than' ) +insert ( 420 2617 0 'less than or equal' ) +insert ( 430 2617 0 'greater than or equal' ) +insert ( 439 2617 0 modulus ) +insert ( 473 2617 0 'absolute value' ) +insert ( 484 2617 0 negate ) +insert ( 485 2617 0 'is left of' ) +insert ( 486 2617 0 'overlaps or is left of' ) +insert ( 487 2617 0 'overlaps or is right of' ) +insert ( 488 2617 0 'is right of' ) +insert ( 489 2617 0 'is contained by' ) +insert ( 490 2617 0 contains ) +insert ( 491 2617 0 'same as' ) +insert ( 492 2617 0 overlaps ) +insert ( 493 2617 0 'is left of' ) +insert ( 494 2617 0 'overlaps or is left of' ) +insert ( 495 2617 0 'overlaps or is right of' ) +insert ( 496 2617 0 'is right of' ) +insert ( 497 2617 0 'is contained by' ) +insert ( 498 2617 0 contains ) +insert ( 499 2617 0 'same as' ) +insert ( 500 2617 0 overlaps ) +insert ( 501 2617 0 'greater than or equal by area' ) +insert ( 502 2617 0 'greater than by area' ) +insert ( 503 2617 0 'equal by area' ) +insert ( 504 2617 0 'less than by area' ) +insert ( 505 2617 0 'less than or equal by area' ) +insert ( 506 2617 0 'deprecated, use |>> instead' ) +insert ( 507 2617 0 'is left of' ) +insert ( 508 2617 0 'is right of' ) +insert ( 509 2617 0 'deprecated, use <<| instead' ) +insert ( 510 2617 0 'same as' ) +insert ( 511 2617 0 'point inside box' ) +insert ( 433 2617 0 contains ) +insert ( 512 2617 0 'point within closed path, or point on open path' ) +insert ( 513 2617 0 'center of' ) +insert ( 514 2617 0 multiply ) +insert ( 517 2617 0 'distance between' ) +insert ( 518 2617 0 'not equal' ) +insert ( 519 2617 0 'not equal' ) +insert ( 520 2617 0 'greater than' ) +insert ( 521 2617 0 'greater than' ) +insert ( 522 2617 0 'less than or equal' ) +insert ( 523 2617 0 'less than or equal' ) +insert ( 524 2617 0 'greater than or equal' ) +insert ( 525 2617 0 'greater than or equal' ) +insert ( 526 2617 0 multiply ) +insert ( 527 2617 0 divide ) +insert ( 528 2617 0 divide ) +insert ( 529 2617 0 modulus ) +insert ( 530 2617 0 modulus ) +insert ( 531 2617 0 'not equal' ) +insert ( 532 2617 0 equal ) +insert ( 533 2617 0 equal ) +insert ( 534 2617 0 'less than' ) +insert ( 535 2617 0 'less than' ) +insert ( 536 2617 0 'greater than' ) +insert ( 537 2617 0 'greater than' ) +insert ( 538 2617 0 'not equal' ) +insert ( 539 2617 0 'not equal' ) +insert ( 540 2617 0 'less than or equal' ) +insert ( 541 2617 0 'less than or equal' ) +insert ( 542 2617 0 'greater than or equal' ) +insert ( 543 2617 0 'greater than or equal' ) +insert ( 544 2617 0 multiply ) +insert ( 545 2617 0 multiply ) +insert ( 546 2617 0 divide ) +insert ( 547 2617 0 divide ) +insert ( 550 2617 0 add ) +insert ( 551 2617 0 add ) +insert ( 552 2617 0 add ) +insert ( 553 2617 0 add ) +insert ( 554 2617 0 subtract ) +insert ( 555 2617 0 subtract ) +insert ( 556 2617 0 subtract ) +insert ( 557 2617 0 subtract ) +insert ( 558 2617 0 negate ) +insert ( 559 2617 0 negate ) +insert ( 584 2617 0 negate ) +insert ( 585 2617 0 negate ) +insert ( 586 2617 0 add ) +insert ( 587 2617 0 subtract ) +insert ( 588 2617 0 divide ) +insert ( 589 2617 0 multiply ) +insert ( 590 2617 0 'absolute value' ) +insert ( 591 2617 0 add ) +insert ( 592 2617 0 subtract ) +insert ( 593 2617 0 divide ) +insert ( 594 2617 0 multiply ) +insert ( 595 2617 0 'absolute value' ) +insert ( 596 2617 0 'square root' ) +insert ( 597 2617 0 'cube root' ) +insert ( 607 2617 0 equal ) +insert ( 608 2617 0 'not equal' ) +insert ( 609 2617 0 'less than' ) +insert ( 610 2617 0 'greater than' ) +insert ( 611 2617 0 'less than or equal' ) +insert ( 612 2617 0 'greater than or equal' ) +insert ( 644 2617 0 'not equal' ) +insert ( 645 2617 0 'less than' ) +insert ( 646 2617 0 'greater than' ) +insert ( 647 2617 0 'less than or equal' ) +insert ( 648 2617 0 'greater than or equal' ) +insert ( 649 2617 0 equal ) +insert ( 613 2617 0 'distance between' ) +insert ( 760 2617 0 'distance between' ) +insert ( 614 2617 0 'distance between' ) +insert ( 761 2617 0 'distance between' ) +insert ( 615 2617 0 'distance between' ) +insert ( 606 2617 0 'distance between' ) +insert ( 616 2617 0 'distance between' ) +insert ( 762 2617 0 'distance between' ) +insert ( 617 2617 0 'distance between' ) +insert ( 763 2617 0 'distance between' ) +insert ( 618 2617 0 'distance between' ) +insert ( 784 2617 0 'distance between' ) +insert ( 620 2617 0 equal ) +insert ( 621 2617 0 'not equal' ) +insert ( 622 2617 0 'less than' ) +insert ( 623 2617 0 'greater than' ) +insert ( 624 2617 0 'less than or equal' ) +insert ( 625 2617 0 'greater than or equal' ) +insert ( 630 2617 0 'not equal' ) +insert ( 631 2617 0 'less than' ) +insert ( 632 2617 0 'less than or equal' ) +insert ( 633 2617 0 'greater than' ) +insert ( 634 2617 0 'greater than or equal' ) +insert ( 639 2617 0 'matches regular expression, case-sensitive' ) +insert ( 640 2617 0 'does not match regular expression, case-sensitive' ) +insert ( 641 2617 0 'matches regular expression, case-sensitive' ) +insert ( 642 2617 0 'does not match regular expression, case-sensitive' ) +insert ( 643 2617 0 'not equal' ) +insert ( 654 2617 0 concatenate ) +insert ( 660 2617 0 'less than' ) +insert ( 661 2617 0 'less than or equal' ) +insert ( 662 2617 0 'greater than' ) +insert ( 663 2617 0 'greater than or equal' ) +insert ( 664 2617 0 'less than' ) +insert ( 665 2617 0 'less than or equal' ) +insert ( 666 2617 0 'greater than' ) +insert ( 667 2617 0 'greater than or equal' ) +insert ( 670 2617 0 equal ) +insert ( 671 2617 0 'not equal' ) +insert ( 672 2617 0 'less than' ) +insert ( 673 2617 0 'less than or equal' ) +insert ( 674 2617 0 'greater than' ) +insert ( 675 2617 0 'greater than or equal' ) +insert ( 682 2617 0 'absolute value' ) +insert ( 684 2617 0 add ) +insert ( 685 2617 0 subtract ) +insert ( 686 2617 0 multiply ) +insert ( 687 2617 0 divide ) +insert ( 688 2617 0 add ) +insert ( 689 2617 0 subtract ) +insert ( 690 2617 0 multiply ) +insert ( 691 2617 0 divide ) +insert ( 692 2617 0 add ) +insert ( 693 2617 0 subtract ) +insert ( 694 2617 0 multiply ) +insert ( 695 2617 0 divide ) +insert ( 818 2617 0 add ) +insert ( 819 2617 0 subtract ) +insert ( 820 2617 0 multiply ) +insert ( 821 2617 0 divide ) +insert ( 822 2617 0 add ) +insert ( 823 2617 0 subtract ) +insert ( 824 2617 0 multiply ) +insert ( 825 2617 0 divide ) +insert ( 706 2617 0 'distance between' ) +insert ( 707 2617 0 'distance between' ) +insert ( 708 2617 0 'distance between' ) +insert ( 709 2617 0 'distance between' ) +insert ( 712 2617 0 'distance between' ) +insert ( 713 2617 0 'not equal' ) +insert ( 731 2617 0 'add points (translate)' ) +insert ( 732 2617 0 'subtract points (translate)' ) +insert ( 733 2617 0 'multiply points (scale/rotate)' ) +insert ( 734 2617 0 'divide points (scale/rotate)' ) +insert ( 735 2617 0 concatenate ) +insert ( 736 2617 0 'add (translate path)' ) +insert ( 737 2617 0 'subtract (translate path)' ) +insert ( 738 2617 0 'multiply (rotate/scale path)' ) +insert ( 739 2617 0 'divide (rotate/scale path)' ) +insert ( 755 2617 0 contains ) +insert ( 756 2617 0 'is contained by' ) +insert ( 757 2617 0 contains ) +insert ( 758 2617 0 'is contained by' ) +insert ( 759 2617 0 contains ) +insert ( 773 2617 0 'absolute value' ) +insert ( 792 2617 0 equal ) +insert ( 793 2617 0 'less than' ) +insert ( 794 2617 0 'greater than' ) +insert ( 795 2617 0 'less than or equal' ) +insert ( 796 2617 0 'greater than or equal' ) +insert ( 797 2617 0 'number of points' ) +insert ( 798 2617 0 intersect ) +insert ( 799 2617 0 'sum of path segment lengths' ) +insert ( 800 2617 0 'is above (allows touching)' ) +insert ( 801 2617 0 'is below (allows touching)' ) +insert ( 802 2617 0 'deprecated, use && instead' ) +insert ( 803 2617 0 'box intersection' ) +insert ( 804 2617 0 'add point to box (translate)' ) +insert ( 805 2617 0 'subtract point from box (translate)' ) +insert ( 806 2617 0 'multiply box by point (scale)' ) +insert ( 807 2617 0 'divide box by point (scale)' ) +insert ( 808 2617 0 'horizontally aligned' ) +insert ( 809 2617 0 'vertically aligned' ) +insert ( 843 2617 0 multiply ) +insert ( 844 2617 0 divide ) +insert ( 845 2617 0 multiply ) +insert ( 900 2617 0 equal ) +insert ( 901 2617 0 'not equal' ) +insert ( 902 2617 0 'less than' ) +insert ( 903 2617 0 'greater than' ) +insert ( 904 2617 0 'less than or equal' ) +insert ( 905 2617 0 'greater than or equal' ) +insert ( 906 2617 0 add ) +insert ( 907 2617 0 subtract ) +insert ( 908 2617 0 multiply ) +insert ( 909 2617 0 divide ) +insert ( 3346 2617 0 multiply ) +insert ( 3347 2617 0 divide ) +insert ( 912 2617 0 multiply ) +insert ( 913 2617 0 divide ) +insert ( 914 2617 0 multiply ) +insert ( 915 2617 0 divide ) +insert ( 916 2617 0 multiply ) +insert ( 3349 2617 0 multiply ) +insert ( 917 2617 0 multiply ) +insert ( 918 2617 0 multiply ) +insert ( 3825 2617 0 divide ) +insert ( 965 2617 0 exponentiation ) +insert ( 966 2617 0 'add/update ACL item' ) +insert ( 967 2617 0 'remove ACL item' ) +insert ( 968 2617 0 contains ) +insert ( 974 2617 0 equal ) +insert ( 969 2617 0 'center of' ) +insert ( 971 2617 0 'center of' ) +insert ( 1054 2617 0 equal ) +insert ( 1055 2617 0 'matches regular expression, case-sensitive' ) +insert ( 1056 2617 0 'does not match regular expression, case-sensitive' ) +insert ( 1057 2617 0 'not equal' ) +insert ( 1058 2617 0 'less than' ) +insert ( 1059 2617 0 'less than or equal' ) +insert ( 1060 2617 0 'greater than' ) +insert ( 1061 2617 0 'greater than or equal' ) +insert ( 1070 2617 0 equal ) +insert ( 1071 2617 0 'not equal' ) +insert ( 1072 2617 0 'less than' ) +insert ( 1073 2617 0 'greater than' ) +insert ( 1074 2617 0 'less than or equal' ) +insert ( 1075 2617 0 'greater than or equal' ) +insert ( 1076 2617 0 add ) +insert ( 1077 2617 0 subtract ) +insert ( 1093 2617 0 equal ) +insert ( 1094 2617 0 'not equal' ) +insert ( 1095 2617 0 'less than' ) +insert ( 1096 2617 0 'less than or equal' ) +insert ( 1097 2617 0 'greater than' ) +insert ( 1098 2617 0 'greater than or equal' ) +insert ( 1099 2617 0 subtract ) +insert ( 1100 2617 0 add ) +insert ( 1101 2617 0 subtract ) +insert ( 1108 2617 0 equal ) +insert ( 1109 2617 0 'not equal' ) +insert ( 1110 2617 0 'less than' ) +insert ( 1111 2617 0 'less than or equal' ) +insert ( 1112 2617 0 'greater than' ) +insert ( 1113 2617 0 'greater than or equal' ) +insert ( 1550 2617 0 equal ) +insert ( 1551 2617 0 'not equal' ) +insert ( 1552 2617 0 'less than' ) +insert ( 1553 2617 0 'less than or equal' ) +insert ( 1554 2617 0 'greater than' ) +insert ( 1555 2617 0 'greater than or equal' ) +insert ( 1116 2617 0 add ) +insert ( 1117 2617 0 subtract ) +insert ( 1118 2617 0 divide ) +insert ( 1119 2617 0 multiply ) +insert ( 1120 2617 0 equal ) +insert ( 1121 2617 0 'not equal' ) +insert ( 1122 2617 0 'less than' ) +insert ( 1123 2617 0 'greater than' ) +insert ( 1124 2617 0 'less than or equal' ) +insert ( 1125 2617 0 'greater than or equal' ) +insert ( 1126 2617 0 add ) +insert ( 1127 2617 0 subtract ) +insert ( 1128 2617 0 divide ) +insert ( 1129 2617 0 multiply ) +insert ( 1130 2617 0 equal ) +insert ( 1131 2617 0 'not equal' ) +insert ( 1132 2617 0 'less than' ) +insert ( 1133 2617 0 'greater than' ) +insert ( 1134 2617 0 'less than or equal' ) +insert ( 1135 2617 0 'greater than or equal' ) +insert ( 1207 2617 0 'matches LIKE expression' ) +insert ( 1208 2617 0 'does not match LIKE expression' ) +insert ( 1209 2617 0 'matches LIKE expression' ) +insert ( 1210 2617 0 'does not match LIKE expression' ) +insert ( 1211 2617 0 'matches LIKE expression' ) +insert ( 1212 2617 0 'does not match LIKE expression' ) +insert ( 1226 2617 0 'matches regular expression, case-insensitive' ) +insert ( 1227 2617 0 'does not match regular expression, case-insensitive' ) +insert ( 1228 2617 0 'matches regular expression, case-insensitive' ) +insert ( 1229 2617 0 'does not match regular expression, case-insensitive' ) +insert ( 1234 2617 0 'matches regular expression, case-insensitive' ) +insert ( 1235 2617 0 'does not match regular expression, case-insensitive' ) +insert ( 1320 2617 0 equal ) +insert ( 1321 2617 0 'not equal' ) +insert ( 1322 2617 0 'less than' ) +insert ( 1323 2617 0 'less than or equal' ) +insert ( 1324 2617 0 'greater than' ) +insert ( 1325 2617 0 'greater than or equal' ) +insert ( 1327 2617 0 add ) +insert ( 1328 2617 0 subtract ) +insert ( 1329 2617 0 subtract ) +insert ( 1330 2617 0 equal ) +insert ( 1331 2617 0 'not equal' ) +insert ( 1332 2617 0 'less than' ) +insert ( 1333 2617 0 'less than or equal' ) +insert ( 1334 2617 0 'greater than' ) +insert ( 1335 2617 0 'greater than or equal' ) +insert ( 1336 2617 0 negate ) +insert ( 1337 2617 0 add ) +insert ( 1338 2617 0 subtract ) +insert ( 1360 2617 0 'convert date and time to timestamp' ) +insert ( 1361 2617 0 'convert date and time with time zone to timestamp with time zone' ) +insert ( 1363 2617 0 'convert time and date to timestamp' ) +insert ( 1366 2617 0 'convert time with time zone and date to timestamp with time zone' ) +insert ( 1399 2617 0 subtract ) +insert ( 1420 2617 0 'center of' ) +insert ( 1500 2617 0 'equal by area' ) +insert ( 1501 2617 0 'not equal by area' ) +insert ( 1502 2617 0 'less than by area' ) +insert ( 1503 2617 0 'greater than by area' ) +insert ( 1504 2617 0 'less than or equal by area' ) +insert ( 1505 2617 0 'greater than or equal by area' ) +insert ( 1506 2617 0 'is left of' ) +insert ( 1507 2617 0 'overlaps or is left of' ) +insert ( 1508 2617 0 'overlaps or is right of' ) +insert ( 1509 2617 0 'is right of' ) +insert ( 1510 2617 0 'is contained by' ) +insert ( 1511 2617 0 contains ) +insert ( 1512 2617 0 'same as' ) +insert ( 1513 2617 0 overlaps ) +insert ( 1514 2617 0 'is above' ) +insert ( 1515 2617 0 'is below' ) +insert ( 1516 2617 0 add ) +insert ( 1517 2617 0 subtract ) +insert ( 1518 2617 0 multiply ) +insert ( 1519 2617 0 divide ) +insert ( 1520 2617 0 'distance between' ) +insert ( 1521 2617 0 'number of points' ) +insert ( 1522 2617 0 'distance between' ) +insert ( 3291 2617 0 'distance between' ) +insert ( 3276 2617 0 'distance between' ) +insert ( 3289 2617 0 'distance between' ) +insert ( 1523 2617 0 'distance between' ) +insert ( 1383 2617 0 'distance between' ) +insert ( 1525 2617 0 intersect ) +insert ( 1526 2617 0 parallel ) +insert ( 1527 2617 0 perpendicular ) +insert ( 1528 2617 0 horizontal ) +insert ( 1529 2617 0 vertical ) +insert ( 1535 2617 0 equal ) +insert ( 1536 2617 0 'intersection point' ) +insert ( 1537 2617 0 intersect ) +insert ( 1538 2617 0 intersect ) +insert ( 1539 2617 0 intersect ) +insert ( 1546 2617 0 'point on line' ) +insert ( 1547 2617 0 'is contained by' ) +insert ( 1548 2617 0 'lseg on line' ) +insert ( 1549 2617 0 'is contained by' ) +insert ( 1557 2617 0 'closest point to A on B' ) +insert ( 1558 2617 0 'closest point to A on B' ) +insert ( 1559 2617 0 'closest point to A on B' ) +insert ( 1567 2617 0 'closest point to A on B' ) +insert ( 1577 2617 0 'closest point to A on B' ) +insert ( 1578 2617 0 'closest point to A on B' ) +insert ( 1583 2617 0 multiply ) +insert ( 1584 2617 0 multiply ) +insert ( 1585 2617 0 divide ) +insert ( 1586 2617 0 'not equal' ) +insert ( 1587 2617 0 'less than by length' ) +insert ( 1588 2617 0 'less than or equal by length' ) +insert ( 1589 2617 0 'greater than by length' ) +insert ( 1590 2617 0 'greater than or equal by length' ) +insert ( 1591 2617 0 'distance between endpoints' ) +insert ( 1611 2617 0 intersect ) +insert ( 1612 2617 0 parallel ) +insert ( 1613 2617 0 perpendicular ) +insert ( 1614 2617 0 horizontal ) +insert ( 1615 2617 0 vertical ) +insert ( 1616 2617 0 equal ) +insert ( 1617 2617 0 'intersection point' ) +insert ( 4161 2617 0 'is above' ) +insert ( 4162 2617 0 'is below' ) +insert ( 1220 2617 0 equal ) +insert ( 1221 2617 0 'not equal' ) +insert ( 1222 2617 0 'less than' ) +insert ( 1223 2617 0 'less than or equal' ) +insert ( 1224 2617 0 'greater than' ) +insert ( 1225 2617 0 'greater than or equal' ) +insert ( 3147 2617 0 'bitwise not' ) +insert ( 3148 2617 0 'bitwise and' ) +insert ( 3149 2617 0 'bitwise or' ) +insert ( 3362 2617 0 equal ) +insert ( 3363 2617 0 'not equal' ) +insert ( 3364 2617 0 'less than' ) +insert ( 3365 2617 0 'less than or equal' ) +insert ( 3366 2617 0 'greater than' ) +insert ( 3367 2617 0 'greater than or equal' ) +insert ( 3368 2617 0 'bitwise not' ) +insert ( 3369 2617 0 'bitwise and' ) +insert ( 3370 2617 0 'bitwise or' ) +insert ( 1201 2617 0 equal ) +insert ( 1202 2617 0 'not equal' ) +insert ( 1203 2617 0 'less than' ) +insert ( 1204 2617 0 'less than or equal' ) +insert ( 1205 2617 0 'greater than' ) +insert ( 1206 2617 0 'greater than or equal' ) +insert ( 931 2617 0 'is subnet' ) +insert ( 932 2617 0 'is subnet or equal' ) +insert ( 933 2617 0 'is supernet' ) +insert ( 934 2617 0 'is supernet or equal' ) +insert ( 3552 2617 0 'overlaps (is subnet or supernet)' ) +insert ( 2634 2617 0 'bitwise not' ) +insert ( 2635 2617 0 'bitwise and' ) +insert ( 2636 2617 0 'bitwise or' ) +insert ( 2637 2617 0 add ) +insert ( 2638 2617 0 add ) +insert ( 2639 2617 0 subtract ) +insert ( 2640 2617 0 subtract ) +insert ( 1625 2617 0 'matches LIKE expression, case-insensitive' ) +insert ( 1626 2617 0 'does not match LIKE expression, case-insensitive' ) +insert ( 1627 2617 0 'matches LIKE expression, case-insensitive' ) +insert ( 1628 2617 0 'does not match LIKE expression, case-insensitive' ) +insert ( 1629 2617 0 'matches LIKE expression, case-insensitive' ) +insert ( 1630 2617 0 'does not match LIKE expression, case-insensitive' ) +insert ( 1751 2617 0 negate ) +insert ( 1752 2617 0 equal ) +insert ( 1753 2617 0 'not equal' ) +insert ( 1754 2617 0 'less than' ) +insert ( 1755 2617 0 'less than or equal' ) +insert ( 1756 2617 0 'greater than' ) +insert ( 1757 2617 0 'greater than or equal' ) +insert ( 1758 2617 0 add ) +insert ( 1759 2617 0 subtract ) +insert ( 1760 2617 0 multiply ) +insert ( 1761 2617 0 divide ) +insert ( 1762 2617 0 modulus ) +insert ( 1038 2617 0 exponentiation ) +insert ( 1763 2617 0 'absolute value' ) +insert ( 1784 2617 0 equal ) +insert ( 1785 2617 0 'not equal' ) +insert ( 1786 2617 0 'less than' ) +insert ( 1787 2617 0 'greater than' ) +insert ( 1788 2617 0 'less than or equal' ) +insert ( 1789 2617 0 'greater than or equal' ) +insert ( 1791 2617 0 'bitwise and' ) +insert ( 1792 2617 0 'bitwise or' ) +insert ( 1793 2617 0 'bitwise exclusive or' ) +insert ( 1794 2617 0 'bitwise not' ) +insert ( 1795 2617 0 'bitwise shift left' ) +insert ( 1796 2617 0 'bitwise shift right' ) +insert ( 1797 2617 0 concatenate ) +insert ( 1800 2617 0 add ) +insert ( 1801 2617 0 subtract ) +insert ( 1802 2617 0 add ) +insert ( 1803 2617 0 subtract ) +insert ( 1804 2617 0 equal ) +insert ( 1805 2617 0 'not equal' ) +insert ( 1806 2617 0 'less than' ) +insert ( 1807 2617 0 'greater than' ) +insert ( 1808 2617 0 'less than or equal' ) +insert ( 1809 2617 0 'greater than or equal' ) +insert ( 1849 2617 0 add ) +insert ( 1862 2617 0 equal ) +insert ( 1863 2617 0 'not equal' ) +insert ( 1864 2617 0 'less than' ) +insert ( 1865 2617 0 'greater than' ) +insert ( 1866 2617 0 'less than or equal' ) +insert ( 1867 2617 0 'greater than or equal' ) +insert ( 1868 2617 0 equal ) +insert ( 1869 2617 0 'not equal' ) +insert ( 1870 2617 0 'less than' ) +insert ( 1871 2617 0 'greater than' ) +insert ( 1872 2617 0 'less than or equal' ) +insert ( 1873 2617 0 'greater than or equal' ) +insert ( 1874 2617 0 'bitwise and' ) +insert ( 1875 2617 0 'bitwise or' ) +insert ( 1876 2617 0 'bitwise exclusive or' ) +insert ( 1877 2617 0 'bitwise not' ) +insert ( 1878 2617 0 'bitwise shift left' ) +insert ( 1879 2617 0 'bitwise shift right' ) +insert ( 1880 2617 0 'bitwise and' ) +insert ( 1881 2617 0 'bitwise or' ) +insert ( 1882 2617 0 'bitwise exclusive or' ) +insert ( 1883 2617 0 'bitwise not' ) +insert ( 1884 2617 0 'bitwise shift left' ) +insert ( 1885 2617 0 'bitwise shift right' ) +insert ( 1886 2617 0 'bitwise and' ) +insert ( 1887 2617 0 'bitwise or' ) +insert ( 1888 2617 0 'bitwise exclusive or' ) +insert ( 1889 2617 0 'bitwise not' ) +insert ( 1890 2617 0 'bitwise shift left' ) +insert ( 1891 2617 0 'bitwise shift right' ) +insert ( 1916 2617 0 'unary plus' ) +insert ( 1917 2617 0 'unary plus' ) +insert ( 1918 2617 0 'unary plus' ) +insert ( 1919 2617 0 'unary plus' ) +insert ( 1920 2617 0 'unary plus' ) +insert ( 1921 2617 0 'unary plus' ) +insert ( 1955 2617 0 equal ) +insert ( 1956 2617 0 'not equal' ) +insert ( 1957 2617 0 'less than' ) +insert ( 1958 2617 0 'less than or equal' ) +insert ( 1959 2617 0 'greater than' ) +insert ( 1960 2617 0 'greater than or equal' ) +insert ( 2016 2617 0 'matches LIKE expression' ) +insert ( 2017 2617 0 'does not match LIKE expression' ) +insert ( 2018 2617 0 concatenate ) +insert ( 2060 2617 0 equal ) +insert ( 2061 2617 0 'not equal' ) +insert ( 2062 2617 0 'less than' ) +insert ( 2063 2617 0 'less than or equal' ) +insert ( 2064 2617 0 'greater than' ) +insert ( 2065 2617 0 'greater than or equal' ) +insert ( 2066 2617 0 add ) +insert ( 2067 2617 0 subtract ) +insert ( 2068 2617 0 subtract ) +insert ( 2314 2617 0 'less than' ) +insert ( 2315 2617 0 'less than or equal' ) +insert ( 2317 2617 0 'greater than or equal' ) +insert ( 2318 2617 0 'greater than' ) +insert ( 2326 2617 0 'less than' ) +insert ( 2327 2617 0 'less than or equal' ) +insert ( 2329 2617 0 'greater than or equal' ) +insert ( 2330 2617 0 'greater than' ) +insert ( 2345 2617 0 'less than' ) +insert ( 2346 2617 0 'less than or equal' ) +insert ( 2347 2617 0 equal ) +insert ( 2348 2617 0 'greater than or equal' ) +insert ( 2349 2617 0 'greater than' ) +insert ( 2350 2617 0 'not equal' ) +insert ( 2358 2617 0 'less than' ) +insert ( 2359 2617 0 'less than or equal' ) +insert ( 2360 2617 0 equal ) +insert ( 2361 2617 0 'greater than or equal' ) +insert ( 2362 2617 0 'greater than' ) +insert ( 2363 2617 0 'not equal' ) +insert ( 2371 2617 0 'less than' ) +insert ( 2372 2617 0 'less than or equal' ) +insert ( 2373 2617 0 equal ) +insert ( 2374 2617 0 'greater than or equal' ) +insert ( 2375 2617 0 'greater than' ) +insert ( 2376 2617 0 'not equal' ) +insert ( 2384 2617 0 'less than' ) +insert ( 2385 2617 0 'less than or equal' ) +insert ( 2386 2617 0 equal ) +insert ( 2387 2617 0 'greater than or equal' ) +insert ( 2388 2617 0 'greater than' ) +insert ( 2389 2617 0 'not equal' ) +insert ( 2534 2617 0 'less than' ) +insert ( 2535 2617 0 'less than or equal' ) +insert ( 2536 2617 0 equal ) +insert ( 2537 2617 0 'greater than or equal' ) +insert ( 2538 2617 0 'greater than' ) +insert ( 2539 2617 0 'not equal' ) +insert ( 2540 2617 0 'less than' ) +insert ( 2541 2617 0 'less than or equal' ) +insert ( 2542 2617 0 equal ) +insert ( 2543 2617 0 'greater than or equal' ) +insert ( 2544 2617 0 'greater than' ) +insert ( 2545 2617 0 'not equal' ) +insert ( 2551 2617 0 add ) +insert ( 2552 2617 0 add ) +insert ( 2553 2617 0 add ) +insert ( 2554 2617 0 add ) +insert ( 2555 2617 0 add ) +insert ( 2570 2617 0 'is below' ) +insert ( 2571 2617 0 'overlaps or is below' ) +insert ( 2572 2617 0 'overlaps or is above' ) +insert ( 2573 2617 0 'is above' ) +insert ( 2574 2617 0 'is below' ) +insert ( 2575 2617 0 'overlaps or is below' ) +insert ( 2576 2617 0 'overlaps or is above' ) +insert ( 2577 2617 0 'is above' ) +insert ( 2589 2617 0 'overlaps or is below' ) +insert ( 2590 2617 0 'overlaps or is above' ) +insert ( 2750 2617 0 overlaps ) +insert ( 2751 2617 0 contains ) +insert ( 2752 2617 0 'is contained by' ) +insert ( 2779 2617 0 concatenate ) +insert ( 2780 2617 0 concatenate ) +insert ( 2972 2617 0 equal ) +insert ( 2973 2617 0 'not equal' ) +insert ( 2974 2617 0 'less than' ) +insert ( 2975 2617 0 'greater than' ) +insert ( 2976 2617 0 'less than or equal' ) +insert ( 2977 2617 0 'greater than or equal' ) +insert ( 3222 2617 0 equal ) +insert ( 3223 2617 0 'not equal' ) +insert ( 3224 2617 0 'less than' ) +insert ( 3225 2617 0 'greater than' ) +insert ( 3226 2617 0 'less than or equal' ) +insert ( 3227 2617 0 'greater than or equal' ) +insert ( 3228 2617 0 minus ) +insert ( 5025 2617 0 add ) +insert ( 5026 2617 0 add ) +insert ( 5027 2617 0 subtract ) +insert ( 3516 2617 0 equal ) +insert ( 3517 2617 0 'not equal' ) +insert ( 3518 2617 0 'less than' ) +insert ( 3519 2617 0 'greater than' ) +insert ( 3520 2617 0 'less than or equal' ) +insert ( 3521 2617 0 'greater than or equal' ) +insert ( 3627 2617 0 'less than' ) +insert ( 3628 2617 0 'less than or equal' ) +insert ( 3629 2617 0 equal ) +insert ( 3630 2617 0 'not equal' ) +insert ( 3631 2617 0 'greater than or equal' ) +insert ( 3632 2617 0 'greater than' ) +insert ( 3633 2617 0 concatenate ) +insert ( 3636 2617 0 'text search match' ) +insert ( 3637 2617 0 'text search match' ) +insert ( 3660 2617 0 'deprecated, use @@ instead' ) +insert ( 3661 2617 0 'deprecated, use @@ instead' ) +insert ( 3674 2617 0 'less than' ) +insert ( 3675 2617 0 'less than or equal' ) +insert ( 3676 2617 0 equal ) +insert ( 3677 2617 0 'not equal' ) +insert ( 3678 2617 0 'greater than or equal' ) +insert ( 3679 2617 0 'greater than' ) +insert ( 3680 2617 0 AND-concatenate ) +insert ( 3681 2617 0 OR-concatenate ) +insert ( 5005 2617 0 phrase-concatenate ) +insert ( 3682 2617 0 'NOT tsquery' ) +insert ( 3693 2617 0 contains ) +insert ( 3694 2617 0 'is contained by' ) +insert ( 3762 2617 0 'text search match' ) +insert ( 3763 2617 0 'text search match' ) +insert ( 2988 2617 0 equal ) +insert ( 2989 2617 0 'not equal' ) +insert ( 2990 2617 0 'less than' ) +insert ( 2991 2617 0 'greater than' ) +insert ( 2992 2617 0 'less than or equal' ) +insert ( 2993 2617 0 'greater than or equal' ) +insert ( 3188 2617 0 identical ) +insert ( 3189 2617 0 'not identical' ) +insert ( 3190 2617 0 'less than' ) +insert ( 3191 2617 0 'greater than' ) +insert ( 3192 2617 0 'less than or equal' ) +insert ( 3193 2617 0 'greater than or equal' ) +insert ( 3882 2617 0 equal ) +insert ( 3883 2617 0 'not equal' ) +insert ( 3884 2617 0 'less than' ) +insert ( 3885 2617 0 'less than or equal' ) +insert ( 3886 2617 0 'greater than or equal' ) +insert ( 3887 2617 0 'greater than' ) +insert ( 3888 2617 0 overlaps ) +insert ( 3889 2617 0 contains ) +insert ( 3890 2617 0 contains ) +insert ( 3891 2617 0 'is contained by' ) +insert ( 3892 2617 0 'is contained by' ) +insert ( 3893 2617 0 'is left of' ) +insert ( 3894 2617 0 'is right of' ) +insert ( 3895 2617 0 'overlaps or is left of' ) +insert ( 3896 2617 0 'overlaps or is right of' ) +insert ( 3897 2617 0 'is adjacent to' ) +insert ( 3898 2617 0 'range union' ) +insert ( 3899 2617 0 'range difference' ) +insert ( 3900 2617 0 'range intersection' ) +insert ( 3962 2617 0 'get json object field' ) +insert ( 3963 2617 0 'get json object field as text' ) +insert ( 3964 2617 0 'get json array element' ) +insert ( 3965 2617 0 'get json array element as text' ) +insert ( 3966 2617 0 'get value from json with path elements' ) +insert ( 3967 2617 0 'get value from json as text with path elements' ) +insert ( 3211 2617 0 'get jsonb object field' ) +insert ( 3477 2617 0 'get jsonb object field as text' ) +insert ( 3212 2617 0 'get jsonb array element' ) +insert ( 3481 2617 0 'get jsonb array element as text' ) +insert ( 3213 2617 0 'get value from jsonb with path elements' ) +insert ( 3206 2617 0 'get value from jsonb as text with path elements' ) +insert ( 3240 2617 0 equal ) +insert ( 3241 2617 0 'not equal' ) +insert ( 3242 2617 0 'less than' ) +insert ( 3243 2617 0 'greater than' ) +insert ( 3244 2617 0 'less than or equal' ) +insert ( 3245 2617 0 'greater than or equal' ) +insert ( 3246 2617 0 contains ) +insert ( 3247 2617 0 'key exists' ) +insert ( 3248 2617 0 'any key exists' ) +insert ( 3249 2617 0 'all keys exist' ) +insert ( 3250 2617 0 'is contained by' ) +insert ( 3284 2617 0 concatenate ) +insert ( 3285 2617 0 'delete object field' ) +insert ( 3398 2617 0 'delete object fields' ) +insert ( 3286 2617 0 'delete array element' ) +insert ( 3287 2617 0 'delete path' ) +insert ( 4012 2617 0 'jsonpath exists' ) +insert ( 4013 2617 0 'jsonpath match' ) +insert ( 2860 2617 0 equal ) +insert ( 2861 2617 0 'not equal' ) +insert ( 2862 2617 0 'less than' ) +insert ( 2863 2617 0 'less than or equal' ) +insert ( 2864 2617 0 'greater than or equal' ) +insert ( 2865 2617 0 'greater than' ) +insert ( 2866 2617 0 overlaps ) +insert ( 2867 2617 0 overlaps ) +insert ( 2868 2617 0 overlaps ) +insert ( 2869 2617 0 contains ) +insert ( 2870 2617 0 contains ) +insert ( 2871 2617 0 contains ) +insert ( 2872 2617 0 'is contained by' ) +insert ( 2873 2617 0 'is contained by' ) +insert ( 2874 2617 0 'is contained by' ) +insert ( 4539 2617 0 contains ) +insert ( 4540 2617 0 'is contained by' ) +insert ( 2875 2617 0 'overlaps or is left of' ) +insert ( 2876 2617 0 'overlaps or is left of' ) +insert ( 2877 2617 0 'overlaps or is left of' ) +insert ( 3585 2617 0 'overlaps or is right of' ) +insert ( 4035 2617 0 'overlaps or is right of' ) +insert ( 4142 2617 0 'overlaps or is right of' ) +insert ( 4179 2617 0 'is adjacent to' ) +insert ( 4180 2617 0 'is adjacent to' ) +insert ( 4198 2617 0 'is adjacent to' ) +insert ( 4392 2617 0 'multirange union' ) +insert ( 4393 2617 0 'multirange minus' ) +insert ( 4394 2617 0 'multirange intersect' ) +insert ( 4395 2617 0 'is left of' ) +insert ( 4396 2617 0 'is left of' ) +insert ( 4397 2617 0 'is left of' ) +insert ( 4398 2617 0 'is right of' ) +insert ( 4399 2617 0 'is right of' ) +insert ( 4400 2617 0 'is right of' ) +insert ( 2 2601 0 'heap table access method' ) +insert ( 403 2601 0 'b-tree index access method' ) +insert ( 405 2601 0 'hash index access method' ) +insert ( 783 2601 0 'GiST index access method' ) +insert ( 2742 2601 0 'GIN index access method' ) +insert ( 4000 2601 0 'SP-GiST index access method' ) +insert ( 3580 2601 0 'block range index (BRIN) access method' ) +insert ( 12 2612 0 'built-in functions' ) +insert ( 13 2612 0 'dynamically-loaded C functions' ) +insert ( 14 2612 0 'SQL-language functions' ) +insert ( 11 2615 0 'system catalog schema' ) +insert ( 99 2615 0 'reserved schema for TOAST tables' ) +insert ( 2200 2615 0 'standard public schema' ) +insert ( 4402 2607 0 'conversion for KOI8R to MULE_INTERNAL' ) +insert ( 4403 2607 0 'conversion for MULE_INTERNAL to KOI8R' ) +insert ( 4404 2607 0 'conversion for ISO-8859-5 to MULE_INTERNAL' ) +insert ( 4405 2607 0 'conversion for MULE_INTERNAL to ISO-8859-5' ) +insert ( 4406 2607 0 'conversion for WIN1251 to MULE_INTERNAL' ) +insert ( 4407 2607 0 'conversion for MULE_INTERNAL to WIN1251' ) +insert ( 4408 2607 0 'conversion for WIN866 to MULE_INTERNAL' ) +insert ( 4409 2607 0 'conversion for MULE_INTERNAL to WIN866' ) +insert ( 4410 2607 0 'conversion for KOI8R to WIN1251' ) +insert ( 4411 2607 0 'conversion for WIN1251 to KOI8R' ) +insert ( 4412 2607 0 'conversion for KOI8R to WIN866' ) +insert ( 4413 2607 0 'conversion for WIN866 to KOI8R' ) +insert ( 4414 2607 0 'conversion for WIN866 to WIN1251' ) +insert ( 4415 2607 0 'conversion for WIN1251 to WIN866' ) +insert ( 4416 2607 0 'conversion for ISO-8859-5 to KOI8R' ) +insert ( 4417 2607 0 'conversion for KOI8R to ISO-8859-5' ) +insert ( 4418 2607 0 'conversion for ISO-8859-5 to WIN1251' ) +insert ( 4419 2607 0 'conversion for WIN1251 to ISO-8859-5' ) +insert ( 4420 2607 0 'conversion for ISO-8859-5 to WIN866' ) +insert ( 4421 2607 0 'conversion for WIN866 to ISO-8859-5' ) +insert ( 4422 2607 0 'conversion for EUC_CN to MULE_INTERNAL' ) +insert ( 4423 2607 0 'conversion for MULE_INTERNAL to EUC_CN' ) +insert ( 4424 2607 0 'conversion for EUC_JP to SJIS' ) +insert ( 4425 2607 0 'conversion for SJIS to EUC_JP' ) +insert ( 4426 2607 0 'conversion for EUC_JP to MULE_INTERNAL' ) +insert ( 4427 2607 0 'conversion for SJIS to MULE_INTERNAL' ) +insert ( 4428 2607 0 'conversion for MULE_INTERNAL to EUC_JP' ) +insert ( 4429 2607 0 'conversion for MULE_INTERNAL to SJIS' ) +insert ( 4430 2607 0 'conversion for EUC_KR to MULE_INTERNAL' ) +insert ( 4431 2607 0 'conversion for MULE_INTERNAL to EUC_KR' ) +insert ( 4432 2607 0 'conversion for EUC_TW to BIG5' ) +insert ( 4433 2607 0 'conversion for BIG5 to EUC_TW' ) +insert ( 4434 2607 0 'conversion for EUC_TW to MULE_INTERNAL' ) +insert ( 4435 2607 0 'conversion for BIG5 to MULE_INTERNAL' ) +insert ( 4436 2607 0 'conversion for MULE_INTERNAL to EUC_TW' ) +insert ( 4437 2607 0 'conversion for MULE_INTERNAL to BIG5' ) +insert ( 4438 2607 0 'conversion for LATIN2 to MULE_INTERNAL' ) +insert ( 4439 2607 0 'conversion for MULE_INTERNAL to LATIN2' ) +insert ( 4440 2607 0 'conversion for WIN1250 to MULE_INTERNAL' ) +insert ( 4441 2607 0 'conversion for MULE_INTERNAL to WIN1250' ) +insert ( 4442 2607 0 'conversion for LATIN2 to WIN1250' ) +insert ( 4443 2607 0 'conversion for WIN1250 to LATIN2' ) +insert ( 4444 2607 0 'conversion for LATIN1 to MULE_INTERNAL' ) +insert ( 4445 2607 0 'conversion for MULE_INTERNAL to LATIN1' ) +insert ( 4446 2607 0 'conversion for LATIN3 to MULE_INTERNAL' ) +insert ( 4447 2607 0 'conversion for MULE_INTERNAL to LATIN3' ) +insert ( 4448 2607 0 'conversion for LATIN4 to MULE_INTERNAL' ) +insert ( 4449 2607 0 'conversion for MULE_INTERNAL to LATIN4' ) +insert ( 4452 2607 0 'conversion for BIG5 to UTF8' ) +insert ( 4453 2607 0 'conversion for UTF8 to BIG5' ) +insert ( 4454 2607 0 'conversion for UTF8 to KOI8R' ) +insert ( 4455 2607 0 'conversion for KOI8R to UTF8' ) +insert ( 4456 2607 0 'conversion for UTF8 to KOI8U' ) +insert ( 4457 2607 0 'conversion for KOI8U to UTF8' ) +insert ( 4458 2607 0 'conversion for UTF8 to WIN866' ) +insert ( 4459 2607 0 'conversion for WIN866 to UTF8' ) +insert ( 4460 2607 0 'conversion for UTF8 to WIN874' ) +insert ( 4461 2607 0 'conversion for WIN874 to UTF8' ) +insert ( 4462 2607 0 'conversion for UTF8 to WIN1250' ) +insert ( 4463 2607 0 'conversion for WIN1250 to UTF8' ) +insert ( 4464 2607 0 'conversion for UTF8 to WIN1251' ) +insert ( 4465 2607 0 'conversion for WIN1251 to UTF8' ) +insert ( 4466 2607 0 'conversion for UTF8 to WIN1252' ) +insert ( 4467 2607 0 'conversion for WIN1252 to UTF8' ) +insert ( 4468 2607 0 'conversion for UTF8 to WIN1253' ) +insert ( 4469 2607 0 'conversion for WIN1253 to UTF8' ) +insert ( 4470 2607 0 'conversion for UTF8 to WIN1254' ) +insert ( 4471 2607 0 'conversion for WIN1254 to UTF8' ) +insert ( 4472 2607 0 'conversion for UTF8 to WIN1255' ) +insert ( 4473 2607 0 'conversion for WIN1255 to UTF8' ) +insert ( 4474 2607 0 'conversion for UTF8 to WIN1256' ) +insert ( 4475 2607 0 'conversion for WIN1256 to UTF8' ) +insert ( 4476 2607 0 'conversion for UTF8 to WIN1257' ) +insert ( 4477 2607 0 'conversion for WIN1257 to UTF8' ) +insert ( 4478 2607 0 'conversion for UTF8 to WIN1258' ) +insert ( 4479 2607 0 'conversion for WIN1258 to UTF8' ) +insert ( 4480 2607 0 'conversion for EUC_CN to UTF8' ) +insert ( 4481 2607 0 'conversion for UTF8 to EUC_CN' ) +insert ( 4482 2607 0 'conversion for EUC_JP to UTF8' ) +insert ( 4483 2607 0 'conversion for UTF8 to EUC_JP' ) +insert ( 4484 2607 0 'conversion for EUC_KR to UTF8' ) +insert ( 4485 2607 0 'conversion for UTF8 to EUC_KR' ) +insert ( 4486 2607 0 'conversion for EUC_TW to UTF8' ) +insert ( 4487 2607 0 'conversion for UTF8 to EUC_TW' ) +insert ( 4488 2607 0 'conversion for GB18030 to UTF8' ) +insert ( 4489 2607 0 'conversion for UTF8 to GB18030' ) +insert ( 4490 2607 0 'conversion for GBK to UTF8' ) +insert ( 4491 2607 0 'conversion for UTF8 to GBK' ) +insert ( 4492 2607 0 'conversion for UTF8 to LATIN2' ) +insert ( 4493 2607 0 'conversion for LATIN2 to UTF8' ) +insert ( 4494 2607 0 'conversion for UTF8 to LATIN3' ) +insert ( 4495 2607 0 'conversion for LATIN3 to UTF8' ) +insert ( 4496 2607 0 'conversion for UTF8 to LATIN4' ) +insert ( 4497 2607 0 'conversion for LATIN4 to UTF8' ) +insert ( 4498 2607 0 'conversion for UTF8 to LATIN5' ) +insert ( 4499 2607 0 'conversion for LATIN5 to UTF8' ) +insert ( 4500 2607 0 'conversion for UTF8 to LATIN6' ) +insert ( 4501 2607 0 'conversion for LATIN6 to UTF8' ) +insert ( 4502 2607 0 'conversion for UTF8 to LATIN7' ) +insert ( 4503 2607 0 'conversion for LATIN7 to UTF8' ) +insert ( 4504 2607 0 'conversion for UTF8 to LATIN8' ) +insert ( 4505 2607 0 'conversion for LATIN8 to UTF8' ) +insert ( 4506 2607 0 'conversion for UTF8 to LATIN9' ) +insert ( 4507 2607 0 'conversion for LATIN9 to UTF8' ) +insert ( 4508 2607 0 'conversion for UTF8 to LATIN10' ) +insert ( 4509 2607 0 'conversion for LATIN10 to UTF8' ) +insert ( 4510 2607 0 'conversion for UTF8 to ISO-8859-5' ) +insert ( 4511 2607 0 'conversion for ISO-8859-5 to UTF8' ) +insert ( 4512 2607 0 'conversion for UTF8 to ISO-8859-6' ) +insert ( 4513 2607 0 'conversion for ISO-8859-6 to UTF8' ) +insert ( 4514 2607 0 'conversion for UTF8 to ISO-8859-7' ) +insert ( 4515 2607 0 'conversion for ISO-8859-7 to UTF8' ) +insert ( 4516 2607 0 'conversion for UTF8 to ISO-8859-8' ) +insert ( 4517 2607 0 'conversion for ISO-8859-8 to UTF8' ) +insert ( 4518 2607 0 'conversion for LATIN1 to UTF8' ) +insert ( 4519 2607 0 'conversion for UTF8 to LATIN1' ) +insert ( 4520 2607 0 'conversion for JOHAB to UTF8' ) +insert ( 4521 2607 0 'conversion for UTF8 to JOHAB' ) +insert ( 4522 2607 0 'conversion for SJIS to UTF8' ) +insert ( 4523 2607 0 'conversion for UTF8 to SJIS' ) +insert ( 4524 2607 0 'conversion for UHC to UTF8' ) +insert ( 4525 2607 0 'conversion for UTF8 to UHC' ) +insert ( 4526 2607 0 'conversion for EUC_JIS_2004 to UTF8' ) +insert ( 4527 2607 0 'conversion for UTF8 to EUC_JIS_2004' ) +insert ( 4528 2607 0 'conversion for SHIFT_JIS_2004 to UTF8' ) +insert ( 4529 2607 0 'conversion for UTF8 to SHIFT_JIS_2004' ) +insert ( 4530 2607 0 'conversion for EUC_JIS_2004 to SHIFT_JIS_2004' ) +insert ( 4531 2607 0 'conversion for SHIFT_JIS_2004 to EUC_JIS_2004' ) +insert ( 3748 3602 0 'simple configuration' ) +insert ( 3765 3600 0 'simple dictionary: just lower case and check for stopword' ) +insert ( 3722 3601 0 'default word parser' ) +insert ( 3727 3764 0 'simple dictionary: just lower case and check for stopword' ) +insert ( 3730 3764 0 'synonym dictionary: replace word by its synonym' ) +insert ( 3733 3764 0 'ispell dictionary' ) +insert ( 3742 3764 0 'thesaurus dictionary: phrase by phrase substitution' ) +insert ( 100 3456 0 'database''s default collation' ) +insert ( 950 3456 0 'standard C collation' ) +insert ( 951 3456 0 'standard POSIX collation' ) +insert ( 962 3456 0 'sorts by Unicode code point' ) +insert ( 963 3456 0 'sorts using the Unicode Collation Algorithm with default settings' ) +close pg_description +create pg_cast 2605 + ( + oid = oid , + castsource = oid , + casttarget = oid , + castfunc = oid , + castcontext = char , + castmethod = char + ) +open pg_cast +insert ( 10000 20 21 714 a f ) +insert ( 10001 20 23 480 a f ) +insert ( 10002 20 700 652 i f ) +insert ( 10003 20 701 482 i f ) +insert ( 10004 20 1700 1781 i f ) +insert ( 10005 21 20 754 i f ) +insert ( 10006 21 23 313 i f ) +insert ( 10007 21 700 236 i f ) +insert ( 10008 21 701 235 i f ) +insert ( 10009 21 1700 1782 i f ) +insert ( 10010 23 20 481 i f ) +insert ( 10011 23 21 314 a f ) +insert ( 10012 23 700 318 i f ) +insert ( 10013 23 701 316 i f ) +insert ( 10014 23 1700 1740 i f ) +insert ( 10015 700 20 653 a f ) +insert ( 10016 700 21 238 a f ) +insert ( 10017 700 23 319 a f ) +insert ( 10018 700 701 311 i f ) +insert ( 10019 700 1700 1742 a f ) +insert ( 10020 701 20 483 a f ) +insert ( 10021 701 21 237 a f ) +insert ( 10022 701 23 317 a f ) +insert ( 10023 701 700 312 a f ) +insert ( 10024 701 1700 1743 a f ) +insert ( 10025 1700 20 1779 a f ) +insert ( 10026 1700 21 1783 a f ) +insert ( 10027 1700 23 1744 a f ) +insert ( 10028 1700 700 1745 i f ) +insert ( 10029 1700 701 1746 i f ) +insert ( 10030 790 1700 3823 a f ) +insert ( 10031 1700 790 3824 a f ) +insert ( 10032 23 790 3811 a f ) +insert ( 10033 20 790 3812 a f ) +insert ( 10034 23 16 2557 e f ) +insert ( 10035 16 23 2558 e f ) +insert ( 10036 5069 28 5071 e f ) +insert ( 10037 20 26 1287 i f ) +insert ( 10038 21 26 313 i f ) +insert ( 10039 23 26 0 i b ) +insert ( 10040 26 20 1288 a f ) +insert ( 10041 26 23 0 a b ) +insert ( 10042 26 24 0 i b ) +insert ( 10043 24 26 0 i b ) +insert ( 10044 20 24 1287 i f ) +insert ( 10045 21 24 313 i f ) +insert ( 10046 23 24 0 i b ) +insert ( 10047 24 20 1288 a f ) +insert ( 10048 24 23 0 a b ) +insert ( 10049 24 2202 0 i b ) +insert ( 10050 2202 24 0 i b ) +insert ( 10051 26 2202 0 i b ) +insert ( 10052 2202 26 0 i b ) +insert ( 10053 20 2202 1287 i f ) +insert ( 10054 21 2202 313 i f ) +insert ( 10055 23 2202 0 i b ) +insert ( 10056 2202 20 1288 a f ) +insert ( 10057 2202 23 0 a b ) +insert ( 10058 26 2203 0 i b ) +insert ( 10059 2203 26 0 i b ) +insert ( 10060 20 2203 1287 i f ) +insert ( 10061 21 2203 313 i f ) +insert ( 10062 23 2203 0 i b ) +insert ( 10063 2203 20 1288 a f ) +insert ( 10064 2203 23 0 a b ) +insert ( 10065 2203 2204 0 i b ) +insert ( 10066 2204 2203 0 i b ) +insert ( 10067 26 2204 0 i b ) +insert ( 10068 2204 26 0 i b ) +insert ( 10069 20 2204 1287 i f ) +insert ( 10070 21 2204 313 i f ) +insert ( 10071 23 2204 0 i b ) +insert ( 10072 2204 20 1288 a f ) +insert ( 10073 2204 23 0 a b ) +insert ( 10074 26 2205 0 i b ) +insert ( 10075 2205 26 0 i b ) +insert ( 10076 20 2205 1287 i f ) +insert ( 10077 21 2205 313 i f ) +insert ( 10078 23 2205 0 i b ) +insert ( 10079 2205 20 1288 a f ) +insert ( 10080 2205 23 0 a b ) +insert ( 10081 26 4191 0 i b ) +insert ( 10082 4191 26 0 i b ) +insert ( 10083 20 4191 1287 i f ) +insert ( 10084 21 4191 313 i f ) +insert ( 10085 23 4191 0 i b ) +insert ( 10086 4191 20 1288 a f ) +insert ( 10087 4191 23 0 a b ) +insert ( 10088 26 2206 0 i b ) +insert ( 10089 2206 26 0 i b ) +insert ( 10090 20 2206 1287 i f ) +insert ( 10091 21 2206 313 i f ) +insert ( 10092 23 2206 0 i b ) +insert ( 10093 2206 20 1288 a f ) +insert ( 10094 2206 23 0 a b ) +insert ( 10095 26 3734 0 i b ) +insert ( 10096 3734 26 0 i b ) +insert ( 10097 20 3734 1287 i f ) +insert ( 10098 21 3734 313 i f ) +insert ( 10099 23 3734 0 i b ) +insert ( 10100 3734 20 1288 a f ) +insert ( 10101 3734 23 0 a b ) +insert ( 10102 26 3769 0 i b ) +insert ( 10103 3769 26 0 i b ) +insert ( 10104 20 3769 1287 i f ) +insert ( 10105 21 3769 313 i f ) +insert ( 10106 23 3769 0 i b ) +insert ( 10107 3769 20 1288 a f ) +insert ( 10108 3769 23 0 a b ) +insert ( 10109 25 2205 1079 i f ) +insert ( 10110 1043 2205 1079 i f ) +insert ( 10111 26 4096 0 i b ) +insert ( 10112 4096 26 0 i b ) +insert ( 10113 20 4096 1287 i f ) +insert ( 10114 21 4096 313 i f ) +insert ( 10115 23 4096 0 i b ) +insert ( 10116 4096 20 1288 a f ) +insert ( 10117 4096 23 0 a b ) +insert ( 10118 26 4089 0 i b ) +insert ( 10119 4089 26 0 i b ) +insert ( 10120 20 4089 1287 i f ) +insert ( 10121 21 4089 313 i f ) +insert ( 10122 23 4089 0 i b ) +insert ( 10123 4089 20 1288 a f ) +insert ( 10124 4089 23 0 a b ) +insert ( 10125 25 1042 0 i b ) +insert ( 10126 25 1043 0 i b ) +insert ( 10127 1042 25 401 i f ) +insert ( 10128 1042 1043 401 i f ) +insert ( 10129 1043 25 0 i b ) +insert ( 10130 1043 1042 0 i b ) +insert ( 10131 18 25 946 i f ) +insert ( 10132 18 1042 860 a f ) +insert ( 10133 18 1043 946 a f ) +insert ( 10134 19 25 406 i f ) +insert ( 10135 19 1042 408 a f ) +insert ( 10136 19 1043 1401 a f ) +insert ( 10137 25 18 944 a f ) +insert ( 10138 1042 18 944 a f ) +insert ( 10139 1043 18 944 a f ) +insert ( 10140 25 19 407 i f ) +insert ( 10141 1042 19 409 i f ) +insert ( 10142 1043 19 1400 i f ) +insert ( 10143 18 23 77 e f ) +insert ( 10144 23 18 78 e f ) +insert ( 10145 194 25 0 i b ) +insert ( 10146 3361 17 0 i b ) +insert ( 10147 3361 25 0 i i ) +insert ( 10148 3402 17 0 i b ) +insert ( 10149 3402 25 0 i i ) +insert ( 10150 5017 17 0 i b ) +insert ( 10151 5017 25 0 i i ) +insert ( 10152 1082 1114 2024 i f ) +insert ( 10153 1082 1184 1174 i f ) +insert ( 10154 1083 1186 1370 i f ) +insert ( 10155 1083 1266 2047 i f ) +insert ( 10156 1114 1082 2029 a f ) +insert ( 10157 1114 1083 1316 a f ) +insert ( 10158 1114 1184 2028 i f ) +insert ( 10159 1184 1082 1178 a f ) +insert ( 10160 1184 1083 2019 a f ) +insert ( 10161 1184 1114 2027 a f ) +insert ( 10162 1184 1266 1388 a f ) +insert ( 10163 1186 1083 1419 a f ) +insert ( 10164 1266 1083 2046 a f ) +insert ( 10165 600 603 4091 a f ) +insert ( 10166 601 600 1532 e f ) +insert ( 10167 602 604 1449 a f ) +insert ( 10168 603 600 1534 e f ) +insert ( 10169 603 601 1541 e f ) +insert ( 10170 603 604 1448 a f ) +insert ( 10171 603 718 1479 e f ) +insert ( 10172 604 600 1540 e f ) +insert ( 10173 604 602 1447 a f ) +insert ( 10174 604 603 1446 e f ) +insert ( 10175 604 718 1474 e f ) +insert ( 10176 718 600 1416 e f ) +insert ( 10177 718 603 1480 e f ) +insert ( 10178 718 604 1544 e f ) +insert ( 10179 829 774 4123 i f ) +insert ( 10180 774 829 4124 i f ) +insert ( 10181 650 869 0 i b ) +insert ( 10182 869 650 1715 a f ) +insert ( 10183 1560 1562 0 i b ) +insert ( 10184 1562 1560 0 i b ) +insert ( 10185 20 1560 2075 e f ) +insert ( 10186 23 1560 1683 e f ) +insert ( 10187 1560 20 2076 e f ) +insert ( 10188 1560 23 1684 e f ) +insert ( 10189 650 25 730 a f ) +insert ( 10190 869 25 730 a f ) +insert ( 10191 16 25 2971 a f ) +insert ( 10192 142 25 0 a b ) +insert ( 10193 25 142 2896 e f ) +insert ( 10194 650 1043 730 a f ) +insert ( 10195 869 1043 730 a f ) +insert ( 10196 16 1043 2971 a f ) +insert ( 10197 142 1043 0 a b ) +insert ( 10198 1043 142 2896 e f ) +insert ( 10199 650 1042 730 a f ) +insert ( 10200 869 1042 730 a f ) +insert ( 10201 16 1042 2971 a f ) +insert ( 10202 142 1042 0 a b ) +insert ( 10203 1042 142 2896 e f ) +insert ( 10204 1042 1042 668 i f ) +insert ( 10205 1043 1043 669 i f ) +insert ( 10206 1083 1083 1968 i f ) +insert ( 10207 1114 1114 1961 i f ) +insert ( 10208 1184 1184 1967 i f ) +insert ( 10209 1186 1186 1200 i f ) +insert ( 10210 1266 1266 1969 i f ) +insert ( 10211 1560 1560 1685 i f ) +insert ( 10212 1562 1562 1687 i f ) +insert ( 10213 1700 1700 1703 i f ) +insert ( 10214 114 3802 0 a i ) +insert ( 10215 3802 114 0 a i ) +insert ( 10216 3802 16 3556 e f ) +insert ( 10217 3802 1700 3449 e f ) +insert ( 10218 3802 21 3450 e f ) +insert ( 10219 3802 23 3451 e f ) +insert ( 10220 3802 20 3452 e f ) +insert ( 10221 3802 700 3453 e f ) +insert ( 10222 3802 701 2580 e f ) +insert ( 10223 3904 4451 4281 e f ) +insert ( 10224 3926 4536 4296 e f ) +insert ( 10225 3906 4532 4284 e f ) +insert ( 10226 3912 4535 4293 e f ) +insert ( 10227 3908 4533 4287 e f ) +insert ( 10228 3910 4534 4290 e f ) +close pg_cast +create pg_enum 3501 + ( + oid = oid , + enumtypid = oid , + enumsortorder = float4 , + enumlabel = name + ) +open pg_enum +close pg_enum +create pg_namespace 2615 + ( + oid = oid , + nspname = name , + nspowner = oid , + nspacl = _aclitem + ) +open pg_namespace +insert ( 11 pg_catalog 10 _null_ ) +insert ( 99 pg_toast 10 _null_ ) +insert ( 2200 public 6171 _null_ ) +close pg_namespace +create pg_conversion 2607 + ( + oid = oid , + conname = name , + connamespace = oid , + conowner = oid , + conforencoding = int4 , + contoencoding = int4 , + conproc = regproc , + condefault = bool + ) +open pg_conversion +insert ( 4402 koi8_r_to_mic 11 10 22 7 4302 t ) +insert ( 4403 mic_to_koi8_r 11 10 7 22 4303 t ) +insert ( 4404 iso_8859_5_to_mic 11 10 25 7 4304 t ) +insert ( 4405 mic_to_iso_8859_5 11 10 7 25 4305 t ) +insert ( 4406 windows_1251_to_mic 11 10 23 7 4306 t ) +insert ( 4407 mic_to_windows_1251 11 10 7 23 4307 t ) +insert ( 4408 windows_866_to_mic 11 10 20 7 4308 t ) +insert ( 4409 mic_to_windows_866 11 10 7 20 4309 t ) +insert ( 4410 koi8_r_to_windows_1251 11 10 22 23 4310 t ) +insert ( 4411 windows_1251_to_koi8_r 11 10 23 22 4311 t ) +insert ( 4412 koi8_r_to_windows_866 11 10 22 20 4312 t ) +insert ( 4413 windows_866_to_koi8_r 11 10 20 22 4313 t ) +insert ( 4414 windows_866_to_windows_1251 11 10 20 23 4314 t ) +insert ( 4415 windows_1251_to_windows_866 11 10 23 20 4315 t ) +insert ( 4416 iso_8859_5_to_koi8_r 11 10 25 22 4316 t ) +insert ( 4417 koi8_r_to_iso_8859_5 11 10 22 25 4317 t ) +insert ( 4418 iso_8859_5_to_windows_1251 11 10 25 23 4318 t ) +insert ( 4419 windows_1251_to_iso_8859_5 11 10 23 25 4319 t ) +insert ( 4420 iso_8859_5_to_windows_866 11 10 25 20 4320 t ) +insert ( 4421 windows_866_to_iso_8859_5 11 10 20 25 4321 t ) +insert ( 4422 euc_cn_to_mic 11 10 2 7 4322 t ) +insert ( 4423 mic_to_euc_cn 11 10 7 2 4323 t ) +insert ( 4424 euc_jp_to_sjis 11 10 1 35 4324 t ) +insert ( 4425 sjis_to_euc_jp 11 10 35 1 4325 t ) +insert ( 4426 euc_jp_to_mic 11 10 1 7 4326 t ) +insert ( 4427 sjis_to_mic 11 10 35 7 4327 t ) +insert ( 4428 mic_to_euc_jp 11 10 7 1 4328 t ) +insert ( 4429 mic_to_sjis 11 10 7 35 4329 t ) +insert ( 4430 euc_kr_to_mic 11 10 3 7 4330 t ) +insert ( 4431 mic_to_euc_kr 11 10 7 3 4331 t ) +insert ( 4432 euc_tw_to_big5 11 10 4 36 4332 t ) +insert ( 4433 big5_to_euc_tw 11 10 36 4 4333 t ) +insert ( 4434 euc_tw_to_mic 11 10 4 7 4334 t ) +insert ( 4435 big5_to_mic 11 10 36 7 4335 t ) +insert ( 4436 mic_to_euc_tw 11 10 7 4 4336 t ) +insert ( 4437 mic_to_big5 11 10 7 36 4337 t ) +insert ( 4438 iso_8859_2_to_mic 11 10 9 7 4338 t ) +insert ( 4439 mic_to_iso_8859_2 11 10 7 9 4339 t ) +insert ( 4440 windows_1250_to_mic 11 10 29 7 4340 t ) +insert ( 4441 mic_to_windows_1250 11 10 7 29 4341 t ) +insert ( 4442 iso_8859_2_to_windows_1250 11 10 9 29 4342 t ) +insert ( 4443 windows_1250_to_iso_8859_2 11 10 29 9 4343 t ) +insert ( 4444 iso_8859_1_to_mic 11 10 8 7 4344 t ) +insert ( 4445 mic_to_iso_8859_1 11 10 7 8 4345 t ) +insert ( 4446 iso_8859_3_to_mic 11 10 10 7 4346 t ) +insert ( 4447 mic_to_iso_8859_3 11 10 7 10 4347 t ) +insert ( 4448 iso_8859_4_to_mic 11 10 11 7 4348 t ) +insert ( 4449 mic_to_iso_8859_4 11 10 7 11 4349 t ) +insert ( 4452 big5_to_utf8 11 10 36 6 4352 t ) +insert ( 4453 utf8_to_big5 11 10 6 36 4353 t ) +insert ( 4454 utf8_to_koi8_r 11 10 6 22 4354 t ) +insert ( 4455 koi8_r_to_utf8 11 10 22 6 4355 t ) +insert ( 4456 utf8_to_koi8_u 11 10 6 34 4356 t ) +insert ( 4457 koi8_u_to_utf8 11 10 34 6 4357 t ) +insert ( 4458 utf8_to_windows_866 11 10 6 20 4358 t ) +insert ( 4459 windows_866_to_utf8 11 10 20 6 4359 t ) +insert ( 4460 utf8_to_windows_874 11 10 6 21 4358 t ) +insert ( 4461 windows_874_to_utf8 11 10 21 6 4359 t ) +insert ( 4462 utf8_to_windows_1250 11 10 6 29 4358 t ) +insert ( 4463 windows_1250_to_utf8 11 10 29 6 4359 t ) +insert ( 4464 utf8_to_windows_1251 11 10 6 23 4358 t ) +insert ( 4465 windows_1251_to_utf8 11 10 23 6 4359 t ) +insert ( 4466 utf8_to_windows_1252 11 10 6 24 4358 t ) +insert ( 4467 windows_1252_to_utf8 11 10 24 6 4359 t ) +insert ( 4468 utf8_to_windows_1253 11 10 6 30 4358 t ) +insert ( 4469 windows_1253_to_utf8 11 10 30 6 4359 t ) +insert ( 4470 utf8_to_windows_1254 11 10 6 31 4358 t ) +insert ( 4471 windows_1254_to_utf8 11 10 31 6 4359 t ) +insert ( 4472 utf8_to_windows_1255 11 10 6 32 4358 t ) +insert ( 4473 windows_1255_to_utf8 11 10 32 6 4359 t ) +insert ( 4474 utf8_to_windows_1256 11 10 6 18 4358 t ) +insert ( 4475 windows_1256_to_utf8 11 10 18 6 4359 t ) +insert ( 4476 utf8_to_windows_1257 11 10 6 33 4358 t ) +insert ( 4477 windows_1257_to_utf8 11 10 33 6 4359 t ) +insert ( 4478 utf8_to_windows_1258 11 10 6 19 4358 t ) +insert ( 4479 windows_1258_to_utf8 11 10 19 6 4359 t ) +insert ( 4480 euc_cn_to_utf8 11 10 2 6 4360 t ) +insert ( 4481 utf8_to_euc_cn 11 10 6 2 4361 t ) +insert ( 4482 euc_jp_to_utf8 11 10 1 6 4362 t ) +insert ( 4483 utf8_to_euc_jp 11 10 6 1 4363 t ) +insert ( 4484 euc_kr_to_utf8 11 10 3 6 4364 t ) +insert ( 4485 utf8_to_euc_kr 11 10 6 3 4365 t ) +insert ( 4486 euc_tw_to_utf8 11 10 4 6 4366 t ) +insert ( 4487 utf8_to_euc_tw 11 10 6 4 4367 t ) +insert ( 4488 gb18030_to_utf8 11 10 39 6 4368 t ) +insert ( 4489 utf8_to_gb18030 11 10 6 39 4369 t ) +insert ( 4490 gbk_to_utf8 11 10 37 6 4370 t ) +insert ( 4491 utf8_to_gbk 11 10 6 37 4371 t ) +insert ( 4492 utf8_to_iso_8859_2 11 10 6 9 4372 t ) +insert ( 4493 iso_8859_2_to_utf8 11 10 9 6 4373 t ) +insert ( 4494 utf8_to_iso_8859_3 11 10 6 10 4372 t ) +insert ( 4495 iso_8859_3_to_utf8 11 10 10 6 4373 t ) +insert ( 4496 utf8_to_iso_8859_4 11 10 6 11 4372 t ) +insert ( 4497 iso_8859_4_to_utf8 11 10 11 6 4373 t ) +insert ( 4498 utf8_to_iso_8859_9 11 10 6 12 4372 t ) +insert ( 4499 iso_8859_9_to_utf8 11 10 12 6 4373 t ) +insert ( 4500 utf8_to_iso_8859_10 11 10 6 13 4372 t ) +insert ( 4501 iso_8859_10_to_utf8 11 10 13 6 4373 t ) +insert ( 4502 utf8_to_iso_8859_13 11 10 6 14 4372 t ) +insert ( 4503 iso_8859_13_to_utf8 11 10 14 6 4373 t ) +insert ( 4504 utf8_to_iso_8859_14 11 10 6 15 4372 t ) +insert ( 4505 iso_8859_14_to_utf8 11 10 15 6 4373 t ) +insert ( 4506 utf8_to_iso_8859_15 11 10 6 16 4372 t ) +insert ( 4507 iso_8859_15_to_utf8 11 10 16 6 4373 t ) +insert ( 4508 utf8_to_iso_8859_16 11 10 6 17 4372 t ) +insert ( 4509 iso_8859_16_to_utf8 11 10 17 6 4373 t ) +insert ( 4510 utf8_to_iso_8859_5 11 10 6 25 4372 t ) +insert ( 4511 iso_8859_5_to_utf8 11 10 25 6 4373 t ) +insert ( 4512 utf8_to_iso_8859_6 11 10 6 26 4372 t ) +insert ( 4513 iso_8859_6_to_utf8 11 10 26 6 4373 t ) +insert ( 4514 utf8_to_iso_8859_7 11 10 6 27 4372 t ) +insert ( 4515 iso_8859_7_to_utf8 11 10 27 6 4373 t ) +insert ( 4516 utf8_to_iso_8859_8 11 10 6 28 4372 t ) +insert ( 4517 iso_8859_8_to_utf8 11 10 28 6 4373 t ) +insert ( 4518 iso_8859_1_to_utf8 11 10 8 6 4374 t ) +insert ( 4519 utf8_to_iso_8859_1 11 10 6 8 4375 t ) +insert ( 4520 johab_to_utf8 11 10 40 6 4376 t ) +insert ( 4521 utf8_to_johab 11 10 6 40 4377 t ) +insert ( 4522 sjis_to_utf8 11 10 35 6 4378 t ) +insert ( 4523 utf8_to_sjis 11 10 6 35 4379 t ) +insert ( 4524 uhc_to_utf8 11 10 38 6 4380 t ) +insert ( 4525 utf8_to_uhc 11 10 6 38 4381 t ) +insert ( 4526 euc_jis_2004_to_utf8 11 10 5 6 4382 t ) +insert ( 4527 utf8_to_euc_jis_2004 11 10 6 5 4383 t ) +insert ( 4528 shift_jis_2004_to_utf8 11 10 41 6 4384 t ) +insert ( 4529 utf8_to_shift_jis_2004 11 10 6 41 4385 t ) +insert ( 4530 euc_jis_2004_to_shift_jis_2004 11 10 5 41 4386 t ) +insert ( 4531 shift_jis_2004_to_euc_jis_2004 11 10 41 5 4387 t ) +close pg_conversion +create pg_depend 2608 + ( + classid = oid , + objid = oid , + objsubid = int4 , + refclassid = oid , + refobjid = oid , + refobjsubid = int4 , + deptype = char + ) +open pg_depend +close pg_depend +create pg_database 1262 shared_relation rowtype_oid 1248 + ( + oid = oid , + datname = name , + datdba = oid , + encoding = int4 , + datlocprovider = char , + datistemplate = bool , + datallowconn = bool , + datconnlimit = int4 , + datfrozenxid = xid , + datminmxid = xid , + dattablespace = oid , + datcollate = text FORCE NOT NULL , + datctype = text FORCE NOT NULL , + daticulocale = text , + daticurules = text , + datcollversion = text , + datacl = _aclitem + ) +open pg_database +insert ( 1 template1 10 ENCODING LOCALE_PROVIDER t t -1 0 1 1663 LC_COLLATE LC_CTYPE ICU_LOCALE ICU_RULES _null_ _null_ ) +close pg_database +create pg_db_role_setting 2964 shared_relation + ( + setdatabase = oid , + setrole = oid , + setconfig = _text + ) +open pg_db_role_setting +close pg_db_role_setting +create pg_tablespace 1213 shared_relation + ( + oid = oid , + spcname = name , + spcowner = oid , + spcacl = _aclitem , + spcoptions = _text + ) +open pg_tablespace +insert ( 1663 pg_default 10 _null_ _null_ ) +insert ( 1664 pg_global 10 _null_ _null_ ) +insert ( 9100 pg_undo 10 _null_ _null_ ) +close pg_tablespace +create pg_authid 1260 shared_relation rowtype_oid 2842 + ( + oid = oid , + rolname = name , + rolsuper = bool , + rolinherit = bool , + rolcreaterole = bool , + rolcreatedb = bool , + rolcanlogin = bool , + rolreplication = bool , + rolbypassrls = bool , + rolconnlimit = int4 , + rolpassword = text , + rolvaliduntil = timestamptz + ) +open pg_authid +insert ( 10 POSTGRES t t t t t t t -1 _null_ _null_ ) +insert ( 6171 pg_database_owner f t f f f f f -1 _null_ _null_ ) +insert ( 6181 pg_read_all_data f t f f f f f -1 _null_ _null_ ) +insert ( 6182 pg_write_all_data f t f f f f f -1 _null_ _null_ ) +insert ( 3373 pg_monitor f t f f f f f -1 _null_ _null_ ) +insert ( 3374 pg_read_all_settings f t f f f f f -1 _null_ _null_ ) +insert ( 3375 pg_read_all_stats f t f f f f f -1 _null_ _null_ ) +insert ( 3377 pg_stat_scan_tables f t f f f f f -1 _null_ _null_ ) +insert ( 4569 pg_read_server_files f t f f f f f -1 _null_ _null_ ) +insert ( 4570 pg_write_server_files f t f f f f f -1 _null_ _null_ ) +insert ( 4571 pg_execute_server_program f t f f f f f -1 _null_ _null_ ) +insert ( 4200 pg_signal_backend f t f f f f f -1 _null_ _null_ ) +insert ( 4544 pg_checkpoint f t f f f f f -1 _null_ _null_ ) +insert ( 4550 pg_use_reserved_connections f t f f f f f -1 _null_ _null_ ) +insert ( 6304 pg_create_subscription f t f f f f f -1 _null_ _null_ ) +close pg_authid +create pg_auth_members 1261 shared_relation rowtype_oid 2843 + ( + oid = oid , + roleid = oid , + member = oid , + grantor = oid , + admin_option = bool , + inherit_option = bool , + set_option = bool + ) +open pg_auth_members +close pg_auth_members +create pg_shdepend 1214 shared_relation + ( + dbid = oid , + classid = oid , + objid = oid , + objsubid = int4 , + refclassid = oid , + refobjid = oid , + deptype = char + ) +open pg_shdepend +close pg_shdepend +create pg_shdescription 2396 shared_relation + ( + objoid = oid , + classoid = oid , + description = text FORCE NOT NULL + ) +open pg_shdescription +insert ( 1 1262 'default template for new databases' ) +close pg_shdescription +create pg_ts_config 3602 + ( + oid = oid , + cfgname = name , + cfgnamespace = oid , + cfgowner = oid , + cfgparser = oid + ) +open pg_ts_config +insert ( 3748 simple 11 10 3722 ) +close pg_ts_config +create pg_ts_config_map 3603 + ( + mapcfg = oid , + maptokentype = int4 , + mapseqno = int4 , + mapdict = oid + ) +open pg_ts_config_map +insert ( 3748 1 1 3765 ) +insert ( 3748 2 1 3765 ) +insert ( 3748 3 1 3765 ) +insert ( 3748 4 1 3765 ) +insert ( 3748 5 1 3765 ) +insert ( 3748 6 1 3765 ) +insert ( 3748 7 1 3765 ) +insert ( 3748 8 1 3765 ) +insert ( 3748 9 1 3765 ) +insert ( 3748 10 1 3765 ) +insert ( 3748 11 1 3765 ) +insert ( 3748 15 1 3765 ) +insert ( 3748 16 1 3765 ) +insert ( 3748 17 1 3765 ) +insert ( 3748 18 1 3765 ) +insert ( 3748 19 1 3765 ) +insert ( 3748 20 1 3765 ) +insert ( 3748 21 1 3765 ) +insert ( 3748 22 1 3765 ) +close pg_ts_config_map +create pg_ts_dict 3600 + ( + oid = oid , + dictname = name , + dictnamespace = oid , + dictowner = oid , + dicttemplate = oid , + dictinitoption = text + ) +open pg_ts_dict +insert ( 3765 simple 11 10 3727 _null_ ) +close pg_ts_dict +create pg_ts_parser 3601 + ( + oid = oid , + prsname = name , + prsnamespace = oid , + prsstart = regproc , + prstoken = regproc , + prsend = regproc , + prsheadline = regproc , + prslextype = regproc + ) +open pg_ts_parser +insert ( 3722 default 11 3717 3718 3719 3720 3721 ) +close pg_ts_parser +create pg_ts_template 3764 + ( + oid = oid , + tmplname = name , + tmplnamespace = oid , + tmplinit = regproc , + tmpllexize = regproc + ) +open pg_ts_template +insert ( 3727 simple 11 3725 3726 ) +insert ( 3730 synonym 11 3728 3729 ) +insert ( 3733 ispell 11 3731 3732 ) +insert ( 3742 thesaurus 11 3740 3741 ) +close pg_ts_template +create pg_extension 3079 + ( + oid = oid , + extname = name , + extowner = oid , + extnamespace = oid , + extrelocatable = bool , + extversion = text FORCE NOT NULL , + extconfig = _oid , + extcondition = _text + ) +open pg_extension +close pg_extension +create pg_foreign_data_wrapper 2328 + ( + oid = oid , + fdwname = name , + fdwowner = oid , + fdwhandler = oid , + fdwvalidator = oid , + fdwacl = _aclitem , + fdwoptions = _text + ) +open pg_foreign_data_wrapper +close pg_foreign_data_wrapper +create pg_foreign_server 1417 + ( + oid = oid , + srvname = name , + srvowner = oid , + srvfdw = oid , + srvtype = text , + srvversion = text , + srvacl = _aclitem , + srvoptions = _text + ) +open pg_foreign_server +close pg_foreign_server +create pg_user_mapping 1418 + ( + oid = oid , + umuser = oid , + umserver = oid , + umoptions = _text + ) +open pg_user_mapping +close pg_user_mapping +create pg_foreign_table 3118 + ( + ftrelid = oid , + ftserver = oid , + ftoptions = _text + ) +open pg_foreign_table +close pg_foreign_table +create pg_policy 3256 + ( + oid = oid , + polname = name , + polrelid = oid , + polcmd = char , + polpermissive = bool , + polroles = _oid FORCE NOT NULL , + polqual = pg_node_tree , + polwithcheck = pg_node_tree + ) +open pg_policy +close pg_policy +create pg_replication_origin 6000 shared_relation + ( + roident = oid , + roname = text FORCE NOT NULL + ) +open pg_replication_origin +close pg_replication_origin +create pg_default_acl 826 + ( + oid = oid , + defaclrole = oid , + defaclnamespace = oid , + defaclobjtype = char , + defaclacl = _aclitem FORCE NOT NULL + ) +open pg_default_acl +close pg_default_acl +create pg_init_privs 3394 + ( + objoid = oid , + classoid = oid , + objsubid = int4 , + privtype = char , + initprivs = _aclitem FORCE NOT NULL + ) +open pg_init_privs +close pg_init_privs +create pg_seclabel 3596 + ( + objoid = oid , + classoid = oid , + objsubid = int4 , + provider = text FORCE NOT NULL , + label = text FORCE NOT NULL + ) +open pg_seclabel +close pg_seclabel +create pg_shseclabel 3592 shared_relation rowtype_oid 4066 + ( + objoid = oid , + classoid = oid , + provider = text FORCE NOT NULL , + label = text FORCE NOT NULL + ) +open pg_shseclabel +close pg_shseclabel +create pg_collation 3456 + ( + oid = oid , + collname = name , + collnamespace = oid , + collowner = oid , + collprovider = char , + collisdeterministic = bool , + collencoding = int4 , + collcollate = text , + collctype = text , + colliculocale = text , + collicurules = text , + collversion = text + ) +open pg_collation +insert ( 100 default 11 10 d t -1 _null_ _null_ _null_ _null_ _null_ ) +insert ( 950 C 11 10 c t -1 C C _null_ _null_ _null_ ) +insert ( 951 POSIX 11 10 c t -1 POSIX POSIX _null_ _null_ _null_ ) +insert ( 962 ucs_basic 11 10 c t 6 C C _null_ _null_ _null_ ) +insert ( 963 unicode 11 10 i t -1 _null_ _null_ und _null_ _null_ ) +close pg_collation +create pg_parameter_acl 6243 shared_relation + ( + oid = oid , + parname = text FORCE NOT NULL , + paracl = _aclitem + ) +open pg_parameter_acl +close pg_parameter_acl +create pg_partitioned_table 3350 + ( + partrelid = oid , + partstrat = char , + partnatts = int2 , + partdefid = oid , + partattrs = int2vector FORCE NOT NULL , + partclass = oidvector FORCE NOT NULL , + partcollation = oidvector FORCE NOT NULL , + partexprs = pg_node_tree + ) +open pg_partitioned_table +close pg_partitioned_table +create pg_range 3541 + ( + rngtypid = oid , + rngsubtype = oid , + rngmultitypid = oid , + rngcollation = oid , + rngsubopc = oid , + rngcanonical = regproc , + rngsubdiff = regproc + ) +open pg_range +insert ( 3904 23 4451 0 1978 3914 3922 ) +insert ( 3906 1700 4532 0 3125 - 3924 ) +insert ( 3908 1114 4533 0 3128 - 3929 ) +insert ( 3910 1184 4534 0 3127 - 3930 ) +insert ( 3912 1082 4535 0 3122 3915 3925 ) +insert ( 3926 20 4536 0 3124 3928 3923 ) +close pg_range +create pg_transform 3576 + ( + oid = oid , + trftype = oid , + trflang = oid , + trffromsql = regproc , + trftosql = regproc + ) +open pg_transform +close pg_transform +create pg_sequence 2224 + ( + seqrelid = oid , + seqtypid = oid , + seqstart = int8 , + seqincrement = int8 , + seqmax = int8 , + seqmin = int8 , + seqcache = int8 , + seqcycle = bool + ) +open pg_sequence +close pg_sequence +create pg_publication 6104 + ( + oid = oid , + pubname = name , + pubowner = oid , + puballtables = bool , + pubinsert = bool , + pubupdate = bool , + pubdelete = bool , + pubtruncate = bool , + pubviaroot = bool + ) +open pg_publication +close pg_publication +create pg_publication_namespace 6237 + ( + oid = oid , + pnpubid = oid , + pnnspid = oid + ) +open pg_publication_namespace +close pg_publication_namespace +create pg_publication_rel 6106 + ( + oid = oid , + prpubid = oid , + prrelid = oid , + prqual = pg_node_tree , + prattrs = int2vector + ) +open pg_publication_rel +close pg_publication_rel +create pg_subscription 6100 shared_relation rowtype_oid 6101 + ( + oid = oid , + subdbid = oid , + subskiplsn = pg_lsn , + subname = name , + subowner = oid , + subenabled = bool , + subbinary = bool , + substream = char , + subtwophasestate = char , + subdisableonerr = bool , + subpasswordrequired = bool , + subrunasowner = bool , + subconninfo = text FORCE NOT NULL , + subslotname = name FORCE NULL , + subsynccommit = text FORCE NOT NULL , + subpublications = _text FORCE NOT NULL , + suborigin = text + ) +open pg_subscription +close pg_subscription +create pg_subscription_rel 6102 + ( + srsubid = oid , + srrelid = oid , + srsubstate = char , + srsublsn = pg_lsn FORCE NULL + ) +open pg_subscription_rel +close pg_subscription_rel +declare toast 2836 2837 on pg_proc +declare toast 4171 4172 on pg_type +declare toast 2830 2831 on pg_attrdef +declare toast 2832 2833 on pg_constraint +declare toast 4157 4158 on pg_language +declare toast 4159 4160 on pg_aggregate +declare toast 2840 2841 on pg_statistic +declare toast 3439 3440 on pg_statistic_ext +declare toast 3430 3431 on pg_statistic_ext_data +declare toast 2838 2839 on pg_rewrite +declare toast 2336 2337 on pg_trigger +declare toast 4145 4146 on pg_event_trigger +declare toast 2834 2835 on pg_description +declare toast 4163 4164 on pg_namespace +declare toast 4177 4178 on pg_database +declare toast 2966 2967 on pg_db_role_setting +declare toast 4185 4186 on pg_tablespace +declare toast 4175 4176 on pg_authid +declare toast 2846 2847 on pg_shdescription +declare toast 4169 4170 on pg_ts_dict +declare toast 4147 4148 on pg_extension +declare toast 4149 4150 on pg_foreign_data_wrapper +declare toast 4151 4152 on pg_foreign_server +declare toast 4173 4174 on pg_user_mapping +declare toast 4153 4154 on pg_foreign_table +declare toast 4167 4168 on pg_policy +declare toast 4181 4182 on pg_replication_origin +declare toast 4143 4144 on pg_default_acl +declare toast 4155 4156 on pg_init_privs +declare toast 3598 3599 on pg_seclabel +declare toast 4060 4061 on pg_shseclabel +declare toast 6175 6176 on pg_collation +declare toast 6244 6245 on pg_parameter_acl +declare toast 4165 4166 on pg_partitioned_table +declare toast 6228 6229 on pg_publication_rel +declare toast 4183 4184 on pg_subscription +declare unique index pg_proc_oid_index 2690 on pg_proc using btree(oid oid_ops) +declare unique index pg_proc_proname_args_nsp_index 2691 on pg_proc using btree(proname name_ops, proargtypes oidvector_ops, pronamespace oid_ops) +declare unique index pg_type_oid_index 2703 on pg_type using btree(oid oid_ops) +declare unique index pg_type_typname_nsp_index 2704 on pg_type using btree(typname name_ops, typnamespace oid_ops) +declare unique index pg_attribute_relid_attnam_index 2658 on pg_attribute using btree(attrelid oid_ops, attname name_ops) +declare unique index pg_attribute_relid_attnum_index 2659 on pg_attribute using btree(attrelid oid_ops, attnum int2_ops) +declare unique index pg_class_oid_index 2662 on pg_class using btree(oid oid_ops) +declare unique index pg_class_relname_nsp_index 2663 on pg_class using btree(relname name_ops, relnamespace oid_ops) +declare index pg_class_tblspc_relfilenode_index 3455 on pg_class using btree(reltablespace oid_ops, relfilenode oid_ops) +declare unique index pg_attrdef_adrelid_adnum_index 2656 on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops) +declare unique index pg_attrdef_oid_index 2657 on pg_attrdef using btree(oid oid_ops) +declare index pg_constraint_conname_nsp_index 2664 on pg_constraint using btree(conname name_ops, connamespace oid_ops) +declare unique index pg_constraint_conrelid_contypid_conname_index 2665 on pg_constraint using btree(conrelid oid_ops, contypid oid_ops, conname name_ops) +declare index pg_constraint_contypid_index 2666 on pg_constraint using btree(contypid oid_ops) +declare unique index pg_constraint_oid_index 2667 on pg_constraint using btree(oid oid_ops) +declare index pg_constraint_conparentid_index 2579 on pg_constraint using btree(conparentid oid_ops) +declare unique index pg_inherits_relid_seqno_index 2680 on pg_inherits using btree(inhrelid oid_ops, inhseqno int4_ops) +declare index pg_inherits_parent_index 2187 on pg_inherits using btree(inhparent oid_ops) +declare index pg_index_indrelid_index 2678 on pg_index using btree(indrelid oid_ops) +declare unique index pg_index_indexrelid_index 2679 on pg_index using btree(indexrelid oid_ops) +declare unique index pg_operator_oid_index 2688 on pg_operator using btree(oid oid_ops) +declare unique index pg_operator_oprname_l_r_n_index 2689 on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprnamespace oid_ops) +declare unique index pg_opfamily_am_name_nsp_index 2754 on pg_opfamily using btree(opfmethod oid_ops, opfname name_ops, opfnamespace oid_ops) +declare unique index pg_opfamily_oid_index 2755 on pg_opfamily using btree(oid oid_ops) +declare unique index pg_opclass_am_name_nsp_index 2686 on pg_opclass using btree(opcmethod oid_ops, opcname name_ops, opcnamespace oid_ops) +declare unique index pg_opclass_oid_index 2687 on pg_opclass using btree(oid oid_ops) +declare unique index pg_am_name_index 2651 on pg_am using btree(amname name_ops) +declare unique index pg_am_oid_index 2652 on pg_am using btree(oid oid_ops) +declare unique index pg_amop_fam_strat_index 2653 on pg_amop using btree(amopfamily oid_ops, amoplefttype oid_ops, amoprighttype oid_ops, amopstrategy int2_ops) +declare unique index pg_amop_opr_fam_index 2654 on pg_amop using btree(amopopr oid_ops, amoppurpose char_ops, amopfamily oid_ops) +declare unique index pg_amop_oid_index 2756 on pg_amop using btree(oid oid_ops) +declare unique index pg_amproc_fam_proc_index 2655 on pg_amproc using btree(amprocfamily oid_ops, amproclefttype oid_ops, amprocrighttype oid_ops, amprocnum int2_ops) +declare unique index pg_amproc_oid_index 2757 on pg_amproc using btree(oid oid_ops) +declare unique index pg_language_name_index 2681 on pg_language using btree(lanname name_ops) +declare unique index pg_language_oid_index 2682 on pg_language using btree(oid oid_ops) +declare unique index pg_largeobject_metadata_oid_index 2996 on pg_largeobject_metadata using btree(oid oid_ops) +declare unique index pg_largeobject_loid_pn_index 2683 on pg_largeobject using btree(loid oid_ops, pageno int4_ops) +declare unique index pg_aggregate_fnoid_index 2650 on pg_aggregate using btree(aggfnoid oid_ops) +declare unique index pg_statistic_relid_att_inh_index 2696 on pg_statistic using btree(starelid oid_ops, staattnum int2_ops, stainherit bool_ops) +declare unique index pg_statistic_ext_oid_index 3380 on pg_statistic_ext using btree(oid oid_ops) +declare unique index pg_statistic_ext_name_index 3997 on pg_statistic_ext using btree(stxname name_ops, stxnamespace oid_ops) +declare index pg_statistic_ext_relid_index 3379 on pg_statistic_ext using btree(stxrelid oid_ops) +declare unique index pg_statistic_ext_data_stxoid_inh_index 3433 on pg_statistic_ext_data using btree(stxoid oid_ops, stxdinherit bool_ops) +declare unique index pg_rewrite_oid_index 2692 on pg_rewrite using btree(oid oid_ops) +declare unique index pg_rewrite_rel_rulename_index 2693 on pg_rewrite using btree(ev_class oid_ops, rulename name_ops) +declare index pg_trigger_tgconstraint_index 2699 on pg_trigger using btree(tgconstraint oid_ops) +declare unique index pg_trigger_tgrelid_tgname_index 2701 on pg_trigger using btree(tgrelid oid_ops, tgname name_ops) +declare unique index pg_trigger_oid_index 2702 on pg_trigger using btree(oid oid_ops) +declare unique index pg_event_trigger_evtname_index 3467 on pg_event_trigger using btree(evtname name_ops) +declare unique index pg_event_trigger_oid_index 3468 on pg_event_trigger using btree(oid oid_ops) +declare unique index pg_description_o_c_o_index 2675 on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops) +declare unique index pg_cast_oid_index 2660 on pg_cast using btree(oid oid_ops) +declare unique index pg_cast_source_target_index 2661 on pg_cast using btree(castsource oid_ops, casttarget oid_ops) +declare unique index pg_enum_oid_index 3502 on pg_enum using btree(oid oid_ops) +declare unique index pg_enum_typid_label_index 3503 on pg_enum using btree(enumtypid oid_ops, enumlabel name_ops) +declare unique index pg_enum_typid_sortorder_index 3534 on pg_enum using btree(enumtypid oid_ops, enumsortorder float4_ops) +declare unique index pg_namespace_nspname_index 2684 on pg_namespace using btree(nspname name_ops) +declare unique index pg_namespace_oid_index 2685 on pg_namespace using btree(oid oid_ops) +declare unique index pg_conversion_default_index 2668 on pg_conversion using btree(connamespace oid_ops, conforencoding int4_ops, contoencoding int4_ops, oid oid_ops) +declare unique index pg_conversion_name_nsp_index 2669 on pg_conversion using btree(conname name_ops, connamespace oid_ops) +declare unique index pg_conversion_oid_index 2670 on pg_conversion using btree(oid oid_ops) +declare index pg_depend_depender_index 2673 on pg_depend using btree(classid oid_ops, objid oid_ops, objsubid int4_ops) +declare index pg_depend_reference_index 2674 on pg_depend using btree(refclassid oid_ops, refobjid oid_ops, refobjsubid int4_ops) +declare unique index pg_database_datname_index 2671 on pg_database using btree(datname name_ops) +declare unique index pg_database_oid_index 2672 on pg_database using btree(oid oid_ops) +declare unique index pg_db_role_setting_databaseid_rol_index 2965 on pg_db_role_setting using btree(setdatabase oid_ops, setrole oid_ops) +declare unique index pg_tablespace_oid_index 2697 on pg_tablespace using btree(oid oid_ops) +declare unique index pg_tablespace_spcname_index 2698 on pg_tablespace using btree(spcname name_ops) +declare unique index pg_authid_rolname_index 2676 on pg_authid using btree(rolname name_ops) +declare unique index pg_authid_oid_index 2677 on pg_authid using btree(oid oid_ops) +declare unique index pg_auth_members_oid_index 6303 on pg_auth_members using btree(oid oid_ops) +declare unique index pg_auth_members_role_member_index 2694 on pg_auth_members using btree(roleid oid_ops, member oid_ops, grantor oid_ops) +declare unique index pg_auth_members_member_role_index 2695 on pg_auth_members using btree(member oid_ops, roleid oid_ops, grantor oid_ops) +declare index pg_auth_members_grantor_index 6302 on pg_auth_members using btree(grantor oid_ops) +declare index pg_shdepend_depender_index 1232 on pg_shdepend using btree(dbid oid_ops, classid oid_ops, objid oid_ops, objsubid int4_ops) +declare index pg_shdepend_reference_index 1233 on pg_shdepend using btree(refclassid oid_ops, refobjid oid_ops) +declare unique index pg_shdescription_o_c_index 2397 on pg_shdescription using btree(objoid oid_ops, classoid oid_ops) +declare unique index pg_ts_config_cfgname_index 3608 on pg_ts_config using btree(cfgname name_ops, cfgnamespace oid_ops) +declare unique index pg_ts_config_oid_index 3712 on pg_ts_config using btree(oid oid_ops) +declare unique index pg_ts_config_map_index 3609 on pg_ts_config_map using btree(mapcfg oid_ops, maptokentype int4_ops, mapseqno int4_ops) +declare unique index pg_ts_dict_dictname_index 3604 on pg_ts_dict using btree(dictname name_ops, dictnamespace oid_ops) +declare unique index pg_ts_dict_oid_index 3605 on pg_ts_dict using btree(oid oid_ops) +declare unique index pg_ts_parser_prsname_index 3606 on pg_ts_parser using btree(prsname name_ops, prsnamespace oid_ops) +declare unique index pg_ts_parser_oid_index 3607 on pg_ts_parser using btree(oid oid_ops) +declare unique index pg_ts_template_tmplname_index 3766 on pg_ts_template using btree(tmplname name_ops, tmplnamespace oid_ops) +declare unique index pg_ts_template_oid_index 3767 on pg_ts_template using btree(oid oid_ops) +declare unique index pg_extension_oid_index 3080 on pg_extension using btree(oid oid_ops) +declare unique index pg_extension_name_index 3081 on pg_extension using btree(extname name_ops) +declare unique index pg_foreign_data_wrapper_oid_index 112 on pg_foreign_data_wrapper using btree(oid oid_ops) +declare unique index pg_foreign_data_wrapper_name_index 548 on pg_foreign_data_wrapper using btree(fdwname name_ops) +declare unique index pg_foreign_server_oid_index 113 on pg_foreign_server using btree(oid oid_ops) +declare unique index pg_foreign_server_name_index 549 on pg_foreign_server using btree(srvname name_ops) +declare unique index pg_user_mapping_oid_index 174 on pg_user_mapping using btree(oid oid_ops) +declare unique index pg_user_mapping_user_server_index 175 on pg_user_mapping using btree(umuser oid_ops, umserver oid_ops) +declare unique index pg_foreign_table_relid_index 3119 on pg_foreign_table using btree(ftrelid oid_ops) +declare unique index pg_policy_oid_index 3257 on pg_policy using btree(oid oid_ops) +declare unique index pg_policy_polrelid_polname_index 3258 on pg_policy using btree(polrelid oid_ops, polname name_ops) +declare unique index pg_replication_origin_roiident_index 6001 on pg_replication_origin using btree(roident oid_ops) +declare unique index pg_replication_origin_roname_index 6002 on pg_replication_origin using btree(roname text_ops) +declare unique index pg_default_acl_role_nsp_obj_index 827 on pg_default_acl using btree(defaclrole oid_ops, defaclnamespace oid_ops, defaclobjtype char_ops) +declare unique index pg_default_acl_oid_index 828 on pg_default_acl using btree(oid oid_ops) +declare unique index pg_init_privs_o_c_o_index 3395 on pg_init_privs using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops) +declare unique index pg_seclabel_object_index 3597 on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_ops) +declare unique index pg_shseclabel_object_index 3593 on pg_shseclabel using btree(objoid oid_ops, classoid oid_ops, provider text_ops) +declare unique index pg_collation_name_enc_nsp_index 3164 on pg_collation using btree(collname name_ops, collencoding int4_ops, collnamespace oid_ops) +declare unique index pg_collation_oid_index 3085 on pg_collation using btree(oid oid_ops) +declare unique index pg_parameter_acl_parname_index 6246 on pg_parameter_acl using btree(parname text_ops) +declare unique index pg_parameter_acl_oid_index 6247 on pg_parameter_acl using btree(oid oid_ops) +declare unique index pg_partitioned_table_partrelid_index 3351 on pg_partitioned_table using btree(partrelid oid_ops) +declare unique index pg_range_rngtypid_index 3542 on pg_range using btree(rngtypid oid_ops) +declare unique index pg_range_rngmultitypid_index 2228 on pg_range using btree(rngmultitypid oid_ops) +declare unique index pg_transform_oid_index 3574 on pg_transform using btree(oid oid_ops) +declare unique index pg_transform_type_lang_index 3575 on pg_transform using btree(trftype oid_ops, trflang oid_ops) +declare unique index pg_sequence_seqrelid_index 5002 on pg_sequence using btree(seqrelid oid_ops) +declare unique index pg_publication_oid_index 6110 on pg_publication using btree(oid oid_ops) +declare unique index pg_publication_pubname_index 6111 on pg_publication using btree(pubname name_ops) +declare unique index pg_publication_namespace_oid_index 6238 on pg_publication_namespace using btree(oid oid_ops) +declare unique index pg_publication_namespace_pnnspid_pnpubid_index 6239 on pg_publication_namespace using btree(pnnspid oid_ops, pnpubid oid_ops) +declare unique index pg_publication_rel_oid_index 6112 on pg_publication_rel using btree(oid oid_ops) +declare unique index pg_publication_rel_prrelid_prpubid_index 6113 on pg_publication_rel using btree(prrelid oid_ops, prpubid oid_ops) +declare index pg_publication_rel_prpubid_index 6116 on pg_publication_rel using btree(prpubid oid_ops) +declare unique index pg_subscription_oid_index 6114 on pg_subscription using btree(oid oid_ops) +declare unique index pg_subscription_subname_index 6115 on pg_subscription using btree(subdbid oid_ops, subname name_ops) +declare unique index pg_subscription_rel_srrelid_srsubid_index 6117 on pg_subscription_rel using btree(srrelid oid_ops, srsubid oid_ops) +build indices diff --git a/install/share/postgresql/postgresql.conf.sample b/install/share/postgresql/postgresql.conf.sample new file mode 100644 index 00000000000..bbdb2dcd66c --- /dev/null +++ b/install/share/postgresql/postgresql.conf.sample @@ -0,0 +1,857 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, run "pg_ctl reload", or execute +# "SELECT pg_reload_conf()". Some parameters, which are marked below, +# require a server shutdown and restart to take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: B = bytes Time units: us = microseconds +# kB = kilobytes ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +#data_directory = 'ConfigDir' # use data in another directory + # (change requires restart) +#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file + # (change requires restart) +#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +#external_pid_file = '' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +#listen_addresses = 'localhost' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +#port = 5432 # (change requires restart) +#max_connections = 100 # (change requires restart) +#reserved_connections = 0 # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +#unix_socket_directories = '/tmp' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - TCP settings - +# see "man tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default +#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 +#password_encryption = scram-sha-256 # scram-sha-256 or md5 +#scram_iterations = 4096 +#db_user_namespace = off + +# GSSAPI using Kerberos +#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' +#krb_caseins_users = off +#gss_accept_delegation = off + +# - SSL - + +#ssl = off +#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 +#ssl_ecdh_curve = 'prime256v1' +#ssl_min_protocol_version = 'TLSv1.2' +#ssl_max_protocol_version = '' +#ssl_dh_params_file = '' +#ssl_passphrase_command = '' +#ssl_passphrase_command_supports_reload = off + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +#shared_buffers = 128MB # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#huge_page_size = 0 # zero for system default + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +#hash_mem_multiplier = 2.0 # 1-1000.0 multiplier on hash table work_mem +#maintenance_work_mem = 64MB # min 1MB +#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem +#logical_decoding_work_mem = 64MB # min 64kB +#max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) +#dynamic_shared_memory_type = posix # the default is usually the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # (change requires restart) +#min_dynamic_shared_memory = 0MB # (change requires restart) +#vacuum_buffer_usage_limit = 256kB # size of vacuum and analyze buffer access strategy ring; + # 0 to disable vacuum buffer access strategy; + # range 128kB to 16GB + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kilobytes, or -1 for no limit + +#file_extend_method = posix_fallocate # the default is the first option supported + # by the operating system: + # posix_fallocate (most Unix-like systems) + # write_zeros + +# - Kernel Resources - + +#max_files_per_process = 1000 # min 64 + # (change requires restart) + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) +#vacuum_cost_page_hit = 1 # 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 + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 0 # measured in pages, 0 disables + +# - 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_workers_per_gather = 2 # limited by max_parallel_workers +#max_parallel_maintenance_workers = 2 # limited by max_parallel_workers +#max_parallel_workers = 8 # 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) + + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = replica # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux and FreeBSD) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_compression = off # enables compression of full-page writes; + # off, pglz, lz4, zstd, or on +#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 + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables +#wal_skip_threshold = 2MB + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 0-1000 + +# - Checkpoints - + +#checkpoint_timeout = 5min # range 30s-1d +#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 + +# - Prefetching during recovery - + +#recovery_prefetch = try # prefetch pages referenced in the WAL? +#wal_decode_buffer_size = 512kB # lookahead window used for prefetching + # (change requires restart) + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_library = '' # library to use to archive a WAL file + # (empty string indicates archive_command should + # be used) +#archive_command = '' # command to use to archive a WAL file + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a WAL file switch after this + # number of seconds; 0 disables + +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived WAL file + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +# Set these on the primary and on any standby that will send replication data. + +#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 +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Primary Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # method to choose sync standbys, number of sync standbys, + # and comma-separated list of application_name + # from standby(s); '*' = all + +# - Standby Servers - + +# These settings are ignored on a primary server. + +#primary_conninfo = '' # connection string to sending server +#primary_slot_name = '' # replication slot on sending server +#hot_standby = on # "off" disallows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name + # is not set +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from primary + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery + +# - Subscribers - + +# These settings are ignored on a publisher. + +#max_logical_replication_workers = 4 # taken from max_worker_processes + # (change requires restart) +#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers +#max_parallel_apply_workers_per_subscription = 2 # taken from max_logical_replication_workers + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - 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_memoize = 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_presorted_aggregate = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # 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; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; + # -1 disables + +# - 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 - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#jit = on # allow JIT compilation +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan +#recursive_worktable_factor = 10.0 # range 0.001-1000000 + + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +#log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, jsonlog, syslog, and + # eventlog, depending on platform. + # csvlog and jsonlog require + # logging_collector to be on. + +# This is used when logging to stderr: +#logging_collector = off # Enable capturing of stderr, jsonlog, + # and csvlog into log files. Required + # to be on for csvlogs and jsonlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +#log_directory = 'log' # directory where log files are written, + # can be absolute or relative to PGDATA +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + # can include strftime() escapes +#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. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. + +# 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 - + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + +#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements + # and their durations, > 0 logs only a sample of + # statements running at least this number + # of milliseconds; + # sample fraction is determined by log_statement_sample_rate + +#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding + # log_min_duration_sample to be logged; + # 1.0 logs all such statements, 0.0 never logs + + +#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements + # are logged regardless of their duration; 1.0 logs all + # statements from all transactions, 0.0 never logs + +#log_startup_progress_interval = 10s # Time between progress updates for + # long-running startup operations. + # 0 disables the feature, > 0 indicates + # the interval in milliseconds. + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_autovacuum_min_duration = 10min # 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 = on +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +#log_line_prefix = '%m [%p] ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %b = backend type + # %p = process ID + # %P = process ID of parallel group leader + # %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 + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # 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 +#log_parameter_max_length_on_error = 0 # when logging an error, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_statement = 'none' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +#log_timezone = 'GMT' + +# - Process Title - + +#cluster_name = '' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +# - Cumulative Query and Index Statistics - + +#track_activities = on +#track_activity_query_size = 1024 # (change requires restart) +#track_counts = on +#track_io_timing = off +#track_wal_io_timing = off +#track_functions = none # none, pl, all +#stats_fetch_consistency = cache # cache, none, snapshot + + +# - Monitoring - + +#compute_query_id = auto +#log_statement_stats = off +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts + # before vacuum; -1 disables insert + # vacuums +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table + # size before insert vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # 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 +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#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 +#idle_session_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_table_age = 150000000 +#vacuum_freeze_min_age = 50000000 +#vacuum_failsafe_age = 1600000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_failsafe_age = 1600000000 +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_pending_list_limit = 4MB +#createrole_self_grant = '' # set and/or inherit + +# - Locale and Formatting - + +#datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +#timezone = 'GMT' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +#lc_messages = '' # locale for system error message + # strings +#lc_monetary = 'C' # locale for monetary formatting +#lc_numeric = 'C' # locale for number formatting +#lc_time = 'C' # locale for time formatting + +#icu_validation_level = warning # report ICU locale validation + # errors at the given level + +# default configuration for text search +#default_text_search_config = 'pg_catalog.simple' + +# - Shared Library Preloading - + +#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 + + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_relation = -2 # negative values mean + # (max_pred_locks_per_transaction + # / -max_pred_locks_per_relation) - 1 +#max_pred_locks_per_page = 2 # min 0 + + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? +#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+) + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. + +#include_dir = '...' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file + + +#------------------------------------------------------------------------------ +# PGRAC CLUSTER (pgrac multi-node fork; spec-2.1+) +#------------------------------------------------------------------------------ + +# These options are pgrac extensions to PostgreSQL 16.13. All listed +# here are PGC_POSTMASTER unless noted. See pgrac/specs/spec-2.1-* +# and pgrac/docs/cluster-conf-design.md for full design rationale. +# +# Note: these comment-out lines are deliberately present (per spec-2.1 +# Hardening v1.0.1 D-H6 / lessons L59) so that PostgreSQL::Test::Cluster +# adjust_conf() always finds an anchor when test setup mutates these +# settings. Do not remove without coordinating with cluster_tap suites. + +#cluster.enabled = on # master toggle: on = pgrac cluster + # runtime active; off = vanilla PG + # behaviour (no cluster shmem, no SCN + # advance, no IC tier_init). + # (change requires restart) +#cluster.node_id = -1 # this node's id within the cluster + # (0..127); -1 = single-node default + # (must match a [node.N] section in + # pgrac.conf when allow_single_node=off). + # (change requires restart) +#cluster.allow_single_node = on # Stage 2.1 backward-compat: + # on = pgrac.conf absent OR zero + # [node.N] sections falls back + # to single-node mode; + # off = strict; pgrac.conf required + # with >= 1 [node.N] section. + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here diff --git a/install/share/postgresql/psqlrc.sample b/install/share/postgresql/psqlrc.sample new file mode 100644 index 00000000000..8152cace2b0 --- /dev/null +++ b/install/share/postgresql/psqlrc.sample @@ -0,0 +1,8 @@ +-- +-- system-wide psql configuration file +-- +-- This file is read before the .psqlrc file in the user's home directory. +-- +-- Copy this to your installation's sysconf directory and rename it psqlrc. +-- The sysconf directory can be identified via "pg_config --sysconfdir". +-- diff --git a/install/share/postgresql/snowball_create.sql b/install/share/postgresql/snowball_create.sql new file mode 100644 index 00000000000..4a5c27707ae --- /dev/null +++ b/install/share/postgresql/snowball_create.sql @@ -0,0 +1,1211 @@ +-- Language-specific snowball dictionaries +/* + * Create underlying C functions for Snowball stemmers + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball_func.sql.in + * + * This file is combined with multiple instances of snowball.sql.in to + * build snowball_create.sql, which is executed during initdb. + * + * 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. + */ + +SET search_path = pg_catalog; + +CREATE FUNCTION dsnowball_init(INTERNAL) + RETURNS INTERNAL AS '$libdir/dict_snowball', 'dsnowball_init' +LANGUAGE C STRICT; + +CREATE FUNCTION dsnowball_lexize(INTERNAL, INTERNAL, INTERNAL, INTERNAL) + RETURNS INTERNAL AS '$libdir/dict_snowball', 'dsnowball_lexize' +LANGUAGE C STRICT; + +CREATE TEXT SEARCH TEMPLATE snowball + (INIT = dsnowball_init, + LEXIZE = dsnowball_lexize); + +COMMENT ON TEXT SEARCH TEMPLATE snowball IS 'snowball stemmer'; +/* + * text search configuration for arabic language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * arabic and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY arabic_stem + (TEMPLATE = snowball, Language = arabic ); + +COMMENT ON TEXT SEARCH DICTIONARY arabic_stem IS 'snowball stemmer for arabic language'; + +CREATE TEXT SEARCH CONFIGURATION arabic + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION arabic IS 'configuration for arabic language'; + +ALTER TEXT SEARCH CONFIGURATION arabic ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION arabic ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH arabic_stem; + +ALTER TEXT SEARCH CONFIGURATION arabic ADD MAPPING + FOR word, hword_part, hword + WITH arabic_stem; +/* + * text search configuration for armenian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * armenian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY armenian_stem + (TEMPLATE = snowball, Language = armenian ); + +COMMENT ON TEXT SEARCH DICTIONARY armenian_stem IS 'snowball stemmer for armenian language'; + +CREATE TEXT SEARCH CONFIGURATION armenian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION armenian IS 'configuration for armenian language'; + +ALTER TEXT SEARCH CONFIGURATION armenian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION armenian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH armenian_stem; + +ALTER TEXT SEARCH CONFIGURATION armenian ADD MAPPING + FOR word, hword_part, hword + WITH armenian_stem; +/* + * text search configuration for basque language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * basque and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY basque_stem + (TEMPLATE = snowball, Language = basque ); + +COMMENT ON TEXT SEARCH DICTIONARY basque_stem IS 'snowball stemmer for basque language'; + +CREATE TEXT SEARCH CONFIGURATION basque + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION basque IS 'configuration for basque language'; + +ALTER TEXT SEARCH CONFIGURATION basque ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION basque ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH basque_stem; + +ALTER TEXT SEARCH CONFIGURATION basque ADD MAPPING + FOR word, hword_part, hword + WITH basque_stem; +/* + * text search configuration for catalan language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * catalan and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY catalan_stem + (TEMPLATE = snowball, Language = catalan ); + +COMMENT ON TEXT SEARCH DICTIONARY catalan_stem IS 'snowball stemmer for catalan language'; + +CREATE TEXT SEARCH CONFIGURATION catalan + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION catalan IS 'configuration for catalan language'; + +ALTER TEXT SEARCH CONFIGURATION catalan ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION catalan ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH catalan_stem; + +ALTER TEXT SEARCH CONFIGURATION catalan ADD MAPPING + FOR word, hword_part, hword + WITH catalan_stem; +/* + * text search configuration for danish language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * danish and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY danish_stem + (TEMPLATE = snowball, Language = danish , StopWords=danish); + +COMMENT ON TEXT SEARCH DICTIONARY danish_stem IS 'snowball stemmer for danish language'; + +CREATE TEXT SEARCH CONFIGURATION danish + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION danish IS 'configuration for danish language'; + +ALTER TEXT SEARCH CONFIGURATION danish ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION danish ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH danish_stem; + +ALTER TEXT SEARCH CONFIGURATION danish ADD MAPPING + FOR word, hword_part, hword + WITH danish_stem; +/* + * text search configuration for dutch language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * dutch and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY dutch_stem + (TEMPLATE = snowball, Language = dutch , StopWords=dutch); + +COMMENT ON TEXT SEARCH DICTIONARY dutch_stem IS 'snowball stemmer for dutch language'; + +CREATE TEXT SEARCH CONFIGURATION dutch + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION dutch IS 'configuration for dutch language'; + +ALTER TEXT SEARCH CONFIGURATION dutch ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION dutch ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH dutch_stem; + +ALTER TEXT SEARCH CONFIGURATION dutch ADD MAPPING + FOR word, hword_part, hword + WITH dutch_stem; +/* + * text search configuration for english language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * english and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY english_stem + (TEMPLATE = snowball, Language = english , StopWords=english); + +COMMENT ON TEXT SEARCH DICTIONARY english_stem IS 'snowball stemmer for english language'; + +CREATE TEXT SEARCH CONFIGURATION english + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION english IS 'configuration for english language'; + +ALTER TEXT SEARCH CONFIGURATION english ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION english ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH english_stem; + +ALTER TEXT SEARCH CONFIGURATION english ADD MAPPING + FOR word, hword_part, hword + WITH english_stem; +/* + * text search configuration for finnish language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * finnish and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY finnish_stem + (TEMPLATE = snowball, Language = finnish , StopWords=finnish); + +COMMENT ON TEXT SEARCH DICTIONARY finnish_stem IS 'snowball stemmer for finnish language'; + +CREATE TEXT SEARCH CONFIGURATION finnish + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION finnish IS 'configuration for finnish language'; + +ALTER TEXT SEARCH CONFIGURATION finnish ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION finnish ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH finnish_stem; + +ALTER TEXT SEARCH CONFIGURATION finnish ADD MAPPING + FOR word, hword_part, hword + WITH finnish_stem; +/* + * text search configuration for french language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * french and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY french_stem + (TEMPLATE = snowball, Language = french , StopWords=french); + +COMMENT ON TEXT SEARCH DICTIONARY french_stem IS 'snowball stemmer for french language'; + +CREATE TEXT SEARCH CONFIGURATION french + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION french IS 'configuration for french language'; + +ALTER TEXT SEARCH CONFIGURATION french ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION french ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH french_stem; + +ALTER TEXT SEARCH CONFIGURATION french ADD MAPPING + FOR word, hword_part, hword + WITH french_stem; +/* + * text search configuration for german language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * german and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY german_stem + (TEMPLATE = snowball, Language = german , StopWords=german); + +COMMENT ON TEXT SEARCH DICTIONARY german_stem IS 'snowball stemmer for german language'; + +CREATE TEXT SEARCH CONFIGURATION german + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION german IS 'configuration for german language'; + +ALTER TEXT SEARCH CONFIGURATION german ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION german ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH german_stem; + +ALTER TEXT SEARCH CONFIGURATION german ADD MAPPING + FOR word, hword_part, hword + WITH german_stem; +/* + * text search configuration for greek language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * greek and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY greek_stem + (TEMPLATE = snowball, Language = greek ); + +COMMENT ON TEXT SEARCH DICTIONARY greek_stem IS 'snowball stemmer for greek language'; + +CREATE TEXT SEARCH CONFIGURATION greek + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION greek IS 'configuration for greek language'; + +ALTER TEXT SEARCH CONFIGURATION greek ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION greek ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH greek_stem; + +ALTER TEXT SEARCH CONFIGURATION greek ADD MAPPING + FOR word, hword_part, hword + WITH greek_stem; +/* + * text search configuration for hindi language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * hindi and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY hindi_stem + (TEMPLATE = snowball, Language = hindi ); + +COMMENT ON TEXT SEARCH DICTIONARY hindi_stem IS 'snowball stemmer for hindi language'; + +CREATE TEXT SEARCH CONFIGURATION hindi + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION hindi IS 'configuration for hindi language'; + +ALTER TEXT SEARCH CONFIGURATION hindi ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION hindi ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH english_stem; + +ALTER TEXT SEARCH CONFIGURATION hindi ADD MAPPING + FOR word, hword_part, hword + WITH hindi_stem; +/* + * text search configuration for hungarian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * hungarian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY hungarian_stem + (TEMPLATE = snowball, Language = hungarian , StopWords=hungarian); + +COMMENT ON TEXT SEARCH DICTIONARY hungarian_stem IS 'snowball stemmer for hungarian language'; + +CREATE TEXT SEARCH CONFIGURATION hungarian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION hungarian IS 'configuration for hungarian language'; + +ALTER TEXT SEARCH CONFIGURATION hungarian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION hungarian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH hungarian_stem; + +ALTER TEXT SEARCH CONFIGURATION hungarian ADD MAPPING + FOR word, hword_part, hword + WITH hungarian_stem; +/* + * text search configuration for indonesian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * indonesian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY indonesian_stem + (TEMPLATE = snowball, Language = indonesian ); + +COMMENT ON TEXT SEARCH DICTIONARY indonesian_stem IS 'snowball stemmer for indonesian language'; + +CREATE TEXT SEARCH CONFIGURATION indonesian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION indonesian IS 'configuration for indonesian language'; + +ALTER TEXT SEARCH CONFIGURATION indonesian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION indonesian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH indonesian_stem; + +ALTER TEXT SEARCH CONFIGURATION indonesian ADD MAPPING + FOR word, hword_part, hword + WITH indonesian_stem; +/* + * text search configuration for irish language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * irish and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY irish_stem + (TEMPLATE = snowball, Language = irish ); + +COMMENT ON TEXT SEARCH DICTIONARY irish_stem IS 'snowball stemmer for irish language'; + +CREATE TEXT SEARCH CONFIGURATION irish + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION irish IS 'configuration for irish language'; + +ALTER TEXT SEARCH CONFIGURATION irish ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION irish ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH irish_stem; + +ALTER TEXT SEARCH CONFIGURATION irish ADD MAPPING + FOR word, hword_part, hword + WITH irish_stem; +/* + * text search configuration for italian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * italian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY italian_stem + (TEMPLATE = snowball, Language = italian , StopWords=italian); + +COMMENT ON TEXT SEARCH DICTIONARY italian_stem IS 'snowball stemmer for italian language'; + +CREATE TEXT SEARCH CONFIGURATION italian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION italian IS 'configuration for italian language'; + +ALTER TEXT SEARCH CONFIGURATION italian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION italian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH italian_stem; + +ALTER TEXT SEARCH CONFIGURATION italian ADD MAPPING + FOR word, hword_part, hword + WITH italian_stem; +/* + * text search configuration for lithuanian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * lithuanian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY lithuanian_stem + (TEMPLATE = snowball, Language = lithuanian ); + +COMMENT ON TEXT SEARCH DICTIONARY lithuanian_stem IS 'snowball stemmer for lithuanian language'; + +CREATE TEXT SEARCH CONFIGURATION lithuanian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION lithuanian IS 'configuration for lithuanian language'; + +ALTER TEXT SEARCH CONFIGURATION lithuanian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION lithuanian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH lithuanian_stem; + +ALTER TEXT SEARCH CONFIGURATION lithuanian ADD MAPPING + FOR word, hword_part, hword + WITH lithuanian_stem; +/* + * text search configuration for nepali language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * nepali and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY nepali_stem + (TEMPLATE = snowball, Language = nepali , StopWords=nepali); + +COMMENT ON TEXT SEARCH DICTIONARY nepali_stem IS 'snowball stemmer for nepali language'; + +CREATE TEXT SEARCH CONFIGURATION nepali + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION nepali IS 'configuration for nepali language'; + +ALTER TEXT SEARCH CONFIGURATION nepali ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION nepali ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH nepali_stem; + +ALTER TEXT SEARCH CONFIGURATION nepali ADD MAPPING + FOR word, hword_part, hword + WITH nepali_stem; +/* + * text search configuration for norwegian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * norwegian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY norwegian_stem + (TEMPLATE = snowball, Language = norwegian , StopWords=norwegian); + +COMMENT ON TEXT SEARCH DICTIONARY norwegian_stem IS 'snowball stemmer for norwegian language'; + +CREATE TEXT SEARCH CONFIGURATION norwegian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION norwegian IS 'configuration for norwegian language'; + +ALTER TEXT SEARCH CONFIGURATION norwegian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION norwegian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH norwegian_stem; + +ALTER TEXT SEARCH CONFIGURATION norwegian ADD MAPPING + FOR word, hword_part, hword + WITH norwegian_stem; +/* + * text search configuration for portuguese language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * portuguese and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY portuguese_stem + (TEMPLATE = snowball, Language = portuguese , StopWords=portuguese); + +COMMENT ON TEXT SEARCH DICTIONARY portuguese_stem IS 'snowball stemmer for portuguese language'; + +CREATE TEXT SEARCH CONFIGURATION portuguese + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION portuguese IS 'configuration for portuguese language'; + +ALTER TEXT SEARCH CONFIGURATION portuguese ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION portuguese ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH portuguese_stem; + +ALTER TEXT SEARCH CONFIGURATION portuguese ADD MAPPING + FOR word, hword_part, hword + WITH portuguese_stem; +/* + * text search configuration for romanian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * romanian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY romanian_stem + (TEMPLATE = snowball, Language = romanian ); + +COMMENT ON TEXT SEARCH DICTIONARY romanian_stem IS 'snowball stemmer for romanian language'; + +CREATE TEXT SEARCH CONFIGURATION romanian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION romanian IS 'configuration for romanian language'; + +ALTER TEXT SEARCH CONFIGURATION romanian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION romanian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH romanian_stem; + +ALTER TEXT SEARCH CONFIGURATION romanian ADD MAPPING + FOR word, hword_part, hword + WITH romanian_stem; +/* + * text search configuration for russian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * russian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY russian_stem + (TEMPLATE = snowball, Language = russian , StopWords=russian); + +COMMENT ON TEXT SEARCH DICTIONARY russian_stem IS 'snowball stemmer for russian language'; + +CREATE TEXT SEARCH CONFIGURATION russian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION russian IS 'configuration for russian language'; + +ALTER TEXT SEARCH CONFIGURATION russian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION russian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH english_stem; + +ALTER TEXT SEARCH CONFIGURATION russian ADD MAPPING + FOR word, hword_part, hword + WITH russian_stem; +/* + * text search configuration for serbian language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * serbian and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY serbian_stem + (TEMPLATE = snowball, Language = serbian ); + +COMMENT ON TEXT SEARCH DICTIONARY serbian_stem IS 'snowball stemmer for serbian language'; + +CREATE TEXT SEARCH CONFIGURATION serbian + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION serbian IS 'configuration for serbian language'; + +ALTER TEXT SEARCH CONFIGURATION serbian ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION serbian ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH serbian_stem; + +ALTER TEXT SEARCH CONFIGURATION serbian ADD MAPPING + FOR word, hword_part, hword + WITH serbian_stem; +/* + * text search configuration for spanish language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * spanish and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY spanish_stem + (TEMPLATE = snowball, Language = spanish , StopWords=spanish); + +COMMENT ON TEXT SEARCH DICTIONARY spanish_stem IS 'snowball stemmer for spanish language'; + +CREATE TEXT SEARCH CONFIGURATION spanish + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION spanish IS 'configuration for spanish language'; + +ALTER TEXT SEARCH CONFIGURATION spanish ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION spanish ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH spanish_stem; + +ALTER TEXT SEARCH CONFIGURATION spanish ADD MAPPING + FOR word, hword_part, hword + WITH spanish_stem; +/* + * text search configuration for swedish language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * swedish and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY swedish_stem + (TEMPLATE = snowball, Language = swedish , StopWords=swedish); + +COMMENT ON TEXT SEARCH DICTIONARY swedish_stem IS 'snowball stemmer for swedish language'; + +CREATE TEXT SEARCH CONFIGURATION swedish + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION swedish IS 'configuration for swedish language'; + +ALTER TEXT SEARCH CONFIGURATION swedish ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION swedish ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH swedish_stem; + +ALTER TEXT SEARCH CONFIGURATION swedish ADD MAPPING + FOR word, hword_part, hword + WITH swedish_stem; +/* + * text search configuration for tamil language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * tamil and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY tamil_stem + (TEMPLATE = snowball, Language = tamil ); + +COMMENT ON TEXT SEARCH DICTIONARY tamil_stem IS 'snowball stemmer for tamil language'; + +CREATE TEXT SEARCH CONFIGURATION tamil + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION tamil IS 'configuration for tamil language'; + +ALTER TEXT SEARCH CONFIGURATION tamil ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION tamil ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH tamil_stem; + +ALTER TEXT SEARCH CONFIGURATION tamil ADD MAPPING + FOR word, hword_part, hword + WITH tamil_stem; +/* + * text search configuration for turkish language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * turkish and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY turkish_stem + (TEMPLATE = snowball, Language = turkish , StopWords=turkish); + +COMMENT ON TEXT SEARCH DICTIONARY turkish_stem IS 'snowball stemmer for turkish language'; + +CREATE TEXT SEARCH CONFIGURATION turkish + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION turkish IS 'configuration for turkish language'; + +ALTER TEXT SEARCH CONFIGURATION turkish ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION turkish ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH turkish_stem; + +ALTER TEXT SEARCH CONFIGURATION turkish ADD MAPPING + FOR word, hword_part, hword + WITH turkish_stem; +/* + * text search configuration for yiddish language + * + * Copyright (c) 2007-2023, PostgreSQL Global Development Group + * + * src/backend/snowball/snowball.sql.in + * + * yiddish and certain other macros are replaced for each language; + * see the Makefile for details. + * + * 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 TEXT SEARCH DICTIONARY yiddish_stem + (TEMPLATE = snowball, Language = yiddish ); + +COMMENT ON TEXT SEARCH DICTIONARY yiddish_stem IS 'snowball stemmer for yiddish language'; + +CREATE TEXT SEARCH CONFIGURATION yiddish + (PARSER = default); + +COMMENT ON TEXT SEARCH CONFIGURATION yiddish IS 'configuration for yiddish language'; + +ALTER TEXT SEARCH CONFIGURATION yiddish ADD MAPPING + FOR email, url, url_path, host, file, version, + sfloat, float, int, uint, + numword, hword_numpart, numhword + WITH simple; + +ALTER TEXT SEARCH CONFIGURATION yiddish ADD MAPPING + FOR asciiword, hword_asciipart, asciihword + WITH yiddish_stem; + +ALTER TEXT SEARCH CONFIGURATION yiddish ADD MAPPING + FOR word, hword_part, hword + WITH yiddish_stem; diff --git a/install/share/postgresql/sql_features.txt b/install/share/postgresql/sql_features.txt new file mode 100644 index 00000000000..784e0e28ed5 --- /dev/null +++ b/install/share/postgresql/sql_features.txt @@ -0,0 +1,755 @@ +B011 Embedded Ada NO +B012 Embedded C YES +B013 Embedded COBOL NO +B014 Embedded Fortran NO +B015 Embedded MUMPS NO +B016 Embedded Pascal NO +B017 Embedded PL/I NO +B021 Direct SQL YES +B030 Enhanced dynamic SQL NO +B031 Basic dynamic SQL NO +B032 Extended dynamic SQL NO +B033 Untyped SQL-invoked function arguments NO +B034 Dynamic specification of cursor attributes NO +B035 Non-extended descriptor names NO +B036 Describe input statement NO +B041 Extensions to embedded SQL exception declarations NO +B051 Enhanced execution rights NO +B111 Module language Ada NO +B112 Module language C NO +B113 Module language COBOL NO +B114 Module language Fortran NO +B115 Module language MUMPS NO +B116 Module language Pascal NO +B117 Module language PL/I NO +B121 Routine language Ada NO +B122 Routine language C NO +B123 Routine language COBOL NO +B124 Routine language Fortran NO +B125 Routine language MUMPS NO +B126 Routine language Pascal NO +B127 Routine language PL/I NO +B128 Routine language SQL YES +B200 Polymorphic table functions NO +B201 More than one PTF generic table parameter NO +B202 PTF copartitioning NO +B203 More than one copartition specification NO +B204 PRUNE WHEN EMPTY NO +B205 Pass-through columns NO +B206 PTF descriptor parameters NO +B207 Cross products of partitionings NO +B208 PTF component procedure interface NO +B209 PTF extended names NO +B211 Module language Ada: VARCHAR and NUMERIC support NO +B221 Routine language Ada: VARCHAR and NUMERIC support NO +E011 Numeric data types YES +E011 Numeric data types 01 INTEGER and SMALLINT data types YES +E011 Numeric data types 02 REAL, DOUBLE PRECISION, and FLOAT data types YES +E011 Numeric data types 03 DECIMAL and NUMERIC data types YES +E011 Numeric data types 04 Arithmetic operators YES +E011 Numeric data types 05 Numeric comparison YES +E011 Numeric data types 06 Implicit casting among the numeric data types YES +E021 Character data types YES +E021 Character string types 01 CHARACTER data type YES +E021 Character string types 02 CHARACTER VARYING data type YES +E021 Character string types 03 Character literals YES +E021 Character string types 04 CHARACTER_LENGTH function YES trims trailing spaces from CHARACTER values before counting +E021 Character string types 05 OCTET_LENGTH function YES +E021 Character string types 06 SUBSTRING function YES +E021 Character string types 07 Character concatenation YES +E021 Character string types 08 UPPER and LOWER functions YES +E021 Character string types 09 TRIM function YES +E021 Character string types 10 Implicit casting among the character string types YES +E021 Character string types 11 POSITION function YES +E021 Character string types 12 Character comparison YES +E031 Identifiers YES +E031 Identifiers 01 Delimited identifiers YES +E031 Identifiers 02 Lower case identifiers YES +E031 Identifiers 03 Trailing underscore YES +E051 Basic query specification YES +E051 Basic query specification 01 SELECT DISTINCT YES +E051 Basic query specification 02 GROUP BY clause YES +E051 Basic query specification 04 GROUP BY can contain columns not in