Skip to content

Commit

Permalink
HCK-7856: FE DDL of CREATE VIEW should include column_list with colum…
Browse files Browse the repository at this point in the history
…n comment (#241)

* HCK-7856: Include column_list to a view

* HCK-7856: Update comment statement

* HCK-7856: refactor getViewScript

* HCK-7856: Fix the issue with wrong comment placement

* HCK-7856: Restore formatter settings

* HCK-7856: Fix template

* HCK-7856: Improve formatting
  • Loading branch information
Nightlngale authored Nov 25, 2024
1 parent 34bdd6a commit dbd967d
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 48 deletions.
2 changes: 2 additions & 0 deletions forward_engineering/ddlProvider/ddlTemplates.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
module.exports = {
createView:
'CREATE ${orReplace}${global}${temporary} VIEW${ifNotExists} ${name}${columnList}${schemaBinding}${comment}${tablePropertyStatements}${query};${viewUnityTagsStatements}',
dropView: 'DROP VIEW IF EXISTS ${name};',

alterViewName: 'ALTER VIEW ${oldName} RENAME TO ${newName};',
Expand Down
105 changes: 57 additions & 48 deletions forward_engineering/helpers/viewHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
const { prepareName, encodeStringLiteral, commentDeactivatedStatement } = require('../utils/general');
const { getTablePropertiesClause } = require('./tableHelper');
const { getViewTagsStatement } = require('./unityTagsHelper');
const ddlTemplates = require('../ddlProvider/ddlTemplates');
const assignTemplates = require('../utils/assignTemplates');

const getColumnNames = _ => (collectionRefsDefinitionsMap, columns) => {
return _.uniq(
Expand Down Expand Up @@ -85,9 +87,42 @@ function joinColumnNames(statements) {
.join('\n');
}

function getCommentStatement(comment) {
return comment ? `COMMENT '${encodeStringLiteral(comment)}'` : '';
}

function getDefaultColumnList(properties) {
const list = Object.entries(properties)
.reduce((columnList, [name, property]) => {
columnList.push({
name: `${prepareName(name)}`,
comment: property.description,
isActivated: property.isActivated,
});

return columnList;
}, [])
.map(({ name, comment, isActivated }) => {
return commentDeactivatedStatement(`${name} ${getCommentStatement(comment)}`, isActivated);
})
.join(',\n');

return list ? `\n(${list}\n)` : '';
}

function getTableSelectStatement({ _, collectionRefsDefinitionsMap, columns }) {
const fromStatement = getFromStatement(_)(collectionRefsDefinitionsMap, columns);
const columnsNames = getColumnNames(_)(collectionRefsDefinitionsMap, columns);

if (fromStatement && columnsNames?.length) {
return `\nAS SELECT ${joinColumnNames(columnsNames)}\n${fromStatement}`;
}

return '';
}

module.exports = {
getViewScript({ _, schema, viewData, containerData, collectionRefsDefinitionsMap }) {
let script = [];
const columns = schema.properties || {};
const view = _.first(viewData) || {};

Expand All @@ -102,60 +137,34 @@ module.exports = {
const orReplace = schema.viewOrReplace;
const ifNotExists = view.viewIfNotExist;
const name = bucketName ? `${bucketName}.${viewName}` : `${viewName}`;
const createStatement = `CREATE ${orReplace && !ifNotExists ? 'OR REPLACE ' : ''}${isGlobal ? 'GLOBAL ' : ''}${isTemporary ? 'TEMPORARY ' : ''}VIEW${ifNotExists ? ' IF NOT EXISTS' : ''} ${name}`;
const comment = schema.description;
let tablePropertyStatements = '';
const tableProperties =
schema.tableProperties && Array.isArray(schema.tableProperties)
? filterRedundantProperties(schema.tableProperties, ['transient_lastDdlTime'])
: [];
const viewUnityTagsStatements =
schema.unityViewTags && getViewTagsStatement({ viewSchema: schema, viewName: name });

if (tableProperties.length) {
tablePropertyStatements = ` TBLPROPERTIES (${getTablePropertiesClause(_)(tableProperties)})`;
}
script.push(createStatement);
if (schema.selectStatement) {
const columnList = view.columnList ? ` (${view.columnList})` : ' ';
return (
createStatement +
`${columnList} ${comment ? " COMMENT '" + encodeStringLiteral(comment) + "'" : ''} ${tablePropertyStatements} AS ${schema.selectStatement};\n\n${viewUnityTagsStatements}`
);
}

if (_.isEmpty(columns)) {
return;
}

if (comment) {
script.push(`COMMENT '${encodeStringLiteral(comment)}'`);
}

if (tablePropertyStatements) {
script.push(tablePropertyStatements);
}

if (!_.isEmpty(columns)) {
const fromStatement = getFromStatement(_)(collectionRefsDefinitionsMap, columns);
const columnsNames = getColumnNames(_)(collectionRefsDefinitionsMap, columns);

if (fromStatement && columnsNames?.length) {
script.push(`AS SELECT ${joinColumnNames(columnsNames)}`);
script.push(fromStatement);
} else {
return;
}
}

if (viewUnityTagsStatements) {
script.push(';\n');
script.push(viewUnityTagsStatements);

return script.join('\n ');
}

return script.join('\n ') + ';\n\n\n\n\n';
return assignTemplates(ddlTemplates.createView, {
orReplace: orReplace && !ifNotExists ? 'OR REPLACE ' : '',
global: isGlobal ? 'GLOBAL ' : '',
temporary: isTemporary ? 'TEMPORARY ' : '',
ifNotExists: ifNotExists ? ' IF NOT EXISTS' : '',
name,
columnList: view.columnList ? `\n(${view.columnList})` : getDefaultColumnList(columns),
schemaBinding: '',
comment: getCommentStatement(schema.description),
tablePropertyStatements: tableProperties.length
? `\nTBLPROPERTIES (${getTablePropertiesClause(_)(tableProperties)})`
: '',
query: schema.selectStatement
? `\nAS ${schema.selectStatement}`
: getTableSelectStatement({
_,
collectionRefsDefinitionsMap,
columns,
}),
viewUnityTagsStatements: viewUnityTagsStatements ? `\n${viewUnityTagsStatements};` : '',
});
},
};

Expand Down
15 changes: 15 additions & 0 deletions forward_engineering/utils/assignTemplates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const template = (modifiers = '') => new RegExp('\\$\\{(.*?)}', modifiers);
const getAllTemplates = str => str.match(template('gi')) || [];
const parseTemplate = str => (str.match(template('i')) || [])[1];

const assignTemplates = (str, templates) => {
return getAllTemplates(str).reduce((result, item) => {
const templateName = parseTemplate(item);

return result.replace(item, () => {
return templates[templateName] || templates[templateName] === 0 ? templates[templateName] : '';
});
}, str);
};

module.exports = assignTemplates;

0 comments on commit dbd967d

Please sign in to comment.