From 406687aa9db98759ab294fcf0392000b4fd034e2 Mon Sep 17 00:00:00 2001 From: "grafana-delivery-bot[bot]" <132647405+grafana-delivery-bot[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 21:32:58 -0300 Subject: [PATCH] [release-11.6.7] Add index IDX_folder_org_id_parent_uid_uid (#111684) * Add index IDX_folder_org_id_parent_uid_uid (#110131) * Add index IDX_folder_org_id_parent_uid Signed-off-by: Maicon Costa * Force index on Dashboard Permission Filter (MYSQL) Signed-off-by: Maicon Costa --------- Signed-off-by: Maicon Costa (cherry picked from commit cfe73925cd0cc84d2adb6c6c21f57fe3937dbff8) * Fix conflicts Signed-off-by: Maicon Costa --------- Signed-off-by: Maicon Costa Co-authored-by: maicon --- pkg/infra/db/sqlbuilder.go | 2 +- .../annotations/accesscontrol/accesscontrol.go | 2 +- pkg/services/dashboards/database/database.go | 2 +- pkg/services/sqlstore/migrations/folder_mig.go | 5 +++++ pkg/services/sqlstore/permissions/dashboard.go | 18 +++++++++++++----- .../sqlstore/permissions/dashboard_test.go | 10 +++++----- .../permissions/dashboards_bench_test.go | 2 +- .../sqlstore/searchstore/search_test.go | 1 + 8 files changed, 28 insertions(+), 14 deletions(-) diff --git a/pkg/infra/db/sqlbuilder.go b/pkg/infra/db/sqlbuilder.go index 0d9e655fe26..f30d1a7c2ea 100644 --- a/pkg/infra/db/sqlbuilder.go +++ b/pkg/infra/db/sqlbuilder.go @@ -72,7 +72,7 @@ func (sb *SQLBuilder) WriteDashboardPermissionFilter(user identity.Requester, pe leftJoin string ) - filterRBAC := permissions.NewAccessControlDashboardPermissionFilter(user, permission, queryType, sb.features, sb.recursiveQueriesAreSupported) + filterRBAC := permissions.NewAccessControlDashboardPermissionFilter(user, permission, queryType, sb.features, sb.recursiveQueriesAreSupported, sb.dialect) leftJoin = filterRBAC.LeftJoin() sql, params = filterRBAC.Where() recQry, recQryParams = filterRBAC.With() diff --git a/pkg/services/annotations/accesscontrol/accesscontrol.go b/pkg/services/annotations/accesscontrol/accesscontrol.go index 0da012cdf82..19eeca27b63 100644 --- a/pkg/services/annotations/accesscontrol/accesscontrol.go +++ b/pkg/services/annotations/accesscontrol/accesscontrol.go @@ -127,7 +127,7 @@ func (authz *AuthService) dashboardsWithVisibleAnnotations(ctx context.Context, } filters := []any{ - permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, dashboardaccess.PERMISSION_VIEW, filterType, authz.features, recursiveQueriesSupported), + permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, dashboardaccess.PERMISSION_VIEW, filterType, authz.features, recursiveQueriesSupported, authz.db.GetDialect()), searchstore.OrgFilter{OrgId: query.OrgID}, } diff --git a/pkg/services/dashboards/database/database.go b/pkg/services/dashboards/database/database.go index a4babacd3e5..517322e2937 100644 --- a/pkg/services/dashboards/database/database.go +++ b/pkg/services/dashboards/database/database.go @@ -1002,7 +1002,7 @@ func (d *dashboardStore) FindDashboards(ctx context.Context, query *dashboards.F } if !query.SkipAccessControlFilter { - filters = append(filters, permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, query.Permission, query.Type, d.features, recursiveQueriesAreSupported)) + filters = append(filters, permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, query.Permission, query.Type, d.features, recursiveQueriesAreSupported, d.store.GetDialect())) } filters = append(filters, searchstore.DeletedFilter{Deleted: query.IsDeleted}) diff --git a/pkg/services/sqlstore/migrations/folder_mig.go b/pkg/services/sqlstore/migrations/folder_mig.go index 7cc9c451a8c..93cdede5176 100644 --- a/pkg/services/sqlstore/migrations/folder_mig.go +++ b/pkg/services/sqlstore/migrations/folder_mig.go @@ -86,6 +86,11 @@ func addFolderMigrations(mg *migrator.Migrator) { Type: migrator.UniqueIndex, Cols: []string{"org_id", "parent_uid", "title"}, })) + + mg.AddMigration("Add index IDX_folder_org_id_parent_uid", migrator.NewAddIndexMigration(folderv1(), &migrator.Index{ + Name: "IDX_folder_org_id_parent_uid", + Cols: []string{"org_id", "parent_uid"}, + })) } func folderv1() migrator.Table { diff --git a/pkg/services/sqlstore/permissions/dashboard.go b/pkg/services/sqlstore/permissions/dashboard.go index 945a7c53e1e..6724174d402 100644 --- a/pkg/services/sqlstore/permissions/dashboard.go +++ b/pkg/services/sqlstore/permissions/dashboard.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/login" + "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" ) @@ -37,6 +38,8 @@ type accessControlDashboardPermissionFilter struct { // any recursive CTE queries (if supported) recQueries []clause recursiveQueriesAreSupported bool + + dialect migrator.Dialect } type PermissionsFilter interface { @@ -51,7 +54,7 @@ type PermissionsFilter interface { // NewAccessControlDashboardPermissionFilter creates a new AccessControlDashboardPermissionFilter that is configured with specific actions calculated based on the dashboardaccess.PermissionType and query type // The filter is configured to use the new permissions filter (without subqueries) if the feature flag is enabled // The filter is configured to use the old permissions filter (with subqueries) if the feature flag is disabled -func NewAccessControlDashboardPermissionFilter(user identity.Requester, permissionLevel dashboardaccess.PermissionType, queryType string, features featuremgmt.FeatureToggles, recursiveQueriesAreSupported bool) PermissionsFilter { +func NewAccessControlDashboardPermissionFilter(user identity.Requester, permissionLevel dashboardaccess.PermissionType, queryType string, features featuremgmt.FeatureToggles, recursiveQueriesAreSupported bool, dialect migrator.Dialect) PermissionsFilter { needEdit := permissionLevel > dashboardaccess.PERMISSION_VIEW var folderAction string @@ -121,12 +124,12 @@ func NewAccessControlDashboardPermissionFilter(user identity.Requester, permissi f = &accessControlDashboardPermissionFilterNoFolderSubquery{ accessControlDashboardPermissionFilter: accessControlDashboardPermissionFilter{ user: user, folderAction: folderAction, folderActionSets: folderActionSets, dashboardAction: dashboardAction, dashboardActionSets: dashboardActionSets, - features: features, recursiveQueriesAreSupported: recursiveQueriesAreSupported, + features: features, recursiveQueriesAreSupported: recursiveQueriesAreSupported, dialect: dialect, }, } } else { f = &accessControlDashboardPermissionFilter{user: user, folderAction: folderAction, folderActionSets: folderActionSets, dashboardAction: dashboardAction, dashboardActionSets: dashboardActionSets, - features: features, recursiveQueriesAreSupported: recursiveQueriesAreSupported, + features: features, recursiveQueriesAreSupported: recursiveQueriesAreSupported, dialect: dialect, } } f.buildClauses() @@ -372,6 +375,11 @@ func (f *accessControlDashboardPermissionFilter) With() (string, []any) { } func (f *accessControlDashboardPermissionFilter) addRecQry(queryName string, whereUIDSelect string, whereParams []any, orgID int64) { + forceIndex := "" + if f.dialect.DriverName() == migrator.MySQL { + forceIndex = " FORCE INDEX (IDX_folder_org_id_parent_uid) " + } + if f.recQueries == nil { f.recQueries = make([]clause, 0, maximumRecursiveQueries) } @@ -382,8 +390,8 @@ func (f *accessControlDashboardPermissionFilter) addRecQry(queryName string, whe // covered by UQE_folder_org_id_uid and UQE_folder_org_id_parent_uid_title string: fmt.Sprintf(`%s AS ( SELECT uid, parent_uid, org_id FROM folder WHERE org_id = ? AND uid IN %s - UNION ALL SELECT f.uid, f.parent_uid, f.org_id FROM folder f INNER JOIN %s r ON f.parent_uid = r.uid and f.org_id = r.org_id - )`, queryName, whereUIDSelect, queryName), + UNION ALL SELECT f.uid, f.parent_uid, f.org_id FROM folder f %s INNER JOIN %s r ON f.parent_uid = r.uid and f.org_id = r.org_id + )`, queryName, whereUIDSelect, forceIndex, queryName), params: c, }) } diff --git a/pkg/services/sqlstore/permissions/dashboard_test.go b/pkg/services/sqlstore/permissions/dashboard_test.go index 3174db18373..efc72764d9d 100644 --- a/pkg/services/sqlstore/permissions/dashboard_test.go +++ b/pkg/services/sqlstore/permissions/dashboard_test.go @@ -183,7 +183,7 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { keys = append(keys, k) } t.Run(tt.desc+" with features "+strings.Join(keys, ","), func(t *testing.T) { - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported, store.GetDialect()) var result int err = store.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { @@ -355,7 +355,7 @@ func TestIntegration_DashboardPermissionFilter_WithSelfContainedPermissions(t *t keys = append(keys, k) } t.Run(tt.desc+" with features "+strings.Join(keys, ","), func(t *testing.T) { - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported, store.GetDialect()) var result int err = store.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { @@ -470,7 +470,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) { db := setupNestedTest(t, usr, tc.permissions, orgID, features) recursiveQueriesAreSupported, err := db.RecursiveQueriesAreSupported() require.NoError(t, err) - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported, db.GetDialect()) var result []string err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() @@ -588,7 +588,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission db := setupNestedTest(t, helperUser, []accesscontrol.Permission{}, orgID, features) recursiveQueriesAreSupported, err := db.RecursiveQueriesAreSupported() require.NoError(t, err) - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported, db.GetDialect()) var result []string err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() @@ -707,7 +707,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithActionSets(t *testing.T db := setupNestedTest(t, usr, tc.signedInUserPermissions, orgID, features) recursiveQueriesAreSupported, err := db.RecursiveQueriesAreSupported() require.NoError(t, err) - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported, db.GetDialect()) var result []string err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() diff --git a/pkg/services/sqlstore/permissions/dashboards_bench_test.go b/pkg/services/sqlstore/permissions/dashboards_bench_test.go index e4fa2de1dbe..b396bb955fb 100644 --- a/pkg/services/sqlstore/permissions/dashboards_bench_test.go +++ b/pkg/services/sqlstore/permissions/dashboards_bench_test.go @@ -56,7 +56,7 @@ func benchmarkDashboardPermissionFilter(b *testing.B, numUsers, numDashboards, n b.ResetTimer() for i := 0; i < b.N; i++ { - filter := permissions.NewAccessControlDashboardPermissionFilter(&usr, dashboardaccess.PERMISSION_VIEW, "", features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(&usr, dashboardaccess.PERMISSION_VIEW, "", features, recursiveQueriesAreSupported, store.GetDialect()) var result int err := store.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() diff --git a/pkg/services/sqlstore/searchstore/search_test.go b/pkg/services/sqlstore/searchstore/search_test.go index 7bccffef1d6..4b0786f4ceb 100644 --- a/pkg/services/sqlstore/searchstore/search_test.go +++ b/pkg/services/sqlstore/searchstore/search_test.go @@ -334,6 +334,7 @@ func TestBuilder_RBAC(t *testing.T) { "", tc.features, recursiveQueriesAreSupported, + store.GetDialect(), ), }, Dialect: store.GetDialect(),