Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114019 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 47717 invoked from network); 11 Apr 2021 00:41:49 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 11 Apr 2021 00:41:49 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id CA4811804B2 for ; Sat, 10 Apr 2021 17:41:56 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,HTML_MESSAGE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from forward101p.mail.yandex.net (forward101p.mail.yandex.net [77.88.28.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 10 Apr 2021 17:41:55 -0700 (PDT) Received: from iva4-b3068118e41e.qloud-c.yandex.net (iva4-b3068118e41e.qloud-c.yandex.net [IPv6:2a02:6b8:c0c:14a6:0:640:b306:8118]) by forward101p.mail.yandex.net (Yandex) with ESMTP id 1B5D6328107A for ; Sun, 11 Apr 2021 03:41:53 +0300 (MSK) Received: from iva5-057a0d1fbbd8.qloud-c.yandex.net (iva5-057a0d1fbbd8.qloud-c.yandex.net [2a02:6b8:c0c:7f1c:0:640:57a:d1f]) by iva4-b3068118e41e.qloud-c.yandex.net (mxback/Yandex) with ESMTP id LNYrakD7bW-fqJKrmph; Sun, 11 Apr 2021 03:41:53 +0300 Authentication-Results: iva4-b3068118e41e.qloud-c.yandex.net; dkim=pass Received: by iva5-057a0d1fbbd8.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id Pxr2iQjpfY-fqKGH3Xs; Sun, 11 Apr 2021 03:41:52 +0300 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client certificate not present) Received: by mail-wr1-f46.google.com with SMTP id 12so9244456wrz.7 for ; Sat, 10 Apr 2021 17:41:52 -0700 (PDT) X-Gm-Message-State: AOAM532tOlyXZixGfhhGRI29uvq7ayL/6fRAS3PR/qwjZZkjVPuFbuqX +0UCtANnXMcNaJDI0Nsr35RG7HrdppxfaSxS3dc= X-Google-Smtp-Source: ABdhPJylVoSiIPDeFRU9YtKH0Vc5L8TlbdNpGK5fyW48gjIBUqEUczf5qKMKSE3xLOUbNlCXyI1kJLkg0hnikuphvwo= X-Received: by 2002:adf:f40f:: with SMTP id g15mr7674882wro.46.1618101711710; Sat, 10 Apr 2021 17:41:51 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Sat, 10 Apr 2021 17:41:40 -0700 X-Gmail-Original-Message-ID: Message-ID: To: Kamil Tekiela Cc: PHP Internals Content-Type: multipart/alternative; boundary="000000000000bcad6305bfa7a93e" Subject: Re: [PHP-DEV] Use MySQL syntax only for parsing MySQL statements in PDO From: morozov@tut.by (Sergei Morozov) --000000000000bcad6305bfa7a93e Content-Type: text/plain; charset="UTF-8" Hi, > it seems to be a cheap hack To me, it seems to be within the existing architecture. I agree that the existing architecture has its flaws. > What about backtick character ` ? What about NO_BACKSLASH_ESCAPES mode? These are out of scope. I wasn't aware of the NO_BACKSLASH_ESCAPES but it indeed seems to be impossible to support on the client side. > Emulated prepares have a lot of issues and this is only one of them. This specific issue doesn't seem to be related to the emulation. As far as I understand, PDO parses SQL as well in order to replace positional placeholders and vise versa depending on the input and the target platform capabilities. > If you want you can see the effect your PR has on this test case I tried running the example on the stock PHP 8.0.3, and regardless of the emulation mode and NO_BACKSLASH_ESCAPES mode I saw the same error: > SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in With my patch, I don't expect to see any changes in parsing MySQL queries so I don't understand how it's relevant. Am I missing something? On Sat, Apr 10, 2021 at 3:33 PM Kamil Tekiela wrote: > This is an interesting solution to the problem, but I am unsure if it's > the best one. I didn't look into it in detail yet, but at first glance, it > seems to be a cheap hack to solve a bug. What about backtick character ` ? > What about NO_BACKSLASH_ESCAPES mode? Any question mark within > backtick-escaped column name would still cause a problem. In fact, when I > tested it with NO_BACKSLASH_ESCAPES the PR didn't fix the problem. I > got a different error, but the problem still exists. > This is a naive solution that fixes one tiny bug in a single driver with > no regards for tons of other issues. I am against adding such hacks into > the PHP source code. > > What we need is a full SQL parser that is context-aware. This task should > be delegated to the PDO drivers. PDO can't do it reliably at the base > level. The problem is that PDO is never going to be able to reliably parse > the SQL even if we have a separate parser for each driver. PDO is not the > server and it doesn't know how the SQL will be parsed at the end of the > day. At its root, it seems to be an unfixable problem. Emulated prepares > have a lot of issues and this is only one of them. The solution is to use > native prepares whenever they are available on the server. > > If you want you can see the effect your PR has on this test case: > > $pdo = new \PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", > 'user', 'password', [ > \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, > \PDO::ATTR_EMULATE_PREPARES => true > ]); > $pdo->exec("SET sql_mode = NO_BACKSLASH_ESCAPES;"); > $stmt = $pdo->prepare("SELECT * FROM foo WHERE text='\' and 1=? and > text='\'"); > $stmt->execute([1]); > > I'm sorry but this is a hard pass from me. > -- Sergei Morozov --000000000000bcad6305bfa7a93e--