1313/**
1414 * This class provides information about the database as a whole.
1515 *
16- * $Id: DatabaseMetaData.java,v 1.31 2001/09/06 12:53:15 momjian Exp $
16+ * $Id: DatabaseMetaData.java,v 1.32 2001/09/10 14:55:08 momjian Exp $
1717 *
1818 * <p>Many of the methods here return lists of information in ResultSets. You
1919 * can use the normal ResultSet methods such as getString and getInt to
@@ -1895,19 +1895,21 @@ public java.sql.ResultSet getTableTypes() throws SQLException
18951895 */
18961896 public java .sql .ResultSet getColumns (String catalog , String schemaPattern , String tableNamePattern , String columnNamePattern ) throws SQLException
18971897 {
1898+ // the field descriptors for the new ResultSet
1899+ Field f [] = new Field [18 ];
1900+ java .sql .ResultSet r ; // ResultSet for the SQL query that we need to do
18981901 Vector v = new Vector (); // The new ResultSet tuple stuff
1899- Field f [] = new Field [18 ]; // The field descriptors for the new ResultSet
1900-
1901- f [ 0 ] = new Field (connection , "TABLE_CAT" , iVarcharOid , 32 );
1902- f [ 1 ] = new Field (connection , "TABLE_SCHEM" , iVarcharOid , 32 );
1903- f [ 2 ] = new Field (connection , "TABLE_NAME" , iVarcharOid , 32 );
1904- f [ 3 ] = new Field (connection , "COLUMN_NAME" , iVarcharOid , 32 );
1905- f [ 4 ] = new Field (connection , "DATA_TYPE" , iInt2Oid , 2 );
1906- f [ 5 ] = new Field (connection , "TYPE_NAME" , iVarcharOid , 32 );
1907- f [ 6 ] = new Field (connection , "COLUMN_SIZE" , iInt4Oid , 4 );
1908- f [ 7 ] = new Field (connection , "BUFFER_LENGTH" , iVarcharOid , 32 );
1909- f [ 8 ] = new Field (connection , "DECIMAL_DIGITS" , iInt4Oid , 4 );
1910- f [ 9 ] = new Field (connection , "NUM_PREC_RADIX" , iInt4Oid , 4 );
1902+
1903+ f [0 ] = new Field (connection , "TABLE_CAT" , iVarcharOid , 32 );
1904+ f [1 ] = new Field (connection , "TABLE_SCHEM" , iVarcharOid , 32 );
1905+ f [2 ] = new Field (connection , "TABLE_NAME" , iVarcharOid , 32 );
1906+ f [3 ] = new Field (connection , "COLUMN_NAME" , iVarcharOid , 32 );
1907+ f [4 ] = new Field (connection , "DATA_TYPE" , iInt2Oid , 2 );
1908+ f [5 ] = new Field (connection , "TYPE_NAME" , iVarcharOid , 32 );
1909+ f [6 ] = new Field (connection , "COLUMN_SIZE" , iInt4Oid , 4 );
1910+ f [7 ] = new Field (connection , "BUFFER_LENGTH" , iVarcharOid , 32 );
1911+ f [8 ] = new Field (connection , "DECIMAL_DIGITS" , iInt4Oid , 4 );
1912+ f [9 ] = new Field (connection , "NUM_PREC_RADIX" , iInt4Oid , 4 );
19111913 f [10 ] = new Field (connection , "NULLABLE" , iInt4Oid , 4 );
19121914 f [11 ] = new Field (connection , "REMARKS" , iVarcharOid , 32 );
19131915 f [12 ] = new Field (connection , "COLUMN_DEF" , iVarcharOid , 32 );
@@ -1917,105 +1919,93 @@ public java.sql.ResultSet getColumns(String catalog, String schemaPattern, Strin
19171919 f [16 ] = new Field (connection , "ORDINAL_POSITION" , iInt4Oid ,4 );
19181920 f [17 ] = new Field (connection , "IS_NULLABLE" , iVarcharOid , 32 );
19191921
1920- StringBuffer sql = new StringBuffer (512 );
1921-
1922- sql .append ("select " +
1923- (connection .haveMinimumServerVersion ("7.2" ) ? "a.attrelid, " : "a.oid, " ) +
1924- " c.relname, " +
1925- " a.attname, " +
1926- " a.atttypid, " +
1927- " a.attnum, " +
1928- " a.attnotnull, " +
1929- " a.attlen, " +
1930- " a.atttypmod, " +
1931- " d.adsrc, " +
1932- " t.typname, " +
1933- " e.description " +
1934- "from" +
1935- " (" +
1936- " (pg_class c inner join pg_attribute a on" +
1937- " (" +
1938- " a.attrelid=c.oid" );
1939-
1940- if ((tableNamePattern != null ) && ! tableNamePattern .equals ("%" )) {
1941- sql .append (" and c.relname like \' " + tableNamePattern + "\' " );
1942- }
1922+ // Added by Stefan Andreasen <stefan@linux.kapow.dk>
1923+ // If the pattern are null then set them to %
1924+ if (tableNamePattern == null ) tableNamePattern ="%" ;
1925+ if (columnNamePattern == null ) columnNamePattern ="%" ;
19431926
1944- if ((columnNamePattern != null ) && ! columnNamePattern .equals ("%" )) {
1945- sql .append (" and a.attname like \' " + columnNamePattern + "\' " );
1946- }
1927+ // Now form the query
1928+ String query =
1929+ "select " +
1930+ (connection .haveMinimumServerVersion ("7.2" ) ? "a.attrelid" : "a.oid" ) +
1931+ ",c.relname,a.attname,a.atttypid," +
1932+ "a.attnum,a.attnotnull,a.attlen,a.atttypmod,d.adsrc " +
1933+ "from (pg_class c inner join pg_attribute a " +
1934+ "on (c.oid=a.attrelid) ) " +
1935+ "left outer join pg_attrdef d " +
1936+ "on (c.oid=d.adrelid and d.adnum=a.attnum) " +
1937+ "where " +
1938+ "c.relname like '" +tableNamePattern .toLowerCase ()+"' and " +
1939+ "a.attname like '" +columnNamePattern .toLowerCase ()+"' and " +
1940+ "a.attnum>0 " +
1941+ "order by c.relname,a.attnum" ;
1942+
1943+ r = connection .ExecSQL (query );
19471944
1948- sql .append (
1949- " and a.attnum > 0" +
1950- " )" +
1951- " ) inner join pg_type t on" +
1952- " (" +
1953- " t.oid = a.atttypid" +
1954- " )" +
1955- " )" +
1956- " left outer join pg_attrdef d on" +
1957- " (" +
1958- " c.oid = d.adrelid" +
1959- " and a.attnum = d.adnum" +
1960- " )" +
1961- " left outer join pg_description e on" +
1962- " (" +
1963- " e.objoid = a.attrelid" );
1964-
1965- if (connection .haveMinimumServerVersion ("7.2" )) {
1966- sql .append (
1967- " and e.objsubid = a.attnum" +
1968- " and e.classoid = (select oid from pg_class where relname = \' pg_class\' )" );
1969- }
1945+ while (r .next ()) {
1946+ byte [][] tuple = new byte [18 ][0 ];
19701947
1971- sql .append (
1972- " ) " +
1973- "order by" +
1974- " c.relname, a.attnum" );
1975-
1976- java .sql .ResultSet r = connection .ExecSQL (sql .toString ());
1977- while (r .next ()) {
1978- byte [][] tuple = new byte [18 ][0 ];
1979-
1980- String nullFlag = r .getString (6 );
1981- String typname = r .getString (10 );
1982-
1983- tuple [0 ] = "" .getBytes (); // Catalog name
1984- tuple [1 ] = "" .getBytes (); // Schema name
1985- tuple [2 ] = r .getBytes (2 ); // Table name
1986- tuple [3 ] = r .getBytes (3 ); // Column name
1987- tuple [4 ] = Integer .toString (connection .getSQLType (typname )).getBytes (); // Data type
1988- tuple [5 ] = typname .getBytes (); // Type name
1989-
1990- // Column size
1991- // Looking at the psql source,
1992- // I think the length of a varchar as specified when the table was created
1993- // should be extracted from atttypmod which contains this length + sizeof(int32)
1994- if (typname .equals ("bpchar" ) || typname .equals ("varchar" )) {
1995- int atttypmod = r .getInt (8 );
1996- tuple [6 ] = Integer .toString (atttypmod != -1 ? atttypmod - VARHDRSZ : 0 ).getBytes ();
1997- } else {
1998- tuple [6 ] = r .getBytes (7 );
1999- }
2000-
2001- tuple [7 ] = null ; // Buffer length
2002- tuple [8 ] = "0" .getBytes (); // Decimal Digits - how to get this?
2003- tuple [9 ] = "10" .getBytes (); // Num Prec Radix - assume decimal
2004- tuple [10 ] = Integer .toString (nullFlag .equals ("f" ) ?
2005- java .sql .DatabaseMetaData .columnNullable :
2006- java .sql .DatabaseMetaData .columnNoNulls ).getBytes (); // Nullable
2007- tuple [11 ] = r .getBytes (11 ); // Description (if any)
2008- tuple [12 ] = r .getBytes (9 ); // Column default
2009- tuple [13 ] = null ; // sql data type (unused)
2010- tuple [14 ] = null ; // sql datetime sub (unused)
2011- tuple [15 ] = tuple [6 ]; // char octet length
2012- tuple [16 ] = r .getBytes (5 ); // ordinal position
2013- tuple [17 ] = (nullFlag .equals ("f" ) ? "YES" : "NO" ).getBytes (); // Is nullable
2014-
2015- v .addElement (tuple );
2016- }
2017- r .close ();
1948+ // Fetch the description for the table (if any)
1949+ String getDescriptionStatement =
1950+ connection .haveMinimumServerVersion ("7.2" ) ?
1951+ "select col_description(" + r .getInt (1 ) + "," + r .getInt (5 ) + ")" :
1952+ "select description from pg_description where objoid=" + r .getInt (1 );
1953+
1954+ java .sql .ResultSet dr = connection .ExecSQL (getDescriptionStatement );
20181955
1956+ if (((org .postgresql .ResultSet )dr ).getTupleCount ()==1 ) {
1957+ dr .next ();
1958+ tuple [11 ] = dr .getBytes (1 );
1959+ } else
1960+ tuple [11 ] = null ;
1961+ dr .close ();
1962+
1963+ tuple [0 ] = "" .getBytes (); // Catalog name
1964+ tuple [1 ] = "" .getBytes (); // Schema name
1965+ tuple [2 ] = r .getBytes (2 ); // Table name
1966+ tuple [3 ] = r .getBytes (3 ); // Column name
1967+
1968+ dr = connection .ExecSQL ("select typname from pg_type where oid = " +r .getString (4 ));
1969+ dr .next ();
1970+ String typname =dr .getString (1 );
1971+ dr .close ();
1972+ tuple [4 ] = Integer .toString (connection .getSQLType (typname )).getBytes (); // Data type
1973+ tuple [5 ] = typname .getBytes (); // Type name
1974+
1975+ // Column size
1976+ // Looking at the psql source,
1977+ // I think the length of a varchar as specified when the table was created
1978+ // should be extracted from atttypmod which contains this length + sizeof(int32)
1979+ if (typname .equals ("bpchar" ) || typname .equals ("varchar" )) {
1980+ int atttypmod = r .getInt (8 );
1981+ tuple [6 ] = Integer .toString (atttypmod != -1 ? atttypmod - VARHDRSZ : 0 ).getBytes ();
1982+ } else
1983+ tuple [6 ] = r .getBytes (7 );
1984+
1985+ tuple [7 ] = null ; // Buffer length
1986+
1987+ tuple [8 ] = "0" .getBytes (); // Decimal Digits - how to get this?
1988+ tuple [9 ] = "10" .getBytes (); // Num Prec Radix - assume decimal
1989+
1990+ // tuple[10] is below
1991+ // tuple[11] is above
1992+
1993+ tuple [12 ] = r .getBytes (9 ); // column default
1994+
1995+ tuple [13 ] = null ; // sql data type (unused)
1996+ tuple [14 ] = null ; // sql datetime sub (unused)
1997+
1998+ tuple [15 ] = tuple [6 ]; // char octet length
1999+
2000+ tuple [16 ] = r .getBytes (5 ); // ordinal position
2001+
2002+ String nullFlag = r .getString (6 );
2003+ tuple [10 ] = Integer .toString (nullFlag .equals ("f" )?java .sql .DatabaseMetaData .columnNullable :java .sql .DatabaseMetaData .columnNoNulls ).getBytes (); // Nullable
2004+ tuple [17 ] = (nullFlag .equals ("f" )?"YES" :"NO" ).getBytes (); // is nullable
2005+
2006+ v .addElement (tuple );
2007+ }
2008+ r .close ();
20192009 return new ResultSet (connection , f , v , "OK" , 1 );
20202010 }
20212011
0 commit comments