Views, views, views! (long)

Started by Josh Berkusalmost 21 years ago129 messageshackers
Jump to latest
#1Josh Berkus
josh@agliodbs.com

PG hackers,

AndrewSN, Jim Nasby, Elein and I have been working for the last couple of
months on a new set of system views for PostgreSQL.   (primarily Andrew, who
did the lion's share of the work and came up with many clever SQL
workarounds)  We'd like to include them in the 8.1 release, so we're going to
post most of the definitions for your feedback now.  Let me summarize:

Goals of the New System Views
---------------------------------------
1. To be easily human-readable, unlike the system tables.
2. To provide a consistent API to PostgreSQL object definitions which will
seldom (if ever) be changed, only added to.
3. To provide queryable definitions for all PostgreSQL objects.

In more detail:
1. The current system tables are designed around performance and code
requirements, and as such are optimized for code access, not
comprehensability.  Column names are obscure, special system data types are
used, and everything is OIDs and typids.  This is perfect for our code, but
too many user-space applications are using these tables for comfort.  Our
first system views (pg_tables, for example) only went halfway in providing a
user-friendly interface.  So the new system views have the following
requirements:
        a) all view and column names are as explicit and as readable as
    possible (e.g. "type_schema_name", not "typnsname")
        b) OIDs, typids, and other system codes are avoided wherever possible
    in preference to full object names
        c) In most places, "system" objects are segregated from "user"
objects,
    e.g. pg_user_indexes

2. One of the issues with user applications querying the system tables is that
they can be subject to significant changes from version to version.   This
has kept the pgAdmin and phpPgAdmin teams busy since 7.2, and means that GUI
tools which fall out of maintenance (like Xpg) soon stop working.  This is
easily remedied through a set of system views which will remain consistent
regardless of changes in the underlying system tables.  This has the
beneficial effect of giving us more freedom to make changes to the system
tables.
      Further, we discovered when we proposed dropping the old system views
that once these views are created we're stuck with them for several years, if
not forever; people's not-easily-recoded tools rely on them.
        d) Columns may be added to the system views, but never dropped or
    changed in incompatible ways.  Likewise, views will be added but
    not dropped or renamed.
        e) Users and app developers should be actively encouraged to use the
    system views rather than the system tables in the documentation.
        f) Existing projects, features and add-ons, where appropriate,
    should gradually be shifted to use the system views to minimize
    version maintenance.

3. The new system views (unlike, for example, \d) are designed to be a SQL
interface to system objects.   This means that:
        g) All views are as normalized as possible, using child views rather
   than arrays, and providing keys and consistent join columns.
        h) Each view or set of views provides all of the data required
    to replicate the appropriate CREATE statement.
        i) Column names are designed to be universal to a particular type of
data,
     where this does not cause duplication.  For example,
     pg_user_tables has "schema_name" rather than "table_schema".
     This was done to make joins easier (i.e. USING, NATURAL JOIN)

Additional assumptions we worked with include:
j) all view names are plural in order to prevent conflict with
    system tables.
     k) no procedural languages are used, as we don't want to make PLs
    mandatory.   Currently everything is SQL (really!) and we may move
    a few functions to a C library eventually.
l) internal functions required for the system views are named using a
   "_pg_" convention.
        m) We will be offering a "back-patch" for 7.4 and 8.0 via pgFoundry.

What We Need From Hackers
--------------------------------------
(other than patch approval, that is)
As stated above, these system views, once incorporated into a pg distribution,
are likely to be with us *forever*.   As such, we really can't afford to do
major refactoring of the column names and structure once they're released.  
So it's really, really, important for everyone on hackers to look over the
definitions below and find stuff that we've missed or doesn't make any sense.  
Also, we'd like to know about 8.1 changes that affect these views.

There are two additional other questions to discuss that our team as not
settled:
I) Should the new views be part of /contrib before they become part of the
main source?
II) Should the new views be in their own schema?   This would make them easier
to manage for DBAs who want to restrict access or dump them, but would add a
second "system" schema to the template.

Information_Schema note
---------------------------------
Q: Why not just use information_schema?
A: Because the columns and layout of information_schema is strictly defined by
the SQL standard.  This prevents it from covering all PostgreSQL objects, or
from covering the existing objects adequately to replicate a CREATE
statement.  As examples, there is no "types" table in information_schema, and
the "constraints" table assumes that constraint names are universally unique
instead of table-unique as they are in PG.

The View Definitions
----------------------------------
The column definitions of the views are below.   Please examine them
carefully.  Currently, the following views are incomplete and thus not
included:
pg_functions
pg_function_parameters
pg_types

pg_acl_modes

    Column    | Type |
 -------------+------+-----------
  object_type | text |
  mode        | text |
  granted     | text |
  description | text |
 
pg_all_aggregates

         Column         |  Type   | Modifiers
 -----------------------+---------+-----------
  schema_name           | name    |
  aggregate_name        | name    |
  input_type_schema     | name    |
  input_type            | name    |
  output_type_schema    | name    |
  output_type           | name    |
  initial_value         | text    |
  trans_function_schema | name    |
  trans_function_name   | name    |
  final_function_schema | name    |
  final_function_name   | name    |
  is_system_aggregate   | boolean |
  owner                 | name    |

pg_user_aggregates

         Column         |  Type   | Modifiers
 -----------------------+---------+-----------
  schema_name           | name    |
  aggregate_name        | name    |
  input_type_schema     | name    |
  input_type            | name    |
  output_type_schema    | name    |
  output_type           | name    |
  initial_value         | text    |
  trans_function_schema | name    |
  trans_function_name   | name    |
  final_function_schema | name    |
  final_function_name   | name    |
  owner                 | name    |

pg_all_casts

        Column       |  Type   |
 --------------------+---------+-----------
  source_schema      | name    |
  source_type        | name    |
  target_schema      | name    |
  target_type        | name    |
  function_schema    | name    |
  function_name      | name    |
  function_arguments | text    |
  context            | text    |
  is_system_cast     | boolean |

pg_user_casts

        Column       |  Type   |
 --------------------+---------+-----------
  source_schema      | name    |
  source_type        | name    |
  target_schema      | name    |
  target_type        | name    |
  function_schema    | name    |
  function_name      | name    |
  function_arguments | text    |
  context            | text    |

pg_all_conversions

         Column        |  Type   | Modifiers
 ----------------------+---------+-----------
  schema_name          | name    |
  conversion_name      | name    |
  source_encoding      | name    |
  destination_encoding | name    |
  is_default           | boolean |
  function_schema      | name    |
  function_name        | name    |
  is_system_conversion | boolean |
  owner                | name    |

pg_user_conversions

         Column        |  Type   |
 ----------------------+---------+-----------
  schema_name          | name    |
  conversion_name      | name    |
  source_encoding      | name    |
  destination_encoding | name    |
  is_default           | boolean |
  function_schema      | name    |
  function_name        | name    |
  owner                | name    |

pg_databases

        Column       |  Type   |
 --------------------+---------+-----------
  database_name      | name    |
  encoding           | name    |
  default_tablespace | name    |
  database_config    | text[]  |
  is_template        | boolean |
  can_connect        | boolean |
  owner              | name    |

pg_database_config

        Column       | Type |
 --------------------+------+-----------
  database_name      | name |
  config_variable    | text |
  config_value       | text |

pg_all_foreign_key_indexes, pg_user_foreign_key_indexes

        Column        |  Type   | Modifiers
 ---------------------+---------+-----------
  schema_name         | name    |
  table_name          | name    |
  constraint_name     | name    |
  num_columns         | integer |
  num_indexed_columns | integer |
  index_name          | name    |

pg_all_foreign_keys, pg_user_foreign_keys

            Column            |  Type   |
 -----------------------------+---------+-----------
  foreign_key_schema_name     | name    |
  foreign_key_table_name      | name    |
  foreign_key_constraint_name | name    |
  foreign_key_table_oid       | oid     |
  foreign_key_columns         | name[]  |
  key_schema_name             | name    |
  key_table_name              | name    |
  key_constraint_name         | name    |
  key_table_oid               | oid     |
  key_index_name              | name    |
  key_columns                 | name[]  |
  match_type                  | text    |
  on_delete                   | text    |
  on_update                   | text    |
  is_deferrable               | boolean |
  is_deferred                 | boolean |

pg_all_foreign_key_columns, pg_user_foreign_key_columns

            Column            |  Type   |
 -----------------------------+---------+-----------
  foreign_key_schema_name     | name    |
  foreign_key_table_name      | name    |
  foreign_key_constraint_name | name    |
  foreign_key_table_oid       | oid     |
  foreign_key_column          | name    |
  column_position             | integer |
  key_schema_name             | name    |
  key_table_name              | name    |
  key_table_oid               | oid     |
  key_column                  | name    |

pg_all_grants, pg_user_grants

     Column    |  Type   |
 --------------+---------+-----------
  object_type  | name    |
  object_oid   | oid     |
  schema_name  | name    |
  object_name  | name    |
  object_args  | text    |
  owner        | name    |
  grantor      | text    |
  grantee      | text    |
  is_group     | boolean |
  privilege    | text    |
  grant_option | boolean |

pg_groups

    Column   |  Type   |
 ------------+---------+-----------
  group_name | name    |
  gid        | integer |

pg_groups_users

    Column   | Type |
 ------------+------+-----------
  group_name | name |
  user_name  | name |

pg_all_index_columns, pg_user_index_columns

      Column      |  Type   |
 -----------------+---------+-----------
  schema_name     | name    |
  table_name      | name    |
  index_name      | name    |
  column_name     | name    | NULL if an expression
  column_position | integer | 1..n
  opclass_schema  | name    |
  opclass_name    | name    |
  definition      | text    | expression or column name

pg_all_indexes

      Column      |     Type      |
 -----------------+---------------+-----------
  schema_name     | name          |
  table_name      | name          |
  index_name      | name          |
  tablespace      | name          |
  index_method    | name          |
  num_columns     | smallint      |
  is_primary_key  | boolean       |
  is_unique       | boolean       |
  is_clustered    | boolean       |
  is_expression   | boolean       |
  is_partial      | boolean       |
  estimated_rows  | real          |
  estimated_mb    | numeric(12,1) |
  is_system_table | boolean       |
  table_oid       | oid           |
  predicate       | text          |
  definition      | text          |
  owner           | name          |
  comment         | text          |

pg_user_indexes

      Column      |     Type      |
 -----------------+---------------+-----------
  schema_name     | name          |
  table_name      | name          |
  index_name      | name          |
  tablespace      | name          |
  index_method    | name          |
  num_columns     | smallint      |
  is_primary_key  | boolean       |
  is_unique       | boolean       |
  is_clustered    | boolean       |
  is_expression   | boolean       |
  is_partial      | boolean       |
  estimated_rows  | real          |
  estimated_mb    | numeric(12,1) |
  predicate       | text          |
  definition      | text          |
  owner           | name          |
  comment         | text          |

pg_all_relation_columns, pg_user_relation_columns

     Column     |  Type   |
 ---------------+---------+-----------
  schema_name   | name    |
  relation_name | name    |
  column_name   | name    |
  relation_oid  | oid     |
  column_number | integer |
  is_view       | boolean |
  nullable      | boolean |
  declared_type | text    |
  default_value | text    |
  comment       | text    |

pg_all_relation_column_type_info, pg_user_relation_column_type_info

        Column       |  Type   |
 --------------------+---------+-----------
  schema_name        | name    |
  relation_name      | name    |
  column_name        | name    |
  relation_oid       | oid     |
  column_number      | integer |
  is_view            | boolean |
  nullable           | boolean |
  domain_schema      | name    |
  domain_name        | name    |
  type_sqlname       | text    | "bare" SQL name, e.g. 'numeric'
  type_sqldef        | text    | full SQL name, e.g. 'numeric(10,2)'
  type_schema        | name    |
  type_name          | name    |
  type_oid           | oid     |
  type_length        | integer |
  is_array           | boolean |
  array_dimensions   | integer | currently always 1 for arrays
  element_sqlname    | text    |
  element_sqldef     | text    |
  element_schema     | name    |
  element_name       | name    |
  element_oid        | oid     |
  element_length     | integer |
  character_length   | integer |
  bit_length         | integer |
  integer_precision  | integer |
  float_precision    | integer |
  numeric_precision  | integer |
  numeric_scale      | integer |
  time_precision     | integer |
  interval_precision | integer |
  interval_fields    | text    |

pg_all_relations

      Column         |     Type      |
 --------------------+---------------+-----------
  schema_name        | name          |
  relation_name      | name          |
  is_system_relation | boolean       |
  is_temporary       | boolean       |
  is_view            | boolean       |
  relation_oid       | oid           |
  owner              | name          |
  comment            | text          |

pg_user_relations

      Column         |     Type      |
 --------------------+---------------+-----------
  schema_name        | name          |
  relation_name      | name          |
  is_temporary       | boolean       |
  is_view            | boolean       |
  owner              | name          |
  comment            | text          |

pg_all_rules, pg_user_rules

     Column     |  Type   |
 ---------------+---------+-----------
  schema_name   | name    |
  relation_name | name    |
  rule_name     | name    |
  rule_event    | text    |
  is_instead    | boolean |
  condition     | text    |
  action        | text    |

pg_all_schemas
        Column        |  Type   |
 ---------------------+---------+-----------
  schema_name         | name    |
  is_system_schema    | boolean |
  is_temporary_schema | boolean |
  owner               | name    |
  comment             | text    |

pg_user_schemas

        Column        |  Type   |
 ---------------------+---------+-----------
  schema_name         | name    |
  is_temporary_schema | boolean |
  owner               | name    |
  comment             | text    |

pg_all_schema_contents, pg_user_schema_contents

    Column    | Type |
 -------------+------+-----------
  schema_name | name |
  owner       | name |
  object_type | name |
  object_name | name |
  object_args | text |

pg_all_sequences

        Column       |  Type   |
 --------------------+---------+-----------
  schema_name        | name    |
  sequence_name      | name    |
  is_system_sequence | boolean |
  is_temporary       | boolean |

pg_user_sequences

        Column       |  Type   |
 --------------------+---------+-----------
  schema_name        | name    |
  sequence_name      | name    |
  is_temporary       | boolean |

pg_all_table_columns, pg_user_table_columns

     Column     |  Type   |
 ---------------+---------+-----------
  schema_name   | name    |
  table_name    | name    |
  column_name   | name    |
  table_oid     | oid     |
  column_number | integer |
  nullable      | boolean |
  declared_type | text    |
  default_value | text    |
  comment       | text    |

pg_all_table_column_type_info, pg_user_table_column_type_info

        Column       |  Type   |
 --------------------+---------+-----------
  schema_name        | name    |
  table_name         | name    |
  column_name        | name    |
  table_oid          | oid     |
  column_number      | integer |
  nullable           | boolean |
  domain_schema      | name    |
  domain_name        | name    |
  type_sqlname       | text    | "bare" SQL name, e.g. 'numeric'
  type_sqldef        | text    | full SQL name, e.g. 'numeric(10,2)'
  type_schema        | name    |
  type_name          | name    |
  type_oid           | oid     |
  type_length        | integer |
  is_array           | boolean |
  array_dimensions   | integer | currently always 1 for arrays
  element_sqlname    | text    |
  element_sqldef     | text    |
  element_schema     | name    |
  element_name       | name    |
  element_oid        | oid     |
  element_length     | integer |
  character_length   | integer |
  bit_length         | integer |
  integer_precision  | integer |
  float_precision    | integer |
  numeric_precision  | integer |
  numeric_scale      | integer |
  time_precision     | integer |
  interval_precision | integer |
  interval_fields    | text    |

pg_all_table_constraints, pg_user_table_constraints

      Column      | Type |
 -----------------+------+-----------
  schema_name     | name |
  table_name      | name |
  constraint_name | name |
  constraint_type | text |
  table_oid       | oid  |
  definition      | text |

pg_all_table_constraint_columns, pg_user_table_constraint_columns

      Column      |  Type   |
 -----------------+---------+-----------
  schema_name     | name    |
  table_name      | name    |
  constraint_name | name    |
  column_name     | name    |
  column_position | integer |
  constraint_type | text    |
  table_oid       | oid     |

pg_all_unique_constraint_columns, pg_user_unique_constraint_columns

      Column      |  Type   |
 -----------------+---------+-----------
  schema_name     | name    |
  table_name      | name    |
  constraint_name | name    |
  is_primary_key  | boolean |
  column_name     | name    |
  column_position | integer |
  table_oid       | oid     |

pg_all_primary_key_columns, pg_user_primary_key_columns

      Column      |  Type   |
 -----------------+---------+-----------
  schema_name     | name    |
  table_name      | name    |
  constraint_name | name    |
  column_name     | name    |
  column_position | integer |
  table_oid       | oid     |

pg_all_table_check_constraints, pg_user_table_check_constraints

      Column      |  Type  |
 -----------------+--------+-----------
  schema_name     | name   |
  table_name      | name   |
  constraint_name | name   |
  table_oid       | oid    |
  columns         | name[] |
  predicate       | text   |

pg_all_table_inheritance, pg_user_table_inheritance
 
       Column       |  Type   |
 -------------------+---------+-----------
  schema_name       | name    |
  table_name        | name    |
  table_oid         | oid     |
  descendent_schema | name    |
  descendent_table  | name    |
  descendent_oid    | oid     |
  ordinal_position  | integer |

pg_all_table_storage, pg_user_table_storage

      Column             |     Type      |
 ------------------------+---------------+-----------
  schema_name            | name          |
  table_name             | name          |
  tablespace             | name          |
  is_temporary           | boolean       |
  num_indexes            | integer       |
  clustered_on           | name          |
  estimated_rows         | real          |
  estimated_index_rows   | real          |
  estimated_total_mb     | numeric       |
  estimated_data_mb      | numeric       |
  estimated_main_mb      | numeric       |
  estimated_external_mb  | numeric       |
  estimated_index_mb     | numeric       |
  index_tablespaces      | name[]        |
 
pg_all_tables

      Column      |     Type      |
 -----------------+---------------+-----------
  schema_name     | name          |
  table_name      | name          |
  tablespace      | name          |
  with_oids       | boolean       |
  estimated_rows  | real          |
  estimated_mb    | numeric(12,1) | includes toast but not indexes
  has_toast_table | boolean       |
  has_descendents | boolean       |
  is_system_table | boolean       |
  is_temporary    | boolean       |
  table_oid       | oid           |
  owner           | name          |
  comment         | text          |

pg_user_tables

      Column      |     Type      |
 -----------------+---------------+-----------
  schema_name     | name          |
  table_name      | name          |
  tablespace      | name          |
  with_oids       | boolean       |
  estimated_rows  | real          |
  estimated_mb    | numeric(12,1) | includes toast but not indexes
  has_toast_table | boolean       |
  has_descendents | boolean       |
  is_temporary    | boolean       |
  owner           | name          |
  comment         | text          |

pg_tablespaces

    Column    |  Type   |
 -------------+---------+-----------
  tablespace  | name    |
  location    | text    |
  is_writable | boolean |
  owner       | name    |
  comment     | text    |

pg_tablespace_usage

    Column   | Type |
 ------------+------+-----------
  tablespace | name |
  database   | name |

pg_all_tablespace_contents, pg_user_tablespace_contents

     Column     |     Type      |
 ---------------+---------------+-----------
  tablespace    | name          |
  object_type   | text          |
  owner         | name          |
  object_schema | name          |
  object_name   | name          |
  estimated_mb  | numeric(12,1) |

pg_all_triggers, pg_user_triggers

      Column      |  Type   |
 -----------------+---------+-----------
  schema_name     | name    |
  table_name      | name    |
  trigger_name    | name    |
  function_schema | name    |
  function_name   | name    |
  function_args   | text[]  |
  function_oid    | oid     |
  before          | boolean |
  for_each_row    | boolean |
  on_insert       | boolean |
  on_delete       | boolean |
  on_update       | boolean |
  enabled         | boolean |
  definition      | text    |
  comment         | text    |
 
pg_users

          Column         |           Type           |
 ------------------------+--------------------------+-----------
  user_name              | name                     |
  uid                    | integer                  |
  create_datebase        | boolean                  |
  create_user            | boolean                  |
  superuser              | boolean                  |
  update_system_catalogs | boolean                  |
  password_expires       | timestamp with time zone |

pg_user_config

      Column      | Type |
 -----------------+------+-----------
  user_name       | name |
  config_variable | text |
  config_value    | text |

pg_all_view_columns, pg_user_view_columns

     Column     |  Type   |
 ---------------+---------+-----------
  schema_name   | name    |
  view_name     | name    |
  column_name   | name    |
  view_oid      | oid     |
  column_number | integer |
  nullable      | boolean |
  declared_type | text    |
  default_value | text    |
  comment       | text    |

pg_all_view_column_type_info, pg_user_view_column_type_info

        Column       |  Type   |
 --------------------+---------+-----------
  schema_name        | name    |
  view_name          | name    |
  column_name        | name    |
  view_oid           | oid     |
  column_number      | integer |
  nullable           | boolean |
  domain_schema      | name    |
  domain_name        | name    |
  type_sqlname       | text    | "bare" SQL name, e.g. 'numeric'
  type_sqldef        | text    | full SQL name, e.g. 'numeric(10,2)'
  type_schema        | name    |
  type_name          | name    |
  type_oid           | oid     |
  type_length        | integer |
  is_array           | boolean |
  array_dimensions   | integer | currently always 1 for arrays
  element_sqlname    | text    |
  element_sqldef     | text    |
  element_schema     | name    |
  element_name       | name    |
  element_oid        | oid     |
  element_length     | integer |
  character_length   | integer |
  bit_length         | integer |
  integer_precision  | integer |
  float_precision    | integer |
  numeric_precision  | integer |
  numeric_scale      | integer |
  time_precision     | integer |
  interval_precision | integer |
  interval_fields    | text    |

pg_all_views

      Column      |     Type      |
 -----------------+---------------+-----------
  schema_name     | name          |
  view_name       | name          |
  is_insertable   | boolean       |
  is_updateable   | boolean       |
  is_deleteable   | boolean       |
  definition      | text          |
  is_system_view  | boolean       |
  view_oid        | oid           |
  owner           | name          |
  comment         | text          |

pg_user_views

      Column      |     Type      |
 -----------------+---------------+-----------
  schema_name     | name          |
  view_name       | name          |
  is_insertable   | boolean       |
  is_updateable   | boolean       |
  is_deleteable   | boolean       |
  definition      | text          |
  owner           | name          |
  comment         | text          |

--
Josh Berkus
Aglio Database Solutions
San Francisco

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#1)
Re: Views, views, views! (long)

Josh Berkus <josh@agliodbs.com> writes:

As stated above, these system views, once incorporated into a pg
distribution, are likely to be with us *forever*.

I dislike to burst your bubble, but this claim is ridiculous on its
face.

We don't whack the system catalogs around from release to release just
because we'd like to break as many user applications as possible ...
quite the contrary. When we change the catalogs it's because there
is some fairly fundamental change in functionality involved. I think
the idea that some views in front of the catalogs can hide this problem
is the merest pipe dream.

To put it more bluntly: exactly what are you accomplishing here that
isn't already accomplished, in a *truly* standard fashion, by the
INFORMATION_SCHEMA? Why do we need yet another nonstandard view on
the underlying reality?

regards, tom lane

#3Josh Berkus
josh@agliodbs.com
In reply to: Tom Lane (#2)
Re: Views, views, views! (long)

Tom,

To put it more bluntly: exactly what are you accomplishing here that
isn't already accomplished, in a *truly* standard fashion, by the
INFORMATION_SCHEMA? Why do we need yet another nonstandard view on
the underlying reality?

To quote myself:

Q: Why not just use information_schema?
A: Because the columns and layout of information_schema is strictly defined by
the SQL standard.  This prevents it from covering all PostgreSQL objects, or
from covering the existing objects adequately to replicate a CREATE
statement.  As examples, there is no "types" table in information_schema, and
the "constraints" table assumes that constraint names are universally unique
instead of table-unique as they are in PG.

--
Josh Berkus
Aglio Database Solutions
San Francisco

#4Tim Allen
tim@proximity.com.au
In reply to: Josh Berkus (#1)
Re: Views, views, views! (long)

Josh Berkus wrote:

PG hackers,

[snip]

What We Need From Hackers --------------------------------------
(other than patch approval, that is) As stated above, these system
views, once incorporated into a pg distribution, are likely to be
with us *forever*. As such, we really can't afford to do major
refactoring of the column names and structure once they're released.
So it's really, really, important for everyone on hackers to look
over the definitions below and find stuff that we've missed or
doesn't make any sense. Also, we'd like to know about 8.1 changes
that affect these views.

This all looks good to me, from a quick read through. I don't claim to
have examined the details, but the general idea is definitely something
that would be very worth having.

A nice thing to add would be a more human-comprehensible view of the
pg_locks table. I keep meaning to write a view for it myself, but
haven't ever gotten a round tuit.

Tim

--
-----------------------------------------------
Tim Allen tim@proximity.com.au
Proximity Pty Ltd http://www.proximity.com.au/
http://www4.tpg.com.au/users/rita_tim/

#5Josh Berkus
josh@agliodbs.com
In reply to: Tim Allen (#4)
Re: Views, views, views! (long)

Tim,

A nice thing to add would be a more human-comprehensible view of the
pg_locks table. I keep meaning to write a view for it myself, but
haven't ever gotten a round tuit.

Jim Nasby is working on that; see his other posts.

--
Josh Berkus
Aglio Database Solutions
San Francisco

#6Dave Page
dpage@pgadmin.org
In reply to: Josh Berkus (#5)
Re: Views, views, views! (long)

Hi Josh,

-----Original Message-----
From: pgsql-hackers-owner@postgresql.org
[mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of Josh Berkus
Sent: 05 May 2005 05:38
To: PostgreSQL-development
Subject: [HACKERS] Views, views, views! (long)

This
has kept the pgAdmin and phpPgAdmin teams busy since 7.2, and
means that GUI
tools which fall out of maintenance (like Xpg) soon stop
working.  This is
easily remedied through a set of system views which will
remain consistent
regardless of changes in the underlying system tables.

6.3/6.4 for pgAdmin. 7.2 is positively recent :-)

However, I cannot see us using these views for a couple of reasons:

1) Users may drop or change them, something they cannot do easily with system catalogs. Yes, I know this is then their fault, but it will stop admin tools that use the views from working even though the database itself is actually OK. If a user does manage to alter a system catalog, they are far more likely to see breakage in other places as well.

2) Catalog changes are infrequent but significant in other areas when they do occur. Consider the 7.2 -> 7.3 namespace changes. Regardless of using views or the catalogs we still have significant work to do to support namespaces. Other smaller changes will likely require GUI updates or internal code changes that will also be necessary whether using views or the catalogs.

3) One example of a catalog change that has caused a number of bug reports for us is the removal of pg_database.datpath. Whilst your views could have prevented the error itself, we would still have had to modify pgAdmin to prevent it displaying the path on newer servers as it is completely meaningless - however, do you proprose that your views would have retained this column forever? If so, it seems they could get very messy, and cluttered with notes in the docs telling users that a given column was only relevant up till version X.

After 8 or so years of dealing with problem, I'm really don't think we would gain anything worthwhile from the views you propose. However, I'm sure some end users may well find them useful, so I do not believe your work is in vain.

Regards, Dave.

#7Oleg Bartunov
oleg@sai.msu.su
In reply to: Josh Berkus (#1)
Re: Views, views, views! (long)

Josh,

it's very difficult to read your messages (I'm using Pine), because
of some symbols (~Z on my xterm) which broke formatting.
Is't known problem of pine (4.62) or your mailer ?

Regards,
Oleg
_____________________________________________________________
Oleg Bartunov, sci.researcher, hostmaster of AstroNet,
Sternberg Astronomical Institute, Moscow University (Russia)
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(095)939-16-83, +007(095)939-23-83

#8Peter Eisentraut
peter_e@gmx.net
In reply to: Josh Berkus (#1)
Re: Views, views, views! (long)

Josh Berkus wrote:

��������a) all view and column names are as explicit and as readable
as possible (e.g. "type_schema_name", not "typnsname")

I would suggest that you align your terminology with the information
schema as much as possible, so it would be "type_schema" and not
"type_schema_name", and "ordinal_position" instead of
"column_position". Otherwise we'll have a lot of confusion ahead if we
instroduced a third parallel set of terminology.

��������c) In most places, "system" objects are segregated from
"user" objects,
� � e.g. pg_user_indexes

I think that is a bad idea as it goes against the fundamental design of
PostgreSQL.

d) Columns may be added to the system views, but never
dropped or changed in incompatible ways. �Likewise, views will be
added but not dropped or renamed.

Dave Page already pointed out an example where this is a bad idea. When
a feature is removed, we can't keep claiming it exists.

��������g) All views are as normalized as possible, using child views
rather than�arrays, and providing keys and consistent join columns.

You still seem to have a bunch of arrays in there. Anything with an
array is never normalized.

That said, I don't particularly care for this proposal. If you want a
human-readable version of the system catalogs, I suggest you work on
extensions of the information schema, not a completely new interface.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#3)
Re: Views, views, views! (long)

Josh Berkus <josh@agliodbs.com> writes:

Tom,

To put it more bluntly: exactly what are you accomplishing here that
isn't already accomplished, in a *truly* standard fashion, by the
INFORMATION_SCHEMA? Why do we need yet another nonstandard view on
the underlying reality?

To quote myself:

Q: Why not just use information_schema?
A: Because the columns and layout of information_schema is strictly defined by
the SQL standard. This prevents it from covering all PostgreSQL objects, or
from covering the existing objects adequately to replicate a CREATE
statement. As examples, there is no "types" table in information_schema, and
the "constraints" table assumes that constraint names are universally unique
instead of table-unique as they are in PG.

So? If you want reality, look at the catalogs.

I think that in a release or three, these views will be just as
distorted a representation of the underlying reality as the
information_schema is now. Either that or you'll be changing them
incompatibly. You can't have both truth and a greater degree of
stability than the underlying catalogs.

So my opinion remains "what's the point?". All you have really
accomplished is some editorialization on table/column names.

regards, tom lane

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dave Page (#6)
Re: Views, views, views! (long)

"Dave Page" <dpage@vale-housing.co.uk> writes:

3) One example of a catalog change that has caused a number of bug
reports for us is the removal of pg_database.datpath. Whilst your
views could have prevented the error itself, we would still have had
to modify pgAdmin to prevent it displaying the path on newer servers
as it is completely meaningless - however, do you proprose that your
views would have retained this column forever?

It's worth noting that we could have left datpath in the catalogs.
Its removal was deliberate: I *wanted* to break any applications
that were looking at it, to ensure that they got updated. If we'd
left it there but nonfunctional, we'd have had subtle bugs in apps
instead of obvious ones. We will have the same tradeoff to make
with respect to these views, anytime the underlying reality changes
in incompatible ways ... which it surely will.

regards, tom lane

#11Josh Berkus
josh@agliodbs.com
In reply to: Peter Eisentraut (#8)
Re: Views, views, views! (long)

Tom, Peter,

That said, I don't particularly care for this proposal. If you want a
human-readable version of the system catalogs, I suggest you work on
extensions of the information schema, not a completely new interface.

So, both of your would prefer that we break the SQL spec with the information
schema? In order to cover all PG objects? Because that's what your
proposing. Either the information schema adheres to the spec, or it only
covers 25% of PostgreSQL objects. There isn't a 3rd alternative. I'm fine
with merging this with the information_schema (some of these views are
derived from the same code) but it's either/or.

So? If you want reality, look at the catalogs.

The system catalogs are NOT user-friendly, nor are they meant to be. The
purpose of the new system views is to answer questions like, "what objects
does user "gregory" have permissions on?" and "do any of my fuctions use
custom type 'joebert' before I change it?" and "I need a way to query all of
my functions in a loop so that I can change their permissions." You can get
that info from the system catalogs, but only if you're a SQL wizard and know
them very well.

These are all things that users (NOT pg hackers) have to do for applications
daily, and that we currently don't provide any easy, comprehensible way to
access. It's certainly easy for pg hackers to say, "oh, use the system
tables" but those tables are baffling and awkward for the many thousands of
users who are not PG hackers. Elein's series on General Bits covering
queries which were the inspiration for many of the views was immensely
popular.

Frankly, this is sounding a lot like "Who needs OpenOffice.org? Use vi!"

Further, Jim and I went over the purpose of the views on this list two months
ago and even Tom seemed positive to the idea. What the hell changed? No
wonder the discussion of the decision process dragged on so. If we
introduce a proposal, do an implementation, and come back with it 2 months
later, I don't expect a bunch of core members to act like they've never heard
of it before.

If there are things (like not dropping columns) that you want to change about
the spec, fine. But if you think that nobody needs these views, it's
because you haven't had much contact with end users lately.

--
Josh Berkus
Aglio Database Solutions
San Francisco

#12Lance Obermeyer
LObermey@pervasive.com
In reply to: Josh Berkus (#11)
Re: Views, views, views! (long)

This is the kind of thing that support engineers love. Instead of having to email a bunch of complex SQL statements to a customer that is having trouble, they can verbally walk through a system catalog type query.

My proprietary database has a very simple system catalog that very human readable, which saves time and improves accuracy. So, it isn't just end users, it is those that touch them as well.

-----Original Message-----
From: Josh Berkus [mailto:josh@agliodbs.com]
Sent: Thursday, May 05, 2005 11:11 AM
Cc: PostgreSQL-development
Subject: Re: Views, views, views! (long)

[...snip...]

If there are things (like not dropping columns) that you want to change about
the spec, fine. But if you think that nobody needs these views, it's
because you haven't had much contact with end users lately.

--
Josh Berkus
Aglio Database Solutions
San Francisco

#13Dann Corbit
DCorbit@connx.com
In reply to: Lance Obermeyer (#12)
Re: Views, views, views! (long)

Why not tack on the missing functionality to the INFORMATION_SCHEMA views?

A couple of new tables and foreign keys should do it, n'est ce pas?

Show quoted text

-----Original Message-----
From: pgsql-hackers-owner@postgresql.org [mailto:pgsql-hackers-
owner@postgresql.org] On Behalf Of Josh Berkus
Sent: Wednesday, May 04, 2005 10:02 PM
To: Tom Lane
Cc: PostgreSQL-development
Subject: Re: [HACKERS] Views, views, views! (long)

Tom,

To put it more bluntly: exactly what are you accomplishing here that
isn't already accomplished, in a *truly* standard fashion, by the
INFORMATION_SCHEMA? Why do we need yet another nonstandard view on
the underlying reality?

To quote myself:

Q: Why not just use information_schema?
A: Because the columns and layout of information_schema is strictly
defined by
the SQL standard.  This prevents it from covering all PostgreSQL objects,
or
from covering the existing objects adequately to replicate a CREATE
statement.  As examples, there is no "types" table in information_schema,
and
the "constraints" table assumes that constraint names are universally
unique
instead of table-unique as they are in PG.

--
Josh Berkus
Aglio Database Solutions
San Francisco

---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

#14Andreas Pflug
pgadmin@pse-consulting.de
In reply to: Josh Berkus (#11)
Re: Views, views, views! (long)

Josh Berkus wrote:

Frankly, this is sounding a lot like "Who needs OpenOffice.org? Use vi!"

Frankly, this is sounding a lot like "Who needs
pgadmin/phppgadmin/pgaccess/younameit? use SELECT * FROM pg_somewot in
psql instead".

As Dave already pointed out, serious admin tools will avoid views. We
have to deal with version specific issues anyway.

Regards,
Andreas

#15Josh Berkus
josh@agliodbs.com
In reply to: Andreas Pflug (#14)
Re: Views, views, views! (long)

Andreas,

As Dave already pointed out, serious admin tools will avoid views. We
have to deal with version specific issues anyway.

Actually, I don't think that's what Dave said. He simply said that modifying
pgAdmin to keep up with pg_catalog changes hasn't actually been a problem.

And, as an increasing number of 3rd-party tools support PostgreSQL (like
Embarcadero) they need a simple comprehensible API for system objects -- more
objects than are included in the information_schema. I'm currently working
on the integration of a major DSS tool with PostgreSQL, and we're already
using the alpha version of the system views because we need them. A 3rd
party proprietary vendor is not going to learn about OIDs, and they're not
going to use pgAdmin.

When we discussed this on this list 2 months ago, I was under the impression
that extending the information_schema was verboten becuase it would break the
SQL spec. If that's not the case, I personally would love to not duplicate
objects. But let's establish that.

--
Josh Berkus
Aglio Database Solutions
San Francisco

#16Andreas Pflug
pgadmin@pse-consulting.de
In reply to: Josh Berkus (#15)
Re: Views, views, views! (long)

Josh Berkus wrote:

And, as an increasing number of 3rd-party tools support PostgreSQL (like
Embarcadero) they need a simple comprehensible API for system objects -- more
objects than are included in the information_schema.

There are only two choices: Creating a minimal subset tool, which will
rely on INFORMATION_SCHEMA (or a schema API as in ODBC) as standardized
by SQL specs, or making it specifically for every DBMS, whether using
some fancy views or not.

A 3rd
party proprietary vendor is not going to learn about OIDs,

Doing it seriously, it probably needs the internal DBMS object
identifiers (oid in the case of pgsql), to uniquely identify objects
even after a rename. Hiding the OIDs in schema views will reduce their
usability.

Regards,
Andreas

#17Josh Berkus
josh@agliodbs.com
In reply to: Andreas Pflug (#16)
Re: Views, views, views! (long)

Andreas,

There are only two choices: Creating a minimal subset tool, which will
rely on INFORMATION_SCHEMA (or a schema API as in ODBC) as standardized
by SQL specs, or making it specifically for every DBMS, whether using
some fancy views or not.

Thing is, INFORMATION_SCHEMA doesn't hold a lot of information that people
need to know. Like permissions, comments, object owners, functions, types,
etc. If adding columns and views to the Information schema ... and changing
keys in a couple of places ... is OK, then we have somewhere to go.

Unfortunately, PostgreSQL does not have a seat on the ANSI committee, so we're
not going to get the standard changed. The standard lately belongs to
Oracle and DB2 and we have to suffer under it.

Doing it seriously, it probably needs the internal DBMS object
identifiers (oid in the case of pgsql), to uniquely identify objects
even after a rename. Hiding the OIDs in schema views will reduce their
usability.

Hmmm ... we argued about this. I was in favor of hiding the OIDs because OIDs
are not consistent after a database reload and names are. I can see your
point though; what do other people think?

--
--Josh

Josh Berkus
Aglio Database Solutions
San Francisco

#18Dann Corbit
DCorbit@connx.com
In reply to: Josh Berkus (#17)
Re: Views, views, views! (long)

-----Original Message-----
From: pgsql-hackers-owner@postgresql.org [mailto:pgsql-hackers-
owner@postgresql.org] On Behalf Of Josh Berkus
Sent: Thursday, May 05, 2005 10:49 AM
To: Andreas Pflug
Cc: PostgreSQL-development
Subject: Re: [HACKERS] Views, views, views! (long)

Andreas,

There are only two choices: Creating a minimal subset tool, which

will

rely on INFORMATION_SCHEMA (or a schema API as in ODBC) as

standardized

by SQL specs, or making it specifically for every DBMS, whether

using

some fancy views or not.

Thing is, INFORMATION_SCHEMA doesn't hold a lot of information that

people

need to know. Like permissions,

COLUMN_PRIVILEGES Has one row for each column level permission granted
to or by the current user
TABLE_PRIVILEGES Has one row for each table level permission granted to
or by the current user

comments,

These tables contain commentary information:
CREATE TABLE SQL_FEATURES
CREATE TABLE SQL_IMPLEMENTATION_INFO
CREATE TABLE SQL_LANGUAGES
CREATE TABLE SQL_SIZING_PROFILES
CREATE VIEW SQL_FEATURES
CREATE VIEW SQL_IMPLEMENTATION_INFO
CREATE VIEW SQL_IMPL_INFO
CREATE VIEW SQL_PACKAGES
CREATE VIEW SQL_SIZING
CREATE VIEW SQL_SIZING_PROFILES
CREATE VIEW SQL_SIZING_PROFS

And you can tack on more tables as needed.

object owners,

Ownership stuff is contained in these:
CREATE TABLE SCHEMATA
CREATE VIEW ASSERTIONS
CREATE VIEW ATTRIBUTES
CREATE VIEW CHARACTER_SETS
CREATE VIEW CHECK_CONSTRAINTS
CREATE VIEW COLLATIONS
CREATE VIEW COLUMNS
CREATE VIEW COLUMN_DOMAIN_USAGE
CREATE VIEW COLUMN_UDT_USAGE
CREATE VIEW CONSTRAINT_COLUMN_USAGE
CREATE VIEW CONSTRAINT_TABLE_USAGE
CREATE VIEW DIRECT_SUPERTABLES
CREATE VIEW DIRECT_SUPERTYPES
CREATE VIEW DOMAINS
CREATE VIEW DOMAIN_CONSTRAINTS
CREATE VIEW DOMAIN_UDT_USAGE
CREATE VIEW KEY_COLUMN_USAGE
CREATE VIEW METHOD_SPECIFICATIONS
CREATE VIEW METHOD_SPECIFICATION_PARAMETERS
CREATE VIEW PARAMETERS
CREATE VIEW REFERENTIAL_CONSTRAINTS
CREATE VIEW ROUTINES
CREATE VIEW ROUTINE_COLUMN_USAGE
CREATE VIEW ROUTINE_TABLE_USAGE
CREATE VIEW SCHEMATA
CREATE VIEW SCHEMATA_S
CREATE VIEW TABLES
CREATE VIEW TABLE_CONSTRAINTS
CREATE VIEW TRANSFORMS
CREATE VIEW TRANSLATIONS
CREATE VIEW TRIGGERED_UPDATE_COLUMNS
CREATE VIEW TRIGGERS
CREATE VIEW TRIGGER_COLUMN_USAGE
CREATE VIEW TRIGGER_TABLE_USAGE
CREATE VIEW USER_DEFINED_TYPES
CREATE VIEW VIEWS
CREATE VIEW VIEW_COLUMN_USAGE
CREATE VIEW VIEW_TABLE_USAGE

If you need more than what is here, create an ownership table that is
connected to the others using key relationships.

functions,

ROUTINES Lists one row for each stored procedure or user-defined
function
ROUTINE_COLUMNS Contains one row for each column returned by any
table-valued functions

types,

DOMAIN_CONSTRAINTS Lists the user-defined datatypes that have rules
bound to them
DOMAINS Lists the user-defined datatypes

etc. If adding columns and views to the Information schema ... and
changing
keys in a couple of places ... is OK, then we have somewhere to go.

Create a new relation that is tied to the table of interest with a key.

Unfortunately, PostgreSQL does not have a seat on the ANSI committee,

so

we're
not going to get the standard changed. The standard lately belongs

to

Oracle and DB2 and we have to suffer under it.

Doing it seriously, it probably needs the internal DBMS object
identifiers (oid in the case of pgsql), to uniquely identify objects
even after a rename. Hiding the OIDs in schema views will reduce

their

usability.

Hmmm ... we argued about this. I was in favor of hiding the OIDs

because

OIDs
are not consistent after a database reload and names are. I can

see

your
point though; what do other people think?

Imagine (if you will) 100 different database systems, each of which has
a different way to access the system tables, and each of which changes
the tables whenever they want. If this picture is firm in mind, then
the absolute necessity of INFORMATION_SCHEMA will crystallize.

Whether or not OID values are published pales in comparison. Of course,
if they do become visible, they should not pollute the
INFORMATION_SCHEMA.

IMO-YMMV.

--Josh

Josh Berkus
Aglio Database Solutions
San Francisco

---------------------------(end of

broadcast)---------------------------

Show quoted text

TIP 8: explain analyze is your friend

#19Peter Eisentraut
peter_e@gmx.net
In reply to: Josh Berkus (#11)
Re: Views, views, views! (long)

Josh Berkus wrote:

Either the information schema adheres to
the spec, or it only covers 25% of PostgreSQL objects. There isn't
a 3rd alternative. I'm fine with merging this with the
information_schema (some of these views are derived from the same
code) but it's either/or.

I can think of a couple of ways offhand about how the information schema
could be extended without breaking the SQL standard. You could just
add columns where needed. Or you could add tables that are joined to
the standard tables and contain the extra information. Or you could
create a "information_schema_2" that contains a copy of the original
information schema with the extra information added somewhere, so users
can easily switch back and forth.

If you look closer, there isn't really all that much that cannot be
gotten from the information schema. Figuring out exactly what that is
might be instructive before deciding how to go forward.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#20Josh Berkus
josh@agliodbs.com
In reply to: Peter Eisentraut (#19)
Re: Views, views, views! (long)

Peter,

I can think of a couple of ways offhand about how the information schema
could be extended without breaking the SQL standard. You could just
add columns where needed. Or you could add tables that are joined to
the standard tables and contain the extra information. Or you could
create a "information_schema_2" that contains a copy of the original
information schema with the extra information added somewhere, so users
can easily switch back and forth.

If you look closer, there isn't really all that much that cannot be
gotten from the information schema. Figuring out exactly what that is
might be instructive before deciding how to go forward.

This makes sense; I do wish that someone had mentioned it when I originally
raised the subject of new system views. It would have saved us some work.

--Josh

--
--Josh

Josh Berkus
Aglio Database Solutions
San Francisco

#21Josh Berkus
josh@agliodbs.com
In reply to: Josh Berkus (#1)
#22Bruno Wolff III
bruno@wolff.to
In reply to: Oleg Bartunov (#7)
#23Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Josh Berkus (#1)
#24Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Josh Berkus (#1)
#25David Fetter
david@fetter.org
In reply to: Andrew - Supernews (#24)
#26Greg Sabino Mullane
greg@turnstep.com
In reply to: Josh Berkus (#11)
#27Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Josh Berkus (#11)
#28Josh Berkus
josh@agliodbs.com
In reply to: Greg Sabino Mullane (#26)
#29Hannu Krosing
hannu@tm.ee
In reply to: Greg Sabino Mullane (#26)
#30elein
elein@varlena.com
In reply to: Peter Eisentraut (#19)
#31Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Greg Sabino Mullane (#26)
#32Dann Corbit
DCorbit@connx.com
In reply to: Andrew - Supernews (#31)
#33Dann Corbit
DCorbit@connx.com
In reply to: Dann Corbit (#32)
#34Josh Berkus
josh@agliodbs.com
In reply to: Dann Corbit (#33)
#35Dann Corbit
DCorbit@connx.com
In reply to: Josh Berkus (#34)
#36elein
elein@varlena.com
In reply to: Dann Corbit (#33)
#37Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Andreas Pflug (#14)
#38Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Josh Berkus (#17)
#39Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Josh Berkus (#1)
#40Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dann Corbit (#33)
#41Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#40)
#42Robert Treat
xzilla@users.sourceforge.net
In reply to: Andrew - Supernews (#27)
#43Robert Treat
xzilla@users.sourceforge.net
In reply to: Hannu Krosing (#29)
#44Joshua D. Drake
jd@commandprompt.com
In reply to: Robert Treat (#43)
#45Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Josh Berkus (#11)
#46Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew - Supernews (#45)
#47Josh Berkus
josh@agliodbs.com
In reply to: Tom Lane (#46)
#48Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Andrew - Supernews (#39)
#49Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Andreas Pflug (#14)
#50Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Robert Treat (#43)
#51Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Dann Corbit (#35)
#52Dawid Kuroczko
qnex42@gmail.com
In reply to: Greg Sabino Mullane (#26)
#53Andreas Pflug
pgadmin@pse-consulting.de
In reply to: Christopher Kings-Lynne (#37)
#54Greg Sabino Mullane
greg@turnstep.com
In reply to: Jim Nasby (#49)
#55Robert Treat
xzilla@users.sourceforge.net
In reply to: Joshua D. Drake (#44)
#56Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Greg Sabino Mullane (#54)
#57Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jim Nasby (#56)
#58Andreas Pflug
pgadmin@pse-consulting.de
In reply to: Tom Lane (#57)
#59Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Tom Lane (#57)
#60Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Robert Treat (#55)
#61elein
elein@varlena.com
In reply to: Jim Nasby (#48)
#62elein
elein@varlena.com
In reply to: Josh Berkus (#47)
#63Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Greg Sabino Mullane (#26)
#64Robert Treat
xzilla@users.sourceforge.net
In reply to: Jim Nasby (#60)
#65Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Robert Treat (#64)
#66Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Greg Sabino Mullane (#26)
#67Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Josh Berkus (#1)
#68Darren King
DarrenK@Routescape.com
In reply to: Andrew - Supernews (#67)
#69Josh Berkus
josh@agliodbs.com
In reply to: Robert Treat (#55)
#70Peter Eisentraut
peter_e@gmx.net
In reply to: Andrew - Supernews (#67)
#71Peter Eisentraut
peter_e@gmx.net
In reply to: Andreas Pflug (#53)
#72Merlin Moncure
merlin.moncure@rcsonline.com
In reply to: Peter Eisentraut (#71)
#73Josh Berkus
josh@agliodbs.com
In reply to: Merlin Moncure (#72)
#74Josh Berkus
josh@agliodbs.com
In reply to: Merlin Moncure (#72)
#75Joshua D. Drake
jd@commandprompt.com
In reply to: Josh Berkus (#74)
#76Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Peter Eisentraut (#70)
#77Dann Corbit
DCorbit@connx.com
In reply to: Joshua D. Drake (#75)
#78Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Josh Berkus (#1)
#79David Fetter
david@fetter.org
In reply to: Josh Berkus (#74)
#80Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jim Nasby (#76)
#81Josh Berkus
josh@agliodbs.com
In reply to: Tom Lane (#80)
#82Greg Sabino Mullane
greg@turnstep.com
In reply to: Josh Berkus (#74)
#83Michael Glaesemann
grzm@seespotcode.net
In reply to: Greg Sabino Mullane (#82)
#84Thomas F.O'Connell
tfo@sitening.com
In reply to: Josh Berkus (#74)
#85Josh Berkus
josh@agliodbs.com
In reply to: Thomas F.O'Connell (#84)
#86Joshua D. Drake
jd@commandprompt.com
In reply to: Josh Berkus (#85)
#87Thomas F.O'Connell
tfo@sitening.com
In reply to: Josh Berkus (#85)
#88Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas F.O'Connell (#87)
#89Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#88)
#90Merlin Moncure
merlin.moncure@rcsonline.com
In reply to: Christopher Kings-Lynne (#89)
#91Tom Lane
tgl@sss.pgh.pa.us
In reply to: Merlin Moncure (#90)
#92elein
elein@varlena.com
In reply to: Tom Lane (#88)
#93Tom Lane
tgl@sss.pgh.pa.us
In reply to: elein (#92)
#94Josh Berkus
josh@agliodbs.com
In reply to: Tom Lane (#93)
#95elein
elein@varlena.com
In reply to: Tom Lane (#93)
#96Andrew Dunstan
andrew@dunslane.net
In reply to: Josh Berkus (#94)
#97Robert Treat
xzilla@users.sourceforge.net
In reply to: Christopher Kings-Lynne (#89)
#98Josh Berkus
josh@agliodbs.com
In reply to: Andrew Dunstan (#96)
#99David Fetter
david@fetter.org
In reply to: Robert Treat (#97)
#100Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Robert Treat (#97)
#101Andrew Dunstan
andrew@dunslane.net
In reply to: Christopher Kings-Lynne (#100)
#102Robert Treat
xzilla@users.sourceforge.net
In reply to: David Fetter (#99)
#103Bruno Wolff III
bruno@wolff.to
In reply to: David Fetter (#99)
#104Merlin Moncure
merlin.moncure@rcsonline.com
In reply to: Bruno Wolff III (#103)
#105Tom Lane
tgl@sss.pgh.pa.us
In reply to: Merlin Moncure (#104)
#106Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#105)
#107Merlin Moncure
merlin.moncure@rcsonline.com
In reply to: Andrew Dunstan (#106)
#108Andrew Dunstan
andrew@dunslane.net
In reply to: Merlin Moncure (#107)
#109Josh Berkus
josh@agliodbs.com
In reply to: Andrew Dunstan (#108)
#110Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#109)
#111Andrew Dunstan
andrew@dunslane.net
In reply to: Josh Berkus (#109)
#112Josh Berkus
josh@agliodbs.com
In reply to: Andrew Dunstan (#111)
#113Andrew Dunstan
andrew@dunslane.net
In reply to: Josh Berkus (#112)
#114Josh Berkus
josh@agliodbs.com
In reply to: Andrew Dunstan (#113)
#115Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Merlin Moncure (#107)
#116Andrew - Supernews
andrew+nonews@supernews.com
In reply to: Merlin Moncure (#107)
#117Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew - Supernews (#116)
#118Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Andrew Dunstan (#96)
#119Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew - Supernews (#115)
#120Josh Berkus
josh@agliodbs.com
In reply to: Andrew Dunstan (#119)
#121Russell Smith
mr-russ@pws.com.au
In reply to: Andrew Dunstan (#117)
#122Alvaro Herrera
alvherre@surnet.cl
In reply to: Russell Smith (#121)
#123Stephen Frost
sfrost@snowman.net
In reply to: Russell Smith (#121)
#124Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Stephen Frost (#123)
#125Stephen Frost
sfrost@snowman.net
In reply to: Christopher Kings-Lynne (#124)
#126Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Stephen Frost (#125)
#127Stephen Frost
sfrost@snowman.net
In reply to: Jim Nasby (#126)
#128Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Stephen Frost (#127)
#129Manfred Koizar
mkoi-pg@aon.at
In reply to: Josh Berkus (#1)