@@ -23,6 +23,12 @@ import { LoadPreAggregationResult, PreAggregationDescription } from './PreAggreg
2323import { getCacheHash } from './utils' ;
2424import { CacheAndQueryDriverType } from './QueryOrchestrator' ;
2525
26+ enum MetadataOperation {
27+ GET_SCHEMAS = 'GET_SCHEMAS' ,
28+ GET_TABLES_FOR_SCHEMAS = 'GET_TABLES_FOR_SCHEMAS' ,
29+ GET_COLUMNS_FOR_TABLES = 'GET_COLUMNS_FOR_TABLES'
30+ }
31+
2632type QueryOptions = {
2733 external ?: boolean ;
2834 renewalThreshold ?: number ;
@@ -579,17 +585,17 @@ export class QueryCache {
579585 const params = req . values && req . values [ 0 ] ? JSON . parse ( req . values [ 0 ] ) : { } ;
580586
581587 switch ( operation ) {
582- case ' GET_SCHEMAS' :
588+ case MetadataOperation . GET_SCHEMAS :
583589 queue . logger ( 'Getting datasource schemas' , { dataSource : req . dataSource , requestId : req . requestId } ) ;
584590 return client . getSchemas ( ) ;
585- case ' GET_TABLES_FOR_SCHEMAS' :
591+ case MetadataOperation . GET_TABLES_FOR_SCHEMAS :
586592 queue . logger ( 'Getting tables for schemas' , {
587593 dataSource : req . dataSource ,
588594 schemaCount : params . schemas ?. length || 0 ,
589595 requestId : req . requestId
590596 } ) ;
591597 return client . getTablesForSpecificSchemas ( params . schemas ) ;
592- case ' GET_COLUMNS_FOR_TABLES' :
598+ case MetadataOperation . GET_COLUMNS_FOR_TABLES :
593599 queue . logger ( 'Getting columns for tables' , {
594600 dataSource : req . dataSource ,
595601 tableCount : params . tables ?. length || 0 ,
@@ -1042,27 +1048,47 @@ export class QueryCache {
10421048 return this . cacheDriver . testConnection ( ) ;
10431049 }
10441050
1045- private createMetadataHash ( items : any [ ] ) : string {
1046- if ( ! items || items . length === 0 ) {
1051+ private createMetadataHash ( operation : MetadataOperation , params : Record < string , any > ) : string {
1052+ if ( ! params || Object . keys ( params ) . length === 0 ) {
10471053 return 'empty' ;
10481054 }
10491055
1050- const sortedKeys = items
1051- . map ( item => {
1052- if ( item . schema_name && item . table_name ) {
1053- return `${ item . schema_name } .${ item . table_name } ` ;
1054- } else if ( item . schema_name && item . column_name ) {
1055- return `${ item . schema_name } .${ item . table_name } .${ item . column_name } ` ;
1056- } else if ( item . schema_name ) {
1057- return item . schema_name ;
1056+ // Create deterministic hash based on operation type and params
1057+ const hashData : string [ ] = [ ] ;
1058+
1059+ switch ( operation ) {
1060+ case MetadataOperation . GET_SCHEMAS :
1061+ // For schemas, we don't have any params to hash
1062+ return 'all_schemas' ;
1063+
1064+ case MetadataOperation . GET_TABLES_FOR_SCHEMAS :
1065+ if ( params . schemas && Array . isArray ( params . schemas ) ) {
1066+ hashData . push ( ...params . schemas . map ( schema => schema . schema_name ) . sort ( ) ) ;
10581067 }
1059- return JSON . stringify ( item ) ;
1060- } )
1061- . sort ( ) ;
1068+ break ;
1069+
1070+ case MetadataOperation . GET_COLUMNS_FOR_TABLES :
1071+ if ( params . tables && Array . isArray ( params . tables ) ) {
1072+ hashData . push ( ...params . tables . map ( table => `${ table . schema_name } .${ table . table_name } ` ) . sort ( ) ) ;
1073+ }
1074+ break ;
1075+
1076+ default :
1077+ // Fallback to JSON serialization for unknown operations
1078+ return crypto
1079+ . createHash ( 'sha256' )
1080+ . update ( JSON . stringify ( params ) )
1081+ . digest ( 'hex' )
1082+ . substring ( 0 , 16 ) ;
1083+ }
1084+
1085+ if ( hashData . length === 0 ) {
1086+ return 'empty' ;
1087+ }
10621088
10631089 return crypto
10641090 . createHash ( 'sha256' )
1065- . update ( sortedKeys . join ( '|' ) )
1091+ . update ( hashData . join ( '|' ) )
10661092 . digest ( 'hex' )
10671093 . substring ( 0 , 16 ) ;
10681094 }
@@ -1076,7 +1102,7 @@ export class QueryCache {
10761102 }
10771103
10781104 private async queryDataSourceMetadata < T > (
1079- operation : string ,
1105+ operation : MetadataOperation ,
10801106 params : Record < string , any > ,
10811107 dataSource : string = 'default' ,
10821108 options : {
@@ -1093,12 +1119,7 @@ export class QueryCache {
10931119 expiration = 7 * 24 * 60 * 60 ,
10941120 } = options ;
10951121
1096- let paramsHash = 'empty' ;
1097- if ( params . schemas ) {
1098- paramsHash = this . createMetadataHash ( params . schemas ) ;
1099- } else if ( params . tables ) {
1100- paramsHash = this . createMetadataHash ( params . tables ) ;
1101- }
1122+ const paramsHash = this . createMetadataHash ( operation , params ) ;
11021123
11031124 const metadataQuery = this . createMetadataQuery ( operation , params ) ;
11041125 const cacheKey : CacheKey = [ `METADATA:${ operation } ` , paramsHash , dataSource ] ;
@@ -1137,7 +1158,7 @@ export class QueryCache {
11371158 } = { }
11381159 ) : Promise < QuerySchemasResult [ ] > {
11391160 return this . queryDataSourceMetadata < QuerySchemasResult [ ] > (
1140- ' GET_SCHEMAS' ,
1161+ MetadataOperation . GET_SCHEMAS ,
11411162 { } ,
11421163 dataSource ,
11431164 options
@@ -1155,7 +1176,7 @@ export class QueryCache {
11551176 } = { }
11561177 ) : Promise < QueryTablesResult [ ] > {
11571178 return this . queryDataSourceMetadata < QueryTablesResult [ ] > (
1158- ' GET_TABLES_FOR_SCHEMAS' ,
1179+ MetadataOperation . GET_TABLES_FOR_SCHEMAS ,
11591180 { schemas } ,
11601181 dataSource ,
11611182 options
@@ -1173,15 +1194,15 @@ export class QueryCache {
11731194 } = { }
11741195 ) : Promise < QueryColumnsResult [ ] > {
11751196 return this . queryDataSourceMetadata < QueryColumnsResult [ ] > (
1176- ' GET_COLUMNS_FOR_TABLES' ,
1197+ MetadataOperation . GET_COLUMNS_FOR_TABLES ,
11771198 { tables } ,
11781199 dataSource ,
11791200 options
11801201 ) ;
11811202 }
11821203
11831204 public async clearDataSourceSchemaCache ( dataSource : string = 'default' ) {
1184- const cacheKey : CacheKey = [ ' METADATA:GET_SCHEMAS' , 'empty' , dataSource ] ;
1205+ const cacheKey : CacheKey = [ ` METADATA:${ MetadataOperation . GET_SCHEMAS } ` , 'empty' , dataSource ] ;
11851206 const redisKey = this . queryRedisKey ( cacheKey ) ;
11861207 await this . cacheDriver . remove ( redisKey ) ;
11871208 this . logger ( 'Cleared datasource schema cache' , { dataSource } ) ;
@@ -1191,8 +1212,8 @@ export class QueryCache {
11911212 schemas : QuerySchemasResult [ ] ,
11921213 dataSource : string = 'default'
11931214 ) {
1194- const paramsHash = this . createMetadataHash ( schemas ) ;
1195- const cacheKey : CacheKey = [ ' METADATA:GET_TABLES_FOR_SCHEMAS' , paramsHash , dataSource ] ;
1215+ const paramsHash = this . createMetadataHash ( MetadataOperation . GET_TABLES_FOR_SCHEMAS , { schemas } ) ;
1216+ const cacheKey : CacheKey = [ ` METADATA:${ MetadataOperation . GET_TABLES_FOR_SCHEMAS } ` , paramsHash , dataSource ] ;
11961217 const redisKey = this . queryRedisKey ( cacheKey ) ;
11971218 await this . cacheDriver . remove ( redisKey ) ;
11981219 this . logger ( 'Cleared tables for schemas cache' , {
@@ -1206,8 +1227,8 @@ export class QueryCache {
12061227 tables : QueryTablesResult [ ] ,
12071228 dataSource : string = 'default'
12081229 ) {
1209- const paramsHash = this . createMetadataHash ( tables ) ;
1210- const cacheKey : CacheKey = [ ' METADATA:GET_COLUMNS_FOR_TABLES' , paramsHash , dataSource ] ;
1230+ const paramsHash = this . createMetadataHash ( MetadataOperation . GET_COLUMNS_FOR_TABLES , { tables } ) ;
1231+ const cacheKey : CacheKey = [ ` METADATA:${ MetadataOperation . GET_COLUMNS_FOR_TABLES } ` , paramsHash , dataSource ] ;
12111232 const redisKey = this . queryRedisKey ( cacheKey ) ;
12121233 await this . cacheDriver . remove ( redisKey ) ;
12131234 this . logger ( 'Cleared columns for tables cache' , {
0 commit comments