Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions reverse_engineering/helpers/postgresHelpers/viewHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const removeViewNameSuffix = name => name.slice(0, -VIEW_SUFFIX.length);
const setViewSuffix = name => `${name}${VIEW_SUFFIX}`;

const generateCreateViewScript = (viewName, viewData, viewDefinitionFallback = {}) => {
const selectStatement = _.trim(viewData.view_definition || viewDefinitionFallback.definition || '');
const selectStatement = _.trim(viewData?.view_definition || viewDefinitionFallback.definition || '');

if (!selectStatement) {
return '';
Expand All @@ -20,13 +20,13 @@ const generateCreateViewScript = (viewName, viewData, viewDefinitionFallback = {
return `CREATE VIEW ${wrapInQuotes(viewName)} AS ${selectStatement}`;
};

const prepareViewData = (viewData, viewOptions, triggers, tableToastOptions) => {
const prepareViewData = ({ viewData, viewOptions, triggers, tableToastOptions, isRecursive }) => {
const data = {
withCheckOption: viewData.check_option !== 'NONE' || _.isNil(viewData.check_option),
checkTestingScope: getCheckTestingScope(viewData.check_option),
withCheckOption: viewData?.check_option !== 'NONE' || _.isNil(viewData?.check_option),
checkTestingScope: getCheckTestingScope(viewData?.check_option),
viewOptions: _.fromPairs(_.map(viewOptions?.view_options, splitByEqualitySymbol)),
temporary: viewOptions?.persistence === 't',
recursive: isViewRecursive(viewData),
recursive: isRecursive,
description: viewOptions?.description,
triggers,
...prepareMaterializedViewData({ viewData, viewOptions, tableToastOptions }),
Expand All @@ -36,9 +36,9 @@ const prepareViewData = (viewData, viewOptions, triggers, tableToastOptions) =>

const prepareMaterializedViewData = ({ viewData, viewOptions, tableToastOptions }) => {
return {
...(viewData.table_type && { materialized: viewData.table_type === TABLE_TYPE.materializedView }),
...(viewData.view_tablespace_name && { view_tablespace_name: viewData.view_tablespace_name }),
...(viewData.is_populated && { withDataOption: viewData.is_populated }),
...(viewData?.table_type && { materialized: viewData.table_type === TABLE_TYPE.materializedView }),
...(viewData?.view_tablespace_name && { view_tablespace_name: viewData.view_tablespace_name }),
...(viewData?.is_populated && { withDataOption: viewData.is_populated }),
...(viewOptions?.view_options && {
storage_parameter: prepareStorageParameters(viewOptions.view_options, tableToastOptions),
}),
Expand All @@ -53,8 +53,8 @@ const getCheckTestingScope = check_option => {
return check_option;
};

const isViewRecursive = viewData => {
return _.startsWith(_.trim(viewData.view_definition), 'WITH RECURSIVE');
const isViewRecursive = viewDefinition => {
return _.startsWith(_.trim(viewDefinition), 'WITH RECURSIVE');
};

const splitByEqualitySymbol = item => _.split(item, '=');
Expand All @@ -66,4 +66,5 @@ module.exports = {
generateCreateViewScript,
setViewSuffix,
prepareViewData,
isViewRecursive,
};
24 changes: 22 additions & 2 deletions reverse_engineering/helpers/postgresService.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const {
generateCreateViewScript,
setViewSuffix,
prepareViewData,
isViewRecursive,
} = require('./postgresHelpers/viewHelper');
const { getTriggers } = require('./postgresHelpers/triggerHelper');
const queryConstants = require('./queryConstants');
Expand Down Expand Up @@ -329,6 +330,18 @@ module.exports = {
logger.progress('Get columns', schemaName, tableName);

const tableColumns = await db.query(queryConstants.GET_TABLE_COLUMNS, [tableName, schemaName]);

// If information_schema.columns returns empty results, it might be due to permission issues
// Fall back to pg_catalog tables which are more accessible
if (tableColumns.length === 0) {
logger.info('No columns returned from information_schema.columns, falling back to pg_catalog tables', {
schemaName,
tableName,
});

return await this._getTableColumnsFromCatalog(tableName, schemaName, tableOid);
}

const tableColumnsAdditionalData = await db.queryTolerant(queryConstants.GET_TABLE_COLUMNS_ADDITIONAL_DATA, [
tableOid,
]);
Expand All @@ -341,6 +354,12 @@ module.exports = {
});
},

async _getTableColumnsFromCatalog(tableName, schemaName, tableOid) {
logger.progress('Get columns from pg_catalog', schemaName, tableName);

return await db.queryTolerant(queryConstants.GET_TABLE_COLUMNS_FROM_CATALOG, [tableOid]);
},

async _getDocuments(schemaName, tableName, attributes, recordSamplingSettings) {
logger.progress('Sampling table', schemaName, tableName);

Expand Down Expand Up @@ -377,7 +396,7 @@ module.exports = {
(await db.query(queryConstants.GET_VIEW_DATA, [viewName, schemaName], true)) ??
(await db.query(queryConstants.GET_MATERIALIZED_VIEW_DATA, [viewName, schemaName], true));
const viewDefinitionFallback =
!viewData.view_definition &&
!viewData?.view_definition &&
(await db.queryTolerant(queryConstants.GET_VIEW_SELECT_STMT_FALLBACK, [viewName, schemaName], true));
const viewOptions = await db.queryTolerant(queryConstants.GET_VIEW_OPTIONS, [viewName, schemaOid], true);
const triggers = await this._getTriggers(
Expand All @@ -394,7 +413,8 @@ module.exports = {
);

const script = generateCreateViewScript(viewName, viewData, viewDefinitionFallback);
const data = prepareViewData(viewData, viewOptions, triggers, tableToastOptions);
const isRecursive = isViewRecursive(viewData?.view_definition || viewDefinitionFallback);
const data = prepareViewData({ viewData, viewOptions, triggers, tableToastOptions, isRecursive });

if (!script) {
logger.info('View select statement was not retrieved', { schemaName, viewName });
Expand Down
Loading