PostgreSQL bug s hledáním podle macaddr type a octet v uvozovkách
- heekon
- Člen | 28
Ahoj ve spolek,
nevím zda se jedná o bug Nette či nikoliv, ale s největší
pravděpodobností ano. O co jde.
Mám funkci v PGSQL, která hledá záznamy v tabulkách podle „macaddr“
type. Normálně to funguje přes query v SQL, ale v Nette vzniká
problém.
Pokud ve vyhledávání použiji MAC 00:10:25:33:45:51, tak je to ok a projde
to.
Pokud ve vyhledávání použiji MAC 00:10:25:3B:45:51, tak je to ok a projde
to.
Pokud ve vyhledávání použiji MAC 00:10:25:B3:45:51, tak to vyhodí laděnku
a chybu ve špatném syntaxu, kdy z nějakého divného důvodu se do dotazu
cpou v adrese uvozovky tam, kde je na začátku octetu písmeno a pak adresa
vypadá v dotazu takto:
00:10:25:"B3":45:51
Samozřejmě díky tomu to nefunguje.
Používám Nette 2.0.10.
Kdyby někdo věděl kde je problém, tak bych byl vděčný. Dík.
PS: udělal jsem si dump před odesláním query na backend Nette a tam je vše v pořádku, tedy chyba není třeba v přeformátování při odeslání formuláře
PPS: jo a ještě detail, funkce v PGSQL bere macaddr jako argument type text, nevim, ale třeba to pomůže, že i tam by mohl být zakopaný pes – musel být použit type text, protože EXECUTE nemíchá typy
Editoval heekon (3. 10. 2013 10:57)
- heekon
- Člen | 28
hrach napsal(a):
No tak hlavne nam rekni, jaky dotaz to posila? A jak ho volas.
No, funkce může vypadat asi takto (resp. vypadá):
CREATE OR REPLACE FUNCTION getdevicebymac(macaddr text)
RETURNS SETOF devicedata AS
$$
DECLARE
tables record;
devRow devicedata%ROWTYPE;
BEGIN
FOR tables IN SELECT * FROM mactables LOOP
EXECUTE 'SELECT * FROM ' || tables.table_name || ' WHERE mac = \'' || macaddr || '\'' INTO devRow;
IF devRow.mac IS NOT NULL THEN
RETURN NEXT devRow;
END IF;
END LOOP;
RETURN;
END;
$$
LANGUAGE plpgsql VOLATILE;
Volám pak dotaz:
$result = $this->connection->table("getdevicebymac('".$mac."')")->select('ip,vlan')->where(array("family(ip)" => 4))->limit(1)->fetch();
Laděnka vyhodí → pokud hledám mac e0:b2:4e:25:21:99:
SELECT "ip","vlan"
FROM getdevicebymac('"e0":"b2":4e:25:21:99')
WHERE (family("ip") = ?)
LIMIT 1
Asi může být problém i v PDO, že si upravuje dotaz dle typu argumentu, ale pak bych tedy potřeboval obejít tenhle zásah „shora“. Jak jsem uvedl, proměná $mac v query je v pořádku, když ji dumpnu ještě před provedením odeslání dotazu.
Editoval heekon (3. 10. 2013 11:22)
- hrach
- Člen | 1844
No, problem je, ze natvrdo busis spojeni stringu, misto toho, aby si pouzil
placeholder. Smula je, ze ten u table()
nepodporujeme. Funguje
volani funkce s uvozovkami? Pokud ano, tak to je pro tebe mozny fix, pokud ne,
tak ne.
Nicmene: pro dane pouziti, co delas, je NAPROSTO nevhodne pouzivat Selection, nevyuzivas ani predikci pouzitych sloupcu, ani relace k resultsetu (ani by neslo). Takze to volej klasicky
$this->connection->query(
'SELECT "ip", "vlan" FROM getdevicebymac(?) WHERE (family("ip") = ?) LIMIT 1',
$mac, 4
);
- heekon
- Člen | 28
hrach napsal(a):
No, problem je, ze natvrdo busis spojeni stringu, misto toho, aby si pouzil placeholder. Smula je, ze ten u
table()
nepodporujeme. Funguje volani funkce s uvozovkami? Pokud ano, tak to je pro tebe mozny fix, pokud ne, tak ne.Nicmene: pro dane pouziti, co delas, je NAPROSTO nevhodne pouzivat Selection, nevyuzivas ani predikci pouzitych sloupcu, ani relace k resultsetu (ani by neslo). Takze to volej klasicky
$this->connection->query( 'SELECT "ip", "vlan" FROM getdevicebymac(?) WHERE (family("ip") = ?) LIMIT 1', $mac, 4 );
ok, děkuju za vysvětlení