* pattern @param tableNamePattern a table name pattern. For all tables this
	 * should be "%" @param types a list of table types to include; null returns
	 * all types @return each row is a table description @exception SQLException
	 * if a database-access error occurs.
	 */
	public java.sql.ResultSet getTables(String catalog, String schemaPattern,
		String tableNamePattern, String types[]) throws SQLException
	{
		String useSchemas = "SCHEMAS";
		String select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, "
				+ " CASE n.nspname LIKE 'pg!_%' ESCAPE '!' OR n.nspname = 'information_schema' "
				+ " WHEN true THEN CASE "
				+ " WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind "
				+ "  WHEN 'r' THEN 'SYSTEM TABLE' "
				+ "  WHEN 'v' THEN 'SYSTEM VIEW' "
				+ "  WHEN 'i' THEN 'SYSTEM INDEX' "
				+ "  ELSE NULL "
				+ "  END "
				+ " WHEN n.nspname = 'pg_toast' THEN CASE c.relkind "
				+ "  WHEN 'r' THEN 'SYSTEM TOAST TABLE' "
				+ "  WHEN 'i' THEN 'SYSTEM TOAST INDEX' "
				+ "  ELSE NULL "
				+ "  END "
				+ " ELSE CASE c.relkind "
				+ "  WHEN 'r' THEN 'TEMPORARY TABLE' "
				+ "  WHEN 'i' THEN 'TEMPORARY INDEX' "
				+ "  ELSE NULL "
				+ "  END "
				+ " END "
				+ " WHEN false THEN CASE c.relkind "
				+ " WHEN 'r' THEN 'TABLE' "
				+ " WHEN 'i' THEN 'INDEX' "
				+ " WHEN 'S' THEN 'SEQUENCE' "
				+ " WHEN 'v' THEN 'VIEW' "
				+ " ELSE NULL "
				+ " END "
				+ " ELSE NULL "
				+ " END "
				+ " AS TABLE_TYPE, d.description AS REMARKS "
				+ " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c "
				+ " LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0) "
				+ " LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class') "
				+ " LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog') "
				+ " WHERE c.relnamespace = n.oid "
                + " AND " + resolveSchemaPatternCondition(
                                "n.nspname", schemaPattern);
		String orderby = " ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME ";

		if(types == null)
		{
			types = s_defaultTableTypes;
		}
		if(tableNamePattern != null)
		{
			select += " AND c.relname LIKE '" + escapeQuotes(tableNamePattern)
				+ "' ";
		}
		String sql = select;
		sql += " AND (false ";
		for(int i = 0; i < types.length; i++)
		{
			HashMap clauses = (HashMap)s_tableTypeClauses.get(types[i]);
			if(clauses != null)
			{
				String clause = (String)clauses.get(useSchemas);
				sql += " OR ( " + clause + " ) ";
			}
		}
		sql += ") ";
		sql += orderby;

		return createMetaDataStatement().executeQuery(sql);
	}