mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-20 00:17:44 +00:00
@@ -406,6 +406,7 @@ type columnInfo struct {
|
||||
NumericPrecision *int `json:"numeric_precision"`
|
||||
NumericScale *int `json:"numeric_scale"`
|
||||
CharacterMaximumLength *int `json:"character_maximum_length"`
|
||||
CharacterLengthUnit *string `json:"-"`
|
||||
}
|
||||
|
||||
type indexInfo struct {
|
||||
@@ -2309,7 +2310,8 @@ SELECT c.COLUMN_NAME,
|
||||
cc.COMMENTS,
|
||||
c.DATA_PRECISION,
|
||||
c.DATA_SCALE,
|
||||
c.CHAR_LENGTH
|
||||
c.CHAR_LENGTH,
|
||||
c.CHAR_USED
|
||||
FROM ALL_TAB_COLUMNS c
|
||||
LEFT JOIN (
|
||||
SELECT acc.OWNER, acc.TABLE_NAME, acc.COLUMN_NAME
|
||||
@@ -2339,6 +2341,7 @@ ORDER BY c.COLUMN_ID`, []any{schema, table})
|
||||
&item.NumericPrecision,
|
||||
&item.NumericScale,
|
||||
&item.CharacterMaximumLength,
|
||||
&item.CharacterLengthUnit,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -3038,6 +3041,9 @@ func oracleColumnTypeDDL(column columnInfo) string {
|
||||
return dataType
|
||||
}
|
||||
if isOracleCharacterType(dataType) && column.CharacterMaximumLength != nil && *column.CharacterMaximumLength > 0 {
|
||||
if unit := oracleCharacterLengthUnit(dataType, column.CharacterLengthUnit); unit != "" {
|
||||
return fmt.Sprintf("%s(%d %s)", dataType, *column.CharacterMaximumLength, unit)
|
||||
}
|
||||
return fmt.Sprintf("%s(%d)", dataType, *column.CharacterMaximumLength)
|
||||
}
|
||||
if dataType == "NUMBER" {
|
||||
@@ -3056,6 +3062,25 @@ func oracleColumnTypeDDL(column columnInfo) string {
|
||||
return dataType
|
||||
}
|
||||
|
||||
func oracleCharacterLengthUnit(dataType string, charUsed *string) string {
|
||||
switch dataType {
|
||||
case "CHAR", "VARCHAR", "VARCHAR2":
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
if charUsed == nil {
|
||||
return ""
|
||||
}
|
||||
switch strings.ToUpper(strings.TrimSpace(*charUsed)) {
|
||||
case "B":
|
||||
return "BYTE"
|
||||
case "C":
|
||||
return "CHAR"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func isOracleCharacterType(dataType string) bool {
|
||||
switch dataType {
|
||||
case "CHAR", "VARCHAR2", "VARCHAR", "NCHAR", "NVARCHAR2", "RAW":
|
||||
|
||||
@@ -536,9 +536,9 @@ func TestGetTableDDLFallbackPreservesQuotedColumnNames(t *testing.T) {
|
||||
args: []driver.Value{schema, table},
|
||||
columns: []string{
|
||||
"COLUMN_NAME", "DATA_TYPE", "NULLABLE", "DATA_DEFAULT", "IS_PRIMARY_KEY",
|
||||
"COMMENTS", "DATA_PRECISION", "DATA_SCALE", "CHAR_LENGTH",
|
||||
"COMMENTS", "DATA_PRECISION", "DATA_SCALE", "CHAR_LENGTH", "CHAR_USED",
|
||||
},
|
||||
rows: [][]driver.Value{{"FlowId", "VARCHAR2", "N", nil, int64(1), nil, nil, nil, int64(50)}},
|
||||
rows: [][]driver.Value{{"FlowId", "VARCHAR2", "N", nil, int64(1), nil, nil, nil, int64(50), "C"}},
|
||||
},
|
||||
})
|
||||
s := newServer()
|
||||
@@ -549,7 +549,7 @@ func TestGetTableDDLFallbackPreservesQuotedColumnNames(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := `CREATE TABLE "ZTZS_ERP2"."ZGJ_FlowSealTemplate" (
|
||||
"FlowId" VARCHAR2(50) NOT NULL,
|
||||
"FlowId" VARCHAR2(50 CHAR) NOT NULL,
|
||||
PRIMARY KEY ("FlowId")
|
||||
)`
|
||||
if got != want {
|
||||
@@ -961,6 +961,8 @@ func TestOracleColumnTypeDDL(t *testing.T) {
|
||||
precision := 10
|
||||
scale := 2
|
||||
zeroScale := 0
|
||||
byteUnit := "B"
|
||||
charUnit := "C"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -968,6 +970,9 @@ func TestOracleColumnTypeDDL(t *testing.T) {
|
||||
want string
|
||||
}{
|
||||
{name: "varchar", column: columnInfo{DataType: "VARCHAR2", CharacterMaximumLength: &charLen}, want: "VARCHAR2(64)"},
|
||||
{name: "varchar byte semantics", column: columnInfo{DataType: "VARCHAR2", CharacterMaximumLength: &charLen, CharacterLengthUnit: &byteUnit}, want: "VARCHAR2(64 BYTE)"},
|
||||
{name: "varchar char semantics", column: columnInfo{DataType: "VARCHAR2", CharacterMaximumLength: &charLen, CharacterLengthUnit: &charUnit}, want: "VARCHAR2(64 CHAR)"},
|
||||
{name: "national character type ignores unit", column: columnInfo{DataType: "NVARCHAR2", CharacterMaximumLength: &charLen, CharacterLengthUnit: &charUnit}, want: "NVARCHAR2(64)"},
|
||||
{name: "number scale", column: columnInfo{DataType: "NUMBER", NumericPrecision: &precision, NumericScale: &scale}, want: "NUMBER(10,2)"},
|
||||
{name: "number zero scale", column: columnInfo{DataType: "NUMBER", NumericPrecision: &precision, NumericScale: &zeroScale}, want: "NUMBER(10)"},
|
||||
{name: "timestamp preserves precision", column: columnInfo{DataType: "TIMESTAMP(6)"}, want: "TIMESTAMP(6)"},
|
||||
|
||||
@@ -73,7 +73,7 @@ import {
|
||||
parseExtraToColumnExtra,
|
||||
rehydrateColumnDraftsFromMetadata,
|
||||
resolveInsertColumnIndex,
|
||||
restoreDamengLengthUnitsAfterSave,
|
||||
restoreCharacterLengthUnitsAfterSave,
|
||||
sameStructureIndexType,
|
||||
splitDataType,
|
||||
toColumnNames,
|
||||
@@ -583,7 +583,7 @@ watch(localStructureDensity, (density, previousDensity) => {
|
||||
function onColResize(e: MouseEvent, col: number) {
|
||||
e.preventDefault();
|
||||
const widthIndex = columnWidthIndex(col);
|
||||
const minimumWidth = widthIndex === 3 && databaseType.value === "dameng" ? structureDensityMetric.value.minLengthColumnWidth : structureDensityMetric.value.minColumnWidth;
|
||||
const minimumWidth = widthIndex === 3 && supportsCharacterLengthUnits.value ? structureDensityMetric.value.minLengthColumnWidth : structureDensityMetric.value.minColumnWidth;
|
||||
colResizing.value = { col: widthIndex, startX: e.clientX, startW: Math.max(colWidths.value[widthIndex] ?? minimumWidth, minimumWidth) };
|
||||
const onMove = (ev: MouseEvent) => {
|
||||
if (!colResizing.value) return;
|
||||
@@ -622,6 +622,7 @@ function onIndexColResize(e: MouseEvent, col: number) {
|
||||
|
||||
const connection = computed(() => (props.connectionId ? store.getConfig(props.connectionId) : undefined));
|
||||
const databaseType = computed(() => tableStructureDatabaseTypeForConnection(connection.value));
|
||||
const supportsCharacterLengthUnits = computed(() => databaseType.value === "dameng" || databaseType.value === "oracle");
|
||||
const usesMysql8SafeDefaults = computed(() => databaseType.value === "mysql" && connection.value?.db_type === "mysql" && connection.value.driver_profile === "mysql");
|
||||
const structureCapabilities = computed(() => getTableStructureCapabilities(databaseType.value, connection.value?.db_type, connection.value?.database_info?.productVersion));
|
||||
const tableMetadataCapabilities = computed(() => getTableMetadataCapabilities(databaseType.value));
|
||||
@@ -772,7 +773,7 @@ const visibleColWidths = computed(() =>
|
||||
colLabels.value.map((column) => {
|
||||
if (column.key === "actions") return columnActionsWidth.value;
|
||||
const width = colWidths.value[column.widthIndex] ?? structureDensityMetric.value.minColumnWidth;
|
||||
return column.key === "length" && databaseType.value === "dameng" ? Math.max(width, structureDensityMetric.value.minLengthColumnWidth) : width;
|
||||
return column.key === "length" && supportsCharacterLengthUnits.value ? Math.max(width, structureDensityMetric.value.minLengthColumnWidth) : width;
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1299,7 +1300,7 @@ async function loadStructure(
|
||||
silent = false,
|
||||
scope: TableStructureRefreshScope = visibleTableStructureRefreshScope(activeTab.value),
|
||||
showErrors = true,
|
||||
options: { blockSecondaryMetadata?: boolean; preserveDraft?: boolean; damengLengthUnitsAfterSave?: ReadonlyMap<string, string>; forceDdl?: boolean; forceMetadata?: boolean } = {},
|
||||
options: { blockSecondaryMetadata?: boolean; preserveDraft?: boolean; characterLengthUnitsAfterSave?: ReadonlyMap<string, string>; forceDdl?: boolean; forceMetadata?: boolean } = {},
|
||||
) {
|
||||
const connectionId = props.connectionId;
|
||||
const database = props.database;
|
||||
@@ -1352,7 +1353,7 @@ async function loadStructure(
|
||||
// editor shows the correct options for the server version.
|
||||
void loadCharsetMetadata();
|
||||
const nextColumnDrafts = createColumnDrafts(nextColumns, databaseType.value);
|
||||
const hydratedColumnDrafts = databaseType.value === "dameng" && options.damengLengthUnitsAfterSave ? restoreDamengLengthUnitsAfterSave(nextColumnDrafts, options.damengLengthUnitsAfterSave) : nextColumnDrafts;
|
||||
const hydratedColumnDrafts = supportsCharacterLengthUnits.value && options.characterLengthUnitsAfterSave ? restoreCharacterLengthUnitsAfterSave(databaseType.value, nextColumnDrafts, options.characterLengthUnitsAfterSave) : nextColumnDrafts;
|
||||
columns.value = applyStoredLocalColumnOrder(hydratedColumnDrafts);
|
||||
loadedMetadataFacets.add("columns");
|
||||
if (!options.preserveDraft) selectedColumnId.value = null;
|
||||
@@ -1411,9 +1412,9 @@ async function loadStructure(
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshStructureAfterSave(scope: TableStructureRefreshScope, damengLengthUnitsAfterSave: ReadonlyMap<string, string>) {
|
||||
async function refreshStructureAfterSave(scope: TableStructureRefreshScope, characterLengthUnitsAfterSave: ReadonlyMap<string, string>) {
|
||||
try {
|
||||
await loadStructure(true, scope, false, { blockSecondaryMetadata: true, damengLengthUnitsAfterSave });
|
||||
await loadStructure(true, scope, false, { blockSecondaryMetadata: true, characterLengthUnitsAfterSave });
|
||||
} catch (e) {
|
||||
console.warn("[DBX][structure-editor:post-save-refresh-failed]", e);
|
||||
} finally {
|
||||
@@ -2325,11 +2326,11 @@ async function applyChanges() {
|
||||
saving.value = true;
|
||||
errorMessage.value = "";
|
||||
const refreshScope = captureStructureRefreshScope();
|
||||
const damengLengthUnitsAfterSave = new Map<string, string>();
|
||||
if (databaseType.value === "dameng") {
|
||||
const characterLengthUnitsAfterSave = new Map<string, string>();
|
||||
if (supportsCharacterLengthUnits.value) {
|
||||
for (const column of columns.value) {
|
||||
if (!column.markedForDrop && dataTypeLengthUnitValue("dameng", column.dataType)) {
|
||||
damengLengthUnitsAfterSave.set(column.name.trim().toLowerCase(), column.dataType);
|
||||
if (!column.markedForDrop && dataTypeLengthUnitValue(databaseType.value, column.dataType)) {
|
||||
characterLengthUnitsAfterSave.set(column.name.trim().toLowerCase(), column.dataType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2363,7 +2364,7 @@ async function applyChanges() {
|
||||
postSaveRefreshing.value = true;
|
||||
skipNextRefreshVersion = true;
|
||||
emit("saved", tableComment.value !== originalTableComment.value);
|
||||
await refreshStructureAfterSave(refreshScope, damengLengthUnitsAfterSave);
|
||||
await refreshStructureAfterSave(refreshScope, characterLengthUnitsAfterSave);
|
||||
}
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
parseExtraToColumnExtra,
|
||||
rehydrateColumnDraftsFromMetadata,
|
||||
resolveInsertColumnIndex,
|
||||
restoreDamengLengthUnitsAfterSave,
|
||||
restoreCharacterLengthUnitsAfterSave,
|
||||
splitDataType,
|
||||
} from "@/lib/table/tableStructureEditorState";
|
||||
|
||||
@@ -189,7 +189,7 @@ describe("tableStructureEditorState", () => {
|
||||
expect(combineDataTypeForDatabase("mysql", "integer", "11")).toBe("integer(11)");
|
||||
});
|
||||
|
||||
it("offers BYTE and CHAR units only for supported Dameng character types", () => {
|
||||
it("offers BYTE and CHAR units for supported Oracle-family character types", () => {
|
||||
expect(getDataTypeLengthUnitOptions("dameng", "varchar2(255 CHAR)")).toEqual(["BYTE", "CHAR"]);
|
||||
expect(getDataTypeLengthUnitOptions("dameng", "varchar(255)")).toEqual(["BYTE", "CHAR"]);
|
||||
expect(getDataTypeLengthUnitOptions("dameng", "char(10 BYTE)")).toEqual(["BYTE", "CHAR"]);
|
||||
@@ -197,7 +197,9 @@ describe("tableStructureEditorState", () => {
|
||||
expect(getDataTypeLengthUnitOptions("dameng", "nchar(10)")).toEqual([]);
|
||||
expect(getDataTypeLengthUnitOptions("dameng", "nvarchar2(10)")).toEqual([]);
|
||||
expect(getDataTypeLengthUnitOptions("dameng", "number(10,0)")).toEqual([]);
|
||||
expect(getDataTypeLengthUnitOptions("oracle", "varchar2(255 CHAR)")).toEqual([]);
|
||||
expect(getDataTypeLengthUnitOptions("oracle", "varchar2(255 CHAR)")).toEqual(["BYTE", "CHAR"]);
|
||||
expect(getDataTypeLengthUnitOptions("oracle", "char(10 BYTE)")).toEqual(["BYTE", "CHAR"]);
|
||||
expect(getDataTypeLengthUnitOptions("oracle", "nvarchar2(10)")).toEqual([]);
|
||||
expect(getDataTypeLengthUnitOptions("mysql", "varchar(255)")).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -213,6 +215,12 @@ describe("tableStructureEditorState", () => {
|
||||
expect(combineDataTypeForDatabaseWithLengthUnit("dameng", "varchar2", "255", "")).toBe("varchar2(255)");
|
||||
});
|
||||
|
||||
it("separates and reconstructs Oracle character length units", () => {
|
||||
expect(dataTypeLengthInputValue("oracle", "VARCHAR2(255 CHAR)")).toBe("255");
|
||||
expect(dataTypeLengthUnitValue("oracle", "VARCHAR2(255 CHAR)")).toBe("CHAR");
|
||||
expect(combineDataTypeForDatabaseWithLengthUnit("oracle", "VARCHAR2", "64", "BYTE")).toBe("VARCHAR2(64 BYTE)");
|
||||
});
|
||||
|
||||
it("does not reinterpret unsupported length parameters or dialects", () => {
|
||||
expect(dataTypeLengthInputValue("dameng", "varchar2(255 WORD)")).toBe("255 WORD");
|
||||
expect(dataTypeLengthUnitValue("dameng", "varchar2(255 WORD)")).toBe("");
|
||||
@@ -235,7 +243,7 @@ describe("tableStructureEditorState", () => {
|
||||
"dameng",
|
||||
);
|
||||
|
||||
const [restored] = restoreDamengLengthUnitsAfterSave([legacyAgentDraft!], new Map([["display_name", "VARCHAR2(255 CHAR)"]]));
|
||||
const [restored] = restoreCharacterLengthUnitsAfterSave("dameng", [legacyAgentDraft!], new Map([["display_name", "VARCHAR2(255 CHAR)"]]));
|
||||
|
||||
expect(restored?.dataType).toBe("VARCHAR2(255 CHAR)");
|
||||
expect(restored?.original?.data_type).toBe("VARCHAR2(255 CHAR)");
|
||||
@@ -256,12 +264,24 @@ describe("tableStructureEditorState", () => {
|
||||
"dameng",
|
||||
);
|
||||
|
||||
const [restored] = restoreDamengLengthUnitsAfterSave([liveDraft!], new Map([["display_name", "VARCHAR2(255 CHAR)"]]));
|
||||
const [restored] = restoreCharacterLengthUnitsAfterSave("dameng", [liveDraft!], new Map([["display_name", "VARCHAR2(255 CHAR)"]]));
|
||||
|
||||
expect(restored?.dataType).toBe("VARCHAR2(255 BYTE)");
|
||||
expect(restored?.original?.data_type).toBe("VARCHAR2(255 BYTE)");
|
||||
});
|
||||
|
||||
it("keeps a saved Oracle length unit when refreshed metadata omits it", () => {
|
||||
const [legacyAgentDraft] = createColumnDrafts(
|
||||
[{ name: "DISPLAY_NAME", data_type: "VARCHAR2(255)", is_nullable: true, column_default: null, is_primary_key: false, extra: null }],
|
||||
"oracle",
|
||||
);
|
||||
|
||||
const [restored] = restoreCharacterLengthUnitsAfterSave("oracle", [legacyAgentDraft!], new Map([["display_name", "VARCHAR2(255 CHAR)"]]));
|
||||
|
||||
expect(restored?.dataType).toBe("VARCHAR2(255 CHAR)");
|
||||
expect(restored?.original?.data_type).toBe("VARCHAR2(255 CHAR)");
|
||||
});
|
||||
|
||||
it("does not add MySQL display lengths when choosing SQLite-family types", () => {
|
||||
for (const databaseType of ["sqlite", "rqlite", "turso"] as const) {
|
||||
expect(getDefaultLengthForType(databaseType, "integer")).toBe("");
|
||||
|
||||
@@ -974,16 +974,16 @@ export function splitDataType(raw: string): { baseType: string; params: string }
|
||||
|
||||
export type DataTypeLengthUnit = "BYTE" | "CHAR";
|
||||
|
||||
const DAMENG_LENGTH_UNIT_TYPES = new Set(["char", "varchar", "varchar2"]);
|
||||
const DAMENG_LENGTH_UNITS: readonly DataTypeLengthUnit[] = ["BYTE", "CHAR"];
|
||||
const CHARACTER_LENGTH_UNIT_TYPES = new Set(["char", "varchar", "varchar2"]);
|
||||
const CHARACTER_LENGTH_UNITS: readonly DataTypeLengthUnit[] = ["BYTE", "CHAR"];
|
||||
|
||||
function normalizedDataTypeName(rawDataType: string): string {
|
||||
return splitDataType(rawDataType).baseType.trim().replace(/\s+/g, " ").toLowerCase();
|
||||
}
|
||||
|
||||
export function getDataTypeLengthUnitOptions(dbType: DatabaseType | undefined, rawDataType: string): readonly DataTypeLengthUnit[] {
|
||||
if (dbType !== "dameng") return [];
|
||||
return DAMENG_LENGTH_UNIT_TYPES.has(normalizedDataTypeName(rawDataType)) ? DAMENG_LENGTH_UNITS : [];
|
||||
if (dbType !== "dameng" && dbType !== "oracle") return [];
|
||||
return CHARACTER_LENGTH_UNIT_TYPES.has(normalizedDataTypeName(rawDataType)) ? CHARACTER_LENGTH_UNITS : [];
|
||||
}
|
||||
|
||||
function splitDataTypeLengthParams(dbType: DatabaseType | undefined, rawDataType: string): { length: string; unit: DataTypeLengthUnit | "" } {
|
||||
@@ -1015,13 +1015,13 @@ export function combineDataTypeForDatabaseWithLengthUnit(dbType: DatabaseType |
|
||||
return combineDataTypeForDatabase(dbType, baseType, params);
|
||||
}
|
||||
|
||||
export function restoreDamengLengthUnitsAfterSave(columns: EditableStructureColumn[], savedDataTypesByColumn: ReadonlyMap<string, string>): EditableStructureColumn[] {
|
||||
export function restoreCharacterLengthUnitsAfterSave(dbType: DatabaseType | undefined, columns: EditableStructureColumn[], savedDataTypesByColumn: ReadonlyMap<string, string>): EditableStructureColumn[] {
|
||||
if (savedDataTypesByColumn.size === 0) return columns;
|
||||
|
||||
return columns.map((column) => {
|
||||
if (dataTypeLengthUnitValue("dameng", column.dataType)) return column;
|
||||
if (dataTypeLengthUnitValue(dbType, column.dataType)) return column;
|
||||
const savedDataType = savedDataTypesByColumn.get(column.name.trim().toLowerCase());
|
||||
if (!savedDataType || !dataTypeLengthUnitValue("dameng", savedDataType)) return column;
|
||||
if (!savedDataType || !dataTypeLengthUnitValue(dbType, savedDataType)) return column;
|
||||
if (normalizedDataTypeName(savedDataType) !== normalizedDataTypeName(column.dataType)) return column;
|
||||
|
||||
return {
|
||||
|
||||
@@ -849,6 +849,57 @@ fn oracle_timestamp_default_precedes_nullability_in_modify_sql() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oracle_create_table_preserves_character_length_units() {
|
||||
let mut byte_col = column("BYTE_COL");
|
||||
byte_col.data_type = "VARCHAR2(12 BYTE)".to_string();
|
||||
let mut char_col = column("CHAR_COL");
|
||||
char_col.data_type = "VARCHAR2(12 CHAR)".to_string();
|
||||
|
||||
let result = build_create_table_sql(TableStructureSqlOptions {
|
||||
database_type: Some(DatabaseType::Oracle),
|
||||
schema: Some("DBX_APP".to_string()),
|
||||
table_name: "DBX_ISSUE_4739".to_string(),
|
||||
columns: vec![byte_col, char_col],
|
||||
indexes: Vec::new(),
|
||||
foreign_keys: Vec::new(),
|
||||
triggers: Vec::new(),
|
||||
table_comment: None,
|
||||
original_table_comment: None,
|
||||
});
|
||||
|
||||
assert!(result.statements[0].contains("\"BYTE_COL\" VARCHAR2(12 BYTE)"));
|
||||
assert!(result.statements[0].contains("\"CHAR_COL\" VARCHAR2(12 CHAR)"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oracle_alter_column_preserves_character_length_unit() {
|
||||
let mut column = column("DISPLAY_NAME");
|
||||
column.data_type = "VARCHAR2(64 CHAR)".to_string();
|
||||
column.original = Some(ColumnInfo {
|
||||
name: "DISPLAY_NAME".to_string(),
|
||||
data_type: "VARCHAR2(64 BYTE)".to_string(),
|
||||
is_nullable: true,
|
||||
column_default: None,
|
||||
is_primary_key: false,
|
||||
extra: None,
|
||||
comment: None,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let result = build_single_column_alter_sql(SingleColumnAlterSqlOptions {
|
||||
database_type: Some(DatabaseType::Oracle),
|
||||
schema: Some("DBX_APP".to_string()),
|
||||
table_name: "DBX_ISSUE_4739".to_string(),
|
||||
column,
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
result.statements,
|
||||
vec!["ALTER TABLE \"DBX_APP\".\"DBX_ISSUE_4739\" MODIFY (\"DISPLAY_NAME\" VARCHAR2(64 CHAR));"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oracle_timestamp_precision_change_does_not_repeat_unchanged_nullability() {
|
||||
let mut col = column("time");
|
||||
|
||||
Reference in New Issue
Block a user