CREATE FOREIGN TABLE

CREATE FOREIGN TABLE — define uma nova tabela estrangeira

Sinopse

CREATE FOREIGN TABLE [ IF NOT EXISTS ] nome_da_tabela ( [
    { nome_da_coluna tipo_de_dados
    [ OPTIONS ( opção 'valor'
    [, ... ] ) ]
    [ COLLATE ordenação ] [ restrição_de_coluna
    [ ... ] ]
    | restrição_de_tabela
    | LIKE tabela_de_origem [ opção_de_cópia ... ] }
    [, ... ]
] )
[ INHERITS ( tabela_mãe [, ... ] ) ]
  SERVER nome_do_servidor
[ OPTIONS ( opção 'valor' [, ... ] ) ]

CREATE FOREIGN TABLE [ IF NOT EXISTS ] nome_da_tabela
  PARTITION OF tabela_mãe [ (
  { nome_da_coluna
    [ WITH OPTIONS ] [ restrição_de_coluna [ ... ] ]
    | restrição_de_tabela }
  [, ... ]
) ]
{ FOR VALUES especificação_de_limite_de_partição | DEFAULT }
  SERVER nome_do_servidor
[ OPTIONS ( opção 'valor' [, ... ] ) ]

onde restrição_de_coluna é:

[ CONSTRAINT nome_da_restrição ]
{ NOT NULL [ NO INHERIT ] |
  NULL |
  CHECK ( expressão ) [ NO INHERIT ] |
  DEFAULT expressão_padrão |
  GENERATED ALWAYS AS ( expressão_de_geração ) [ STORED | VIRTUAL ] }
[ ENFORCED | NOT ENFORCED ]

e restrição_de_tabela é:

[ CONSTRAINT nome_da_restrição ]
{ NOT NULL nome_da_coluna [ NO INHERIT ] |
  CHECK ( expressão ) [ NO INHERIT ] }
[ ENFORCED | NOT ENFORCED ]

e opção_de_cópia é:

{ INCLUDING | EXCLUDING }
  { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | STATISTICS | ALL }

e especificação_de_limite_de_partição é:

IN ( expressão_de_limite_de_partição [, ...] ) |
FROM ( { expressão_de_limite_de_partição | MINVALUE | MAXVALUE } [, ...] )
  TO ( { expressão_de_limite_de_partição | MINVALUE | MAXVALUE } [, ...] ) |
WITH ( MODULUS literal_numérico, REMAINDER literal_numérico )

Descrição

O comando CREATE FOREIGN TABLE define uma nova tabela estrangeira no banco de dados corrente. O usuário que executa o comando ser torna o dono da tabela.

Se for fornecido o nome do esquema (por exemplo, CREATE FOREIGN TABLE meu_esquema.minha_tabela ...), a tabela será criada no esquema especificado. Caso contrário, será criada no esquema corrente. O nome da tabela estrangeira deve ser distinto do nome de qualquer outra relação (tabela, sequência, índice, visão, visão materializada ou tabela estrangeira) no mesmo esquema.

O comando CREATE FOREIGN TABLE também cria automaticamente o tipo de dados que representa o tipo composto correspondente a uma linha da tabela estrangeira. Portanto, as tabelas estrangeiras não podem ter o mesmo nome de nenhum tipo de dados existente no mesmo esquema.

Se for especificada a cláusula PARTITION OF, a tabela será criada como uma partição da tabela_mãe com os limites especificados.

Para poder criar uma tabela estrangeira, é necessário ter o privilégio USAGE ON FOREIGN SERVER no servidor estrangeiro, bem como o privilégio USAGE em todos os tipos de dados de coluna usados na tabela.

Parâmetros

IF NOT EXISTS

Não relata um erro se já existir uma relação com o mesmo nome. É emitido um aviso neste caso. Note não haver garantia de que a relação existente seja semelhante com a que deveria ter sido criada.

nome_da_tabela

O nome (opcionalmente qualificado pelo esquema) da tabela a ser criada.

nome_da_coluna

O nome da coluna a ser criada na nova tabela.

tipo_de_dados

O tipo de dados da coluna. Pode incluir especificadores de matriz. Para obter mais informações sobre os tipos de dados com suporte no PostgreSQL, veja Tipos de dados.

COLLATE ordenação

A cláusula COLLATE atribui uma ordenação à coluna (que deve ser de um tipo de dados que possa ser ordenado). Se não for especificada, será usada a ordenação padrão do tipo de dados da coluna.

INHERITS ( tabela_mãe [, ... ] )

A cláusula opcional INHERITS especifica uma lista de tabelas das quais a nova tabela estrangeira herda automaticamente todas as colunas. As tabelas mãe podem ser tabelas comuns ou tabelas estrangeiras. Veja a forma semelhante do comando CREATE TABLE para obter mais detalhes.

PARTITION OF tabela_mãe { FOR VALUES especificação_de_limite_de_partição | DEFAULT }

Esta forma pode ser usada para criar a tabela estrangeira como uma partição da tabela mãe indicada, com os valores de limite de partição especificados. Veja a forma semelhante do comando CREATE TABLE para obter mais detalhes. Note que, no momento, não é permitido criar a tabela estrangeira como uma partição da tabela mãe, se houver índices UNIQUE na tabela mãe. (Veja também o comando ALTER TABLE.)

LIKE tabela_de_origem [ opção_de_cópia ... ]

A cláusula LIKE especifica uma tabela da qual a nova tabela copia automaticamente todos os nomes de coluna, seus tipos de dados e suas restrições de não nulo.

Diferentemente de INHERITS, a nova tabela e a tabela de origem são completamente desacopladas após a conclusão da criação. As alterações feitas na tabela de origem não serão aplicadas à nova tabela, e não é possível incluir dados da varreduras da nova tabela na tabela de origem.

Diferentemente de INHERITS, as colunas e restrições copiadas por LIKE não são mescladas com colunas e restrições de nomes semelhantes. Se o mesmo nome for especificado explicitamente ou em outra cláusula LIKE, será sinalizado um erro.

As cláusulas opcionais opção_de_cópia especificam quais propriedades adicionais da tabela de origem devem ser copiadas. Especificar INCLUDING copia a propriedade, especificar EXCLUDING omite a propriedade. EXCLUDING é o padrão. Caso sejam feitas várias especificações para o mesmo tipo de objeto, será utilizada a última. As opções disponíveis são:

INCLUDING COMMENTS

Serão copiados os comentários das colunas e restrições copiadas. O comportamento padrão é excluir os comentários, resultando em colunas e restrições copiadas na nova tabela ficando sem comentários.

INCLUDING CONSTRAINTS

As restrições CHECK serão copiadas. Não é feita distinção entre restrições de coluna e restrições de tabela. As restrições de não-nulo são sempre copiadas para a nova tabela.

INCLUDING DEFAULTS

Serão copiadas as expressões de padrão para as definições de coluna copiadas. Caso contrário, as expressões de padrão não são copiadas, resultando em colunas copiadas na nova tabela tendo como valore padrão o valor nulo. Note que copiar valores padrão que chamam funções de modificação de banco de dados, como nextval, pode criar um vínculo funcional entre as tabelas de origem e a nova.

INCLUDING GENERATED

Serão copiadas quaisquer expressões de geração de definições de coluna copiadas. Por padrão, as novas colunas serão colunas base regulares.

INCLUDING STATISTICS

Serão copiadas as estatísticas estendidas para a nova tabela.

INCLUDING ALL

INCLUDING ALL é uma forma abreviada que seleciona todas as opções individuais disponíveis. (Pode ser útil escrever cláusulas individuais EXCLUDING após INCLUDING ALL para selecionar todas as opções, exceto algumas específicas.)

CONSTRAINT nome_da_restrição

O nome opcional para uma restrição de coluna ou tabela. Se a restrição for violada, o nome da restrição estará presente nas mensagens de erro, portanto, podem ser usados nomes de restrição como "col deve ser positivo" para comunicar informações úteis da restrição às aplicações cliente. (É necessário o uso de aspas para especificar nomes de restrições que contêm espaços.) Se não for especificado o nome da restrição, o sistema irá gerar um nome.

NOT NULL [ NO INHERIT ]

A coluna não pode conter valores nulos.

Uma restrição marcada com NO INHERIT não será propagada para as tabelas filhas.

NULL

A coluna pode conter valores nulos. Este é o padrão.

Esta cláusula é fornecida apenas para manter a compatibilidade com bancos de dados SQL fora do padrão. Seu uso é desencorajado em novas aplicações.

CHECK ( expressão ) [ NO INHERIT ]

A cláusula CHECK especifica uma expressão que produz um resultado booleano que cada linha na tabela estrangeira deve satisfazer; ou seja, a expressão deve produzir TRUE ou UNKNOWN, e nunca FALSE, para todas as linhas da tabela estrangeira. Uma restrição de verificação especificada como restrição de coluna deve fazer referência apenas ao valor dessa coluna, enquanto uma expressão que aparece em uma restrição de tabela pode fazer referência a várias colunas.

No momento, as expressões CHECK não podem conter subconsultas, nem se referir a variáveis que não sejam colunas da linha corrente. A coluna do sistema tableoid pode ser referenciada, mas não qualquer outra coluna do sistema.

Uma restrição marcada com NO INHERIT não será propagada para as tabelas filhas.

DEFAULT expressão_padrão

A cláusula DEFAULT atribui um valor de dados padrão para a coluna em cuja definição de coluna aparece. O valor é qualquer expressão livre de variável (não são permitidas subconsultas e referências cruzadas a outras colunas na tabela corrente). O tipo de dados da expressão de valor padrão deve corresponder ao tipo de dados da coluna.

A expressão de valor padrão será usada em qualquer operação de inserção que não especifique um valor para a coluna. Se não houver valor padrão para a coluna, o valor padrão será o valor nulo.

GENERATED ALWAYS AS ( expressão_de_geração ) [ STORED | VIRTUAL ]

Esta cláusula cria a coluna como uma coluna gerada. A coluna não pode ser escrita e, quando lida, será retornado o resultado da expressão especificada.

Quando for especificado VIRTUAL, a coluna será calculada no momento da leitura. (O empacotador de dados estrangeiros irá interpretar isto como um valor nulo em novas linhas, podendo optar por armazená-lo como um valor nulo ou ignorá-lo completamente.) Quando for especificado STORED, a coluna será calculada na escrita. (O valor calculado será apresentado ao empacotador de dados estrangeiros para armazenamento e deverá ser retornado na leitura.) O padrão é VIRTUAL.

A expressão de geração pode se referir a outras colunas na tabela, mas não a outras colunas geradas. Quaisquer funções e operadores usados devem ser imutáveis. Não são permitidas referências a outras tabelas.

nome_do_servidor

O nome do servidor estrangeiro existente a ser usado para a tabela estrangeira. Para obter detalhes sobre como definir um servidor, veja o comando CREATE SERVER.

OPTIONS ( opção 'valor' [, ...] )

As opções a serem associadas à nova tabela estrangeira, ou a uma de suas colunas. Os nomes e valores de opção permitidos são específicos para cada empacotador de dados estrangeiros, e são validados usando a função validadora do empacotador de dados estrangeiros. Não são permitidos nomes de opção duplicados (embora seja aceitável que uma opção de tabela e uma opção de coluna tenham o mesmo nome).

Notas

As restrições em tabelas estrangeiras (como as cláusulas CHECK e NOT NULL) não são impostas pelo sistema PostgreSQL principal, e a maioria dos empacotadores de dados estrangeiros também não tenta aplicá-los; ou seja, simplesmente assume-se que a restrição seja verdade. Haveria pouco sentido em tal imposição, porque só se aplicaria a linhas inseridas ou atualizadas por meio da tabela estrangeira, e não a linhas modificadas por outros meios, como diretamente no servidor remoto. Em vez disso, uma restrição anexada a uma tabela estrangeira deve representar uma restrição que está sendo imposta pelo servidor remoto.

Alguns empacotadores de dados estrangeiros de finalidade especial podem ser o único mecanismo de acesso para os dados que eles acessam e, neste caso, pode ser apropriado para o próprio empacotador de dados estrangeiros executar a imposição da restrição. Mas não se deve assumir que o empacotador de dados estrangeiros faça isto, a menos que sua documentação diga isto.

Embora o PostgreSQL não tente impor restrições em tabelas estrangeiras, ele assume que elas estão corretas para fins de otimização de consulta. Se houver linhas visíveis na tabela estrangeira que não satisfaçam uma restrição declarada, as consultas na tabela poderão produzir erros ou respostas incorretas. É responsabilidade do usuário garantir que a definição da restrição corresponda à realidade.

Cuidado

Quando uma tabela estrangeira é usada como uma partição de uma tabela particionada, há uma restrição implícita de que seu conteúdo deve satisfazer a regra de particionamento. Novamente, é responsabilidade do usuário garantir que isto seja verdade, o que é melhor feito instalando uma restrição correspondente no servidor remoto.

Em uma tabela particionada contendo partições de tabelas estrangeiras, um comando UPDATE que altera o valor da chave de partição pode fazer com que a linha seja movida de uma partição local para uma partição de tabela estrangeira, desde que o empacotador de dados estrangeiros forneça suporte a roteamento de tupla. No entanto, no momento não é possível mover uma linha de uma partição de tabela estrangeira para outra partição. Um comando UPDATE exigindo isto irá falhar devido à restrição de particionamento, assumindo que isto é devidamente aplicado pelo servidor remoto.

Considerações semelhantes se aplicam a colunas geradas. As colunas geradas armazenadas são calculadas na inserção ou atualização no servidor PostgreSQL local, e entregues ao empacotador de dados estrangeiros para escrita no armazenamento de dados estrangeiro, mas não é obrigatório que uma consulta à tabela estrangeira retorne valores para colunas geradas armazenadas que sejam consistentes com a expressão de geração. Novamente, isto pode resultar em resultados de consulta incorretos.

Exemplos

Criar a tabela estrangeira films, que será acessada através do servidor film_server:

CREATE FOREIGN TABLE films (
    code        char(5) NOT NULL,
    title       varchar(40) NOT NULL,
    did         integer NOT NULL,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute
)
SERVER film_server;

Criar a tabela estrangeira measurement_y2016m07, que será acessada através do servidor server_07, como uma partição da tabela particionada por intervalo measurement:

CREATE FOREIGN TABLE measurement_y2016m07
    PARTITION OF measurement FOR VALUES FROM ('2016-07-01') TO ('2016-08-01')
    SERVER server_07;

Conformidade

O comando CREATE FOREIGN TABLE está bastante em conformidade com o padrão SQL; no entanto, assim como no comando CREATE TABLE, são permitidas restrições NULL e tabelas estrangeiras de zero-colunas. A capacidade de especificar valores padrão de coluna também é uma extensão do PostgreSQL. A herança de tabela, na forma definida pelo PostgreSQL, não é a padrão. A cláusula LIKE, da forma como tem suporte neste comando, não é padrão.

Veja também

ALTER FOREIGN TABLE, DROP FOREIGN TABLE, CREATE TABLE, CREATE SERVER, IMPORT FOREIGN SCHEMA