You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-3416 Revived MULT_EQUAL_FUNC support in conditions.
Removed unused symbol from DML code of the plugin.
This commit is contained in:
@ -470,6 +470,27 @@ bool SimpleFilter::operator==(const SimpleFilter& t) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SimpleFilter::semanticEq(const SimpleFilter& t) const
|
||||||
|
{
|
||||||
|
if (fOp != NULL)
|
||||||
|
{
|
||||||
|
if (*fOp != *t.fOp)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fLhs != NULL)
|
||||||
|
{
|
||||||
|
if (*fLhs != t.fLhs && *fLhs != *t.fRhs)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fRhs != NULL)
|
||||||
|
{
|
||||||
|
if (*fRhs != t.fRhs && *fRhs != *t.fLhs)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool SimpleFilter::operator==(const TreeNode* t) const
|
bool SimpleFilter::operator==(const TreeNode* t) const
|
||||||
{
|
{
|
||||||
const SimpleFilter* o;
|
const SimpleFilter* o;
|
||||||
|
@ -138,28 +138,36 @@ public:
|
|||||||
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
||||||
*
|
*
|
||||||
* Do a deep, strict (as opposed to semantic) equivalence test.
|
* Do a deep, strict (as opposed to semantic) equivalence test.
|
||||||
* @return true iff every member of t is a duplicate copy of every member of this; false otherwise
|
* @return true if every member of t is a duplicate copy of every member of this; false otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool operator==(const TreeNode* t) const;
|
virtual bool operator==(const TreeNode* t) const;
|
||||||
|
|
||||||
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
||||||
*
|
*
|
||||||
* Do a deep, strict (as opposed to semantic) equivalence test.
|
* Do a deep, strict (as opposed to semantic) equivalence test.
|
||||||
* @return true iff every member of t is a duplicate copy of every member of this; false otherwise
|
* @return true if every member of t is a duplicate copy of every member of this; false otherwise
|
||||||
*/
|
*/
|
||||||
bool operator==(const SimpleFilter& t) const;
|
bool operator==(const SimpleFilter& t) const;
|
||||||
|
|
||||||
|
/** @brief Do a semantic equivalence test
|
||||||
|
*
|
||||||
|
* Do a semantic equivalence test.
|
||||||
|
* @return true if filter operation are the same and
|
||||||
|
* the sets of arguments are the same; false otherwise
|
||||||
|
*/
|
||||||
|
bool semanticEq(const SimpleFilter& t) const;
|
||||||
|
|
||||||
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
||||||
*
|
*
|
||||||
* Do a deep, strict (as opposed to semantic) equivalence test.
|
* Do a deep, strict (as opposed to semantic) equivalence test.
|
||||||
* @return false iff every member of t is a duplicate copy of every member of this; true otherwise
|
* @return false if every member of t is a duplicate copy of every member of this; true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool operator!=(const TreeNode* t) const;
|
virtual bool operator!=(const TreeNode* t) const;
|
||||||
|
|
||||||
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
/** @brief Do a deep, strict (as opposed to semantic) equivalence test
|
||||||
*
|
*
|
||||||
* Do a deep, strict (as opposed to semantic) equivalence test.
|
* Do a deep, strict (as opposed to semantic) equivalence test.
|
||||||
* @return false iff every member of t is a duplicate copy of every member of this; true otherwise
|
* @return false if every member of t is a duplicate copy of every member of this; true otherwise
|
||||||
*/
|
*/
|
||||||
bool operator!=(const SimpleFilter& t) const;
|
bool operator!=(const SimpleFilter& t) const;
|
||||||
|
|
||||||
|
@ -88,109 +88,6 @@ inline uint32_t tid2sid(const uint32_t tid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//StopWatch timer;
|
//StopWatch timer;
|
||||||
int buildBuffer(uchar* buf, string& buffer, int& columns, TABLE* table)
|
|
||||||
{
|
|
||||||
char attribute_buffer[1024];
|
|
||||||
String attribute(attribute_buffer, sizeof(attribute_buffer),
|
|
||||||
&my_charset_bin);
|
|
||||||
|
|
||||||
std::string cols = " (";
|
|
||||||
std::string vals = " values (";
|
|
||||||
columns = 0;
|
|
||||||
|
|
||||||
for (Field** field = table->field; *field; field++)
|
|
||||||
{
|
|
||||||
const char* ptr;
|
|
||||||
const char* end_ptr;
|
|
||||||
|
|
||||||
if ((*field)->is_null())
|
|
||||||
ptr = end_ptr = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bitmap_set_bit(table->read_set, (*field)->field_index);
|
|
||||||
(*field)->val_str(&attribute, &attribute);
|
|
||||||
ptr = attribute.ptr();
|
|
||||||
end_ptr = attribute.length() + ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (columns > 0)
|
|
||||||
{
|
|
||||||
cols.append(",");
|
|
||||||
vals.append(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
columns++;
|
|
||||||
|
|
||||||
cols.append((*field)->field_name.str);
|
|
||||||
|
|
||||||
if (ptr == end_ptr)
|
|
||||||
{
|
|
||||||
vals.append ("NULL");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( (*field)->type() == MYSQL_TYPE_VARCHAR ||
|
|
||||||
/*FIXME: (*field)->type() == MYSQL_TYPE_VARBINARY || */
|
|
||||||
(*field)->type() == MYSQL_TYPE_VAR_STRING ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_STRING ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_DATE ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_DATETIME ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_DATETIME2 ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_TIMESTAMP ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_TIMESTAMP2 ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_TIME )
|
|
||||||
vals.append("'");
|
|
||||||
|
|
||||||
while (ptr < end_ptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*ptr == '\r')
|
|
||||||
{
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
else if (*ptr == '\n')
|
|
||||||
{
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
else if (*ptr == '\'' )
|
|
||||||
{
|
|
||||||
//@Bug 1820. Replace apostrophe with strange character to pass parser.
|
|
||||||
vals += '\252';
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vals += *ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (*field)->type() == MYSQL_TYPE_VARCHAR ||
|
|
||||||
/*FIXME: (*field)->type() == MYSQL_TYPE_VARBINARY || */
|
|
||||||
(*field)->type() == MYSQL_TYPE_VAR_STRING ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_STRING ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_DATE ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_DATETIME ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_DATETIME2 ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_TIMESTAMP ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_TIMESTAMP2 ||
|
|
||||||
(*field)->type() == MYSQL_TYPE_TIME )
|
|
||||||
vals.append("'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (columns)
|
|
||||||
{
|
|
||||||
cols.append(") ");
|
|
||||||
vals.append(") ");
|
|
||||||
buffer = "INSERT INTO ";
|
|
||||||
buffer.append(table->s->table_name.str);
|
|
||||||
buffer.append(cols);
|
|
||||||
buffer.append(vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t buildValueList (TABLE* table, cal_connection_info& ci )
|
uint32_t buildValueList (TABLE* table, cal_connection_info& ci )
|
||||||
{
|
{
|
||||||
char attribute_buffer[1024];
|
char attribute_buffer[1024];
|
||||||
|
@ -395,6 +395,40 @@ ReturnedColumn* buildAggFrmTempField(Item* item, gp_walk_info& gwi)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*@brief isDuplicateSF - search for a duplicate SimpleFilter*/
|
||||||
|
/***********************************************************
|
||||||
|
* DESCRIPTION:
|
||||||
|
* As of 1.4 CS potentially has duplicate filter predicates
|
||||||
|
* in both join->conds and join->cond_equal. This utility f()
|
||||||
|
* searches for semantically equal SF in the list of already
|
||||||
|
* applied equi predicates.
|
||||||
|
* TODO
|
||||||
|
* We must move find_select_handler to either future or
|
||||||
|
* later execution phase.
|
||||||
|
* PARAMETERS:
|
||||||
|
* gwi main structure
|
||||||
|
* sf SimpleFilter * to find
|
||||||
|
* RETURNS
|
||||||
|
* true if sf has been found in the applied SF list
|
||||||
|
* false otherwise
|
||||||
|
* USED
|
||||||
|
* buildPredicateItem()
|
||||||
|
***********************************************************/
|
||||||
|
bool isDuplicateSF(gp_walk_info *gwip, execplan::SimpleFilter *sfp)
|
||||||
|
{
|
||||||
|
List_iterator<execplan::SimpleFilter> it(gwip->equiCondSFList);
|
||||||
|
execplan::SimpleFilter *isfp;
|
||||||
|
while((isfp = it++))
|
||||||
|
{
|
||||||
|
if (sfp->semanticEq(*isfp))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
string getViewName(TABLE_LIST* table_ptr)
|
string getViewName(TABLE_LIST* table_ptr)
|
||||||
{
|
{
|
||||||
string viewName = "";
|
string viewName = "";
|
||||||
@ -1941,34 +1975,35 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
|||||||
}
|
}
|
||||||
else if (ifp->functype() == Item_func::MULT_EQUAL_FUNC)
|
else if (ifp->functype() == Item_func::MULT_EQUAL_FUNC)
|
||||||
{
|
{
|
||||||
#if 0 // MYSQL_5.6
|
Item_equal *cur_item_eq = (Item_equal*)ifp;
|
||||||
Item_equal* item_eq = (Item_equal*)ifp;
|
Item *lhs_item, *rhs_item;
|
||||||
// This code is for mysql 5.6. Need to convert to MariaDB 10.1
|
// There must be at least two items
|
||||||
List_iterator_fast<Item_field> it(item_eq->fields);
|
Item_equal_fields_iterator lhs_it(*cur_item_eq);
|
||||||
idbassert(item_eq->fields.elements == 2);
|
Item_equal_fields_iterator rhs_it(*cur_item_eq); rhs_it++;
|
||||||
|
while ((lhs_item = lhs_it++) && (rhs_item = rhs_it++))
|
||||||
// @todo handle more than 2 equal fields
|
|
||||||
Item* item_field = it++;
|
|
||||||
ReturnedColumn* lhs = buildReturnedColumn(item_field, *gwip, gwip->fatalParseError);
|
|
||||||
item_field = it++;
|
|
||||||
ReturnedColumn* rhs = buildReturnedColumn(item_field, *gwip, gwip->fatalParseError);
|
|
||||||
|
|
||||||
if (!rhs || !lhs)
|
|
||||||
{
|
{
|
||||||
gwip->fatalParseError = true;
|
ReturnedColumn* lhs = buildReturnedColumn(lhs_item, *gwip, gwip->fatalParseError);
|
||||||
gwip->parseErrorText = "Unsupport elements in MULT_EQUAL item";
|
ReturnedColumn* rhs = buildReturnedColumn(rhs_item, *gwip, gwip->fatalParseError);
|
||||||
delete rhs;
|
if (!rhs || !lhs)
|
||||||
delete lhs;
|
{
|
||||||
return false;
|
gwip->fatalParseError = true;
|
||||||
|
gwip->parseErrorText = "Unsupport elements in MULT_EQUAL item";
|
||||||
|
delete rhs;
|
||||||
|
delete lhs;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PredicateOperator* po = new PredicateOperator("=");
|
||||||
|
boost::shared_ptr<Operator> sop(po);
|
||||||
|
sop->setOpType(lhs->resultType(), rhs->resultType());
|
||||||
|
SimpleFilter* sf = new SimpleFilter(sop, lhs, rhs);
|
||||||
|
// Search in ptWorkStack for duplicates of the SF
|
||||||
|
// before we push the SF
|
||||||
|
if (!isDuplicateSF(gwip, sf))
|
||||||
|
{
|
||||||
|
ParseTree* pt = new ParseTree(sf);
|
||||||
|
gwip->ptWorkStack.push(pt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PredicateOperator* po = new PredicateOperator("=");
|
|
||||||
boost::shared_ptr<Operator> sop(po);
|
|
||||||
sop->setOpType(lhs->resultType(), rhs->resultType());
|
|
||||||
SimpleFilter* sf = new SimpleFilter(sop, lhs, rhs);
|
|
||||||
ParseTree* pt = new ParseTree(sf);
|
|
||||||
gwip->ptWorkStack.push(pt);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (ifp->functype() == Item_func::EQUAL_FUNC)
|
else if (ifp->functype() == Item_func::EQUAL_FUNC)
|
||||||
{
|
{
|
||||||
@ -2189,6 +2224,11 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ifp->functype() == Item_func::EQ_FUNC)
|
||||||
|
{
|
||||||
|
gwip->equiCondSFList.push_back(sf);
|
||||||
|
}
|
||||||
|
|
||||||
ParseTree* ptp = new ParseTree(sf);
|
ParseTree* ptp = new ParseTree(sf);
|
||||||
gwip->ptWorkStack.push(ptp);
|
gwip->ptWorkStack.push(ptp);
|
||||||
}
|
}
|
||||||
@ -3570,7 +3610,7 @@ ReturnedColumn* buildFunctionColumn(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO MariaDB 10.1: Until we figure out what to do with this
|
// Item_equal is supported by buildPredicateItem()
|
||||||
if (funcName == "multiple equal")
|
if (funcName == "multiple equal")
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -5077,9 +5117,7 @@ void gp_walk(const Item* item, void* arg)
|
|||||||
string aliasTableName(scp->tableAlias());
|
string aliasTableName(scp->tableAlias());
|
||||||
scp->tableAlias(lower(aliasTableName));
|
scp->tableAlias(lower(aliasTableName));
|
||||||
gwip->rcWorkStack.push(scp->clone());
|
gwip->rcWorkStack.push(scp->clone());
|
||||||
//gwip->rcWorkStack.push(scp);
|
|
||||||
boost::shared_ptr<SimpleColumn> scsp(scp);
|
boost::shared_ptr<SimpleColumn> scsp(scp);
|
||||||
//boost::shared_ptr<SimpleColumn> scsp(scp->clone());
|
|
||||||
gwip->scsp = scsp;
|
gwip->scsp = scsp;
|
||||||
|
|
||||||
gwip->funcName.clear();
|
gwip->funcName.clear();
|
||||||
@ -6257,6 +6295,27 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
#ifdef DEBUG_WALK_COND
|
#ifdef DEBUG_WALK_COND
|
||||||
cerr << "------------------ WHERE -----------------------" << endl;
|
cerr << "------------------ WHERE -----------------------" << endl;
|
||||||
icp->traverse_cond(debug_walk, &gwi, Item::POSTFIX);
|
icp->traverse_cond(debug_walk, &gwi, Item::POSTFIX);
|
||||||
|
if (join && join->cond_equal)
|
||||||
|
{
|
||||||
|
List_iterator<Item_equal> li(join->cond_equal->current_level);
|
||||||
|
Item_equal *cur_item_eq;
|
||||||
|
while ((cur_item_eq= li++))
|
||||||
|
{
|
||||||
|
// WIP replace the block with
|
||||||
|
//cur_item_eq->traverse_cond(debug_walk, gwip, Item::POSTFIX);
|
||||||
|
std::cerr << "item_equal(";
|
||||||
|
Item *item;
|
||||||
|
Item_equal_fields_iterator it(*cur_item_eq);
|
||||||
|
while ((item= it++))
|
||||||
|
{
|
||||||
|
std::ostringstream ostream;
|
||||||
|
std::ostringstream& osr = ostream;
|
||||||
|
getColNameFromItem(osr, item);
|
||||||
|
std::cerr << osr.str() << ",";
|
||||||
|
}
|
||||||
|
std::cerr << ")" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
cerr << "------------------------------------------------\n" << endl;
|
cerr << "------------------------------------------------\n" << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -6279,6 +6338,19 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi);
|
setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi);
|
||||||
return ER_INTERNAL_ERROR;
|
return ER_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MCOL-3416 support for EQUAL_COND in MDB >= 10.1
|
||||||
|
if (join && join->cond_equal)
|
||||||
|
{
|
||||||
|
// TODO MCOL-3416 This must traverse all levels not current_level only
|
||||||
|
List_iterator<Item_equal> li(join->cond_equal->current_level);
|
||||||
|
Item_equal *cur_item_eq;
|
||||||
|
while ((cur_item_eq= li++))
|
||||||
|
{
|
||||||
|
cur_item_eq->traverse_cond(gp_walk, &gwi, Item::POSTFIX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (join && join->zero_result_cause)
|
else if (join && join->zero_result_cause)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +143,9 @@ struct gp_walk_info
|
|||||||
std::map<std::string, execplan::ParseTree*> derivedTbFilterMap;
|
std::map<std::string, execplan::ParseTree*> derivedTbFilterMap;
|
||||||
uint32_t derivedTbCnt;
|
uint32_t derivedTbCnt;
|
||||||
std::vector<execplan::SCSEP> subselectList;
|
std::vector<execplan::SCSEP> subselectList;
|
||||||
|
// Workaround for duplicate equi-JOIN predicates
|
||||||
|
// See isDuplicateSF() for more info.
|
||||||
|
List<execplan::SimpleFilter> equiCondSFList;
|
||||||
|
|
||||||
// Kludge for Bug 750
|
// Kludge for Bug 750
|
||||||
int32_t recursionLevel;
|
int32_t recursionLevel;
|
||||||
|
Reference in New Issue
Block a user