Merge branch 'master' into master
commit
1bb665ce37
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pgver: [13, 14, 15, 16, 17]
|
||||
pgver: [13, 14, 15, 16, 17, 18]
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
|
|
|
|||
|
|
@ -105,8 +105,13 @@ jobs:
|
|||
run: |
|
||||
# Note: we use a custom port for PostgreSQL as the runner may already have a version of PostgreSQL installed
|
||||
sudo su -c "echo local all all trust > /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all 127.0.0.1/32 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all ::1/128 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres 127.0.0.1/32 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres ::1/128 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo sed -i "s/port = 544[0-9]/port = 58${{ matrix.pgver }}/g" /etc/edb-as/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo sed -i "s/shared_preload_libraries = '/shared_preload_libraries = '\$libdir\/plugin_debugger,/g" /etc/edb-as/${{ matrix.pgver }}/main/postgresql.conf
|
||||
echo "wal_level = logical" | sudo tee -a /etc/edb-as/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo su - enterprisedb -c "mkdir -p /var/run/edb-as/${{ matrix.pgver }}-main.epas_stat_tmp"
|
||||
sudo systemctl restart edb-as@${{ matrix.pgver }}-main
|
||||
|
||||
|
|
@ -115,6 +120,16 @@ jobs:
|
|||
sleep 2
|
||||
done
|
||||
|
||||
- name: Start PostgreSQL on Windows
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
echo host replication postgres 127.0.0.1/32 trust >> "C:\EPAS\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo host replication postgres ::1/128 trust >> "C:\EPAS\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo wal_level = logical >> "C:\EPAS\${{ matrix.pgver }}\data\postgresql.conf"
|
||||
net stop epas-${{ matrix.pgver }}
|
||||
net start epas-${{ matrix.pgver }}
|
||||
shell: cmd
|
||||
|
||||
- name: Create pgagent extension on Linux
|
||||
if: ${{ matrix.os == 'ubuntu-22.04' && matrix.pgver <= 16 }}
|
||||
run: psql -U enterprisedb -d postgres -p 58${{ matrix.pgver }} -c 'CREATE EXTENSION IF NOT EXISTS pgagent;'
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-22.04, windows-latest]
|
||||
pgver: [13, 14, 15, 16, 17]
|
||||
pgver: [13, 14, 15, 16, 17, 18]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
|
@ -116,8 +116,13 @@ jobs:
|
|||
if: ${{ matrix.os == 'ubuntu-22.04' }}
|
||||
run: |
|
||||
sudo su -c "echo local all all trust > /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all 127.0.0.1/32 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all ::1/128 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres 127.0.0.1/32 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres ::1/128 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo sed -i "s/port = 543[0-9]/port = 59${{ matrix.pgver }}/g" /etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = '\$libdir\/plugin_debugger'/g" /etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf
|
||||
echo "wal_level = logical" | sudo tee -a /etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo su - postgres -c "/usr/lib/postgresql/${{ matrix.pgver }}/bin/postgres -D /var/lib/postgresql/${{ matrix.pgver }}/main -c config_file=/etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf &"
|
||||
|
||||
until sudo runuser -l postgres -c "pg_isready -p 59${{ matrix.pgver }}" 2>/dev/null; do
|
||||
|
|
@ -133,7 +138,12 @@ jobs:
|
|||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
run: |
|
||||
echo local all all trust > /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host all all 127.0.0.1/32 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host all all ::1/128 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host replication postgres 127.0.0.1/32 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host replication postgres ::1/128 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
sed -i '' "s/#port = 543[0-9]/port = 59${{ matrix.pgver }}/g" /opt/homebrew/var/postgresql@${{ matrix.pgver }}/postgresql.conf
|
||||
echo "wal_level = logical" >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/postgresql.conf
|
||||
brew services restart postgresql@${{ matrix.pgver }}
|
||||
|
||||
until /opt/homebrew/opt/postgresql@${{ matrix.pgver }}/bin/pg_isready -p 59${{ matrix.pgver }} 2>/dev/null; do
|
||||
|
|
@ -143,6 +153,16 @@ jobs:
|
|||
|
||||
psql postgres -p 59${{ matrix.pgver }} -c 'CREATE ROLE postgres SUPERUSER LOGIN;'
|
||||
|
||||
- name: Start PostgreSQL on Windows
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
echo host replication postgres 127.0.0.1/32 trust >> "C:\PostgreSQL\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo host replication postgres ::1/128 trust >> "C:\PostgreSQL\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo wal_level = logical >> "C:\PostgreSQL\${{ matrix.pgver }}\data\postgresql.conf"
|
||||
net stop postgresql-x64-${{ matrix.pgver }}
|
||||
net start postgresql-x64-${{ matrix.pgver }}
|
||||
shell: cmd
|
||||
|
||||
- name: Install Python dependencies on Linux and macOS
|
||||
if: ${{ matrix.os == 'macos-latest' || matrix.os == 'ubuntu-22.04' }}
|
||||
run: make install-python-testing
|
||||
|
|
|
|||
22
Dockerfile
22
Dockerfile
|
|
@ -120,21 +120,16 @@ RUN rm -rf /pgadmin4/docs/en_US/_build/html/_static/*.png
|
|||
# Create additional builders to get all of the PostgreSQL utilities
|
||||
#########################################################################
|
||||
|
||||
FROM postgres:12-alpine AS pg12-builder
|
||||
FROM postgres:13-alpine AS pg13-builder
|
||||
FROM postgres:14-alpine AS pg14-builder
|
||||
FROM postgres:15-alpine AS pg15-builder
|
||||
FROM postgres:16-alpine AS pg16-builder
|
||||
FROM postgres:17-alpine AS pg17-builder
|
||||
FROM postgres:18-alpine AS pg18-builder
|
||||
|
||||
FROM alpine:latest AS tool-builder
|
||||
|
||||
# Copy the PG binaries
|
||||
COPY --from=pg12-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-12/
|
||||
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-13/
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-13/
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-13/
|
||||
|
|
@ -160,6 +155,11 @@ COPY --from=pg17-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-17/
|
|||
COPY --from=pg17-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-17/
|
||||
COPY --from=pg17-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-17/
|
||||
|
||||
COPY --from=pg18-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-18/
|
||||
COPY --from=pg18-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-18/
|
||||
COPY --from=pg18-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-18/
|
||||
COPY --from=pg18-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-18/
|
||||
|
||||
#########################################################################
|
||||
# Assemble everything into the final container.
|
||||
#########################################################################
|
||||
|
|
@ -171,12 +171,12 @@ COPY --from=env-builder /venv /venv
|
|||
|
||||
# Copy in the tools
|
||||
COPY --from=tool-builder /usr/local/pgsql /usr/local/
|
||||
COPY --from=pg17-builder /usr/local/lib/libpq.so.5.17 /usr/lib/
|
||||
COPY --from=pg17-builder /usr/lib/libzstd.so.1.5.7 /usr/lib/
|
||||
COPY --from=pg17-builder /usr/lib/liblz4.so.1.10.0 /usr/lib/
|
||||
COPY --from=pg18-builder /usr/local/lib/libpq.so.5.18 /usr/lib/
|
||||
COPY --from=pg18-builder /usr/lib/libzstd.so.1.5.7 /usr/lib/
|
||||
COPY --from=pg18-builder /usr/lib/liblz4.so.1.10.0 /usr/lib/
|
||||
|
||||
RUN ln -s libpq.so.5.17 /usr/lib/libpq.so.5 && \
|
||||
ln -s libpq.so.5.17 /usr/lib/libpq.so && \
|
||||
RUN ln -s libpq.so.5.18 /usr/lib/libpq.so.5 && \
|
||||
ln -s libpq.so.5.18 /usr/lib/libpq.so && \
|
||||
ln -s libzstd.so.1.5.7 /usr/lib/libzstd.so.1 && \
|
||||
ln -s liblz4.so.1.10.0 /usr/lib/liblz4.so.1
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ The default binary paths set in the container are as follows:
|
|||
.. code-block:: bash
|
||||
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
'pg-18': '/usr/local/pgsql-18',
|
||||
'pg-17': '/usr/local/pgsql-17',
|
||||
'pg-16': '/usr/local/pgsql-16',
|
||||
'pg-15': '/usr/local/pgsql-15',
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ Use the fields in the *Definition* tab to define the function:
|
|||
will change to an input text field.
|
||||
* Use the drop-down listbox next to *Language* to select the implementation
|
||||
language. The default is *sql*.
|
||||
* Use the drop-down listbox next to *Depends on extensions* to select the extension that this function
|
||||
depends on (for example, plpgsql). If set, dropping the extension will automatically drop the
|
||||
function as well.
|
||||
* Use the fields in the *Arguments* to define an argument. Click the *Add*
|
||||
icon (+) to set parameters and values for the argument:
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 89 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 64 KiB |
|
|
@ -22,6 +22,7 @@ New features
|
|||
|
||||
| `Issue #6394 <https://github.com/pgadmin-org/pgadmin4/issues/6394>`_ - Added "MULTIRANGE_TYPE_NAME" option while creating a Range Type.
|
||||
| `Issue #6395 <https://github.com/pgadmin-org/pgadmin4/issues/6395>`_ - Added "SUBSCRIPT" option while creating a External Type.
|
||||
| `Issue #8932 <https://github.com/pgadmin-org/pgadmin4/issues/8932>`_ - Added 'failover' and 'two_phase' parameter support in CREATE/ALTER SUBSCRIPTION for PostgreSQL v17+.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
|
@ -30,6 +31,7 @@ Housekeeping
|
|||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #9158 <https://github.com/pgadmin-org/pgadmin4/issues/9158>`_ - Fixed an issue where saving the newly changed preferences was not reflecting on the preferences tab.
|
||||
| `Issue #9098 <https://github.com/pgadmin-org/pgadmin4/issues/9098>`_ - Fixed an issue where the query tool displayed 'default' instead of 'null' for null text data in the data output.
|
||||
| `Issue #9125 <https://github.com/pgadmin-org/pgadmin4/issues/9125>`_ - Fixed an issue where the pgAdmin configuration database wasn't being created on a fresh install when an external database was used for the configuration.
|
||||
| `Issue #9157 <https://github.com/pgadmin-org/pgadmin4/issues/9157>`_ - Fixed an issue where shortcuts are not working as expected on multiple keyboard layouts.
|
||||
| `Issue #9158 <https://github.com/pgadmin-org/pgadmin4/issues/9158>`_ - Fixed an issue where saving the newly changed preferences was not reflecting on the preferences tab.
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ Use the *With* tab to define some parameters for a subscription:
|
|||
* Move the *Run as owner?* switch to *true* position to specify all replication actions are performed as the subscription owner. If *false*, replication workers will perform actions on each table as the owner of that table. The default is *false*. This option is available only on PostgreSQL 16 and above.
|
||||
* Use the *Password required?* to specify whether connections to the publisher made as a result of this subscription must use password authentication. This setting is ignored when the subscription is owned by a superuser. The default is true. Only superusers can set this value to *false*. This option is available only on PostgreSQL 16 and above.
|
||||
* Use the *Origin* to specify whether the subscription will request the publisher to only send changes that don't have an origin or send changes regardless of origin. The default is *any*. This option is available only on PostgreSQL 16 and above.
|
||||
* Use the *Failover* to specify whether the replication slots associated with the subscription are enabled to be synced to the standbys so that logical replication can be resumed from the new primary after failover. The default is false. This option is available only on PostgreSQL 17 and above.
|
||||
|
||||
Click the *SQL* tab to continue.
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ CA_FILE = '/etc/ssl/certs/ca-certificates.crt'
|
|||
LOG_FILE = '/dev/null'
|
||||
HELP_PATH = '../../docs'
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
'pg': '/usr/local/pgsql-17',
|
||||
'pg': '/usr/local/pgsql-18',
|
||||
'pg-18': '/usr/local/pgsql-18',
|
||||
'pg-17': '/usr/local/pgsql-17',
|
||||
'pg-16': '/usr/local/pgsql-16',
|
||||
'pg-15': '/usr/local/pgsql-15',
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ azure-identity==1.25.0
|
|||
azure-mgmt-rdbms==10.1.0
|
||||
azure-mgmt-resource==24.0.0
|
||||
azure-mgmt-subscription==3.1.1
|
||||
bcrypt==4.3.*
|
||||
bcrypt==5.0.*
|
||||
boto3==1.40.*
|
||||
cryptography==46.0.*
|
||||
Flask-Babel==4.0.*
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@
|
|||
},
|
||||
"packageManager": "yarn@4.9.2",
|
||||
"devDependencies": {
|
||||
"electron": "38.1.2",
|
||||
"electron": "38.2.0",
|
||||
"eslint": "^9.36.0",
|
||||
"eslint-plugin-unused-imports": "^4.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.12.0",
|
||||
"electron-context-menu": "^4.1.0",
|
||||
"electron-store": "^10.1.0"
|
||||
"electron-store": "^11.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,20 +200,20 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@types/node@npm:*":
|
||||
version: 24.5.2
|
||||
resolution: "@types/node@npm:24.5.2"
|
||||
version: 24.6.1
|
||||
resolution: "@types/node@npm:24.6.1"
|
||||
dependencies:
|
||||
undici-types: "npm:~7.12.0"
|
||||
checksum: 10c0/96baaca6564d39c6f7f6eddd73ce41e2a7594ef37225cd52df3be36fad31712af8ae178387a72d0b80f2e2799e7fd30c014bc0ae9eb9f962d9079b691be00c48
|
||||
undici-types: "npm:~7.13.0"
|
||||
checksum: 10c0/f2f8aea441d72139345cfa2e392af51bc27d12eb5f74b9b4d202046a2e82ab70d6da89c46a2ac7feea98854c2919e53070869d4af9d448e173a77249fcb7bca3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^22.7.7":
|
||||
version: 22.18.6
|
||||
resolution: "@types/node@npm:22.18.6"
|
||||
version: 22.18.8
|
||||
resolution: "@types/node@npm:22.18.8"
|
||||
dependencies:
|
||||
undici-types: "npm:~6.21.0"
|
||||
checksum: 10c0/7ba190da2e64e56c59270661af8cd682c830a1375b6f965ab153be90baabfdaa867aa1d63f87b42de80956996d46dfe1cf93ecefe982d9a16e485b6756949f9a
|
||||
checksum: 10c0/54473730e7417b923fec427f62ed3204259acbd8e450a7593bad8ae02a75effcfcc864b34bf02c108eeb9c04a404791687f42b801bafa5264a8761f4df9122fd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -321,6 +321,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"async-function@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "async-function@npm:1.0.0"
|
||||
checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"async-generator-function@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "async-generator-function@npm:1.0.0"
|
||||
checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"asynckit@npm:^0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "asynckit@npm:0.4.0"
|
||||
|
|
@ -480,20 +494,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"conf@npm:^14.0.0":
|
||||
version: 14.0.0
|
||||
resolution: "conf@npm:14.0.0"
|
||||
"conf@npm:^15.0.0":
|
||||
version: 15.0.0
|
||||
resolution: "conf@npm:15.0.0"
|
||||
dependencies:
|
||||
ajv: "npm:^8.17.1"
|
||||
ajv-formats: "npm:^3.0.1"
|
||||
atomically: "npm:^2.0.3"
|
||||
debounce-fn: "npm:^6.0.0"
|
||||
dot-prop: "npm:^9.0.0"
|
||||
dot-prop: "npm:^10.0.0"
|
||||
env-paths: "npm:^3.0.0"
|
||||
json-schema-typed: "npm:^8.0.1"
|
||||
semver: "npm:^7.7.2"
|
||||
uint8array-extras: "npm:^1.4.0"
|
||||
checksum: 10c0/d1472ea24dad78d0d33dee47a795dfefe92fcdf2633763a8b35563989f22b2658e768c9d338de8e8e5f9163525d22df9e5f8733094d822a8329f4571dedce208
|
||||
uint8array-extras: "npm:^1.5.0"
|
||||
checksum: 10c0/50d7c479276541540773ee31becdf2861b02338d257f219e17773c170419d7c24353dc564b0d392fb77090fa96e66a46d5110ad4f9b965a349e98b1392140693
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -588,12 +602,12 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dot-prop@npm:^9.0.0":
|
||||
version: 9.0.0
|
||||
resolution: "dot-prop@npm:9.0.0"
|
||||
"dot-prop@npm:^10.0.0":
|
||||
version: 10.0.0
|
||||
resolution: "dot-prop@npm:10.0.0"
|
||||
dependencies:
|
||||
type-fest: "npm:^4.18.2"
|
||||
checksum: 10c0/4bac49a2f559156811862ac92813906f70529c50da918eaab81b38dd869743c667d578e183607f5ae11e8ae2a02e43e98e32c8a37bc4cae76b04d5b576e3112f
|
||||
type-fest: "npm:^5.0.0"
|
||||
checksum: 10c0/549e1c7f8440dac358f934367047c6993797dd0d52bfb1617dcad43f1d6ebeb15a1a4658f2b268e105de47e3dd59e9fd4ff9b61bdbc6159723df0d96dbcd2226
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -637,26 +651,26 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"electron-store@npm:^10.1.0":
|
||||
version: 10.1.0
|
||||
resolution: "electron-store@npm:10.1.0"
|
||||
"electron-store@npm:^11.0.0":
|
||||
version: 11.0.0
|
||||
resolution: "electron-store@npm:11.0.0"
|
||||
dependencies:
|
||||
conf: "npm:^14.0.0"
|
||||
type-fest: "npm:^4.41.0"
|
||||
checksum: 10c0/a527a1957b09decbbb36828e299bb06c239ed9a7d406ceda07abe84d2a9dfd1920120c63859e42c9c7a0922b95b840c4f4e5d8db90256814445f22a8a48de07e
|
||||
conf: "npm:^15.0.0"
|
||||
type-fest: "npm:^5.0.1"
|
||||
checksum: 10c0/9253ae08ec4e1b58518b47bcfdd016b1779a035b9b80956c6051e090af473f9fa4531818a68119b71211ad26964a67688e13a8a31ed55075423b9baf7bd51a8a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"electron@npm:38.1.2":
|
||||
version: 38.1.2
|
||||
resolution: "electron@npm:38.1.2"
|
||||
"electron@npm:38.2.0":
|
||||
version: 38.2.0
|
||||
resolution: "electron@npm:38.2.0"
|
||||
dependencies:
|
||||
"@electron/get": "npm:^2.0.0"
|
||||
"@types/node": "npm:^22.7.7"
|
||||
extract-zip: "npm:^2.0.1"
|
||||
bin:
|
||||
electron: cli.js
|
||||
checksum: 10c0/63f768e8ac396221db17c280e483ac838067e881ee61eb78c5c8f587017e51c587cc1eb687f29672b5e63c0af8a5d818d721d49aef20bac082544a8cf2d323ea
|
||||
checksum: 10c0/86c1a429b11d273c606d6827bdd114e6b0d57c8d12867e27c3f8542f1f5d85bda8da4330d17ad1556007860e4b2ac6aa71699a0648c9021bfdd83e4224e01c20
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -1033,6 +1047,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"generator-function@npm:^2.0.0":
|
||||
version: 2.0.1
|
||||
resolution: "generator-function@npm:2.0.1"
|
||||
checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"get-east-asian-width@npm:^1.0.0":
|
||||
version: 1.4.0
|
||||
resolution: "get-east-asian-width@npm:1.4.0"
|
||||
|
|
@ -1041,20 +1062,23 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"get-intrinsic@npm:^1.2.6":
|
||||
version: 1.3.0
|
||||
resolution: "get-intrinsic@npm:1.3.0"
|
||||
version: 1.3.1
|
||||
resolution: "get-intrinsic@npm:1.3.1"
|
||||
dependencies:
|
||||
async-function: "npm:^1.0.0"
|
||||
async-generator-function: "npm:^1.0.0"
|
||||
call-bind-apply-helpers: "npm:^1.0.2"
|
||||
es-define-property: "npm:^1.0.1"
|
||||
es-errors: "npm:^1.3.0"
|
||||
es-object-atoms: "npm:^1.1.1"
|
||||
function-bind: "npm:^1.1.2"
|
||||
generator-function: "npm:^2.0.0"
|
||||
get-proto: "npm:^1.0.1"
|
||||
gopd: "npm:^1.2.0"
|
||||
has-symbols: "npm:^1.1.0"
|
||||
hasown: "npm:^2.0.2"
|
||||
math-intrinsics: "npm:^1.1.0"
|
||||
checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a
|
||||
checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -1563,9 +1587,9 @@ __metadata:
|
|||
resolution: "pgadmin4@workspace:."
|
||||
dependencies:
|
||||
axios: "npm:^1.12.0"
|
||||
electron: "npm:38.1.2"
|
||||
electron: "npm:38.2.0"
|
||||
electron-context-menu: "npm:^4.1.0"
|
||||
electron-store: "npm:^10.1.0"
|
||||
electron-store: "npm:^11.0.0"
|
||||
eslint: "npm:^9.36.0"
|
||||
eslint-plugin-unused-imports: "npm:^4.2.0"
|
||||
languageName: unknown
|
||||
|
|
@ -1806,6 +1830,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tagged-tag@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "tagged-tag@npm:1.0.0"
|
||||
checksum: 10c0/91d25c9ffb86a91f20522cefb2cbec9b64caa1febe27ad0df52f08993ff60888022d771e868e6416cf2e72dab68449d2139e8709ba009b74c6c7ecd4000048d1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type-check@npm:^0.4.0, type-check@npm:~0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "type-check@npm:0.4.0"
|
||||
|
|
@ -1822,14 +1853,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type-fest@npm:^4.18.2, type-fest@npm:^4.41.0":
|
||||
version: 4.41.0
|
||||
resolution: "type-fest@npm:4.41.0"
|
||||
checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4
|
||||
"type-fest@npm:^5.0.0, type-fest@npm:^5.0.1":
|
||||
version: 5.0.1
|
||||
resolution: "type-fest@npm:5.0.1"
|
||||
dependencies:
|
||||
tagged-tag: "npm:^1.0.0"
|
||||
checksum: 10c0/8d248edd9705e0da3cc14f4f4ca7fb40a6c5b2c822fe4ba8fc226743578bc229f66fa4ff66e7d4070806ab8312adc64199ce0f0836d20ede13922ced2ff36118
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uint8array-extras@npm:^1.4.0":
|
||||
"uint8array-extras@npm:^1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "uint8array-extras@npm:1.5.0"
|
||||
checksum: 10c0/0e74641ac7dadb02eadefc1ccdadba6010e007757bda824960de3c72bbe2b04e6d3af75648441f412148c4103261d54fcb60be45a2863beb76643a55fddba3bd
|
||||
|
|
@ -1843,10 +1876,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~7.12.0":
|
||||
version: 7.12.0
|
||||
resolution: "undici-types@npm:7.12.0"
|
||||
checksum: 10c0/326e455bbc0026db1d6b81c76a1cf10c63f7e2f9821db2e24fdc258f482814e5bfa8481f8910d07c68e305937c5c049610fdc441c5e8b7bb0daca7154fb8a306
|
||||
"undici-types@npm:~7.13.0":
|
||||
version: 7.13.0
|
||||
resolution: "undici-types@npm:7.13.0"
|
||||
checksum: 10c0/44bbb0935425291351bfd8039571f017295b5d6dc5727045d0a4fea8c6ffe73a6703b48ce010f9cb539b9041a75b463f8cfe1e7309cab7486452505fb0d66151
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@
|
|||
"html-react-parser": "^5.2.0",
|
||||
"image-minimizer-webpack-plugin": "^4.1.4",
|
||||
"imports-loader": "^5.0.0",
|
||||
"jest": "^30.1.3",
|
||||
"jest-environment-jsdom": "^30.1.2",
|
||||
"jest": "^30.2.0",
|
||||
"jest-environment-jsdom": "^30.2.0",
|
||||
"loader-utils": "^3.2.1",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
"postcss-loader": "^8.1.1",
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
"@fortawesome/fontawesome-free": "latest",
|
||||
"@mui/icons-material": "^7.3.2",
|
||||
"@mui/material": "^7.3.2",
|
||||
"@mui/x-date-pickers": "^8.11.3",
|
||||
"@mui/x-date-pickers": "^8.12.0",
|
||||
"@nozbe/microfuzz": "^1.0.0",
|
||||
"@projectstorm/react-diagrams": "^7.0.4",
|
||||
"@simonwep/pickr": "^1.5.1",
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
|||
list_params = []
|
||||
if request.method == 'GET':
|
||||
list_params = ['arguments', 'variables', 'proacl',
|
||||
'seclabels', 'acl', 'args']
|
||||
'seclabels', 'acl', 'args', 'dependsonextensions']
|
||||
|
||||
if key in list_params and req[key] != '' and req[key] is not None:
|
||||
# Coverts string into python list as expected.
|
||||
|
|
@ -1171,6 +1171,10 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
|||
old_data['proparallel'] = \
|
||||
parallel_dict[old_data['proparallel']]
|
||||
|
||||
if self.node_type == 'function' and \
|
||||
old_data['dependsonextensions'] is None:
|
||||
old_data['dependsonextensions'] = []
|
||||
|
||||
# If any of the below argument is changed,
|
||||
# then CREATE OR REPLACE SQL statement should be called
|
||||
fun_change_args = ['lanname', 'prosrc', 'probin', 'prosrc_c',
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ define('pgadmin.node.function', [
|
|||
|
||||
},
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
let nodeObj = pgBrowser.Nodes['extension'];
|
||||
return new FunctionSchema(
|
||||
(privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges),
|
||||
()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false),
|
||||
|
|
@ -85,6 +86,16 @@ define('pgadmin.node.function', [
|
|||
cacheLevel: 'database'
|
||||
}
|
||||
),
|
||||
extensionsList:()=>getNodeAjaxOptions('nodes', nodeObj, treeNodeInfo, itemNodeData, { cacheLevel: 'server'},
|
||||
(data)=>{
|
||||
let res = [];
|
||||
if (data && _.isArray(data)) {
|
||||
_.each(data, function(d) {
|
||||
res.push({label: d.label, value: d.label, data: d});
|
||||
});
|
||||
}
|
||||
return res;
|
||||
}),
|
||||
getTypes: ()=>getNodeAjaxOptions('get_types', this, treeNodeInfo, itemNodeData),
|
||||
getLanguage: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData),
|
||||
getSupportFunctions: ()=>getNodeAjaxOptions('get_support_functions', this, treeNodeInfo, itemNodeData, {
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ export default class FunctionSchema extends BaseUISchema {
|
|||
role: [],
|
||||
schema: [],
|
||||
getTypes: [],
|
||||
extensionsList: [],
|
||||
...fieldOptions,
|
||||
};
|
||||
}
|
||||
|
|
@ -274,8 +275,21 @@ export default class FunctionSchema extends BaseUISchema {
|
|||
|
||||
return this.node_info && 'catalog' in this.node_info;
|
||||
}
|
||||
},
|
||||
{
|
||||
},{
|
||||
id: 'dependsonextensions',
|
||||
label: gettext('Depends on extensions'),
|
||||
group: gettext('Definition'),
|
||||
type: 'select',
|
||||
options: this.fieldOptions.extensionsList,
|
||||
controlProps: {
|
||||
multiple: true,
|
||||
allowClear: true,
|
||||
allowSelectAll: true,
|
||||
placeholder: gettext('Select the Depends on extensions...'),
|
||||
},
|
||||
min_version: 130000,
|
||||
mode: ['create', 'edit', 'properties'],
|
||||
},{
|
||||
id: 'probin', label: gettext('Object file'), cell: 'string',
|
||||
type: 'text', group: gettext('Definition'), deps: ['lanname'], visible:
|
||||
function(state) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}
|
||||
{% set is_columns = [] %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% if data %}
|
||||
{% if query_for == 'sql_panel' and func_def is defined %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
|
||||
{% else %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
{% endif %}
|
||||
RETURNS{% if data.proretset and (data.prorettypename.startswith('SETOF ') or data.prorettypename.startswith('TABLE')) %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ data.prorettypename }}{% else %} {{ data.prorettypename }}{% endif %}
|
||||
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }}
|
||||
{% if data.procost %}
|
||||
COST {{data.procost}}
|
||||
{% endif %}
|
||||
{% if data.provolatile %}{% if data.provolatile == 'i' %}IMMUTABLE{% elif data.provolatile == 's' %}STABLE{% else %}VOLATILE{% endif %} {% endif %}{% if data.proleakproof %}LEAKPROOF {% endif %}
|
||||
{% if data.proisstrict %}STRICT {% endif %}
|
||||
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
|
||||
{% if data.proiswindow %}WINDOW {% endif %}
|
||||
{% if data.proparallel and (data.proparallel == 'r' or data.proparallel == 's' or data.proparallel == 'u') %}
|
||||
{% if data.proparallel == 'r' %}PARALLEL RESTRICTED {% elif data.proparallel == 's' %}PARALLEL SAFE {% elif data.proparallel == 'u' %}PARALLEL UNSAFE{% endif %}{% endif %}
|
||||
{% if data.prorows and (data.prorows | int) > 0 %}
|
||||
|
||||
ROWS {{data.prorows}}
|
||||
{% endif %}
|
||||
{% if data.prosupportfunc %}
|
||||
SUPPORT {{ data.prosupportfunc }}
|
||||
{% endif -%}
|
||||
{% if data.variables %}{% for v in data.variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
AS {% if data.lanname == 'c' %}
|
||||
{{ data.probin|qtLiteral(conn) }}, {{ data.prosrc_c|qtLiteral(conn) }}
|
||||
{% else %}
|
||||
$BODY${{ data.prosrc }}$BODY${% endif -%};
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args_without)}}
|
||||
{% endfor %}{% endif %}
|
||||
{% if data.revoke_all %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, "FUNCTION", "PUBLIC", data.name, data.pronamespace, data.func_args_without)}}
|
||||
{% endif %}
|
||||
{% if data.description %}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
{% if data.seclabels %}
|
||||
{% for r in data.seclabels %}
|
||||
{% if r.label and r.provider %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.label, data.pronamespace, data.func_args_without) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
SELECT
|
||||
pr.oid, pr.xmin,
|
||||
CASE WHEN pr.prokind = 'w' THEN true ELSE false END AS proiswindow,
|
||||
pr.prosrc, pr.prosrc AS prosrc_c, pr.pronamespace, pr.prolang, pr.procost, pr.prorows, pr.prokind,
|
||||
pr.prosecdef, pr.proleakproof, pr.proisstrict, pr.proretset, pr.provolatile, pr.proparallel,
|
||||
pr.pronargs, pr.prorettype, pr.proallargtypes, pr.proargmodes, pr.probin, pr.proacl,
|
||||
pr.proname, pr.proname AS name, pg_catalog.pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, pg_catalog.oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_catalog.pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
CASE WHEN prosupport = 0::oid THEN ''
|
||||
ELSE (
|
||||
SELECT pg_catalog.quote_ident(nspname) || '.' || pg_catalog.quote_ident(proname) AS tfunctions
|
||||
FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n
|
||||
WHERE p.pronamespace = n.oid
|
||||
AND p.oid = pr.prosupport::OID
|
||||
) END AS prosupportfunc,
|
||||
(SELECT
|
||||
pg_catalog.array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_catalog.pg_seclabel sl1
|
||||
WHERE
|
||||
sl1.objoid=pr.oid) AS seclabels
|
||||
FROM
|
||||
pg_catalog.pg_proc pr
|
||||
JOIN
|
||||
pg_catalog.pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_catalog.pg_namespace typns ON typns.oid=typ.typnamespace
|
||||
JOIN
|
||||
pg_catalog.pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_catalog.pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass and des.objsubid = 0)
|
||||
WHERE
|
||||
pr.prokind IN ('f', 'w')
|
||||
AND typname NOT IN ('trigger', 'event_trigger')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% else %}
|
||||
AND pronamespace = {{scid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
|
||||
{% set name = o_data.name %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% set set_variables = [] %}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
{% set set_variables = data.merged_variables %}
|
||||
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
|
||||
{% set set_variables = o_data.variables %}
|
||||
{% endif %}
|
||||
{% if data.name %}
|
||||
{% if data.name != o_data.name %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
|
||||
o_data.proargtypenames }})
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
{% set name = data.name %}
|
||||
{% endif %}
|
||||
{% endif -%}
|
||||
{% if data.change_func %}
|
||||
|
||||
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
RETURNS {% if 'prorettypename' in data %}{{ data.prorettypename }}{% else %}{{ o_data.prorettypename }}{% endif %}
|
||||
|
||||
{% if 'lanname' in data %}
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }} {% else %}
|
||||
LANGUAGE {{ o_data.lanname|qtLiteral(conn) }}
|
||||
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
|
||||
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %} LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %} NOT LEAKPROOF{% endif %}
|
||||
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
|
||||
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
|
||||
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
|
||||
|
||||
{% if 'proparallel' in data and data.proparallel %}PARALLEL {{ data.proparallel }}{% elif 'proparallel' not in data and o_data.proparallel %}PARALLEL {{ o_data.proparallel }}{% endif %}
|
||||
|
||||
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows and data.prorows != '0' %}
|
||||
|
||||
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
|
||||
|
||||
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if (data.lanname == 'c' or o_data.lanname == 'c') and ('probin' in data or 'prosrc_c' in data) %}
|
||||
{% if 'probin' in data %}{{ data.probin|qtLiteral(conn) }}{% else %}{{ o_data.probin|qtLiteral(conn) }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral(conn) }}{% else %}{{ o_data.prosrc_c|qtLiteral(conn) }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral(conn) }}, {{ o_data.prosrc_c|qtLiteral(conn) }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% endif -%};
|
||||
{% endif -%}
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
{# The SQL generated below will change priviledges #}
|
||||
{% if data.acl %}
|
||||
{% if 'deleted' in data.acl %}
|
||||
{% for priv in data.acl.deleted %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in data.acl %}
|
||||
{% for priv in data.acl.changed %}
|
||||
|
||||
{% if priv.grantee != priv.old_grantee %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.old_grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% else %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in data.acl %}
|
||||
{% for priv in data.acl.added %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}{% endif -%}
|
||||
{% endif -%}
|
||||
{% if data.change_func == False %}
|
||||
{% if data.variables %}
|
||||
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
|
||||
|
||||
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
|
||||
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% set seclabels = data.seclabels %}
|
||||
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
|
||||
{% for r in seclabels.deleted %}
|
||||
|
||||
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in seclabels and seclabels.added|length > 0 %}
|
||||
{% for r in seclabels.added %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
|
||||
{% for r in seclabels.changed %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if data.description is defined and data.description != o_data.description%}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.pronamespace %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -50,6 +50,15 @@ $BODY${{ data.prosrc }}$BODY${% endif -%};
|
|||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@ SELECT
|
|||
pg_catalog.pg_get_function_sqlbody(pr.oid) AS prosrc_sql,
|
||||
CASE WHEN pr.prosqlbody IS NOT NULL THEN true ELSE false END as is_pure_sql,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
CASE WHEN prosupport = 0::oid THEN ''
|
||||
ELSE (
|
||||
SELECT pg_catalog.quote_ident(nspname) || '.' || pg_catalog.quote_ident(proname) AS tfunctions
|
||||
|
|
|
|||
|
|
@ -130,4 +130,20 @@ ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtype
|
|||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}
|
||||
{% set is_columns = [] %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% if data %}
|
||||
{% if query_for == 'sql_panel' and func_def is defined %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
|
||||
{% else %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
{% endif %}
|
||||
RETURNS{% if data.proretset and (data.prorettypename.startswith('SETOF ') or data.prorettypename.startswith('TABLE')) %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ data.prorettypename }}{% else %} {{ data.prorettypename }}{% endif %}
|
||||
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }}
|
||||
{% if data.procost %}
|
||||
COST {{data.procost}}
|
||||
{% endif %}
|
||||
{% if data.provolatile %}{% if data.provolatile == 'i' %}IMMUTABLE{% elif data.provolatile == 's' %}STABLE{% else %}VOLATILE{% endif %} {% endif %}{% if data.proleakproof %}LEAKPROOF {% endif %}
|
||||
{% if data.proisstrict %}STRICT {% endif %}
|
||||
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
|
||||
{% if data.proiswindow %}WINDOW {% endif %}
|
||||
{% if data.proparallel and (data.proparallel == 'r' or data.proparallel == 's' or data.proparallel == 'u') %}
|
||||
{% if data.proparallel == 'r' %}PARALLEL RESTRICTED {% elif data.proparallel == 's' %}PARALLEL SAFE {% elif data.proparallel == 'u' %}PARALLEL UNSAFE{% endif %}{% endif %}
|
||||
{% if data.prorows and (data.prorows | int) > 0 %}
|
||||
|
||||
ROWS {{data.prorows}}
|
||||
{% endif %}
|
||||
{% if data.prosupportfunc %}
|
||||
|
||||
SUPPORT {{ data.prosupportfunc }}
|
||||
{% endif -%}
|
||||
{% if data.variables %}{% for v in data.variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
AS {% if data.lanname == 'c' %}
|
||||
{{ data.probin|qtLiteral(conn) }}, {{ data.prosrc_c|qtLiteral(conn) }}
|
||||
{% else %}
|
||||
$BODY${{ data.prosrc }}$BODY${% endif -%};
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args_without)}}
|
||||
{% endfor %}{% endif %}
|
||||
{% if data.revoke_all %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, "FUNCTION", "PUBLIC", data.name, data.pronamespace, data.func_args_without)}}
|
||||
{% endif %}
|
||||
{% if data.description %}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
{% if data.seclabels %}
|
||||
{% for r in data.seclabels %}
|
||||
{% if r.label and r.provider %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.label, data.pronamespace, data.func_args_without) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
SELECT
|
||||
pr.oid, pr.xmin,
|
||||
CASE WHEN pr.prokind = 'w' THEN true ELSE false END AS proiswindow,
|
||||
pr.prosrc, pr.prosrc AS prosrc_c, pr.pronamespace, pr.prolang, pr.procost, pr.prorows, pr.prokind,
|
||||
pr.prosecdef, pr.proleakproof, pr.proisstrict, pr.proretset, pr.provolatile, pr.proparallel,
|
||||
pr.pronargs, pr.prorettype, pr.proallargtypes, pr.proargmodes, pr.probin, pr.proacl,
|
||||
pr.proname, pr.proname AS name, pg_catalog.pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, pg_catalog.oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_catalog.pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
CASE WHEN prosupport = 0::oid THEN '' ELSE prosupport::text END AS prosupportfunc,
|
||||
(SELECT
|
||||
pg_catalog.array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_catalog.pg_seclabel sl1
|
||||
WHERE
|
||||
sl1.objoid=pr.oid) AS seclabels
|
||||
FROM
|
||||
pg_catalog.pg_proc pr
|
||||
JOIN
|
||||
pg_catalog.pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_catalog.pg_namespace typns ON typns.oid=typ.typnamespace
|
||||
JOIN
|
||||
pg_catalog.pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_catalog.pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass and des.objsubid = 0)
|
||||
WHERE
|
||||
pr.prokind IN ('f', 'w')
|
||||
AND typname NOT IN ('trigger', 'event_trigger')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% else %}
|
||||
AND pronamespace = {{scid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
|
||||
{% set name = o_data.name %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% set set_variables = [] %}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
{% set set_variables = data.merged_variables %}
|
||||
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
|
||||
{% set set_variables = o_data.variables %}
|
||||
{% endif %}
|
||||
{% if data.name %}
|
||||
{% if data.name != o_data.name %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
|
||||
o_data.proargtypenames }})
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
{% set name = data.name %}
|
||||
{% endif %}
|
||||
{% endif -%}
|
||||
{% if data.change_func %}
|
||||
|
||||
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
RETURNS {% if 'prorettypename' in data %}{{ data.prorettypename }}{% else %}{{ o_data.prorettypename }}{% endif %}
|
||||
|
||||
{% if 'lanname' in data %}
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }} {% else %}
|
||||
LANGUAGE {{ o_data.lanname|qtLiteral(conn) }}
|
||||
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
|
||||
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %} LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %} NOT LEAKPROOF{% endif %}
|
||||
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
|
||||
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
|
||||
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
|
||||
|
||||
{% if 'proparallel' in data and data.proparallel %}PARALLEL {{ data.proparallel }}{% elif 'proparallel' not in data and o_data.proparallel %}PARALLEL {{ o_data.proparallel }}{% endif %}
|
||||
|
||||
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows and data.prorows != '0' %}
|
||||
|
||||
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
|
||||
|
||||
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if (data.lanname == 'c' or o_data.lanname == 'c') and ('probin' in data or 'prosrc_c' in data) %}
|
||||
{% if 'probin' in data %}{{ data.probin|qtLiteral(conn) }}{% else %}{{ o_data.probin|qtLiteral(conn) }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral(conn) }}{% else %}{{ o_data.prosrc_c|qtLiteral(conn) }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral(conn) }}, {{ o_data.prosrc_c|qtLiteral(conn) }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% endif -%};
|
||||
{% endif -%}
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
{# The SQL generated below will change priviledges #}
|
||||
{% if data.acl %}
|
||||
{% if 'deleted' in data.acl %}
|
||||
{% for priv in data.acl.deleted %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in data.acl %}
|
||||
{% for priv in data.acl.changed %}
|
||||
|
||||
{% if priv.grantee != priv.old_grantee %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.old_grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% else %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in data.acl %}
|
||||
{% for priv in data.acl.added %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}{% endif -%}
|
||||
{% endif -%}
|
||||
{% if data.change_func == False %}
|
||||
{% if data.variables %}
|
||||
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
|
||||
|
||||
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
|
||||
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% set seclabels = data.seclabels %}
|
||||
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
|
||||
{% for r in seclabels.deleted %}
|
||||
|
||||
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in seclabels and seclabels.added|length > 0 %}
|
||||
{% for r in seclabels.added %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
|
||||
{% for r in seclabels.changed %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if data.description is defined and data.description != o_data.description%}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.pronamespace %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -50,6 +50,15 @@ $BODY${{ data.prosrc }}$BODY${% endif -%};
|
|||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ SELECT
|
|||
typns.nspname AS typnsp, lanname, proargnames, pg_catalog.oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_catalog.pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
pg_catalog.pg_get_function_sqlbody(pr.oid) AS prosrc_sql,
|
||||
CASE WHEN pr.prosqlbody IS NOT NULL THEN true ELSE false END as is_pure_sql,
|
||||
CASE WHEN prosupport = 0::oid THEN '' ELSE prosupport::text END AS prosupportfunc,
|
||||
|
|
|
|||
|
|
@ -130,4 +130,20 @@ ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtype
|
|||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
NO DEPENDS ON EXTENSION postgres_fdw;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO postgres;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
CREATE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(IN param character varying DEFAULT '1')
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort=true
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO postgres;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO postgres;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
|
|
@ -0,0 +1,434 @@
|
|||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function.sql",
|
||||
"expected_msql_file": "create_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function comment",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"description": "Some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_function_comment.sql",
|
||||
"expected_msql_file": "alter_function_comment.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for alter.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function rename.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name":"Function3_$%{}[]()&*^!@\"'`\\/#"
|
||||
},
|
||||
"expected_sql_file": "alter_function_rename.sql",
|
||||
"expected_msql_file": "alter_function_rename.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function code and add parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"prosrc": "begin\nselect '2';\nend\n",
|
||||
"variables": {
|
||||
"added": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_parameter.sql",
|
||||
"expected_msql_file": "alter_function_add_parameter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"deleted": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_parameter.sql",
|
||||
"expected_msql_file": "alter_function_delete_parameter.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for acl.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function add acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_acl.sql",
|
||||
"expected_msql_file": "alter_function_add_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function remove partial privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function change grantee in privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"old_grantee": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_change_grantee_acl.sql",
|
||||
"expected_msql_file": "alter_function_change_grantee_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_acl.sql",
|
||||
"expected_msql_file": "alter_function_delete_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"name": "Create function with custom return type.",
|
||||
"data": {
|
||||
"name": "Function3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "table(val character varying)",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\n return query select '1'::character varying;\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_with_custom_return.sql",
|
||||
"expected_msql_file": "create_function_with_custom_return.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +1,81 @@
|
|||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
NO DEPENDS ON EXTENSION postgres_fdw;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO enterprisedb;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
CREATE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(IN param character varying DEFAULT '1')
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort=true
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO enterprisedb;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO enterprisedb;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
|
|
@ -0,0 +1,446 @@
|
|||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function.sql",
|
||||
"expected_msql_file": "create_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function comment",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"description": "Some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_function_comment.sql",
|
||||
"expected_msql_file": "alter_function_comment.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for alter.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"prosecdef": true,
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function rename.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function3_$%{}[]()&*^!@\"'`\\/#"
|
||||
},
|
||||
"expected_sql_file": "alter_function_rename.sql",
|
||||
"expected_msql_file": "alter_function_rename.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function code and add parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"prosrc": "begin\nselect '2';\nend\n",
|
||||
"variables": {
|
||||
"added": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_parameter.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"deleted": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_parameter.sql",
|
||||
"expected_msql_file": "alter_function_delete_parameter.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for acl.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"prosecdef": true,
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function add acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "enterprisedb",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_acl.sql",
|
||||
"expected_msql_file": "alter_function_add_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function remove partial privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function change grantee in privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"old_grantee": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_change_grantee_acl.sql",
|
||||
"expected_msql_file": "alter_function_change_grantee_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "enterprisedb",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_acl.sql",
|
||||
"expected_msql_file": "alter_function_delete_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"name": "Create function with custom return type.",
|
||||
"data": {
|
||||
"name": "Function3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "table(val character varying)",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\n return query select '1'::character varying;\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_with_custom_return.sql",
|
||||
"expected_msql_file": "create_function_with_custom_return.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +1,81 @@
|
|||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
|
|
|
|||
|
|
@ -76,6 +76,19 @@ class FunctionAddTestCase(BaseTestGenerator):
|
|||
"status_code": 500
|
||||
}
|
||||
)),
|
||||
('Create Function With Invalid Depends On Extension Fail', dict(
|
||||
url='/browser/function/obj/',
|
||||
is_positive_test=False,
|
||||
mocking_required=True,
|
||||
is_mock_function=True,
|
||||
mock_data={
|
||||
"function_name": "_get_sql",
|
||||
"return_value": "(False, 'Invalid extension specified')"
|
||||
},
|
||||
expected_data={
|
||||
"status_code": 500
|
||||
}
|
||||
))
|
||||
]
|
||||
|
||||
def create_function(self, data):
|
||||
|
|
@ -113,6 +126,7 @@ class FunctionAddTestCase(BaseTestGenerator):
|
|||
"lanname": "sql",
|
||||
"name": "test_function",
|
||||
"options": [],
|
||||
"dependsonextensions": ["plpgsql"],
|
||||
"proleakproof": True,
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "integer",
|
||||
|
|
@ -143,10 +157,13 @@ class FunctionAddTestCase(BaseTestGenerator):
|
|||
)
|
||||
|
||||
data['prosupportfuc'] = support_function_name
|
||||
|
||||
if self.is_positive_test:
|
||||
response = self.create_function(data)
|
||||
else:
|
||||
if "Invalid Depends On Extension" in getattr(
|
||||
self, 'scenario_name', ''
|
||||
):
|
||||
data["dependsonextensions"] = ["non_existing_extensions"]
|
||||
if hasattr(self, 'is_mock_function'):
|
||||
def _get_sql(self, **kwargs):
|
||||
return False, ''
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
|||
"funcowner": "",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"dependsonextensions": [],
|
||||
"lanname": "sql",
|
||||
"arguments": [],
|
||||
"prosrc": "select '1'",
|
||||
|
|
@ -67,7 +68,8 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
|||
"probin": "$libdir/",
|
||||
"variables": [],
|
||||
"seclabels": [],
|
||||
"acl": []
|
||||
"acl": [],
|
||||
"dependsonextensions": ["non_existing_extension"]
|
||||
},
|
||||
mock_data={
|
||||
"function_name": '_get_sql',
|
||||
|
|
@ -178,7 +180,6 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
|||
func_name = "test_function_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
function_info = funcs_utils.create_function(
|
||||
self.server, self.db_name, self.schema_name, func_name)
|
||||
|
||||
func_id = function_info[0]
|
||||
self.test_data['oid'] = func_id
|
||||
self.test_data['name'] = func_name
|
||||
|
|
@ -187,6 +188,7 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
|||
self.schema_id) + '/' + str(func_id) + '?' + (
|
||||
urlencode(self.test_data))
|
||||
else:
|
||||
self.test_data['dependsonextensions'] = json.dumps(["plpgsql"])
|
||||
url = self.url + str(utils.SERVER_GROUP) + '/' + str(
|
||||
self.server_id) + '/' + str(self.db_id) + '/' + str(
|
||||
self.schema_id) + '/?' + (urlencode(self.test_data))
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class FunctionPutTestCase(BaseTestGenerator):
|
|||
}
|
||||
)),
|
||||
(
|
||||
'Fetch Function update with arguments',
|
||||
'Fetch Function update with arguments and depends on exxtensions.',
|
||||
dict(
|
||||
url='/browser/function/obj/',
|
||||
is_positive_test=True,
|
||||
|
|
@ -155,7 +155,8 @@ class FunctionPutTestCase(BaseTestGenerator):
|
|||
|
||||
data = {
|
||||
"description": "This is a procedure update comment",
|
||||
"id": func_id
|
||||
"id": func_id,
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
}
|
||||
|
||||
if hasattr(self, "is_add_argument") and self.is_add_argument:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
add empty bracket with table name
|
||||
#}
|
||||
{% set empty_bracket = ""%}
|
||||
{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %}
|
||||
{% if not (data.coll_inherits or data.columns or data.typname or data.like_relation or data.primary_key or data.unique_constraint or data.foreign_key or data.check_constraint or data.exclude_constraint) %}
|
||||
{% set empty_bracket = "\n(\n)"%}
|
||||
{% endif %}
|
||||
{% set with_clause = false%}
|
||||
|
|
|
|||
|
|
@ -652,6 +652,14 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
|||
if len(res['rows']) == 0:
|
||||
return gone(self._NOT_FOUND_PUB_INFORMATION)
|
||||
|
||||
if self.manager.version >= 150000:
|
||||
res['rows'][0]['two_phase'] = \
|
||||
self.two_phase_mapping[res['rows'][0]['two_phase']]
|
||||
|
||||
if self.manager.version >= 160000:
|
||||
res['rows'][0]['streaming'] = \
|
||||
self.streaming_mapping[res['rows'][0]['streaming']]
|
||||
|
||||
old_data = res['rows'][0]
|
||||
|
||||
data, old_data = self.get_required_details(data, old_data)
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ export default class SubscriptionSchema extends BaseUISchema{
|
|||
binary:false,
|
||||
two_phase:false,
|
||||
disable_on_error:false,
|
||||
streaming:false,
|
||||
streaming: (node_info?.node_info?.version >= 180000) ? 'parallel' : false,
|
||||
password_required:true,
|
||||
run_as_owner:false,
|
||||
origin:'any',
|
||||
failover:false,
|
||||
copy_data_after_refresh:false,
|
||||
sync:'off',
|
||||
refresh_pub: false,
|
||||
|
|
@ -72,13 +73,7 @@ export default class SubscriptionSchema extends BaseUISchema{
|
|||
(this.node_info['node_info'].host == 'localhost' || this.node_info['node_info'].host == '127.0.0.1')){
|
||||
host = this.node_info['node_info'].host;
|
||||
}
|
||||
if (host == this.node_info['node_info'].host && port == this.node_info['node_info'].port){
|
||||
state.create_slot = false;
|
||||
return true;
|
||||
} else {
|
||||
state.create_slot = true;
|
||||
}
|
||||
return false;
|
||||
return (host == this.node_info['node_info'].host && port == this.node_info['node_info'].port);
|
||||
}
|
||||
isAllConnectionDataEnter(state){
|
||||
let host = state.host,
|
||||
|
|
@ -317,6 +312,14 @@ export default class SubscriptionSchema extends BaseUISchema{
|
|||
readonly: obj.isConnect, deps :['connect', 'host', 'port'],
|
||||
helpMessage: gettext('Specifies whether the command should create the replication slot on the publisher.This field will be disabled and set to false if subscription connects to same database.Otherwise, the CREATE SUBSCRIPTION call will hang.'),
|
||||
helpMessageMode: ['edit', 'create'],
|
||||
depChange: (state) => {
|
||||
// Set create_slot to false if same DB, else true
|
||||
if(obj.isSameDB(state)) {
|
||||
state.create_slot = false;
|
||||
} else {
|
||||
state.create_slot = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'enabled', label: gettext('Enabled?'),
|
||||
|
|
@ -419,9 +422,18 @@ export default class SubscriptionSchema extends BaseUISchema{
|
|||
helpMessageMode: ['edit', 'create'],
|
||||
},
|
||||
{
|
||||
id: 'two_phase', label: gettext('Two phase?'),
|
||||
type: 'switch', mode: ['create', 'properties'],
|
||||
id: 'two_phase',
|
||||
label: gettext('Two phase?'),
|
||||
type: 'switch',
|
||||
group: gettext('With'),
|
||||
mode: (() => {
|
||||
if (obj.version >= 180000) {
|
||||
return ['create', 'edit', 'properties'];
|
||||
} else if (obj.version >= 150000 && obj.version < 180000) {
|
||||
return ['create', 'properties'];
|
||||
}
|
||||
return [];
|
||||
})(),
|
||||
min_version: 150000,
|
||||
helpMessage: gettext('Specifies whether two-phase commit is enabled for this subscription.'),
|
||||
helpMessageMode: ['edit', 'create'],
|
||||
|
|
@ -465,6 +477,14 @@ export default class SubscriptionSchema extends BaseUISchema{
|
|||
helpMessage: gettext('Specifies whether the subscription will request the publisher to only send changes that do not have an origin or send changes regardless of origin. Setting origin to none means that the subscription will request the publisher to only send changes that do not have an origin. Setting origin to any means that the publisher sends changes regardless of their origin.'),
|
||||
helpMessageMode: ['edit', 'create'],
|
||||
},
|
||||
{
|
||||
id: 'failover', label: gettext('Failover'),
|
||||
type: 'switch', mode: ['create', 'edit', 'properties'],
|
||||
group: gettext('With'),
|
||||
min_version: 170000,
|
||||
helpMessage: gettext('Specifies whether the replication slots associated with the subscription are enabled to be synced to the standbys so that logical replication can be resumed from the new primary after failover'),
|
||||
helpMessageMode: ['edit', 'create'],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
{% if data.copy_data is defined or data.create_slot is defined or data.slot_name is defined or data.sync is defined %}
|
||||
{% set add_semicolon_after_enabled = 'enabled' %}
|
||||
{% endif %}
|
||||
{% if data.create_slot is defined or data.slot_name is defined %}
|
||||
{% set add_semicolon_after_copy_data = 'copy_data' %}
|
||||
{% endif %}
|
||||
{% if data.slot_name is defined or data.sync is defined %}
|
||||
{% set add_semicolon_after_create_slot = 'create_slot' %}
|
||||
{% endif %}
|
||||
{% if data.sync is defined %}
|
||||
{% set add_semicolon_after_slot_name = 'slot_name' %}
|
||||
{% endif %}
|
||||
|
||||
CREATE SUBSCRIPTION {{ conn|qtIdent(data.name) }}
|
||||
{% if data.host or data.port or data.username or data.password or data.db or data.connect_timeout or data.passfile or data.sslmode or data.sslcompression or data.sslcert or data.sslkey or data.sslrootcert or data.sslcrl%}
|
||||
CONNECTION '{% if data.host %}host={{data.host}}{% endif %}{% if data.port %} port={{ data.port }}{% endif %}{% if data.username %} user={{ data.username }}{% endif %}{% if data.db %} dbname={{ data.db }}{% endif %}{% if data.connect_timeout %} connect_timeout={{ data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %}password={{ data.password}}{% endif %}{% endif %}{% if data.sslmode %} sslmode={{ data.sslmode }}{% endif %}{% if data.sslcompression %} sslcompression={{ data.sslcompression }}{% endif %}{% if data.sslcert %} sslcert={{ data.sslcert }}{% endif %}{% if data.sslkey %} sslkey={{ data.sslkey }}{% endif %}{% if data.sslrootcert %} sslrootcert={{ data.sslrootcert }}{% endif %}{% if data.sslcrl %} sslcrl={{ data.sslcrl }}{% endif %}'
|
||||
{% endif %}
|
||||
{% if data.pub %}
|
||||
PUBLICATION {% for pub in data.pub %}{% if loop.index != 1 %},{% endif %}{{ conn|qtIdent(pub) }}{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
WITH ({% if data.connect is defined %}connect = {{ data.connect|lower}}, {% endif %}enabled = {{ data.enabled|lower}}, {% if data.copy_data is defined %}copy_data = {{ data.copy_data|lower}}{% if add_semicolon_after_copy_data == 'copy_data' %}, {% endif %}{% endif %}
|
||||
{% if data.create_slot is defined %}create_slot = {{ data.create_slot|lower }}{% if add_semicolon_after_create_slot == 'create_slot' %}, {% endif %}{% endif %}
|
||||
{% if data.slot_name is defined and data.slot_name != ''%}slot_name = {{ data.slot_name }}{% if add_semicolon_after_slot_name == 'slot_name' %}, {% endif %}{% endif %}{% if data.sync %}synchronous_commit = '{{ data.sync }}', {% endif %}binary = {{ data.binary|lower}}, streaming = '{{ data.streaming}}', two_phase = {{ data.two_phase|lower}}, disable_on_error = {{ data.disable_on_error|lower}}, run_as_owner = {{ data.run_as_owner|lower}}, password_required = {{ data.password_required|lower}}, origin = '{{ data.origin}}', failover = {{ data.failover|lower}});
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
SELECT sub.oid as oid,
|
||||
subname as name,
|
||||
subpublications as pub,
|
||||
subpublications as proppub,
|
||||
sub.subsynccommit as sync,
|
||||
pga.rolname as subowner,
|
||||
subslotname as slot_name,
|
||||
subenabled as enabled,
|
||||
subbinary as binary,
|
||||
substream as streaming,
|
||||
subtwophasestate as two_phase,
|
||||
subdisableonerr as disable_on_error,
|
||||
subpasswordrequired as password_required,
|
||||
subrunasowner as run_as_owner,
|
||||
suborigin as origin,
|
||||
subfailover as failover,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,' port',1), '=',2) as host,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'port=',2), ' ',1) as port,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'user=',2), ' ',1) as username,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'dbname=',2), ' ',1) as db,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'connect_timeout=',2), ' ',1) as connect_timeout,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'passfile=',2), ' ',1) as passfile,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'sslmode=',2), ' ',1) as sslmode,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'sslcompression=',2), ' ',1) as sslcompression,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'sslcert=',2), ' ',1) as sslcert,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'sslkey=',2), ' ',1) as sslkey,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'sslrootcert=',2), ' ',1) as sslrootcert,
|
||||
pg_catalog.SPLIT_PART(pg_catalog.SPLIT_PART(subconninfo,'sslcrl=',2), ' ',1) as sslcrl
|
||||
FROM pg_catalog.pg_subscription sub join pg_catalog.pg_roles pga on sub.subowner= pga.oid
|
||||
WHERE
|
||||
{% if subid %}
|
||||
sub.oid = {{ subid }};
|
||||
{% else %}
|
||||
sub.subdbid = {{ did }};
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
{% if data.sync is defined or data.failover is defined %}
|
||||
{% set add_comma_after_slot_name = 'slot_name' %}
|
||||
{% endif %}
|
||||
{% if data.binary is defined or data.streaming is defined or data.disable_on_error is defined or data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_sync = 'sync' %}
|
||||
{% endif %}
|
||||
{% if data.streaming is defined or data.disable_on_error is defined or data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_binary = 'binary' %}
|
||||
{% endif %}
|
||||
{% if data.disable_on_error is defined or data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_streaming = 'streaming' %}
|
||||
{% endif %}
|
||||
{% if data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_disable_on_error = 'disable_on_error' %}
|
||||
{% endif %}
|
||||
{% if data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_run_as_owner = 'run_as_owner' %}
|
||||
{% endif %}
|
||||
{% if data.origin is defined %}
|
||||
{% set add_comma_after_password_required = 'password_required' %}
|
||||
{% endif %}
|
||||
{% if data.failover is defined %}
|
||||
{% set add_comma_after_origin = 'origin' %}
|
||||
{% endif %}
|
||||
{#####################################################}
|
||||
{## Change owner of subscription ##}
|
||||
{#####################################################}
|
||||
{% if data.subowner and data.subowner != o_data.subowner %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
OWNER TO {{ data.subowner }};
|
||||
|
||||
{% endif %}
|
||||
{### Disable subscription ###}
|
||||
{% if data.enabled is defined and data.enabled != o_data.enabled %}
|
||||
{% if not data.enabled %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }} DISABLE;
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{### Alter parameters of subscription ###}
|
||||
{% if (data.slot_name is defined and data.slot_name != o_data.slot_name) or (data.sync is defined and data.sync != o_data.sync) or (data.binary is defined and data.binary!=o_data.binary) or (data.streaming is defined and data.streaming!=o_data.streaming) or (data.disable_on_error is defined and data.disable_on_error!=o_data.disable_on_error) or (data.run_as_owner is defined and data.run_as_owner!=o_data.run_as_owner) or (data.password_required is defined and data.password_required!=o_data.password_required) or (data.origin is defined and data.origin!=o_data.origin) or (data.failover is defined and data.failover!=o_data.failover) %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
SET ({% if data.slot_name is defined and data.slot_name != o_data.slot_name %}slot_name = {{ data.slot_name }}{% if add_comma_after_slot_name == 'slot_name' %}, {% endif %}{% endif %}{% if data.sync is defined and data.sync != o_data.sync %}synchronous_commit = '{{ data.sync }}'{% if add_comma_after_sync == 'sync' %}, {% endif %}{% endif %}{% if data.binary is defined and data.binary!=o_data.binary %}binary = {{ data.binary|lower}}{% if add_comma_after_binary == 'binary' %}, {% endif %}{% endif %}{% if data.streaming is defined and data.streaming!=o_data.streaming %}streaming = '{{ data.streaming }}'{% if add_comma_after_streaming == 'streaming' %}, {% endif %}{% endif %}{% if data.disable_on_error is defined and data.disable_on_error!=o_data.disable_on_error %}disable_on_error = {{ data.disable_on_error|lower}}{% if add_comma_after_disable_on_error == 'disable_on_error' %}, {% endif %}{% endif %}{% if data.run_as_owner is defined and data.run_as_owner!=o_data.run_as_owner %}run_as_owner = {{ data.run_as_owner|lower}}{% if add_comma_after_run_as_owner == 'run_as_owner' %}, {% endif %}{% endif %}{% if data.password_required is defined and data.password_required!=o_data.password_required %}password_required = {{ data.password_required|lower}}{% if add_comma_after_password_required == 'password_required' %}, {% endif %}{% endif %}{% if data.origin is defined and data.origin!=o_data.origin %}origin = '{{ data.origin }}'{% if add_comma_after_origin == 'origin' %}, {% endif %}{% endif %}{% if data.failover is defined and data.failover!=o_data.failover %}failover = {{ data.failover|lower}}{% endif %});
|
||||
|
||||
{% endif %}
|
||||
{### Enable subscription ###}
|
||||
{% if data.enabled is defined and data.enabled != o_data.enabled %}
|
||||
{% if data.enabled %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }} ENABLE;
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{### Refresh publication ###}
|
||||
{% if data.refresh_pub %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
REFRESH PUBLICATION{% if not data.copy_data_after_refresh %} WITH (copy_data = false){% else %} WITH (copy_data = true){% endif %};
|
||||
|
||||
{% endif %}
|
||||
{### Alter publication of subscription ###}
|
||||
{% if data.pub%}
|
||||
{% if data.pub and not data.refresh_pub and not data.enabled %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
SET PUBLICATION {% for pub in data.pub %}{% if loop.index != 1 %},{% endif %}{{ conn|qtIdent(pub) }}{% endfor %} WITH (refresh = false);
|
||||
{% else %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
SET PUBLICATION {% for pub in data.pub %}{% if loop.index != 1 %},{% endif %}{{ conn|qtIdent(pub) }}{% endfor %};
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{### Alter subscription connection info ###}
|
||||
{% if data.host or data.port or data.username or data.db or data.connect_timeout or data.passfile or data.sslmode or data.sslcompression or data.sslcert or data.sslkey or data.sslrootcert or data.sslcrl %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
CONNECTION 'host={{ o_data.host}} port={{ o_data.port }} user={{ o_data.username }} dbname={{ o_data.db }} connect_timeout={{ o_data.connect_timeout }} {% if data.passfile %} passfile={{ o_data.passfile }}{% endif %} sslmode={{ o_data.sslmode }}{% if data.sslcompression %} sslcompression={{ data.sslcompression }}{% endif %}{% if data.sslcert %} sslcert={{ data.sslcert }}{% endif %}{% if data.sslkey %} sslkey={{ data.sslkey }}{% endif %}{% if data.sslrootcert %} sslrootcert={{ data.sslrootcert }}{% endif %}{% if data.sslcrl %} sslcrl={{ data.sslcrl }}{% endif %}';
|
||||
{% endif %}
|
||||
{### Alter subscription name ###}
|
||||
{% if data.name and data.name != o_data.name %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
{% if data.sync is defined or data.failover is defined %}
|
||||
{% set add_comma_after_slot_name = 'slot_name' %}
|
||||
{% endif %}
|
||||
{% if data.binary is defined or data.streaming is defined or data.disable_on_error is defined or data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_sync = 'sync' %}
|
||||
{% endif %}
|
||||
{% if data.streaming is defined or data.disable_on_error is defined or data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_binary = 'binary' %}
|
||||
{% endif %}
|
||||
{% if data.disable_on_error is defined or data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_streaming = 'streaming' %}
|
||||
{% endif %}
|
||||
{% if data.run_as_owner is defined or data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_disable_on_error = 'disable_on_error' %}
|
||||
{% endif %}
|
||||
{% if data.password_required is defined or data.origin is defined %}
|
||||
{% set add_comma_after_run_as_owner = 'run_as_owner' %}
|
||||
{% endif %}
|
||||
{% if data.origin is defined %}
|
||||
{% set add_comma_after_password_required = 'password_required' %}
|
||||
{% endif %}
|
||||
{% if data.failover is defined %}
|
||||
{% set add_comma_after_origin = 'origin' %}
|
||||
{% endif %}
|
||||
{% if data.two_phase is defined %}
|
||||
{% set add_comma_after_failover = 'failover' %}
|
||||
{% endif %}
|
||||
{#####################################################}
|
||||
{## Change owner of subscription ##}
|
||||
{#####################################################}
|
||||
{% if data.subowner and data.subowner != o_data.subowner %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
OWNER TO {{ data.subowner }};
|
||||
|
||||
{% endif %}
|
||||
{### Disable subscription ###}
|
||||
{% if data.enabled is defined and data.enabled != o_data.enabled %}
|
||||
{% if not data.enabled %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }} DISABLE;
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{### Alter parameters of subscription ###}
|
||||
{% if (data.slot_name is defined and data.slot_name != o_data.slot_name) or (data.sync is defined and data.sync != o_data.sync) or (data.binary is defined and data.binary!=o_data.binary) or (data.streaming is defined and data.streaming!=o_data.streaming) or (data.disable_on_error is defined and data.disable_on_error!=o_data.disable_on_error) or (data.run_as_owner is defined and data.run_as_owner!=o_data.run_as_owner) or (data.password_required is defined and data.password_required!=o_data.password_required) or (data.origin is defined and data.origin!=o_data.origin) or (data.failover is defined and data.failover!=o_data.failover) or (data.two_phase is defined and data.two_phase!=o_data.two_phase) %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
SET ({% if data.slot_name is defined and data.slot_name != o_data.slot_name %}slot_name = {{ data.slot_name }}{% if add_comma_after_slot_name == 'slot_name' %}, {% endif %}{% endif %}{% if data.sync is defined and data.sync != o_data.sync %}synchronous_commit = '{{ data.sync }}'{% if add_comma_after_sync == 'sync' %}, {% endif %}{% endif %}{% if data.binary is defined and data.binary!=o_data.binary %}binary = {{ data.binary|lower}}{% if add_comma_after_binary == 'binary' %}, {% endif %}{% endif %}{% if data.streaming is defined and data.streaming!=o_data.streaming %}streaming = '{{ data.streaming }}'{% if add_comma_after_streaming == 'streaming' %}, {% endif %}{% endif %}{% if data.disable_on_error is defined and data.disable_on_error!=o_data.disable_on_error %}disable_on_error = {{ data.disable_on_error|lower}}{% if add_comma_after_disable_on_error == 'disable_on_error' %}, {% endif %}{% endif %}{% if data.run_as_owner is defined and data.run_as_owner!=o_data.run_as_owner %}run_as_owner = {{ data.run_as_owner|lower}}{% if add_comma_after_run_as_owner == 'run_as_owner' %}, {% endif %}{% endif %}{% if data.password_required is defined and data.password_required!=o_data.password_required %}password_required = {{ data.password_required|lower}}{% if add_comma_after_password_required == 'password_required' %}, {% endif %}{% endif %}{% if data.origin is defined and data.origin!=o_data.origin %}origin = '{{ data.origin }}'{% if add_comma_after_origin == 'origin' %}, {% endif %}{% endif %}{% if data.failover is defined and data.failover!=o_data.failover %}failover = {{ data.failover|lower}}{% if add_comma_after_failover == 'failover' %}, {% endif %}{% endif %}{% if data.two_phase is defined and data.two_phase!=o_data.two_phase %}two_phase = {{ data.two_phase|lower}}{% endif %});
|
||||
|
||||
{% endif %}
|
||||
{### Enable subscription ###}
|
||||
{% if data.enabled is defined and data.enabled != o_data.enabled %}
|
||||
{% if data.enabled %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }} ENABLE;
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{### Refresh publication ###}
|
||||
{% if data.refresh_pub %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
REFRESH PUBLICATION{% if not data.copy_data_after_refresh %} WITH (copy_data = false){% else %} WITH (copy_data = true){% endif %};
|
||||
|
||||
{% endif %}
|
||||
{### Alter publication of subscription ###}
|
||||
{% if data.pub%}
|
||||
{% if data.pub and not data.refresh_pub and not data.enabled %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
SET PUBLICATION {% for pub in data.pub %}{% if loop.index != 1 %},{% endif %}{{ conn|qtIdent(pub) }}{% endfor %} WITH (refresh = false);
|
||||
{% else %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
SET PUBLICATION {% for pub in data.pub %}{% if loop.index != 1 %},{% endif %}{{ conn|qtIdent(pub) }}{% endfor %};
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{### Alter subscription connection info ###}
|
||||
{% if data.host or data.port or data.username or data.db or data.connect_timeout or data.passfile or data.sslmode or data.sslcompression or data.sslcert or data.sslkey or data.sslrootcert or data.sslcrl %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
CONNECTION 'host={{ o_data.host}} port={{ o_data.port }} user={{ o_data.username }} dbname={{ o_data.db }} connect_timeout={{ o_data.connect_timeout }} {% if data.passfile %} passfile={{ o_data.passfile }}{% endif %} sslmode={{ o_data.sslmode }}{% if data.sslcompression %} sslcompression={{ data.sslcompression }}{% endif %}{% if data.sslcert %} sslcert={{ data.sslcert }}{% endif %}{% if data.sslkey %} sslkey={{ data.sslkey }}{% endif %}{% if data.sslrootcert %} sslrootcert={{ data.sslrootcert }}{% endif %}{% if data.sslcrl %} sslcrl={{ data.sslcrl }}{% endif %}';
|
||||
{% endif %}
|
||||
{### Alter subscription name ###}
|
||||
{% if data.name and data.name != o_data.name %}
|
||||
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- Subscription: test_create_subscription
|
||||
|
||||
-- DROP SUBSCRIPTION IF EXISTS test_create_subscription;
|
||||
|
||||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5917 user=postgres dbname=postgres connect_timeout=10 sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = test_create_subscription, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = true, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = true);
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER SUBSCRIPTION test_create_subscription
|
||||
SET (failover = true);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- Subscription: test_create_subscription
|
||||
|
||||
-- DROP SUBSCRIPTION IF EXISTS test_create_subscription;
|
||||
|
||||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5917 user=postgres dbname=postgres connect_timeout=10 sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = true, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = true);
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER SUBSCRIPTION test_create_subscription
|
||||
SET (slot_name = None);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- Subscription: test_create_subscription
|
||||
|
||||
-- DROP SUBSCRIPTION IF EXISTS test_create_subscription;
|
||||
|
||||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5917 user=postgres dbname=postgres connect_timeout=10 sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = test_create_subscription, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = true, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = false);
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5917 user=postgres dbname=postgres connect_timeout=10 password=xxxxxx sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = true, enabled = false, copy_data = false, create_slot = false, slot_name = test_create_subscription, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = true, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = false);
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Table For Subscription",
|
||||
"endpoint": "NODE-table.obj",
|
||||
"sql_endpoint": "NODE-table.sql_id",
|
||||
"data": {
|
||||
"name": "test_table",
|
||||
"columns": [
|
||||
{
|
||||
"name": "emp_id",
|
||||
"cltype": "integer",
|
||||
"is_primary_key": true
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"cltype": "text"
|
||||
},
|
||||
{
|
||||
"name": "salary",
|
||||
"cltype": "bigint"
|
||||
}
|
||||
],
|
||||
"is_partitioned": false,
|
||||
"schema": "public",
|
||||
"spcname": "pg_default"
|
||||
},
|
||||
"store_object_id": true
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Publication for Subscription",
|
||||
"endpoint": "NODE-publication.obj",
|
||||
"sql_endpoint": "NODE-publication.sql_id",
|
||||
"msql_endpoint": "NODE-publication.msql",
|
||||
"precondition_sql": "SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription' UNION ALL SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription') AND pg_create_logical_replication_slot('test_create_subscription', 'pgoutput', false) IS NOT NULL LIMIT 1;",
|
||||
"data": {
|
||||
"name": "test_publication",
|
||||
"evnt_insert": true,
|
||||
"evnt_update": true,
|
||||
"evnt_delete": true,
|
||||
"evnt_truncate": true,
|
||||
"pubowner": "postgres",
|
||||
"publish_via_partition_root": false,
|
||||
"all_table": false,
|
||||
"only_table": false,
|
||||
"pubtable": [{
|
||||
"table_name": "public.test_table"
|
||||
}],
|
||||
"pubschema": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Subscription",
|
||||
"endpoint": "NODE-subscription.obj",
|
||||
"sql_endpoint": "NODE-subscription.sql_id",
|
||||
"msql_endpoint": "NODE-subscription.msql",
|
||||
"data": {
|
||||
"name": "test_create_subscription",
|
||||
"subowner": "postgres",
|
||||
"host": "localhost",
|
||||
"port": 5917,
|
||||
"db": "postgres",
|
||||
"username": "postgres",
|
||||
"password": "postgres",
|
||||
"connect_timeout": 10,
|
||||
"pub": ["test_publication"],
|
||||
"sslmode": "prefer",
|
||||
"copy_data": false,
|
||||
"create_slot": false,
|
||||
"enabled": false,
|
||||
"connect": true,
|
||||
"slot_name": "test_create_subscription",
|
||||
"sync": "remote_apply",
|
||||
"streaming": true,
|
||||
"binary": true,
|
||||
"two_phase": true,
|
||||
"disable_on_error": true,
|
||||
"run_as_owner": true,
|
||||
"password_required": true,
|
||||
"origin": "any",
|
||||
"service": "",
|
||||
"failover": false
|
||||
},
|
||||
"expected_sql_file": "create_subscription.sql",
|
||||
"expected_msql_file": "create_subscription_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter failover parameter of subscription",
|
||||
"endpoint": "NODE-subscription.obj_id",
|
||||
"sql_endpoint": "NODE-subscription.sql_id",
|
||||
"msql_endpoint": "NODE-subscription.msql_id",
|
||||
"data": {
|
||||
"failover": true
|
||||
},
|
||||
"expected_sql_file": "alter_failover_parameter.sql",
|
||||
"expected_msql_file": "alter_failover_parameter_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter slot_name parameter of subscription",
|
||||
"endpoint": "NODE-subscription.obj_id",
|
||||
"sql_endpoint": "NODE-subscription.sql_id",
|
||||
"msql_endpoint": "NODE-subscription.msql_id",
|
||||
"data": {
|
||||
"slot_name": "None"
|
||||
},
|
||||
"expected_sql_file": "alter_slot_name_parameter.sql",
|
||||
"expected_msql_file": "alter_slot_name_parameter_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop subscription",
|
||||
"endpoint": "NODE-subscription.delete_id",
|
||||
"data": {
|
||||
"name": "test_create_subscription"
|
||||
},
|
||||
"post_scenario_sql": "SELECT 1 WHERE EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription') AND (SELECT pg_drop_replication_slot('test_create_subscription')) IS NOT NULL UNION ALL SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription') LIMIT 1;"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- Subscription: test_create_subscription
|
||||
|
||||
-- DROP SUBSCRIPTION IF EXISTS test_create_subscription;
|
||||
|
||||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5434 user=postgres dbname=postgres connect_timeout=10 sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = true, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = false);
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER SUBSCRIPTION test_create_subscription
|
||||
SET (slot_name = None);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- Subscription: test_create_subscription
|
||||
|
||||
-- DROP SUBSCRIPTION IF EXISTS test_create_subscription;
|
||||
|
||||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5434 user=postgres dbname=postgres connect_timeout=10 sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = test_create_subscription, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = true, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = false);
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER SUBSCRIPTION test_create_subscription
|
||||
SET (two_phase = true);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- Subscription: test_create_subscription
|
||||
|
||||
-- DROP SUBSCRIPTION IF EXISTS test_create_subscription;
|
||||
|
||||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5434 user=postgres dbname=postgres connect_timeout=10 sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = test_create_subscription, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = false, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = false);
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5434 user=postgres dbname=postgres connect_timeout=10 password=xxxxxx sslmode=prefer'
|
||||
PUBLICATION test_publication
|
||||
WITH (connect = false, enabled = false, copy_data = false, create_slot = false, slot_name = test_create_subscription, synchronous_commit = 'remote_apply', binary = true, streaming = 'True', two_phase = false, disable_on_error = true, run_as_owner = true, password_required = true, origin = 'any', failover = false);
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Subscription",
|
||||
"endpoint": "NODE-subscription.obj",
|
||||
"sql_endpoint": "NODE-subscription.sql_id",
|
||||
"msql_endpoint": "NODE-subscription.msql",
|
||||
"precondition_sql": "SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription' UNION ALL SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription') AND pg_create_logical_replication_slot('test_create_subscription', 'pgoutput', false) IS NOT NULL LIMIT 1;",
|
||||
"data": {
|
||||
"name": "test_create_subscription",
|
||||
"subowner": "postgres",
|
||||
"host": "localhost",
|
||||
"port": 5434,
|
||||
"db": "postgres",
|
||||
"username": "postgres",
|
||||
"password": "edb",
|
||||
"connect_timeout": 10,
|
||||
"pub": ["test_publication"],
|
||||
"sslmode": "prefer",
|
||||
"copy_data": false,
|
||||
"create_slot": false,
|
||||
"enabled": false,
|
||||
"connect": false,
|
||||
"slot_name": "test_create_subscription",
|
||||
"sync": "remote_apply",
|
||||
"streaming": true,
|
||||
"binary": true,
|
||||
"two_phase": false,
|
||||
"disable_on_error": true,
|
||||
"run_as_owner": true,
|
||||
"password_required": true,
|
||||
"origin": "any",
|
||||
"service": "",
|
||||
"failover": false
|
||||
},
|
||||
"expected_sql_file": "create_subscription.sql",
|
||||
"expected_msql_file": "create_subscription_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter two_phase parameter of subscription",
|
||||
"endpoint": "NODE-subscription.obj_id",
|
||||
"sql_endpoint": "NODE-subscription.sql_id",
|
||||
"msql_endpoint": "NODE-subscription.msql_id",
|
||||
"data": {
|
||||
"two_phase": true
|
||||
},
|
||||
"expected_sql_file": "alter_two_phase_parameter.sql",
|
||||
"expected_msql_file": "alter_two_phase_parameter_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter slot_name parameter of subscription",
|
||||
"endpoint": "NODE-subscription.obj_id",
|
||||
"sql_endpoint": "NODE-subscription.sql_id",
|
||||
"msql_endpoint": "NODE-subscription.msql_id",
|
||||
"data": {
|
||||
"slot_name": "None"
|
||||
},
|
||||
"expected_sql_file": "alter_slot_name_parameter.sql",
|
||||
"expected_msql_file": "alter_slot_name_parameter_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop subscription",
|
||||
"endpoint": "NODE-subscription.delete_id",
|
||||
"data": {
|
||||
"name": "test_create_subscription"
|
||||
},
|
||||
"post_scenario_sql": "SELECT 1 WHERE EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription') AND (SELECT pg_drop_replication_slot('test_create_subscription')) IS NOT NULL UNION ALL SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_create_subscription') LIMIT 1;"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
"streaming":false,
|
||||
"password_required":true,
|
||||
"run_as_owner":false,
|
||||
"failover": false,
|
||||
"origin":"any",
|
||||
"pub": ["sample__1"]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -428,7 +428,7 @@ export class ResultSetUtils {
|
|||
async (formData) => {
|
||||
try {
|
||||
await connectServer(
|
||||
this.api,
|
||||
this.api,
|
||||
this.queryToolCtx.modal,
|
||||
this.queryToolCtx.params.sid,
|
||||
this.queryToolCtx.params.user,
|
||||
|
|
@ -669,8 +669,9 @@ export class ResultSetUtils {
|
|||
return columnVal;
|
||||
}
|
||||
|
||||
processRows(result, columns, fromClipboard=false, pasteSerials=false) {
|
||||
processRows(result, columns, options={}) {
|
||||
let retVal = [];
|
||||
let {fromClipboard=false, pasteSerials=false, isNewRow=false} = options;
|
||||
if(!_.isArray(result) || !_.size(result)) {
|
||||
return retVal;
|
||||
}
|
||||
|
|
@ -685,8 +686,9 @@ export class ResultSetUtils {
|
|||
// Convert 2darray to dict.
|
||||
let rowObj = {};
|
||||
for(const col of columns) {
|
||||
// if column data is undefined and there is not default value then set it to null.
|
||||
let columnVal = rec[col.pos] ?? (col.has_default_val ? undefined : null);
|
||||
// if column data is not present for existing rows then use null
|
||||
// for new rows, it should be undefined if there is default value.
|
||||
let columnVal = rec[col.pos] ?? ((col.has_default_val && isNewRow) ? undefined : null);
|
||||
/* If the source is clipboard, then it needs some extra handling */
|
||||
if(fromClipboard) {
|
||||
columnVal = this.processClipboardVal(columnVal, col, copiedRowsObjects[recIdx]?.[col.key], pasteSerials);
|
||||
|
|
@ -1379,7 +1381,7 @@ export function ResultSet() {
|
|||
}, [selectedRows, queryData, dataChangeStore, rows, allRowsSelect]);
|
||||
|
||||
useEffect(()=>{
|
||||
const triggerAddRows = (_rows, fromClipboard, pasteSerials)=>{
|
||||
const triggerAddRows = (_rows, options)=>{
|
||||
let insPosn = 0;
|
||||
if(selectedRows.size > 0) {
|
||||
let selectedRowsSorted = Array.from(selectedRows);
|
||||
|
|
@ -1396,7 +1398,7 @@ export function ResultSet() {
|
|||
return x;
|
||||
});
|
||||
}
|
||||
let newRows = rsu.current.processRows(_rows, columns, fromClipboard, pasteSerials);
|
||||
let newRows = rsu.current.processRows(_rows, columns, options);
|
||||
setRows((prev)=>[
|
||||
...prev.slice(0, insPosn),
|
||||
...newRows,
|
||||
|
|
|
|||
|
|
@ -281,13 +281,13 @@ export function ResultSetToolbar({query, canEdit, totalRowCount, pagination, all
|
|||
field_separator: queryToolPref.results_grid_field_separator,
|
||||
});
|
||||
let copiedRows = copyUtils.getCopiedRows();
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, copiedRows, true, checkedMenuItems['paste_with_serials']);
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, copiedRows, {fromClipboard: true, pasteSerials: checkedMenuItems['paste_with_serials']});
|
||||
}, [queryToolPref, checkedMenuItems['paste_with_serials']]);
|
||||
const copyData = ()=>{
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.COPY_DATA, checkedMenuItems['copy_with_headers']);
|
||||
};
|
||||
const addRow = useCallback(()=>{
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, [[]]);
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, [[]], {isNewRow: true});
|
||||
}, []);
|
||||
const downloadResult = useCallback(()=>{
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_RESULTS);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ def get_version_mapping_directories():
|
|||
:param server_type:
|
||||
:return:
|
||||
"""
|
||||
return ({'name': "17_plus", 'number': 170000},
|
||||
return ({'name': "18_plus", 'number': 180000},
|
||||
{'name': "17_plus", 'number': 170000},
|
||||
{'name': "16_plus", 'number': 160000},
|
||||
{'name': "15_plus", 'number': 150000},
|
||||
{'name': "14_plus", 'number': 140000},
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ describe('FunctionSchema', ()=>{
|
|||
getLanguage: [],
|
||||
getTypes: [],
|
||||
getSupportFunctions: [],
|
||||
extensionsList: [],
|
||||
},
|
||||
{
|
||||
node_info: {
|
||||
|
|
@ -109,10 +110,6 @@ describe('FunctionSchema', ()=>{
|
|||
let schemaObj = createSchemaObj();
|
||||
let getInitData = ()=>Promise.resolve({});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
beforeEach(()=>{
|
||||
genericBeforeEach();
|
||||
});
|
||||
|
|
@ -133,6 +130,13 @@ describe('FunctionSchema', ()=>{
|
|||
await getPropertiesView(createSchemaObj(), getInitData);
|
||||
});
|
||||
|
||||
it('dependsonextensions field exists', ()=>{
|
||||
let field = _.find(schemaObj.fields, (f)=>f.id=='dependsonextensions');
|
||||
expect(field).toBeTruthy();
|
||||
expect(field.type).toBe('select');
|
||||
expect(field.controlProps.multiple).toBe(true);
|
||||
});
|
||||
|
||||
it('proiswindow visible', async ()=>{
|
||||
|
||||
|
||||
|
|
@ -449,7 +453,7 @@ describe('FunctionSchema', ()=>{
|
|||
schemaObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('prosrc_c', null);
|
||||
});
|
||||
|
||||
|
||||
it('validate', ()=>{
|
||||
let state = {prorettypename: 'char'};
|
||||
let setError = jest.fn();
|
||||
|
|
|
|||
|
|
@ -153,7 +153,6 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator):
|
|||
# Check the final status of the test case
|
||||
self.assertEqual(self.final_test_status, True)
|
||||
|
||||
def tearDown(self):
|
||||
database_utils.disconnect_database(
|
||||
self, self.server_information['server_id'],
|
||||
self.server_information['db_id'])
|
||||
|
|
@ -601,7 +600,10 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator):
|
|||
try:
|
||||
pg_cursor.execute(precondition_sql)
|
||||
precondition_result = pg_cursor.fetchone()
|
||||
if len(precondition_result) >= 1 and precondition_result[0] == '1':
|
||||
if ((len(precondition_result) >= 1 and
|
||||
precondition_result[0] == '1') or
|
||||
(isinstance(precondition_result, tuple) and
|
||||
precondition_result[0] == 1)):
|
||||
precondition_flag = True
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
|
|
|||
1008
web/yarn.lock
1008
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue