Problem/Motivation

PostgreSQL provides a native uuid data type but Drupal does not allow using that for database schemas.

Proposed resolution

Provide a uuid schema field type for database schemas. This will translate to the native uuid data type for PostgreSQL and use a BINARY(36) field on MySQL and a simple blob field on SQLite.

Aside from test coverage the uuid schema field will not be used by any code as of yet, that will happen in follow-up issues, in particular #2491989: [PP-1] Use the 'uuid' database schema type (with native PostgreSQL implementation) for UUID fields. But it will already allow usage by custom and contrib modules so it makes sense to get this in separately as any respective changes to the entity system (even opt-in ones) will require a lot of discussion.

Remaining tasks

-

API changes

The database schema API provides a new uuid field type. Database drivers are expected to handle this by either utilizing a native UUID implementation or a simple string field, potentially with a length limit of 36.

Data model changes

Database schema array may contain fields of a new type uuid.

Original issue summary

Quoting @Berdir from #1642526-16: Add upgrade path from for generating UUIDs for all core entities:

PostgreSQL for example seems to have native support for that (http://www.postgresql.org/docs/9.1/static/datatype-uuid.html) and there's quite some discussion what exactly the best and fastest type for MySQL is.

Seeing suggestions such as BINARY(36), while you're currently using varchar(128), which I'm not sure why but that seems like a considerable overhead.

Comments

andypost’s picture

@sun It's not clear the title of issue - do you mean storage column type or database-level generation of uuid?

EDIT: I think we need to make a column type for each of supported database

Postgresql supports storage for uuid from 8.3 which is required version for D7

About generation for sqlite

sun’s picture

Assigned: Unassigned » damien tournoud
Status: Active » Needs review
StatusFileSize
new3.01 KB

This is not about generating UUIDs. It's only about a new Database schema field/column type that can be specified in hook_schema() implementations.

A database might have special support for UUID values, and some engines might operate faster on the values/index when using a certain column definition (e.g., BINARY vs. VARCHAR).

Not sure whether attached patch is correct (definitely incomplete), but it hopefully clarifies what's meant.

Assigning to @Damien Tournoud in the hope to get some input and expertise from him early.

damien tournoud’s picture

It really depends on what we want to do here. Do we really want to mandate actual RFC 4122 UUIDs, or do we want to support arbitrary string identifiers, as long as they are unique.

The latter might be a little bit slower, but it would be infinitely more flexible. The initial "UUID" patch clearly wanted to support arbitrary string identifiers, that's why we went with varchar(128).

I'm personally for supporting arbitrary string identifiers everywhere. It will be definitely slower then numeric keys, but I doubt it would make any difference for any practical application. (I would welcome benchmarks proving that the difference in join performance matters for any real-life Drupal site.)

andypost’s picture

sun’s picture

Assigned: damien tournoud » Unassigned

Hm. I'd actually prefer to follow the official RFC standard.

Ensures and increases interoperability with (any) other systems, since it's a clearly defined industry standard. Arbitrary strings would not comply and thus be yet another Drupalism.

It might also improve performance, depending on the database engine, but I'd actually say that matters (much) less than interoperability.

damien tournoud’s picture

Actually, interoperability would be *increased* if we allow arbitrary string identifiers. Most external systems do not have a UUID key, or even a meaning full primary key to begin with.

There is a way to convert arbitrary string identifiers into a UUID (it's the whole point of UUID version 3 and 5), but that's a one way street: once you converted it there is no way back, and you have to maintain a map of ID => UUID if you need this information down the line (you usually do).

sun’s picture

Hm. As usual, you're making too much sense. :)

So I guess the decision of _not_ using varchar and forcing people to use mapping tables when needed would have to be backed up by performance benchmarks that show considerably better numbers?

That said. Doesn't this patch here, i.e., the introduction of a 'uuid' field type within DBTNG, allow people who absolutely need a non-RDF compliant UUID schema definition to do exactly that by overriding the driver?

I.e., concrete proposal:

1) Introduce a 'uuid' field type for DBTNG.
2) Make Drupal core comply with RFC 4122.
3) Potentially leverage native DB driver support for UUIDs, if any.
4) Allow custom sites to swap out/override the driver to use arbitrary strings as UUIDs (already a given).

berdir’s picture

@sun: I'm not sure if that would work, as it would require sites to make this decision before they install and I'm not even sure if it's possible to replace the driver that early.

Status: Needs review » Needs work

The last submitted patch, 2: drupal8.db-uuid-type.2.patch, failed testing.

andypost’s picture

Issue summary: View changes
Issue tags: +Entity Field API, +Needs reroll
estoyausente’s picture

StatusFileSize
new3.01 KB

Rerolled

estoyausente’s picture

Status: Needs work » Needs review
Issue tags: +Amsterdam2014
star-szr’s picture

Issue tags: -Needs reroll

Thanks @estoyausente, please remove the 'Needs reroll' tag when posting a rerolled patch :)

estoyausente’s picture

Oh, thank for the tip. :)

jhedstrom’s picture

Status: Needs review » Needs work

Is still up for consideration for 8.0?

Regardless, we should provide the PostgreSQL equivalent as well, and probably some tests.

nlisgo’s picture

Status: Needs work » Needs review
StatusFileSize
new1.27 KB
new4.28 KB

Added PostgreSQL equivalent.

nlisgo’s picture

Issue tags: +Needs tests
jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
deepakaryan1988’s picture

Assigned: Unassigned » deepakaryan1988
deepakaryan1988’s picture

Assigned: deepakaryan1988 » Unassigned
StatusFileSize
new2.7 KB

re-rolling the patch but I couldn't find changes which mentioned in #17 in /core/lib/Drupal/Core/Database/Schema.php file so I left it. I feel I might be doing something wrong.
Can anyone help me with this?

jhedstrom’s picture

@deepakaryan1988 the documentation changes contained in the patch #17 to Drupal\Core\Database\Schema were moved in #2469941: Move database-related hook docs from system.api.php to a new database.api.php file to core/modules/system/database.api.php, so this patch would need to update that file instead.

deepakaryan1988’s picture

@jhedstrom Ok Thanks for the info. I will do that :)

erik.erskine’s picture

StatusFileSize
new4.54 KB

Straight reroll of #17/#21 including documentation changes in core/modules/system/database.api.php.

erik.erskine’s picture

Issue tags: -Needs reroll
StatusFileSize
new4.54 KB
new2.33 KB

A few modifications to the patch in #24:

  • PostgreSQL has a native uuid type, so use it on that platform.
  • On MySQL, remove the !isset($field['length']) and always enforce the length to be 36.
  • Added a SQLite implementation, this just maps to the TEXT type, as SQLite has no length checking.
erik.erskine’s picture

Status: Needs work » Needs review
deepakaryan1988’s picture

Patch in #25 looks good to me!

amateescu’s picture

+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
@@ -380,6 +383,8 @@ function getFieldTypeMap() {
+      'uuid:normal' => 'bytea',

Why are we not using the 'uuid' data type on PostgreSQL?

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

daffie’s picture

Version: 8.1.x-dev » 9.x-dev

WE are not going to change this in Drupal 8. So moving this to Drupal 9.

andypost’s picture

Version: 9.x-dev » 8.2.x-dev

I think this doable in minor releases, and fully BC while no data models changed

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

andypost’s picture

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

daffie’s picture

Version: 9.2.x-dev » 10.0.x-dev
Status: Needs review » Needs work

I very much like the idea of using native support of UUID's on the database. For me the best would be if all the by Drupal supported databases would support the feature. See: #3109340: [policy] Decide whether to require json support for all database drivers for Drupal 10.
Also Microsoft SQL Server and Oracle DB support native UUID's for all currently supported versions.
The only problem is SQLite. SQLite offers support for the feature from version 3.31. Therefor we shall have to wait and what the minimum required version of SQLite will be for Drupal 10.

Setting the issue back to needs work as the patch is for D7 instead of D9.2.

andypost’s picture

Btw uuid.c included into source code base since sqlite 3.31 but I see it should be built by end user as extra extension... No idea how to use it yet

tstoeckler’s picture

Issue tags: +ContributionWeekend2021
StatusFileSize
new3.46 KB

Taking a look at this this weekend. First a re-roll of the patch in #25. Note that that patch did not contain the interdiff attached there, so not including that either yet, will "re-roll" that next.

tstoeckler’s picture

StatusFileSize
new2.32 KB
new3.16 KB

OK, here is the rerolled interdiff and the patch that actually has that applied now.

Will play around with this a bit and ideally write some tests now. We'll see.

tstoeckler’s picture

Status: Needs work » Needs review
StatusFileSize
new5.22 KB
new6.53 KB

OK, here's an updated patch. I changed the SQLITE type from TEXT to BLOB as text columns have an encoding, which is not necessary here. I am not an expert on SQLite, though, I just looked a bit through the documentation and since there wasn't a detailed reasoning for using TEXT I just went ahead and changed it.

Other than that this adds a test. It adds a basic table with a UUID column and then tests using that for a unique key and a primary key. Not sure if there is anything else we want to test. I added a new method to SchemaTest as I didn't find a specific place where are testing different schema types.

The test passes locally on all three database engines.

tstoeckler’s picture

Issue tags: -Needs tests
immaculatexavier’s picture

Issue tags: +Needs reroll

Reviewed whether the old patch still applies to the latest code and passes automated tests.

Steps taken to review:
1. Downloaded the latest patch file.
2. Used Git to clone local Git repository of 10.0.x of the development version that the issue pertains to.
3. The patch #47 does not apply.
Result:
So changed the issue status to Needs work.
 Added the issue tag "needs reroll".

immaculatexavier’s picture

Status: Needs review » Needs work

Changing the status to Need work

rassoni’s picture

Status: Needs work » Needs review
StatusFileSize
new46.43 KB
new43.01 KB

Rerolled patch against #49
Attached interdiff

quietone’s picture

Move to D9 upgrade path

pooja saraah’s picture

StatusFileSize
new47.04 KB
new1.14 KB

Fixed failed commands on #51
Attached patch against Drupal 10.0.x

daffie’s picture

Status: Needs review » Needs work
Issue tags: -Needs reroll

Could all the changes in the patch that are not related or necessary for adding the 'uuid' database schema type be removed. They are out of scope for this issue.

andypost’s picture

+++ b/core/modules/pgsql/src/Driver/Database/pgsql/Schema.php
@@ -28,8 +28,9 @@ class Schema extends DatabaseSchema {
-   * @see \Drupal\pgsql\Driver\Database\pgsql\Schema::queryTableInformation()
    * @var array
+   *
+   * @see \Drupal\pgsql\Driver\Database\pgsql\Schema::queryTableInformation()

Patch contains a lot of useless formatting changes which should be removed

smustgrave’s picture

StatusFileSize
new6.5 KB

Rerolled from #47 vs cherry picking changes from following patches

Interdiff unfortunately failed to generate

Going to see if it applies before moving to NR

smustgrave’s picture

Status: Needs work » Needs review
andypost’s picture

Yay, just 6kb

And passed

andypost’s picture

Status: Needs review » Needs work
Issue tags: -Upgrade path, -D9 upgrade path +Needs issue summary update

Otherwise it's rtbc, upgrade path should in conversation issues for each subsystem like fields

tstoeckler’s picture

Issue summary: View changes
tstoeckler’s picture

Issue summary: View changes
tstoeckler’s picture

Version: 10.0.x-dev » 10.1.x-dev
Category: Task » Feature request
Issue tags: -Needs issue summary update

Thanks for breathing some new life into this @smustgrave and @andypost! 👍

Alright, updated the issue summary and created a little draft change notice in particular for database drivers, which will presumably appreciate the heads-up. Also reclassifying as a feature request and updating to 10.1.

Hopefully this can be RTBC now.

tstoeckler’s picture

Status: Needs work » Needs review
andypost’s picture

Status: Needs review » Reviewed & tested by the community

@tstoeckler thank you! Now I hope it ready for commiters

daffie’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs issue summary update

The IS needs to be updated. I have a couple of questions that I would like to see answered in the IS:
- WHY do we need a different storage type for UUID fields. Just because we can or are there other reasons to do it?
- MySQL is the most used database for Drupal. In the current patch the UUID storage will change to BINARY(36). Why this type? Are there other possibilities?
- For SQLite we are going to store it BLOB's. Why is that better than how we are storing it now?

Changing the storage for UUID fields will be a lot of work. Not only for core, but also for contrib and custom code. Site owners will be forced to to run update hooks to use the new storage for UUID field. There need to be a clear advantage and at the moment it is not clear to me that there is any. Please convince me that there is.

Is there anything we can do to prevent a BC break for the contrib database drivers for Microsoft and Oracle?

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

tstoeckler’s picture

StatusFileSize
new6.27 KB

For now just a re-roll for #3315604: Move remaining database specific kernel tests to the driver modules. Will try to find some time to reply to #65 properly at some point, but just as a quick note: This patch would not change anything for core and for contrib it's just enablement to be able to experiment and validate with in contrib and eventually in core. Because the Schema API is not in any way alterable or extendable, it is necessary to take this first step in order to get something for people to build on.

tstoeckler’s picture

StatusFileSize
new696 bytes
new6.59 KB

Oops, this one should be better.

andypost’s picture

For SQLite we are going to store it BLOB's. Why is that better than how we are storing it now?

Re #65 There's few choices

- https://www.sqlite.org/lang_corefunc.html#randomblob for binary representation, available since 3.3.13 but for 10.x we set 3.26
- check for uuid.c extension but available since 3.31 and not every linux distro i bet

There's no difference this days about binary/text storage but generation (when running migrations) could be affected

Also there could be some analysis in which way uuids are consumed by core, as I know most of places using it as string

andypost’s picture

btw there's great answer to sqlite data-type https://stackoverflow.com/a/10105431

andypost’s picture

CR is incomplete

oracle and mssql drivers should use change record to add compatibility, for BC it could be CHAR(36)

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.