tomoakin / RPostgreSQL

Automatically exported from code.google.com/p/rpostgresql
64 stars 19 forks source link

dbListFields incorrectly returns columns which have been removed #129

Open warnes opened 1 year ago

warnes commented 1 year ago

Apparently postgresql doesn't actually remove 'dropped' columns, instead it renames them something like ........pg.dropped.23........, fills them with NULL and marks them as unused using the attisdroppped column of the pg_attribute table.

For example:

DROP TABLE IF EXISTS test_persons;

CREATE TABLE test_persons (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255),
    State varchar(2),
    Dummy varchar(255)
);

INSERT INTO test_persons 
    (PersonID, LastName, FirstName, Address, City, State, Dummy)
VALUES
    (1, 'Sawyer', 'Tom',  'Apple Street', 'Riverside', 'MO', 'Dummy'),
    (2, 'Finn',   'Huck', 'Back Street', 'Riverside', 'MO', 'Dummy')
;    

ALTER TABLE test_persons
    DROP COLUMN Dummy;

SELECT
    a.attname,
    a.attisdropped
FROM
    pg_attribute a,
    pg_class c,
    pg_tables t,
    pg_namespace nsp
WHERE
    a.attrelid = c.oid
    AND c.relname = tablename
    AND c.relnamespace = nsp.oid
    AND a.attnum > 0
    AND nspname = CURRENT_SCHEMA()
    AND schemaname = nspname
    AND tablename = 'test_persons'
;

yeilds:

attname attisdropped
personid false
lastname false
firstname false
address false
city false
state false
........pg.dropped.7........ true

and consequently

dbListFields(conn, 'test_persons')

yields

[1] "personid"                     "lastname"                    
[3] "firstname"                    "address"                     
[5] "city"                         "state"                       
[7] "........pg.dropped.7........"

Suggestion: Add an additional AND NOT a.attisdropped clause to the WHERE.