diff --git a/packages/datalib/src/ChangeSet.ts b/packages/datalib/src/ChangeSet.ts index d0b2e0f37..598c847ed 100644 --- a/packages/datalib/src/ChangeSet.ts +++ b/packages/datalib/src/ChangeSet.ts @@ -234,26 +234,56 @@ function extractFields( item: ChangeSetItem, allowNulls = true, allowedDocumentColumns: string[] = [], - table?: TableInfo + table?: TableInfo, + dialect?: SqlDialect ): UpdateField[] { const allFields = { ...item.fields, }; + function isUuidColumn(columnName: string): boolean { + return table?.columns.find(x => x.columnName == columnName)?.dataType.toLowerCase() == 'uuid'; + } + + function createUpdateField(targetColumn: string): UpdateField { + const shouldGenerateDefaultValue = + isUuidColumn(targetColumn) && allFields[targetColumn] == null && dialect?.generateDefaultValueForUuid; + + if (shouldGenerateDefaultValue) { + return { + targetColumn, + sql: dialect?.generateDefaultValueForUuid, + exprType: 'raw', + }; + } + + return { + targetColumn, + exprType: 'value', + value: allFields[targetColumn], + dataType: table?.columns?.find(x => x.columnName == targetColumn)?.dataType, + }; + } + for (const docField in item.document || {}) { if (allowedDocumentColumns.includes(docField)) { allFields[docField] = item.document[docField]; } } - return _.keys(allFields) - .filter(targetColumn => allowNulls || allFields[targetColumn] != null) - .map(targetColumn => ({ - targetColumn, - exprType: 'value', - value: allFields[targetColumn], - dataType: table?.columns?.find(x => x.columnName == targetColumn)?.dataType, - })); + const columnNames = Object.keys(allFields); + if (dialect?.generateDefaultValueForUuid && table) { + columnNames.push(...table.columns.map(i => i.columnName)); + } + + return _.uniq(columnNames) + .filter( + targetColumn => + allowNulls || + allFields[targetColumn] != null || + (isUuidColumn(targetColumn) && dialect?.generateDefaultValueForUuid) + ) + .map(targetColumn => createUpdateField(targetColumn)); } function changeSetInsertToSql( @@ -266,13 +296,13 @@ function changeSetInsertToSql( item, false, table?.columns?.map(x => x.columnName), - table + table, + dialect ); if (fields.length == 0) return null; let autoInc = false; if (table) { const autoIncCol = table.columns.find(x => x.autoIncrement); - // console.log('autoIncCol', autoIncCol); if (autoIncCol && fields.find(x => x.targetColumn == autoIncCol.columnName)) { autoInc = true; } diff --git a/packages/types/dialect.d.ts b/packages/types/dialect.d.ts index 7598bdc5b..9aabe7026 100644 --- a/packages/types/dialect.d.ts +++ b/packages/types/dialect.d.ts @@ -54,6 +54,7 @@ export interface SqlDialect { disableRenameTable?: boolean; defaultNewTableColumns?: ColumnInfo[]; sortingKeys?: boolean; + generateDefaultValueForUuid?: string; // syntax for create column: ALTER TABLE table ADD COLUMN column createColumnWithColumnKeyword?: boolean; diff --git a/plugins/dbgate-plugin-cassandra/src/frontend/driver.js b/plugins/dbgate-plugin-cassandra/src/frontend/driver.js index 3fe64d4e1..0920f45b4 100644 --- a/plugins/dbgate-plugin-cassandra/src/frontend/driver.js +++ b/plugins/dbgate-plugin-cassandra/src/frontend/driver.js @@ -21,6 +21,7 @@ const dialect = { createColumnWithColumnKeyword: true, specificNullabilityImplementation: true, disableRenameTable: true, + generateDefaultValueForUuid: 'uuid()', omitForeignKeys: true, omitUniqueConstraints: true, omitIndexes: true,