From c0d96da3f21363e84667087402ee659c39d50f3b Mon Sep 17 00:00:00 2001 From: zhenggli Date: Mon, 22 Apr 2024 16:35:23 -0500 Subject: [PATCH] Support NAME keyword in Oracle XMLELEMENT function --- .../druid/sql/parser/SQLExprParser.java | 9 ++++ .../bvt/sql/oracle/OracleXmlelementTest.java | 45 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 core/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleXmlelementTest.java diff --git a/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 7b6a005c6f..d55606ec7c 100644 --- a/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -1873,6 +1873,15 @@ protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) { SQLExpr contentExpr = expr(); methodInvokeExpr.setContent(contentExpr); } + if ("XMLELEMENT".equals(methodName) && lexer.identifierEquals("NAME")) { + Lexer.SavePoint mark = lexer.markOut(); + lexer.nextToken(); // Skip NAME if it is a keyword + if (lexer.token != Token.IDENTIFIER) { + // No other identifier name comes after NAME, so NAME itself is + // the xml element name. Reset lexer to NAME + lexer.reset(mark); + } + } if (token != Token.RPAREN && token != Token.FROM) { exprList(methodInvokeExpr.getArguments(), methodInvokeExpr); if (lexer.token == Token.RPAREN) { diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleXmlelementTest.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleXmlelementTest.java new file mode 100644 index 0000000000..87a36a4e45 --- /dev/null +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleXmlelementTest.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import org.junit.Assert; + +import java.util.List; + +public class OracleXmlelementTest extends OracleTest { + public void testOracleXmlelement() { + String sql = "SELECT /* NUSQL.TEST */ XMLELEMENT(NAME foo).getstringval() from dual"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statement = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statement.accept(visitor); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + } + + public void testOracleXmlelement_WithoutNameKeyword() { + String sql = "SELECT /* NUSQL.TEST */ XMLELEMENT(foo).getstringval() from dual"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statement = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statement.accept(visitor); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + } +}