SPI_execute

SPI_execute — executa um comando

Sinopse

int SPI_execute(const char * command, bool read_only, long count)

Descrição

A função SPI_execute executa o comando SQL especificado para count linhas. Se o parâmetro read_only for true, o comando deverá ser de leitura-apenas, e a sobrecarga de execução será um pouco reduzida.

Esta função só pode ser chamada a partir de uma função C conectada.

Se o parâmetro count for zero, o comando será executado para todas as linhas às quais se aplica. Se o parâmetro count for maior que zero, então não mais que count linhas serão recuperadas; a execução termina quando a contagem é atingida, assim como se tivesse sido adicionada uma cláusula LIMIT à consulta. Por exemplo,

SPI_execute("SELECT * FROM foo", true, 5);

irá recuperar no máximo 5 linhas da tabela. Note que este limite só é efetivo quando o comando realmente retorna linhas. Por exemplo,

SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);

insere todas as linhas de bar em foo, ignorando o parâmetro count. No entanto, em

SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);

seriam inseridas no máximo 5 linhas, já que a execução iria parar após a quinta linha de resultado da cláusula RETURNING ser recuperada.

Podem ser passados vários comandos em uma cadeia de caracteres; a função SPI_execute retorna o resultado do último comando executado. O limite count se aplica a cada comando separadamente (mesmo que apenas o último resultado seja realmente retornado). O limite não se aplica a nenhum comando oculto gerado por regras.

Quando o parâmetro read_only é false, a função SPI_execute incrementa o contador de comandos, e calcula um novo instantâneo antes de executar cada comando na cadeia de caracteres. O instantâneo não mudará se o nível de isolamento da transação corrente for SERIALIZABLE ou REPEATABLE READ, mas no modo READ COMMITTED a atualização do instantâneo permite que cada comando veja os resultados de transações recentemente efetivadas de outras sessões. Isto é essencial para um comportamento consistente quando os comandos modificam o banco de dados.

Quando o parâmetro read_only é true, a função SPI_execute não atualiza o instantâneo nem o contador de comandos, e permite que apenas comandos SELECT simples apareçam na cadeia de caracteres de comando. Os comandos são executados usando o instantâneo previamente estabelecido para a consulta envoltória. Este modo de execução é um pouco mais rápido que o modo de leitura/escrita devido à eliminação da sobrecarga por comando. Também permite que sejam construídas funções genuinamente estáveis: uma vez que todas as execuções sucessivas usam o mesmo instantâneo, não há alteração nos resultados.

Geralmente não é aconselhável misturar comandos de leitura-apenas com leitura-escrita em uma única função usando a SPI; isto pode resultar em um comportamento muito confuso, já que as consultas de leitura-apenas não veriam os resultados de nenhuma atualização no banco de dados feita pelas consultas de leitura/escrita.

O número real de linhas para as quais o (último) comando foi executado é retornado na variável global SPI_processed. Se o valor retornado pela função for SPI_OK_SELECT, SPI_OK_INSERT_RETURNING, SPI_OK_DELETE_RETURNING, SPI_OK_UPDATE_RETURNING ou SPI_OK_MERGE_RETURNING, então poderá ser usado o ponteiro global SPITupleTable *SPI_tuptable para acessar as linhas do resultado. Alguns comandos utilitários (como o EXPLAIN) também retornam conjuntos de linhas, e SPI_tuptable também contém o resultado nesses casos. Alguns comandos utilitários (COPY, CREATE TABLE AS) não retornam um conjunto de linhas, então SPI_tuptable é NULL, mas eles ainda retornam o número de linhas processadas em SPI_processed.

A estrutura SPITupleTable é definida assim:

typedef struct SPITupleTable
{
    /* Membros públicos */
    TupleDesc   tupdesc;        /* descritor da tupla */
    HeapTuple  *vals;           /* matriz de tuplas */
    uint64      numvals;        /* número de tuplas válidas */

    /* Membros privados, não destinados a chamadores externos */
    uint64      alloced;        /* comprimento alocado da matriz vals */
    MemoryContext tuptabcxt;    /* contexto de memória da tabela de resultados */
    slist_node  next;           /* link para escrituração interna */
    SubTransactionId subid;     /* subxact em que tuptable foi criado */
} SPITupleTable;

Os membros tupdesc, vals, e numvals podem ser usados por funções que usam a SPI; os campos restantes são internos. O membro vals é uma matriz de ponteiros para linhas. O número de linhas é dado por numvals (por razões um tanto históricas, esta contagem também é retornada em SPI_processed). O membro tupdesc é um descritor de linha que pode ser passado para funções SPI que lidam com linhas.

A função SPI_finish libera todos as estruturas SPITupleTables alocados durante a função C corrente. É possível liberar os resultados de uma tabela específica mais cedo, se tiver terminado, chamando SPI_freetuptable.

Argumentos

const char * command

cadeia de caracteres contendo comando para executar

bool read_only

true para execução de leitura-apenas

long count

número máximo de linhas a serem retornadas, ou 0 para sem limite

Valor retornado

Se a execução do comando for bem-sucedida, será retornado um dos seguintes valores (não negativos):

SPI_OK_SELECT

se foi executado um SELECT (mas não um SELECT INTO)

SPI_OK_SELINTO

se foi executado um SELECT INTO

SPI_OK_INSERT

se foi executado um INSERT

SPI_OK_DELETE

se foi executado um DELETE

SPI_OK_UPDATE

se foi executado um UPDATE

SPI_OK_MERGE

se foi executado um MERGE

SPI_OK_INSERT_RETURNING

se foi executado um INSERT RETURNING

SPI_OK_DELETE_RETURNING

se foi executado um DELETE RETURNING

SPI_OK_UPDATE_RETURNING

se foi executado um UPDATE RETURNING

SPI_OK_MERGE_RETURNING

se foi executado um MERGE RETURNING

SPI_OK_UTILITY

se foi executado um comando utilitário (por exemplo, CREATE TABLE)

SPI_OK_REWRITTEN

se o comando foi reescrito em outro tipo de comando por uma regra (por exemplo, UPDATE se tornou INSERT).

Em caso de erro, é retornado um dos seguintes valores negativos:

SPI_ERROR_ARGUMENT

se o parâmetro command for NULL, ou count for menor que zero

SPI_ERROR_COPY

Se foi tentado COPY TO stdout ou COPY FROM stdin

SPI_ERROR_TRANSACTION

se foi tentado um comando de manipulação de transação (BEGIN, COMMIT, ROLLBACK, SAVEPOINT, PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED, ou qualquer variante deles)

SPI_ERROR_OPUNKNOWN

se o tipo de comando for desconhecido (não deveria acontecer)

SPI_ERROR_UNCONNECTED

se chamado de uma função C não conectada

Notas

Todas as funções de execução de consulta da SPI definem SPI_processed e SPI_tuptable (apenas o ponteiro, não o conteúdo da estrutura). Estas duas variáveis ​​globais devem ser salvas em variáveis ​​locais da função C, se for necessário acessar a tabela de resultados de SPI_execute ou outra função de execução de consulta em chamadas posteriores.