[DB error] PostgreSQL, for tables without sequences get "Undefined table: ERROR: relation '%_seq' does not exist"
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Facilidade para iniciantes
- 45/100
Direção de pesquisa
Comece em Codeception\Lib\Driver\PostgreSql::lastInsertId e, em seguida, rastreie como Db::haveInDatabase o utiliza para o driver PostgreSQL. Reproduza o exemplo com uma tabela que tenha uma chave primária inteira, mas nenhuma sequência, e adicione cobertura mostrando que a inserção é concluída sem o erro undefined-relation quando nenhuma sequência existe.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Hi, found this little issue, I get an error when insert a row into a table that has NO sequence, one possible use case - it could happen with UUID as primary key that are generated on an application side, so it's not completely imaginary case :)
I'm using postgres:15, codeception/module-db looks like version 3.1.0,
and for example I have a table (for simplicity, integer primary key, no sequence)
create table t
(
c integer not null primary key
);
Then I call \Codeception\Module\Db::haveInDatabase ($this->tester->haveInDatabase('t', ['c' => 1]);) in my test and see in the console
[DB error] SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "t_c_seq" does not exist
Row is inserted, but after it is trying to extract last inserted ID and (cause it's not possible) it fails.
Happens here in \Codeception\Lib\Driver\PostgreSql::lastInsertId
public function lastInsertId(string $tableName): string
{
$sequenceName = $this->getQuotedName($tableName . '_id_seq');
$lastSequence = null;
try {
$lastSequence = $this->getDbh()->lastInsertId($sequenceName);
} catch (PDOException $exception) {
// in this case, the sequence name might be combined with the primary key name
}
if (!$lastSequence) {
$primaryKeys = $this->getPrimaryKey($tableName);
$pkName = array_shift($primaryKeys);
// next line we get an error
$lastSequence = $this->getDbh()->lastInsertId($this->getQuotedName($tableName . '_' . $pkName . '_seq'));
}
return $lastSequence;
}
And I guess technically that is not an error, because we never should be checking for a last inserted ID in those cases.
Not really sure how to better handle this case, maybe it is possible to add some additional checks before calling \Codeception\Lib\Driver\Db::lastInsertId, trying to detect if a sequence for the given table even exists. If there are no sequence - no need to call \Codeception\Lib\Driver\Db::lastInsertIdmaybe?
In that case I found this monster here https://dba.stackexchange.com/questions/260975/postgresql-how-can-i-list-the-tables-to-which-a-sequence-belongs
SELECT t.oid::regclass AS table_name,
a.attname AS column_name,
s.relname AS sequence_name
FROM pg_class AS t
JOIN pg_attribute AS a
ON a.attrelid = t.oid
JOIN pg_depend AS d
ON d.refobjid = t.oid
AND d.refobjsubid = a.attnum
JOIN pg_class AS s
ON s.oid = d.objid
WHERE d.classid = 'pg_catalog.pg_class'::regclass
AND d.refclassid = 'pg_catalog.pg_class'::regclass
AND d.deptype IN ('i', 'a')
AND t.relkind IN ('r', 'P')
AND s.relkind = 'S';
Maybe it is possible to filter by table and if there is no sequences - return 0 or smth like that. But I'm not sure how to handle different postgresql's version issues - if there's any...
Or add a custom exception and throw it in the lastInsertId method, checking sequence's existence before calling \PDO::lastInsertId. Don't like that one though) But the names for a sequence are building and checking inside this method..
Would be happy to discuss or just hear your thoughts about it, and if I'm lucky even make MR :)
I could try to provide a test that covers that case and fails?
- Linguagem predominante
- PHP
- Estrelas
- 23
- Forks
- 31
- Métricas de merge de PRs
- Nenhum PR com merge em 30d
Preparar o ambiente
- Inclui um Dockerfile ou arquivo Docker Compose
- Sem modelo de pull request
- Sem guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de Codeception/module-db
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 42/100
Codeception/module-db#87 ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 25/100
Codeception/module-db#85 ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 35/100
Codeception/module-db#68 · 1 comentário ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 35/100
Codeception/module-db#67 ·
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 38/100
Codeception/module-db#58 ·
Todas as issues de Codeception/module-db
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
PrestaShopCorp/ps_accounts#666 ·
-
Security SecurityBundle
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
symfony/symfony-docs#23173 ·
Mantenedores costumam responder em até 3 dias
-
incomplete
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
opnsense/plugins#5763 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
fossology/fossology#3893 · 1 comentário ·
Mantenedores costumam responder em até 2 dias
-
Documentation Feature: Self-Register / Verify UI
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
Mantenedores costumam responder em até 1 dia