Compare commits

..
78 Commits
Author SHA1 Message Date
Akshay Joshi 8b130b3351 Added corepack enable command. 2024-03-04 17:30:16 +05:30
Akshay Joshi d26182d178 Update yarn version for OSX build functions. 2024-03-04 15:23:07 +05:30
Akshay Joshi 8ddcdbf499 Updated version for release 8.4 2024-03-04 14:50:23 +05:30
Akshay Joshi 4e49d752fb Unsafe Deserialization and Remote Code Execution by an Authenticated user in pgAdmin 4 (CVE-2024-2044). 2024-03-04 13:22:09 +05:30
Libor M 0cbb5324bf Czech translation for version 8.4 2024-03-04 11:12:05 +05:30
Akshay Joshi 1e90245650 Update release note 2024-03-01 12:14:43 +05:30
Florian 3425bc0349 Ensure that the OAuth2 session is logged out when users log out from pgAdmin. #7193 2024-03-01 12:09:01 +05:30
Domenico Sgarbossa 7593bb98c1 Italian translation update for v8.4 2024-03-01 11:56:47 +05:30
Akshay Joshi d8c007f644 Fixed duplicate explicit target name issue in the documentation. 2024-02-29 19:14:59 +05:30
Akshay Joshi 0ea51861c7 Update message catalogs for v8.4 2024-02-29 18:40:50 +05:30
Akshay Joshi cfbf4d8452 Updated URL in the container deployment docs. 2024-02-29 18:37:34 +05:30
Pravesh Sharma af88851228 Remove role related checks on the UI dashboard when terminating session/query and let PostgreSQL take care of it. #7217 2024-02-29 16:43:07 +05:30
Akshay Joshi 864f23c60d Update release note. 2024-02-29 11:53:33 +05:30
Anil Sahoo 8dffcf842f Added documentation for System Statistics tab. #7148 2024-02-29 11:34:54 +05:30
Pravesh Sharma 6971d8c3a1 Fixed an issue where preferences.json mapped to container was not having any effect on preferences. #6058 2024-02-27 12:11:59 +05:30
Aditya Toshniwal 43f4cc4e17 Fix an issue where type column in dependencies tab is not showing correct label. #7225 2024-02-26 11:59:30 +05:30
Aditya Toshniwal a5530f59f7 Fix sonarqube issues for the rule - 'If' statement should not be the only statement in 'else' block 2024-02-26 11:55:36 +05:30
Aditya Toshniwal e272552780 Fix doc builds failing because of release notes update 2024-02-23 14:13:06 +05:30
Aditya Toshniwal dfbbc3b1a1 Update release notes. 2024-02-23 14:08:56 +05:30
Anil Sahoo a8ab714606 Fix multiple issues where PasswordExecCommand was not working in server mode and PasswordExecCommand was not loaded when importing servers. #6792 2024-02-23 14:05:26 +05:30
Pravesh Sharma 2ab419c8a5 Fixed EPAS RESQL test case failure. 2024-02-23 11:25:54 +05:30
Aditya Toshniwal 29e85a6b06 Fix SonarQube issues 2024-02-22 16:54:20 +05:30
Khushboo Vashi 125d36e7d2 Update release notes. 2024-02-22 16:43:50 +05:30
Florian 16406f88a7 Add support for JSON log format. #7138 2024-02-22 16:39:25 +05:30
Pravesh Sharma dee1a2ae6b Upgrade python package Flask-Security-Too to 5.3.* #7234 2024-02-22 14:43:48 +05:30
Aditya Toshniwal 1f879b3e87 Upgrade python package cryptography to 42.0.* 2024-02-22 11:57:44 +05:30
Aditya Toshniwal b5bd236387 Fix edit menu related issues of query tool codemirror 2024-02-21 15:54:57 +05:30
Akshay Joshi 41812c9fde Update release note. 2024-02-21 11:25:55 +05:30
Pravesh Sharma 4faf2a3c6d Fixed an issue where dependencies and dependents were not showing if a composite type is used as an attribute in another composite type. #7027 2024-02-21 11:18:44 +05:30
Aditya Toshniwal d3ede3151a Upgrade CodeMirror from version 5 to 6. #7097 2024-02-21 11:15:25 +05:30
Aditya Toshniwal 721290b1e9 Fix an issue where type column in dependents/dependencies tab is not showing correct label. #7225 2024-02-20 16:23:05 +05:30
Khushboo Vashi 10929157b4 Update Release Note. 2024-02-15 15:00:48 +05:30
Yogesh Mahajan 5a74022e8a Allow preferences customization using a configuration file. #6058 2024-02-15 14:58:31 +05:30
Akshay Joshi a74b0232f9 Update release note 2024-02-15 11:41:42 +05:30
Anil Sahoo e81a036850 Fix an issue where the scripts created by generate script of Schema diff for Table with sequence was not working earlier. #7165 2024-02-15 11:38:44 +05:30
Khushboo Vashi 389896411a Update Release Notes. 2024-02-14 11:24:20 +05:30
octo-dama 6adae46a4c Add --yes option for skipping the confirmation prompt while deleting the user via CLI for scripting purpose. #7204 2024-02-14 11:20:44 +05:30
Akshay Joshi 96ed38292f Added release note for v8.4 2024-02-09 16:49:58 +05:30
Anil Sahoo 47b2bc8a83 1) Fix the tabbed panel backward/forward shortcut for tabs. #6808
2) Remove shortcuts for the dialog tab backward/forward.
3) Used hotkeys.js in place of mousetrap for listening to keyboard shortcuts.
2024-02-09 16:33:30 +05:30
Anil Sahoo 9ad223c41c Fix an issue where constraint check control is enabled in edit table dialog. #7164 2024-02-09 16:26:46 +05:30
Ashesh Vashi d09833744a Separate the application name, branding & version information from the configuration file. #7187 2024-02-09 16:25:03 +05:30
Akshay Joshi c92e9c2953 Fixed all broken submenus of the Help menu due to the SonarQube fix. 2024-02-08 12:24:40 +05:30
Akshay Joshi af1f4b3aa7 Update version for release v8.3 2024-02-05 12:38:40 +05:30
Domenico Sgarbossa 4b40aac89f Italian translation for version 8.3 2024-02-05 10:48:35 +05:30
Libor M 0ff34ab6ae Czech translation for version 8.3 2024-02-05 10:48:04 +05:30
Yogesh Mahajan 9462296d33 Fixed API tests failed due to #7113 changes. 2024-02-05 10:47:43 +05:30
Aditya Toshniwal 0904adaed0 Update release notes 2024-02-02 12:55:13 +05:30
Pravesh Sharma f7045b58d4 Fixed an issue where format sql was messing up operator. #5083
- The formatting is done on client side now using sql-formattor JS lib. Backend API based formatting is removed.
- Added new options data type case, expression width, function case, lines between queries, logical operator new line and new line before semicolon available in the new lib.
- Removed old options comma-first notations, re-indent aligned, re-indent, strip comments and wrap after N characters as not available in the new library.
- Capitalise casing is replaced with Preserve casing as it is not supported by the new library.
- Also fixes #6785, #6990, #7115.
2024-02-02 12:28:25 +05:30
Sebastian Bogaci 459121566c Fix wrong default for FORCE_LOWER in the FLASK_GRAVATAR module #7175 2024-02-02 11:47:14 +05:30
Akshay Joshi e12e8bc9cf Update message catalogs for v8.3 2024-02-01 21:27:06 +05:30
Kristof Mattei 956401015d Fixed an issue pgAdmin fails to launch due to inconsistent PATH variable name on windows. #7153, #7125 2024-02-01 21:07:39 +05:30
Khushboo Vashi 1ac385be27 Update documentation for creating the configuration database. 2024-02-01 14:37:09 +05:30
Anil Sahoo 8145e042a6 Fix a backend server error when creating a named restore point. #7166 2024-02-01 14:20:22 +05:30
Aditya Toshniwal cdf49d6300 Fix failing feature tests 2024-01-30 13:01:57 +05:30
Aditya Toshniwal 028b70203c Fix SonarQube bugs 2024-01-29 18:39:30 +05:30
Akshay Joshi e23ef5d9df Update release note. 2024-01-29 14:54:53 +05:30
Yogesh Mahajan 711181c752 Ensure that the correct SQL is generated when changing the column data type to "char". #7113 2024-01-29 14:53:03 +05:30
Pravesh Sharma 3de19f66f2 Added support for column storage syntax while creating table. #6450 2024-01-29 11:32:34 +05:30
Akshay Joshi 4c5324bd99 Fixed API test cases for Backup. 2024-01-25 18:07:40 +05:30
Akshay Joshi 639a28fbfc Fixed code smell 'Prefer using an optional chain expression instead, as it's more concise and easier to read'. 2024-01-25 16:51:40 +05:30
Akshay Joshi 41fe1db884 Fixed PEP8 2024-01-25 12:51:29 +05:30
Akshay Joshi cafe69c235 Fixed SonarQube Bugs and API test cases. 2024-01-25 12:46:55 +05:30
Akshay Joshi d55c35c0e8 Revert yarnrc.yml and yarn.lock 2024-01-24 18:55:32 +05:30
Akshay Joshi 0e0cbc40b8 Fixed SonarQube code smell Replace the unused local variable with '_'. 2024-01-24 18:33:43 +05:30
Aditya Toshniwal 47aa070cc3 Update release notes 2024-01-22 16:17:58 +05:30
Yogesh Mahajan 4fe47b8e92 Ensure that password exec command is included in exported server data json. #6792 2024-01-22 13:38:34 +05:30
Aditya Toshniwal e80e82cd7f Allow drag-n-drop columns collection tree node as comma separated columns. #4419 2024-01-22 13:19:04 +05:30
Khushboo Vashi 29f13f8832 Update release notes. 2024-01-22 12:41:43 +05:30
Akshay Joshi 81fccc87b5 Added support to rename columns in Views. #6380 2024-01-22 12:27:55 +05:30
Aditya Toshniwal 93d25eea0b Use COOKIE_DEFAULT_PATH or SCRIPT_NAME in session cookie path. #6557 2024-01-22 12:25:20 +05:30
Yogesh Mahajan a166f8dc89 Skip debugger test cases to fix "too many clients" error on github actions. 2024-01-18 16:41:18 +05:30
Aditya Toshniwal d26c167c76 Improve auto-focus of editable data grid when adding/editing rows 2024-01-17 18:38:00 +05:30
Akshay Joshi 60983a25d2 Updated release note. 2024-01-12 17:48:56 +05:30
Yogesh Mahajan 2d08b0dd13 Added configurable parameter to enable support for PasswordExecCommand in server mode. #6792 2024-01-12 17:34:40 +05:30
Pravesh Sharma b28df5874e Fixed an issue where multiple errors were showing if user does not have connect privileges. #7073 2024-01-12 17:20:51 +05:30
Nikhil Mohite ad0567bd85 Add support for selecting a schema in the backup database dialog with no tables, mviews, views or foreign tables. #7053
Fixed a UI border issue on the dependencies tab for columns with icon. #7055
2024-01-12 17:19:27 +05:30
Pravesh Sharma 701085adaf Fixed an issue where group membership information was displayed incorrectly. #7085 2024-01-12 16:48:49 +05:30
Akshay Joshi 5240e8ccf8 Added BYPASSRLS|NOBYPASSRLS option while creating a Role. #6392 2024-01-11 19:14:01 +05:30
372 changed files with 68121 additions and 59150 deletions

No files matched your search

+4 -4
View File
@@ -63,13 +63,13 @@ REM Main build sequence Ends
set "VCREDIST_FILE=vcredist_x64.exe"
REM Set additional variables we need
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\config.py') DO SET APP_MAJOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_REVISION =" %WD%\web\config.py') DO SET APP_MINOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_SUFFIX =" %WD%\web\config.py') DO SET APP_VERSION_SUFFIX=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\version.py') DO SET APP_MAJOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_REVISION =" %WD%\web\version.py') DO SET APP_MINOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_SUFFIX =" %WD%\web\version.py') DO SET APP_VERSION_SUFFIX=%%a
REM remove single quote from the string
SET APP_VERSION_SUFFIX=%APP_VERSION_SUFFIX:'=%
SET APP_NAME=""
FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\config.py') DO SET APP_NAME=%%a
FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\branding.py') DO SET APP_NAME=%%a
FOR /f "tokens=1 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "print('%APP_NAME%'.lower().replace(' ', ''))"') DO SET APP_SHORTNAME=%%G
SET APP_VERSION=%APP_MAJOR%.%APP_MINOR%
SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-%APP_VERSION_SUFFIX%-x64.exe
+3 -3
View File
@@ -9,9 +9,9 @@
SHELL = /bin/sh
APP_NAME := $(shell grep ^APP_NAME web/config.py | awk -F"=" '{print $$NF}' | tr -d '[:space:]' | tr -d "'" | awk '{print tolower($$0)}')
APP_RELEASE := $(shell grep ^APP_RELEASE web/config.py | awk -F"=" '{print $$NF}' | tr -d '[:space:]')
APP_REVISION := $(shell grep ^APP_REVISION web/config.py | awk -F"=" '{print $$NF}' | tr -d '[:space:]')
APP_NAME := $(shell grep ^APP_NAME web/branding.py | awk -F"=" '{print $$NF}' | tr -d '[:space:]' | tr -d "'" | awk '{print tolower($$0)}')
APP_RELEASE := $(shell grep ^APP_RELEASE web/version.py | awk -F"=" '{print $$NF}' | tr -d '[:space:]')
APP_REVISION := $(shell grep ^APP_REVISION web/version.py | awk -F"=" '{print $$NF}' | tr -d '[:space:]')
#########################################################################
# High-level targets
+2
View File
@@ -43,6 +43,8 @@ are disabled if inapplicable.)
for the column. Compression is supported only for variable-width data types,
and is used only when the column's storage mode is main or extended. This
option is available from v14 and above.
* Use the drop-down listbox next to *Storage* to set the storage mode for the
column. This option is available from v16 and above.
Click the *Constraints* tab to continue.
+20 -4
View File
@@ -26,9 +26,9 @@ where *<tag name>* is one of the following:
+==========+===============================================================================+
| latest | The most recent release. |
+----------+-------------------------------------------------------------------------------+
| 7.4 | A specific version (7.4 in this case). |
| 8.4 | A specific version (8.4 in this case). |
+----------+-------------------------------------------------------------------------------+
| 7 | the latest release of a specific major version (major version 7 in this case).|
| 8 | the latest release of a specific major version (major version 8 in this case).|
+----------+-------------------------------------------------------------------------------+
| snapshot | The latest nightly test build. |
+----------+-------------------------------------------------------------------------------+
@@ -42,11 +42,11 @@ maintenance functions to be executed. Multiple versions are included in the
following directories to allow use with different versions of the database
server:
* PostgreSQL 11: */usr/local/pgsql-11*
* PostgreSQL 12: */usr/local/pgsql-12*
* PostgreSQL 13: */usr/local/pgsql-13*
* PostgreSQL 14: */usr/local/pgsql-14*
* PostgreSQL 15: */usr/local/pgsql-15*
* PostgreSQL 16: */usr/local/pgsql-16*
The default binary paths set in the container are as follows:
@@ -132,7 +132,15 @@ than using the default.
Override the default file path for the server definition list. See the
/pgadmin4/servers.json mapped file below for more information. See the format
of the `JSON file <https://www.pgadmin.org/docs/pgadmin4/latest/import_export_servers.html#json-format>`_.
of the `Servers JSON file <https://www.pgadmin.org/docs/pgadmin4/latest/import_export_servers.html#json-format>`_.
**PGADMIN_PREFERENCES_JSON_FILE**
*Default: /pgadmin4/preferences.json*
Override the default file path for the preferences customization at the container creation. See the
/pgadmin4/preferences.json mapped file below for more information. See the format
of the `Preferences JSON file <https://www.pgadmin.org/docs/pgadmin4/latest/preferences.html#json-format>`_.
**GUNICORN_ACCESS_LOGFILE**
@@ -228,6 +236,14 @@ pgAdmin in the container. Note that server definitions are only loaded on first
launch, i.e. when the configuration database is created, and not on subsequent
launches using the same configuration database.
**/pgadmin4/preferences.json**
If this file is mapped, preferences defined in it will be updated at launch
time. This allows customization of preferences settings into the instance of
pgAdmin in the container. Note that preferences are only set on first
launch, i.e. when the configuration database is created, and not on subsequent
launches using the same configuration database.
**/certs/server.cert**
If TLS is enabled, this file will be used as the servers TLS certificate.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 79 KiB

+1 -22
View File
@@ -26,10 +26,6 @@ When using main browser window, the following keyboard shortcuts are available:
+----------------------------+-------------------------------------------------------+
| Shift+Alt+d | Delete object |
+----------------------------+-------------------------------------------------------+
| Shift+Ctrl+[ | Dialog tab backward |
+----------------------------+-------------------------------------------------------+
| Shift+Ctrl+] | Dialog tab forward |
+----------------------------+-------------------------------------------------------+
| Shift+Alt+g | Direct debugging |
+----------------------------+-------------------------------------------------------+
| Shift+Alt+e | Edit object properties |
@@ -59,23 +55,6 @@ When using main browser window, the following keyboard shortcuts are available:
| Shift+Alt+v | View data |
+----------------------------+-------------------------------------------------------+
Dialog Tabs
***********
Use the shortcuts below to navigate the tabsets on dialogs:
.. table::
:class: longtable
:widths: 2 3
+----------------------------+-------------------------------------------------------+
| Shortcut for all platforms | Function |
+============================+=======================================================+
| Control+Shift+[ | Dialog tab backward |
+----------------------------+-------------------------------------------------------+
| Control+Shift+] | Dialog tab forward |
+----------------------------+-------------------------------------------------------+
Property Grid Controls
**********************
@@ -139,7 +118,7 @@ When using the syntax-highlighting SQL editors, the following shortcuts are avai
+--------------------------+----------------------+-------------------------------------+
| Shift + Tab | Shift + Tab | Un-indent selected text |
+--------------------------+----------------------+-------------------------------------+
| Alt + g | Option + g | Jump (to line:column) |
| Ctrl + l | Cmd + l | Go to line, column |
+--------------------------+----------------------+-------------------------------------+
| Ctrl + Space | Ctrl + Space | Auto-complete |
+--------------------------+----------------------+-------------------------------------+
+43 -12
View File
@@ -486,26 +486,27 @@ Query Tool window navigation:
Use the fields on the *SQL formatting* panel to specify your preferences for
reformatting of SQL.
* Use the *Comma-first notation* option to specify whether to place commas
before or after column names.
* Use the *Data type case* option to specify whether to change data types
into upper, lower, or preserve case.
* Use the *Expression width* option to specify maximum number of characters
in parenthesized expressions to be kept on single line.
* Use the *Function case* option to specify whether to change function
names into upper, lower, or preserve case.
* Use the *Identifier case* option to specify whether to change identifiers
(object names) into upper, lower, or capitalized case.
* Use the *Keyword case* option to specify whether to change keywords into
upper, lower, or capitalized case.
* Use the *Re-indent aligned?* option to specify that indentations of statements
should be changed, aligned by keywords.
* Use the *Re-indent?* option to specify that indentations of statements should
be changed.
upper, lower, or preserve case.
* Use *Lines between queries* to specify how many empty lines to leave
between SQL statements. If set to zero it puts no new line.
* Use *Logical operator new line* to specify newline placement before or
after logical operators (AND, OR, XOR).
* Use *New line before semicolon?* to specify whether to place query
separator (;) on a separate line.
* Use the *Spaces around operators?* option to specify whether or not to include
spaces on either side of operators.
* Use the *Strip comments?* option to specify whether or not comments should be
removed.
* Use the *Tab size* option to specify the number of spaces per tab or indent.
* Use the *Use spaces?* option to select whether to use spaces or tabs when
indenting.
* Use the *Wrap after N characters* option to specify the column limit for
wrapping column separated lists (e.g. of column names in a table). If set to
0 (zero), each item will be on it's own line.
The Schema Diff Node
********************
@@ -589,3 +590,33 @@ If auth_source is not given, Internal authentication will be consider by default
# to specify an auth_source
/path/to/python /path/to/setup.py set-prefs user1@gmail.com sqleditor:editor:comma_first=true --auth-source=ldap
Updating Preferences preferences.json
*************************************
To update preferences defined in json file, simply run ``setup.py `` with ``set-prefs`` command followed by username
and JSON file containing the preferences.
.. code-block:: bash
/path/to/python /path/to/setup.py set-prefs user1@gmail.com --input-file /Users/yogeshmahajan/Desktop/pref.json
JSON format
***********
The JSON file simply contains preference_key=value. Preference key value mapping can be obtained by hovering the
individual preference in the Preference UI dialog.
The following is an typical example for preferences.json :
.. code-block:: python
{
"preferences":
{
"browser:display:show_system_objects": true,
"browser:display:show_user_defined_templates": true,
"browser:display:confirm_on_refresh_close": false,
"misc:themes:theme": "dark",
}
}
+1 -1
View File
@@ -87,7 +87,7 @@ Query Editing Options
| | Select *Replace* to locate and replace (with prompting) individual occurrences of the target. | Option+Cmd+F (MAC) |
| | | Ctrl+Shift+F (Others) |
| +---------------------------------------------------------------------------------------------------+-----------------------+
| | Select *Jump* to navigate to the next occurrence of the search target. | Alt+G |
| | Select *Go to Line/Column* to go to specified line number and column position | Cmd+L or Ctrl+L |
| +---------------------------------------------------------------------------------------------------+-----------------------+
| | Select *Indent Selection* to indent the currently selected text. | Tab |
| +---------------------------------------------------------------------------------------------------+-----------------------+
+3
View File
@@ -11,6 +11,9 @@ notes for it.
.. toctree::
:maxdepth: 1
release_notes_8_4
release_notes_8_3
release_notes_8_2
release_notes_8_1
release_notes_8_0
+46
View File
@@ -0,0 +1,46 @@
***********
Version 8.3
***********
Release date: 2024-02-09
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v8.2.
Supported Database Servers
**************************
**PostgreSQL**: 12, 13, 14, 15, and 16
**EDB Advanced Server**: 12, 13, 14, 15, and 16
Bundled PostgreSQL Utilities
****************************
**psql**, **pg_dump**, **pg_dumpall**, **pg_restore**: 16.0
New features
************
| `Issue #4419 <https://github.com/pgadmin-org/pgadmin4/issues/4419>`_ - Allow drag-n-drop columns collection tree node as comma separated columns.
| `Issue #6380 <https://github.com/pgadmin-org/pgadmin4/issues/6380>`_ - Added support to rename columns in Views.
| `Issue #6392 <https://github.com/pgadmin-org/pgadmin4/issues/6392>`_ - Added BYPASSRLS|NOBYPASSRLS option while creating a Role.
| `Issue #6450 <https://github.com/pgadmin-org/pgadmin4/issues/6450>`_ - Added support for column storage syntax while creating table.
| `Issue #6557 <https://github.com/pgadmin-org/pgadmin4/issues/6557>`_ - Use COOKIE_DEFAULT_PATH or SCRIPT_NAME in session cookie path.
| `Issue #6792 <https://github.com/pgadmin-org/pgadmin4/issues/6792>`_ - Added configurable parameter to enable support for PasswordExecCommand in server mode.
Housekeeping
************
Bug fixes
*********
| `Issue #5083 <https://github.com/pgadmin-org/pgadmin4/issues/5083>`_ - Fixed an issue where format sql was messing up operator. Included many other feature changes, more details `here <https://github.com/pgadmin-org/pgadmin4/commit/f7045b58d4d1b98b6a2f035267d2dd01c7235aa6>`_
| `Issue #6785 <https://github.com/pgadmin-org/pgadmin4/issues/6785>`_ - Fixed an issue where formatting inserts empty lines in specific case.
| `Issue #7053 <https://github.com/pgadmin-org/pgadmin4/issues/7053>`_ - Add support for selecting a schema in the backup database dialog with no tables, mviews, views or foreign tables.
| `Issue #7055 <https://github.com/pgadmin-org/pgadmin4/issues/7055>`_ - Fixed a UI border issue on the dependencies tab for columns with icon.
| `Issue #7073 <https://github.com/pgadmin-org/pgadmin4/issues/7073>`_ - Fixed an issue where multiple errors were showing if user does not have connect privileges.
| `Issue #7085 <https://github.com/pgadmin-org/pgadmin4/issues/7085>`_ - Fixed an issue where group membership information was displayed incorrectly.
| `Issue #7113 <https://github.com/pgadmin-org/pgadmin4/issues/7113>`_ - Ensure that the correct SQL is generated when changing the column data type to "char".
| `Issue #7153 <https://github.com/pgadmin-org/pgadmin4/issues/7153>`_ - Fixed an issue pgAdmin fails to launch due to inconsistent PATH variable name on windows.
| `Issue #7166 <https://github.com/pgadmin-org/pgadmin4/issues/7166>`_ - Fix a backend server error when creating a named restore point.
| `Issue #7175 <https://github.com/pgadmin-org/pgadmin4/issues/7175>`_ - Fix wrong default for FORCE_LOWER in the FLASK_GRAVATAR module.
+46
View File
@@ -0,0 +1,46 @@
***********
Version 8.4
***********
Release date: 2024-03-07
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v8.3.
Supported Database Servers
**************************
**PostgreSQL**: 12, 13, 14, 15, and 16
**EDB Advanced Server**: 12, 13, 14, 15, and 16
Bundled PostgreSQL Utilities
****************************
**psql**, **pg_dump**, **pg_dumpall**, **pg_restore**: 16.1
New features
************
| `Issue #6058 <https://github.com/pgadmin-org/pgadmin4/issues/6058>`_ - Allow preferences customization using a configuration file.
| `Issue #7138 <https://github.com/pgadmin-org/pgadmin4/issues/7138>`_ - Add support for JSON log format.
| `Issue #7204 <https://github.com/pgadmin-org/pgadmin4/issues/7204>`_ - Add --yes option for skipping the confirmation prompt while deleting the user via CLI for scripting purpose.
Housekeeping
************
| `Issue #7097 <https://github.com/pgadmin-org/pgadmin4/issues/7097>`_ - Upgrade CodeMirror from version 5 to 6.
| `Issue #7148 <https://github.com/pgadmin-org/pgadmin4/issues/7148>`_ - Added documentation for Dashboard's System Statistics tab.
| `Issue #7187 <https://github.com/pgadmin-org/pgadmin4/issues/7187>`_ - Separate the application name, branding & version information from the configuration file.
| `Issue #7234 <https://github.com/pgadmin-org/pgadmin4/issues/7234>`_ - Upgrade python packages cryptography to 42.0.x and Flask-Security-Too to 5.3.x.
Bug fixes
*********
| `Issue #6792 <https://github.com/pgadmin-org/pgadmin4/issues/6792>`_ - Fix multiple issues where PasswordExecCommand was not working in server mode and PasswordExecCommand was not loaded when importing servers.
| `Issue #6808 <https://github.com/pgadmin-org/pgadmin4/issues/6808>`_ - Fix the tabbed panel backward/forward shortcut for tabs.
| `Issue #7027 <https://github.com/pgadmin-org/pgadmin4/issues/7027>`_ - Fixed an issue where dependencies and dependents were not showing if a composite type is used as an attribute in another composite type.
| `Issue #7164 <https://github.com/pgadmin-org/pgadmin4/issues/7164>`_ - Fix an issue where constraint check control is enabled in the edit table dialog.
| `Issue #7165 <https://github.com/pgadmin-org/pgadmin4/issues/7165>`_ - Fix an issue where the scripts created by generate script of Schema diff for Table with sequence was not working earlier.
| `Issue #7193 <https://github.com/pgadmin-org/pgadmin4/issues/7193>`_ - Ensure that the OAuth2 session is logged out when users log out from pgAdmin.
| `Issue #7217 <https://github.com/pgadmin-org/pgadmin4/issues/7217>`_ - Remove role related checks on the UI dashboard when terminating session/query and let PostgreSQL take care of it.
| `Issue #7225 <https://github.com/pgadmin-org/pgadmin4/issues/7225>`_ - Fix an issue where type column in dependents/dependencies tab is not showing correct label.
| `Issue #7258 <https://github.com/pgadmin-org/pgadmin4/issues/7258>`_ - Unsafe Deserialization and Remote Code Execution by an Authenticated user in pgAdmin 4 (CVE-2024-2044).
+2 -4
View File
@@ -57,15 +57,13 @@ Use the *Privileges* tab to grant privileges to the role.
drop roles. The default value is *No*.
* Move the *Create databases* switch to the *Yes* position to control whether a
role can create databases. The default value is *No*.
* The *Update catalog?* switch is disabled until the role is given superuser
privileges. Move the *Update catalogs?* switch to the *No* position to control
whether a role can update catalogs. The default value is *Yes* when the
*Superuser* switch is in the *Yes* position.
* Move the *Inherit rights from the parent roles?* switch to the *No* position
if a role does not inherit privileges. The default value is *Yes*.
* Move the *Can initiate streaming replication and backups?* switch to the *Yes*
position to control whether a role can initiate streaming replication or put
the system in and out of backup mode. The default value is *No*.
* Move the *Bypass RLS?* switch to the *Yes* position to control whether a
role can bypasses every row-level security (RLS) policy. The default value is *No*.
.. image:: images/role_membership.png
:alt: Role dialog membership tab
+2 -2
View File
@@ -103,7 +103,7 @@ In order to configure the Python code, follow these steps:
.. code-block:: bash
# python setup.py
# python setup.py setup-db
5. Change the ownership of the configuration database to the user that the web server
processes will run as, for example, assuming that the web server runs as user
@@ -312,4 +312,4 @@ Additional Information
relies on the *sys.executable* variable in Python to do this. In some cases,
you may need to override that value to ensure the correct interpreter is
used, instead of the WSGI host process. For example, uWSGI offers the
*--py-sys-executable* command line option to achieve this.
*--py-sys-executable* command line option to achieve this.
+54 -3
View File
@@ -9,12 +9,14 @@ display information about the object currently selected in the *pgAdmin* tree
control in the left window. Select a tab to access information about the
highlighted object in the tree control.
.. image:: images/main_dashboard.png
.. image:: images/main_dashboard_general.png
:alt: Dashboard panel
:align: center
The graphs on the *Dashboard* tab provides an active analysis of the usage
statistics for the selected server or database:
The graphs and tables on the *Dashboard* tab provides an active analysis of system statistics and the usage
statistics for the selected server or database.
Click the *General* tab to get the usage statistics for the selected server or database:
* The *Server sessions* or *Database sessions* graph displays the interactions
with the server or database.
@@ -33,6 +35,7 @@ transactions, and server configuration (if applicable). The information is
presented in context-sensitive tables. Use controls located above the table to:
* Click the *Refresh* button to update the information displayed in each table.
* Select *Active sessions only* checkbox to get the information about active sessions only from the list of all the sessions.
* Enter a value in the *Search* box to restrict the table content to one or more
sessions that satisfy the search criteria. For example, you can enter a
process ID to locate a specific session, or a session state (such as *idle*)
@@ -53,6 +56,54 @@ session:
* Use the *Details* icon (located in the third column) to open the *Details*
tab; the tab displays information about the selected session.
Click the *System Statistics* tab to get the statistics for the system:
.. image:: images/main_dashboard_sys_statistics_summary.png
:alt: Summary panel
:align: center
Click the *Summary* tab to get the summary of the system:
* The *OS Information* table displays the basic information about the operating system.
* The *CPU Information* table displays the information about system CPU.
* The *Process & Handle Count* graph displays the total count of processes running and handles opened for the system.
.. image:: images/main_dashboard_sys_statistics_cpu.png
:alt: CPU panel
:align: center
Click the *CPU* tab to get the detailed usage statistics of the system CPU:
* The *CPU Usage* graph displays the percentage of time spent by CPU for user normal process, user niced process, kernel mode process, idle mode.
* The *Load average* graph displays the average load of the system over 1, 5, 10, and 15 minute intervals.
* The *Process CPU Usage* table displays information about CPU for each process ID. Enter a value like process ID or name in the Search box to restrict the table content to one or more processes that satisfy the search criteria.
.. image:: images/main_dashboard_sys_statistics_memory.png
:alt: Memory panel
:align: center
Click the *Memory* tab to get the detailed usage statistics of the system memory:
* The *Memory Usage* graph displays the size of total, free and used memory per seconds in Gigabytes.
* The *Swap Memory* graph displays the size of total, free and used swap memory per seconds in Gigabytes.
* The *Process Memory Usage* table displays information about memory for each process ID. Enter a value like process ID or name in the Search box to restrict the table content to one or more processes that satisfy the search criteria.
.. image:: images/main_dashboard_sys_statistics_storage.png
:alt: Storage panel
:align: center
Click the *Storage* tab to get the detailed information of the system storage:
* The *Disk Information* table displays the information about the disk, such as file system type, mount point, total space, used space and free space and count of total, free, used inodes. The pie graph shows the total spaces in Gigabytes and stacked bar graph shows the used and available space in Gigabytes, for different mount points for file system.
* The *Swap Memory* graph displays the size of total, free and used swap memory per seconds in Gigabytes.
The *disk0* panel displays statistics about the only I/O block device of system:
* The *I/O Operations Count* graph displays the count of read and write operations per second.
* The *Data Transfer* graph displays the size of read and writes happened in Gigabytes per second.
* The *Time spent in I/O operations* graph displays the time spent by the device for reading and writing in minutes per second.
.. image:: images/main_properties_table.png
:alt: Properties panel
:align: center
+2 -1
View File
@@ -187,11 +187,12 @@ Delete User
***********
To delete the user, invoke ``setup.py`` with ``delete-user`` command line option, followed by
username and auth_source. For Internal users, email adress will be used instead of username.
username and auth_source. For Internal users, email adress will be used instead of username. the option ``--yes`` is available to skip the confirmation prompt before deleting the user.
.. code-block:: bash
/path/to/python /path/to/setup.py delete-user user1@gmail.com --auth-source internal
/path/to/python /path/to/setup.py delete-user user2@gmail.com --auth-source internal --yes
/path/to/python /path/to/setup.py delete-user ldapuser --auth-source ldap
+12
View File
@@ -64,6 +64,7 @@ if [ ! -f /var/lib/pgadmin/pgadmin4.db ]; then
/venv/bin/python3 run_pgadmin.py
export PGADMIN_SERVER_JSON_FILE="${PGADMIN_SERVER_JSON_FILE:-/pgadmin4/servers.json}"
export PGADMIN_PREFERENCES_JSON_FILE="${PGADMIN_PREFERENCES_JSON_FILE:-/pgadmin4/preferences.json}"
# Pre-load any required servers
if [ -f "${PGADMIN_SERVER_JSON_FILE}" ]; then
@@ -75,6 +76,17 @@ if [ ! -f /var/lib/pgadmin/pgadmin4.db ]; then
/venv/bin/python3 /pgadmin4/setup.py load-servers "${PGADMIN_SERVER_JSON_FILE}" --user "${PGADMIN_DEFAULT_EMAIL}"
fi
fi
if [ -f "${PGADMIN_PREFERENCES_JSON_FILE}" ]; then
# When running in Desktop mode, no user is created
# so we have to import servers anonymously
if [ "${PGADMIN_CONFIG_SERVER_MODE}" = "False" ]; then
DESKTOP_USER=$(cd /pgadmin4 && /venv/bin/python3 -c 'import config; print(config.DESKTOP_USER)')
/venv/bin/python3 /pgadmin4/setup.py set-prefs "${DESKTOP_USER}" --input-file "${PGADMIN_PREFERENCES_JSON_FILE}"
else
/venv/bin/python3 /pgadmin4/setup.py set-prefs "${PGADMIN_DEFAULT_EMAIL}" --input-file "${PGADMIN_PREFERENCES_JSON_FILE}"
fi
fi
fi
# Start Postfix to handle password resets etc.
+4 -4
View File
@@ -10,11 +10,11 @@ _setup_env() {
SERVERROOT=${BUILDROOT}/server
WEBROOT=${BUILDROOT}/web
DISTROOT=$(realpath "${WD}/../../dist")
APP_RELEASE=$(grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //' | sed 's/ //g' | tr '[:upper:]' '[:lower:]')
APP_RELEASE=$(grep "^APP_RELEASE" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" web/branding.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //' | sed 's/ //g' | tr '[:upper:]' '[:lower:]')
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
APP_SUFFIX=$(grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
APP_SUFFIX=$(grep "^APP_SUFFIX" web/version.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
if [ -n "${APP_SUFFIX}" ]; then
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
fi
+7 -4
View File
@@ -2,11 +2,11 @@
_setup_env() {
FUNCS_DIR=$(cd "$(dirname "$0")" && pwd)/../..
APP_RELEASE=$(grep "^APP_RELEASE" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
APP_RELEASE=$(grep "^APP_RELEASE" "${FUNCS_DIR}/web/version.py" | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" "${FUNCS_DIR}/web/version.py" | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" "${FUNCS_DIR}/web/branding.py" | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
APP_SUFFIX=$(grep "^APP_SUFFIX" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
APP_SUFFIX=$(grep "^APP_SUFFIX" "${FUNCS_DIR}/web/version.py" | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
if [ -n "${APP_SUFFIX}" ]; then
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
fi
@@ -288,6 +288,9 @@ _complete_bundle() {
# Build node modules
pushd "${SOURCE_DIR}/web" > /dev/null || exit
corepack enable
yarn set version berry
yarn set version 3
yarn install
yarn run bundle
+4 -4
View File
@@ -21,11 +21,11 @@ if [ ! -d .git ] && [ ! -f .git/config ]; then
fi
# Get the required package info
APP_RELEASE=$(grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
APP_RELEASE=$(grep "^APP_RELEASE" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" web/branding.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
APP_SUFFIX=$(grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
APP_SUFFIX=$(grep "^APP_SUFFIX" web/version.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
if [ -n "${APP_SUFFIX}" ]; then
export APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
fi
+4 -4
View File
@@ -21,11 +21,11 @@ if [ ! -d .git ] && [ ! -f .git/config ]; then
fi
# Get the required package info
APP_RELEASE=$(grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
APP_RELEASE=$(grep "^APP_RELEASE" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" web/branding.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
APP_SUFFIX=$(grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
APP_SUFFIX=$(grep "^APP_SUFFIX" web/version.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
if [ -n "${APP_SUFFIX}" ]; then
export APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
fi
+3 -2
View File
@@ -23,7 +23,7 @@ Flask-Compress==1.*
Flask-Paranoid==0.*
Flask-Babel==4.0.*; python_version > '3.7'
Flask-Babel==3.1.*; python_version <= '3.7'
Flask-Security-Too==5.2.*; python_version > '3.7'
Flask-Security-Too==5.3.*; python_version > '3.7'
Flask-Security-Too==5.1.*; python_version <= '3.7'
Flask-SocketIO==5.3.*
WTForms==3.1.*; python_version > '3.7'
@@ -37,7 +37,7 @@ psycopg[c]==3.1.12
python-dateutil==2.*
SQLAlchemy==2.*
bcrypt==4.0.*
cryptography==41.0.*
cryptography==42.0.*
sshtunnel==0.*
ldap3==2.*
gssapi==1.8.*
@@ -62,3 +62,4 @@ Werkzeug==2.3.*; python_version > '3.7'
Werkzeug==2.2.3; python_version <= '3.7'
typer[all]==0.9.*
setuptools==69.*; python_version >= '3.12'
jsonformatter~=0.3.2
+11 -17
View File
@@ -72,12 +72,10 @@ const getAppDataPath = () => {
default:
if (platform().startsWith('win')) {
appDataPath = path.join(process.env.APPDATA, 'pgadmin');
} else if ('XDG_CONFIG_HOME' in process.env) {
appDataPath = path.join(process.env.XDG_CONFIG_HOME, 'pgadmin');
} else {
if ('XDG_CONFIG_HOME' in process.env) {
appDataPath = path.join(process.env.XDG_CONFIG_HOME, 'pgadmin');
} else {
appDataPath = path.join(homedir(), '.config', 'pgadmin');
}
appDataPath = path.join(homedir(), '.config', 'pgadmin');
}
}
@@ -108,12 +106,10 @@ const getLocalAppDataPath = () => {
default:
if (platform().startsWith('win')) {
localAppDataPath = path.join(process.env.LOCALAPPDATA, 'pgadmin');
} else if ('XDG_DATA_HOME' in process.env) {
localAppDataPath = path.join(process.env.XDG_DATA_HOME, 'pgadmin');
} else {
if ('XDG_DATA_HOME' in process.env) {
localAppDataPath = path.join(process.env.XDG_DATA_HOME, 'pgadmin');
} else {
localAppDataPath = path.join(homedir(), '.local', 'share', 'pgadmin');
}
localAppDataPath = path.join(homedir(), '.local', 'share', 'pgadmin');
}
}
@@ -412,14 +408,12 @@ let ConfigureStore = {
...this.jsonData,
...key,
};
} else {
if(value === '' || value == null || typeof(value) == 'undefined') {
if(this.jsonData[key] !== undefined) {
delete this.jsonData[key];
}
} else {
this.jsonData[key] = value;
} else if(value === '' || value == null || typeof(value) == 'undefined') {
if(this.jsonData[key] !== undefined) {
delete this.jsonData[key];
}
} else {
this.jsonData[key] = value;
}
},
};
+3 -5
View File
@@ -80,7 +80,7 @@ function startDesktopMode() {
process.env[key] = updated_path;
}
if (platform() === 'win32' && (key === 'PATH' || key == 'Path')) {
if (platform() === 'win32' && key.toUpperCase() === 'PATH') {
let _libpq_path = path.join(path.dirname(path.dirname(path.resolve(pgadminFile))), 'runtime');
process.env[key] = _libpq_path + ';' + process.env[key];
}
@@ -633,10 +633,8 @@ function updateCheckedMenuItem(menuItem) {
sm.checked = menuItem.checked
}
})
} else {
if (sub.label == menuItem.label && type == 'checkbox') {
sub.checked = menuItem.checked
}
} else if (sub.label == menuItem.label && type == 'checkbox') {
sub.checked = menuItem.checked
}
});
});
+2
View File
@@ -1,3 +1,5 @@
requests>=2.21.0
requests[security]>=2.21.0
safety>=1.9.0
Sphinx==7.2.6
sphinxcontrib-youtube==1.4.1
+28
View File
@@ -0,0 +1,28 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2024, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
##########################################################################
# Application branding
##########################################################################
# Name of the application to display in the UI
APP_NAME = 'pgAdmin 4'
APP_ICON = 'pg-icon'
# To help define the configuration directory and data directory
APP_SHORT_NAME = 'pgadmin4'
APP_PATH = 'pgadmin'
APP_WIN_PATH = "pgAdmin"
# Copyright string for display in the app
APP_COPYRIGHT = 'Copyright (C) 2013 - 2024, The pgAdmin Development Team'
# User ID (email address) to use for the default user in desktop mode.
# The default should be fine here, as it's not exposed in the app.
APP_DEFAULT_EMAIL = 'pgadmin4@pgadmin.org'
+46 -50
View File
@@ -15,6 +15,7 @@ import builtins
import logging
import os
import sys
from collections import OrderedDict
# We need to include the root directory in sys.path to ensure that we can
# find everything we need when running in the standalone runtime.
@@ -30,46 +31,10 @@ CONFIG_DATABASE_CONNECTION_POOL_SIZE = 5
CONFIG_DATABASE_CONNECTION_MAX_OVERFLOW = 100
from pgadmin.utils import env, IS_WIN, fs_short_path
##########################################################################
# Application settings
##########################################################################
# Name of the application to display in the UI
APP_NAME = 'pgAdmin 4'
APP_ICON = 'pg-icon'
##########################################################################
# Application settings
##########################################################################
# NOTE!!!
# If you change any of APP_RELEASE, APP_REVISION or APP_SUFFIX, then you
# must also change APP_VERSION_INT to match.
#
# Application version number components
APP_RELEASE = 8
APP_REVISION = 2
# Application version suffix, e.g. 'beta1', 'dev'. Usually an empty string
# for GA releases.
APP_SUFFIX = ''
# Numeric application version for upgrade checks. Should be in the format:
# [X]XYYZZ, where X is the release version, Y is the revision, with a leading
# zero if needed, and Z represents the suffix, with a leading zero if needed
APP_VERSION_INT = 80200
# DO NOT CHANGE!
# The application version string, constructed from the components
if not APP_SUFFIX:
APP_VERSION = '%s.%s' % (APP_RELEASE, APP_REVISION)
else:
APP_VERSION = '%s.%s-%s' % (APP_RELEASE, APP_REVISION, APP_SUFFIX)
# Copyright string for display in the app
APP_COPYRIGHT = 'Copyright (C) 2013 - 2024, The pgAdmin Development Team'
from version import APP_VERSION, APP_RELEASE, APP_REVISION, APP_SUFFIX, \
APP_VERSION_INT
from branding import APP_NAME, APP_ICON, APP_COPYRIGHT, APP_PATH, \
APP_WIN_PATH, APP_SHORT_NAME, APP_DEFAULT_EMAIL
##########################################################################
# Misc stuff
@@ -133,7 +98,7 @@ WTF_CSRF_HEADERS = ['X-pgA-CSRFToken']
# User ID (email address) to use for the default user in desktop mode.
# The default should be fine here, as it's not exposed in the app.
DESKTOP_USER = 'pgadmin4@pgadmin.org'
DESKTOP_USER = APP_DEFAULT_EMAIL
# This option allows the user to host the application on a LAN
# Default hosting is on localhost (DEFAULT_SERVER='localhost').
@@ -250,18 +215,21 @@ APP_VERSION_EXTN = ('.css', '.js', '.html', '.svg', '.png', '.gif', '.ico')
# Data directory for storage of config settings etc. This shouldn't normally
# need to be changed - it's here as various other settings depend on it.
# On Windows, we always store data in %APPDATA%\pgAdmin. On other platforms,
# if we're in server mode we use /var/lib/pgadmin, otherwise ~/.pgadmin
# On Windows, we always store data in %APPDATA%\$(APP_WIN_PATH). On other
# platforms, if we're in server mode we use /var/lib/$(APP_PATH),
# otherwise ~/.$(APP_PATH)
if IS_WIN:
# Use the short path on windows
DATA_DIR = os.path.realpath(
os.path.join(fs_short_path(env('APPDATA')), "pgAdmin")
os.path.join(fs_short_path(env('APPDATA')), APP_WIN_PATH)
)
else:
if SERVER_MODE:
DATA_DIR = '/var/lib/pgadmin'
DATA_DIR = os.path.join('/var/lib/', APP_PATH)
else:
DATA_DIR = os.path.realpath(os.path.expanduser('~/.pgadmin/'))
DATA_DIR = os.path.realpath(
os.path.expanduser('~/' + '.' + APP_PATH + '/')
)
# An optional login banner to show security warnings/disclaimers etc. at
# login and password recovery etc. HTML may be included for basic formatting,
@@ -289,15 +257,29 @@ CONSOLE_LOG_LEVEL = logging.WARNING
FILE_LOG_LEVEL = logging.WARNING
# Log format.
JSON_LOGGER = False
CONSOLE_LOG_FORMAT_JSON = OrderedDict([
("time", "asctime"),
("message", "message"),
("level", "levelname")
])
FILE_LOG_FORMAT_JSON = OrderedDict([
("time", "asctime"),
("message", "message"),
("level", "levelname")
])
CONSOLE_LOG_FORMAT = '%(asctime)s: %(levelname)s\t%(name)s:\t%(message)s'
FILE_LOG_FORMAT = '%(asctime)s: %(levelname)s\t%(name)s:\t%(message)s'
# Log file name. This goes in the data directory, except on non-Windows
# platforms in server mode.
if SERVER_MODE and not IS_WIN:
LOG_FILE = '/var/log/pgadmin/pgadmin4.log'
LOG_FILE = os.path.join('/var/log', APP_PATH, APP_SHORT_NAME + '.log')
else:
LOG_FILE = os.path.join(DATA_DIR, 'pgadmin4.log')
LOG_FILE = os.path.join(DATA_DIR, APP_SHORT_NAME + '.log')
# Log rotation setting
# Log file will be rotated considering values for LOG_ROTATION_SIZE
@@ -341,7 +323,8 @@ CONFIG_DATABASE_URI = ''
# The default path to the SQLite database used to store user accounts and
# settings. This default places the file in the same directory as this
# config file, but generates an absolute path for use througout the app.
SQLITE_PATH = env('SQLITE_PATH') or os.path.join(DATA_DIR, 'pgadmin4.db')
SQLITE_PATH = env('SQLITE_PATH') or \
os.path.join(DATA_DIR, APP_SHORT_NAME + '.db')
# SQLITE_TIMEOUT will define how long to wait before throwing the error -
# OperationError due to database lock. On slower system, you may need to change
@@ -819,7 +802,12 @@ OAUTH2_CONFIG = [
# for OAuth2 provider.
# This may need to set False, in case of self-signed certificates.
# Ref: https://github.com/psf/requests/issues/6071
'OAUTH2_SSL_CERT_VERIFICATION': True
'OAUTH2_SSL_CERT_VERIFICATION': True,
# set this variable to invalidate the session of the oauth2 provider
# Example for keycloak:
# 'OAUTH2_LOGOUT_URL':
# 'https://example.com/realms/master/protocol/openid-connect/logout?post_logout_redirect_uri={redirect_uri}&id_token_hint={id_token}'
'OAUTH2_LOGOUT_URL': None
}
]
@@ -909,6 +897,14 @@ AUTO_DISCOVER_SERVERS = True
#############################################################################
SERVER_HEARTBEAT_TIMEOUT = 30 # In seconds
#############################################################################
# ENABLE_SERVER_PASS_EXEC_CMD is used to enable/disable Password exec command
# field in server properties. This is used to specify a shell command to be
# executed to retrieve a password to be used for server authentication.
# This setting is applicable only for server mode.
#############################################################################
ENABLE_SERVER_PASS_EXEC_CMD = False
#############################################################################
# Patch the default config with custom config and other manipulations
#############################################################################
+5 -2
View File
@@ -76,6 +76,7 @@
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/preset-react": "^7.12.13",
"@codemirror/lang-sql": "^6.5.5",
"@date-io/core": "^1.3.6",
"@date-io/date-fns": "1.x",
"@emotion/sheet": "^1.0.1",
@@ -102,12 +103,13 @@
"chartjs-plugin-zoom": "^2.0.1",
"classnames": "^2.2.6",
"closest": "^0.0.1",
"codemirror": "^5.59.2",
"codemirror": "^6.0.1",
"convert-units": "^2.3.4",
"cssnano": "^5.0.2",
"dagre": "^0.8.4",
"date-fns": "^2.24.0",
"diff-arrays-of-objects": "^1.1.8",
"hotkeys-js": "^3.13.3",
"html-to-image": "^1.11.11",
"immutability-helper": "^3.0.0",
"insert-if": "^1.1.0",
@@ -119,7 +121,6 @@
"ml-matrix": "^6.5.0",
"moment": "^2.29.4",
"moment-timezone": "^0.5.34",
"mousetrap": "^1.6.3",
"notificar": "^1.0.1",
"notistack": "^1.0.10",
"path-fx": "^2.0.0",
@@ -152,6 +153,7 @@
"snapsvg-cjs": "^0.0.6",
"socket.io-client": "^4.5.0",
"split.js": "^1.5.10",
"sql-formatter": "^15.1.2",
"styled-components": "^5.2.1",
"uplot": "^1.6.24",
"uplot-react": "^1.1.4",
@@ -173,6 +175,7 @@
"bundle": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=2048 yarn run bundle:dev",
"test:js-once": "yarn run linter && yarn run jest --maxWorkers=50%",
"test:js": "yarn run test:js-once --watch",
"test:js-file": "yarn run test:js-once -t",
"test:js-coverage": "yarn run test:js-once --collect-coverage",
"test:feature": "yarn run bundle && python regression/runtests.py --pkg feature_tests",
"test": "yarn run test:js-once && yarn run bundle && python regression/runtests.py",
-1
View File
@@ -39,7 +39,6 @@ if (3, 10) > sys.version_info > (3, 8, 99) and os.name == 'posix':
# Fix eventlet issue with Python 3.9.
# Ref: https://github.com/eventlet/eventlet/issues/670
# This was causing issue in psycopg3
import select
from eventlet import hubs
hubs.use_hub("poll")
+1 -1
View File
@@ -26,7 +26,7 @@ def load_providers():
if os.path.isfile(filename):
basename = os.path.basename(filename)
base, extension = os.path.splitext(basename)
_, extension = os.path.splitext(basename)
if extension == ".py" and not basename.startswith("_"):
module = __import__("providers." + basename[:-3],
+1 -1
View File
@@ -197,7 +197,7 @@ class AzureProvider(AbsProvider):
""" Create/cache/return an Azure client object """
# Acquire a credential object using CLI-based authentication.
if self._credentials is None:
status, self._credentials = \
_, self._credentials = \
self._get_azure_credentials()
if type in self._clients:
+16 -9
View File
@@ -50,7 +50,7 @@ from pgadmin.utils.csrf import pgCSRFProtect
from pgadmin import authenticate
from pgadmin.utils.security_headers import SecurityHeaders
from pgadmin.utils.constants import KERBEROS, OAUTH2, INTERNAL, LDAP, WEBSERVER
from jsonformatter import JsonFormatter
# Explicitly set the mime-types so that a corrupted windows registry will not
# affect pgAdmin 4 to be load properly. This will avoid the issues that may
@@ -260,14 +260,26 @@ def create_app(app_name=None):
config.LOG_ROTATION_MAX_LOG_FILES)
fh.setLevel(config.FILE_LOG_LEVEL)
fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT))
if config.JSON_LOGGER:
json_formatter = JsonFormatter(config.FILE_LOG_FORMAT_JSON)
fh.setFormatter(json_formatter)
else:
fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT))
app.logger.addHandler(fh)
logger.addHandler(fh)
# Console logging
ch = logging.StreamHandler()
ch.setLevel(config.CONSOLE_LOG_LEVEL)
ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT))
if config.JSON_LOGGER:
json_formatter = JsonFormatter(config.CONSOLE_LOG_FORMAT_JSON)
ch.setFormatter(json_formatter)
else:
ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT))
app.logger.addHandler(ch)
logger.addHandler(ch)
@@ -496,11 +508,6 @@ def create_app(app_name=None):
'SECURITY_EMAIL_VALIDATOR_ARGS': config.SECURITY_EMAIL_VALIDATOR_ARGS
}))
if 'SCRIPT_NAME' in os.environ and os.environ["SCRIPT_NAME"]:
app.config.update(dict({
'APPLICATION_ROOT': os.environ["SCRIPT_NAME"]
}))
app.config.update(dict({
'INTERNAL': INTERNAL,
'LDAP': LDAP,
@@ -833,7 +840,7 @@ def create_app(app_name=None):
config.COOKIE_DEFAULT_DOMAIN != 'localhost':
domain['domain'] = config.COOKIE_DEFAULT_DOMAIN
response.set_cookie('PGADMIN_INT_KEY', value=request.args['key'],
path=config.COOKIE_DEFAULT_PATH,
path=config.SESSION_COOKIE_PATH,
secure=config.SESSION_COOKIE_SECURE,
httponly=config.SESSION_COOKIE_HTTPONLY,
samesite=config.SESSION_COOKIE_SAMESITE,
@@ -11,7 +11,6 @@ import gettext from 'sources/gettext';
import url_for from 'sources/url_for';
import React, { useEffect, useState, useRef } from 'react';
import { Box, Grid, InputLabel } from '@material-ui/core';
import PropTypes from 'prop-types';
import { DefaultButton } from '../../../static/js/components/Buttons';
import { makeStyles } from '@material-ui/styles';
import { InputText } from '../../../static/js/components/FormComponents';
@@ -149,8 +148,4 @@ export default function AboutComponent() {
}
</Box>
);
}
AboutComponent.propTypes = {
closeModal: PropTypes.func
};
}
+1 -1
View File
@@ -227,7 +227,7 @@ class EmailAuthentication(BaseMFAuth):
def _registration_view_after_code_sent(self, _form_data):
session['mfa_email_id'] = _form_data.get('send_to', None)
success, http_code, message = _send_code_to_email(
success, _, message = _send_code_to_email(
session['mfa_email_id']
)
+15
View File
@@ -69,11 +69,21 @@ def init_app(app):
methods=['GET', 'POST'])
@pgCSRFProtect.exempt
def oauth_logout():
id_token = session['oauth2_token']['id_token']
logout_url = None
if 'oauth2_logout_url' in session:
logout_url = session['oauth2_logout_url']
if not current_user.is_authenticated:
return redirect(get_safe_post_logout_redirect())
for key in list(session.keys()):
session.pop(key)
logout_user()
if logout_url:
return redirect(logout_url.format(
redirect_uri=request.url_root,
id_token=id_token))
return redirect(get_safe_post_logout_redirect())
app.register_blueprint(blueprint)
@@ -202,6 +212,11 @@ class OAuth2Authentication(BaseAuthentication):
session['pass_enc_key'] = session['oauth2_token']['access_token']
if 'OAUTH2_LOGOUT_URL' in self.oauth2_config[
self.oauth2_current_client]:
session['oauth2_logout_url'] = self.oauth2_config[
self.oauth2_current_client]['OAUTH2_LOGOUT_URL']
resp = self.oauth2_clients[self.oauth2_current_client].get(
self.oauth2_config[
self.oauth2_current_client]['OAUTH2_USERINFO_ENDPOINT'],
+3 -1
View File
@@ -374,6 +374,7 @@ def index():
rating='g',
default='retro',
force_default=False,
force_lower=True,
use_ssl=True,
base_url=None
)
@@ -422,7 +423,7 @@ def index():
domain['domain'] = config.COOKIE_DEFAULT_DOMAIN
response.set_cookie("PGADMIN_LANGUAGE", value=language,
path=config.COOKIE_DEFAULT_PATH,
path=config.SESSION_COOKIE_PATH,
secure=config.SESSION_COOKIE_SECURE,
httponly=config.SESSION_COOKIE_HTTPONLY,
samesite=config.SESSION_COOKIE_SAMESITE,
@@ -568,6 +569,7 @@ def utils():
shared_storage_list=shared_storage_list,
restricted_shared_storage_list=[] if current_user.has_role(
"Administrator") else restricted_shared_storage_list,
enable_server_passexec_cmd=config.ENABLE_SERVER_PASS_EXEC_CMD,
),
200, {'Content-Type': MIMETYPE_APP_JS})
@@ -352,36 +352,6 @@ def register_browser_preferences(self):
fields=fields
)
self.preference.register(
'keyboard_shortcuts',
'dialog_tab_forward',
gettext('Dialog tab forward'),
'keyboardshortcut',
{
'alt': False,
'shift': True,
'control': True,
'key': {'key_code': 93, 'char': ']'}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=fields
)
self.preference.register(
'keyboard_shortcuts',
'dialog_tab_backward',
gettext('Dialog tab backward'),
'keyboardshortcut',
{
'alt': False,
'shift': True,
'control': True,
'key': {'key_code': 91, 'char': '['}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=fields
)
self.preference.register(
'keyboard_shortcuts',
'sub_menu_refresh',
@@ -1799,7 +1799,11 @@ class ServerNode(PGChildNodeView):
None
"""
try:
data = request.form
data = None
if request.form:
data = request.form
elif request.data:
data = json.loads(request.data)
restore_point_name = data['value'] if data else None
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
conn = manager.connection()
@@ -1812,10 +1816,10 @@ class ServerNode(PGChildNodeView):
restore_point_name
)
)
if not status:
return internal_server_error(
errormsg=str(res)
)
if not status:
return internal_server_error(
errormsg=str(res)
)
return make_json_response(
data={
@@ -566,7 +566,7 @@ class CastView(PGChildNodeView, SchemaDiffObjectCompare):
:return:
"""
data = request.args
sql, name = self.get_sql(gid, sid, did, data, cid)
sql, _ = self.get_sql(gid, sid, did, data, cid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -809,8 +809,8 @@ class CastView(PGChildNodeView, SchemaDiffObjectCompare):
drop_sql = kwargs.get('drop_sql', False)
if data:
sql, name = self.get_sql(gid=gid, sid=sid, did=did, data=data,
cid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, did=did, data=data,
cid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -415,7 +415,7 @@ class ExtensionView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
try:
SQL, name = self.getSQL(gid, sid, data, did, eid)
SQL, _ = self.getSQL(gid, sid, data, did, eid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -601,8 +601,8 @@ class ExtensionView(PGChildNodeView, SchemaDiffObjectCompare):
drop_sql = kwargs.get('drop_sql', False)
if data:
sql, name = self.getSQL(gid=gid, sid=sid, did=did, data=data,
eid=oid)
sql, _ = self.getSQL(gid=gid, sid=sid, did=did, data=data,
eid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -634,7 +634,7 @@ class ForeignDataWrapperView(PGChildNodeView, SchemaDiffObjectCompare):
except ValueError:
data[k] = v
try:
sql, name = self.get_sql(gid, sid, data, did, fid)
sql, _ = self.get_sql(gid, sid, data, did, fid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -1009,8 +1009,8 @@ class ForeignDataWrapperView(PGChildNodeView, SchemaDiffObjectCompare):
drop_sql = kwargs.get('drop_sql', False)
if data:
sql, name = self.get_sql(gid=gid, sid=sid, did=did, data=data,
fid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, did=did, data=data,
fid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -631,7 +631,7 @@ class ForeignServerView(PGChildNodeView, SchemaDiffObjectCompare):
except ValueError:
data[k] = v
try:
sql, name = self.get_sql(gid, sid, data, did, fid, fsid)
sql, _ = self.get_sql(gid, sid, data, did, fid, fsid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -967,8 +967,8 @@ class ForeignServerView(PGChildNodeView, SchemaDiffObjectCompare):
drop_sql = kwargs.get('drop_sql', False)
if data:
sql, name = self.get_sql(gid=gid, sid=sid, did=did, data=data,
fid=fdw_id, fsid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, did=did, data=data,
fid=fdw_id, fsid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did, fid=fdw_id,
@@ -656,7 +656,7 @@ class UserMappingView(PGChildNodeView, SchemaDiffObjectCompare):
except ValueError:
data[k] = v
try:
sql, name = self.get_sql(data=data, fsid=fsid, umid=umid)
sql, _ = self.get_sql(data=data, fsid=fsid, umid=umid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -941,7 +941,7 @@ class UserMappingView(PGChildNodeView, SchemaDiffObjectCompare):
drop_sql = kwargs.get('drop_sql', False)
if data:
sql, name = self.get_sql(data=data, fsid=fsid, umid=oid)
sql, _ = self.get_sql(data=data, fsid=fsid, umid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did, fid=fid,
@@ -595,7 +595,7 @@ class LanguageView(PGChildNodeView, SchemaDiffObjectCompare):
except ValueError:
data[k] = v
try:
sql, name = self.get_sql(data, lid)
sql, _ = self.get_sql(data, lid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -868,7 +868,7 @@ class LanguageView(PGChildNodeView, SchemaDiffObjectCompare):
drop_sql = kwargs.get('drop_sql', False)
if data:
sql, name = self.get_sql(data=data, lid=oid)
sql, _ = self.get_sql(data=data, lid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -594,7 +594,7 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
try:
sql, name = self.get_sql(data, pbid)
sql, _ = self.get_sql(data, pbid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -701,11 +701,9 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
if 'pubschema' in data:
for schema in data['pubschema']:
if 'pubschema' in old_data and \
schema not in old_data['pubschema']:
add_schema_data.append(schema)
add_schema = True
elif 'pubschema' not in old_data:
if (('pubschema' in old_data and
schema not in old_data['pubschema']) or
('pubschema' not in old_data)):
add_schema_data.append(schema)
add_schema = True
@@ -900,7 +898,7 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
)
pub_table = []
status, table_res = self.conn.execute_dict(table_sql)
_, table_res = self.conn.execute_dict(table_sql)
for table in table_res['rows']:
if 'columns' in table and 'where' in table:
@@ -1111,7 +1109,7 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
drop_sql = kwargs.get('drop_sql', False)
if data:
sql, name = self.get_sql(data=data, pbid=oid)
sql, _ = self.get_sql(data=data, pbid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -865,7 +865,7 @@ It may have been removed by another user.
data[k] = v
try:
SQL, name = self.get_sql(gid, sid, data, scid)
SQL, _ = self.get_sql(gid, sid, data, scid)
if SQL and SQL.strip('\n') and SQL.strip(' '):
return make_json_response(
data=SQL.strip('\n'),
@@ -645,7 +645,7 @@ class CollationView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
try:
SQL, name = self.get_sql(gid, sid, data, scid, coid)
SQL, _ = self.get_sql(gid, sid, data, scid, coid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -834,8 +834,8 @@ class CollationView(PGChildNodeView, SchemaDiffObjectCompare):
if data:
if target_schema:
data['schema'] = target_schema
sql, name = self.get_sql(gid=gid, sid=sid, data=data, scid=scid,
coid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, data=data, scid=scid,
coid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -61,7 +61,7 @@ export default class CollationSchema extends BaseUISchema {
filter: (options) => {
let res = [];
options.forEach((d) => {
if (!(d && d.label.match(/^pg_/)))
if (!(d?.label.match(/^pg_/)))
res.push(d);
});
return res;
@@ -585,7 +585,7 @@ AND relkind != 'c'))"""
"""
data = self.request
SQL, name = self.get_sql(gid, sid, data, scid)
SQL, _ = self.get_sql(gid, sid, data, scid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -814,7 +814,7 @@ AND relkind != 'c'))"""
"""
try:
SQL, name = self.get_sql(gid, sid, self.request, scid, doid)
SQL, _ = self.get_sql(gid, sid, self.request, scid, doid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -980,9 +980,8 @@ AND relkind != 'c'))"""
if data:
if target_schema:
data['schema'] = target_schema
sql, name = self.get_sql(gid=gid, sid=sid, scid=scid,
data=data, doid=oid,
is_schema_diff=True)
sql, _ = self.get_sql(gid=gid, sid=sid, scid=scid,
data=data, doid=oid, is_schema_diff=True)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -433,7 +433,7 @@ class DomainConstraintView(PGChildNodeView):
"""
data = self.request
try:
status, SQL, name = self.get_sql(gid, sid, data, scid, doid)
status, SQL, _ = self.get_sql(gid, sid, data, scid, doid)
if not status:
return SQL
@@ -652,7 +652,7 @@ class DomainConstraintView(PGChildNodeView):
"""
data = self.request
status, SQL, name = self.get_sql(gid, sid, data, scid, doid, coid)
status, SQL, _ = self.get_sql(gid, sid, data, scid, doid, coid)
if status and SQL:
return make_json_response(
data=SQL,
@@ -35,8 +35,8 @@ ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}}
-- the current datatype cannot be cast to the target cltype so this conversion cannot be made automatically.
{% endif %}
{% if data.col_type_conversion is defined and data.col_type_conversion == False %} -- {% endif %}ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}}
{% if data.col_type_conversion is defined and data.col_type_conversion == False %} -- {% endif %} ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {{ GET_TYPE.UPDATE_TYPE_SQL(conn, data, o_data) }}{% if data.collspcname and data.collspcname != o_data.collspcname %}
COLLATE {{data.collspcname}}{% elif o_data.collspcname %} COLLATE {{o_data.collspcname}}{% endif %};
{% if data.col_type_conversion is defined and data.col_type_conversion == False %} -- {% endif %} ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {{ GET_TYPE.UPDATE_TYPE_SQL(conn, data, o_data) }}{% if data.collspcname and data.collspcname != o_data.collspcname and data.cltype != '"char"' %}
COLLATE {{data.collspcname}}{% elif o_data.collspcname and data.cltype != '"char"' %} COLLATE {{o_data.collspcname}}{% endif %};
{% endif %}
{### Alter column default value ###}
@@ -269,7 +269,7 @@
}
],
"name": "emp",
"cltype": "text",
"cltype": "\"char\"",
"attlen": null,
"attnum": 1,
"attnotnull": false,
@@ -651,7 +651,7 @@ class FtsConfigurationView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
# Fetch sql query for modified data
SQL, name = self.get_sql(gid, sid, did, scid, data, cfgid)
SQL, _ = self.get_sql(gid, sid, did, scid, data, cfgid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -1059,8 +1059,8 @@ class FtsConfigurationView(PGChildNodeView, SchemaDiffObjectCompare):
target_schema = kwargs.get('target_schema', None)
if data:
sql, name = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, cfgid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, cfgid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -642,7 +642,7 @@ class FtsDictionaryView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
# Fetch sql query for modified data
SQL, name = self.get_sql(gid, sid, did, scid, data, dcid)
SQL, _ = self.get_sql(gid, sid, did, scid, data, dcid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -963,8 +963,8 @@ class FtsDictionaryView(PGChildNodeView, SchemaDiffObjectCompare):
target_schema = kwargs.get('target_schema', None)
if data:
sql, name = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, dcid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, dcid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -588,7 +588,7 @@ class FtsParserView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
# Fetch sql query for modified data
SQL, name = self.get_sql(gid, sid, did, scid, data, pid)
SQL, _ = self.get_sql(gid, sid, did, scid, data, pid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -1001,8 +1001,8 @@ class FtsParserView(PGChildNodeView, SchemaDiffObjectCompare):
target_schema = kwargs.get('target_schema', None)
if data:
sql, name = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, pid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, pid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -426,7 +426,7 @@ class FtsTemplateView(PGChildNodeView, SchemaDiffObjectCompare):
)
# Fetch sql query to update fts template
sql, name = self.get_sql(gid, sid, did, scid, data, tid)
sql, _ = self.get_sql(gid, sid, did, scid, data, tid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -540,7 +540,7 @@ class FtsTemplateView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
# Fetch sql query for modified data
SQL, name = self.get_sql(gid, sid, did, scid, data, tid)
SQL, _ = self.get_sql(gid, sid, did, scid, data, tid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -867,8 +867,8 @@ class FtsTemplateView(PGChildNodeView, SchemaDiffObjectCompare):
target_schema = kwargs.get('target_schema', None)
if data:
sql, name = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, tid=oid)
sql, _ = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, tid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -778,7 +778,7 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
status=200
)
except Exception:
exc_type, exc_value, exc_traceback = sys.exc_info()
_, exc_value, _ = sys.exc_info()
return internal_server_error(errormsg=str(exc_value))
@check_precondition
@@ -1883,10 +1883,10 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
if data:
if target_schema:
data['schema'] = target_schema
status, sql = self._get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, fnid=oid, is_sql=False,
is_schema_diff=True,
allow_code_formatting=False)
_, sql = self._get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=data, fnid=oid, is_sql=False,
is_schema_diff=True,
allow_code_formatting=False)
# Check if return type is changed then we need to drop the
# function first and then recreate it.
if 'prorettypename' in data:
@@ -449,15 +449,13 @@ export default class FunctionSchema extends BaseUISchema {
setError('prosrc_c', null);
}
}else {
}else if (isEmptyString(state.prosrc)) {
/* code validation*/
if (isEmptyString(state.prosrc)) {
errmsg = gettext('Code cannot be empty.');
setError('prosrc', errmsg);
return true;
} else {
setError('prosrc', null);
}
errmsg = gettext('Code cannot be empty.');
setError('prosrc', errmsg);
return true;
} else {
setError('prosrc', null);
}
}
}
@@ -13,7 +13,7 @@ from functools import wraps
import json
from flask import render_template, make_response, request, jsonify
from flask_babel import gettext as _
from flask_babel import gettext
import pgadmin.browser.server_groups.servers.databases as database
from config import PG_DEFAULT_DRIVER
@@ -54,7 +54,7 @@ class PackageModule(SchemaChildModule):
"""
_NODE_TYPE = 'package'
_COLLECTION_LABEL = _("Packages")
_COLLECTION_LABEL = gettext("Packages")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -152,7 +152,7 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
# If DB not connected then return error to browser
if not self.conn.connected():
return precondition_required(
_(
gettext(
"Connection to the server has been lost."
)
)
@@ -399,13 +399,13 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
return make_json_response(
status=400,
success=0,
errormsg=_(
errormsg=gettext(
"Could not find the required parameter ({})."
).format(arg)
)
data['schema'] = self.schema
sql, name = self.getSQL(data=data, scid=scid, pkgid=None)
sql, _ = self.getSQL(data=data, scid=scid, pkgid=None)
status, msg = self.conn.execute_scalar(sql)
if not status:
@@ -475,7 +475,7 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
elif not res['rows']:
return make_json_response(
success=0,
errormsg=_(
errormsg=gettext(
'Error: Object not found.'
),
info=self.not_found_error_msg()
@@ -497,7 +497,7 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
return make_json_response(
success=1,
info=_("Package dropped")
info=gettext("Package dropped")
)
except Exception as e:
@@ -577,12 +577,12 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
return make_json_response(
status=400,
success=0,
errormsg=_(
errormsg=gettext(
"Could not find the required parameter ({})."
).format(arg)
)
sql, name = self.getSQL(data=data, scid=scid, pkgid=pkgid)
sql, _ = self.getSQL(data=data, scid=scid, pkgid=pkgid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -752,10 +752,9 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
if target_schema:
result['schema'] = target_schema
sql, name = self.getSQL(data=result, scid=scid, pkgid=pkgid,
sqltab=True,
is_schema_diff=is_schema_diff,
target_schema=target_schema)
sql, _ = self.getSQL(data=result, scid=scid, pkgid=pkgid,
sqltab=True, is_schema_diff=is_schema_diff,
target_schema=target_schema)
# Most probably this is due to error
if not isinstance(sql, str):
@@ -886,7 +885,7 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
if data:
if target_schema:
data['schema'] = target_schema
sql, name = self.getSQL(data=data, scid=scid, pkgid=oid)
sql, _ = self.getSQL(data=data, scid=scid, pkgid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -74,7 +74,7 @@ export default class PackageSchema extends BaseUISchema {
if (state && packageSchemaObj.isNew(state)) {
options.forEach((option) => {
// If schema name start with pg_* then we need to exclude them
if(option && option.label.match(/^pg_/)) {
if(option?.label.match(/^pg_/)) {
return;
}
res.push({ label: option.label, value: option.value, image: 'icon-schema' });
@@ -543,7 +543,7 @@ class SequenceView(PGChildNodeView, SchemaDiffObjectCompare):
data = request.form if request.form else json.loads(
request.data
)
sql, name = self.get_SQL(gid, sid, did, data, scid, seid)
sql, _ = self.get_SQL(gid, sid, did, data, scid, seid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -614,7 +614,7 @@ class SequenceView(PGChildNodeView, SchemaDiffObjectCompare):
"Could not find the required parameter ({})."
).format(arg)
)
sql, name = self.get_SQL(gid, sid, did, data, scid, seid)
sql, _ = self.get_SQL(gid, sid, did, data, scid, seid)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -753,8 +753,8 @@ class SequenceView(PGChildNodeView, SchemaDiffObjectCompare):
result['schema'] = target_schema
result = self._formatter(result, scid, seid)
sql, name = self.get_SQL(gid, sid, did, result, scid,
add_not_exists_clause=True)
sql, _ = self.get_SQL(gid, sid, did, result, scid,
add_not_exists_clause=True)
# Most probably this is due to error
if not isinstance(sql, str):
return sql
@@ -977,7 +977,7 @@ class SequenceView(PGChildNodeView, SchemaDiffObjectCompare):
if data:
if target_schema:
data['schema'] = target_schema
sql, name = self.get_SQL(gid, sid, did, data, scid, oid)
sql, _ = self.get_SQL(gid, sid, did, data, scid, oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -14,5 +14,5 @@ CREATE {% if data.relpersistence %}UNLOGGED {% endif %}SEQUENCE{% if add_not_exi
CACHE {{data.cache|int}}{% endif %}{% if data.owned_table is defined and data.owned_table != None and data.owned_column is defined and data.owned_column != None %}
OWNED BY {{ conn|qtIdent(data.owned_table) }}.{{ conn|qtIdent(data.owned_column) }}{% endif %};
OWNED BY {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.owned_table) }}.{{ conn|qtIdent(data.owned_column) }}{% endif %};
@@ -14,5 +14,5 @@ CREATE SEQUENCE{% if add_not_exists_clause %} IF NOT EXISTS{% endif %} {{ conn|q
CACHE {{data.cache|int}}{% endif %}{% if data.owned_table is defined and data.owned_table != None and data.owned_column is defined and data.owned_column != None %}
OWNED BY {{ conn|qtIdent(data.owned_table) }}.{{ conn|qtIdent(data.owned_column) }}{% endif %};
OWNED BY {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.owned_table) }}.{{ conn|qtIdent(data.owned_column) }}{% endif %};
@@ -8,7 +8,7 @@ CREATE SEQUENCE IF NOT EXISTS public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 999
CACHE 1
OWNED BY tableforownedby.col2;
OWNED BY public.tableforownedby.col2;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO postgres;
@@ -8,7 +8,7 @@ CREATE SEQUENCE IF NOT EXISTS public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 900
CACHE 1
OWNED BY tableforownedby.col2;
OWNED BY public.tableforownedby.col2;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO postgres;
@@ -8,7 +8,7 @@ CREATE SEQUENCE IF NOT EXISTS public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 999
CACHE 1
OWNED BY tableforownedby.col1;
OWNED BY public.tableforownedby.col1;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO postgres;
@@ -4,7 +4,7 @@ CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 999
CACHE 1
OWNED BY tableforownedby.col1;
OWNED BY public.tableforownedby.col1;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO postgres;
@@ -8,7 +8,7 @@ CREATE SEQUENCE IF NOT EXISTS public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 999
CACHE 1
OWNED BY tableforownedby.col2;
OWNED BY public.tableforownedby.col2;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO enterprisedb;
@@ -8,7 +8,7 @@ CREATE SEQUENCE IF NOT EXISTS public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 900
CACHE 1
OWNED BY tableforownedby.col2;
OWNED BY public.tableforownedby.col2;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO enterprisedb;
@@ -8,7 +8,7 @@ CREATE SEQUENCE IF NOT EXISTS public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 999
CACHE 1
OWNED BY tableforownedby.col1;
OWNED BY public.tableforownedby.col1;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO enterprisedb;
@@ -4,7 +4,7 @@ CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
MINVALUE 5
MAXVALUE 999
CACHE 1
OWNED BY tableforownedby.col1;
OWNED BY public.tableforownedby.col1;
ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
OWNER TO enterprisedb;
@@ -609,7 +609,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
data[k] = v
try:
SQL, name = self.get_sql(gid, sid, data, scid, syid)
SQL, _ = self.get_sql(gid, sid, data, scid, syid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -789,7 +789,7 @@ class SynonymView(PGChildNodeView, SchemaDiffObjectCompare):
if data:
if target_schema:
data['schema'] = target_schema
sql, name = self.get_sql(gid, sid, data, scid, oid)
sql, _ = self.get_sql(gid, sid, data, scid, oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
@@ -1079,6 +1079,7 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
return super().update(
gid, sid, did, scid, tid, data=data, res=res)
except Exception as e:
current_app.logger.exception(e)
return internal_server_error(errormsg=str(e))
@BaseTableView.check_precondition
@@ -1295,7 +1296,7 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
if target_schema:
data['schema'] = target_schema
sql, partition_sql = BaseTableView.get_reverse_engineered_sql(
sql, _ = BaseTableView.get_reverse_engineered_sql(
self, did=did, scid=scid, tid=tid, main_sql=main_sql,
data=data, json_resp=json_resp,
add_not_exists_clause=if_exists_flag)
@@ -1336,7 +1337,7 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
if not status:
return res
SQL, name = self.get_sql(did, scid, tid, data, res)
SQL, _ = self.get_sql(did, scid, tid, data, res)
SQL = re.sub('\n{2,}', '\n\n', SQL)
SQL = SQL.strip('\n')
@@ -600,7 +600,7 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
column_utils.type_formatter(data['cltype'])
try:
SQL, name = self.get_sql(scid, tid, clid, data)
SQL, _ = self.get_sql(scid, tid, clid, data)
if not isinstance(SQL, str):
return SQL
@@ -688,7 +688,7 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
column_utils.type_formatter(old_data['cltype'])
if 'cltype' in data and data['cltype'] != old_data['cltype']:
length, precision, typeval = \
length, precision, _ = \
self.get_length_precision(data['cltype'])
# if new datatype does not have length or precision
@@ -793,7 +793,7 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
data = column_utils.column_formatter(self.conn, tid, clid,
data, [])
SQL, name = self.get_sql(scid, tid, None, data, is_sql=True)
SQL, _ = self.get_sql(scid, tid, None, data, is_sql=True)
if not isinstance(SQL, str):
return SQL
@@ -77,7 +77,7 @@ export default class ColumnSchema extends BaseUISchema {
inSchemaWithColumnCheck(state) {
// disable all fields if column is listed under view or mview
if (this.nodeInfo && ('view' in this.nodeInfo || 'mview' in this.nodeInfo)) {
if (this.nodeInfo && (('view' in this.nodeInfo && this.nodeInfo?.server?.version < 130000) || 'mview' in this.nodeInfo)) {
return true;
}
@@ -384,17 +384,38 @@ export default class ColumnSchema extends BaseUISchema {
group: gettext('Definition'),
},{
id: 'attstorage', label: gettext('Storage'), group: gettext('Definition'),
type: 'select', mode: ['properties', 'edit'],
type: 'select', mode: ['properties', 'edit', 'create'],
cell: 'select', readonly: obj.inSchemaWithColumnCheck,
controlProps: { placeholder: gettext('Select storage'),
allowClear: false,
},
options: [
{label: 'PLAIN', value: 'p'},
{label: 'MAIN', value: 'm'},
{label: 'EXTERNAL', value: 'e'},
{label: 'EXTENDED', value: 'x'},
],
options: function() {
let options = [{
label: gettext('PLAIN'), value: 'p'
},{
label: gettext('MAIN'), value: 'm'
},{
label: gettext('EXTERNAL'), value: 'e'
},{
label: gettext('EXTENDED'), value: 'x'
}];
if (obj.getServerVersion() >= 160000) {
options.push({
label: gettext('DEFAULT'), value: 'd',
});
}
return options;
},
visible: (state) => {
if (obj.getServerVersion() >= 160000) {
return true;
} else if (obj.isNew(state)) {
return false;
} else {
return true;
}
},
},{
id: 'defval', label: gettext('Default'), cell: 'text',
type: 'text', group: gettext('Constraints'), deps: ['cltype', 'colconstype'],
@@ -201,6 +201,35 @@
"error_msg": "Mocked Internal Server Error",
"test_result_data": {}
}
},
{
"name": "Create: Add column with storage",
"is_positive_test": true,
"inventory_data": {},
"test_data": {
"server_min_version": 160000,
"skip_msg": "Creating column with storage is supported by EPAS/PG 16.0 and above.",
"name": "test_column_add_",
"cltype": "character varying",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attoptions": [],
"seclabels": [],
"attstorage": "e",
"description": {
"comment": "jsoncomment"
}
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {}
}
}
],
"column_delete": [
@@ -0,0 +1,2 @@
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE PLAIN;
@@ -0,0 +1,12 @@
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
-- ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN IF EXISTS "col_1111_$%{}[]()&*^!@""'`\/#";
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ADD COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
IS 'Comment for create';
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE PLAIN;
@@ -0,0 +1,8 @@
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ADD COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
IS 'Comment for create';
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE MAIN;
@@ -0,0 +1,12 @@
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
-- ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN IF EXISTS "col_1111_$%{}[]()&*^!@""'`\/#";
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ADD COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
IS 'Comment for create';
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE MAIN;
@@ -0,0 +1,972 @@
{
"scenarios": [
{
"type": "create",
"name": "Create Table for testing column node (v.12+)",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"data": {
"name": "table_3_$%{}[]()&*^!@\"'`\\/#",
"is_partitioned": false,
"columns": [],
"schema": "testschema"
},
"store_object_id": true
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_1_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"defval": "1"
},
"expected_sql_file": "create_column_int.sql",
"expected_msql_file": "create_column_int.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 1,
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"cltype": "real",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "w",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_int.sql",
"expected_msql_file": "alter_column_int.msql"
},
{
"type": "alter",
"name": "Alter Column (Privilege change)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 1,
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
"attacl": {
"changed": [
{
"grantee": "postgres",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_alt_privilege.sql",
"expected_msql_file": "alter_column_alt_privilege.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Character type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_2_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "character varying",
"collspcname": "pg_catalog.\"C\"",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "50",
"attprecision": "",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_char.sql",
"expected_msql_file": "create_column_char.msql"
},
{
"type": "alter",
"name": "Alter Column (Character type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 2,
"name": "new_col_2_$%{}[]()&*^!@\"'`\\/#",
"attlen": "",
"attstattarget": "5",
"attstorage": "p",
"description": "Comment for alter",
"cltype": "character",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_char.sql",
"expected_msql_file": "alter_column_char.msql"
},
{
"type": "delete",
"name": "Drop Column (Character type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_2_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type) with identity",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_3_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"attidentity": "a",
"seqincrement": "1",
"seqstart": "1",
"seqmin": "1",
"seqmax": "99999",
"seqcache": "10",
"seqcycle": true,
"colconstype": "i"
},
"expected_sql_file": "create_column_int_identity.sql",
"expected_msql_file": "create_column_int_identity.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) with identity",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 3,
"name": "new_col_3_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_identity.sql",
"expected_msql_file": "alter_column_identity.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) drop identity",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 3,
"colconstype": "n"
},
"expected_sql_file": "alter_column_drop_identity.sql",
"expected_msql_file": "alter_column_drop_identity.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_3_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type) with Generated feature",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_4_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "g",
"genexpr": "1 + 2 + 3",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_int_generated.sql",
"expected_msql_file": "create_column_int_generated.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) with Generated feature",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 4,
"name": "new_col_4_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_generated.sql",
"expected_msql_file": "alter_column_generated.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_4_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Numeric type with Length Precision & Variables)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_5_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"min_val": 0,
"max_val": 1000,
"cltype": "numeric",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "10",
"attprecision": "5",
"attidentity": "a",
"attoptions": [
{
"name": "n_distinct",
"value": "1"
}
],
"seclabels": []
},
"expected_sql_file": "create_column_numeric.sql",
"expected_msql_file": "create_column_numeric.msql"
},
{
"type": "alter",
"name": "Alter Column (Numeric type with Length Precision & Variables)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "new_col_5_$%{}[]()&*^!@\"'`\\/#",
"attnum": 5,
"attlen": "15",
"attprecision": "6",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "w",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_numeric.sql",
"expected_msql_file": "alter_column_numeric.msql"
},
{
"type": "alter",
"name": "Alter Column (Remove Length)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 3,
"attlen": ""
},
"expected_sql_file": "alter_column_remove_length.sql",
"expected_msql_file": "alter_column_remove_length.msql"
},
{
"type": "delete",
"name": "Drop Column (Numeric type with Length Precision & Variables)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_5_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Dummy Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "dummy1",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"defval": "1"
}
},
{
"type": "create",
"name": "Create Dummy Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "dummy2",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"defval": "1"
}
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type) with Generated feature with columns",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_8_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "g",
"genexpr": "dummy1 + dummy2",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_int_generated_with_existing_columns.sql",
"expected_msql_file": "create_column_int_generated_with_existing_columns.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) with Generated feature with columns",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 8,
"name": "new_col_8_$%{}[]()&*^!@\"'`\\/#",
"genexpr": "dummy1 - dummy2",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_generated_with_existing_columns.sql",
"expected_msql_file": "alter_column_generated_with_existing_columns.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type) with Generated feature with columns",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_8_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with identity (Generated by default)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_9_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"attidentity": "d",
"seqincrement": "1",
"seqstart": "1",
"seqmin": "1",
"seqmax": "99999",
"seqcache": "10",
"seqcycle": true,
"colconstype": "i"
},
"expected_sql_file": "create_column_int_identity_by_default.sql",
"expected_msql_file": "create_column_int_identity_by_default.msql"
},
{
"type": "alter",
"name": "Alter Column with identity (Generated by default)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 9,
"name": "new_col_9_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"seqincrement": "2",
"seqmax": "200",
"seqcache": "2",
"seqcycle": true,
"seqmin": "1"
},
"expected_sql_file": "alter_column_identity_by_default.sql",
"expected_msql_file": "alter_column_identity_by_default.msql"
},
{
"type": "alter",
"name": "Alter Column with drop identity (Generated by default)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 9,
"colconstype": "n"
},
"expected_sql_file": "alter_column_drop_identity_by_default.sql",
"expected_msql_file": "alter_column_drop_identity_by_default.msql"
},
{
"type": "delete",
"name": "Drop Column Column with identity (Generated by default)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_9_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with identity (BY DEFAULT) for combination of identity options & initiate START",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_6_$%{}[]()&*^!@\"'`\\/#",
"cltype": "bigint",
"attacl": [],
"description": "demo comments",
"is_primary_key": false,
"attnotnull": true,
"attlen": null,
"attprecision": null,
"attidentity": "d",
"seqincrement": "1",
"seqstart": "1",
"seqmin": "1",
"seqmax": "10",
"seqcache": "1",
"seqcycle": true,
"colconstype": "i",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_identity_for_restart_seq.sql",
"expected_msql_file": "create_column_identity_for_restart_seq.msql"
},
{
"type": "alter",
"name": "Alter identity Column (BY DEFAULT) to ALWAYS & Update START",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnotnull": true,
"attidentity": "a",
"seqstart": 2,
"seqcycle": false
},
"expected_sql_file": "alter_column_identity_for_restart_seq.sql",
"expected_msql_file": "alter_column_identity_for_restart_seq.msql"
},
{
"type": "alter",
"name": "Alter identity Column (ALWAYS) for combination of identity options & Update START",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 9,
"attidentity": "a",
"seqincrement": "3",
"seqstart": "3",
"seqmin": "3",
"seqmax": "30",
"seqcache": "3",
"seqcycle": true
},
"expected_sql_file": "alter_column_identity_for_comb_start_seq.sql",
"expected_msql_file": "alter_column_identity_for_comb_start_seq.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col_6_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with text & default value",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
"cltype": "text",
"attacl": [],
"description": "test comment",
"is_primary_key": false,
"attnotnull": false,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": [],
"defval": "'xyz'"
},
"expected_sql_file": "create_column_text_with_default_value.sql",
"expected_msql_file": "create_column_text_with_default_value.msql"
},
{
"type": "alter",
"name": "Alter Column with text & update default value",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
"defval": "'changed default value'",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_text_with_default_value.sql",
"expected_msql_file": "alter_column_text_with_default_value.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col__1_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with time with time zone & default value using function",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
"cltype": "time with time zone",
"attacl": [],
"description": "test comment",
"min_val_attlen": 0,
"max_val_attlen": 6,
"is_primary_key": false,
"attnotnull": false,
"attlen": "4",
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": [],
"defval": "now()"
},
"expected_sql_file": "create_column_timestamp_with_default_value_using_function.sql",
"expected_msql_file": "create_column_timestamp_with_default_value_using_function.msql"
},
{
"type": "alter",
"name": "Alter Column with time with time zone & update length",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
"attlen": "6",
"attnotnull": true,
"description": "test comment modification"
},
"expected_sql_file": "alter_column_timestamp_with_default_value_using_function.sql",
"expected_msql_file": "alter_column_timestamp_with_default_value_using_function.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col__2_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with interger_array and options",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
"cltype": "integer[]",
"attacl": [],
"description": "comment",
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "n",
"attoptions": [
{
"name": "n_distinct",
"value": "1"
}
],
"seclabels": []
},
"expected_sql_file": "create_column_with_interger_array_and_options.sql",
"expected_msql_file": "create_column_with_interger_array_and_options.msql"
},
{
"type": "alter",
"name": "Alter Column with interger_array and options",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
"attoptions": {
"changed": [
{
"name": "n_distinct",
"value": "2"
}
]
}
},
"expected_sql_file": "alter_column_with_interger_array_and_options.sql",
"expected_msql_file": "alter_column_with_interger_array_and_options.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col__3_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with compression",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_comp_$%{}[]()&*^!@\"'`\\/#",
"cltype": "character varying",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attcompression": "pglz",
"attoptions": [],
"seclabels": [],
"defval": "1"
},
"expected_sql_file": "create_column_comp.sql",
"expected_msql_file": "create_column_comp.msql"
},
{
"type": "alter",
"name": "Alter Column compression type",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col_comp_$%{}[]()&*^!@\"'`\\/#",
"attcompression": "lz4"
},
"expected_sql_file": "alter_column_compression.sql",
"expected_msql_file": "alter_column_compression.msql"
},
{
"type": "delete",
"name": "Drop Column with compression",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col_comp_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with storage",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_1111_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "character varying",
"collspcname": "pg_catalog.\"C\"",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "50",
"attstorage": "m",
"attprecision": "",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_with_storage.sql",
"expected_msql_file": "create_column_with_storage.msql"
},
{
"type": "alter",
"name": "Alter Column storage type",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col_1111_$%{}[]()&*^!@\"'`\\/#",
"attstorage": "p"
},
"expected_sql_file": "alter_column_storage.sql",
"expected_msql_file": "alter_column_storage.msql"
},
{
"type": "delete",
"name": "Drop Column with storage",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col_1111_$%{}[]()&*^!@\"'`\\/#"
}
}
]
}
@@ -0,0 +1,2 @@
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE PLAIN;
@@ -0,0 +1,12 @@
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
-- ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN IF EXISTS "col_1111_$%{}[]()&*^!@""'`\/#";
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ADD COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
IS 'Comment for create';
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE PLAIN;
@@ -0,0 +1,8 @@
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ADD COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
IS 'Comment for create';
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE MAIN;
@@ -0,0 +1,12 @@
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
-- ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN IF EXISTS "col_1111_$%{}[]()&*^!@""'`\/#";
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ADD COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1111_$%{}[]()&*^!@""'`\/#"
IS 'Comment for create';
ALTER TABLE IF EXISTS testschema."table_3_$%{}[]()&*^!@""'`\/#"
ALTER COLUMN "col_1111_$%{}[]()&*^!@""'`\/#" SET STORAGE MAIN;
@@ -0,0 +1,972 @@
{
"scenarios": [
{
"type": "create",
"name": "Create Table for testing column node (v.12+)",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"data": {
"name": "table_3_$%{}[]()&*^!@\"'`\\/#",
"is_partitioned": false,
"columns": [],
"schema": "testschema"
},
"store_object_id": true
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_1_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"defval": "1"
},
"expected_sql_file": "create_column_int.sql",
"expected_msql_file": "create_column_int.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 1,
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"cltype": "real",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "enterprisedb",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "w",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_int.sql",
"expected_msql_file": "alter_column_int.msql"
},
{
"type": "alter",
"name": "Alter Column (Privilege change)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 1,
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
"attacl": {
"changed": [
{
"grantee": "enterprisedb",
"grantor": "enterprisedb",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_alt_privilege.sql",
"expected_msql_file": "alter_column_alt_privilege.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Character type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_2_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "character varying",
"collspcname": "pg_catalog.\"C\"",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "50",
"attprecision": "",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_char.sql",
"expected_msql_file": "create_column_char.msql"
},
{
"type": "alter",
"name": "Alter Column (Character type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 2,
"name": "new_col_2_$%{}[]()&*^!@\"'`\\/#",
"attlen": null,
"attstattarget": "5",
"attstorage": "p",
"description": "Comment for alter",
"cltype": "character",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "enterprisedb",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_char.sql",
"expected_msql_file": "alter_column_char.msql"
},
{
"type": "delete",
"name": "Drop Column (Character type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_2_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type) with identity",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_3_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"attidentity": "a",
"seqincrement": "1",
"seqstart": "1",
"seqmin": "1",
"seqmax": "99999",
"seqcache": "10",
"seqcycle": true,
"colconstype": "i"
},
"expected_sql_file": "create_column_int_identity.sql",
"expected_msql_file": "create_column_int_identity.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) with identity",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 3,
"name": "new_col_3_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "enterprisedb",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_identity.sql",
"expected_msql_file": "alter_column_identity.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) drop identity",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 3,
"colconstype": "n"
},
"expected_sql_file": "alter_column_drop_identity.sql",
"expected_msql_file": "alter_column_drop_identity.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_3_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type) with Generated feature",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_4_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "g",
"genexpr": "1 + 2 + 3",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_int_generated.sql",
"expected_msql_file": "create_column_int_generated.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) with Generated feature",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 4,
"name": "new_col_4_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "enterprisedb",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_generated.sql",
"expected_msql_file": "alter_column_generated.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_4_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column (Numeric type with Length Precision & Variables)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_5_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"min_val": 0,
"max_val": 1000,
"cltype": "numeric",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "10",
"attprecision": "5",
"attidentity": "a",
"attoptions": [
{
"name": "n_distinct",
"value": "1"
}
],
"seclabels": []
},
"expected_sql_file": "create_column_numeric.sql",
"expected_msql_file": "create_column_numeric.msql"
},
{
"type": "alter",
"name": "Alter Column (Numeric type with Length Precision & Variables)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "new_col_5_$%{}[]()&*^!@\"'`\\/#",
"attnum": 5,
"attlen": "15",
"attprecision": "6",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "enterprisedb",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "w",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_numeric.sql",
"expected_msql_file": "alter_column_numeric.msql"
},
{
"type": "alter",
"name": "Alter Column (Remove Length)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 3,
"attlen": ""
},
"expected_sql_file": "alter_column_remove_length.sql",
"expected_msql_file": "alter_column_remove_length.msql"
},
{
"type": "delete",
"name": "Drop Column (Numeric type with Length Precision & Variables)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_5_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Dummy Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "dummy1",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"defval": "1"
}
},
{
"type": "create",
"name": "Create Dummy Column (Integer/Numeric type)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "dummy2",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"defval": "1"
}
},
{
"type": "create",
"name": "Create Column (Integer/Numeric type) with Generated feature with columns",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_8_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "g",
"genexpr": "dummy1 + dummy2",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_int_generated_with_existing_columns.sql",
"expected_msql_file": "create_column_int_generated_with_existing_columns.msql"
},
{
"type": "alter",
"name": "Alter Column (Integer/Numeric type) with Generated feature with columns",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 8,
"name": "new_col_8_$%{}[]()&*^!@\"'`\\/#",
"genexpr": "dummy1 - dummy2",
"description": "Comment for alter",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "enterprisedb",
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_generated_with_existing_columns.sql",
"expected_msql_file": "alter_column_generated_with_existing_columns.msql"
},
{
"type": "delete",
"name": "Drop Column (Integer/Numeric type) with Generated feature with columns",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_8_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with identity (Generated by default)",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_9_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "bigint",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attoptions": [],
"seclabels": [],
"attidentity": "d",
"seqincrement": "1",
"seqstart": "1",
"seqmin": "1",
"seqmax": "99999",
"seqcache": "10",
"seqcycle": true,
"colconstype": "i"
},
"expected_sql_file": "create_column_int_identity_by_default.sql",
"expected_msql_file": "create_column_int_identity_by_default.msql"
},
{
"type": "alter",
"name": "Alter Column with identity (Generated by default)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 9,
"name": "new_col_9_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for alter",
"seqincrement": "2",
"seqmax": "200",
"seqcache": "2",
"seqcycle": true,
"seqmin": "1"
},
"expected_sql_file": "alter_column_identity_by_default.sql",
"expected_msql_file": "alter_column_identity_by_default.msql"
},
{
"type": "alter",
"name": "Alter Column with drop identity (Generated by default)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 9,
"colconstype": "n"
},
"expected_sql_file": "alter_column_drop_identity_by_default.sql",
"expected_msql_file": "alter_column_drop_identity_by_default.msql"
},
{
"type": "delete",
"name": "Drop Column Column with identity (Generated by default)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "new_col_9_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with identity (BY DEFAULT) for combination of identity options & initiate START",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_6_$%{}[]()&*^!@\"'`\\/#",
"cltype": "bigint",
"attacl": [],
"description": "demo comments",
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attidentity": "d",
"seqincrement": "1",
"seqstart": "1",
"seqmin": "1",
"seqmax": "10",
"seqcache": "1",
"seqcycle": true,
"colconstype": "i",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_identity_for_restart_seq.sql",
"expected_msql_file": "create_column_identity_for_restart_seq.msql"
},
{
"type": "alter",
"name": "Alter identity Column (BY DEFAULT) to ALWAYS & Update START",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnotnull": true,
"attidentity": "a",
"seqstart": 2,
"seqcycle": false
},
"expected_sql_file": "alter_column_identity_for_restart_seq.sql",
"expected_msql_file": "alter_column_identity_for_restart_seq.msql"
},
{
"type": "alter",
"name": "Alter identity Column (ALWAYS) for combination of identity options & Update START",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"attnum": 9,
"attidentity": "a",
"seqincrement": "3",
"seqstart": "3",
"seqmin": "3",
"seqmax": "30",
"seqcache": "3",
"seqcycle": true
},
"expected_sql_file": "alter_column_identity_for_comb_start_seq.sql",
"expected_msql_file": "alter_column_identity_for_comb_start_seq.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col_6_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with text & default value",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
"cltype": "text",
"attacl": [],
"description": "test comment",
"is_primary_key": false,
"attnotnull": false,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": [],
"defval": "'xyz'"
},
"expected_sql_file": "create_column_text_with_default_value.sql",
"expected_msql_file": "create_column_text_with_default_value.msql"
},
{
"type": "alter",
"name": "Alter Column with text & update default value",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
"defval": "'changed default value'",
"attacl": {
"added": [
{
"grantee": "PUBLIC",
"grantor": "postgres",
"privileges": [
{
"privilege_type": "r",
"privilege": true,
"with_grant": false
}
]
}
]
}
},
"expected_sql_file": "alter_column_text_with_default_value.sql",
"expected_msql_file": "alter_column_text_with_default_value.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col__1_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with time with time zone & default value using function",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
"cltype": "time with time zone",
"attacl": [],
"description": "test comment",
"min_val_attlen": 0,
"max_val_attlen": 6,
"is_primary_key": false,
"attnotnull": false,
"attlen": "4",
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": [],
"defval": "now()"
},
"expected_sql_file": "create_column_timestamp_with_default_value_using_function.sql",
"expected_msql_file": "create_column_timestamp_with_default_value_using_function.msql"
},
{
"type": "alter",
"name": "Alter Column with time with time zone & update length",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
"attlen": "6",
"attnotnull": true,
"description": "test comment modification"
},
"expected_sql_file": "alter_column_timestamp_with_default_value_using_function.sql",
"expected_msql_file": "alter_column_timestamp_with_default_value_using_function.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col__2_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with interger_array and options",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
"cltype": "integer[]",
"attacl": [],
"description": "comment",
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attidentity": "a",
"colconstype": "n",
"attoptions": [
{
"name": "n_distinct",
"value": "1"
}
],
"seclabels": []
},
"expected_sql_file": "create_column_with_interger_array_and_options.sql",
"expected_msql_file": "create_column_with_interger_array_and_options.msql"
},
{
"type": "alter",
"name": "Alter Column with interger_array and options",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
"attoptions": {
"changed": [
{
"name": "n_distinct",
"value": "2"
}
]
}
},
"expected_sql_file": "alter_column_with_interger_array_and_options.sql",
"expected_msql_file": "alter_column_with_interger_array_and_options.msql"
},
{
"type": "delete",
"name": "Drop Column with identity (ALWAYS)",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col__3_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with compression",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_comp_$%{}[]()&*^!@\"'`\\/#",
"cltype": "character varying",
"attacl": [],
"is_primary_key": false,
"attnotnull": true,
"attlen": "",
"attprecision": "",
"attcompression": "pglz",
"attoptions": [],
"seclabels": [],
"defval": "1"
},
"expected_sql_file": "create_column_comp.sql",
"expected_msql_file": "create_column_comp.msql"
},
{
"type": "alter",
"name": "Alter Column compression type",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col_comp_$%{}[]()&*^!@\"'`\\/#",
"attcompression": "lz4"
},
"expected_sql_file": "alter_column_compression.sql",
"expected_msql_file": "alter_column_compression.msql"
},
{
"type": "delete",
"name": "Drop Column with compression",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col_comp_$%{}[]()&*^!@\"'`\\/#"
}
},
{
"type": "create",
"name": "Create Column with storage",
"endpoint": "NODE-column.obj",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql",
"data": {
"name": "col_1111_$%{}[]()&*^!@\"'`\\/#",
"description": "Comment for create",
"cltype": "character varying",
"collspcname": "pg_catalog.\"C\"",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": "50",
"attstorage": "m",
"attprecision": "",
"attoptions": [],
"seclabels": []
},
"expected_sql_file": "create_column_with_storage.sql",
"expected_msql_file": "create_column_with_storage.msql"
},
{
"type": "alter",
"name": "Alter Column storage type",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"msql_endpoint": "NODE-column.msql_id",
"data": {
"name": "col_1111_$%{}[]()&*^!@\"'`\\/#",
"attstorage": "p"
},
"expected_sql_file": "alter_column_storage.sql",
"expected_msql_file": "alter_column_storage.msql"
},
{
"type": "delete",
"name": "Drop Column with storage",
"endpoint": "NODE-column.obj_id",
"sql_endpoint": "NODE-column.sql_id",
"data": {
"name": "col_1111_$%{}[]()&*^!@\"'`\\/#"
}
}
]
}
@@ -714,7 +714,7 @@ class CompoundTriggerView(PGChildNodeView, SchemaDiffObjectCompare):
data['table'] = self.table
try:
sql, name = compound_trigger_utils.get_sql(
sql, _ = compound_trigger_utils.get_sql(
self.conn, data, tid, trid, self._DATABASE_LAST_SYSTEM_OID)
if not isinstance(sql, str):
return sql
@@ -884,7 +884,7 @@ class CompoundTriggerView(PGChildNodeView, SchemaDiffObjectCompare):
target_schema = kwargs.get('target_schema', None)
if data:
sql, name = compound_trigger_utils.get_sql(
sql, _ = compound_trigger_utils.get_sql(
self.conn, data, tid, oid, self._DATABASE_LAST_SYSTEM_OID)
if not isinstance(sql, str):
return sql
@@ -932,7 +932,7 @@ class CompoundTriggerView(PGChildNodeView, SchemaDiffObjectCompare):
if target_schema:
data['schema'] = target_schema
sql, name = compound_trigger_utils.get_sql(
sql, _ = compound_trigger_utils.get_sql(
self.conn, data, tid, None, self._DATABASE_LAST_SYSTEM_OID)
# If compound trigger is disbaled then add sql
@@ -10,7 +10,7 @@
""" Implements Utility class for Compound Triggers. """
from flask import render_template
from flask_babel import gettext as _
from flask_babel import gettext
from pgadmin.utils.ajax import internal_server_error
from pgadmin.utils.exception import ObjectGone, ExecuteError
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
@@ -108,7 +108,7 @@ def get_sql(conn, data, tid, trid, datlastsysoid, template_path=None):
raise ExecuteError(res)
elif len(res['rows']) == 0:
raise ObjectGone(
_('Could not find the compound trigger in the table.'))
gettext('Could not find the compound trigger in the table.'))
old_data = dict(res['rows'][0])
# If name is not present in data then
@@ -133,7 +133,7 @@ def get_sql(conn, data, tid, trid, datlastsysoid, template_path=None):
for arg in required_args:
if arg not in data:
return _('-- definition incomplete')
return gettext('-- definition incomplete')
# If the request for new object which do not have did
SQL = render_template("/".join([template_path, 'create.sql']),
@@ -166,7 +166,7 @@ def get_reverse_engineered_sql(conn, **kwargs):
if len(res['rows']) == 0:
raise ObjectGone(
_('Could not find the compound trigger in the table.'))
gettext('Could not find the compound trigger in the table.'))
data = dict(res['rows'][0])
# Adding parent into data dict, will be using it while creating sql
@@ -179,7 +179,7 @@ def get_reverse_engineered_sql(conn, **kwargs):
data = trigger_definition(data)
SQL, name = get_sql(conn, data, tid, None, datlastsysoid)
SQL, _ = get_sql(conn, data, tid, None, datlastsysoid)
sql_header = "-- Compound Trigger: {0}\n\n-- ".format(data['name'])
@@ -14,7 +14,7 @@ from functools import wraps
import pgadmin.browser.server_groups.servers.databases as database
from flask import render_template, make_response, request, jsonify
from flask_babel import gettext as _
from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.server_groups.servers.databases.schemas.tables.\
constraints.type import ConstraintRegistry
@@ -49,7 +49,7 @@ class CheckConstraintModule(CollectionNodeModule):
Check node is initialized.
"""
_NODE_TYPE = 'check_constraint'
_COLLECTION_LABEL = _("Check Constraints")
_COLLECTION_LABEL = gettext("Check Constraints")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -279,7 +279,7 @@ class CheckConstraintView(PGChildNodeView):
SQL = render_template("/".join([self.template_path,
self._PROPERTIES_SQL]), tid=tid)
status, res = self.conn.execute_dict(SQL)
_, res = self.conn.execute_dict(SQL)
for row in res['rows']:
row['_type'] = self.node_type
@@ -303,10 +303,10 @@ class CheckConstraintView(PGChildNodeView):
self._NODES_SQL]),
tid=tid,
cid=cid)
status, rset = self.conn.execute_2darray(SQL)
_, rset = self.conn.execute_2darray(SQL)
if len(rset['rows']) == 0:
return gone(_("""Could not find the check constraint."""))
return gone(gettext("""Could not find the check constraint."""))
if "convalidated" in rset['rows'][0] and \
rset['rows'][0]["convalidated"]:
@@ -344,7 +344,7 @@ class CheckConstraintView(PGChildNodeView):
SQL = render_template("/".join([self.template_path,
self._NODES_SQL]),
tid=tid)
status, rset = self.conn.execute_2darray(SQL)
_, rset = self.conn.execute_2darray(SQL)
for row in rset['rows']:
if "convalidated" in row and row["convalidated"]:
@@ -399,7 +399,7 @@ class CheckConstraintView(PGChildNodeView):
SQL = render_template("/".join([self.template_path,
self._NODES_SQL]),
tid=tid)
status, rset = self.conn.execute_2darray(SQL)
_, rset = self.conn.execute_2darray(SQL)
for row in rset['rows']:
if "convalidated" in row and row["convalidated"]:
@@ -437,7 +437,7 @@ class CheckConstraintView(PGChildNodeView):
return res
if len(res) == 0:
return gone(_(
return gone(gettext(
"""Could not find the check constraint in the table."""
))
@@ -481,7 +481,7 @@ class CheckConstraintView(PGChildNodeView):
return True, make_json_response(
status=400,
success=0,
errormsg=_(
errormsg=gettext(
"Could not find the required parameter ({})."
).format(arg),
), data
@@ -527,7 +527,7 @@ class CheckConstraintView(PGChildNodeView):
data['table'] = self.table
# Checking whether the table is deleted via query tool
if len(data['table']) == 0:
return gone(_(self.not_found_error_msg('Table')))
return gone(gettext(self.not_found_error_msg('Table')))
try:
if 'name' not in data or data['name'] == "":
@@ -630,10 +630,10 @@ class CheckConstraintView(PGChildNodeView):
if not res['rows']:
return make_json_response(
success=0,
errormsg=_(
errormsg=gettext(
'Error: Object not found.'
),
info=_(
info=gettext(
'The specified check constraint '
'could not be found.\n'
)
@@ -650,7 +650,7 @@ class CheckConstraintView(PGChildNodeView):
return make_json_response(
success=1,
info=_("Check constraint dropped.")
info=gettext("Check constraint dropped.")
)
except Exception as e:
@@ -739,7 +739,7 @@ class CheckConstraintView(PGChildNodeView):
return internal_server_error(errormsg=res)
if len(res['rows']) == 0:
return gone(
_("Could not find the object on the server.")
gettext("Could not find the object on the server.")
)
data = res['rows'][0]
@@ -880,7 +880,7 @@ class CheckConstraintView(PGChildNodeView):
return make_json_response(
success=1,
info=_("Check constraint updated."),
info=gettext("Check constraint updated."),
data={
'id': cid,
'tid': tid,
@@ -67,7 +67,7 @@ export default class CheckConstraintSchema extends BaseUISchema {
},{
id: 'consrc', label: gettext('Check'), type: 'multiline', cell: 'text',
group: gettext('Definition'), mode: ['properties', 'create', 'edit'],
readonly: obj.isReadonly, editable: true, noEmpty: true,
readonly: obj.isReadonly, noEmpty: true, editable: (state) => {return obj.isNew(state);},
},{
id: 'connoinherit', label: gettext('No inherit?'), type: 'switch', cell: 'switch',
group: gettext('Definition'), mode: ['properties', 'create', 'edit'], min_version: 90200,
@@ -128,7 +128,7 @@ def get_check_constraint_sql(conn, tid, data, template_path=None):
c['schema'] = data['schema']
c['table'] = data['name']
modified_sql, name = get_sql(conn, c, tid, c['oid'])
modified_sql, _ = get_sql(conn, c, tid, c['oid'])
sql.append(modified_sql.strip('\n'))
if 'added' in constraint:
@@ -136,7 +136,7 @@ def get_check_constraint_sql(conn, tid, data, template_path=None):
c['schema'] = data['schema']
c['table'] = data['name']
add_sql, name = get_sql(conn, c, tid)
add_sql, _ = get_sql(conn, c, tid)
sql.append(add_sql.strip("\n"))
if len(sql) > 0:
@@ -14,7 +14,7 @@ from functools import wraps
import pgadmin.browser.server_groups.servers.databases as database
from flask import render_template, make_response, request, jsonify
from flask_babel import gettext as _
from flask_babel import gettext
from pgadmin.browser.server_groups.servers.databases.schemas.tables.\
constraints.type import ConstraintRegistry, ConstraintTypeModule
from pgadmin.browser.utils import PGChildNodeView
@@ -51,7 +51,7 @@ class ExclusionConstraintModule(ConstraintTypeModule):
"""
_NODE_TYPE = 'exclusion_constraint'
_COLLECTION_LABEL = _("Exclusion Constraints")
_COLLECTION_LABEL = gettext("Exclusion Constraints")
def __init__(self, *args, **kwargs):
"""
@@ -272,7 +272,7 @@ class ExclusionConstraintView(PGChildNodeView):
return res
if len(res) == 0:
return gone(_(
return gone(gettext(
"""Could not find the exclusion constraint in the table."""
))
@@ -345,7 +345,7 @@ class ExclusionConstraintView(PGChildNodeView):
self._PROPERTIES_SQL]),
did=did,
tid=tid)
status, res = self.conn.execute_dict(SQL)
_, res = self.conn.execute_dict(SQL)
for row in res['rows']:
row['_type'] = self.node_type
@@ -374,10 +374,11 @@ class ExclusionConstraintView(PGChildNodeView):
self._NODES_SQL]),
tid=tid,
exid=exid)
status, rset = self.conn.execute_2darray(SQL)
_, rset = self.conn.execute_2darray(SQL)
if len(rset['rows']) == 0:
return gone(_("""Could not find the exclusion constraint."""))
return gone(
gettext("""Could not find the exclusion constraint."""))
res = self.blueprint.generate_browser_node(
rset['rows'][0]['oid'],
@@ -411,7 +412,7 @@ class ExclusionConstraintView(PGChildNodeView):
SQL = render_template("/".join([self.template_path,
self._NODES_SQL]),
tid=tid)
status, rset = self.conn.execute_2darray(SQL)
_, rset = self.conn.execute_2darray(SQL)
for row in rset['rows']:
res.append(
@@ -457,7 +458,7 @@ class ExclusionConstraintView(PGChildNodeView):
SQL = render_template("/".join([self.template_path,
self._NODES_SQL]),
tid=tid)
status, rset = self.conn.execute_2darray(SQL)
_, rset = self.conn.execute_2darray(SQL)
for row in rset['rows']:
res.append(
@@ -529,7 +530,7 @@ class ExclusionConstraintView(PGChildNodeView):
return make_json_response(
status=400,
success=0,
errormsg=_(
errormsg=gettext(
"Could not find required parameter ({})."
).format(arg_missing)
)
@@ -695,10 +696,10 @@ class ExclusionConstraintView(PGChildNodeView):
if not res['rows']:
return make_json_response(
success=0,
errormsg=_(
errormsg=gettext(
'Error: Object not found.'
),
info=_(
info=gettext(
'The specified exclusion constraint could not '
'be found.\n'
)
@@ -718,7 +719,7 @@ class ExclusionConstraintView(PGChildNodeView):
return make_json_response(
success=1,
info=_("Exclusion constraint dropped.")
info=gettext("Exclusion constraint dropped.")
)
except Exception as e:
@@ -756,7 +757,7 @@ class ExclusionConstraintView(PGChildNodeView):
data['schema'] = self.schema
data['table'] = self.table
try:
sql, name = \
sql, _ = \
exclusion_utils.get_sql(self.conn, data, did, tid, exid)
if not isinstance(sql, str):
return sql
@@ -795,7 +796,8 @@ class ExclusionConstraintView(PGChildNodeView):
if not status:
return rows
if len(rows) == 0:
return gone(_("Could not find the exclusion constraint."))
return gone(
gettext("Could not find the exclusion constraint."))
data = rows[0]
data['schema'] = self.schema
@@ -854,7 +856,8 @@ class ExclusionConstraintView(PGChildNodeView):
if not status:
return internal_server_error(errormsg=result)
if len(result['rows']) == 0:
return gone(_("Could not find the exclusion constraint."))
return gone(
gettext("Could not find the exclusion constraint."))
data = result['rows'][0]
name = data['name']
@@ -181,7 +181,7 @@ def get_exclusion_constraint_sql(conn, did, tid, data, template_path=None):
c['schema'] = data['schema']
c['table'] = data['name']
modified_sql, name = get_sql(conn, c, did, tid, c['oid'])
modified_sql, _ = get_sql(conn, c, did, tid, c['oid'])
sql.append(modified_sql.strip('\n'))
if 'added' in constraint:
@@ -189,7 +189,7 @@ def get_exclusion_constraint_sql(conn, did, tid, data, template_path=None):
c['schema'] = data['schema']
c['table'] = data['name']
add_sql, name = get_sql(conn, c, did, tid)
add_sql, _ = get_sql(conn, c, did, tid)
sql.append(add_sql.strip("\n"))
if len(sql) > 0:
Loaded 100 of 372 files, more files were not shown because too many files have changed in this diff. Show more