From ffd5964ad8606a13f6f9f168a92b5d6e4c04c8b6 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Fri, 15 May 2026 07:46:18 +0530 Subject: [PATCH 01/20] feat: added-bulk-edit --- server/internal/constants/constants.go | 2 +- .../internal/handlers/optimization/table.go | 22 +++++ server/internal/models/dto/requests.go | 6 ++ server/internal/models/dto/response.go | 9 ++ .../services/optimization/terminal.go | 90 ++++++++++++++++--- server/routes/router.go | 1 + 6 files changed, 119 insertions(+), 11 deletions(-) diff --git a/server/internal/constants/constants.go b/server/internal/constants/constants.go index fffd76c7..f1122000 100644 --- a/server/internal/constants/constants.go +++ b/server/internal/constants/constants.go @@ -101,7 +101,7 @@ var ( OptPathTerminalExecute = "/api/ams/v1/terminal/catalogs/%s/execute" OptPathTerminalLogs = "/api/ams/v1/terminal/%s/logs" // others - OptMaxTimeout = 30 * time.Second + OptMaxTimeout = 5 * time.Minute OptQueryResultPollTime = 1500 * time.Millisecond OptMinorCron = "self-optimizing.minor.trigger.cron" OptMajorCron = "self-optimizing.major.trigger.cron" diff --git a/server/internal/handlers/optimization/table.go b/server/internal/handlers/optimization/table.go index 8aeb035f..747ca3c3 100644 --- a/server/internal/handlers/optimization/table.go +++ b/server/internal/handlers/optimization/table.go @@ -44,6 +44,28 @@ func (h *Handler) SetProperties(c *gin.Context) { utils.SuccessResponse(c, result.Message, result) } +// SetBulkProperties configures the same optimization properties on multiple tables (one terminal batch). +func (h *Handler) SetBulkProperties(c *gin.Context) { + catalog, database, ok := h.requiredCatalogAndDatabase(c) + if !ok { + return + } + + var req dto.BulkSQLInput + if err := utils.BindAndValidate(c, &req); err != nil { + utils.ErrorResponse(c, utils.StatusFromBindError(err), "invalid request body for bulk table properties", err) + return + } + + result, err := h.opt.BulkSetProperties(c.Request.Context(), catalog, database, req) + if err != nil { + utils.ErrorResponse(c, upstreamStatus(err), err.Error(), err) + return + } + + utils.SuccessResponse(c, result.Message, result) +} + func (h *Handler) requiredCatalogDatabaseTable(c *gin.Context) (string, string, string, bool) { catalog := c.Param("catalog") database := c.Param("database") diff --git a/server/internal/models/dto/requests.go b/server/internal/models/dto/requests.go index c52e4342..5c470e89 100644 --- a/server/internal/models/dto/requests.go +++ b/server/internal/models/dto/requests.go @@ -181,3 +181,9 @@ type SQLInput struct { TargetFileSize *int64 `json:"target_file_size"` EnabledForOptimization *string `json:"enabled_for_optimization"` } + +// BulkSQLInput configures optimization properties for multiple tables in one AMS terminal session. +type BulkSQLInput struct { + Tables []string `json:"tables" binding:"required,min=1,dive,required"` + SQLInput SQLInput `json:"sql_input"` +} diff --git a/server/internal/models/dto/response.go b/server/internal/models/dto/response.go index b20c204c..c932237c 100644 --- a/server/internal/models/dto/response.go +++ b/server/internal/models/dto/response.go @@ -252,6 +252,15 @@ type TableProperties struct { Logs []string `json:"logs,omitempty"` } +// BulkTableProperties is the response from bulk-setting optimization properties. +type BulkTableProperties struct { + SessionID string `json:"sessionId"` + Success bool `json:"success"` + Message string `json:"message"` + Logs []string `json:"logs,omitempty"` + Tables []string `json:"tables"` +} + // TerminalSessionResponse represents the response from terminal execute type TerminalSessionResponse struct { SessionID string `json:"sessionId"` diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 731713d3..61829f16 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -13,9 +13,8 @@ import ( "github.com/datazip-inc/olake-ui/server/internal/utils" ) -func (s *Service) SetProperties(ctx context.Context, catalog, database, table string, config dto.SQLInput) (*dto.TableProperties, error) { +func SetPropertiesMap(config dto.SQLInput) map[string]string { properties := make(map[string]string) - if config.MinorCron != nil { properties[constants.OptMinorCron] = *config.MinorCron } @@ -31,7 +30,11 @@ func (s *Service) SetProperties(ctx context.Context, catalog, database, table st if config.TargetFileSize != nil { properties[constants.OptTargetFileSize] = utils.ConvertMBToBytes(*config.TargetFileSize) } + return properties +} +func (s *Service) SetProperties(ctx context.Context, catalog, database, table string, config dto.SQLInput) (*dto.TableProperties, error) { + properties := SetPropertiesMap(config) // sql query sqlResult, err := s.SetTableProperties(ctx, dto.SetTablePropertiesRequest{ Catalog: catalog, @@ -47,14 +50,80 @@ func (s *Service) SetProperties(ctx context.Context, catalog, database, table st return sqlResult, nil } -// sets table properties using the SQL query -func (s *Service) SetTableProperties(ctx context.Context, req dto.SetTablePropertiesRequest) (*dto.TableProperties, error) { - var propsSQL []string - for key, value := range req.Properties { - propsSQL = append(propsSQL, fmt.Sprintf("'%s' = '%s'", key, value)) +// createAlterQuery returns one ALTER TABLE ... SET TBLPROPERTIES (...) statement for database.table, ending with ';'. +func createAlterQuery(database string, table string, properties map[string]string) string { + keys := make([]string, 0, len(properties)) + for k := range properties { + keys = append(keys, k) + } + + parts := make([]string, 0, len(keys)) + for _, k := range keys { + parts = append(parts, fmt.Sprintf("'%s'='%s'", k, properties[k])) + } + propsJoined := strings.Join(parts, ", ") + + return fmt.Sprintf(constants.OptSQLCommand, database, table, propsJoined) + ";" +} + +// BulkSetProperties runs one AMS terminal session that executes ALTER TABLE ... SET TBLPROPERTIES +// for every table in req.Tables (same property set on each). +func (s *Service) BulkSetProperties(ctx context.Context, catalog, database string, req dto.BulkSQLInput) (*dto.BulkTableProperties, error) { + tables := req.Tables + properties := SetPropertiesMap(req.SQLInput) + // Bulk apply always enables self-optimizing on every selected table. + properties[constants.OptEnableOptimization] = "true" + + stmts := make([]string, 0, len(tables)) + for _, t := range tables { + stmts = append(stmts, createAlterQuery(database, t, properties)) + } + // One AMS terminal execute body: multiple statements, one Spark session (AMS splits on ';' per line). + sqlScript := strings.Join(stmts, "\n") + + path := fmt.Sprintf(constants.OptPathTerminalExecute, catalog) + requestBody := dto.TerminalExecuteRequest{ + SQL: sqlScript, + } + + var sessionResult dto.TerminalSessionResponse + if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { + return nil, fmt.Errorf("failed to execute bulk ALTER TABLE for catalog %s: %w", catalog, err) + } + + logInfo, err := s.pollForCompletion(ctx, catalog, sessionResult.SessionID) + if err != nil { + return nil, fmt.Errorf("failed to poll for completion: %w", err) + } + + success := logInfo.LogStatus == "Finished" + var message string + if success { + message = fmt.Sprintf( + "bulk optimization sql command completed successfully for %d table(s), session ID: %s", + len(tables), + sessionResult.SessionID, + ) + } else { + message = fmt.Sprintf( + "bulk optimization sql command failed for catalog %s, session ID: %s", + catalog, + sessionResult.SessionID, + ) } - sql := fmt.Sprintf(constants.OptSQLCommand, req.Database, req.Table, strings.Join(propsSQL, ", ")) + return &dto.BulkTableProperties{ + SessionID: sessionResult.SessionID, + Success: success, + Message: message, + Logs: logInfo.Logs, + Tables: tables, + }, nil +} + +// sets table properties using the SQL query +func (s *Service) SetTableProperties(ctx context.Context, req dto.SetTablePropertiesRequest) (*dto.TableProperties, error) { + sql := createAlterQuery(req.Database, req.Table, req.Properties) // execute via Terminal API path := fmt.Sprintf(constants.OptPathTerminalExecute, req.Catalog) @@ -109,8 +178,9 @@ func (s *Service) pollForCompletion(ctx context.Context, _, sessionID string) (* if err := s.DoInto(ctx, http.MethodGet, path, url.Values{}, nil, &logInfo); err != nil { return nil, fmt.Errorf("failed to get logs for session %s: %w", sessionID, err) } - - return &logInfo, nil + if logInfo.LogStatus == "Finished" { + return &logInfo, nil + } } } } diff --git a/server/routes/router.go b/server/routes/router.go index d2f8cfa3..d80d234e 100644 --- a/server/routes/router.go +++ b/server/routes/router.go @@ -91,6 +91,7 @@ func RegisterRoutes(engine *gin.Engine, h *handlers.Handler) { opt.DELETE("/catalog/:catalog", optHandler.DeleteCatalog) // terminal: cron, enable/disable optimization + opt.PUT("/:catalog/:database/config/bulk", optHandler.SetBulkProperties) opt.PUT("/:catalog/:database/:table/config", optHandler.SetProperties) // tables: view From 04c3c9453d4ab19932c2c3d235a308f0f813ebbc Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Fri, 15 May 2026 19:06:31 +0530 Subject: [PATCH 02/20] fix: minor-fix --- .../internal/services/optimization/terminal.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 61829f16..edc41acb 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -57,11 +57,11 @@ func createAlterQuery(database string, table string, properties map[string]strin keys = append(keys, k) } - parts := make([]string, 0, len(keys)) + props := make([]string, 0, len(keys)) for _, k := range keys { - parts = append(parts, fmt.Sprintf("'%s'='%s'", k, properties[k])) + props = append(props, fmt.Sprintf("'%s'='%s'", k, properties[k])) } - propsJoined := strings.Join(parts, ", ") + propsJoined := strings.Join(props, ", ") return fmt.Sprintf(constants.OptSQLCommand, database, table, propsJoined) + ";" } @@ -74,16 +74,16 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin // Bulk apply always enables self-optimizing on every selected table. properties[constants.OptEnableOptimization] = "true" - stmts := make([]string, 0, len(tables)) + sql := make([]string, 0, len(tables)) for _, t := range tables { - stmts = append(stmts, createAlterQuery(database, t, properties)) + sql= append(sql, createAlterQuery(database, t, properties)) } // One AMS terminal execute body: multiple statements, one Spark session (AMS splits on ';' per line). - sqlScript := strings.Join(stmts, "\n") + bulkSqlScript := strings.Join(sql, "\n") path := fmt.Sprintf(constants.OptPathTerminalExecute, catalog) requestBody := dto.TerminalExecuteRequest{ - SQL: sqlScript, + SQL: bulkSqlScript, } var sessionResult dto.TerminalSessionResponse @@ -178,9 +178,7 @@ func (s *Service) pollForCompletion(ctx context.Context, _, sessionID string) (* if err := s.DoInto(ctx, http.MethodGet, path, url.Values{}, nil, &logInfo); err != nil { return nil, fmt.Errorf("failed to get logs for session %s: %w", sessionID, err) } - if logInfo.LogStatus == "Finished" { - return &logInfo, nil - } + return &logInfo, nil } } } From d9e6874464db15cee8058304296283e7ab33049c Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Fri, 15 May 2026 19:40:30 +0530 Subject: [PATCH 03/20] fix: fixed-lint-error --- server/internal/models/dto/requests.go | 4 ++-- server/internal/services/optimization/terminal.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/server/internal/models/dto/requests.go b/server/internal/models/dto/requests.go index 5c470e89..be20159e 100644 --- a/server/internal/models/dto/requests.go +++ b/server/internal/models/dto/requests.go @@ -184,6 +184,6 @@ type SQLInput struct { // BulkSQLInput configures optimization properties for multiple tables in one AMS terminal session. type BulkSQLInput struct { - Tables []string `json:"tables" binding:"required,min=1,dive,required"` - SQLInput SQLInput `json:"sql_input"` + Tables []string `json:"tables" binding:"required"` + SQLInput SQLInput `json:"sql_input"` } diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index edc41acb..9eb4c343 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -51,7 +51,7 @@ func (s *Service) SetProperties(ctx context.Context, catalog, database, table st } // createAlterQuery returns one ALTER TABLE ... SET TBLPROPERTIES (...) statement for database.table, ending with ';'. -func createAlterQuery(database string, table string, properties map[string]string) string { +func createAlterQuery(database, table string, properties map[string]string) string { keys := make([]string, 0, len(properties)) for k := range properties { keys = append(keys, k) @@ -76,14 +76,14 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin sql := make([]string, 0, len(tables)) for _, t := range tables { - sql= append(sql, createAlterQuery(database, t, properties)) + sql = append(sql, createAlterQuery(database, t, properties)) } // One AMS terminal execute body: multiple statements, one Spark session (AMS splits on ';' per line). - bulkSqlScript := strings.Join(sql, "\n") + bulkSQLScript := strings.Join(sql, "\n") path := fmt.Sprintf(constants.OptPathTerminalExecute, catalog) requestBody := dto.TerminalExecuteRequest{ - SQL: bulkSqlScript, + SQL: bulkSQLScript, } var sessionResult dto.TerminalSessionResponse From 9941f4cd78ee449cdb1ec30f9cd3319388abf4a9 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Fri, 22 May 2026 16:00:47 +0530 Subject: [PATCH 04/20] fix: minor-fix --- server/internal/constants/constants.go | 3 +- .../services/optimization/terminal.go | 30 ++++++++----------- server/routes/router.go | 2 +- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/server/internal/constants/constants.go b/server/internal/constants/constants.go index f1122000..32cddea3 100644 --- a/server/internal/constants/constants.go +++ b/server/internal/constants/constants.go @@ -101,7 +101,8 @@ var ( OptPathTerminalExecute = "/api/ams/v1/terminal/catalogs/%s/execute" OptPathTerminalLogs = "/api/ams/v1/terminal/%s/logs" // others - OptMaxTimeout = 5 * time.Minute + OptMaxTimeout = 30 * time.Second + OptSessionTimeout = 1 * time.Minute OptQueryResultPollTime = 1500 * time.Millisecond OptMinorCron = "self-optimizing.minor.trigger.cron" OptMajorCron = "self-optimizing.major.trigger.cron" diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 9eb4c343..0470fbd9 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -13,7 +13,7 @@ import ( "github.com/datazip-inc/olake-ui/server/internal/utils" ) -func SetPropertiesMap(config dto.SQLInput) map[string]string { +func setPropertiesMap(config dto.SQLInput) map[string]string { properties := make(map[string]string) if config.MinorCron != nil { properties[constants.OptMinorCron] = *config.MinorCron @@ -34,7 +34,7 @@ func SetPropertiesMap(config dto.SQLInput) map[string]string { } func (s *Service) SetProperties(ctx context.Context, catalog, database, table string, config dto.SQLInput) (*dto.TableProperties, error) { - properties := SetPropertiesMap(config) + properties := setPropertiesMap(config) // sql query sqlResult, err := s.SetTableProperties(ctx, dto.SetTablePropertiesRequest{ Catalog: catalog, @@ -52,25 +52,19 @@ func (s *Service) SetProperties(ctx context.Context, catalog, database, table st // createAlterQuery returns one ALTER TABLE ... SET TBLPROPERTIES (...) statement for database.table, ending with ';'. func createAlterQuery(database, table string, properties map[string]string) string { - keys := make([]string, 0, len(properties)) - for k := range properties { - keys = append(keys, k) - } - - props := make([]string, 0, len(keys)) - for _, k := range keys { - props = append(props, fmt.Sprintf("'%s'='%s'", k, properties[k])) + props := make([]string, 0, len(properties)) + for k, value := range properties { + props = append(props, fmt.Sprintf("'%s'='%s'", k, value)) } propsJoined := strings.Join(props, ", ") return fmt.Sprintf(constants.OptSQLCommand, database, table, propsJoined) + ";" } -// BulkSetProperties runs one AMS terminal session that executes ALTER TABLE ... SET TBLPROPERTIES -// for every table in req.Tables (same property set on each). +// BulkSetProperties runs one terminal session that executes ALTER TABLE ... SET TBLPROPERTIES func (s *Service) BulkSetProperties(ctx context.Context, catalog, database string, req dto.BulkSQLInput) (*dto.BulkTableProperties, error) { tables := req.Tables - properties := SetPropertiesMap(req.SQLInput) + properties := setPropertiesMap(req.SQLInput) // Bulk apply always enables self-optimizing on every selected table. properties[constants.OptEnableOptimization] = "true" @@ -78,7 +72,6 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin for _, t := range tables { sql = append(sql, createAlterQuery(database, t, properties)) } - // One AMS terminal execute body: multiple statements, one Spark session (AMS splits on ';' per line). bulkSQLScript := strings.Join(sql, "\n") path := fmt.Sprintf(constants.OptPathTerminalExecute, catalog) @@ -88,12 +81,12 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin var sessionResult dto.TerminalSessionResponse if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { - return nil, fmt.Errorf("failed to execute bulk ALTER TABLE for catalog %s: %w", catalog, err) + return nil, fmt.Errorf("failed to execute bulk ALTER TABLE for catalog %s, database %s: %w", catalog, database, err) } logInfo, err := s.pollForCompletion(ctx, catalog, sessionResult.SessionID) if err != nil { - return nil, fmt.Errorf("failed to poll for completion: %w", err) + return nil, fmt.Errorf("failed to poll for completion for selected %d table(s): %w", len(tables), err) } success := logInfo.LogStatus == "Finished" @@ -106,8 +99,9 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin ) } else { message = fmt.Sprintf( - "bulk optimization sql command failed for catalog %s, session ID: %s", + "bulk optimization sql command failed for catalog %s, database %s, session ID: %s", catalog, + database, sessionResult.SessionID, ) } @@ -163,7 +157,7 @@ func (s *Service) SetTableProperties(ctx context.Context, req dto.SetTableProper // pollForCompletion polls the terminal API for SQL execution completion func (s *Service) pollForCompletion(ctx context.Context, _, sessionID string) (*dto.LogInfo, error) { path := fmt.Sprintf(constants.OptPathTerminalLogs, sessionID) - timeoutCtx, cancel := context.WithTimeout(ctx, constants.OptMaxTimeout) + timeoutCtx, cancel := context.WithTimeout(ctx, constants.OptSessionTimeout) defer cancel() ticker := time.NewTicker(constants.OptQueryResultPollTime) diff --git a/server/routes/router.go b/server/routes/router.go index d80d234e..e5e0ae9a 100644 --- a/server/routes/router.go +++ b/server/routes/router.go @@ -91,8 +91,8 @@ func RegisterRoutes(engine *gin.Engine, h *handlers.Handler) { opt.DELETE("/catalog/:catalog", optHandler.DeleteCatalog) // terminal: cron, enable/disable optimization - opt.PUT("/:catalog/:database/config/bulk", optHandler.SetBulkProperties) opt.PUT("/:catalog/:database/:table/config", optHandler.SetProperties) + opt.PUT("/:catalog/:database/tables/config", optHandler.SetBulkProperties) // tables: view opt.GET("/:catalog/:database/tables", optHandler.GetTablesWithDetails) From aea19aaf946022863ddbfda347537d30f5d76840 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Wed, 27 May 2026 11:03:59 +0530 Subject: [PATCH 05/20] fix: minor-fix --- server/internal/models/dto/requests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/models/dto/requests.go b/server/internal/models/dto/requests.go index be20159e..ba7e61b5 100644 --- a/server/internal/models/dto/requests.go +++ b/server/internal/models/dto/requests.go @@ -182,7 +182,7 @@ type SQLInput struct { EnabledForOptimization *string `json:"enabled_for_optimization"` } -// BulkSQLInput configures optimization properties for multiple tables in one AMS terminal session. +// BulkSQLInput configures optimization properties for multiple tables in one terminal session. type BulkSQLInput struct { Tables []string `json:"tables" binding:"required"` SQLInput SQLInput `json:"sql_input"` From 6f15a2ca51e6993b6851bd3171c790ec45652cdb Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Wed, 27 May 2026 13:52:17 +0530 Subject: [PATCH 06/20] fix: upgraded-go-crypto-v0.52.0 --- server/go.mod | 14 +++++++------- server/go.sum | 49 ++++++++++++++++--------------------------------- 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/server/go.mod b/server/go.mod index 4f17cfd8..dd85980d 100644 --- a/server/go.mod +++ b/server/go.mod @@ -18,8 +18,8 @@ require ( github.com/swaggo/swag v1.16.6 github.com/testcontainers/testcontainers-go v0.42.0 go.temporal.io/sdk v1.39.0 - golang.org/x/crypto v0.50.0 - golang.org/x/mod v0.34.0 + golang.org/x/crypto v0.52.0 + golang.org/x/mod v0.35.0 google.golang.org/api v0.265.0 gorm.io/driver/postgres v1.6.0 gorm.io/gorm v1.31.1 @@ -145,8 +145,8 @@ require ( golang.org/x/arch v0.22.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/oauth2 v0.35.0 // indirect - golang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c // indirect - golang.org/x/tools v0.43.0 // indirect + golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa // indirect + golang.org/x/tools v0.44.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect ) @@ -174,10 +174,10 @@ require ( github.com/stretchr/testify v1.11.1 github.com/subosito/gotenv v1.6.0 // indirect go.temporal.io/api v1.62.0 - golang.org/x/net v0.53.0 // indirect + golang.org/x/net v0.54.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect - golang.org/x/text v0.36.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.14.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect diff --git a/server/go.sum b/server/go.sum index 4c37f360..f25dde43 100644 --- a/server/go.sum +++ b/server/go.sum @@ -392,36 +392,28 @@ golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= +golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -436,24 +428,17 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= -golang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c h1:6a8FdnNk6bTXBjR4AGKFgUKuo+7GnR3FX5L7CbveeZc= -golang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c/go.mod h1:TpUTTEp9frx7rTdLpC9gFG9kdI7zVLFTFFlqaH2Cncw= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa h1:efT73AJZfAAUV7SOip6pWGkwJDzIGiKBZGVzHYa+ve4= +golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa/go.mod h1:kHjTxDEnAu6/Nl9lDkzjWpR+bmKfxeiRuSDlsMb70gE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -461,10 +446,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= -golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= -golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 13a4cb1c83f02364cac016911f4e5807c2e507ef Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Wed, 27 May 2026 15:18:06 +0530 Subject: [PATCH 07/20] fix: upgrade-golang.org/x/net-v0.55.0 --- server/go.mod | 2 +- server/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index dd85980d..7d154f34 100644 --- a/server/go.mod +++ b/server/go.mod @@ -174,7 +174,7 @@ require ( github.com/stretchr/testify v1.11.1 github.com/subosito/gotenv v1.6.0 // indirect go.temporal.io/api v1.62.0 - golang.org/x/net v0.54.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.45.0 // indirect golang.org/x/text v0.37.0 // indirect diff --git a/server/go.sum b/server/go.sum index f25dde43..6e0d0697 100644 --- a/server/go.sum +++ b/server/go.sum @@ -406,8 +406,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From 59e12f58880d167354218ee1b03c9007cf78e6f8 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Wed, 27 May 2026 16:22:23 +0530 Subject: [PATCH 08/20] fix: removed unnecessary args --- server/internal/services/optimization/terminal.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 0470fbd9..00e5c0d3 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -84,7 +84,7 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin return nil, fmt.Errorf("failed to execute bulk ALTER TABLE for catalog %s, database %s: %w", catalog, database, err) } - logInfo, err := s.pollForCompletion(ctx, catalog, sessionResult.SessionID) + logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) if err != nil { return nil, fmt.Errorf("failed to poll for completion for selected %d table(s): %w", len(tables), err) } @@ -131,7 +131,7 @@ func (s *Service) SetTableProperties(ctx context.Context, req dto.SetTableProper } // Poll for execution completion - logInfo, err := s.pollForCompletion(ctx, req.Catalog, sessionResult.SessionID) + logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) if err != nil { return nil, fmt.Errorf("failed to poll for completion: %w", err) } @@ -155,7 +155,7 @@ func (s *Service) SetTableProperties(ctx context.Context, req dto.SetTableProper } // pollForCompletion polls the terminal API for SQL execution completion -func (s *Service) pollForCompletion(ctx context.Context, _, sessionID string) (*dto.LogInfo, error) { +func (s *Service) pollForCompletion(ctx context.Context, sessionID string) (*dto.LogInfo, error) { path := fmt.Sprintf(constants.OptPathTerminalLogs, sessionID) timeoutCtx, cancel := context.WithTimeout(ctx, constants.OptSessionTimeout) defer cancel() From 0a9ef4fe721714167ab9ead6610f1b6d82cef5ec Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Wed, 27 May 2026 21:02:56 +0530 Subject: [PATCH 09/20] fix: minor-fix --- server/internal/services/optimization/terminal.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 00e5c0d3..520f5e90 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -50,7 +50,6 @@ func (s *Service) SetProperties(ctx context.Context, catalog, database, table st return sqlResult, nil } -// createAlterQuery returns one ALTER TABLE ... SET TBLPROPERTIES (...) statement for database.table, ending with ';'. func createAlterQuery(database, table string, properties map[string]string) string { props := make([]string, 0, len(properties)) for k, value := range properties { From 0ad5e9f06cf41d579d89ec0164dc67d2b60403d4 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Wed, 27 May 2026 22:17:20 +0530 Subject: [PATCH 10/20] fix: removed-redundant-logic --- server/internal/models/dto/requests.go | 7 -- server/internal/models/dto/response.go | 9 -- .../services/optimization/terminal.go | 82 +++++++------------ 3 files changed, 31 insertions(+), 67 deletions(-) diff --git a/server/internal/models/dto/requests.go b/server/internal/models/dto/requests.go index ba7e61b5..1ed89844 100644 --- a/server/internal/models/dto/requests.go +++ b/server/internal/models/dto/requests.go @@ -162,13 +162,6 @@ type LogInfo struct { Logs []string `json:"logs"` } -type SetTablePropertiesRequest struct { - Catalog string `json:"catalog"` - Database string `json:"database"` - Table string `json:"table"` - Properties map[string]string `json:"properties"` -} - // TerminalExecuteRequest represents the request body for terminal SQL execution type TerminalExecuteRequest struct { SQL string `json:"sql"` diff --git a/server/internal/models/dto/response.go b/server/internal/models/dto/response.go index c932237c..b20c204c 100644 --- a/server/internal/models/dto/response.go +++ b/server/internal/models/dto/response.go @@ -252,15 +252,6 @@ type TableProperties struct { Logs []string `json:"logs,omitempty"` } -// BulkTableProperties is the response from bulk-setting optimization properties. -type BulkTableProperties struct { - SessionID string `json:"sessionId"` - Success bool `json:"success"` - Message string `json:"message"` - Logs []string `json:"logs,omitempty"` - Tables []string `json:"tables"` -} - // TerminalSessionResponse represents the response from terminal execute type TerminalSessionResponse struct { SessionID string `json:"sessionId"` diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 520f5e90..ccb78702 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -35,19 +35,39 @@ func setPropertiesMap(config dto.SQLInput) map[string]string { func (s *Service) SetProperties(ctx context.Context, catalog, database, table string, config dto.SQLInput) (*dto.TableProperties, error) { properties := setPropertiesMap(config) - // sql query - sqlResult, err := s.SetTableProperties(ctx, dto.SetTablePropertiesRequest{ - Catalog: catalog, - Database: database, - Table: table, - Properties: properties, - }) + sql := createAlterQuery(database, table, properties) + path := fmt.Sprintf(constants.OptPathTerminalExecute, catalog) + requestBody := dto.TerminalExecuteRequest{ + SQL: sql, + } + + var sessionResult dto.TerminalSessionResponse + if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { + return nil, fmt.Errorf("failed to execute ALTER TABLE for %s.%s.%s: %w", catalog, database, table, err) + } + //poll for execution completion + logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) if err != nil { - return nil, fmt.Errorf("failed to set optimization properties: %w", err) + return nil, fmt.Errorf("failed to poll for completion: %w", err) } - return sqlResult, nil + // TODO: Fusion may return "Finished" even if the query fails (e.g., syntax error). + // Solution: validate execution status by checking logs for "Finished" vs "Failed". + success := logInfo.LogStatus == "Finished" + var message string + if success { + message = fmt.Sprintf("optimization sql command completed successfully with session ID: %s", sessionResult.SessionID) + } else { + message = fmt.Sprintf("optimization sql command failed with session ID: %s", sessionResult.SessionID) + } + + return &dto.TableProperties{ + SessionID: sessionResult.SessionID, + Success: success, + Message: message, + Logs: logInfo.Logs, + }, nil } func createAlterQuery(database, table string, properties map[string]string) string { @@ -60,8 +80,8 @@ func createAlterQuery(database, table string, properties map[string]string) stri return fmt.Sprintf(constants.OptSQLCommand, database, table, propsJoined) + ";" } -// BulkSetProperties runs one terminal session that executes ALTER TABLE ... SET TBLPROPERTIES -func (s *Service) BulkSetProperties(ctx context.Context, catalog, database string, req dto.BulkSQLInput) (*dto.BulkTableProperties, error) { +// set properties for multiple tables using sql query +func (s *Service) BulkSetProperties(ctx context.Context, catalog, database string, req dto.BulkSQLInput) (*dto.TableProperties, error) { tables := req.Tables properties := setPropertiesMap(req.SQLInput) // Bulk apply always enables self-optimizing on every selected table. @@ -105,46 +125,6 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin ) } - return &dto.BulkTableProperties{ - SessionID: sessionResult.SessionID, - Success: success, - Message: message, - Logs: logInfo.Logs, - Tables: tables, - }, nil -} - -// sets table properties using the SQL query -func (s *Service) SetTableProperties(ctx context.Context, req dto.SetTablePropertiesRequest) (*dto.TableProperties, error) { - sql := createAlterQuery(req.Database, req.Table, req.Properties) - - // execute via Terminal API - path := fmt.Sprintf(constants.OptPathTerminalExecute, req.Catalog) - requestBody := dto.TerminalExecuteRequest{ - SQL: sql, - } - - var sessionResult dto.TerminalSessionResponse - if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { - return nil, fmt.Errorf("failed to execute ALTER TABLE for %s.%s.%s: %w", req.Catalog, req.Database, req.Table, err) - } - - // Poll for execution completion - logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) - if err != nil { - return nil, fmt.Errorf("failed to poll for completion: %w", err) - } - - // TODO: Fusion may return "Finished" even if the query fails (e.g., syntax error). - // Solution: validate execution status by checking logs for "Finished" vs "Failed". - success := logInfo.LogStatus == "Finished" - var message string - if success { - message = fmt.Sprintf("optimization sql command completed successfully with session ID: %s", sessionResult.SessionID) - } else { - message = fmt.Sprintf("optimization sql command failed with session ID: %s", sessionResult.SessionID) - } - return &dto.TableProperties{ SessionID: sessionResult.SessionID, Success: success, From d3320e685c273e21519aa3afd180e0f1d5aa6405 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Wed, 27 May 2026 22:47:23 +0530 Subject: [PATCH 11/20] fix: fixed-lint-error --- server/internal/services/optimization/terminal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index ccb78702..04c80fb4 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -46,7 +46,7 @@ func (s *Service) SetProperties(ctx context.Context, catalog, database, table st if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { return nil, fmt.Errorf("failed to execute ALTER TABLE for %s.%s.%s: %w", catalog, database, table, err) } - //poll for execution completion + // poll for execution completion logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) if err != nil { return nil, fmt.Errorf("failed to poll for completion: %w", err) From c77572f39c8e5ac5febe41df45b44f81eb1c4a51 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Thu, 28 May 2026 00:27:55 +0530 Subject: [PATCH 12/20] fix: added-error-logs --- server/internal/handlers/optimization/table.go | 4 ++++ server/internal/services/optimization/terminal.go | 3 +++ 2 files changed, 7 insertions(+) diff --git a/server/internal/handlers/optimization/table.go b/server/internal/handlers/optimization/table.go index 747ca3c3..d9ca67ab 100644 --- a/server/internal/handlers/optimization/table.go +++ b/server/internal/handlers/optimization/table.go @@ -56,6 +56,10 @@ func (h *Handler) SetBulkProperties(c *gin.Context) { utils.ErrorResponse(c, utils.StatusFromBindError(err), "invalid request body for bulk table properties", err) return } + if len(req.Tables) <= 1 { + utils.ErrorResponse(c, badRequestStatusCode, "select more than one table to bulk configure", nil) + return + } result, err := h.opt.BulkSetProperties(c.Request.Context(), catalog, database, req) if err != nil { diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 04c80fb4..14ad38b3 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -83,6 +83,9 @@ func createAlterQuery(database, table string, properties map[string]string) stri // set properties for multiple tables using sql query func (s *Service) BulkSetProperties(ctx context.Context, catalog, database string, req dto.BulkSQLInput) (*dto.TableProperties, error) { tables := req.Tables + if len(tables) <= 1 { + return nil, fmt.Errorf("select more than one table to bulk configure") + } properties := setPropertiesMap(req.SQLInput) // Bulk apply always enables self-optimizing on every selected table. properties[constants.OptEnableOptimization] = "true" From 5cc9c60d5357a8cda6626f13fade1cc553cda11a Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Thu, 28 May 2026 00:33:30 +0530 Subject: [PATCH 13/20] fix: minor-fix --- server/internal/services/optimization/terminal.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 14ad38b3..04c80fb4 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -83,9 +83,6 @@ func createAlterQuery(database, table string, properties map[string]string) stri // set properties for multiple tables using sql query func (s *Service) BulkSetProperties(ctx context.Context, catalog, database string, req dto.BulkSQLInput) (*dto.TableProperties, error) { tables := req.Tables - if len(tables) <= 1 { - return nil, fmt.Errorf("select more than one table to bulk configure") - } properties := setPropertiesMap(req.SQLInput) // Bulk apply always enables self-optimizing on every selected table. properties[constants.OptEnableOptimization] = "true" From 74db0852c60d7dc58aa42d4306af391aba2085d8 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Tue, 2 Jun 2026 16:31:27 +0530 Subject: [PATCH 14/20] feat: abstracted --- .../services/optimization/terminal.go | 46 +++++++------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 04c80fb4..74178092 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -46,28 +46,9 @@ func (s *Service) SetProperties(ctx context.Context, catalog, database, table st if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { return nil, fmt.Errorf("failed to execute ALTER TABLE for %s.%s.%s: %w", catalog, database, table, err) } - // poll for execution completion - logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) - if err != nil { - return nil, fmt.Errorf("failed to poll for completion: %w", err) - } - // TODO: Fusion may return "Finished" even if the query fails (e.g., syntax error). // Solution: validate execution status by checking logs for "Finished" vs "Failed". - success := logInfo.LogStatus == "Finished" - var message string - if success { - message = fmt.Sprintf("optimization sql command completed successfully with session ID: %s", sessionResult.SessionID) - } else { - message = fmt.Sprintf("optimization sql command failed with session ID: %s", sessionResult.SessionID) - } - - return &dto.TableProperties{ - SessionID: sessionResult.SessionID, - Success: success, - Message: message, - Logs: logInfo.Logs, - }, nil + return s.pollAndBuild(ctx, sessionResult.SessionID, catalog, database) } func createAlterQuery(database, table string, properties map[string]string) string { @@ -103,30 +84,35 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin return nil, fmt.Errorf("failed to execute bulk ALTER TABLE for catalog %s, database %s: %w", catalog, database, err) } - logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) + return s.pollAndBuild(ctx, sessionResult.SessionID, catalog, database) +} + +// polls for SQL execution completion and constructs a TableProperties response. +func (s *Service) pollAndBuild(ctx context.Context, sessionID, catalog, database string) (*dto.TableProperties, error) { + logInfo, err := s.pollForCompletion(ctx, sessionID) + if err != nil { - return nil, fmt.Errorf("failed to poll for completion for selected %d table(s): %w", len(tables), err) + return nil, fmt.Errorf("failed to poll for completion: %w", err) } - success := logInfo.LogStatus == "Finished" var message string if success { message = fmt.Sprintf( - "bulk optimization sql command completed successfully for %d table(s), session ID: %s", - len(tables), - sessionResult.SessionID, + "optimization sql command completed successfully for catalog %s, database %s, session ID: %s", + catalog, + database, + sessionID, ) } else { message = fmt.Sprintf( - "bulk optimization sql command failed for catalog %s, database %s, session ID: %s", + "optimization sql command failed for catalog %s, database %s, session ID: %s", catalog, database, - sessionResult.SessionID, + sessionID, ) } - return &dto.TableProperties{ - SessionID: sessionResult.SessionID, + SessionID: sessionID, Success: success, Message: message, Logs: logInfo.Logs, From 9dabc8fa429bfa5b9901bc641fa1a67590744c00 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Tue, 2 Jun 2026 16:37:32 +0530 Subject: [PATCH 15/20] feat: minor-fix --- server/internal/services/optimization/terminal.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 74178092..9c02c21a 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -98,14 +98,14 @@ func (s *Service) pollAndBuild(ctx context.Context, sessionID, catalog, database var message string if success { message = fmt.Sprintf( - "optimization sql command completed successfully for catalog %s, database %s, session ID: %s", + "optimization sql command completed successfully for catalog %v, database %v, session ID: %v", catalog, database, sessionID, ) } else { message = fmt.Sprintf( - "optimization sql command failed for catalog %s, database %s, session ID: %s", + "optimization sql command failed for catalog %v, database %v, session ID: %v", catalog, database, sessionID, From 5b239c2d8bfe576947493433cafcc068342f6aea Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Tue, 9 Jun 2026 11:24:38 +0530 Subject: [PATCH 16/20] fix: fix-lint --- server/internal/services/optimization/terminal.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 9c02c21a..ff89e273 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -87,7 +87,6 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin return s.pollAndBuild(ctx, sessionResult.SessionID, catalog, database) } -// polls for SQL execution completion and constructs a TableProperties response. func (s *Service) pollAndBuild(ctx context.Context, sessionID, catalog, database string) (*dto.TableProperties, error) { logInfo, err := s.pollForCompletion(ctx, sessionID) From 6879636d5fbe8812866719e84881d4095e222665 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Tue, 9 Jun 2026 11:34:18 +0530 Subject: [PATCH 17/20] fix: fix-lint --- server/internal/services/optimization/terminal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index ff89e273..47617739 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -89,7 +89,7 @@ func (s *Service) BulkSetProperties(ctx context.Context, catalog, database strin func (s *Service) pollAndBuild(ctx context.Context, sessionID, catalog, database string) (*dto.TableProperties, error) { logInfo, err := s.pollForCompletion(ctx, sessionID) - + if err != nil { return nil, fmt.Errorf("failed to poll for completion: %w", err) } From 3e2cac625fc3c0663692414e9b91243fb712e294 Mon Sep 17 00:00:00 2001 From: arsalan-datazip Date: Tue, 9 Jun 2026 11:49:33 +0530 Subject: [PATCH 18/20] fix: increased-polling-timeout --- server/internal/constants/constants.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/constants/constants.go b/server/internal/constants/constants.go index 32cddea3..408e1502 100644 --- a/server/internal/constants/constants.go +++ b/server/internal/constants/constants.go @@ -102,7 +102,7 @@ var ( OptPathTerminalLogs = "/api/ams/v1/terminal/%s/logs" // others OptMaxTimeout = 30 * time.Second - OptSessionTimeout = 1 * time.Minute + OptSessionTimeout = 5 * time.Minute OptQueryResultPollTime = 1500 * time.Millisecond OptMinorCron = "self-optimizing.minor.trigger.cron" OptMajorCron = "self-optimizing.major.trigger.cron" From 60e7b1fd9dc923616e635fba07a0f3c961e2c3ad Mon Sep 17 00:00:00 2001 From: Ankit Sharma <111491139+hash-data@users.noreply.github.com> Date: Tue, 9 Jun 2026 19:03:39 +0530 Subject: [PATCH 19/20] chore: refactoring bulk edit (#391) * chore: refactoring bulk edit * chore: reataining the todo --- server/internal/constants/constants.go | 17 ++- .../internal/handlers/optimization/table.go | 51 +-------- server/internal/models/dto/requests.go | 20 ++-- server/internal/models/dto/response.go | 1 - .../services/optimization/terminal.go | 104 ++++++------------ server/routes/router.go | 3 +- ui/src/config/apiConfig.ts | 4 +- .../features/tables/services/tableService.ts | 10 +- .../features/tables/types/tableTypes.ts | 8 +- 9 files changed, 73 insertions(+), 145 deletions(-) diff --git a/server/internal/constants/constants.go b/server/internal/constants/constants.go index 408e1502..075ed465 100644 --- a/server/internal/constants/constants.go +++ b/server/internal/constants/constants.go @@ -101,15 +101,14 @@ var ( OptPathTerminalExecute = "/api/ams/v1/terminal/catalogs/%s/execute" OptPathTerminalLogs = "/api/ams/v1/terminal/%s/logs" // others - OptMaxTimeout = 30 * time.Second - OptSessionTimeout = 5 * time.Minute - OptQueryResultPollTime = 1500 * time.Millisecond - OptMinorCron = "self-optimizing.minor.trigger.cron" - OptMajorCron = "self-optimizing.major.trigger.cron" - OptFullCron = "self-optimizing.full.trigger.cron" - OptTargetFileSize = "self-optimizing.target-size" - OptEnableOptimization = "self-optimizing.enabled" - OptSQLCommand = "ALTER TABLE %s.%s SET TBLPROPERTIES (%s)" + OptMaxTimeout = 30 * time.Second + OptSessionTimeout = 5 * time.Minute // used for fusion poll (terminal query execution) + OptMinorCron = "self-optimizing.minor.trigger.cron" + OptMajorCron = "self-optimizing.major.trigger.cron" + OptFullCron = "self-optimizing.full.trigger.cron" + OptTargetFileSize = "self-optimizing.target-size" + OptEnableOptimization = "self-optimizing.enabled" + OptSQLCommand = "ALTER TABLE %s.%s SET TBLPROPERTIES (%s)" // properties OptCreatedAt = "created-at" OptCacheEnabled = "cache-enabled" diff --git a/server/internal/handlers/optimization/table.go b/server/internal/handlers/optimization/table.go index d9ca67ab..16714757 100644 --- a/server/internal/handlers/optimization/table.go +++ b/server/internal/handlers/optimization/table.go @@ -22,65 +22,26 @@ func (h *Handler) GetTablesWithDetails(c *gin.Context) { utils.SuccessResponse(c, "Successfully fetched tables with details", tables) } -// SetProperties configures table level properties for optimization +// SetProperties configures the same optimization properties on multiple tables (one terminal batch). func (h *Handler) SetProperties(c *gin.Context) { - catalog, database, table, ok := h.requiredCatalogDatabaseTable(c) - if !ok { - return - } - - var req dto.SQLInput - if err := utils.BindAndValidate(c, &req); err != nil { - utils.ErrorResponse(c, utils.StatusFromBindError(err), "invalid request body for setting config in table properties", err) - return - } - - result, err := h.opt.SetProperties(c.Request.Context(), catalog, database, table, req) - if err != nil { - utils.ErrorResponse(c, upstreamStatus(err), err.Error(), err) - return - } - - utils.SuccessResponse(c, result.Message, result) -} - -// SetBulkProperties configures the same optimization properties on multiple tables (one terminal batch). -func (h *Handler) SetBulkProperties(c *gin.Context) { catalog, database, ok := h.requiredCatalogAndDatabase(c) if !ok { return } - var req dto.BulkSQLInput - if err := utils.BindAndValidate(c, &req); err != nil { - utils.ErrorResponse(c, utils.StatusFromBindError(err), "invalid request body for bulk table properties", err) - return - } - if len(req.Tables) <= 1 { - utils.ErrorResponse(c, badRequestStatusCode, "select more than one table to bulk configure", nil) + var tableConfigs dto.OptimizationTableConfig + if err := utils.BindAndValidate(c, &tableConfigs); err != nil { + utils.ErrorResponse(c, utils.StatusFromBindError(err), "invalid request body for optimization table config", err) return } - result, err := h.opt.BulkSetProperties(c.Request.Context(), catalog, database, req) + result, err := h.opt.SetProperties(c.Request.Context(), catalog, database, tableConfigs) if err != nil { utils.ErrorResponse(c, upstreamStatus(err), err.Error(), err) return } - utils.SuccessResponse(c, result.Message, result) -} - -func (h *Handler) requiredCatalogDatabaseTable(c *gin.Context) (string, string, string, bool) { - catalog := c.Param("catalog") - database := c.Param("database") - table := c.Param("table") - - if catalog == "" || database == "" || table == "" { - utils.ErrorResponse(c, badRequestStatusCode, "catalog, database, and table parameters are required", nil) - return "", "", "", false - } - - return catalog, database, table, true + utils.SuccessResponse(c, "Finished setting properties for selected tables", result) } func (h *Handler) requiredCatalogAndDatabase(c *gin.Context) (string, string, bool) { diff --git a/server/internal/models/dto/requests.go b/server/internal/models/dto/requests.go index 1ed89844..ecb249d3 100644 --- a/server/internal/models/dto/requests.go +++ b/server/internal/models/dto/requests.go @@ -167,16 +167,14 @@ type TerminalExecuteRequest struct { SQL string `json:"sql"` } -type SQLInput struct { - MinorCron *string `json:"minor_cron"` - MajorCron *string `json:"major_cron"` - FullCron *string `json:"full_cron"` - TargetFileSize *int64 `json:"target_file_size"` - EnabledForOptimization *string `json:"enabled_for_optimization"` -} - -// BulkSQLInput configures optimization properties for multiple tables in one terminal session. -type BulkSQLInput struct { +// OptimizationTableConfig configures optimization properties for multiple tables in one terminal session. +type OptimizationTableConfig struct { Tables []string `json:"tables" binding:"required"` - SQLInput SQLInput `json:"sql_input"` + SQLInput struct { + MinorCron *string `json:"minor_cron"` + MajorCron *string `json:"major_cron"` + FullCron *string `json:"full_cron"` + TargetFileSize *int64 `json:"target_file_size"` + EnabledForOptimization *string `json:"enabled_for_optimization"` + } `json:"sql_input"` } diff --git a/server/internal/models/dto/response.go b/server/internal/models/dto/response.go index b20c204c..496f2802 100644 --- a/server/internal/models/dto/response.go +++ b/server/internal/models/dto/response.go @@ -248,7 +248,6 @@ type OptimizationInfo struct { type TableProperties struct { SessionID string `json:"sessionId"` Success bool `json:"success"` - Message string `json:"message"` Logs []string `json:"logs,omitempty"` } diff --git a/server/internal/services/optimization/terminal.go b/server/internal/services/optimization/terminal.go index 47617739..02935753 100644 --- a/server/internal/services/optimization/terminal.go +++ b/server/internal/services/optimization/terminal.go @@ -13,44 +13,26 @@ import ( "github.com/datazip-inc/olake-ui/server/internal/utils" ) -func setPropertiesMap(config dto.SQLInput) map[string]string { +func convertConfigToMap(config dto.OptimizationTableConfig) map[string]string { properties := make(map[string]string) - if config.MinorCron != nil { - properties[constants.OptMinorCron] = *config.MinorCron + if config.SQLInput.MinorCron != nil { + properties[constants.OptMinorCron] = *config.SQLInput.MinorCron } - if config.MajorCron != nil { - properties[constants.OptMajorCron] = *config.MajorCron + if config.SQLInput.MajorCron != nil { + properties[constants.OptMajorCron] = *config.SQLInput.MajorCron } - if config.FullCron != nil { - properties[constants.OptFullCron] = *config.FullCron + if config.SQLInput.FullCron != nil { + properties[constants.OptFullCron] = *config.SQLInput.FullCron } - if config.EnabledForOptimization != nil { - properties[constants.OptEnableOptimization] = *config.EnabledForOptimization + if config.SQLInput.EnabledForOptimization != nil { + properties[constants.OptEnableOptimization] = *config.SQLInput.EnabledForOptimization } - if config.TargetFileSize != nil { - properties[constants.OptTargetFileSize] = utils.ConvertMBToBytes(*config.TargetFileSize) + if config.SQLInput.TargetFileSize != nil { + properties[constants.OptTargetFileSize] = utils.ConvertMBToBytes(*config.SQLInput.TargetFileSize) } return properties } -func (s *Service) SetProperties(ctx context.Context, catalog, database, table string, config dto.SQLInput) (*dto.TableProperties, error) { - properties := setPropertiesMap(config) - sql := createAlterQuery(database, table, properties) - - path := fmt.Sprintf(constants.OptPathTerminalExecute, catalog) - requestBody := dto.TerminalExecuteRequest{ - SQL: sql, - } - - var sessionResult dto.TerminalSessionResponse - if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { - return nil, fmt.Errorf("failed to execute ALTER TABLE for %s.%s.%s: %w", catalog, database, table, err) - } - // TODO: Fusion may return "Finished" even if the query fails (e.g., syntax error). - // Solution: validate execution status by checking logs for "Finished" vs "Failed". - return s.pollAndBuild(ctx, sessionResult.SessionID, catalog, database) -} - func createAlterQuery(database, table string, properties map[string]string) string { props := make([]string, 0, len(properties)) for k, value := range properties { @@ -62,58 +44,34 @@ func createAlterQuery(database, table string, properties map[string]string) stri } // set properties for multiple tables using sql query -func (s *Service) BulkSetProperties(ctx context.Context, catalog, database string, req dto.BulkSQLInput) (*dto.TableProperties, error) { - tables := req.Tables - properties := setPropertiesMap(req.SQLInput) - // Bulk apply always enables self-optimizing on every selected table. - properties[constants.OptEnableOptimization] = "true" - - sql := make([]string, 0, len(tables)) - for _, t := range tables { - sql = append(sql, createAlterQuery(database, t, properties)) +func (s *Service) SetProperties(ctx context.Context, catalog, database string, config dto.OptimizationTableConfig) (*dto.TableProperties, error) { + tables := config.Tables + properties := convertConfigToMap(config) + + alterTableQuery := make([]string, 0, len(tables)) + for _, tableName := range tables { + alterTableQuery = append(alterTableQuery, createAlterQuery(database, tableName, properties)) } - bulkSQLScript := strings.Join(sql, "\n") - path := fmt.Sprintf(constants.OptPathTerminalExecute, catalog) + var sessionResult dto.TerminalSessionResponse requestBody := dto.TerminalExecuteRequest{ - SQL: bulkSQLScript, + SQL: strings.Join(alterTableQuery, "\n"), } - var sessionResult dto.TerminalSessionResponse - if err := s.DoInto(ctx, http.MethodPost, path, url.Values{}, requestBody, &sessionResult); err != nil { + if err := s.DoInto(ctx, http.MethodPost, fmt.Sprintf(constants.OptPathTerminalExecute, catalog), url.Values{}, requestBody, &sessionResult); err != nil { return nil, fmt.Errorf("failed to execute bulk ALTER TABLE for catalog %s, database %s: %w", catalog, database, err) } - return s.pollAndBuild(ctx, sessionResult.SessionID, catalog, database) -} - -func (s *Service) pollAndBuild(ctx context.Context, sessionID, catalog, database string) (*dto.TableProperties, error) { - logInfo, err := s.pollForCompletion(ctx, sessionID) + logInfo, err := s.pollForCompletion(ctx, sessionResult.SessionID) if err != nil { return nil, fmt.Errorf("failed to poll for completion: %w", err) } - success := logInfo.LogStatus == "Finished" - var message string - if success { - message = fmt.Sprintf( - "optimization sql command completed successfully for catalog %v, database %v, session ID: %v", - catalog, - database, - sessionID, - ) - } else { - message = fmt.Sprintf( - "optimization sql command failed for catalog %v, database %v, session ID: %v", - catalog, - database, - sessionID, - ) - } + + // TODO: Fusion may return "Finished" even if the query fails, but query logs will contain error message return &dto.TableProperties{ - SessionID: sessionID, - Success: success, - Message: message, + SessionID: sessionResult.SessionID, + Success: logInfo.LogStatus == "Finished", Logs: logInfo.Logs, }, nil } @@ -124,18 +82,20 @@ func (s *Service) pollForCompletion(ctx context.Context, sessionID string) (*dto timeoutCtx, cancel := context.WithTimeout(ctx, constants.OptSessionTimeout) defer cancel() - ticker := time.NewTicker(constants.OptQueryResultPollTime) - defer ticker.Stop() - for { select { case <-timeoutCtx.Done(): return nil, fmt.Errorf("timeout waiting for SQL execution to complete") - case <-ticker.C: + case <-time.After(1 * time.Second): var logInfo dto.LogInfo if err := s.DoInto(ctx, http.MethodGet, path, url.Values{}, nil, &logInfo); err != nil { return nil, fmt.Errorf("failed to get logs for session %s: %w", sessionID, err) } + + if logInfo.LogStatus == "Running" { + continue + } + return &logInfo, nil } } diff --git a/server/routes/router.go b/server/routes/router.go index e5e0ae9a..c476609c 100644 --- a/server/routes/router.go +++ b/server/routes/router.go @@ -91,8 +91,7 @@ func RegisterRoutes(engine *gin.Engine, h *handlers.Handler) { opt.DELETE("/catalog/:catalog", optHandler.DeleteCatalog) // terminal: cron, enable/disable optimization - opt.PUT("/:catalog/:database/:table/config", optHandler.SetProperties) - opt.PUT("/:catalog/:database/tables/config", optHandler.SetBulkProperties) + opt.PUT("/:catalog/:database/tables/config", optHandler.SetProperties) // tables: view opt.GET("/:catalog/:database/tables", optHandler.GetTablesWithDetails) diff --git a/ui/src/config/apiConfig.ts b/ui/src/config/apiConfig.ts index 72d300f4..460c6319 100644 --- a/ui/src/config/apiConfig.ts +++ b/ui/src/config/apiConfig.ts @@ -25,8 +25,8 @@ export const API_CONFIG = { catalogName ? `/api/opt/v1/catalog/${encodeURIComponent(catalogName)}` : `/api/opt/v1/catalog`, - TABLE_CONFIG: (catalog: string, database: string, tableName: string) => - `/api/opt/v1/${encodeURIComponent(catalog)}/${encodeURIComponent(database)}/${encodeURIComponent(tableName)}`, + TABLE_CONFIG: (catalog: string, database: string) => + `/api/opt/v1/${encodeURIComponent(catalog)}/${encodeURIComponent(database)}/tables/config`, TABLE: (catalog: string, database: string, tableName: string) => `/api/opt/v1/tables/catalogs/${encodeURIComponent(catalog)}/dbs/${encodeURIComponent(database)}/tables/${encodeURIComponent(tableName)}`, TABLES: (catalog: string, database: string) => diff --git a/ui/src/modules/maintenance/features/tables/services/tableService.ts b/ui/src/modules/maintenance/features/tables/services/tableService.ts index da54b24c..c76dc353 100644 --- a/ui/src/modules/maintenance/features/tables/services/tableService.ts +++ b/ui/src/modules/maintenance/features/tables/services/tableService.ts @@ -11,6 +11,7 @@ import type { TableMetricsApiResponse, UpdateTableCronApiRequest, UpdateTableConfigApiResponse, + UpdateTablesConfigApiRequest, } from "../types" export const tableService = { @@ -86,9 +87,14 @@ export const tableService = { payload: UpdateTableCronApiRequest, ): Promise => { try { + const request: UpdateTablesConfigApiRequest = { + tables: [tableName], + sql_input: payload, + } + const response = await api.put( - `${API_CONFIG.ENDPOINTS.OPT.TABLE_CONFIG(catalog, database, tableName)}/config`, - payload, + API_CONFIG.ENDPOINTS.OPT.TABLE_CONFIG(catalog, database), + request, { disableErrorNotification: true }, ) return response.data diff --git a/ui/src/modules/maintenance/features/tables/types/tableTypes.ts b/ui/src/modules/maintenance/features/tables/types/tableTypes.ts index a5554f12..a7974b05 100644 --- a/ui/src/modules/maintenance/features/tables/types/tableTypes.ts +++ b/ui/src/modules/maintenance/features/tables/types/tableTypes.ts @@ -99,6 +99,11 @@ export interface UpdateTableCronApiRequest { target_file_size?: number } +export interface UpdateTablesConfigApiRequest { + tables: string[] + sql_input: UpdateTableCronApiRequest +} + // Frontend Domain Types export type FilterKey = "all" | "olake" | "external" @@ -191,8 +196,9 @@ export interface CancelRunRequest { } export interface UpdateTableConfigApiResponse { + sessionId?: string success: boolean - message: string + message?: string logs?: string[] } From d548918cdf013015378c0c2df969ff194b98e9b7 Mon Sep 17 00:00:00 2001 From: deepanshupal09-datazip Date: Tue, 16 Jun 2026 12:28:45 +0530 Subject: [PATCH 20/20] fix: trivy error --- ui/package.json | 5 +++-- ui/pnpm-lock.yaml | 33 ++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/ui/package.json b/ui/package.json index aab12a13..12171ee2 100644 --- a/ui/package.json +++ b/ui/package.json @@ -4,13 +4,14 @@ "version": "0.0.0", "type": "module", "resolutions": { - "form-data": "4.0.4", + "form-data": "4.0.6", "lodash": ">=4.18.1", "lodash-es": ">=4.18.1" }, "pnpm": { "overrides": { - "fast-uri": "3.1.2" + "fast-uri": "3.1.2", + "form-data": "4.0.6" } }, "scripts": { diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index c1f0737b..814f606e 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - form-data: 4.0.4 + form-data: 4.0.6 lodash: '>=4.18.1' lodash-es: '>=4.18.1' fast-uri: 3.1.2 @@ -678,56 +678,67 @@ packages: resolution: {integrity: sha512-9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.50.2': resolution: {integrity: sha512-+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.50.2': resolution: {integrity: sha512-df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.50.2': resolution: {integrity: sha512-iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.50.2': resolution: {integrity: sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.50.2': resolution: {integrity: sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.50.2': resolution: {integrity: sha512-Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.50.2': resolution: {integrity: sha512-82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.50.2': resolution: {integrity: sha512-4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.50.2': resolution: {integrity: sha512-9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.50.2': resolution: {integrity: sha512-HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xvw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openharmony-arm64@4.50.2': resolution: {integrity: sha512-nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KYA==} @@ -1466,8 +1477,8 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} fraction.js@4.3.7: @@ -1567,6 +1578,10 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + hast-util-to-jsx-runtime@2.3.6: resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} @@ -3899,7 +3914,7 @@ snapshots: axios@1.16.0: dependencies: follow-redirects: 1.16.0 - form-data: 4.0.4 + form-data: 4.0.6 proxy-from-env: 2.1.0 transitivePeerDependencies: - debug @@ -4209,7 +4224,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.4 es-shim-unscopables@1.1.0: dependencies: @@ -4474,12 +4489,12 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data@4.0.4: + form-data@4.0.6: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.2 + hasown: 2.0.4 mime-types: 2.1.35 fraction.js@4.3.7: {} @@ -4581,6 +4596,10 @@ snapshots: dependencies: function-bind: 1.1.2 + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + hast-util-to-jsx-runtime@2.3.6: dependencies: '@types/estree': 1.0.8