fix(kingbase): preserve SQLServer identity metadata
This commit is contained in:
1 parent
002dbbf602
commit
904863a57c
6 files changed
+192
-2
No files matched your search
@@ -4,8 +4,15 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public final class DdlBuilder {
|
public final class DdlBuilder {
|
||||||
|
private static final Pattern SQLSERVER_IDENTITY = Pattern.compile(
|
||||||
|
"^\\s*identity\\s*\\(\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*\\)\\s*$",
|
||||||
|
Pattern.CASE_INSENSITIVE
|
||||||
|
);
|
||||||
|
|
||||||
private DdlBuilder() {
|
private DdlBuilder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +91,10 @@ public final class DdlBuilder {
|
|||||||
line.append(quoteIdent(column.getName(), useBacktick));
|
line.append(quoteIdent(column.getName(), useBacktick));
|
||||||
line.append(" ");
|
line.append(" ");
|
||||||
line.append(columnTypeSql(column));
|
line.append(columnTypeSql(column));
|
||||||
|
String identityClause = sqlServerIdentityClause(column.getExtra());
|
||||||
|
if (identityClause != null) {
|
||||||
|
line.append(" ").append(identityClause);
|
||||||
|
}
|
||||||
if (!column.getIs_nullable()) {
|
if (!column.getIs_nullable()) {
|
||||||
line.append(" NOT NULL");
|
line.append(" NOT NULL");
|
||||||
}
|
}
|
||||||
@@ -230,6 +241,14 @@ public final class DdlBuilder {
|
|||||||
return "numeric".equals(normalized) || "decimal".equals(normalized);
|
return "numeric".equals(normalized) || "decimal".equals(normalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String sqlServerIdentityClause(String extra) {
|
||||||
|
if (extra == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Matcher matcher = SQLSERVER_IDENTITY.matcher(extra);
|
||||||
|
return matcher.matches() ? "IDENTITY(" + matcher.group(1) + "," + matcher.group(2) + ")" : null;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean notBlank(String value) {
|
private static boolean notBlank(String value) {
|
||||||
return value != null && !value.trim().isEmpty();
|
return value != null && !value.trim().isEmpty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public final class KingbaseAgent extends PostgresLikeAgent {
|
|||||||
private static final String KINGBASE_MATVIEW_NAME = "CAST(mv.matviewname AS varchar(256))";
|
private static final String KINGBASE_MATVIEW_NAME = "CAST(mv.matviewname AS varchar(256))";
|
||||||
private static final String KINGBASE_MATVIEW_SCHEMA = "CAST(mv.schemaname AS varchar(256))";
|
private static final String KINGBASE_MATVIEW_SCHEMA = "CAST(mv.schemaname AS varchar(256))";
|
||||||
private boolean postgresCatalogMode;
|
private boolean postgresCatalogMode;
|
||||||
|
private boolean sqlServerIdentityCatalogMode;
|
||||||
|
|
||||||
public static final PostgresLikeAgentProfile KINGBASE_PROFILE = new PostgresLikeAgentProfile(
|
public static final PostgresLikeAgentProfile KINGBASE_PROFILE = new PostgresLikeAgentProfile(
|
||||||
"com.kingbase8.Driver",
|
"com.kingbase8.Driver",
|
||||||
@@ -60,6 +61,7 @@ public final class KingbaseAgent extends PostgresLikeAgent {
|
|||||||
@Override
|
@Override
|
||||||
protected void afterConnect(ConnectParams params, Connection connection) {
|
protected void afterConnect(ConnectParams params, Connection connection) {
|
||||||
postgresCatalogMode = false;
|
postgresCatalogMode = false;
|
||||||
|
sqlServerIdentityCatalogMode = false;
|
||||||
setMysqlCompatMode(params.isMysql_compat_mode());
|
setMysqlCompatMode(params.isMysql_compat_mode());
|
||||||
if (params.isMysql_compat_mode()) {
|
if (params.isMysql_compat_mode()) {
|
||||||
return;
|
return;
|
||||||
@@ -69,6 +71,10 @@ public final class KingbaseAgent extends PostgresLikeAgent {
|
|||||||
if (!postgresCatalogMode && mysqlSqlModeExists(connection)) {
|
if (!postgresCatalogMode && mysqlSqlModeExists(connection)) {
|
||||||
setMysqlCompatMode(true);
|
setMysqlCompatMode(true);
|
||||||
}
|
}
|
||||||
|
// SQLServer compatibility exposes identity metadata through this catalog only.
|
||||||
|
sqlServerIdentityCatalogMode = !postgresCatalogMode
|
||||||
|
&& !isMysqlCompatMode()
|
||||||
|
&& catalogExists(connection, "sys.identity_columns");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean mysqlSqlModeExists(Connection connection) {
|
private static boolean mysqlSqlModeExists(Connection connection) {
|
||||||
@@ -413,13 +419,19 @@ public final class KingbaseAgent extends PostgresLikeAgent {
|
|||||||
"CASE WHEN t.typname = 'numeric' AND a.atttypmod > 0 " +
|
"CASE WHEN t.typname = 'numeric' AND a.atttypmod > 0 " +
|
||||||
"THEN (a.atttypmod - 4) & 65535 ELSE NULL END AS numeric_scale, " +
|
"THEN (a.atttypmod - 4) & 65535 ELSE NULL END AS numeric_scale, " +
|
||||||
"CASE WHEN t.typname IN ('varchar', 'bpchar') AND a.atttypmod > 0 " +
|
"CASE WHEN t.typname IN ('varchar', 'bpchar') AND a.atttypmod > 0 " +
|
||||||
"THEN a.atttypmod - 4 ELSE NULL END AS character_maximum_length " +
|
"THEN a.atttypmod - 4 ELSE NULL END AS character_maximum_length, " +
|
||||||
|
(sqlServerIdentityCatalogMode
|
||||||
|
? "ic.seed_value AS identity_seed, ic.increment_value AS identity_increment "
|
||||||
|
: "NULL AS identity_seed, NULL AS identity_increment ") +
|
||||||
"FROM sys_catalog.sys_attribute a " +
|
"FROM sys_catalog.sys_attribute a " +
|
||||||
"JOIN sys_catalog.sys_type t ON t.oid = a.atttypid " +
|
"JOIN sys_catalog.sys_type t ON t.oid = a.atttypid " +
|
||||||
"JOIN sys_catalog.sys_class c ON c.oid = a.attrelid " +
|
"JOIN sys_catalog.sys_class c ON c.oid = a.attrelid " +
|
||||||
"JOIN sys_catalog.sys_namespace n ON n.oid = c.relnamespace " +
|
"JOIN sys_catalog.sys_namespace n ON n.oid = c.relnamespace " +
|
||||||
"LEFT JOIN sys_catalog.sys_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum " +
|
"LEFT JOIN sys_catalog.sys_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum " +
|
||||||
"LEFT JOIN sys_catalog.sys_description d ON d.objoid = a.attrelid AND d.objsubid = a.attnum " +
|
"LEFT JOIN sys_catalog.sys_description d ON d.objoid = a.attrelid AND d.objsubid = a.attnum " +
|
||||||
|
(sqlServerIdentityCatalogMode
|
||||||
|
? "LEFT JOIN sys.identity_columns ic ON ic.object_id = c.oid AND ic.column_id = a.attnum "
|
||||||
|
: "") +
|
||||||
"WHERE n.nspname = " + sqlString(effectiveSchema(schema)) +
|
"WHERE n.nspname = " + sqlString(effectiveSchema(schema)) +
|
||||||
" AND c.relname = " + sqlString(table) + " " +
|
" AND c.relname = " + sqlString(table) + " " +
|
||||||
"AND a.attnum > 0 AND NOT a.attisdropped " +
|
"AND a.attnum > 0 AND NOT a.attisdropped " +
|
||||||
@@ -434,7 +446,7 @@ public final class KingbaseAgent extends PostgresLikeAgent {
|
|||||||
rs.getBoolean("is_nullable"),
|
rs.getBoolean("is_nullable"),
|
||||||
rs.getString("column_default"),
|
rs.getString("column_default"),
|
||||||
primaryKeys.contains(columnName),
|
primaryKeys.contains(columnName),
|
||||||
null,
|
identityExtra(rs),
|
||||||
rs.getString("column_comment"),
|
rs.getString("column_comment"),
|
||||||
intObject(rs, "numeric_precision"),
|
intObject(rs, "numeric_precision"),
|
||||||
intObject(rs, "numeric_scale"),
|
intObject(rs, "numeric_scale"),
|
||||||
@@ -447,6 +459,15 @@ public final class KingbaseAgent extends PostgresLikeAgent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String identityExtra(ResultSet rs) throws Exception {
|
||||||
|
String seed = rs.getString("identity_seed");
|
||||||
|
String increment = rs.getString("identity_increment");
|
||||||
|
if (seed == null || increment == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return "identity(" + seed + "," + increment + ")";
|
||||||
|
}
|
||||||
|
|
||||||
private List<ColumnInfo> getInformationSchemaColumns(String schema, String table, Set<String> primaryKeys) {
|
private List<ColumnInfo> getInformationSchemaColumns(String schema, String table, Set<String> primaryKeys) {
|
||||||
return unchecked(() -> {
|
return unchecked(() -> {
|
||||||
List<ColumnInfo> result = new ArrayList<>();
|
List<ColumnInfo> result = new ArrayList<>();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.dbx.agent.ColumnInfo;
|
|||||||
import com.dbx.agent.ConnectParams;
|
import com.dbx.agent.ConnectParams;
|
||||||
import com.dbx.agent.DatabaseAgent;
|
import com.dbx.agent.DatabaseAgent;
|
||||||
import com.dbx.agent.DatabaseInfo;
|
import com.dbx.agent.DatabaseInfo;
|
||||||
|
import com.dbx.agent.DdlBuilder;
|
||||||
import com.dbx.agent.IndexInfo;
|
import com.dbx.agent.IndexInfo;
|
||||||
import com.dbx.agent.MetadataListConstraints;
|
import com.dbx.agent.MetadataListConstraints;
|
||||||
import com.dbx.agent.ObjectInfo;
|
import com.dbx.agent.ObjectInfo;
|
||||||
@@ -27,6 +28,7 @@ import java.sql.Timestamp;
|
|||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
|
class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
|
||||||
@@ -154,6 +156,22 @@ class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
|
|||||||
Assertions.assertEquals("SELECT 1 FROM sys_settings WHERE LOWER(name) = 'sql_mode'", sql.get(1));
|
Assertions.assertEquals("SELECT 1 FROM sys_settings WHERE LOWER(name) = 'sql_mode'", sql.get(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void detectsSqlServerIdentityCatalogMode() throws Exception {
|
||||||
|
List<String> sql = new ArrayList<>();
|
||||||
|
KingbaseAgent agent = new KingbaseAgent();
|
||||||
|
Connection connection = sqlServerCompatConnection(sql);
|
||||||
|
|
||||||
|
Method afterConnect = KingbaseAgent.class.getDeclaredMethod("afterConnect", ConnectParams.class, Connection.class);
|
||||||
|
afterConnect.setAccessible(true);
|
||||||
|
afterConnect.invoke(agent, new ConnectParams(), connection);
|
||||||
|
|
||||||
|
Assertions.assertTrue(isSqlServerIdentityCatalogMode(agent));
|
||||||
|
Assertions.assertEquals("SELECT 1 FROM sys_catalog.sys_namespace WHERE 1 = 0", sql.get(0));
|
||||||
|
Assertions.assertEquals("SELECT 1 FROM sys_settings WHERE LOWER(name) = 'sql_mode'", sql.get(1));
|
||||||
|
Assertions.assertEquals("SELECT 1 FROM sys.identity_columns WHERE 1 = 0", sql.get(2));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void mysqlCompatListTablesUsesInformationSchema() {
|
void mysqlCompatListTablesUsesInformationSchema() {
|
||||||
List<String> sql = new ArrayList<>();
|
List<String> sql = new ArrayList<>();
|
||||||
@@ -406,6 +424,7 @@ class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
|
|||||||
Assertions.assertTrue(sql.get(1).contains("format_type(a.atttypid, a.atttypmod) AS data_type"), sql.get(1));
|
Assertions.assertTrue(sql.get(1).contains("format_type(a.atttypid, a.atttypmod) AS data_type"), sql.get(1));
|
||||||
Assertions.assertTrue(sql.get(1).contains("FROM sys_catalog.sys_attribute"), sql.get(1));
|
Assertions.assertTrue(sql.get(1).contains("FROM sys_catalog.sys_attribute"), sql.get(1));
|
||||||
Assertions.assertFalse(sql.get(1).contains("information_schema.columns"), sql.get(1));
|
Assertions.assertFalse(sql.get(1).contains("information_schema.columns"), sql.get(1));
|
||||||
|
Assertions.assertNull(columns.get(0).getExtra());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -439,6 +458,59 @@ class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
|
|||||||
Assertions.assertEquals("identifier", columns.get(0).getComment());
|
Assertions.assertEquals("identifier", columns.get(0).getComment());
|
||||||
Assertions.assertTrue(sql.get(1).contains("FROM information_schema.columns"), sql.get(1));
|
Assertions.assertTrue(sql.get(1).contains("FROM information_schema.columns"), sql.get(1));
|
||||||
Assertions.assertTrue(sql.get(1).contains("LEFT JOIN sys_catalog.sys_description"), sql.get(1));
|
Assertions.assertTrue(sql.get(1).contains("LEFT JOIN sys_catalog.sys_description"), sql.get(1));
|
||||||
|
Assertions.assertNull(columns.get(0).getExtra());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sqlServerCompatGetColumnsPreservesIdentityMetadata() throws Exception {
|
||||||
|
List<String> sql = new ArrayList<>();
|
||||||
|
KingbaseAgent agent = new KingbaseAgent();
|
||||||
|
setSqlServerIdentityCatalogMode(agent, true);
|
||||||
|
TestSupport.setPrivateConnection(agent, preparedConnection(sql,
|
||||||
|
resultSet(new String[]{"column_name"}, new Object[][]{{"id"}}),
|
||||||
|
resultSet(
|
||||||
|
new String[]{
|
||||||
|
"column_name",
|
||||||
|
"data_type",
|
||||||
|
"is_nullable",
|
||||||
|
"column_default",
|
||||||
|
"column_comment",
|
||||||
|
"numeric_precision",
|
||||||
|
"numeric_scale",
|
||||||
|
"character_maximum_length",
|
||||||
|
"identity_seed",
|
||||||
|
"identity_increment"
|
||||||
|
},
|
||||||
|
new Object[][]{
|
||||||
|
{"id", "int", false, null, null, 32, 0, null, "1", "1"},
|
||||||
|
{"name", "character varying", true, null, null, null, null, 64, null, null}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
List<ColumnInfo> columns = agent.getColumns("dbo", "orders");
|
||||||
|
|
||||||
|
Assertions.assertEquals("identity(1,1)", columns.get(0).getExtra());
|
||||||
|
Assertions.assertNull(columns.get(1).getExtra());
|
||||||
|
Assertions.assertTrue(sql.get(1).contains("LEFT JOIN sys.identity_columns"), sql.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void ddlRendersOnlyWellFormedSqlServerIdentityMetadata() {
|
||||||
|
ColumnInfo identity = new ColumnInfo("id", "int", false, null, true, "identity(1,1)", null, null, null, null);
|
||||||
|
ColumnInfo ordinary = new ColumnInfo("name", "varchar", true, null, false, "unknown metadata", null, null, null, 64);
|
||||||
|
|
||||||
|
String ddl = DdlBuilder.buildTableDdl(
|
||||||
|
"dbo",
|
||||||
|
"orders",
|
||||||
|
Arrays.asList(identity, ordinary),
|
||||||
|
Collections.emptyList(),
|
||||||
|
Collections.emptyList()
|
||||||
|
);
|
||||||
|
|
||||||
|
Assertions.assertTrue(ddl.contains("\"id\" int IDENTITY(1,1) NOT NULL"), ddl);
|
||||||
|
Assertions.assertTrue(ddl.contains("\"name\" varchar(64)"), ddl);
|
||||||
|
Assertions.assertFalse(ddl.contains("unknown metadata"), ddl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -602,6 +674,23 @@ class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Connection sqlServerCompatConnection(List<String> sql) {
|
||||||
|
return proxy(Connection.class, (method, args) -> {
|
||||||
|
if ("createStatement".equals(method.getName())) {
|
||||||
|
return proxy(Statement.class, (statementMethod, statementArgs) -> {
|
||||||
|
if ("executeQuery".equals(statementMethod.getName())) {
|
||||||
|
String query = String.valueOf(statementArgs[0]);
|
||||||
|
sql.add(query);
|
||||||
|
return resultSet(new String[]{"probe"}, new Object[][]{});
|
||||||
|
}
|
||||||
|
return defaultValue(statementMethod.getReturnType());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ("isClosed".equals(method.getName())) return false;
|
||||||
|
return defaultValue(method.getReturnType());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static ResultSet resultSet(String[] columns, Object[][] rows) {
|
private static ResultSet resultSet(String[] columns, Object[][] rows) {
|
||||||
int[] index = {-1};
|
int[] index = {-1};
|
||||||
return proxy(ResultSet.class, (method, args) -> {
|
return proxy(ResultSet.class, (method, args) -> {
|
||||||
@@ -694,4 +783,16 @@ class KingbaseAgentTest extends JdbcFakeExecutionBehaviorTest {
|
|||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(agent, rs, 1, sqlType, columnTypeName);
|
return method.invoke(agent, rs, 1, sqlType, columnTypeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setSqlServerIdentityCatalogMode(KingbaseAgent agent, boolean enabled) throws Exception {
|
||||||
|
java.lang.reflect.Field field = KingbaseAgent.class.getDeclaredField("sqlServerIdentityCatalogMode");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.setBoolean(agent, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSqlServerIdentityCatalogMode(KingbaseAgent agent) throws Exception {
|
||||||
|
java.lang.reflect.Field field = KingbaseAgent.class.getDeclaredField("sqlServerIdentityCatalogMode");
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.getBoolean(agent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,12 +16,24 @@ import {
|
|||||||
isMysqlEnumDataType,
|
isMysqlEnumDataType,
|
||||||
isSqlServerIdentityCompatibleDataType,
|
isSqlServerIdentityCompatibleDataType,
|
||||||
mysqlEnumDataType,
|
mysqlEnumDataType,
|
||||||
|
parseExtraToColumnExtra,
|
||||||
rehydrateColumnDraftsFromMetadata,
|
rehydrateColumnDraftsFromMetadata,
|
||||||
restoreDamengLengthUnitsAfterSave,
|
restoreDamengLengthUnitsAfterSave,
|
||||||
splitDataType,
|
splitDataType,
|
||||||
} from "@/lib/table/tableStructureEditorState";
|
} from "@/lib/table/tableStructureEditorState";
|
||||||
|
|
||||||
describe("tableStructureEditorState", () => {
|
describe("tableStructureEditorState", () => {
|
||||||
|
it("parses Kingbase SQLServer compatibility identity metadata", () => {
|
||||||
|
expect(parseExtraToColumnExtra("identity(10, 2)", "kingbase")).toEqual({
|
||||||
|
autoIncrement: true,
|
||||||
|
identity: { seed: 10, increment: 2 },
|
||||||
|
});
|
||||||
|
expect(parseExtraToColumnExtra("generated always as identity", "kingbase")).toEqual({
|
||||||
|
identity: { generation: "ALWAYS" },
|
||||||
|
});
|
||||||
|
expect(parseExtraToColumnExtra("identity(1,1)", "postgres")).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps mysql unsigned attributes in the editable base type", () => {
|
it("keeps mysql unsigned attributes in the editable base type", () => {
|
||||||
expect(splitDataType("int(11) unsigned")).toEqual({ baseType: "int unsigned", params: "11" });
|
expect(splitDataType("int(11) unsigned")).toEqual({ baseType: "int unsigned", params: "11" });
|
||||||
expect(splitDataType("bigint(20) unsigned zerofill")).toEqual({
|
expect(splitDataType("bigint(20) unsigned zerofill")).toEqual({
|
||||||
|
|||||||
@@ -477,6 +477,16 @@ export function parseExtraToColumnExtra(extra: string | null | undefined, databa
|
|||||||
result.identity.seed = Number(sequenceMatch[1]);
|
result.identity.seed = Number(sequenceMatch[1]);
|
||||||
result.identity.increment = Number(sequenceMatch[2]);
|
result.identity.increment = Number(sequenceMatch[2]);
|
||||||
}
|
}
|
||||||
|
} else if (databaseType === "kingbase") {
|
||||||
|
// SQLServer compatibility reports IDENTITY(seed, increment) instead of PostgreSQL identity syntax.
|
||||||
|
const sqlServerIdentityMatch = lower.match(/identity\s*\(\s*(-?\d+)\s*,\s*(-?\d+)\s*\)/i);
|
||||||
|
if (sqlServerIdentityMatch) {
|
||||||
|
result.autoIncrement = true;
|
||||||
|
result.identity = {
|
||||||
|
seed: Number(sqlServerIdentityMatch[1]),
|
||||||
|
increment: Number(sqlServerIdentityMatch[2]),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (databaseType === "sqlserver") {
|
} else if (databaseType === "sqlserver") {
|
||||||
if (lower.includes("identity")) {
|
if (lower.includes("identity")) {
|
||||||
|
|||||||
@@ -4668,6 +4668,33 @@ mod tests {
|
|||||||
assert_eq!(result.statements, vec!["INSERT INTO `app`.`users` (`name`) VALUES ('Ada');"]);
|
assert_eq!(result.statements, vec!["INSERT INTO `app`.`users` (`name`) VALUES ('Ada');"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prepare_data_grid_save_omits_empty_kingbase_sqlserver_identity_value() {
|
||||||
|
let result = prepare_data_grid_save(DataGridSaveStatementOptions {
|
||||||
|
database_type: Some(DatabaseType::Kingbase),
|
||||||
|
table_meta: DataGridTableMeta {
|
||||||
|
catalog: None,
|
||||||
|
database: None,
|
||||||
|
schema: Some("dbo".to_string()),
|
||||||
|
table_name: "orders".to_string(),
|
||||||
|
primary_keys: vec!["id".to_string()],
|
||||||
|
columns: Some(vec![
|
||||||
|
pk_column("id", "int", false, Some("identity(1,1)")),
|
||||||
|
column("name", "varchar", false, None),
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
columns: vec!["id".to_string(), "name".to_string()],
|
||||||
|
source_columns: None,
|
||||||
|
rows: vec![],
|
||||||
|
dirty_rows: vec![],
|
||||||
|
deleted_rows: vec![],
|
||||||
|
new_rows: vec![vec![Value::Null, json!("Ada")]],
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.validation_error, None);
|
||||||
|
assert_eq!(result.statements, vec![r#"INSERT INTO "dbo"."orders" ("name") VALUES ('Ada');"#]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prepare_data_grid_save_still_validates_other_not_null_columns_in_sqlite() {
|
fn prepare_data_grid_save_still_validates_other_not_null_columns_in_sqlite() {
|
||||||
let result = prepare_data_grid_save(DataGridSaveStatementOptions {
|
let result = prepare_data_grid_save(DataGridSaveStatementOptions {
|
||||||
|
|||||||
Reference in new issue
Block a user