doctrine/dbal — pull request #113 by avit (2012-02-14 01:08:33+00:00)
Title: Fixed SQL placeholder parsing

I reworked DoctrineSQLParser to fix these problems:

### Named placeholder patterns

The parser used a pattern that would match multiple colons, so junk like `:fir:stNa::m:e` was a "valid" placeholder name.

The parser neglected the underscore so `:first_name` was invalid and only captured `:first`.

This is cleaned up so placeholder names are consistent with PHP variable names: "starts with a letter or underscore, followed by any number of letters, numbers, or underscores".

### Quote characters in strings

The parser had a simplistic way of matching quote pairs, ignoring that a quote character could be escaped by a backslash inside a string.

It now recognizes `'it\'s a trap?'` as a whole literal string instead of breaking out after `it\` and parsing the `?` as a SQL placeholder.

### Speed

The original algorithm looped a regular expression over each character position in the whole statement. The new algorithm handles matching in two steps:

* One regular expression to select unquoted SQL.
* One regular expression to match placeholder tokens in the result.

I measured the result to be over 100% faster given the simple strings from the test case (even with 2 new runs added to the test data). The improvement would be greater on longer statements:

```
Doctrine\DBAL\SQLParserUtils::getPlaceholderPositions
| version: | invocation count: | total inclusive time: |
| original | 37 | 5719 |
| this patch | 39 | 2380 |
```