Posted by xjm
The documentation states:
Rather than using a textfield or weight field, this form depends entirely upon the order of form elements on the page to determine new weights.
Because there might be hundreds or thousands of taxonomy terms that need to be ordered, terms are weighted from 0 to the number of terms in the vocabulary, rather than the standard -10 to 10 scale. Numbers are sorted lowest to highest, but are not necessarily sequential. Numbers may be skipped when a term has children so that reordering is minimal when a child is added or removed from a term.
However, the weight field of term_data is implemented as a signed tinyint in the taxonomy_schema(), which would mean it can only range from -128 to 127, and I don't see any function in taxonomy.module to update the schema. Indeed, I tested it for a vocabulary with 150 terms or so, and ordering stops working after term weight 126 (all heavier terms are inserted as 127). I understand this could be corrected with contrib, but the core documentation is incorrect given the current functionality.
| Comment | File | Size | Author |
|---|---|---|---|
| #45 | 612870.45-increase-weights-d6.patch | 5.26 KB | mrfelton |
| #23 | 612870-increase-weights-d6.patch | 6.16 KB | benshell |
| #10 | 612870-increase-weights_02.patch | 7.88 KB | asimmonds |
| #8 | 612870-increase-weights.patch | 8.3 KB | asimmonds |
Comments
Comment #1
xjmFor reference, #471082: Taxonomy term weights range only 0-127 when dragged and http://drupal.org/node/117274#comment-1815970 are about this weighting behavior.
Comment #2
jhodgdonWow, good catch! This is a bug in the code, in my opinion, not the documentation (although if the code is not going to be fixed for some reason, the documentation is clearly wrong compared to the documentation).
The bug being that if you have more than 125 taxonomy terms in a given vocabulary, taxonomy_overview_terms_submit() will assign weights that exceed the tinyint size of the weight field in the database. See
http://api.drupal.org/api/function/taxonomy_overview_terms_submit/7
http://api.drupal.org/api/function/taxonomy_schema/7
Actually, you could run into trouble with even fewer than 126 terms, because (if the current doc header is correct about that) the numbering might not be sequential.
It's a bug in Drupal 7, but probably should be backported to the next release of Drupal 6 as well? It seems serious to me. The fix is easy: change the taxonomy schema so that the weight field is not a "tiny" integer.
Comment #3
jhodgdonOther possible places in the Drupal 7 code that might have this problem are from fields (aside from "flag" or boolean fields) in the Drupal database that are defined to be type="int", size="tiny". Here is what I found in the Drupal 7 code base:
- block module/block table/weight field
- contact module/contact table/weight field
- filter module/filter table/weight field
- filter module/filter_format table/weight field
- poll module/poll_choice table/weight field
- profile module/profile_field table/weight field
- taxonomy module/taxonomy_term_data table/weight field
- taxonomy module/taxonomy_vocabulary table/weight field
- upload module/upload table/weight field
These mostly apply in Drupal 6 as well, with minor changes (such as table names that have changed).
I haven't yet examined the form submit code for these modules to see whether they have the same problem as taxonomy_overview_terms_submit() either, just noting that these are tables with tinyint weight fields, which seems like at least a potential problem.
Comment #4
jhodgdonUpon further reflection, this is probably a critical bug.
Comment #5
chx commentedsuncatch asked me how big our terms table is, it's less than a million, a normal int will do.Comment #6
jhodgdonWell then, probably all of the tables listed in #3 should be changed so their weight fields are int/medium or int/normal rather than int/tiny. In both Drupal 6 and 7.
Hmmm... http://drupal.org/node/159605 says that medium int is 3 bytes in MySQL, 4 bytes in PostgreSQL.... That's enough to go to 8 million, so that should be OK (see http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html). "int/normal" is 4 bytes on both platforms.
Comment #7
catchAgreed, and this should be done across the board. Since it's a schema change would be nice to get it in soonish. This is only critical for taxonomy and possibly profile since the rest are much less likely to hit the restriction, but since contrib modules will likely copy and paste schema from places it's better to be consistent here.
Comment #8
asimmonds commentedFirst stab at a patch to increase the weight columns to 'normal' for the tables listed in #3.
Uploaded so the testbot can test.
- Does 'normal' have to specified? I think this is the default if you don't specify a size (ie menu_links table)
@ #drupalsouth
Comment #9
dave reidI think we can just exclude 'size' => 'normal' since that's the default? And we don't need to drop and define all the indexes again?
Comment #10
asimmonds commenteddb_change_field() api help has:
I am just re-creating the indexes where the weight field was included.
Patch updated to remove the size => 'normal'. Pretty certain that is the default, on mysql 5.0 'normal' is int(11) and leaving it out is int(11)
Comment #11
dries commentedThis looks good to me, but let's see what the test bot says (currently in 'test request sent').
Comment #12
jhodgdonHow about putting in an explicit size rather than just removing 'size' => 'tiny' in all of those db columns?
Comment #13
dave reid@Dries Test bot won't work until #693362: taxonomy_form_all() is dangerous is rolled back as well.
Comment #14
dries commented#693362: taxonomy_form_all() is dangerous was rolled back.
Comment #15
jhodgdonLooks like this is RTBC then? My comment in #12 was negated by #9 & #10.
Comment #16
webchickI didn't notice any menu module hunks in here, but checked and those weight fields are already set to ints. I have a feeling this fix will solve a couple of other issues in the queue now.
Committed to HEAD. Marking for backport, depending on how Gábor feels about this.
Comment #17
RonD commentedI wish to encourage Gabor to backport this fix.
We are building out a site in 6.15 and encountered this issue with blocks yesterday. I found http://drupal.org/node/565220#comment-2161254 yesterday and found this issue today while checking for duplicates before posting a new issue.
Comment #18
grendzy commentedI also encountered this today on a D6 site with a large number of blocks. They could be re-ordered with tabledrag, but saving the form had no effect.
Comment #19
NaX commented+1 for the backport
I just run into this problem with taxonomy on a large vocabulary. If you have a large vocabulary of more than 127 items you are forced by this limitation to sort alphabetically or at least from the 127th item onwards. In my case Countries grouped by continent. I was unable to have a No Region item last, until I manually changed the column.
Comment #20
jhodgdonGabor doesn't normally backport fixes. Someone in the community writes the patch, someone else in the community reviews and tests the patch sufficiently to mark it "reviewed and tested by the community", and then Gabor commits it if he agrees it is a good patch. That is the process.
So, if you are interested in getting this fix into Drupal 6, the next step is for someone to scan through the hook_schema() functions in Drupal 6 core, find everywhere that weight fields are tinyint instead of int, and make a patch to change them. In Drupal 6, this will also require update functions, besides changing the schema definition, similar to what was done in Drupal 7 patch in #10 above.
Anyway, it isn't the exact patch from #10, but it should be somewhat similar.
Comment #21
cyberwolf commentedSubscribing. Also encountering the weight limitation, on the terms of a taxonomy vocabulary.
Comment #22
Dublin Drupaller commentedI'm having the same problem in drupal 6.x specifically with blocks but I see that the patch in #10 covers a lot of other tables which would be useful if it was rolled back.
Comment #23
benshell commentedHere is a D6 backport of this patch, ready for testing. At least the taxonomy part of this patch is critical for many sites.
Comment #24
zilverdistel commentedTested the patch in #23, seems to work for me ...
Comment #25
EvanDonovan commentedWill test this soon. Ran into this today with profile.module (shudder!) fields...
Comment #26
chrisarusso commented#23 worked well for me too. Thanks benshell et al.
Comment #27
cydharttha commentedThanks much, was beating my head against an Ubercart install with a large catalog (taxonomy). Updating DB schema solved it.
Comment #28
Mac Clemmens commentedThanks, Ben! Prior to this patch, I kept running into issues and have had to increase the size of the int field manually.
Comment #29
mile23Marked this as duplicate: #329740: Blocks cannot be rearranged if there are more than 128 in a given region (they get automatically arranged in alphabetical order)
Comment #30
xjmWe RTBC here (based on #24-28)?
Comment #31
EvanDonovan commentedSorry didn't actually test. But others seem to have had success...
Comment #32
gábor hojtsyUhm, why do we need to have separate code blocks here for MySQL and PostgreSQL? Also, how should we coordinate fixes for this in the D7 update path? I assume the update will not be a problem except unneeded code runs. Anybody verified that?
Comment #33
gábor hojtsyComment #34
pgillis commentedSubscribe
Comment #35
Foonaka commentedIf there's any noobies out there, be sure to run Update.php after applying the patch. I about beat myself over the head until I remembered that I had not done that yet. Once I did, it worked like a charm!!! Thanks to benshell for backporting that patch for D6.
Comment #36
Foonaka commentedSorry, I accidentally changed the title of this topic! Hopefully this will change it back...
Comment #37
brulain commented#8: 612870-increase-weights.patch queued for re-testing.
Comment #38
harrrrrrr commentedany progress?
Comment #39
xjmSee #32 for the questions that still need to be addressed.
Comment #40
forbesgraham commentedSubscribed!
Comment #41
xjm@forbesgraham: You do not need to post "subscribe" comments any more. There is a green "Follow" button in the upper right corner of issues.
Comment #42
aloyr commentedhere is a thought for the first part of your question: I am not all that familiar with postgresql, but it seems that it handles alter column differently than mysql, so drupal 6 has an api function to deal with that kind of stuff. of course drupal 7 implements the database layer pretty differently than 6 and doesn't have that api call anymore.
can this change for drupal 6 be moved upstream?
Comment #44
xjmSee #16. This is already fixed in D7.
Comment #45
mrfelton commentedPatch updated to apply against latest D6 git code.
Comment #46
fietserwinIn reply to the concerns mentioned in #32:
Separate lines of code for postgress versus mysql: I guess these are not needed. Drupal 6 does have change_db_field() as well, so the D6 patch could be very similar to the D7 patch. However, the patch as posted also works as already confirmed before by others and now once more by myself (site with more than 255 blocks). So the discussion is not about whether it works or not, but about more subjective terms like cleanliness, maintainability, understandability. Regarding these, I would like to mention that it doesn't really matter in this case.
- This code won't be maintained. Errors in hook_update() can often only be solved by writing yet another hook_update,not by changing the code itself.
- This code was readable and understandable for me.
Moreover, considering D6 is already far in the maintenance phase of its life cylce, chances that this code needs to be refactored are minimal. And we all know that if I would put this issue back by rewriting the patch, it will not reach RTBC for the next year.
So, the choice is: accept this possibly slightly inferior but tested, reviewed and working patch, or accept that this issue will "never" reach RTBC and that from time to time Drupal users will loose many hours of debugging and searching before they stumble upon this issue.
D7 update: I tested these steps:
- clean 6.26 install
- applying the patch from #45
- run update.php
- install 7.14
- run update.php from 7.14
No problems at all. Database is as it should be.
Furthermore: I reviewed the hook_update()s that will be run between the updates in this patch and the "corresponding" hook_update()s in the D7 .install files: none of these resets, touches or assumes anything about the size of the weight field. So no problems here either.
Comment #47
sunward commentedthis patch (#45) works.
But to have to redo the patch with every update is just asking for trouble. It is also getting annoying having to redo the taxonomy for the catalog (getting big for an ecommerce site)
Any chance this could be made permanent or as a module?
Comment #48
Jenechka commentedThank you! Patch from #45 works!
Comment #49
jvieille commentedAny hope? 3 years old bug...
Comment #49.0
jvieille commentedRemoving myself from the author field to unfollow the issue. --xjm
Comment #50
pianodavid commentedHi, any hope of getting this commited to D6?