Although there is no official limit for the length of URLs, they can be up to 2000 characters long and still be manageable by browsers.
The source field in the redirect table has a size of 255 characters. Increasing it to 2000 may be overkill, so the suggested patch in the following comment increases it to 1000 characters.
Comments
Comment #1
juampynr commentedHere it is.
Comment #2
mitchmac commented1000 characters seems too arbitrary considering in the wild implementations don't have this limit. I would suggest switching to text type.
Comment #3
juampynr commentedRelated http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-...
Comment #4
mrharolda commentedI had to lower the limit to 900 to be able to install this update on our servers ...
Comment #5
luckydad commentedI would like database columns source and redirect both to be able to handle much longer urls (1000 characters would work).
Also, would like the overlay form input box you enter the source and redirect urls into to accept much longer urls (1000 characters would work).
Thanks,
Michael
Comment #6
mogwaay commentedWe haven't had any problems with the length of redirect source field (yet) but ran into the "PDOException: SQLSTATE" error when trying to enter more than the the 255 DB character limit.
Ie, following test URL:
go/TGezh0aB7wkV8xx8TqrpKVwMclUPMtUWOKpvM1KKc1qsyjqUzlk65acnDxwos5QOtiwXsXAPYwvtyvqntqfyPrlItC1IWkA5wYno08yxrjRXyg14YSMsyFLMK5T7IDSQaXC0Yz95628fT0iaU1xw4UtleIPAISEbmfXxQOP0SByq7vfFgctvWiDW6wilBtei3HD3omP8vBUg1elK4PBW6hkTn9hly5yT5KAFL54HISNlumcmm0zTB85vlSam5A8H
inserted into the admin/config/search/redirect/add form creates error:
messagePDOException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'source' at row 1: INSERT INTO {redirect} (hash, type, source, source_options, redirect, redirect_options, language, status_code, count, access) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9); Array ( [:db_insert_placeholder_0] => MHVGlY7ipqw3Izr0Qb5cvcJ_jQq7wnITSoZbfWsWomY [:db_insert_placeholder_1] => redirect [:db_insert_placeholder_2] => go/TGezh0aB7wkV8xx8TqrpKVwMclUPMtUWOKpvM1KKc1qsyjqUzlk65acnDxwos5QOtiwXsXAPYwvtyvqntqfyPrlItC1IWkA5wYno08yxrjRXyg14YSMsyFLMK5T7IDSQaXC0Yz95628fT0iaU1xw4UtleIPAISEbmfXxQOP0SByq7vfFgctvWiDW6wilBtei3HD3omP8vBUg1elK4PBW6hkTn9hly5yT5KAFL54HISNlumcmm0zTB85vlSam5A8H [:db_insert_placeholder_3] => a:0:{} [:db_insert_placeholder_4] => node/9719 [:db_insert_placeholder_5] => a:0:{} [:db_insert_placeholder_6] => en [:db_insert_placeholder_7] => 0 [:db_insert_placeholder_8] => 0 [:db_insert_placeholder_9] => 0 ) in drupal_write_record() (line 7246 of /var/www/drupal-staging/includes/common.inc).
Be nice to have had some more validation on this as well as increase the character length as others have requested.
Comment #7
rudiedirkx commentedMySQL doesn't care how long a VARCHAR is, it can be 30k, that's fine. The index/key can't be more than 3k though, so that might be a problem. Only 1k if you want to support 'old' MySQLs.
I'd go with @MrHaroldA's solution and make the total index/key < 1k. 900 chars for
sourceshould be enough 99.9% of the time.Comment #8
mvcRight, the 255 character limit for VARCHAR ended with MySQL 5.0.3 and D7 requires 5.0.15, so let's increase this. I used 900 characters since going over that seemed to cause problems for some folks. While we're at it, we should increase the redirect field too, since that can point to any arbitrary URL.
I also noticed that the form sets both these fields' limits at 560 chars. I have no idea why that didn't match the limit in the schema, so I changed that too.
Comment #9
mrharolda commentedWorks like a charm!
Comment #10
joachim commentedUnfortunately, the update crashes on my production server:
> SQLSTATE42000: Syntax error or access violation: 1071 Specified keyerror was too long; max key length is 767 bytes
I'm told by my sysadmin that can be worked around by some config setting, but it doesn't work OOTB.
The only way I can see for this is to remove the index that uses the source column. The problem with doing that is that we rely on the index for looking for redirects in hook_init().
I do wonder though -- why aren't we using redirect_load_by_hash() in hook_init()?
Comment #11
mvcHmm, I see. The larger InnoDB key size of 3072 bytes was made a (default) option in MySQL 5.5, and made mandatory in 5.7.7: http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_inn...
D7 supports MySQL 5.0.15 so that won't work for us and we'll have to make the table shorter. I think removing the index and loading by hash would cause very serious performance problems for large sites, so let's definitely not do that. At least D8 requires MySQL 5.5 so we could use 900 characters there.
joachim, would you mind doing some tests and figuring out how large a value you can use for the source column? (Perhaps this is where the value of 560 bytes came from.) We should be able to leave the redirect column at 900 characters since there's no index on it. The actual length of the index would depend on the character set used, if you have time to experiment with that as well. Also, what version of MySQL are you running?
And all of this is to accomodate a single source value of 260 characters on my client's site :)
Comment #12
joachim commentedMy local dev site has MySQL 5.5.38, but the production server I tried this on which crashed has XtraDB 5.6.25-73.1.
I'm afraid I'm not able to tinker with the production server to see what it'll tolerate!
> I think removing the index and loading by hash would cause very serious performance problems for large sites, so let's definitely not do that.
I'm rather confused what the loading by hash functionality is for. I assumed it actually *was* for speed, but it's not used in hook_init(), so I've probably misunderstood its purpose.
> We should be able to leave the redirect column at 900 characters since there's no index on it.
Bad news on that front: #2194099: Create database index on the redirect column.
> And all of this is to accomodate a single source value of 260 characters on my client's site :)
Ha, I know the feeling! I had a CSV of redirects to migrate in, and some had source URLs of about 700 characters!!
Comment #13
rudiedirkx commentedIs it possible to create a schema and update that set the index size to 'max', being platform dependent? Is there a way to get the current db's max index size?
Comment #14
mvcjoachim, I just realized I had access to a MySQL 5.1.73 environment to test this. I can create the index without any problems, plus create the index for the redirect column. If I manually try to create a UNIQUE index this fails with the same error you saw, but the BTREE index created by this update hook runs without errors by indexing just 255 characters of the text columns.
Percona XtraDB seems to be doing something different here, and I don't see a way in DatabaseSchema_mysql::addIndex() to force it to index 255 characters. Can you try to just create a test table with a varchar(900) text column, using charset utf8, and see if you can run the following?
alter table test add index my_long_index (my_long_column)For me that works and when I run
show create table testI seeKEY `my_long_index` (`my_long_column`(255))Comment #15
heykarthikwithuInstead of increasing the field size of varchar, we can have the LONGTEXT type to the source field.
So, in this case source url size can be saved upto 2000 chars.
Comment #16
joachim commentedWhat's the benefit of using LONGTEXT? The problem here as I understand it isn't the length of the VARCHAR, but the size of the field used in the index.
A few other problems:
You've removed 'source' from the index, so that hook_update_N() needs to make that change too.
Why would the field exist when the module is installed? That shouldn't be possible.
Missing a docblock.
Comment #17
heykarthikwithuSince we want to 'Increase size of source field to hold long URLs', we shall use the LONGTEXT.
And yes their is a problem with the index size of the source field, so we shall drop and add the index of source field, in this case data loss will not be their.
Comment #18
joachim commented> so we shall drop and add the index of source field, in this case data loss will not be their.
Won't that mean a big drop in performance? hook_init() does a query of redirects with a condition on the source field.
Comment #19
heykarthikwithu> Won't that mean a big drop in performance?
https://api.drupal.org/api/drupal/modules%21system%21system.api.php/func...
yes, hook_init() runs on every page load. This will have impact on server response time performance for every page access.
but our module upgrade runs only once which re-indexes the redirect table.
So i believe after this, the performance will be the same as in the earlier state.
Comment #20
mvcheykarthikwithu, i agree with joachim that using a fulltext field would be a performance killer. afaict you can't create an index combining fulltext columns with other types so looking up whether a redirect exists is going to be very slow with your change. yes, hypothetically a url could be arbitrarily long but i don't think we need to support such massive values in practice.
my proposed change seems to work fine on all supported versions of mysql, we just need to figure out what's up with Percona XtraDB here (since that's officially supported too) to accept this change.
Comment #21
rudiedirkx commentedLONGTEXT is crazy insanely long (like 2GB). VARCHAR can be up to 65k, which is waaaay longer than any URL. Exactly what joachim says in #16.
This is getting ridiculous. Let's please fix the field size to a length we know ALL databases will accept as index size. It's definitely more than 255, which probably fixes this issue for many many people.
Comment #22
sebastien m. commentedKeep in mind that this patch must work both on MySQL, Postgres and any other DBMS supported by Drupal.
So, native sql queries are not recommended. You should work instead DB API to drop or create sql indexes.
Concerning changing type of "source", I would recommended to create a temporary column a copy data.
Comment #23
malcomio commentedI still need to investigate further, but on Acquia (Server version: 5.5.24-55-log Percona Server (GPL), Release 26.0) I observed problems increasing the size of these database fields - it wasn't possible to set the source to anything larger than 255 (once the index had been added in redirect_update_7101):
Possibly related - #2815099: exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 3072 bytes' in
Comment #24
mvcAs discussed, using ALTER TABLE is MySQL specific and LONGTEXT is *far* too large. My patch in #8 still applies cleanly to the 7.x-1.x and 7.x-2.x branches, so let's see if the tests still pass. Plus, it updates the form API settings to allow people to actually use the longer values, without which this patch is somewhat pointless. As mentioned above, this works for me with MySQL 5.1.73. The only outstanding issue is one report of problems with Percona XtraDB from joachim, for which I'd like more information, as mentioned in #14.
OTOH, given malcomio's report that Acquia won't allow increasing these fields from 255 to 256, perhaps any attempt at a patch here is dead in the water unless it's decided we don't need to support Acquia's hosting platform and/or Percona Server's default settings.
Comment #25
mvcOops, forgot to trigger the testbot.
Comment #26
mvcI also forgot to set the version to 7.x-2.x, which is where I assume the active development is happening. The relevant code doesn't seem to have changed between those branches, although if/when #2194099: Create database index on the redirect column lands this patch will need a minor change to manage the new index on the redirect column.
Comment #27
joachim commented> As mentioned above, this works for me with MySQL 5.1.73. The only outstanding issue is one report of problems with Percona XtraDB from joachim, for which I'd like more information, as mentioned in #14.
I'm sorry, but this was so long ago that I don't even remember which project I was working on at the time!
Comment #28
nagarsethDoes the limitations on Acquia's environment still hold true?
I would like to fix this issue too, from what I have found, some people have created new modules to edit the existing DB using hook_schema_alter, and then basically just adding their field below it. Has anyone here tried that?
Comment #29
vbard commented#24 failed to apply on 1.x-dev. On update db there was an error:
So I had to remove from #24 patch everything exept the following:
Then I patched the module with modified patch and run the following in mysql cli:
My Mysql server version is:
Comment #30
socialnicheguru commentedcauses major issue:
https://www.drupal.org/node/2815099
Comment #31
jyraya commentedHello,
I meet also the PDO Exception mentioned by @vbard.
Same repro steps but with a MySQL 5.6.38.
Note that without the patch, I do not have the issue.
EDIT:
I managed to redirect working with column sizes of 900 by following this steps:
ALTER TABLE redirect ADD INDEX status_source_language (status, source, language);I tried to translate this into code as follow:
But That does not work, I still have the PDOException:
exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes'I hope that can helps.
Comment #32
jyraya commentedI managed to install "redirect" with the the column size set 900.
For this, I created a new patch with the help I found in this issue: #2549049: Data too long for 'mailto' and its patch 2549049-10.patch.
I set to 255 the number of characters that the index must take into account for the field "source":
.
The part I do not get is that according to the MySQL documentation, if the number of characters is not set, MySQL sets it to 255 by default.
So, the patch #24 should work and the number of character should be 255 but it does not while executing the SQL cli "ALTER TABLE redirect ADD INDEX status_source_language (status, source, language);" does not generate an error.
See screenshot " 2057615-index-db-screenshot.png".
Anyway, I tested the patch with MySQL 5.6 and SQLite and I did not meet any issue with it.
Feedbacks are welcomed.
Comment #33
enriquelacoma commentedI updated the patch to include in the field help information regarding the number of characters that can be used
Comment #34
albapb commentedPatch #33 worked as expected for me
Comment #35
jyraya commented@enriquelacoma,
I aligned the "redirect" field description on the "source" one.
Otherwise, everything is ok.
@every one
I think that we address with this last patch all points reported in the issue.
Could we consider it as RTBC?
Comment #36
enriquelacoma commentedComment #37
alex_optimLooks good.
Comment #38
pifagor commentedComment #41
pifagor commentedComment #43
ion.macaria commentedI think we also have to add this code in update_7101.
Comment #44
jwilson3Its hard to follow all the comments and different patches on this issue and whether the support for older Mysql versions was actually added, but I can confirm that on latest 7.x-dev version, installing this on a site with Mysql 5.6.34 fails horribly.
The module is partially installed, but the redirect table is not built, I still get the error message mentioned above:
I had to leave the module disabled for now. Drush even had problems disabling the module the first time, but the second attempt worked.
Comment #45
andralex commentedI've created the patch in similar issue
It should solve last issue.
Comment #46
ulethjay commentedUh... Hate to dig up an old issue but...
Shouldn't there be a hook_update_n for this?
I just updated to from rc3 to rc4 and did the database updates (7103, 7104) and noticed that my field lengths were still 255 bytes. Personally I wouldn't much care how long they are, but the UI now claims a 900 char limit. I suspect this disparity may cause issues for some people.
Comment #47
pendaco commentedWith ulethjay #46
I wasn't sure whether or not I should create a new ticket for this but I think it's mostly related to this one.
After upgrading from 7.x-1.0-rc3 to 7.x-1.0-rc4 I get the following notices from the Schema module:
Is there any way to easily fix these?