N
N
nazmutdinovrafael2017-02-09 07:56:19
PostgreSQL
nazmutdinovrafael, 2017-02-09 07:56:19

Dollar quoting postgresql syntax error in Yii2 Db execute()?

I create a trigger using migration, PostgreSQL.
I make a request directly to the database -> it works correctly: both the function and the trigger are created.
I make a request through migration -> I get an error.
Migration file:

public function up()
    {
        $this->execute('DROP TRIGGER IF EXISTS trigger_window_view_before_del ON window_view;');

        $this->execute('DROP FUNCTION IF EXISTS trigger_window_view_before_del();');
        $this->execute('
            CREATE FUNCTION trigger_window_view_before_del() RETURNS trigger AS $trigger_window_view_before_del$
            BEGIN 
            IF (SELECT COUNT(*) FROM object_rent WHERE window_view ? OLD.id::text) > 0 THEN
            RAISE EXCEPTION \'Sorry, cannot delete this window_view, because it used in object_rent.\';
            ELSIF (SELECT COUNT(*) FROM object_sale WHERE window_view ? OLD.id::text) > 0 THEN
            RAISE EXCEPTION \'Sorry, cannot delete this window_view, because it used in object_sale.\';
            ELSE
            DELETE FROM window_view WHERE window_view.id = OLD.id;
            END IF;
            END; 
            $trigger_window_view_before_del$ LANGUAGE plpgsql;
        ');

        $this->execute('
            CREATE TRIGGER trigger_window_view_before_del 
            BEFORE DELETE ON window_view FOR EACH ROW 
            EXECUTE PROCEDURE trigger_window_view_before_del();
        ');
    }

Error text:
> execute SQL: DROP TRIGGER IF EXISTS trigger_window_view_before_del ON window_view; ... done (time: 0.009s)
    > execute SQL: DROP FUNCTION IF EXISTS trigger_window_view_before_del(); ... done (time: 0.001s)
    > execute SQL: 
            CREATE FUNCTION trigger_window_view_before_del() RETURNS trigger AS $trigger_window_view_before_del$
            BEGIN 
            IF (SELECT COUNT(*) FROM object_rent WHERE window_view ? OLD.id::text) > 0 THEN
            RAISE EXCEPTION 'Sorry, cannot delete this window_view, because it used in object_rent.';
            ELSIF (SELECT COUNT(*) FROM object_sale WHERE window_view ? OLD.id::text) > 0 THEN
            RAISE EXCEPTION 'Sorry, cannot delete this window_view, because it used in object_sale.';
            ELSE
            DELETE FROM window_view WHERE window_view.id = OLD.id;
            END IF;
            END; 
            $trigger_window_view_before_del$ LANGUAGE plpgsql;
         ...Exception 'yii\db\Exception' with message 'SQLSTATE[42601]: Syntax error: 7 ERROR:  syntax error at or near "$1" at character 201
The SQL being executed was: 
            CREATE FUNCTION trigger_window_view_before_del() RETURNS trigger AS $trigger_window_view_before_del$
            BEGIN 
            IF (SELECT COUNT(*) FROM object_rent WHERE window_view ? OLD.id::text) > 0 THEN
            RAISE EXCEPTION 'Sorry, cannot delete this window_view, because it used in object_rent.';
            ELSIF (SELECT COUNT(*) FROM object_sale WHERE window_view ? OLD.id::text) > 0 THEN
            RAISE EXCEPTION 'Sorry, cannot delete this window_view, because it used in object_sale.';
            ELSE
            DELETE FROM window_view WHERE window_view.id = OLD.id;
            END IF;
            END; 
            $trigger_window_view_before_del$ LANGUAGE plpgsql;
        '

in /src/vendor/yiisoft/yii2/db/Schema.php:636

Error Info:
Array
(
    [0] => 42601
    [1] => 7
    [2] => ERROR:  syntax error at or near "$1" at character 201
)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Goncharov, 2017-09-21
@morozovsk

most likely a problem with PDO, perhaps before $ you need to put \
I got exactly the same error (they apparently have it for all occasions, if suddenly the parser did not figure it out) to the request

created >= now() - interval :created
corrected for
created >= now() - :created::interval
and the error disappeared, although both options work if you make a request to the database through other tools, and the second option, on the contrary, should look more complicated for the parser.
Errors like this make me think that PDO is not just parameter substitution, but parsing queries, which will inevitably affect performance.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question