Skip to content

Conversation

derrabus
Copy link
Member

@derrabus derrabus commented Aug 6, 2025

This is my attempt at getting our SchemaTool ready for DBAL 5. Not all tests are green with DBAL 5 yet, but we're getting there.

@derrabus derrabus added this to the 3.5.2 milestone Aug 6, 2025
@derrabus derrabus requested a review from morozov August 6, 2025 12:59
@derrabus
Copy link
Member Author

derrabus commented Aug 6, 2025

I'll look into the PHPStan failures later.

@derrabus
Copy link
Member Author

derrabus commented Aug 6, 2025

@morozov The new schema API distinguished between "quoted" and "unquoted" identifiers (e.g. index or column names). I'm using "unquoted" here in the sense of "if this needs to be quoted, the I did this already, so don't automatically quote this for me". Please advice if that's correct.

For ORM 4, we should probably find a way to leverage the quoted identifiers properly.

@derrabus derrabus force-pushed the improvement/schema-tool-new-api branch from 23ae208 to 0142977 Compare August 6, 2025 14:17
@derrabus derrabus requested a review from greg0ire August 6, 2025 14:35
@derrabus
Copy link
Member Author

derrabus commented Aug 6, 2025

I'm using "unquoted" here in the sense of "if this needs to be quoted, the I did this already, so don't automatically quote this for me".

Answering my own question, my assumption is not correct, looking at the test failures I get with DBAL 5. I guess, I'll dig a bit more into this matter. I think, our QuoteStrategy system is mostly obsolete now.


$table->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, $primaryKeyColumnNames, true));
} else {
/** @param string[] $primaryKeyColumns */
Copy link
Member

@greg0ire greg0ire Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use the same advanced types you used somewhere else in this PR? Maybe it will address the baselined issue.

Suggested change
/** @param string[] $primaryKeyColumns */
/** @param non-empty-list<non-empty-string> $primaryKeyColumns */


-
message: '#^Parameter \#2 \$columns of class Doctrine\\DBAL\\Schema\\Index constructor expects non\-empty\-list\<string\>, list\<string\> given\.$#'
message: '#^Parameter \#1 \$firstColumnName of method Doctrine\\DBAL\\Schema\\PrimaryKeyConstraintEditor\:\:setUnquotedColumnNames\(\) expects non\-empty\-string, string given\.$#'
Copy link
Member

@greg0ire greg0ire Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have identifiers at our disposal, I think we should not add new issues to the baseline, and instead resort to e.g. /** @phpstan-ignore argument.type (reason why we ignore this) */

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll try to do that when I rework the PR.

@morozov
Copy link
Member

morozov commented Aug 7, 2025

The new schema API distinguished between "quoted" and "unquoted" identifiers (e.g. index or column names). I'm using "unquoted" here in the sense of "if this needs to be quoted, the I did this already, so don't automatically quote this for me". Please advice if that's correct.

I haven't had a chance to look at the code, but this not how this API is intended to be used.

First, from the DBAL 5's standpoint, all identifiers (whether they are quoted or not) will end up surrounded with quotes in SQL – this is how we eliminate the need to maintain dictionaries of keywords. Quoting identifiers (as in surrounding them with quotes) is not the responsibility of the user, and this is not portable anyways.

Second, on those platforms that don't respect SQL'92 (SQLite, MySQL and SQL Server), whether the identifier is quoted or not doesn't make any difference.

Whether the identifier is quoted or not, only determines the resulting case of the identifier when it's rendered to SQL for SQL'92 compliant databases (Postgres, Oracle, Db2):

  1. Quoted identifiers retain their original case.
  2. Unquoted identifiers on Oracle and Db2 are upper-cased
  3. Unquoted identifiers on Postgres are lower-cased

The bottom line is you need to use quoted identifiers only if your application uses identifiers in a case that isn't natural for supported platforms or it supports platforms with non-matching natural case of the identifiers. For instance:

  1. Uses lower-case identifiers with Oracle or Db2 (case needs to be retained)
  2. Uses upper-case identifiers with Postgres (case needs to be retained)
  3. Supports Oracle and Postgres (their natural cases are different, so the original case needs to be retained)


return $index->getColumns();
return Index::editor()
->setUnquotedName($indexName)
Copy link
Member

@morozov morozov Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would double-check how this code behaves if the index name contains quotes (e.g. "123_index"). Previously, Index would parse it resulting in quoted name 123_index. In the new version, it will result in an unquoted name "123_index" (i.e. quotes will be included in the name, not part of the syntax).

If that's the case, you'll need to parse the string with UnqualifiedNameParser and use setName() instead of setUnquotedName().

@greg0ire greg0ire removed this from the 3.5.2 milestone Aug 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants