Merge branch 'dev' into feature/20260602_connection_driver_i18n

# Conflicts:
#	frontend/package.json.md5
#	frontend/src/App.tsx
#	frontend/src/components/AIChatPanel.message-boundary.test.tsx
#	frontend/src/components/AIChatPanel.tsx
#	frontend/src/components/AISettingsModal.tsx
#	frontend/src/components/ConnectionModal.tsx
#	frontend/src/components/DataGrid.ddl.test.tsx
#	frontend/src/components/DataGrid.layout.test.tsx
#	frontend/src/components/DataGrid.tsx
#	frontend/src/components/DataGridColumnTitle.test.tsx
#	frontend/src/components/DataGridLegacyCellContextMenu.tsx
#	frontend/src/components/DataGridSecondaryActions.tsx
#	frontend/src/components/DataGridToolbarFrame.tsx
#	frontend/src/components/DataSyncModal.tsx
#	frontend/src/components/DataViewer.tsx
#	frontend/src/components/DefinitionViewer.tsx
#	frontend/src/components/DriverManagerModal.tsx
#	frontend/src/components/QueryEditor.external-sql-save.test.tsx
#	frontend/src/components/QueryEditor.tsx
#	frontend/src/components/RedisViewer.tsx
#	frontend/src/components/Sidebar.locate-toolbar.test.tsx
#	frontend/src/components/Sidebar.tsx
#	frontend/src/components/TabManager.hover.test.tsx
#	frontend/src/components/TabManager.tsx
#	frontend/src/components/TableDesigner.tsx
#	frontend/src/components/V2TableContextMenu.tsx
#	frontend/src/components/ai/AIChatHeader.tsx
#	frontend/src/components/ai/AIHistoryDrawer.tsx
#	frontend/src/main.tsx
#	frontend/src/store.ts
#	frontend/src/utils/aiComposerNotice.test.ts
#	frontend/src/utils/aiComposerNotice.ts
#	frontend/src/utils/connectionModalPresentation.ts
#	frontend/src/utils/driverImportGuidance.ts
#	frontend/src/utils/externalSqlTree.test.ts
#	frontend/src/utils/externalSqlTree.ts
#	frontend/src/utils/sqlDialect.ts
#	internal/ai/service/service.go
This commit is contained in:
tianqijiuyun-latiao
2026-06-16 18:35:11 +08:00
631 changed files with 101151 additions and 10056 deletions

View File

@@ -20,6 +20,7 @@ export type SqlDialect =
| 'highgo'
| 'vastbase'
| 'opengauss'
| 'gaussdb'
| 'oracle'
| 'dameng'
| 'sqlserver'
@@ -28,8 +29,16 @@ export type SqlDialect =
| 'duckdb'
| 'clickhouse'
| 'tdengine'
| 'iotdb'
| 'rocketmq'
| 'mqtt'
| 'kafka'
| 'rabbitmq'
| 'mongodb'
| 'redis'
| 'elasticsearch'
| 'chroma'
| 'qdrant'
| 'unknown'
| string;
@@ -66,6 +75,10 @@ export const resolveSqlDialect = (
case 'open_gauss':
case 'open-gauss':
return 'opengauss';
case 'gaussdb':
case 'gauss_db':
case 'gauss-db':
return 'gaussdb';
case 'mssql':
case 'sql_server':
case 'sql-server':
@@ -94,6 +107,10 @@ export const resolveSqlDialect = (
case 'kingbasees':
case 'kingbasev8':
return 'kingbase';
case 'gdb':
case 'goldendb':
case 'greatdb':
return 'mysql';
case 'mariadb':
case 'oceanbase':
case 'mysql':
@@ -105,17 +122,52 @@ export const resolveSqlDialect = (
case 'duckdb':
case 'clickhouse':
case 'tdengine':
case 'iotdb':
case 'mongodb':
case 'redis':
case 'elasticsearch':
return source;
case 'elastic':
return 'elasticsearch';
case 'chromadb':
case 'chroma-db':
case 'chroma':
return 'chroma';
case 'qdrantdb':
case 'qdrant-db':
case 'qdrant':
return 'qdrant';
case 'apache-iotdb':
case 'apache_iotdb':
return 'iotdb';
case 'rocketmq':
case 'rocket-mq':
case 'rocket_mq':
case 'apache-rocketmq':
case 'apache_rocketmq':
case 'rmq':
return 'rocketmq';
case 'mqtt':
case 'mqtts':
return 'mqtt';
case 'kafka':
case 'apache-kafka':
case 'apache_kafka':
return 'kafka';
case 'rabbitmq':
case 'rabbit-mq':
case 'rabbit_mq':
return 'rabbitmq';
default:
break;
}
if (source.includes('opengauss') || source.includes('open_gauss') || source.includes('open-gauss')) return 'opengauss';
if (source.includes('gaussdb') || source.includes('gauss_db') || source.includes('gauss-db')) return 'gaussdb';
if (source.includes('postgres')) return 'postgres';
if (source.includes('oceanbase')) return 'oceanbase';
if (source.includes('mariadb')) return 'mariadb';
if (source.includes('goldendb') || source.includes('greatdb')) return 'mysql';
if (source.includes('mysql')) return 'mysql';
if (source.includes('doris') || source.includes('diros')) return 'diros';
if (source.includes('starrocks')) return 'starrocks';
@@ -129,8 +181,16 @@ export const resolveSqlDialect = (
if (source.includes('duckdb')) return 'duckdb';
if (source.includes('clickhouse')) return 'clickhouse';
if (source.includes('tdengine')) return 'tdengine';
if (source.includes('iotdb')) return 'iotdb';
if (source.includes('rocketmq') || source.includes('rocket-mq') || source.includes('rocket_mq') || source === 'rmq') return 'rocketmq';
if (source.includes('mqtt')) return 'mqtt';
if (source.includes('kafka')) return 'kafka';
if (source.includes('rabbitmq') || source.includes('rabbit-mq') || source.includes('rabbit_mq')) return 'rabbitmq';
if (source.includes('sqlserver') || source.includes('mssql')) return 'sqlserver';
if (source.includes('iris') || source.includes('intersystems')) return 'iris';
if (source.includes('elastic')) return 'elasticsearch';
if (source.includes('chroma')) return 'chroma';
if (source.includes('qdrant')) return 'qdrant';
return source;
};
@@ -140,7 +200,7 @@ export const isMysqlFamilyDialect = (dbType: string): boolean => (
);
export const isPgLikeDialect = (dbType: string): boolean => (
['postgres', 'kingbase', 'highgo', 'vastbase', 'opengauss'].includes(resolveSqlDialect(dbType))
['postgres', 'kingbase', 'highgo', 'vastbase', 'opengauss', 'gaussdb'].includes(resolveSqlDialect(dbType))
);
export const isOracleLikeDialect = (dbType: string): boolean => (
@@ -150,7 +210,7 @@ export const isOracleLikeDialect = (dbType: string): boolean => (
export const isSqlServerDialect = (dbType: string): boolean => resolveSqlDialect(dbType) === 'sqlserver';
export const isBacktickIdentifierDialect = (dbType: string): boolean => (
isMysqlFamilyDialect(dbType) || ['clickhouse', 'tdengine'].includes(resolveSqlDialect(dbType))
isMysqlFamilyDialect(dbType) || ['clickhouse', 'tdengine', 'iotdb'].includes(resolveSqlDialect(dbType))
);
const stripIdentifierQuotes = (part: string): string => {
@@ -449,6 +509,19 @@ const TDENGINE_TYPES = optionValues([
'GEOMETRY',
]);
const IOTDB_TYPES = optionValues([
'BOOLEAN',
'INT32',
'INT64',
'FLOAT',
'DOUBLE',
'TEXT',
'STRING',
'BLOB',
'TIMESTAMP',
'DATE',
]);
const DUCKDB_TYPES = optionValues([
'BOOLEAN',
'TINYINT',
@@ -493,6 +566,7 @@ export const resolveColumnTypeOptions = (dbType: string): ColumnTypeOption[] =>
if (dialect === 'duckdb') return DUCKDB_TYPES;
if (dialect === 'clickhouse') return CLICKHOUSE_TYPES;
if (dialect === 'tdengine') return TDENGINE_TYPES;
if (dialect === 'iotdb') return IOTDB_TYPES;
return COMMON_TYPES;
};
@@ -544,6 +618,67 @@ const STARROCKS_KEYWORDS = [
const TDENGINE_KEYWORDS = ['LIMIT', 'SLIMIT', 'SOFFSET', 'TAGS', 'USING', 'INTERVAL', 'FILL', 'PARTITION BY'];
const IOTDB_KEYWORDS = [
'LIMIT',
'OFFSET',
'ALIGN BY DEVICE',
'DISABLE ALIGN',
'GROUP BY',
'LEVEL',
'FILL',
'SLIMIT',
'SOFFSET',
'CREATE TIMESERIES',
'SHOW TIMESERIES',
'SHOW DEVICES',
'SHOW DATABASES',
'STORAGE GROUP',
'WITH DATATYPE',
'ENCODING',
'COMPRESSION',
];
const ROCKETMQ_KEYWORDS = [
'SHOW TOPICS',
'DESCRIBE TOPIC',
'CONSUME',
'FROM',
'LIMIT',
'OFFSET',
];
const MQTT_KEYWORDS = [
'SHOW TOPICS',
'DESCRIBE TOPIC',
'CONSUME',
'FROM',
'LIMIT',
'OFFSET',
];
const KAFKA_KEYWORDS = [
'SHOW TOPICS',
'SHOW TOPIC',
'DESCRIBE TOPIC',
'CONSUME',
'GROUP',
'FROM',
'LIMIT',
'OFFSET',
];
const RABBITMQ_KEYWORDS = [
'SHOW VHOSTS',
'SHOW QUEUES',
'SHOW EXCHANGES',
'DESCRIBE QUEUE',
'DESCRIBE EXCHANGE',
'CONSUME',
'FROM',
'LIMIT',
'OFFSET',
];
export const resolveSqlKeywords = (dbType: string): string[] => {
const dialect = resolveSqlDialect(dbType);
if (dialect === 'starrocks') return unique([...COMMON_KEYWORDS, ...MYSQL_KEYWORDS, ...STARROCKS_KEYWORDS]);
@@ -555,6 +690,11 @@ export const resolveSqlKeywords = (dbType: string): string[] => {
if (dialect === 'duckdb') return unique([...COMMON_KEYWORDS, ...DUCKDB_KEYWORDS]);
if (dialect === 'clickhouse') return unique([...COMMON_KEYWORDS, ...CLICKHOUSE_KEYWORDS]);
if (dialect === 'tdengine') return unique([...COMMON_KEYWORDS, ...TDENGINE_KEYWORDS]);
if (dialect === 'iotdb') return unique([...COMMON_KEYWORDS, ...IOTDB_KEYWORDS]);
if (dialect === 'rocketmq') return unique([...COMMON_KEYWORDS, ...ROCKETMQ_KEYWORDS]);
if (dialect === 'mqtt') return unique([...COMMON_KEYWORDS, ...MQTT_KEYWORDS]);
if (dialect === 'kafka') return unique([...COMMON_KEYWORDS, ...KAFKA_KEYWORDS]);
if (dialect === 'rabbitmq') return unique([...COMMON_KEYWORDS, ...RABBITMQ_KEYWORDS]);
return COMMON_KEYWORDS;
};
@@ -790,6 +930,19 @@ const TDENGINE_FUNCTIONS = [
fn('IRATE', vendorDetail('TDengine', 'query_editor.completion.action.instant_rate_of_change')),
];
const IOTDB_FUNCTIONS = [
fn('NOW', vendorDetail('IoTDB', 'query_editor.completion.action.current_time')),
fn('DATE_BIN', vendorDetail('IoTDB', 'query_editor.completion.action.date_truncation')),
fn('DIFF', vendorDetail('IoTDB', 'query_editor.completion.action.time_difference')),
fn('TIME_DIFFERENCE', vendorDetail('IoTDB', 'query_editor.completion.action.time_difference')),
fn('DERIVATIVE', vendorDetail('IoTDB', 'query_editor.completion.action.rate_of_change')),
fn('NON_NEGATIVE_DERIVATIVE', vendorDetail('IoTDB', 'query_editor.completion.action.rate_of_change')),
fn('TOP_K', vendorDetail('IoTDB', 'query_editor.completion.action.maximum')),
fn('BOTTOM_K', vendorDetail('IoTDB', 'query_editor.completion.action.minimum')),
fn('M4', vendorDetail('IoTDB', 'query_editor.completion.action.approximate_quantile')),
fn('EQUAL_SIZE_BUCKET_RANDOM_SAMPLE', vendorDetail('IoTDB', 'query_editor.completion.action.random_number')),
];
const mergeFunctions = (items: SqlFunctionDefinition[]): SqlFunctionCompletion[] => {
const seen = new Set<string>();
const result: SqlFunctionCompletion[] = [];
@@ -816,5 +969,6 @@ export const resolveSqlFunctions = (dbType: string): SqlFunctionCompletion[] =>
if (dialect === 'duckdb') return mergeFunctions([...COMMON_FUNCTIONS, ...DUCKDB_FUNCTIONS]);
if (dialect === 'clickhouse') return mergeFunctions([...COMMON_FUNCTIONS, ...CLICKHOUSE_FUNCTIONS]);
if (dialect === 'tdengine') return mergeFunctions([...COMMON_FUNCTIONS, ...TDENGINE_FUNCTIONS]);
if (dialect === 'iotdb') return mergeFunctions([...COMMON_FUNCTIONS, ...IOTDB_FUNCTIONS]);
return mergeFunctions(COMMON_FUNCTIONS);
};