db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1039084 - in /db/derby/code/trunk/java: testing/org/apache/derbyTesting/functionTests/tests/lang/XplainStatisticsTest.java tools/org/apache/derby/impl/tools/planexporter/AccessDatabase.java
Date Thu, 25 Nov 2010 16:24:18 GMT
Author: kahatlen
Date: Thu Nov 25 16:24:18 2010
New Revision: 1039084

URL: http://svn.apache.org/viewvc?rev=1039084&view=rev
Log:
DERBY-4903: Plan exporter tool produces broken output if query contains less-than operator

Patch contributed by C.S. Nirmal J. Fernando <nirmal070125@gmail.com>.

Modified:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XplainStatisticsTest.java
    db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/planexporter/AccessDatabase.java

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XplainStatisticsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XplainStatisticsTest.java?rev=1039084&r1=1039083&r2=1039084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XplainStatisticsTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XplainStatisticsTest.java
Thu Nov 25 16:24:18 2010
@@ -632,6 +632,28 @@ public class XplainStatisticsTest extend
     
     /**
      * Added by DERBY-4587
+     * Returns the stmt_id for this particular statement
+     * @param s Statement
+     * @return stmt_id
+     * */
+    private String[] getStmtIDArray(Statement s, int length) throws SQLException{
+        ResultSet rs;
+        String[] stmt_id = new String[length];
+        int i=0;
+        rs = s.executeQuery(
+            "select stmt_id from XPLTEST.sysxplain_statements");
+        while(rs.next()){
+            stmt_id[i] = rs.getString(1);
+            i++;
+            if (i==length)
+                assertFalse(rs.next());
+        }
+        rs.close();
+        return stmt_id;
+    }
+
+    /**
+     * Added by DERBY-4587
      * @param file name of the XML file - without extension
      * @return a Document object
      * @throws Exception
@@ -2380,6 +2402,27 @@ public class XplainStatisticsTest extend
         }
         assertEquals("Captured wrong number of statements?",
                 searches.length, matchedStatements);
+
+        /* * This test is added by DERBY-4587, to verify the content
+         * of the XML file generated by the new tool, PlanExporter.
+         * This test specially checks the behaviour of the tool
+         * when the query executed contains special XML characters
+         * such as <,> etc.
+         * */
+        if(XML.classpathMeetsXMLReqs()){
+
+            //getting the stmt_ids, because files are generated using
+            //stmt_id as their name.
+            String[] stmt_id = getStmtIDArray(s, searches.length);
+
+            for(int i=0;i<stmt_id.length;i++){
+                //testing the <statement> element
+                Assert.assertEquals(
+                        searches[i],
+                        readStatement(stmt_id[i]));
+            }
+        }
+
     }
 
     /**
@@ -2512,6 +2555,46 @@ public class XplainStatisticsTest extend
     }
 
     /**
+     * Test that queries that contain table names with quotation marks are not garbled
+     * by the plan exporter tool. Regression test case for DERBY-4903.
+     */
+    public void testPlanExporterHandlingSpecialCharacters() throws Exception{
+        String table = "\"A \"\"quoted\"\" table name\"";
+        String queryText = "SELECT * FROM " + table;
+
+        Statement s = createStatement();
+        s.execute("CREATE TABLE " + table + "(X INT)");
+
+        enableXplainStyle(s);
+        JDBC.assertEmpty(s.executeQuery(queryText));
+        disableXplainStyle(s);
+
+        ResultSet rs = s.executeQuery(
+        "SELECT STMT_ID, STMT_TEXT FROM XPLTEST.SYSXPLAIN_STATEMENTS");
+        assertTrue(rs.next());
+        String stmtId = rs.getString(1);
+        assertEquals(queryText, rs.getString(2));
+        assertFalse(rs.next());
+        rs.close();
+
+        if (XML.classpathMeetsXMLReqs()) {
+            assertEquals(queryText, readStatement(stmtId));
+
+            //testing the root <node> element's name attributes
+            Assert.assertEquals(
+                    "TABLESCAN|",
+                    getNodeName(stmtId));
+
+            //for TABLESCAN node, test scanned_object entry
+            //is exist and verify its value correctly replaced
+            //by special XML symbols.
+            Assert.assertEquals("A \"quoted\" table name",
+                    getNodeAttribute(stmtId,"scanned_object",0));
+        }
+
+    }
+
+    /**
      * Abstract class for a thread executing a database action (i.e. a query).
      */
     private static abstract class AbstractMTThread

Modified: db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/planexporter/AccessDatabase.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/planexporter/AccessDatabase.java?rev=1039084&r1=1039083&r2=1039084&view=diff
==============================================================================
--- db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/planexporter/AccessDatabase.java
(original)
+++ db/derby/code/trunk/java/tools/org/apache/derby/impl/tools/planexporter/AccessDatabase.java
Thu Nov 25 16:24:18 2010
@@ -260,6 +260,7 @@ public class AccessDatabase {
         for(int i=0;i<data.length;i++){
             //assume only one root element for any query
             if(data[i].getDepth()==0){//root element
+
                 xmlDetails += indent(1);
                 xmlDetails += data[i].toString();
                 getChildren(1, data[i].getId());
@@ -374,7 +375,16 @@ public class AccessDatabase {
         while(results.next())
         {
             String text= results.getString(1);
+
             if(text != null){
+
+                /*Removing possible occurrences of special XML characters
+                 * from XML node attributes in XML representation.*/
+                text = replaceInAttribute(text, '<',"&lt;");
+                text = replaceInAttribute(text, '>',"&gt;");
+                text = replaceInAttribute(text, '\'',"&apos;");
+                text = replaceInAttribute(text, '"',"&quot;");
+
                 switch(x){
                 case ID:
                     data[i].setId(text+" ");
@@ -466,32 +476,50 @@ public class AccessDatabase {
         String statement = results.getString(1);
         results.close();
         ps.close();
-        /*Removing possible less than and greater than characters
-         * in a query statement with XML representation.*/
-        if(statement.indexOf('<')!= -1){
-            statement = replace(statement, "<","&lt;");
-        }
-        if(statement.indexOf('>')!= -1){
-            statement = replace(statement, ">","&gt;");
-        }
+
+        /*Removing possible occurrences of special XML characters
+         * from a query statement with XML representation.*/
+        statement = replace(statement, '<',"&lt;");
+        statement = replace(statement, '>',"&gt;");
+        statement = replace(statement, '\'',"&apos;");
+        statement = replace(statement, '"',"&quot;");
+
         return "<statement>"+statement+"</statement>\n";
     }
 
     /**
      *
-     * @param stmt statement to be changed
+     * @param text text to be checked
      * @param expr string to be removed
      * @param replace string to be added
      * @return modified string
      */
-    private String replace(String stmt, String expr, String replace){
-    	 int idx = stmt.indexOf(expr);
+    private String replace(String text, char expr, String replace){
+         int idx = text.indexOf(expr);
     	 while (idx >= 0)
     	 {
-    	   stmt = stmt.substring(0, idx) + replace + stmt.substring(idx+1);
-    	   idx = stmt.indexOf(expr);
+             text = text.substring(0, idx) + replace + text.substring(idx+1);
+             idx = text.indexOf(expr);
     	 }
-    	 return stmt;
+         return text;
+    }
+
+    /**
+     * This method is needed since in the case of XML attributes
+     * we have to filter the quotation (&quot;) marks that is compulsory.
+     * eg:
+     * scanned_object="A &quot;quoted&quot;  table name";
+     *
+     * @param text attribute string to be checked
+     * @param expr string to be removed
+     * @param replace string to be added
+     * @return modified string
+     */
+    private String replaceInAttribute(String text, char expr, String replace){
+        if (text.indexOf('"') == -1)
+            return text;
+        String correctXMLString = replace(text.substring(text.indexOf('"')+1, text.length()-1),
expr, replace);
+        return text.substring(0,text.indexOf('"')+1)+correctXMLString+"\"";
     }
    
     /**



Mime
View raw message