Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php |
— | — | @@ -693,9 +693,7 @@ |
694 | 694 | $res = $db->query( $sql, $fname ); |
695 | 695 | } |
696 | 696 | |
697 | | - $this->setupIndex($smw_relations, 'subject_id', $db); |
698 | | - $this->setupIndex($smw_relations, 'relation_title', $db); |
699 | | - $this->setupIndex($smw_relations, 'object_title', $db); |
| 697 | + $this->setupIndex($smw_relations, array('subject_id','relation_title','object_title,object_namespace'), $db); |
700 | 698 | |
701 | 699 | // create attribute table |
702 | 700 | if ($db->tableExists('smw_attributes') === false) { |
— | — | @@ -712,10 +710,7 @@ |
713 | 711 | $res = $db->query( $sql, $fname ); |
714 | 712 | } |
715 | 713 | |
716 | | - $this->setupIndex($smw_attributes, 'subject_id', $db); |
717 | | - $this->setupIndex($smw_attributes, 'attribute_title', $db); |
718 | | - $this->setupIndex($smw_attributes, 'value_num', $db); |
719 | | - $this->setupIndex($smw_attributes, 'value_xsd', $db); |
| 714 | + $this->setupIndex($smw_attributes, array('subject_id','attribute_title','value_num','value_xsd'), $db); |
720 | 715 | |
721 | 716 | // create table for long string attributes |
722 | 717 | if ($db->tableExists('smw_longstrings') === false) { |
— | — | @@ -729,23 +724,21 @@ |
730 | 725 | $res = $db->query( $sql, $fname ); |
731 | 726 | } |
732 | 727 | |
733 | | - $this->setupIndex($smw_longstrings, 'subject_id', $db); |
734 | | - $this->setupIndex($smw_longstrings, 'attribute_title', $db); |
| 728 | + $this->setupIndex($smw_longstrings, array('subject_id','attribute_title'), $db); |
735 | 729 | |
736 | 730 | // create table for special properties |
737 | 731 | if ($db->tableExists('smw_specialprops') === false) { |
738 | 732 | $sql = 'CREATE TABLE ' . $wgDBname . '.' . $smw_specialprops . ' |
739 | | - ( subject_id INT(8) UNSIGNED NOT NULL, |
| 733 | + ( subject_id INT(8) UNSIGNED NOT NULL, |
740 | 734 | subject_namespace INT(11) NOT NULL, |
741 | 735 | subject_title VARCHAR(255) NOT NULL, |
742 | 736 | property_id SMALLINT NOT NULL, |
743 | 737 | value_string VARCHAR(255) NOT NULL |
744 | | - ) TYPE=innodb'; |
| 738 | + ) TYPE=innodb'; /// TODO: remove subject_namespace and subject_title columns completely |
745 | 739 | $res = $db->query( $sql, $fname ); |
746 | 740 | } |
747 | 741 | |
748 | | - $this->setupIndex($smw_specialprops, 'subject_id', $db); |
749 | | - $this->setupIndex($smw_specialprops, 'property_id', $db); |
| 742 | + $this->setupIndex($smw_specialprops, array('subject_id', 'property_id'), $db); |
750 | 743 | |
751 | 744 | return true; |
752 | 745 | } |
— | — | @@ -850,6 +843,7 @@ |
851 | 844 | * wasn't possible to make a suitable inner join. |
852 | 845 | */ |
853 | 846 | protected function addInnerJoin($tablename, &$from, &$db, &$curtables) { |
| 847 | + global $smwgIQRedirectNormalization; |
854 | 848 | if (array_key_exists($tablename, $curtables)) { // table already present |
855 | 849 | return true; |
856 | 850 | } |
— | — | @@ -864,13 +858,30 @@ |
865 | 859 | } elseif ($tablename == 'CATS') { |
866 | 860 | if ($this->addInnerJoin('PAGE', $from, $db, $curtables)) { // try to add PAGE |
867 | 861 | $curtables['CATS'] = 'cl' . $this->m_tablenum++; |
868 | | - $from .= ' INNER JOIN ' . $db->tableName('categorylinks') . ' AS ' . $curtables['CATS'] . ' ON ' . $curtables['CATS'] . '.cl_from=' . $curtables['PAGE'] . '.page_id'; |
| 862 | + $cond = $curtables['CATS'] . '.cl_from=' . $curtables['PAGE'] . '.page_id'; |
| 863 | +// if ($smwgIQRedirectNormalization) { |
| 864 | +// $this->addInnerJoin('REDIPAGE', $from, $db, $curtables); |
| 865 | +// $cond = '((' . $cond . ') OR (' . |
| 866 | +// $curtables['PAGE'] . '.page_id=' . $curtables['REDIRECT'] . '.rd_from AND ' . |
| 867 | +// $curtables['REDIRECT'] . '.rd_title=' . $curtables['REDIPAGE'] . '.page_title AND ' . |
| 868 | +// $curtables['REDIRECT'] . '.rd_namespace=' . $curtables['REDIPAGE'] . '.page_namespace AND ' . |
| 869 | +// $curtables['REDIPAGE'] . '.page_id=' . $curtables['CATS'] . '.cl_from))'; |
| 870 | +// } |
| 871 | + $from .= ' INNER JOIN ' . $db->tableName('categorylinks') . ' AS ' . $curtables['CATS'] . ' ON ' . $cond; |
869 | 872 | return true; |
870 | 873 | } |
871 | 874 | } elseif ($tablename == 'RELS') { |
872 | 875 | if ($this->addInnerJoin('PAGE', $from, $db, $curtables)) { // try to add PAGE |
873 | 876 | $curtables['RELS'] = 'rel' . $this->m_tablenum++; |
874 | | - $from .= ' INNER JOIN ' . $db->tableName('smw_relations') . ' AS ' . $curtables['RELS'] . ' ON ' . $curtables['RELS'] . '.subject_id=' . $curtables['PAGE'] . '.page_id'; |
| 877 | + $cond = $curtables['RELS'] . '.subject_id=' . $curtables['PAGE'] . '.page_id'; |
| 878 | +// if ($smwgIQRedirectNormalization) { |
| 879 | +// $this->addInnerJoin('REDIRECT', $from, $db, $curtables); |
| 880 | +// $cond = '((' . $cond . ') OR (' . |
| 881 | +// $curtables['PAGE'] . '.page_id=' . $curtables['REDIRECT'] . '.rd_from AND ' . |
| 882 | +// $curtables['REDIRECT'] . '.rd_title=' . $curtables['RELS'] . '.subject_title AND ' . |
| 883 | +// $curtables['REDIRECT'] . '.rd_namespace=' . $curtables['RELS'] . '.subject_namespace))'; |
| 884 | +// } |
| 885 | + $from .= ' INNER JOIN ' . $db->tableName('smw_relations') . ' AS ' . $curtables['RELS'] . ' ON ' . $cond; |
875 | 886 | return true; |
876 | 887 | } |
877 | 888 | } elseif ($tablename == 'ATTS') { |
— | — | @@ -891,6 +902,12 @@ |
892 | 903 | $from .= ' INNER JOIN ' . $db->tableName('redirect') . ' AS ' . $curtables['REDIRECT']; |
893 | 904 | return true; |
894 | 905 | } |
| 906 | + } elseif ($tablename == 'REDIPAGE') { // add another copy of page for getting ids of redirect targets |
| 907 | + if ($this->addInnerJoin('REDIRECT', $from, $db, $curtables)) { |
| 908 | + $curtables['REDIPAGE'] = 'rp' . $this->m_tablenum++; |
| 909 | + $from .= ' INNER JOIN ' . $db->tableName('page') . ' AS ' . $curtables['REDIPAGE']; |
| 910 | + return true; |
| 911 | + } |
895 | 912 | } |
896 | 913 | return false; |
897 | 914 | } |
— | — | @@ -1064,26 +1081,35 @@ |
1065 | 1082 | } |
1066 | 1083 | |
1067 | 1084 | /** |
1068 | | - * Make sure that the given column in the given DB table is indexed by *one* index. |
| 1085 | + * Make sure that each of the column descriptions in the given array is indexed by *one* index |
| 1086 | + * in the given DB table. |
1069 | 1087 | */ |
1070 | | - protected function setupIndex($table, $column, $db) { |
| 1088 | + protected function setupIndex($table, $columns, $db) { |
1071 | 1089 | $fname = 'SMW::SetupIndex'; |
1072 | 1090 | $res = $db->query( 'SHOW INDEX FROM ' . $table , $fname); |
1073 | 1091 | if ( !$res ) { |
1074 | 1092 | return false; |
1075 | 1093 | } |
1076 | | - $exists = false; |
| 1094 | + $indexes = array(); |
1077 | 1095 | while ( $row = $db->fetchObject( $res ) ) { |
1078 | | - if ( $row->Column_name == $column ) { |
1079 | | - if ($exists) { // duplicate index, fix this |
1080 | | - $db->query( 'DROP INDEX ' . $row->Key_name . ' ON ' . $table); |
1081 | | - } |
1082 | | - $exists = true; |
| 1096 | + if (!array_key_exists($row->Key_name, $indexes)) { |
| 1097 | + $indexes[$row->Key_name] = array(); |
1083 | 1098 | } |
| 1099 | + $indexes[$row->Key_name][$row->Seq_in_index] = $row->Column_name; |
1084 | 1100 | } |
| 1101 | + foreach ($indexes as $key => $index) { // clean up existing indexes |
| 1102 | + $id = array_search(implode(',', $index), $columns ); |
| 1103 | + if ( $id !== false ) { |
| 1104 | + $columns[$id] = false; |
| 1105 | + } else { // duplicate or unrequired index |
| 1106 | + $db->query( 'DROP INDEX ' . $key . ' ON ' . $table); |
| 1107 | + } |
| 1108 | + } |
1085 | 1109 | |
1086 | | - if (!$exists) { |
1087 | | - $db->query( "ALTER TABLE $table ADD INDEX ( `$column` )", $fname ); |
| 1110 | + foreach ($columns as $column) { // add remaining indexes |
| 1111 | + if ($column != false) { |
| 1112 | + $db->query( "ALTER TABLE $table ADD INDEX ( $column )", $fname ); |
| 1113 | + } |
1088 | 1114 | } |
1089 | 1115 | return true; |
1090 | 1116 | } |