Re: JDBC Driver - Schema Awareness - Mailing list pgsql-patches

From Kris Jurka
Subject Re: JDBC Driver - Schema Awareness
Date
Msg-id 3D8AAFF2.B20D088@ejurka.com
Whole thread Raw
In response to JDBC Driver - Schema Awareness  (Kris Jurka <jurka@ejurka.com>)
List pgsql-patches
Barry Lind wrote:
>
> Kris,
>
> This all looks great.  However I did notice that you didn't include
> changes for LargeObjectManager.java and Serialize.java.  Both of these
> classes issue selects against pg_ tables and thus should be made schema
> aware.  Is that something you can include?   If not I can do it.
>
> thanks,
> --Barry

The following patch adds schema awareness to the LargeObjectManager and
parts of Serialize.  The API for Serialize has no notion of schemas and
did not change that.  It also adds some missing escape characters on
LIKE clauses missing from the original patch.  This patch does not
supercede the original, but adds to it.  Two new files have been added
to implement a Serialize regression test.


Kris JurkaOnly in src/interfaces/jdbc/norg/postgresql/fastpath: .Fastpath.java.swp
Only in src/interfaces/jdbc/norg/postgresql/jdbc1: .AbstractJdbc1DatabaseMetaData.java.swp
diff -r -c src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java
src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java
*** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java    Thu Sep 19 15:13:06 2002
--- src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java    Thu Sep 19 16:08:54 2002
***************
*** 1962,1968 ****
          if (connection.haveMinimumServerVersion("7.3")) {
              useSchemas = "SCHEMAS";
              select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+
!             " CASE n.nspname LIKE 'pg\\_%' "+
              " WHEN true THEN CASE n.nspname "+
              "    WHEN 'pg_catalog' THEN CASE c.relkind "+
              "        WHEN 'r' THEN 'SYSTEM TABLE' "+
--- 1962,1968 ----
          if (connection.haveMinimumServerVersion("7.3")) {
              useSchemas = "SCHEMAS";
              select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+
!             " CASE n.nspname LIKE 'pg\\\\_%' "+
              " WHEN true THEN CASE n.nspname "+
              "    WHEN 'pg_catalog' THEN CASE c.relkind "+
              "        WHEN 'r' THEN 'SYSTEM TABLE' "+
***************
*** 2006,2019 ****
          } else {
              useSchemas = "NOSCHEMAS";
              String tableType =  ""+
!             " CASE c.relname LIKE 'pg\\_%' "+
!             " WHEN true THEN CASE c.relname LIKE 'pg\\_toast\\_%' "+
              "    WHEN true THEN CASE c.relkind "+
              "        WHEN 'r' THEN 'SYSTEM TOAST TABLE' "+
              "        WHEN 'i' THEN 'SYSTEM TOAST INDEX' "+
              "        ELSE NULL "+
              "        END "+
!             "    WHEN false THEN CASE c.relname LIKE 'pg\\_temp\\_%' "+
              "        WHEN true THEN CASE c.relkind "+
              "            WHEN 'r' THEN 'TEMPORARY TABLE' "+
              "            WHEN 'i' THEN 'TEMPORARY INDEX' "+
--- 2006,2019 ----
          } else {
              useSchemas = "NOSCHEMAS";
              String tableType =  ""+
!             " CASE c.relname LIKE 'pg\\\\_%' "+
!             " WHEN true THEN CASE c.relname LIKE 'pg\\\\_toast\\\\_%' "+
              "    WHEN true THEN CASE c.relkind "+
              "        WHEN 'r' THEN 'SYSTEM TOAST TABLE' "+
              "        WHEN 'i' THEN 'SYSTEM TOAST INDEX' "+
              "        ELSE NULL "+
              "        END "+
!             "    WHEN false THEN CASE c.relname LIKE 'pg\\\\_temp\\\\_%' "+
              "        WHEN true THEN CASE c.relkind "+
              "            WHEN 'r' THEN 'TEMPORARY TABLE' "+
              "            WHEN 'i' THEN 'TEMPORARY INDEX' "+
***************
*** 2075,2090 ****
          tableTypeClauses = new Hashtable();
          Hashtable ht = new Hashtable();
          tableTypeClauses.put("TABLE",ht);
!         ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname NOT LIKE 'pg\\_%'");
!         ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname NOT LIKE 'pg\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("VIEW",ht);
          ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname <> 'pg_catalog'");
!         ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname NOT LIKE 'pg\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("INDEX",ht);
!         ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname NOT LIKE 'pg\\_%'");
!         ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname NOT LIKE 'pg\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SEQUENCE",ht);
          ht.put("SCHEMAS","c.relkind = 'S'");
--- 2075,2090 ----
          tableTypeClauses = new Hashtable();
          Hashtable ht = new Hashtable();
          tableTypeClauses.put("TABLE",ht);
!         ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname NOT LIKE 'pg\\\\_%'");
!         ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname NOT LIKE 'pg\\\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("VIEW",ht);
          ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname <> 'pg_catalog'");
!         ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname NOT LIKE 'pg\\\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("INDEX",ht);
!         ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname NOT LIKE 'pg\\\\_%'");
!         ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname NOT LIKE 'pg\\\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SEQUENCE",ht);
          ht.put("SCHEMAS","c.relkind = 'S'");
***************
*** 2092,2122 ****
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM TABLE",ht);
          ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_catalog'");
!         ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\_%' AND c.relname NOT LIKE 'pg\\_toast\\_%' AND
c.relnameNOT LIKE 'pg\\_temp\\_%'"); 
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM TOAST TABLE",ht);
          ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_toast'");
!         ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\_toast\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM TOAST INDEX",ht);
          ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_toast'");
!         ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\_toast\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM VIEW",ht);
          ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname = 'pg_catalog' ");
!         ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM INDEX",ht);
          ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_catalog'");
!         ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\_%' AND c.relname NOT LIKE 'pg\\_toast\\_%' AND
c.relnameNOT LIKE 'pg\\_temp\\_%'"); 
          ht = new Hashtable();
          tableTypeClauses.put("TEMPORARY TABLE",ht);
!         ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname LIKE 'pg\\_temp\\_%' ");
!         ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname LIKE 'pg\\_temp\\_%' ");
          ht = new Hashtable();
          tableTypeClauses.put("TEMPORARY INDEX",ht);
!         ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname LIKE 'pg\\_temp\\_%' ");
!         ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\_temp\\_%' ");
      }

      // These are the default tables, used when NULL is passed to getTables
--- 2092,2122 ----
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM TABLE",ht);
          ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_catalog'");
!         ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\\\_%' AND c.relname NOT LIKE 'pg\\\\_toast\\\\_%'
ANDc.relname NOT LIKE 'pg\\\\_temp\\\\_%'"); 
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM TOAST TABLE",ht);
          ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_toast'");
!         ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\\\_toast\\\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM TOAST INDEX",ht);
          ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_toast'");
!         ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\\\_toast\\\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM VIEW",ht);
          ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname = 'pg_catalog' ");
!         ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\\\_%'");
          ht = new Hashtable();
          tableTypeClauses.put("SYSTEM INDEX",ht);
          ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_catalog'");
!         ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\\\_%' AND c.relname NOT LIKE 'pg\\\\_toast\\\\_%'
ANDc.relname NOT LIKE 'pg\\\\_temp\\\\_%'"); 
          ht = new Hashtable();
          tableTypeClauses.put("TEMPORARY TABLE",ht);
!         ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname LIKE 'pg\\\\_temp\\\\_%' ");
!         ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname LIKE 'pg\\\\_temp\\\\_%' ");
          ht = new Hashtable();
          tableTypeClauses.put("TEMPORARY INDEX",ht);
!         ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname LIKE 'pg\\\\_temp\\\\_%' ");
!         ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\\\_temp\\\\_%' ");
      }

      // These are the default tables, used when NULL is passed to getTables
***************
*** 2141,2147 ****
      {
          String sql;
          if (connection.haveMinimumServerVersion("7.3")) {
!             sql = "SELECT nspname AS TABLE_SCHEM FROM pg_catalog.pg_namespace WHERE nspname <> 'pg_toast' AND nspname
NOTLIKE 'pg\\_temp\\_%' ORDER BY TABLE_SCHEM"; 
          } else {
              sql = "SELECT ''::text AS TABLE_SCHEM ORDER BY TABLE_SCHEM";
          }
--- 2141,2147 ----
      {
          String sql;
          if (connection.haveMinimumServerVersion("7.3")) {
!             sql = "SELECT nspname AS TABLE_SCHEM FROM pg_catalog.pg_namespace WHERE nspname <> 'pg_toast' AND nspname
NOTLIKE 'pg\\\\_temp\\\\_%' ORDER BY TABLE_SCHEM"; 
          } else {
              sql = "SELECT ''::text AS TABLE_SCHEM ORDER BY TABLE_SCHEM";
          }
***************
*** 3031,3037 ****
              + "AND t.tgisconstraint "
              + "AND t.tgconstrrelid=c2.oid "
              + "AND t.tgfoid=p1.oid "
!             + "and p1.proname like 'RI\\_FKey\\_%\\_upd') "

              + "and "
              // isolate the delete rule
--- 3031,3037 ----
              + "AND t.tgisconstraint "
              + "AND t.tgconstrrelid=c2.oid "
              + "AND t.tgfoid=p1.oid "
!             + "and p1.proname like 'RI\\\\_FKey\\\\_%\\\\_upd') "

              + "and "
              // isolate the delete rule
***************
*** 3039,3045 ****
              + "and t1.tgisconstraint "
              + "and t1.tgconstrrelid=c2.oid "
              + "AND t1.tgfoid=p2.oid "
!             + "and p2.proname like 'RI\\_FKey\\_%\\_del') "
              + "AND i.indrelid=c.oid "
              + "AND i.indexrelid=ic.oid "
              + "AND ic.oid=a.attrelid "
--- 3039,3045 ----
              + "and t1.tgisconstraint "
              + "and t1.tgconstrrelid=c2.oid "
              + "AND t1.tgfoid=p2.oid "
!             + "and p2.proname like 'RI\\\\_FKey\\\\_%\\\\_del') "
              + "AND i.indrelid=c.oid "
              + "AND i.indexrelid=ic.oid "
              + "AND ic.oid=a.attrelid "
Only in src/interfaces/jdbc/norg/postgresql/jdbc1: AbstractJdbc1DatabaseMetaData.java~
diff -r -c src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1Statement.java
*** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java    Fri Sep 13 20:52:56 2002
--- src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1Statement.java    Thu Sep 19 12:03:02 2002
***************
*** 1757,1764 ****
       */
      private void setSerialize(int parameterIndex, long x, String classname) throws SQLException
      {
!         // converts . to _, toLowerCase, and ensures length<32
!         String tablename = Serialize.toPostgreSQL( classname );
          DriverManager.println("setSerialize: setting " + x + "::" + tablename );

          // OID reference to tablerow-type must be cast like:  <oid>::<tablename>
--- 1757,1764 ----
       */
      private void setSerialize(int parameterIndex, long x, String classname) throws SQLException
      {
!         // converts . to _, toLowerCase, and ensures length < max name length
!         String tablename = Serialize.toPostgreSQL((java.sql.Connection)connection, classname );
          DriverManager.println("setSerialize: setting " + x + "::" + tablename );

          // OID reference to tablerow-type must be cast like:  <oid>::<tablename>
diff -r -c src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
src/interfaces/jdbc/norg/postgresql/largeobject/LargeObjectManager.java
*** src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java    Fri Sep  6 14:23:06 2002
--- src/interfaces/jdbc/norg/postgresql/largeobject/LargeObjectManager.java    Thu Sep 19 11:58:04 2002
***************
*** 103,117 ****
          //
          // This is an example of Fastpath.addFunctions();
          //
!         ResultSet res = conn.createStatement().executeQuery("select proname, oid from pg_proc" +
!                         " where proname = 'lo_open'" +
!                         "    or proname = 'lo_close'" +
!                         "    or proname = 'lo_creat'" +
!                         "    or proname = 'lo_unlink'" +
!                         "    or proname = 'lo_lseek'" +
!                         "    or proname = 'lo_tell'" +
!                         "    or proname = 'loread'" +
!                         "    or proname = 'lowrite'");

          if (res == null)
              throw new PSQLException("postgresql.lo.init");
--- 103,126 ----
          //
          // This is an example of Fastpath.addFunctions();
          //
!         String sql;
!         if (conn.getMetaData().supportsSchemasInTableDefinitions()) {
!             sql = "SELECT p.proname,p.oid "+
!                 " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "+
!                 " WHERE p.pronamespace=n.oid AND n.nspname='pg_catalog' AND ";
!         } else {
!             sql = "SELECT proname,oid FROM pg_proc WHERE ";
!         }
!         sql += " proname = 'lo_open'" +
!             " or proname = 'lo_close'" +
!             " or proname = 'lo_creat'" +
!             " or proname = 'lo_unlink'" +
!             " or proname = 'lo_lseek'" +
!             " or proname = 'lo_tell'" +
!             " or proname = 'loread'" +
!             " or proname = 'lowrite'";
!
!         ResultSet res = conn.createStatement().executeQuery(sql);

          if (res == null)
              throw new PSQLException("postgresql.lo.init");
Only in src/interfaces/jdbc/norg/postgresql/largeobject: LargeObjectManager.java~
diff -r -c src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
src/interfaces/jdbc/norg/postgresql/test/jdbc2/Jdbc2TestSuite.java
*** src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java    Thu Sep 19 15:13:06 2002
--- src/interfaces/jdbc/norg/postgresql/test/jdbc2/Jdbc2TestSuite.java    Thu Sep 19 13:23:22 2002
***************
*** 48,60 ****

          // PreparedStatement

!         // ServerSide Prepared Statements
!         suite.addTestSuite(ServerPreparedStmtTest.class);

          // BatchExecute
          suite.addTestSuite(BatchExecuteTest.class);

-         // MetaData

          // Other misc tests, based on previous problems users have had or specific
          // features some applications require.
--- 48,59 ----

          // PreparedStatement

!         // ServerSide Prepared Statements
!         suite.addTestSuite(ServerPreparedStmtTest.class);

          // BatchExecute
          suite.addTestSuite(BatchExecuteTest.class);


          // Other misc tests, based on previous problems users have had or specific
          // features some applications require.
***************
*** 63,68 ****
--- 62,69 ----

          // Fastpath/LargeObject
          suite.addTestSuite(BlobTest.class);
+
+         suite.addTestSuite(SerializeTest.class);
          suite.addTestSuite(UpdateableResultTest.class );

          suite.addTestSuite(CallableStmtTest.class );
Only in src/interfaces/jdbc/norg/postgresql/test/jdbc2: SerializeObject.java
Only in src/interfaces/jdbc/norg/postgresql/test/jdbc2: SerializeTest.java
Only in src/interfaces/jdbc/norg/postgresql/util: .Serialize.java.swp
diff -r -c src/interfaces/jdbc/org/postgresql/util/Serialize.java
src/interfaces/jdbc/norg/postgresql/util/Serialize.java
*** src/interfaces/jdbc/org/postgresql/util/Serialize.java    Fri Sep  6 14:23:06 2002
--- src/interfaces/jdbc/norg/postgresql/util/Serialize.java    Thu Sep 19 13:31:30 2002
***************
*** 124,137 ****
       * This creates an instance that can be used to serialize or deserialize
       * a Java object from a PostgreSQL table.
       */
!     public Serialize(Connection c, String type) throws SQLException
      {
          try
          {
!             conn = c;
              if (Driver.logDebug)
                  Driver.debug("Serialize: initializing instance for type: " + type);
!             tableName = toPostgreSQL(type);
              className = type;
              ourClass = Class.forName(className);
          }
--- 124,137 ----
       * This creates an instance that can be used to serialize or deserialize
       * a Java object from a PostgreSQL table.
       */
!     public Serialize(Connection conn, String type) throws SQLException
      {
          try
          {
!             this.conn = conn;
              if (Driver.logDebug)
                  Driver.debug("Serialize: initializing instance for type: " + type);
!             tableName = toPostgreSQL(conn,type);
              className = type;
              ourClass = Class.forName(className);
          }
***************
*** 144,150 ****

          // Second check, the type must be a table
          boolean status = false;
!         ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL("select typname from
pg_type,pg_classwhere typname=relname and typname='" + tableName + "'"); 
          if (rs != null)
          {
              if (rs.next())
--- 144,157 ----

          // Second check, the type must be a table
          boolean status = false;
!         String sql;
!         if (conn.getMetaData().supportsSchemasInTableDefinitions()) {
!             sql = "SELECT 1 FROM pg_catalog.pg_type t, pg_catalog.pg_class c WHERE t.typrelid=c.oid AND c.relkind='r'
ANDt.typname='" + tableName + "' AND pg_table_is_visible(c.oid) "; 
!         } else {
!             sql = "SELECT 1 FROM pg_type t, pg_class c WHERE t.typrelid=c.oid AND c.relkind='r' AND
t.typname='"+tableName+"'";
!         }
!
!         ResultSet rs = conn.createStatement().executeQuery(sql);
          if (rs != null)
          {
              if (rs.next())
***************
*** 187,193 ****
       * @return Object relating to oid
       * @exception SQLException on error
       */
!     public Object fetch(int oid) throws SQLException
      {
          try
          {
--- 194,200 ----
       * @return Object relating to oid
       * @exception SQLException on error
       */
!     public Object fetch(long oid) throws SQLException
      {
          try
          {
***************
*** 228,234 ****

              if (Driver.logDebug)
                  Driver.debug("Serialize.fetch: " + sb.toString());
!             ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL(sb.toString());

              if (rs != null)
              {
--- 235,241 ----

              if (Driver.logDebug)
                  Driver.debug("Serialize.fetch: " + sb.toString());
!             ResultSet rs = conn.createStatement().executeQuery(sb.toString());

              if (rs != null)
              {
***************
*** 493,507 ****
       * @param o Class to base table on
       * @exception SQLException on error
       */
!     public static void create(Connection con, Class c) throws SQLException
      {
          if (c.isInterface())
              throw new PSQLException("postgresql.serial.interface");

          // See if the table exists
!         String tableName = toPostgreSQL(c.getName());

!         ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL("select relname from pg_class
whererelname = '" + tableName + "'"); 
          if ( rs.next() )
          {
              if (Driver.logDebug)
--- 500,521 ----
       * @param o Class to base table on
       * @exception SQLException on error
       */
!     public static void create(Connection conn, Class c) throws SQLException
      {
          if (c.isInterface())
              throw new PSQLException("postgresql.serial.interface");

          // See if the table exists
!         String tableName = toPostgreSQL(conn,c.getName());

!         String sql;
!         if (conn.getMetaData().supportsSchemasInTableDefinitions()) {
!             sql = "SELECT 1 FROM pg_catalog.pg_class WHERE relkind='r' AND relname='" + tableName + "' AND
pg_table_is_visible(oid)"; 
!         } else {
!             sql = "SELECT 1 FROM pg_class WHERE relkind='r' AND relname='"+tableName+"'";
!         }
!
!         ResultSet rs = conn.createStatement().executeQuery(sql);
          if ( rs.next() )
          {
              if (Driver.logDebug)
***************
*** 549,556 ****
                          sb.append(tp[j][1]);
                      else
                      {
!                         create(con, type);
!                         sb.append(toPostgreSQL(n));
                      }
                  }
              }
--- 563,570 ----
                          sb.append(tp[j][1]);
                      else
                      {
!                         create(conn, type);
!                         sb.append(toPostgreSQL(conn,n));
                      }
                  }
              }
***************
*** 560,566 ****
          // Now create the table
          if (Driver.logDebug)
              Driver.debug("Serialize.create: " + sb );
!         ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL(sb.toString());
      }

      // This is used to translate between Java primitives and PostgreSQL types.
--- 574,580 ----
          // Now create the table
          if (Driver.logDebug)
              Driver.debug("Serialize.create: " + sb );
!         conn.createStatement().executeUpdate(sb.toString());
      }

      // This is used to translate between Java primitives and PostgreSQL types.
***************
*** 582,616 ****
                                               {"byte", "int2"}
                                           };

!     /*
       * This converts a Java Class name to a org.postgresql table, by replacing . with
       * _<p>
       *
       * Because of this, a Class name may not have _ in the name.<p>
       * Another limitation, is that the entire class name (including packages)
!      * cannot be longer than 64 characters (a limit forced by PostgreSQL).
       *
       * @param name Class name
       * @return PostgreSQL table name
       * @exception SQLException on error
       */
!     public static String toPostgreSQL(String name) throws SQLException
      {
          name = name.toLowerCase();

          if (name.indexOf("_") > -1)
              throw new PSQLException("postgresql.serial.underscore");

!         // Postgres table names can only be 64 character long.
!         // Reserve 1 char, so allow only up to 63 chars.
          // If the full class name with package is too long
          // then just use the class name. If the class name is
          // too long throw an exception.
          //
!         if ( name.length() > 63 )
          {
              name = name.substring(name.lastIndexOf(".") + 1);
!             if ( name.length() > 63 )
                  throw new PSQLException("postgresql.serial.namelength", name, new Integer(name.length()));
          }
          return name.replace('.', '_');
--- 596,648 ----
                                               {"byte", "int2"}
                                           };

!     /**
       * This converts a Java Class name to a org.postgresql table, by replacing . with
       * _<p>
       *
       * Because of this, a Class name may not have _ in the name.<p>
       * Another limitation, is that the entire class name (including packages)
!      * cannot be longer than the maximum table name length.
       *
+      * @param con The database connection
       * @param name Class name
       * @return PostgreSQL table name
       * @exception SQLException on error
+      * @since 7.3
       */
!     public static String toPostgreSQL(Connection con, String name) throws SQLException
      {
+         DatabaseMetaData dbmd = con.getMetaData();
+         int maxNameLength = dbmd.getMaxTableNameLength();
+         return toPostgreSQL(maxNameLength,name);
+     }
+
+     /**
+      * Convert a Java Class Name to an org.postgresql table name, by replacing .
+      * with _ <p>
+      *
+      * @deprecated Replaced by toPostgresql(connection, name) in 7.3
+      */
+     public static String toPostgreSQL(String name) throws SQLException {
+         return toPostgreSQL(31,name);
+     }
+
+     private static String toPostgreSQL(int maxNameLength, String name) throws SQLException {
+
          name = name.toLowerCase();

          if (name.indexOf("_") > -1)
              throw new PSQLException("postgresql.serial.underscore");

!         // Postgres table names can only be so many characters long.
          // If the full class name with package is too long
          // then just use the class name. If the class name is
          // too long throw an exception.
          //
!         if ( name.length() > maxNameLength )
          {
              name = name.substring(name.lastIndexOf(".") + 1);
!             if ( name.length() > maxNameLength )
                  throw new PSQLException("postgresql.serial.namelength", name, new Integer(name.length()));
          }
          return name.replace('.', '_');
Only in src/interfaces/jdbc/norg/postgresql/util: Serialize.java~
package org.postgresql.test.jdbc2;

import org.postgresql.test.TestUtil;
import junit.framework.TestCase;
import java.sql.*;
import org.postgresql.util.Serialize;

public class SerializeTest extends TestCase {

    private Connection conn;
    private SerializeObject serobj;
    private Serialize ser;

    public SerializeTest(String name) {
        super(name);
    }

    protected void setUp() throws Exception {
        conn = TestUtil.openDB();
        serobj = new SerializeObject();
        serobj.intcol = 1;
        serobj.doublecol = 3.4;
        serobj.stringcol = "Hello";
        TestUtil.dropTable(conn,Serialize.toPostgreSQL(conn,serobj.getClass().getName()));
        Serialize.create(conn, serobj);
        Serialize.create(conn, serobj);
        ser = new Serialize(conn,serobj);
    }

    protected void tearDown() throws Exception {
        TestUtil.dropTable(conn,Serialize.toPostgreSQL(conn,serobj.getClass().getName()));
    }

    public void testCreateSerialize() {
        try {
            long oid = ser.storeObject(serobj);
            SerializeObject serobj2 = (SerializeObject)ser.fetch(oid);
            assertNotNull(serobj2);
            assertEquals(serobj.intcol,serobj2.intcol);
            assertTrue(Math.abs(serobj.doublecol-serobj2.doublecol) < 0.0001);
            assertTrue(serobj.stringcol.equals(serobj2.stringcol));
        } catch (SQLException sqle) {
            fail(sqle.getMessage());
        }
    }

}
package org.postgresql.test.jdbc2;

import java.io.Serializable;

public class SerializeObject implements Serializable {

    public int intcol;
    public double doublecol;
    public String stringcol;

}

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: to_char(FM9.9) bug fix
Next
From: "Nigel J. Andrews"
Date:
Subject: Re: [HACKERS] [GENERAL] Memory Errors...