Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Postgres: missing FK constraints for non-owner #1940

Open
nbenn opened this issue Aug 5, 2023 · 0 comments
Open

Postgres: missing FK constraints for non-owner #1940

nbenn opened this issue Aug 5, 2023 · 0 comments

Comments

@nbenn
Copy link

nbenn commented Aug 5, 2023

General set up:

CREATE DATABASE fk_vis_reprex;

CREATE USER fk_vis_owner WITH PASSWORD 'pwd123';
CREATE USER fk_vis_reader WITH PASSWORD 'pwd345';

GRANT CONNECT, TEMPORARY, CREATE ON DATABASE fk_vis_reprex TO fk_vis_owner;
GRANT CONNECT, TEMPORARY ON DATABASE fk_vis_reprex TO fk_vis_reader;

then, with a connection of our user fk_vis_owner, some more set up (as psql -d fk_vis_reprex -U fk_vis_owner ):

CREATE SCHEMA fk_vis;

GRANT USAGE ON SCHEMA fk_vis TO fk_vis_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA fk_vis GRANT SELECT ON TABLES TO fk_vis_reader;

CREATE TABLE fk_vis.item (
  item INT GENERATED ALWAYS AS IDENTITY,
  name VARCHAR(255) NOT NULL,
  PRIMARY KEY(item)
);

CREATE TABLE fk_vis.customer (
  customer INT GENERATED ALWAYS AS IDENTITY,
  name VARCHAR(255) NOT NULL,
  PRIMARY KEY(customer)
);

CREATE TABLE fk_vis.sale (
  sale INT GENERATED ALWAYS AS IDENTITY,
  item INT,
  customer INT,
  PRIMARY KEY(sale),
  CONSTRAINT fk_item
    FOREIGN KEY(item)
    REFERENCES fk_vis.item(item),
  CONSTRAINT fk_customer
    FOREIGN KEY(customer)
    REFERENCES fk_vis.customer(customer)
);

Running atlas schema inspect using our two users gives different results

fk_vis_owner
> atlas schema inspect -u "postgres://fk_vis_owner:pwd123@localhost:5432/fk_vis_reprex?search_path=fk_vis&sslmode=disable"

table "customer" {
  schema = schema.fk_vis
  column "customer" {
    null = false
    type = integer
    identity {
      generated = ALWAYS
    }
  }
  column "name" {
    null = false
    type = character_varying(255)
  }
  primary_key {
    columns = [column.customer]
  }
}
table "item" {
  schema = schema.fk_vis
  column "item" {
    null = false
    type = integer
    identity {
      generated = ALWAYS
    }
  }
  column "name" {
    null = false
    type = character_varying(255)
  }
  primary_key {
    columns = [column.item]
  }
}
table "sale" {
  schema = schema.fk_vis
  column "sale" {
    null = false
    type = integer
    identity {
      generated = ALWAYS
    }
  }
  column "item" {
    null = true
    type = integer
  }
  column "customer" {
    null = true
    type = integer
  }
  primary_key {
    columns = [column.sale]
  }
  foreign_key "fk_customer" {
    columns     = [column.customer]
    ref_columns = [table.customer.column.customer]
    on_update   = NO_ACTION
    on_delete   = NO_ACTION
  }
  foreign_key "fk_item" {
    columns     = [column.item]
    ref_columns = [table.item.column.item]
    on_update   = NO_ACTION
    on_delete   = NO_ACTION
  }
}
schema "fk_vis" {
}
fk_vis_reader
> atlas schema inspect -u "postgres://fk_vis_reader:pwd345@localhost:5432/fk_vis_reprex?sslmode=disable" --schema fk_vis

table "customer" {
  schema = schema.fk_vis
  column "customer" {
    null = false
    type = integer
    identity {
      generated = ALWAYS
    }
  }
  column "name" {
    null = false
    type = character_varying(255)
  }
  primary_key {
    columns = [column.customer]
  }
}
table "item" {
  schema = schema.fk_vis
  column "item" {
    null = false
    type = integer
    identity {
      generated = ALWAYS
    }
  }
  column "name" {
    null = false
    type = character_varying(255)
  }
  primary_key {
    columns = [column.item]
  }
}
table "sale" {
  schema = schema.fk_vis
  column "sale" {
    null = false
    type = integer
    identity {
      generated = ALWAYS
    }
  }
  column "item" {
    null = true
    type = integer
  }
  column "customer" {
    null = true
    type = integer
  }
  primary_key {
    columns = [column.sale]
  }
}
schema "fk_vis" {
}

with foreign keys missing for the second invocation (using the "reader" user, i.e. not the owner of the tables).

From what I understand, there is no restriction for getting this information as the "reader" user (as psql -d fk_vis_reprex -U fk_vis_reader):

SELECT conrelid::regclass AS table_name,
       conname AS foreign_key,
       pg_get_constraintdef(oid)
FROM   pg_constraint
WHERE  contype = 'f'
AND    connamespace = 'fk_vis'::regnamespace
ORDER  BY conrelid::regclass::text, contype DESC;
#>  table_name  | foreign_key |                    pg_get_constraintdef
#>  -------------+-------------+-------------------------------------------------------------
#>  fk_vis.sale | fk_item     | FOREIGN KEY (item) REFERENCES fk_vis.item(item)
#>  fk_vis.sale | fk_customer | FOREIGN KEY (customer) REFERENCES fk_vis.customer(customer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant