/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.extension.sql.parser; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.seasar.extension.sql.EndCommentNotFoundRuntimeException; import org.seasar.extension.sql.Node; import org.seasar.extension.sql.SemicolonNotAllowedRuntimeException; import org.seasar.extension.sql.SqlContext; import org.seasar.extension.sql.SqlParser; import org.seasar.extension.sql.TokenNotClosedRuntimeException; import org.seasar.extension.sql.VariableSqlNotAllowedRuntimeException; import org.seasar.extension.sql.context.SqlContextImpl; import org.seasar.extension.sql.node.BindVariableNode; import org.seasar.extension.sql.node.IfNode; import org.seasar.extension.sql.node.SqlNode; /** * @author higa * */ public class SqlParserImplTest extends TestCase { /** * @throws Exception */ public void testParse() throws Exception { String sql = "SELECT * FROM emp"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Node node = parser.parse(); node.accept(ctx); assertEquals("1", sql, ctx.getSql()); } /** * @throws Exception */ public void testParseEndSemicolon() throws Exception { testParseEndSemicolon(";"); testParseEndSemicolon(";\t"); testParseEndSemicolon("; "); } /** * @param endChar */ public void testParseEndSemicolon(String endChar) { String sql = "SELECT * FROM emp"; SqlParser parser = new SqlParserImpl(sql + endChar); SqlContext ctx = new SqlContextImpl(); Node node = parser.parse(); node.accept(ctx); assertEquals("1", sql, ctx.getSql()); } /** * @throws Exception */ public void testCommentEndNotFound() throws Exception { String sql = "SELECT * FROM emp/*hoge"; SqlParser parser = new SqlParserImpl(sql); try { parser.parse(); fail("1"); } catch (TokenNotClosedRuntimeException ex) { System.out.println(ex); } } /** * @throws Exception */ public void testParseBindVariable() throws Exception { String sql = "SELECT * FROM emp WHERE job = /*job*/'CLERK' AND deptno = /*deptno*/20"; String sql2 = "SELECT * FROM emp WHERE job = ? AND deptno = ?"; String sql3 = "SELECT * FROM emp WHERE job = "; String sql4 = " AND deptno = "; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); String job = "CLERK"; Integer deptno = new Integer(20); ctx.addArg("job", job, job.getClass()); ctx.addArg("deptno", deptno, deptno.getClass()); Node root = parser.parse(); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 2, vars.length); assertEquals("3", job, vars[0]); assertEquals("4", deptno, vars[1]); assertEquals("5", 4, root.getChildSize()); SqlNode sqlNode = (SqlNode) root.getChild(0); assertEquals("6", sql3, sqlNode.getSql()); BindVariableNode varNode = (BindVariableNode) root.getChild(1); assertEquals("7", "job", varNode.getExpression()); SqlNode sqlNode2 = (SqlNode) root.getChild(2); assertEquals("8", sql4, sqlNode2.getSql()); BindVariableNode varNode2 = (BindVariableNode) root.getChild(3); assertEquals("9", "deptno", varNode2.getExpression()); } /** * @throws Exception */ public void testParseBindVariable2() throws Exception { String sql = "SELECT * FROM emp WHERE job = /* job*/'CLERK'"; String sql2 = "SELECT * FROM emp WHERE job = 'CLERK'"; String sql3 = "SELECT * FROM emp WHERE job = "; String sql4 = "'CLERK'"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Node root = parser.parse(); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); assertEquals("2", 2, root.getChildSize()); SqlNode sqlNode = (SqlNode) root.getChild(0); assertEquals("3", sql3, sqlNode.getSql()); SqlNode sqlNode2 = (SqlNode) root.getChild(1); assertEquals("4", sql4, sqlNode2.getSql()); } /** * @throws Exception */ public void testParseBindVariable3() throws Exception { String sql = "BETWEEN sal ? AND ?"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); ctx.addArg("$1", new Integer(0), Integer.class); ctx.addArg("$2", new Integer(1000), Integer.class); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("BETWEEN sal ? AND ?", ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 2, vars.length); assertEquals("3", new Integer(0), vars[0]); assertEquals("4", new Integer(1000), vars[1]); } /** * @throws Exception */ public void testParseBindVariable4() throws Exception { String sql = "SELECT * FROM emp WHERE job = #*job*#'CLERK' AND deptno = #*deptno*#20"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); String job = "CLERK"; Integer deptno = new Integer(20); ctx.addArg("job", job, job.getClass()); ctx.addArg("deptno", deptno, deptno.getClass()); Node root = parser.parse(); root.accept(ctx); System.out.println(ctx.getSql()); } /** * @throws Exception */ public void testParseBindVariable5() throws Exception { String sql = "SELECT * FROM emp WHERE job = /*job*/'CLERK'"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); String job = "HOGE"; ctx.addArg("job", job, job.getClass()); Node root = parser.parse(); root.accept(ctx); } /** * @throws Exception */ public void testParseWhiteSpace() throws Exception { String sql = "SELECT * FROM emp WHERE empno = /*empno*/1 AND 1 = 1"; String sql2 = "SELECT * FROM emp WHERE empno = ? AND 1 = 1"; String sql3 = " AND 1 = 1"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Integer empno = new Integer(7788); ctx.addArg("empno", empno, empno.getClass()); Node root = parser.parse(); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); SqlNode sqlNode = (SqlNode) root.getChild(2); assertEquals("2", sql3, sqlNode.getSql()); } /** * @throws Exception */ public void testParseIf() throws Exception { String sql = "SELECT * FROM emp/*IF job != null*/ WHERE job = /*job*/'CLERK'/*END*/"; String sql2 = "SELECT * FROM emp WHERE job = ?"; String sql3 = "SELECT * FROM emp"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); String job = "CLERK"; ctx.addArg("job", job, job.getClass()); Node root = parser.parse(); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 1, vars.length); assertEquals("3", job, vars[0]); assertEquals("4", 2, root.getChildSize()); SqlNode sqlNode = (SqlNode) root.getChild(0); assertEquals("5", sql3, sqlNode.getSql()); IfNode ifNode = (IfNode) root.getChild(1); assertEquals("6", "job != null", ifNode.getExpression()); assertEquals("7", 2, ifNode.getChildSize()); SqlNode sqlNode2 = (SqlNode) ifNode.getChild(0); assertEquals("8", " WHERE job = ", sqlNode2.getSql()); BindVariableNode varNode = (BindVariableNode) ifNode.getChild(1); assertEquals("9", "job", varNode.getExpression()); SqlContext ctx2 = new SqlContextImpl(); root.accept(ctx2); System.out.println(ctx2.getSql()); assertEquals("10", sql3, ctx2.getSql()); } /** * @throws Exception */ public void testParseIf2() throws Exception { String sql = "/*IF aaa != null*/aaa/*IF bbb != null*/bbb/*END*//*END*/"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Node root = parser.parse(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("1", "", ctx.getSql()); ctx.addArg("aaa", null, String.class); ctx.addArg("bbb", "hoge", String.class); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("2", "", ctx.getSql()); ctx.addArg("aaa", "hoge", String.class); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("3", "aaabbb", ctx.getSql()); SqlContext ctx2 = new SqlContextImpl(); ctx2.addArg("aaa", "hoge", String.class); ctx2.addArg("bbb", null, String.class); root.accept(ctx2); System.out.println("[" + ctx2.getSql() + "]"); assertEquals("4", "aaa", ctx2.getSql()); } /** * @throws Exception */ public void testParseIf3() throws Exception { String sql = "/*IF aaa != null*/aaa,/*END*/"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Node root = parser.parse(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("", ctx.getSql()); ctx.addArg("aaa", "hoge", String.class); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("aaa,", ctx.getSql()); } /** * @throws Exception */ public void testParseIf4() throws Exception { String sql = "/*IF has_aaa*/aaa,/*END*/"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Node root = parser.parse(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("", ctx.getSql()); ctx.addArg("aaa", null, String.class); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("aaa,", ctx.getSql()); } /** * @throws Exception */ public void testParseIf5() throws Exception { String sql = "/*BEGIN*//*IF has_aaa*/,aaa/*END*//*END*/"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Node root = parser.parse(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("", ctx.getSql()); ctx.addArg("aaa", null, String.class); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("aaa", ctx.getSql()); } /** * @throws Exception */ public void testParseIf_NotAllowed() throws Exception { String sql = "SELECT * FROM emp/*IF job != null*/ WHERE job = /*job*/'CLERK'/*END*/"; SqlParser parser = new SqlParserImpl(sql, false); try { parser.parse(); fail(); } catch (VariableSqlNotAllowedRuntimeException expected) { } } /** * @throws Exception */ public void testParseElse() throws Exception { String sql = "SELECT * FROM emp WHERE /*IF job != null*/job = /*job*/'CLERK'-- ELSE job is null/*END*/"; String sql2 = "SELECT * FROM emp WHERE job = ?"; String sql3 = "SELECT * FROM emp WHERE job is null"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); String job = "CLERK"; ctx.addArg("job", job, job.getClass()); Node root = parser.parse(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("1", sql2, ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 1, vars.length); assertEquals("3", job, vars[0]); SqlContext ctx2 = new SqlContextImpl(); root.accept(ctx2); System.out.println("[" + ctx2.getSql() + "]"); assertEquals("4", sql3, ctx2.getSql()); } /** * @throws Exception */ public void testParseElse2() throws Exception { String sql = "/*IF false*/aaa--ELSE bbb = /*bbb*/123/*END*/"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Integer bbb = new Integer(123); ctx.addArg("bbb", bbb, bbb.getClass()); Node root = parser.parse(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("1", "bbb = ?", ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 1, vars.length); assertEquals("3", bbb, vars[0]); } /** * @throws Exception */ public void testParseElse3() throws Exception { String sql = "/*IF false*/aaa--ELSE bbb/*IF false*/ccc--ELSE ddd/*END*//*END*/"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); Node root = parser.parse(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("1", "bbbddd", ctx.getSql()); } /** * @throws Exception */ public void testElse4() throws Exception { String sql = "SELECT * FROM emp/*BEGIN*/ WHERE /*IF false*/aaa-- ELSE AND deptno = 10/*END*//*END*/"; String sql2 = "SELECT * FROM emp WHERE deptno = 10"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); } /** * @throws Exception */ public void testBegin() throws Exception { String sql = "SELECT * FROM emp/*BEGIN*/ WHERE /*IF job != null*/job = /*job*/'CLERK'/*END*//*IF deptno != null*/ AND deptno = /*deptno*/20/*END*//*END*/"; String sql2 = "SELECT * FROM emp"; String sql3 = "SELECT * FROM emp WHERE job = ?"; String sql4 = "SELECT * FROM emp WHERE job = ? AND deptno = ?"; String sql5 = "SELECT * FROM emp WHERE deptno = ?"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); SqlContext ctx2 = new SqlContextImpl(); ctx2.addArg("job", "CLERK", String.class); ctx2.addArg("deptno", null, Integer.class); root.accept(ctx2); System.out.println(ctx2.getSql()); assertEquals("2", sql3, ctx2.getSql()); SqlContext ctx3 = new SqlContextImpl(); ctx3.addArg("job", "CLERK", String.class); ctx3.addArg("deptno", new Integer(20), Integer.class); root.accept(ctx3); System.out.println(ctx3.getSql()); assertEquals("3", sql4, ctx3.getSql()); SqlContext ctx4 = new SqlContextImpl(); ctx4.addArg("deptno", new Integer(20), Integer.class); ctx4.addArg("job", null, String.class); root.accept(ctx4); System.out.println(ctx4.getSql()); assertEquals("4", sql5, ctx4.getSql()); } /** * @throws Exception */ public void testBegin2() throws Exception { String sql = "SELECT * FROM emp /*BEGIN*/WHERE /*IF job != null*/job = /*job*/'CLERK'/*END*//*END*/"; SqlParser parser = new SqlParserImpl(sql); SqlContext ctx = new SqlContextImpl(); String job = "HOGE"; ctx.addArg("job", job, job.getClass()); Node root = parser.parse(); root.accept(ctx); } /** * @throws Exception */ public void testBeginAnd() throws Exception { String sql = "/*BEGIN*/WHERE /*IF true*/aaa BETWEEN /*bbb*/111 AND /*ccc*/123/*END*//*END*/"; String sql2 = "WHERE aaa BETWEEN ? AND ?"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); ctx.addArg("bbb", "111", String.class); ctx.addArg("ccc", "222", String.class); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals(sql2, ctx.getSql()); } /** * @throws Exception */ public void testPrefixSql_comma() throws Exception { String sql = "/*BEGIN*//*IF false*/aaa/*END*//*IF true*/,bbb/*END*//*END*/"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); root.accept(ctx); System.out.println("[" + ctx.getSql() + "]"); assertEquals("bbb", ctx.getSql()); } /** * @throws Exception */ public void testIn() throws Exception { String sql = "SELECT * FROM emp WHERE deptno IN /*deptnoList*/(10, 20) ORDER BY ename"; String sql2 = "SELECT * FROM emp WHERE deptno IN (?, ?) ORDER BY ename"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); List deptnoList = new ArrayList(); deptnoList.add(new Integer(10)); deptnoList.add(new Integer(20)); ctx.addArg("deptnoList", deptnoList, List.class); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 2, vars.length); assertEquals("3", new Integer(10), vars[0]); assertEquals("4", new Integer(20), vars[1]); } /** * @throws Exception */ public void testIn2() throws Exception { String sql = "SELECT * FROM emp WHERE deptno IN /*deptnoList*/(10, 20) ORDER BY ename"; String sql2 = "SELECT * FROM emp WHERE deptno IN (?, ?) ORDER BY ename"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); int[] deptnoArray = { 10, 20 }; ctx.addArg("deptnoList", deptnoArray, deptnoArray.getClass()); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 2, vars.length); assertEquals("3", new Integer(10), vars[0]); assertEquals("4", new Integer(20), vars[1]); } /** * @throws Exception */ public void testIn3() throws Exception { String sql = "SELECT * FROM emp WHERE ename IN /*enames*/('SCOTT','MARY') AND job IN /*jobs*/('ANALYST', 'FREE')"; String sql2 = "SELECT * FROM emp WHERE ename IN (?, ?) AND job IN (?, ?)"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); String[] enames = { "SCOTT", "MARY" }; String[] jobs = { "ANALYST", "FREE" }; ctx.addArg("enames", enames, enames.getClass()); ctx.addArg("jobs", jobs, jobs.getClass()); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", sql2, ctx.getSql()); Object[] vars = ctx.getBindVariables(); assertEquals("2", 4, vars.length); assertEquals("3", "SCOTT", vars[0]); assertEquals("4", "MARY", vars[1]); assertEquals("5", "ANALYST", vars[2]); assertEquals("6", "FREE", vars[3]); } /** * @throws Exception */ public void testEndNotFound() throws Exception { String sql = "/*BEGIN*/"; SqlParser parser = new SqlParserImpl(sql); try { parser.parse(); fail("1"); } catch (EndCommentNotFoundRuntimeException ex) { System.out.println(ex); } } /** * @throws Exception */ public void testEndParent() throws Exception { String sql = "INSERT INTO ITEM (ID, NUM) VALUES (/*id*/1, /*num*/20)"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); ctx.addArg("id", new Integer(0), Integer.class); ctx.addArg("num", new Integer(1), Integer.class); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", true, ctx.getSql().endsWith(")")); } /** * @throws Exception */ public void testEmbeddedValue() throws Exception { String sql = "/*$aaa*/"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); ctx.addArg("aaa", new Integer(0), Integer.class); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("1", "0", ctx.getSql()); } /** * @throws Exception */ public void testEmbeddedValue_semicolon() throws Exception { String sql = "/*$aaa*/"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); ctx.addArg("aaa", ";update", String.class); try { root.accept(ctx); fail(); } catch (SemicolonNotAllowedRuntimeException e) { System.out.println(e); } } /** * @throws Exception */ public void testEmbeddedValue_orderBy() throws Exception { String sql = "/*orderBy*/"; SqlParser parser = new SqlParserImpl(sql); Node root = parser.parse(); SqlContext ctx = new SqlContextImpl(); ctx.addArg("orderBy", "id desc", String.class); root.accept(ctx); System.out.println(ctx.getSql()); assertEquals("id desc", ctx.getSql()); } /** * @throws Exception */ public void testEmbeddedValue_NotAllowed() throws Exception { String sql = "/*$aaa*/"; SqlParser parser = new SqlParserImpl(sql, false); try { parser.parse(); fail(); } catch (VariableSqlNotAllowedRuntimeException expected) { } } }