Added index hints for SQL Server. Improvements to existing query hints for Mysql and Cubrid.

git-svn-id: http://xe-core.googlecode.com/svn/branches/1.5.0@9481 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
ucorina 2011-10-04 13:19:45 +00:00
parent eaa1a02adc
commit 3815aece09
19 changed files with 320 additions and 6 deletions

View file

@ -30,6 +30,7 @@
require(_XE_PATH_.'classes/db/queryparts/table/JoinTable.class.php');
require(_XE_PATH_.'classes/db/queryparts/table/CubridTableWithHint.class.php');
require(_XE_PATH_.'classes/db/queryparts/table/MysqlTableWithHint.class.php');
require(_XE_PATH_.'classes/db/queryparts/table/MssqlTableWithHint.class.php');
require(_XE_PATH_.'classes/db/queryparts/table/IndexHint.class.php');
require(_XE_PATH_.'classes/db/queryparts/condition/ConditionGroup.class.php');
require(_XE_PATH_.'classes/db/queryparts/condition/Condition.class.php');
@ -566,8 +567,9 @@
if(is_a($tableObject, 'CubridTableWithHint'))
$index_hint_list .= $tableObject->getIndexHintString() . ', ';
}
$index_hint_list = substr($index_hint_list, 0, -2);
if($index_hint_list != '')
$index_hint_list = 'USING INDEX ' . substr($index_hint_list, 0, -2);
$index_hint_list = 'USING INDEX ' . $index_hint_list;
$groupBy = $query->getGroupByString();
if($groupBy != '') $groupBy = ' GROUP BY ' . $groupBy;

View file

@ -12,9 +12,19 @@
function getIndexHintString(){
$result = '';
// Retrieve table prefix, to add it to index name
$db_info = Context::getDBInfo();
$prefix = $db_info->master_db["db_table_prefix"];
foreach($this->index_hints_list as $index_hint){
$result .= $this->alias . '.' . $index_hint->getIndexName()
. ($index_hint->getIndexHintType() == 'FORCE' ? '(+)' : '') . ', ';
$index_hint_type = $index_hint->getIndexHintType();
if($index_hint_type !== 'IGNORE'){
$result .= $this->alias . '.'
. '"' . $prefix . substr($index_hint->getIndexName(), 1)
. ($index_hint_type == 'FORCE' ? '(+)' : '')
. ', ';
}
}
$result = substr($result, 0, -2);

View file

@ -0,0 +1,29 @@
<?php
class MssqlTableWithHint extends Table {
var $name;
var $alias;
var $index_hints_list;
function MssqlTableWithHint($name, $alias = NULL, $index_hints_list){
parent::Table($name, $alias);
$this->index_hints_list = $index_hints_list;
}
function toString(){
$result = parent::toString();
$index_hint_string = '';
foreach($this->index_hints_list as $index_hint){
$index_hint_type = $index_hint->getIndexHintType();
if(in_array($index_hint_type, array('USE', 'FORCE')))
$index_hint_string .= 'INDEX(' . $index_hint->getIndexName() . '), ';
}
if($index_hint_string != ''){
$result .= ' WITH(' . substr($index_hint_string, 0, -2) . ') ';
}
return $result;
}
}
?>

View file

@ -42,6 +42,7 @@
require_once(_XE_PATH_.'classes/db/queryparts/table/JoinTable.class.php');
require_once(_XE_PATH_.'classes/db/queryparts/table/CubridTableWithHint.class.php');
require_once(_XE_PATH_.'classes/db/queryparts/table/MysqlTableWithHint.class.php');
require_once(_XE_PATH_.'classes/db/queryparts/table/MssqlTableWithHint.class.php');
require_once(_XE_PATH_.'classes/db/queryparts/table/IndexHint.class.php');
require_once(_XE_PATH_.'classes/db/queryparts/condition/ConditionGroup.class.php');
require_once(_XE_PATH_.'classes/db/queryparts/condition/Condition.class.php');

View file

@ -15,7 +15,7 @@
function testOneUseIndexHintAndOneTable(){
$xml_file = $this->xmlPath . "one_index_hint_one_table.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member" using index "member"."idx_member_list_order"';
$expected = 'select * from "xe_member" as "member" using index "member"."xe_idx_member_list_order"';
$this->_test($xml_file, $argsString, $expected);
}
@ -23,7 +23,7 @@
function testTwoUseIndexHintsAndOneTable(){
$xml_file = $this->xmlPath . "two_index_hints_one_table.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member" using index "member"."idx_member_list_order", "member"."idx_member_srl"';
$expected = 'select * from "xe_member" as "member" using index "member"."xe_idx_member_list_order", "member"."xe_idx_member_srl"';
$this->_test($xml_file, $argsString, $expected);
}
@ -31,7 +31,53 @@
$xml_file = $this->xmlPath . "three_index_hints_two_tables.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member", "xe_document" as "document"
using index "member"."idx_member_list_order", "member"."idx_member_srl", "document"."idx_document_srl"';
using index "member"."xe_idx_member_list_order", "member"."xe_idx_member_srl", "document"."xe_idx_document_srl"';
$this->_test($xml_file, $argsString, $expected);
}
function testThreeUseIndexHintsAndTwoTablesCombined(){
$xml_file = $this->xmlPath . "three_index_hints_two_tables_combined.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member", "xe_document" as "document"
using index "member"."xe_idx_member_list_order", "member"."xe_idx_member_srl"(+), "document"."xe_idx_document_srl"';
$this->_test($xml_file, $argsString, $expected);
}
function testIgnoreIndexHintIsSkipped(){
$xml_file = $this->xmlPath . "ignore_index_hint.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member"';
$this->_test($xml_file, $argsString, $expected);
}
function testMysqlIndexHintIsSkipped(){
$xml_file = $this->xmlPath . "mysql_index_hint.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member"';
$this->_test($xml_file, $argsString, $expected);
}
/**
* If CUBRID database is used, indexes are created with prefix.
*
* e.g.: xe_indx_list_order
*/
function testPrefixIsAddedToIndexName(){
$xml_file = $this->xmlPath . "one_index_hint_one_table.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member" using index "member"."xe_idx_member_list_order"';
$this->_test($xml_file, $argsString, $expected);
}
/**
* Tests that index is added if "for" attribute is "ALL"
*
* example: <index_hint for="ALL"> ... </index_hint>
*/
function testIndexHintForAll(){
$xml_file = $this->xmlPath . "index_hint_for_all.xml";
$argsString = '';
$expected = 'select * from "xe_member" as "member" using index "member"."xe_idx_member_list_order"';
$this->_test($xml_file, $argsString, $expected);
}

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="CUBRID">
<index table="member" name="idx_member_list_order" type="IGNORE" />
</index_hint>
</query>

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="ALL">
<index table="member" name="idx_member_list_order" type="USE" />
</index_hint>
</query>

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="MYSQL">
<index table="member" name="idx_member_list_order" type="IGNORE" />
</index_hint>
</query>

View file

@ -0,0 +1,14 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
<table name="document" alias="document" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="CUBRID">
<index table="member" name="idx_member_list_order" type="USE" />
<index table="member" name="idx_member_srl" type="FORCE" />
<index table="document" name="idx_document_srl" type="USE" />
</index_hint>
</query>

View file

@ -0,0 +1,64 @@
<?php
class MssqlIndexHintTest extends MssqlTest {
var $xmlPath = 'data/';
function MssqlIndexHintTest(){
$this->xmlPath = str_replace('MssqlIndexHintTest.php', '', str_replace('\\', '/', __FILE__)) . $this->xmlPath;
}
function _test($xml_file, $argsString, $expected){
$this->_testQuery($xml_file, $argsString, $expected, 'getSelectSql');
}
function testOneUseIndexHintAndOneTable(){
$xml_file = $this->xmlPath . "one_index_hint_one_table.xml";
$argsString = '';
$expected = 'select * from [xe_member] as [member] with(index([idx_member_list_order]))';
$this->_test($xml_file, $argsString, $expected);
}
function testTwoUseIndexHintsAndOneTable(){
$xml_file = $this->xmlPath . "two_index_hints_one_table.xml";
$argsString = '';
$expected = 'select * from [xe_member] as [member] with(index([idx_member_list_order]), index([idx_member_srl]))';
$this->_test($xml_file, $argsString, $expected);
}
function testThreeUseIndexHintsAndTwoTables(){
$xml_file = $this->xmlPath . "three_index_hints_two_tables.xml";
$argsString = '';
$expected = 'select * from [xe_member] as [member] with(index([idx_member_list_order]), index([idx_member_srl]))
, [xe_document] as [document] with(index([idx_document_srl]))';
$this->_test($xml_file, $argsString, $expected);
}
/**
* Tests that index is added if "for" attribute is "ALL"
*
* example: <index_hint for="ALL"> ... </index_hint>
*/
function testIndexHintForAll(){
$xml_file = $this->xmlPath . "index_hint_for_all.xml";
$argsString = '';
$expected = 'select * from [xe_member] as [member] with(index([idx_member_list_order]))';
$this->_test($xml_file, $argsString, $expected);
}
function testIgnoreIndexHintIsSkipped(){
$xml_file = $this->xmlPath . "ignore_index_hint.xml";
$argsString = '';
$expected = 'select * from [xe_member] as [member]';
$this->_test($xml_file, $argsString, $expected);
}
function testMysqlIndexHintIsSkipped(){
$xml_file = $this->xmlPath . "mysql_index_hint.xml";
$argsString = '';
$expected = 'select * from [xe_member] as [member]';
$this->_test($xml_file, $argsString, $expected);
}
}
?>

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="MSSQL">
<index table="member" name="idx_member_list_order" type="IGNORE" />
</index_hint>
</query>

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="ALL">
<index table="member" name="idx_member_list_order" type="USE" />
</index_hint>
</query>

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="MYSQL">
<index table="member" name="idx_member_list_order" type="IGNORE" />
</index_hint>
</query>

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="MSSQL">
<index table="member" name="idx_member_list_order" type="USE" />
</index_hint>
</query>

View file

@ -0,0 +1,14 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
<table name="document" alias="document" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="MSSQL">
<index table="member" name="idx_member_list_order" type="USE" />
<index table="member" name="idx_member_srl" type="USE" />
<index table="document" name="idx_document_srl" type="USE" />
</index_hint>
</query>

View file

@ -0,0 +1,12 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="MSSQL">
<index table="member" name="idx_member_list_order" type="USE" />
<index table="member" name="idx_member_srl" type="USE" />
</index_hint>
</query>

View file

@ -34,5 +34,25 @@
$this->_test($xml_file, $argsString, $expected);
}
function testThreeIndexHintsAndTwoTables_ForceAndIgnore(){
$xml_file = $this->xmlPath . "three_index_hints_two_tables_combined.xml";
$argsString = '';
$expected = 'select * from `xe_member` as `member` force index (`idx_member_list_order`, `idx_member_srl`)
, `xe_document` as `document` ignore index (`idx_document_srl`)';
$this->_test($xml_file, $argsString, $expected);
}
/**
* Tests that index is added if "for" attribute is "ALL"
*
* example: <index_hint for="ALL"> ... </index_hint>
*/
function testIndexHintForAll(){
$xml_file = $this->xmlPath . "index_hint_for_all.xml";
$argsString = '';
$expected = 'select * from `xe_member` as `member` use index (`idx_member_list_order`)';
$this->_test($xml_file, $argsString, $expected);
}
}
?>

View file

@ -0,0 +1,11 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="ALL">
<index table="member" name="idx_member_list_order" type="USE" />
</index_hint>
</query>

View file

@ -0,0 +1,14 @@
<query id="index_hint" action="select">
<tables>
<table name="member" alias="member" />
<table name="document" alias="document" />
</tables>
<columns>
<column name="*" />
</columns>
<index_hint for="MYSQL">
<index table="member" name="idx_member_list_order" type="FORCE" />
<index table="member" name="idx_member_srl" type="FORCE" />
<index table="document" name="idx_document_srl" type="IGNORE" />
</index_hint>
</query>