diff --git a/src/DebugBar/DataCollector/PDO/TracedStatement.php b/src/DebugBar/DataCollector/PDO/TracedStatement.php index 9111489b..56d492b5 100644 --- a/src/DebugBar/DataCollector/PDO/TracedStatement.php +++ b/src/DebugBar/DataCollector/PDO/TracedStatement.php @@ -125,18 +125,19 @@ public function getSqlWithParams(string $quotationChar = '<>') : string } $matchRule = "/({$marker}(?!\w))(?=(?:[^$quotationChar]|[$quotationChar][^$quotationChar]*[$quotationChar])*$)/"; - $count = mb_substr_count($sql, $k); - if ($count < 1) { - $count = mb_substr_count($sql, $matchRule); - } - for ($i = 0; $i <= $count; $i++) { - $sql = preg_replace($matchRule, $v, $sql, 1); + $sqlSplit = explode(PHP_EOL, $sql); + $sql = null; + foreach ($sqlSplit as $pieces) { + for ($i = 0; $i <= mb_substr_count($pieces, $k); $i++) { + $pieces = preg_replace($matchRule, $v, $pieces, 1); + } + $sql .= $pieces . PHP_EOL; } } $sql = strtr($sql, array_flip($cleanBackRefCharMap)); - return $sql; + return trim($sql); } /** diff --git a/tests/DebugBar/Tests/TracedStatementTest.php b/tests/DebugBar/Tests/TracedStatementTest.php index 89b3b42d..5844a2bf 100644 --- a/tests/DebugBar/Tests/TracedStatementTest.php +++ b/tests/DebugBar/Tests/TracedStatementTest.php @@ -151,6 +151,250 @@ public function testRepeadParamsQuery() $this->assertEquals($expected, $result); } + /** + * Big query generate regex error + */ + public function testBigQuery() + { + $params = [ + ':id_segmento' => 1, + ':id_part' => 1, + ':inativo' => 1, + ':ativo' => 1 + ]; + $query = 'select sum(qtd) as total from ( + select count(*) as qtd from ( + select distinct vw.id_modulo, vw.id_envio, vw.id_form, + vw.versao, vw.id_sistema, vw.id_grupo + from vw_forms_disponiveis vw + where vw.id_part = :id_part + and vw.id_servico = :id_segmento + and vw.concluido = :inativo + ) as forms + + union + select distinct count(pesq.*) as qtd from + pesquisa.avaliacao_modulo_disponivel pesq + join envio e + on e.id_envio = pesq.id_envio + and e.id_servico = pesq.id_servico + join rodada r + on e.id_envio = r.id_envio + join part_form pf + on r.ano = pf.ano + and r.id_rodada = pf.id_rodada + and pf.id_modulo = r.id_modulo + where pf.id_part = :id_part + and ( + r.data_fim > date(now()) + or pf.data_excecao_fim > date(now()) + ) + and ( + r.data_ini <= date(now()) + or pf.data_excecao_ini <= date(now()) + ) + and e.id_servico = :id_segmento + and pesq.id_modulo = :inativo + + union + select distinct count(p.id_pesquisa) as qtd + from pesquisas.pesquisa p + join pesquisas.publicacao as pub + on pub.id_pesquisa = p.id_pesquisa + left join pesquisas.resposta r + on r.id_pesquisa = p.id_pesquisa + and r.id_publicacao = pub.id_publicacao + and r.id_part = :id_part + where pub.id_servico = :id_segmento + and pub.excluido = :inativo + and p.excluido = :inativo + and r.id_resposta is null + and pub.data_ini <= date(now()) + and pub.data_fim >= date (now()) + and ( + p.resp_primeira_publicacao = :inativo + or ( + pub.id_publicacao in ( + select r2.id_publicacao + from pesquisas.resposta r2 + where r2.id_part = :id_part + and r2.id_pesquisa = p.id_pesquisa + ) + ) + or ( + not exists ( + select r2.id_pesquisa + from pesquisas.resposta r2 + where r2.id_part = :id_part + and r2.id_pesquisa = p.id_pesquisa + ) + ) + ) + and ( + pub.todos_parts = :ativo + or :id_part in ( + select id_part + from pesquisas.publicacao_part pp + where pp.id_pesquisa = pub.id_pesquisa + and pp.id_publicacao = pub.id_publicacao + and pp.id_part = :id_part + ) + ) + + union + select count(es.*) as qtd from especial.solicitacao es + join especial.dados_solicitacao d + on es.id_servico = d.id_servico + and es.ano = d.ano + join especial.liberacao el + on el.ano = d.ano + and el.id_servico = d.id_servico + and el.id_part = es.id_part + left join especial.prorrogados p + on p.ano = el.ano + and p.id_servico = el.id_servico + and p.id_part = el.id_part + where es.id_usu is null -- possui resp + and el.id_servico = :id_segmento + and el.id_part = :id_part + and ( + el.id_part in (8005, 8012) + or + d.liberada = :ativo + ) + and ((d.data_ini <= date(now()) and d.data_fim >= date(now())) + or ( + d.data_ini_excecao <= date(now()) + and d.data_fim_excecao >= date(now()) + and p.id_part not in ( + select s.id_part from especial.solicitacao s + where s.data < d.data_ini_excecao + and s.id_part = el.id_part and s.ano = d.ano + and s.id_servico = d.id_servico + ) + ) + or (p.data_fim >= date(now())) + ) + ) as resultados_em_aberto'; + $expected = 'select sum(qtd) as total from ( + select count(*) as qtd from ( + select distinct vw.id_modulo, vw.id_envio, vw.id_form, + vw.versao, vw.id_sistema, vw.id_grupo + from vw_forms_disponiveis vw + where vw.id_part = <1> + and vw.id_servico = <1> + and vw.concluido = <1> + ) as forms + + union + select distinct count(pesq.*) as qtd from + pesquisa.avaliacao_modulo_disponivel pesq + join envio e + on e.id_envio = pesq.id_envio + and e.id_servico = pesq.id_servico + join rodada r + on e.id_envio = r.id_envio + join part_form pf + on r.ano = pf.ano + and r.id_rodada = pf.id_rodada + and pf.id_modulo = r.id_modulo + where pf.id_part = <1> + and ( + r.data_fim > date(now()) + or pf.data_excecao_fim > date(now()) + ) + and ( + r.data_ini <= date(now()) + or pf.data_excecao_ini <= date(now()) + ) + and e.id_servico = <1> + and pesq.id_modulo = <1> + + union + select distinct count(p.id_pesquisa) as qtd + from pesquisas.pesquisa p + join pesquisas.publicacao as pub + on pub.id_pesquisa = p.id_pesquisa + left join pesquisas.resposta r + on r.id_pesquisa = p.id_pesquisa + and r.id_publicacao = pub.id_publicacao + and r.id_part = <1> + where pub.id_servico = <1> + and pub.excluido = <1> + and p.excluido = <1> + and r.id_resposta is null + and pub.data_ini <= date(now()) + and pub.data_fim >= date (now()) + and ( + p.resp_primeira_publicacao = <1> + or ( + pub.id_publicacao in ( + select r2.id_publicacao + from pesquisas.resposta r2 + where r2.id_part = <1> + and r2.id_pesquisa = p.id_pesquisa + ) + ) + or ( + not exists ( + select r2.id_pesquisa + from pesquisas.resposta r2 + where r2.id_part = <1> + and r2.id_pesquisa = p.id_pesquisa + ) + ) + ) + and ( + pub.todos_parts = <1> + or <1> in ( + select id_part + from pesquisas.publicacao_part pp + where pp.id_pesquisa = pub.id_pesquisa + and pp.id_publicacao = pub.id_publicacao + and pp.id_part = <1> + ) + ) + + union + select count(es.*) as qtd from especial.solicitacao es + join especial.dados_solicitacao d + on es.id_servico = d.id_servico + and es.ano = d.ano + join especial.liberacao el + on el.ano = d.ano + and el.id_servico = d.id_servico + and el.id_part = es.id_part + left join especial.prorrogados p + on p.ano = el.ano + and p.id_servico = el.id_servico + and p.id_part = el.id_part + where es.id_usu is null -- possui resp + and el.id_servico = <1> + and el.id_part = <1> + and ( + el.id_part in (8005, 8012) + or + d.liberada = <1> + ) + and ((d.data_ini <= date(now()) and d.data_fim >= date(now())) + or ( + d.data_ini_excecao <= date(now()) + and d.data_fim_excecao >= date(now()) + and p.id_part not in ( + select s.id_part from especial.solicitacao s + where s.data < d.data_ini_excecao + and s.id_part = el.id_part and s.ano = d.ano + and s.id_servico = d.id_servico + ) + ) + or (p.data_fim >= date(now())) + ) + ) as resultados_em_aberto'; + $traced = new TracedStatement($query, $params); + $result = $traced->getSqlWithParams(); + $this->assertEquals($expected, $result); + } + /** * Check that query parameters are being replaced only once * @bugFix Before fix it: select * from