SPI_execute — executa um comando
int SPI_execute(const char *command, boolread_only, longcount)
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.
const char * commandcadeia de caracteres contendo comando para executar
bool read_onlytrue para execução de leitura-apenas
long count
número máximo de linhas a serem retornadas, ou
0 para sem limite
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_OPUNKNOWNse o tipo de comando for desconhecido (não deveria acontecer)
SPI_ERROR_UNCONNECTEDse chamado de uma função C não conectada
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.