mirror of https://github.com/citusdata/citus.git
Compare commits
161 Commits
Author | SHA1 | Date |
---|---|---|
|
4c7004df42 | |
|
bbe0539df2 | |
|
12651a2320 | |
|
759b49f69d | |
|
80dc4bd90c | |
|
1d0b15723b | |
|
43f3786c1f | |
|
86107ca191 | |
|
2b964228bc | |
|
c1f5762645 | |
|
459c283e7d | |
|
8f3d9deffe | |
|
d28a5eae6c | |
|
e5a1c17134 | |
|
b6b73e2f4c | |
|
0b4896f7b4 | |
|
ee76c4423e | |
|
9a7f6d6c59 | |
|
6b70724b31 | |
|
26f16a7654 | |
|
24758c39a1 | |
|
684b4c6b96 | |
|
cbe0de33a6 | |
|
b886cfa223 | |
|
548395fd77 | |
|
cba8e57737 | |
|
23d5207701 | |
|
ab7c3b7804 | |
|
c2bc7aca4a | |
|
fa8e867662 | |
|
c55bc8c669 | |
|
7e316c90c4 | |
|
d2ca63fb8c | |
|
a19e180212 | |
|
cdded256ef | |
|
353033d3f0 | |
|
1893d9a900 | |
|
063cff908e | |
|
a115b3043a | |
|
5eb037ac50 | |
|
ef946e44af | |
|
89ccafff50 | |
|
e2a03ce6a0 | |
|
657575114c | |
|
ddef97212a | |
|
f42e8556ec | |
|
01945bd3a3 | |
|
1a8349aeaf | |
|
f18c21c2b4 | |
|
3e924db90a | |
|
32c058e448 | |
|
9bad33f89d | |
|
48849ff3c2 | |
|
6d2a329da6 | |
|
a5780c519f | |
|
103125fa08 | |
|
bee8e9cbb6 | |
|
80678bb07e | |
|
b3448a1661 | |
|
7dc97d3dc9 | |
|
9e3c3297fc | |
|
8a8b2f9a6d | |
|
1a3316281c | |
|
62a00b1b34 | |
|
b4cc7219ae | |
|
d682bf06f7 | |
|
af88c37b56 | |
|
6fed917a53 | |
|
743f0ebb75 | |
|
351b1ca63c | |
|
aa8ed4c60b | |
|
2d843cb382 | |
|
f123632f85 | |
|
61d11ec2d4 | |
|
e4d48dc5da | |
|
e3db375149 | |
|
acd7b1e690 | |
|
ad9a3bfc1a | |
|
a0cd8bd37b | |
|
e91ee245ac | |
|
89e0b53644 | |
|
1c2e78405b | |
|
7c9280f6e3 | |
|
90d76e8097 | |
|
30a75eadf1 | |
|
063be46444 | |
|
698699d89e | |
|
5f479d5f47 | |
|
26c09f340f | |
|
089555c197 | |
|
e9110de7e1 | |
|
d5f067a03f | |
|
1d0111aed6 | |
|
12dd9c1f6b | |
|
65dcc5904d | |
|
d7f04aa187 | |
|
7e701befde | |
|
680c23ffcf | |
|
0fed87ada9 | |
|
b29ecd1b12 | |
|
ed137001a5 | |
|
a93887b3de | |
|
84b52fc908 | |
|
32a2a31b13 | |
|
8c0feee74d | |
|
16ab11622b | |
|
c0a5f5c78c | |
|
da2624cee8 | |
|
9d364332ac | |
|
15ecc37ecd | |
|
5c2ef8e2d8 | |
|
6349f2d52d | |
|
f60c4cbd19 | |
|
f0ea07a813 | |
|
9dcfcb92ff | |
|
caee20ad7c | |
|
d9635609f4 | |
|
4f0053ed6d | |
|
3594bd7ac0 | |
|
7e0dc18b22 | |
|
4e838a471a | |
|
035aa6eada | |
|
75ff237340 | |
|
40e9e2614d | |
|
bac95cc523 | |
|
38967491ef | |
|
fc09e1cfdc | |
|
7513061057 | |
|
f4af59ab4b | |
|
5708fca1ea | |
|
2a6164d2d9 | |
|
db391c0bb7 | |
|
146725fc9b | |
|
94ab1dc240 | |
|
812a2b759f | |
|
452564c19b | |
|
9b06d02c43 | |
|
2ee43fd00c | |
|
f2d102d54b | |
|
82637f3e13 | |
|
79616bc7db | |
|
364e8ece14 | |
|
62c32067f1 | |
|
d9069b1e01 | |
|
fa6743d436 | |
|
26178fb538 | |
|
48c62095ff | |
|
f1b1d7579c | |
|
75df19b616 | |
|
e2d18c5472 | |
|
c12a4f7626 | |
|
a945971f48 | |
|
4c110faf1b | |
|
2c630eca50 | |
|
b421479d46 | |
|
2502e7e754 | |
|
a4fe969947 | |
|
e59ffbf549 | |
|
3b908eec2a | |
|
9b6ffece5e | |
|
1b4d7a51f8 |
1131
.circleci/config.yml
1131
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,33 @@
|
||||||
|
# gdbpg.py contains scripts to nicely print the postgres datastructures
|
||||||
|
# while in a gdb session. Since the vscode debugger is based on gdb this
|
||||||
|
# actually also works when debugging with vscode. Providing nice tools
|
||||||
|
# to understand the internal datastructures we are working with.
|
||||||
|
source /root/gdbpg.py
|
||||||
|
|
||||||
|
# when debugging postgres it is convenient to _always_ have a breakpoint
|
||||||
|
# trigger when an error is logged. Because .gdbinit is sourced before gdb
|
||||||
|
# is fully attached and has the sources loaded. To make sure the breakpoint
|
||||||
|
# is added when the library is loaded we temporary set the breakpoint pending
|
||||||
|
# to on. After we have added out breakpoint we revert back to the default
|
||||||
|
# configuration for breakpoint pending.
|
||||||
|
# The breakpoint is hard to read, but at entry of the function we don't have
|
||||||
|
# the level loaded in elevel. Instead we hardcode the location where the
|
||||||
|
# level of the current error is stored. Also gdb doesn't understand the
|
||||||
|
# ERROR symbol so we hardcode this to the value of ERROR. It is very unlikely
|
||||||
|
# this value will ever change in postgres, but if it does we might need to
|
||||||
|
# find a way to conditionally load the correct breakpoint.
|
||||||
|
set breakpoint pending on
|
||||||
|
break elog.c:errfinish if errordata[errordata_stack_depth].elevel == 21
|
||||||
|
set breakpoint pending auto
|
||||||
|
|
||||||
|
echo \n
|
||||||
|
echo ----------------------------------------------------------------------------------\n
|
||||||
|
echo when attaching to a postgres backend a breakpoint will be set on elog.c:errfinish \n
|
||||||
|
echo it will only break on errors being raised in postgres \n
|
||||||
|
echo \n
|
||||||
|
echo to disable this breakpoint from vscode run `-exec disable 1` in the debug console \n
|
||||||
|
echo this assumes it's the first breakpoint loaded as it is loaded from .gdbinit \n
|
||||||
|
echo this can be verified with `-exec info break`, enabling can be done with \n
|
||||||
|
echo `-exec enable 1` \n
|
||||||
|
echo ----------------------------------------------------------------------------------\n
|
||||||
|
echo \n
|
|
@ -0,0 +1 @@
|
||||||
|
postgresql-*.tar.bz2
|
|
@ -0,0 +1,7 @@
|
||||||
|
\timing on
|
||||||
|
\pset linestyle unicode
|
||||||
|
\pset border 2
|
||||||
|
\setenv PAGER 'pspg --no-mouse -bX --no-commandbar --no-topbar'
|
||||||
|
\set HISTSIZE 100000
|
||||||
|
\set PROMPT1 '\n%[%033[1m%]%M %n@%/:%> (PID: %p)%R%[%033[0m%]%# '
|
||||||
|
\set PROMPT2 ' '
|
|
@ -0,0 +1,12 @@
|
||||||
|
[[source]]
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
name = "pypi"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
docopt = "*"
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.9"
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"hash": {
|
||||||
|
"sha256": "6956a6700ead5804aa56bd597c93bb4a13f208d2d49d3b5399365fd240ca0797"
|
||||||
|
},
|
||||||
|
"pipfile-spec": 6,
|
||||||
|
"requires": {
|
||||||
|
"python_version": "3.9"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"name": "pypi",
|
||||||
|
"url": "https://pypi.org/simple",
|
||||||
|
"verify_ssl": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"docopt": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"develop": {}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
#! /usr/bin/env pipenv-shebang
|
||||||
|
"""Generate C/C++ properties file for VSCode.
|
||||||
|
|
||||||
|
Uses pgenv to iterate postgres versions and generate
|
||||||
|
a C/C++ properties file for VSCode containing the
|
||||||
|
include paths for the postgres headers.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
generate_c_cpp_properties-json.py <target_path>
|
||||||
|
generate_c_cpp_properties-json.py (-h | --help)
|
||||||
|
generate_c_cpp_properties-json.py --version
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h --help Show this screen.
|
||||||
|
--version Show version.
|
||||||
|
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from docopt import docopt
|
||||||
|
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
target_path = args['<target_path>']
|
||||||
|
|
||||||
|
output = subprocess.check_output(['pgenv', 'versions'])
|
||||||
|
# typical output is:
|
||||||
|
# 14.8 pgsql-14.8
|
||||||
|
# * 15.3 pgsql-15.3
|
||||||
|
# 16beta2 pgsql-16beta2
|
||||||
|
# where the line marked with a * is the currently active version
|
||||||
|
#
|
||||||
|
# we are only interested in the first word of each line, which is the version number
|
||||||
|
# thus we strip the whitespace and the * from the line and split it into words
|
||||||
|
# and take the first word
|
||||||
|
versions = [line.strip('* ').split()[0] for line in output.decode('utf-8').splitlines()]
|
||||||
|
|
||||||
|
# create the list of configurations per version
|
||||||
|
configurations = []
|
||||||
|
for version in versions:
|
||||||
|
configurations.append(generate_configuration(version))
|
||||||
|
|
||||||
|
# create the json file
|
||||||
|
c_cpp_properties = {
|
||||||
|
"configurations": configurations,
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
|
|
||||||
|
# write the c_cpp_properties.json file
|
||||||
|
with open(target_path, 'w') as f:
|
||||||
|
json.dump(c_cpp_properties, f, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_configuration(version):
|
||||||
|
"""Returns a configuration for the given postgres version.
|
||||||
|
|
||||||
|
>>> generate_configuration('14.8')
|
||||||
|
{
|
||||||
|
"name": "Citus Development Configuration - Postgres 14.8",
|
||||||
|
"includePath": [
|
||||||
|
"/usr/local/include",
|
||||||
|
"/home/citus/.pgenv/src/postgresql-14.8/src/**",
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"${workspaceFolder}/src/include/",
|
||||||
|
],
|
||||||
|
"configurationProvider": "ms-vscode.makefile-tools"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"name": f"Citus Development Configuration - Postgres {version}",
|
||||||
|
"includePath": [
|
||||||
|
"/usr/local/include",
|
||||||
|
f"/home/citus/.pgenv/src/postgresql-{version}/src/**",
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"${workspaceFolder}/src/include/",
|
||||||
|
],
|
||||||
|
"configurationProvider": "ms-vscode.makefile-tools"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
arguments = docopt(__doc__, version='0.1.0')
|
||||||
|
main(arguments)
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Attach Citus (devcontainer)",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "attach",
|
||||||
|
"processId": "${command:pickProcess}",
|
||||||
|
"program": "/home/citus/.pgenv/pgsql/bin/postgres",
|
||||||
|
"additionalSOLibSearchPath": "/home/citus/.pgenv/pgsql/lib",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"text": "handle SIGUSR1 noprint nostop pass",
|
||||||
|
"description": "let gdb not stop when SIGUSR1 is sent to process",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Open core file",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "/home/citus/.pgenv/pgsql/bin/postgres",
|
||||||
|
"coreDumpPath": "${input:corefile}",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"MIMode": "gdb",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"id": "corefile",
|
||||||
|
"type": "command",
|
||||||
|
"command": "extension.commandvariable.file.pickFile",
|
||||||
|
"args": {
|
||||||
|
"dialogTitle": "Select core file",
|
||||||
|
"include": "**/core*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
|
@ -0,0 +1,229 @@
|
||||||
|
FROM ubuntu:22.04 AS base
|
||||||
|
|
||||||
|
# environment is to make python pass an interactive shell, probably not the best timezone given a wide variety of colleagues
|
||||||
|
ENV TZ=UTC
|
||||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
|
# install build tools
|
||||||
|
RUN apt update && apt install -y \
|
||||||
|
bzip2 \
|
||||||
|
cpanminus \
|
||||||
|
curl \
|
||||||
|
flex \
|
||||||
|
gcc \
|
||||||
|
git \
|
||||||
|
libcurl4-gnutls-dev \
|
||||||
|
libicu-dev \
|
||||||
|
libkrb5-dev \
|
||||||
|
liblz4-dev \
|
||||||
|
libpam0g-dev \
|
||||||
|
libreadline-dev \
|
||||||
|
libselinux1-dev \
|
||||||
|
libssl-dev \
|
||||||
|
libxslt-dev \
|
||||||
|
libzstd-dev \
|
||||||
|
locales \
|
||||||
|
make \
|
||||||
|
perl \
|
||||||
|
pkg-config \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
software-properties-common \
|
||||||
|
sudo \
|
||||||
|
uuid-dev \
|
||||||
|
valgrind \
|
||||||
|
zlib1g-dev \
|
||||||
|
&& add-apt-repository ppa:deadsnakes/ppa -y \
|
||||||
|
&& apt install -y \
|
||||||
|
python3.9-full \
|
||||||
|
# software properties pulls in pkexec, which makes the debugger unusable in vscode
|
||||||
|
&& apt purge -y \
|
||||||
|
software-properties-common \
|
||||||
|
&& apt autoremove -y \
|
||||||
|
&& apt clean
|
||||||
|
|
||||||
|
RUN sudo pip3 install pipenv pipenv-shebang
|
||||||
|
|
||||||
|
RUN cpanm install IPC::Run
|
||||||
|
|
||||||
|
RUN locale-gen en_US.UTF-8
|
||||||
|
|
||||||
|
# add the citus user to sudoers and allow all sudoers to login without a password prompt
|
||||||
|
RUN useradd -ms /bin/bash citus \
|
||||||
|
&& usermod -aG sudo citus \
|
||||||
|
&& echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||||
|
|
||||||
|
WORKDIR /home/citus
|
||||||
|
USER citus
|
||||||
|
|
||||||
|
# run all make commands with the number of cores available
|
||||||
|
RUN echo "export MAKEFLAGS=\"-j \$(nproc)\"" >> "/home/citus/.bashrc"
|
||||||
|
|
||||||
|
RUN git clone --branch v1.3.2 --depth 1 https://github.com/theory/pgenv.git .pgenv
|
||||||
|
COPY --chown=citus:citus pgenv/config/ .pgenv/config/
|
||||||
|
ENV PATH="/home/citus/.pgenv/bin:${PATH}"
|
||||||
|
ENV PATH="/home/citus/.pgenv/pgsql/bin:${PATH}"
|
||||||
|
|
||||||
|
USER citus
|
||||||
|
|
||||||
|
# build postgres versions separately for effective parrallelism and caching of already built versions when changing only certain versions
|
||||||
|
FROM base AS pg14
|
||||||
|
RUN MAKEFLAGS="-j $(nproc)" pgenv build 14.15
|
||||||
|
RUN rm .pgenv/src/*.tar*
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/ clean
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/src/include install
|
||||||
|
|
||||||
|
# create a staging directory with all files we want to copy from our pgenv build
|
||||||
|
# we will copy the contents of the staged folder into the final image at once
|
||||||
|
RUN mkdir .pgenv-staging/
|
||||||
|
RUN cp -r .pgenv/src .pgenv/pgsql-* .pgenv/config .pgenv-staging/
|
||||||
|
RUN rm .pgenv-staging/config/default.conf
|
||||||
|
|
||||||
|
FROM base AS pg15
|
||||||
|
RUN MAKEFLAGS="-j $(nproc)" pgenv build 15.10
|
||||||
|
RUN rm .pgenv/src/*.tar*
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/ clean
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/src/include install
|
||||||
|
|
||||||
|
# create a staging directory with all files we want to copy from our pgenv build
|
||||||
|
# we will copy the contents of the staged folder into the final image at once
|
||||||
|
RUN mkdir .pgenv-staging/
|
||||||
|
RUN cp -r .pgenv/src .pgenv/pgsql-* .pgenv/config .pgenv-staging/
|
||||||
|
RUN rm .pgenv-staging/config/default.conf
|
||||||
|
|
||||||
|
FROM base AS pg16
|
||||||
|
RUN MAKEFLAGS="-j $(nproc)" pgenv build 16.6
|
||||||
|
RUN rm .pgenv/src/*.tar*
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/ clean
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/src/include install
|
||||||
|
|
||||||
|
# create a staging directory with all files we want to copy from our pgenv build
|
||||||
|
# we will copy the contents of the staged folder into the final image at once
|
||||||
|
RUN mkdir .pgenv-staging/
|
||||||
|
RUN cp -r .pgenv/src .pgenv/pgsql-* .pgenv/config .pgenv-staging/
|
||||||
|
RUN rm .pgenv-staging/config/default.conf
|
||||||
|
|
||||||
|
FROM base AS pg17
|
||||||
|
RUN MAKEFLAGS="-j $(nproc)" pgenv build 17.2
|
||||||
|
RUN rm .pgenv/src/*.tar*
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/ clean
|
||||||
|
RUN make -C .pgenv/src/postgresql-*/src/include install
|
||||||
|
|
||||||
|
# create a staging directory with all files we want to copy from our pgenv build
|
||||||
|
# we will copy the contents of the staged folder into the final image at once
|
||||||
|
RUN mkdir .pgenv-staging/
|
||||||
|
RUN cp -r .pgenv/src .pgenv/pgsql-* .pgenv/config .pgenv-staging/
|
||||||
|
RUN rm .pgenv-staging/config/default.conf
|
||||||
|
|
||||||
|
FROM base AS uncrustify-builder
|
||||||
|
|
||||||
|
RUN sudo apt update && sudo apt install -y cmake tree
|
||||||
|
|
||||||
|
WORKDIR /uncrustify
|
||||||
|
RUN curl -L https://github.com/uncrustify/uncrustify/archive/uncrustify-0.68.1.tar.gz | tar xz
|
||||||
|
WORKDIR /uncrustify/uncrustify-uncrustify-0.68.1/
|
||||||
|
RUN mkdir build
|
||||||
|
WORKDIR /uncrustify/uncrustify-uncrustify-0.68.1/build/
|
||||||
|
RUN cmake ..
|
||||||
|
RUN MAKEFLAGS="-j $(nproc)" make -s
|
||||||
|
|
||||||
|
RUN make install DESTDIR=/uncrustify
|
||||||
|
|
||||||
|
# builder for all pipenv's to get them contained in a single layer
|
||||||
|
FROM base AS pipenv
|
||||||
|
|
||||||
|
WORKDIR /workspaces/citus/
|
||||||
|
|
||||||
|
# tools to sync pgenv with vscode
|
||||||
|
COPY --chown=citus:citus .vscode/Pipfile .vscode/Pipfile.lock .devcontainer/.vscode/
|
||||||
|
RUN ( cd .devcontainer/.vscode && pipenv install )
|
||||||
|
|
||||||
|
# environment to run our failure tests
|
||||||
|
COPY --chown=citus:citus src/ src/
|
||||||
|
RUN ( cd src/test/regress && pipenv install )
|
||||||
|
|
||||||
|
# assemble the final container by copying over the artifacts from separately build containers
|
||||||
|
FROM base AS devcontainer
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.source=https://github.com/citusdata/citus
|
||||||
|
LABEL org.opencontainers.image.description="Development container for the Citus project"
|
||||||
|
LABEL org.opencontainers.image.licenses=AGPL-3.0-only
|
||||||
|
|
||||||
|
RUN yes | sudo unminimize
|
||||||
|
|
||||||
|
# install developer productivity tools
|
||||||
|
RUN sudo apt update \
|
||||||
|
&& sudo apt install -y \
|
||||||
|
autoconf2.69 \
|
||||||
|
bash-completion \
|
||||||
|
fswatch \
|
||||||
|
gdb \
|
||||||
|
htop \
|
||||||
|
libdbd-pg-perl \
|
||||||
|
libdbi-perl \
|
||||||
|
lsof \
|
||||||
|
man \
|
||||||
|
net-tools \
|
||||||
|
psmisc \
|
||||||
|
pspg \
|
||||||
|
tree \
|
||||||
|
vim \
|
||||||
|
&& sudo apt clean
|
||||||
|
|
||||||
|
# Since gdb will run in the context of the root user when debugging citus we will need to both
|
||||||
|
# download the gdbpg.py script as the root user, into their home directory, as well as add .gdbinit
|
||||||
|
# as a file owned by root
|
||||||
|
# This will make that as soon as the debugger attaches to a postgres backend (or frankly any other process)
|
||||||
|
# the gdbpg.py script will be sourced and the developer can direcly use it.
|
||||||
|
RUN sudo curl -o /root/gdbpg.py https://raw.githubusercontent.com/tvesely/gdbpg/6065eee7872457785f830925eac665aa535caf62/gdbpg.py
|
||||||
|
COPY --chown=root:root .gdbinit /root/
|
||||||
|
|
||||||
|
# install developer dependencies in the global environment
|
||||||
|
RUN --mount=type=bind,source=requirements.txt,target=requirements.txt pip install -r requirements.txt
|
||||||
|
|
||||||
|
# for persistent bash history across devcontainers we need to have
|
||||||
|
# a) a directory to store the history in
|
||||||
|
# b) a prompt command to append the history to the file
|
||||||
|
# c) specify the history file to store the history in
|
||||||
|
# b and c are done in the .bashrc to make it persistent across shells only
|
||||||
|
RUN sudo install -d -o citus -g citus /commandhistory \
|
||||||
|
&& echo "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" >> "/home/citus/.bashrc"
|
||||||
|
|
||||||
|
# install citus-dev
|
||||||
|
RUN git clone --branch develop https://github.com/citusdata/tools.git citus-tools \
|
||||||
|
&& ( cd citus-tools/citus_dev && pipenv install ) \
|
||||||
|
&& mkdir -p ~/.local/bin \
|
||||||
|
&& ln -s /home/citus/citus-tools/citus_dev/citus_dev-pipenv .local/bin/citus_dev \
|
||||||
|
&& sudo make -C citus-tools/uncrustify install bindir=/usr/local/bin pkgsysconfdir=/usr/local/etc/ \
|
||||||
|
&& mkdir -p ~/.local/share/bash-completion/completions/ \
|
||||||
|
&& ln -s ~/citus-tools/citus_dev/bash_completion ~/.local/share/bash-completion/completions/citus_dev
|
||||||
|
|
||||||
|
# TODO some LC_ALL errors, possibly solved by locale-gen
|
||||||
|
RUN git clone https://github.com/so-fancy/diff-so-fancy.git \
|
||||||
|
&& mkdir -p ~/.local/bin \
|
||||||
|
&& ln -s /home/citus/diff-so-fancy/diff-so-fancy .local/bin/
|
||||||
|
|
||||||
|
COPY --link --from=uncrustify-builder /uncrustify/usr/ /usr/
|
||||||
|
|
||||||
|
COPY --link --from=pg14 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
|
||||||
|
COPY --link --from=pg15 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
|
||||||
|
COPY --link --from=pg16 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
|
||||||
|
|
||||||
|
COPY --link --from=pipenv /home/citus/.local/share/virtualenvs/ /home/citus/.local/share/virtualenvs/
|
||||||
|
|
||||||
|
# place to run your cluster with citus_dev
|
||||||
|
VOLUME /data
|
||||||
|
RUN sudo mkdir /data \
|
||||||
|
&& sudo chown citus:citus /data
|
||||||
|
|
||||||
|
COPY --chown=citus:citus .psqlrc .
|
||||||
|
|
||||||
|
# with the copy linking of layers github actions seem to misbehave with the ownership of the
|
||||||
|
# directories leading upto the link, hence a small patch layer to have to right ownerships set
|
||||||
|
RUN sudo chown --from=root:root citus:citus -R ~
|
||||||
|
|
||||||
|
# sets default pg version
|
||||||
|
RUN pgenv switch 17.2
|
||||||
|
|
||||||
|
# make connecting to the coordinator easy
|
||||||
|
ENV PGPORT=9700
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
init: ../.vscode/c_cpp_properties.json ../.vscode/launch.json
|
||||||
|
|
||||||
|
../.vscode:
|
||||||
|
mkdir -p ../.vscode
|
||||||
|
|
||||||
|
../.vscode/launch.json: ../.vscode .vscode/launch.json
|
||||||
|
cp .vscode/launch.json ../.vscode/launch.json
|
||||||
|
|
||||||
|
../.vscode/c_cpp_properties.json: ../.vscode
|
||||||
|
./.vscode/generate_c_cpp_properties-json.py ../.vscode/c_cpp_properties.json
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"image": "ghcr.io/citusdata/citus-devcontainer:main",
|
||||||
|
"runArgs": [
|
||||||
|
"--cap-add=SYS_PTRACE",
|
||||||
|
"--ulimit=core=-1",
|
||||||
|
],
|
||||||
|
"forwardPorts": [
|
||||||
|
9700
|
||||||
|
],
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"eamodio.gitlens",
|
||||||
|
"GitHub.copilot-chat",
|
||||||
|
"GitHub.copilot",
|
||||||
|
"github.vscode-github-actions",
|
||||||
|
"github.vscode-pull-request-github",
|
||||||
|
"ms-vscode.cpptools-extension-pack",
|
||||||
|
"ms-vsliveshare.vsliveshare",
|
||||||
|
"rioj7.command-variable",
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"files.exclude": {
|
||||||
|
"**/*.o": true,
|
||||||
|
"**/.deps/": true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mounts": [
|
||||||
|
"type=volume,target=/data",
|
||||||
|
"source=citus-bashhistory,target=/commandhistory,type=volume",
|
||||||
|
],
|
||||||
|
"updateContentCommand": "./configure",
|
||||||
|
"postCreateCommand": "make -C .devcontainer/",
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
PGENV_MAKE_OPTIONS=(-s)
|
||||||
|
|
||||||
|
PGENV_CONFIGURE_OPTIONS=(
|
||||||
|
--enable-debug
|
||||||
|
--enable-depend
|
||||||
|
--enable-cassert
|
||||||
|
--enable-tap-tests
|
||||||
|
'CFLAGS=-ggdb -Og -g3 -fno-omit-frame-pointer -DUSE_VALGRIND'
|
||||||
|
--with-openssl
|
||||||
|
--with-libxml
|
||||||
|
--with-libxslt
|
||||||
|
--with-uuid=e2fs
|
||||||
|
--with-icu
|
||||||
|
--with-lz4
|
||||||
|
)
|
|
@ -0,0 +1,9 @@
|
||||||
|
black==23.11.0
|
||||||
|
click==8.1.7
|
||||||
|
isort==5.12.0
|
||||||
|
mypy-extensions==1.0.0
|
||||||
|
packaging==23.2
|
||||||
|
pathspec==0.11.2
|
||||||
|
platformdirs==4.0.0
|
||||||
|
tomli==2.0.1
|
||||||
|
typing_extensions==4.8.0
|
|
@ -0,0 +1,28 @@
|
||||||
|
[[source]]
|
||||||
|
name = "pypi"
|
||||||
|
url = "https://pypi.python.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
mitmproxy = {editable = true, ref = "main", git = "https://github.com/citusdata/mitmproxy.git"}
|
||||||
|
construct = "*"
|
||||||
|
docopt = "==0.6.2"
|
||||||
|
cryptography = ">=41.0.4"
|
||||||
|
pytest = "*"
|
||||||
|
psycopg = "*"
|
||||||
|
filelock = "*"
|
||||||
|
pytest-asyncio = "*"
|
||||||
|
pytest-timeout = "*"
|
||||||
|
pytest-xdist = "*"
|
||||||
|
pytest-repeat = "*"
|
||||||
|
pyyaml = "*"
|
||||||
|
werkzeug = "==2.3.7"
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
black = "*"
|
||||||
|
isort = "*"
|
||||||
|
flake8 = "*"
|
||||||
|
flake8-bugbear = "*"
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.9"
|
File diff suppressed because it is too large
Load Diff
|
@ -25,10 +25,9 @@ configure -whitespace
|
||||||
|
|
||||||
# except these exceptions...
|
# except these exceptions...
|
||||||
src/backend/distributed/utils/citus_outfuncs.c -citus-style
|
src/backend/distributed/utils/citus_outfuncs.c -citus-style
|
||||||
src/backend/distributed/deparser/ruleutils_13.c -citus-style
|
|
||||||
src/backend/distributed/deparser/ruleutils_14.c -citus-style
|
|
||||||
src/backend/distributed/deparser/ruleutils_15.c -citus-style
|
src/backend/distributed/deparser/ruleutils_15.c -citus-style
|
||||||
src/backend/distributed/deparser/ruleutils_16.c -citus-style
|
src/backend/distributed/deparser/ruleutils_16.c -citus-style
|
||||||
|
src/backend/distributed/deparser/ruleutils_17.c -citus-style
|
||||||
src/backend/distributed/commands/index_pg_source.c -citus-style
|
src/backend/distributed/commands/index_pg_source.c -citus-style
|
||||||
|
|
||||||
src/include/distributed/citus_nodes.h -citus-style
|
src/include/distributed/citus_nodes.h -citus-style
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
name: 'Parallelization matrix'
|
||||||
|
inputs:
|
||||||
|
count:
|
||||||
|
required: false
|
||||||
|
default: 32
|
||||||
|
outputs:
|
||||||
|
json:
|
||||||
|
value: ${{ steps.generate_matrix.outputs.json }}
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Generate parallelization matrix
|
||||||
|
id: generate_matrix
|
||||||
|
shell: bash
|
||||||
|
run: |-
|
||||||
|
json_array="{\"include\": ["
|
||||||
|
for ((i = 1; i <= ${{ inputs.count }}; i++)); do
|
||||||
|
json_array+="{\"id\":\"$i\"},"
|
||||||
|
done
|
||||||
|
json_array=${json_array%,}
|
||||||
|
json_array+=" ]}"
|
||||||
|
echo "json=$json_array" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "json=$json_array"
|
|
@ -0,0 +1,38 @@
|
||||||
|
name: save_logs_and_results
|
||||||
|
inputs:
|
||||||
|
folder:
|
||||||
|
required: false
|
||||||
|
default: "log"
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- uses: actions/upload-artifact@v4.6.0
|
||||||
|
name: Upload logs
|
||||||
|
with:
|
||||||
|
name: ${{ inputs.folder }}
|
||||||
|
if-no-files-found: ignore
|
||||||
|
path: |
|
||||||
|
src/test/**/proxy.output
|
||||||
|
src/test/**/results/
|
||||||
|
src/test/**/tmp_check/master/log
|
||||||
|
src/test/**/tmp_check/worker.57638/log
|
||||||
|
src/test/**/tmp_check/worker.57637/log
|
||||||
|
src/test/**/*.diffs
|
||||||
|
src/test/**/out/ddls.sql
|
||||||
|
src/test/**/out/queries.sql
|
||||||
|
src/test/**/logfile_*
|
||||||
|
/tmp/pg_upgrade_newData_logs
|
||||||
|
- name: Publish regression.diffs
|
||||||
|
run: |-
|
||||||
|
diffs="$(find src/test/regress -name "*.diffs" -exec cat {} \;)"
|
||||||
|
if ! [ -z "$diffs" ]; then
|
||||||
|
echo '```diff' >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo -E "$diffs" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo -E $diffs
|
||||||
|
fi
|
||||||
|
shell: bash
|
||||||
|
- name: Print stack traces
|
||||||
|
run: "./ci/print_stack_trace.sh"
|
||||||
|
if: failure()
|
||||||
|
shell: bash
|
|
@ -0,0 +1,35 @@
|
||||||
|
name: setup_extension
|
||||||
|
inputs:
|
||||||
|
pg_major:
|
||||||
|
required: false
|
||||||
|
skip_installation:
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Expose $PG_MAJOR to Github Env
|
||||||
|
run: |-
|
||||||
|
if [ -z "${{ inputs.pg_major }}" ]; then
|
||||||
|
echo "PG_MAJOR=${PG_MAJOR}" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "PG_MAJOR=${{ inputs.pg_major }}" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
shell: bash
|
||||||
|
- uses: actions/download-artifact@v4.1.8
|
||||||
|
with:
|
||||||
|
name: build-${{ env.PG_MAJOR }}
|
||||||
|
- name: Install Extension
|
||||||
|
if: ${{ inputs.skip_installation == 'false' }}
|
||||||
|
run: tar xfv "install-$PG_MAJOR.tar" --directory /
|
||||||
|
shell: bash
|
||||||
|
- name: Configure
|
||||||
|
run: |-
|
||||||
|
chown -R circleci .
|
||||||
|
git config --global --add safe.directory ${GITHUB_WORKSPACE}
|
||||||
|
gosu circleci ./configure --without-pg-version-check
|
||||||
|
shell: bash
|
||||||
|
- name: Enable core dumps
|
||||||
|
run: ulimit -c unlimited
|
||||||
|
shell: bash
|
|
@ -0,0 +1,27 @@
|
||||||
|
name: coverage
|
||||||
|
inputs:
|
||||||
|
flags:
|
||||||
|
required: false
|
||||||
|
codecov_token:
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
flags: ${{ inputs.flags }}
|
||||||
|
token: ${{ inputs.codecov_token }}
|
||||||
|
verbose: true
|
||||||
|
gcov: true
|
||||||
|
- name: Create codeclimate coverage
|
||||||
|
run: |-
|
||||||
|
lcov --directory . --capture --output-file lcov.info
|
||||||
|
lcov --remove lcov.info -o lcov.info '/usr/*'
|
||||||
|
sed "s=^SF:$PWD/=SF:=g" -i lcov.info # relative pats are required by codeclimate
|
||||||
|
mkdir -p /tmp/codeclimate
|
||||||
|
cc-test-reporter format-coverage -t lcov -o /tmp/codeclimate/${{ inputs.flags }}.json lcov.info
|
||||||
|
shell: bash
|
||||||
|
- uses: actions/upload-artifact@v4.6.0
|
||||||
|
with:
|
||||||
|
path: "/tmp/codeclimate/*.json"
|
||||||
|
name: codeclimate-${{ inputs.flags }}
|
|
@ -32,7 +32,10 @@ python3 -m pip install -r tools/packaging_automation/requirements.txt
|
||||||
echo "Package type: ${package_type}"
|
echo "Package type: ${package_type}"
|
||||||
echo "OS version: $(get_rpm_os_version)"
|
echo "OS version: $(get_rpm_os_version)"
|
||||||
|
|
||||||
# if os version is centos 7 or oracle linux 7, then remove urllib3 with pip uninstall and install urllib3<2.0.0 with pip install
|
# For RHEL 7, we need to install urllib3<2 due to below execution error
|
||||||
|
# ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl'
|
||||||
|
# module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017'.
|
||||||
|
# See: https://github.com/urllib3/urllib3/issues/2168
|
||||||
if [[ ${package_type} == "rpm" && $(get_rpm_os_version) == 7* ]]; then
|
if [[ ${package_type} == "rpm" && $(get_rpm_os_version) == 7* ]]; then
|
||||||
python3 -m pip uninstall -y urllib3
|
python3 -m pip uninstall -y urllib3
|
||||||
python3 -m pip install 'urllib3<2'
|
python3 -m pip install 'urllib3<2'
|
||||||
|
|
|
@ -0,0 +1,523 @@
|
||||||
|
name: Build & Test
|
||||||
|
run-name: Build & Test - ${{ github.event.pull_request.title || github.ref_name }}
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
skip_test_flakyness:
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
pull_request:
|
||||||
|
types: [opened, reopened,synchronize]
|
||||||
|
jobs:
|
||||||
|
# Since GHA does not interpolate env varibles in matrix context, we need to
|
||||||
|
# define them in a separate job and use them in other jobs.
|
||||||
|
params:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Initialize parameters
|
||||||
|
outputs:
|
||||||
|
build_image_name: "ghcr.io/citusdata/extbuilder"
|
||||||
|
test_image_name: "ghcr.io/citusdata/exttester"
|
||||||
|
citusupgrade_image_name: "ghcr.io/citusdata/citusupgradetester"
|
||||||
|
fail_test_image_name: "ghcr.io/citusdata/failtester"
|
||||||
|
pgupgrade_image_name: "ghcr.io/citusdata/pgupgradetester"
|
||||||
|
style_checker_image_name: "ghcr.io/citusdata/stylechecker"
|
||||||
|
style_checker_tools_version: "0.8.18"
|
||||||
|
sql_snapshot_pg_version: "17.2"
|
||||||
|
image_suffix: "-v889e4c1"
|
||||||
|
image_suffix_citus_upgrade: "-dev-2ad1f90"
|
||||||
|
pg15_version: '{ "major": "15", "full": "15.10" }'
|
||||||
|
pg16_version: '{ "major": "16", "full": "16.6" }'
|
||||||
|
pg17_version: '{ "major": "17", "full": "17.2" }'
|
||||||
|
upgrade_pg_versions: "14.15-15.10-16.6-17.2"
|
||||||
|
steps:
|
||||||
|
# Since GHA jobs need at least one step we use a noop step here.
|
||||||
|
- name: Set up parameters
|
||||||
|
run: echo 'noop'
|
||||||
|
check-sql-snapshots:
|
||||||
|
needs: params
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: ${{ needs.params.outputs.build_image_name }}:${{ needs.params.outputs.sql_snapshot_pg_version }}${{ needs.params.outputs.image_suffix }}
|
||||||
|
options: --user root
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check Snapshots
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory ${GITHUB_WORKSPACE}
|
||||||
|
ci/check_sql_snapshots.sh
|
||||||
|
check-style:
|
||||||
|
needs: params
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: ${{ needs.params.outputs.style_checker_image_name }}:${{ needs.params.outputs.style_checker_tools_version }}${{ needs.params.outputs.image_suffix }}
|
||||||
|
steps:
|
||||||
|
- name: Check Snapshots
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory ${GITHUB_WORKSPACE}
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Check C Style
|
||||||
|
run: citus_indent --check
|
||||||
|
- name: Check Python style
|
||||||
|
run: black --check .
|
||||||
|
- name: Check Python import order
|
||||||
|
run: isort --check .
|
||||||
|
- name: Check Python lints
|
||||||
|
run: flake8 .
|
||||||
|
- name: Fix whitespace
|
||||||
|
run: ci/editorconfig.sh && git diff --exit-code
|
||||||
|
- name: Remove useless declarations
|
||||||
|
run: ci/remove_useless_declarations.sh && git diff --cached --exit-code
|
||||||
|
- name: Sort and group includes
|
||||||
|
run: ci/sort_and_group_includes.sh && git diff --exit-code
|
||||||
|
- name: Normalize test output
|
||||||
|
run: ci/normalize_expected.sh && git diff --exit-code
|
||||||
|
- name: Check for C-style comments in migration files
|
||||||
|
run: ci/disallow_c_comments_in_migrations.sh && git diff --exit-code
|
||||||
|
- name: 'Check for comment--cached ns that start with # character in spec files'
|
||||||
|
run: ci/disallow_hash_comments_in_spec_files.sh && git diff --exit-code
|
||||||
|
- name: Check for gitignore entries .for source files
|
||||||
|
run: ci/fix_gitignore.sh && git diff --exit-code
|
||||||
|
- name: Check for lengths of changelog entries
|
||||||
|
run: ci/disallow_long_changelog_entries.sh
|
||||||
|
- name: Check for banned C API usage
|
||||||
|
run: ci/banned.h.sh
|
||||||
|
- name: Check for tests missing in schedules
|
||||||
|
run: ci/check_all_tests_are_run.sh
|
||||||
|
- name: Check if all CI scripts are actually run
|
||||||
|
run: ci/check_all_ci_scripts_are_run.sh
|
||||||
|
- name: Check if all GUCs are sorted alphabetically
|
||||||
|
run: ci/check_gucs_are_alphabetically_sorted.sh
|
||||||
|
- name: Check for missing downgrade scripts
|
||||||
|
run: ci/check_migration_files.sh
|
||||||
|
build:
|
||||||
|
needs: params
|
||||||
|
name: Build for PG${{ fromJson(matrix.pg_version).major }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
image_name:
|
||||||
|
- ${{ needs.params.outputs.build_image_name }}
|
||||||
|
image_suffix:
|
||||||
|
- ${{ needs.params.outputs.image_suffix}}
|
||||||
|
pg_version:
|
||||||
|
- ${{ needs.params.outputs.pg15_version }}
|
||||||
|
- ${{ needs.params.outputs.pg16_version }}
|
||||||
|
- ${{ needs.params.outputs.pg17_version }}
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: "${{ matrix.image_name }}:${{ fromJson(matrix.pg_version).full }}${{ matrix.image_suffix }}"
|
||||||
|
options: --user root
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Expose $PG_MAJOR to Github Env
|
||||||
|
run: echo "PG_MAJOR=${PG_MAJOR}" >> $GITHUB_ENV
|
||||||
|
shell: bash
|
||||||
|
- name: Build
|
||||||
|
run: "./ci/build-citus.sh"
|
||||||
|
shell: bash
|
||||||
|
- uses: actions/upload-artifact@v4.6.0
|
||||||
|
with:
|
||||||
|
name: build-${{ env.PG_MAJOR }}
|
||||||
|
path: |-
|
||||||
|
./build-${{ env.PG_MAJOR }}/*
|
||||||
|
./install-${{ env.PG_MAJOR }}.tar
|
||||||
|
test-citus:
|
||||||
|
name: PG${{ fromJson(matrix.pg_version).major }} - ${{ matrix.make }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
suite:
|
||||||
|
- regress
|
||||||
|
image_name:
|
||||||
|
- ${{ needs.params.outputs.test_image_name }}
|
||||||
|
pg_version:
|
||||||
|
- ${{ needs.params.outputs.pg15_version }}
|
||||||
|
- ${{ needs.params.outputs.pg16_version }}
|
||||||
|
- ${{ needs.params.outputs.pg17_version }}
|
||||||
|
make:
|
||||||
|
- check-split
|
||||||
|
- check-multi
|
||||||
|
- check-multi-1
|
||||||
|
- check-multi-mx
|
||||||
|
- check-vanilla
|
||||||
|
- check-isolation
|
||||||
|
- check-operations
|
||||||
|
- check-follower-cluster
|
||||||
|
- check-columnar
|
||||||
|
- check-columnar-isolation
|
||||||
|
- check-enterprise
|
||||||
|
- check-enterprise-isolation
|
||||||
|
- check-enterprise-isolation-logicalrep-1
|
||||||
|
- check-enterprise-isolation-logicalrep-2
|
||||||
|
- check-enterprise-isolation-logicalrep-3
|
||||||
|
include:
|
||||||
|
- make: check-failure
|
||||||
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-failure
|
||||||
|
pg_version: ${{ needs.params.outputs.pg16_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-failure
|
||||||
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-enterprise-failure
|
||||||
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-enterprise-failure
|
||||||
|
pg_version: ${{ needs.params.outputs.pg16_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-enterprise-failure
|
||||||
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-pytest
|
||||||
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-pytest
|
||||||
|
pg_version: ${{ needs.params.outputs.pg16_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-pytest
|
||||||
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: installcheck
|
||||||
|
suite: cdc
|
||||||
|
image_name: ${{ needs.params.outputs.test_image_name }}
|
||||||
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
|
- make: installcheck
|
||||||
|
suite: cdc
|
||||||
|
image_name: ${{ needs.params.outputs.test_image_name }}
|
||||||
|
pg_version: ${{ needs.params.outputs.pg16_version }}
|
||||||
|
- make: installcheck
|
||||||
|
suite: cdc
|
||||||
|
image_name: ${{ needs.params.outputs.test_image_name }}
|
||||||
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
|
- make: check-query-generator
|
||||||
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-query-generator
|
||||||
|
pg_version: ${{ needs.params.outputs.pg16_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
- make: check-query-generator
|
||||||
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
|
suite: regress
|
||||||
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: "${{ matrix.image_name }}:${{ fromJson(matrix.pg_version).full }}${{ needs.params.outputs.image_suffix }}"
|
||||||
|
options: --user root --dns=8.8.8.8
|
||||||
|
# Due to Github creates a default network for each job, we need to use
|
||||||
|
# --dns= to have similar DNS settings as our other CI systems or local
|
||||||
|
# machines. Otherwise, we may see different results.
|
||||||
|
needs:
|
||||||
|
- params
|
||||||
|
- build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: "./.github/actions/setup_extension"
|
||||||
|
- name: Run Test
|
||||||
|
run: gosu circleci make -C src/test/${{ matrix.suite }} ${{ matrix.make }}
|
||||||
|
timeout-minutes: 20
|
||||||
|
- uses: "./.github/actions/save_logs_and_results"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
folder: ${{ fromJson(matrix.pg_version).major }}_${{ matrix.make }}
|
||||||
|
- uses: "./.github/actions/upload_coverage"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
flags: ${{ env.PG_MAJOR }}_${{ matrix.suite }}_${{ matrix.make }}
|
||||||
|
codecov_token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
test-arbitrary-configs:
|
||||||
|
name: PG${{ fromJson(matrix.pg_version).major }} - check-arbitrary-configs-${{ matrix.parallel }}
|
||||||
|
runs-on: ["self-hosted", "1ES.Pool=1es-gha-citusdata-pool"]
|
||||||
|
container:
|
||||||
|
image: "${{ matrix.image_name }}:${{ fromJson(matrix.pg_version).full }}${{ needs.params.outputs.image_suffix }}"
|
||||||
|
options: --user root
|
||||||
|
needs:
|
||||||
|
- params
|
||||||
|
- build
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
image_name:
|
||||||
|
- ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
|
pg_version:
|
||||||
|
- ${{ needs.params.outputs.pg15_version }}
|
||||||
|
- ${{ needs.params.outputs.pg16_version }}
|
||||||
|
- ${{ needs.params.outputs.pg17_version }}
|
||||||
|
parallel: [0,1,2,3,4,5] # workaround for running 6 parallel jobs
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: "./.github/actions/setup_extension"
|
||||||
|
- name: Test arbitrary configs
|
||||||
|
run: |-
|
||||||
|
# we use parallel jobs to split the tests into 6 parts and run them in parallel
|
||||||
|
# the script below extracts the tests for the current job
|
||||||
|
N=6 # Total number of jobs (see matrix.parallel)
|
||||||
|
X=${{ matrix.parallel }} # Current job number
|
||||||
|
TESTS=$(src/test/regress/citus_tests/print_test_names.py |
|
||||||
|
tr '\n' ',' | awk -v N="$N" -v X="$X" -F, '{
|
||||||
|
split("", parts)
|
||||||
|
for (i = 1; i <= NF; i++) {
|
||||||
|
parts[i % N] = parts[i % N] $i ","
|
||||||
|
}
|
||||||
|
print substr(parts[X], 1, length(parts[X])-1)
|
||||||
|
}')
|
||||||
|
echo $TESTS
|
||||||
|
gosu circleci \
|
||||||
|
make -C src/test/regress \
|
||||||
|
check-arbitrary-configs parallel=4 CONFIGS=$TESTS
|
||||||
|
- uses: "./.github/actions/save_logs_and_results"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
folder: ${{ env.PG_MAJOR }}_arbitrary_configs_${{ matrix.parallel }}
|
||||||
|
- uses: "./.github/actions/upload_coverage"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
flags: ${{ env.PG_MAJOR }}_arbitrary_configs_${{ matrix.parallel }}
|
||||||
|
codecov_token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
test-pg-upgrade:
|
||||||
|
name: PG${{ matrix.old_pg_major }}-PG${{ matrix.new_pg_major }} - check-pg-upgrade
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: "${{ needs.params.outputs.pgupgrade_image_name }}:${{ needs.params.outputs.upgrade_pg_versions }}${{ needs.params.outputs.image_suffix }}"
|
||||||
|
options: --user root
|
||||||
|
needs:
|
||||||
|
- params
|
||||||
|
- build
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- old_pg_major: 15
|
||||||
|
new_pg_major: 16
|
||||||
|
- old_pg_major: 16
|
||||||
|
new_pg_major: 17
|
||||||
|
- old_pg_major: 15
|
||||||
|
new_pg_major: 17
|
||||||
|
env:
|
||||||
|
old_pg_major: ${{ matrix.old_pg_major }}
|
||||||
|
new_pg_major: ${{ matrix.new_pg_major }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: "./.github/actions/setup_extension"
|
||||||
|
with:
|
||||||
|
pg_major: "${{ env.old_pg_major }}"
|
||||||
|
- uses: "./.github/actions/setup_extension"
|
||||||
|
with:
|
||||||
|
pg_major: "${{ env.new_pg_major }}"
|
||||||
|
- name: Install and test postgres upgrade
|
||||||
|
run: |-
|
||||||
|
gosu circleci \
|
||||||
|
make -C src/test/regress \
|
||||||
|
check-pg-upgrade \
|
||||||
|
old-bindir=/usr/lib/postgresql/${{ env.old_pg_major }}/bin \
|
||||||
|
new-bindir=/usr/lib/postgresql/${{ env.new_pg_major }}/bin
|
||||||
|
- name: Copy pg_upgrade logs for newData dir
|
||||||
|
run: |-
|
||||||
|
mkdir -p /tmp/pg_upgrade_newData_logs
|
||||||
|
if ls src/test/regress/tmp_upgrade/newData/*.log 1> /dev/null 2>&1; then
|
||||||
|
cp src/test/regress/tmp_upgrade/newData/*.log /tmp/pg_upgrade_newData_logs
|
||||||
|
fi
|
||||||
|
if: failure()
|
||||||
|
- uses: "./.github/actions/save_logs_and_results"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
folder: ${{ env.old_pg_major }}_${{ env.new_pg_major }}_upgrade
|
||||||
|
- uses: "./.github/actions/upload_coverage"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
flags: ${{ env.old_pg_major }}_${{ env.new_pg_major }}_upgrade
|
||||||
|
codecov_token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
test-citus-upgrade:
|
||||||
|
name: PG${{ fromJson(needs.params.outputs.pg15_version).major }} - check-citus-upgrade
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: "${{ needs.params.outputs.citusupgrade_image_name }}:${{ fromJson(needs.params.outputs.pg15_version).full }}${{ needs.params.outputs.image_suffix_citus_upgrade }}"
|
||||||
|
options: --user root
|
||||||
|
needs:
|
||||||
|
- params
|
||||||
|
- build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: "./.github/actions/setup_extension"
|
||||||
|
with:
|
||||||
|
skip_installation: true
|
||||||
|
- name: Install and test citus upgrade
|
||||||
|
run: |-
|
||||||
|
# run make check-citus-upgrade for all citus versions
|
||||||
|
# the image has ${CITUS_VERSIONS} set with all verions it contains the binaries of
|
||||||
|
for citus_version in ${CITUS_VERSIONS}; do \
|
||||||
|
gosu circleci \
|
||||||
|
make -C src/test/regress \
|
||||||
|
check-citus-upgrade \
|
||||||
|
bindir=/usr/lib/postgresql/${PG_MAJOR}/bin \
|
||||||
|
citus-old-version=${citus_version} \
|
||||||
|
citus-pre-tar=/install-pg${PG_MAJOR}-citus${citus_version}.tar \
|
||||||
|
citus-post-tar=${GITHUB_WORKSPACE}/install-$PG_MAJOR.tar; \
|
||||||
|
done;
|
||||||
|
# run make check-citus-upgrade-mixed for all citus versions
|
||||||
|
# the image has ${CITUS_VERSIONS} set with all verions it contains the binaries of
|
||||||
|
for citus_version in ${CITUS_VERSIONS}; do \
|
||||||
|
gosu circleci \
|
||||||
|
make -C src/test/regress \
|
||||||
|
check-citus-upgrade-mixed \
|
||||||
|
citus-old-version=${citus_version} \
|
||||||
|
bindir=/usr/lib/postgresql/${PG_MAJOR}/bin \
|
||||||
|
citus-pre-tar=/install-pg${PG_MAJOR}-citus${citus_version}.tar \
|
||||||
|
citus-post-tar=${GITHUB_WORKSPACE}/install-$PG_MAJOR.tar; \
|
||||||
|
done;
|
||||||
|
- uses: "./.github/actions/save_logs_and_results"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
folder: ${{ env.PG_MAJOR }}_citus_upgrade
|
||||||
|
- uses: "./.github/actions/upload_coverage"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
flags: ${{ env.PG_MAJOR }}_citus_upgrade
|
||||||
|
codecov_token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
upload-coverage:
|
||||||
|
if: always()
|
||||||
|
env:
|
||||||
|
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: ${{ needs.params.outputs.test_image_name }}:${{ fromJson(needs.params.outputs.pg17_version).full }}${{ needs.params.outputs.image_suffix }}
|
||||||
|
needs:
|
||||||
|
- params
|
||||||
|
- test-citus
|
||||||
|
- test-arbitrary-configs
|
||||||
|
- test-citus-upgrade
|
||||||
|
- test-pg-upgrade
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v4.1.8
|
||||||
|
with:
|
||||||
|
pattern: codeclimate*
|
||||||
|
path: codeclimate
|
||||||
|
merge-multiple: true
|
||||||
|
- name: Upload coverage results to Code Climate
|
||||||
|
run: |-
|
||||||
|
cc-test-reporter sum-coverage codeclimate/*.json -o total.json
|
||||||
|
cc-test-reporter upload-coverage -i total.json
|
||||||
|
ch_benchmark:
|
||||||
|
name: CH Benchmark
|
||||||
|
if: startsWith(github.ref, 'refs/heads/ch_benchmark/')
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: azure/login@v1
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
- name: install dependencies and run ch_benchmark tests
|
||||||
|
uses: azure/CLI@v1
|
||||||
|
with:
|
||||||
|
inlineScript: |
|
||||||
|
cd ./src/test/hammerdb
|
||||||
|
chmod +x run_hammerdb.sh
|
||||||
|
run_hammerdb.sh citusbot_ch_benchmark_rg
|
||||||
|
tpcc_benchmark:
|
||||||
|
name: TPCC Benchmark
|
||||||
|
if: startsWith(github.ref, 'refs/heads/tpcc_benchmark/')
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: azure/login@v1
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
- name: install dependencies and run tpcc_benchmark tests
|
||||||
|
uses: azure/CLI@v1
|
||||||
|
with:
|
||||||
|
inlineScript: |
|
||||||
|
cd ./src/test/hammerdb
|
||||||
|
chmod +x run_hammerdb.sh
|
||||||
|
run_hammerdb.sh citusbot_tpcc_benchmark_rg
|
||||||
|
prepare_parallelization_matrix_32:
|
||||||
|
name: Parallel 32
|
||||||
|
if: ${{ needs.test-flakyness-pre.outputs.tests != ''}}
|
||||||
|
needs: test-flakyness-pre
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
outputs:
|
||||||
|
json: ${{ steps.parallelization.outputs.json }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: "./.github/actions/parallelization"
|
||||||
|
id: parallelization
|
||||||
|
with:
|
||||||
|
count: 32
|
||||||
|
test-flakyness-pre:
|
||||||
|
name: Detect regression tests need to be ran
|
||||||
|
if: ${{ !inputs.skip_test_flakyness }}}
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: build
|
||||||
|
outputs:
|
||||||
|
tests: ${{ steps.detect-regression-tests.outputs.tests }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Detect regression tests need to be ran
|
||||||
|
id: detect-regression-tests
|
||||||
|
run: |-
|
||||||
|
detected_changes=$(git diff origin/release-12.1... --name-only --diff-filter=AM | (grep 'src/test/regress/sql/.*\.sql\|src/test/regress/spec/.*\.spec\|src/test/regress/citus_tests/test/test_.*\.py' || true))
|
||||||
|
tests=${detected_changes}
|
||||||
|
if [ -z "$tests" ]; then
|
||||||
|
echo "No test found."
|
||||||
|
else
|
||||||
|
echo "Detected tests " $tests
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'tests<<EOF' >> $GITHUB_OUTPUT
|
||||||
|
echo "$tests" >> "$GITHUB_OUTPUT"
|
||||||
|
echo 'EOF' >> $GITHUB_OUTPUT
|
||||||
|
test-flakyness:
|
||||||
|
if: false
|
||||||
|
name: Test flakyness
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: ${{ needs.params.outputs.fail_test_image_name }}:${{ needs.params.outputs.pg17_version }}${{ needs.params.outputs.image_suffix }}
|
||||||
|
options: --user root
|
||||||
|
env:
|
||||||
|
runs: 8
|
||||||
|
needs:
|
||||||
|
- params
|
||||||
|
- build
|
||||||
|
- test-flakyness-pre
|
||||||
|
- prepare_parallelization_matrix_32
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJson(needs.prepare_parallelization_matrix_32.outputs.json) }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/download-artifact@v4.1.8
|
||||||
|
- uses: "./.github/actions/setup_extension"
|
||||||
|
- name: Run minimal tests
|
||||||
|
run: |-
|
||||||
|
tests="${{ needs.test-flakyness-pre.outputs.tests }}"
|
||||||
|
tests_array=($tests)
|
||||||
|
for test in "${tests_array[@]}"
|
||||||
|
do
|
||||||
|
test_name=$(echo "$test" | sed -r "s/.+\/(.+)\..+/\1/")
|
||||||
|
gosu circleci src/test/regress/citus_tests/run_test.py $test_name --repeat ${{ env.runs }} --use-base-schedule --use-whole-schedule-line
|
||||||
|
done
|
||||||
|
shell: bash
|
||||||
|
- uses: "./.github/actions/save_logs_and_results"
|
||||||
|
if: always()
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v2
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
name: Flaky test debugging
|
||||||
|
run-name: Flaky test debugging - ${{ inputs.flaky_test }} (${{ inputs.flaky_test_runs_per_job }}x${{ inputs.flaky_test_parallel_jobs }})
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
flaky_test:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
description: Test to run
|
||||||
|
flaky_test_runs_per_job:
|
||||||
|
required: false
|
||||||
|
default: 8
|
||||||
|
type: number
|
||||||
|
description: Number of times to run the test
|
||||||
|
flaky_test_parallel_jobs:
|
||||||
|
required: false
|
||||||
|
default: 32
|
||||||
|
type: number
|
||||||
|
description: Number of parallel jobs to run
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build Citus
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ vars.build_image_name }}:${{ vars.pg15_version }}${{ vars.image_suffix }}
|
||||||
|
options: --user root
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Configure, Build, and Install
|
||||||
|
run: |
|
||||||
|
echo "PG_MAJOR=${PG_MAJOR}" >> $GITHUB_ENV
|
||||||
|
./ci/build-citus.sh
|
||||||
|
shell: bash
|
||||||
|
- uses: actions/upload-artifact@v4.6.0
|
||||||
|
with:
|
||||||
|
name: build-${{ env.PG_MAJOR }}
|
||||||
|
path: |-
|
||||||
|
./build-${{ env.PG_MAJOR }}/*
|
||||||
|
./install-${{ env.PG_MAJOR }}.tar
|
||||||
|
prepare_parallelization_matrix:
|
||||||
|
name: Prepare parallelization matrix
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
json: ${{ steps.parallelization.outputs.json }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: "./.github/actions/parallelization"
|
||||||
|
id: parallelization
|
||||||
|
with:
|
||||||
|
count: ${{ inputs.flaky_test_parallel_jobs }}
|
||||||
|
test_flakyness:
|
||||||
|
name: Test flakyness
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ vars.fail_test_image_name }}:${{ vars.pg15_version }}${{ vars.image_suffix }}
|
||||||
|
options: --user root
|
||||||
|
needs:
|
||||||
|
[build, prepare_parallelization_matrix]
|
||||||
|
env:
|
||||||
|
test: "${{ inputs.flaky_test }}"
|
||||||
|
runs: "${{ inputs.flaky_test_runs_per_job }}"
|
||||||
|
skip: false
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJson(needs.prepare_parallelization_matrix.outputs.json) }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: "./.github/actions/setup_extension"
|
||||||
|
- name: Run minimal tests
|
||||||
|
run: |-
|
||||||
|
gosu circleci src/test/regress/citus_tests/run_test.py ${{ env.test }} --repeat ${{ env.runs }} --use-base-schedule --use-whole-schedule-line
|
||||||
|
shell: bash
|
||||||
|
- uses: "./.github/actions/save_logs_and_results"
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
folder: ${{ matrix.id }}
|
|
@ -18,20 +18,22 @@ jobs:
|
||||||
pg_versions: ${{ steps.get-postgres-versions.outputs.pg_versions }}
|
pg_versions: ${{ steps.get-postgres-versions.outputs.pg_versions }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
- name: Get Postgres Versions
|
- name: Get Postgres Versions
|
||||||
id: get-postgres-versions
|
id: get-postgres-versions
|
||||||
run: |
|
run: |
|
||||||
# Postgres versions are stored in .circleci/config.yml file in "build-[pg-version] format. Below command
|
set -euxo pipefail
|
||||||
# extracts the versions and get the unique values.
|
# Postgres versions are stored in .github/workflows/build_and_test.yml
|
||||||
pg_versions=`grep -Eo 'build-[[:digit:]]{2}' .circleci/config.yml|sed -e "s/^build-//"|sort|uniq|tr '\n' ','| head -c -1`
|
# file in json strings with major and full keys.
|
||||||
|
# Below command extracts the versions and get the unique values.
|
||||||
|
pg_versions=$(cat .github/workflows/build_and_test.yml | grep -oE '"major": "[0-9]+", "full": "[0-9.]+"' | sed -E 's/"major": "([0-9]+)", "full": "([0-9.]+)"/\1/g' | sort | uniq | tr '\n', ',')
|
||||||
pg_versions_array="[ ${pg_versions} ]"
|
pg_versions_array="[ ${pg_versions} ]"
|
||||||
echo "Supported PG Versions: ${pg_versions_array}"
|
echo "Supported PG Versions: ${pg_versions_array}"
|
||||||
# Below line is needed to set the output variable to be used in the next job
|
# Below line is needed to set the output variable to be used in the next job
|
||||||
echo "pg_versions=${pg_versions_array}" >> $GITHUB_OUTPUT
|
echo "pg_versions=${pg_versions_array}" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
rpm_build_tests:
|
rpm_build_tests:
|
||||||
name: rpm_build_tests
|
name: rpm_build_tests
|
||||||
needs: get_postgres_versions_from_file
|
needs: get_postgres_versions_from_file
|
||||||
|
@ -44,9 +46,7 @@ jobs:
|
||||||
# For this reason, we need to use a "matrix" to generate names of
|
# For this reason, we need to use a "matrix" to generate names of
|
||||||
# rpm images, e.g. citus/packaging:centos-7-pg12
|
# rpm images, e.g. citus/packaging:centos-7-pg12
|
||||||
packaging_docker_image:
|
packaging_docker_image:
|
||||||
- oraclelinux-7
|
|
||||||
- oraclelinux-8
|
- oraclelinux-8
|
||||||
- centos-7
|
|
||||||
- almalinux-8
|
- almalinux-8
|
||||||
- almalinux-9
|
- almalinux-9
|
||||||
POSTGRES_VERSION: ${{ fromJson(needs.get_postgres_versions_from_file.outputs.pg_versions) }}
|
POSTGRES_VERSION: ${{ fromJson(needs.get_postgres_versions_from_file.outputs.pg_versions) }}
|
||||||
|
@ -57,7 +57,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set Postgres and python parameters for rpm based distros
|
- name: Set Postgres and python parameters for rpm based distros
|
||||||
run: |
|
run: |
|
||||||
|
@ -99,11 +99,6 @@ jobs:
|
||||||
PACKAGING_DOCKER_IMAGE: ${{ matrix.packaging_docker_image }}
|
PACKAGING_DOCKER_IMAGE: ${{ matrix.packaging_docker_image }}
|
||||||
run: |
|
run: |
|
||||||
echo "Postgres version: ${POSTGRES_VERSION}"
|
echo "Postgres version: ${POSTGRES_VERSION}"
|
||||||
|
|
||||||
## Install required packages to execute packaging tools for rpm based distros
|
|
||||||
yum install python3-pip python3-devel postgresql-devel -y
|
|
||||||
python3 -m pip install wheel
|
|
||||||
|
|
||||||
./.github/packaging/validate_build_output.sh "rpm"
|
./.github/packaging/validate_build_output.sh "rpm"
|
||||||
|
|
||||||
deb_build_tests:
|
deb_build_tests:
|
||||||
|
@ -120,7 +115,6 @@ jobs:
|
||||||
# for each deb based image and we use POSTGRES_VERSION to set
|
# for each deb based image and we use POSTGRES_VERSION to set
|
||||||
# PG_CONFIG variable in each of those runs.
|
# PG_CONFIG variable in each of those runs.
|
||||||
packaging_docker_image:
|
packaging_docker_image:
|
||||||
- debian-buster-all
|
|
||||||
- debian-bookworm-all
|
- debian-bookworm-all
|
||||||
- debian-bullseye-all
|
- debian-bullseye-all
|
||||||
- ubuntu-focal-all
|
- ubuntu-focal-all
|
||||||
|
@ -134,7 +128,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set pg_config path and python parameters for deb based distros
|
- name: Set pg_config path and python parameters for deb based distros
|
||||||
run: |
|
run: |
|
||||||
|
@ -179,9 +173,4 @@ jobs:
|
||||||
PACKAGING_DOCKER_IMAGE: ${{ matrix.packaging_docker_image }}
|
PACKAGING_DOCKER_IMAGE: ${{ matrix.packaging_docker_image }}
|
||||||
run: |
|
run: |
|
||||||
echo "Postgres version: ${POSTGRES_VERSION}"
|
echo "Postgres version: ${POSTGRES_VERSION}"
|
||||||
|
|
||||||
apt-get update -y
|
|
||||||
## Install required packages to execute packaging tools for deb based distros
|
|
||||||
apt-get install python3-dev python3-pip -y
|
|
||||||
apt-get purge -y python3-yaml
|
|
||||||
./.github/packaging/validate_build_output.sh "deb"
|
./.github/packaging/validate_build_output.sh "deb"
|
||||||
|
|
139
CHANGELOG.md
139
CHANGELOG.md
|
@ -1,3 +1,138 @@
|
||||||
|
### citus v13.0.3 (March 20th, 2025) ###
|
||||||
|
|
||||||
|
* Fixes a version bump issue in 13.0.2
|
||||||
|
|
||||||
|
### citus v13.0.2 (March 12th, 2025) ###
|
||||||
|
|
||||||
|
* Fixes a crash in columnar custom scan that happens when a columnar table is
|
||||||
|
used in a join. (#7647)
|
||||||
|
|
||||||
|
* Fixes a bug that breaks `UPDATE SET (...) = (SELECT some_func(),... )`
|
||||||
|
type of queries on Citus tables (#7914)
|
||||||
|
|
||||||
|
* Fixes a planning error caused by a redundant WHERE clause (#7907)
|
||||||
|
|
||||||
|
* Fixes a crash in left outer joins that can happen when there is an aggregate
|
||||||
|
on a column from the inner side of the join. (#7901)
|
||||||
|
|
||||||
|
* Fixes deadlock with transaction recovery that is possible during Citus
|
||||||
|
upgrades. (#7910)
|
||||||
|
|
||||||
|
* Fixes a bug that prevents inserting into Citus tables that uses
|
||||||
|
a GENERATED ALWAYS AS IDENTITY column. (#7920)
|
||||||
|
|
||||||
|
* Ensures that a MERGE command on a distributed table with a WHEN NOT MATCHED BY
|
||||||
|
SOURCE clause runs against all shards of the distributed table. (#7900)
|
||||||
|
|
||||||
|
* Fixes a bug that breaks router updates on distributed tables
|
||||||
|
when a reference table is used in the subquery (#7897)
|
||||||
|
|
||||||
|
### citus v13.0.1 (February 4th, 2025) ###
|
||||||
|
|
||||||
|
* Drops support for PostgreSQL 14 (#7753)
|
||||||
|
|
||||||
|
### citus v13.0.0 (January 22, 2025) ###
|
||||||
|
|
||||||
|
* Adds support for PostgreSQL 17 (#7699, #7661)
|
||||||
|
|
||||||
|
* Adds `JSON_TABLE()` support in distributed queries (#7816)
|
||||||
|
|
||||||
|
* Propagates `MERGE ... WHEN NOT MATCHED BY SOURCE` (#7807)
|
||||||
|
|
||||||
|
* Propagates `MEMORY` and `SERIALIZE` options of `EXPLAIN` (#7802)
|
||||||
|
|
||||||
|
* Adds support for identity columns in distributed partitioned tables (#7785)
|
||||||
|
|
||||||
|
* Allows specifying an access method for distributed partitioned tables (#7818)
|
||||||
|
|
||||||
|
* Allows exclusion constraints on distributed partitioned tables (#7733)
|
||||||
|
|
||||||
|
* Allows configuring sslnegotiation using `citus.node_conn_info` (#7821)
|
||||||
|
|
||||||
|
* Avoids wal receiver timeouts during large shard splits (#7229)
|
||||||
|
|
||||||
|
* Fixes a bug causing incorrect writing of data to target `MERGE` repartition
|
||||||
|
command (#7659)
|
||||||
|
|
||||||
|
* Fixes a crash that happens because of unsafe catalog access when re-assigning
|
||||||
|
the global pid after `application_name` changes (#7791)
|
||||||
|
|
||||||
|
* Fixes incorrect `VALID UNTIL` setting assumption made for roles when syncing
|
||||||
|
them to new nodes (#7534)
|
||||||
|
|
||||||
|
* Fixes segfault when calling distributed procedure with a parameterized
|
||||||
|
distribution argument (#7242)
|
||||||
|
|
||||||
|
* Fixes server crash when trying to execute `activate_node_snapshot()` on a
|
||||||
|
single-node cluster (#7552)
|
||||||
|
|
||||||
|
* Improves `citus_move_shard_placement()` to fail early if there is a new node
|
||||||
|
without reference tables yet (#7467)
|
||||||
|
|
||||||
|
### citus v12.1.5 (July 17, 2024) ###
|
||||||
|
|
||||||
|
* Adds support for MERGE commands with single shard distributed target tables
|
||||||
|
(#7643)
|
||||||
|
|
||||||
|
* Fixes an error with MERGE commands when insert value does not have source
|
||||||
|
distribution column (#7627)
|
||||||
|
|
||||||
|
### citus v12.1.4 (May 28, 2024) ###
|
||||||
|
|
||||||
|
* Adds null check for node in HasRangeTableRef (#7604)
|
||||||
|
|
||||||
|
### citus v12.1.3 (April 18, 2024) ###
|
||||||
|
|
||||||
|
* Allows overwriting host name for all inter-node connections by
|
||||||
|
supporting "host" parameter in citus.node_conninfo (#7541)
|
||||||
|
|
||||||
|
* Changes the order in which the locks are acquired for the target and
|
||||||
|
reference tables, when a modify request is initiated from a worker
|
||||||
|
node that is not the "FirstWorkerNode" (#7542)
|
||||||
|
|
||||||
|
* Fixes a performance issue when distributing a table that depends on an
|
||||||
|
extension (#7574)
|
||||||
|
|
||||||
|
* Fixes a performance issue when using "\d tablename" on a server with
|
||||||
|
many tables (#7577)
|
||||||
|
|
||||||
|
* Fixes a crash caused by some form of ALTER TABLE ADD COLUMN
|
||||||
|
statements. When adding multiple columns, if one of the ADD COLUMN
|
||||||
|
statements contains a FOREIGN constraint omitting the referenced
|
||||||
|
columns in the statement, a SEGFAULT was occurring. (#7522)
|
||||||
|
|
||||||
|
* Fixes a performance issue when creating distributed tables if many
|
||||||
|
already exist (#7575, #7579)
|
||||||
|
|
||||||
|
* Fixes a bug when hostname in pg_dist_node resolves to multiple IPs
|
||||||
|
(#7377)
|
||||||
|
|
||||||
|
* Fixes performance issue when tracking foreign key constraints on
|
||||||
|
systems with many constraints (#7578)
|
||||||
|
|
||||||
|
* Fixes segmentation fault when using CASE WHEN in DO block within
|
||||||
|
functions. (#7554)
|
||||||
|
|
||||||
|
* Fixes undefined behavior in master_disable_node due to argument
|
||||||
|
mismatch (#7492)
|
||||||
|
|
||||||
|
* Fixes some potential bugs by correctly marking some variables as
|
||||||
|
volatile (#7570)
|
||||||
|
|
||||||
|
* Logs username in the failed connection message (#7432)
|
||||||
|
|
||||||
|
### citus v12.1.2 (February 12, 2024) ###
|
||||||
|
|
||||||
|
* Fixes the incorrect column count after ALTER TABLE (#7379)
|
||||||
|
|
||||||
|
### citus v12.1.1 (November 9, 2023) ###
|
||||||
|
|
||||||
|
* Fixes leaking of memory and memory contexts in Citus foreign key cache
|
||||||
|
(#7236)
|
||||||
|
|
||||||
|
* Makes sure to disallow creating a replicated distributed table concurrently
|
||||||
|
(#7219)
|
||||||
|
|
||||||
### citus v12.1.0 (September 12, 2023) ###
|
### citus v12.1.0 (September 12, 2023) ###
|
||||||
|
|
||||||
* Adds support for PostgreSQL 16.0 (#7173)
|
* Adds support for PostgreSQL 16.0 (#7173)
|
||||||
|
@ -5,8 +140,8 @@
|
||||||
* Add `citus_schema_move()` function which moves tables within a
|
* Add `citus_schema_move()` function which moves tables within a
|
||||||
distributed schema to another node (#7180)
|
distributed schema to another node (#7180)
|
||||||
|
|
||||||
* Adds `citus_pause_node()` UDF that allows pausing the node with given id
|
* Adds `citus_pause_node_within_txn()` UDF that allows pausing the node with
|
||||||
(#7089)
|
given id (#7089)
|
||||||
|
|
||||||
* Makes sure to enforce shard level colocation with the GUC
|
* Makes sure to enforce shard level colocation with the GUC
|
||||||
`citus.enable_non_colocated_router_query_pushdown` (#7076)
|
`citus.enable_non_colocated_router_query_pushdown` (#7076)
|
||||||
|
|
15
ci/README.md
15
ci/README.md
|
@ -385,3 +385,18 @@ definitions are in alphabetical order.
|
||||||
## `print_stack_trace.sh`
|
## `print_stack_trace.sh`
|
||||||
|
|
||||||
This script prints stack traces for failed tests, if they left core files.
|
This script prints stack traces for failed tests, if they left core files.
|
||||||
|
|
||||||
|
## `sort_and_group_includes.sh`
|
||||||
|
|
||||||
|
This script checks and fixes issues with include grouping and sorting in C files.
|
||||||
|
|
||||||
|
Includes are grouped in the following groups:
|
||||||
|
- System includes (eg. `#include <math>`)
|
||||||
|
- Postgres.h include (eg. `#include "postgres.h"`)
|
||||||
|
- Toplevel postgres includes (includes not in a directory eg. `#include "miscadmin.h`)
|
||||||
|
- Postgres includes in a directory (eg. `#include "catalog/pg_type.h"`)
|
||||||
|
- Toplevel citus includes (includes not in a directory eg. `#include "pg_version_constants.h"`)
|
||||||
|
- Columnar includes (eg. `#include "columnar/columnar.h"`)
|
||||||
|
- Distributed includes (eg. `#include "distributed/maintenanced.h"`)
|
||||||
|
|
||||||
|
Within every group the include lines are sorted alphabetically.
|
||||||
|
|
|
@ -15,9 +15,6 @@ PG_MAJOR=${PG_MAJOR:?please provide the postgres major version}
|
||||||
codename=${VERSION#*(}
|
codename=${VERSION#*(}
|
||||||
codename=${codename%)*}
|
codename=${codename%)*}
|
||||||
|
|
||||||
# get project from argument
|
|
||||||
project="${CIRCLE_PROJECT_REPONAME}"
|
|
||||||
|
|
||||||
# we'll do everything with absolute paths
|
# we'll do everything with absolute paths
|
||||||
basedir="$(pwd)"
|
basedir="$(pwd)"
|
||||||
|
|
||||||
|
@ -28,7 +25,7 @@ build_ext() {
|
||||||
pg_major="$1"
|
pg_major="$1"
|
||||||
|
|
||||||
builddir="${basedir}/build-${pg_major}"
|
builddir="${basedir}/build-${pg_major}"
|
||||||
echo "Beginning build of ${project} for PostgreSQL ${pg_major}..." >&2
|
echo "Beginning build for PostgreSQL ${pg_major}..." >&2
|
||||||
|
|
||||||
# do everything in a subdirectory to avoid clutter in current directory
|
# do everything in a subdirectory to avoid clutter in current directory
|
||||||
mkdir -p "${builddir}" && cd "${builddir}"
|
mkdir -p "${builddir}" && cd "${builddir}"
|
||||||
|
|
|
@ -14,8 +14,8 @@ ci_scripts=$(
|
||||||
grep -v -E '^(ci_helpers.sh|fix_style.sh)$'
|
grep -v -E '^(ci_helpers.sh|fix_style.sh)$'
|
||||||
)
|
)
|
||||||
for script in $ci_scripts; do
|
for script in $ci_scripts; do
|
||||||
if ! grep "\\bci/$script\\b" .circleci/config.yml > /dev/null; then
|
if ! grep "\\bci/$script\\b" -r .github > /dev/null; then
|
||||||
echo "ERROR: CI script with name \"$script\" is not actually used in .circleci/config.yml"
|
echo "ERROR: CI script with name \"$script\" is not actually used in .github folder"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if ! grep "^## \`$script\`\$" ci/README.md > /dev/null; then
|
if ! grep "^## \`$script\`\$" ci/README.md > /dev/null; then
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Testing this script locally requires you to set the following environment
|
|
||||||
# variables:
|
|
||||||
# CIRCLE_BRANCH, GIT_USERNAME and GIT_TOKEN
|
|
||||||
|
|
||||||
# fail if trying to reference a variable that is not set.
|
|
||||||
set -u
|
|
||||||
# exit immediately if a command fails
|
|
||||||
set -e
|
|
||||||
# Fail on pipe failures
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
PR_BRANCH="${CIRCLE_BRANCH}"
|
|
||||||
ENTERPRISE_REMOTE="https://${GIT_USERNAME}:${GIT_TOKEN}@github.com/citusdata/citus-enterprise"
|
|
||||||
|
|
||||||
# shellcheck disable=SC1091
|
|
||||||
source ci/ci_helpers.sh
|
|
||||||
|
|
||||||
# List executed commands. This is done so debugging this script is easier when
|
|
||||||
# it fails. It's explicitly done after git remote add so username and password
|
|
||||||
# are not shown in CI output (even though it's also filtered out by CircleCI)
|
|
||||||
set -x
|
|
||||||
|
|
||||||
check_compile () {
|
|
||||||
echo "INFO: checking if merged code can be compiled"
|
|
||||||
./configure --without-libcurl
|
|
||||||
make -j10
|
|
||||||
}
|
|
||||||
|
|
||||||
# Clone current git repo (which should be community) to a temporary working
|
|
||||||
# directory and go there
|
|
||||||
GIT_DIR_ROOT="$(git rev-parse --show-toplevel)"
|
|
||||||
TMP_GIT_DIR="$(mktemp --directory -t citus-merge-check.XXXXXXXXX)"
|
|
||||||
git clone "$GIT_DIR_ROOT" "$TMP_GIT_DIR"
|
|
||||||
cd "$TMP_GIT_DIR"
|
|
||||||
|
|
||||||
# Fails in CI without this
|
|
||||||
git config user.email "citus-bot@microsoft.com"
|
|
||||||
git config user.name "citus bot"
|
|
||||||
|
|
||||||
# Disable "set -x" temporarily, because $ENTERPRISE_REMOTE contains passwords
|
|
||||||
{ set +x ; } 2> /dev/null
|
|
||||||
git remote add enterprise "$ENTERPRISE_REMOTE"
|
|
||||||
set -x
|
|
||||||
|
|
||||||
git remote set-url --push enterprise no-pushing
|
|
||||||
|
|
||||||
# Fetch enterprise-master
|
|
||||||
git fetch enterprise enterprise-master
|
|
||||||
|
|
||||||
|
|
||||||
git checkout "enterprise/enterprise-master"
|
|
||||||
|
|
||||||
if git merge --no-commit "origin/$PR_BRANCH"; then
|
|
||||||
echo "INFO: community PR branch could be merged into enterprise-master"
|
|
||||||
# check that we can compile after the merge
|
|
||||||
if check_compile; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "WARN: Failed to compile after community PR branch was merged into enterprise"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# undo partial merge
|
|
||||||
git merge --abort
|
|
||||||
|
|
||||||
# If we have a conflict on enterprise merge on the master branch, we have a problem.
|
|
||||||
# Provide an error message to indicate that enterprise merge is needed to fix this check.
|
|
||||||
if [[ $PR_BRANCH = master ]]; then
|
|
||||||
echo "ERROR: Master branch has merge conflicts with enterprise-master."
|
|
||||||
echo "Try re-running this CI job after merging your changes into enterprise-master."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! git fetch enterprise "$PR_BRANCH" ; then
|
|
||||||
echo "ERROR: enterprise/$PR_BRANCH was not found and community PR branch could not be merged into enterprise-master"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Show the top commit of the enterprise PR branch to make debugging easier
|
|
||||||
git log -n 1 "enterprise/$PR_BRANCH"
|
|
||||||
|
|
||||||
# Check that this branch contains the top commit of the current community PR
|
|
||||||
# branch. If it does not it means it's not up to date with the current PR, so
|
|
||||||
# the enterprise branch should be updated.
|
|
||||||
if ! git merge-base --is-ancestor "origin/$PR_BRANCH" "enterprise/$PR_BRANCH" ; then
|
|
||||||
echo "ERROR: enterprise/$PR_BRANCH is not up to date with community PR branch"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Now check if we can merge the enterprise PR into enterprise-master without
|
|
||||||
# issues.
|
|
||||||
git merge --no-commit "enterprise/$PR_BRANCH"
|
|
||||||
# check that we can compile after the merge
|
|
||||||
check_compile
|
|
|
@ -5,6 +5,6 @@ set -euo pipefail
|
||||||
source ci/ci_helpers.sh
|
source ci/ci_helpers.sh
|
||||||
|
|
||||||
# extract citus gucs in the form of "citus.X"
|
# extract citus gucs in the form of "citus.X"
|
||||||
grep -o -E "(\.*\"citus.\w+\")," src/backend/distributed/shared_library_init.c > gucs.out
|
grep -o -E "(\.*\"citus\.\w+\")," src/backend/distributed/shared_library_init.c > gucs.out
|
||||||
sort -c gucs.out
|
sort -c gucs.out
|
||||||
rm gucs.out
|
rm gucs.out
|
||||||
|
|
|
@ -19,3 +19,4 @@ ci/disallow_long_changelog_entries.sh
|
||||||
ci/normalize_expected.sh
|
ci/normalize_expected.sh
|
||||||
ci/fix_gitignore.sh
|
ci/fix_gitignore.sh
|
||||||
ci/print_stack_trace.sh
|
ci/print_stack_trace.sh
|
||||||
|
ci/sort_and_group_includes.sh
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
easy command line to run against all citus-style checked files:
|
||||||
|
|
||||||
|
$ git ls-files \
|
||||||
|
| git check-attr --stdin citus-style \
|
||||||
|
| grep 'citus-style: set' \
|
||||||
|
| awk '{print $1}' \
|
||||||
|
| cut -d':' -f1 \
|
||||||
|
| xargs -n1 ./ci/include_grouping.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import collections
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
if len(args) < 2:
|
||||||
|
print("Usage: include_grouping.py <file>")
|
||||||
|
return
|
||||||
|
|
||||||
|
file = args[1]
|
||||||
|
if not os.path.isfile(file):
|
||||||
|
sys.exit(f"File '{file}' does not exist")
|
||||||
|
|
||||||
|
with open(file, "r") as in_file:
|
||||||
|
with open(file + ".tmp", "w") as out_file:
|
||||||
|
includes = []
|
||||||
|
skipped_lines = []
|
||||||
|
|
||||||
|
# This calls print_sorted_includes on a set of consecutive #include lines.
|
||||||
|
# This implicitly keeps separation of any #include lines that are contained in
|
||||||
|
# an #ifdef, because it will order the #include lines inside and after the
|
||||||
|
# #ifdef completely separately.
|
||||||
|
for line in in_file:
|
||||||
|
# if a line starts with #include we don't want to print it yet, instead we
|
||||||
|
# want to collect all consecutive #include lines
|
||||||
|
if line.startswith("#include"):
|
||||||
|
includes.append(line)
|
||||||
|
skipped_lines = []
|
||||||
|
continue
|
||||||
|
|
||||||
|
# if we have collected any #include lines, we want to print them sorted
|
||||||
|
# before printing the current line. However, if the current line is empty
|
||||||
|
# we want to perform a lookahead to see if the next line is an #include.
|
||||||
|
# To maintain any separation between #include lines and their subsequent
|
||||||
|
# lines we keep track of all lines we have skipped inbetween.
|
||||||
|
if len(includes) > 0:
|
||||||
|
if len(line.strip()) == 0:
|
||||||
|
skipped_lines.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# we have includes that need to be grouped before printing the current
|
||||||
|
# line.
|
||||||
|
print_sorted_includes(includes, file=out_file)
|
||||||
|
includes = []
|
||||||
|
|
||||||
|
# print any skipped lines
|
||||||
|
print("".join(skipped_lines), end="", file=out_file)
|
||||||
|
skipped_lines = []
|
||||||
|
|
||||||
|
print(line, end="", file=out_file)
|
||||||
|
|
||||||
|
# move out_file to file
|
||||||
|
os.rename(file + ".tmp", file)
|
||||||
|
|
||||||
|
|
||||||
|
def print_sorted_includes(includes, file=sys.stdout):
|
||||||
|
default_group_key = 1
|
||||||
|
groups = collections.defaultdict(set)
|
||||||
|
|
||||||
|
# define the groups that we separate correctly. The matchers are tested in the order
|
||||||
|
# of their priority field. The first matcher that matches the include is used to
|
||||||
|
# assign the include to a group.
|
||||||
|
# The groups are printed in the order of their group_key.
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
"name": "system includes",
|
||||||
|
"matcher": lambda x: x.startswith("<"),
|
||||||
|
"group_key": -2,
|
||||||
|
"priority": 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "toplevel postgres includes",
|
||||||
|
"matcher": lambda x: "/" not in x,
|
||||||
|
"group_key": 0,
|
||||||
|
"priority": 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "postgres.h",
|
||||||
|
"matcher": lambda x: x.strip() in ['"postgres.h"'],
|
||||||
|
"group_key": -1,
|
||||||
|
"priority": -1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "toplevel citus inlcudes",
|
||||||
|
"matcher": lambda x: x.strip()
|
||||||
|
in [
|
||||||
|
'"citus_version.h"',
|
||||||
|
'"pg_version_compat.h"',
|
||||||
|
'"pg_version_constants.h"',
|
||||||
|
],
|
||||||
|
"group_key": 3,
|
||||||
|
"priority": 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "columnar includes",
|
||||||
|
"matcher": lambda x: x.startswith('"columnar/'),
|
||||||
|
"group_key": 4,
|
||||||
|
"priority": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "distributed includes",
|
||||||
|
"matcher": lambda x: x.startswith('"distributed/'),
|
||||||
|
"group_key": 5,
|
||||||
|
"priority": 1,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
matchers.sort(key=lambda x: x["priority"])
|
||||||
|
|
||||||
|
# throughout our codebase we have some includes where either postgres or citus
|
||||||
|
# includes are wrongfully included with the syntax for system includes. Before we
|
||||||
|
# try to match those we will change the <> to "" to make them match our system. This
|
||||||
|
# will also rewrite the include to the correct syntax.
|
||||||
|
common_system_include_error_prefixes = ["<nodes/", "<distributed/"]
|
||||||
|
|
||||||
|
# assign every include to a group
|
||||||
|
for include in includes:
|
||||||
|
# extract the group key from the include
|
||||||
|
include_content = include.split(" ")[1]
|
||||||
|
|
||||||
|
# fix common system includes which are secretly postgres or citus includes
|
||||||
|
for common_prefix in common_system_include_error_prefixes:
|
||||||
|
if include_content.startswith(common_prefix):
|
||||||
|
include_content = '"' + include_content.strip()[1:-1] + '"'
|
||||||
|
include = include.split(" ")[0] + " " + include_content + "\n"
|
||||||
|
break
|
||||||
|
|
||||||
|
group_key = default_group_key
|
||||||
|
for matcher in matchers:
|
||||||
|
if matcher["matcher"](include_content):
|
||||||
|
group_key = matcher["group_key"]
|
||||||
|
break
|
||||||
|
|
||||||
|
groups[group_key].add(include)
|
||||||
|
|
||||||
|
# iterate over all groups in the natural order of its keys
|
||||||
|
for i, group in enumerate(sorted(groups.items())):
|
||||||
|
if i > 0:
|
||||||
|
print(file=file)
|
||||||
|
includes = group[1]
|
||||||
|
print("".join(sorted(includes)), end="", file=file)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv)
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source ci/ci_helpers.sh
|
||||||
|
|
||||||
|
git ls-files \
|
||||||
|
| git check-attr --stdin citus-style \
|
||||||
|
| grep 'citus-style: set' \
|
||||||
|
| awk '{print $1}' \
|
||||||
|
| cut -d':' -f1 \
|
||||||
|
| xargs -n1 ./ci/include_grouping.py
|
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69 for Citus 12.1devel.
|
# Generated by GNU Autoconf 2.69 for Citus 13.0.3.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||||
|
@ -579,8 +579,8 @@ MAKEFLAGS=
|
||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='Citus'
|
PACKAGE_NAME='Citus'
|
||||||
PACKAGE_TARNAME='citus'
|
PACKAGE_TARNAME='citus'
|
||||||
PACKAGE_VERSION='12.1devel'
|
PACKAGE_VERSION='13.0.3'
|
||||||
PACKAGE_STRING='Citus 12.1devel'
|
PACKAGE_STRING='Citus 13.0.3'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
|
@ -1262,7 +1262,7 @@ if test "$ac_init_help" = "long"; then
|
||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures Citus 12.1devel to adapt to many kinds of systems.
|
\`configure' configures Citus 13.0.3 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
|
@ -1324,7 +1324,7 @@ fi
|
||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of Citus 12.1devel:";;
|
short | recursive ) echo "Configuration of Citus 13.0.3:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
|
@ -1429,7 +1429,7 @@ fi
|
||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
Citus configure 12.1devel
|
Citus configure 13.0.3
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
@ -1912,7 +1912,7 @@ cat >config.log <<_ACEOF
|
||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by Citus $as_me 12.1devel, which was
|
It was created by Citus $as_me 13.0.3, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
|
@ -2588,7 +2588,7 @@ fi
|
||||||
if test "$with_pg_version_check" = no; then
|
if test "$with_pg_version_check" = no; then
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num (skipped compatibility check)" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num (skipped compatibility check)" >&5
|
||||||
$as_echo "$as_me: building against PostgreSQL $version_num (skipped compatibility check)" >&6;}
|
$as_echo "$as_me: building against PostgreSQL $version_num (skipped compatibility check)" >&6;}
|
||||||
elif test "$version_num" != '14' -a "$version_num" != '15' -a "$version_num" != '16'; then
|
elif test "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; then
|
||||||
as_fn_error $? "Citus is not compatible with the detected PostgreSQL version ${version_num}." "$LINENO" 5
|
as_fn_error $? "Citus is not compatible with the detected PostgreSQL version ${version_num}." "$LINENO" 5
|
||||||
else
|
else
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num" >&5
|
||||||
|
@ -5393,7 +5393,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by Citus $as_me 12.1devel, which was
|
This file was extended by Citus $as_me 13.0.3, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
|
@ -5455,7 +5455,7 @@ _ACEOF
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
Citus config.status 12.1devel
|
Citus config.status 13.0.3
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# everyone needing autoconf installed, the resulting files are checked
|
# everyone needing autoconf installed, the resulting files are checked
|
||||||
# into the SCM.
|
# into the SCM.
|
||||||
|
|
||||||
AC_INIT([Citus], [12.1devel])
|
AC_INIT([Citus], [13.0.3])
|
||||||
AC_COPYRIGHT([Copyright (c) Citus Data, Inc.])
|
AC_COPYRIGHT([Copyright (c) Citus Data, Inc.])
|
||||||
|
|
||||||
# we'll need sed and awk for some of the version commands
|
# we'll need sed and awk for some of the version commands
|
||||||
|
@ -80,7 +80,7 @@ AC_SUBST(with_pg_version_check)
|
||||||
|
|
||||||
if test "$with_pg_version_check" = no; then
|
if test "$with_pg_version_check" = no; then
|
||||||
AC_MSG_NOTICE([building against PostgreSQL $version_num (skipped compatibility check)])
|
AC_MSG_NOTICE([building against PostgreSQL $version_num (skipped compatibility check)])
|
||||||
elif test "$version_num" != '14' -a "$version_num" != '15' -a "$version_num" != '16'; then
|
elif test "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; then
|
||||||
AC_MSG_ERROR([Citus is not compatible with the detected PostgreSQL version ${version_num}.])
|
AC_MSG_ERROR([Citus is not compatible with the detected PostgreSQL version ${version_num}.])
|
||||||
else
|
else
|
||||||
AC_MSG_NOTICE([building against PostgreSQL $version_num])
|
AC_MSG_NOTICE([building against PostgreSQL $version_num])
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
"citus.all_modifications_commutative",
|
||||||
|
"citus.allow_modifications_from_workers_to_replicated_tables",
|
||||||
|
"citus.allow_nested_distributed_execution",
|
||||||
|
"citus.allow_unsafe_constraints",
|
||||||
|
"citus.allow_unsafe_locks_from_workers",
|
||||||
|
"citus.background_task_queue_interval",
|
||||||
|
"citus.check_available_space_before_move",
|
||||||
|
"citus.cluster_name",
|
||||||
|
"citus.coordinator_aggregation_strategy",
|
||||||
|
"citus.copy_switchover_threshold",
|
||||||
|
"citus.count_distinct_error_rate",
|
||||||
|
"citus.cpu_priority",
|
||||||
|
"citus.cpu_priority_for_logical_replication_senders",
|
||||||
|
"citus.create_object_propagation",
|
||||||
|
"citus.defer_drop_after_shard_move",
|
||||||
|
"citus.defer_drop_after_shard_split",
|
||||||
|
"citus.defer_shard_delete_interval",
|
||||||
|
"citus.desired_percent_disk_available_after_move",
|
||||||
|
"citus.distributed_deadlock_detection_factor",
|
||||||
|
"citus.enable_alter_database_owner",
|
||||||
|
"citus.enable_alter_role_propagation",
|
||||||
|
"citus.enable_alter_role_set_propagation",
|
||||||
|
"citus.enable_binary_protocol",
|
||||||
|
"citus.enable_change_data_capture",
|
||||||
|
"citus.enable_cluster_clock",
|
||||||
|
"citus.enable_cost_based_connection_establishment",
|
||||||
|
"citus.enable_create_role_propagation",
|
||||||
|
"citus.enable_create_type_propagation",
|
||||||
|
"citus.enable_ddl_propagation",
|
||||||
|
"citus.enable_deadlock_prevention",
|
||||||
|
"citus.enable_fast_path_router_planner",
|
||||||
|
"citus.enable_local_execution",
|
||||||
|
"citus.enable_local_reference_table_foreign_keys",
|
||||||
|
"citus.enable_manual_changes_to_shards",
|
||||||
|
"citus.enable_manual_metadata_changes_for_user",
|
||||||
|
"citus.enable_metadata_sync",
|
||||||
|
"citus.enable_non_colocated_router_query_pushdown",
|
||||||
|
"citus.enable_repartition_joins",
|
||||||
|
"citus.enable_repartitioned_insert_select",
|
||||||
|
"citus.enable_router_execution",
|
||||||
|
"citus.enable_schema_based_sharding",
|
||||||
|
"citus.enable_single_hash_repartition_joins",
|
||||||
|
"citus.enable_statistics_collection",
|
||||||
|
"citus.enable_unique_job_ids",
|
||||||
|
"citus.enable_unsafe_triggers",
|
||||||
|
"citus.enable_unsupported_feature_messages",
|
||||||
|
"citus.enable_version_checks",
|
||||||
|
"citus.enforce_foreign_key_restrictions",
|
||||||
|
"citus.enforce_object_restrictions_for_local_objects",
|
||||||
|
"citus.executor_slow_start_interval",
|
||||||
|
"citus.explain_all_tasks",
|
||||||
|
"citus.explain_analyze_sort_method",
|
||||||
|
"citus.explain_distributed_queries",
|
||||||
|
"citus.force_max_query_parallelization",
|
||||||
|
"citus.function_opens_transaction_block",
|
||||||
|
"citus.grep_remote_commands",
|
||||||
|
"citus.hide_citus_dependent_objects",
|
||||||
|
"citus.hide_shards_from_app_name_prefixes",
|
||||||
|
"citus.isolation_test_session_process_id",
|
||||||
|
"citus.isolation_test_session_remote_process_id",
|
||||||
|
"citus.limit_clause_row_fetch_count",
|
||||||
|
"citus.local_copy_flush_threshold",
|
||||||
|
"citus.local_hostname",
|
||||||
|
"citus.local_shared_pool_size",
|
||||||
|
"citus.local_table_join_policy",
|
||||||
|
"citus.log_distributed_deadlock_detection",
|
||||||
|
"citus.log_intermediate_results",
|
||||||
|
"citus.log_local_commands",
|
||||||
|
"citus.log_multi_join_order",
|
||||||
|
"citus.log_remote_commands",
|
||||||
|
"citus.logical_replication_timeout",
|
||||||
|
"citus.main_db",
|
||||||
|
"citus.max_adaptive_executor_pool_size",
|
||||||
|
"citus.max_background_task_executors",
|
||||||
|
"citus.max_background_task_executors_per_node",
|
||||||
|
"citus.max_cached_connection_lifetime",
|
||||||
|
"citus.max_cached_conns_per_worker",
|
||||||
|
"citus.max_client_connections",
|
||||||
|
"citus.max_high_priority_background_processes",
|
||||||
|
"citus.max_intermediate_result_size",
|
||||||
|
"citus.max_matview_size_to_auto_recreate",
|
||||||
|
"citus.max_rebalancer_logged_ignored_moves",
|
||||||
|
"citus.max_shared_pool_size",
|
||||||
|
"citus.max_worker_nodes_tracked",
|
||||||
|
"citus.metadata_sync_interval",
|
||||||
|
"citus.metadata_sync_mode",
|
||||||
|
"citus.metadata_sync_retry_interval",
|
||||||
|
"citus.mitmfifo",
|
||||||
|
"citus.multi_shard_modify_mode",
|
||||||
|
"citus.multi_task_query_log_level",
|
||||||
|
"citus.next_cleanup_record_id",
|
||||||
|
"citus.next_operation_id",
|
||||||
|
"citus.next_placement_id",
|
||||||
|
"citus.next_shard_id",
|
||||||
|
"citus.node_connection_timeout",
|
||||||
|
"citus.node_conninfo",
|
||||||
|
"citus.override_table_visibility",
|
||||||
|
"citus.prevent_incomplete_connection_establishment",
|
||||||
|
"citus.propagate_session_settings_for_loopback_connection",
|
||||||
|
"citus.propagate_set_commands",
|
||||||
|
"citus.rebalancer_by_disk_size_base_cost",
|
||||||
|
"citus.recover_2pc_interval",
|
||||||
|
"citus.remote_copy_flush_threshold",
|
||||||
|
"citus.remote_task_check_interval",
|
||||||
|
"citus.repartition_join_bucket_count_per_node",
|
||||||
|
"citus.replicate_reference_tables_on_activate",
|
||||||
|
"citus.replication_model",
|
||||||
|
"citus.running_under_citus_test_suite",
|
||||||
|
"citus.select_opens_transaction_block",
|
||||||
|
"citus.shard_count",
|
||||||
|
"citus.shard_replication_factor",
|
||||||
|
"citus.show_shards_for_app_name_prefixes",
|
||||||
|
"citus.skip_advisory_lock_permission_checks",
|
||||||
|
"citus.skip_constraint_validation",
|
||||||
|
"citus.skip_jsonb_validation_in_copy",
|
||||||
|
"citus.sort_returning",
|
||||||
|
"citus.stat_statements_max",
|
||||||
|
"citus.stat_statements_purge_interval",
|
||||||
|
"citus.stat_statements_track",
|
||||||
|
"citus.stat_tenants_limit",
|
||||||
|
"citus.stat_tenants_log_level",
|
||||||
|
"citus.stat_tenants_period",
|
||||||
|
"citus.stat_tenants_track",
|
||||||
|
"citus.stat_tenants_untracked_sample_rate",
|
||||||
|
"citus.subquery_pushdown",
|
||||||
|
"citus.task_assignment_policy",
|
||||||
|
"citus.task_executor_type",
|
||||||
|
"citus.use_citus_managed_tables",
|
||||||
|
"citus.use_secondary_nodes",
|
||||||
|
"citus.values_materialization_threshold",
|
||||||
|
"citus.version",
|
||||||
|
"citus.worker_min_messages",
|
||||||
|
"citus.writable_standby_coordinator",
|
|
@ -11,16 +11,18 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
|
||||||
#include "citus_version.h"
|
#include "citus_version.h"
|
||||||
|
|
||||||
#include "columnar/columnar.h"
|
#include "columnar/columnar.h"
|
||||||
#include "columnar/columnar_tableam.h"
|
#include "columnar/columnar_tableam.h"
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,13 @@
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "citus_version.h"
|
|
||||||
#include "common/pg_lzcompress.h"
|
#include "common/pg_lzcompress.h"
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
|
|
||||||
|
#include "citus_version.h"
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "columnar/columnar_compression.h"
|
#include "columnar/columnar_compression.h"
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
|
|
||||||
#if HAVE_CITUS_LIBLZ4
|
#if HAVE_CITUS_LIBLZ4
|
||||||
#include <lz4.h>
|
#include <lz4.h>
|
||||||
|
|
|
@ -10,18 +10,17 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "citus_version.h"
|
#include <math.h>
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/amapi.h"
|
#include "access/amapi.h"
|
||||||
#include "access/skey.h"
|
#include "access/skey.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "catalog/pg_statistic.h"
|
#include "catalog/pg_statistic.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/extensible.h"
|
#include "nodes/extensible.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
|
@ -33,6 +32,8 @@
|
||||||
#include "optimizer/paths.h"
|
#include "optimizer/paths.h"
|
||||||
#include "optimizer/plancat.h"
|
#include "optimizer/plancat.h"
|
||||||
#include "optimizer/restrictinfo.h"
|
#include "optimizer/restrictinfo.h"
|
||||||
|
|
||||||
|
#include "citus_version.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
#include "columnar/columnar_customscan.h"
|
#include "columnar/columnar_customscan.h"
|
||||||
#include "columnar/columnar_metadata.h"
|
#include "columnar/columnar_metadata.h"
|
||||||
#include "columnar/columnar_tableam.h"
|
#include "columnar/columnar_tableam.h"
|
||||||
|
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -361,7 +363,7 @@ ColumnarGetRelationInfoHook(PlannerInfo *root, Oid relationObjectId,
|
||||||
|
|
||||||
/* disable index-only scan */
|
/* disable index-only scan */
|
||||||
IndexOptInfo *indexOptInfo = NULL;
|
IndexOptInfo *indexOptInfo = NULL;
|
||||||
foreach_ptr(indexOptInfo, rel->indexlist)
|
foreach_declared_ptr(indexOptInfo, rel->indexlist)
|
||||||
{
|
{
|
||||||
memset(indexOptInfo->canreturn, false, indexOptInfo->ncolumns * sizeof(bool));
|
memset(indexOptInfo->canreturn, false, indexOptInfo->ncolumns * sizeof(bool));
|
||||||
}
|
}
|
||||||
|
@ -379,7 +381,7 @@ RemovePathsByPredicate(RelOptInfo *rel, PathPredicate removePathPredicate)
|
||||||
List *filteredPathList = NIL;
|
List *filteredPathList = NIL;
|
||||||
|
|
||||||
Path *path = NULL;
|
Path *path = NULL;
|
||||||
foreach_ptr(path, rel->pathlist)
|
foreach_declared_ptr(path, rel->pathlist)
|
||||||
{
|
{
|
||||||
if (!removePathPredicate(path))
|
if (!removePathPredicate(path))
|
||||||
{
|
{
|
||||||
|
@ -426,7 +428,7 @@ static void
|
||||||
CostColumnarPaths(PlannerInfo *root, RelOptInfo *rel, Oid relationId)
|
CostColumnarPaths(PlannerInfo *root, RelOptInfo *rel, Oid relationId)
|
||||||
{
|
{
|
||||||
Path *path = NULL;
|
Path *path = NULL;
|
||||||
foreach_ptr(path, rel->pathlist)
|
foreach_declared_ptr(path, rel->pathlist)
|
||||||
{
|
{
|
||||||
if (IsA(path, IndexPath))
|
if (IsA(path, IndexPath))
|
||||||
{
|
{
|
||||||
|
@ -781,7 +783,7 @@ ExtractPushdownClause(PlannerInfo *root, RelOptInfo *rel, Node *node)
|
||||||
List *pushdownableArgs = NIL;
|
List *pushdownableArgs = NIL;
|
||||||
|
|
||||||
Node *boolExprArg = NULL;
|
Node *boolExprArg = NULL;
|
||||||
foreach_ptr(boolExprArg, boolExpr->args)
|
foreach_declared_ptr(boolExprArg, boolExpr->args)
|
||||||
{
|
{
|
||||||
Expr *pushdownableArg = ExtractPushdownClause(root, rel,
|
Expr *pushdownableArg = ExtractPushdownClause(root, rel,
|
||||||
(Node *) boolExprArg);
|
(Node *) boolExprArg);
|
||||||
|
@ -1049,6 +1051,15 @@ FindCandidateRelids(PlannerInfo *root, RelOptInfo *rel, List *joinClauses)
|
||||||
|
|
||||||
candidateRelids = bms_del_members(candidateRelids, rel->relids);
|
candidateRelids = bms_del_members(candidateRelids, rel->relids);
|
||||||
candidateRelids = bms_del_members(candidateRelids, rel->lateral_relids);
|
candidateRelids = bms_del_members(candidateRelids, rel->lateral_relids);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the relevant PG16 commit requiring this addition:
|
||||||
|
* postgres/postgres@2489d76
|
||||||
|
*/
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
|
candidateRelids = bms_del_members(candidateRelids, root->outer_join_rels);
|
||||||
|
#endif
|
||||||
|
|
||||||
return candidateRelids;
|
return candidateRelids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1310,11 +1321,8 @@ AddColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte,
|
||||||
|
|
||||||
cpath->methods = &ColumnarScanPathMethods;
|
cpath->methods = &ColumnarScanPathMethods;
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/* necessary to avoid extra Result node in PG15 */
|
/* necessary to avoid extra Result node in PG15 */
|
||||||
cpath->flags = CUSTOMPATH_SUPPORT_PROJECTION;
|
cpath->flags = CUSTOMPATH_SUPPORT_PROJECTION;
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* populate generic path information
|
* populate generic path information
|
||||||
|
@ -1548,7 +1556,7 @@ ColumnarPerStripeScanCost(RelOptInfo *rel, Oid relationId, int numberOfColumnsRe
|
||||||
uint32 maxColumnCount = 0;
|
uint32 maxColumnCount = 0;
|
||||||
uint64 totalStripeSize = 0;
|
uint64 totalStripeSize = 0;
|
||||||
StripeMetadata *stripeMetadata = NULL;
|
StripeMetadata *stripeMetadata = NULL;
|
||||||
foreach_ptr(stripeMetadata, stripeList)
|
foreach_declared_ptr(stripeMetadata, stripeList)
|
||||||
{
|
{
|
||||||
totalStripeSize += stripeMetadata->dataLength;
|
totalStripeSize += stripeMetadata->dataLength;
|
||||||
maxColumnCount = Max(maxColumnCount, stripeMetadata->columnCount);
|
maxColumnCount = Max(maxColumnCount, stripeMetadata->columnCount);
|
||||||
|
@ -1922,11 +1930,6 @@ ColumnarScan_EndCustomScan(CustomScanState *node)
|
||||||
*/
|
*/
|
||||||
TableScanDesc scanDesc = node->ss.ss_currentScanDesc;
|
TableScanDesc scanDesc = node->ss.ss_currentScanDesc;
|
||||||
|
|
||||||
/*
|
|
||||||
* Free the exprcontext
|
|
||||||
*/
|
|
||||||
ExecFreeExprContext(&node->ss.ps);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "funcapi.h"
|
#include "funcapi.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/nbtree.h"
|
#include "access/nbtree.h"
|
||||||
#include "access/table.h"
|
#include "access/table.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
|
@ -25,6 +25,8 @@
|
||||||
#include "utils/tuplestore.h"
|
#include "utils/tuplestore.h"
|
||||||
|
|
||||||
#include "pg_version_compat.h"
|
#include "pg_version_compat.h"
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "columnar/columnar.h"
|
#include "columnar/columnar.h"
|
||||||
#include "columnar/columnar_storage.h"
|
#include "columnar/columnar_storage.h"
|
||||||
#include "columnar/columnar_version_compat.h"
|
#include "columnar/columnar_version_compat.h"
|
||||||
|
|
|
@ -19,46 +19,50 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
#include "safe_lib.h"
|
#include "safe_lib.h"
|
||||||
|
|
||||||
#include "citus_version.h"
|
|
||||||
#include "columnar/columnar.h"
|
|
||||||
#include "columnar/columnar_storage.h"
|
|
||||||
#include "columnar/columnar_version_compat.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/nbtree.h"
|
#include "access/nbtree.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_namespace.h"
|
|
||||||
#include "catalog/pg_collation.h"
|
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
|
#include "catalog/pg_collation.h"
|
||||||
|
#include "catalog/pg_namespace.h"
|
||||||
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/sequence.h"
|
#include "commands/sequence.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "executor/spi.h"
|
#include "executor/spi.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/execnodes.h"
|
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
|
#include "nodes/execnodes.h"
|
||||||
|
|
||||||
|
#include "citus_version.h"
|
||||||
|
|
||||||
|
#include "columnar/columnar.h"
|
||||||
|
#include "columnar/columnar_storage.h"
|
||||||
|
#include "columnar/columnar_version_compat.h"
|
||||||
|
|
||||||
|
#include "distributed/listutils.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
#endif
|
#endif
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
|
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "storage/procarray.h"
|
#include "storage/procarray.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/memutils.h"
|
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
#include "storage/relfilelocator.h"
|
#include "storage/relfilelocator.h"
|
||||||
|
@ -1682,7 +1686,7 @@ DeleteTupleAndEnforceConstraints(ModifyState *state, HeapTuple heapTuple)
|
||||||
simple_heap_delete(state->rel, tid);
|
simple_heap_delete(state->rel, tid);
|
||||||
|
|
||||||
/* execute AFTER ROW DELETE Triggers to enforce constraints */
|
/* execute AFTER ROW DELETE Triggers to enforce constraints */
|
||||||
ExecARDeleteTriggers_compat(estate, resultRelInfo, tid, NULL, NULL, false);
|
ExecARDeleteTriggers(estate, resultRelInfo, tid, NULL, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2038,7 +2042,7 @@ GetHighestUsedRowNumber(uint64 storageId)
|
||||||
List *stripeMetadataList = ReadDataFileStripeList(storageId,
|
List *stripeMetadataList = ReadDataFileStripeList(storageId,
|
||||||
GetTransactionSnapshot());
|
GetTransactionSnapshot());
|
||||||
StripeMetadata *stripeMetadata = NULL;
|
StripeMetadata *stripeMetadata = NULL;
|
||||||
foreach_ptr(stripeMetadata, stripeMetadataList)
|
foreach_declared_ptr(stripeMetadata, stripeMetadataList)
|
||||||
{
|
{
|
||||||
highestRowNumber = Max(highestRowNumber,
|
highestRowNumber = Max(highestRowNumber,
|
||||||
StripeGetHighestRowNumber(stripeMetadata));
|
StripeGetHighestRowNumber(stripeMetadata));
|
||||||
|
|
|
@ -22,16 +22,15 @@
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
#include "optimizer/optimizer.h"
|
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
|
#include "optimizer/optimizer.h"
|
||||||
#include "optimizer/restrictinfo.h"
|
#include "optimizer/restrictinfo.h"
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
#include "utils/memutils.h"
|
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
|
||||||
#include "columnar/columnar.h"
|
#include "columnar/columnar.h"
|
||||||
|
@ -39,6 +38,8 @@
|
||||||
#include "columnar/columnar_tableam.h"
|
#include "columnar/columnar_tableam.h"
|
||||||
#include "columnar/columnar_version_compat.h"
|
#include "columnar/columnar_version_compat.h"
|
||||||
|
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
|
||||||
#define UNEXPECTED_STRIPE_READ_ERR_MSG \
|
#define UNEXPECTED_STRIPE_READ_ERR_MSG \
|
||||||
"attempted to read an unexpected stripe while reading columnar " \
|
"attempted to read an unexpected stripe while reading columnar " \
|
||||||
"table %s, stripe with id=" UINT64_FORMAT " is not flushed"
|
"table %s, stripe with id=" UINT64_FORMAT " is not flushed"
|
||||||
|
@ -879,7 +880,7 @@ ReadChunkGroupNextRow(ChunkGroupReadState *chunkGroupReadState, Datum *columnVal
|
||||||
memset(columnNulls, true, sizeof(bool) * chunkGroupReadState->columnCount);
|
memset(columnNulls, true, sizeof(bool) * chunkGroupReadState->columnCount);
|
||||||
|
|
||||||
int attno;
|
int attno;
|
||||||
foreach_int(attno, chunkGroupReadState->projectedColumnList)
|
foreach_declared_int(attno, chunkGroupReadState->projectedColumnList)
|
||||||
{
|
{
|
||||||
const ChunkData *chunkGroupData = chunkGroupReadState->chunkGroupData;
|
const ChunkData *chunkGroupData = chunkGroupReadState->chunkGroupData;
|
||||||
const int rowIndex = chunkGroupReadState->currentRow;
|
const int rowIndex = chunkGroupReadState->currentRow;
|
||||||
|
@ -1488,7 +1489,7 @@ ProjectedColumnMask(uint32 columnCount, List *projectedColumnList)
|
||||||
bool *projectedColumnMask = palloc0(columnCount * sizeof(bool));
|
bool *projectedColumnMask = palloc0(columnCount * sizeof(bool));
|
||||||
int attno;
|
int attno;
|
||||||
|
|
||||||
foreach_int(attno, projectedColumnList)
|
foreach_declared_int(attno, projectedColumnList)
|
||||||
{
|
{
|
||||||
/* attno is 1-indexed; projectedColumnMask is 0-indexed */
|
/* attno is 1-indexed; projectedColumnMask is 0-indexed */
|
||||||
int columnIndex = attno - 1;
|
int columnIndex = attno - 1;
|
||||||
|
|
|
@ -36,11 +36,11 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
#include "safe_lib.h"
|
#include "safe_lib.h"
|
||||||
|
|
||||||
#include "access/generic_xlog.h"
|
#include "access/generic_xlog.h"
|
||||||
#include "catalog/storage.h"
|
#include "catalog/storage.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,38 @@
|
||||||
#include "citus_version.h"
|
#include <math.h>
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "pgstat.h"
|
||||||
|
#include "safe_lib.h"
|
||||||
|
|
||||||
|
#include "access/detoast.h"
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/multixact.h"
|
#include "access/multixact.h"
|
||||||
#include "access/rewriteheap.h"
|
#include "access/rewriteheap.h"
|
||||||
#include "access/tableam.h"
|
#include "access/tableam.h"
|
||||||
#include "access/tsmapi.h"
|
#include "access/tsmapi.h"
|
||||||
#include "access/detoast.h"
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/objectaccess.h"
|
#include "catalog/objectaccess.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
|
#include "catalog/pg_extension.h"
|
||||||
#include "catalog/pg_publication.h"
|
#include "catalog/pg_publication.h"
|
||||||
#include "catalog/pg_trigger.h"
|
#include "catalog/pg_trigger.h"
|
||||||
#include "catalog/pg_extension.h"
|
|
||||||
#include "catalog/storage.h"
|
#include "catalog/storage.h"
|
||||||
#include "catalog/storage_xlog.h"
|
#include "catalog/storage_xlog.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
#include "commands/extension.h"
|
||||||
#include "commands/progress.h"
|
#include "commands/progress.h"
|
||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
#include "commands/extension.h"
|
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "optimizer/plancat.h"
|
#include "optimizer/plancat.h"
|
||||||
#include "pg_version_compat.h"
|
|
||||||
#include "pgstat.h"
|
|
||||||
#include "safe_lib.h"
|
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "storage/bufpage.h"
|
#include "storage/bufpage.h"
|
||||||
#include "storage/bufmgr.h"
|
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "storage/predicate.h"
|
#include "storage/predicate.h"
|
||||||
#include "storage/procarray.h"
|
#include "storage/procarray.h"
|
||||||
|
@ -44,17 +40,22 @@
|
||||||
#include "tcop/utility.h"
|
#include "tcop/utility.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/pg_rusage.h"
|
#include "utils/pg_rusage.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "citus_version.h"
|
||||||
|
#include "pg_version_compat.h"
|
||||||
|
|
||||||
#include "columnar/columnar.h"
|
#include "columnar/columnar.h"
|
||||||
#include "columnar/columnar_customscan.h"
|
#include "columnar/columnar_customscan.h"
|
||||||
#include "columnar/columnar_storage.h"
|
#include "columnar/columnar_storage.h"
|
||||||
#include "columnar/columnar_tableam.h"
|
#include "columnar/columnar_tableam.h"
|
||||||
#include "columnar/columnar_version_compat.h"
|
#include "columnar/columnar_version_compat.h"
|
||||||
|
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -876,7 +877,7 @@ columnar_relation_set_new_filelocator(Relation rel,
|
||||||
|
|
||||||
*freezeXid = RecentXmin;
|
*freezeXid = RecentXmin;
|
||||||
*minmulti = GetOldestMultiXactId();
|
*minmulti = GetOldestMultiXactId();
|
||||||
SMgrRelation srel = RelationCreateStorage_compat(*newrlocator, persistence, true);
|
SMgrRelation srel = RelationCreateStorage(*newrlocator, persistence, true);
|
||||||
|
|
||||||
ColumnarStorageInit(srel, ColumnarMetadataNewStorageId());
|
ColumnarStorageInit(srel, ColumnarMetadataNewStorageId());
|
||||||
InitColumnarOptions(rel->rd_id);
|
InitColumnarOptions(rel->rd_id);
|
||||||
|
@ -1423,15 +1424,32 @@ ConditionalLockRelationWithTimeout(Relation rel, LOCKMODE lockMode, int timeout,
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
columnar_scan_analyze_next_block(TableScanDesc scan, BlockNumber blockno,
|
columnar_scan_analyze_next_block(TableScanDesc scan,
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
|
ReadStream *stream)
|
||||||
|
#else
|
||||||
|
BlockNumber blockno,
|
||||||
BufferAccessStrategy bstrategy)
|
BufferAccessStrategy bstrategy)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Our access method is not pages based, i.e. tuples are not confined
|
* Our access method is not pages based, i.e. tuples are not confined
|
||||||
* to pages boundaries. So not much to do here. We return true anyway
|
* to pages boundaries. So not much to do here. We return true anyway
|
||||||
* so acquire_sample_rows() in analyze.c would call our
|
* so acquire_sample_rows() in analyze.c would call our
|
||||||
* columnar_scan_analyze_next_tuple() callback.
|
* columnar_scan_analyze_next_tuple() callback.
|
||||||
|
* In PG17, we return false in case there is no buffer left, since
|
||||||
|
* the outer loop changed in acquire_sample_rows(), and it is
|
||||||
|
* expected for the scan_analyze_next_block function to check whether
|
||||||
|
* there are any blocks left in the block sampler.
|
||||||
*/
|
*/
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
|
Buffer buf = read_stream_next_buffer(stream, NULL);
|
||||||
|
if (!BufferIsValid(buf))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ReleaseBuffer(buf);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2227,7 +2245,6 @@ ColumnarProcessAlterTable(AlterTableStmt *alterTableStmt, List **columnarOptions
|
||||||
columnarRangeVar = alterTableStmt->relation;
|
columnarRangeVar = alterTableStmt->relation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
else if (alterTableCmd->subtype == AT_SetAccessMethod)
|
else if (alterTableCmd->subtype == AT_SetAccessMethod)
|
||||||
{
|
{
|
||||||
if (columnarRangeVar || *columnarOptions)
|
if (columnarRangeVar || *columnarOptions)
|
||||||
|
@ -2238,14 +2255,15 @@ ColumnarProcessAlterTable(AlterTableStmt *alterTableStmt, List **columnarOptions
|
||||||
"Specify SET ACCESS METHOD before storage parameters, or use separate ALTER TABLE commands.")));
|
"Specify SET ACCESS METHOD before storage parameters, or use separate ALTER TABLE commands.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
destIsColumnar = (strcmp(alterTableCmd->name, COLUMNAR_AM_NAME) == 0);
|
destIsColumnar = (strcmp(alterTableCmd->name ? alterTableCmd->name :
|
||||||
|
default_table_access_method,
|
||||||
|
COLUMNAR_AM_NAME) == 0);
|
||||||
|
|
||||||
if (srcIsColumnar && !destIsColumnar)
|
if (srcIsColumnar && !destIsColumnar)
|
||||||
{
|
{
|
||||||
DeleteColumnarTableOptions(RelationGetRelid(rel), true);
|
DeleteColumnarTableOptions(RelationGetRelid(rel), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PG_VERSION_15 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
relation_close(rel, NoLock);
|
relation_close(rel, NoLock);
|
||||||
|
@ -2629,21 +2647,12 @@ ColumnarCheckLogicalReplication(Relation rel)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
{
|
{
|
||||||
PublicationDesc pubdesc;
|
PublicationDesc pubdesc;
|
||||||
|
|
||||||
RelationBuildPublicationDesc(rel, &pubdesc);
|
RelationBuildPublicationDesc(rel, &pubdesc);
|
||||||
pubActionInsert = pubdesc.pubactions.pubinsert;
|
pubActionInsert = pubdesc.pubactions.pubinsert;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (rel->rd_pubactions == NULL)
|
|
||||||
{
|
|
||||||
GetRelationPublicationActions(rel);
|
|
||||||
Assert(rel->rd_pubactions != NULL);
|
|
||||||
}
|
|
||||||
pubActionInsert = rel->rd_pubactions->pubinsert;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pubActionInsert)
|
if (pubActionInsert)
|
||||||
{
|
{
|
||||||
|
@ -2945,7 +2954,7 @@ MajorVersionsCompatibleColumnar(char *leftVersion, char *rightVersion)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rightComparisionLimit = strlen(leftVersion);
|
rightComparisionLimit = strlen(rightVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we can error out early if hypens are not in the same position */
|
/* we can error out early if hypens are not in the same position */
|
||||||
|
@ -3020,6 +3029,8 @@ AvailableExtensionVersionColumnar(void)
|
||||||
|
|
||||||
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||||
errmsg("citus extension is not found")));
|
errmsg("citus extension is not found")));
|
||||||
|
|
||||||
|
return NULL; /* keep compiler happy */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3082,7 +3093,7 @@ DefElem *
|
||||||
GetExtensionOption(List *extensionOptions, const char *defname)
|
GetExtensionOption(List *extensionOptions, const char *defname)
|
||||||
{
|
{
|
||||||
DefElem *defElement = NULL;
|
DefElem *defElement = NULL;
|
||||||
foreach_ptr(defElement, extensionOptions)
|
foreach_declared_ptr(defElement, extensionOptions)
|
||||||
{
|
{
|
||||||
if (IsA(defElement, DefElem) &&
|
if (IsA(defElement, DefElem) &&
|
||||||
strncmp(defElement->defname, defname, NAMEDATALEN) == 0)
|
strncmp(defElement->defname, defname, NAMEDATALEN) == 0)
|
||||||
|
|
|
@ -16,18 +16,19 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
#include "safe_lib.h"
|
#include "safe_lib.h"
|
||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/nbtree.h"
|
#include "access/nbtree.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "pg_version_compat.h"
|
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
|
||||||
|
#include "pg_version_compat.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
#include "storage/relfilelocator.h"
|
#include "storage/relfilelocator.h"
|
||||||
#include "utils/relfilenumbermap.h"
|
#include "utils/relfilenumbermap.h"
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
|
|
||||||
#include "citus_version.h"
|
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
#include "columnar/columnar.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "pgstat.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
|
#include "access/heaptoast.h"
|
||||||
#include "access/multixact.h"
|
#include "access/multixact.h"
|
||||||
#include "access/rewriteheap.h"
|
#include "access/rewriteheap.h"
|
||||||
#include "access/tsmapi.h"
|
#include "access/tsmapi.h"
|
||||||
#include "access/heaptoast.h"
|
|
||||||
#include "common/hashfn.h"
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
|
@ -26,14 +22,12 @@
|
||||||
#include "catalog/storage_xlog.h"
|
#include "catalog/storage_xlog.h"
|
||||||
#include "commands/progress.h"
|
#include "commands/progress.h"
|
||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
|
#include "common/hashfn.h"
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "optimizer/plancat.h"
|
#include "optimizer/plancat.h"
|
||||||
#include "pg_version_compat.h"
|
|
||||||
#include "pgstat.h"
|
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "storage/bufpage.h"
|
#include "storage/bufpage.h"
|
||||||
#include "storage/bufmgr.h"
|
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "storage/predicate.h"
|
#include "storage/predicate.h"
|
||||||
#include "storage/procarray.h"
|
#include "storage/procarray.h"
|
||||||
|
@ -44,6 +38,10 @@
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "citus_version.h"
|
||||||
|
#include "pg_version_compat.h"
|
||||||
|
|
||||||
|
#include "columnar/columnar.h"
|
||||||
#include "columnar/columnar_customscan.h"
|
#include "columnar/columnar_customscan.h"
|
||||||
#include "columnar/columnar_tableam.h"
|
#include "columnar/columnar_tableam.h"
|
||||||
#include "columnar/columnar_version_compat.h"
|
#include "columnar/columnar_version_compat.h"
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cdc_decoder_utils.h"
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "cdc_decoder_utils.h"
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
|
@ -21,6 +22,8 @@
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/typcache.h"
|
#include "utils/typcache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
PG_MODULE_MAGIC;
|
PG_MODULE_MAGIC;
|
||||||
|
|
||||||
extern void _PG_output_plugin_init(OutputPluginCallbacks *cb);
|
extern void _PG_output_plugin_init(OutputPluginCallbacks *cb);
|
||||||
|
@ -434,6 +437,74 @@ TranslateChangesIfSchemaChanged(Relation sourceRelation, Relation targetRelation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
|
|
||||||
|
/* Check the ReorderBufferChange's action type and handle them accordingly.*/
|
||||||
|
switch (change->action)
|
||||||
|
{
|
||||||
|
case REORDER_BUFFER_CHANGE_INSERT:
|
||||||
|
{
|
||||||
|
/* For insert action, only new tuple should always be translated*/
|
||||||
|
HeapTuple sourceRelationNewTuple = change->data.tp.newtuple;
|
||||||
|
HeapTuple targetRelationNewTuple = GetTupleForTargetSchemaForCdc(
|
||||||
|
sourceRelationNewTuple, sourceRelationDesc, targetRelationDesc);
|
||||||
|
change->data.tp.newtuple = targetRelationNewTuple;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For update changes both old and new tuples need to be translated for target relation
|
||||||
|
* if the REPLICA IDENTITY is set to FULL. Otherwise, only the new tuple needs to be
|
||||||
|
* translated for target relation.
|
||||||
|
*/
|
||||||
|
case REORDER_BUFFER_CHANGE_UPDATE:
|
||||||
|
{
|
||||||
|
/* For update action, new tuple should always be translated*/
|
||||||
|
/* Get the new tuple from the ReorderBufferChange, and translate it to target relation. */
|
||||||
|
HeapTuple sourceRelationNewTuple = change->data.tp.newtuple;
|
||||||
|
HeapTuple targetRelationNewTuple = GetTupleForTargetSchemaForCdc(
|
||||||
|
sourceRelationNewTuple, sourceRelationDesc, targetRelationDesc);
|
||||||
|
change->data.tp.newtuple = targetRelationNewTuple;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format oldtuple according to the target relation. If the column values of replica
|
||||||
|
* identiy change, then the old tuple is non-null and needs to be formatted according
|
||||||
|
* to the target relation schema.
|
||||||
|
*/
|
||||||
|
if (change->data.tp.oldtuple != NULL)
|
||||||
|
{
|
||||||
|
HeapTuple sourceRelationOldTuple = change->data.tp.oldtuple;
|
||||||
|
HeapTuple targetRelationOldTuple = GetTupleForTargetSchemaForCdc(
|
||||||
|
sourceRelationOldTuple,
|
||||||
|
sourceRelationDesc,
|
||||||
|
targetRelationDesc);
|
||||||
|
|
||||||
|
change->data.tp.oldtuple = targetRelationOldTuple;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case REORDER_BUFFER_CHANGE_DELETE:
|
||||||
|
{
|
||||||
|
/* For delete action, only old tuple should be translated*/
|
||||||
|
HeapTuple sourceRelationOldTuple = change->data.tp.oldtuple;
|
||||||
|
HeapTuple targetRelationOldTuple = GetTupleForTargetSchemaForCdc(
|
||||||
|
sourceRelationOldTuple,
|
||||||
|
sourceRelationDesc,
|
||||||
|
targetRelationDesc);
|
||||||
|
|
||||||
|
change->data.tp.oldtuple = targetRelationOldTuple;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
/* Do nothing for other action types. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
/* Check the ReorderBufferChange's action type and handle them accordingly.*/
|
/* Check the ReorderBufferChange's action type and handle them accordingly.*/
|
||||||
switch (change->action)
|
switch (change->action)
|
||||||
{
|
{
|
||||||
|
@ -498,4 +569,5 @@ TranslateChangesIfSchemaChanged(Relation sourceRelation, Relation targetRelation
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,21 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "commands/extension.h"
|
|
||||||
|
#include "cdc_decoder_utils.h"
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
|
#include "catalog/pg_namespace.h"
|
||||||
|
#include "commands/extension.h"
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#include "common/string.h"
|
#include "common/string.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/typcache.h"
|
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "catalog/pg_namespace.h"
|
#include "utils/typcache.h"
|
||||||
#include "cdc_decoder_utils.h"
|
|
||||||
#include "distributed/pg_dist_partition.h"
|
#include "distributed/pg_dist_partition.h"
|
||||||
#include "distributed/pg_dist_shard.h"
|
#include "distributed/pg_dist_shard.h"
|
||||||
#include "distributed/relay_utility.h"
|
#include "distributed/relay_utility.h"
|
||||||
|
|
|
@ -12,9 +12,11 @@
|
||||||
#define CITUS_CDC_DECODER_H
|
#define CITUS_CDC_DECODER_H
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "fmgr.h"
|
|
||||||
#include "replication/logical.h"
|
|
||||||
#include "c.h"
|
#include "c.h"
|
||||||
|
#include "fmgr.h"
|
||||||
|
|
||||||
|
#include "replication/logical.h"
|
||||||
|
|
||||||
#define InvalidRepOriginId 0
|
#define InvalidRepOriginId 0
|
||||||
#define INVALID_SHARD_ID 0
|
#define INVALID_SHARD_ID 0
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Citus extension
|
# Citus extension
|
||||||
comment = 'Citus distributed database'
|
comment = 'Citus distributed database'
|
||||||
default_version = '12.1-1'
|
default_version = '13.0-1'
|
||||||
module_pathname = '$libdir/citus'
|
module_pathname = '$libdir/citus'
|
||||||
relocatable = false
|
relocatable = false
|
||||||
schema = pg_catalog
|
schema = pg_catalog
|
||||||
|
|
|
@ -11,36 +11,37 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
#include "funcapi.h"
|
#include "funcapi.h"
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/datum.h"
|
|
||||||
#include "utils/numeric.h"
|
|
||||||
#include "utils/typcache.h"
|
|
||||||
#include "nodes/pg_list.h"
|
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
#include "commands/sequence.h"
|
#include "commands/sequence.h"
|
||||||
#include "executor/spi.h"
|
#include "executor/spi.h"
|
||||||
|
#include "nodes/pg_list.h"
|
||||||
#include "postmaster/postmaster.h"
|
#include "postmaster/postmaster.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
#include "storage/lwlock.h"
|
#include "storage/lwlock.h"
|
||||||
|
#include "storage/s_lock.h"
|
||||||
#include "storage/shmem.h"
|
#include "storage/shmem.h"
|
||||||
#include "storage/spin.h"
|
#include "storage/spin.h"
|
||||||
#include "storage/s_lock.h"
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/datum.h"
|
||||||
|
#include "utils/numeric.h"
|
||||||
|
#include "utils/typcache.h"
|
||||||
|
|
||||||
#include "distributed/causal_clock.h"
|
#include "distributed/causal_clock.h"
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/lock_graph.h"
|
|
||||||
#include "distributed/local_executor.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
|
||||||
#include "distributed/remote_commands.h"
|
|
||||||
#include "distributed/placement_connection.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/citus_safe_lib.h"
|
#include "distributed/citus_safe_lib.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/local_executor.h"
|
||||||
|
#include "distributed/lock_graph.h"
|
||||||
|
#include "distributed/metadata_cache.h"
|
||||||
|
#include "distributed/placement_connection.h"
|
||||||
|
#include "distributed/remote_commands.h"
|
||||||
|
|
||||||
#define SAVE_AND_PERSIST(c) \
|
#define SAVE_AND_PERSIST(c) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -144,17 +145,6 @@ LogicalClockShmemSize(void)
|
||||||
void
|
void
|
||||||
InitializeClusterClockMem(void)
|
InitializeClusterClockMem(void)
|
||||||
{
|
{
|
||||||
/* On PG 15 and above, we use shmem_request_hook_type */
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
|
|
||||||
/* allocate shared memory for pre PG-15 versions */
|
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
{
|
|
||||||
RequestAddinShmemSpace(LogicalClockShmemSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
prev_shmem_startup_hook = shmem_startup_hook;
|
prev_shmem_startup_hook = shmem_startup_hook;
|
||||||
shmem_startup_hook = LogicalClockShmemInit;
|
shmem_startup_hook = LogicalClockShmemInit;
|
||||||
}
|
}
|
||||||
|
@ -327,7 +317,7 @@ GetHighestClockInTransaction(List *nodeConnectionList)
|
||||||
{
|
{
|
||||||
MultiConnection *connection = NULL;
|
MultiConnection *connection = NULL;
|
||||||
|
|
||||||
foreach_ptr(connection, nodeConnectionList)
|
foreach_declared_ptr(connection, nodeConnectionList)
|
||||||
{
|
{
|
||||||
int querySent =
|
int querySent =
|
||||||
SendRemoteCommand(connection, "SELECT citus_get_node_clock();");
|
SendRemoteCommand(connection, "SELECT citus_get_node_clock();");
|
||||||
|
@ -348,7 +338,7 @@ GetHighestClockInTransaction(List *nodeConnectionList)
|
||||||
globalClockValue->counter)));
|
globalClockValue->counter)));
|
||||||
|
|
||||||
/* fetch the results and pick the highest clock value of all the nodes */
|
/* fetch the results and pick the highest clock value of all the nodes */
|
||||||
foreach_ptr(connection, nodeConnectionList)
|
foreach_declared_ptr(connection, nodeConnectionList)
|
||||||
{
|
{
|
||||||
bool raiseInterrupts = true;
|
bool raiseInterrupts = true;
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,16 @@
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "catalog/pg_depend.h"
|
#include "catalog/pg_depend.h"
|
||||||
#include "catalog/pg_rewrite_d.h"
|
#include "catalog/pg_rewrite_d.h"
|
||||||
|
#include "commands/defrem.h"
|
||||||
|
#include "executor/spi.h"
|
||||||
|
#include "nodes/pg_list.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#include "columnar/columnar.h"
|
#include "columnar/columnar.h"
|
||||||
#include "columnar/columnar_tableam.h"
|
#include "columnar/columnar_tableam.h"
|
||||||
#include "commands/defrem.h"
|
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
@ -57,16 +64,11 @@
|
||||||
#include "distributed/reference_table_utils.h"
|
#include "distributed/reference_table_utils.h"
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "distributed/replication_origin_session_utils.h"
|
#include "distributed/replication_origin_session_utils.h"
|
||||||
#include "distributed/shared_library_init.h"
|
|
||||||
#include "distributed/shard_utils.h"
|
#include "distributed/shard_utils.h"
|
||||||
|
#include "distributed/shared_library_init.h"
|
||||||
#include "distributed/tenant_schema_metadata.h"
|
#include "distributed/tenant_schema_metadata.h"
|
||||||
#include "distributed/worker_protocol.h"
|
#include "distributed/worker_protocol.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "executor/spi.h"
|
|
||||||
#include "nodes/pg_list.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Table Conversion Types */
|
/* Table Conversion Types */
|
||||||
|
@ -207,12 +209,9 @@ static void ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommand
|
||||||
static bool HasAnyGeneratedStoredColumns(Oid relationId);
|
static bool HasAnyGeneratedStoredColumns(Oid relationId);
|
||||||
static List * GetNonGeneratedStoredColumnNameList(Oid relationId);
|
static List * GetNonGeneratedStoredColumnNameList(Oid relationId);
|
||||||
static void CheckAlterDistributedTableConversionParameters(TableConversionState *con);
|
static void CheckAlterDistributedTableConversionParameters(TableConversionState *con);
|
||||||
static char * CreateWorkerChangeSequenceDependencyCommand(char *sequenceSchemaName,
|
static char * CreateWorkerChangeSequenceDependencyCommand(char *qualifiedSequeceName,
|
||||||
char *sequenceName,
|
char *qualifiedSourceName,
|
||||||
char *sourceSchemaName,
|
char *qualifiedTargetName);
|
||||||
char *sourceName,
|
|
||||||
char *targetSchemaName,
|
|
||||||
char *targetName);
|
|
||||||
static void ErrorIfMatViewSizeExceedsTheLimit(Oid matViewOid);
|
static void ErrorIfMatViewSizeExceedsTheLimit(Oid matViewOid);
|
||||||
static char * CreateMaterializedViewDDLCommand(Oid matViewOid);
|
static char * CreateMaterializedViewDDLCommand(Oid matViewOid);
|
||||||
static char * GetAccessMethodForMatViewIfExists(Oid viewOid);
|
static char * GetAccessMethodForMatViewIfExists(Oid viewOid);
|
||||||
|
@ -415,7 +414,7 @@ UndistributeTables(List *relationIdList)
|
||||||
*/
|
*/
|
||||||
List *originalForeignKeyRecreationCommands = NIL;
|
List *originalForeignKeyRecreationCommands = NIL;
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
List *fkeyCommandsForRelation =
|
List *fkeyCommandsForRelation =
|
||||||
GetFKeyCreationCommandsRelationInvolvedWithTableType(relationId,
|
GetFKeyCreationCommandsRelationInvolvedWithTableType(relationId,
|
||||||
|
@ -789,19 +788,21 @@ ConvertTableInternal(TableConversionState *con)
|
||||||
justBeforeDropCommands = lappend(justBeforeDropCommands, detachFromParentCommand);
|
justBeforeDropCommands = lappend(justBeforeDropCommands, detachFromParentCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *qualifiedRelationName = quote_qualified_identifier(con->schemaName,
|
||||||
|
con->relationName);
|
||||||
|
|
||||||
if (PartitionedTable(con->relationId))
|
if (PartitionedTable(con->relationId))
|
||||||
{
|
{
|
||||||
if (!con->suppressNoticeMessages)
|
if (!con->suppressNoticeMessages)
|
||||||
{
|
{
|
||||||
ereport(NOTICE, (errmsg("converting the partitions of %s",
|
ereport(NOTICE, (errmsg("converting the partitions of %s",
|
||||||
quote_qualified_identifier(con->schemaName,
|
qualifiedRelationName)));
|
||||||
con->relationName))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List *partitionList = PartitionList(con->relationId);
|
List *partitionList = PartitionList(con->relationId);
|
||||||
|
|
||||||
Oid partitionRelationId = InvalidOid;
|
Oid partitionRelationId = InvalidOid;
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
foreach_declared_oid(partitionRelationId, partitionList)
|
||||||
{
|
{
|
||||||
char *tableQualifiedName = generate_qualified_relation_name(
|
char *tableQualifiedName = generate_qualified_relation_name(
|
||||||
partitionRelationId);
|
partitionRelationId);
|
||||||
|
@ -868,13 +869,11 @@ ConvertTableInternal(TableConversionState *con)
|
||||||
|
|
||||||
if (!con->suppressNoticeMessages)
|
if (!con->suppressNoticeMessages)
|
||||||
{
|
{
|
||||||
ereport(NOTICE, (errmsg("creating a new table for %s",
|
ereport(NOTICE, (errmsg("creating a new table for %s", qualifiedRelationName)));
|
||||||
quote_qualified_identifier(con->schemaName,
|
|
||||||
con->relationName))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TableDDLCommand *tableCreationCommand = NULL;
|
TableDDLCommand *tableCreationCommand = NULL;
|
||||||
foreach_ptr(tableCreationCommand, preLoadCommands)
|
foreach_declared_ptr(tableCreationCommand, preLoadCommands)
|
||||||
{
|
{
|
||||||
Assert(CitusIsA(tableCreationCommand, TableDDLCommand));
|
Assert(CitusIsA(tableCreationCommand, TableDDLCommand));
|
||||||
|
|
||||||
|
@ -948,7 +947,7 @@ ConvertTableInternal(TableConversionState *con)
|
||||||
con->suppressNoticeMessages);
|
con->suppressNoticeMessages);
|
||||||
|
|
||||||
TableDDLCommand *tableConstructionCommand = NULL;
|
TableDDLCommand *tableConstructionCommand = NULL;
|
||||||
foreach_ptr(tableConstructionCommand, postLoadCommands)
|
foreach_declared_ptr(tableConstructionCommand, postLoadCommands)
|
||||||
{
|
{
|
||||||
Assert(CitusIsA(tableConstructionCommand, TableDDLCommand));
|
Assert(CitusIsA(tableConstructionCommand, TableDDLCommand));
|
||||||
char *tableConstructionSQL = GetTableDDLCommand(tableConstructionCommand);
|
char *tableConstructionSQL = GetTableDDLCommand(tableConstructionCommand);
|
||||||
|
@ -966,7 +965,7 @@ ConvertTableInternal(TableConversionState *con)
|
||||||
MemoryContext oldContext = MemoryContextSwitchTo(citusPerPartitionContext);
|
MemoryContext oldContext = MemoryContextSwitchTo(citusPerPartitionContext);
|
||||||
|
|
||||||
char *attachPartitionCommand = NULL;
|
char *attachPartitionCommand = NULL;
|
||||||
foreach_ptr(attachPartitionCommand, attachPartitionCommands)
|
foreach_declared_ptr(attachPartitionCommand, attachPartitionCommands)
|
||||||
{
|
{
|
||||||
MemoryContextReset(citusPerPartitionContext);
|
MemoryContextReset(citusPerPartitionContext);
|
||||||
|
|
||||||
|
@ -991,14 +990,12 @@ ConvertTableInternal(TableConversionState *con)
|
||||||
|
|
||||||
/* For now we only support cascade to colocation for alter_distributed_table UDF */
|
/* For now we only support cascade to colocation for alter_distributed_table UDF */
|
||||||
Assert(con->conversionType == ALTER_DISTRIBUTED_TABLE);
|
Assert(con->conversionType == ALTER_DISTRIBUTED_TABLE);
|
||||||
foreach_oid(colocatedTableId, con->colocatedTableList)
|
foreach_declared_oid(colocatedTableId, con->colocatedTableList)
|
||||||
{
|
{
|
||||||
if (colocatedTableId == con->relationId)
|
if (colocatedTableId == con->relationId)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char *qualifiedRelationName = quote_qualified_identifier(con->schemaName,
|
|
||||||
con->relationName);
|
|
||||||
|
|
||||||
TableConversionParameters cascadeParam = {
|
TableConversionParameters cascadeParam = {
|
||||||
.relationId = colocatedTableId,
|
.relationId = colocatedTableId,
|
||||||
|
@ -1021,7 +1018,7 @@ ConvertTableInternal(TableConversionState *con)
|
||||||
if (con->cascadeToColocated != CASCADE_TO_COLOCATED_NO_ALREADY_CASCADED)
|
if (con->cascadeToColocated != CASCADE_TO_COLOCATED_NO_ALREADY_CASCADED)
|
||||||
{
|
{
|
||||||
char *foreignKeyCommand = NULL;
|
char *foreignKeyCommand = NULL;
|
||||||
foreach_ptr(foreignKeyCommand, foreignKeyCommands)
|
foreach_declared_ptr(foreignKeyCommand, foreignKeyCommands)
|
||||||
{
|
{
|
||||||
ExecuteQueryViaSPI(foreignKeyCommand, SPI_OK_UTILITY);
|
ExecuteQueryViaSPI(foreignKeyCommand, SPI_OK_UTILITY);
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1054,7 @@ CopyTableConversionReturnIntoCurrentContext(TableConversionReturn *tableConversi
|
||||||
tableConversionReturnCopy = palloc0(sizeof(TableConversionReturn));
|
tableConversionReturnCopy = palloc0(sizeof(TableConversionReturn));
|
||||||
List *copyForeignKeyCommands = NIL;
|
List *copyForeignKeyCommands = NIL;
|
||||||
char *foreignKeyCommand = NULL;
|
char *foreignKeyCommand = NULL;
|
||||||
foreach_ptr(foreignKeyCommand, tableConversionReturn->foreignKeyCommands)
|
foreach_declared_ptr(foreignKeyCommand, tableConversionReturn->foreignKeyCommands)
|
||||||
{
|
{
|
||||||
char *copyForeignKeyCommand = MemoryContextStrdup(CurrentMemoryContext,
|
char *copyForeignKeyCommand = MemoryContextStrdup(CurrentMemoryContext,
|
||||||
foreignKeyCommand);
|
foreignKeyCommand);
|
||||||
|
@ -1132,7 +1129,7 @@ DropIndexesNotSupportedByColumnar(Oid relationId, bool suppressNoticeMessages)
|
||||||
RelationClose(columnarRelation);
|
RelationClose(columnarRelation);
|
||||||
|
|
||||||
Oid indexId = InvalidOid;
|
Oid indexId = InvalidOid;
|
||||||
foreach_oid(indexId, indexIdList)
|
foreach_declared_oid(indexId, indexIdList)
|
||||||
{
|
{
|
||||||
char *indexAmName = GetIndexAccessMethodName(indexId);
|
char *indexAmName = GetIndexAccessMethodName(indexId);
|
||||||
if (extern_ColumnarSupportsIndexAM(indexAmName))
|
if (extern_ColumnarSupportsIndexAM(indexAmName))
|
||||||
|
@ -1392,7 +1389,7 @@ CreateTableConversion(TableConversionParameters *params)
|
||||||
* since they will be handled separately.
|
* since they will be handled separately.
|
||||||
*/
|
*/
|
||||||
Oid colocatedTableId = InvalidOid;
|
Oid colocatedTableId = InvalidOid;
|
||||||
foreach_oid(colocatedTableId, colocatedTableList)
|
foreach_declared_oid(colocatedTableId, colocatedTableList)
|
||||||
{
|
{
|
||||||
if (PartitionTable(colocatedTableId))
|
if (PartitionTable(colocatedTableId))
|
||||||
{
|
{
|
||||||
|
@ -1608,7 +1605,7 @@ DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
|
||||||
targetObjectId);
|
targetObjectId);
|
||||||
|
|
||||||
HeapTuple depTup = NULL;
|
HeapTuple depTup = NULL;
|
||||||
foreach_ptr(depTup, dependencyTupleList)
|
foreach_declared_ptr(depTup, dependencyTupleList)
|
||||||
{
|
{
|
||||||
Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
|
Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
|
||||||
|
|
||||||
|
@ -1648,7 +1645,7 @@ GetViewCreationCommandsOfTable(Oid relationId)
|
||||||
List *commands = NIL;
|
List *commands = NIL;
|
||||||
|
|
||||||
Oid viewOid = InvalidOid;
|
Oid viewOid = InvalidOid;
|
||||||
foreach_oid(viewOid, views)
|
foreach_declared_oid(viewOid, views)
|
||||||
{
|
{
|
||||||
StringInfo query = makeStringInfo();
|
StringInfo query = makeStringInfo();
|
||||||
|
|
||||||
|
@ -1686,7 +1683,7 @@ WrapTableDDLCommands(List *commandStrings)
|
||||||
List *tableDDLCommands = NIL;
|
List *tableDDLCommands = NIL;
|
||||||
|
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
foreach_ptr(command, commandStrings)
|
foreach_declared_ptr(command, commandStrings)
|
||||||
{
|
{
|
||||||
tableDDLCommands = lappend(tableDDLCommands, makeTableDDLCommandString(command));
|
tableDDLCommands = lappend(tableDDLCommands, makeTableDDLCommandString(command));
|
||||||
}
|
}
|
||||||
|
@ -1748,9 +1745,7 @@ CreateMaterializedViewDDLCommand(Oid matViewOid)
|
||||||
{
|
{
|
||||||
StringInfo query = makeStringInfo();
|
StringInfo query = makeStringInfo();
|
||||||
|
|
||||||
char *viewName = get_rel_name(matViewOid);
|
char *qualifiedViewName = generate_qualified_relation_name(matViewOid);
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(matViewOid));
|
|
||||||
char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName);
|
|
||||||
|
|
||||||
/* here we need to get the access method of the view to recreate it */
|
/* here we need to get the access method of the view to recreate it */
|
||||||
char *accessMethodName = GetAccessMethodForMatViewIfExists(matViewOid);
|
char *accessMethodName = GetAccessMethodForMatViewIfExists(matViewOid);
|
||||||
|
@ -1799,9 +1794,8 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
bool suppressNoticeMessages)
|
bool suppressNoticeMessages)
|
||||||
{
|
{
|
||||||
char *sourceName = get_rel_name(sourceId);
|
char *sourceName = get_rel_name(sourceId);
|
||||||
char *targetName = get_rel_name(targetId);
|
char *qualifiedSourceName = generate_qualified_relation_name(sourceId);
|
||||||
Oid schemaId = get_rel_namespace(sourceId);
|
char *qualifiedTargetName = generate_qualified_relation_name(targetId);
|
||||||
char *schemaName = get_namespace_name(schemaId);
|
|
||||||
|
|
||||||
StringInfo query = makeStringInfo();
|
StringInfo query = makeStringInfo();
|
||||||
|
|
||||||
|
@ -1809,8 +1803,7 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
{
|
{
|
||||||
if (!suppressNoticeMessages)
|
if (!suppressNoticeMessages)
|
||||||
{
|
{
|
||||||
ereport(NOTICE, (errmsg("moving the data of %s",
|
ereport(NOTICE, (errmsg("moving the data of %s", qualifiedSourceName)));
|
||||||
quote_qualified_identifier(schemaName, sourceName))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HasAnyGeneratedStoredColumns(sourceId))
|
if (!HasAnyGeneratedStoredColumns(sourceId))
|
||||||
|
@ -1820,8 +1813,7 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
* "INSERT INTO .. SELECT *"".
|
* "INSERT INTO .. SELECT *"".
|
||||||
*/
|
*/
|
||||||
appendStringInfo(query, "INSERT INTO %s SELECT * FROM %s",
|
appendStringInfo(query, "INSERT INTO %s SELECT * FROM %s",
|
||||||
quote_qualified_identifier(schemaName, targetName),
|
qualifiedTargetName, qualifiedSourceName);
|
||||||
quote_qualified_identifier(schemaName, sourceName));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1836,9 +1828,8 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
char *insertColumnString = StringJoin(nonStoredColumnNameList, ',');
|
char *insertColumnString = StringJoin(nonStoredColumnNameList, ',');
|
||||||
appendStringInfo(query,
|
appendStringInfo(query,
|
||||||
"INSERT INTO %s (%s) OVERRIDING SYSTEM VALUE SELECT %s FROM %s",
|
"INSERT INTO %s (%s) OVERRIDING SYSTEM VALUE SELECT %s FROM %s",
|
||||||
quote_qualified_identifier(schemaName, targetName),
|
qualifiedTargetName, insertColumnString,
|
||||||
insertColumnString, insertColumnString,
|
insertColumnString, qualifiedSourceName);
|
||||||
quote_qualified_identifier(schemaName, sourceName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecuteQueryViaSPI(query->data, SPI_OK_INSERT);
|
ExecuteQueryViaSPI(query->data, SPI_OK_INSERT);
|
||||||
|
@ -1849,7 +1840,7 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
*/
|
*/
|
||||||
List *ownedSequences = getOwnedSequences_internal(sourceId, 0, DEPENDENCY_AUTO);
|
List *ownedSequences = getOwnedSequences_internal(sourceId, 0, DEPENDENCY_AUTO);
|
||||||
Oid sequenceOid = InvalidOid;
|
Oid sequenceOid = InvalidOid;
|
||||||
foreach_oid(sequenceOid, ownedSequences)
|
foreach_declared_oid(sequenceOid, ownedSequences)
|
||||||
{
|
{
|
||||||
changeDependencyFor(RelationRelationId, sequenceOid,
|
changeDependencyFor(RelationRelationId, sequenceOid,
|
||||||
RelationRelationId, sourceId, targetId);
|
RelationRelationId, sourceId, targetId);
|
||||||
|
@ -1862,14 +1853,11 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
*/
|
*/
|
||||||
if (ShouldSyncTableMetadata(targetId))
|
if (ShouldSyncTableMetadata(targetId))
|
||||||
{
|
{
|
||||||
Oid sequenceSchemaOid = get_rel_namespace(sequenceOid);
|
char *qualifiedSequenceName = generate_qualified_relation_name(sequenceOid);
|
||||||
char *sequenceSchemaName = get_namespace_name(sequenceSchemaOid);
|
|
||||||
char *sequenceName = get_rel_name(sequenceOid);
|
|
||||||
char *workerChangeSequenceDependencyCommand =
|
char *workerChangeSequenceDependencyCommand =
|
||||||
CreateWorkerChangeSequenceDependencyCommand(sequenceSchemaName,
|
CreateWorkerChangeSequenceDependencyCommand(qualifiedSequenceName,
|
||||||
sequenceName,
|
qualifiedSourceName,
|
||||||
schemaName, sourceName,
|
qualifiedTargetName);
|
||||||
schemaName, targetName);
|
|
||||||
SendCommandToWorkersWithMetadata(workerChangeSequenceDependencyCommand);
|
SendCommandToWorkersWithMetadata(workerChangeSequenceDependencyCommand);
|
||||||
}
|
}
|
||||||
else if (ShouldSyncTableMetadata(sourceId))
|
else if (ShouldSyncTableMetadata(sourceId))
|
||||||
|
@ -1885,32 +1873,30 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
}
|
}
|
||||||
|
|
||||||
char *justBeforeDropCommand = NULL;
|
char *justBeforeDropCommand = NULL;
|
||||||
foreach_ptr(justBeforeDropCommand, justBeforeDropCommands)
|
foreach_declared_ptr(justBeforeDropCommand, justBeforeDropCommands)
|
||||||
{
|
{
|
||||||
ExecuteQueryViaSPI(justBeforeDropCommand, SPI_OK_UTILITY);
|
ExecuteQueryViaSPI(justBeforeDropCommand, SPI_OK_UTILITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!suppressNoticeMessages)
|
if (!suppressNoticeMessages)
|
||||||
{
|
{
|
||||||
ereport(NOTICE, (errmsg("dropping the old %s",
|
ereport(NOTICE, (errmsg("dropping the old %s", qualifiedSourceName)));
|
||||||
quote_qualified_identifier(schemaName, sourceName))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resetStringInfo(query);
|
resetStringInfo(query);
|
||||||
appendStringInfo(query, "DROP %sTABLE %s CASCADE",
|
appendStringInfo(query, "DROP %sTABLE %s CASCADE",
|
||||||
IsForeignTable(sourceId) ? "FOREIGN " : "",
|
IsForeignTable(sourceId) ? "FOREIGN " : "",
|
||||||
quote_qualified_identifier(schemaName, sourceName));
|
qualifiedSourceName);
|
||||||
ExecuteQueryViaSPI(query->data, SPI_OK_UTILITY);
|
ExecuteQueryViaSPI(query->data, SPI_OK_UTILITY);
|
||||||
|
|
||||||
if (!suppressNoticeMessages)
|
if (!suppressNoticeMessages)
|
||||||
{
|
{
|
||||||
ereport(NOTICE, (errmsg("renaming the new table to %s",
|
ereport(NOTICE, (errmsg("renaming the new table to %s", qualifiedSourceName)));
|
||||||
quote_qualified_identifier(schemaName, sourceName))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resetStringInfo(query);
|
resetStringInfo(query);
|
||||||
appendStringInfo(query, "ALTER TABLE %s RENAME TO %s",
|
appendStringInfo(query, "ALTER TABLE %s RENAME TO %s",
|
||||||
quote_qualified_identifier(schemaName, targetName),
|
qualifiedTargetName,
|
||||||
quote_identifier(sourceName));
|
quote_identifier(sourceName));
|
||||||
ExecuteQueryViaSPI(query->data, SPI_OK_UTILITY);
|
ExecuteQueryViaSPI(query->data, SPI_OK_UTILITY);
|
||||||
}
|
}
|
||||||
|
@ -2001,7 +1987,7 @@ CheckAlterDistributedTableConversionParameters(TableConversionState *con)
|
||||||
Oid colocatedTableOid = InvalidOid;
|
Oid colocatedTableOid = InvalidOid;
|
||||||
text *colocateWithText = cstring_to_text(con->colocateWith);
|
text *colocateWithText = cstring_to_text(con->colocateWith);
|
||||||
Oid colocateWithTableOid = ResolveRelationId(colocateWithText, false);
|
Oid colocateWithTableOid = ResolveRelationId(colocateWithText, false);
|
||||||
foreach_oid(colocatedTableOid, con->colocatedTableList)
|
foreach_declared_oid(colocatedTableOid, con->colocatedTableList)
|
||||||
{
|
{
|
||||||
if (colocateWithTableOid == colocatedTableOid)
|
if (colocateWithTableOid == colocatedTableOid)
|
||||||
{
|
{
|
||||||
|
@ -2170,18 +2156,13 @@ CheckAlterDistributedTableConversionParameters(TableConversionState *con)
|
||||||
* worker_change_sequence_dependency query with the parameters.
|
* worker_change_sequence_dependency query with the parameters.
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
CreateWorkerChangeSequenceDependencyCommand(char *sequenceSchemaName, char *sequenceName,
|
CreateWorkerChangeSequenceDependencyCommand(char *qualifiedSequeceName,
|
||||||
char *sourceSchemaName, char *sourceName,
|
char *qualifiedSourceName,
|
||||||
char *targetSchemaName, char *targetName)
|
char *qualifiedTargetName)
|
||||||
{
|
{
|
||||||
char *qualifiedSchemaName = quote_qualified_identifier(sequenceSchemaName,
|
|
||||||
sequenceName);
|
|
||||||
char *qualifiedSourceName = quote_qualified_identifier(sourceSchemaName, sourceName);
|
|
||||||
char *qualifiedTargetName = quote_qualified_identifier(targetSchemaName, targetName);
|
|
||||||
|
|
||||||
StringInfo query = makeStringInfo();
|
StringInfo query = makeStringInfo();
|
||||||
appendStringInfo(query, "SELECT worker_change_sequence_dependency(%s, %s, %s)",
|
appendStringInfo(query, "SELECT worker_change_sequence_dependency(%s, %s, %s)",
|
||||||
quote_literal_cstr(qualifiedSchemaName),
|
quote_literal_cstr(qualifiedSequeceName),
|
||||||
quote_literal_cstr(qualifiedSourceName),
|
quote_literal_cstr(qualifiedSourceName),
|
||||||
quote_literal_cstr(qualifiedTargetName));
|
quote_literal_cstr(qualifiedTargetName));
|
||||||
|
|
||||||
|
@ -2233,7 +2214,7 @@ WillRecreateForeignKeyToReferenceTable(Oid relationId,
|
||||||
{
|
{
|
||||||
List *colocatedTableList = ColocatedTableList(relationId);
|
List *colocatedTableList = ColocatedTableList(relationId);
|
||||||
Oid colocatedTableOid = InvalidOid;
|
Oid colocatedTableOid = InvalidOid;
|
||||||
foreach_oid(colocatedTableOid, colocatedTableList)
|
foreach_declared_oid(colocatedTableOid, colocatedTableList)
|
||||||
{
|
{
|
||||||
if (HasForeignKeyToReferenceTable(colocatedTableOid))
|
if (HasForeignKeyToReferenceTable(colocatedTableOid))
|
||||||
{
|
{
|
||||||
|
@ -2261,7 +2242,7 @@ WarningsForDroppingForeignKeysWithDistributedTables(Oid relationId)
|
||||||
List *foreignKeys = list_concat(referencingForeingKeys, referencedForeignKeys);
|
List *foreignKeys = list_concat(referencingForeingKeys, referencedForeignKeys);
|
||||||
|
|
||||||
Oid foreignKeyOid = InvalidOid;
|
Oid foreignKeyOid = InvalidOid;
|
||||||
foreach_oid(foreignKeyOid, foreignKeys)
|
foreach_declared_oid(foreignKeyOid, foreignKeys)
|
||||||
{
|
{
|
||||||
ereport(WARNING, (errmsg("foreign key %s will be dropped",
|
ereport(WARNING, (errmsg("foreign key %s will be dropped",
|
||||||
get_constraint_name(foreignKeyOid))));
|
get_constraint_name(foreignKeyOid))));
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "c.h"
|
#include "c.h"
|
||||||
|
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/transaction_management.h"
|
#include "distributed/transaction_management.h"
|
||||||
#include "nodes/parsenodes.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -31,7 +33,7 @@ SaveBeginCommandProperties(TransactionStmt *transactionStmt)
|
||||||
*
|
*
|
||||||
* While BEGIN can be quite frequent it will rarely have options set.
|
* While BEGIN can be quite frequent it will rarely have options set.
|
||||||
*/
|
*/
|
||||||
foreach_ptr(item, transactionStmt->options)
|
foreach_declared_ptr(item, transactionStmt->options)
|
||||||
{
|
{
|
||||||
A_Const *constant = (A_Const *) item->arg;
|
A_Const *constant = (A_Const *) item->arg;
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,23 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "funcapi.h"
|
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "funcapi.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
#include "nodes/nodeFuncs.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "nodes/primnodes.h"
|
||||||
|
#include "optimizer/clauses.h"
|
||||||
|
#include "tcop/dest.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/adaptive_executor.h"
|
||||||
#include "distributed/backend_data.h"
|
#include "distributed/backend_data.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
|
@ -26,27 +37,17 @@
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
#include "distributed/deparse_shard_query.h"
|
#include "distributed/deparse_shard_query.h"
|
||||||
#include "distributed/function_call_delegation.h"
|
#include "distributed/function_call_delegation.h"
|
||||||
#include "distributed/metadata_utility.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
|
#include "distributed/metadata_utility.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
#include "distributed/multi_physical_planner.h"
|
#include "distributed/multi_physical_planner.h"
|
||||||
#include "distributed/adaptive_executor.h"
|
|
||||||
#include "distributed/reference_table_utils.h"
|
#include "distributed/reference_table_utils.h"
|
||||||
#include "distributed/remote_commands.h"
|
#include "distributed/remote_commands.h"
|
||||||
#include "distributed/reference_table_utils.h"
|
|
||||||
#include "distributed/shard_pruning.h"
|
#include "distributed/shard_pruning.h"
|
||||||
#include "distributed/tuple_destination.h"
|
#include "distributed/tuple_destination.h"
|
||||||
#include "distributed/version_compat.h"
|
#include "distributed/version_compat.h"
|
||||||
#include "distributed/worker_manager.h"
|
|
||||||
#include "distributed/worker_log_messages.h"
|
#include "distributed/worker_log_messages.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "distributed/worker_manager.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
|
||||||
#include "nodes/parsenodes.h"
|
|
||||||
#include "nodes/primnodes.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "tcop/dest.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* global variable tracking whether we are in a delegated procedure call */
|
/* global variable tracking whether we are in a delegated procedure call */
|
||||||
|
|
|
@ -12,12 +12,19 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "executor/spi.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/foreign_key_relationship.h"
|
#include "distributed/foreign_key_relationship.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
|
@ -26,11 +33,6 @@
|
||||||
#include "distributed/reference_table_utils.h"
|
#include "distributed/reference_table_utils.h"
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "distributed/worker_protocol.h"
|
#include "distributed/worker_protocol.h"
|
||||||
#include "executor/spi.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void EnsureSequentialModeForCitusTableCascadeFunction(List *relationIdList);
|
static void EnsureSequentialModeForCitusTableCascadeFunction(List *relationIdList);
|
||||||
|
@ -166,7 +168,7 @@ GetPartitionRelationIds(List *relationIdList)
|
||||||
List *partitionRelationIdList = NIL;
|
List *partitionRelationIdList = NIL;
|
||||||
|
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
if (PartitionTable(relationId))
|
if (PartitionTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -187,7 +189,7 @@ LockRelationsWithLockMode(List *relationIdList, LOCKMODE lockMode)
|
||||||
{
|
{
|
||||||
Oid relationId;
|
Oid relationId;
|
||||||
relationIdList = SortList(relationIdList, CompareOids);
|
relationIdList = SortList(relationIdList, CompareOids);
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
LockRelationOid(relationId, lockMode);
|
LockRelationOid(relationId, lockMode);
|
||||||
}
|
}
|
||||||
|
@ -205,7 +207,7 @@ static void
|
||||||
ErrorIfConvertingMultiLevelPartitionedTable(List *relationIdList)
|
ErrorIfConvertingMultiLevelPartitionedTable(List *relationIdList)
|
||||||
{
|
{
|
||||||
Oid relationId;
|
Oid relationId;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
if (PartitionedTable(relationId) && PartitionTable(relationId))
|
if (PartitionedTable(relationId) && PartitionTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -234,7 +236,7 @@ void
|
||||||
ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(List *relationIdList)
|
ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(List *relationIdList)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
if (!PartitionTable(relationId))
|
if (!PartitionTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -298,7 +300,7 @@ bool
|
||||||
RelationIdListHasReferenceTable(List *relationIdList)
|
RelationIdListHasReferenceTable(List *relationIdList)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
if (IsCitusTableType(relationId, REFERENCE_TABLE))
|
if (IsCitusTableType(relationId, REFERENCE_TABLE))
|
||||||
{
|
{
|
||||||
|
@ -320,7 +322,7 @@ GetFKeyCreationCommandsForRelationIdList(List *relationIdList)
|
||||||
List *fKeyCreationCommands = NIL;
|
List *fKeyCreationCommands = NIL;
|
||||||
|
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
List *relationFKeyCreationCommands =
|
List *relationFKeyCreationCommands =
|
||||||
GetReferencingForeignConstaintCommands(relationId);
|
GetReferencingForeignConstaintCommands(relationId);
|
||||||
|
@ -340,7 +342,7 @@ static void
|
||||||
DropRelationIdListForeignKeys(List *relationIdList, int fKeyFlags)
|
DropRelationIdListForeignKeys(List *relationIdList, int fKeyFlags)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
DropRelationForeignKeys(relationId, fKeyFlags);
|
DropRelationForeignKeys(relationId, fKeyFlags);
|
||||||
}
|
}
|
||||||
|
@ -397,7 +399,7 @@ GetRelationDropFkeyCommands(Oid relationId, int fKeyFlags)
|
||||||
List *relationFKeyIdList = GetForeignKeyOids(relationId, fKeyFlags);
|
List *relationFKeyIdList = GetForeignKeyOids(relationId, fKeyFlags);
|
||||||
|
|
||||||
Oid foreignKeyId;
|
Oid foreignKeyId;
|
||||||
foreach_oid(foreignKeyId, relationFKeyIdList)
|
foreach_declared_oid(foreignKeyId, relationFKeyIdList)
|
||||||
{
|
{
|
||||||
char *dropFkeyCascadeCommand = GetDropFkeyCascadeCommand(foreignKeyId);
|
char *dropFkeyCascadeCommand = GetDropFkeyCascadeCommand(foreignKeyId);
|
||||||
dropFkeyCascadeCommandList = lappend(dropFkeyCascadeCommandList,
|
dropFkeyCascadeCommandList = lappend(dropFkeyCascadeCommandList,
|
||||||
|
@ -448,7 +450,7 @@ ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
||||||
cascadeOperationType)
|
cascadeOperationType)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The reason behind skipping certain table types in below loop is
|
* The reason behind skipping certain table types in below loop is
|
||||||
|
@ -529,7 +531,7 @@ ExecuteAndLogUtilityCommandListInTableTypeConversionViaSPI(List *utilityCommandL
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
char *utilityCommand = NULL;
|
char *utilityCommand = NULL;
|
||||||
foreach_ptr(utilityCommand, utilityCommandList)
|
foreach_declared_ptr(utilityCommand, utilityCommandList)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* CREATE MATERIALIZED VIEW commands need to be parsed/transformed,
|
* CREATE MATERIALIZED VIEW commands need to be parsed/transformed,
|
||||||
|
@ -567,7 +569,7 @@ void
|
||||||
ExecuteAndLogUtilityCommandList(List *utilityCommandList)
|
ExecuteAndLogUtilityCommandList(List *utilityCommandList)
|
||||||
{
|
{
|
||||||
char *utilityCommand = NULL;
|
char *utilityCommand = NULL;
|
||||||
foreach_ptr(utilityCommand, utilityCommandList)
|
foreach_declared_ptr(utilityCommand, utilityCommandList)
|
||||||
{
|
{
|
||||||
ExecuteAndLogUtilityCommand(utilityCommand);
|
ExecuteAndLogUtilityCommand(utilityCommand);
|
||||||
}
|
}
|
||||||
|
@ -595,7 +597,7 @@ void
|
||||||
ExecuteForeignKeyCreateCommandList(List *ddlCommandList, bool skip_validation)
|
ExecuteForeignKeyCreateCommandList(List *ddlCommandList, bool skip_validation)
|
||||||
{
|
{
|
||||||
char *ddlCommand = NULL;
|
char *ddlCommand = NULL;
|
||||||
foreach_ptr(ddlCommand, ddlCommandList)
|
foreach_declared_ptr(ddlCommand, ddlCommandList)
|
||||||
{
|
{
|
||||||
ExecuteForeignKeyCreateCommand(ddlCommand, skip_validation);
|
ExecuteForeignKeyCreateCommand(ddlCommand, skip_validation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
|
@ -25,29 +26,30 @@
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "catalog/pg_statistic_ext.h"
|
#include "catalog/pg_statistic_ext.h"
|
||||||
#include "catalog/pg_trigger.h"
|
#include "catalog/pg_trigger.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
#include "foreign/foreign.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/ruleutils.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/sequence.h"
|
#include "distributed/commands/sequence.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/metadata/dependency.h"
|
|
||||||
#include "distributed/foreign_key_relationship.h"
|
#include "distributed/foreign_key_relationship.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
|
#include "distributed/metadata/dependency.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/namespace_utils.h"
|
#include "distributed/namespace_utils.h"
|
||||||
#include "distributed/reference_table_utils.h"
|
#include "distributed/reference_table_utils.h"
|
||||||
#include "distributed/worker_protocol.h"
|
#include "distributed/worker_protocol.h"
|
||||||
#include "distributed/worker_shard_visibility.h"
|
#include "distributed/worker_shard_visibility.h"
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/fmgroids.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/ruleutils.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
#include "foreign/foreign.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -586,7 +588,7 @@ ErrorIfOptionListHasNoTableName(List *optionList)
|
||||||
{
|
{
|
||||||
char *table_nameString = "table_name";
|
char *table_nameString = "table_name";
|
||||||
DefElem *option = NULL;
|
DefElem *option = NULL;
|
||||||
foreach_ptr(option, optionList)
|
foreach_declared_ptr(option, optionList)
|
||||||
{
|
{
|
||||||
char *optionName = option->defname;
|
char *optionName = option->defname;
|
||||||
if (strcmp(optionName, table_nameString) == 0)
|
if (strcmp(optionName, table_nameString) == 0)
|
||||||
|
@ -611,7 +613,7 @@ ForeignTableDropsTableNameOption(List *optionList)
|
||||||
{
|
{
|
||||||
char *table_nameString = "table_name";
|
char *table_nameString = "table_name";
|
||||||
DefElem *option = NULL;
|
DefElem *option = NULL;
|
||||||
foreach_ptr(option, optionList)
|
foreach_declared_ptr(option, optionList)
|
||||||
{
|
{
|
||||||
char *optionName = option->defname;
|
char *optionName = option->defname;
|
||||||
DefElemAction optionAction = option->defaction;
|
DefElemAction optionAction = option->defaction;
|
||||||
|
@ -730,7 +732,7 @@ UpdateAutoConvertedForConnectedRelations(List *relationIds, bool autoConverted)
|
||||||
|
|
||||||
List *relationIdList = NIL;
|
List *relationIdList = NIL;
|
||||||
Oid relid = InvalidOid;
|
Oid relid = InvalidOid;
|
||||||
foreach_oid(relid, relationIds)
|
foreach_declared_oid(relid, relationIds)
|
||||||
{
|
{
|
||||||
List *connectedRelations = GetForeignKeyConnectedRelationIdList(relid);
|
List *connectedRelations = GetForeignKeyConnectedRelationIdList(relid);
|
||||||
relationIdList = list_concat_unique_oid(relationIdList, connectedRelations);
|
relationIdList = list_concat_unique_oid(relationIdList, connectedRelations);
|
||||||
|
@ -738,7 +740,7 @@ UpdateAutoConvertedForConnectedRelations(List *relationIds, bool autoConverted)
|
||||||
|
|
||||||
relationIdList = SortList(relationIdList, CompareOids);
|
relationIdList = SortList(relationIdList, CompareOids);
|
||||||
|
|
||||||
foreach_oid(relid, relationIdList)
|
foreach_declared_oid(relid, relationIdList)
|
||||||
{
|
{
|
||||||
UpdatePgDistPartitionAutoConverted(relid, autoConverted);
|
UpdatePgDistPartitionAutoConverted(relid, autoConverted);
|
||||||
}
|
}
|
||||||
|
@ -774,7 +776,7 @@ GetShellTableDDLEventsForCitusLocalTable(Oid relationId)
|
||||||
|
|
||||||
List *shellTableDDLEvents = NIL;
|
List *shellTableDDLEvents = NIL;
|
||||||
TableDDLCommand *tableDDLCommand = NULL;
|
TableDDLCommand *tableDDLCommand = NULL;
|
||||||
foreach_ptr(tableDDLCommand, tableDDLCommands)
|
foreach_declared_ptr(tableDDLCommand, tableDDLCommands)
|
||||||
{
|
{
|
||||||
Assert(CitusIsA(tableDDLCommand, TableDDLCommand));
|
Assert(CitusIsA(tableDDLCommand, TableDDLCommand));
|
||||||
shellTableDDLEvents = lappend(shellTableDDLEvents,
|
shellTableDDLEvents = lappend(shellTableDDLEvents,
|
||||||
|
@ -861,7 +863,7 @@ RenameShardRelationConstraints(Oid shardRelationId, uint64 shardId)
|
||||||
List *constraintNameList = GetConstraintNameList(shardRelationId);
|
List *constraintNameList = GetConstraintNameList(shardRelationId);
|
||||||
|
|
||||||
char *constraintName = NULL;
|
char *constraintName = NULL;
|
||||||
foreach_ptr(constraintName, constraintNameList)
|
foreach_declared_ptr(constraintName, constraintNameList)
|
||||||
{
|
{
|
||||||
const char *commandString =
|
const char *commandString =
|
||||||
GetRenameShardConstraintCommand(shardRelationId, constraintName, shardId);
|
GetRenameShardConstraintCommand(shardRelationId, constraintName, shardId);
|
||||||
|
@ -956,7 +958,7 @@ RenameShardRelationIndexes(Oid shardRelationId, uint64 shardId)
|
||||||
List *indexOidList = GetExplicitIndexOidList(shardRelationId);
|
List *indexOidList = GetExplicitIndexOidList(shardRelationId);
|
||||||
|
|
||||||
Oid indexOid = InvalidOid;
|
Oid indexOid = InvalidOid;
|
||||||
foreach_oid(indexOid, indexOidList)
|
foreach_declared_oid(indexOid, indexOidList)
|
||||||
{
|
{
|
||||||
const char *commandString = GetRenameShardIndexCommand(indexOid, shardId);
|
const char *commandString = GetRenameShardIndexCommand(indexOid, shardId);
|
||||||
ExecuteAndLogUtilityCommand(commandString);
|
ExecuteAndLogUtilityCommand(commandString);
|
||||||
|
@ -1006,7 +1008,7 @@ RenameShardRelationStatistics(Oid shardRelationId, uint64 shardId)
|
||||||
List *statsCommandList = GetRenameStatsCommandList(statsOidList, shardId);
|
List *statsCommandList = GetRenameStatsCommandList(statsOidList, shardId);
|
||||||
|
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
foreach_ptr(command, statsCommandList)
|
foreach_declared_ptr(command, statsCommandList)
|
||||||
{
|
{
|
||||||
ExecuteAndLogUtilityCommand(command);
|
ExecuteAndLogUtilityCommand(command);
|
||||||
}
|
}
|
||||||
|
@ -1042,7 +1044,7 @@ RenameShardRelationNonTruncateTriggers(Oid shardRelationId, uint64 shardId)
|
||||||
List *triggerIdList = GetExplicitTriggerIdList(shardRelationId);
|
List *triggerIdList = GetExplicitTriggerIdList(shardRelationId);
|
||||||
|
|
||||||
Oid triggerId = InvalidOid;
|
Oid triggerId = InvalidOid;
|
||||||
foreach_oid(triggerId, triggerIdList)
|
foreach_declared_oid(triggerId, triggerIdList)
|
||||||
{
|
{
|
||||||
bool missingOk = false;
|
bool missingOk = false;
|
||||||
HeapTuple triggerTuple = GetTriggerTupleById(triggerId, missingOk);
|
HeapTuple triggerTuple = GetTriggerTupleById(triggerId, missingOk);
|
||||||
|
@ -1095,7 +1097,7 @@ DropRelationTruncateTriggers(Oid relationId)
|
||||||
List *triggerIdList = GetExplicitTriggerIdList(relationId);
|
List *triggerIdList = GetExplicitTriggerIdList(relationId);
|
||||||
|
|
||||||
Oid triggerId = InvalidOid;
|
Oid triggerId = InvalidOid;
|
||||||
foreach_oid(triggerId, triggerIdList)
|
foreach_declared_oid(triggerId, triggerIdList)
|
||||||
{
|
{
|
||||||
bool missingOk = false;
|
bool missingOk = false;
|
||||||
HeapTuple triggerTuple = GetTriggerTupleById(triggerId, missingOk);
|
HeapTuple triggerTuple = GetTriggerTupleById(triggerId, missingOk);
|
||||||
|
@ -1158,9 +1160,7 @@ DropIdentitiesOnTable(Oid relationId)
|
||||||
|
|
||||||
if (attributeForm->attidentity)
|
if (attributeForm->attidentity)
|
||||||
{
|
{
|
||||||
char *tableName = get_rel_name(relationId);
|
char *qualifiedTableName = generate_qualified_relation_name(relationId);
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(relationId));
|
|
||||||
char *qualifiedTableName = quote_qualified_identifier(schemaName, tableName);
|
|
||||||
|
|
||||||
StringInfo dropCommand = makeStringInfo();
|
StringInfo dropCommand = makeStringInfo();
|
||||||
|
|
||||||
|
@ -1175,7 +1175,7 @@ DropIdentitiesOnTable(Oid relationId)
|
||||||
relation_close(relation, NoLock);
|
relation_close(relation, NoLock);
|
||||||
|
|
||||||
char *dropCommand = NULL;
|
char *dropCommand = NULL;
|
||||||
foreach_ptr(dropCommand, dropCommandList)
|
foreach_declared_ptr(dropCommand, dropCommandList)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We need to disable/enable ddl propagation for this command, to prevent
|
* We need to disable/enable ddl propagation for this command, to prevent
|
||||||
|
@ -1218,11 +1218,9 @@ DropViewsOnTable(Oid relationId)
|
||||||
List *reverseOrderedViews = ReversedOidList(views);
|
List *reverseOrderedViews = ReversedOidList(views);
|
||||||
|
|
||||||
Oid viewId = InvalidOid;
|
Oid viewId = InvalidOid;
|
||||||
foreach_oid(viewId, reverseOrderedViews)
|
foreach_declared_oid(viewId, reverseOrderedViews)
|
||||||
{
|
{
|
||||||
char *viewName = get_rel_name(viewId);
|
char *qualifiedViewName = generate_qualified_relation_name(viewId);
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(viewId));
|
|
||||||
char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName);
|
|
||||||
|
|
||||||
StringInfo dropCommand = makeStringInfo();
|
StringInfo dropCommand = makeStringInfo();
|
||||||
appendStringInfo(dropCommand, "DROP %sVIEW IF EXISTS %s",
|
appendStringInfo(dropCommand, "DROP %sVIEW IF EXISTS %s",
|
||||||
|
@ -1243,7 +1241,7 @@ ReversedOidList(List *oidList)
|
||||||
{
|
{
|
||||||
List *reversed = NIL;
|
List *reversed = NIL;
|
||||||
Oid oid = InvalidOid;
|
Oid oid = InvalidOid;
|
||||||
foreach_oid(oid, oidList)
|
foreach_declared_oid(oid, oidList)
|
||||||
{
|
{
|
||||||
reversed = lcons_oid(oid, reversed);
|
reversed = lcons_oid(oid, reversed);
|
||||||
}
|
}
|
||||||
|
@ -1295,7 +1293,7 @@ GetRenameStatsCommandList(List *statsOidList, uint64 shardId)
|
||||||
{
|
{
|
||||||
List *statsCommandList = NIL;
|
List *statsCommandList = NIL;
|
||||||
Oid statsOid;
|
Oid statsOid;
|
||||||
foreach_oid(statsOid, statsOidList)
|
foreach_declared_oid(statsOid, statsOidList)
|
||||||
{
|
{
|
||||||
HeapTuple tup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statsOid));
|
HeapTuple tup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statsOid));
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,16 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "signal.h"
|
||||||
|
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/backend_data.h"
|
#include "distributed/backend_data.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/remote_commands.h"
|
#include "distributed/remote_commands.h"
|
||||||
#include "distributed/worker_manager.h"
|
#include "distributed/worker_manager.h"
|
||||||
#include "lib/stringinfo.h"
|
|
||||||
#include "signal.h"
|
|
||||||
|
|
||||||
static bool CitusSignalBackend(uint64 globalPID, uint64 timeout, int sig);
|
static bool CitusSignalBackend(uint64 globalPID, uint64 timeout, int sig);
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "catalog/namespace.h"
|
||||||
|
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
|
||||||
#include "catalog/namespace.h"
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
@ -115,7 +115,7 @@ static bool
|
||||||
IsClusterStmtVerbose_compat(ClusterStmt *clusterStmt)
|
IsClusterStmtVerbose_compat(ClusterStmt *clusterStmt)
|
||||||
{
|
{
|
||||||
DefElem *opt = NULL;
|
DefElem *opt = NULL;
|
||||||
foreach_ptr(opt, clusterStmt->params)
|
foreach_declared_ptr(opt, clusterStmt->params)
|
||||||
{
|
{
|
||||||
if (strcmp(opt->defname, "verbose") == 0)
|
if (strcmp(opt->defname, "verbose") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,30 +10,32 @@
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "pg_version_compat.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/pg_collation.h"
|
#include "catalog/pg_collation.h"
|
||||||
#include "distributed/citus_safe_lib.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/metadata_utility.h"
|
|
||||||
#include "distributed/metadata/dependency.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/worker_create_or_replace.h"
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
#include "distributed/worker_manager.h"
|
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
|
#include "pg_version_compat.h"
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_safe_lib.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/dependency.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/metadata_utility.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/worker_create_or_replace.h"
|
||||||
|
#include "distributed/worker_manager.h"
|
||||||
|
|
||||||
|
|
||||||
static char * CreateCollationDDLInternal(Oid collationId, Oid *collowner,
|
static char * CreateCollationDDLInternal(Oid collationId, Oid *collowner,
|
||||||
|
@ -66,8 +68,6 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
char *collcollate;
|
char *collcollate;
|
||||||
char *collctype;
|
char *collctype;
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In PG15, there is an added option to use ICU as global locale provider.
|
* In PG15, there is an added option to use ICU as global locale provider.
|
||||||
* pg_collation has three locale-related fields: collcollate and collctype,
|
* pg_collation has three locale-related fields: collcollate and collctype,
|
||||||
|
@ -75,7 +75,7 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
* ICU-related field. Only the libc-related fields or the ICU-related field
|
* ICU-related field. Only the libc-related fields or the ICU-related field
|
||||||
* is set, never both.
|
* is set, never both.
|
||||||
*/
|
*/
|
||||||
char *colliculocale;
|
char *colllocale;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
|
|
||||||
Datum datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collcollate,
|
Datum datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collcollate,
|
||||||
|
@ -99,27 +99,17 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
collctype = NULL;
|
collctype = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_colliculocale, &isnull);
|
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_colllocale, &isnull);
|
||||||
if (!isnull)
|
if (!isnull)
|
||||||
{
|
{
|
||||||
colliculocale = TextDatumGetCString(datum);
|
colllocale = TextDatumGetCString(datum);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
colliculocale = NULL;
|
colllocale = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert((collcollate && collctype) || colliculocale);
|
Assert((collcollate && collctype) || colllocale);
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In versions before 15, collcollate and collctype were type "name". Use
|
|
||||||
* pstrdup() to match the interface of 15 so that we consistently free the
|
|
||||||
* result later.
|
|
||||||
*/
|
|
||||||
collcollate = pstrdup(NameStr(collationForm->collcollate));
|
|
||||||
collctype = pstrdup(NameStr(collationForm->collctype));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (collowner != NULL)
|
if (collowner != NULL)
|
||||||
{
|
{
|
||||||
|
@ -130,6 +120,7 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
char *schemaName = get_namespace_name(collnamespace);
|
char *schemaName = get_namespace_name(collnamespace);
|
||||||
*quotedCollationName = quote_qualified_identifier(schemaName, collname);
|
*quotedCollationName = quote_qualified_identifier(schemaName, collname);
|
||||||
const char *providerString =
|
const char *providerString =
|
||||||
|
collprovider == COLLPROVIDER_BUILTIN ? "builtin" :
|
||||||
collprovider == COLLPROVIDER_DEFAULT ? "default" :
|
collprovider == COLLPROVIDER_DEFAULT ? "default" :
|
||||||
collprovider == COLLPROVIDER_ICU ? "icu" :
|
collprovider == COLLPROVIDER_ICU ? "icu" :
|
||||||
collprovider == COLLPROVIDER_LIBC ? "libc" : NULL;
|
collprovider == COLLPROVIDER_LIBC ? "libc" : NULL;
|
||||||
|
@ -144,13 +135,12 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
"CREATE COLLATION %s (provider = '%s'",
|
"CREATE COLLATION %s (provider = '%s'",
|
||||||
*quotedCollationName, providerString);
|
*quotedCollationName, providerString);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
if (colllocale)
|
||||||
if (colliculocale)
|
|
||||||
{
|
{
|
||||||
appendStringInfo(&collationNameDef,
|
appendStringInfo(&collationNameDef,
|
||||||
", locale = %s",
|
", locale = %s",
|
||||||
quote_literal_cstr(colliculocale));
|
quote_literal_cstr(colllocale));
|
||||||
pfree(colliculocale);
|
pfree(colllocale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -170,24 +160,7 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
pfree(collcollate);
|
pfree(collcollate);
|
||||||
pfree(collctype);
|
pfree(collctype);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (strcmp(collcollate, collctype) == 0)
|
|
||||||
{
|
|
||||||
appendStringInfo(&collationNameDef,
|
|
||||||
", locale = %s",
|
|
||||||
quote_literal_cstr(collcollate));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
appendStringInfo(&collationNameDef,
|
|
||||||
", lc_collate = %s, lc_ctype = %s",
|
|
||||||
quote_literal_cstr(collcollate),
|
|
||||||
quote_literal_cstr(collctype));
|
|
||||||
}
|
|
||||||
|
|
||||||
pfree(collcollate);
|
|
||||||
pfree(collctype);
|
|
||||||
#endif
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
char *collicurules = NULL;
|
char *collicurules = NULL;
|
||||||
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collicurules, &isnull);
|
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collicurules, &isnull);
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/dependency.h"
|
#include "distributed/metadata/dependency.h"
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ PreprocessDropDistributedObjectStmt(Node *node, const char *queryString,
|
||||||
List *distributedObjects = NIL;
|
List *distributedObjects = NIL;
|
||||||
List *distributedObjectAddresses = NIL;
|
List *distributedObjectAddresses = NIL;
|
||||||
Node *object = NULL;
|
Node *object = NULL;
|
||||||
foreach_ptr(object, stmt->objects)
|
foreach_declared_ptr(object, stmt->objects)
|
||||||
{
|
{
|
||||||
/* TODO understand if the lock should be sth else */
|
/* TODO understand if the lock should be sth else */
|
||||||
Relation rel = NULL; /* not used, but required to pass to get_object_address */
|
Relation rel = NULL; /* not used, but required to pass to get_object_address */
|
||||||
|
@ -267,7 +267,7 @@ PreprocessDropDistributedObjectStmt(Node *node, const char *queryString,
|
||||||
* remove the entries for the distributed objects on dropping
|
* remove the entries for the distributed objects on dropping
|
||||||
*/
|
*/
|
||||||
ObjectAddress *address = NULL;
|
ObjectAddress *address = NULL;
|
||||||
foreach_ptr(address, distributedObjectAddresses)
|
foreach_declared_ptr(address, distributedObjectAddresses)
|
||||||
{
|
{
|
||||||
UnmarkObjectDistributed(address);
|
UnmarkObjectDistributed(address);
|
||||||
}
|
}
|
||||||
|
@ -303,7 +303,7 @@ DropTextSearchDictObjectAddress(Node *node, bool missing_ok, bool isPostprocess)
|
||||||
List *objectAddresses = NIL;
|
List *objectAddresses = NIL;
|
||||||
|
|
||||||
List *objNameList = NIL;
|
List *objNameList = NIL;
|
||||||
foreach_ptr(objNameList, stmt->objects)
|
foreach_declared_ptr(objNameList, stmt->objects)
|
||||||
{
|
{
|
||||||
Oid tsdictOid = get_ts_dict_oid(objNameList, missing_ok);
|
Oid tsdictOid = get_ts_dict_oid(objNameList, missing_ok);
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ DropTextSearchConfigObjectAddress(Node *node, bool missing_ok, bool isPostproces
|
||||||
List *objectAddresses = NIL;
|
List *objectAddresses = NIL;
|
||||||
|
|
||||||
List *objNameList = NIL;
|
List *objNameList = NIL;
|
||||||
foreach_ptr(objNameList, stmt->objects)
|
foreach_declared_ptr(objNameList, stmt->objects)
|
||||||
{
|
{
|
||||||
Oid tsconfigOid = get_ts_config_oid(objNameList, missing_ok);
|
Oid tsconfigOid = get_ts_config_oid(objNameList, missing_ok);
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "miscadmin.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/hash.h"
|
#include "access/hash.h"
|
||||||
|
@ -24,6 +22,7 @@
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
|
#include "catalog/pg_attrdef.h"
|
||||||
#include "catalog/pg_attribute.h"
|
#include "catalog/pg_attribute.h"
|
||||||
#include "catalog/pg_enum.h"
|
#include "catalog/pg_enum.h"
|
||||||
#include "catalog/pg_extension.h"
|
#include "catalog/pg_extension.h"
|
||||||
|
@ -37,42 +36,6 @@
|
||||||
#include "commands/sequence.h"
|
#include "commands/sequence.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "distributed/commands/multi_copy.h"
|
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/colocation_utils.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/distributed_execution_locks.h"
|
|
||||||
#include "distributed/distribution_column.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/local_executor.h"
|
|
||||||
#include "distributed/metadata_utility.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata/dependency.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/multi_logical_planner.h"
|
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
|
||||||
#include "distributed/pg_dist_colocation.h"
|
|
||||||
#include "distributed/pg_dist_partition.h"
|
|
||||||
#include "distributed/reference_table_utils.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/remote_commands.h"
|
|
||||||
#include "distributed/replicate_none_dist_table_shard.h"
|
|
||||||
#include "distributed/resource_lock.h"
|
|
||||||
#include "distributed/shard_cleaner.h"
|
|
||||||
#include "distributed/shard_rebalancer.h"
|
|
||||||
#include "distributed/shard_split.h"
|
|
||||||
#include "distributed/shard_transfer.h"
|
|
||||||
#include "distributed/shared_library_init.h"
|
|
||||||
#include "distributed/shard_rebalancer.h"
|
|
||||||
#include "distributed/worker_protocol.h"
|
|
||||||
#include "distributed/worker_shard_visibility.h"
|
|
||||||
#include "distributed/worker_transaction.h"
|
|
||||||
#include "distributed/utils/distribution_column_map.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "executor/spi.h"
|
#include "executor/spi.h"
|
||||||
#include "nodes/execnodes.h"
|
#include "nodes/execnodes.h"
|
||||||
|
@ -88,12 +51,52 @@
|
||||||
#include "tcop/pquery.h"
|
#include "tcop/pquery.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/inval.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/snapmgr.h"
|
#include "utils/snapmgr.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "utils/inval.h"
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/colocation_utils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/multi_copy.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/distributed_execution_locks.h"
|
||||||
|
#include "distributed/distribution_column.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/local_executor.h"
|
||||||
|
#include "distributed/metadata/dependency.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_cache.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/metadata_utility.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/multi_logical_planner.h"
|
||||||
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
|
#include "distributed/pg_dist_colocation.h"
|
||||||
|
#include "distributed/pg_dist_partition.h"
|
||||||
|
#include "distributed/reference_table_utils.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/remote_commands.h"
|
||||||
|
#include "distributed/replicate_none_dist_table_shard.h"
|
||||||
|
#include "distributed/resource_lock.h"
|
||||||
|
#include "distributed/shard_cleaner.h"
|
||||||
|
#include "distributed/shard_rebalancer.h"
|
||||||
|
#include "distributed/shard_split.h"
|
||||||
|
#include "distributed/shard_transfer.h"
|
||||||
|
#include "distributed/shared_library_init.h"
|
||||||
|
#include "distributed/utils/distribution_column_map.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_protocol.h"
|
||||||
|
#include "distributed/worker_shard_visibility.h"
|
||||||
|
#include "distributed/worker_transaction.h"
|
||||||
|
|
||||||
|
|
||||||
/* common params that apply to all Citus table types */
|
/* common params that apply to all Citus table types */
|
||||||
|
@ -167,12 +170,10 @@ static void EnsureDistributedSequencesHaveOneType(Oid relationId,
|
||||||
static void CopyLocalDataIntoShards(Oid distributedTableId);
|
static void CopyLocalDataIntoShards(Oid distributedTableId);
|
||||||
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static bool DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
static bool DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
||||||
Var *distributionColumn);
|
Var *distributionColumn);
|
||||||
static int numeric_typmod_scale(int32 typmod);
|
static int numeric_typmod_scale(int32 typmod);
|
||||||
static bool is_valid_numeric_typmod(int32 typmod);
|
static bool is_valid_numeric_typmod(int32 typmod);
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
static bool DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
||||||
Var *distributionColumn);
|
Var *distributionColumn);
|
||||||
|
@ -445,6 +446,19 @@ CreateDistributedTableConcurrently(Oid relationId, char *distributionColumnName,
|
||||||
if (!IsColocateWithDefault(colocateWithTableName) && !IsColocateWithNone(
|
if (!IsColocateWithDefault(colocateWithTableName) && !IsColocateWithNone(
|
||||||
colocateWithTableName))
|
colocateWithTableName))
|
||||||
{
|
{
|
||||||
|
if (replicationModel != REPLICATION_MODEL_STREAMING)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg("cannot create distributed table "
|
||||||
|
"concurrently because Citus allows "
|
||||||
|
"concurrent table distribution only when "
|
||||||
|
"citus.shard_replication_factor = 1"),
|
||||||
|
errhint("table %s is requested to be colocated "
|
||||||
|
"with %s which has "
|
||||||
|
"citus.shard_replication_factor > 1",
|
||||||
|
get_rel_name(relationId),
|
||||||
|
colocateWithTableName)));
|
||||||
|
}
|
||||||
|
|
||||||
EnsureColocateWithTableIsValid(relationId, distributionMethod,
|
EnsureColocateWithTableIsValid(relationId, distributionMethod,
|
||||||
distributionColumnName,
|
distributionColumnName,
|
||||||
colocateWithTableName);
|
colocateWithTableName);
|
||||||
|
@ -818,7 +832,7 @@ HashSplitPointsForShardList(List *shardList)
|
||||||
List *splitPointList = NIL;
|
List *splitPointList = NIL;
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardList)
|
foreach_declared_ptr(shardInterval, shardList)
|
||||||
{
|
{
|
||||||
int32 shardMaxValue = DatumGetInt32(shardInterval->maxValue);
|
int32 shardMaxValue = DatumGetInt32(shardInterval->maxValue);
|
||||||
|
|
||||||
|
@ -874,7 +888,7 @@ WorkerNodesForShardList(List *shardList)
|
||||||
List *nodeIdList = NIL;
|
List *nodeIdList = NIL;
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardList)
|
foreach_declared_ptr(shardInterval, shardList)
|
||||||
{
|
{
|
||||||
WorkerNode *workerNode = ActiveShardPlacementWorkerNode(shardInterval->shardId);
|
WorkerNode *workerNode = ActiveShardPlacementWorkerNode(shardInterval->shardId);
|
||||||
nodeIdList = lappend_int(nodeIdList, workerNode->nodeId);
|
nodeIdList = lappend_int(nodeIdList, workerNode->nodeId);
|
||||||
|
@ -1309,10 +1323,7 @@ CreateCitusTable(Oid relationId, CitusTableType tableType,
|
||||||
{
|
{
|
||||||
List *partitionList = PartitionList(relationId);
|
List *partitionList = PartitionList(relationId);
|
||||||
Oid partitionRelationId = InvalidOid;
|
Oid partitionRelationId = InvalidOid;
|
||||||
Oid namespaceId = get_rel_namespace(relationId);
|
char *parentRelationName = generate_qualified_relation_name(relationId);
|
||||||
char *schemaName = get_namespace_name(namespaceId);
|
|
||||||
char *relationName = get_rel_name(relationId);
|
|
||||||
char *parentRelationName = quote_qualified_identifier(schemaName, relationName);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* when there are many partitions, each call to CreateDistributedTable
|
* when there are many partitions, each call to CreateDistributedTable
|
||||||
|
@ -1324,7 +1335,7 @@ CreateCitusTable(Oid relationId, CitusTableType tableType,
|
||||||
ALLOCSET_DEFAULT_SIZES);
|
ALLOCSET_DEFAULT_SIZES);
|
||||||
MemoryContext oldContext = MemoryContextSwitchTo(citusPartitionContext);
|
MemoryContext oldContext = MemoryContextSwitchTo(citusPartitionContext);
|
||||||
|
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
foreach_declared_oid(partitionRelationId, partitionList)
|
||||||
{
|
{
|
||||||
MemoryContextReset(citusPartitionContext);
|
MemoryContextReset(citusPartitionContext);
|
||||||
|
|
||||||
|
@ -1538,7 +1549,7 @@ ConvertCitusLocalTableToTableType(Oid relationId, CitusTableType tableType,
|
||||||
MemoryContext oldContext = MemoryContextSwitchTo(citusPartitionContext);
|
MemoryContext oldContext = MemoryContextSwitchTo(citusPartitionContext);
|
||||||
|
|
||||||
Oid partitionRelationId = InvalidOid;
|
Oid partitionRelationId = InvalidOid;
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
foreach_declared_oid(partitionRelationId, partitionList)
|
||||||
{
|
{
|
||||||
MemoryContextReset(citusPartitionContext);
|
MemoryContextReset(citusPartitionContext);
|
||||||
|
|
||||||
|
@ -1685,52 +1696,39 @@ PropagatePrerequisiteObjectsForDistributedTable(Oid relationId)
|
||||||
void
|
void
|
||||||
EnsureSequenceTypeSupported(Oid seqOid, Oid attributeTypeId, Oid ownerRelationId)
|
EnsureSequenceTypeSupported(Oid seqOid, Oid attributeTypeId, Oid ownerRelationId)
|
||||||
{
|
{
|
||||||
List *citusTableIdList = CitusTableTypeIdList(ANY_CITUS_TABLE_TYPE);
|
Oid attrDefOid;
|
||||||
citusTableIdList = list_append_unique_oid(citusTableIdList, ownerRelationId);
|
List *attrDefOids = GetAttrDefsFromSequence(seqOid);
|
||||||
|
|
||||||
Oid citusTableId = InvalidOid;
|
foreach_declared_oid(attrDefOid, attrDefOids)
|
||||||
foreach_oid(citusTableId, citusTableIdList)
|
|
||||||
{
|
{
|
||||||
List *seqInfoList = NIL;
|
ObjectAddress columnAddress = GetAttrDefaultColumnAddress(attrDefOid);
|
||||||
GetDependentSequencesWithRelation(citusTableId, &seqInfoList, 0, DEPENDENCY_AUTO);
|
|
||||||
|
|
||||||
SequenceInfo *seqInfo = NULL;
|
/*
|
||||||
foreach_ptr(seqInfo, seqInfoList)
|
* If another distributed table is using the same sequence
|
||||||
|
* in one of its column defaults, make sure the types of the
|
||||||
|
* columns match.
|
||||||
|
*
|
||||||
|
* We skip non-distributed tables, but we need to check the current
|
||||||
|
* table as it might reference the same sequence multiple times.
|
||||||
|
*/
|
||||||
|
if (columnAddress.objectId != ownerRelationId &&
|
||||||
|
!IsCitusTable(columnAddress.objectId))
|
||||||
{
|
{
|
||||||
AttrNumber currentAttnum = seqInfo->attributeNumber;
|
continue;
|
||||||
Oid currentSeqOid = seqInfo->sequenceOid;
|
}
|
||||||
|
Oid currentAttributeTypId = GetAttributeTypeOid(columnAddress.objectId,
|
||||||
if (!seqInfo->isNextValDefault)
|
columnAddress.objectSubId);
|
||||||
{
|
if (attributeTypeId != currentAttributeTypId)
|
||||||
/*
|
{
|
||||||
* If a sequence is not on the nextval, we don't need any check.
|
char *sequenceName = generate_qualified_relation_name(
|
||||||
* This is a dependent sequence via ALTER SEQUENCE .. OWNED BY col
|
seqOid);
|
||||||
*/
|
char *citusTableName =
|
||||||
continue;
|
generate_qualified_relation_name(columnAddress.objectId);
|
||||||
}
|
ereport(ERROR, (errmsg(
|
||||||
|
"The sequence %s is already used for a different"
|
||||||
/*
|
" type in column %d of the table %s",
|
||||||
* If another distributed table is using the same sequence
|
sequenceName, columnAddress.objectSubId,
|
||||||
* in one of its column defaults, make sure the types of the
|
citusTableName)));
|
||||||
* columns match
|
|
||||||
*/
|
|
||||||
if (currentSeqOid == seqOid)
|
|
||||||
{
|
|
||||||
Oid currentAttributeTypId = GetAttributeTypeOid(citusTableId,
|
|
||||||
currentAttnum);
|
|
||||||
if (attributeTypeId != currentAttributeTypId)
|
|
||||||
{
|
|
||||||
char *sequenceName = generate_qualified_relation_name(
|
|
||||||
seqOid);
|
|
||||||
char *citusTableName =
|
|
||||||
generate_qualified_relation_name(citusTableId);
|
|
||||||
ereport(ERROR, (errmsg(
|
|
||||||
"The sequence %s is already used for a different"
|
|
||||||
" type in column %d of the table %s",
|
|
||||||
sequenceName, currentAttnum,
|
|
||||||
citusTableName)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1783,7 +1781,7 @@ static void
|
||||||
EnsureDistributedSequencesHaveOneType(Oid relationId, List *seqInfoList)
|
EnsureDistributedSequencesHaveOneType(Oid relationId, List *seqInfoList)
|
||||||
{
|
{
|
||||||
SequenceInfo *seqInfo = NULL;
|
SequenceInfo *seqInfo = NULL;
|
||||||
foreach_ptr(seqInfo, seqInfoList)
|
foreach_declared_ptr(seqInfo, seqInfoList)
|
||||||
{
|
{
|
||||||
if (!seqInfo->isNextValDefault)
|
if (!seqInfo->isNextValDefault)
|
||||||
{
|
{
|
||||||
|
@ -2114,8 +2112,6 @@ EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
||||||
"AS (...) STORED.")));
|
"AS (...) STORED.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/* verify target relation is not distributed by a column of type numeric with negative scale */
|
/* verify target relation is not distributed by a column of type numeric with negative scale */
|
||||||
if (distributionMethod != DISTRIBUTE_BY_NONE &&
|
if (distributionMethod != DISTRIBUTE_BY_NONE &&
|
||||||
DistributionColumnUsesNumericColumnNegativeScale(relationDesc,
|
DistributionColumnUsesNumericColumnNegativeScale(relationDesc,
|
||||||
|
@ -2126,7 +2122,6 @@ EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
||||||
errdetail("Distribution column must not use numeric type "
|
errdetail("Distribution column must not use numeric type "
|
||||||
"with negative scale")));
|
"with negative scale")));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* check for support function needed by specified partition method */
|
/* check for support function needed by specified partition method */
|
||||||
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
||||||
|
@ -2844,8 +2839,6 @@ TupleDescColumnNameList(TupleDesc tupleDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* is_valid_numeric_typmod checks if the typmod value is valid
|
* is_valid_numeric_typmod checks if the typmod value is valid
|
||||||
*
|
*
|
||||||
|
@ -2895,8 +2888,6 @@ DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DistributionColumnUsesGeneratedStoredColumn returns whether a given relation uses
|
* DistributionColumnUsesGeneratedStoredColumn returns whether a given relation uses
|
||||||
* GENERATED ALWAYS AS (...) STORED on distribution column
|
* GENERATED ALWAYS AS (...) STORED on distribution column
|
||||||
|
|
|
@ -11,18 +11,20 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/objectaddress.h"
|
#include "catalog/objectaddress.h"
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/metadata_utility.h"
|
#include "distributed/metadata_utility.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
|
@ -31,6 +33,8 @@
|
||||||
|
|
||||||
static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid);
|
static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid);
|
||||||
static Oid get_database_owner(Oid db_oid);
|
static Oid get_database_owner(Oid db_oid);
|
||||||
|
static ObjectAddress * GetDatabaseAddressFromDatabaseName(char *databaseName,
|
||||||
|
bool missingOk);
|
||||||
List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
|
List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
|
|
||||||
|
@ -160,13 +164,15 @@ List *
|
||||||
PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
|
PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext)
|
ProcessUtilityContext processUtilityContext)
|
||||||
{
|
{
|
||||||
if (!ShouldPropagate())
|
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
|
||||||
|
bool missingOk = false;
|
||||||
|
ObjectAddress *dbAddress = GetDatabaseAddressFromDatabaseName(stmt->dbname,
|
||||||
|
missingOk);
|
||||||
|
if (!ShouldPropagate() || !IsAnyObjectDistributed(list_make1(dbAddress)))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
|
|
||||||
|
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
|
|
||||||
char *sql = DeparseTreeNode((Node *) stmt);
|
char *sql = DeparseTreeNode((Node *) stmt);
|
||||||
|
@ -179,8 +185,6 @@ PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local
|
* PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local
|
||||||
* postgres instance.
|
* postgres instance.
|
||||||
|
@ -211,4 +215,15 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
/*
|
||||||
|
* GetDatabaseAddressFromDatabaseName gets the database name and returns the ObjectAddress
|
||||||
|
* of the database.
|
||||||
|
*/
|
||||||
|
static ObjectAddress *
|
||||||
|
GetDatabaseAddressFromDatabaseName(char *databaseName, bool missingOk)
|
||||||
|
{
|
||||||
|
Oid databaseOid = get_database_oid(databaseName, missingOk);
|
||||||
|
ObjectAddress *dbObjectAddress = palloc0(sizeof(ObjectAddress));
|
||||||
|
ObjectAddressSet(*dbObjectAddress, DatabaseRelationId, databaseOid);
|
||||||
|
return dbObjectAddress;
|
||||||
|
}
|
||||||
|
|
|
@ -10,9 +10,14 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/objectaddress.h"
|
#include "catalog/objectaddress.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
|
#include "storage/lmgr.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
|
@ -25,9 +30,6 @@
|
||||||
#include "distributed/remote_commands.h"
|
#include "distributed/remote_commands.h"
|
||||||
#include "distributed/worker_manager.h"
|
#include "distributed/worker_manager.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "storage/lmgr.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void EnsureDependenciesCanBeDistributed(const ObjectAddress *relationAddress);
|
static void EnsureDependenciesCanBeDistributed(const ObjectAddress *relationAddress);
|
||||||
|
@ -67,7 +69,7 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
||||||
/* collect all dependencies in creation order and get their ddl commands */
|
/* collect all dependencies in creation order and get their ddl commands */
|
||||||
List *dependencies = GetDependenciesForObject(target);
|
List *dependencies = GetDependenciesForObject(target);
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
foreach_ptr(dependency, dependencies)
|
foreach_declared_ptr(dependency, dependencies)
|
||||||
{
|
{
|
||||||
List *dependencyCommands = GetDependencyCreateDDLCommands(dependency);
|
List *dependencyCommands = GetDependencyCreateDDLCommands(dependency);
|
||||||
ddlCommands = list_concat(ddlCommands, dependencyCommands);
|
ddlCommands = list_concat(ddlCommands, dependencyCommands);
|
||||||
|
@ -106,7 +108,7 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
||||||
*/
|
*/
|
||||||
List *addressSortedDependencies = SortList(dependenciesWithCommands,
|
List *addressSortedDependencies = SortList(dependenciesWithCommands,
|
||||||
ObjectAddressComparator);
|
ObjectAddressComparator);
|
||||||
foreach_ptr(dependency, addressSortedDependencies)
|
foreach_declared_ptr(dependency, addressSortedDependencies)
|
||||||
{
|
{
|
||||||
LockDatabaseObject(dependency->classId, dependency->objectId,
|
LockDatabaseObject(dependency->classId, dependency->objectId,
|
||||||
dependency->objectSubId, ExclusiveLock);
|
dependency->objectSubId, ExclusiveLock);
|
||||||
|
@ -132,7 +134,7 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WorkerNode *workerNode = NULL;
|
WorkerNode *workerNode = NULL;
|
||||||
foreach_ptr(workerNode, workerNodeList)
|
foreach_declared_ptr(workerNode, workerNodeList)
|
||||||
{
|
{
|
||||||
const char *nodeName = workerNode->workerName;
|
const char *nodeName = workerNode->workerName;
|
||||||
uint32 nodePort = workerNode->workerPort;
|
uint32 nodePort = workerNode->workerPort;
|
||||||
|
@ -148,7 +150,7 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
||||||
* that objects have been created on worker nodes before marking them
|
* that objects have been created on worker nodes before marking them
|
||||||
* distributed, so MarkObjectDistributed wouldn't fail.
|
* distributed, so MarkObjectDistributed wouldn't fail.
|
||||||
*/
|
*/
|
||||||
foreach_ptr(dependency, dependenciesWithCommands)
|
foreach_declared_ptr(dependency, dependenciesWithCommands)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* pg_dist_object entries must be propagated with the super user, since
|
* pg_dist_object entries must be propagated with the super user, since
|
||||||
|
@ -171,7 +173,7 @@ void
|
||||||
EnsureAllObjectDependenciesExistOnAllNodes(const List *targets)
|
EnsureAllObjectDependenciesExistOnAllNodes(const List *targets)
|
||||||
{
|
{
|
||||||
ObjectAddress *target = NULL;
|
ObjectAddress *target = NULL;
|
||||||
foreach_ptr(target, targets)
|
foreach_declared_ptr(target, targets)
|
||||||
{
|
{
|
||||||
EnsureDependenciesExistOnAllNodes(target);
|
EnsureDependenciesExistOnAllNodes(target);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +230,7 @@ DeferErrorIfCircularDependencyExists(const ObjectAddress *objectAddress)
|
||||||
List *dependencies = GetAllDependenciesForObject(objectAddress);
|
List *dependencies = GetAllDependenciesForObject(objectAddress);
|
||||||
|
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
foreach_ptr(dependency, dependencies)
|
foreach_declared_ptr(dependency, dependencies)
|
||||||
{
|
{
|
||||||
if (dependency->classId == objectAddress->classId &&
|
if (dependency->classId == objectAddress->classId &&
|
||||||
dependency->objectId == objectAddress->objectId &&
|
dependency->objectId == objectAddress->objectId &&
|
||||||
|
@ -316,7 +318,7 @@ GetDistributableDependenciesForObject(const ObjectAddress *target)
|
||||||
|
|
||||||
/* filter the ones that can be distributed */
|
/* filter the ones that can be distributed */
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
foreach_ptr(dependency, dependencies)
|
foreach_declared_ptr(dependency, dependencies)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* TODO: maybe we can optimize the logic applied in below line. Actually we
|
* TODO: maybe we can optimize the logic applied in below line. Actually we
|
||||||
|
@ -400,7 +402,7 @@ GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
|
||||||
INCLUDE_IDENTITY,
|
INCLUDE_IDENTITY,
|
||||||
creatingShellTableOnRemoteNode);
|
creatingShellTableOnRemoteNode);
|
||||||
TableDDLCommand *tableDDLCommand = NULL;
|
TableDDLCommand *tableDDLCommand = NULL;
|
||||||
foreach_ptr(tableDDLCommand, tableDDLCommands)
|
foreach_declared_ptr(tableDDLCommand, tableDDLCommands)
|
||||||
{
|
{
|
||||||
Assert(CitusIsA(tableDDLCommand, TableDDLCommand));
|
Assert(CitusIsA(tableDDLCommand, TableDDLCommand));
|
||||||
commandList = lappend(commandList, GetTableDDLCommand(
|
commandList = lappend(commandList, GetTableDDLCommand(
|
||||||
|
@ -562,7 +564,7 @@ GetAllDependencyCreateDDLCommands(const List *dependencies)
|
||||||
List *commands = NIL;
|
List *commands = NIL;
|
||||||
|
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
foreach_ptr(dependency, dependencies)
|
foreach_declared_ptr(dependency, dependencies)
|
||||||
{
|
{
|
||||||
commands = list_concat(commands, GetDependencyCreateDDLCommands(dependency));
|
commands = list_concat(commands, GetDependencyCreateDDLCommands(dependency));
|
||||||
}
|
}
|
||||||
|
@ -710,7 +712,7 @@ bool
|
||||||
ShouldPropagateAnyObject(List *addresses)
|
ShouldPropagateAnyObject(List *addresses)
|
||||||
{
|
{
|
||||||
ObjectAddress *address = NULL;
|
ObjectAddress *address = NULL;
|
||||||
foreach_ptr(address, addresses)
|
foreach_declared_ptr(address, addresses)
|
||||||
{
|
{
|
||||||
if (ShouldPropagateObject(address))
|
if (ShouldPropagateObject(address))
|
||||||
{
|
{
|
||||||
|
@ -732,7 +734,7 @@ FilterObjectAddressListByPredicate(List *objectAddressList, AddressPredicate pre
|
||||||
List *result = NIL;
|
List *result = NIL;
|
||||||
|
|
||||||
ObjectAddress *address = NULL;
|
ObjectAddress *address = NULL;
|
||||||
foreach_ptr(address, objectAddressList)
|
foreach_declared_ptr(address, objectAddressList)
|
||||||
{
|
{
|
||||||
if (predicate(address))
|
if (predicate(address))
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,11 +12,12 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
|
||||||
static DistributeObjectOps NoDistributeOps = {
|
static DistributeObjectOps NoDistributeOps = {
|
||||||
.deparse = NULL,
|
.deparse = NULL,
|
||||||
|
@ -363,6 +364,15 @@ static DistributeObjectOps Any_Rename = {
|
||||||
.address = NULL,
|
.address = NULL,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
|
static DistributeObjectOps Any_SecLabel = {
|
||||||
|
.deparse = DeparseSecLabelStmt,
|
||||||
|
.qualify = NULL,
|
||||||
|
.preprocess = NULL,
|
||||||
|
.postprocess = PostprocessSecLabelStmt,
|
||||||
|
.operationType = DIST_OPS_ALTER,
|
||||||
|
.address = SecLabelStmtObjectAddress,
|
||||||
|
.markDistributed = false,
|
||||||
|
};
|
||||||
static DistributeObjectOps Attribute_Rename = {
|
static DistributeObjectOps Attribute_Rename = {
|
||||||
.deparse = DeparseRenameAttributeStmt,
|
.deparse = DeparseRenameAttributeStmt,
|
||||||
.qualify = QualifyRenameAttributeStmt,
|
.qualify = QualifyRenameAttributeStmt,
|
||||||
|
@ -455,7 +465,6 @@ static DistributeObjectOps Database_Alter = {
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
static DistributeObjectOps Database_RefreshColl = {
|
static DistributeObjectOps Database_RefreshColl = {
|
||||||
.deparse = DeparseAlterDatabaseRefreshCollStmt,
|
.deparse = DeparseAlterDatabaseRefreshCollStmt,
|
||||||
.qualify = NULL,
|
.qualify = NULL,
|
||||||
|
@ -466,7 +475,6 @@ static DistributeObjectOps Database_RefreshColl = {
|
||||||
.address = NULL,
|
.address = NULL,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
static DistributeObjectOps Domain_Alter = {
|
static DistributeObjectOps Domain_Alter = {
|
||||||
.deparse = DeparseAlterDomainStmt,
|
.deparse = DeparseAlterDomainStmt,
|
||||||
|
@ -827,7 +835,6 @@ static DistributeObjectOps Sequence_AlterOwner = {
|
||||||
.address = AlterSequenceOwnerStmtObjectAddress,
|
.address = AlterSequenceOwnerStmtObjectAddress,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static DistributeObjectOps Sequence_AlterPersistence = {
|
static DistributeObjectOps Sequence_AlterPersistence = {
|
||||||
.deparse = DeparseAlterSequencePersistenceStmt,
|
.deparse = DeparseAlterSequencePersistenceStmt,
|
||||||
.qualify = QualifyAlterSequencePersistenceStmt,
|
.qualify = QualifyAlterSequencePersistenceStmt,
|
||||||
|
@ -837,7 +844,6 @@ static DistributeObjectOps Sequence_AlterPersistence = {
|
||||||
.address = AlterSequencePersistenceStmtObjectAddress,
|
.address = AlterSequencePersistenceStmtObjectAddress,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
static DistributeObjectOps Sequence_Drop = {
|
static DistributeObjectOps Sequence_Drop = {
|
||||||
.deparse = DeparseDropSequenceStmt,
|
.deparse = DeparseDropSequenceStmt,
|
||||||
.qualify = QualifyDropSequenceStmt,
|
.qualify = QualifyDropSequenceStmt,
|
||||||
|
@ -1289,7 +1295,7 @@ static DistributeObjectOps View_Rename = {
|
||||||
static DistributeObjectOps Trigger_Rename = {
|
static DistributeObjectOps Trigger_Rename = {
|
||||||
.deparse = NULL,
|
.deparse = NULL,
|
||||||
.qualify = NULL,
|
.qualify = NULL,
|
||||||
.preprocess = PreprocessAlterTriggerRenameStmt,
|
.preprocess = NULL,
|
||||||
.operationType = DIST_OPS_ALTER,
|
.operationType = DIST_OPS_ALTER,
|
||||||
.postprocess = PostprocessAlterTriggerRenameStmt,
|
.postprocess = PostprocessAlterTriggerRenameStmt,
|
||||||
.address = NULL,
|
.address = NULL,
|
||||||
|
@ -1311,13 +1317,11 @@ GetDistributeObjectOps(Node *node)
|
||||||
return &Database_Alter;
|
return &Database_Alter;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
case T_AlterDatabaseRefreshCollStmt:
|
case T_AlterDatabaseRefreshCollStmt:
|
||||||
{
|
{
|
||||||
return &Database_RefreshColl;
|
return &Database_RefreshColl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
case T_AlterDomainStmt:
|
case T_AlterDomainStmt:
|
||||||
{
|
{
|
||||||
return &Domain_Alter;
|
return &Domain_Alter;
|
||||||
|
@ -1602,7 +1606,6 @@ GetDistributeObjectOps(Node *node)
|
||||||
|
|
||||||
case OBJECT_SEQUENCE:
|
case OBJECT_SEQUENCE:
|
||||||
{
|
{
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
ListCell *cmdCell = NULL;
|
ListCell *cmdCell = NULL;
|
||||||
foreach(cmdCell, stmt->cmds)
|
foreach(cmdCell, stmt->cmds)
|
||||||
{
|
{
|
||||||
|
@ -1630,7 +1633,6 @@ GetDistributeObjectOps(Node *node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prior to PG15, the only Alter Table statement
|
* Prior to PG15, the only Alter Table statement
|
||||||
|
@ -1990,6 +1992,11 @@ GetDistributeObjectOps(Node *node)
|
||||||
return &Vacuum_Analyze;
|
return &Vacuum_Analyze;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_SecLabelStmt:
|
||||||
|
{
|
||||||
|
return &Any_SecLabel;
|
||||||
|
}
|
||||||
|
|
||||||
case T_RenameStmt:
|
case T_RenameStmt:
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
|
|
|
@ -210,7 +210,7 @@ MakeCollateClauseFromOid(Oid collationOid)
|
||||||
getObjectIdentityParts(&collateAddress, &objName, &objArgs, false);
|
getObjectIdentityParts(&collateAddress, &objName, &objArgs, false);
|
||||||
|
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
foreach_ptr(name, objName)
|
foreach_declared_ptr(name, objName)
|
||||||
{
|
{
|
||||||
collateClause->collname = lappend(collateClause->collname, makeString(name));
|
collateClause->collname = lappend(collateClause->collname, makeString(name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,20 +9,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/metadata_utility.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/metadata_utility.h"
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/tenant_schema_metadata.h"
|
#include "distributed/tenant_schema_metadata.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* local function forward declarations */
|
/* local function forward declarations */
|
||||||
|
|
|
@ -12,32 +12,35 @@
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "citus_version.h"
|
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/pg_depend.h"
|
#include "catalog/pg_depend.h"
|
||||||
#include "catalog/pg_extension_d.h"
|
#include "catalog/pg_extension_d.h"
|
||||||
#include "columnar/columnar.h"
|
|
||||||
#include "catalog/pg_foreign_data_wrapper.h"
|
#include "catalog/pg_foreign_data_wrapper.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
|
#include "foreign/foreign.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "citus_version.h"
|
||||||
|
|
||||||
|
#include "columnar/columnar.h"
|
||||||
|
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/dependency.h"
|
#include "distributed/metadata/dependency.h"
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "distributed/transaction_management.h"
|
#include "distributed/transaction_management.h"
|
||||||
#include "foreign/foreign.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/fmgroids.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Local functions forward declarations for helper functions */
|
/* Local functions forward declarations for helper functions */
|
||||||
|
@ -271,7 +274,7 @@ PreprocessDropExtensionStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
/* unmark each distributed extension */
|
/* unmark each distributed extension */
|
||||||
ObjectAddress *address = NULL;
|
ObjectAddress *address = NULL;
|
||||||
foreach_ptr(address, distributedExtensionAddresses)
|
foreach_declared_ptr(address, distributedExtensionAddresses)
|
||||||
{
|
{
|
||||||
UnmarkObjectDistributed(address);
|
UnmarkObjectDistributed(address);
|
||||||
}
|
}
|
||||||
|
@ -310,7 +313,7 @@ FilterDistributedExtensions(List *extensionObjectList)
|
||||||
List *extensionNameList = NIL;
|
List *extensionNameList = NIL;
|
||||||
|
|
||||||
String *objectName = NULL;
|
String *objectName = NULL;
|
||||||
foreach_ptr(objectName, extensionObjectList)
|
foreach_declared_ptr(objectName, extensionObjectList)
|
||||||
{
|
{
|
||||||
const char *extensionName = strVal(objectName);
|
const char *extensionName = strVal(objectName);
|
||||||
const bool missingOk = true;
|
const bool missingOk = true;
|
||||||
|
@ -348,7 +351,7 @@ ExtensionNameListToObjectAddressList(List *extensionObjectList)
|
||||||
List *extensionObjectAddressList = NIL;
|
List *extensionObjectAddressList = NIL;
|
||||||
|
|
||||||
String *objectName;
|
String *objectName;
|
||||||
foreach_ptr(objectName, extensionObjectList)
|
foreach_declared_ptr(objectName, extensionObjectList)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We set missingOk to false as we assume all the objects in
|
* We set missingOk to false as we assume all the objects in
|
||||||
|
@ -524,7 +527,7 @@ MarkExistingObjectDependenciesDistributedIfSupported()
|
||||||
List *citusTableIdList = CitusTableTypeIdList(ANY_CITUS_TABLE_TYPE);
|
List *citusTableIdList = CitusTableTypeIdList(ANY_CITUS_TABLE_TYPE);
|
||||||
|
|
||||||
Oid citusTableId = InvalidOid;
|
Oid citusTableId = InvalidOid;
|
||||||
foreach_oid(citusTableId, citusTableIdList)
|
foreach_declared_oid(citusTableId, citusTableIdList)
|
||||||
{
|
{
|
||||||
if (!ShouldMarkRelationDistributed(citusTableId))
|
if (!ShouldMarkRelationDistributed(citusTableId))
|
||||||
{
|
{
|
||||||
|
@ -568,7 +571,7 @@ MarkExistingObjectDependenciesDistributedIfSupported()
|
||||||
*/
|
*/
|
||||||
List *viewList = GetAllViews();
|
List *viewList = GetAllViews();
|
||||||
Oid viewOid = InvalidOid;
|
Oid viewOid = InvalidOid;
|
||||||
foreach_oid(viewOid, viewList)
|
foreach_declared_oid(viewOid, viewList)
|
||||||
{
|
{
|
||||||
if (!ShouldMarkRelationDistributed(viewOid))
|
if (!ShouldMarkRelationDistributed(viewOid))
|
||||||
{
|
{
|
||||||
|
@ -602,7 +605,7 @@ MarkExistingObjectDependenciesDistributedIfSupported()
|
||||||
List *distributedObjectAddressList = GetDistributedObjectAddressList();
|
List *distributedObjectAddressList = GetDistributedObjectAddressList();
|
||||||
|
|
||||||
ObjectAddress *distributedObjectAddress = NULL;
|
ObjectAddress *distributedObjectAddress = NULL;
|
||||||
foreach_ptr(distributedObjectAddress, distributedObjectAddressList)
|
foreach_declared_ptr(distributedObjectAddress, distributedObjectAddressList)
|
||||||
{
|
{
|
||||||
List *distributableDependencyObjectAddresses =
|
List *distributableDependencyObjectAddresses =
|
||||||
GetDistributableDependenciesForObject(distributedObjectAddress);
|
GetDistributableDependenciesForObject(distributedObjectAddress);
|
||||||
|
@ -624,7 +627,7 @@ MarkExistingObjectDependenciesDistributedIfSupported()
|
||||||
SetLocalEnableMetadataSync(false);
|
SetLocalEnableMetadataSync(false);
|
||||||
|
|
||||||
ObjectAddress *objectAddress = NULL;
|
ObjectAddress *objectAddress = NULL;
|
||||||
foreach_ptr(objectAddress, uniqueObjectAddresses)
|
foreach_declared_ptr(objectAddress, uniqueObjectAddresses)
|
||||||
{
|
{
|
||||||
MarkObjectDistributed(objectAddress);
|
MarkObjectDistributed(objectAddress);
|
||||||
}
|
}
|
||||||
|
@ -773,7 +776,7 @@ PreprocessCreateExtensionStmtForCitusColumnar(Node *parsetree)
|
||||||
/*create extension citus version xxx*/
|
/*create extension citus version xxx*/
|
||||||
if (newVersionValue)
|
if (newVersionValue)
|
||||||
{
|
{
|
||||||
char *newVersion = strdup(defGetString(newVersionValue));
|
char *newVersion = pstrdup(defGetString(newVersionValue));
|
||||||
versionNumber = GetExtensionVersionNumber(newVersion);
|
versionNumber = GetExtensionVersionNumber(newVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +796,7 @@ PreprocessCreateExtensionStmtForCitusColumnar(Node *parsetree)
|
||||||
Oid citusOid = get_extension_oid("citus", true);
|
Oid citusOid = get_extension_oid("citus", true);
|
||||||
if (citusOid != InvalidOid)
|
if (citusOid != InvalidOid)
|
||||||
{
|
{
|
||||||
char *curCitusVersion = strdup(get_extension_version(citusOid));
|
char *curCitusVersion = pstrdup(get_extension_version(citusOid));
|
||||||
int curCitusVersionNum = GetExtensionVersionNumber(curCitusVersion);
|
int curCitusVersionNum = GetExtensionVersionNumber(curCitusVersion);
|
||||||
if (curCitusVersionNum < 1110)
|
if (curCitusVersionNum < 1110)
|
||||||
{
|
{
|
||||||
|
@ -828,7 +831,7 @@ IsDropCitusExtensionStmt(Node *parseTree)
|
||||||
|
|
||||||
/* now that we have a DropStmt, check if citus extension is among the objects to dropped */
|
/* now that we have a DropStmt, check if citus extension is among the objects to dropped */
|
||||||
String *objectName;
|
String *objectName;
|
||||||
foreach_ptr(objectName, dropStmt->objects)
|
foreach_declared_ptr(objectName, dropStmt->objects)
|
||||||
{
|
{
|
||||||
const char *extensionName = strVal(objectName);
|
const char *extensionName = strVal(objectName);
|
||||||
|
|
||||||
|
@ -888,7 +891,7 @@ PreprocessAlterExtensionCitusStmtForCitusColumnar(Node *parseTree)
|
||||||
if (newVersionValue)
|
if (newVersionValue)
|
||||||
{
|
{
|
||||||
char *newVersion = defGetString(newVersionValue);
|
char *newVersion = defGetString(newVersionValue);
|
||||||
double newVersionNumber = GetExtensionVersionNumber(strdup(newVersion));
|
double newVersionNumber = GetExtensionVersionNumber(pstrdup(newVersion));
|
||||||
|
|
||||||
/*alter extension citus update to version >= 11.1-1, and no citus_columnar installed */
|
/*alter extension citus update to version >= 11.1-1, and no citus_columnar installed */
|
||||||
if (newVersionNumber >= 1110 && citusColumnarOid == InvalidOid)
|
if (newVersionNumber >= 1110 && citusColumnarOid == InvalidOid)
|
||||||
|
@ -932,7 +935,7 @@ PostprocessAlterExtensionCitusStmtForCitusColumnar(Node *parseTree)
|
||||||
if (newVersionValue)
|
if (newVersionValue)
|
||||||
{
|
{
|
||||||
char *newVersion = defGetString(newVersionValue);
|
char *newVersion = defGetString(newVersionValue);
|
||||||
double newVersionNumber = GetExtensionVersionNumber(strdup(newVersion));
|
double newVersionNumber = GetExtensionVersionNumber(pstrdup(newVersion));
|
||||||
if (newVersionNumber >= 1110 && citusColumnarOid != InvalidOid)
|
if (newVersionNumber >= 1110 && citusColumnarOid != InvalidOid)
|
||||||
{
|
{
|
||||||
/*upgrade citus, after "ALTER EXTENSION citus update to xxx" updates citus_columnar Y to version Z. */
|
/*upgrade citus, after "ALTER EXTENSION citus update to xxx" updates citus_columnar Y to version Z. */
|
||||||
|
@ -1058,7 +1061,7 @@ GenerateGrantCommandsOnExtensionDependentFDWs(Oid extensionId)
|
||||||
List *FDWOids = GetDependentFDWsToExtension(extensionId);
|
List *FDWOids = GetDependentFDWsToExtension(extensionId);
|
||||||
|
|
||||||
Oid FDWOid = InvalidOid;
|
Oid FDWOid = InvalidOid;
|
||||||
foreach_oid(FDWOid, FDWOids)
|
foreach_declared_oid(FDWOid, FDWOids)
|
||||||
{
|
{
|
||||||
Acl *aclEntry = GetPrivilegesForFDW(FDWOid);
|
Acl *aclEntry = GetPrivilegesForFDW(FDWOid);
|
||||||
|
|
||||||
|
@ -1090,33 +1093,26 @@ List *
|
||||||
GetDependentFDWsToExtension(Oid extensionId)
|
GetDependentFDWsToExtension(Oid extensionId)
|
||||||
{
|
{
|
||||||
List *extensionFDWs = NIL;
|
List *extensionFDWs = NIL;
|
||||||
ScanKeyData key[3];
|
ScanKeyData key[1];
|
||||||
int scanKeyCount = 3;
|
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
|
|
||||||
Relation pgDepend = table_open(DependRelationId, AccessShareLock);
|
Relation pgDepend = table_open(DependRelationId, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyInit(&key[0],
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_depend_refclassid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(ExtensionRelationId));
|
|
||||||
ScanKeyInit(&key[1],
|
|
||||||
Anum_pg_depend_refobjid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(extensionId));
|
|
||||||
ScanKeyInit(&key[2],
|
|
||||||
Anum_pg_depend_classid,
|
Anum_pg_depend_classid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(ForeignDataWrapperRelationId));
|
ObjectIdGetDatum(ForeignDataWrapperRelationId));
|
||||||
|
|
||||||
SysScanDesc scan = systable_beginscan(pgDepend, InvalidOid, false,
|
SysScanDesc scan = systable_beginscan(pgDepend, DependDependerIndexId, true,
|
||||||
NULL, scanKeyCount, key);
|
NULL, lengthof(key), key);
|
||||||
|
|
||||||
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||||
{
|
{
|
||||||
Form_pg_depend pgDependEntry = (Form_pg_depend) GETSTRUCT(tup);
|
Form_pg_depend pgDependEntry = (Form_pg_depend) GETSTRUCT(tup);
|
||||||
|
|
||||||
if (pgDependEntry->deptype == DEPENDENCY_EXTENSION)
|
if (pgDependEntry->deptype == DEPENDENCY_EXTENSION &&
|
||||||
|
pgDependEntry->refclassid == ExtensionRelationId &&
|
||||||
|
pgDependEntry->refobjid == extensionId)
|
||||||
{
|
{
|
||||||
extensionFDWs = lappend_oid(extensionFDWs, pgDependEntry->objid);
|
extensionFDWs = lappend_oid(extensionFDWs, pgDependEntry->objid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,27 +12,16 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
|
#include "access/genam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/sysattr.h"
|
#include "access/sysattr.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "access/genam.h"
|
#include "catalog/pg_depend.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "distributed/colocation_utils.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/commands/sequence.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/multi_join_order.h"
|
|
||||||
#include "distributed/namespace_utils.h"
|
|
||||||
#include "distributed/reference_table_utils.h"
|
|
||||||
#include "distributed/utils/array_type.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/inval.h"
|
#include "utils/inval.h"
|
||||||
|
@ -42,6 +31,20 @@
|
||||||
#include "utils/ruleutils.h"
|
#include "utils/ruleutils.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/colocation_utils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/sequence.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/hash_helpers.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/multi_join_order.h"
|
||||||
|
#include "distributed/namespace_utils.h"
|
||||||
|
#include "distributed/reference_table_utils.h"
|
||||||
|
#include "distributed/utils/array_type.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
|
||||||
|
|
||||||
#define BehaviorIsRestrictOrNoAction(x) \
|
#define BehaviorIsRestrictOrNoAction(x) \
|
||||||
((x) == FKCONSTR_ACTION_NOACTION || (x) == FKCONSTR_ACTION_RESTRICT)
|
((x) == FKCONSTR_ACTION_NOACTION || (x) == FKCONSTR_ACTION_RESTRICT)
|
||||||
|
@ -199,7 +202,7 @@ ErrorIfUnsupportedForeignConstraintExists(Relation relation, char referencingDis
|
||||||
List *foreignKeyOids = GetForeignKeyOids(referencingTableId, flags);
|
List *foreignKeyOids = GetForeignKeyOids(referencingTableId, flags);
|
||||||
|
|
||||||
Oid foreignKeyOid = InvalidOid;
|
Oid foreignKeyOid = InvalidOid;
|
||||||
foreach_oid(foreignKeyOid, foreignKeyOids)
|
foreach_declared_oid(foreignKeyOid, foreignKeyOids)
|
||||||
{
|
{
|
||||||
HeapTuple heapTuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(foreignKeyOid));
|
HeapTuple heapTuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(foreignKeyOid));
|
||||||
|
|
||||||
|
@ -411,7 +414,7 @@ ForeignKeySetsNextValColumnToDefault(HeapTuple pgConstraintTuple)
|
||||||
|
|
||||||
List *setDefaultAttrs = ForeignKeyGetDefaultingAttrs(pgConstraintTuple);
|
List *setDefaultAttrs = ForeignKeyGetDefaultingAttrs(pgConstraintTuple);
|
||||||
AttrNumber setDefaultAttr = InvalidAttrNumber;
|
AttrNumber setDefaultAttr = InvalidAttrNumber;
|
||||||
foreach_int(setDefaultAttr, setDefaultAttrs)
|
foreach_declared_int(setDefaultAttr, setDefaultAttrs)
|
||||||
{
|
{
|
||||||
if (ColumnDefaultsToNextVal(pgConstraintForm->conrelid, setDefaultAttr))
|
if (ColumnDefaultsToNextVal(pgConstraintForm->conrelid, setDefaultAttr))
|
||||||
{
|
{
|
||||||
|
@ -464,7 +467,6 @@ ForeignKeyGetDefaultingAttrs(HeapTuple pgConstraintTuple)
|
||||||
}
|
}
|
||||||
|
|
||||||
List *onDeleteSetDefColumnList = NIL;
|
List *onDeleteSetDefColumnList = NIL;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
Datum onDeleteSetDefColumnsDatum = SysCacheGetAttr(CONSTROID, pgConstraintTuple,
|
Datum onDeleteSetDefColumnsDatum = SysCacheGetAttr(CONSTROID, pgConstraintTuple,
|
||||||
Anum_pg_constraint_confdelsetcols,
|
Anum_pg_constraint_confdelsetcols,
|
||||||
&isNull);
|
&isNull);
|
||||||
|
@ -479,7 +481,6 @@ ForeignKeyGetDefaultingAttrs(HeapTuple pgConstraintTuple)
|
||||||
onDeleteSetDefColumnList =
|
onDeleteSetDefColumnList =
|
||||||
IntegerArrayTypeToList(DatumGetArrayTypeP(onDeleteSetDefColumnsDatum));
|
IntegerArrayTypeToList(DatumGetArrayTypeP(onDeleteSetDefColumnsDatum));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (list_length(onDeleteSetDefColumnList) == 0)
|
if (list_length(onDeleteSetDefColumnList) == 0)
|
||||||
{
|
{
|
||||||
|
@ -724,7 +725,7 @@ ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid relationId)
|
||||||
GetForeignKeyIdsForColumn(columnName, relationId, searchForeignKeyColumnFlags);
|
GetForeignKeyIdsForColumn(columnName, relationId, searchForeignKeyColumnFlags);
|
||||||
|
|
||||||
Oid foreignKeyId = InvalidOid;
|
Oid foreignKeyId = InvalidOid;
|
||||||
foreach_oid(foreignKeyId, foreignKeyIdsColumnAppeared)
|
foreach_declared_oid(foreignKeyId, foreignKeyIdsColumnAppeared)
|
||||||
{
|
{
|
||||||
Oid referencedTableId = GetReferencedTableId(foreignKeyId);
|
Oid referencedTableId = GetReferencedTableId(foreignKeyId);
|
||||||
if (IsCitusTableType(referencedTableId, REFERENCE_TABLE))
|
if (IsCitusTableType(referencedTableId, REFERENCE_TABLE))
|
||||||
|
@ -898,7 +899,7 @@ GetForeignConstraintCommandsInternal(Oid relationId, int flags)
|
||||||
int saveNestLevel = PushEmptySearchPath();
|
int saveNestLevel = PushEmptySearchPath();
|
||||||
|
|
||||||
Oid foreignKeyOid = InvalidOid;
|
Oid foreignKeyOid = InvalidOid;
|
||||||
foreach_oid(foreignKeyOid, foreignKeyOids)
|
foreach_declared_oid(foreignKeyOid, foreignKeyOids)
|
||||||
{
|
{
|
||||||
char *statementDef = pg_get_constraintdef_command(foreignKeyOid);
|
char *statementDef = pg_get_constraintdef_command(foreignKeyOid);
|
||||||
|
|
||||||
|
@ -1154,7 +1155,7 @@ static Oid
|
||||||
FindForeignKeyOidWithName(List *foreignKeyOids, const char *inputConstraintName)
|
FindForeignKeyOidWithName(List *foreignKeyOids, const char *inputConstraintName)
|
||||||
{
|
{
|
||||||
Oid foreignKeyOid = InvalidOid;
|
Oid foreignKeyOid = InvalidOid;
|
||||||
foreach_oid(foreignKeyOid, foreignKeyOids)
|
foreach_declared_oid(foreignKeyOid, foreignKeyOids)
|
||||||
{
|
{
|
||||||
char *constraintName = get_constraint_name(foreignKeyOid);
|
char *constraintName = get_constraint_name(foreignKeyOid);
|
||||||
|
|
||||||
|
@ -1197,6 +1198,114 @@ TableHasExternalForeignKeys(Oid relationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ForeignConstraintMatchesFlags is a function with logic that's very specific
|
||||||
|
* to GetForeignKeyOids. There's no reason to use it in any other context.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
ForeignConstraintMatchesFlags(Form_pg_constraint constraintForm,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
if (constraintForm->contype != CONSTRAINT_FOREIGN)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inheritedConstraint = OidIsValid(constraintForm->conparentid);
|
||||||
|
if (inheritedConstraint)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We only consider the constraints that are explicitly created on
|
||||||
|
* the table as we already process the constraints from parent tables
|
||||||
|
* implicitly when a command is issued
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool excludeSelfReference = (flags & EXCLUDE_SELF_REFERENCES);
|
||||||
|
bool isSelfReference = (constraintForm->conrelid == constraintForm->confrelid);
|
||||||
|
if (excludeSelfReference && isSelfReference)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Oid otherTableId = InvalidOid;
|
||||||
|
if (flags & INCLUDE_REFERENCING_CONSTRAINTS)
|
||||||
|
{
|
||||||
|
otherTableId = constraintForm->confrelid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
otherTableId = constraintForm->conrelid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsTableTypeIncluded(otherTableId, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetForeignKeyOidsForReferencedTable returns a list of foreign key OIDs that
|
||||||
|
* reference the relationId and match the given flags.
|
||||||
|
*
|
||||||
|
* This is separated from GetForeignKeyOids because we need to scan pg_depend
|
||||||
|
* instead of pg_constraint directly. The reason for this is that there is no
|
||||||
|
* index on the confrelid of pg_constraint, so searching by that column
|
||||||
|
* requires a seqscan.
|
||||||
|
*/
|
||||||
|
static List *
|
||||||
|
GetForeignKeyOidsForReferencedTable(Oid relationId, int flags)
|
||||||
|
{
|
||||||
|
HTAB *foreignKeyOidsSet = CreateSimpleHashSetWithName(
|
||||||
|
Oid, "ReferencingForeignKeyOidsSet");
|
||||||
|
List *foreignKeyOidsList = NIL;
|
||||||
|
ScanKeyData key[2];
|
||||||
|
HeapTuple dependTup;
|
||||||
|
Relation depRel = table_open(DependRelationId, AccessShareLock);
|
||||||
|
|
||||||
|
ScanKeyInit(&key[0],
|
||||||
|
Anum_pg_depend_refclassid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(RelationRelationId));
|
||||||
|
ScanKeyInit(&key[1],
|
||||||
|
Anum_pg_depend_refobjid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(relationId));
|
||||||
|
SysScanDesc scan = systable_beginscan(depRel, DependReferenceIndexId, true,
|
||||||
|
NULL, lengthof(key), key);
|
||||||
|
while (HeapTupleIsValid(dependTup = systable_getnext(scan)))
|
||||||
|
{
|
||||||
|
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(dependTup);
|
||||||
|
|
||||||
|
if (deprec->classid != ConstraintRelationId ||
|
||||||
|
deprec->deptype != DEPENDENCY_NORMAL ||
|
||||||
|
hash_search(foreignKeyOidsSet, &deprec->objid, HASH_FIND, NULL))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HeapTuple constraintTup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(
|
||||||
|
deprec->objid));
|
||||||
|
if (!HeapTupleIsValid(constraintTup)) /* can happen during DROP TABLE */
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(constraintTup);
|
||||||
|
if (constraint->confrelid == relationId &&
|
||||||
|
ForeignConstraintMatchesFlags(constraint, flags))
|
||||||
|
{
|
||||||
|
foreignKeyOidsList = lappend_oid(foreignKeyOidsList, constraint->oid);
|
||||||
|
hash_search(foreignKeyOidsSet, &constraint->oid, HASH_ENTER, NULL);
|
||||||
|
}
|
||||||
|
ReleaseSysCache(constraintTup);
|
||||||
|
}
|
||||||
|
systable_endscan(scan);
|
||||||
|
table_close(depRel, AccessShareLock);
|
||||||
|
return foreignKeyOidsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetForeignKeyOids takes in a relationId, and returns a list of OIDs for
|
* GetForeignKeyOids takes in a relationId, and returns a list of OIDs for
|
||||||
* foreign constraints that the relation with relationId is involved according
|
* foreign constraints that the relation with relationId is involved according
|
||||||
|
@ -1206,9 +1315,8 @@ TableHasExternalForeignKeys(Oid relationId)
|
||||||
List *
|
List *
|
||||||
GetForeignKeyOids(Oid relationId, int flags)
|
GetForeignKeyOids(Oid relationId, int flags)
|
||||||
{
|
{
|
||||||
AttrNumber pgConstraintTargetAttrNumber = InvalidAttrNumber;
|
bool extractReferencing PG_USED_FOR_ASSERTS_ONLY = (flags &
|
||||||
|
INCLUDE_REFERENCING_CONSTRAINTS);
|
||||||
bool extractReferencing = (flags & INCLUDE_REFERENCING_CONSTRAINTS);
|
|
||||||
bool extractReferenced = (flags & INCLUDE_REFERENCED_CONSTRAINTS);
|
bool extractReferenced = (flags & INCLUDE_REFERENCED_CONSTRAINTS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1219,22 +1327,10 @@ GetForeignKeyOids(Oid relationId, int flags)
|
||||||
Assert(!(extractReferencing && extractReferenced));
|
Assert(!(extractReferencing && extractReferenced));
|
||||||
Assert(extractReferencing || extractReferenced);
|
Assert(extractReferencing || extractReferenced);
|
||||||
|
|
||||||
bool useIndex = false;
|
if (extractReferenced)
|
||||||
Oid indexOid = InvalidOid;
|
|
||||||
|
|
||||||
if (extractReferencing)
|
|
||||||
{
|
{
|
||||||
pgConstraintTargetAttrNumber = Anum_pg_constraint_conrelid;
|
return GetForeignKeyOidsForReferencedTable(relationId, flags);
|
||||||
|
|
||||||
useIndex = true;
|
|
||||||
indexOid = ConstraintRelidTypidNameIndexId;
|
|
||||||
}
|
}
|
||||||
else if (extractReferenced)
|
|
||||||
{
|
|
||||||
pgConstraintTargetAttrNumber = Anum_pg_constraint_confrelid;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool excludeSelfReference = (flags & EXCLUDE_SELF_REFERENCES);
|
|
||||||
|
|
||||||
List *foreignKeyOids = NIL;
|
List *foreignKeyOids = NIL;
|
||||||
|
|
||||||
|
@ -1242,62 +1338,22 @@ GetForeignKeyOids(Oid relationId, int flags)
|
||||||
int scanKeyCount = 1;
|
int scanKeyCount = 1;
|
||||||
|
|
||||||
Relation pgConstraint = table_open(ConstraintRelationId, AccessShareLock);
|
Relation pgConstraint = table_open(ConstraintRelationId, AccessShareLock);
|
||||||
ScanKeyInit(&scanKey[0], pgConstraintTargetAttrNumber,
|
ScanKeyInit(&scanKey[0], Anum_pg_constraint_conrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relationId));
|
BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relationId));
|
||||||
SysScanDesc scanDescriptor = systable_beginscan(pgConstraint, indexOid, useIndex,
|
|
||||||
|
SysScanDesc scanDescriptor = systable_beginscan(pgConstraint,
|
||||||
|
ConstraintRelidTypidNameIndexId, true,
|
||||||
NULL, scanKeyCount, scanKey);
|
NULL, scanKeyCount, scanKey);
|
||||||
|
|
||||||
HeapTuple heapTuple = systable_getnext(scanDescriptor);
|
HeapTuple heapTuple;
|
||||||
while (HeapTupleIsValid(heapTuple))
|
while (HeapTupleIsValid(heapTuple = systable_getnext(scanDescriptor)))
|
||||||
{
|
{
|
||||||
Form_pg_constraint constraintForm = (Form_pg_constraint) GETSTRUCT(heapTuple);
|
Form_pg_constraint constraintForm = (Form_pg_constraint) GETSTRUCT(heapTuple);
|
||||||
|
|
||||||
if (constraintForm->contype != CONSTRAINT_FOREIGN)
|
if (ForeignConstraintMatchesFlags(constraintForm, flags))
|
||||||
{
|
{
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
foreignKeyOids = lappend_oid(foreignKeyOids, constraintForm->oid);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inheritedConstraint = OidIsValid(constraintForm->conparentid);
|
|
||||||
if (inheritedConstraint)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We only consider the constraints that are explicitly created on
|
|
||||||
* the table as we already process the constraints from parent tables
|
|
||||||
* implicitly when a command is issued
|
|
||||||
*/
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Oid constraintId = constraintForm->oid;
|
|
||||||
|
|
||||||
bool isSelfReference = (constraintForm->conrelid == constraintForm->confrelid);
|
|
||||||
if (excludeSelfReference && isSelfReference)
|
|
||||||
{
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Oid otherTableId = InvalidOid;
|
|
||||||
if (extractReferencing)
|
|
||||||
{
|
|
||||||
otherTableId = constraintForm->confrelid;
|
|
||||||
}
|
|
||||||
else if (extractReferenced)
|
|
||||||
{
|
|
||||||
otherTableId = constraintForm->conrelid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsTableTypeIncluded(otherTableId, flags))
|
|
||||||
{
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreignKeyOids = lappend_oid(foreignKeyOids, constraintId);
|
|
||||||
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
systable_endscan(scanDescriptor);
|
systable_endscan(scanDescriptor);
|
||||||
|
@ -1414,7 +1470,7 @@ RelationInvolvedInAnyNonInheritedForeignKeys(Oid relationId)
|
||||||
List *foreignKeysRelationInvolved = list_concat(referencingForeignKeys,
|
List *foreignKeysRelationInvolved = list_concat(referencingForeignKeys,
|
||||||
referencedForeignKeys);
|
referencedForeignKeys);
|
||||||
Oid foreignKeyId = InvalidOid;
|
Oid foreignKeyId = InvalidOid;
|
||||||
foreach_oid(foreignKeyId, foreignKeysRelationInvolved)
|
foreach_declared_oid(foreignKeyId, foreignKeysRelationInvolved)
|
||||||
{
|
{
|
||||||
HeapTuple heapTuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(foreignKeyId));
|
HeapTuple heapTuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(foreignKeyId));
|
||||||
if (!HeapTupleIsValid(heapTuple))
|
if (!HeapTupleIsValid(heapTuple))
|
||||||
|
|
|
@ -11,17 +11,18 @@
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "catalog/pg_foreign_data_wrapper.h"
|
#include "catalog/pg_foreign_data_wrapper.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "foreign/foreign.h"
|
#include "foreign/foreign.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
|
||||||
static bool NameListHasFDWOwnedByDistributedExtension(List *FDWNames);
|
static bool NameListHasFDWOwnedByDistributedExtension(List *FDWNames);
|
||||||
static ObjectAddress GetObjectAddressByFDWName(char *FDWName, bool missing_ok);
|
static ObjectAddress GetObjectAddressByFDWName(char *FDWName, bool missing_ok);
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ static bool
|
||||||
NameListHasFDWOwnedByDistributedExtension(List *FDWNames)
|
NameListHasFDWOwnedByDistributedExtension(List *FDWNames)
|
||||||
{
|
{
|
||||||
String *FDWValue = NULL;
|
String *FDWValue = NULL;
|
||||||
foreach_ptr(FDWValue, FDWNames)
|
foreach_declared_ptr(FDWValue, FDWNames)
|
||||||
{
|
{
|
||||||
/* captures the extension address during lookup */
|
/* captures the extension address during lookup */
|
||||||
ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress));
|
ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress));
|
||||||
|
|
|
@ -9,11 +9,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "catalog/pg_foreign_server.h"
|
#include "catalog/pg_foreign_server.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "foreign/foreign.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "nodes/primnodes.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/log_utils.h"
|
#include "distributed/log_utils.h"
|
||||||
|
@ -21,11 +28,6 @@
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "foreign/foreign.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
|
||||||
#include "nodes/parsenodes.h"
|
|
||||||
#include "nodes/primnodes.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
|
|
||||||
static char * GetForeignServerAlterOwnerCommand(Oid serverId);
|
static char * GetForeignServerAlterOwnerCommand(Oid serverId);
|
||||||
static Node * RecreateForeignServerStmt(Oid serverId);
|
static Node * RecreateForeignServerStmt(Oid serverId);
|
||||||
|
@ -227,7 +229,7 @@ RecreateForeignServerStmt(Oid serverId)
|
||||||
|
|
||||||
int location = -1;
|
int location = -1;
|
||||||
DefElem *option = NULL;
|
DefElem *option = NULL;
|
||||||
foreach_ptr(option, server->options)
|
foreach_declared_ptr(option, server->options)
|
||||||
{
|
{
|
||||||
DefElem *copyOption = makeDefElem(option->defname, option->arg, location);
|
DefElem *copyOption = makeDefElem(option->defname, option->arg, location);
|
||||||
createStmt->options = lappend(createStmt->options, copyOption);
|
createStmt->options = lappend(createStmt->options, copyOption);
|
||||||
|
@ -245,7 +247,7 @@ static bool
|
||||||
NameListHasDistributedServer(List *serverNames)
|
NameListHasDistributedServer(List *serverNames)
|
||||||
{
|
{
|
||||||
String *serverValue = NULL;
|
String *serverValue = NULL;
|
||||||
foreach_ptr(serverValue, serverNames)
|
foreach_declared_ptr(serverValue, serverNames)
|
||||||
{
|
{
|
||||||
List *addresses = GetObjectAddressByServerName(strVal(serverValue), false);
|
List *addresses = GetObjectAddressByServerName(strVal(serverValue), false);
|
||||||
|
|
||||||
|
|
|
@ -18,43 +18,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "funcapi.h"
|
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "funcapi.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/pg_aggregate.h"
|
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
|
#include "catalog/pg_aggregate.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
#include "distributed/citus_depended_object.h"
|
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/citus_safe_lib.h"
|
|
||||||
#include "distributed/colocation_utils.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/maintenanced.h"
|
|
||||||
#include "distributed/metadata_utility.h"
|
|
||||||
#include "distributed/metadata/dependency.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/metadata/pg_dist_object.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/namespace_utils.h"
|
|
||||||
#include "distributed/pg_dist_node.h"
|
|
||||||
#include "distributed/reference_table_utils.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/worker_create_or_replace.h"
|
|
||||||
#include "distributed/worker_transaction.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "parser/parse_coerce.h"
|
#include "parser/parse_coerce.h"
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
|
@ -63,8 +39,34 @@
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/fmgrprotos.h"
|
#include "utils/fmgrprotos.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
|
||||||
#include "utils/regproc.h"
|
#include "utils/regproc.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_depended_object.h"
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/citus_safe_lib.h"
|
||||||
|
#include "distributed/colocation_utils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/maintenanced.h"
|
||||||
|
#include "distributed/metadata/dependency.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata/pg_dist_object.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/metadata_utility.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/namespace_utils.h"
|
||||||
|
#include "distributed/pg_dist_node.h"
|
||||||
|
#include "distributed/reference_table_utils.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_create_or_replace.h"
|
||||||
|
#include "distributed/worker_transaction.h"
|
||||||
|
|
||||||
#define DISABLE_LOCAL_CHECK_FUNCTION_BODIES "SET LOCAL check_function_bodies TO off;"
|
#define DISABLE_LOCAL_CHECK_FUNCTION_BODIES "SET LOCAL check_function_bodies TO off;"
|
||||||
#define RESET_CHECK_FUNCTION_BODIES "RESET check_function_bodies;"
|
#define RESET_CHECK_FUNCTION_BODIES "RESET check_function_bodies;"
|
||||||
|
@ -254,7 +256,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
createFunctionSQL, alterFunctionOwnerSQL);
|
createFunctionSQL, alterFunctionOwnerSQL);
|
||||||
List *grantDDLCommands = GrantOnFunctionDDLCommands(funcOid);
|
List *grantDDLCommands = GrantOnFunctionDDLCommands(funcOid);
|
||||||
char *grantOnFunctionSQL = NULL;
|
char *grantOnFunctionSQL = NULL;
|
||||||
foreach_ptr(grantOnFunctionSQL, grantDDLCommands)
|
foreach_declared_ptr(grantOnFunctionSQL, grantDDLCommands)
|
||||||
{
|
{
|
||||||
appendStringInfo(&ddlCommand, ";%s", grantOnFunctionSQL);
|
appendStringInfo(&ddlCommand, ";%s", grantOnFunctionSQL);
|
||||||
}
|
}
|
||||||
|
@ -368,7 +370,7 @@ ErrorIfAnyNodeDoesNotHaveMetadata(void)
|
||||||
ActivePrimaryNonCoordinatorNodeList(ShareLock);
|
ActivePrimaryNonCoordinatorNodeList(ShareLock);
|
||||||
|
|
||||||
WorkerNode *workerNode = NULL;
|
WorkerNode *workerNode = NULL;
|
||||||
foreach_ptr(workerNode, workerNodeList)
|
foreach_declared_ptr(workerNode, workerNodeList)
|
||||||
{
|
{
|
||||||
if (!workerNode->hasMetadata)
|
if (!workerNode->hasMetadata)
|
||||||
{
|
{
|
||||||
|
@ -1475,7 +1477,7 @@ CreateFunctionStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess)
|
||||||
objectWithArgs->objname = stmt->funcname;
|
objectWithArgs->objname = stmt->funcname;
|
||||||
|
|
||||||
FunctionParameter *funcParam = NULL;
|
FunctionParameter *funcParam = NULL;
|
||||||
foreach_ptr(funcParam, stmt->parameters)
|
foreach_declared_ptr(funcParam, stmt->parameters)
|
||||||
{
|
{
|
||||||
if (ShouldAddFunctionSignature(funcParam->mode))
|
if (ShouldAddFunctionSignature(funcParam->mode))
|
||||||
{
|
{
|
||||||
|
@ -1518,7 +1520,7 @@ DefineAggregateStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess
|
||||||
if (stmt->args != NIL)
|
if (stmt->args != NIL)
|
||||||
{
|
{
|
||||||
FunctionParameter *funcParam = NULL;
|
FunctionParameter *funcParam = NULL;
|
||||||
foreach_ptr(funcParam, linitial(stmt->args))
|
foreach_declared_ptr(funcParam, linitial(stmt->args))
|
||||||
{
|
{
|
||||||
objectWithArgs->objargs = lappend(objectWithArgs->objargs,
|
objectWithArgs->objargs = lappend(objectWithArgs->objargs,
|
||||||
funcParam->argType);
|
funcParam->argType);
|
||||||
|
@ -1527,7 +1529,7 @@ DefineAggregateStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DefElem *defItem = NULL;
|
DefElem *defItem = NULL;
|
||||||
foreach_ptr(defItem, stmt->definition)
|
foreach_declared_ptr(defItem, stmt->definition)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If no explicit args are given, pg includes basetype in the signature.
|
* If no explicit args are given, pg includes basetype in the signature.
|
||||||
|
@ -1932,7 +1934,7 @@ static void
|
||||||
ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt)
|
ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt)
|
||||||
{
|
{
|
||||||
DefElem *action = NULL;
|
DefElem *action = NULL;
|
||||||
foreach_ptr(action, stmt->actions)
|
foreach_declared_ptr(action, stmt->actions)
|
||||||
{
|
{
|
||||||
if (strcmp(action->defname, "set") == 0)
|
if (strcmp(action->defname, "set") == 0)
|
||||||
{
|
{
|
||||||
|
@ -2039,7 +2041,7 @@ PreprocessGrantOnFunctionStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
List *grantFunctionList = NIL;
|
List *grantFunctionList = NIL;
|
||||||
ObjectAddress *functionAddress = NULL;
|
ObjectAddress *functionAddress = NULL;
|
||||||
foreach_ptr(functionAddress, distributedFunctions)
|
foreach_declared_ptr(functionAddress, distributedFunctions)
|
||||||
{
|
{
|
||||||
ObjectWithArgs *distFunction = ObjectWithArgsFromOid(
|
ObjectWithArgs *distFunction = ObjectWithArgsFromOid(
|
||||||
functionAddress->objectId);
|
functionAddress->objectId);
|
||||||
|
@ -2082,7 +2084,7 @@ PostprocessGrantOnFunctionStmt(Node *node, const char *queryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress *functionAddress = NULL;
|
ObjectAddress *functionAddress = NULL;
|
||||||
foreach_ptr(functionAddress, distributedFunctions)
|
foreach_declared_ptr(functionAddress, distributedFunctions)
|
||||||
{
|
{
|
||||||
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(functionAddress));
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(functionAddress));
|
||||||
}
|
}
|
||||||
|
@ -2119,7 +2121,7 @@ FilterDistributedFunctions(GrantStmt *grantStmt)
|
||||||
|
|
||||||
/* iterate over all namespace names provided to get their oid's */
|
/* iterate over all namespace names provided to get their oid's */
|
||||||
String *namespaceValue = NULL;
|
String *namespaceValue = NULL;
|
||||||
foreach_ptr(namespaceValue, grantStmt->objects)
|
foreach_declared_ptr(namespaceValue, grantStmt->objects)
|
||||||
{
|
{
|
||||||
char *nspname = strVal(namespaceValue);
|
char *nspname = strVal(namespaceValue);
|
||||||
bool missing_ok = false;
|
bool missing_ok = false;
|
||||||
|
@ -2131,7 +2133,7 @@ FilterDistributedFunctions(GrantStmt *grantStmt)
|
||||||
* iterate over all distributed functions to filter the ones
|
* iterate over all distributed functions to filter the ones
|
||||||
* that belong to one of the namespaces from above
|
* that belong to one of the namespaces from above
|
||||||
*/
|
*/
|
||||||
foreach_ptr(distributedFunction, distributedFunctionList)
|
foreach_declared_ptr(distributedFunction, distributedFunctionList)
|
||||||
{
|
{
|
||||||
Oid namespaceOid = get_func_namespace(distributedFunction->objectId);
|
Oid namespaceOid = get_func_namespace(distributedFunction->objectId);
|
||||||
|
|
||||||
|
@ -2150,7 +2152,7 @@ FilterDistributedFunctions(GrantStmt *grantStmt)
|
||||||
{
|
{
|
||||||
bool missingOk = false;
|
bool missingOk = false;
|
||||||
ObjectWithArgs *objectWithArgs = NULL;
|
ObjectWithArgs *objectWithArgs = NULL;
|
||||||
foreach_ptr(objectWithArgs, grantStmt->objects)
|
foreach_declared_ptr(objectWithArgs, grantStmt->objects)
|
||||||
{
|
{
|
||||||
ObjectAddress *functionAddress = palloc0(sizeof(ObjectAddress));
|
ObjectAddress *functionAddress = palloc0(sizeof(ObjectAddress));
|
||||||
functionAddress->classId = ProcedureRelationId;
|
functionAddress->classId = ProcedureRelationId;
|
||||||
|
|
|
@ -10,15 +10,16 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/version_compat.h"
|
#include "distributed/version_compat.h"
|
||||||
#include "lib/stringinfo.h"
|
|
||||||
#include "nodes/parsenodes.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Local functions forward declarations for helper functions */
|
/* Local functions forward declarations for helper functions */
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
|
@ -18,32 +17,16 @@
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/deparse_shard_query.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/distributed_planner.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/local_executor.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/multi_physical_planner.h"
|
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
|
||||||
#include "distributed/namespace_utils.h"
|
|
||||||
#include "distributed/resource_lock.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/relation_utils.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/worker_manager.h"
|
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "parser/parse_utilcmd.h"
|
#include "parser/parse_utilcmd.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
|
@ -53,6 +36,26 @@
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/deparse_shard_query.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/distributed_planner.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/local_executor.h"
|
||||||
|
#include "distributed/metadata_cache.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
|
#include "distributed/multi_physical_planner.h"
|
||||||
|
#include "distributed/namespace_utils.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/relation_utils.h"
|
||||||
|
#include "distributed/resource_lock.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_manager.h"
|
||||||
|
|
||||||
|
|
||||||
/* Local functions forward declarations for helper functions */
|
/* Local functions forward declarations for helper functions */
|
||||||
static void ErrorIfCreateIndexHasTooManyColumns(IndexStmt *createIndexStatement);
|
static void ErrorIfCreateIndexHasTooManyColumns(IndexStmt *createIndexStatement);
|
||||||
|
@ -331,7 +334,7 @@ ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor pgIndexProcesso
|
||||||
|
|
||||||
List *indexIdList = RelationGetIndexList(relation);
|
List *indexIdList = RelationGetIndexList(relation);
|
||||||
Oid indexId = InvalidOid;
|
Oid indexId = InvalidOid;
|
||||||
foreach_oid(indexId, indexIdList)
|
foreach_declared_oid(indexId, indexIdList)
|
||||||
{
|
{
|
||||||
HeapTuple indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId));
|
HeapTuple indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId));
|
||||||
if (!HeapTupleIsValid(indexTuple))
|
if (!HeapTupleIsValid(indexTuple))
|
||||||
|
@ -700,7 +703,7 @@ PreprocessDropIndexStmt(Node *node, const char *dropIndexCommand,
|
||||||
|
|
||||||
/* check if any of the indexes being dropped belong to a distributed table */
|
/* check if any of the indexes being dropped belong to a distributed table */
|
||||||
List *objectNameList = NULL;
|
List *objectNameList = NULL;
|
||||||
foreach_ptr(objectNameList, dropIndexStatement->objects)
|
foreach_declared_ptr(objectNameList, dropIndexStatement->objects)
|
||||||
{
|
{
|
||||||
struct DropRelationCallbackState state;
|
struct DropRelationCallbackState state;
|
||||||
uint32 rvrFlags = RVR_MISSING_OK;
|
uint32 rvrFlags = RVR_MISSING_OK;
|
||||||
|
@ -871,7 +874,7 @@ ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement)
|
||||||
/* error out if any of the subcommands are unsupported */
|
/* error out if any of the subcommands are unsupported */
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, commandList)
|
foreach_declared_ptr(command, commandList)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -923,7 +926,7 @@ CreateIndexTaskList(IndexStmt *indexStmt)
|
||||||
LockShardListMetadata(shardIntervalList, ShareLock);
|
LockShardListMetadata(shardIntervalList, ShareLock);
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardIntervalList)
|
foreach_declared_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
uint64 shardId = shardInterval->shardId;
|
uint64 shardId = shardInterval->shardId;
|
||||||
|
|
||||||
|
@ -968,7 +971,7 @@ CreateReindexTaskList(Oid relationId, ReindexStmt *reindexStmt)
|
||||||
LockShardListMetadata(shardIntervalList, ShareLock);
|
LockShardListMetadata(shardIntervalList, ShareLock);
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardIntervalList)
|
foreach_declared_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
uint64 shardId = shardInterval->shardId;
|
uint64 shardId = shardInterval->shardId;
|
||||||
|
|
||||||
|
@ -1106,6 +1109,7 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, Oid relId, Oid oldRelI
|
||||||
char relkind;
|
char relkind;
|
||||||
struct ReindexIndexCallbackState *state = arg;
|
struct ReindexIndexCallbackState *state = arg;
|
||||||
LOCKMODE table_lockmode;
|
LOCKMODE table_lockmode;
|
||||||
|
Oid table_oid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lock level here should match table lock in reindex_index() for
|
* Lock level here should match table lock in reindex_index() for
|
||||||
|
@ -1143,13 +1147,24 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, Oid relId, Oid oldRelI
|
||||||
errmsg("\"%s\" is not an index", relation->relname)));
|
errmsg("\"%s\" is not an index", relation->relname)));
|
||||||
|
|
||||||
/* Check permissions */
|
/* Check permissions */
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
|
table_oid = IndexGetRelation(relId, true);
|
||||||
|
if (OidIsValid(table_oid))
|
||||||
|
{
|
||||||
|
AclResult aclresult = pg_class_aclcheck(table_oid, GetUserId(), ACL_MAINTAIN);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, OBJECT_INDEX, relation->relname);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!object_ownercheck(RelationRelationId, relId, GetUserId()))
|
if (!object_ownercheck(RelationRelationId, relId, GetUserId()))
|
||||||
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, relation->relname);
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, relation->relname);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Lock heap before index to avoid deadlock. */
|
/* Lock heap before index to avoid deadlock. */
|
||||||
if (relId != oldRelId)
|
if (relId != oldRelId)
|
||||||
{
|
{
|
||||||
Oid table_oid = IndexGetRelation(relId, true);
|
table_oid = IndexGetRelation(relId, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the OID isn't valid, it means the index was concurrently
|
* If the OID isn't valid, it means the index was concurrently
|
||||||
|
@ -1217,7 +1232,7 @@ ErrorIfUnsupportedIndexStmt(IndexStmt *createIndexStatement)
|
||||||
Var *partitionKey = DistPartitionKeyOrError(relationId);
|
Var *partitionKey = DistPartitionKeyOrError(relationId);
|
||||||
List *indexParameterList = createIndexStatement->indexParams;
|
List *indexParameterList = createIndexStatement->indexParams;
|
||||||
IndexElem *indexElement = NULL;
|
IndexElem *indexElement = NULL;
|
||||||
foreach_ptr(indexElement, indexParameterList)
|
foreach_declared_ptr(indexElement, indexParameterList)
|
||||||
{
|
{
|
||||||
const char *columnName = indexElement->name;
|
const char *columnName = indexElement->name;
|
||||||
|
|
||||||
|
@ -1286,7 +1301,7 @@ DropIndexTaskList(Oid relationId, Oid indexId, DropStmt *dropStmt)
|
||||||
LockShardListMetadata(shardIntervalList, ShareLock);
|
LockShardListMetadata(shardIntervalList, ShareLock);
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardIntervalList)
|
foreach_declared_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
uint64 shardId = shardInterval->shardId;
|
uint64 shardId = shardInterval->shardId;
|
||||||
char *shardIndexName = pstrdup(indexName);
|
char *shardIndexName = pstrdup(indexName);
|
||||||
|
|
|
@ -19,24 +19,27 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
#include "commands/copy.h"
|
|
||||||
#include "catalog/namespace.h"
|
|
||||||
#include "parser/parse_relation.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
|
||||||
#include "safe_lib.h"
|
|
||||||
#include <netinet/in.h> /* for htons */
|
#include <netinet/in.h> /* for htons */
|
||||||
|
|
||||||
#include "distributed/transmit.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "safe_lib.h"
|
||||||
|
|
||||||
|
#include "catalog/namespace.h"
|
||||||
|
#include "commands/copy.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "parser/parse_relation.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
#include "distributed/commands/multi_copy.h"
|
#include "distributed/commands/multi_copy.h"
|
||||||
#include "distributed/intermediate_results.h"
|
#include "distributed/intermediate_results.h"
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
#include "distributed/local_multi_copy.h"
|
#include "distributed/local_multi_copy.h"
|
||||||
#include "distributed/shard_utils.h"
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/replication_origin_session_utils.h"
|
#include "distributed/replication_origin_session_utils.h"
|
||||||
|
#include "distributed/shard_utils.h"
|
||||||
|
#include "distributed/transmit.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
|
||||||
/* managed via GUC, default is 512 kB */
|
/* managed via GUC, default is 512 kB */
|
||||||
int LocalCopyFlushThresholdByte = 512 * 1024;
|
int LocalCopyFlushThresholdByte = 512 * 1024;
|
||||||
|
|
|
@ -43,19 +43,18 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
#include "libpq-fe.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "pgstat.h"
|
|
||||||
|
|
||||||
#include <arpa/inet.h> /* for htons */
|
#include <arpa/inet.h> /* for htons */
|
||||||
#include <netinet/in.h> /* for htons */
|
#include <netinet/in.h> /* for htons */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "libpq-fe.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
|
#include "pgstat.h"
|
||||||
|
|
||||||
#include "access/htup_details.h"
|
|
||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
|
#include "access/htup_details.h"
|
||||||
#include "access/sdir.h"
|
#include "access/sdir.h"
|
||||||
#include "access/sysattr.h"
|
#include "access/sysattr.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
|
@ -65,41 +64,30 @@
|
||||||
#include "commands/copy.h"
|
#include "commands/copy.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/progress.h"
|
#include "commands/progress.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/citus_safe_lib.h"
|
#include "distributed/citus_safe_lib.h"
|
||||||
#include "distributed/commands/multi_copy.h"
|
#include "distributed/commands/multi_copy.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/intermediate_results.h"
|
#include "distributed/intermediate_results.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
|
#include "distributed/locally_reserved_shared_connections.h"
|
||||||
#include "distributed/log_utils.h"
|
#include "distributed/log_utils.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/multi_physical_planner.h"
|
#include "distributed/multi_physical_planner.h"
|
||||||
#include "distributed/multi_router_planner.h"
|
#include "distributed/multi_router_planner.h"
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/locally_reserved_shared_connections.h"
|
|
||||||
#include "distributed/placement_connection.h"
|
#include "distributed/placement_connection.h"
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
#include "distributed/relation_utils.h"
|
#include "distributed/relation_utils.h"
|
||||||
#endif
|
#endif
|
||||||
#include "distributed/remote_commands.h"
|
|
||||||
#include "distributed/remote_transaction.h"
|
|
||||||
#include "distributed/replication_origin_session_utils.h"
|
|
||||||
#include "distributed/resource_lock.h"
|
|
||||||
#include "distributed/shard_pruning.h"
|
|
||||||
#include "distributed/shared_connection_stats.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/worker_protocol.h"
|
|
||||||
#include "distributed/local_multi_copy.h"
|
|
||||||
#include "distributed/hash_helpers.h"
|
|
||||||
#include "distributed/transmit.h"
|
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "foreign/foreign.h"
|
#include "foreign/foreign.h"
|
||||||
|
|
||||||
#include "libpq/libpq.h"
|
#include "libpq/libpq.h"
|
||||||
#include "libpq/pqformat.h"
|
#include "libpq/pqformat.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
|
@ -110,9 +98,21 @@
|
||||||
#include "tsearch/ts_locale.h"
|
#include "tsearch/ts_locale.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "utils/memutils.h"
|
|
||||||
|
#include "distributed/hash_helpers.h"
|
||||||
|
#include "distributed/local_multi_copy.h"
|
||||||
|
#include "distributed/remote_commands.h"
|
||||||
|
#include "distributed/remote_transaction.h"
|
||||||
|
#include "distributed/replication_origin_session_utils.h"
|
||||||
|
#include "distributed/resource_lock.h"
|
||||||
|
#include "distributed/shard_pruning.h"
|
||||||
|
#include "distributed/shared_connection_stats.h"
|
||||||
|
#include "distributed/transmit.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_protocol.h"
|
||||||
|
|
||||||
|
|
||||||
/* constant used in binary protocol */
|
/* constant used in binary protocol */
|
||||||
|
@ -301,6 +301,7 @@ static SelectStmt * CitusCopySelect(CopyStmt *copyStatement);
|
||||||
static void CitusCopyTo(CopyStmt *copyStatement, QueryCompletion *completionTag);
|
static void CitusCopyTo(CopyStmt *copyStatement, QueryCompletion *completionTag);
|
||||||
static int64 ForwardCopyDataFromConnection(CopyOutState copyOutState,
|
static int64 ForwardCopyDataFromConnection(CopyOutState copyOutState,
|
||||||
MultiConnection *connection);
|
MultiConnection *connection);
|
||||||
|
static void ErrorIfCopyHasOnErrorLogVerbosity(CopyStmt *copyStatement);
|
||||||
|
|
||||||
/* Private functions copied and adapted from copy.c in PostgreSQL */
|
/* Private functions copied and adapted from copy.c in PostgreSQL */
|
||||||
static void SendCopyBegin(CopyOutState cstate);
|
static void SendCopyBegin(CopyOutState cstate);
|
||||||
|
@ -346,6 +347,7 @@ static LocalCopyStatus GetLocalCopyStatus(void);
|
||||||
static bool ShardIntervalListHasLocalPlacements(List *shardIntervalList);
|
static bool ShardIntervalListHasLocalPlacements(List *shardIntervalList);
|
||||||
static void LogLocalCopyToRelationExecution(uint64 shardId);
|
static void LogLocalCopyToRelationExecution(uint64 shardId);
|
||||||
static void LogLocalCopyToFileExecution(uint64 shardId);
|
static void LogLocalCopyToFileExecution(uint64 shardId);
|
||||||
|
static void ErrorIfMergeInCopy(CopyStmt *copyStatement);
|
||||||
|
|
||||||
|
|
||||||
/* exports for SQL callable functions */
|
/* exports for SQL callable functions */
|
||||||
|
@ -1957,7 +1959,7 @@ ShardIntervalListHasLocalPlacements(List *shardIntervalList)
|
||||||
{
|
{
|
||||||
int32 localGroupId = GetLocalGroupId();
|
int32 localGroupId = GetLocalGroupId();
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardIntervalList)
|
foreach_declared_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
if (ActiveShardPlacementOnGroup(localGroupId, shardInterval->shardId) != NULL)
|
if (ActiveShardPlacementOnGroup(localGroupId, shardInterval->shardId) != NULL)
|
||||||
{
|
{
|
||||||
|
@ -2452,7 +2454,7 @@ ProcessAppendToShardOption(Oid relationId, CopyStmt *copyStatement)
|
||||||
bool appendToShardSet = false;
|
bool appendToShardSet = false;
|
||||||
|
|
||||||
DefElem *defel = NULL;
|
DefElem *defel = NULL;
|
||||||
foreach_ptr(defel, copyStatement->options)
|
foreach_declared_ptr(defel, copyStatement->options)
|
||||||
{
|
{
|
||||||
if (strncmp(defel->defname, APPEND_TO_SHARD_OPTION, NAMEDATALEN) == 0)
|
if (strncmp(defel->defname, APPEND_TO_SHARD_OPTION, NAMEDATALEN) == 0)
|
||||||
{
|
{
|
||||||
|
@ -2547,12 +2549,8 @@ ShardIdForTuple(CitusCopyDestReceiver *copyDest, Datum *columnValues, bool *colu
|
||||||
|
|
||||||
if (columnNulls[partitionColumnIndex])
|
if (columnNulls[partitionColumnIndex])
|
||||||
{
|
{
|
||||||
Oid relationId = copyDest->distributedRelationId;
|
char *qualifiedTableName = generate_qualified_relation_name(
|
||||||
char *relationName = get_rel_name(relationId);
|
copyDest->distributedRelationId);
|
||||||
Oid schemaOid = get_rel_namespace(relationId);
|
|
||||||
char *schemaName = get_namespace_name(schemaOid);
|
|
||||||
char *qualifiedTableName = quote_qualified_identifier(schemaName,
|
|
||||||
relationName);
|
|
||||||
|
|
||||||
ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||||
errmsg("the partition column of table %s cannot be NULL",
|
errmsg("the partition column of table %s cannot be NULL",
|
||||||
|
@ -2572,7 +2570,7 @@ ShardIdForTuple(CitusCopyDestReceiver *copyDest, Datum *columnValues, bool *colu
|
||||||
* Find the shard interval and id for the partition column value for
|
* Find the shard interval and id for the partition column value for
|
||||||
* non-reference tables.
|
* non-reference tables.
|
||||||
*
|
*
|
||||||
* For reference table, this function blindly returns the tables single
|
* For reference table, and single shard distributed table this function blindly returns the tables single
|
||||||
* shard.
|
* shard.
|
||||||
*/
|
*/
|
||||||
ShardInterval *shardInterval = FindShardInterval(partitionColumnValue, cacheEntry);
|
ShardInterval *shardInterval = FindShardInterval(partitionColumnValue, cacheEntry);
|
||||||
|
@ -2828,6 +2826,70 @@ CopyStatementHasFormat(CopyStmt *copyStatement, char *formatName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorIfCopyHasOnErrorLogVerbosity errors out if the COPY statement
|
||||||
|
* has on_error option or log_verbosity option specified
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ErrorIfCopyHasOnErrorLogVerbosity(CopyStmt *copyStatement)
|
||||||
|
{
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
|
bool log_verbosity = false;
|
||||||
|
foreach_ptr(DefElem, option, copyStatement->options)
|
||||||
|
{
|
||||||
|
if (strcmp(option->defname, "on_error") == 0)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg(
|
||||||
|
"Citus does not support COPY FROM with ON_ERROR option.")));
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "log_verbosity") == 0)
|
||||||
|
{
|
||||||
|
log_verbosity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given that log_verbosity is currently used in COPY FROM
|
||||||
|
* when ON_ERROR option is set to ignore, it makes more
|
||||||
|
* sense to error out for ON_ERROR option first. For this reason,
|
||||||
|
* we don't error out in the previous loop directly.
|
||||||
|
* Relevant PG17 commit: https://github.com/postgres/postgres/commit/f5a227895
|
||||||
|
*/
|
||||||
|
if (log_verbosity)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg(
|
||||||
|
"Citus does not support COPY FROM with LOG_VERBOSITY option.")));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorIfMergeInCopy Raises an exception if the MERGE is called in the COPY
|
||||||
|
* where Citus tables are involved, as we don't support this yet
|
||||||
|
* Relevant PG17 commit: c649fa24a
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ErrorIfMergeInCopy(CopyStmt *copyStatement)
|
||||||
|
{
|
||||||
|
#if PG_VERSION_NUM < 170000
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
if (!copyStatement->relation && (IsA(copyStatement->query, MergeStmt)))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This path is currently not reachable because Merge in COPY can
|
||||||
|
* only work with a RETURNING clause, and a RETURNING check
|
||||||
|
* will error out sooner for Citus
|
||||||
|
*/
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("MERGE with Citus tables "
|
||||||
|
"is not yet supported in COPY")));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProcessCopyStmt handles Citus specific concerns for COPY like supporting
|
* ProcessCopyStmt handles Citus specific concerns for COPY like supporting
|
||||||
* COPYing from distributed tables and preventing unsupported actions. The
|
* COPYing from distributed tables and preventing unsupported actions. The
|
||||||
|
@ -2865,6 +2927,8 @@ ProcessCopyStmt(CopyStmt *copyStatement, QueryCompletion *completionTag, const
|
||||||
*/
|
*/
|
||||||
if (copyStatement->relation != NULL)
|
if (copyStatement->relation != NULL)
|
||||||
{
|
{
|
||||||
|
ErrorIfMergeInCopy(copyStatement);
|
||||||
|
|
||||||
bool isFrom = copyStatement->is_from;
|
bool isFrom = copyStatement->is_from;
|
||||||
|
|
||||||
/* consider using RangeVarGetRelidExtended to check perms before locking */
|
/* consider using RangeVarGetRelidExtended to check perms before locking */
|
||||||
|
@ -2902,6 +2966,8 @@ ProcessCopyStmt(CopyStmt *copyStatement, QueryCompletion *completionTag, const
|
||||||
"Citus does not support COPY FROM with WHERE")));
|
"Citus does not support COPY FROM with WHERE")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorIfCopyHasOnErrorLogVerbosity(copyStatement);
|
||||||
|
|
||||||
/* check permissions, we're bypassing postgres' normal checks */
|
/* check permissions, we're bypassing postgres' normal checks */
|
||||||
CheckCopyPermissions(copyStatement);
|
CheckCopyPermissions(copyStatement);
|
||||||
CitusCopyFrom(copyStatement, completionTag);
|
CitusCopyFrom(copyStatement, completionTag);
|
||||||
|
|
|
@ -10,33 +10,20 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/genam.h"
|
|
||||||
#include "access/table.h"
|
#include "access/table.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/objectaddress.h"
|
||||||
#include "catalog/pg_auth_members.h"
|
#include "catalog/pg_auth_members.h"
|
||||||
#include "catalog/pg_authid.h"
|
#include "catalog/pg_authid.h"
|
||||||
#include "catalog/pg_db_role_setting.h"
|
#include "catalog/pg_db_role_setting.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "catalog/objectaddress.h"
|
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/citus_safe_lib.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/worker_transaction.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
|
@ -44,8 +31,22 @@
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/varlena.h"
|
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
#include "utils/varlena.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/citus_safe_lib.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_transaction.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessDropOwnedStmt finds the distributed role out of the ones
|
* PreprocessDropOwnedStmt finds the distributed role out of the ones
|
||||||
|
|
|
@ -10,15 +10,10 @@
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "commands/policy.h"
|
#include "commands/policy.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "parser/parse_clause.h"
|
#include "parser/parse_clause.h"
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
|
@ -27,6 +22,13 @@
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/ruleutils.h"
|
#include "utils/ruleutils.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata_cache.h"
|
||||||
|
|
||||||
|
|
||||||
static const char * unparse_policy_command(const char aclchar);
|
static const char * unparse_policy_command(const char aclchar);
|
||||||
static RowSecurityPolicy * GetPolicyByName(Oid relationId, const char *policyName);
|
static RowSecurityPolicy * GetPolicyByName(Oid relationId, const char *policyName);
|
||||||
|
@ -46,7 +48,7 @@ CreatePolicyCommands(Oid relationId)
|
||||||
List *policyList = GetPolicyListForRelation(relationId);
|
List *policyList = GetPolicyListForRelation(relationId);
|
||||||
|
|
||||||
RowSecurityPolicy *policy;
|
RowSecurityPolicy *policy;
|
||||||
foreach_ptr(policy, policyList)
|
foreach_declared_ptr(policy, policyList)
|
||||||
{
|
{
|
||||||
char *createPolicyCommand = CreatePolicyCommandForPolicy(relationId, policy);
|
char *createPolicyCommand = CreatePolicyCommandForPolicy(relationId, policy);
|
||||||
commands = lappend(commands, makeTableDDLCommandString(createPolicyCommand));
|
commands = lappend(commands, makeTableDDLCommandString(createPolicyCommand));
|
||||||
|
@ -86,7 +88,7 @@ GetPolicyListForRelation(Oid relationId)
|
||||||
List *policyList = NIL;
|
List *policyList = NIL;
|
||||||
|
|
||||||
RowSecurityPolicy *policy;
|
RowSecurityPolicy *policy;
|
||||||
foreach_ptr(policy, relation->rd_rsdesc->policies)
|
foreach_declared_ptr(policy, relation->rd_rsdesc->policies)
|
||||||
{
|
{
|
||||||
policyList = lappend(policyList, policy);
|
policyList = lappend(policyList, policy);
|
||||||
}
|
}
|
||||||
|
@ -308,7 +310,7 @@ GetPolicyByName(Oid relationId, const char *policyName)
|
||||||
List *policyList = GetPolicyListForRelation(relationId);
|
List *policyList = GetPolicyListForRelation(relationId);
|
||||||
|
|
||||||
RowSecurityPolicy *policy = NULL;
|
RowSecurityPolicy *policy = NULL;
|
||||||
foreach_ptr(policy, policyList)
|
foreach_declared_ptr(policy, policyList)
|
||||||
{
|
{
|
||||||
if (strncmp(policy->policy_name, policyName, NAMEDATALEN) == 0)
|
if (strncmp(policy->policy_name, policyName, NAMEDATALEN) == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,18 +9,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "catalog/pg_publication.h"
|
#include "catalog/pg_publication.h"
|
||||||
#include "catalog/pg_publication_rel.h"
|
#include "catalog/pg_publication_rel.h"
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/metadata_utility.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/reference_table_utils.h"
|
|
||||||
#include "distributed/worker_create_or_replace.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
@ -29,13 +22,20 @@
|
||||||
|
|
||||||
#include "pg_version_compat.h"
|
#include "pg_version_compat.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/metadata_utility.h"
|
||||||
|
#include "distributed/reference_table_utils.h"
|
||||||
|
#include "distributed/worker_create_or_replace.h"
|
||||||
|
|
||||||
|
|
||||||
static CreatePublicationStmt * BuildCreatePublicationStmt(Oid publicationId);
|
static CreatePublicationStmt * BuildCreatePublicationStmt(Oid publicationId);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static PublicationObjSpec * BuildPublicationRelationObjSpec(Oid relationId,
|
static PublicationObjSpec * BuildPublicationRelationObjSpec(Oid relationId,
|
||||||
Oid publicationId,
|
Oid publicationId,
|
||||||
bool tableOnly);
|
bool tableOnly);
|
||||||
#endif
|
|
||||||
static void AppendPublishOptionList(StringInfo str, List *strings);
|
static void AppendPublishOptionList(StringInfo str, List *strings);
|
||||||
static char * AlterPublicationOwnerCommand(Oid publicationId);
|
static char * AlterPublicationOwnerCommand(Oid publicationId);
|
||||||
static bool ShouldPropagateCreatePublication(CreatePublicationStmt *stmt);
|
static bool ShouldPropagateCreatePublication(CreatePublicationStmt *stmt);
|
||||||
|
@ -152,11 +152,10 @@ BuildCreatePublicationStmt(Oid publicationId)
|
||||||
|
|
||||||
ReleaseSysCache(publicationTuple);
|
ReleaseSysCache(publicationTuple);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
List *schemaIds = GetPublicationSchemas(publicationId);
|
List *schemaIds = GetPublicationSchemas(publicationId);
|
||||||
Oid schemaId = InvalidOid;
|
Oid schemaId = InvalidOid;
|
||||||
|
|
||||||
foreach_oid(schemaId, schemaIds)
|
foreach_declared_oid(schemaId, schemaIds)
|
||||||
{
|
{
|
||||||
char *schemaName = get_namespace_name(schemaId);
|
char *schemaName = get_namespace_name(schemaId);
|
||||||
|
|
||||||
|
@ -168,7 +167,6 @@ BuildCreatePublicationStmt(Oid publicationId)
|
||||||
|
|
||||||
createPubStmt->pubobjects = lappend(createPubStmt->pubobjects, publicationObject);
|
createPubStmt->pubobjects = lappend(createPubStmt->pubobjects, publicationObject);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
List *relationIds = GetPublicationRelations(publicationId,
|
List *relationIds = GetPublicationRelations(publicationId,
|
||||||
publicationForm->pubviaroot ?
|
publicationForm->pubviaroot ?
|
||||||
|
@ -180,9 +178,8 @@ BuildCreatePublicationStmt(Oid publicationId)
|
||||||
/* mainly for consistent ordering in test output */
|
/* mainly for consistent ordering in test output */
|
||||||
relationIds = SortList(relationIds, CompareOids);
|
relationIds = SortList(relationIds, CompareOids);
|
||||||
|
|
||||||
foreach_oid(relationId, relationIds)
|
foreach_declared_oid(relationId, relationIds)
|
||||||
{
|
{
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
bool tableOnly = false;
|
bool tableOnly = false;
|
||||||
|
|
||||||
/* since postgres 15, tables can have a column list and filter */
|
/* since postgres 15, tables can have a column list and filter */
|
||||||
|
@ -190,15 +187,6 @@ BuildCreatePublicationStmt(Oid publicationId)
|
||||||
BuildPublicationRelationObjSpec(relationId, publicationId, tableOnly);
|
BuildPublicationRelationObjSpec(relationId, publicationId, tableOnly);
|
||||||
|
|
||||||
createPubStmt->pubobjects = lappend(createPubStmt->pubobjects, publicationObject);
|
createPubStmt->pubobjects = lappend(createPubStmt->pubobjects, publicationObject);
|
||||||
#else
|
|
||||||
|
|
||||||
/* before postgres 15, only full tables are supported */
|
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(relationId));
|
|
||||||
char *tableName = get_rel_name(relationId);
|
|
||||||
RangeVar *rangeVar = makeRangeVar(schemaName, tableName, -1);
|
|
||||||
|
|
||||||
createPubStmt->tables = lappend(createPubStmt->tables, rangeVar);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (IsCitusTable(relationId))
|
if (IsCitusTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -274,8 +262,6 @@ AppendPublishOptionList(StringInfo str, List *options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BuildPublicationRelationObjSpec returns a PublicationObjSpec that
|
* BuildPublicationRelationObjSpec returns a PublicationObjSpec that
|
||||||
* can be included in a CREATE or ALTER PUBLICATION statement.
|
* can be included in a CREATE or ALTER PUBLICATION statement.
|
||||||
|
@ -355,9 +341,6 @@ BuildPublicationRelationObjSpec(Oid relationId, Oid publicationId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterPublicationStmt handles ALTER PUBLICATION statements
|
* PreprocessAlterPublicationStmt handles ALTER PUBLICATION statements
|
||||||
* in a way that is mostly similar to PreprocessAlterDistributedObjectStmt,
|
* in a way that is mostly similar to PreprocessAlterDistributedObjectStmt,
|
||||||
|
@ -418,7 +401,7 @@ GetAlterPublicationDDLCommandsForTable(Oid relationId, bool isAdd)
|
||||||
List *publicationIds = GetRelationPublications(relationId);
|
List *publicationIds = GetRelationPublications(relationId);
|
||||||
Oid publicationId = InvalidOid;
|
Oid publicationId = InvalidOid;
|
||||||
|
|
||||||
foreach_oid(publicationId, publicationIds)
|
foreach_declared_oid(publicationId, publicationIds)
|
||||||
{
|
{
|
||||||
char *command = GetAlterPublicationTableDDLCommand(publicationId,
|
char *command = GetAlterPublicationTableDDLCommand(publicationId,
|
||||||
relationId, isAdd);
|
relationId, isAdd);
|
||||||
|
@ -456,7 +439,6 @@ GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId,
|
||||||
|
|
||||||
ReleaseSysCache(pubTuple);
|
ReleaseSysCache(pubTuple);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
bool tableOnly = !isAdd;
|
bool tableOnly = !isAdd;
|
||||||
|
|
||||||
/* since postgres 15, tables can have a column list and filter */
|
/* since postgres 15, tables can have a column list and filter */
|
||||||
|
@ -465,16 +447,6 @@ GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId,
|
||||||
|
|
||||||
alterPubStmt->pubobjects = lappend(alterPubStmt->pubobjects, publicationObject);
|
alterPubStmt->pubobjects = lappend(alterPubStmt->pubobjects, publicationObject);
|
||||||
alterPubStmt->action = isAdd ? AP_AddObjects : AP_DropObjects;
|
alterPubStmt->action = isAdd ? AP_AddObjects : AP_DropObjects;
|
||||||
#else
|
|
||||||
|
|
||||||
/* before postgres 15, only full tables are supported */
|
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(relationId));
|
|
||||||
char *tableName = get_rel_name(relationId);
|
|
||||||
RangeVar *rangeVar = makeRangeVar(schemaName, tableName, -1);
|
|
||||||
|
|
||||||
alterPubStmt->tables = lappend(alterPubStmt->tables, rangeVar);
|
|
||||||
alterPubStmt->tableAction = isAdd ? DEFELEM_ADD : DEFELEM_DROP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* we take the WHERE clause from the catalog where it is already transformed */
|
/* we take the WHERE clause from the catalog where it is already transformed */
|
||||||
bool whereClauseNeedsTransform = false;
|
bool whereClauseNeedsTransform = false;
|
||||||
|
|
|
@ -12,11 +12,12 @@
|
||||||
|
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "nodes/parsenodes.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -10,37 +10,21 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "pg_version_compat.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
|
|
||||||
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/genam.h"
|
|
||||||
#include "access/table.h"
|
#include "access/table.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/objectaddress.h"
|
||||||
#include "catalog/pg_auth_members.h"
|
#include "catalog/pg_auth_members.h"
|
||||||
#include "catalog/pg_authid.h"
|
#include "catalog/pg_authid.h"
|
||||||
#include "catalog/pg_db_role_setting.h"
|
#include "catalog/pg_db_role_setting.h"
|
||||||
|
#include "catalog/pg_shseclabel.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "catalog/objectaddress.h"
|
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/citus_safe_lib.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/worker_transaction.h"
|
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
|
@ -48,11 +32,28 @@
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/guc_tables.h"
|
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
|
#include "utils/guc_tables.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/varlena.h"
|
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
#include "utils/varlena.h"
|
||||||
|
|
||||||
|
#include "pg_version_compat.h"
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/citus_safe_lib.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_transaction.h"
|
||||||
|
|
||||||
static const char * ExtractEncryptedPassword(Oid roleOid);
|
static const char * ExtractEncryptedPassword(Oid roleOid);
|
||||||
static const char * CreateAlterRoleIfExistsCommand(AlterRoleStmt *stmt);
|
static const char * CreateAlterRoleIfExistsCommand(AlterRoleStmt *stmt);
|
||||||
|
@ -65,13 +66,16 @@ static DefElem * makeDefElemBool(char *name, bool value);
|
||||||
static List * GenerateRoleOptionsList(HeapTuple tuple);
|
static List * GenerateRoleOptionsList(HeapTuple tuple);
|
||||||
static List * GenerateGrantRoleStmtsFromOptions(RoleSpec *roleSpec, List *options);
|
static List * GenerateGrantRoleStmtsFromOptions(RoleSpec *roleSpec, List *options);
|
||||||
static List * GenerateGrantRoleStmtsOfRole(Oid roleid);
|
static List * GenerateGrantRoleStmtsOfRole(Oid roleid);
|
||||||
|
static List * GenerateSecLabelOnRoleStmts(Oid roleid, char *rolename);
|
||||||
static void EnsureSequentialModeForRoleDDL(void);
|
static void EnsureSequentialModeForRoleDDL(void);
|
||||||
|
|
||||||
static char * GetRoleNameFromDbRoleSetting(HeapTuple tuple,
|
static char * GetRoleNameFromDbRoleSetting(HeapTuple tuple,
|
||||||
TupleDesc DbRoleSettingDescription);
|
TupleDesc DbRoleSettingDescription);
|
||||||
static char * GetDatabaseNameFromDbRoleSetting(HeapTuple tuple,
|
static char * GetDatabaseNameFromDbRoleSetting(HeapTuple tuple,
|
||||||
TupleDesc DbRoleSettingDescription);
|
TupleDesc DbRoleSettingDescription);
|
||||||
|
#if PG_VERSION_NUM < PG_VERSION_17
|
||||||
static Node * makeStringConst(char *str, int location);
|
static Node * makeStringConst(char *str, int location);
|
||||||
|
#endif
|
||||||
static Node * makeIntConst(int val, int location);
|
static Node * makeIntConst(int val, int location);
|
||||||
static Node * makeFloatConst(char *str, int location);
|
static Node * makeFloatConst(char *str, int location);
|
||||||
static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec *role);
|
static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec *role);
|
||||||
|
@ -161,7 +165,7 @@ PostprocessAlterRoleStmt(Node *node, const char *queryString)
|
||||||
AlterRoleStmt *stmt = castNode(AlterRoleStmt, node);
|
AlterRoleStmt *stmt = castNode(AlterRoleStmt, node);
|
||||||
|
|
||||||
DefElem *option = NULL;
|
DefElem *option = NULL;
|
||||||
foreach_ptr(option, stmt->options)
|
foreach_declared_ptr(option, stmt->options)
|
||||||
{
|
{
|
||||||
if (strcasecmp(option->defname, "password") == 0)
|
if (strcasecmp(option->defname, "password") == 0)
|
||||||
{
|
{
|
||||||
|
@ -489,18 +493,17 @@ GenerateRoleOptionsList(HeapTuple tuple)
|
||||||
options = lappend(options, makeDefElem("password", NULL, -1));
|
options = lappend(options, makeDefElem("password", NULL, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load valid unitl data from the heap tuple, use default of infinity if not set */
|
/* load valid until data from the heap tuple */
|
||||||
Datum rolValidUntilDatum = SysCacheGetAttr(AUTHNAME, tuple,
|
Datum rolValidUntilDatum = SysCacheGetAttr(AUTHNAME, tuple,
|
||||||
Anum_pg_authid_rolvaliduntil, &isNull);
|
Anum_pg_authid_rolvaliduntil, &isNull);
|
||||||
char *rolValidUntil = "infinity";
|
|
||||||
if (!isNull)
|
if (!isNull)
|
||||||
{
|
{
|
||||||
rolValidUntil = pstrdup((char *) timestamptz_to_str(rolValidUntilDatum));
|
char *rolValidUntil = pstrdup((char *) timestamptz_to_str(rolValidUntilDatum));
|
||||||
}
|
|
||||||
|
|
||||||
Node *validUntilStringNode = (Node *) makeString(rolValidUntil);
|
Node *validUntilStringNode = (Node *) makeString(rolValidUntil);
|
||||||
DefElem *validUntilOption = makeDefElem("validUntil", validUntilStringNode, -1);
|
DefElem *validUntilOption = makeDefElem("validUntil", validUntilStringNode, -1);
|
||||||
options = lappend(options, validUntilOption);
|
options = lappend(options, validUntilOption);
|
||||||
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
@ -515,13 +518,14 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid)
|
||||||
{
|
{
|
||||||
HeapTuple roleTuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleOid));
|
HeapTuple roleTuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleOid));
|
||||||
Form_pg_authid role = ((Form_pg_authid) GETSTRUCT(roleTuple));
|
Form_pg_authid role = ((Form_pg_authid) GETSTRUCT(roleTuple));
|
||||||
|
char *rolename = pstrdup(NameStr(role->rolname));
|
||||||
|
|
||||||
CreateRoleStmt *createRoleStmt = NULL;
|
CreateRoleStmt *createRoleStmt = NULL;
|
||||||
if (EnableCreateRolePropagation)
|
if (EnableCreateRolePropagation)
|
||||||
{
|
{
|
||||||
createRoleStmt = makeNode(CreateRoleStmt);
|
createRoleStmt = makeNode(CreateRoleStmt);
|
||||||
createRoleStmt->stmt_type = ROLESTMT_ROLE;
|
createRoleStmt->stmt_type = ROLESTMT_ROLE;
|
||||||
createRoleStmt->role = pstrdup(NameStr(role->rolname));
|
createRoleStmt->role = rolename;
|
||||||
createRoleStmt->options = GenerateRoleOptionsList(roleTuple);
|
createRoleStmt->options = GenerateRoleOptionsList(roleTuple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +536,7 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid)
|
||||||
alterRoleStmt->role = makeNode(RoleSpec);
|
alterRoleStmt->role = makeNode(RoleSpec);
|
||||||
alterRoleStmt->role->roletype = ROLESPEC_CSTRING;
|
alterRoleStmt->role->roletype = ROLESPEC_CSTRING;
|
||||||
alterRoleStmt->role->location = -1;
|
alterRoleStmt->role->location = -1;
|
||||||
alterRoleStmt->role->rolename = pstrdup(NameStr(role->rolname));
|
alterRoleStmt->role->rolename = rolename;
|
||||||
alterRoleStmt->action = 1;
|
alterRoleStmt->action = 1;
|
||||||
alterRoleStmt->options = GenerateRoleOptionsList(roleTuple);
|
alterRoleStmt->options = GenerateRoleOptionsList(roleTuple);
|
||||||
}
|
}
|
||||||
|
@ -544,7 +548,7 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid)
|
||||||
{
|
{
|
||||||
/* add a worker_create_or_alter_role command if any of them are set */
|
/* add a worker_create_or_alter_role command if any of them are set */
|
||||||
char *createOrAlterRoleQuery = CreateCreateOrAlterRoleCommand(
|
char *createOrAlterRoleQuery = CreateCreateOrAlterRoleCommand(
|
||||||
pstrdup(NameStr(role->rolname)),
|
rolename,
|
||||||
createRoleStmt,
|
createRoleStmt,
|
||||||
alterRoleStmt);
|
alterRoleStmt);
|
||||||
|
|
||||||
|
@ -562,7 +566,21 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid)
|
||||||
{
|
{
|
||||||
List *grantRoleStmts = GenerateGrantRoleStmtsOfRole(roleOid);
|
List *grantRoleStmts = GenerateGrantRoleStmtsOfRole(roleOid);
|
||||||
Node *stmt = NULL;
|
Node *stmt = NULL;
|
||||||
foreach_ptr(stmt, grantRoleStmts)
|
foreach_declared_ptr(stmt, grantRoleStmts)
|
||||||
|
{
|
||||||
|
completeRoleList = lappend(completeRoleList, DeparseTreeNode(stmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* append SECURITY LABEL ON ROLE commands for this specific user
|
||||||
|
* When we propagate user creation, we also want to make sure that we propagate
|
||||||
|
* all the security labels it has been given. For this, we check pg_shseclabel
|
||||||
|
* for the ROLE entry corresponding to roleOid, and generate the relevant
|
||||||
|
* SecLabel stmts to be run in the new node.
|
||||||
|
*/
|
||||||
|
List *secLabelOnRoleStmts = GenerateSecLabelOnRoleStmts(roleOid, rolename);
|
||||||
|
stmt = NULL;
|
||||||
|
foreach_declared_ptr(stmt, secLabelOnRoleStmts)
|
||||||
{
|
{
|
||||||
completeRoleList = lappend(completeRoleList, DeparseTreeNode(stmt));
|
completeRoleList = lappend(completeRoleList, DeparseTreeNode(stmt));
|
||||||
}
|
}
|
||||||
|
@ -760,7 +778,7 @@ MakeSetStatementArguments(char *configurationName, char *configurationValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *configuration = NULL;
|
char *configuration = NULL;
|
||||||
foreach_ptr(configuration, configurationList)
|
foreach_declared_ptr(configuration, configurationList)
|
||||||
{
|
{
|
||||||
Node *arg = makeStringConst(configuration, -1);
|
Node *arg = makeStringConst(configuration, -1);
|
||||||
args = lappend(args, arg);
|
args = lappend(args, arg);
|
||||||
|
@ -796,7 +814,7 @@ GenerateGrantRoleStmtsFromOptions(RoleSpec *roleSpec, List *options)
|
||||||
List *stmts = NIL;
|
List *stmts = NIL;
|
||||||
|
|
||||||
DefElem *option = NULL;
|
DefElem *option = NULL;
|
||||||
foreach_ptr(option, options)
|
foreach_declared_ptr(option, options)
|
||||||
{
|
{
|
||||||
if (strcmp(option->defname, "adminmembers") != 0 &&
|
if (strcmp(option->defname, "adminmembers") != 0 &&
|
||||||
strcmp(option->defname, "rolemembers") != 0 &&
|
strcmp(option->defname, "rolemembers") != 0 &&
|
||||||
|
@ -895,6 +913,54 @@ GenerateGrantRoleStmtsOfRole(Oid roleid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateSecLabelOnRoleStmts generates the SecLabelStmts for the role
|
||||||
|
* whose oid is roleid.
|
||||||
|
*/
|
||||||
|
static List *
|
||||||
|
GenerateSecLabelOnRoleStmts(Oid roleid, char *rolename)
|
||||||
|
{
|
||||||
|
List *secLabelStmts = NIL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that roles are shared database objects, therefore their
|
||||||
|
* security labels are stored in pg_shseclabel instead of pg_seclabel.
|
||||||
|
*/
|
||||||
|
Relation pg_shseclabel = table_open(SharedSecLabelRelationId, AccessShareLock);
|
||||||
|
ScanKeyData skey[1];
|
||||||
|
ScanKeyInit(&skey[0], Anum_pg_shseclabel_objoid, BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(roleid));
|
||||||
|
SysScanDesc scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId,
|
||||||
|
true, NULL, 1, &skey[0]);
|
||||||
|
|
||||||
|
HeapTuple tuple = NULL;
|
||||||
|
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
|
||||||
|
{
|
||||||
|
SecLabelStmt *secLabelStmt = makeNode(SecLabelStmt);
|
||||||
|
secLabelStmt->objtype = OBJECT_ROLE;
|
||||||
|
secLabelStmt->object = (Node *) makeString(pstrdup(rolename));
|
||||||
|
|
||||||
|
Datum datumArray[Natts_pg_shseclabel];
|
||||||
|
bool isNullArray[Natts_pg_shseclabel];
|
||||||
|
|
||||||
|
heap_deform_tuple(tuple, RelationGetDescr(pg_shseclabel), datumArray,
|
||||||
|
isNullArray);
|
||||||
|
|
||||||
|
secLabelStmt->provider = TextDatumGetCString(
|
||||||
|
datumArray[Anum_pg_shseclabel_provider - 1]);
|
||||||
|
secLabelStmt->label = TextDatumGetCString(
|
||||||
|
datumArray[Anum_pg_shseclabel_label - 1]);
|
||||||
|
|
||||||
|
secLabelStmts = lappend(secLabelStmts, secLabelStmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
systable_endscan(scan);
|
||||||
|
table_close(pg_shseclabel, AccessShareLock);
|
||||||
|
|
||||||
|
return secLabelStmts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessCreateRoleStmt creates a worker_create_or_alter_role query for the
|
* PreprocessCreateRoleStmt creates a worker_create_or_alter_role query for the
|
||||||
* role that is being created. With that query we can create the role in the
|
* role that is being created. With that query we can create the role in the
|
||||||
|
@ -938,7 +1004,7 @@ PreprocessCreateRoleStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
/* deparse all grant statements and add them to the commands list */
|
/* deparse all grant statements and add them to the commands list */
|
||||||
Node *stmt = NULL;
|
Node *stmt = NULL;
|
||||||
foreach_ptr(stmt, grantRoleStmts)
|
foreach_declared_ptr(stmt, grantRoleStmts)
|
||||||
{
|
{
|
||||||
commands = lappend(commands, DeparseTreeNode(stmt));
|
commands = lappend(commands, DeparseTreeNode(stmt));
|
||||||
}
|
}
|
||||||
|
@ -949,6 +1015,8 @@ PreprocessCreateRoleStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM < PG_VERSION_17
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* makeStringConst creates a Const Node that stores a given string
|
* makeStringConst creates a Const Node that stores a given string
|
||||||
*
|
*
|
||||||
|
@ -959,19 +1027,17 @@ makeStringConst(char *str, int location)
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
n->val.sval.type = T_String;
|
n->val.sval.type = T_String;
|
||||||
n->val.sval.sval = str;
|
n->val.sval.sval = str;
|
||||||
#else
|
|
||||||
n->val.type = T_String;
|
|
||||||
n->val.val.str = str;
|
|
||||||
#endif
|
|
||||||
n->location = location;
|
n->location = location;
|
||||||
|
|
||||||
return (Node *) n;
|
return (Node *) n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* makeIntConst creates a Const Node that stores a given integer
|
* makeIntConst creates a Const Node that stores a given integer
|
||||||
*
|
*
|
||||||
|
@ -982,13 +1048,8 @@ makeIntConst(int val, int location)
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
n->val.ival.type = T_Integer;
|
n->val.ival.type = T_Integer;
|
||||||
n->val.ival.ival = val;
|
n->val.ival.ival = val;
|
||||||
#else
|
|
||||||
n->val.type = T_Integer;
|
|
||||||
n->val.val.ival = val;
|
|
||||||
#endif
|
|
||||||
n->location = location;
|
n->location = location;
|
||||||
|
|
||||||
return (Node *) n;
|
return (Node *) n;
|
||||||
|
@ -1005,13 +1066,8 @@ makeFloatConst(char *str, int location)
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
n->val.fval.type = T_Float;
|
n->val.fval.type = T_Float;
|
||||||
n->val.fval.fval = str;
|
n->val.fval.fval = str;
|
||||||
#else
|
|
||||||
n->val.type = T_Float;
|
|
||||||
n->val.val.str = str;
|
|
||||||
#endif
|
|
||||||
n->location = location;
|
n->location = location;
|
||||||
|
|
||||||
return (Node *) n;
|
return (Node *) n;
|
||||||
|
@ -1064,7 +1120,7 @@ void
|
||||||
UnmarkRolesDistributed(List *roles)
|
UnmarkRolesDistributed(List *roles)
|
||||||
{
|
{
|
||||||
Node *roleNode = NULL;
|
Node *roleNode = NULL;
|
||||||
foreach_ptr(roleNode, roles)
|
foreach_declared_ptr(roleNode, roles)
|
||||||
{
|
{
|
||||||
RoleSpec *role = castNode(RoleSpec, roleNode);
|
RoleSpec *role = castNode(RoleSpec, roleNode);
|
||||||
ObjectAddress roleAddress = { 0 };
|
ObjectAddress roleAddress = { 0 };
|
||||||
|
@ -1094,7 +1150,7 @@ FilterDistributedRoles(List *roles)
|
||||||
{
|
{
|
||||||
List *distributedRoles = NIL;
|
List *distributedRoles = NIL;
|
||||||
Node *roleNode = NULL;
|
Node *roleNode = NULL;
|
||||||
foreach_ptr(roleNode, roles)
|
foreach_declared_ptr(roleNode, roles)
|
||||||
{
|
{
|
||||||
RoleSpec *role = castNode(RoleSpec, roleNode);
|
RoleSpec *role = castNode(RoleSpec, roleNode);
|
||||||
Oid roleOid = get_rolespec_oid(role, true);
|
Oid roleOid = get_rolespec_oid(role, true);
|
||||||
|
@ -1189,7 +1245,7 @@ PostprocessGrantRoleStmt(Node *node, const char *queryString)
|
||||||
GrantRoleStmt *stmt = castNode(GrantRoleStmt, node);
|
GrantRoleStmt *stmt = castNode(GrantRoleStmt, node);
|
||||||
|
|
||||||
RoleSpec *role = NULL;
|
RoleSpec *role = NULL;
|
||||||
foreach_ptr(role, stmt->grantee_roles)
|
foreach_declared_ptr(role, stmt->grantee_roles)
|
||||||
{
|
{
|
||||||
Oid roleOid = get_rolespec_oid(role, false);
|
Oid roleOid = get_rolespec_oid(role, false);
|
||||||
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||||
|
@ -1213,7 +1269,7 @@ IsGrantRoleWithInheritOrSetOption(GrantRoleStmt *stmt)
|
||||||
{
|
{
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
DefElem *opt = NULL;
|
DefElem *opt = NULL;
|
||||||
foreach_ptr(opt, stmt->opt)
|
foreach_declared_ptr(opt, stmt->opt)
|
||||||
{
|
{
|
||||||
if (strcmp(opt->defname, "inherit") == 0 || strcmp(opt->defname, "set") == 0)
|
if (strcmp(opt->defname, "inherit") == 0 || strcmp(opt->defname, "set") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,28 +19,28 @@
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
#include "distributed/colocation_utils.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include <distributed/connection_management.h>
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
|
||||||
#include <distributed/metadata_sync.h>
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/reference_table_utils.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/resource_lock.h"
|
|
||||||
#include <distributed/remote_commands.h>
|
|
||||||
#include <distributed/remote_commands.h>
|
|
||||||
#include "distributed/tenant_schema_metadata.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
|
|
||||||
|
#include "distributed/colocation_utils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/connection_management.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_cache.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/reference_table_utils.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/remote_commands.h"
|
||||||
|
#include "distributed/resource_lock.h"
|
||||||
|
#include "distributed/tenant_schema_metadata.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
|
||||||
|
|
||||||
static List * GetObjectAddressBySchemaName(char *schemaName, bool missing_ok);
|
static List * GetObjectAddressBySchemaName(char *schemaName, bool missing_ok);
|
||||||
static List * FilterDistributedSchemas(List *schemas);
|
static List * FilterDistributedSchemas(List *schemas);
|
||||||
|
@ -162,7 +162,7 @@ PreprocessDropSchemaStmt(Node *node, const char *queryString,
|
||||||
EnsureSequentialMode(OBJECT_SCHEMA);
|
EnsureSequentialMode(OBJECT_SCHEMA);
|
||||||
|
|
||||||
String *schemaVal = NULL;
|
String *schemaVal = NULL;
|
||||||
foreach_ptr(schemaVal, distributedSchemas)
|
foreach_declared_ptr(schemaVal, distributedSchemas)
|
||||||
{
|
{
|
||||||
if (SchemaHasDistributedTableWithFKey(strVal(schemaVal)))
|
if (SchemaHasDistributedTableWithFKey(strVal(schemaVal)))
|
||||||
{
|
{
|
||||||
|
@ -322,7 +322,7 @@ FilterDistributedSchemas(List *schemas)
|
||||||
List *distributedSchemas = NIL;
|
List *distributedSchemas = NIL;
|
||||||
|
|
||||||
String *schemaValue = NULL;
|
String *schemaValue = NULL;
|
||||||
foreach_ptr(schemaValue, schemas)
|
foreach_declared_ptr(schemaValue, schemas)
|
||||||
{
|
{
|
||||||
const char *schemaName = strVal(schemaValue);
|
const char *schemaName = strVal(schemaValue);
|
||||||
Oid schemaOid = get_namespace_oid(schemaName, true);
|
Oid schemaOid = get_namespace_oid(schemaName, true);
|
||||||
|
@ -443,7 +443,7 @@ GetGrantCommandsFromCreateSchemaStmt(Node *node)
|
||||||
CreateSchemaStmt *stmt = castNode(CreateSchemaStmt, node);
|
CreateSchemaStmt *stmt = castNode(CreateSchemaStmt, node);
|
||||||
|
|
||||||
Node *element = NULL;
|
Node *element = NULL;
|
||||||
foreach_ptr(element, stmt->schemaElts)
|
foreach_declared_ptr(element, stmt->schemaElts)
|
||||||
{
|
{
|
||||||
if (!IsA(element, GrantStmt))
|
if (!IsA(element, GrantStmt))
|
||||||
{
|
{
|
||||||
|
@ -480,7 +480,7 @@ static bool
|
||||||
CreateSchemaStmtCreatesTable(CreateSchemaStmt *stmt)
|
CreateSchemaStmtCreatesTable(CreateSchemaStmt *stmt)
|
||||||
{
|
{
|
||||||
Node *element = NULL;
|
Node *element = NULL;
|
||||||
foreach_ptr(element, stmt->schemaElts)
|
foreach_declared_ptr(element, stmt->schemaElts)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* CREATE TABLE AS and CREATE FOREIGN TABLE commands cannot be
|
* CREATE TABLE AS and CREATE FOREIGN TABLE commands cannot be
|
||||||
|
|
|
@ -7,27 +7,29 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/pg_namespace_d.h"
|
#include "catalog/pg_namespace_d.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#include "distributed/argutils.h"
|
#include "distributed/argutils.h"
|
||||||
#include "distributed/backend_data.h"
|
#include "distributed/backend_data.h"
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/shard_transfer.h"
|
#include "distributed/shard_transfer.h"
|
||||||
#include "distributed/tenant_schema_metadata.h"
|
#include "distributed/tenant_schema_metadata.h"
|
||||||
#include "distributed/worker_shard_visibility.h"
|
#include "distributed/worker_shard_visibility.h"
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/fmgroids.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* return value of CreateCitusMoveSchemaParams() */
|
/* return value of CreateCitusMoveSchemaParams() */
|
||||||
|
@ -172,7 +174,7 @@ EnsureTableKindSupportedForTenantSchema(Oid relationId)
|
||||||
List *partitionList = PartitionList(relationId);
|
List *partitionList = PartitionList(relationId);
|
||||||
|
|
||||||
Oid partitionRelationId = InvalidOid;
|
Oid partitionRelationId = InvalidOid;
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
foreach_declared_oid(partitionRelationId, partitionList)
|
||||||
{
|
{
|
||||||
ErrorIfIllegalPartitioningInTenantSchema(relationId, partitionRelationId);
|
ErrorIfIllegalPartitioningInTenantSchema(relationId, partitionRelationId);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +199,7 @@ EnsureFKeysForTenantTable(Oid relationId)
|
||||||
int fKeyReferencingFlags = INCLUDE_REFERENCING_CONSTRAINTS | INCLUDE_ALL_TABLE_TYPES;
|
int fKeyReferencingFlags = INCLUDE_REFERENCING_CONSTRAINTS | INCLUDE_ALL_TABLE_TYPES;
|
||||||
List *referencingForeignKeys = GetForeignKeyOids(relationId, fKeyReferencingFlags);
|
List *referencingForeignKeys = GetForeignKeyOids(relationId, fKeyReferencingFlags);
|
||||||
Oid foreignKeyId = InvalidOid;
|
Oid foreignKeyId = InvalidOid;
|
||||||
foreach_oid(foreignKeyId, referencingForeignKeys)
|
foreach_declared_oid(foreignKeyId, referencingForeignKeys)
|
||||||
{
|
{
|
||||||
Oid referencingTableId = GetReferencingTableId(foreignKeyId);
|
Oid referencingTableId = GetReferencingTableId(foreignKeyId);
|
||||||
Oid referencedTableId = GetReferencedTableId(foreignKeyId);
|
Oid referencedTableId = GetReferencedTableId(foreignKeyId);
|
||||||
|
@ -230,7 +232,7 @@ EnsureFKeysForTenantTable(Oid relationId)
|
||||||
|
|
||||||
int fKeyReferencedFlags = INCLUDE_REFERENCED_CONSTRAINTS | INCLUDE_ALL_TABLE_TYPES;
|
int fKeyReferencedFlags = INCLUDE_REFERENCED_CONSTRAINTS | INCLUDE_ALL_TABLE_TYPES;
|
||||||
List *referencedForeignKeys = GetForeignKeyOids(relationId, fKeyReferencedFlags);
|
List *referencedForeignKeys = GetForeignKeyOids(relationId, fKeyReferencedFlags);
|
||||||
foreach_oid(foreignKeyId, referencedForeignKeys)
|
foreach_declared_oid(foreignKeyId, referencedForeignKeys)
|
||||||
{
|
{
|
||||||
Oid referencingTableId = GetReferencingTableId(foreignKeyId);
|
Oid referencingTableId = GetReferencingTableId(foreignKeyId);
|
||||||
Oid referencedTableId = GetReferencedTableId(foreignKeyId);
|
Oid referencedTableId = GetReferencedTableId(foreignKeyId);
|
||||||
|
@ -427,7 +429,7 @@ EnsureSchemaCanBeDistributed(Oid schemaId, List *schemaTableIdList)
|
||||||
}
|
}
|
||||||
|
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, schemaTableIdList)
|
foreach_declared_oid(relationId, schemaTableIdList)
|
||||||
{
|
{
|
||||||
EnsureTenantTable(relationId, "citus_schema_distribute");
|
EnsureTenantTable(relationId, "citus_schema_distribute");
|
||||||
}
|
}
|
||||||
|
@ -635,7 +637,7 @@ citus_schema_distribute(PG_FUNCTION_ARGS)
|
||||||
List *tableIdListInSchema = SchemaGetNonShardTableIdList(schemaId);
|
List *tableIdListInSchema = SchemaGetNonShardTableIdList(schemaId);
|
||||||
List *tableIdListToConvert = NIL;
|
List *tableIdListToConvert = NIL;
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, tableIdListInSchema)
|
foreach_declared_oid(relationId, tableIdListInSchema)
|
||||||
{
|
{
|
||||||
/* prevent concurrent drop of the relation */
|
/* prevent concurrent drop of the relation */
|
||||||
LockRelationOid(relationId, AccessShareLock);
|
LockRelationOid(relationId, AccessShareLock);
|
||||||
|
@ -673,7 +675,7 @@ citus_schema_distribute(PG_FUNCTION_ARGS)
|
||||||
* tables.
|
* tables.
|
||||||
*/
|
*/
|
||||||
List *originalForeignKeyRecreationCommands = NIL;
|
List *originalForeignKeyRecreationCommands = NIL;
|
||||||
foreach_oid(relationId, tableIdListToConvert)
|
foreach_declared_oid(relationId, tableIdListToConvert)
|
||||||
{
|
{
|
||||||
List *fkeyCommandsForRelation =
|
List *fkeyCommandsForRelation =
|
||||||
GetFKeyCreationCommandsRelationInvolvedWithTableType(relationId,
|
GetFKeyCreationCommandsRelationInvolvedWithTableType(relationId,
|
||||||
|
@ -739,7 +741,7 @@ citus_schema_undistribute(PG_FUNCTION_ARGS)
|
||||||
List *tableIdListInSchema = SchemaGetNonShardTableIdList(schemaId);
|
List *tableIdListInSchema = SchemaGetNonShardTableIdList(schemaId);
|
||||||
List *tableIdListToConvert = NIL;
|
List *tableIdListToConvert = NIL;
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, tableIdListInSchema)
|
foreach_declared_oid(relationId, tableIdListInSchema)
|
||||||
{
|
{
|
||||||
/* prevent concurrent drop of the relation */
|
/* prevent concurrent drop of the relation */
|
||||||
LockRelationOid(relationId, AccessShareLock);
|
LockRelationOid(relationId, AccessShareLock);
|
||||||
|
@ -881,7 +883,7 @@ TenantSchemaPickAnchorShardId(Oid schemaId)
|
||||||
}
|
}
|
||||||
|
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, tablesInSchema)
|
foreach_declared_oid(relationId, tablesInSchema)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Make sure the relation isn't dropped for the remainder of
|
* Make sure the relation isn't dropped for the remainder of
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* seclabel.c
|
||||||
|
*
|
||||||
|
* This file contains the logic of SECURITY LABEL statement propagation.
|
||||||
|
*
|
||||||
|
* Copyright (c) Citus Data, Inc.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/log_utils.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PostprocessSecLabelStmt prepares the commands that need to be run on all workers to assign
|
||||||
|
* security labels on distributed objects, currently supporting just Role objects.
|
||||||
|
* It also ensures that all object dependencies exist on all
|
||||||
|
* nodes for the object in the SecLabelStmt.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
PostprocessSecLabelStmt(Node *node, const char *queryString)
|
||||||
|
{
|
||||||
|
if (!ShouldPropagate())
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);
|
||||||
|
|
||||||
|
List *objectAddresses = GetObjectAddressListFromParseTree(node, false, true);
|
||||||
|
if (!IsAnyObjectDistributed(objectAddresses))
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secLabelStmt->objtype != OBJECT_ROLE)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we are not in the coordinator, we don't want to interrupt the security
|
||||||
|
* label command with notices, the user expects that from the worker node
|
||||||
|
* the command will not be propagated
|
||||||
|
*/
|
||||||
|
if (EnableUnsupportedFeatureMessages && IsCoordinator())
|
||||||
|
{
|
||||||
|
ereport(NOTICE, (errmsg("not propagating SECURITY LABEL commands whose "
|
||||||
|
"object type is not role"),
|
||||||
|
errhint("Connect to worker nodes directly to manually "
|
||||||
|
"run the same SECURITY LABEL command.")));
|
||||||
|
}
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EnableCreateRolePropagation)
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureCoordinator();
|
||||||
|
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
|
||||||
|
|
||||||
|
const char *sql = DeparseTreeNode((Node *) secLabelStmt);
|
||||||
|
|
||||||
|
List *commandList = list_make3(DISABLE_DDL_PROPAGATION,
|
||||||
|
(void *) sql,
|
||||||
|
ENABLE_DDL_PROPAGATION);
|
||||||
|
|
||||||
|
return NodeDDLTaskList(NON_COORDINATOR_NODES, commandList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SecLabelStmtObjectAddress returns the object address of the object on
|
||||||
|
* which this statement operates (secLabelStmt->object). Note that it has no limitation
|
||||||
|
* on the object type being OBJECT_ROLE. This is intentionally implemented like this
|
||||||
|
* since it is fairly simple to implement and we might extend SECURITY LABEL propagation
|
||||||
|
* in the future to include more object types.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
SecLabelStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess)
|
||||||
|
{
|
||||||
|
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);
|
||||||
|
|
||||||
|
Relation rel = NULL;
|
||||||
|
ObjectAddress address = get_object_address(secLabelStmt->objtype,
|
||||||
|
secLabelStmt->object, &rel,
|
||||||
|
AccessShareLock, missing_ok);
|
||||||
|
if (rel != NULL)
|
||||||
|
{
|
||||||
|
relation_close(rel, AccessShareLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectAddress *addressPtr = palloc0(sizeof(ObjectAddress));
|
||||||
|
*addressPtr = address;
|
||||||
|
return list_make1(addressPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* citus_test_object_relabel is a dummy function for check_object_relabel_type hook.
|
||||||
|
* It is meant to be used in tests combined with citus_test_register_label_provider
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
citus_test_object_relabel(const ObjectAddress *object, const char *seclabel)
|
||||||
|
{
|
||||||
|
if (seclabel == NULL ||
|
||||||
|
strcmp(seclabel, "citus_unclassified") == 0 ||
|
||||||
|
strcmp(seclabel, "citus_classified") == 0 ||
|
||||||
|
strcmp(seclabel, "citus '!unclassified") == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_NAME),
|
||||||
|
errmsg("'%s' is not a valid security label for Citus tests.", seclabel)));
|
||||||
|
}
|
|
@ -14,8 +14,15 @@
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
|
#include "catalog/pg_attrdef.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "rewrite/rewriteHandler.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/sequence.h"
|
#include "distributed/commands/sequence.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
@ -24,12 +31,7 @@
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "nodes/makefuncs.h"
|
|
||||||
#include "distributed/worker_create_or_replace.h"
|
#include "distributed/worker_create_or_replace.h"
|
||||||
#include "nodes/parsenodes.h"
|
|
||||||
#include "rewrite/rewriteHandler.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
|
|
||||||
/* Local functions forward declarations for helper functions */
|
/* Local functions forward declarations for helper functions */
|
||||||
static bool OptionsSpecifyOwnedBy(List *optionList, Oid *ownedByTableId);
|
static bool OptionsSpecifyOwnedBy(List *optionList, Oid *ownedByTableId);
|
||||||
|
@ -121,7 +123,7 @@ static bool
|
||||||
OptionsSpecifyOwnedBy(List *optionList, Oid *ownedByTableId)
|
OptionsSpecifyOwnedBy(List *optionList, Oid *ownedByTableId)
|
||||||
{
|
{
|
||||||
DefElem *defElem = NULL;
|
DefElem *defElem = NULL;
|
||||||
foreach_ptr(defElem, optionList)
|
foreach_declared_ptr(defElem, optionList)
|
||||||
{
|
{
|
||||||
if (strcmp(defElem->defname, "owned_by") == 0)
|
if (strcmp(defElem->defname, "owned_by") == 0)
|
||||||
{
|
{
|
||||||
|
@ -200,7 +202,7 @@ ExtractDefaultColumnsAndOwnedSequences(Oid relationId, List **columnNameList,
|
||||||
}
|
}
|
||||||
|
|
||||||
Oid ownedSequenceId = InvalidOid;
|
Oid ownedSequenceId = InvalidOid;
|
||||||
foreach_oid(ownedSequenceId, columnOwnedSequences)
|
foreach_declared_oid(ownedSequenceId, columnOwnedSequences)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* A column might have multiple sequences one via OWNED BY one another
|
* A column might have multiple sequences one via OWNED BY one another
|
||||||
|
@ -286,7 +288,7 @@ PreprocessDropSequenceStmt(Node *node, const char *queryString,
|
||||||
*/
|
*/
|
||||||
List *deletingSequencesList = stmt->objects;
|
List *deletingSequencesList = stmt->objects;
|
||||||
List *objectNameList = NULL;
|
List *objectNameList = NULL;
|
||||||
foreach_ptr(objectNameList, deletingSequencesList)
|
foreach_declared_ptr(objectNameList, deletingSequencesList)
|
||||||
{
|
{
|
||||||
RangeVar *seq = makeRangeVarFromNameList(objectNameList);
|
RangeVar *seq = makeRangeVarFromNameList(objectNameList);
|
||||||
|
|
||||||
|
@ -320,7 +322,7 @@ PreprocessDropSequenceStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
/* remove the entries for the distributed objects on dropping */
|
/* remove the entries for the distributed objects on dropping */
|
||||||
ObjectAddress *address = NULL;
|
ObjectAddress *address = NULL;
|
||||||
foreach_ptr(address, distributedSequenceAddresses)
|
foreach_declared_ptr(address, distributedSequenceAddresses)
|
||||||
{
|
{
|
||||||
UnmarkObjectDistributed(address);
|
UnmarkObjectDistributed(address);
|
||||||
}
|
}
|
||||||
|
@ -354,7 +356,7 @@ SequenceDropStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess)
|
||||||
|
|
||||||
List *droppingSequencesList = dropSeqStmt->objects;
|
List *droppingSequencesList = dropSeqStmt->objects;
|
||||||
List *objectNameList = NULL;
|
List *objectNameList = NULL;
|
||||||
foreach_ptr(objectNameList, droppingSequencesList)
|
foreach_declared_ptr(objectNameList, droppingSequencesList)
|
||||||
{
|
{
|
||||||
RangeVar *seq = makeRangeVarFromNameList(objectNameList);
|
RangeVar *seq = makeRangeVarFromNameList(objectNameList);
|
||||||
|
|
||||||
|
@ -474,7 +476,7 @@ PreprocessAlterSequenceStmt(Node *node, const char *queryString,
|
||||||
{
|
{
|
||||||
List *options = stmt->options;
|
List *options = stmt->options;
|
||||||
DefElem *defel = NULL;
|
DefElem *defel = NULL;
|
||||||
foreach_ptr(defel, options)
|
foreach_declared_ptr(defel, options)
|
||||||
{
|
{
|
||||||
if (strcmp(defel->defname, "as") == 0)
|
if (strcmp(defel->defname, "as") == 0)
|
||||||
{
|
{
|
||||||
|
@ -506,22 +508,14 @@ PreprocessAlterSequenceStmt(Node *node, const char *queryString,
|
||||||
static Oid
|
static Oid
|
||||||
SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress, char depType)
|
SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress, char depType)
|
||||||
{
|
{
|
||||||
List *citusTableIdList = CitusTableTypeIdList(ANY_CITUS_TABLE_TYPE);
|
Oid relationId;
|
||||||
Oid citusTableId = InvalidOid;
|
List *relations = GetDependentRelationsWithSequence(sequenceAddress->objectId,
|
||||||
foreach_oid(citusTableId, citusTableIdList)
|
depType);
|
||||||
|
foreach_declared_oid(relationId, relations)
|
||||||
{
|
{
|
||||||
List *seqInfoList = NIL;
|
if (IsCitusTable(relationId))
|
||||||
GetDependentSequencesWithRelation(citusTableId, &seqInfoList, 0, depType);
|
|
||||||
SequenceInfo *seqInfo = NULL;
|
|
||||||
foreach_ptr(seqInfo, seqInfoList)
|
|
||||||
{
|
{
|
||||||
/*
|
return relationId;
|
||||||
* This sequence is used in a distributed table
|
|
||||||
*/
|
|
||||||
if (seqInfo->sequenceOid == sequenceAddress->objectId)
|
|
||||||
{
|
|
||||||
return citusTableId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,8 +735,6 @@ PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterSequencePersistenceStmt is called for change of persistence
|
* PreprocessAlterSequencePersistenceStmt is called for change of persistence
|
||||||
* of sequences before the persistence is changed on the local instance.
|
* of sequences before the persistence is changed on the local instance.
|
||||||
|
@ -853,9 +845,6 @@ PreprocessSequenceAlterTableStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessGrantOnSequenceStmt is executed before the statement is applied to the local
|
* PreprocessGrantOnSequenceStmt is executed before the statement is applied to the local
|
||||||
* postgres instance.
|
* postgres instance.
|
||||||
|
@ -936,7 +925,7 @@ PostprocessGrantOnSequenceStmt(Node *node, const char *queryString)
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
|
|
||||||
RangeVar *sequence = NULL;
|
RangeVar *sequence = NULL;
|
||||||
foreach_ptr(sequence, distributedSequences)
|
foreach_declared_ptr(sequence, distributedSequences)
|
||||||
{
|
{
|
||||||
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
Oid sequenceOid = RangeVarGetRelid(sequence, NoLock, false);
|
Oid sequenceOid = RangeVarGetRelid(sequence, NoLock, false);
|
||||||
|
@ -1020,7 +1009,7 @@ FilterDistributedSequences(GrantStmt *stmt)
|
||||||
/* iterate over all namespace names provided to get their oid's */
|
/* iterate over all namespace names provided to get their oid's */
|
||||||
List *namespaceOidList = NIL;
|
List *namespaceOidList = NIL;
|
||||||
String *namespaceValue = NULL;
|
String *namespaceValue = NULL;
|
||||||
foreach_ptr(namespaceValue, stmt->objects)
|
foreach_declared_ptr(namespaceValue, stmt->objects)
|
||||||
{
|
{
|
||||||
char *nspname = strVal(namespaceValue);
|
char *nspname = strVal(namespaceValue);
|
||||||
bool missing_ok = false;
|
bool missing_ok = false;
|
||||||
|
@ -1034,7 +1023,7 @@ FilterDistributedSequences(GrantStmt *stmt)
|
||||||
*/
|
*/
|
||||||
List *distributedSequenceList = DistributedSequenceList();
|
List *distributedSequenceList = DistributedSequenceList();
|
||||||
ObjectAddress *sequenceAddress = NULL;
|
ObjectAddress *sequenceAddress = NULL;
|
||||||
foreach_ptr(sequenceAddress, distributedSequenceList)
|
foreach_declared_ptr(sequenceAddress, distributedSequenceList)
|
||||||
{
|
{
|
||||||
Oid namespaceOid = get_rel_namespace(sequenceAddress->objectId);
|
Oid namespaceOid = get_rel_namespace(sequenceAddress->objectId);
|
||||||
|
|
||||||
|
@ -1058,7 +1047,7 @@ FilterDistributedSequences(GrantStmt *stmt)
|
||||||
{
|
{
|
||||||
bool missing_ok = false;
|
bool missing_ok = false;
|
||||||
RangeVar *sequenceRangeVar = NULL;
|
RangeVar *sequenceRangeVar = NULL;
|
||||||
foreach_ptr(sequenceRangeVar, stmt->objects)
|
foreach_declared_ptr(sequenceRangeVar, stmt->objects)
|
||||||
{
|
{
|
||||||
Oid sequenceOid = RangeVarGetRelid(sequenceRangeVar, NoLock, missing_ok);
|
Oid sequenceOid = RangeVarGetRelid(sequenceRangeVar, NoLock, missing_ok);
|
||||||
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
|
@ -26,8 +28,16 @@
|
||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
#include "catalog/pg_statistic_ext.h"
|
#include "catalog/pg_statistic_ext.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/fmgrprotos.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/relcache.h"
|
||||||
|
#include "utils/ruleutils.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/deparse_shard_query.h"
|
#include "distributed/deparse_shard_query.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
@ -37,14 +47,6 @@
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "distributed/resource_lock.h"
|
#include "distributed/resource_lock.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/fmgroids.h"
|
|
||||||
#include "utils/fmgrprotos.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/relcache.h"
|
|
||||||
#include "utils/ruleutils.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
#define DEFAULT_STATISTICS_TARGET -1
|
#define DEFAULT_STATISTICS_TARGET -1
|
||||||
#define ALTER_INDEX_COLUMN_SET_STATS_COMMAND \
|
#define ALTER_INDEX_COLUMN_SET_STATS_COMMAND \
|
||||||
|
@ -182,7 +184,7 @@ PreprocessDropStatisticsStmt(Node *node, const char *queryString,
|
||||||
List *ddlJobs = NIL;
|
List *ddlJobs = NIL;
|
||||||
List *processedStatsOids = NIL;
|
List *processedStatsOids = NIL;
|
||||||
List *objectNameList = NULL;
|
List *objectNameList = NULL;
|
||||||
foreach_ptr(objectNameList, dropStatisticsStmt->objects)
|
foreach_declared_ptr(objectNameList, dropStatisticsStmt->objects)
|
||||||
{
|
{
|
||||||
Oid statsOid = get_statistics_object_oid(objectNameList,
|
Oid statsOid = get_statistics_object_oid(objectNameList,
|
||||||
dropStatisticsStmt->missing_ok);
|
dropStatisticsStmt->missing_ok);
|
||||||
|
@ -232,7 +234,7 @@ DropStatisticsObjectAddress(Node *node, bool missing_ok, bool isPostprocess)
|
||||||
List *objectAddresses = NIL;
|
List *objectAddresses = NIL;
|
||||||
|
|
||||||
List *objectNameList = NULL;
|
List *objectNameList = NULL;
|
||||||
foreach_ptr(objectNameList, dropStatisticsStmt->objects)
|
foreach_declared_ptr(objectNameList, dropStatisticsStmt->objects)
|
||||||
{
|
{
|
||||||
Oid statsOid = get_statistics_object_oid(objectNameList,
|
Oid statsOid = get_statistics_object_oid(objectNameList,
|
||||||
dropStatisticsStmt->missing_ok);
|
dropStatisticsStmt->missing_ok);
|
||||||
|
@ -533,7 +535,7 @@ GetExplicitStatisticsCommandList(Oid relationId)
|
||||||
int saveNestLevel = PushEmptySearchPath();
|
int saveNestLevel = PushEmptySearchPath();
|
||||||
|
|
||||||
Oid statisticsId = InvalidOid;
|
Oid statisticsId = InvalidOid;
|
||||||
foreach_oid(statisticsId, statisticsIdList)
|
foreach_declared_oid(statisticsId, statisticsIdList)
|
||||||
{
|
{
|
||||||
/* we need create commands for already created stats before distribution */
|
/* we need create commands for already created stats before distribution */
|
||||||
Datum commandText = DirectFunctionCall1(pg_get_statisticsobjdef,
|
Datum commandText = DirectFunctionCall1(pg_get_statisticsobjdef,
|
||||||
|
@ -604,7 +606,7 @@ GetExplicitStatisticsSchemaIdList(Oid relationId)
|
||||||
RelationClose(relation);
|
RelationClose(relation);
|
||||||
|
|
||||||
Oid statsId = InvalidOid;
|
Oid statsId = InvalidOid;
|
||||||
foreach_oid(statsId, statsIdList)
|
foreach_declared_oid(statsId, statsIdList)
|
||||||
{
|
{
|
||||||
HeapTuple heapTuple = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statsId));
|
HeapTuple heapTuple = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statsId));
|
||||||
if (!HeapTupleIsValid(heapTuple))
|
if (!HeapTupleIsValid(heapTuple))
|
||||||
|
@ -649,14 +651,15 @@ GetAlterIndexStatisticsCommands(Oid indexOid)
|
||||||
}
|
}
|
||||||
|
|
||||||
Form_pg_attribute targetAttr = (Form_pg_attribute) GETSTRUCT(attTuple);
|
Form_pg_attribute targetAttr = (Form_pg_attribute) GETSTRUCT(attTuple);
|
||||||
if (targetAttr->attstattarget != DEFAULT_STATISTICS_TARGET)
|
int32 targetAttstattarget = getAttstattarget_compat(attTuple);
|
||||||
|
if (targetAttstattarget != DEFAULT_STATISTICS_TARGET)
|
||||||
{
|
{
|
||||||
char *indexNameWithSchema = generate_qualified_relation_name(indexOid);
|
char *indexNameWithSchema = generate_qualified_relation_name(indexOid);
|
||||||
|
|
||||||
char *command =
|
char *command =
|
||||||
GenerateAlterIndexColumnSetStatsCommand(indexNameWithSchema,
|
GenerateAlterIndexColumnSetStatsCommand(indexNameWithSchema,
|
||||||
targetAttr->attnum,
|
targetAttr->attnum,
|
||||||
targetAttr->attstattarget);
|
targetAttstattarget);
|
||||||
|
|
||||||
alterIndexStatisticsCommandList =
|
alterIndexStatisticsCommandList =
|
||||||
lappend(alterIndexStatisticsCommandList,
|
lappend(alterIndexStatisticsCommandList,
|
||||||
|
@ -771,9 +774,10 @@ CreateAlterCommandIfTargetNotDefault(Oid statsOid)
|
||||||
}
|
}
|
||||||
|
|
||||||
Form_pg_statistic_ext statisticsForm = (Form_pg_statistic_ext) GETSTRUCT(tup);
|
Form_pg_statistic_ext statisticsForm = (Form_pg_statistic_ext) GETSTRUCT(tup);
|
||||||
|
int16 currentStxstattarget = getStxstattarget_compat(tup);
|
||||||
ReleaseSysCache(tup);
|
ReleaseSysCache(tup);
|
||||||
|
|
||||||
if (statisticsForm->stxstattarget == -1)
|
if (currentStxstattarget == -1)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -783,7 +787,8 @@ CreateAlterCommandIfTargetNotDefault(Oid statsOid)
|
||||||
char *schemaName = get_namespace_name(statisticsForm->stxnamespace);
|
char *schemaName = get_namespace_name(statisticsForm->stxnamespace);
|
||||||
char *statName = NameStr(statisticsForm->stxname);
|
char *statName = NameStr(statisticsForm->stxname);
|
||||||
|
|
||||||
alterStatsStmt->stxstattarget = statisticsForm->stxstattarget;
|
alterStatsStmt->stxstattarget = getAlterStatsStxstattarget_compat(
|
||||||
|
currentStxstattarget);
|
||||||
alterStatsStmt->defnames = list_make2(makeString(schemaName), makeString(statName));
|
alterStatsStmt->defnames = list_make2(makeString(schemaName), makeString(statName));
|
||||||
|
|
||||||
return DeparseAlterStatisticsStmt((Node *) alterStatsStmt);
|
return DeparseAlterStatisticsStmt((Node *) alterStatsStmt);
|
||||||
|
|
|
@ -8,21 +8,23 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
#include "safe_lib.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "commands/defrem.h"
|
#include "postgres.h"
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/connection_management.h"
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
#include "safe_lib.h"
|
||||||
|
|
||||||
|
#include "commands/defrem.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/connection_management.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
|
||||||
|
|
||||||
static char * GenerateConninfoWithAuth(char *conninfo);
|
static char * GenerateConninfoWithAuth(char *conninfo);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
|
@ -20,28 +20,6 @@
|
||||||
#include "catalog/pg_depend.h"
|
#include "catalog/pg_depend.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/colocation_utils.h"
|
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/deparse_shard_query.h"
|
|
||||||
#include "distributed/distribution_column.h"
|
|
||||||
#include "distributed/foreign_key_relationship.h"
|
|
||||||
#include "distributed/local_executor.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/dependency.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
|
||||||
#include "distributed/reference_table_utils.h"
|
|
||||||
#include "distributed/relation_access_tracking.h"
|
|
||||||
#include "distributed/resource_lock.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "distributed/worker_shard_visibility.h"
|
|
||||||
#include "distributed/tenant_schema_metadata.h"
|
|
||||||
#include "foreign/foreign.h"
|
#include "foreign/foreign.h"
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
|
@ -53,6 +31,31 @@
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/colocation_utils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/deparse_shard_query.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/distribution_column.h"
|
||||||
|
#include "distributed/foreign_key_relationship.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/local_executor.h"
|
||||||
|
#include "distributed/metadata/dependency.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
|
#include "distributed/reference_table_utils.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/resource_lock.h"
|
||||||
|
#include "distributed/tenant_schema_metadata.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_shard_visibility.h"
|
||||||
|
|
||||||
|
|
||||||
/* controlled via GUC, should be accessed via GetEnableLocalReferenceForeignKeys() */
|
/* controlled via GUC, should be accessed via GetEnableLocalReferenceForeignKeys() */
|
||||||
bool EnableLocalReferenceForeignKeys = true;
|
bool EnableLocalReferenceForeignKeys = true;
|
||||||
|
@ -151,7 +154,7 @@ PreprocessDropTableStmt(Node *node, const char *queryString,
|
||||||
Assert(dropTableStatement->removeType == OBJECT_TABLE);
|
Assert(dropTableStatement->removeType == OBJECT_TABLE);
|
||||||
|
|
||||||
List *tableNameList = NULL;
|
List *tableNameList = NULL;
|
||||||
foreach_ptr(tableNameList, dropTableStatement->objects)
|
foreach_declared_ptr(tableNameList, dropTableStatement->objects)
|
||||||
{
|
{
|
||||||
RangeVar *tableRangeVar = makeRangeVarFromNameList(tableNameList);
|
RangeVar *tableRangeVar = makeRangeVarFromNameList(tableNameList);
|
||||||
bool missingOK = true;
|
bool missingOK = true;
|
||||||
|
@ -199,7 +202,7 @@ PreprocessDropTableStmt(Node *node, const char *queryString,
|
||||||
SendCommandToWorkersWithMetadata(DISABLE_DDL_PROPAGATION);
|
SendCommandToWorkersWithMetadata(DISABLE_DDL_PROPAGATION);
|
||||||
|
|
||||||
Oid partitionRelationId = InvalidOid;
|
Oid partitionRelationId = InvalidOid;
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
foreach_declared_oid(partitionRelationId, partitionList)
|
||||||
{
|
{
|
||||||
char *detachPartitionCommand =
|
char *detachPartitionCommand =
|
||||||
GenerateDetachPartitionCommand(partitionRelationId);
|
GenerateDetachPartitionCommand(partitionRelationId);
|
||||||
|
@ -260,7 +263,7 @@ PostprocessCreateTableStmt(CreateStmt *createStatement, const char *queryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeVar *parentRelation = NULL;
|
RangeVar *parentRelation = NULL;
|
||||||
foreach_ptr(parentRelation, createStatement->inhRelations)
|
foreach_declared_ptr(parentRelation, createStatement->inhRelations)
|
||||||
{
|
{
|
||||||
Oid parentRelationId = RangeVarGetRelid(parentRelation, NoLock,
|
Oid parentRelationId = RangeVarGetRelid(parentRelation, NoLock,
|
||||||
missingOk);
|
missingOk);
|
||||||
|
@ -477,7 +480,7 @@ PreprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement,
|
||||||
{
|
{
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
AlterTableCmd *alterTableCommand = NULL;
|
AlterTableCmd *alterTableCommand = NULL;
|
||||||
foreach_ptr(alterTableCommand, commandList)
|
foreach_declared_ptr(alterTableCommand, commandList)
|
||||||
{
|
{
|
||||||
if (alterTableCommand->subtype == AT_AttachPartition)
|
if (alterTableCommand->subtype == AT_AttachPartition)
|
||||||
{
|
{
|
||||||
|
@ -789,7 +792,7 @@ ChooseForeignKeyConstraintNameAddition(List *columnNames)
|
||||||
|
|
||||||
String *columnNameString = NULL;
|
String *columnNameString = NULL;
|
||||||
|
|
||||||
foreach_ptr(columnNameString, columnNames)
|
foreach_declared_ptr(columnNameString, columnNames)
|
||||||
{
|
{
|
||||||
const char *name = strVal(columnNameString);
|
const char *name = strVal(columnNameString);
|
||||||
|
|
||||||
|
@ -1150,7 +1153,6 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
{
|
{
|
||||||
AlterTableStmt *stmtCopy = copyObject(alterTableStatement);
|
AlterTableStmt *stmtCopy = copyObject(alterTableStatement);
|
||||||
stmtCopy->objtype = OBJECT_SEQUENCE;
|
stmtCopy->objtype = OBJECT_SEQUENCE;
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* it must be ALTER TABLE .. OWNER TO ..
|
* it must be ALTER TABLE .. OWNER TO ..
|
||||||
|
@ -1160,16 +1162,6 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
*/
|
*/
|
||||||
return PreprocessSequenceAlterTableStmt((Node *) stmtCopy, alterTableCommand,
|
return PreprocessSequenceAlterTableStmt((Node *) stmtCopy, alterTableCommand,
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* it must be ALTER TABLE .. OWNER TO .. command
|
|
||||||
* since this is the only ALTER command of a sequence that
|
|
||||||
* passes through an AlterTableStmt
|
|
||||||
*/
|
|
||||||
return PreprocessAlterSequenceOwnerStmt((Node *) stmtCopy, alterTableCommand,
|
|
||||||
processUtilityContext);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (relKind == RELKIND_VIEW)
|
else if (relKind == RELKIND_VIEW)
|
||||||
{
|
{
|
||||||
|
@ -1311,7 +1303,7 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
AlterTableCmd *newCmd = makeNode(AlterTableCmd);
|
AlterTableCmd *newCmd = makeNode(AlterTableCmd);
|
||||||
|
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, commandList)
|
foreach_declared_ptr(command, commandList)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -1415,7 +1407,7 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
List *columnConstraints = columnDefinition->constraints;
|
List *columnConstraints = columnDefinition->constraints;
|
||||||
|
|
||||||
Constraint *constraint = NULL;
|
Constraint *constraint = NULL;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_FOREIGN)
|
if (constraint->contype == CONSTR_FOREIGN)
|
||||||
{
|
{
|
||||||
|
@ -1439,7 +1431,7 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
deparseAT = true;
|
deparseAT = true;
|
||||||
|
|
||||||
constraint = NULL;
|
constraint = NULL;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (ConstrTypeCitusCanDefaultName(constraint->contype))
|
if (ConstrTypeCitusCanDefaultName(constraint->contype))
|
||||||
{
|
{
|
||||||
|
@ -1464,7 +1456,7 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
*/
|
*/
|
||||||
constraint = NULL;
|
constraint = NULL;
|
||||||
int constraintIdx = 0;
|
int constraintIdx = 0;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_DEFAULT)
|
if (constraint->contype == CONSTR_DEFAULT)
|
||||||
{
|
{
|
||||||
|
@ -1693,7 +1685,7 @@ DeparserSupportsAlterTableAddColumn(AlterTableStmt *alterTableStatement,
|
||||||
{
|
{
|
||||||
ColumnDef *columnDefinition = (ColumnDef *) addColumnSubCommand->def;
|
ColumnDef *columnDefinition = (ColumnDef *) addColumnSubCommand->def;
|
||||||
Constraint *constraint = NULL;
|
Constraint *constraint = NULL;
|
||||||
foreach_ptr(constraint, columnDefinition->constraints)
|
foreach_declared_ptr(constraint, columnDefinition->constraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_CHECK)
|
if (constraint->contype == CONSTR_CHECK)
|
||||||
{
|
{
|
||||||
|
@ -1789,7 +1781,7 @@ static bool
|
||||||
RelationIdListContainsCitusTableType(List *relationIdList, CitusTableType citusTableType)
|
RelationIdListContainsCitusTableType(List *relationIdList, CitusTableType citusTableType)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
if (IsCitusTableType(relationId, citusTableType))
|
if (IsCitusTableType(relationId, citusTableType))
|
||||||
{
|
{
|
||||||
|
@ -1809,7 +1801,7 @@ static bool
|
||||||
RelationIdListContainsPostgresTable(List *relationIdList)
|
RelationIdListContainsPostgresTable(List *relationIdList)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
if (OidIsValid(relationId) && !IsCitusTable(relationId))
|
if (OidIsValid(relationId) && !IsCitusTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -1848,7 +1840,7 @@ ConvertPostgresLocalTablesToCitusLocalTables(AlterTableStmt *alterTableStatement
|
||||||
* change in below loop due to CreateCitusLocalTable.
|
* change in below loop due to CreateCitusLocalTable.
|
||||||
*/
|
*/
|
||||||
RangeVar *relationRangeVar;
|
RangeVar *relationRangeVar;
|
||||||
foreach_ptr(relationRangeVar, relationRangeVarList)
|
foreach_declared_ptr(relationRangeVar, relationRangeVarList)
|
||||||
{
|
{
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
LOCKMODE lockMode = AlterTableGetLockLevel(commandList);
|
LOCKMODE lockMode = AlterTableGetLockLevel(commandList);
|
||||||
|
@ -1976,7 +1968,7 @@ RangeVarListHasLocalRelationConvertedByUser(List *relationRangeVarList,
|
||||||
AlterTableStmt *alterTableStatement)
|
AlterTableStmt *alterTableStatement)
|
||||||
{
|
{
|
||||||
RangeVar *relationRangeVar;
|
RangeVar *relationRangeVar;
|
||||||
foreach_ptr(relationRangeVar, relationRangeVarList)
|
foreach_declared_ptr(relationRangeVar, relationRangeVarList)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Here we iterate the relation list, and if at least one of the relations
|
* Here we iterate the relation list, and if at least one of the relations
|
||||||
|
@ -2073,7 +2065,7 @@ GetAlterTableAddFKeyConstraintList(AlterTableStmt *alterTableStatement)
|
||||||
|
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, commandList)
|
foreach_declared_ptr(command, commandList)
|
||||||
{
|
{
|
||||||
List *commandForeignKeyConstraintList =
|
List *commandForeignKeyConstraintList =
|
||||||
GetAlterTableCommandFKeyConstraintList(command);
|
GetAlterTableCommandFKeyConstraintList(command);
|
||||||
|
@ -2113,7 +2105,7 @@ GetAlterTableCommandFKeyConstraintList(AlterTableCmd *command)
|
||||||
List *columnConstraints = columnDefinition->constraints;
|
List *columnConstraints = columnDefinition->constraints;
|
||||||
|
|
||||||
Constraint *constraint = NULL;
|
Constraint *constraint = NULL;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_FOREIGN)
|
if (constraint->contype == CONSTR_FOREIGN)
|
||||||
{
|
{
|
||||||
|
@ -2136,7 +2128,7 @@ GetRangeVarListFromFKeyConstraintList(List *fKeyConstraintList)
|
||||||
List *rightRelationRangeVarList = NIL;
|
List *rightRelationRangeVarList = NIL;
|
||||||
|
|
||||||
Constraint *fKeyConstraint = NULL;
|
Constraint *fKeyConstraint = NULL;
|
||||||
foreach_ptr(fKeyConstraint, fKeyConstraintList)
|
foreach_declared_ptr(fKeyConstraint, fKeyConstraintList)
|
||||||
{
|
{
|
||||||
RangeVar *rightRelationRangeVar = fKeyConstraint->pktable;
|
RangeVar *rightRelationRangeVar = fKeyConstraint->pktable;
|
||||||
rightRelationRangeVarList = lappend(rightRelationRangeVarList,
|
rightRelationRangeVarList = lappend(rightRelationRangeVarList,
|
||||||
|
@ -2157,7 +2149,7 @@ GetRelationIdListFromRangeVarList(List *rangeVarList, LOCKMODE lockMode, bool mi
|
||||||
List *relationIdList = NIL;
|
List *relationIdList = NIL;
|
||||||
|
|
||||||
RangeVar *rangeVar = NULL;
|
RangeVar *rangeVar = NULL;
|
||||||
foreach_ptr(rangeVar, rangeVarList)
|
foreach_declared_ptr(rangeVar, rangeVarList)
|
||||||
{
|
{
|
||||||
Oid rightRelationId = RangeVarGetRelid(rangeVar, lockMode, missingOk);
|
Oid rightRelationId = RangeVarGetRelid(rangeVar, lockMode, missingOk);
|
||||||
relationIdList = lappend_oid(relationIdList, rightRelationId);
|
relationIdList = lappend_oid(relationIdList, rightRelationId);
|
||||||
|
@ -2231,7 +2223,7 @@ AlterTableDropsForeignKey(AlterTableStmt *alterTableStatement)
|
||||||
Oid relationId = AlterTableLookupRelation(alterTableStatement, lockmode);
|
Oid relationId = AlterTableLookupRelation(alterTableStatement, lockmode);
|
||||||
|
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, alterTableStatement->cmds)
|
foreach_declared_ptr(command, alterTableStatement->cmds)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -2293,7 +2285,7 @@ AnyForeignKeyDependsOnIndex(Oid indexId)
|
||||||
GetPgDependTuplesForDependingObjects(dependentObjectClassId, dependentObjectId);
|
GetPgDependTuplesForDependingObjects(dependentObjectClassId, dependentObjectId);
|
||||||
|
|
||||||
HeapTuple dependencyTuple = NULL;
|
HeapTuple dependencyTuple = NULL;
|
||||||
foreach_ptr(dependencyTuple, dependencyTupleList)
|
foreach_declared_ptr(dependencyTuple, dependencyTupleList)
|
||||||
{
|
{
|
||||||
Form_pg_depend dependencyForm = (Form_pg_depend) GETSTRUCT(dependencyTuple);
|
Form_pg_depend dependencyForm = (Form_pg_depend) GETSTRUCT(dependencyTuple);
|
||||||
Oid dependingClassId = dependencyForm->classid;
|
Oid dependingClassId = dependencyForm->classid;
|
||||||
|
@ -2481,7 +2473,7 @@ SkipForeignKeyValidationIfConstraintIsFkey(AlterTableStmt *alterTableStatement,
|
||||||
* shards anyway.
|
* shards anyway.
|
||||||
*/
|
*/
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, alterTableStatement->cmds)
|
foreach_declared_ptr(command, alterTableStatement->cmds)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -2562,7 +2554,7 @@ ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement)
|
||||||
/* then check if any of subcommands drop partition column.*/
|
/* then check if any of subcommands drop partition column.*/
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, commandList)
|
foreach_declared_ptr(command, commandList)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
if (alterTableType == AT_DropColumn)
|
if (alterTableType == AT_DropColumn)
|
||||||
|
@ -2631,7 +2623,7 @@ PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
|
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, commandList)
|
foreach_declared_ptr(command, commandList)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -2667,7 +2659,7 @@ PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
}
|
}
|
||||||
|
|
||||||
Constraint *constraint = NULL;
|
Constraint *constraint = NULL;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->conname == NULL &&
|
if (constraint->conname == NULL &&
|
||||||
(constraint->contype == CONSTR_PRIMARY ||
|
(constraint->contype == CONSTR_PRIMARY ||
|
||||||
|
@ -2687,7 +2679,7 @@ PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
* that sequence is supported
|
* that sequence is supported
|
||||||
*/
|
*/
|
||||||
constraint = NULL;
|
constraint = NULL;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_DEFAULT)
|
if (constraint->contype == CONSTR_DEFAULT)
|
||||||
{
|
{
|
||||||
|
@ -2799,7 +2791,7 @@ FixAlterTableStmtIndexNames(AlterTableStmt *alterTableStatement)
|
||||||
|
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, commandList)
|
foreach_declared_ptr(command, commandList)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -3050,11 +3042,15 @@ ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command,
|
||||||
else if (constraint->contype == CONSTR_FOREIGN)
|
else if (constraint->contype == CONSTR_FOREIGN)
|
||||||
{
|
{
|
||||||
RangeVar *referencedTable = constraint->pktable;
|
RangeVar *referencedTable = constraint->pktable;
|
||||||
char *referencedColumn = strVal(lfirst(list_head(constraint->pk_attrs)));
|
|
||||||
Oid referencedRelationId = RangeVarGetRelid(referencedTable, NoLock, false);
|
Oid referencedRelationId = RangeVarGetRelid(referencedTable, NoLock, false);
|
||||||
|
|
||||||
appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s(%s)", colName,
|
appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s", colName,
|
||||||
get_rel_name(referencedRelationId), referencedColumn);
|
get_rel_name(referencedRelationId));
|
||||||
|
|
||||||
|
if (list_length(constraint->pk_attrs) > 0)
|
||||||
|
{
|
||||||
|
AppendColumnNameList(errHint, constraint->pk_attrs);
|
||||||
|
}
|
||||||
|
|
||||||
if (constraint->fk_del_action == FKCONSTR_ACTION_SETNULL)
|
if (constraint->fk_del_action == FKCONSTR_ACTION_SETNULL)
|
||||||
{
|
{
|
||||||
|
@ -3158,7 +3154,7 @@ ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod,
|
||||||
List *indexOidList = RelationGetIndexList(relation);
|
List *indexOidList = RelationGetIndexList(relation);
|
||||||
|
|
||||||
Oid indexOid = InvalidOid;
|
Oid indexOid = InvalidOid;
|
||||||
foreach_oid(indexOid, indexOidList)
|
foreach_declared_oid(indexOid, indexOidList)
|
||||||
{
|
{
|
||||||
Relation indexDesc = index_open(indexOid, RowExclusiveLock);
|
Relation indexDesc = index_open(indexOid, RowExclusiveLock);
|
||||||
bool hasDistributionColumn = false;
|
bool hasDistributionColumn = false;
|
||||||
|
@ -3303,7 +3299,7 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
|
|
||||||
/* error out if any of the subcommands are unsupported */
|
/* error out if any of the subcommands are unsupported */
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, commandList)
|
foreach_declared_ptr(command, commandList)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -3378,7 +3374,7 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
|
|
||||||
|
|
||||||
Constraint *columnConstraint = NULL;
|
Constraint *columnConstraint = NULL;
|
||||||
foreach_ptr(columnConstraint, column->constraints)
|
foreach_declared_ptr(columnConstraint, column->constraints)
|
||||||
{
|
{
|
||||||
if (columnConstraint->contype == CONSTR_IDENTITY)
|
if (columnConstraint->contype == CONSTR_IDENTITY)
|
||||||
{
|
{
|
||||||
|
@ -3410,7 +3406,7 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
List *columnConstraints = column->constraints;
|
List *columnConstraints = column->constraints;
|
||||||
|
|
||||||
Constraint *constraint = NULL;
|
Constraint *constraint = NULL;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_DEFAULT)
|
if (constraint->contype == CONSTR_DEFAULT)
|
||||||
{
|
{
|
||||||
|
@ -3657,9 +3653,36 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
case AT_SetAccessMethod:
|
case AT_SetExpression:
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg(
|
||||||
|
"ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION commands "
|
||||||
|
"are currently unsupported.")));
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case AT_SetAccessMethod:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If command->name == NULL, that means the user is trying to use
|
||||||
|
* ALTER TABLE ... SET ACCESS METHOD DEFAULT
|
||||||
|
* which we don't support currently.
|
||||||
|
*/
|
||||||
|
if (command->name == NULL)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg(
|
||||||
|
"DEFAULT option in ALTER TABLE ... SET ACCESS METHOD "
|
||||||
|
"is currently unsupported."),
|
||||||
|
errhint(
|
||||||
|
"You can rerun the command by explicitly writing the access method name.")));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case AT_SetNotNull:
|
case AT_SetNotNull:
|
||||||
case AT_ReplicaIdentity:
|
case AT_ReplicaIdentity:
|
||||||
case AT_ChangeOwner:
|
case AT_ChangeOwner:
|
||||||
|
@ -3763,7 +3786,7 @@ SetupExecutionModeForAlterTable(Oid relationId, AlterTableCmd *command)
|
||||||
List *columnConstraints = columnDefinition->constraints;
|
List *columnConstraints = columnDefinition->constraints;
|
||||||
|
|
||||||
Constraint *constraint = NULL;
|
Constraint *constraint = NULL;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_declared_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_FOREIGN)
|
if (constraint->contype == CONSTR_FOREIGN)
|
||||||
{
|
{
|
||||||
|
@ -3963,10 +3986,10 @@ SetInterShardDDLTaskPlacementList(Task *task, ShardInterval *leftShardInterval,
|
||||||
List *intersectedPlacementList = NIL;
|
List *intersectedPlacementList = NIL;
|
||||||
|
|
||||||
ShardPlacement *leftShardPlacement = NULL;
|
ShardPlacement *leftShardPlacement = NULL;
|
||||||
foreach_ptr(leftShardPlacement, leftShardPlacementList)
|
foreach_declared_ptr(leftShardPlacement, leftShardPlacementList)
|
||||||
{
|
{
|
||||||
ShardPlacement *rightShardPlacement = NULL;
|
ShardPlacement *rightShardPlacement = NULL;
|
||||||
foreach_ptr(rightShardPlacement, rightShardPlacementList)
|
foreach_declared_ptr(rightShardPlacement, rightShardPlacementList)
|
||||||
{
|
{
|
||||||
if (leftShardPlacement->nodeId == rightShardPlacement->nodeId)
|
if (leftShardPlacement->nodeId == rightShardPlacement->nodeId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "fmgr.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
|
@ -22,7 +24,6 @@
|
||||||
#include "commands/comment.h"
|
#include "commands/comment.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
#include "fmgr.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "tsearch/ts_cache.h"
|
#include "tsearch/ts_cache.h"
|
||||||
#include "tsearch/ts_public.h"
|
#include "tsearch/ts_public.h"
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/table.h"
|
#include "access/table.h"
|
||||||
|
@ -18,6 +17,14 @@
|
||||||
#include "catalog/pg_trigger.h"
|
#include "catalog/pg_trigger.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/fmgrprotos.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
@ -29,11 +36,6 @@
|
||||||
#include "distributed/namespace_utils.h"
|
#include "distributed/namespace_utils.h"
|
||||||
#include "distributed/shard_utils.h"
|
#include "distributed/shard_utils.h"
|
||||||
#include "distributed/worker_protocol.h"
|
#include "distributed/worker_protocol.h"
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/fmgrprotos.h"
|
|
||||||
#include "utils/fmgroids.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* appropriate lock modes for the owner relation according to postgres */
|
/* appropriate lock modes for the owner relation according to postgres */
|
||||||
|
@ -55,9 +57,6 @@ static void ExtractDropStmtTriggerAndRelationName(DropStmt *dropTriggerStmt,
|
||||||
static void ErrorIfDropStmtDropsMultipleTriggers(DropStmt *dropTriggerStmt);
|
static void ErrorIfDropStmtDropsMultipleTriggers(DropStmt *dropTriggerStmt);
|
||||||
static char * GetTriggerNameById(Oid triggerId);
|
static char * GetTriggerNameById(Oid triggerId);
|
||||||
static int16 GetTriggerTypeById(Oid triggerId);
|
static int16 GetTriggerTypeById(Oid triggerId);
|
||||||
#if (PG_VERSION_NUM < PG_VERSION_15)
|
|
||||||
static void ErrorOutIfCloneTrigger(Oid tgrelid, const char *tgname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* GUC that overrides trigger checks for distributed tables and reference tables */
|
/* GUC that overrides trigger checks for distributed tables and reference tables */
|
||||||
|
@ -79,7 +78,7 @@ GetExplicitTriggerCommandList(Oid relationId)
|
||||||
List *triggerIdList = GetExplicitTriggerIdList(relationId);
|
List *triggerIdList = GetExplicitTriggerIdList(relationId);
|
||||||
|
|
||||||
Oid triggerId = InvalidOid;
|
Oid triggerId = InvalidOid;
|
||||||
foreach_oid(triggerId, triggerIdList)
|
foreach_declared_oid(triggerId, triggerIdList)
|
||||||
{
|
{
|
||||||
bool prettyOutput = false;
|
bool prettyOutput = false;
|
||||||
Datum commandText = DirectFunctionCall2(pg_get_triggerdef_ext,
|
Datum commandText = DirectFunctionCall2(pg_get_triggerdef_ext,
|
||||||
|
@ -402,40 +401,6 @@ CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt, char *schemaNam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PreprocessAlterTriggerRenameStmt is called before a ALTER TRIGGER RENAME
|
|
||||||
* command has been executed by standard process utility. This function errors
|
|
||||||
* out if we are trying to rename a child trigger on a partition of a distributed
|
|
||||||
* table. In PG15, this is not allowed anyway.
|
|
||||||
*/
|
|
||||||
List *
|
|
||||||
PreprocessAlterTriggerRenameStmt(Node *node, const char *queryString,
|
|
||||||
ProcessUtilityContext processUtilityContext)
|
|
||||||
{
|
|
||||||
#if (PG_VERSION_NUM < PG_VERSION_15)
|
|
||||||
RenameStmt *renameTriggerStmt = castNode(RenameStmt, node);
|
|
||||||
Assert(renameTriggerStmt->renameType == OBJECT_TRIGGER);
|
|
||||||
|
|
||||||
RangeVar *relation = renameTriggerStmt->relation;
|
|
||||||
|
|
||||||
bool missingOk = false;
|
|
||||||
Oid relationId = RangeVarGetRelid(relation, ALTER_TRIGGER_LOCK_MODE, missingOk);
|
|
||||||
|
|
||||||
if (!IsCitusTable(relationId))
|
|
||||||
{
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnsureCoordinator();
|
|
||||||
ErrorOutForTriggerIfNotSupported(relationId);
|
|
||||||
|
|
||||||
ErrorOutIfCloneTrigger(relationId, renameTriggerStmt->subname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PostprocessAlterTriggerRenameStmt is called after a ALTER TRIGGER RENAME
|
* PostprocessAlterTriggerRenameStmt is called after a ALTER TRIGGER RENAME
|
||||||
* command has been executed by standard process utility. This function errors
|
* command has been executed by standard process utility. This function errors
|
||||||
|
@ -740,7 +705,7 @@ ErrorIfRelationHasUnsupportedTrigger(Oid relationId)
|
||||||
List *relationTriggerList = GetExplicitTriggerIdList(relationId);
|
List *relationTriggerList = GetExplicitTriggerIdList(relationId);
|
||||||
|
|
||||||
Oid triggerId = InvalidOid;
|
Oid triggerId = InvalidOid;
|
||||||
foreach_oid(triggerId, relationTriggerList)
|
foreach_declared_oid(triggerId, relationTriggerList)
|
||||||
{
|
{
|
||||||
ObjectAddress triggerObjectAddress = InvalidObjectAddress;
|
ObjectAddress triggerObjectAddress = InvalidObjectAddress;
|
||||||
ObjectAddressSet(triggerObjectAddress, TriggerRelationId, triggerId);
|
ObjectAddressSet(triggerObjectAddress, TriggerRelationId, triggerId);
|
||||||
|
@ -757,64 +722,6 @@ ErrorIfRelationHasUnsupportedTrigger(Oid relationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM < PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ErrorOutIfCloneTrigger is a helper function to error
|
|
||||||
* out if we are trying to rename a child trigger on a
|
|
||||||
* partition of a distributed table.
|
|
||||||
* A lot of this code is borrowed from PG15 because
|
|
||||||
* renaming clone triggers isn't allowed in PG15 anymore.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ErrorOutIfCloneTrigger(Oid tgrelid, const char *tgname)
|
|
||||||
{
|
|
||||||
HeapTuple tuple;
|
|
||||||
ScanKeyData key[2];
|
|
||||||
|
|
||||||
Relation tgrel = table_open(TriggerRelationId, RowExclusiveLock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search for the trigger to modify.
|
|
||||||
*/
|
|
||||||
ScanKeyInit(&key[0],
|
|
||||||
Anum_pg_trigger_tgrelid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(tgrelid));
|
|
||||||
ScanKeyInit(&key[1],
|
|
||||||
Anum_pg_trigger_tgname,
|
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
|
||||||
CStringGetDatum(tgname));
|
|
||||||
SysScanDesc tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
|
|
||||||
NULL, 2, key);
|
|
||||||
|
|
||||||
if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
|
||||||
{
|
|
||||||
Form_pg_trigger trigform = (Form_pg_trigger) GETSTRUCT(tuple);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the trigger descends from a trigger on a parent partitioned
|
|
||||||
* table, reject the rename.
|
|
||||||
* Appended shard ids to find the trigger on the partition's shards
|
|
||||||
* are not correct. Hence we would fail to find the trigger on the
|
|
||||||
* partition's shard.
|
|
||||||
*/
|
|
||||||
if (OidIsValid(trigform->tgparentid))
|
|
||||||
{
|
|
||||||
ereport(ERROR, (
|
|
||||||
errmsg(
|
|
||||||
"cannot rename child triggers on distributed partitions")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
systable_endscan(tgscan);
|
|
||||||
table_close(tgrel, RowExclusiveLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetDropTriggerStmtRelation takes a DropStmt for a trigger object and returns
|
* GetDropTriggerStmtRelation takes a DropStmt for a trigger object and returns
|
||||||
* RangeVar for the relation that owns the trigger.
|
* RangeVar for the relation that owns the trigger.
|
||||||
|
|
|
@ -9,12 +9,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
|
#include "storage/lmgr.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/regproc.h"
|
||||||
|
#include "utils/rel.h"
|
||||||
|
|
||||||
#include "distributed/adaptive_executor.h"
|
#include "distributed/adaptive_executor.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
|
@ -31,13 +38,8 @@
|
||||||
#include "distributed/reference_table_utils.h"
|
#include "distributed/reference_table_utils.h"
|
||||||
#include "distributed/resource_lock.h"
|
#include "distributed/resource_lock.h"
|
||||||
#include "distributed/transaction_management.h"
|
#include "distributed/transaction_management.h"
|
||||||
#include "distributed/worker_transaction.h"
|
|
||||||
#include "distributed/worker_shard_visibility.h"
|
#include "distributed/worker_shard_visibility.h"
|
||||||
#include "storage/lmgr.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/regproc.h"
|
|
||||||
#include "utils/rel.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Local functions forward declarations for unsupported command checks */
|
/* Local functions forward declarations for unsupported command checks */
|
||||||
|
@ -133,7 +135,7 @@ TruncateTaskList(Oid relationId)
|
||||||
LockShardListMetadata(shardIntervalList, ShareLock);
|
LockShardListMetadata(shardIntervalList, ShareLock);
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardIntervalList)
|
foreach_declared_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
uint64 shardId = shardInterval->shardId;
|
uint64 shardId = shardInterval->shardId;
|
||||||
char *shardRelationName = pstrdup(relationName);
|
char *shardRelationName = pstrdup(relationName);
|
||||||
|
@ -262,7 +264,7 @@ ErrorIfUnsupportedTruncateStmt(TruncateStmt *truncateStatement)
|
||||||
{
|
{
|
||||||
List *relationList = truncateStatement->relations;
|
List *relationList = truncateStatement->relations;
|
||||||
RangeVar *rangeVar = NULL;
|
RangeVar *rangeVar = NULL;
|
||||||
foreach_ptr(rangeVar, relationList)
|
foreach_declared_ptr(rangeVar, relationList)
|
||||||
{
|
{
|
||||||
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, false);
|
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, false);
|
||||||
|
|
||||||
|
@ -292,7 +294,7 @@ static void
|
||||||
EnsurePartitionTableNotReplicatedForTruncate(TruncateStmt *truncateStatement)
|
EnsurePartitionTableNotReplicatedForTruncate(TruncateStmt *truncateStatement)
|
||||||
{
|
{
|
||||||
RangeVar *rangeVar = NULL;
|
RangeVar *rangeVar = NULL;
|
||||||
foreach_ptr(rangeVar, truncateStatement->relations)
|
foreach_declared_ptr(rangeVar, truncateStatement->relations)
|
||||||
{
|
{
|
||||||
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, false);
|
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, false);
|
||||||
|
|
||||||
|
@ -320,7 +322,7 @@ ExecuteTruncateStmtSequentialIfNecessary(TruncateStmt *command)
|
||||||
bool failOK = false;
|
bool failOK = false;
|
||||||
|
|
||||||
RangeVar *rangeVar = NULL;
|
RangeVar *rangeVar = NULL;
|
||||||
foreach_ptr(rangeVar, relationList)
|
foreach_declared_ptr(rangeVar, relationList)
|
||||||
{
|
{
|
||||||
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, failOK);
|
Oid relationId = RangeVarGetRelid(rangeVar, NoLock, failOK);
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
|
@ -52,6 +52,18 @@
|
||||||
#include "catalog/pg_enum.h"
|
#include "catalog/pg_enum.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "parser/parse_type.h"
|
||||||
|
#include "storage/lmgr.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/regproc.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
#include "utils/typcache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/citus_safe_lib.h"
|
#include "distributed/citus_safe_lib.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
@ -64,20 +76,10 @@
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "distributed/remote_commands.h"
|
#include "distributed/remote_commands.h"
|
||||||
#include "distributed/transaction_management.h"
|
#include "distributed/transaction_management.h"
|
||||||
#include "distributed/worker_create_or_replace.h"
|
|
||||||
#include "distributed/version_compat.h"
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_create_or_replace.h"
|
||||||
#include "distributed/worker_manager.h"
|
#include "distributed/worker_manager.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "miscadmin.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
|
||||||
#include "parser/parse_type.h"
|
|
||||||
#include "storage/lmgr.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/fmgroids.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/regproc.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
#include "utils/typcache.h"
|
|
||||||
|
|
||||||
#define AlterEnumIsRename(stmt) (stmt->oldVal != NULL)
|
#define AlterEnumIsRename(stmt) (stmt->oldVal != NULL)
|
||||||
#define AlterEnumIsAddValue(stmt) (stmt->oldVal == NULL)
|
#define AlterEnumIsAddValue(stmt) (stmt->oldVal == NULL)
|
||||||
|
|
|
@ -25,9 +25,8 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/attnum.h"
|
#include "access/attnum.h"
|
||||||
|
@ -35,11 +34,25 @@
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "citus_version.h"
|
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
|
#include "foreign/foreign.h"
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "nodes/pg_list.h"
|
||||||
|
#include "tcop/utility.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/inval.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "citus_version.h"
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/adaptive_executor.h"
|
#include "distributed/adaptive_executor.h"
|
||||||
#include "distributed/backend_data.h"
|
#include "distributed/backend_data.h"
|
||||||
#include "distributed/citus_depended_object.h"
|
#include "distributed/citus_depended_object.h"
|
||||||
|
@ -48,19 +61,19 @@
|
||||||
#include "distributed/commands/multi_copy.h"
|
#include "distributed/commands/multi_copy.h"
|
||||||
#include "distributed/commands/utility_hook.h" /* IWYU pragma: keep */
|
#include "distributed/commands/utility_hook.h" /* IWYU pragma: keep */
|
||||||
#include "distributed/coordinator_protocol.h"
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/deparse_shard_query.h"
|
#include "distributed/deparse_shard_query.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/executor_util.h"
|
#include "distributed/executor_util.h"
|
||||||
#include "distributed/foreign_key_relationship.h"
|
#include "distributed/foreign_key_relationship.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
#include "distributed/maintenanced.h"
|
#include "distributed/maintenanced.h"
|
||||||
#include "distributed/multi_logical_replication.h"
|
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
#include "distributed/multi_explain.h"
|
#include "distributed/multi_explain.h"
|
||||||
|
#include "distributed/multi_logical_replication.h"
|
||||||
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/multi_physical_planner.h"
|
#include "distributed/multi_physical_planner.h"
|
||||||
#include "distributed/reference_table_utils.h"
|
#include "distributed/reference_table_utils.h"
|
||||||
#include "distributed/resource_lock.h"
|
#include "distributed/resource_lock.h"
|
||||||
|
@ -69,17 +82,6 @@
|
||||||
#include "distributed/version_compat.h"
|
#include "distributed/version_compat.h"
|
||||||
#include "distributed/worker_shard_visibility.h"
|
#include "distributed/worker_shard_visibility.h"
|
||||||
#include "distributed/worker_transaction.h"
|
#include "distributed/worker_transaction.h"
|
||||||
#include "foreign/foreign.h"
|
|
||||||
#include "lib/stringinfo.h"
|
|
||||||
#include "nodes/parsenodes.h"
|
|
||||||
#include "nodes/pg_list.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
|
||||||
#include "tcop/utility.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/fmgroids.h"
|
|
||||||
#include "utils/inval.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/syscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool EnableDDLPropagation = true; /* ddl propagation is enabled */
|
bool EnableDDLPropagation = true; /* ddl propagation is enabled */
|
||||||
|
@ -434,7 +436,7 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
|
||||||
bool analyze = false;
|
bool analyze = false;
|
||||||
|
|
||||||
DefElem *option = NULL;
|
DefElem *option = NULL;
|
||||||
foreach_ptr(option, explainStmt->options)
|
foreach_declared_ptr(option, explainStmt->options)
|
||||||
{
|
{
|
||||||
if (strcmp(option->defname, "analyze") == 0)
|
if (strcmp(option->defname, "analyze") == 0)
|
||||||
{
|
{
|
||||||
|
@ -675,7 +677,7 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
|
||||||
{
|
{
|
||||||
AlterTableStmt *alterTableStmt = (AlterTableStmt *) parsetree;
|
AlterTableStmt *alterTableStmt = (AlterTableStmt *) parsetree;
|
||||||
AlterTableCmd *command = NULL;
|
AlterTableCmd *command = NULL;
|
||||||
foreach_ptr(command, alterTableStmt->cmds)
|
foreach_declared_ptr(command, alterTableStmt->cmds)
|
||||||
{
|
{
|
||||||
AlterTableType alterTableType = command->subtype;
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
@ -874,7 +876,7 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
|
||||||
}
|
}
|
||||||
|
|
||||||
DDLJob *ddlJob = NULL;
|
DDLJob *ddlJob = NULL;
|
||||||
foreach_ptr(ddlJob, ddlJobs)
|
foreach_declared_ptr(ddlJob, ddlJobs)
|
||||||
{
|
{
|
||||||
ExecuteDistributedDDLJob(ddlJob);
|
ExecuteDistributedDDLJob(ddlJob);
|
||||||
}
|
}
|
||||||
|
@ -934,7 +936,7 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
|
||||||
{
|
{
|
||||||
List *addresses = GetObjectAddressListFromParseTree(parsetree, false, true);
|
List *addresses = GetObjectAddressListFromParseTree(parsetree, false, true);
|
||||||
ObjectAddress *address = NULL;
|
ObjectAddress *address = NULL;
|
||||||
foreach_ptr(address, addresses)
|
foreach_declared_ptr(address, addresses)
|
||||||
{
|
{
|
||||||
MarkObjectDistributed(address);
|
MarkObjectDistributed(address);
|
||||||
TrackPropagatedObject(address);
|
TrackPropagatedObject(address);
|
||||||
|
@ -957,7 +959,7 @@ UndistributeDisconnectedCitusLocalTables(void)
|
||||||
citusLocalTableIdList = SortList(citusLocalTableIdList, CompareOids);
|
citusLocalTableIdList = SortList(citusLocalTableIdList, CompareOids);
|
||||||
|
|
||||||
Oid citusLocalTableId = InvalidOid;
|
Oid citusLocalTableId = InvalidOid;
|
||||||
foreach_oid(citusLocalTableId, citusLocalTableIdList)
|
foreach_declared_oid(citusLocalTableId, citusLocalTableIdList)
|
||||||
{
|
{
|
||||||
/* acquire ShareRowExclusiveLock to prevent concurrent foreign key creation */
|
/* acquire ShareRowExclusiveLock to prevent concurrent foreign key creation */
|
||||||
LOCKMODE lockMode = ShareRowExclusiveLock;
|
LOCKMODE lockMode = ShareRowExclusiveLock;
|
||||||
|
@ -1339,7 +1341,7 @@ CurrentSearchPath(void)
|
||||||
bool schemaAdded = false;
|
bool schemaAdded = false;
|
||||||
|
|
||||||
Oid searchPathOid = InvalidOid;
|
Oid searchPathOid = InvalidOid;
|
||||||
foreach_oid(searchPathOid, searchPathList)
|
foreach_declared_oid(searchPathOid, searchPathList)
|
||||||
{
|
{
|
||||||
char *schemaName = get_namespace_name(searchPathOid);
|
char *schemaName = get_namespace_name(searchPathOid);
|
||||||
|
|
||||||
|
@ -1473,7 +1475,7 @@ DDLTaskList(Oid relationId, const char *commandString)
|
||||||
LockShardListMetadata(shardIntervalList, ShareLock);
|
LockShardListMetadata(shardIntervalList, ShareLock);
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardIntervalList)
|
foreach_declared_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
uint64 shardId = shardInterval->shardId;
|
uint64 shardId = shardInterval->shardId;
|
||||||
StringInfo applyCommand = makeStringInfo();
|
StringInfo applyCommand = makeStringInfo();
|
||||||
|
@ -1527,7 +1529,7 @@ NodeDDLTaskList(TargetWorkerSet targets, List *commands)
|
||||||
SetTaskQueryStringList(task, commands);
|
SetTaskQueryStringList(task, commands);
|
||||||
|
|
||||||
WorkerNode *workerNode = NULL;
|
WorkerNode *workerNode = NULL;
|
||||||
foreach_ptr(workerNode, workerNodes)
|
foreach_declared_ptr(workerNode, workerNodes)
|
||||||
{
|
{
|
||||||
ShardPlacement *targetPlacement = CitusMakeNode(ShardPlacement);
|
ShardPlacement *targetPlacement = CitusMakeNode(ShardPlacement);
|
||||||
targetPlacement->nodeName = workerNode->workerName;
|
targetPlacement->nodeName = workerNode->workerName;
|
||||||
|
|
|
@ -10,10 +10,16 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "access/xact.h"
|
||||||
|
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
|
#include "postmaster/bgworker_internals.h"
|
||||||
|
#include "storage/lmgr.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/adaptive_executor.h"
|
#include "distributed/adaptive_executor.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
@ -24,11 +30,6 @@
|
||||||
#include "distributed/resource_lock.h"
|
#include "distributed/resource_lock.h"
|
||||||
#include "distributed/transaction_management.h"
|
#include "distributed/transaction_management.h"
|
||||||
#include "distributed/version_compat.h"
|
#include "distributed/version_compat.h"
|
||||||
#include "storage/lmgr.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "postmaster/bgworker_internals.h"
|
|
||||||
#include "access/xact.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define VACUUM_PARALLEL_NOTSET -2
|
#define VACUUM_PARALLEL_NOTSET -2
|
||||||
|
@ -134,7 +135,7 @@ VacuumRelationIdList(VacuumStmt *vacuumStmt, CitusVacuumParams vacuumParams)
|
||||||
List *relationIdList = NIL;
|
List *relationIdList = NIL;
|
||||||
|
|
||||||
RangeVar *vacuumRelation = NULL;
|
RangeVar *vacuumRelation = NULL;
|
||||||
foreach_ptr(vacuumRelation, vacuumRelationList)
|
foreach_declared_ptr(vacuumRelation, vacuumRelationList)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If skip_locked option is enabled, we are skipping that relation
|
* If skip_locked option is enabled, we are skipping that relation
|
||||||
|
@ -163,7 +164,7 @@ static bool
|
||||||
IsDistributedVacuumStmt(List *vacuumRelationIdList)
|
IsDistributedVacuumStmt(List *vacuumRelationIdList)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, vacuumRelationIdList)
|
foreach_declared_oid(relationId, vacuumRelationIdList)
|
||||||
{
|
{
|
||||||
if (OidIsValid(relationId) && IsCitusTable(relationId))
|
if (OidIsValid(relationId) && IsCitusTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -187,7 +188,7 @@ ExecuteVacuumOnDistributedTables(VacuumStmt *vacuumStmt, List *relationIdList,
|
||||||
int executedVacuumCount = 0;
|
int executedVacuumCount = 0;
|
||||||
|
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_declared_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
if (IsCitusTable(relationId))
|
if (IsCitusTable(relationId))
|
||||||
{
|
{
|
||||||
|
@ -253,7 +254,7 @@ VacuumTaskList(Oid relationId, CitusVacuumParams vacuumParams, List *vacuumColum
|
||||||
LockShardListMetadata(shardIntervalList, ShareLock);
|
LockShardListMetadata(shardIntervalList, ShareLock);
|
||||||
|
|
||||||
ShardInterval *shardInterval = NULL;
|
ShardInterval *shardInterval = NULL;
|
||||||
foreach_ptr(shardInterval, shardIntervalList)
|
foreach_declared_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
uint64 shardId = shardInterval->shardId;
|
uint64 shardId = shardInterval->shardId;
|
||||||
char *shardRelationName = pstrdup(relationName);
|
char *shardRelationName = pstrdup(relationName);
|
||||||
|
@ -474,7 +475,7 @@ DeparseVacuumColumnNames(List *columnNameList)
|
||||||
appendStringInfoString(columnNames, " (");
|
appendStringInfoString(columnNames, " (");
|
||||||
|
|
||||||
String *columnName = NULL;
|
String *columnName = NULL;
|
||||||
foreach_ptr(columnName, columnNameList)
|
foreach_declared_ptr(columnName, columnNameList)
|
||||||
{
|
{
|
||||||
appendStringInfo(columnNames, "%s,", strVal(columnName));
|
appendStringInfo(columnNames, "%s,", strVal(columnName));
|
||||||
}
|
}
|
||||||
|
@ -509,7 +510,7 @@ ExtractVacuumTargetRels(VacuumStmt *vacuumStmt)
|
||||||
List *vacuumList = NIL;
|
List *vacuumList = NIL;
|
||||||
|
|
||||||
VacuumRelation *vacuumRelation = NULL;
|
VacuumRelation *vacuumRelation = NULL;
|
||||||
foreach_ptr(vacuumRelation, vacuumStmt->rels)
|
foreach_declared_ptr(vacuumRelation, vacuumStmt->rels)
|
||||||
{
|
{
|
||||||
vacuumList = lappend(vacuumList, vacuumRelation->relation);
|
vacuumList = lappend(vacuumList, vacuumRelation->relation);
|
||||||
}
|
}
|
||||||
|
@ -553,7 +554,7 @@ VacuumStmtParams(VacuumStmt *vacstmt)
|
||||||
|
|
||||||
/* Parse options list */
|
/* Parse options list */
|
||||||
DefElem *opt = NULL;
|
DefElem *opt = NULL;
|
||||||
foreach_ptr(opt, vacstmt->options)
|
foreach_declared_ptr(opt, vacstmt->options)
|
||||||
{
|
{
|
||||||
/* Parse common options for VACUUM and ANALYZE */
|
/* Parse common options for VACUUM and ANALYZE */
|
||||||
if (strcmp(opt->defname, "verbose") == 0)
|
if (strcmp(opt->defname, "verbose") == 0)
|
||||||
|
@ -726,7 +727,7 @@ ExecuteUnqualifiedVacuumTasks(VacuumStmt *vacuumStmt, CitusVacuumParams vacuumPa
|
||||||
int32 localNodeGroupId = GetLocalGroupId();
|
int32 localNodeGroupId = GetLocalGroupId();
|
||||||
|
|
||||||
WorkerNode *workerNode = NULL;
|
WorkerNode *workerNode = NULL;
|
||||||
foreach_ptr(workerNode, workerNodes)
|
foreach_declared_ptr(workerNode, workerNodes)
|
||||||
{
|
{
|
||||||
if (workerNode->groupId != localNodeGroupId)
|
if (workerNode->groupId != localNodeGroupId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,21 +9,23 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "c.h"
|
#include "c.h"
|
||||||
|
|
||||||
#include "common/string.h"
|
#include "common/string.h"
|
||||||
#include "distributed/commands.h"
|
#include "lib/ilist.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
|
||||||
#include "distributed/resource_lock.h"
|
|
||||||
#include "distributed/transaction_management.h"
|
|
||||||
#include "distributed/version_compat.h"
|
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "lib/ilist.h"
|
|
||||||
#include "utils/varlena.h"
|
#include "utils/varlena.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/remote_commands.h"
|
#include "distributed/remote_commands.h"
|
||||||
|
#include "distributed/resource_lock.h"
|
||||||
|
#include "distributed/transaction_management.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShouldPropagateSetCommand determines whether a SET or RESET command should be
|
* ShouldPropagateSetCommand determines whether a SET or RESET command should be
|
||||||
|
|
|
@ -9,23 +9,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "catalog/objectaddress.h"
|
#include "catalog/objectaddress.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
#include "distributed/commands.h"
|
|
||||||
#include "distributed/citus_ruleutils.h"
|
|
||||||
#include "distributed/commands/utility_hook.h"
|
|
||||||
#include "distributed/deparser.h"
|
|
||||||
#include "distributed/errormessage.h"
|
|
||||||
#include "distributed/listutils.h"
|
|
||||||
#include "distributed/metadata_sync.h"
|
|
||||||
#include "distributed/metadata/dependency.h"
|
|
||||||
#include "distributed/metadata/distobject.h"
|
|
||||||
#include "distributed/multi_executor.h"
|
|
||||||
#include "distributed/namespace_utils.h"
|
|
||||||
#include "distributed/worker_transaction.h"
|
|
||||||
#include "executor/spi.h"
|
#include "executor/spi.h"
|
||||||
#include "nodes/nodes.h"
|
#include "nodes/nodes.h"
|
||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
|
@ -35,6 +24,19 @@
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/errormessage.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/dependency.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/namespace_utils.h"
|
||||||
|
#include "distributed/worker_transaction.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GUC controls some restrictions for local objects. For example,
|
* GUC controls some restrictions for local objects. For example,
|
||||||
* if it is disabled, a local view with no distributed relation dependency
|
* if it is disabled, a local view with no distributed relation dependency
|
||||||
|
@ -67,7 +69,7 @@ ViewHasDistributedRelationDependency(ObjectAddress *viewObjectAddress)
|
||||||
List *dependencies = GetAllDependenciesForObject(viewObjectAddress);
|
List *dependencies = GetAllDependenciesForObject(viewObjectAddress);
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
|
|
||||||
foreach_ptr(dependency, dependencies)
|
foreach_declared_ptr(dependency, dependencies)
|
||||||
{
|
{
|
||||||
if (dependency->classId == RelationRelationId && IsAnyObjectDistributed(
|
if (dependency->classId == RelationRelationId && IsAnyObjectDistributed(
|
||||||
list_make1(dependency)))
|
list_make1(dependency)))
|
||||||
|
@ -302,7 +304,7 @@ DropViewStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess)
|
||||||
List *objectAddresses = NIL;
|
List *objectAddresses = NIL;
|
||||||
|
|
||||||
List *possiblyQualifiedViewName = NULL;
|
List *possiblyQualifiedViewName = NULL;
|
||||||
foreach_ptr(possiblyQualifiedViewName, dropStmt->objects)
|
foreach_declared_ptr(possiblyQualifiedViewName, dropStmt->objects)
|
||||||
{
|
{
|
||||||
RangeVar *viewRangeVar = makeRangeVarFromNameList(possiblyQualifiedViewName);
|
RangeVar *viewRangeVar = makeRangeVarFromNameList(possiblyQualifiedViewName);
|
||||||
Oid viewOid = RangeVarGetRelid(viewRangeVar, AccessShareLock,
|
Oid viewOid = RangeVarGetRelid(viewRangeVar, AccessShareLock,
|
||||||
|
@ -330,7 +332,7 @@ FilterNameListForDistributedViews(List *viewNamesList, bool missing_ok)
|
||||||
List *distributedViewNames = NIL;
|
List *distributedViewNames = NIL;
|
||||||
|
|
||||||
List *possiblyQualifiedViewName = NULL;
|
List *possiblyQualifiedViewName = NULL;
|
||||||
foreach_ptr(possiblyQualifiedViewName, viewNamesList)
|
foreach_declared_ptr(possiblyQualifiedViewName, viewNamesList)
|
||||||
{
|
{
|
||||||
char *viewName = NULL;
|
char *viewName = NULL;
|
||||||
char *schemaName = NULL;
|
char *schemaName = NULL;
|
||||||
|
@ -390,9 +392,7 @@ CreateViewDDLCommand(Oid viewOid)
|
||||||
static void
|
static void
|
||||||
AppendQualifiedViewNameToCreateViewCommand(StringInfo buf, Oid viewOid)
|
AppendQualifiedViewNameToCreateViewCommand(StringInfo buf, Oid viewOid)
|
||||||
{
|
{
|
||||||
char *viewName = get_rel_name(viewOid);
|
char *qualifiedViewName = generate_qualified_relation_name(viewOid);
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(viewOid));
|
|
||||||
char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName);
|
|
||||||
|
|
||||||
appendStringInfo(buf, "%s ", qualifiedViewName);
|
appendStringInfo(buf, "%s ", qualifiedViewName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
|
|
||||||
#include "access/transam.h"
|
#include "access/transam.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
|
#include "mb/pg_wchar.h"
|
||||||
|
#include "postmaster/postmaster.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
#include "distributed/backend_data.h"
|
#include "distributed/backend_data.h"
|
||||||
#include "distributed/citus_safe_lib.h"
|
#include "distributed/citus_safe_lib.h"
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
|
@ -19,10 +23,6 @@
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/worker_manager.h"
|
#include "distributed/worker_manager.h"
|
||||||
|
|
||||||
#include "postmaster/postmaster.h"
|
|
||||||
#include "mb/pg_wchar.h"
|
|
||||||
#include "utils/builtins.h"
|
|
||||||
|
|
||||||
/* stores the string representation of our node connection GUC */
|
/* stores the string representation of our node connection GUC */
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
char *NodeConninfo = "sslmode=require";
|
char *NodeConninfo = "sslmode=require";
|
||||||
|
@ -123,6 +123,10 @@ AddConnParam(const char *keyword, const char *value)
|
||||||
errmsg("ConnParams arrays bound check failed")));
|
errmsg("ConnParams arrays bound check failed")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't use pstrdup here to avoid being tied to a memory context, we free
|
||||||
|
* these later using ResetConnParams
|
||||||
|
*/
|
||||||
ConnParams.keywords[ConnParams.size] = strdup(keyword);
|
ConnParams.keywords[ConnParams.size] = strdup(keyword);
|
||||||
ConnParams.values[ConnParams.size] = strdup(value);
|
ConnParams.values[ConnParams.size] = strdup(value);
|
||||||
ConnParams.size++;
|
ConnParams.size++;
|
||||||
|
@ -267,9 +271,24 @@ GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
||||||
* We allocate everything in the provided context so as to facilitate using
|
* We allocate everything in the provided context so as to facilitate using
|
||||||
* pfree on all runtime parameters when connections using these entries are
|
* pfree on all runtime parameters when connections using these entries are
|
||||||
* invalidated during config reloads.
|
* invalidated during config reloads.
|
||||||
|
*
|
||||||
|
* Also, when "host" is already provided in global parameters, we use hostname
|
||||||
|
* from the key as "hostaddr" instead of "host" to avoid host name lookup. In
|
||||||
|
* that case, the value for "host" becomes useful only if the authentication
|
||||||
|
* method requires it.
|
||||||
*/
|
*/
|
||||||
|
bool gotHostParamFromGlobalParams = false;
|
||||||
|
for (Size paramIndex = 0; paramIndex < ConnParams.size; paramIndex++)
|
||||||
|
{
|
||||||
|
if (strcmp(ConnParams.keywords[paramIndex], "host") == 0)
|
||||||
|
{
|
||||||
|
gotHostParamFromGlobalParams = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char *runtimeKeywords[] = {
|
const char *runtimeKeywords[] = {
|
||||||
"host",
|
gotHostParamFromGlobalParams ? "hostaddr" : "host",
|
||||||
"port",
|
"port",
|
||||||
"dbname",
|
"dbname",
|
||||||
"user",
|
"user",
|
||||||
|
|
|
@ -9,39 +9,39 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "pgstat.h"
|
|
||||||
|
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "pg_config.h"
|
||||||
|
#include "pgstat.h"
|
||||||
#include "safe_lib.h"
|
#include "safe_lib.h"
|
||||||
#include "postmaster/postmaster.h"
|
|
||||||
#include "access/hash.h"
|
#include "access/hash.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
|
#include "mb/pg_wchar.h"
|
||||||
|
#include "portability/instr_time.h"
|
||||||
|
#include "postmaster/postmaster.h"
|
||||||
|
#include "storage/ipc.h"
|
||||||
|
#include "utils/hsearch.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
|
|
||||||
#include "distributed/backend_data.h"
|
#include "distributed/backend_data.h"
|
||||||
|
#include "distributed/cancel_utils.h"
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
#include "distributed/errormessage.h"
|
|
||||||
#include "distributed/error_codes.h"
|
#include "distributed/error_codes.h"
|
||||||
|
#include "distributed/errormessage.h"
|
||||||
|
#include "distributed/hash_helpers.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/log_utils.h"
|
#include "distributed/log_utils.h"
|
||||||
#include "distributed/memutils.h"
|
#include "distributed/memutils.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/hash_helpers.h"
|
|
||||||
#include "distributed/placement_connection.h"
|
#include "distributed/placement_connection.h"
|
||||||
|
#include "distributed/remote_commands.h"
|
||||||
#include "distributed/run_from_same_connection.h"
|
#include "distributed/run_from_same_connection.h"
|
||||||
#include "distributed/shared_connection_stats.h"
|
#include "distributed/shared_connection_stats.h"
|
||||||
#include "distributed/cancel_utils.h"
|
|
||||||
#include "distributed/remote_commands.h"
|
|
||||||
#include "distributed/time_constants.h"
|
#include "distributed/time_constants.h"
|
||||||
#include "distributed/version_compat.h"
|
#include "distributed/version_compat.h"
|
||||||
#include "distributed/worker_log_messages.h"
|
#include "distributed/worker_log_messages.h"
|
||||||
#include "mb/pg_wchar.h"
|
|
||||||
#include "pg_config.h"
|
|
||||||
#include "portability/instr_time.h"
|
|
||||||
#include "storage/ipc.h"
|
|
||||||
#include "utils/hsearch.h"
|
|
||||||
#include "utils/memutils.h"
|
|
||||||
|
|
||||||
|
|
||||||
int NodeConnectionTimeout = 30000;
|
int NodeConnectionTimeout = 30000;
|
||||||
|
@ -866,7 +866,8 @@ WaitEventSetFromMultiConnectionStates(List *connections, int *waitCount)
|
||||||
*waitCount = 0;
|
*waitCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitEventSet *waitEventSet = CreateWaitEventSet(CurrentMemoryContext, eventSetSize);
|
WaitEventSet *waitEventSet = CreateWaitEventSet(WaitEventSetTracker_compat,
|
||||||
|
eventSetSize);
|
||||||
EnsureReleaseResource((MemoryContextCallbackFunction) (&FreeWaitEventSet),
|
EnsureReleaseResource((MemoryContextCallbackFunction) (&FreeWaitEventSet),
|
||||||
waitEventSet);
|
waitEventSet);
|
||||||
|
|
||||||
|
@ -879,7 +880,7 @@ WaitEventSetFromMultiConnectionStates(List *connections, int *waitCount)
|
||||||
numEventsAdded += 2;
|
numEventsAdded += 2;
|
||||||
|
|
||||||
MultiConnectionPollState *connectionState = NULL;
|
MultiConnectionPollState *connectionState = NULL;
|
||||||
foreach_ptr(connectionState, connections)
|
foreach_declared_ptr(connectionState, connections)
|
||||||
{
|
{
|
||||||
if (numEventsAdded >= eventSetSize)
|
if (numEventsAdded >= eventSetSize)
|
||||||
{
|
{
|
||||||
|
@ -961,7 +962,7 @@ FinishConnectionListEstablishment(List *multiConnectionList)
|
||||||
int waitCount = 0;
|
int waitCount = 0;
|
||||||
|
|
||||||
MultiConnection *connection = NULL;
|
MultiConnection *connection = NULL;
|
||||||
foreach_ptr(connection, multiConnectionList)
|
foreach_declared_ptr(connection, multiConnectionList)
|
||||||
{
|
{
|
||||||
MultiConnectionPollState *connectionState =
|
MultiConnectionPollState *connectionState =
|
||||||
palloc0(sizeof(MultiConnectionPollState));
|
palloc0(sizeof(MultiConnectionPollState));
|
||||||
|
@ -1046,8 +1047,15 @@ FinishConnectionListEstablishment(List *multiConnectionList)
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
bool beforePollSocket = PQsocket(connectionState->connection->pgConn);
|
||||||
bool connectionStateChanged = MultiConnectionStatePoll(connectionState);
|
bool connectionStateChanged = MultiConnectionStatePoll(connectionState);
|
||||||
|
|
||||||
|
if (beforePollSocket != PQsocket(connectionState->connection->pgConn))
|
||||||
|
{
|
||||||
|
/* rebuild the wait events if MultiConnectionStatePoll() changed the socket */
|
||||||
|
waitEventSetRebuild = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (connectionStateChanged)
|
if (connectionStateChanged)
|
||||||
{
|
{
|
||||||
if (connectionState->phase != MULTI_CONNECTION_PHASE_CONNECTING)
|
if (connectionState->phase != MULTI_CONNECTION_PHASE_CONNECTING)
|
||||||
|
@ -1153,7 +1161,7 @@ static void
|
||||||
CloseNotReadyMultiConnectionStates(List *connectionStates)
|
CloseNotReadyMultiConnectionStates(List *connectionStates)
|
||||||
{
|
{
|
||||||
MultiConnectionPollState *connectionState = NULL;
|
MultiConnectionPollState *connectionState = NULL;
|
||||||
foreach_ptr(connectionState, connectionStates)
|
foreach_declared_ptr(connectionState, connectionStates)
|
||||||
{
|
{
|
||||||
MultiConnection *connection = connectionState->connection;
|
MultiConnection *connection = connectionState->connection;
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,15 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/hash.h"
|
#include "access/hash.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
|
#include "common/hashfn.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/locally_reserved_shared_connections.h"
|
#include "distributed/locally_reserved_shared_connections.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
|
@ -47,8 +50,6 @@
|
||||||
#include "distributed/shared_connection_stats.h"
|
#include "distributed/shared_connection_stats.h"
|
||||||
#include "distributed/tuplestore.h"
|
#include "distributed/tuplestore.h"
|
||||||
#include "distributed/worker_manager.h"
|
#include "distributed/worker_manager.h"
|
||||||
#include "utils/builtins.h"
|
|
||||||
#include "common/hashfn.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define RESERVED_CONNECTION_COLUMNS 4
|
#define RESERVED_CONNECTION_COLUMNS 4
|
||||||
|
@ -359,7 +360,7 @@ EnsureConnectionPossibilityForNodeList(List *nodeList)
|
||||||
nodeList = SortList(nodeList, CompareWorkerNodes);
|
nodeList = SortList(nodeList, CompareWorkerNodes);
|
||||||
|
|
||||||
WorkerNode *workerNode = NULL;
|
WorkerNode *workerNode = NULL;
|
||||||
foreach_ptr(workerNode, nodeList)
|
foreach_declared_ptr(workerNode, nodeList)
|
||||||
{
|
{
|
||||||
bool waitForConnection = true;
|
bool waitForConnection = true;
|
||||||
EnsureConnectionPossibilityForNode(workerNode, waitForConnection);
|
EnsureConnectionPossibilityForNode(workerNode, waitForConnection);
|
||||||
|
|
|
@ -11,23 +11,24 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
|
||||||
|
|
||||||
#include "access/hash.h"
|
#include "access/hash.h"
|
||||||
|
#include "common/hashfn.h"
|
||||||
|
#include "utils/hsearch.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
|
|
||||||
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/distributed_planner.h"
|
||||||
#include "distributed/hash_helpers.h"
|
#include "distributed/hash_helpers.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
#include "distributed/distributed_planner.h"
|
|
||||||
#include "distributed/multi_partitioning_utils.h"
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/placement_connection.h"
|
#include "distributed/placement_connection.h"
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "utils/hsearch.h"
|
|
||||||
#include "common/hashfn.h"
|
|
||||||
#include "utils/memutils.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -369,7 +370,7 @@ AssignPlacementListToConnection(List *placementAccessList, MultiConnection *conn
|
||||||
const char *userName = connection->user;
|
const char *userName = connection->user;
|
||||||
|
|
||||||
ShardPlacementAccess *placementAccess = NULL;
|
ShardPlacementAccess *placementAccess = NULL;
|
||||||
foreach_ptr(placementAccess, placementAccessList)
|
foreach_declared_ptr(placementAccess, placementAccessList)
|
||||||
{
|
{
|
||||||
ShardPlacement *placement = placementAccess->placement;
|
ShardPlacement *placement = placementAccess->placement;
|
||||||
ShardPlacementAccessType accessType = placementAccess->accessType;
|
ShardPlacementAccessType accessType = placementAccess->accessType;
|
||||||
|
@ -532,7 +533,7 @@ FindPlacementListConnection(int flags, List *placementAccessList, const char *us
|
||||||
* suitable connection found for a placement in the placementAccessList.
|
* suitable connection found for a placement in the placementAccessList.
|
||||||
*/
|
*/
|
||||||
ShardPlacementAccess *placementAccess = NULL;
|
ShardPlacementAccess *placementAccess = NULL;
|
||||||
foreach_ptr(placementAccess, placementAccessList)
|
foreach_declared_ptr(placementAccess, placementAccessList)
|
||||||
{
|
{
|
||||||
ShardPlacement *placement = placementAccess->placement;
|
ShardPlacement *placement = placementAccess->placement;
|
||||||
ShardPlacementAccessType accessType = placementAccess->accessType;
|
ShardPlacementAccessType accessType = placementAccess->accessType;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue