Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BugFix] Fix MySQL 8.0.x compatibility problem #56872

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

Zac-saodiseng
Copy link
Contributor

@Zac-saodiseng Zac-saodiseng commented Mar 13, 2025

Why I'm doing:

  1. Connect to the Cluster via IntelliJ (might occur on other database management tools) using a compatible 8.0.x MySQL driver
  2. Attempt to refresh the Schema in the Database UI
  3. Exception being thrown when trying to scan the schema using the MySQL 8.0.33 driver:
Connection Error
[HY000][1193] Getting analyzing error. Detail message:
Unknown system variable 'default_storage_engine', the
most similar variables are {'default_rowset_type',
'default_table_compression', 'enable_sort_aggregate'}.

Connection Error
Getting analyzing error. Detail message:
Column 'subpartition_ordinal_position' cannot
be resolved.
and 1 duplicate report.

Getting analyzing error. Detail message:
Unknown table 'information_schema.applicable_roles'.

Connection Error
Unknown compression type (0) backend [id=10002].

Getting analyzing error. Detail message:
Column expression cannot be resolved.

Getting analyzing error. Detail message:
Column 'c.enforced' cannot be resolved.

Getting analyzing error. Detail message:
Column 'subpartition_ordinal_position' cannot be resolved.
and 9 duplicate reports.

What I'm doing:

  1. Need to add INFORMATION_SCHEMA.APPLICABLE_ROLES table.
  2. Need to add the system variable 'default_storage_engine' and 'default_table_compression'.
  3. Need to add the column 'EXPRESSION' in INFORMATION_SCHEMA.STATISTICS and 'ENFORCED' in INFORMATION_SCHEMA.TABLE_CONSTRAINTS.
mysql> select * from applicable_roles ;
+------+------+---------+--------------+-----------+-----------+--------------+------------+--------------+
| USER | HOST | GRANTEE | GRANTEE_HOST | ROLE_NAME | ROLE_HOST | IS_GRANTABLE | IS_DEFAULT | IS_MANDATORY |
+------+------+---------+--------------+-----------+-----------+--------------+------------+--------------+
| root | %    | root    | %            | root      | %         | NO           | YES        | NO           |
+------+------+---------+--------------+-----------+-----------+--------------+------------+--------------+
1 row in set (0.07 sec)

Fixes #55629

What type of PR is this:

  • BugFix
  • Feature
  • Enhancement
  • Refactor
  • UT
  • Doc
  • Tool

Does this PR entail a change in behavior?

  • Yes, this PR will result in a change in behavior.
  • No, this PR will not result in a change in behavior.

If yes, please specify the type of change:

  • Interface/UI changes: syntax, type conversion, expression evaluation, display information
  • Parameter changes: default values, similar parameters but with different default values
  • Policy changes: use new policy to replace old one, functionality automatically enabled
  • Feature removed
  • Miscellaneous: upgrade & downgrade compatibility, etc.

Checklist:

  • I have added test cases for my bug fix or my new feature
  • This pr needs user documentation (for new or modified features or behaviors)
    • I have added documentation for my new feature or new function
  • This is a backport pr

Bugfix cherry-pick branch check:

  • I have checked the version labels which the pr will be auto-backported to the target branch
    • 3.4
    • 3.3
    • 3.2
    • 3.1
    • 3.0

@Zac-saodiseng Zac-saodiseng requested review from a team as code owners March 13, 2025 08:33
@wanpengfei-git wanpengfei-git requested a review from a team March 13, 2025 08:34
@github-actions github-actions bot added the 3.4 label Mar 13, 2025
@wanpengfei-git wanpengfei-git requested a review from a team March 13, 2025 08:34
_applicable_roles_index++;
return Status::OK();
}
} // namespace starrocks No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most risky bug in this code is:
Potential out-of-bounds access due to _column_num being uninitialized, leading to unpredictable slot_id validation.

You can modify the code like this:

// Within SchemaApplicableRolesScanner constructor or initialization part:
_column_num = sizeof(_s_columns) / sizeof(SchemaScanner::ColumnDesc); // Initialize _column_num

// Ensure to include this initialization logic to avoid potential issues.
SchemaScanner::SchemaScanner(_s_columns, _column_num);

} finally {
roleReadUnlock();
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most risky bug in this code is:
Improper handling of lock acquisition and release order might lead to deadlocks. Specifically, mixing userReadLock/Unlock with roleReadLock/Unlock without a consistent order can cause deadlock issues if another method acquires them in a conflicting order.

You can modify the code like this:

public List<RolePrivilegeCollectionV2> getApplicableRoles(UserIdentity user) throws PrivilegeException {
    List<RolePrivilegeCollectionV2> applicableRoles = new ArrayList<>();
    
    // Ensure a consistent locking order by acquiring role lock before user lock
    roleReadLock();
    try {
        userReadLock();
        try {
            Set<Long> roleIds = getRoleIdsByUser(user);
            for (Long roleId : roleIds) {
                RolePrivilegeCollectionV2 rolePrivilegeCollection = roleIdToPrivilegeCollection.get(roleId);
                if (rolePrivilegeCollection != null) {
                    applicableRoles.add(rolePrivilegeCollection);
                }
            }
        } finally {
            userReadUnlock();
        }
    } finally {
        roleReadUnlock();
    }
    return applicableRoles;
}

This modification ensures that locks are always acquired and released in a consistent order, mitigating the risk of deadlocks.

response.setRoles(roleList);
return response;
}

public static TGetTemporaryTablesInfoResponse generateTemporaryTablesInfoResponse(TGetTemporaryTablesInfoRequest request)
throws TException {
TemporaryTableMgr temporaryTableMgr = GlobalStateMgr.getCurrentState().getTemporaryTableMgr();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most risky bug in this code is: If getAuthDbRequestResult(request.getAuth_info()) returns a null value for authorizedDbs, calling isEmpty() on it will result in a NullPointerException.

You can modify the code like this:

public static TGetApplicableRolesResponse generateApplicableRolesResp(TGetApplicableRolesRequest request) throws TException {
    TGetApplicableRolesResponse response = new TGetApplicableRolesResponse();
    List<TApplicableRolesInfo> roleList = new ArrayList<>();

    AuthDbRequestResult result = getAuthDbRequestResult(request.getAuth_info());

    if (result == null || result.authorizedDbs == null || result.authorizedDbs.isEmpty()) {
        response.setRoles(roleList);
        return response;
    }

    UserIdentity currentUser = result.currentUser;
    if (currentUser == null) {
        response.setRoles(roleList);
        return response;
    }

    AuthorizationMgr authMgr = GlobalStateMgr.getCurrentState().getAuthorizationMgr();
    try {
        for (RolePrivilegeCollectionV2 role : authMgr.getApplicableRoles(currentUser)) {
            String roleName = role.getName();
            String roleHost = "%";

            String isGrantable = authMgr.isRoleGrantable(currentUser, roleName) ? "YES" : "NO";
            String isDefault = authMgr.isRoleDefault(currentUser, roleName) ? "YES" : "NO";
            String isMandatory = authMgr.isRoleMandatory(currentUser, roleName) ? "YES" : "NO";

            TApplicableRolesInfo roleInfo = new TApplicableRolesInfo();
            roleInfo.setUser(currentUser.getUser());
            roleInfo.setHost(currentUser.getHost());
            roleInfo.setGrantee(currentUser.getUser());
            roleInfo.setGrantee_host(currentUser.getHost());
            roleInfo.setRole_name(roleName);
            roleInfo.setRole_host(roleHost);
            roleInfo.setIs_grantable(isGrantable);
            roleInfo.setIs_default(isDefault);
            roleInfo.setIs_mandatory(isMandatory);

            roleList.add(roleInfo);
        }
    } catch (PrivilegeException e) {
        throw new RuntimeException(e);
    }

    response.setRoles(roleList);
    return response;
}

@@ -182,6 +182,7 @@ enum TSchemaTableType {
SCH_CLUSTER_SNAPSHOTS,
SCH_CLUSTER_SNAPSHOT_JOBS,

SCH_APPLICABLE_ROLES,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New items should be added to the last.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've already revised it.

Copy link

[Java-Extensions Incremental Coverage Report]

pass : 0 / 0 (0%)

Copy link

[FE Incremental Coverage Report]

pass : 80 / 92 (86.96%)

file detail

path covered_line new_line coverage not_covered_line_detail
🔵 com/starrocks/authorization/RolePrivilegeCollectionV2.java 3 5 60.00% [144, 169]
🔵 com/starrocks/service/InformationSchemaDataSource.java 28 34 82.35% [622, 623, 628, 629, 655, 656]
🔵 com/starrocks/authorization/AuthorizationMgr.java 30 33 90.91% [1811, 1825, 1839]
🔵 com/starrocks/catalog/system/information/ApplicableRolesSystemTable.java 12 13 92.31% [25]
🔵 com/starrocks/qe/SessionVariable.java 2 2 100.00% []
🔵 com/starrocks/catalog/system/information/InfoSchemaDb.java 1 1 100.00% []
🔵 com/starrocks/catalog/system/information/StatisticsSystemTable.java 1 1 100.00% []
🔵 com/starrocks/service/FrontendServiceImpl.java 1 1 100.00% []
🔵 com/starrocks/catalog/system/information/TableConstraintsSystemTable.java 1 1 100.00% []
🔵 com/starrocks/catalog/system/information/PartitionsSystemTableSystemTable.java 1 1 100.00% []

Copy link

[BE Incremental Coverage Report]

pass : 83 / 92 (90.22%)

file detail

path covered_line new_line coverage not_covered_line_detail
🔵 be/src/exec/schema_scanner/schema_applicable_roles_scanner.cpp 78 87 89.66% [45, 49, 54, 55, 57, 58, 86, 89, 104]
🔵 be/src/exec/schema_scanner.cpp 2 2 100.00% []
🔵 be/src/exec/schema_scanner/schema_helper.cpp 2 2 100.00% []
🔵 be/src/exec/schema_scanner/schema_applicable_roles_scanner.h 1 1 100.00% []

@@ -103,6 +103,7 @@ public class SystemId {
public static final long FE_METRICS_ID = 42L;

public static final long TEMP_TABLES_ID = 43L;
public static final long APPLICABLE_ROLES_ID = 45L;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be moved behind 44.

@SerializedName(value = "d")
private boolean isDefault;
@SerializedName(value = "m")
private boolean isMandatory;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s best not to add extra persistent fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MySQL 8.0.x compatibility problem
4 participants