laravel / pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.
https://pulse.laravel.com
MIT License
1.43k stars 165 forks source link

Add table prefix on raw expressions when a table name is in the string #385

Closed simonecosci closed 4 months ago

simonecosci commented 4 months ago

Pulse Version

v1.2.1

Laravel Version

11.8.0

PHP Version

8.2.12

Livewire Version

3.5.0

Database Driver & Version

Postgres 13

Description

I don't know if this can be considered a bug ...

When using a raw Expression consider using the table-prefix before the table name if the table name is hardcoded I have table names prefixed with 'kp_' and pulse throws the following exception:

#18 {main}An exception happened in PulseSQLSTATE[42P01]: Undefined table: 7 ERROR:  missing FROM-clause entry for table "pulse_aggregates"
LINE 1: ... "aggregate", "key_hash") do update set "value" = "pulse_agg...
                                                             ^ (Connection: pgsql, SQL: insert into "kp_pulse_aggregates" ("aggregate", "bucket", "key", "period", "type", "value") values (count, 1717076700, ["select count(*) as aggregate from \"kp_migrations\"","C:\\Software\\kp\\api\\vendor\\laravel\\pulse\\src\\Pulse.php:594"], 60, slow_query, 1), (count, 1717076520, ["select count(*) as aggregate from \"kp_migrations\"","C:\\Software\\kp\\api\\vendor\\laravel\\pulse\\src\\Pulse.php:594"], 360, slow_query, 1), (count, 1717076160, ["select count(*) as aggregate from \"kp_migrations\"","C:\\Software\\kp\\api\\vendor\\laravel\\pulse\\src\\Pulse.php:594"], 1440, slow_query, 1), (count, 1717067520, ["select count(*) as aggregate from \"kp_migrations\"","C:\\Software\\kp\\api\\vendor\\laravel\\pulse\\src\\Pulse.php:594"], 10080, slow_query, 1) on conflict ("bucket", "period", "type", "aggregate", "key_hash") do update set "value" = "pulse_aggregates"."value" + "excluded"."value")

avoid this behavior by using $this->connection()->getTablePrefix() just before the table name in src/Storage/DatabaseStorage.php

Eg.

            match ($driver = $this->connection()->getDriverName()) {
                'mariadb', 'mysql' => [
                    'value' => new Expression('(`value` * `count` + (values(`value`) * values(`count`))) / (`count` + values(`count`))'),
                    'count' => new Expression('`count` + values(`count`)'),
                ],
                'pgsql', 'sqlite' => [
                    'value' => new Expression('("' . $this->connection()->getTablePrefix() . 'pulse_aggregates"."value" * "' . $this->connection()->getTablePrefix() . 'pulse_aggregates"."count" + ("excluded"."value" * "excluded"."count")) / ("' . $this->connection()->getTablePrefix() . 'pulse_aggregates"."count" + "excluded"."count")'),
                    'count' => new Expression('"' . $this->connection()->getTablePrefix() . 'pulse_aggregates"."count" + "excluded"."count"'),
                ],
                default => throw new RuntimeException("Unsupported database driver [{$driver}]"),
            }

Regards S.

Steps To Reproduce

Put in .env

DB_PREFIX=kp_

jessarcher commented 4 months ago

Thanks for reporting @simonecosci. I've created a fix for this at #386.