in packages/@aws-cdk/aws-redshift-alpha/lib/private/database-query-provider/table.ts [89:226]
async function updateTable(
tableName: string,
tableNamePrefix: string,
tableNameSuffix: string,
tableColumns: Column[],
useColumnIds: boolean,
tableAndClusterProps: TableAndClusterProps,
oldResourceProperties: TableAndClusterProps,
isTableV2: boolean,
): Promise<string> {
const alterationStatements: string[] = [];
const newTableName = tableNamePrefix + tableNameSuffix;
const oldClusterProps = oldResourceProperties;
if (tableAndClusterProps.clusterName !== oldClusterProps.clusterName || tableAndClusterProps.databaseName !== oldClusterProps.databaseName) {
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps);
}
const oldTableColumns = oldResourceProperties.tableColumns;
const columnDeletions = oldTableColumns.filter(oldColumn => (
tableColumns.every(column => {
if (useColumnIds) {
return oldColumn.id ? oldColumn.id !== column.id : oldColumn.name !== column.name;
}
return oldColumn.name !== column.name;
})
));
if (columnDeletions.length > 0) {
alterationStatements.push(...columnDeletions.map(column => `ALTER TABLE ${tableName} DROP COLUMN ${column.name}`));
}
const columnAdditions = tableColumns.filter(column => {
return !oldTableColumns.some(oldColumn => {
if (useColumnIds) {
return oldColumn.id ? oldColumn.id === column.id : oldColumn.name === column.name;
}
return oldColumn.name === column.name;
});
}).map(column => `ADD ${column.name} ${column.dataType}`);
if (columnAdditions.length > 0) {
alterationStatements.push(...columnAdditions.map(addition => `ALTER TABLE ${tableName} ${addition}`));
}
const columnEncoding = tableColumns.filter(column => {
return oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.encoding !== oldColumn.encoding);
}).map(column => `ALTER COLUMN ${column.name} ENCODE ${column.encoding || 'AUTO'}`);
if (columnEncoding.length > 0) {
alterationStatements.push(`ALTER TABLE ${tableName} ${columnEncoding.join(', ')}`);
}
const columnComments = tableColumns.filter(column => {
return oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.comment !== oldColumn.comment);
}).map(column => `COMMENT ON COLUMN ${tableName}.${column.name} IS ${column.comment ? `'${column.comment}'` : 'NULL'}`);
if (columnComments.length > 0) {
alterationStatements.push(...columnComments);
}
if (useColumnIds) {
const columnNameUpdates = tableColumns.reduce((updates, column) => {
const oldColumn = oldTableColumns.find(oldCol => oldCol.id && oldCol.id === column.id);
if (oldColumn && oldColumn.name !== column.name) {
updates[oldColumn.name] = column.name;
}
return updates;
}, {} as Record<string, string>);
if (Object.keys(columnNameUpdates).length > 0) {
alterationStatements.push(...Object.entries(columnNameUpdates).map(([oldName, newName]) => (
`ALTER TABLE ${tableName} RENAME COLUMN ${oldName} TO ${newName}`
)));
}
}
const oldDistStyle = oldResourceProperties.distStyle;
if ((!oldDistStyle && tableAndClusterProps.distStyle) ||
(oldDistStyle && !tableAndClusterProps.distStyle)) {
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps);
} else if (oldDistStyle !== tableAndClusterProps.distStyle) {
alterationStatements.push(`ALTER TABLE ${tableName} ALTER DISTSTYLE ${tableAndClusterProps.distStyle}`);
}
const oldDistKey = getDistKeyColumn(oldTableColumns)?.name;
const newDistKey = getDistKeyColumn(tableColumns)?.name;
if (!oldDistKey && newDistKey) {
// Table has no existing distribution key, add a new one
alterationStatements.push(`ALTER TABLE ${tableName} ALTER DISTSTYLE KEY DISTKEY ${newDistKey}`);
} else if (oldDistKey && !newDistKey) {
// Table has a distribution key, remove and set to AUTO
alterationStatements.push(`ALTER TABLE ${tableName} ALTER DISTSTYLE AUTO`);
} else if (oldDistKey !== newDistKey) {
// Table has an existing distribution key, change it
alterationStatements.push(`ALTER TABLE ${tableName} ALTER DISTKEY ${newDistKey}`);
}
const oldSortKeyColumns = getSortKeyColumns(oldTableColumns);
const newSortKeyColumns = getSortKeyColumns(tableColumns);
const oldSortStyle = oldResourceProperties.sortStyle;
const newSortStyle = tableAndClusterProps.sortStyle;
if ((oldSortStyle === newSortStyle && !areColumnsEqual(oldSortKeyColumns, newSortKeyColumns))
|| (oldSortStyle !== newSortStyle)) {
switch (newSortStyle) {
case TableSortStyle.INTERLEAVED:
// INTERLEAVED sort key addition requires replacement.
// https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps);
case TableSortStyle.COMPOUND: {
const sortKeyColumnsString = getSortKeyColumnsString(newSortKeyColumns);
alterationStatements.push(`ALTER TABLE ${tableName} ALTER ${newSortStyle} SORTKEY(${sortKeyColumnsString})`);
break;
}
case TableSortStyle.AUTO: {
alterationStatements.push(`ALTER TABLE ${tableName} ALTER SORTKEY ${newSortStyle}`);
break;
}
}
}
const oldComment = oldResourceProperties.tableComment;
const newComment = tableAndClusterProps.tableComment;
if (oldComment !== newComment) {
alterationStatements.push(`COMMENT ON TABLE ${tableName} IS ${newComment ? `'${newComment}'` : 'NULL'}`);
}
// Limited by human input
// eslint-disable-next-line @cdklabs/promiseall-no-unbounded-parallelism
await Promise.all(alterationStatements.map(statement => executeStatement(statement, tableAndClusterProps)));
if (isTableV2) {
const oldTableNamePrefix = oldResourceProperties.tableName.prefix;
if (tableNamePrefix !== oldTableNamePrefix) {
await executeStatement(`ALTER TABLE ${tableName} RENAME TO ${newTableName}`, tableAndClusterProps);
return tableNamePrefix + tableNameSuffix;
}
}
return tableName;
}