Database a detekcia typu – chyba pri dátovom type TINYINT
- dakota
- Člen | 148
Nette Framework 2.0-dev rev. f8b6f0f released on 2011–02–24
V Nette\Database pri detekcii typu ak ide o dátový typ TINYINT tak to vyhadzuje chybu:
PHP Notice: Undefined index: native_type in ...\libs\Nette\Database\Statement.php:103
Ide asi o bug v PHP, kde PDO v getColumnMeta nevráti pri TINYINT, YEAR a BIT native_type http://bugs.php.net/bug.php?….
Chybu som spozoroval v PHP 5.2 aj 5.3
Tiež by som chcel upozorniť na chybu v DatabasePanel kde sa zobrazuje iný počet dotazov a čas v tabe a iný v paneli – v paneli sa k počte dotazov a k času pripočitajú aj explain dotazy.
Editoval dakota (24. 2. 2011 19:16)
- David Grudl
- Nette Core | 8228
Bohužel nic spolehlivějšího neznám. PDO je, zdá se, zatím hodně nedotažené.
- David Grudl
- Nette Core | 8228
No pokud to nepodporují, tak se to přetypovávat nebude. Nenapadá mě
důvod, proč by někdo přetypování vypínal, pokud do DB uložím integer,
tak očekávám integer i na výstupu. Takže spíš bych udělal fix pro
špatně fungující getColumnMeta() (je to experimental už 5 let a koukám,
že od 5.3 do vrací nesmyslně i položku len
).
- David Grudl
- Nette Core | 8228
Nefunguje? Postgres tu nemám, můžete někdo prosím ověřit, že se všechny typy přetypovávají správně?
- dakota
- Člen | 148
Asi je to len dočasne zle fungujúce (revízia z 24.02.2011): po type TINYINT – chybajúci native_type – dôjde k tomu že sa na detekciu typu používa zlý index stĺpca (na základe count($this->types)) a tym prestane správne pretypovávať ostatné zvyšné stĺpce.
$this->types = array();
foreach ($row as $key => $foo) {
$type = $this->getColumnMeta(count($this->types));
if (isset($type['native_type'])) {
$this->types[$key] = NDatabaseReflection::detectType($type['native_type']);
}
}
Editoval dakota (25. 2. 2011 20:27)
- Ondřej Mirtes
- Člen | 1536
Průšvih je, že když to přijde z databáze, tak nevíš, jestli máš uložený string ‚t‘ nebo true, resp. string ‚f‘ nebo false. Řešením je uložit si informaci o typu sloupce ještě někam vedle v PHP.
PostgreSQL je jinak skvělá databáze :)
- David Grudl
- Nette Core | 8228
Boolean by to mělo zvládat bez obtíží https://github.com/…tatement.php#L126
- PaBi3
- Bronze Partner | 62
Je korektné chovanie, že napr. pri inserte, či update nie sú vstupné údaje normalizované na správne typy?
V prípade, že používam PostgreSQL a vložím nejaké údaje do tabuľky,
ktorá má stĺpec typu boolean, tak sa vyhodí PDOException:
Datatype mismatch: 7 ERROR: column "visible" is of type boolean but expression is of type integer
.
- PaBi3
- Bronze Partner | 62
Áno. Ak chceš napr. vložiť PHP boolean hodnotu do PostgreSQL so stĺpcom boolean, tak sa nepretypuje.
Ako workaround máš možnosť boolean vkladať ako string
true
/false
. Myslím, že v dibi existovalo
detectTypes, ktoré typy automaticky rozpoznalo a tento problém riešilo.
<?php
$db->table('test')->insert(array('somebool' => true)); // vyhodí PDOException
$db->table('test')->insert(array('somebool' => 'true')); // prejde
?>
- David Grudl
- Nette Core | 8228
To se může vyhodnotit dvěma způsoby, zkus teda obojí:
$database->query('INSERT INTO tbl VALUES(?)', array(TRUE, FALSE));
$database->query('INSERT INTO tbl VALUES(?, ?)', TRUE, FALSE);
Které z toho selže?
- PaBi3
- Bronze Partner | 62
Selže iba to prvé za predpokladu štruktúry:
create table tbl (
data1 boolean,
data2 boolean
);
Lenže je bežnou praxou insertovať rovno údaje z formulára. Napr.:
<?php
$form = $form->getValues();
$database->table('tbl')->insert($values);
?>
To týmto pádom nefunguje, ak mám v tabuľke boolean stĺpec.
Editoval PaBi3 (24. 3. 2011 15:42)
- dakota
- Člen | 148
PDO v MySQL v getColumnMeta() nevráti pri TINYINT, YEAR a BIT native_type,
Ak je niektorý z stĺpcov typu TINYINT, YEAR a BIT, tak v MySQL pri načítaní dat sú ostatné zvyšné stĺpce nesprávne pretypované – je to spôsobené chybným count($this->types).
Uprava Database\Statement::normalizeRow() – doplnené else {…}:
foreach ($row as $key => $foo) {
$type = $this->getColumnMeta(count($this->types));
if (isset($type['native_type'])) {
$this->types[$key] = Reflection\DatabaseReflection::detectType($type['native_type']);
} else {
$this->types[$key] = NULL;
// prip. $this->types[$key] = Reflection\DatabaseReflection::FIELD_UNKNOWN;
}
}
Editoval dakota (2. 6. 2011 12:35)