diff --git a/docs/en_US/images/index_columns.png b/docs/en_US/images/index_columns.png new file mode 100644 index 00000000000..d344be56895 Binary files /dev/null and b/docs/en_US/images/index_columns.png differ diff --git a/docs/en_US/images/index_definition.png b/docs/en_US/images/index_definition.png index 589a342b447..a524b5af4a8 100644 Binary files a/docs/en_US/images/index_definition.png and b/docs/en_US/images/index_definition.png differ diff --git a/docs/en_US/images/index_general.png b/docs/en_US/images/index_general.png index 133f05857cb..c7e7cb373be 100644 Binary files a/docs/en_US/images/index_general.png and b/docs/en_US/images/index_general.png differ diff --git a/docs/en_US/images/index_sql.png b/docs/en_US/images/index_sql.png index 970f6821a5b..d1a1e54f2bc 100644 Binary files a/docs/en_US/images/index_sql.png and b/docs/en_US/images/index_sql.png differ diff --git a/docs/en_US/index_dialog.rst b/docs/en_US/index_dialog.rst index 79c1e2e78ed..5635a3329ac 100644 --- a/docs/en_US/index_dialog.rst +++ b/docs/en_US/index_dialog.rst @@ -8,7 +8,7 @@ Use the *Index* dialog to create an index on a specified table or materialized view. The *Index* dialog organizes the development of a index through the following -dialog tabs: *General* and *Definition*. The *SQL* tab displays the SQL code +dialog tabs: *General*, *Definition*, and *Columns*. The *SQL* tab displays the SQL code generated by dialog selections. .. image:: images/index_general.png @@ -76,28 +76,36 @@ Use the fields in the *Definition* tab to define the index: expression limits the entries in the index to those rows that satisfy the constraint. -Use the context-sensitive fields in the *Columns* panel to specify which -column(s) the index queries. Click the *Add* icon (+) to add a column: +Click the *Columns* tab to continue. -* Use the drop-down listbox in *Column* field to select the name of the column - rom the table. +.. image:: images/index_columns.png + :alt: Index dialog columns tab + :align: center + +Use the fields in the *Columns* tab to specify which column(s) or expression(s) +the index queries. Use the *Is expression ?* switch to enable +expression sql input. Use the drop-down listbox next to *Column* +to select a column. Once the *Column* is selected or the *Expression* is +entered then click the *Add* icon (+) to provide details of the action on the +column/expression: + +* The *Col/Exp* field is populated with the selection made in the *Column* + drop-down listbox or the *Expression* entered. * If enabled, use the drop-down listbox to select an available *Operator class* to specify the type of action performed on the column. -* If enabled, move the *Sort order* switch to specify the sort order: +* If enabled, use the drop-down listbox to select *Sort order*: * Select *ASC* to specify an ascending sort order (the default); * Select *DESC* to specify a descending sort order. - -* If enabled, move the *Nulls* switch to specify the sort order of nulls: +* If enabled, use the drop-down listbox to select *Nulls*: * Select *First* to specify nulls sort before non-nulls; * Select *Last* to specify nulls sort after non-nulls (the default). - * Use the drop-down listbox in the *Collation* field to select a collation to use for the index. Use *Include columns* field to specify columns for *INCLUDE* clause of the -index. This option is available in Postgres 11 and later. +constraint. This option is available in Postgres 11 and later. Click the *SQL* tab to continue. diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js index 11377e3ffb0..b3a7bb10235 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js @@ -7,7 +7,7 @@ // ////////////////////////////////////////////////////////////// -import IndexSchema, { getColumnSchema } from './index.ui'; +import IndexSchema from './index.ui'; import { getNodeAjaxOptions, getNodeListByName } from 'pgbrowser/node_ajax'; import _ from 'lodash'; @@ -46,7 +46,7 @@ define('pgadmin.node.index', [ hasSQL: true, hasDepends: true, hasStatistics: true, - width: pgBrowser.stdW.md + 'px', + width: pgBrowser.stdW.lg + 'px', statsPrettifyFields: [gettext('Size'), gettext('Index size')], url_jump_after_node: 'schema', Init: function() { @@ -124,13 +124,14 @@ define('pgadmin.node.index', [ getSchema: (treeNodeInfo, itemNodeData) => { let nodeObj = pgAdmin.Browser.Nodes['index']; return new IndexSchema( - ()=>getColumnSchema(nodeObj, treeNodeInfo, itemNodeData), { tablespaceList: ()=>getNodeListByName('tablespace', treeNodeInfo, itemNodeData, {}, (m)=>{ return (m.label != 'pg_global'); }), amnameList : ()=>getNodeAjaxOptions('get_access_methods', nodeObj, treeNodeInfo, itemNodeData, {jumpAfterNode: 'schema'}), columnList: ()=>getNodeListByName('column', treeNodeInfo, itemNodeData, {}), + collationList: ()=>getNodeAjaxOptions('get_collations', nodeObj, treeNodeInfo, itemNodeData, {jumpAfterNode: 'schema'}), + opClassList: ()=>getNodeAjaxOptions('get_op_class', nodeObj, treeNodeInfo, itemNodeData, {jumpAfterNode: 'schema'}) }, { node_info: treeNodeInfo diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.ui.js index acb337851e0..464369d2784 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.ui.js @@ -9,65 +9,79 @@ import gettext from 'sources/gettext'; import BaseUISchema from 'sources/SchemaView/base_schema.ui'; -import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../../../static/js/node_ajax'; +import DataGridViewWithHeaderForm from '../../../../../../../../../static/js/helpers/DataGridViewWithHeaderForm'; import _ from 'lodash'; import { isEmptyString } from 'sources/validators'; import Notify from '../../../../../../../../../static/js/helpers/Notifier'; -export function getColumnSchema(nodeObj, treeNodeInfo, itemNodeData) { - return new ColumnSchema( - { - columnList: ()=>getNodeListByName('column', treeNodeInfo, itemNodeData, {}), - collationList: ()=>getNodeAjaxOptions('get_collations', nodeObj, treeNodeInfo, itemNodeData, {jumpAfterNode: 'schema'}), - opClassList: ()=>getNodeAjaxOptions('get_op_class', nodeObj, treeNodeInfo, itemNodeData, {jumpAfterNode: 'schema'}) - }, { - node_info: treeNodeInfo - } - ); + +function inSchema(node_info) { + return node_info && 'catalog' in node_info; } -export class ColumnSchema extends BaseUISchema { - constructor(fieldOptions = {}, nodeData = [], initValues={}) { +class IndexColHeaderSchema extends BaseUISchema { + constructor(columns) { + super({ + is_exp: true, + colname: undefined, + expression: undefined, + }); + + this.columns = columns; + } + + changeColumnOptions(columns) { + this.columns = columns; + } + + addDisabled(state) { + return !(state.is_exp ? state.expression : state.colname); + } + + /* Data to IndexColumnSchema will be added using the header form */ + getNewData(data) { + return this.indexColumnSchema.getNewData({ + is_exp: data.is_exp, + colname: data.is_exp ? data.expression : data.colname, + }); + } + + get baseFields() { + return [{ + id: 'is_exp', label: gettext('Is expression'), type:'switch', editable: false, + },{ + id: 'colname', label: gettext('Column'), type: 'select', editable: false, + options: this.columns, deps: ['is_exp'], + optionsReloadBasis: this.columns?.map ? _.join(this.columns.map((c)=>c.label), ',') : null, + optionsLoaded: (res)=>this.columnOptions=res, + disabled: (state)=>state.is_exp, node: 'column', + },{ + id: 'expression', label: gettext('Expression'), editable: false, deps: ['is_exp'], + type: 'sql', disabled: (state)=>!state.is_exp, + }]; + } +} + +class IndexColumnSchema extends BaseUISchema { + constructor(nodeData = {}) { super({ - name: null, - oid: undefined, - description: '', - is_sys_obj: false, colname: undefined, - collspcname: undefined, + is_exp: false, op_class: undefined, sort_order: false, nulls: false, - is_sort_nulls_applicable: true, - ...initValues + is_sort_nulls_applicable: false, + collspcname:undefined }); - this.fieldOptions = { - columnList: [], - collationList: [], - opClassList: [], - ...fieldOptions - }; this.node_info = { - ...nodeData.node_info + ...nodeData }; + this.operClassOptions = []; + this.collationOptions = []; this.op_class_types = []; } - get idAttribute() { - return 'oid'; - } - - // We will check if we are under schema node & in 'create' mode - inSchemaWithModelCheck(state) { - if(this.node_info && 'schema' in this.node_info) { - // We will disable control if it's in 'edit' mode - return !this.isNew(state); - } - return true; - } - setOpClassTypes(options) { - if(!options || (_.isArray(options) && options.length == 0)) return this.op_class_types; @@ -88,37 +102,52 @@ export class ColumnSchema extends BaseUISchema { return false; } + setOperClassOptions(options) { + this.operClassOptions = options; + } + + setCollationOptions(options) { + this.collationOptions = options; + } + + getNewData(data) { + return { + ...super.getNewData(data), + }; + } + + // We will check if we are under schema node & in 'create' mode + inSchemaWithModelCheck(state) { + if(this.node_info && 'schema' in this.node_info) { + // We will disable control if it's in 'edit' mode + return !this.isNew(state); + } + return true; + } + get baseFields() { - let columnSchemaObj = this; + let obj = this; return [ { - id: 'colname', label: gettext('Column'), - type: 'select', cell: 'select', noEmpty: true, - disabled: () => inSchema(columnSchemaObj.node_info), - editable: function (state) { - return !columnSchemaObj.inSchemaWithModelCheck(state); - }, - options: columnSchemaObj.fieldOptions.columnList, - node: 'column', + id: 'is_exp', label: '', type:'', cell: '', editable: false, width: 20, + disableResizing: true, + controlProps: { + formatter: { + fromRaw: function (rawValue) { + return rawValue ? 'E' : 'C'; + }, + } + }, visible: false, },{ - id: 'collspcname', label: gettext('Collation'), - type: 'select', - cell: 'select', - disabled: () => inSchema(columnSchemaObj.node_info), - editable: function (state) { - return !columnSchemaObj.inSchemaWithModelCheck(state); - }, - options: columnSchemaObj.fieldOptions.collationList, - node: 'index', - url_jump_after_node: 'schema', + id: 'colname', label: gettext('Col/Exp'), type:'', editable: false, + cell:'', width: 100, },{ - id: 'op_class', label: gettext('Operator class'), - tags: true, type: 'select', + id: 'op_class', label: gettext('Operator class'), tags: true, type: 'select', cell: () => { return { cell: 'select', - options: columnSchemaObj.fieldOptions.opClassList, - optionsLoaded: (options)=>{columnSchemaObj.setOpClassTypes(options);}, + options: obj.operClassOptions, + optionsLoaded: (options)=>{obj.setOpClassTypes(options);}, controlProps: { allowClear: true, filter: (options) => { @@ -126,12 +155,12 @@ export class ColumnSchema extends BaseUISchema { * to access method selected by user if not selected * send btree related op_class options */ - let amname = columnSchemaObj._top?._sessData ? columnSchemaObj._top?._sessData.amname : columnSchemaObj._top?._origData.amname; + let amname = obj._top?._sessData ? obj._top?._sessData.amname : obj._top?._origData.amname; if(_.isUndefined(amname)) return options; - _.each(this.op_class_types, function(v, k) { + _.each(obj.op_class_types, function(v, k) { if(amname === k) { options = v; } @@ -142,14 +171,13 @@ export class ColumnSchema extends BaseUISchema { }; }, editable: function (state) { - return !columnSchemaObj.inSchemaWithModelCheck(state); + return !obj.inSchemaWithModelCheck(state); }, node: 'index', url_jump_after_node: 'schema', deps: ['amname'], },{ - id: 'sort_order', label: gettext('Sort order'), - type: 'select', cell: 'select', + id: 'sort_order', label: gettext('Sort order'), type: 'select', cell: 'select', options: [ {label: 'ASC', value: false}, {label: 'DESC', value: true}, @@ -174,22 +202,38 @@ export class ColumnSchema extends BaseUISchema { } }, editable: function(state) { - return columnSchemaObj.isEditable(state); + return obj.isEditable(state); }, deps: ['amname'], },{ - id: 'nulls', label: gettext('NULLs'), - editable: function(state) { - return columnSchemaObj.isEditable(state); - }, - deps: ['amname', 'sort_order'], - type:'select', cell: 'select', + id: 'nulls', label: gettext('NULLs'), type:'select', cell: 'select', options: [ {label: 'FIRST', value: true}, {label: 'LAST', value: false}, ], controlProps: {allowClear: false}, width: 110, disableResizing: true, - }, + editable: function(state) { + return obj.isEditable(state); + }, + deps: ['amname', 'sort_order'], + },{ + id: 'collspcname', label: gettext('Collation'), + type: 'select', + cell: 'select', + disabled: () => inSchema(obj.node_info), + editable: function (state) { + return !obj.inSchemaWithModelCheck(state); + }, + options: obj.collationOptions, + node: 'index', + url_jump_after_node: 'schema', + },{ + id: 'statistics', label: gettext('Statistics'), + type: 'int', cell: 'int', disabled: (state)=> { + return (!state.is_exp || obj.node_info.server.version < 110000); + }, + min: -1, max: 10000, mode: ['edit','properties'], + } ]; } } @@ -298,12 +342,8 @@ export class WithSchema extends BaseUISchema { } } -function inSchema(node_info) { - return node_info && 'catalog' in node_info; -} - export default class IndexSchema extends BaseUISchema { - constructor(columnSchema, fieldOptions = {}, nodeData = [], initValues={}) { + constructor(fieldOptions = {}, nodeData = {}, initValues={}) { super({ name: undefined, oid: undefined, @@ -322,12 +362,16 @@ export default class IndexSchema extends BaseUISchema { tablespaceList: [], amnameList: [], columnList: [], + opClassList: [], + collationList: [], ...fieldOptions }; this.node_info = { ...nodeData.node_info }; - this.getColumnSchema = columnSchema; + this.indexHeaderSchema = new IndexColHeaderSchema(this.fieldOptions.columnList); + this.indexColumnSchema = new IndexColumnSchema(this.node_info); + this.indexHeaderSchema.indexColumnSchema = this.indexColumnSchema; this.withSchema = new WithSchema(this.node_info); } @@ -335,6 +379,16 @@ export default class IndexSchema extends BaseUISchema { return 'oid'; } + initialise() { + this.indexColumnSchema.setOperClassOptions(this.fieldOptions.opClassList); + this.indexColumnSchema.setCollationOptions(this.fieldOptions.collationList); + } + + changeColumnOptions(columns) { + this.indexHeaderSchema.changeColumnOptions(columns); + this.fieldOptions.columns = columns; + } + getColumns() { return { type: 'select', @@ -412,16 +466,15 @@ export default class IndexSchema extends BaseUISchema { }; }, deferredDepChange: (state, source, topState, actionObj) => { - const setColumns = (resolve)=>{ resolve(()=>{ - state.columns.splice(0, state.columns.length); + state.columns.splice(0, state.columns?.length); return { columns: state.columns, }; }); }; - if((state.amname != actionObj.oldState.amname) && state.columns.length > 0) { + if((state.amname != actionObj?.oldState.amname) && state.columns?.length > 0) { return new Promise((resolve)=>{ Notify.confirm( gettext('Warning'), @@ -431,7 +484,7 @@ export default class IndexSchema extends BaseUISchema { }, function() { resolve(()=>{ - state.amname = actionObj.oldState.amname; + state.amname = actionObj?.oldState.amname; return { amname: state.amname, }; @@ -443,22 +496,6 @@ export default class IndexSchema extends BaseUISchema { return Promise.resolve(()=>{/*This is intentional (SonarQube)*/}); } }, - }, - { - id: 'include', label: gettext('Include columns'), - group: gettext('Definition'), - editable: false, canDelete: true, canAdd: true, mode: ['properties'], - disabled: () => inSchema(indexSchemaObj.node_info), - readonly: function (state) { - return !indexSchemaObj.isNew(state); - }, - type: () => { - return indexSchemaObj.getColumns(); - }, - visible: function() { - return indexSchemaObj.isVisible(); - }, - node:'column', },{ type: 'nested-fieldset', label: gettext('With'), group: gettext('Definition'), schema: this.withSchema, @@ -529,29 +566,36 @@ export default class IndexSchema extends BaseUISchema { }, mode: ['create', 'edit'], control: 'sql-field', visible: true, group: gettext('Definition'), - }, { - id: 'columns', label: gettext('Columns'), type: 'collection', deps: ['amname'], - group: gettext('Definition'), schema: indexSchemaObj.getColumnSchema(), - mode: ['edit', 'create', 'properties'], - canAdd: function(state) { - // We will disable it if it's in 'edit' mode - return indexSchemaObj.isNew(state); - }, - canEdit: false, - canDelete: function(state) { - // We will disable it if it's in 'edit' mode + },{ + id: 'columns', label: gettext('Columns/Expressions'), + group: gettext('Columns'), type: 'collection', + mode: ['create', 'edit', 'properties'], + editable: false, schema: this.indexColumnSchema, + headerSchema: this.indexHeaderSchema, headerVisible: (state)=>indexSchemaObj.isNew(state), + CustomControl: DataGridViewWithHeaderForm, + uniqueCol: ['colname'], + canAdd: false, canDelete: function(state) { + // We can't update columns of existing return indexSchemaObj.isNew(state); - }, - uniqueCol : ['colname'], - columns: ['colname', 'op_class', 'sort_order', 'nulls', 'collspcname'] - }, { + }, cell: ()=>({ + cell: '', + controlProps: { + formatter: { + fromRaw: (rawValue)=>{ + return _.map(rawValue || [], 'colname').join(', '); + }, + } + }, + width: 245, + }) + },{ id: 'include', label: gettext('Include columns'), type: () => { return indexSchemaObj.getColumns(); }, - group: gettext('Definition'), + group: gettext('Columns'), editable: false, - canDelete: true, canAdd: true, mode: ['edit', 'create'], + canDelete: true, canAdd: true, mode: ['edit', 'create', 'properties'], disabled: () => inSchema(indexSchemaObj.node_info), readonly: function (state) { return !indexSchemaObj.isNew(state); @@ -590,7 +634,7 @@ export default class IndexSchema extends BaseUISchema { // Checks if columns is empty let cols = state.columns; if(_.isArray(cols) && cols.length == 0){ - msg = gettext('You must specify at least one column.'); + msg = gettext('You must specify at least one column/expression.'); setError('columns', msg); return true; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_expr_statistics.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_expr_statistics.sql new file mode 100644 index 00000000000..f7c25eae1f2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_expr_statistics.sql @@ -0,0 +1,14 @@ +-- Index: Idx3_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx3_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx3_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, lower(name) COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx3_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_name_fillfactor_comment.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_name_fillfactor_comment.sql new file mode 100644 index 00000000000..89a4e57b2ce --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_name_fillfactor_comment.sql @@ -0,0 +1,16 @@ +-- Index: Idx1_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx1_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx1_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default; + +ALTER TABLE IF EXISTS public.test_table_for_indexes + CLUSTER ON "Idx1_$%{}[]()&*^!@""'`\/#"; + +COMMENT ON INDEX public."Idx1_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_reset_fillfactor_cluster.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_reset_fillfactor_cluster.sql new file mode 100644 index 00000000000..d8c7cd5c5a3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/alter_reset_fillfactor_cluster.sql @@ -0,0 +1,12 @@ +-- Index: Idx1_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx1_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx1_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) + TABLESPACE pg_default; + +COMMENT ON INDEX public."Idx1_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_first.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_first.sql new file mode 100644 index 00000000000..4b2dab72fe2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_first.sql @@ -0,0 +1,14 @@ +-- Index: Idx_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS FIRST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_first_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_first_msql.sql new file mode 100644 index 00000000000..26260514194 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_first_msql.sql @@ -0,0 +1,10 @@ +CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS FIRST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_last.sql new file mode 100644 index 00000000000..7d49e7c5fa8 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_last.sql @@ -0,0 +1,14 @@ +-- Index: Idx_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_last_msql.sql new file mode 100644 index 00000000000..7b00025c24a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_asc_null_last_msql.sql @@ -0,0 +1,10 @@ +CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_first.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_first.sql new file mode 100644 index 00000000000..d7f87ff1081 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_first.sql @@ -0,0 +1,9 @@ +-- Index: Idx_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) + TABLESPACE pg_default; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_first_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_first_msql.sql new file mode 100644 index 00000000000..7492543e267 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_first_msql.sql @@ -0,0 +1,5 @@ +CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) + TABLESPACE pg_default; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_last.sql new file mode 100644 index 00000000000..1aed1dd4a47 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_last.sql @@ -0,0 +1,14 @@ +-- Index: Idx_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id DESC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS LAST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_last_msql.sql new file mode 100644 index 00000000000..c72fd51c634 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_desc_null_last_msql.sql @@ -0,0 +1,10 @@ +CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id DESC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS LAST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_expr_asc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_expr_asc_null_last.sql new file mode 100644 index 00000000000..f7c25eae1f2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_expr_asc_null_last.sql @@ -0,0 +1,14 @@ +-- Index: Idx3_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx3_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx3_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, lower(name) COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx3_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_expr_asc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_expr_asc_null_last_msql.sql new file mode 100644 index 00000000000..ada43a67b06 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/create_btree_expr_asc_null_last_msql.sql @@ -0,0 +1,10 @@ +CREATE UNIQUE INDEX "Idx3_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, (lower(name)) COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx3_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/test_indexes.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/test_indexes.json new file mode 100644 index 00000000000..12182d16a14 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/11_plus/test_indexes.json @@ -0,0 +1,364 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create Table for indexes", + "endpoint": "NODE-table.obj", + "sql_endpoint": "NODE-table.sql_id", + "data": { + "name": "test_table_for_indexes", + "columns": [{ + "name": "id", + "cltype": "bigint", + "is_primary_key": true + }, { + "name": "name", + "cltype": "text" + }], + "is_partitioned": false, + "spcname": "pg_default", + "schema": "public" + }, + "store_object_id": true + }, + { + "type": "create", + "name": "Create btree index with ASC and NULLS LAST -- 11 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "include": ["name", "id"], + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }, { + "colname":"name", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }], + "description":"Test Comment", + "fillfactor":"10", + "indisunique":true, + "indisclustered":false, + "isconcurrent":false, + "indconstraint":"id < 100" + }, + "expected_sql_file": "create_btree_asc_null_last.sql", + "expected_msql_file": "create_btree_asc_null_last_msql.sql" + }, + { + "type": "delete", + "name": "Drop index -- 11 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx_$%{}[]()&*^!@\"'`\\/#" + } + }, + { + "type": "create", + "name": "Create btree index with ASC and NULLS FIRST -- 11 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "include": ["name", "id"], + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":false, + "nulls":true, + "is_sort_nulls_applicable":true + }, { + "colname":"name", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":true, + "is_sort_nulls_applicable":true + }], + "description":"Test Comment", + "fillfactor":"10", + "indisunique":true, + "indisclustered":false, + "isconcurrent":false, + "indconstraint":"id < 100" + }, + "expected_sql_file": "create_btree_asc_null_first.sql", + "expected_msql_file": "create_btree_asc_null_first_msql.sql" + }, + { + "type": "delete", + "name": "Drop index -- 11 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx_$%{}[]()&*^!@\"'`\\/#" + } + }, + { + "type": "create", + "name": "Create btree index with DESC and NULLS LAST -- 11 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "include": ["name", "id"], + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":true, + "nulls":false, + "is_sort_nulls_applicable":true + }, { + "colname":"name", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":true, + "nulls":false, + "is_sort_nulls_applicable":true + }], + "description":"Test Comment", + "fillfactor":"10", + "indisunique":true, + "indisclustered":false, + "isconcurrent":false, + "indconstraint":"id < 100" + }, + "expected_sql_file": "create_btree_desc_null_last.sql", + "expected_msql_file": "create_btree_desc_null_last_msql.sql" + }, + { + "type": "delete", + "name": "Drop index -- 11 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx_$%{}[]()&*^!@\"'`\\/#" + } + }, + { + "type": "create", + "name": "Create btree index with DESC and NULLS FIRST -- 11 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "include": ["name", "id"], + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":true, + "nulls":true, + "is_sort_nulls_applicable":true + }, { + "colname":"name", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":true, + "nulls":true, + "is_sort_nulls_applicable":true + }], + "indisunique":true, + "indisclustered":false, + "isconcurrent":false + }, + "expected_sql_file": "create_btree_desc_null_first.sql", + "expected_msql_file": "create_btree_desc_null_first_msql.sql" + }, + { + "type": "alter", + "name": "Alter index name, fill factor, comment and clustered -- 11 Plus", + "endpoint": "NODE-index.obj_id", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql_id", + "data": { + "name": "Idx1_$%{}[]()&*^!@\"'`\\/#", + "description":"Test Comment", + "fillfactor":"10", + "indisclustered":true + }, + "expected_sql_file": "alter_name_fillfactor_comment.sql", + "expected_msql_file": "alter_name_fillfactor_comment_msql.sql" + }, + { + "type": "alter", + "name": "Alter reset fill factor and cluster -- 11 Plus", + "endpoint": "NODE-index.obj_id", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql_id", + "data": { + "fillfactor": "", + "indisclustered": false + }, + "expected_sql_file": "alter_reset_fillfactor_cluster.sql", + "expected_msql_file": "alter_reset_fillfactor_cluster_msql.sql" + }, + { + "type": "delete", + "name": "Drop index -- 11 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx1_$%{}[]()&*^!@\"'`\\/#" + } + }, + { + "type": "create", + "name": "Create btree index with expression and ASC and NULLS LAST -- 11 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx3_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "include": ["name", "id"], + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }, { + "is_exp": true, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }], + "description":"Test Comment", + "fillfactor":"10", + "indisunique":true, + "indisclustered":false, + "isconcurrent":false, + "indconstraint":"id < 100" + }, + "expected_sql_file": "create_btree_expr_asc_null_last.sql", + "expected_msql_file": "create_btree_expr_asc_null_last_msql.sql" + }, + { + "type": "alter", + "name": "Alter index statistics of expression -- 11 Plus", + "endpoint": "NODE-index.obj_id", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#", + "columns":{ + "changed": [{ + "is_exp": true, + "col_num": 2, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true, + "statistics": 1000 + }] + } + }, + "expected_sql_file": "alter_expr_statistics.sql", + "expected_msql_file": "alter_expr_statistics_msql.sql" + }, + { + "type": "delete", + "name": "Drop index -- 11 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#" + } + }, + { + "type": "create", + "name": "Create hash index -- 11 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name": "Idx_$%{}[]()&*^!@\"'`\\/#", + "spcname": "pg_default", + "amname": "hash", + "columns": [{ + "colname": "id", + "collspcname": "", + "op_class": "", + "sort_order": false, + "nulls": false, + "is_sort_nulls_applicable": false + }], + "indisunique": false, + "indisclustered": false, + "isconcurrent": false + }, + "expected_sql_file": "create_hash_index.sql", + "expected_msql_file": "create_hash_index_msql.sql" + }, + { + "type": "delete", + "name": "Drop hash index -- 11 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx_$%{}[]()&*^!@\"'`\\/#" + } + }, + { + "type": "delete", + "name": "Drop Table", + "endpoint": "NODE-table.delete_id", + "data": { + "name": "test_table_for_indexes" + } + }, + { + "type": "create", + "name": "Create unnamed hash index -- 11 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "spcname": "pg_default", + "amname": "hash", + "columns": [{ + "colname": "id", + "collspcname": "", + "op_class": "", + "sort_order": false, + "nulls": false, + "is_sort_nulls_applicable": false + }], + "indisunique": false, + "isconcurrent": false + }, + "expected_msql_file": "create_unnamed_hash_index_msql.sql" + }, + { + "type": "delete", + "name": "Drop hash index -- 11 Plus", + "endpoint": "NODE-index.delete_id" + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first.sql index 79be5b2fd59..7a707969d2e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS FIRST) + INCLUDE(name, id) WITH (fillfactor=10, deduplicate_items=False) TABLESPACE pg_default WHERE id < 100; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first_msql.sql index 1ce641cdd04..a1547386a2b 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_first_msql.sql @@ -1,6 +1,7 @@ CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS FIRST) + INCLUDE(name, id) WITH (fillfactor=10, deduplicate_items=False) TABLESPACE pg_default WHERE id < 100; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last.sql index 0f94e381c6b..b4b7b6ec757 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) WITH (fillfactor=10, deduplicate_items=False) TABLESPACE pg_default WHERE id < 100; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last_msql.sql index 27b27c31fbb..210314f3388 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_asc_null_last_msql.sql @@ -1,6 +1,7 @@ CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) WITH (fillfactor=10, deduplicate_items=False) TABLESPACE pg_default WHERE id < 100; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last.sql index 5a3d31b5e3d..f0faed97b8f 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS LAST) + INCLUDE(name, id) WITH (fillfactor=10, deduplicate_items=False) TABLESPACE pg_default WHERE id < 100; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last_msql.sql index 30119b40de8..61e5e8f1650 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/create_btree_desc_null_last_msql.sql @@ -1,6 +1,7 @@ CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS LAST) + INCLUDE(name, id) WITH (fillfactor=10, deduplicate_items=False) TABLESPACE pg_default WHERE id < 100; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/test_indexes.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/test_indexes.json index 5b598f5a382..31e555a670f 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/test_indexes.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/13_plus/test_indexes.json @@ -23,7 +23,7 @@ }, { "type": "create", - "name": "Create btree index with ASC and NULLS LAST -- 15 Plus", + "name": "Create btree index with ASC and NULLS LAST -- 13 Plus", "endpoint": "NODE-index.obj", "sql_endpoint": "NODE-index.sql_id", "msql_endpoint": "NODE-index.msql", @@ -31,6 +31,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -60,7 +61,7 @@ }, { "type": "delete", - "name": "Drop index", + "name": "Drop index -- 13 Plus", "endpoint": "NODE-index.delete_id", "data": { "name": "Idx_$%{}[]()&*^!@\"'`\\/#" @@ -76,6 +77,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -105,7 +107,7 @@ }, { "type": "delete", - "name": "Drop index -- 15 Plus", + "name": "Drop index -- 13 Plus", "endpoint": "NODE-index.delete_id", "data": { "name": "Idx_$%{}[]()&*^!@\"'`\\/#" @@ -113,7 +115,7 @@ }, { "type": "create", - "name": "Create btree index with DESC and NULLS LAST -- 15 Plus", + "name": "Create btree index with DESC and NULLS LAST -- 13 Plus", "endpoint": "NODE-index.obj", "sql_endpoint": "NODE-index.sql_id", "msql_endpoint": "NODE-index.msql", @@ -121,6 +123,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -150,7 +153,7 @@ }, { "type": "delete", - "name": "Drop index -- 15 Plus", + "name": "Drop index -- 13 Plus", "endpoint": "NODE-index.delete_id", "data": { "name": "Idx_$%{}[]()&*^!@\"'`\\/#" @@ -158,7 +161,7 @@ }, { "type": "create", - "name": "Create btree index with DESC and NULLS FIRST -- 15 Plus", + "name": "Create btree index with DESC and NULLS FIRST -- 13 Plus", "endpoint": "NODE-index.obj", "sql_endpoint": "NODE-index.sql_id", "msql_endpoint": "NODE-index.msql", @@ -166,6 +169,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -191,7 +195,7 @@ }, { "type": "alter", - "name": "Alter index name, fill factor, comment and clustered -- 15 Plus", + "name": "Alter index name, fill factor, comment and clustered -- 13 Plus", "endpoint": "NODE-index.obj_id", "sql_endpoint": "NODE-index.sql_id", "msql_endpoint": "NODE-index.msql_id", @@ -206,7 +210,7 @@ }, { "type": "alter", - "name": "Alter reset fill factor and cluster -- 15 Plus", + "name": "Alter reset fill factor and cluster -- 13 Plus", "endpoint": "NODE-index.obj_id", "sql_endpoint": "NODE-index.sql_id", "msql_endpoint": "NODE-index.msql_id", @@ -219,15 +223,85 @@ }, { "type": "delete", - "name": "Drop index -- 15 Plus", + "name": "Drop index -- 13 Plus", "endpoint": "NODE-index.delete_id", "data": { "name": "Idx1_$%{}[]()&*^!@\"'`\\/#" } }, + { + "type": "create", + "name": "Create btree index with expression and ASC and NULLS LAST -- 13 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx3_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "include": ["name", "id"], + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }, { + "is_exp": true, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }], + "description":"Test Comment", + "fillfactor":"10", + "indisunique":true, + "indisclustered":false, + "isconcurrent":false, + "indconstraint":"id < 100" + }, + "expected_sql_file": "create_btree_expr_asc_null_last.sql", + "expected_msql_file": "create_btree_expr_asc_null_last_msql.sql" + }, + { + "type": "alter", + "name": "Alter index statistics of expression -- 13 Plus", + "endpoint": "NODE-index.obj_id", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#", + "columns":{ + "changed": [{ + "is_exp": true, + "col_num": 2, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true, + "statistics": 1000 + }] + } + }, + "expected_sql_file": "alter_expr_statistics.sql", + "expected_msql_file": "alter_expr_statistics_msql.sql" + }, + { + "type": "delete", + "name": "Drop index -- 13 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#" + } + }, { "type": "create", - "name": "Create hash index -- 15 Plus", + "name": "Create hash index -- 13 Plus", "endpoint": "NODE-index.obj", "sql_endpoint": "NODE-index.sql_id", "msql_endpoint": "NODE-index.msql", @@ -252,7 +326,7 @@ }, { "type": "delete", - "name": "Drop hash index -- 15 Plus", + "name": "Drop hash index -- 13 Plus", "endpoint": "NODE-index.delete_id", "data": { "name": "Idx_$%{}[]()&*^!@\"'`\\/#" @@ -268,7 +342,7 @@ }, { "type": "create", - "name": "Create unnamed hash index -- 15 Plus", + "name": "Create unnamed hash index -- 13 Plus", "endpoint": "NODE-index.obj", "sql_endpoint": "NODE-index.sql_id", "msql_endpoint": "NODE-index.msql", @@ -290,9 +364,8 @@ }, { "type": "delete", - "name": "Drop hash index -- 15 Plus", + "name": "Drop hash index -- 13 Plus", "endpoint": "NODE-index.delete_id" } ] } - \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_name_fillfactor_comment.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_name_fillfactor_comment.sql index de7fef907fc..4260ca9569c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_name_fillfactor_comment.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_name_fillfactor_comment.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx1_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) NULLS NOT DISTINCT WITH (fillfactor=10) TABLESPACE pg_default; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_reset_fillfactor_cluster.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_reset_fillfactor_cluster.sql index 8b69df72b00..f429e8358d2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_reset_fillfactor_cluster.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/alter_reset_fillfactor_cluster.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx1_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) NULLS NOT DISTINCT TABLESPACE pg_default; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first.sql index 9bfa43f7096..802e195002b 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS FIRST) + INCLUDE(name, id) NULLS NOT DISTINCT WITH (fillfactor=10) TABLESPACE pg_default diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first_msql.sql index 0854aa63624..05b9ec8d72f 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_first_msql.sql @@ -1,6 +1,7 @@ CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS FIRST) + INCLUDE(name, id) NULLS NOT DISTINCT WITH (fillfactor=10) TABLESPACE pg_default diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last.sql index 5ac5624e70b..2cf9c9e3a37 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) NULLS NOT DISTINCT WITH (fillfactor=10) TABLESPACE pg_default diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last_msql.sql index 44727d7b9c2..53f42abb091 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_asc_null_last_msql.sql @@ -1,6 +1,7 @@ CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id ASC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + INCLUDE(name, id) NULLS NOT DISTINCT WITH (fillfactor=10) TABLESPACE pg_default diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first.sql index bde3398ba5c..6f6c8cd77fc 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first.sql @@ -5,5 +5,6 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) NULLS NOT DISTINCT TABLESPACE pg_default; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first_msql.sql index 5859ffef20f..9660ac05a5f 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_first_msql.sql @@ -1,5 +1,6 @@ CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS FIRST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS FIRST) + INCLUDE(name, id) NULLS NOT DISTINCT TABLESPACE pg_default; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last.sql index 50ea618736f..56ed7687856 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last.sql @@ -5,6 +5,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS LAST) + INCLUDE(name, id) NULLS NOT DISTINCT WITH (fillfactor=10) TABLESPACE pg_default diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last_msql.sql index 1afc831eeaa..9eec0a7ff26 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/create_btree_desc_null_last_msql.sql @@ -1,6 +1,7 @@ CREATE UNIQUE INDEX "Idx_$%{}[]()&*^!@""'`\/#" ON public.test_table_for_indexes USING btree (id DESC NULLS LAST, name COLLATE pg_catalog."POSIX" text_pattern_ops DESC NULLS LAST) + INCLUDE(name, id) NULLS NOT DISTINCT WITH (fillfactor=10) TABLESPACE pg_default diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/test_indexes.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/test_indexes.json index dc2b3b0a711..a15d5dcfe0e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/test_indexes.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/15_plus/test_indexes.json @@ -31,6 +31,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -75,6 +76,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -119,6 +121,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -163,6 +166,7 @@ "name":"Idx_$%{}[]()&*^!@\"'`\\/#", "spcname":"pg_default", "amname":"btree", + "include": ["name", "id"], "columns":[{ "colname":"id", "collspcname":"", @@ -222,6 +226,76 @@ "name": "Idx1_$%{}[]()&*^!@\"'`\\/#" } }, + { + "type": "create", + "name": "Create btree index with expression and ASC and NULLS LAST -- 15 Plus", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx3_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "include": ["name", "id"], + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }, { + "is_exp": true, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }], + "description":"Test Comment", + "fillfactor":"10", + "indisunique":true, + "indisclustered":false, + "isconcurrent":false, + "indconstraint":"id < 100" + }, + "expected_sql_file": "create_btree_expr_asc_null_last.sql", + "expected_msql_file": "create_btree_expr_asc_null_last_msql.sql" + }, + { + "type": "alter", + "name": "Alter index statistics of expression -- 15 Plus", + "endpoint": "NODE-index.obj_id", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#", + "columns":{ + "changed": [{ + "is_exp": true, + "col_num": 2, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true, + "statistics": 1000 + }] + } + }, + "expected_sql_file": "alter_expr_statistics.sql", + "expected_msql_file": "alter_expr_statistics_msql.sql" + }, + { + "type": "delete", + "name": "Drop index -- 15 Plus", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#" + } + }, { "type": "create", "name": "Create hash index -- 15 Plus", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/alter_expr_statistics.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/alter_expr_statistics.sql new file mode 100644 index 00000000000..51c1afec95b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/alter_expr_statistics.sql @@ -0,0 +1,13 @@ +-- Index: Idx3_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx3_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx3_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, lower(name) COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx3_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/alter_expr_statistics_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/alter_expr_statistics_msql.sql new file mode 100644 index 00000000000..2f60ff734b3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/alter_expr_statistics_msql.sql @@ -0,0 +1,2 @@ +ALTER INDEX IF EXISTS public."Idx3_$%{}[]()&*^!@""'`\/#" + ALTER COLUMN 2 SET STATISTICS 1000; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/create_btree_expr_asc_null_last.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/create_btree_expr_asc_null_last.sql new file mode 100644 index 00000000000..51c1afec95b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/create_btree_expr_asc_null_last.sql @@ -0,0 +1,13 @@ +-- Index: Idx3_$%{}[]()&*^!@"'`\/# + +-- DROP INDEX IF EXISTS public."Idx3_$%{}[]()&*^!@""'`\/#"; + +CREATE UNIQUE INDEX IF NOT EXISTS "Idx3_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, lower(name) COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx3_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/create_btree_expr_asc_null_last_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/create_btree_expr_asc_null_last_msql.sql new file mode 100644 index 00000000000..53c401357a6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/create_btree_expr_asc_null_last_msql.sql @@ -0,0 +1,9 @@ +CREATE UNIQUE INDEX "Idx3_$%{}[]()&*^!@""'`\/#" + ON public.test_table_for_indexes USING btree + (id ASC NULLS LAST, (lower(name)) COLLATE pg_catalog."POSIX" text_pattern_ops ASC NULLS LAST) + WITH (fillfactor=10) + TABLESPACE pg_default + WHERE id < 100; + +COMMENT ON INDEX public."Idx3_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/test_indexes.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/test_indexes.json index a85e2804a08..f8279fbf2aa 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/test_indexes.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/default/test_indexes.json @@ -150,6 +150,75 @@ "name": "Idx_$%{}[]()&*^!@\"'`\\/#" } }, + { + "type": "create", + "name": "Create btree index with expression and ASC and NULLS LAST", + "endpoint": "NODE-index.obj", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql", + "data": { + "name":"Idx3_$%{}[]()&*^!@\"'`\\/#", + "spcname":"pg_default", + "amname":"btree", + "columns":[{ + "colname":"id", + "collspcname":"", + "op_class":"", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }, { + "is_exp": true, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true + }], + "description":"Test Comment", + "fillfactor":"10", + "indisunique":true, + "indisclustered":false, + "isconcurrent":false, + "indconstraint":"id < 100" + }, + "expected_sql_file": "create_btree_expr_asc_null_last.sql", + "expected_msql_file": "create_btree_expr_asc_null_last_msql.sql" + }, + { + "type": "alter", + "name": "Alter index statistics of expression", + "endpoint": "NODE-index.obj_id", + "sql_endpoint": "NODE-index.sql_id", + "msql_endpoint": "NODE-index.msql_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#", + "columns":{ + "changed": [{ + "is_exp": true, + "col_num": 2, + "colname":"lower(name)", + "collspcname":"pg_catalog.\"POSIX\"", + "op_class":"text_pattern_ops", + "sort_order":false, + "nulls":false, + "is_sort_nulls_applicable":true, + "statistics": 1000 + }] + } + }, + "expected_sql_file": "alter_expr_statistics.sql", + "expected_msql_file": "alter_expr_statistics_msql.sql" + }, + { + "type": "delete", + "name": "Drop index", + "endpoint": "NODE-index.delete_id", + "data": { + "name": "Idx3_$%{}[]()&*^!@\"'`\\/#" + } + }, { "type": "create", "name": "Create btree index with DESC and NULLS FIRST", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/index_test_data.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/index_test_data.json index 27ab3066412..58ec65e3240 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/index_test_data.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/index_test_data.json @@ -79,7 +79,7 @@ } }, { - "name": "Create index: With valid data mumtiple.", + "name": "Create index: With valid data with multiple columns.", "is_positive_test": true, "inventory_data": {}, "test_data": { @@ -110,6 +110,39 @@ "test_result_data": {} } }, + { + "name": "Create index: With valid data with multiple columns and expressions.", + "is_positive_test": true, + "inventory_data": {}, + "test_data": { + "name": "test_index_add", + "spcname": "pg_default", + "amname": "btree", + "columns": [ + { + "is_exp": true, + "colname": "lower(name)", + "sort_order": false, + "nulls": false + }, + { + "colname": "id", + "sort_order": true, + "nulls": false + } + ], + "include": [ + "name" + ] + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, { "name": "Create index: With invalid data - No column name.", "is_positive_test": false, @@ -507,6 +540,24 @@ }, "is_list": false }, + { + "name": "Put index statistics : With existing index id.", + "is_positive_test": true, + "update_statistics": true, + "inventory_data": { + }, + "test_data": { + "columns": "PLACE_HOLDER" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, { "name": "Put index : With existing index id while server is down.", "is_positive_test": false, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/test_indexes_put.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/test_indexes_put.py index 6609806f204..56e4018d5bb 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/test_indexes_put.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/test_indexes_put.py @@ -57,6 +57,8 @@ def setUp(self): self.schema_name, self.table_name, self.column_name) + if hasattr(self, "update_statistics"): + self.column_name = "lower(%s)" % self.column_name self.index_name = "test_index_delete_%s" % (str(uuid.uuid4())[1:8]) self.index_id = indexes_utils.create_index(self.server, self.db_name, self.schema_name, @@ -70,6 +72,15 @@ def runTest(self): self.index_name) if not index_response: raise Exception("Could not find the index to update.") + + if hasattr(self, "update_statistics"): + index_details = indexes_utils.api_get_index(self, self.index_id) + self.test_data['columns'] = {'changed': [ + {"is_exp": True, "col_num": + index_details.json['columns'][0]['col_num'], + "colname": self.column_name, + "nulls": False, "sort_order": False, + "statistics": "1000"}]} self.data = self.test_data self.data['oid'] = self.index_id diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/utils.py index c2e01c4b60b..9d1017c9911 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/utils.py @@ -117,6 +117,9 @@ def get_column_details(conn, idx, data, mode='properties', template_path=None): row['attdef'].strip('"'), 'collspcname': row['collnspname'], 'op_class': row['opcname'], + 'col_num': row['attnum'], + 'is_exp': row['is_exp'], + 'statistics': row['statistics'] } # ASC/DESC and NULLS works only with btree indexes @@ -245,6 +248,12 @@ def get_sql(conn, **kwargs): raise ObjectGone(_('Could not find the index in the table.')) old_data = dict(res['rows'][0]) + + # Add column details for current index + old_data = get_column_details(conn, idx, old_data) + + update_column_data, update_column = \ + _get_column_details_to_update(old_data, data) # Remove opening and closing bracket as we already have in jinja # template. if 'using' in old_data and old_data['using'] is not None and \ @@ -263,7 +272,8 @@ def get_sql(conn, **kwargs): sql = render_template( "/".join([template_path, 'update.sql']), - data=data, o_data=old_data, conn=conn + data=data, o_data=old_data, conn=conn, + update_column_data=update_column_data, update_column=update_column ) else: sql = _get_create_sql(data, template_path, conn, mode, name, @@ -353,3 +363,25 @@ def get_storage_params(amname): "heap": [] } return storage_parameters[amname] + + +def _get_column_details_to_update(old_data, data): + """ + This function returns the columns/expressions which need to update + :param old_data: + :param data: + :return: + """ + update_column_data = [] + update_column = False + + if 'columns' in data and 'changed' in data['columns']: + for index, col1 in enumerate(old_data['columns']): + for col2 in data['columns']['changed']: + if col1['col_num'] == col2['col_num'] and col1['statistics'] \ + != col2['statistics']: + update_column_data.append(col2) + update_column = True + break + + return update_column_data, update_column diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/column_details.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/column_details.sql index 491ff4d47c1..05c468df5f2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/column_details.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/column_details.sql @@ -9,6 +9,8 @@ SELECT END::text[] AS options, i.attnum, pg_catalog.pg_get_indexdef(i.indexrelid, i.attnum, true) as attdef, + CASE WHEN pg_catalog.pg_get_indexdef(i.indexrelid, i.attnum, true) = a.attname THEN FALSE ELSE TRUE END AS is_exp, + a.attstattarget as statistics, CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname, op.oprname AS oprname, CASE WHEN length(nspc.nspname::text) > 0 AND length(coll.collname::text) > 0 THEN diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/create.sql index 603255943d2..2800857d5d5 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/11_plus/create.sql @@ -3,7 +3,7 @@ CREATE{% if data.indisunique %} UNIQUE{% endif %} INDEX{% if add_not_exists_clau ON {{conn|qtIdent(data.schema, data.table)}} {% if data.amname %}USING {{conn|qtIdent(data.amname)}}{% endif %} {% if mode == 'create' %} - ({% for c in data.columns %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(c.colname)}}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.op_class %} + ({% for c in data.columns %}{% if loop.index != 1 %}, {% endif %}{% if c.is_exp %}({{c.colname}}){% else %}{{conn|qtIdent(c.colname)}}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.op_class %} {{c.op_class}}{% endif %}{% if data.amname is defined %}{% if c.sort_order is defined and c.is_sort_nulls_applicable %}{% if c.sort_order %} DESC{% else %} ASC{% endif %}{% endif %}{% if c.nulls is defined and c.is_sort_nulls_applicable %} NULLS {% if c.nulls %} FIRST{% else %}LAST{% endif %}{% endif %}{% endif %}{% endfor %}) {% if data.include|length > 0 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/15_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/15_plus/create.sql index 4f0a1e911e7..f1994631c70 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/15_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/15_plus/create.sql @@ -3,7 +3,7 @@ CREATE{% if data.indisunique %} UNIQUE{% endif %} INDEX{% if add_not_exists_clau ON {{conn|qtIdent(data.schema, data.table)}} {% if data.amname %}USING {{conn|qtIdent(data.amname)}}{% endif %} {% if mode == 'create' %} - ({% for c in data.columns %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(c.colname)}}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.op_class %} + ({% for c in data.columns %}{% if loop.index != 1 %}, {% endif %}{% if c.is_exp %}({{c.colname}}){% else %}{{conn|qtIdent(c.colname)}}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.op_class %} {{c.op_class}}{% endif %}{% if data.amname is defined %}{% if c.sort_order is defined and c.is_sort_nulls_applicable %}{% if c.sort_order %} DESC{% else %} ASC{% endif %}{% endif %}{% if c.nulls is defined and c.is_sort_nulls_applicable %} NULLS {% if c.nulls %} FIRST{% else %}LAST{% endif %}{% endif %}{% endif %}{% endfor %}) {% if data.include|length > 0 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/column_details.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/column_details.sql index dc9d79ee2e2..9e79b0cff67 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/column_details.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/column_details.sql @@ -9,6 +9,8 @@ SELECT END::text[] AS options, i.attnum, pg_catalog.pg_get_indexdef(i.indexrelid, i.attnum, true) as attdef, + CASE WHEN pg_catalog.pg_get_indexdef(i.indexrelid, i.attnum, true) = a.attname THEN FALSE ELSE TRUE END AS is_exp, + a.attstattarget as statistics, CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname, op.oprname AS oprname, CASE WHEN length(nspc.nspname::text) > 0 AND length(coll.collname::text) > 0 THEN diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/create.sql index 34b8d3c70d5..ea3ce45f872 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/create.sql @@ -3,7 +3,7 @@ CREATE{% if data.indisunique %} UNIQUE{% endif %} INDEX{% if add_not_exists_clau ON {{conn|qtIdent(data.schema, data.table)}} {% if data.amname %}USING {{conn|qtIdent(data.amname)}}{% endif %} {% if mode == 'create' %} - ({% for c in data.columns %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(c.colname)}}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.op_class %} + ({% for c in data.columns %}{% if loop.index != 1 %}, {% endif %}{% if c.is_exp %}({{c.colname}}){% else %}{{conn|qtIdent(c.colname)}}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.op_class %} {{c.op_class}}{% endif %}{% if data.amname is defined %}{% if c.sort_order is defined and c.is_sort_nulls_applicable %}{% if c.sort_order %} DESC{% else %} ASC{% endif %}{% endif %}{% if c.nulls is defined and c.is_sort_nulls_applicable %} NULLS {% if c.nulls %} FIRST{% else %}LAST{% endif %}{% endif %}{% endif %}{% endfor %}) {% else %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/update.sql index 71cdb754e48..bef61d07f1d 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/update.sql @@ -85,3 +85,12 @@ ALTER TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}} {% if data.description is defined and o_data.description != data.description %} COMMENT ON INDEX {{conn|qtIdent(data.schema, data.name)}} IS {{data.description|qtLiteral(conn)}};{% endif %} + +{## Alter column statistics##} +{% if update_column %} +{% for col in update_column_data %} +ALTER INDEX IF EXISTS {{conn|qtIdent(data.schema, data.name)}} + ALTER COLUMN {{col.col_num}} SET STATISTICS {{col.statistics}}; + +{% endfor %} +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/static/js/privilege.ui.js b/web/pgadmin/browser/server_groups/servers/static/js/privilege.ui.js index 1b5bf531250..d2e6caad862 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/privilege.ui.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/privilege.ui.js @@ -62,7 +62,7 @@ export default class PrivilegeRoleSchema extends BaseUISchema { disabled : function(state) { return !( obj.nodeInfo && - obj.nodeInfo.server.user.name == state['grantor'] + obj.nodeInfo.server?.user?.name == state['grantor'] ); }, }, diff --git a/web/pgadmin/static/js/SchemaView/DataGridView.jsx b/web/pgadmin/static/js/SchemaView/DataGridView.jsx index 61a78e0a3e9..d43cbdd1434 100644 --- a/web/pgadmin/static/js/SchemaView/DataGridView.jsx +++ b/web/pgadmin/static/js/SchemaView/DataGridView.jsx @@ -133,8 +133,12 @@ const useStyles = makeStyles((theme)=>({ } })); -function DataTableHeader({headerGroups}) { +function DataTableHeader({headerGroups, viewHelperProps, schema}) { const classes = useStyles(); + + /* Using ref so that schema variable is not frozen in columns closure */ + const schemaRef = useRef(schema); + const sortIcon = (isDesc) => { return isDesc ? ' 🔽' : ' 🔼'; }; @@ -142,21 +146,24 @@ function DataTableHeader({headerGroups}) {