Added search object functionality. Fixes #2172

This commit is contained in:
Aditya Toshniwal
2020-04-06 17:33:07 +05:30
committed by Akshay Joshi
parent f77aa3284f
commit e1f990190e
57 changed files with 5968 additions and 494 deletions

View File

@@ -0,0 +1,87 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
"""Implements Search Object feature"""
from flask import request
from flask_babelex import gettext
from flask_security import login_required
from pgadmin.utils import PgAdminModule
from pgadmin.utils.ajax import make_json_response, bad_request,\
internal_server_error
from pgadmin.utils.preferences import Preferences
from pgadmin.tools.search_objects.utils import SearchObjectsHelper
MODULE_NAME = 'search_objects'
class SearchObjectsModule(PgAdminModule):
LABEL = gettext('Search objects')
def get_exposed_url_endpoints(self):
"""
Returns:
list: URL endpoints for search_object module
"""
return ['search_objects.search', 'search_objects.types']
def show_system_objects(self):
"""
return system preference objects
"""
return self.pref_show_system_objects.get()
def register_preferences(self):
"""
Get show_system_objects preference
"""
browser_preference = Preferences.module('browser')
self.pref_show_system_objects =\
browser_preference.preference('show_system_objects')
# Create blueprint for BackupModule class
blueprint = SearchObjectsModule(
MODULE_NAME, __name__, static_url_path=''
)
@blueprint.route("/", endpoint='index')
@login_required
def index():
return bad_request(errormsg=_("This URL cannot be called directly."))
@blueprint.route("types/<int:sid>/<int:did>", endpoint='types')
@login_required
def types(sid, did):
so_obj = SearchObjectsHelper(sid, did, blueprint.show_system_objects())
return make_json_response(data=so_obj.get_supported_types())
@blueprint.route("search/<int:sid>/<int:did>", endpoint='search')
@login_required
def search(sid, did):
"""
URL args:
text <required>: search text
type <optional>: type of object to be searched.
"""
text = request.args.get('text', None)
obj_type = request.args.get('type', None)
so_obj = SearchObjectsHelper(sid, did, blueprint.show_system_objects())
status, res = so_obj.search(text, obj_type)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(data=res)

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define([
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'pgadmin.alertifyjs',
'sources/pgadmin', 'sources/csrf', 'pgadmin.browser.toolbar',
'pgadmin.search_objects/search_objects_dialog',
], function(
gettext, url_for, $, _, alertify, pgAdmin, csrfToken, toolBar, SearchObjectsDialog
) {
var pgBrowser = pgAdmin.Browser;
if (pgAdmin.SearchObjects)
return pgAdmin.SearchObjects;
pgAdmin.SearchObjects = {
init: function() {
if (this.initialized)
return;
this.initialized = true;
csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
// Define the nodes on which the menus to be appear
var menus = [{
name: 'search_objects',
module: this,
applies: ['tools'],
callback: 'show_search_objects',
enable: this.search_objects_enabled,
priority: 1,
label: gettext('Search objects'),
}, {
name: 'search_objects',
module: this,
applies: ['context'],
callback: 'show_search_objects',
enable: this.search_objects_enabled,
priority: 1,
label: gettext('Search objects'),
}];
pgBrowser.add_menus(menus);
return this;
},
search_objects_enabled: function(obj) {
/* Same as query tool */
var isEnabled = (() => {
if (!_.isUndefined(obj) && !_.isNull(obj)) {
if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) {
if (obj._type == 'database' && obj.allowConn) {
return true;
} else if (obj._type != 'database') {
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
})();
toolBar.enable(gettext('Search objects'), isEnabled);
return isEnabled;
},
// Callback to show the dialog
show_search_objects: function(action, item) {
let dialog = new SearchObjectsDialog.default(
pgBrowser,
$,
alertify,
{},
);
dialog.draw(action, item, {}, pgBrowser.stdW.md, pgBrowser.stdH.lg);
},
};
return pgAdmin.SearchObjects;
});

View File

@@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import gettext from 'sources/gettext';
import {Dialog} from 'sources/alertify/dialog';
import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title';
export default class SearchObjectsDialog extends Dialog {
constructor(pgBrowser, $, alertify, BackupModel, backform = null) {
super(gettext('Search Objects Error'),
'<div class=\'search_objects_dialog\'></div>',
pgBrowser, $, alertify, BackupModel, backform
);
}
dialogName() {
return 'search_objects';
}
draw(action, aciTreeItem, params, width=0, height=0) {
let dbInfo = this.retrieveAncestorOfTypeDatabase(aciTreeItem);
if (!dbInfo) {
return;
}
let dialogTitle = getPanelTitle(this.pgBrowser, aciTreeItem);
dialogTitle = gettext('Search Objects - ') + dialogTitle;
const dialog = this.createOrGetDialog(
gettext('Search Objects...'),
'search_objects'
);
dialog(dialogTitle).resizeTo(width, height);
}
}

View File

@@ -0,0 +1,649 @@
import {getTreeNodeHierarchyFromElement} from 'sources/tree/pgadmin_tree_node';
import axios from 'axios/index';
import gettext from 'sources/gettext';
import url_for from 'sources/url_for';
import 'select2';
import {DialogWrapper} from 'sources/alertify/dialog_wrapper';
import Slick from 'sources/../bundle/slickgrid';
import pgAdmin from 'sources/pgadmin';
export default class SearchObjectsDialogWrapper extends DialogWrapper {
constructor(dialogContainerSelector, dialogTitle, typeOfDialog,
jquery, pgBrowser, alertify, dialogModel, backform) {
super(dialogContainerSelector, dialogTitle, jquery,
pgBrowser, alertify, dialogModel, backform);
this.grid = null;
this.dataview = null;
this.gridContainer = null;
}
showMessage(text, is_error, call_after_show=()=>{}) {
if(text == '' || text == null) {
this.statusBar.classList.add('d-none');
} else {
if(is_error) {
this.statusBar.innerHTML = `
<div class="error-in-footer">
<div class="d-flex px-2 py-1">
<div class="pr-2">
<i class="fa fa-exclamation-triangle text-danger" aria-hidden="true" role="img"></i>
</div>
<div role="alert" class="alert-text">${text}</div>
<div class="ml-auto close-error-bar">
<a class="close-error fa fa-times text-danger"></a>
</div>
</div>
</div>
`;
this.statusBar.querySelector('.close-error').addEventListener('click', ()=>{
this.showMessage(null);
});
} else {
this.statusBar.innerHTML = `
<div class="info-in-footer">
<div class="d-flex px-2 py-1">
<div class="pr-2">
<i class="fa fa-info-circle text-primary" aria-hidden="true"></i>
</div>
<div class="alert-text" role="alert">${text}</div>
</div>
</div>
`;
}
this.statusBar.classList.remove('d-none');
call_after_show(this.statusBar);
}
}
createDialogDOM(dialogContainer) {
dialogContainer.innerHTML = `
<div class="d-flex flex-column w-100 h-100">
<div class="p-2">
<div class="row">
<div class="col-8 d-flex">
<div class="input-group pgadmin-controls">
<div class="input-group-prepend">
<span class="input-group-text fa fa-search" id="labelSearch" aria-label="` + gettext('Search') + `"></span>
</div>
<input type="search" class="form-control" id="txtGridSearch" placeholder="` + gettext('Type at least 3 characters') + `"
tabindex="0" aria-describedby="labelSearch" aria-labelledby="labelSearch" autocomplete="off">
</div>
<div class="ml-2">
<button class="btn btn-primary btn-search" disabled>`+ gettext('Search') +`</button>
</div>
</div>
<div class="col-4">
<select aria-label="` + gettext('Object types') + `" class="node-types"></select>
</div>
</div>
</div>
<div class="search-result-container flex-grow-1">
<div class="pg-sp-container d-none">
<div class="pg-sp-content">
<div class="row"><div class="col-12 pg-sp-icon"></div></div>
<div class="row"><div class="col-12 pg-sp-text"></div></div>
</div>
</div>
<div class="search-result"></div>
</div>
<div class='search-result-count p-1'>
</div>
<div class="pg-prop-status-bar">
</div>
</div>
`;
return dialogContainer;
}
updateDimOfSearchResult() {
let dim = this.searchResultContainer.getBoundingClientRect();
this.searchResult.style.height = dim.height + 'px';
this.searchResult.style.width = dim.width + 'px';
}
setLoading(text) {
if(text != null) {
this.loader.classList.remove('d-none');
this.loader.querySelector('.pg-sp-text').innerHTML = text;
} else {
this.loader.classList.add('d-none');
}
}
searchBtnEnabled(enabled) {
if(typeof(enabled) != 'undefined') {
this.searchBtn.disabled = !enabled;
} else {
return !this.searchBtn.disabled;
}
}
searchBoxVal(val) {
if(typeof(val) != 'undefined') {
this.searchBox.value = val;
} else {
return this.searchBox.value.trim();
}
}
typesVal(val) {
if(typeof(val) != 'undefined') {
this.typesSelect.value = val;
} else {
return this.typesSelect.value;
}
}
setTypes(data, enabled=true) {
this.jquery(this.typesSelect).empty().select2({
data: data,
});
this.typesSelect.disabled = !enabled;
}
setResultCount(count) {
if(count != 0 && !count) {
count = gettext('Unknown');
}
this.searchResultCount.innerHTML = count + ' ' +
(count===1 ? gettext('match found.'): gettext('matches found.'));
}
showOtherInfo(rowno) {
let rowData = this.dataview.getItem(rowno);
rowData.name += ` (${rowData.other_info})`;
rowData.other_info = null;
this.dataview.updateItem(rowData.id, rowData);
}
setGridData(data) {
this.dataview.setItems(data);
}
prepareGrid() {
this.dataview = new Slick.Data.DataView();
this.dataview.getItemMetadata = (row)=>{
let rowData = this.dataview.getItem(row);
if(!rowData.show_node){
return {
cssClasses: 'object-muted',
};
}
return null;
};
this.dataview.setFilter((item, args)=>{
return !(args && args.type != 'all' && item.type != args.type);
});
/* jquery required for select2 */
this.jquery(this.typesSelect).on('change', ()=>{
this.dataview.setFilterArgs({ type: this.typesVal() });
this.dataview.refresh();
});
this.dataview.onRowCountChanged.subscribe((e, args) => {
this.grid.updateRowCount();
this.grid.render();
this.setResultCount(args.current);
});
this.dataview.onRowsChanged.subscribe((e, args) => {
this.grid.invalidateRows(args.rows);
this.grid.render();
});
this.grid = new Slick.Grid(
this.searchResult,
this.dataview,
[
{ id: 'name', name: gettext('Object name'), field: 'name', sortable: true,
formatter: (row, cell, value, columnDef, dataContext) => {
let ret_el = `<i class='wcTabIcon ${dataContext.icon}'></i>${value}`;
if(dataContext.other_info != null && dataContext.other_info != '') {
ret_el += '&nbsp;<span class="object-other-info">(...)</span>';
}
return ret_el;
},
width: 50,
},
{ id: 'type', name: gettext('Type'), field: 'type_label', sortable: true, width: 35 },
{ id: 'path', name: gettext('Browser path'), field: 'path', sortable: false },
],
{
enableCellNavigation: true,
enableColumnReorder: false,
multiColumnSort: true,
explicitInitialization: true,
}
);
this.grid.registerPlugin(new Slick.AutoColumnSize());
this.grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: true}));
this.grid.onKeyDown.subscribe((event) => {
let activeRow = this.grid.getActiveCell();
if(activeRow && !event.ctrlKey && !event.altKey && !event.metaKey && event.keyCode == 9) {
event.preventDefault();
event.stopImmediatePropagation();
if(event.shiftKey) {
this.prevToGrid.focus();
} else {
this.nextToGrid.focus();
}
}
});
this.grid.onClick.subscribe((event, args) => {
if(event.target.classList.contains('object-other-info')) {
this.showOtherInfo(args.row);
}
});
this.grid.onDblClick.subscribe((event, args) => {
let rowData = this.dataview.getItem(args.row);
let treeMenu = this.pgBrowser.treeMenu;
if(!rowData.show_node) {
this.showMessage(
gettext('%s objects are disabled in the browser.', rowData.type_label) + ' ' +
gettext('You can enable them in the') + ' <a class="pref-dialog-link">' + gettext('preferences dialog') + '</a>.',
true,
(statusBar)=>{
statusBar.querySelector('.pref-dialog-link').addEventListener('click', ()=>{
if(pgAdmin.Preferences) {
pgAdmin.Preferences.show();
}
});
}
);
return false;
}
this.showMessage(gettext('Locating...'));
treeMenu.findNodeWithToggle(rowData.id_path)
.then((treeItem)=>{
treeMenu.selectNode(treeItem.domNode, true);
this.showMessage(null);
})
.catch((args)=>{
this.showMessage(gettext('Unable to locate this object in the browser.'), true);
console.warn(args);
});
});
this.grid.onSort.subscribe((event, args) => {
let cols = args.sortCols;
this.dataview.sort(function (dataRow1, dataRow2) {
for (var i = 0, l = cols.length; i < l; i++) {
var field = cols[i].sortCol.field;
var sign = cols[i].sortAsc ? 1 : -1;
var value1 = dataRow1[field], value2 = dataRow2[field];
var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
if (result != 0) {
return result;
}
}
return false;
}, true);
});
}
onDialogResize() {
this.updateDimOfSearchResult();
if(this.grid) {
this.grid.resizeCanvas();
this.grid.autosizeColumns();
}
}
onDialogShow() {
this.focusOnDialog(this);
setTimeout(()=>{
if(!this.grid) {
this.prepareGrid();
}
this.updateDimOfSearchResult();
this.grid.init();
this.setGridData([]);
this.onDialogResize();
}, 500);
}
getBaseUrl(endpoint) {
return url_for('search_objects.'+endpoint, {
sid: this.treeInfo.server._id,
did: this.treeInfo.database._id,
});
}
getCollNode(node_type) {
if('coll-'+node_type in this.pgBrowser.Nodes) {
return this.pgBrowser.Nodes['coll-'+node_type];
} else if(node_type in this.pgBrowser.Nodes &&
typeof(this.pgBrowser.Nodes[node_type].collection_type) === 'string') {
return this.pgBrowser.Nodes[this.pgBrowser.Nodes[node_type].collection_type];
}
return null;
}
getSelectedNode() {
const tree = this.pgBrowser.treeMenu;
const selectedNode = tree.selected();
if (selectedNode) {
return tree.findNodeByDomElement(selectedNode);
} else {
return undefined;
}
}
finaliseData(datum) {
datum.icon = 'icon-' + datum.type;
/* finalise path */
[datum.path, datum.id_path] = this.translateSearchObjectsPath(datum.path, datum.catalog_level);
/* id is required by slickgrid dataview */
datum.id = datum.id_path;
return datum;
}
/* This function will translate the path given by search objects API into two parts
* 1. The display path on the UI
* 2. The tree search path to locate the object on the tree.
*
* Sample path returned by search objects API
* :schema.11:/pg_catalog/:table.2604:/pg_attrdef
*
* Sample path required by tree locator
* Normal object - server_group/1.server/3.coll-database/3.database/13258.coll-schema/13258.schema/2200.coll-table/2200.table/41773
* pg_catalog schema - server_group/1.server/3.coll-database/3.database/13258.coll-catalog/13258.catalog/11.coll-table/11.table/2600
* Information Schema, dbo, sys - server_group/1.server/3.coll-database/3.database/13258.coll-catalog/13258.catalog/12967.coll-catalog_object/12967.catalog_object/13204
*
* Column catalog_level has values as
* N - Not a catalog schema
* D - Catalog schema with DB support - pg_catalog
* O - Catalog schema with object support only - info schema, dbo, sys
*/
translateSearchObjectsPath(path, catalog_level) {
if (path === null) {
return path;
}
catalog_level = catalog_level || 'N';
/* path required by tree locator */
/* the path received from the backend is after the DB node, initial path setup */
let id_path = [
this.treeInfo.server_group.id,
this.treeInfo.server.id,
this.getCollNode('database').type + '/' + this.treeInfo.server._id,
this.treeInfo.database.id,
];
let prev_node_id = this.treeInfo.database._id;
/* add the slash to match regex, remove it from display path later */
path = '/' + path;
/* the below regex will match all /:server_group.1:/ */
let new_path = path.replace(/\/:[a-zA-Z_]+\.[0-9]+:\//g, (token)=>{
let orig_token = token;
/* remove the slash and colon */
token = token.slice(2, -2);
let [node_type, node_oid, others] = token.split('.');
if(typeof(others) !== 'undefined') {
return token;
}
/* schema type is "catalog" for catalog schemas */
node_type = (['D', 'O'].indexOf(catalog_level) != -1 && node_type == 'schema') ? 'catalog' : node_type;
/* catalog like info schema will only have views and tables AKA catalog_object except for pg_catalog */
node_type = (catalog_level === 'O' && ['view', 'table'].indexOf(node_type) != -1) ? 'catalog_object' : node_type;
/* If collection node present then add it */
let coll_node = this.getCollNode(node_type);
if(coll_node) {
/* Add coll node to the path */
if(prev_node_id != null) id_path.push(`${coll_node.type}/${prev_node_id}`);
/* Add the node to the path */
id_path.push(`${node_type}/${node_oid}`);
/* This will be needed for coll node */
prev_node_id = node_oid;
/* This will be displayed in the grid */
return `/${coll_node.label}/`;
} else if(node_type in this.pgBrowser.Nodes) {
/* Add the node to the path */
id_path.push(`${node_type}/${node_oid}`);
/* This will be need for coll node id path */
prev_node_id = node_oid;
/* Remove the token and replace with slash. This will be displayed in the grid */
return '/';
}
prev_node_id = null;
return orig_token;
});
/* Remove the slash we had added */
new_path = new_path.substring(1);
return [new_path, id_path];
}
prepareDialog() {
this.showMessage(null);
this.setResultCount(0);
if(this.grid) {
this.grid.destroy();
this.grid = null;
}
/* Load types */
this.setTypes([{
id: -1,
text: gettext('Loading...'),
value: null,
}], false);
axios.get(
this.getBaseUrl('types')
).then((res)=>{
let types = [{
id: 'all',
text: 'All types',
}];
for (const key of Object.keys(res.data.data).sort()) {
types.push({
id: key,
text: res.data.data[key],
});
}
this.setTypes(types);
}).catch(()=>{
this.setTypes([{
id: -1,
text: gettext('Failed'),
value: null,
}], false);
});
}
main(title) {
this.set('title', title);
}
setup() {
return {
buttons: [{
text: '',
key: 112,
className: 'btn btn-secondary pull-left fa fa-question pg-alertify-icon-button',
attrs: {
name: 'dialog_help',
type: 'button',
label: gettext('Help'),
'aria-label': gettext('Help'),
url: url_for('help.static', {
'filename': 'search_objects.html',
}),
},
}, {
text: gettext('Close'),
key: 27,
className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button',
'data-btn-name': 'cancel',
}],
// Set options for dialog
options: {
title: this.dialogTitle,
//disable both padding and overflow control.
padding: !1,
overflow: !1,
model: 0,
resizable: true,
maximizable: true,
pinnable: false,
closableByDimmer: false,
modal: false,
},
};
}
build() {
let tmpEle = document.createElement('div');
tmpEle.innerHTML = this.dialogContainerSelector;
let dialogContainer = tmpEle.firstChild;
// Append the container
this.elements.content.innerHTML = '';
this.elements.content.appendChild(dialogContainer);
this.createDialogDOM(dialogContainer);
this.alertify.pgDialogBuild.apply(this);
this.loader = dialogContainer.getElementsByClassName('pg-sp-container')[0];
this.searchBox = dialogContainer.querySelector('#txtGridSearch');
this.searchBtn = dialogContainer.querySelector('.btn-search');
this.typesSelect = dialogContainer.querySelector('.node-types');
this.searchResultContainer = dialogContainer.querySelector('.search-result-container');
this.searchResult = dialogContainer.querySelector('.search-result');
this.searchResultCount = dialogContainer.querySelector('.search-result-count');
this.statusBar = dialogContainer.querySelector('.pg-prop-status-bar');
/* These two values are required to come out of grid when tab is
* pressed in the grid. Slickgrid does not allow any way to come out
*/
this.nextToGrid = this.elements.footer.querySelector('.ajs-button');
this.prevToGrid = this.typesSelect;
/* init select2 */
this.setTypes([{
id: -1,
text: gettext('Loading...'),
value: null,
}], false);
/* on search box change */
this.searchBox.addEventListener('input', ()=>{
if(this.searchBoxVal().length >= 3) {
this.searchBtnEnabled(true);
} else {
this.searchBtnEnabled(false);
}
});
/* on enter key press */
this.searchBox.addEventListener('keypress', (e)=>{
if(e.keyCode == 13) {
e.stopPropagation();
if(this.searchBtnEnabled()) {
this.searchBtn.dispatchEvent(new Event('click'));
}
}
});
/* on search button click */
this.searchBtn.addEventListener('click', ()=>{
this.searchBtnEnabled(false);
this.setGridData([]);
this.showMessage(null);
this.setLoading(gettext('Searching....'));
axios.get(this.getBaseUrl('search'), {
params: {
text: this.searchBoxVal(),
type: this.typesVal(),
},
}).then((res)=>{
let grid_data = res.data.data.map((row)=>{
return this.finaliseData(row);
});
this.setGridData(grid_data);
}).catch((error)=>{
let errmsg = '';
if (error.response) {
errmsg = error.response.statusText;
} else if (error.request) {
errmsg = gettext('No response received');
} else {
errmsg = error.message;
}
this.showMessage(gettext('An unexpected occurred: %s', errmsg), true);
console.warn(error);
}).finally(()=>{
this.setLoading(null);
this.searchBtnEnabled(true);
});
});
this.set({
'onresized': this.onDialogResize.bind(this),
'onmaximized': this.onDialogResize.bind(this),
'onrestored': this.onDialogResize.bind(this),
'onshow': this.onDialogShow.bind(this),
});
}
prepare() {
let selectedTreeNode = this.getSelectedNode();
if (!this.getSelectedNodeData(selectedTreeNode)) {
return;
}
this.treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode);
this.prepareDialog();
this.focusOnDialog(this);
}
callback(event) {
if (this.wasHelpButtonPressed(event)) {
event.cancel = true;
this.pgBrowser.showHelp(
event.button.element.name,
event.button.element.getAttribute('url'),
null,
null,
);
return;
}
}
}

View File

@@ -0,0 +1,122 @@
.search_objects_dialog {
height: 100%;
.object-other-info {
&:hover {
font-weight: bold;
}
}
.pref-dialog-link {
color: $color-fg !important;
text-decoration: underline !important;
cursor: pointer;
}
.search-result-container {
width: 100%;
height: 100%;
min-height: 0;
}
.node-types ~ .select2-container {
min-width: 100%;
}
.search-result-count {
border-top: $panel-border;
}
.ui-widget {
font-family: $font-family-primary;
font-size: $font-size-base;
.slick-header.ui-state-default {
border: $table-border-width solid $table-border-color;
.slick-header-columns {
background: $table-bg;
color: $color-fg;
border-bottom: $panel-border;
.slick-header-column-sorted {
font-style: unset;
}
.ui-state-default {
background: $table-bg !important;
color: $color-fg !important;
padding: $table-header-cell-padding $table-cell-padding;
border-right: $table-border-width solid $table-border-color;
.slick-column-name {
font-weight: bold;
}
.slick-sort-indicator {
float: unset;
}
}
.slick-header-sortable {
cursor: pointer !important;
.slick-sort-indicator-asc {
background: none;
border-top: none;
border-right: 0.25rem solid transparent;
border-bottom: 0.25rem solid $color-fg;
border-left: 0.25rem solid transparent;
}
.slick-sort-indicator-desc {
background: none;
border-top: 0.25rem solid $color-fg;
border-right: 0.25rem solid transparent;
border-bottom: none;
border-left: 0.25rem solid transparent;
}
}
}
}
.ui-widget-content {
color: $color-fg;
&.slick-row {
&.object-muted {
&.active, &.active:hover, &:hover, & {
.slick-cell {
color: $text-muted !important;
cursor: default !important;
}
}
}
&.active, &.active:hover {
.slick-cell {
border-top: $table-border-width solid transparent !important;
background-color: $tree-bg-selected !important;
color: $tree-fg-selected !important;
}
}
&:hover {
cursor: pointer;
.slick-cell {
border-top: $table-border-width solid transparent !important;
border-bottom: $table-border-width solid transparent !important;
background-color: $tree-bg-hover !important;
color: $tree-fg-hover !important;
cursor: pointer !important;
}
}
}
}
}
.pg-prop-status-bar {
position: absolute;
bottom: 0;
right: 0;
left: 0;
}
}

View File

@@ -0,0 +1,435 @@
{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
{% set all_obj = false %}
{% if obj_type == 'all' or obj_type is none %}
{% set all_obj = true %}
{% endif %}
SELECT obj_type, obj_name,
REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
schema_name, show_node, other_info,
CASE
WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
ELSE 'N'
END AS catalog_level
FROM (
{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
SELECT
CASE
WHEN c.relkind = 'S' THEN 'sequence'
WHEN c.relkind = 'v' THEN 'view'
WHEN c.relkind = 'm' THEN 'mview'
ELSE 'should not happen'
END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' ||
CASE
WHEN c.relkind = 'S' THEN ':sequence.'
WHEN c.relkind = 'v' THEN ':view.'
WHEN c.relkind = 'm' THEN ':mview.'
ELSE 'should not happen'
END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
CASE
WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
ELSE False
END AS show_node, NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
{% if all_obj %}
WHERE c.relkind in ('S','v','m')
{% elif obj_type == 'sequence' %}
WHERE c.relkind = 'S'
{% elif obj_type == 'view' %}
WHERE c.relkind = 'v'
{% elif obj_type == 'mview' %}
WHERE c.relkind = 'm'
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['table', 'partition'] %}
SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' || (
WITH RECURSIVE table_path_data as (
select c.oid as oid, 0 as height,
CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) obj_path, n.nspname AS schema_name,
CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
ELSE {{ show_node_prefs['table'] }} END AS show_node,
NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind in ('p','r')
{% if obj_type == 'table' %}
AND NOT c.relispartition
{% elif obj_type == 'partition' %}
AND c.relispartition
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['index'] %}
SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
JOIN pg_namespace n ON n.oid=tab.relnamespace
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
WHERE contype IS NULL
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger_function', 'function'] %}
SELECT
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
ELSE 'function' END::text AS obj_type, p.proname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' || case when t.typname = 'trigger' then ':trigger_function.' else ':function.' end || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name,
CASE WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }} ELSE {{ show_node_prefs['function'] }} END AS show_node,
pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info
from pg_proc p
left join pg_namespace n on p.pronamespace = n.oid
left join pg_type t on p.prorettype = t.oid
WHERE ({{ CATALOGS.DB_SUPPORT('n') }})
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['event_trigger'] %}
select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['schema'] %}
select 'schema'::text AS obj_type, n.nspname AS obj_name,
':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
{{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
where {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['column'] %}
select 'column'::text AS obj_type, a.attname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/' ||
case
WHEN t.relkind in ('r', 'p') THEN ':table.'
WHEN t.relkind = 'v' THEN ':view.'
WHEN t.relkind = 'm' THEN ':mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
from pg_attribute a
inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m')
left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
and not t.relispartition
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
SELECT
CASE
WHEN c.contype = 'c' THEN 'check_constraint'
WHEN c.contype = 'f' THEN 'foreign_key'
WHEN c.contype = 'p' THEN 'primary_key'
WHEN c.contype = 'u' THEN 'unique_constraint'
WHEN c.contype = 'x' THEN 'exclusion_constraint'
END::text AS obj_type,
case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
':schema.'||n.oid||':/' || n.nspname||'/'||
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) ||
CASE
WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid
WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid
WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid
WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid
WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid
END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
from pg_constraint c
left join pg_class t on c.conrelid = t.oid
left join pg_class tf on c.confrelid = tf.oid
left join pg_namespace n on t.relnamespace = n.oid
where c.contypid = 0
{% if obj_type == 'check_constraint' %}
AND c.contype = 'c'
{% elif obj_type == 'foreign_key' %}
AND c.contype = 'f'
{% elif obj_type == 'primary_key' %}
AND c.contype = 'p'
{% elif obj_type == 'unique_constraint' %}
AND c.contype = 'u'
{% elif obj_type == 'exclusion_constraint' %}
AND c.contype = 'x'
{% else %}
AND c.contype IN ('c', 'f', 'p', 'u', 'x')
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['rule'] %}
select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
case
when t.relkind = 'v' then ':view.'
when t.relkind = 'm' then ':mview.'
WHEN t.relkind in ('r', 'p') THEN
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
)
end
||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
from pg_rewrite r
left join pg_class t on r.ev_class = t.oid
left join pg_namespace n on t.relnamespace = n.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger'] %}
select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
case
when t.relkind = 'v' then ':view.'
when t.relkind = 'm' then ':mview.'
WHEN t.relkind in ('r', 'p') THEN
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
)
end || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
from pg_trigger tr
left join pg_class t on tr.tgrelid = t.oid
left join pg_namespace n on t.relnamespace = n.oid
where tr.tgisinternal = false
and {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['type'] %}
SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
'/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
FROM pg_type t
LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
{% if not show_system_objects %}
AND ct.oid is NULL
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['cast'] %}
SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
{% if not show_system_objects %}
WHERE ca.oid > {{last_system_oid}}::OID
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['language'] %}
SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
FROM pg_language lan
WHERE lanispl IS TRUE
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_configuration'] %}
SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
FROM pg_ts_config cfg
left join pg_namespace n on cfg.cfgnamespace = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_dictionary'] %}
SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
FROM pg_ts_dict dict
left join pg_namespace ns on dict.dictnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_parser'] %}
SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
FROM pg_ts_parser prs
left join pg_namespace ns on prs.prsnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_template'] %}
SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
FROM pg_ts_template tmpl
left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
AND {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain'] %}
select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
from pg_type t
inner join pg_namespace n on t.typnamespace = n.oid
where t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain_constraints'] %}
SELECT 'domain_constraints' AS obj_type,
c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
FROM pg_constraint c JOIN pg_type t
ON t.oid=contypid JOIN pg_namespace n
ON n.oid=t.typnamespace
WHERE t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
from pg_foreign_data_wrapper
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_server'] %}
select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
from pg_foreign_server sr
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['user_mapping'] %}
select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
from pg_user_mapping um
inner join pg_roles ro on um.umuser = ro.oid
inner join pg_foreign_server sr on um.umserver = sr.oid
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_table'] %}
select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
from pg_foreign_table ft
inner join pg_class c on ft.ftrelid = c.oid
inner join pg_namespace ns on c.relnamespace = ns.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['extension'] %}
select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
FROM pg_extension x
JOIN pg_namespace n on x.extnamespace=n.oid
join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['collation'] %}
SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
FROM pg_collation c
JOIN pg_namespace n ON n.oid=c.collnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
) sn
where lower(sn.obj_name) like '%{{ search_text }}%'
{% if not show_system_objects %}
AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
{% endif %}
ORDER BY 1, 2, 3

View File

@@ -0,0 +1,452 @@
{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
{% set all_obj = false %}
{% if obj_type == 'all' or obj_type is none %}
{% set all_obj = true %}
{% endif %}
SELECT obj_type, obj_name,
REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
schema_name, show_node, other_info,
CASE
WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
ELSE 'N'
END AS catalog_level
FROM (
{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
SELECT
CASE
WHEN c.relkind = 'S' THEN 'sequence'
WHEN c.relkind = 'v' THEN 'view'
WHEN c.relkind = 'm' THEN 'mview'
ELSE 'should not happen'
END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' ||
CASE
WHEN c.relkind = 'S' THEN ':sequence.'
WHEN c.relkind = 'v' THEN ':view.'
WHEN c.relkind = 'm' THEN ':mview.'
ELSE 'should not happen'
END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
CASE
WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
ELSE False
END AS show_node, NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
{% if all_obj %}
WHERE c.relkind in ('S','v','m')
{% elif obj_type == 'sequence' %}
WHERE c.relkind = 'S'
{% elif obj_type == 'view' %}
WHERE c.relkind = 'v'
{% elif obj_type == 'mview' %}
WHERE c.relkind = 'm'
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['table', 'partition'] %}
SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' || (
WITH RECURSIVE table_path_data as (
select c.oid as oid, 0 as height,
CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) obj_path, n.nspname AS schema_name,
CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
ELSE {{ show_node_prefs['table'] }} END AS show_node,
NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind in ('p','r')
{% if obj_type == 'table' %}
AND NOT c.relispartition
{% elif obj_type == 'partition' %}
AND c.relispartition
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['index'] %}
SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
JOIN pg_namespace n ON n.oid=tab.relnamespace
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
WHERE contype IS NULL
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure'] %}
SELECT
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
WHEN p.prokind = 'p' THEN 'procedure'
ELSE 'function'
END::text AS obj_type, p.proname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' ||
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN ':trigger_function.'
WHEN p.prokind = 'p' THEN ':procedure.'
ELSE ':function.'
END || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name,
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }}
WHEN p.prokind = 'p' THEN {{ show_node_prefs['procedure'] }}
ELSE {{ show_node_prefs['function'] }}
END AS show_node,
pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info
from pg_proc p join pg_namespace n
on p.pronamespace = n.oid join pg_type t
on p.prorettype = t.oid join pg_language lng
ON lng.oid=p.prolang
WHERE p.prokind IN ('f', 'w', 'p')
AND CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN lng.lanname NOT IN ('edbspl', 'sql', 'internal')
ELSE true
END
AND ({{ CATALOGS.DB_SUPPORT('n') }})
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['event_trigger'] %}
select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['schema'] %}
select 'schema'::text AS obj_type, n.nspname AS obj_name,
':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
{{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
where {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['column'] %}
select 'column'::text AS obj_type, a.attname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/' ||
case
WHEN t.relkind in ('r', 'p') THEN ':table.'
WHEN t.relkind = 'v' THEN ':view.'
WHEN t.relkind = 'm' THEN ':mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
from pg_attribute a
inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m')
left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
and not t.relispartition
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
SELECT
CASE
WHEN c.contype = 'c' THEN 'check_constraint'
WHEN c.contype = 'f' THEN 'foreign_key'
WHEN c.contype = 'p' THEN 'primary_key'
WHEN c.contype = 'u' THEN 'unique_constraint'
WHEN c.contype = 'x' THEN 'exclusion_constraint'
END::text AS obj_type,
case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
':schema.'||n.oid||':/' || n.nspname||'/'||
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) ||
CASE
WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid
WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid
WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid
WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid
WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid
END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
from pg_constraint c
left join pg_class t on c.conrelid = t.oid
left join pg_class tf on c.confrelid = tf.oid
left join pg_namespace n on t.relnamespace = n.oid
where c.contypid = 0
{% if obj_type == 'check_constraint' %}
AND c.contype = 'c'
{% elif obj_type == 'foreign_key' %}
AND c.contype = 'f'
{% elif obj_type == 'primary_key' %}
AND c.contype = 'p'
{% elif obj_type == 'unique_constraint' %}
AND c.contype = 'u'
{% elif obj_type == 'exclusion_constraint' %}
AND c.contype = 'x'
{% else %}
AND c.contype IN ('c', 'f', 'p', 'u', 'x')
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['rule'] %}
select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
case
when t.relkind = 'v' then ':view.'
when t.relkind = 'm' then ':mview.'
WHEN t.relkind in ('r', 'p') THEN
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
)
end
||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
from pg_rewrite r
left join pg_class t on r.ev_class = t.oid
left join pg_namespace n on t.relnamespace = n.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger'] %}
select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
case
when t.relkind = 'v' then ':view.'
when t.relkind = 'm' then ':mview.'
WHEN t.relkind in ('r', 'p') THEN
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
)
end || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
from pg_trigger tr
left join pg_class t on tr.tgrelid = t.oid
left join pg_namespace n on t.relnamespace = n.oid
where tr.tgisinternal = false
and {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['type'] %}
SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
'/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
FROM pg_type t
LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
{% if not show_system_objects %}
AND ct.oid is NULL
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['cast'] %}
SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
{% if not show_system_objects %}
WHERE ca.oid > {{last_system_oid}}::OID
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['language'] %}
SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
FROM pg_language lan
WHERE lanispl IS TRUE
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_configuration'] %}
SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
FROM pg_ts_config cfg
left join pg_namespace n on cfg.cfgnamespace = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_dictionary'] %}
SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
FROM pg_ts_dict dict
left join pg_namespace ns on dict.dictnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_parser'] %}
SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
FROM pg_ts_parser prs
left join pg_namespace ns on prs.prsnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_template'] %}
SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
FROM pg_ts_template tmpl
left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
AND {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain'] %}
select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
from pg_type t
inner join pg_namespace n on t.typnamespace = n.oid
where t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain_constraints'] %}
SELECT 'domain_constraints' AS obj_type,
c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
FROM pg_constraint c JOIN pg_type t
ON t.oid=contypid JOIN pg_namespace n
ON n.oid=t.typnamespace
WHERE t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
from pg_foreign_data_wrapper
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_server'] %}
select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
from pg_foreign_server sr
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['user_mapping'] %}
select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
from pg_user_mapping um
inner join pg_roles ro on um.umuser = ro.oid
inner join pg_foreign_server sr on um.umserver = sr.oid
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_table'] %}
select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
from pg_foreign_table ft
inner join pg_class c on ft.ftrelid = c.oid
inner join pg_namespace ns on c.relnamespace = ns.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['extension'] %}
select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
FROM pg_extension x
JOIN pg_namespace n on x.extnamespace=n.oid
join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['collation'] %}
SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
FROM pg_collation c
JOIN pg_namespace n ON n.oid=c.collnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
) sn
where lower(sn.obj_name) like '%{{ search_text }}%'
{% if not show_system_objects %}
AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
{% endif %}
ORDER BY 1, 2, 3

View File

@@ -0,0 +1,367 @@
{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
{% set all_obj = false %}
{% if obj_type == 'all' or obj_type is none %}
{% set all_obj = true %}
{% endif %}
SELECT obj_type, obj_name,
REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
schema_name, show_node, other_info,
CASE
WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
ELSE 'N'
END AS catalog_level
FROM (
{% if all_obj or obj_type in ['table', 'sequence', 'view', 'mview'] %}
SELECT
CASE
WHEN c.relkind = 'r' THEN 'table'
WHEN c.relkind = 'S' THEN 'sequence'
WHEN c.relkind = 'v' THEN 'view'
WHEN c.relkind = 'm' THEN 'mview'
ELSE 'should not happen'
END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' ||
CASE
WHEN c.relkind = 'r' THEN ':table.'
WHEN c.relkind = 'S' THEN ':sequence.'
WHEN c.relkind = 'v' THEN ':view.'
WHEN c.relkind = 'm' THEN ':mview.'
ELSE 'should not happen'
END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
CASE
WHEN c.relkind = 'r' THEN {{ show_node_prefs['table'] }}
WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
ELSE False
END AS show_node, NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
{% if all_obj %}
WHERE c.relkind in ('r','S','v','m')
{% elif obj_type == 'table' %}
WHERE c.relkind = 'r'
{% elif obj_type == 'sequence' %}
WHERE c.relkind = 'S'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% elif obj_type == 'view' %}
WHERE c.relkind = 'v'
{% elif obj_type == 'mview' %}
WHERE c.relkind = 'm'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['index'] %}
SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
JOIN pg_namespace n ON n.oid=tab.relnamespace
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
WHERE contype IS NULL
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger_function', 'function'] %}
SELECT
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
ELSE 'function' END::text AS obj_type, p.proname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' || case when t.typname = 'trigger' then ':trigger_function.' else ':function.' end || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name,
CASE WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }} ELSE {{ show_node_prefs['function'] }} END AS show_node,
pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info
from pg_proc p
left join pg_namespace n on p.pronamespace = n.oid
left join pg_type t on p.prorettype = t.oid
WHERE ({{ CATALOGS.DB_SUPPORT('n') }})
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['event_trigger'] %}
select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['schema'] %}
select 'schema'::text AS obj_type, n.nspname AS obj_name,
':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
{{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
where {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['column'] %}
select 'column'::text AS obj_type, a.attname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/' ||
case
WHEN t.relkind = 'r' THEN ':table.'
WHEN t.relkind = 'v' THEN ':view.'
WHEN t.relkind = 'm' THEN ':mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
from pg_attribute a
inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
SELECT
CASE
WHEN c.contype = 'c' THEN 'check_constraint'
WHEN c.contype = 'f' THEN 'foreign_key'
WHEN c.contype = 'p' THEN 'primary_key'
WHEN c.contype = 'u' THEN 'unique_constraint'
WHEN c.contype = 'x' THEN 'exclusion_constraint'
END::text AS obj_type,
case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
':schema.'||n.oid||':/' || n.nspname||'/:table.'|| t.oid || ':/'||t.relname||
CASE
WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid
WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid
WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid
WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid
WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid
END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
from pg_constraint c
left join pg_class t on c.conrelid = t.oid
left join pg_class tf on c.confrelid = tf.oid
left join pg_namespace n on t.relnamespace = n.oid
where c.contypid = 0
{% if obj_type == 'check_constraint' %}
AND c.contype = 'c'
{% elif obj_type == 'foreign_key' %}
AND c.contype = 'f'
{% elif obj_type == 'primary_key' %}
AND c.contype = 'p'
{% elif obj_type == 'unique_constraint' %}
AND c.contype = 'u'
{% elif obj_type == 'exclusion_constraint' %}
AND c.contype = 'x'
{% else %}
AND c.contype IN ('c', 'f', 'p', 'u', 'x')
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['rule'] %}
select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
case
WHEN t.relkind = 'r' THEN '/:table.'
when t.relkind = 'v' then '/:view.'
when t.relkind = 'm' then '/:mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
from pg_rewrite r
left join pg_class t on r.ev_class = t.oid
left join pg_namespace n on t.relnamespace = n.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger'] %}
select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
case
WHEN t.relkind = 'r' THEN '/:table.'
when t.relkind = 'v' then '/:view.'
when t.relkind = 'm' then '/:mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
from pg_trigger tr
left join pg_class t on tr.tgrelid = t.oid
left join pg_namespace n on t.relnamespace = n.oid
where tr.tgisinternal = false
and {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['type'] %}
SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
'/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
FROM pg_type t
LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
{% if not show_system_objects %}
AND ct.oid is NULL
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['cast'] %}
SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
{% if not show_system_objects %}
WHERE ca.oid > {{last_system_oid}}::OID
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['language'] %}
SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
FROM pg_language lan
WHERE lanispl IS TRUE
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_configuration'] %}
SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
FROM pg_ts_config cfg
left join pg_namespace n on cfg.cfgnamespace = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_dictionary'] %}
SELECT 'fts_dictionary'::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
FROM pg_ts_dict dict
left join pg_namespace ns on dict.dictnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_parser'] %}
SELECT 'fts_parser'::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
FROM pg_ts_parser prs
left join pg_namespace ns on prs.prsnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_template'] %}
SELECT 'fts_template'::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
FROM pg_ts_template tmpl
left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
AND {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain'] %}
select 'domain'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
from pg_type t
inner join pg_namespace n on t.typnamespace = n.oid
where t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain_constraints'] %}
SELECT 'domain_constraints'::text AS obj_type,
c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
FROM pg_constraint c JOIN pg_type t
ON t.oid=contypid JOIN pg_namespace n
ON n.oid=t.typnamespace
WHERE t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
from pg_foreign_data_wrapper
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_server'] %}
select 'foreign_server'::text AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
from pg_foreign_server sr
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['user_mapping'] %}
select 'user_mapping'::text AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
from pg_user_mapping um
inner join pg_roles ro on um.umuser = ro.oid
inner join pg_foreign_server sr on um.umserver = sr.oid
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_table'] %}
select 'foreign_table'::text AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
from pg_foreign_table ft
inner join pg_class c on ft.ftrelid = c.oid
inner join pg_namespace ns on c.relnamespace = ns.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['extension'] %}
select 'extension'::text AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
FROM pg_extension x
JOIN pg_namespace n on x.extnamespace=n.oid
join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['collation'] %}
SELECT 'collation'::text AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
FROM pg_collation c
JOIN pg_namespace n ON n.oid=c.collnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
) sn
where lower(sn.obj_name) like '%{{ search_text }}%'
{% if not show_system_objects %}
AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
{% endif %}
ORDER BY 1, 2, 3

View File

@@ -0,0 +1,493 @@
{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %}
{% set all_obj = false %}
{% if obj_type == 'all' or obj_type is none %}
{% set all_obj = true %}
{% endif %}
SELECT obj_type, obj_name,
REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
schema_name, show_node, other_info,
CASE
WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
ELSE 'N'
END AS catalog_level
FROM (
{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
SELECT
CASE
WHEN c.relkind = 'S' THEN 'sequence'
WHEN c.relkind = 'v' THEN 'view'
WHEN c.relkind = 'm' THEN 'mview'
ELSE 'should not happen'
END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' ||
CASE
WHEN c.relkind = 'S' THEN ':sequence.'
WHEN c.relkind = 'v' THEN ':view.'
WHEN c.relkind = 'm' THEN ':mview.'
ELSE 'should not happen'
END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
CASE
WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
ELSE False
END AS show_node, NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
{% if all_obj %}
WHERE c.relkind in ('S','v','m')
{% elif obj_type == 'sequence' %}
WHERE c.relkind = 'S'
{% elif obj_type == 'view' %}
WHERE c.relkind = 'v'
{% elif obj_type == 'mview' %}
WHERE c.relkind = 'm'
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['table', 'partition'] %}
SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' || (
WITH RECURSIVE table_path_data as (
select c.oid as oid, 0 as height,
CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) obj_path, n.nspname AS schema_name,
CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
ELSE {{ show_node_prefs['table'] }} END AS show_node,
NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind in ('p','r')
{% if obj_type == 'table' %}
AND NOT c.relispartition
{% elif obj_type == 'partition' %}
AND c.relispartition
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['index'] %}
SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
JOIN pg_namespace n ON n.oid=tab.relnamespace
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
WHERE contype IS NULL
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %}
SELECT fd.obj_type, fd.obj_name,
CASE
WHEN fd.obj_type = 'function' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'procedure' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'trigger_function' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'edbfunc' THEN
':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'edbproc' THEN
':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name
ELSE NULL
END AS obj_path,
CASE
WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name
WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name
ELSE NULL
END AS schema_name,
CASE
WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }}
WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }}
WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }}
WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }}
WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }}
ELSE NULL
END AS show_node, other_info
FROM (
SELECT
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
WHEN pr.protype = '0'::char THEN
CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END
WHEN pr.protype = '1'::char THEN
CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END
ELSE null
END::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name,
pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info
FROM pg_proc pr left join pg_namespace n
ON pr.pronamespace = n.oid left JOIN pg_namespace np
ON np.oid=n.nspparent left JOIN pg_type t
ON t.oid = pr.prorettype left JOIN pg_language l
ON l.oid = pr.prolang
WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl')
AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }})
) fd
{% if not all_obj %}
WHERE fd.obj_type = '{{ obj_type }}'
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['event_trigger'] %}
select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['schema'] %}
select 'schema'::text AS obj_type, n.nspname AS obj_name,
':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
{{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
where n.nspparent = 0
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['column'] %}
select 'column'::text AS obj_type, a.attname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/' ||
case
WHEN t.relkind in ('r', 'p') THEN ':table.'
WHEN t.relkind = 'v' THEN ':view.'
WHEN t.relkind = 'm' THEN ':mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
from pg_attribute a
inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m')
left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
and not t.relispartition
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
SELECT
CASE
WHEN c.contype = 'c' THEN 'check_constraint'
WHEN c.contype = 'f' THEN 'foreign_key'
WHEN c.contype = 'p' THEN 'primary_key'
WHEN c.contype = 'u' THEN 'unique_constraint'
WHEN c.contype = 'x' THEN 'exclusion_constraint'
END::text AS obj_type,
case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
':schema.'||n.oid||':/' || n.nspname||'/'||
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) ||
CASE
WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid
WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid
WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid
WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid
WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid
END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
from pg_constraint c
left join pg_class t on c.conrelid = t.oid
left join pg_class tf on c.confrelid = tf.oid
left join pg_namespace n on t.relnamespace = n.oid
where c.contypid = 0
{% if obj_type == 'check_constraint' %}
AND c.contype = 'c'
{% elif obj_type == 'foreign_key' %}
AND c.contype = 'f'
{% elif obj_type == 'primary_key' %}
AND c.contype = 'p'
{% elif obj_type == 'unique_constraint' %}
AND c.contype = 'u'
{% elif obj_type == 'exclusion_constraint' %}
AND c.contype = 'x'
{% else %}
AND c.contype IN ('c', 'f', 'p', 'u', 'x')
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['rule'] %}
select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
case
when t.relkind = 'v' then ':view.'
when t.relkind = 'm' then ':mview.'
WHEN t.relkind in ('r', 'p') THEN
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
)
end
||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
from pg_rewrite r
left join pg_class t on r.ev_class = t.oid
left join pg_namespace n on t.relnamespace = n.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger'] %}
select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
case
WHEN t.relkind = 'r' THEN '/:table.'
when t.relkind = 'v' then '/:view.'
when t.relkind = 'm' then '/:mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
from pg_trigger tr
left join pg_class t on tr.tgrelid = t.oid
left join pg_namespace n on t.relnamespace = n.oid
where tr.tgisinternal = false
and {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['type'] %}
SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
'/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
FROM pg_type t
LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
{% if not show_system_objects %}
AND ct.oid is NULL
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['cast'] %}
SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
{% if not show_system_objects %}
WHERE ca.oid > {{last_system_oid}}::OID
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['language'] %}
SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
FROM pg_language lan
WHERE lanispl IS TRUE
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_configuration'] %}
SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
FROM pg_ts_config cfg
left join pg_namespace n on cfg.cfgnamespace = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_dictionary'] %}
SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
FROM pg_ts_dict dict
left join pg_namespace ns on dict.dictnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_parser'] %}
SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
FROM pg_ts_parser prs
left join pg_namespace ns on prs.prsnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_template'] %}
SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
FROM pg_ts_template tmpl
left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
AND {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain'] %}
select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
from pg_type t
inner join pg_namespace n on t.typnamespace = n.oid
where t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain_constraints'] %}
SELECT 'domain_constraints' AS obj_type,
c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
FROM pg_constraint c JOIN pg_type t
ON t.oid=contypid JOIN pg_namespace n
ON n.oid=t.typnamespace
WHERE t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
from pg_foreign_data_wrapper
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_server'] %}
select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
from pg_foreign_server sr
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['user_mapping'] %}
select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
from pg_user_mapping um
inner join pg_roles ro on um.umuser = ro.oid
inner join pg_foreign_server sr on um.umserver = sr.oid
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_table'] %}
select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
from pg_foreign_table ft
inner join pg_class c on ft.ftrelid = c.oid
inner join pg_namespace ns on c.relnamespace = ns.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['extension'] %}
select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
FROM pg_extension x
JOIN pg_namespace n on x.extnamespace=n.oid
join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['collation'] %}
SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
FROM pg_collation c
JOIN pg_namespace n ON n.oid=c.collnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['synonym'] %}
SELECT 'synonym' AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info
FROM pg_synonym s
JOIN pg_namespace n ON n.oid=s.synnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['package'] %}
SELECT 'package' AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['package'] }} AS show_node, NULL AS other_info
FROM pg_namespace p
JOIN pg_namespace n ON n.oid=p.nspparent
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['edbvar'] %}
SELECT 'edbvar' AS obj_type, v.varname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info
FROM edb_variable v JOIN pg_namespace p
ON v.varpackage = p.oid JOIN pg_namespace n
ON p.nspparent = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('p') }}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
) sn
where lower(sn.obj_name) like '%{{ search_text }}%'
{% if not show_system_objects %}
AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
{% endif %}
ORDER BY 1, 2, 3

View File

@@ -0,0 +1,516 @@
{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %}
{% set all_obj = false %}
{% if obj_type == 'all' or obj_type is none %}
{% set all_obj = true %}
{% endif %}
SELECT obj_type, obj_name,
REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
schema_name, show_node, other_info,
CASE
WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
ELSE 'N'
END AS catalog_level
FROM (
{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
SELECT
CASE
WHEN c.relkind = 'S' THEN 'sequence'
WHEN c.relkind = 'v' THEN 'view'
WHEN c.relkind = 'm' THEN 'mview'
ELSE 'should not happen'
END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' ||
CASE
WHEN c.relkind = 'S' THEN ':sequence.'
WHEN c.relkind = 'v' THEN ':view.'
WHEN c.relkind = 'm' THEN ':mview.'
ELSE 'should not happen'
END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
CASE
WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
ELSE False
END AS show_node, NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
{% if all_obj %}
WHERE c.relkind in ('S','v','m')
{% elif obj_type == 'sequence' %}
WHERE c.relkind = 'S'
{% elif obj_type == 'view' %}
WHERE c.relkind = 'v'
{% elif obj_type == 'mview' %}
WHERE c.relkind = 'm'
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['table', 'partition'] %}
SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' || (
WITH RECURSIVE table_path_data as (
select c.oid as oid, 0 as height,
CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) obj_path, n.nspname AS schema_name,
CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
ELSE {{ show_node_prefs['table'] }} END AS show_node,
NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind in ('p','r')
{% if obj_type == 'table' %}
AND NOT c.relispartition
{% elif obj_type == 'partition' %}
AND c.relispartition
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['index'] %}
SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
JOIN pg_namespace n ON n.oid=tab.relnamespace
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
WHERE contype IS NULL
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %}
SELECT fd.obj_type, fd.obj_name,
CASE
WHEN fd.obj_type = 'function' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'procedure' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'trigger_function' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'edbfunc' THEN
':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'edbproc' THEN
':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name
ELSE NULL
END AS obj_path,
CASE
WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name
WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name
ELSE NULL
END AS schema_name,
CASE
WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }}
WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }}
WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }}
WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }}
WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }}
ELSE NULL
END AS show_node, other_info
FROM (
SELECT
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
WHEN pr.protype = '0'::char THEN
CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END
WHEN pr.protype = '1'::char THEN
CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END
ELSE null
END::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name,
pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info
FROM pg_proc pr left join pg_namespace n
ON pr.pronamespace = n.oid left JOIN pg_namespace np
ON np.oid=n.nspparent left JOIN pg_type t
ON t.oid = pr.prorettype left JOIN pg_language l
ON l.oid = pr.prolang
WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl')
AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }})
) fd
{% if not all_obj %}
WHERE fd.obj_type = '{{ obj_type }}'
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['event_trigger'] %}
select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['schema'] %}
select 'schema'::text AS obj_type, n.nspname AS obj_name,
':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
{{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
where n.nspparent = 0
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['column'] %}
select 'column'::text AS obj_type, a.attname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/' ||
case
WHEN t.relkind in ('r', 'p') THEN ':table.'
WHEN t.relkind = 'v' THEN ':view.'
WHEN t.relkind = 'm' THEN ':mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
from pg_attribute a
inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m')
left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
and not t.relispartition
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
SELECT
CASE
WHEN c.contype = 'c' THEN 'check_constraint'
WHEN c.contype = 'f' THEN 'foreign_key'
WHEN c.contype = 'p' THEN 'primary_key'
WHEN c.contype = 'u' THEN 'unique_constraint'
WHEN c.contype = 'x' THEN 'exclusion_constraint'
END::text AS obj_type,
case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
':schema.'||n.oid||':/' || n.nspname||'/'||
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
) ||
CASE
WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid
WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid
WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid
WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid
WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid
END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
from pg_constraint c
left join pg_class t on c.conrelid = t.oid
left join pg_class tf on c.confrelid = tf.oid
left join pg_namespace n on t.relnamespace = n.oid
where c.contypid = 0
{% if obj_type == 'check_constraint' %}
AND c.contype = 'c'
{% elif obj_type == 'foreign_key' %}
AND c.contype = 'f'
{% elif obj_type == 'primary_key' %}
AND c.contype = 'p'
{% elif obj_type == 'unique_constraint' %}
AND c.contype = 'u'
{% elif obj_type == 'exclusion_constraint' %}
AND c.contype = 'x'
{% else %}
AND c.contype IN ('c', 'f', 'p', 'u', 'x')
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['rule'] %}
select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
case
when t.relkind = 'v' then ':view.'
when t.relkind = 'm' then ':mview.'
WHEN t.relkind in ('r', 'p') THEN
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
)
end
||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
from pg_rewrite r
left join pg_class t on r.ev_class = t.oid
left join pg_namespace n on t.relnamespace = n.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger', 'compound_trigger'] %}
select
CASE WHEN tr.tgpackageoid != 0 THEN 'compound_trigger' ELSE 'trigger' END::text AS obj_type, tr.tgname AS obj_name,
':schema.'||n.oid||':/' || n.nspname|| '/' ||
case
when t.relkind = 'v' then ':view.'
when t.relkind = 'm' then ':mview.'
WHEN t.relkind in ('r', 'p') THEN
(
WITH RECURSIVE table_path_data as (
select t.oid as oid, 0 as height,
CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
union
select rel.oid, pt.height+1 as height,
CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
join pg_inherits inh ON inh.inhparent = rel.oid
join table_path_data pt ON inh.inhrelid = pt.oid
)
select path from table_path_data order by height desc limit 1
)
end || CASE WHEN tr.tgpackageoid != 0 THEN '/:compound_trigger.' ELSE '/:trigger.' END || tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
CASE WHEN tr.tgpackageoid != 0 THEN {{ show_node_prefs['compound_trigger'] }} ELSE {{ show_node_prefs['trigger'] }} END AS show_node,
NULL AS other_info
from pg_trigger tr
left join pg_class t on tr.tgrelid = t.oid
left join pg_namespace n on t.relnamespace = n.oid
where tr.tgisinternal = false
and {{ CATALOGS.DB_SUPPORT('n') }}
{% if obj_type == 'compound_trigger' %}
AND tr.tgpackageoid != 0
{% elif obj_type == 'trigger' %}
AND tr.tgpackageoid = 0
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['type'] %}
SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
'/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
FROM pg_type t
LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
{% if not show_system_objects %}
AND ct.oid is NULL
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['cast'] %}
SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
{% if not show_system_objects %}
WHERE ca.oid > {{last_system_oid}}::OID
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['language'] %}
SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
FROM pg_language lan
WHERE lanispl IS TRUE
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_configuration'] %}
SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
FROM pg_ts_config cfg
left join pg_namespace n on cfg.cfgnamespace = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_dictionary'] %}
SELECT 'fts_dictionary'::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
FROM pg_ts_dict dict
left join pg_namespace ns on dict.dictnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_parser'] %}
SELECT 'fts_parser'::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
FROM pg_ts_parser prs
left join pg_namespace ns on prs.prsnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_template'] %}
SELECT 'fts_template'::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
FROM pg_ts_template tmpl
left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
AND {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain'] %}
select 'domain'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
from pg_type t
inner join pg_namespace n on t.typnamespace = n.oid
where t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain_constraints'] %}
SELECT 'domain_constraints'::text AS obj_type,
c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
FROM pg_constraint c JOIN pg_type t
ON t.oid=contypid JOIN pg_namespace n
ON n.oid=t.typnamespace
WHERE t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
from pg_foreign_data_wrapper
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_server'] %}
select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
from pg_foreign_server sr
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['user_mapping'] %}
select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
from pg_user_mapping um
inner join pg_roles ro on um.umuser = ro.oid
inner join pg_foreign_server sr on um.umserver = sr.oid
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_table'] %}
select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
from pg_foreign_table ft
inner join pg_class c on ft.ftrelid = c.oid
inner join pg_namespace ns on c.relnamespace = ns.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['extension'] %}
select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
FROM pg_extension x
JOIN pg_namespace n on x.extnamespace=n.oid
join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['collation'] %}
SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
FROM pg_collation c
JOIN pg_namespace n ON n.oid=c.collnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['synonym'] %}
SELECT 'synonym' AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info
FROM pg_synonym s
JOIN pg_namespace n ON n.oid=s.synnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['package'] %}
SELECT 'package' AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['package'] }} AS show_node, NULL AS other_info
FROM pg_namespace p
JOIN pg_namespace n ON n.oid=p.nspparent
WHERE p.nspcompoundtrigger = false
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['edbvar'] %}
SELECT 'edbvar' AS obj_type, v.varname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info
FROM edb_variable v JOIN pg_namespace p
ON v.varpackage = p.oid JOIN pg_namespace n
ON p.nspparent = n.oid
WHERE p.nspcompoundtrigger = false
AND {{ CATALOGS.DB_SUPPORT('p') }}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
) sn
where lower(sn.obj_name) like '%{{ search_text }}%'
{% if not show_system_objects %}
AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
{% endif %}
ORDER BY 1, 2, 3

View File

@@ -0,0 +1,437 @@
{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %}
{% set all_obj = false %}
{% if obj_type == 'all' or obj_type is none %}
{% set all_obj = true %}
{% endif %}
SELECT obj_type, obj_name,
REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
schema_name, show_node, other_info,
CASE
WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
ELSE 'N'
END AS catalog_level
FROM (
{% if all_obj or obj_type in ['table', 'sequence', 'view', 'mview'] %}
SELECT
CASE
WHEN c.relkind = 'r' THEN 'table'
WHEN c.relkind = 'S' THEN 'sequence'
WHEN c.relkind = 'v' THEN 'view'
WHEN c.relkind = 'm' THEN 'mview'
ELSE 'should not happen'
END::text::text AS obj_type, c.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/' ||
CASE
WHEN c.relkind = 'r' THEN ':table.'
WHEN c.relkind = 'S' THEN ':sequence.'
WHEN c.relkind = 'v' THEN ':view.'
WHEN c.relkind = 'm' THEN ':mview.'
ELSE 'should not happen'
END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
CASE
WHEN c.relkind = 'r' THEN {{ show_node_prefs['table'] }}
WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
ELSE False
END AS show_node, NULL AS other_info
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
{% if all_obj %}
WHERE c.relkind in ('r','S','v','m')
{% elif obj_type == 'table' %}
WHERE c.relkind = 'r'
{% elif obj_type == 'sequence' %}
WHERE c.relkind = 'S'
{% elif obj_type == 'view' %}
WHERE c.relkind = 'v'
{% elif obj_type == 'mview' %}
WHERE c.relkind = 'm'
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['index'] %}
SELECT 'index'::text::text AS obj_type, cls.relname AS obj_name,
':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
JOIN pg_namespace n ON n.oid=tab.relnamespace
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
WHERE contype IS NULL
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %}
SELECT fd.obj_type, fd.obj_name,
CASE
WHEN fd.obj_type = 'function' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'procedure' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'trigger_function' THEN
':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'edbfunc' THEN
':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name
WHEN fd.obj_type = 'edbproc' THEN
':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name
ELSE NULL
END AS obj_path,
CASE
WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name
WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name
ELSE NULL
END AS schema_name,
CASE
WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }}
WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }}
WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }}
WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }}
WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }}
ELSE NULL
END AS show_node, other_info
FROM (
SELECT
CASE
WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
WHEN pr.protype = '0'::char THEN
CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END
WHEN pr.protype = '1'::char THEN
CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END
ELSE null
END::text::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name,
pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info
FROM pg_proc pr left join pg_namespace n
ON pr.pronamespace = n.oid left JOIN pg_namespace np
ON np.oid=n.nspparent left JOIN pg_type t
ON t.oid = pr.prorettype left JOIN pg_language l
ON l.oid = pr.prolang
WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl')
AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }})
) fd
{% if not all_obj %}
WHERE fd.obj_type = '{{ obj_type }}'
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['event_trigger'] %}
select 'event_trigger'::text::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['schema'] %}
select 'schema'::text::text AS obj_type, n.nspname AS obj_name,
':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
{{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
where n.nspparent = 0
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['column'] %}
select 'column'::text::text AS obj_type, a.attname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/' ||
case
WHEN t.relkind = 'r' THEN ':table.'
WHEN t.relkind = 'v' THEN ':view.'
WHEN t.relkind = 'm' THEN ':mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
from pg_attribute a
inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
SELECT
CASE
WHEN c.contype = 'c' THEN 'check_constraint'
WHEN c.contype = 'f' THEN 'foreign_key'
WHEN c.contype = 'p' THEN 'primary_key'
WHEN c.contype = 'u' THEN 'unique_constraint'
WHEN c.contype = 'x' THEN 'exclusion_constraint'
END::text::text AS obj_type,
case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
':schema.'||n.oid||':/' || n.nspname||'/:table.'|| t.oid || ':/'||t.relname||
CASE
WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid
WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid
WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid
WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid
WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid
END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
from pg_constraint c
left join pg_class t on c.conrelid = t.oid
left join pg_class tf on c.confrelid = tf.oid
left join pg_namespace n on t.relnamespace = n.oid
where c.contypid = 0
{% if obj_type == 'check_constraint' %}
AND c.contype = 'c'
{% elif obj_type == 'foreign_key' %}
AND c.contype = 'f'
{% elif obj_type == 'primary_key' %}
AND c.contype = 'p'
{% elif obj_type == 'unique_constraint' %}
AND c.contype = 'u'
{% elif obj_type == 'exclusion_constraint' %}
AND c.contype = 'x'
{% else %}
AND c.contype IN ('c', 'f', 'p', 'u', 'x')
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['rule'] %}
select 'rule'::text::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
case
WHEN t.relkind = 'r' THEN '/:table.'
when t.relkind = 'v' then '/:view.'
when t.relkind = 'm' then '/:mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
from pg_rewrite r
left join pg_class t on r.ev_class = t.oid
left join pg_namespace n on t.relnamespace = n.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['trigger'] %}
select 'trigger'::text::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
case
WHEN t.relkind = 'r' THEN '/:table.'
when t.relkind = 'v' then '/:view.'
when t.relkind = 'm' then '/:mview.'
else 'should not happen'
end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
from pg_trigger tr
left join pg_class t on tr.tgrelid = t.oid
left join pg_namespace n on t.relnamespace = n.oid
where tr.tgisinternal = false
and {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['type'] %}
SELECT 'type'::text::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
'/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
FROM pg_type t
LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
{% if not show_system_objects %}
AND ct.oid is NULL
{% endif %}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['cast'] %}
SELECT 'cast'::text::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
{% if not show_system_objects %}
WHERE ca.oid > {{last_system_oid}}::OID
{% endif %}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['language'] %}
SELECT 'language'::text::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
FROM pg_language lan
WHERE lanispl IS TRUE
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_configuration'] %}
SELECT 'fts_configuration'::text::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
FROM pg_ts_config cfg
left join pg_namespace n on cfg.cfgnamespace = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_dictionary'] %}
SELECT 'fts_dictionary'::text::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
FROM pg_ts_dict dict
left join pg_namespace ns on dict.dictnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_parser'] %}
SELECT 'fts_parser'::text::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
FROM pg_ts_parser prs
left join pg_namespace ns on prs.prsnamespace = ns.oid
WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['fts_template'] %}
SELECT 'fts_template'::text::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
FROM pg_ts_template tmpl
left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
AND {{ CATALOGS.DB_SUPPORT('ns') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain'] %}
select 'domain'::text::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
from pg_type t
inner join pg_namespace n on t.typnamespace = n.oid
where t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['domain_constraints'] %}
SELECT 'domain_constraints'::text::text AS obj_type,
c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
n.nspname AS schema_name,
{{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
FROM pg_constraint c JOIN pg_type t
ON t.oid=contypid JOIN pg_namespace n
ON n.oid=t.typnamespace
WHERE t.typtype = 'd'
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
from pg_foreign_data_wrapper
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_server'] %}
select 'foreign_server'::text AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
from pg_foreign_server sr
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['user_mapping'] %}
select 'user_mapping'::text AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
from pg_user_mapping um
inner join pg_roles ro on um.umuser = ro.oid
inner join pg_foreign_server sr on um.umserver = sr.oid
inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['foreign_table'] %}
select 'foreign_table'::text AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
{{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
from pg_foreign_table ft
inner join pg_class c on ft.ftrelid = c.oid
inner join pg_namespace ns on c.relnamespace = ns.oid
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['extension'] %}
select 'extension'::text AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
{{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
FROM pg_extension x
JOIN pg_namespace n on x.extnamespace=n.oid
join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['collation'] %}
SELECT 'collation'::text AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
FROM pg_collation c
JOIN pg_namespace n ON n.oid=c.collnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['synonym'] %}
SELECT 'synonym'::text AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info
FROM pg_synonym s
JOIN pg_namespace n ON n.oid=s.synnamespace
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['package'] %}
SELECT 'package'::text AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['package'] }} AS show_node, NULL AS other_info
FROM pg_namespace p
JOIN pg_namespace n ON n.oid=p.nspparent
WHERE {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
{% if all_obj %}
UNION
{% endif %}
{% if all_obj or obj_type in ['edbvar'] %}
SELECT 'edbvar'::text AS obj_type, v.varname AS obj_name,
':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name,
{{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info
FROM edb_variable v JOIN pg_namespace p
ON v.varpackage = p.oid JOIN pg_namespace n
ON p.nspparent = n.oid
WHERE {{ CATALOGS.DB_SUPPORT('p') }}
AND {{ CATALOGS.DB_SUPPORT('n') }}
{% endif %}
) sn
where lower(sn.obj_name) like '%{{ search_text }}%'
{% if not show_system_objects %}
AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
{% endif %}
ORDER BY 1, 2, 3

View File

@@ -0,0 +1,75 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
from __future__ import print_function
import sys
import json
from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
database_utils
from regression.python_test_utils import test_utils as utils
try:
from urllib import urlencode
except Exception as e:
from urllib.parse import urlencode
class SearchObjectsApiSearch(BaseTestGenerator):
""" This class will test search API of search objects. """
scenarios = [
('Search with all types', dict(text='emp', type='all', singles=False)),
('Search with None types', dict(text='emp', type=None, singles=False)),
('Search for all single types',
dict(text='emp', type=None, singles=True)),
]
def runFor(self, text=None, type=None):
url_params = dict(
text=text
)
if type is not None:
url_params['type'] = type
url_params = urlencode(url_params)
response = self.tester.get(self.base_url + '?' + url_params)
self.assertEquals(response.status_code, 200)
def runTest(self):
database_info = parent_node_dict["database"][-1]
server_id = database_info["server_id"]
db_id = database_info["db_id"]
db_con = database_utils.connect_database(self,
utils.SERVER_GROUP,
server_id,
db_id)
if not db_con["info"] == "Database connected.":
raise Exception("Could not connect to database to add the schema.")
self.base_url = '/search_objects/search/' \
+ str(server_id) + '/' + str(db_id)
if not self.singles:
self.runFor(text=self.text, type=self.type)
else:
# test for all the node types individually
types_url = '/search_objects/types/' +\
str(server_id) + '/' + str(db_id)
response = self.tester.get(types_url)
self.assertEquals(response.status_code, 200)
types_data = json.loads(response.data.decode('utf-8'))['data']
for a_type in types_data:
print('Running search for type {0}'.format(a_type),
file=sys.stderr)
self.runFor(text=self.text, type=a_type)

View File

@@ -0,0 +1,47 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
import json
from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
database_utils
from regression.python_test_utils import test_utils as utils
class SearchObjectsApiTypes(BaseTestGenerator):
""" This class will test types API of search objects. """
scenarios = [
# Fetching default URL for schema node.
('Types API URL', dict(url='/search_objects/types'))
]
def runTest(self):
database_info = parent_node_dict["database"][-1]
server_id = database_info["server_id"]
db_id = database_info["db_id"]
db_con = database_utils.connect_database(self,
utils.SERVER_GROUP,
server_id,
db_id)
if not db_con["info"] == "Database connected.":
raise Exception("Could not connect to database to add the schema.")
url = self.url + '/' + str(server_id) + '/' + str(db_id)
response = self.tester.get(url)
self.assertEquals(response.status_code, 200)
# repsonse data should be dict
response_data = json.loads(response.data.decode('utf-8'))['data']
self.assertEquals(type(response_data), dict)
# response data key values should not be None
for key, value in response_data.items():
self.assertIsNotNone(value, 'Key {0} has value None'.format(key))

View File

@@ -0,0 +1,117 @@
import sys
from pgadmin.tools.search_objects.utils import SearchObjectsHelper, current_app
from pgadmin.utils.route import BaseTestGenerator
if sys.version_info < (3, 3):
from mock import patch, MagicMock
else:
from unittest.mock import patch, MagicMock
class SearchObjectsHelperTest(BaseTestGenerator):
scenarios = [
('scenario', dict(
node_blueprints=[
dict(node_type='table', coll_label='Tables',
backend_supported=True),
dict(node_type='view', coll_label='Views',
backend_supported=False),
dict(node_type='index', coll_label='Indexes',
backend_supported=True),
dict(node_type='role', coll_label='Roles',
backend_supported=True)
],
all_node_types=['table', 'view', 'index'],
expected_show_node_prefs=dict(table=True, view=False, index=True),
expected_supported_types=dict(table='Tables', index='Indexes'),
expected_supported_types_skip=dict(table='Tables', view='Views',
index='Indexes'),
execute_dict_return_value=(
True, dict(rows=[
dict(obj_name='name1', obj_type='table',
obj_path='some/path', show_node=True,
other_info=None, catalog_level='N'),
dict(obj_name='name2', obj_type='view',
obj_path='some1/path', show_node=True,
other_info=None, catalog_level='D'),
dict(obj_name='name3', obj_type='index',
obj_path='some2/path1', show_node=True,
other_info='oid', catalog_level='O'),
])),
expected_search_op=(
True, [
dict(name='name1', type='table', type_label='Tables',
path='some/path',
show_node=True, other_info=None, catalog_level='N'),
dict(name='name2', type='view', type_label='Views',
path='some1/path',
show_node=True, other_info=None, catalog_level='D'),
dict(name='name3', type='index', type_label='Indexes',
path='some2/path1',
show_node=True, other_info='oid', catalog_level='O'),
]
)
))
]
def __create_manager(self):
connection = MagicMock(
execute_dict=MagicMock(),
db='somedb'
)
connection.execute_dict.return_value = self.execute_dict_return_value
def connection_function(did):
return connection
return MagicMock(
connection=connection_function
)
@patch('pgadmin.tools.search_objects.utils.get_node_blueprint')
@patch('pgadmin.tools.search_objects.utils.get_driver')
def runTest(self, get_driver_mock, get_node_blueprint_mock):
manager = self.__create_manager()
get_driver_mock.return_value = MagicMock(
connection_manager=lambda session_id: manager)
def __get_node_blueprint_mock(node_type):
blueprints = self.node_blueprints
blueprint = None
for data in blueprints:
if node_type == data['node_type']:
blueprint = MagicMock(
BackendSupported=MagicMock(
return_value=data['backend_supported']),
collection_label=data['coll_label'],
show_node=data['backend_supported'],
)
return blueprint
get_node_blueprint_mock.side_effect = __get_node_blueprint_mock
with self.app.app_context():
so_obj = SearchObjectsHelper(2, 18456,
node_types=self.all_node_types)
so_obj.get_sql = MagicMock(return_value='dummy query')
# test template path
manager.server_type = 'pg'
manager.version = 906000
self.assertEquals(so_obj.get_template_path(),
'search_objects/sql/pg/#906000#')
self.assertEquals(so_obj.get_show_node_prefs(),
self.expected_show_node_prefs)
self.assertEquals(so_obj.get_supported_types(),
self.expected_supported_types)
self.assertEquals(so_obj.get_supported_types(skip_check=True),
self.expected_supported_types_skip)
self.assertEquals(so_obj.search('searchtext', 'all'),
self.expected_search_op)

View File

@@ -0,0 +1,131 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
from flask import current_app, render_template
from flask_babelex import gettext
from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER
def get_node_blueprint(node_type):
blueprint = None
node_type = 'NODE-' + node_type
if node_type in current_app.blueprints:
blueprint = current_app.blueprints[node_type]
return blueprint
class SearchObjectsHelper:
def __init__(self, sid, did, show_system_objects=False, node_types=None):
self.sid = sid
self.did = did
self.show_system_objects = show_system_objects
self.manager = get_driver(
PG_DEFAULT_DRIVER
).connection_manager(sid)
self._all_node_types = [
'cast', 'fts_dictionary', 'check_constraint',
'exclusion_constraint', 'foreign_key',
'primary_key', 'unique_constraint', 'constraints', 'trigger',
'table', 'compound_trigger', 'rule', 'column', 'partition',
'index', 'type', 'domain', 'domain_constraints', 'schema',
'synonym', 'sequence', 'edbvar', 'edbfunc', 'edbproc', 'package',
'foreign_table', 'fts_parser', 'function', 'procedure',
'trigger_function', 'fts_template', 'collation', 'view', 'mview',
'fts_configuration', 'extension', 'language',
'event_trigger', 'foreign_server', 'user_mapping',
'foreign_data_wrapper'
] if node_types is None else node_types
@property
def all_node_types(self):
return self._all_node_types
def get_template_path(self):
return 'search_objects/sql/{0}/#{1}#'.format(
self.manager.server_type, self.manager.version)
def get_show_node_prefs(self):
return_types = {}
for node_type in self.all_node_types:
blueprint = get_node_blueprint(node_type)
if blueprint is None:
continue
return_types[node_type] = blueprint.show_node
return return_types
def get_supported_types(self, skip_check=False):
return_types = {}
for node_type in self.all_node_types:
blueprint = get_node_blueprint(node_type)
if blueprint is None:
continue
if blueprint.BackendSupported(self.manager, is_catalog=False,
did=self.did) or skip_check:
if node_type in ['edbfunc', 'edbproc']:
return_types[node_type] =\
gettext('Package {0}').format(
blueprint.collection_label)
else:
return_types[node_type] = blueprint.collection_label
return return_types
def get_sql(self, sql_file, **kwargs):
return render_template(
"/".join([self.get_template_path(), sql_file]),
**kwargs
)
def finalize_id_path(self, path, base_path):
if base_path is not None:
path = '{0}/{1}'.format(base_path, path)
return path
def search(self, text, obj_type=None):
conn = self.manager.connection(did=self.did)
last_system_oid = (self.manager.db_info[self.did])['datlastsysoid'] \
if self.manager.db_info is not None and self.did in \
self.manager.db_info else 0
show_node_prefs = self.get_show_node_prefs()
node_labels = self.get_supported_types(skip_check=True)
# Column catalog_level has values as
# N - Not a catalog schema
# D - Catalog schema with DB support - pg_catalog
# O - Catalog schema with object support only - info schema, dbo, sys
status, res = conn.execute_dict(
self.get_sql('search.sql', search_text=text, obj_type=obj_type,
show_system_objects=self.show_system_objects,
show_node_prefs=show_node_prefs, _=gettext,
last_system_oid=last_system_oid)
)
if not status:
return status, res
ret_val = [
{
'name': row['obj_name'],
'type': row['obj_type'],
'type_label': node_labels[row['obj_type']],
'path': row['obj_path'],
'show_node': row['show_node'],
'other_info': row['other_info'],
'catalog_level': row['catalog_level'],
}
for row in res['rows']
]
return True, ret_val

View File

@@ -112,7 +112,7 @@ li {
font-size: 9pt;
}
.slick-header-column.ui-state-default {
#datagrid .slick-header-column.ui-state-default {
height: 32px !important;
}