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

审核特定带别名的SQL会导致进行索引建议时服务奔溃; #657

Closed
GLguoliang opened this issue Jul 6, 2022 · 8 comments
Closed
Assignees
Labels
bug Something isn't working verified the issue all pr is verified
Milestone

Comments

@GLguoliang
Copy link

GLguoliang commented Jul 6, 2022

审核sql语句为:

select appnamespa0_.`Id` as Id1_1_, appnamespa0_.`DataChange_CreatedBy` as DataChan2_1_, appnamespa0_.`DataChange_CreatedTime` as DataChan3_1_, appnamespa0_.`DataChange_LastModifiedBy` as DataChan4_1_, appnamespa0_.`DataChange_LastTime` as DataChan5_1_, appnamespa0_.`IsDeleted` as IsDelete6_1_, appnamespa0_.`AppId` as AppId7_1_, appnamespa0_.`Comment` as Comment8_1_, appnamespa0_.`Format` as Format9_1_, appnamespa0_.`IsPublic` as IsPubli10_1_, appnamespa0_.`Name` as Name11_1_ from `AppNamespace` appnamespa0_ where ( appnamespa0_.isDeleted = 0) and (appnamespa0_.`Id` in (3 , 5 , 6 , 15 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 , 88 , 91 , 93 , 94 , 95 , 96 , 98 , 99 , 100 , 101 , 104 , 105 , 106 , 107 , 110 , 111))

建表语句为:

 CREATE TABLE `appnamespace` (
  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `Name` varchar(32) NOT NULL DEFAULT '',
  `AppId` varchar(32) NOT NULL DEFAULT '',
  `Format` varchar(32) NOT NULL DEFAULT 'properties',
  `IsPublic` bit(1) NOT NULL DEFAULT b'0',
  `Comment` varchar(64) NOT NULL DEFAULT '',
  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT '',
  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`Id`),
  KEY `IX_AppId` (`AppId`),
  KEY `Name_AppId` (`Name`,`AppId`),
  KEY `DataChange_LastTime` (`DataChange_LastTime`)
) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8mb4
@GLguoliang GLguoliang added the bug Something isn't working label Jul 6, 2022
@sjjian sjjian added this to the v1.2207.0 milestone Jul 6, 2022
@GLguoliang
Copy link
Author

GLguoliang commented Jul 7, 2022

补充:在规则模板里开启索引优化——索引创建建议,审核该语句时会导致服务崩溃
关闭索引创建建议后,该sql审核结果会报禁止使用没有where条件的sql语句或者使用where 1=1等变相没有条件的sql,但该sql语句使用了where条件
image

@taolx0
Copy link
Collaborator

taolx0 commented Jul 25, 2022

1. 为什么extractTableNameFromAST返回值是nil?

因为explain获取执行计划,会优先获取表的别名(如果有别名的话)。此处程序的逻辑,通过explain获取的表名与解析器中解析出的表名对比,如果相等则返回表名结构体。但是此处未考虑到解析器提取表别名的情况,导致返回nil,且未对返回nil的情况做处理,引发空指针错误,导致程序panic。

修复效果

image

@taolx0
Copy link
Collaborator

taolx0 commented Jul 25, 2022

2.为什么会误报禁止使用没有where条件的sql语句或者使用where 1=1等变相没有条件的sql?

因为程序未对大括号()这种情况做处理,程序误认为where后没有列,导致做出错误的判断。

@GLguoliang
Copy link
Author

那这个对大括号的处理,还需要单独提个issue吗

@taolx0
Copy link
Collaborator

taolx0 commented Jul 25, 2022

那这个对大括号的处理,还需要单独提个issue吗
我建了issue:#691

@taolx0
Copy link
Collaborator

taolx0 commented Jul 27, 2022

审核sql语句为:

select appnamespa0_.`Id` as Id1_1_, appnamespa0_.`DataChange_CreatedBy` as DataChan2_1_, appnamespa0_.`DataChange_CreatedTime` as DataChan3_1_, appnamespa0_.`DataChange_LastModifiedBy` as DataChan4_1_, appnamespa0_.`DataChange_LastTime` as DataChan5_1_, appnamespa0_.`IsDeleted` as IsDelete6_1_, appnamespa0_.`AppId` as AppId7_1_, appnamespa0_.`Comment` as Comment8_1_, appnamespa0_.`Format` as Format9_1_, appnamespa0_.`IsPublic` as IsPubli10_1_, appnamespa0_.`Name` as Name11_1_ from `AppNamespace` appnamespa0_ where ( appnamespa0_.isDeleted = 0) and (appnamespa0_.`Id` in (3 , 5 , 6 , 15 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 , 88 , 91 , 93 , 94 , 95 , 96 , 98 , 99 , 100 , 101 , 104 , 105 , 106 , 107 , 110 , 111))

建表语句为:

 CREATE TABLE `appnamespace` (
  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `Name` varchar(32) NOT NULL DEFAULT '',
  `AppId` varchar(32) NOT NULL DEFAULT '',
  `Format` varchar(32) NOT NULL DEFAULT 'properties',
  `IsPublic` bit(1) NOT NULL DEFAULT b'0',
  `Comment` varchar(64) NOT NULL DEFAULT '',
  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT '',
  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`Id`),
  KEY `IX_AppId` (`AppId`),
  KEY `Name_AppId` (`Name`,`AppId`),
  KEY `DataChange_LastTime` (`DataChange_LastTime`)
) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8mb4

在默认情况下,建表DDL的表名应该与查询sql的from后跟的表名相同。这里建表ddl表名是小写,但是select的from表名是驼峰写法,如果执行这条查询sql会导致找不到表名。
将查询sql的表名修改到和建表DDL的表名一致:

select appnamespa0_.`Id`                        as Id1_1_,
       appnamespa0_.`DataChange_CreatedBy`      as DataChan2_1_,
       appnamespa0_.`DataChange_CreatedTime`    as DataChan3_1_,
       appnamespa0_.`DataChange_LastModifiedBy` as DataChan4_1_,
       appnamespa0_.`DataChange_LastTime`       as DataChan5_1_,
       appnamespa0_.`IsDeleted`                 as IsDelete6_1_,
       appnamespa0_.`AppId`                     as AppId7_1_,
       appnamespa0_.`Comment`                   as Comment8_1_,
       appnamespa0_.`Format`                    as Format9_1_,
       appnamespa0_.`IsPublic`                  as IsPubli10_1_,
       appnamespa0_.`Name`                      as Name11_1_
from `appnamespace` appnamespa0_
where (appnamespa0_.isDeleted = 0)
  and (appnamespa0_.`Id` in
       (3, 5, 6, 15, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
        66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 91, 93, 94, 95, 96, 98,
        99, 100, 101, 104, 105, 106, 107, 110, 111));

@Marcus9530
Copy link
Collaborator

复现版本
UI Version: release-1.2206.x 614a04c
Server Version: release-1.2206.x-ee c1a9993
复现步骤:
1.开启索引优化审核规则
2.使用上述备注中使用的表结构语句和审核语句去创建工单
3.对审核语句进行审核之后界面出现未知错误
image
4.关闭索引优化审核规则之后,再次进行审核
出现禁止使用没有where条件的sql语句或者使用where 1=1等变相没有条件的sql审核提示
image

@Marcus9530
Copy link
Collaborator

验证版本
UI Version: main c981fec
Server Version: main-ee 3ba4f96
验证步骤:
1.开启索引优化审核规则
2.使用上述备注中使用的表结构语句和审核语句去创建工单
3.对审核语句进行审核之后界面出现三星索引优化提示

image
4.关闭所有的审核规则,然后只开启禁止使用没有where条件的sql语句或者使用where 1=1等变相没有条件的sql审核规则
5.再次进行审核,并没有出现相关审核提示信息

image
image

@Marcus9530 Marcus9530 added the verified the issue all pr is verified label Jul 27, 2022
@sjjian sjjian changed the title 审核sql时,extractTableNameFromAST(ss, tbl)方法返回nil,导致服务奔溃 审核特定带别名的SQL会导致进行索引建议时服务奔溃; Jul 29, 2022
LordofAvernus pushed a commit that referenced this issue Nov 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working verified the issue all pr is verified
Projects
None yet
Development

No branches or pull requests

4 participants