incubator-seata
incubator-seata copied to clipboard
feature: support batch insert sql
- [ ] I have registered the PR changes.
Ⅰ. Describe what this PR did
1、支持oracle批量插入(insert all into table1 into table2 select * from table3) 2、支持insert into table select * from table1
Ⅱ. Does this pull request fix one issue?
#4375 #3965
Ⅲ. Why don't you add test cases (unit test/integration test)?
后续补上
Ⅳ. Describe how to verify it
Ⅴ. Special notes for reviews
This pull request introduces 1 alert when merging 093fdbdcddaa9a3138fbbd67058bf0c611cd600d into 61924a9f246b107984084c419b51560fc985eb7b - view on LGTM.com
new alerts:
- 1 for Dereferenced variable may be null
This pull request introduces 1 alert when merging a4551148ad1a7d2ce230fc89633a7990e893a21d into dc7a61faa965130ab30a555fa61e19e97836251f - view on LGTM.com
new alerts:
- 1 for Dereferenced variable may be null
一、oracle批量插入语句支持(insert all into table1 into table2 select * from table3) 1、需要考虑的场景 1)部分表插入自带完整的字段和值,eg: insert all into stu_info_1(sno,sname) values(1,2) into stu_info_2 select t.sno,t.sname,t.sex from stu_info; 2)部分表插入需要条件判断,eg: insert all when sno >=2 then into stu_info_1(sno,sname,sex) when sno >= 3 then into stu_info_2(sno,sname,sex) select t.sno,t.sname,t.sex from stu_info t; 2、总体思路 1)拆分为子sql表达式,针对每个表达式分配特定的解析器(SqlInsertRecognizer) 2)每个子sql表达式按照表名分类去解析生成相应的查询后置镜像的sql语句 3)查询语句主要考虑查询哪些字段,以及查询哪些值 字段的获取:如果子sql表达式自带完整的字段和值,则跟普通的insert into语句做法一样;如果不自带,则字段和值通过批量插入语句后面的子查询获取,需要注意的是子sql表达式若带条件,则要考虑将条件加入到子查询中。 3、代码实现 1)DruidSQLRecognizerFactoryImpl#create()方法通过druid语法数解析识别批量插入语句sql为MultiInsertStatement类型,通过RecognizerHolder#getMultiInsertStatement方法将子表达式包装为子表达式对应的解析器MultiInsertItemRecognizer 2)OracleMultiInsertItemRecognizer中会根据子表达式的不同获取表名、插入字段以及插入的行数据 3)由于转换为了多个表达式Item识别器,在ExecuteTemplate中找executor时会找到MultiExecutor,在multiExecutor中针对插入语句会转换为OracleMultiInsertExecutor来执行批量插入的具体逻辑 4)在OracleMultiInsertExecutor会对每个子表达式通过对应的解析器recognizer去找到生成后置镜像所需的字段和值,需要注意的是子表达式没有字段和值时,会转换为批量插入语句中的子查询语句来查询(BaseTransactionalExecutor#buildTableRecords) 4、暂不支持的sql语句情况
- 部分表带条件,部分表又不带条件;eg: insert all when sno >=2 then into stu_info_1(sno,sname,sex) into stu_info_2(sno,sname,sex) select t.sno,t.sname,t.sex from stu_info t; 这种语句druid在解析的时候出问题了,已给druid提issue了 二、insert into table1 select * from table2语句支持实现思路 整体思路和oracle的批量插入的思路一致,字段从子查询中获取(InsertRecognizer#getInsertColumns),值也从子查询中获取
This pull request introduces 1 alert when merging d029817ea4d818d6295a06acc6a417af12f3e763 into 53d65bf3aead904004f180a801c5abfa2e066a5a - view on LGTM.com
new alerts:
- 1 for Dereferenced variable may be null
This pull request introduces 1 alert when merging 7994a047a6a5f3c35bf6128575f9ed647ba76a80 into 53d65bf3aead904004f180a801c5abfa2e066a5a - view on LGTM.com
new alerts:
- 1 for Dereferenced variable may be null
1、字段值是函数,需要动态获取的情况
1、字段值是函数,需要动态获取的情况 2、
insert all into table1 into table2 select * from table3
2、拆分PR,先支持主流批量插入场景
Due to code conflicts and age, if you are still interested in participating in the community, please resubmit this pr to the 2.x branch after resolving the conflict. 由于代码冲突以及年代久远,如果你还有兴趣参与到社区,请解决完冲突后重新请提交这份pr至2.x分支中