You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-07 03:22:57 +03:00
Merge branch 'develop' into MCOL-521-b
This commit is contained in:
@@ -1187,18 +1187,6 @@ ha_calpont_group_by_handler::ha_calpont_group_by_handler(THD* thd_arg, Query* qu
|
||||
order_by(query->order_by),
|
||||
having(query->having)
|
||||
{
|
||||
List_iterator_fast<Item> item_iter(*select);
|
||||
Item* item;
|
||||
char* str = NULL;
|
||||
while((item = item_iter++))
|
||||
{
|
||||
String descr;
|
||||
item->print(&descr, QT_ORDINARY);
|
||||
str = new char[descr.length()+1];
|
||||
strncpy(str, descr.ptr(), descr.length());
|
||||
str[descr.length()] = '\0';
|
||||
select_list_descr.push_back(str);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
@@ -1207,7 +1195,6 @@ ha_calpont_group_by_handler::ha_calpont_group_by_handler(THD* thd_arg, Query* qu
|
||||
***********************************************************/
|
||||
ha_calpont_group_by_handler::~ha_calpont_group_by_handler()
|
||||
{
|
||||
select_list_descr.delete_elements();
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
|
@@ -286,7 +286,6 @@ public:
|
||||
int end_scan();
|
||||
|
||||
List<Item>* select;
|
||||
List<char> select_list_descr;
|
||||
TABLE_LIST* table_list;
|
||||
bool distinct;
|
||||
Item* where;
|
||||
|
@@ -1912,6 +1912,79 @@ pair<string, string> parseTableName(const string& tn)
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// get_field_default_value: Returns the default value as a string value
|
||||
// NOTE: This is duplicated code copied from show.cc and a MDEV-17006 has
|
||||
// been created.
|
||||
//
|
||||
|
||||
static bool get_field_default_value(THD *thd, Field *field, String *def_value,
|
||||
bool quoted)
|
||||
{
|
||||
bool has_default;
|
||||
enum enum_field_types field_type= field->type();
|
||||
|
||||
has_default= (field->default_value ||
|
||||
(!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
|
||||
field->unireg_check != Field::NEXT_NUMBER));
|
||||
|
||||
def_value->length(0);
|
||||
if (has_default)
|
||||
{
|
||||
StringBuffer<MAX_FIELD_WIDTH> str(field->charset());
|
||||
if (field->default_value)
|
||||
{
|
||||
field->default_value->print(&str);
|
||||
if (field->default_value->expr->need_parentheses_in_default())
|
||||
{
|
||||
def_value->set_charset(&my_charset_utf8mb4_general_ci);
|
||||
def_value->append('(');
|
||||
def_value->append(str);
|
||||
def_value->append(')');
|
||||
}
|
||||
else
|
||||
def_value->append(str);
|
||||
}
|
||||
else if (!field->is_null())
|
||||
{ // Not null by default
|
||||
if (field_type == MYSQL_TYPE_BIT)
|
||||
{
|
||||
str.qs_append('b');
|
||||
str.qs_append('\'');
|
||||
str.qs_append(field->val_int(), 2);
|
||||
str.qs_append('\'');
|
||||
quoted= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
field->val_str(&str);
|
||||
if (!field->str_needs_quotes())
|
||||
quoted= 0;
|
||||
}
|
||||
if (str.length())
|
||||
{
|
||||
StringBuffer<MAX_FIELD_WIDTH> def_val;
|
||||
uint dummy_errors;
|
||||
/* convert to system_charset_info == utf8 */
|
||||
def_val.copy(str.ptr(), str.length(), field->charset(),
|
||||
system_charset_info, &dummy_errors);
|
||||
if (quoted)
|
||||
append_unescaped(def_value, def_val.ptr(), def_val.length());
|
||||
else
|
||||
def_value->append(def_val);
|
||||
}
|
||||
else if (quoted)
|
||||
def_value->set(STRING_WITH_LEN("''"), system_charset_info);
|
||||
}
|
||||
else if (field->maybe_null() && quoted)
|
||||
def_value->set(STRING_WITH_LEN("NULL"), system_charset_info); // Null as default
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
return has_default;
|
||||
}
|
||||
|
||||
int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* create_info, cal_connection_info& ci)
|
||||
{
|
||||
#ifdef INFINIDB_DEBUG
|
||||
@@ -2096,6 +2169,97 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO*
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if this is a "CREATE TABLE ... LIKE " statement.
|
||||
// If so generate a full create table statement using the properties of
|
||||
// the source table. Note that source table has to be a columnstore table and
|
||||
// we only check for currently supported options.
|
||||
//
|
||||
|
||||
if (thd->lex->create_info.like())
|
||||
{
|
||||
TABLE_SHARE *share = table_arg->s;
|
||||
my_bitmap_map *old_map; // To save the read_set
|
||||
char datatype_buf[MAX_FIELD_WIDTH], def_value_buf[MAX_FIELD_WIDTH];
|
||||
String datatype, def_value;
|
||||
ostringstream oss;
|
||||
string tbl_name (name+2);
|
||||
std::replace(tbl_name.begin(), tbl_name.end(), '/', '.');
|
||||
|
||||
// Save the current read_set map and mark it for read
|
||||
old_map= tmp_use_all_columns(table_arg, table_arg->read_set);
|
||||
|
||||
oss << "CREATE TABLE " << tbl_name << " (";
|
||||
|
||||
restore_record(table_arg, s->default_values);
|
||||
for (Field **field= table_arg->field; *field; field++)
|
||||
{
|
||||
uint flags = (*field)->flags;
|
||||
datatype.set(datatype_buf, sizeof(datatype_buf), system_charset_info);
|
||||
(*field)->sql_type(datatype);
|
||||
if (field != table_arg->field)
|
||||
oss << ", ";
|
||||
oss << (*field)->field_name.str << " " << datatype.ptr();
|
||||
|
||||
if (flags & NOT_NULL_FLAG)
|
||||
oss << " NOT NULL";
|
||||
|
||||
def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info);
|
||||
if (get_field_default_value(thd, *field, &def_value, true)) {
|
||||
oss << " DEFAULT " << def_value.c_ptr();
|
||||
}
|
||||
if ((*field)->comment.length)
|
||||
{
|
||||
String comment;
|
||||
append_unescaped(&comment, (*field)->comment.str, (*field)->comment.length);
|
||||
oss << " COMMENT ";
|
||||
oss << comment.c_ptr();
|
||||
}
|
||||
|
||||
}
|
||||
// End the list of columns
|
||||
oss<< ") ENGINE=columnstore ";
|
||||
|
||||
// Process table level options
|
||||
|
||||
if (create_info->auto_increment_value > 1)
|
||||
{
|
||||
oss << " AUTO_INCREMENT=" << create_info->auto_increment_value;
|
||||
}
|
||||
|
||||
if (share->table_charset)
|
||||
{
|
||||
oss << " DEFAULT CHARSET=" << share->table_charset->csname;
|
||||
}
|
||||
|
||||
// Process table level options such as MIN_ROWS, MAX_ROWS, COMMENT
|
||||
|
||||
if (share->min_rows)
|
||||
{
|
||||
char buff[80];
|
||||
longlong10_to_str(share->min_rows, buff, 10);
|
||||
oss << " MIN_ROWS=" << buff;
|
||||
}
|
||||
|
||||
if (share->max_rows) {
|
||||
char buff[80];
|
||||
longlong10_to_str(share->max_rows, buff, 10);
|
||||
oss << " MAX_ROWS=" << buff;
|
||||
}
|
||||
|
||||
if (share->comment.length) {
|
||||
String comment;
|
||||
append_unescaped(&comment, share->comment.str, share->comment.length);
|
||||
oss << " COMMENT ";
|
||||
oss << comment.c_ptr();
|
||||
}
|
||||
|
||||
oss << ";";
|
||||
stmt = oss.str();
|
||||
|
||||
tmp_restore_column_map(table_arg->read_set, old_map);
|
||||
}
|
||||
|
||||
rc = ProcessDDLStatement(stmt, db, tbl, tid2sid(thd->thread_id), emsg, compressiontype, isAnyAutoincreCol, startValue, columnName);
|
||||
|
||||
if (rc != 0)
|
||||
|
@@ -1820,8 +1820,11 @@ int ha_calpont_impl_write_batch_row_(uchar* buf, TABLE* table, cal_impl_if::cal_
|
||||
}
|
||||
else if (ci.columnTypes[colpos].colWidth < 16777216)
|
||||
{
|
||||
dataLength = *(uint32_t*) buf;
|
||||
buf = buf + 3 ;
|
||||
dataLength = *(uint16_t*) buf;
|
||||
buf = buf + 2 ;
|
||||
if (*(uint8_t*)buf)
|
||||
dataLength += 256*256*(*(uint8_t*)buf) ;
|
||||
buf++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -190,21 +190,57 @@ bool nonConstFunc(Item_func* ifp)
|
||||
return false;
|
||||
}
|
||||
|
||||
ReturnedColumn* findCorrespTempField(Item_ref* item, gp_walk_info& gwi, bool clone = true)
|
||||
/*@brief buildAggFrmTempField- build aggr func from extSELECT list item*/
|
||||
/***********************************************************
|
||||
* DESCRIPTION:
|
||||
* Server adds additional aggregation items to extended SELECT list and
|
||||
* references them in projection and HAVING. This f() finds
|
||||
* corresponding item in extSelAggColsItems and builds
|
||||
* ReturnedColumn using the item.
|
||||
* PARAMETERS:
|
||||
* item Item* used to build aggregation
|
||||
* gwi main structure
|
||||
* RETURNS
|
||||
* ReturnedColumn* if corresponding Item has been found
|
||||
* NULL otherwise
|
||||
***********************************************************/
|
||||
ReturnedColumn* buildAggFrmTempField(Item* item, gp_walk_info& gwi)
|
||||
{
|
||||
ReturnedColumn* result = NULL;
|
||||
uint32_t i;
|
||||
for (i = 0; i < gwi.returnedCols.size(); i++)
|
||||
Item_field* ifip = NULL;
|
||||
Item_ref* irip;
|
||||
Item_func_or_sum* isfp;
|
||||
|
||||
switch ( item->type() )
|
||||
{
|
||||
if (item->ref[0] && item->ref[0]->name.length &&
|
||||
gwi.returnedCols[i]->alias().c_str() &&
|
||||
!strcasecmp(item->ref[0]->name.str, gwi.returnedCols[i]->alias().c_str()))
|
||||
{
|
||||
if (clone)
|
||||
result = gwi.returnedCols[i]->clone();
|
||||
else
|
||||
result = gwi.returnedCols[i].get();
|
||||
case Item::FIELD_ITEM:
|
||||
ifip = reinterpret_cast<Item_field*>(item);
|
||||
break;
|
||||
default:
|
||||
irip = reinterpret_cast<Item_ref*>(item);
|
||||
if ( irip )
|
||||
ifip = reinterpret_cast<Item_field*>(irip->ref[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ifip && ifip->field)
|
||||
{
|
||||
std::vector<Item*>::iterator iter = gwi.extSelAggColsItems.begin();
|
||||
for ( ; iter != gwi.extSelAggColsItems.end(); iter++ )
|
||||
{
|
||||
//Item* temp_isfp = *iter;
|
||||
isfp = reinterpret_cast<Item_func_or_sum*>(*iter);
|
||||
|
||||
if ( isfp->type() == Item::SUM_FUNC_ITEM &&
|
||||
isfp->result_field == ifip->field )
|
||||
{
|
||||
ReturnedColumn* rc = buildAggregateColumn(isfp, gwi);
|
||||
|
||||
if (rc)
|
||||
result = rc;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1548,8 +1584,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
||||
ifp->functype() == Item_func::ISNOTNULL_FUNC)
|
||||
{
|
||||
ReturnedColumn* rhs = NULL;
|
||||
|
||||
if (!gwip->rcWorkStack.empty())
|
||||
if (!gwip->rcWorkStack.empty() && !gwip->inCaseStmt)
|
||||
{
|
||||
rhs = gwip->rcWorkStack.top();
|
||||
gwip->rcWorkStack.pop();
|
||||
@@ -1650,8 +1685,49 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
||||
|
||||
idbassert(ifp->argument_count() == 1);
|
||||
ParseTree* ptp = 0;
|
||||
if (((Item_func*)(ifp->arguments()[0]))->functype() == Item_func::EQUAL_FUNC)
|
||||
{
|
||||
// negate it in place
|
||||
// Note that an EQUAL_FUNC ( a <=> b) was converted to
|
||||
// ( a = b OR ( a is null AND b is null) )
|
||||
// NOT of the above expression is: ( a != b AND (a is not null OR b is not null )
|
||||
|
||||
if (isPredicateFunction(ifp->arguments()[0], gwip) || ifp->arguments()[0]->type() == Item::COND_ITEM)
|
||||
if (!gwip->ptWorkStack.empty())
|
||||
ptp = gwip->ptWorkStack.top();
|
||||
|
||||
if (ptp)
|
||||
{
|
||||
ParseTree* or_ptp = ptp;
|
||||
ParseTree* and_ptp = or_ptp->right();
|
||||
ParseTree* equal_ptp = or_ptp->left();
|
||||
ParseTree* nullck_left_ptp = and_ptp->left();
|
||||
ParseTree* nullck_right_ptp = and_ptp->right();
|
||||
SimpleFilter *sf_left_nullck = dynamic_cast<SimpleFilter*>(nullck_left_ptp->data());
|
||||
SimpleFilter *sf_right_nullck = dynamic_cast<SimpleFilter*>(nullck_right_ptp->data());
|
||||
SimpleFilter *sf_equal = dynamic_cast<SimpleFilter*>(equal_ptp->data());
|
||||
|
||||
if (sf_left_nullck && sf_right_nullck && sf_equal) {
|
||||
// Negate the null checks
|
||||
sf_left_nullck->op()->reverseOp();
|
||||
sf_right_nullck->op()->reverseOp();
|
||||
sf_equal->op()->reverseOp();
|
||||
// Rehook the nodes
|
||||
ptp = and_ptp;
|
||||
ptp->left(equal_ptp);
|
||||
ptp->right(or_ptp);
|
||||
or_ptp->left(nullck_left_ptp);
|
||||
or_ptp->right(nullck_right_ptp);
|
||||
gwip->ptWorkStack.pop();
|
||||
gwip->ptWorkStack.push(ptp);
|
||||
}
|
||||
else {
|
||||
gwip->fatalParseError = true;
|
||||
gwip->parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_ASSERTION_FAILURE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isPredicateFunction(ifp->arguments()[0], gwip) || ifp->arguments()[0]->type() == Item::COND_ITEM)
|
||||
{
|
||||
// negate it in place
|
||||
if (!gwip->ptWorkStack.empty())
|
||||
@@ -1725,7 +1801,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
||||
}
|
||||
else if (ifp->functype() == Item_func::EQUAL_FUNC)
|
||||
{
|
||||
// a = b OR (a IS NULL AND b IS NULL)
|
||||
// Convert "a <=> b" to (a = b OR (a IS NULL AND b IS NULL))"
|
||||
idbassert (gwip->rcWorkStack.size() >= 2);
|
||||
ReturnedColumn* rhs = gwip->rcWorkStack.top();
|
||||
gwip->rcWorkStack.pop();
|
||||
@@ -1737,7 +1813,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
||||
// b IS NULL
|
||||
ConstantColumn* nlhs1 = new ConstantColumn("", ConstantColumn::NULLDATA);
|
||||
sop.reset(new PredicateOperator("isnull"));
|
||||
sop->setOpType(lhs->resultType(), rhs->resultType());
|
||||
sop->setOpType(lhs->resultType(), rhs->resultType());
|
||||
sfn1 = new SimpleFilter(sop, rhs, nlhs1);
|
||||
ParseTree* ptpl = new ParseTree(sfn1);
|
||||
// a IS NULL
|
||||
@@ -1752,7 +1828,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
||||
ptpn->right(ptpr);
|
||||
// a = b
|
||||
sop.reset(new PredicateOperator("="));
|
||||
sop->setOpType(lhs->resultType(), lhs->resultType());
|
||||
sop->setOpType(lhs->resultType(), rhs->resultType());
|
||||
sfo = new SimpleFilter(sop, lhs->clone(), rhs->clone());
|
||||
// OR with the NULL comparison tree
|
||||
ParseTree* ptp = new ParseTree(new LogicOperator("or"));
|
||||
@@ -3061,7 +3137,10 @@ ArithmeticColumn* buildArithmeticColumn(
|
||||
{
|
||||
// There must be an aggregation column in extended SELECT
|
||||
// list so find the corresponding column.
|
||||
ReturnedColumn* rc = findCorrespTempField(static_cast<Item_ref*>(sfitempp[0]), gwi);
|
||||
// Could have it set if there are aggregation funcs as this function arguments.
|
||||
gwi.fatalParseError = false;
|
||||
|
||||
ReturnedColumn* rc = buildAggFrmTempField(sfitempp[0], gwi);
|
||||
if(rc)
|
||||
lhs = new ParseTree(rc);
|
||||
}
|
||||
@@ -3077,7 +3156,10 @@ ArithmeticColumn* buildArithmeticColumn(
|
||||
{
|
||||
// There must be an aggregation column in extended SELECT
|
||||
// list so find the corresponding column.
|
||||
ReturnedColumn* rc = findCorrespTempField(static_cast<Item_ref*>(sfitempp[1]), gwi);
|
||||
// Could have it set if there are aggregation funcs as this function arguments.
|
||||
gwi.fatalParseError = false;
|
||||
|
||||
ReturnedColumn* rc = buildAggFrmTempField(sfitempp[1], gwi);
|
||||
if(rc)
|
||||
rhs = new ParseTree(rc);
|
||||
}
|
||||
@@ -3416,10 +3498,11 @@ ReturnedColumn* buildFunctionColumn(
|
||||
ReturnedColumn* rc = buildReturnedColumn(ifp->arguments()[i], gwi, nonSupport, pushdownHand);
|
||||
|
||||
// MCOL-1510 It must be a temp table field, so find the corresponding column.
|
||||
if (pushdownHand
|
||||
if (!rc && pushdownHand
|
||||
&& ifp->arguments()[i]->type() == Item::REF_ITEM)
|
||||
{
|
||||
rc = findCorrespTempField(static_cast<Item_ref*>(ifp->arguments()[i]), gwi);
|
||||
gwi.fatalParseError = false;
|
||||
rc = buildAggFrmTempField(ifp->arguments()[i], gwi);
|
||||
}
|
||||
|
||||
if (!rc || nonSupport)
|
||||
@@ -3772,8 +3855,12 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
|
||||
if (funcName == "case_searched" &&
|
||||
(i < arg_offset))
|
||||
{
|
||||
// MCOL-1472 Nested CASE with an ISNULL predicate. We don't want the predicate
|
||||
// to pull off of rcWorkStack, so we set this inCaseStmt flag to tell it
|
||||
// not to.
|
||||
gwi.inCaseStmt = true;
|
||||
sptp.reset(buildParseTree((Item_func*)(item->arguments()[i]), gwi, nonSupport));
|
||||
|
||||
gwi.inCaseStmt = false;
|
||||
if (!gwi.ptWorkStack.empty() && *gwi.ptWorkStack.top()->data() == sptp->data())
|
||||
{
|
||||
gwi.ptWorkStack.pop();
|
||||
@@ -4101,7 +4188,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
||||
// MCOL-1201 For UDAnF multiple parameters
|
||||
vector<SRCP> selCols;
|
||||
vector<SRCP> orderCols;
|
||||
|
||||
bool bIsConst = false;
|
||||
if (!(gwi.thd->infinidb_vtable.cal_conn_info))
|
||||
gwi.thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info());
|
||||
|
||||
@@ -4280,6 +4367,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
||||
|
||||
parm.reset(buildReturnedColumn(sfitemp, gwi, gwi.fatalParseError));
|
||||
ac->constCol(parm);
|
||||
bIsConst = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4396,7 +4484,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
||||
|
||||
// Get result type
|
||||
// Modified for MCOL-1201 multi-argument aggregate
|
||||
if (ac->aggParms().size() > 0)
|
||||
if (!bIsConst && ac->aggParms().size() > 0)
|
||||
{
|
||||
// These are all one parm functions, so we can safely
|
||||
// use the first parm for result type.
|
||||
@@ -5299,26 +5387,9 @@ void gp_walk(const Item* item, void* arg)
|
||||
}
|
||||
else if (col->type() == Item::FIELD_ITEM && gwip->clauseType == HAVING)
|
||||
{
|
||||
Item_field* ifip = static_cast<Item_field*>(col);
|
||||
std::vector<Item*>::iterator iter = gwip->havingAggColsItems.begin();
|
||||
Item_func_or_sum* isfp = NULL;
|
||||
|
||||
for ( ; iter != gwip->havingAggColsItems.end(); iter++ )
|
||||
{
|
||||
Item* temp_isfp = *iter;
|
||||
isfp = reinterpret_cast<Item_func_or_sum*>(temp_isfp);
|
||||
|
||||
if ( isfp->type() == Item::SUM_FUNC_ITEM &&
|
||||
isfp->result_field == ifip->field )
|
||||
{
|
||||
ReturnedColumn* rc = buildAggregateColumn(isfp, *gwip);
|
||||
|
||||
if (rc)
|
||||
gwip->rcWorkStack.push(rc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
ReturnedColumn* rc = buildAggFrmTempField(const_cast<Item*>(item), *gwip);
|
||||
if (rc)
|
||||
gwip->rcWorkStack.push(rc);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -5583,7 +5654,7 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
|
||||
// and set hasNonSupportItem if it is so.
|
||||
ReturnedColumn* rc = NULL;
|
||||
if (gwi)
|
||||
rc = findCorrespTempField(ref, *gwi, false);
|
||||
rc = buildAggFrmTempField(ref, *gwi);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
@@ -8193,12 +8264,13 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi)
|
||||
SELECT_LEX select_lex = lex->select_lex;
|
||||
gp_walk_info gwi;
|
||||
gwi.thd = thd;
|
||||
gwi.groupByAuxDescr = gi.groupByAuxDescr;
|
||||
int status = getGroupPlan(gwi, select_lex, csep, gi);
|
||||
|
||||
#ifdef DEBUG_WALK_COND
|
||||
cerr << "---------------- cp_get_group_plan EXECUTION PLAN ----------------" << endl;
|
||||
cerr << *csep << endl ;
|
||||
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
|
||||
#endif
|
||||
|
||||
if (status > 0)
|
||||
return ER_INTERNAL_ERROR;
|
||||
@@ -8575,8 +8647,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
string sel_cols_in_create;
|
||||
string sel_cols_in_select;
|
||||
bool redo = false;
|
||||
List_iterator_fast<char> itDescr(*gi.groupByAuxDescr);
|
||||
char* fieldDescr;
|
||||
|
||||
// empty rcWorkStack and ptWorkStack. They should all be empty by now.
|
||||
clearStacks(gwi);
|
||||
@@ -8595,14 +8665,12 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
|
||||
while ((item = it++))
|
||||
{
|
||||
// Given the size of gi.groupByAuxDescr is equal to gi.groupByFields
|
||||
fieldDescr = itDescr++;
|
||||
string itemAlias;
|
||||
if(item->name.length)
|
||||
itemAlias = (item->name.str);
|
||||
else
|
||||
{
|
||||
itemAlias = (fieldDescr ? fieldDescr: "<NULL>");
|
||||
itemAlias = "<NULL>";
|
||||
}
|
||||
|
||||
// @bug 5916. Need to keep checking until getting concret item in case
|
||||
@@ -8709,18 +8777,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
return ER_CHECK_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if(!ac->alias().length())
|
||||
ac->alias(fieldDescr);
|
||||
// add this agg col to returnedColumnList
|
||||
boost::shared_ptr<ReturnedColumn> spac(ac);
|
||||
gwi.returnedCols.push_back(spac);
|
||||
// This item will be used in HAVING later.
|
||||
Item_func_or_sum* isfp = reinterpret_cast<Item_func_or_sum*>(item);
|
||||
|
||||
if ( ! isfp->name.length )
|
||||
{
|
||||
gwi.havingAggColsItems.push_back(item);
|
||||
}
|
||||
// This item could be used in projection or HAVING later.
|
||||
gwi.extSelAggColsItems.push_back(item);
|
||||
|
||||
gwi.selectCols.push_back('`' + escapeBackTick(spac->alias().c_str()) + '`');
|
||||
String str(256);
|
||||
@@ -10103,20 +10164,28 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
}
|
||||
}
|
||||
|
||||
if (ord_cols.length() > 0) // has order by
|
||||
if ( gwi.orderByCols.size() ) // has order by
|
||||
{
|
||||
gwi.thd->infinidb_vtable.has_order_by = true;
|
||||
csep->hasOrderBy(true);
|
||||
ord_cols = " order by " + ord_cols;
|
||||
select_query += ord_cols;
|
||||
csep->specHandlerProcessed(true);
|
||||
}
|
||||
}
|
||||
|
||||
// LIMIT and OFFSET are extracted from TABLE_LIST elements.
|
||||
// All of JOIN-ed tables contain relevant limit and offset.
|
||||
if (gi.groupByTables->select_lex->select_limit)
|
||||
uint64_t limit = (uint64_t)-1;
|
||||
if (gi.groupByTables->select_lex->select_limit &&
|
||||
( limit = static_cast<Item_int*>(gi.groupByTables->select_lex->select_limit)->val_int() ) &&
|
||||
limit != (uint64_t)-1 )
|
||||
{
|
||||
csep->limitNum(((Item_int*)gi.groupByTables->select_lex->select_limit)->val_int());
|
||||
csep->limitNum(limit);
|
||||
}
|
||||
else if (csep->hasOrderBy())
|
||||
{
|
||||
// We use LimitedOrderBy so set the limit to
|
||||
// go through the check in addOrderByAndLimit
|
||||
csep->limitNum((uint64_t) - 2);
|
||||
}
|
||||
|
||||
if (gi.groupByTables->select_lex->offset_limit)
|
||||
@@ -10228,3 +10297,4 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
|
||||
|
||||
}
|
||||
// vim:ts=4 sw=4:
|
||||
|
@@ -1964,7 +1964,7 @@ uint32_t doUpdateDelete(THD* thd)
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->set_row_count_func(dmlRowCount);
|
||||
thd->set_row_count_func(dmlRowCount+thd->get_row_count_func());
|
||||
}
|
||||
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, errorMsg.c_str());
|
||||
@@ -1972,7 +1972,7 @@ uint32_t doUpdateDelete(THD* thd)
|
||||
else
|
||||
{
|
||||
// if (dmlRowCount != 0) //Bug 5117. Handling self join.
|
||||
thd->set_row_count_func(dmlRowCount);
|
||||
thd->set_row_count_func(dmlRowCount+thd->get_row_count_func());
|
||||
|
||||
|
||||
//cout << " error status " << ci->rc << " and rowcount = " << dmlRowCount << endl;
|
||||
@@ -5265,7 +5265,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
|
||||
// MCOL-1052 Send Items lists down to the optimizer.
|
||||
gi.groupByTables = group_hand->table_list;
|
||||
gi.groupByFields = group_hand->select;
|
||||
gi.groupByAuxDescr = &group_hand->select_list_descr;
|
||||
gi.groupByWhere = group_hand->where;
|
||||
gi.groupByGroup = group_hand->group_by;
|
||||
gi.groupByOrder = group_hand->order_by;
|
||||
|
@@ -99,7 +99,7 @@ struct gp_walk_info
|
||||
execplan::CalpontSelectExecutionPlan::ReturnedColumnList groupByCols;
|
||||
execplan::CalpontSelectExecutionPlan::ReturnedColumnList subGroupByCols;
|
||||
execplan::CalpontSelectExecutionPlan::ReturnedColumnList orderByCols;
|
||||
std::vector <Item*> havingAggColsItems;
|
||||
std::vector <Item*> extSelAggColsItems;
|
||||
execplan::CalpontSelectExecutionPlan::ColumnMap columnMap;
|
||||
// This vector temporarily hold the projection columns to be added
|
||||
// to the returnedCols vector for subquery processing. It will be appended
|
||||
@@ -142,13 +142,15 @@ struct gp_walk_info
|
||||
std::map<std::string, execplan::ParseTree*> derivedTbFilterMap;
|
||||
uint32_t derivedTbCnt;
|
||||
std::vector<execplan::SCSEP> subselectList;
|
||||
List<char>* groupByAuxDescr;
|
||||
|
||||
// Kludge for Bug 750
|
||||
int32_t recursionLevel;
|
||||
int32_t recursionHWM;
|
||||
std::stack<int32_t> rcBookMarkStack;
|
||||
|
||||
// Kludge for MCOL-1472
|
||||
bool inCaseStmt;
|
||||
|
||||
gp_walk_info() : sessionid(0),
|
||||
fatalParseError(false),
|
||||
condPush(false),
|
||||
@@ -164,7 +166,8 @@ struct gp_walk_info
|
||||
lastSub(0),
|
||||
derivedTbCnt(0),
|
||||
recursionLevel(-1),
|
||||
recursionHWM(0)
|
||||
recursionHWM(0),
|
||||
inCaseStmt(false)
|
||||
{}
|
||||
|
||||
~gp_walk_info() {}
|
||||
@@ -196,7 +199,6 @@ struct cal_table_info
|
||||
struct cal_group_info
|
||||
{
|
||||
cal_group_info() : groupByFields(0),
|
||||
groupByAuxDescr(0),
|
||||
groupByTables(0),
|
||||
groupByWhere(0),
|
||||
groupByGroup(0),
|
||||
@@ -207,7 +209,6 @@ struct cal_group_info
|
||||
~cal_group_info() { }
|
||||
|
||||
List<Item>* groupByFields; // MCOL-1052 SELECT
|
||||
List<char>* groupByAuxDescr; //MCOL-1052 Auxilary column descriptions
|
||||
TABLE_LIST* groupByTables; // MCOL-1052 FROM
|
||||
Item* groupByWhere; // MCOL-1052 WHERE
|
||||
ORDER* groupByGroup; // MCOL-1052 GROUP BY
|
||||
|
Reference in New Issue
Block a user