#6705·druid

MySQL: 使用简单形式创建函数(返回不包含 BEGIN...END 的表达式)会在多语句脚本中中断后续语句

作者: leungjun创建于 2026年8月10日更新于 2026年8月10日

** 描述错误** 当 MySQL 脚本包含一个简单的形式 CREATE 函数' (正体是一个单独的RETURN expr;没有BEGIN.END'),然后是其他语句 SQLUTIls.parse Statements(sql,"MySQL")' 扔出ParserException:语法错误. sorder SELECT' 。 开始... 身体正常 覆盖所有测试过的版本1.2.14~1.2.28(最晚).

** 废除** 贾瓦 列表<SQL声明> stmts = SQLUTils.parse声明 () “(f) 返回的返回的返回1;\nelite 1;”,“MySQL”; // 解析器例外: 语法出错. pos 36 第2行 第2行 符号 SELECT

`CREATE 功能.返回1; ' 之后又有一个`CREATE 功能 ' 于1.2.14日通过,但也于1.2.27/1.2.28日失败(`不支持.象征CREATE ' ),因为只有`Case SELECT' (现在的`CREATE ' )旗下警卫。

** 预期行为**
脚本分为2个语句: " SQLCreate功能声明 " + " SQLS Elect Statement " 。

** 循环原因**
`SQL StatementParser.parse Return () ' 消耗终止的`SEMI'本身(`接受(token.SEMI)'+`Setsemi')。 因此,在“议会声明”一文中,当地“半旗”仍为“假旗”,“案件SELECT”分支的警卫`i'0'-dbType!=odps &&!semi'错误地投入下一个声明。 `案件CREATE ' 在1.2.14上没有这种警卫,这就是为什么`功能+功能 ' 意外通过。

** 建议的固定件**
让`Parse Return()'不消耗`SEMI';将语句终止分号留给`Parse StatementList'的`SEMI'分支,该分支统一规定`semi = true'和`semi'之后:
贾瓦
公开 SQL 声明解析返回 () {
if (lexer.token = token.RETURN = lexer.identifer Equals ("RETURN")) (中文(简体) ). {
exter.nextToken( ); (中文(简体) ).
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
SQL 返回状态 stmt = 新的 SQL 返回状态 ();
如果(lexer.token!=token.SEMI) {(列克谢.token!).
stmt.setExpr( 此为. exprParser. expr () ) ;
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
返回 stmt; // 在此不接受( SEMI)
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?

本地( 通过“ MySqlStatementParser” 子类) 我们验证了此更改 : 函数+ SELECT, 函数+函数, BEGIN... END+ SELECT, 混合脚本全部正确解析 .