From 6d254be3ca276b578eed7da58df62728a513dbab Mon Sep 17 00:00:00 2001 From: zgq <203083679@qq.com> Date: Thu, 13 Jun 2024 15:14:00 +0800 Subject: [PATCH 1/6] fix(chat2db-dm): correct spelling of NUMERIC in DMColumnTypeEnum --- .../main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java index ea9876c92..cd422fbde 100644 --- a/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java +++ b/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java @@ -89,7 +89,7 @@ public enum DMColumnTypeEnum implements ColumnBuilder { TEXT("TEXT", false, false, true, false, false, false, true, true, false, false), - NUMBERIC("NUMBERIC", true, true, true, false, false, false, true, true, false, false), + NUMERIC("NUMERIC", true, true, true, false, false, false, true, true, false, false), NUMBER("NUMBER", true, true, true, false, false, false, true, true, false, false), @@ -222,7 +222,7 @@ private String buildDataType(TableColumn column, DMColumnTypeEnum type) { return script.toString(); } - if (Arrays.asList(DECIMAL,DEC, FLOAT, NUMBER, TIMESTAMP, NUMBERIC).contains(type)) { + if (Arrays.asList(DECIMAL, DEC, FLOAT, NUMBER, TIMESTAMP, NUMERIC).contains(type)) { StringBuilder script = new StringBuilder(); script.append(columnType); if (column.getColumnSize() != null && column.getDecimalDigits() == null) { From 959f8258eccc8ef1271113b71f662fc12bfafa8e Mon Sep 17 00:00:00 2001 From: zgq <203083679@qq.com> Date: Thu, 13 Jun 2024 15:14:27 +0800 Subject: [PATCH 2/6] Revert "fix(chat2db-dm): correct spelling of NUMERIC in DMColumnTypeEnum" This reverts commit 6d254be3ca276b578eed7da58df62728a513dbab. --- .../main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java index cd422fbde..ea9876c92 100644 --- a/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java +++ b/chat2db-server/chat2db-plugins/chat2db-dm/src/main/java/ai/chat2db/plugin/dm/type/DMColumnTypeEnum.java @@ -89,7 +89,7 @@ public enum DMColumnTypeEnum implements ColumnBuilder { TEXT("TEXT", false, false, true, false, false, false, true, true, false, false), - NUMERIC("NUMERIC", true, true, true, false, false, false, true, true, false, false), + NUMBERIC("NUMBERIC", true, true, true, false, false, false, true, true, false, false), NUMBER("NUMBER", true, true, true, false, false, false, true, true, false, false), @@ -222,7 +222,7 @@ private String buildDataType(TableColumn column, DMColumnTypeEnum type) { return script.toString(); } - if (Arrays.asList(DECIMAL, DEC, FLOAT, NUMBER, TIMESTAMP, NUMERIC).contains(type)) { + if (Arrays.asList(DECIMAL,DEC, FLOAT, NUMBER, TIMESTAMP, NUMBERIC).contains(type)) { StringBuilder script = new StringBuilder(); script.append(columnType); if (column.getColumnSize() != null && column.getDecimalDigits() == null) { From 931b316cd618b55c4f58d53ff5f68a8f3d6e7372 Mon Sep 17 00:00:00 2001 From: zgq <203083679@qq.com> Date: Sat, 15 Jun 2024 19:04:36 +0800 Subject: [PATCH 3/6] fix-pgsql-table-ddl --- .../plugin/postgresql/PostgreSQLMetaData.java | 616 +++++++++++++++++- .../type/PostgreSQLColumnTypeEnum.java | 8 + .../domain/core/impl/TableServiceImpl.java | 2 +- .../java/ai/chat2db/spi/sql/SQLExecutor.java | 43 +- 4 files changed, 659 insertions(+), 10 deletions(-) diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java index 4a05533ab..e621a7955 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java @@ -19,8 +19,6 @@ import java.util.*; import java.util.stream.Collectors; -import static ai.chat2db.plugin.postgresql.consts.SQLConst.DROP_TYPE_SQL; -import static ai.chat2db.plugin.postgresql.consts.SQLConst.TABLE_DEF_FUNCTION_SQL; import static ai.chat2db.spi.util.SortUtils.sortDatabase; public class PostgreSQLMetaData extends DefaultMetaService implements MetaData { @@ -102,17 +100,621 @@ public List triggers(Connection connection, String databaseName, String }); } + private static final String TABLE_SPACE_SQL = """ + select tablespace + from pg_tables + where schemaname = ? + and tablename = ? + and tablespace is not null;"""; + + private static final String PARTITIONED_CONDITION_SQL = """ + SELECT pg_get_partkeydef(c1.oid) as partition_key + FROM pg_class c1 + JOIN pg_namespace n ON (n.oid = c1.relnamespace) + LEFT JOIN pg_partitioned_table p ON (c1.oid = p.partrelid) + WHERE n.nspname = ? + and n.oid = c1.relnamespace + and c1.relname = ? + and c1.relkind = 'p' + and pg_get_partkeydef(c1.oid) IS NOT NULL + and pg_get_partkeydef(c1.oid) <> '';"""; + + private static final String PARTITIONED_SUB_TABLE_SQL = """ + SELECT + quote_ident(c2.relname) as PARENT_TABLE, + pg_get_expr(c1.relpartbound, c1.oid, true) as PARTITION_DEFINITION + from pg_class c1, + pg_namespace n, + pg_inherits i, + pg_class c2 + WHERE n.nspname = ? + and n.oid = c1.relnamespace + and c1.relname = ? + and c1.oid = i.inhrelid + and i.inhparent = c2.oid + and c1.relkind = 'r';"""; + + private static final String LIST_PARTITIONED_SUB_TABLE_SQL = """ + WITH PartitionTables AS ( + SELECT + child_ns.nspname AS child_schema, + child.relname AS child_table + FROM + pg_inherits + JOIN + pg_class parent ON pg_inherits.inhparent = parent.oid + JOIN + pg_namespace ns ON parent.relnamespace = ns.oid + JOIN + pg_class child ON pg_inherits.inhrelid = child.oid + JOIN + pg_namespace child_ns ON child.relnamespace = child_ns.oid + WHERE + ns.nspname = ? + AND parent.relname = ? + ) + SELECT + quote_ident(c2.relname) as parent_table, + pg_get_expr(c1.relpartbound, c1.oid, true) as partition_definition, + quote_ident(c1.relname) as sub_name, + quote_ident(n.nspname) as schema_name + FROM + pg_class c1 + JOIN + pg_namespace n ON n.oid = c1.relnamespace + JOIN + pg_inherits i ON c1.oid = i.inhrelid + JOIN + pg_class c2 ON i.inhparent = c2.oid + JOIN + PartitionTables pt ON pt.child_schema = n.nspname AND pt.child_table = c1.relname + WHERE + c1.relkind = 'r';"""; + + private static final String CONSTRAINT_SQL = """ + SELECT con.conname as CONSTRAINT_NAME, + con.contype as CONSTRAINT_TYPE, + CASE + WHEN con.contype = 'p' THEN 1 -- primary key constraint + WHEN con.contype = 'u' THEN 2 -- unique constraint + WHEN con.contype = 'f' THEN 3 -- foreign key constraint + WHEN con.contype = 'c' THEN 4 + ELSE 5 + END as type_rank, + pg_get_constraintdef(con.oid) as CONSTRAINT_DEFINITION + FROM pg_catalog.pg_constraint con + JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid + JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace + WHERE nsp.nspname = ? + AND rel.relname = ? + AND con.conparentid = 0 + ORDER BY type_rank;"""; + private static final String INDEX_SQL = """ + SELECT INDEXDEF, INDEXNAME + FROM pg_indexes + WHERE (schemaname, tablename) = (?, ?)"""; + + private static final String TABLE_COLUMN_COMMENT_SQL = """ + SELECT quote_ident(c.relname) AS table_name, + CASE + WHEN c.relkind IN ('r', 'p') and a.attname is not null THEN 'COLUMN' + WHEN c.relkind IN ('r', 'p') THEN 'TABLE' + END AS object_type, + quote_literal(d.description) AS comment, + quote_ident(n.nspname) AS schema_name, + CASE + WHEN a.attname IS NOT NULL THEN quote_ident(a.attname) + END AS column_name + FROM pg_class c + JOIN + pg_namespace n ON (n.oid = c.relnamespace) + LEFT JOIN + pg_description d ON (c.oid = d.objoid) + LEFT JOIN + pg_attribute a ON (c.oid = a.attrelid AND a.attnum > 0 AND a.attnum = d.objsubid) + WHERE d.description IS NOT NULL + AND d.description <> '' + AND n.nspname = ? + AND c.relname = ? + ORDER BY 2 desc;"""; + + private static final String COLUMN_SQL = """ + SELECT quote_ident(c.column_name) as column_name , + c.data_type, + c.udt_name, + quote_ident(c.udt_schema) as udt_schema, + c.character_maximum_length, + c.is_nullable, + c.column_default, + c.numeric_precision, + c.numeric_scale, + c.datetime_precision, + c.is_identity, + c.identity_start, + c.identity_increment, + c.identity_maximum, + c.identity_minimum, + c.identity_cycle, + c.identity_generation, + c.is_generated, + c.generation_expression, + c.identity_increment, + case + when pg_get_serial_sequence(table_schema || '.' || table_name, + column_name) IS NOT NULL THEN True + ELSE False end as is_serial + FROM information_schema.columns c + WHERE (table_schema, table_name) = (?, ?) + ORDER BY ordinal_position;"""; + + + private static final String TABLE_INDEX_COMMENT_SQL = """ + SELECT quote_ident(n.nspname) as schema_name, + quote_ident(t.relname) AS table_name, + quote_ident(i.relname) AS index_name, + quote_literal(pg_catalog.obj_description(i.oid)) AS index_comment, + i.oid + FROM pg_class t + INNER JOIN pg_index idx ON t.oid = idx.indrelid + INNER JOIN pg_class i ON i.oid = idx.indexrelid + INNER JOIN pg_catalog.pg_namespace n ON i.relnamespace = n.oid + WHERE n.nspname = ? + AND t.relname = ? + AND pg_catalog.obj_description(i.oid) IS NOT NULL + AND pg_catalog.obj_description(i.oid) <> '';"""; + + private static final String TABLE_SEQUENCES_COMMENT_SQL = """ + SELECT + quote_ident(seq.relname) AS sequence_name, + quote_literal(pg_catalog.obj_description(seq.oid)) AS sequence_comment + FROM pg_catalog.pg_class seq + JOIN + pg_catalog.pg_namespace seq_ns ON seq.relnamespace = seq_ns.oid + JOIN + pg_catalog.pg_depend dep ON dep.objid = seq.oid + JOIN + pg_catalog.pg_class tbl ON dep.refobjid = tbl.oid + JOIN + pg_catalog.pg_namespace tbl_ns ON tbl.relnamespace = tbl_ns.oid + WHERE seq.relkind = 'S' + AND seq_ns.nspname = ? + AND tbl_ns.nspname = ? + AND tbl.relname = ? + AND pg_catalog.obj_description(seq.oid) is not null + AND pg_catalog.obj_description(seq.oid) <> '';"""; + + private static final String NORMAL_SUB_TABLE_SQL = """ + -- 获取继承关系信息,包括父表和子表的模式、名称及OID + WITH inheritance_info AS ( + SELECT p_ns.nspname AS parent_schema, + p.relname AS parent_table, + c_ns.nspname AS child_schema, + c.relname AS child_table, + p.oid AS parent_oid, + c.oid AS child_oid + FROM pg_inherits + JOIN pg_class p ON pg_inherits.inhparent = p.oid + JOIN pg_class c ON pg_inherits.inhrelid = c.oid + JOIN pg_namespace p_ns ON p.relnamespace = p_ns.oid + JOIN pg_namespace c_ns ON c.relnamespace = c_ns.oid + WHERE c_ns.nspname = ? -- 替换为实际的子表模式名 + AND c.relname = ? -- 替换为实际的子表名 + ), + -- 获取子表中不包含在父表中的字段 + unique_child_columns AS ( + SELECT att.attname AS child_column, + ii.child_table, + ii.parent_table, + ii.parent_schema + FROM pg_attribute att + JOIN pg_class cls ON att.attrelid = cls.oid + JOIN inheritance_info ii ON cls.oid = ii.child_oid + LEFT JOIN pg_attribute p_att ON att.attname = p_att.attname + AND p_att.attrelid = ii.parent_oid + WHERE att.attnum > 0 + AND NOT att.attisdropped + AND p_att.attname IS NULL -- 排除父表中已有的字段 + ) + -- 返回子表自定义字段名、子表名、父表名及父表模式名 + SELECT + quote_ident(child_column) as child_column, + quote_ident(parent_table) as parent_table, + quote_ident(parent_schema) as parent_schema + FROM unique_child_columns + where parent_table is not null + and parent_table <> '' + ORDER BY child_table, child_column; -- 按子表名和字段名排序"""; + + private static final String TABLE_OPTION_SQL = """ + select reloptions as table_options + from pg_class c + join pg_namespace n on c.relnamespace = n.oid + where nspname = ? + and relname = ?;"""; + + private String format(String objectName) { + int singleQuoteCount = StringUtils.countMatches(objectName, '\''); + if (singleQuoteCount % 2 != 0) { + return '"' + objectName + '"'; + } else { + return objectName; + } + } + @Override public String tableDDL(Connection connection, String databaseName, String schemaName, String tableName) { - SQLExecutor.getInstance().execute(connection, String.format(DROP_TYPE_SQL,schemaName,"tabledefs"), resultSet -> null); - SQLExecutor.getInstance().execute(connection, TABLE_DEF_FUNCTION_SQL, resultSet -> null); - String ddlSql = String.format("select * from pg_get_tabledef('%s','%s',false,'COMMENTS') as ddl;", schemaName, tableName); - return SQLExecutor.getInstance().execute(connection, ddlSql, resultSet -> { + StringBuilder ddlBuilder = new StringBuilder(); + String formatSchemaName = format(schemaName); + String formatTableName = format(tableName); + ddlBuilder.append("create table ").append(formatSchemaName).append(".").append(formatTableName); + String options = SQLExecutor.getInstance().preExecute(connection, TABLE_OPTION_SQL, new String[]{schemaName, tableName}, resultSet -> { if (resultSet.next()) { - return resultSet.getString("ddl"); + StringBuilder optionBuilder = new StringBuilder(); + String tableOptions = resultSet.getString("table_options"); + if (StringUtils.isNotBlank(tableOptions)) { + tableOptions = tableOptions.replace("{", "(").replace("}", ")"); + return optionBuilder.append("with ").append(tableOptions).toString(); + } } return null; }); + String tablespace = SQLExecutor.getInstance().preExecute(connection, TABLE_SPACE_SQL, new String[]{schemaName, tableName}, resultSet -> { + StringBuilder tableSpaceBuilder = new StringBuilder(); + tableSpaceBuilder.append(" tablespace "); + if (resultSet.next()) { + tableSpaceBuilder.append(resultSet.getString("tablespace")); + } else { + tableSpaceBuilder.append("pg_default"); + } + tableSpaceBuilder.append(";\n"); + return tableSpaceBuilder.toString(); + }); + Boolean subTable = SQLExecutor.getInstance().preExecute(connection, PARTITIONED_SUB_TABLE_SQL, new String[]{schemaName, tableName}, resultSet -> { + boolean isSub = false; + if (resultSet.next()) { + String parentTableName = resultSet.getString("PARENT_TABLE"); + String partitionDefinition = resultSet.getString("PARTITION_DEFINITION"); + if (StringUtils.isNotBlank(parentTableName) && StringUtils.isNotBlank(partitionDefinition)) { + ddlBuilder.append("\n").append(" partition of ").append(parentTableName).append("\n") + .append(partitionDefinition); + isSub = true; + } + } + return isSub; + }); + if (subTable) { + if (StringUtils.isNotBlank(options)) { + ddlBuilder.append("WITH ").append(options); + } + return ddlBuilder.append("\n").append(tablespace).toString(); + } + ddlBuilder.append("\n(\n"); + ArrayList childTableInfo = SQLExecutor.getInstance().preExecute(connection, NORMAL_SUB_TABLE_SQL, new String[]{schemaName, tableName}, resultSet -> { + ArrayList subColumnSet = new ArrayList<>(2); + boolean isFirst = true; + while (resultSet.next()) { + if (isFirst) { + //set 集合的前两位存储父表的schema以及名称 + String parentSchema = resultSet.getString("parent_schema"); + String parentTableName = resultSet.getString("parent_table"); + subColumnSet.add(parentSchema); + subColumnSet.add(parentTableName); + isFirst = false; + } + String childColumnName = resultSet.getString("child_column"); + if (StringUtils.isNotBlank(childColumnName)) { + subColumnSet.add(childColumnName); + } + } + return subColumnSet; + }); + Long columnCount = SQLExecutor.getInstance().preExecute(connection, COLUMN_SQL, new String[]{schemaName, tableName}, resultSet -> { + long total = 0; + while (resultSet.next()) { + total++; + String columnName = resultSet.getString("column_name"); + // childTableInfo 前两位是父表信息 + if (childTableInfo.size() > 2) { + //检查该字段在不在子表字段列表,如果不在就是父表字段,所以需要跳过 + if (!childTableInfo.contains(columnName)) { + continue; + } + } + String dataType = resultSet.getString("data_type"); + String columnDefault = resultSet.getString("column_default"); + String udtName = resultSet.getString("udt_name"); + String udtSchema = resultSet.getString("udt_schema"); + String identityGeneration = resultSet.getString("identity_generation"); + boolean isNullable = "YES".equals(resultSet.getString("is_nullable")); + boolean isIdentity = "YES".equals(resultSet.getString("is_identity")); + boolean isSerial = resultSet.getBoolean("is_serial"); + int identityIncrement = resultSet.getInt("identity_increment"); + int identityStart = resultSet.getInt("identity_start"); + int characterMaximumLength = resultSet.getInt("character_maximum_length"); + int numericPrecision = resultSet.getInt("numeric_precision"); + int numericScale = resultSet.getInt("numeric_scale"); + int datetimePrecision = resultSet.getInt("datetime_precision"); + ddlBuilder.append("\t").append(columnName).append(" ").append("\t"); + + if (PostgreSQLColumnTypeEnum.CHARACTERVARYING.getColumnType().getTypeName().toLowerCase().equals(dataType)) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.VARCHAR.name().toLowerCase()); + if (characterMaximumLength >= 1) { + ddlBuilder.append("(").append(characterMaximumLength).append(")"); + } + } else if ("ARRAY".equals(dataType)) { + if (udtName.contains(PostgreSQLColumnTypeEnum.INT4.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.INTEGER.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.INT2.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.SMALLINT.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.INT8.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.BIGINT.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.VARBIT.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.BITVARYING.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.VARCHAR.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.CHARACTERVARYING.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.JSON.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.JSON.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.JSONB.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.JSONB.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.JSONPATH.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.JSONPATH.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.TEXT.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.TEXT.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.BPCHAR.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.CHAR.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.BIT.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.BIT.getColumnType().getTypeName().toLowerCase()).append("[]"); + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.TIME.name().toLowerCase())) { + ddlBuilder.append("time without time zone").append("[]"); + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.TIMESTAMP.name().toLowerCase())) { + ddlBuilder.append("timestamp without time zone").append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.TIMETZ.name().toLowerCase())) { + ddlBuilder.append("time with time zone").append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.TIMESTAMPTZ.name().toLowerCase())) { + ddlBuilder.append("timestamp with time zone").append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.PATH.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.PATH.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.POINT.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.POINT.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.LINE.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.LINE.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.BOX.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.BOX.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.LSEG.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.LSEG.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.POLYGON.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.POLYGON.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.CIRCLE.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.CIRCLE.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.CIDR.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.CIDR.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.INET.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.INET.name().toLowerCase()).append("[]"); + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.MACADDR.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.MACADDR.name().toLowerCase()).append("[]"); + } else if (udtName.contains("macaddr8")) { + ddlBuilder.append("macaddr8").append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.XML.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.XML.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.TSQUERY.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.TSQUERY.name().toLowerCase()).append("[]"); + } else if (udtName.contains(PostgreSQLColumnTypeEnum.TSVECTOR.name().toLowerCase())) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.TSVECTOR.name().toLowerCase()).append("[]"); + } else { + ddlBuilder.append(dataType); + } + } else if (PostgreSQLColumnTypeEnum.BIT.name().toLowerCase().equals(dataType)) { + ddlBuilder.append(udtName); + if (characterMaximumLength > 0 && characterMaximumLength != 1) { + ddlBuilder.append("(").append(characterMaximumLength).append(")"); + } + } else if (PostgreSQLColumnTypeEnum.BITVARYING.getColumnType().getTypeName().toLowerCase().equals(dataType)) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.BITVARYING.getColumnType().getTypeName().toLowerCase()); + if (characterMaximumLength > 0) { + ddlBuilder.append("(").append(characterMaximumLength).append(")"); + } + } else if ("USER-DEFINED".equals(dataType)) { + dataType = udtSchema + "." + format(udtName); + ddlBuilder.append(dataType); + + } else if (PostgreSQLColumnTypeEnum.TIMETZ.getColumnType().getTypeName().toLowerCase().equals(udtName)) { + if (datetimePrecision >= 0 && datetimePrecision != 6) { + dataType = "time" + "(" + datetimePrecision + ")" + " with time zone"; + } + ddlBuilder.append(dataType); + + } else if (PostgreSQLColumnTypeEnum.TIMESTAMPTZ.getColumnType().getTypeName().toLowerCase().equals(udtName)) { + if (datetimePrecision >= 0 && datetimePrecision != 6) { + dataType = "timestamp" + "(" + datetimePrecision + ")" + " with time zone"; + } + ddlBuilder.append(dataType); + } else if (PostgreSQLColumnTypeEnum.TIMESTAMP.name().toLowerCase().equals(udtName)) { + ddlBuilder.append(udtName); + if (datetimePrecision >= 0 && datetimePrecision != 6) { + ddlBuilder.append("(").append(datetimePrecision).append(")"); + } + } else if (PostgreSQLColumnTypeEnum.INTERVAL.name().toLowerCase().equals(udtName)) { + ddlBuilder.append(udtName); + if (datetimePrecision >= 0 && datetimePrecision != 6) { + ddlBuilder.append("(").append(datetimePrecision).append(")"); + } + } else if (PostgreSQLColumnTypeEnum.TIME.name().toLowerCase().equals(udtName)) { + ddlBuilder.append(udtName); + if (datetimePrecision >= 0 && datetimePrecision != 6) { + ddlBuilder.append("(").append(datetimePrecision).append(")"); + } + } else if (PostgreSQLColumnTypeEnum.CHARACTER.name().toLowerCase().equals(dataType)) { + ddlBuilder.append(PostgreSQLColumnTypeEnum.CHAR.name().toLowerCase()); + if (characterMaximumLength > 1) { + ddlBuilder.append("(").append(characterMaximumLength).append(")"); + } + } else if (PostgreSQLColumnTypeEnum.NUMERIC.name().toLowerCase().equals(dataType)) { + ddlBuilder.append(dataType); + if (numericPrecision > 0) { + ddlBuilder.append("(").append(numericPrecision); + if (numericScale != 0) { + ddlBuilder.append(",").append(numericScale); + } + ddlBuilder.append(")"); + } + } else if (isSerial && StringUtils.isNotBlank(columnDefault) && columnDefault.contains("nextval")) { + if (PostgreSQLColumnTypeEnum.INT8.name().toLowerCase().equals(udtName)) { + dataType = PostgreSQLColumnTypeEnum.BIGSERIAL.name().toLowerCase(); + } else if (PostgreSQLColumnTypeEnum.INT2.name().toLowerCase().equals(udtName)) { + dataType = PostgreSQLColumnTypeEnum.SMALLSERIAL.name().toLowerCase(); + } else if (PostgreSQLColumnTypeEnum.INT4.name().toLowerCase().equals(udtName)) { + dataType = PostgreSQLColumnTypeEnum.SERIAL.name().toLowerCase(); + } + ddlBuilder.append(dataType); + } else { + ddlBuilder.append(dataType); + if (isIdentity) { + ddlBuilder.append(" generated ").append(identityGeneration.toLowerCase()).append(" as identity"); + if (!(identityStart == 1 && identityIncrement == 1)) { + ddlBuilder.append(" (start with ").append(identityStart).append(" increment by ").append(identityIncrement).append(")"); + } + } + } + if (StringUtils.isNotBlank(columnDefault) && !isIdentity && !isSerial) { + ddlBuilder.append(" default ").append(columnDefault); + } + if (!isNullable && !isIdentity && !isSerial) { + ddlBuilder.append(" not null"); + } + + if (!resultSet.isLast()) { + ddlBuilder.append(",\n"); + } + } + return total; + }); + + if (columnCount == 0) { + ddlBuilder.append(")").append(tablespace); + return ddlBuilder.toString(); + } + + HashSet constraints = SQLExecutor.getInstance().preExecute(connection, CONSTRAINT_SQL, new String[]{schemaName, tableName}, resultSet -> { + HashSet constraintNameSet = new HashSet<>(); + boolean isFirst = true; + while (resultSet.next()) { + String constraintDefinition = resultSet.getString("CONSTRAINT_DEFINITION"); + String constraintName = resultSet.getString("CONSTRAINT_NAME"); + if (StringUtils.isNotBlank(constraintName) && StringUtils.isNotBlank(constraintName)) { + constraintNameSet.add(constraintName); + if (isFirst) { + ddlBuilder.append(",\n"); + isFirst = false; + } + ddlBuilder.append("\t").append("constraint ").append(constraintName).append(" ").append(constraintDefinition); + if (resultSet.isLast()) { + ddlBuilder.append("\n"); + } else { + ddlBuilder.append(",\n"); + } + } + } + return constraintNameSet; + + }); + ddlBuilder.append("\n)"); + + Boolean isPartitionedTable = SQLExecutor.getInstance().preExecute(connection, PARTITIONED_CONDITION_SQL, new String[]{schemaName, tableName}, resultSet -> { + boolean isPartitioned = false; + if (resultSet.next()) { + ddlBuilder.append("partition by ").append(resultSet.getString("partition_key")).append(";"); + isPartitioned = true; + ddlBuilder.append("\n"); + } + return isPartitioned; + }); + if (isPartitionedTable) { + SQLExecutor.getInstance().preExecute(connection, LIST_PARTITIONED_SUB_TABLE_SQL, new String[]{schemaName, tableName}, resultSet -> { + while (resultSet.next()) { + String subName = resultSet.getString("sub_name"); + String schema_name = resultSet.getString("schema_name"); + String parentTableName = resultSet.getString("PARENT_TABLE"); + String partitionDefinition = resultSet.getString("PARTITION_DEFINITION"); + if (StringUtils.isNotBlank(parentTableName) && StringUtils.isNotBlank(partitionDefinition)) { + ddlBuilder.append("create table ").append(schema_name).append(".").append(subName).append("\n") + .append("partition of ").append(parentTableName).append("\n") + .append(partitionDefinition).append(";\n"); + } + } + + }); + //证明这个是子表 + } else if (childTableInfo.size() >= 2) { + String parentSchema = childTableInfo.get(0); + String parentTableName = childTableInfo.get(1); + ddlBuilder.append(" ").append(" inherits ").append("(").append(parentSchema).append(".").append(parentTableName).append(")").append("\n"); + if (StringUtils.isNotBlank(options)) { + ddlBuilder.append(" ").append(options).append("\n"); + } + ddlBuilder.append(tablespace); + } else { + ddlBuilder.append(tablespace); + } + SQLExecutor.getInstance().preExecute(connection, INDEX_SQL, new String[]{schemaName, tableName}, resultSet -> { + while (resultSet.next()) { + String indexName = resultSet.getString("INDEXNAME"); + if (StringUtils.isNotBlank(indexName) && constraints.contains(indexName)) { + continue; + } + String indexDef = resultSet.getString("INDEXDEF"); + if (StringUtils.isNotBlank(indexDef) && StringUtils.isNotBlank(indexName)) { + ddlBuilder.append(indexDef).append(";").append("\n"); + } + } + ddlBuilder.append("\n"); + }); + + SQLExecutor.getInstance().preExecute(connection, TABLE_COLUMN_COMMENT_SQL, new String[]{schemaName, tableName}, resultSet -> { + while (resultSet.next()) { + String comment = resultSet.getString("comment"); + + if (StringUtils.isBlank(comment)) { + continue; + } + + String objectType = resultSet.getString("object_type"); + String quoteTableName = resultSet.getString("table_name"); + String quoteSchemaName = resultSet.getString("schema_name"); + String columnName = resultSet.getString("column_name"); + + ddlBuilder.append("comment on ").append(objectType.toLowerCase()).append(" ").append(quoteSchemaName).append(".").append(quoteTableName); + + if (StringUtils.isNotBlank(columnName)) { + ddlBuilder.append(".").append(columnName); + } + + ddlBuilder.append(" is ").append(comment).append(";\n"); + + } + }); + + SQLExecutor.getInstance().preExecute(connection, TABLE_INDEX_COMMENT_SQL, new String[]{schemaName, tableName}, resultSet -> { + while (resultSet.next()) { + + String index_name = resultSet.getString("index_name"); + String index_comment = resultSet.getString("index_comment"); + + ddlBuilder.append("comment on index ").append(index_name) + .append(" is ").append(index_comment).append(";\n"); + } + + }); + +// SQLExecutor.getInstance().preExecute(connection, TABLE_SEQUENCES_COMMENT_SQL, new String[]{schemaName, schemaName, tableName}, resultSet -> { +// while (resultSet.next()) { +// String sequence_name = resultSet.getString("sequence_name"); +// String sequence_comment = resultSet.getString("sequence_comment"); +// ddlBuilder.append("COMMENT ON SEQUENCE ").append(sequence_name) +// .append(" IS ").append(sequence_comment).append(";\n"); +// +// } +// }); + return ddlBuilder.toString(); } diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java index c0b6a6213..06d089a75 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java @@ -19,6 +19,8 @@ public enum PostgreSQLColumnTypeEnum implements ColumnBuilder { BOX("BOX", false, false, true, false, false, false, true, true, false, false), BYTEA("BYTEA", false, false, true, false, false, false, true, true, false, false), CHAR("CHAR", true, false, true, false, false, true, true, true, false, false), + BPCHAR("BPCHAR", true, false, true, false, false, true, true, true, false, false), + CHARACTER("CHARACTER", true, false, true, false, false, true, true, true, false, false), CIDR("CIDR", false, false, true, false, false, false, true, true, false, false), CIRCLE("CIRCLE", false, false, true, false, false, false, true, true, false, false), DATE("DATE", false, false, true, false, false, false, true, true, false, false), @@ -27,11 +29,15 @@ public enum PostgreSQLColumnTypeEnum implements ColumnBuilder { FLOAT8("FLOAT8", false, false, true, false, false, false, true, true, false, false), INET("INET", false, false, true, false, false, false, true, true, false, false), INT2("INT2", false, false, true, false, false, false, true, true, false, false), + SMALLINT("SMALLINT", false, false, true, false, false, false, true, true, false, false), INT4("INT4", false, false, true, false, false, false, true, true, false, false), + INTEGER("INTEGER", false, false, true, false, false, false, true, true, false, false), INT8("INT8", false, false, true, false, false, false, true, true, false, false), + BIGINT("BIGINT", false, false, true, false, false, false, true, true, false, false), INTERVAL("INTERVAL", false, false, true, false, false, false, true, true, false, false), JSON("JSON", false, false, true, false, false, false, true, true, false, false), JSONB("JSONB", false, false, true, false, false, false, true, true, false, false), + JSONPATH("JSONPATH", false, false, true, false, false, false, true, true, false, false), LINE("LINE", false, false, true, false, false, false, true, true, false, false), LSEG("LSEG", false, false, true, false, false, false, true, true, false, false), MACADDR("MACADDR", false, false, true, false, false, false, true, true, false, false), @@ -55,7 +61,9 @@ public enum PostgreSQLColumnTypeEnum implements ColumnBuilder { TXID_SNAPSHOT("TXID_SNAPSHOT", false, false, true, false, false, false, true, true, false, false), UUID("UUID", false, false, true, false, false, false, true, true, false, false), VARBIT("VARBIT", true, false, true, false, false, false, true, true, false, false), + BITVARYING("BIT VARYING", true, false, true, false, false, false, true, true, false, false), VARCHAR("VARCHAR", true, false, true, false, false, true, true, true, false, false), + CHARACTERVARYING("CHARACTER VARYING", true, false, true, false, false, true, true, true, false, false), XML("XML", false, false, true, false, false, false, true, true, false, false), ; diff --git a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java index 5e0282efc..63ec1e41a 100644 --- a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java +++ b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java @@ -424,7 +424,7 @@ private long addDBCache(Long dataSourceId, String databaseName, String schemaNam Connection connection = Chat2DBContext.getConnection(); long n = 0; try (ResultSet resultSet = connection.getMetaData().getTables(databaseName, schemaName, null, - new String[]{"TABLE", "SYSTEM TABLE"})) { + new String[]{"TABLE", "SYSTEM TABLE","PARTITIONED TABLE"})) { List cacheDOS = new ArrayList<>(); while (resultSet.next()) { TableCacheDO tableCacheDO = new TableCacheDO(); diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java index e51181743..df5e62220 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/sql/SQLExecutor.java @@ -30,7 +30,6 @@ import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.parser.ParserException; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; @@ -39,6 +38,8 @@ import org.bson.Document; import org.springframework.util.Assert; +import java.sql.*; + /** * Dbhub unified database connection management * @@ -76,6 +77,44 @@ public R execute(Connection connection, String sql, ResultSetFunction fun return null; } + + public R preExecute(Connection connection, String sql, String[] parameters, ResultSetFunction function) { + log.info("execute:{}", sql); + try (PreparedStatement stmt = connection.prepareStatement(sql)) { + for (int i = 0; i < parameters.length; i++) { + stmt.setString(i + 1, parameters[i]); + } + boolean query = stmt.execute(); + if (query) { + // Represents the query + try (ResultSet rs = stmt.getResultSet();) { + return function.apply(rs); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } + + public void preExecute(Connection connection, String sql, String[] parameters, ResultSetConsumer consumer) { + log.info("execute:{}", sql); + try (PreparedStatement stmt = connection.prepareStatement(sql)) { + for (int i = 0; i < parameters.length; i++) { + stmt.setString(i + 1, parameters[i]); + } + boolean query = stmt.execute(); + if (query) { + // Represents the query + try (ResultSet rs = stmt.getResultSet();) { + consumer.accept(rs); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + public void execute(Connection connection, String sql, ResultSetConsumer consumer) { log.info("execute:{}", sql); try (Statement stmt = connection.createStatement()) { @@ -671,7 +710,7 @@ private ExecuteResult executeSQL(String originalSql, DbType dbType, Command para Header rowNumberHeader = Header.builder() .name(I18nUtils.getMessage("sqlResult.rowNumber")) .dataType(DataTypeEnum.CHAT2DB_ROW_NUMBER - .getCode()).build(); + .getCode()).build(); executeResult.setHeaderList(EasyCollectionUtils.union(Arrays.asList(rowNumberHeader), headers)); if (executeResult.getDataList() != null) { From 03cfa4a2545b9f5058a67b254d39ef7b9877cdfd Mon Sep 17 00:00:00 2001 From: zgq <203083679@qq.com> Date: Sat, 15 Jun 2024 19:29:50 +0800 Subject: [PATCH 4/6] fix-pgsql-table-ddl --- .../chat2db/plugin/postgresql/PostgreSQLMetaData.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java index e621a7955..ec3987802 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java @@ -448,21 +448,21 @@ public String tableDDL(Connection connection, String databaseName, String schema ddlBuilder.append(PostgreSQLColumnTypeEnum.SMALLINT.getColumnType().getTypeName().toLowerCase()).append("[]"); } else if (udtName.contains(PostgreSQLColumnTypeEnum.INT8.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.BIGINT.getColumnType().getTypeName().toLowerCase()).append("[]"); - } else if (udtName.contains(PostgreSQLColumnTypeEnum.VARBIT.name().toLowerCase())) { + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.VARBIT.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.BITVARYING.getColumnType().getTypeName().toLowerCase()).append("[]"); } else if (udtName.contains(PostgreSQLColumnTypeEnum.VARCHAR.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.CHARACTERVARYING.getColumnType().getTypeName().toLowerCase()).append("[]"); - } else if (udtName.contains(PostgreSQLColumnTypeEnum.JSON.name().toLowerCase())) { + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.JSON.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.JSON.getColumnType().getTypeName().toLowerCase()).append("[]"); - } else if (udtName.contains(PostgreSQLColumnTypeEnum.JSONB.name().toLowerCase())) { + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.JSONB.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.JSONB.getColumnType().getTypeName().toLowerCase()).append("[]"); - } else if (udtName.contains(PostgreSQLColumnTypeEnum.JSONPATH.name().toLowerCase())) { + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.JSONPATH.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.JSONPATH.getColumnType().getTypeName().toLowerCase()).append("[]"); } else if (udtName.contains(PostgreSQLColumnTypeEnum.TEXT.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.TEXT.getColumnType().getTypeName().toLowerCase()).append("[]"); } else if (udtName.contains(PostgreSQLColumnTypeEnum.BPCHAR.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.CHAR.getColumnType().getTypeName().toLowerCase()).append("[]"); - } else if (udtName.contains(PostgreSQLColumnTypeEnum.BIT.name().toLowerCase())) { + } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.BIT.name().toLowerCase())) { ddlBuilder.append(PostgreSQLColumnTypeEnum.BIT.getColumnType().getTypeName().toLowerCase()).append("[]"); } else if (udtName.substring(1).equals(PostgreSQLColumnTypeEnum.TIME.name().toLowerCase())) { ddlBuilder.append("time without time zone").append("[]"); From fb14ae3b3c5009a15a43533ec36ef9ce37247dab Mon Sep 17 00:00:00 2001 From: zgq <203083679@qq.com> Date: Tue, 18 Jun 2024 19:00:30 +0800 Subject: [PATCH 5/6] fix serial --- .../ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java index ec3987802..3858cde2b 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java @@ -238,11 +238,7 @@ SELECT quote_ident(c.column_name) as column_name , c.identity_generation, c.is_generated, c.generation_expression, - c.identity_increment, - case - when pg_get_serial_sequence(table_schema || '.' || table_name, - column_name) IS NOT NULL THEN True - ELSE False end as is_serial + c.identity_increment FROM information_schema.columns c WHERE (table_schema, table_name) = (?, ?) ORDER BY ordinal_position;"""; @@ -427,7 +423,7 @@ public String tableDDL(Connection connection, String databaseName, String schema String identityGeneration = resultSet.getString("identity_generation"); boolean isNullable = "YES".equals(resultSet.getString("is_nullable")); boolean isIdentity = "YES".equals(resultSet.getString("is_identity")); - boolean isSerial = resultSet.getBoolean("is_serial"); + boolean isSerial = false; int identityIncrement = resultSet.getInt("identity_increment"); int identityStart = resultSet.getInt("identity_start"); int characterMaximumLength = resultSet.getInt("character_maximum_length"); From f05d1512c5dcee6bf8d8798c3c60477b49f200df Mon Sep 17 00:00:00 2001 From: zgq <203083679@qq.com> Date: Tue, 18 Jun 2024 19:44:46 +0800 Subject: [PATCH 6/6] fix(postgres): correct table options --- .../java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java | 4 ++-- .../ai/chat2db/server/domain/core/impl/TableServiceImpl.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java index 3858cde2b..669639870 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/PostgreSQLMetaData.java @@ -349,7 +349,7 @@ public String tableDDL(Connection connection, String databaseName, String schema String tableOptions = resultSet.getString("table_options"); if (StringUtils.isNotBlank(tableOptions)) { tableOptions = tableOptions.replace("{", "(").replace("}", ")"); - return optionBuilder.append("with ").append(tableOptions).toString(); + return optionBuilder.append(" with ").append(tableOptions).toString(); } } return null; @@ -380,7 +380,7 @@ public String tableDDL(Connection connection, String databaseName, String schema }); if (subTable) { if (StringUtils.isNotBlank(options)) { - ddlBuilder.append("WITH ").append(options); + ddlBuilder.append(options); } return ddlBuilder.append("\n").append(tablespace).toString(); } diff --git a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java index 13b9bb40d..18038e95a 100644 --- a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java +++ b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java @@ -424,7 +424,7 @@ private long addDBCache(Long dataSourceId, String databaseName, String schemaNam Connection connection = Chat2DBContext.getConnection(); long n = 0; try (ResultSet resultSet = connection.getMetaData().getTables(databaseName, schemaName, null, - new String[]{"TABLE", "SYSTEM TABLE","PARTITIONED TABLE"})) { + new String[]{"TABLE", "SYSTEM TABLE"})) { List cacheDOS = new ArrayList<>(); while (resultSet.next()) { TableCacheDO tableCacheDO = new TableCacheDO();