flink table select sqlnode的生成过程
javacc parsejj 这个需要去calcite去找
/** * Parses a leaf SELECT expression without ORDER BY. */ SqlSelect SqlSelect() : { final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>(); final SqlNodeList keywordList; List<SqlNode> selectList; final SqlNode fromClause; final SqlNode where; final SqlNodeList groupBy; final SqlNode having; final SqlNodeList windowDecls; final Span s; } { <SELECT> { s = span(); } SqlSelectKeywords(keywords) ( <STREAM> { keywords.add(SqlSelectKeyword.STREAM.symbol(getPos())); } )? ( <DISTINCT> { keywords.add(SqlSelectKeyword.DISTINCT.symbol(getPos())); } | <ALL> { keywords.add(SqlSelectKeyword.ALL.symbol(getPos())); } )? { keywordList = new SqlNodeList(keywords, s.addAll(keywords).pos()); } selectList = SelectList() ( <FROM> fromClause = FromClause() where = WhereOpt() groupBy = GroupByOpt() having = HavingOpt() windowDecls = WindowOpt() | E() { fromClause = null; where = null; groupBy = null; having = null; windowDecls = null; } ) { return new SqlSelect(s.end(this), keywordList, new SqlNodeList(selectList, Span.of(selectList).pos()), fromClause, where, groupBy, having, windowDecls, null, null, null); } }
经过javacc生成的代码,这个位置
/** * Parses a leaf SELECT expression without ORDER BY. */ final public SqlSelect SqlSelect() throws ParseException { final List<SqlLiteral> keywords = new ArrayList<SqlLiteral>(); final SqlNodeList keywordList; List<SqlNode> selectList; final SqlNode fromClause; final SqlNode where; final SqlNodeList groupBy; final SqlNode having; final SqlNodeList windowDecls; final Span s; jj_consume_token(SELECT); s = span(); SqlSelectKeywords(keywords); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case STREAM: jj_consume_token(STREAM); keywords.add(SqlSelectKeyword.STREAM.symbol(getPos())); break; default: jj_la1[73] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ALL: case DISTINCT: switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DISTINCT: jj_consume_token(DISTINCT); keywords.add(SqlSelectKeyword.DISTINCT.symbol(getPos())); break; case ALL: jj_consume_token(ALL); keywords.add(SqlSelectKeyword.ALL.symbol(getPos())); break; default: jj_la1[74] = jj_gen; jj_consume_token(-1); throw new ParseException(); } break; default: jj_la1[75] = jj_gen; ; } keywordList = new SqlNodeList(keywords, s.addAll(keywords).pos()); selectList = SelectList(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case FROM: jj_consume_token(FROM); fromClause = FromClause(); where = WhereOpt(); groupBy = GroupByOpt(); having = HavingOpt(); windowDecls = WindowOpt(); break; default: jj_la1[76] = jj_gen; E(); fromClause = null; where = null; groupBy = null; having = null; windowDecls = null; } {if (true) return new SqlSelect(s.end(this), keywordList, new SqlNodeList(selectList, Span.of(selectList).pos()), fromClause, where, groupBy, having, windowDecls, null, null, null);} throw new Error("Missing return statement in function"); }
解析后的sql node。
使用的sql为
Table table = tEnv.sqlQuery("SELECT * FROM test");
主要是为了弄清楚sql node中的pos到底是什么,以及parseimpl.flt文件中的
pos = getPos() 这个方法有什么用。
pos就是在描述sql 在整个text中的位置,防止sql中的 换行 空格 对最终解析造成影响。
以上面的sql为例,sql就一行 18个字符,所以pos 最后就是 1 1 1 18