2121package com .dtstack .flink .sql .side ;
2222
2323import com .dtstack .flink .sql .config .CalciteConfig ;
24- import com .dtstack .flink .sql .util .ParseUtils ;
25- import com .google .common .collect .HashBasedTable ;
24+ import com .google .common .base .Strings ;
25+ import com .google .common .collect .Maps ;
26+ import com .google .common .collect .Queues ;
2627import org .apache .calcite .sql .JoinType ;
2728import org .apache .calcite .sql .SqlAsOperator ;
2829import org .apache .calcite .sql .SqlBasicCall ;
4243import org .apache .calcite .sql .parser .SqlParserPos ;
4344import org .apache .commons .lang3 .StringUtils ;
4445import org .apache .flink .api .java .tuple .Tuple2 ;
45- import com .google .common .base .Strings ;
46- import com .google .common .collect .Lists ;
47- import com .google .common .collect .Maps ;
48- import com .google .common .collect .Queues ;
4946import org .apache .flink .table .api .Table ;
5047import org .slf4j .Logger ;
5148import org .slf4j .LoggerFactory ;
5249
53- import java .util .HashMap ;
54- import java .util .Iterator ;
55- import java .util .List ;
5650import java .util .Map ;
5751import java .util .Queue ;
5852import java .util .Set ;
@@ -71,13 +65,6 @@ public class SideSQLParser {
7165
7266 private Map <String , Table > localTableCache = Maps .newHashMap ();
7367 private final char SPLIT = '_' ;
74- private String tempSQL = "SELECT * FROM TMP" ;
75-
76- /** 处理连续join时,中间表存储子表字段映射 */
77- private Map <String , HashBasedTable <String , String , String >> midTableFileNameMapping = Maps .newHashMap ();
78- /** 处理连续join时,原始表与中间表的映射 */
79- private Map <String , List <Tuple2 <String , String >>> midTableNameMapping = Maps .newHashMap ();
80-
8168
8269 public Queue <Object > getExeQueue (String exeSql , Set <String > sideTableSet ) throws SqlParseException {
8370 System .out .println ("---exeSql---" );
@@ -88,14 +75,6 @@ public Queue<Object> getExeQueue(String exeSql, Set<String> sideTableSet) throws
8875 Queue <Object > queueInfo = Queues .newLinkedBlockingQueue ();
8976 SqlParser sqlParser = SqlParser .create (exeSql , CalciteConfig .MYSQL_LEX_CONFIG );
9077 SqlNode sqlNode = sqlParser .parseStmt ();
91- SqlNode original = sqlNode ;
92-
93- try {
94- checkAndReplaceMultiJoin (sqlNode , sideTableSet );
95- } catch (Exception e ) {
96- sqlNode = original ;
97- LOG .error ("checkAndReplaceMultiJoin method error " , e );
98- }
9978
10079 parseSql (sqlNode , sideTableSet , queueInfo );
10180 queueInfo .offer (sqlNode );
@@ -126,7 +105,7 @@ private void checkAndReplaceMultiJoin(SqlNode sqlNode, Set<String> sideTableSet)
126105 }
127106 break ;
128107 case JOIN :
129- convertMultiJoinToNestQuery ((SqlJoin ) sqlNode , sideTableSet );
108+ convertSideJoinToNewQuery ((SqlJoin ) sqlNode , sideTableSet );
130109 break ;
131110 case AS :
132111 SqlNode info = ((SqlBasicCall ) sqlNode ).getOperands ()[0 ];
@@ -213,10 +192,6 @@ private Object parseSql(SqlNode sqlNode, Set<String> sideTableSet, Queue<Object>
213192 return "" ;
214193 }
215194
216- private boolean isMultiJoinSqlNode (SqlNode sqlNode ) {
217- return sqlNode .getKind () == JOIN && ((SqlJoin ) sqlNode ).getLeft ().getKind () == JOIN ;
218- }
219-
220195 private AliasInfo getSqlNodeAliasInfo (SqlNode sqlNode ) {
221196 SqlNode info = ((SqlBasicCall ) sqlNode ).getOperands ()[0 ];
222197 SqlNode alias = ((SqlBasicCall ) sqlNode ).getOperands ()[1 ];
@@ -228,49 +203,18 @@ private AliasInfo getSqlNodeAliasInfo(SqlNode sqlNode) {
228203 return aliasInfo ;
229204 }
230205
231- private void convertMultiJoinToNestQuery (SqlNode sqlNode , Set <String > sideTableSet ) {
232- SqlKind sqlKind = sqlNode .getKind ();
233- switch (sqlKind ) {
234- case JOIN :
235- checkAndReplaceMultiJoin (((SqlJoin ) sqlNode ).getRight (), sideTableSet );
236- checkAndReplaceMultiJoin (((SqlJoin ) sqlNode ).getLeft (), sideTableSet );
237- if (isMultiJoinSqlNode (sqlNode )) {
238- AliasInfo rightTableAliasInfo = getSqlNodeAliasInfo (((SqlJoin ) sqlNode ).getRight ());
239- String rightTableName = StringUtils .isEmpty (rightTableAliasInfo .getName ()) ? rightTableAliasInfo .getAlias () : rightTableAliasInfo .getName ();
240- if (sideTableSet .contains (rightTableName )) {
241- List <Tuple2 <String , String >> joinIncludeSourceTable = Lists .newArrayList ();
242- ParseUtils .parseLeftNodeTableName (((SqlJoin ) sqlNode ).getLeft (), joinIncludeSourceTable , sideTableSet );
243-
244- // last source table alias name + side or child query table alias name + _0
245- String leftFirstTableAlias = joinIncludeSourceTable .get (0 ).f0 ;
246- String internalTableName = buildInternalTableName (leftFirstTableAlias , SPLIT , rightTableName ) + "_0" ;
247- midTableNameMapping .put (internalTableName , joinIncludeSourceTable );
248-
249- // select * from xxx
250- SqlNode newSource = buildSelectByLeftNode (((SqlJoin ) sqlNode ).getLeft ());
251- // ( select * from xxx) as xxx_0
252- SqlBasicCall newAsNode = buildAsSqlNode (internalTableName , newSource );
253- ((SqlJoin ) sqlNode ).setLeft (newAsNode );
254-
255- String asNodeAlias = buildInternalTableName (internalTableName , SPLIT , rightTableName );
256- buildAsSqlNode (asNodeAlias , sqlNode );
257-
258- HashBasedTable <String , String , String > mappingTable = HashBasedTable .create ();
259- Set <String > sourceTableName = localTableCache .keySet ();
260- joinIncludeSourceTable .stream ().filter ((Tuple2 <String , String > tabName ) -> {
261- return null != tabName .f1 && sourceTableName .contains (tabName .f1 );
262- }).forEach ((Tuple2 <String , String > tabName ) -> {
263- String realTableName = tabName .f1 ;
264- String tableAlias = tabName .f0 ;
265- Table table = localTableCache .get (realTableName );
266- ParseUtils .fillFieldNameMapping (mappingTable , table .getSchema ().getFieldNames (), tableAlias );
267-
268- });
269- // ParseUtils.replaceJoinConditionTabName(((SqlJoin) sqlNode).getCondition(), mappingTable, internalTableName);
270- System .out .println ("" );
271- }
272- }
273- break ;
206+ /**
207+ * 将和维表关联的join 替换为一个新的查询
208+ * @param sqlNode
209+ * @param sideTableSet
210+ */
211+ private void convertSideJoinToNewQuery (SqlJoin sqlNode , Set <String > sideTableSet ) {
212+ checkAndReplaceMultiJoin (sqlNode .getLeft (), sideTableSet );
213+ checkAndReplaceMultiJoin (sqlNode .getRight (), sideTableSet );
214+
215+ AliasInfo rightTableAliasInfo = getSqlNodeAliasInfo (sqlNode .getRight ());
216+ if (sideTableSet .contains (rightTableAliasInfo .getName ())){
217+ //构建新的查询
274218 }
275219 }
276220
@@ -288,15 +232,21 @@ private JoinInfo dealJoinNode(SqlJoin joinNode, Set<String> sideTableSet, Queue<
288232 SqlNode leftNode = joinNode .getLeft ();
289233 SqlNode rightNode = joinNode .getRight ();
290234 JoinType joinType = joinNode .getJoinType ();
235+
291236 String leftTbName = "" ;
292237 String leftTbAlias = "" ;
293238 String rightTableName = "" ;
294239 String rightTableAlias = "" ;
240+ boolean leftTbisTmp = false ;
241+
295242 Tuple2 <String , String > rightTableNameAndAlias = null ;
296243 if (leftNode .getKind () == IDENTIFIER ){
297244 leftTbName = leftNode .toString ();
298245 } else if (leftNode .getKind () == JOIN ) {
299- System .out .println (leftNode .toString ());
246+ //处理连续join
247+ SqlBasicCall sqlBasicCall = dealNestJoin ((SqlJoin ) leftNode , sideTableSet , queueInfo );
248+ leftTbName = sqlBasicCall .getOperands ()[0 ].toString ();
249+ leftTbisTmp = true ;
300250 } else if (leftNode .getKind () == AS ) {
301251 AliasInfo aliasInfo = (AliasInfo ) parseSql (leftNode , sideTableSet , queueInfo );
302252 leftTbName = aliasInfo .getName ();
@@ -320,19 +270,6 @@ private JoinInfo dealJoinNode(SqlJoin joinNode, Set<String> sideTableSet, Queue<
320270 throw new RuntimeException ("side join not support join type of right[current support inner join and left join]" );
321271 }
322272
323- Iterator iterator = ((HashMap ) midTableNameMapping ).values ().iterator ();
324- while (iterator .hasNext ()) {
325- List <Tuple2 <String , String >> next = (List ) iterator .next ();
326- String finalRightTableAlias = rightTableAlias ;
327- String finalRightTableName = rightTableName ;
328- next .forEach (tp2 -> {
329- if (tp2 .f1 == null && tp2 .f0 == finalRightTableAlias ) {
330- tp2 .f1 = finalRightTableName ;
331- }
332- });
333- }
334-
335-
336273 JoinInfo tableInfo = new JoinInfo ();
337274 tableInfo .setLeftTableName (leftTbName );
338275 tableInfo .setRightTableName (rightTableName );
@@ -341,11 +278,15 @@ private JoinInfo dealJoinNode(SqlJoin joinNode, Set<String> sideTableSet, Queue<
341278 } else {
342279 tableInfo .setLeftTableAlias (leftTbAlias );
343280 }
281+
344282 if (StringUtils .isEmpty (rightTableAlias )){
345283 tableInfo .setRightTableAlias (rightTableName );
346284 } else {
347285 tableInfo .setRightTableAlias (rightTableAlias );
348286 }
287+
288+ tableInfo .setLeftIsTmpTable (leftTbisTmp );
289+
349290 tableInfo .setLeftIsSideTable (leftIsSide );
350291 tableInfo .setRightIsSideTable (rightIsSide );
351292 tableInfo .setLeftNode (leftNode );
@@ -355,6 +296,24 @@ private JoinInfo dealJoinNode(SqlJoin joinNode, Set<String> sideTableSet, Queue<
355296 return tableInfo ;
356297 }
357298
299+ //构建新的查询
300+ private SqlBasicCall dealNestJoin (SqlJoin joinNode , Set <String > sideTableSet , Queue <Object > queueInfo ){
301+ SqlNode rightNode = joinNode .getRight ();
302+
303+ Tuple2 <String , String > rightTableNameAndAlias = parseRightNode (rightNode , sideTableSet , queueInfo );
304+ String rightTableName = rightTableNameAndAlias .f0 ;
305+ boolean rightIsSide = checkIsSideTable (rightTableName , sideTableSet );
306+
307+ if (!rightIsSide ){
308+ return null ;
309+ }
310+
311+ JoinInfo joinInfo = dealJoinNode (joinNode , sideTableSet , queueInfo );
312+ queueInfo .offer (joinInfo );
313+ return buildAsNodeByJoinInfo (joinInfo , null , null );
314+
315+ }
316+
358317 private Tuple2 <String , String > parseRightNode (SqlNode sqlNode , Set <String > sideTableSet , Queue <Object > queueInfo ) {
359318 Tuple2 <String , String > tabName = new Tuple2 <>("" , "" );
360319 if (sqlNode .getKind () == IDENTIFIER ){
@@ -367,19 +326,25 @@ private Tuple2<String, String> parseRightNode(SqlNode sqlNode, Set<String> sideT
367326 return tabName ;
368327 }
369328
370- private SqlNode buildSelectByLeftNode (SqlNode leftNode ) {
371- SqlParser sqlParser = SqlParser .create (tempSQL , CalciteConfig .MYSQL_LEX_CONFIG );
372- SqlNode sqlNode = null ;
373- try {
374- sqlNode = sqlParser .parseStmt ();
375- }catch (Exception e ) {
376- LOG .error ("tmp sql parse error.." , e );
329+ private Tuple2 <String , String > parseLeftNode (SqlNode sqlNode ){
330+ Tuple2 <String , String > tabName = new Tuple2 <>("" , "" );
331+ if (sqlNode .getKind () == IDENTIFIER ){
332+ tabName .f0 = sqlNode .toString ();
333+ tabName .f1 = sqlNode .toString ();
334+ }else if (sqlNode .getKind () == AS ){
335+ SqlNode info = ((SqlBasicCall )sqlNode ).getOperands ()[0 ];
336+ SqlNode alias = ((SqlBasicCall ) sqlNode ).getOperands ()[1 ];
337+
338+ tabName .f0 = info .toString ();
339+ tabName .f1 = alias .toString ();
340+ }else {
341+ throw new RuntimeException ("" );
377342 }
378343
379- ((SqlSelect ) sqlNode ).setFrom (leftNode );
380- return sqlNode ;
344+ return tabName ;
381345 }
382346
347+
383348 /**
384349 *
385350 * @param joinInfo
@@ -452,14 +417,6 @@ private boolean checkIsSideTable(String tableName, Set<String> sideTableList){
452417 return false ;
453418 }
454419
455- public Map <String , HashBasedTable <String , String , String >> getMidTableFileNameMapping () {
456- return midTableFileNameMapping ;
457- }
458-
459- public Map <String , List <Tuple2 <String , String >>> getMidTableNameMapping () {
460- return midTableNameMapping ;
461- }
462-
463420 public void setLocalTableCache (Map <String , Table > localTableCache ) {
464421 this .localTableCache = localTableCache ;
465422 }
0 commit comments