You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ma...@apache.org on 2007/07/18 19:04:03 UTC

svn commit: r557334 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/EmbedDatabaseMetaData.java engine/org/apache/derby/impl/jdbc/metadata.properties testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java

Author: mamta
Date: Wed Jul 18 10:04:02 2007
New Revision: 557334

URL: http://svn.apache.org/viewvc?view=rev&rev=557334
Log:
DERBY-2896

Metadata calls getTables and getUDTs were failing when run from a user schema in a territory based collated database.
The reason for it is that these metadata calls were not getting compiled in SYS schema when they were executed from
a user schema. Metadata calls should always compile in SYS schema no matter what the current schema might be. The
reason getTables was not getting compiled in SYS schema was because we were trying to modify it's metadata sql on
the fly and then were compiling that modified sql in whatever the current schema might be. I have changed the 
metadata sql for getTables in metadata.properties so that we do not need to modify it on the fly anymore. This will
allow getTables to follow the same codepath as other metadata queries which will also ensure that the sql gets
compiled in SYS schema.

As for getUDTs, it was merely a coding bug that we didn't follow the same logic as other metadata queries for it.
I have changed getUDTs implementation to follow the same codepath as other metadata queries.


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedDatabaseMetaData.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedDatabaseMetaData.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedDatabaseMetaData.java?view=diff&rev=557334&r1=557333&r2=557334
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedDatabaseMetaData.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedDatabaseMetaData.java Wed Jul 18 10:04:02 2007
@@ -1707,55 +1707,67 @@
      */
 	public ResultSet getTables(String catalog, String schemaPattern,
 		String tableNamePattern, String types[]) throws SQLException {
-		synchronized (getConnectionSynchronization()) {
-                        setupContextStack();
-			ResultSet rs = null;
-			try {
-			
-			String queryText =
-				getQueryDescriptions(false).getProperty("getTables");
-
-			/*
-			 * The query text is assumed to end with a "where" clause, so
-			 * that we can safely append
-			 * "and table_Type in ('xxx','yyy','zzz', ...)" and
-			 * have it become part of the where clause.
-			 *
-			 * Let's assume for now that the table type first char corresponds
-			 * to JBMS table type identifiers.
-			 */
-			StringBuffer whereClauseTail = new StringBuffer(queryText);
-
-			if (types != null  &&  types.length >= 1) {
-				whereClauseTail.append(" AND TABLETYPE IN ('");
-				whereClauseTail.append(types[0].substring(0, 1));
-
-				for (int i=1; i<types.length; i++) {
-					whereClauseTail.append("','");
-					whereClauseTail.append(types[i].substring(0, 1));
-				}
-				whereClauseTail.append("')");
+		PreparedStatement s = getPreparedQuery("getTables");
+		s.setString(1, swapNull(catalog));
+		s.setString(2, swapNull(schemaPattern));
+		s.setString(3, swapNull(tableNamePattern));
+		//IMPORTANT
+		//Whenever a new table type is added to Derby, the sql for 
+		//getTables in metadata.properties will have to change and the 
+		//following if else will need to be modified too. 
+		//
+		//The getTables sql in metadata.properties has following clause 
+		//TABLETYPE IN (?, ?, ?, ?)
+		//There are 4?s for IN list because Derby supports 4 tables types 
+		//at the moment which are 'T','S','V' and 'A'.
+		//Anytime a new table type is added, an additional ? should be
+		//added to the above clause. In addition, the following code will 
+		//have to change too because it will need to set value for that 
+		//additional ?.
+		//
+		//Following explains the logic for table types handling.
+		//If the user has asked for specific table types in getTables,
+		//then the "if" statement below will use those types values
+		//for ?s. If there are still some ?s in the IN list that are left 
+		//with unassigned values, then we will set those ? to NULL.
+		//eg if getTables is called to only look for table types 'S' and 
+		//'A', then 'S' will be used for first ? in TABLETYPE IN (?, ?, ?, ?)
+		//'A' will be used for second ? in TABLETYPE IN (?, ?, ?, ?) and
+		//NULL will be used for third and fourth ?s in 
+		//TABLETYPE IN (?, ?, ?, ?)
+		//If the user hasn't asked for any specific table types, then the
+		//"else" statement below will kick in. When the control comes to 
+		//"else" statement, it means that the user wants to see all the
+		//table types supported by Derby. And hence, we simply set first
+		//? to 'T', second ? to 'S', third ? to 'V' and fourth ? to 'A'.
+		//When a new table type is added to Derby in future, we will have
+		//to do another setString for that in the "else" statement for that
+		//new table type.
+		if (types != null  &&  types.length >= 1) {
+			int i=0;
+			final int numberOfTableTypesInDerby = 4;
+			for (; i<types.length; i++){
+				/*
+				 * Let's assume for now that the table type first char 
+				 * corresponds to JBMS table type identifiers.
+				 * 
+				 * The reason I have i+4 is because there are already 3 ?s in
+				 * the getTables sql before the ?s in the IN clause. Hence
+				 * setString for table types should be done starting 4th 
+				 * parameter.
+				 */
+				s.setString(i+4, types[i].substring(0, 1));					
 			}
-			// Add the order by clause after the 'in' list.
-			whereClauseTail.append(
-				" ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME");
-
-			PreparedStatement s =
-				getEmbedConnection().prepareMetaDataStatement(whereClauseTail.toString());
-
-			s.setString(1, swapNull(catalog));
-			s.setString(2, swapNull(schemaPattern));
-			s.setString(3, swapNull(tableNamePattern));
-
-			rs = s.executeQuery();
-		    } catch (Throwable t) {
-				throw handleException(t);
-			} finally {
-			    restoreContextStack();
+			for (; i<numberOfTableTypesInDerby; i++) {
+				s.setNull(i+4, Types.CHAR);
 			}
-
-			return rs;
+		} else {
+			s.setString(4, "T");
+			s.setString(5, "S");
+			s.setString(6, "V");
+			s.setString(7, "A");				
 		}
+		return s.executeQuery();
 	}
 
     /**
@@ -3038,40 +3050,26 @@
     public ResultSet getUDTs(String catalog, String schemaPattern, 
 		      String typeNamePattern, int[] types)
       throws SQLException {
-      //we don't have support for catalog names
-      //we don't have java class types per schema, instead it's per database and hence
-      //we ignore schemapattern.
-      //the only type of user-named types we support are JAVA_OBJECT
-      synchronized (getConnectionSynchronization()) {
-      setupContextStack();
-      ResultSet rs = null;
-      int getClassTypes = 0;
-      try {
-        String queryText = getQueryDescriptions(false).getProperty("getUDTs");
-
-        if (types != null  &&  types.length >= 1) {
-          for (int i=0; i<types.length; i++){
-            if (types[i] == java.sql.Types.JAVA_OBJECT)
-              getClassTypes = 1;
-          }
-        } else
-          getClassTypes = 1;
-
-        PreparedStatement s =
-          getEmbedConnection().prepareMetaDataStatement(queryText);
-
-        s.setInt(1, java.sql.Types.JAVA_OBJECT);
-        s.setString(2, catalog);
-        s.setString(3, schemaPattern);
-        s.setString(4, swapNull(typeNamePattern));
-        s.setInt(5, getClassTypes);
-
-        rs = s.executeQuery();
-      } finally {
-        restoreContextStack();
-      }
-      return rs;
-    }
+        //we don't have support for catalog names
+        //we don't have java class types per schema, instead it's per database and hence
+        //we ignore schemapattern.
+        //the only type of user-named types we support are JAVA_OBJECT
+        int getClassTypes = 0;
+          if (types != null  &&  types.length >= 1) {
+            for (int i=0; i<types.length; i++){
+              if (types[i] == java.sql.Types.JAVA_OBJECT)
+                getClassTypes = 1;
+            }
+          } else
+            getClassTypes = 1;
+
+  		PreparedStatement s = getPreparedQuery("getUDTs");
+  		s.setInt(1, java.sql.Types.JAVA_OBJECT);
+  		s.setString(2, catalog);
+  		s.setString(3, schemaPattern);
+  		s.setString(4, swapNull(typeNamePattern));
+  		s.setInt(5, getClassTypes);
+        return s.executeQuery();
 	}
 
     /**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties?view=diff&rev=557334&r1=557333&r2=557334
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties Wed Jul 18 10:04:02 2007
@@ -109,15 +109,17 @@
 # parameter 1 = catalog name pattern 
 # parameter 2 = schema name pattern
 # parameter 3 = table name pattern (should have like comparison)
-# a list of table types is added to this query, in the form
-# table_type in ('val1','val2',...)
+# parameter 4,5,6,7 = a list of table types. In Derby 10.3, there
+# are 4 tables types, 'T','S','V','A' and hence only 4 parameters
+# are needed for table types. More information can be found in
+# EmbedDatabaseMetaDate.getTables
 #
 # IMPORTANT NOTE:
 # --------------
-# As a list of table_types to serach for is added to this query,
-# the ORDER BY clause below is also added as well, following the list:
-# ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME
-# Therefore, no need to mention it here.
+# DERBY-2896 
+# When we add a new table type in VALUES clause below, we should  
+# also add a ? in TABLETYPE IN clause. In addition, we should  
+# modify EmbedDatabaseMetaData.getTables to account for that new ? 
 #
 getTables=\
 	SELECT CAST ('' AS VARCHAR(128)) AS TABLE_CAT, \
@@ -139,12 +141,8 @@
 	  AND (SYS.SYSTABLES.SCHEMAID = SYS.SYSSCHEMAS.SCHEMAID) \
 	  AND ((1=1) OR ? IS NOT NULL) \
 	  AND (SYS.SYSSCHEMAS.SCHEMANAME LIKE ?) \
-	  AND (TABLENAME LIKE ?))
-#
-# ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME
-#
-# See 'IMPORTANT NOTE' above
-#
+	  AND (TABLENAME LIKE ?) AND TABLETYPE IN (?, ?, ?, ?)) \
+	  ORDER BY TABLE_TYPE, TABLE_SCHEM, TABLE_NAME
 
 # REMIND: this query is set up to return 0 rows of the right shape, since
 # there are no catalogs or metadata about them in our system yet.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java?view=diff&rev=557334&r1=557333&r2=557334
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java Wed Jul 18 10:04:02 2007
@@ -1043,8 +1043,8 @@
       TestSuite suite = new TestSuite("CollationTest:territory="+locale);
       suite.addTest(new CollationTest(baseFixture));
       
-      // DERBY-2986 - DMD.getTables() fails
-      // suite.addTest(DatabaseMetaDataTest.suite());
+      // DMD.getTables() should not fail after the fix to DERBY-2896
+      suite.addTest(DatabaseMetaDataTest.suite());
       return Decorator.territoryCollatedDatabase(suite, locale);
   }