1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-08 14:22:09 +03:00

MCOL-265 Add support for TIMESTAMP data type

This commit is contained in:
Gagan Goel
2019-03-17 14:14:03 -04:00
parent 8a7ccd7d93
commit e89d1ac3cf
167 changed files with 4346 additions and 250 deletions

View File

@@ -178,6 +178,10 @@ uint32_t convertDataType(int dataType)
calpontDataType = CalpontSystemCatalog::TIME;
break;
case ddlpackage::DDL_TIMESTAMP:
calpontDataType = CalpontSystemCatalog::TIMESTAMP;
break;
case ddlpackage::DDL_CLOB:
calpontDataType = CalpontSystemCatalog::CLOB;
break;
@@ -524,7 +528,177 @@ bool anyRowInTable(string& schema, string& tableName, int sessionID)
}
}
bool anyNullInTheColumn (string& schema, string& table, string& columnName, int sessionID)
bool anyTimestampColumn(string& schema, string& tableName, int sessionID)
{
boost::shared_ptr<CalpontSystemCatalog> csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID);
csc->identity(execplan::CalpontSystemCatalog::FE);
CalpontSystemCatalog::TableName aTableName;
algorithm::to_lower(schema);
algorithm::to_lower(tableName);
// select columnname from calpontsys.syscolumn
// where schema = schema and tablename = tableName
// and datatype = 'timestamp'
CalpontSelectExecutionPlan csep;
CalpontSelectExecutionPlan::ReturnedColumnList returnedColumnList;
CalpontSelectExecutionPlan::FilterTokenList filterTokenList;
CalpontSelectExecutionPlan::ColumnMap colMap;
SessionManager sm;
BRM::TxnID txnID;
txnID = sm.getTxnID(sessionID);
if (!txnID.valid)
{
txnID.id = 0;
txnID.valid = true;
}
QueryContext verID;
verID = sm.verID();
csep.txnID(txnID.id);
csep.verID(verID);
csep.sessionID(sessionID);
string sysTable = "calpontsys.syscolumn.";
string firstCol = sysTable + "columnname";
SimpleColumn* c1 = new SimpleColumn(firstCol, sessionID);
string secondCol = sysTable + "schema";
SimpleColumn* c2 = new SimpleColumn(secondCol, sessionID);
string thirdCol = sysTable + "tablename";
SimpleColumn* c3 = new SimpleColumn(thirdCol, sessionID);
string fourthCol = sysTable + "datatype";
SimpleColumn* c4 = new SimpleColumn(fourthCol, sessionID);
SRCP srcp;
srcp.reset(c1);
colMap.insert(CMVT_(firstCol, srcp));
srcp.reset(c2);
colMap.insert(CMVT_(secondCol, srcp));
srcp.reset(c3);
colMap.insert(CMVT_(thirdCol, srcp));
srcp.reset(c4);
colMap.insert(CMVT_(fourthCol, srcp));
csep.columnMapNonStatic(colMap);
srcp.reset(c1->clone());
returnedColumnList.push_back(srcp);
csep.returnedCols(returnedColumnList);
// Filters
const SOP opeq(new Operator("="));
SimpleFilter* f1 = new SimpleFilter (opeq,
c2->clone(),
new ConstantColumn(schema, ConstantColumn::LITERAL));
filterTokenList.push_back(f1);
filterTokenList.push_back(new Operator("and"));
SimpleFilter* f2 = new SimpleFilter (opeq,
c3->clone(),
new ConstantColumn(tableName, ConstantColumn::LITERAL));
filterTokenList.push_back(f2);
filterTokenList.push_back(new Operator("and"));
SimpleFilter* f3 = new SimpleFilter (opeq,
c4->clone(),
new ConstantColumn((uint64_t) execplan::CalpontSystemCatalog::TIMESTAMP, ConstantColumn::NUM));
filterTokenList.push_back(f3);
csep.filterTokenList(filterTokenList);
CalpontSelectExecutionPlan::TableList tablelist;
tablelist.push_back(make_aliastable("calpontsys", "syscolumn", ""));
csep.tableList(tablelist);
boost::shared_ptr<messageqcpp::MessageQueueClient> exemgrClient (new messageqcpp::MessageQueueClient("ExeMgr1"));
ByteStream msg, emsgBs;
rowgroup::RGData rgData;
ByteStream::quadbyte qb = 4;
msg << qb;
rowgroup::RowGroup* rowGroup = 0;
bool anyRow = false;
exemgrClient->write(msg);
ByteStream msgPlan;
csep.serialize(msgPlan);
exemgrClient->write(msgPlan);
msg.restart();
msg = exemgrClient->read(); //error handling
emsgBs = exemgrClient->read();
ByteStream::quadbyte qb1;
if (emsgBs.length() == 0)
{
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error("Lost conection to ExeMgr.");
}
string emsgStr;
emsgBs >> emsgStr;
if (msg.length() == 4)
{
msg >> qb1;
if (qb1 != 0)
{
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error(emsgStr);
}
}
while (true)
{
msg.restart();
msg = exemgrClient->read();
if ( msg.length() == 0 )
{
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error("Lost conection to ExeMgr.");
}
else
{
if (!rowGroup)
{
//This is mete data
rowGroup = new rowgroup::RowGroup();
rowGroup->deserialize(msg);
qb = 100;
msg.restart();
msg << qb;
exemgrClient->write(msg);
continue;
}
rgData.deserialize(msg);
rowGroup->setData(&rgData);
if (rowGroup->getStatus() != 0)
{
//msg.advance(rowGroup->getDataSize());
msg >> emsgStr;
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error(emsgStr);
}
if (rowGroup->getRowCount() > 0)
anyRow = true;
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
return anyRow;
}
}
}
bool anyNullInTheColumn (THD* thd, string& schema, string& table, string& columnName, int sessionID)
{
CalpontSelectExecutionPlan csep;
CalpontSelectExecutionPlan::ReturnedColumnList returnedColumnList;
@@ -561,9 +735,11 @@ bool anyNullInTheColumn (string& schema, string& table, string& columnName, int
csep.returnedCols(returnedColumnList);
SimpleFilter* sf = new SimpleFilter();
sf->timeZone(thd->variables.time_zone->get_name()->ptr());
boost::shared_ptr<Operator> sop(new PredicateOperator("isnull"));
sf->op(sop);
ConstantColumn* rhs = new ConstantColumn("", ConstantColumn::NULLDATA);
rhs->timeZone(thd->variables.time_zone->get_name()->ptr());
sf->lhs(col[0]->clone());
sf->rhs(rhs);
@@ -725,6 +901,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
}
bool matchedCol = false;
bool isFirstTimestamp = true;
for ( unsigned i = 0; i < createTable->fTableDef->fColumns.size(); i++ )
{
@@ -775,6 +952,13 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
return rc;
}
// For TIMESTAMP, if no constraint is given, default to NOT NULL
if (createTable->fTableDef->fColumns[i]->fType->fType == ddlpackage::DDL_TIMESTAMP &&
createTable->fTableDef->fColumns[i]->fConstraints.empty())
{
createTable->fTableDef->fColumns[i]->fConstraints.push_back(new ColumnConstraintDef(DDL_NOT_NULL));
}
if (createTable->fTableDef->fColumns[i]->fDefaultValue)
{
if ((!createTable->fTableDef->fColumns[i]->fDefaultValue->fNull) && (createTable->fTableDef->fColumns[i]->fType->fType == ddlpackage::DDL_VARBINARY))
@@ -803,7 +987,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
try
{
convertedVal = DataConvert::convertColumnData(colType, createTable->fTableDef->fColumns[i]->fDefaultValue->fValue, pushWarning, false, false );
convertedVal = DataConvert::convertColumnData(colType, createTable->fTableDef->fColumns[i]->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false);
}
catch (std::exception&)
{
@@ -824,6 +1008,35 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
ci->isAlter = false;
return rc;
}
if (createTable->fTableDef->fColumns[i]->fType->fType == ddlpackage::DDL_TIMESTAMP)
{
if (createTable->fTableDef->fColumns[i]->fDefaultValue->fValue == "0")
{
createTable->fTableDef->fColumns[i]->fDefaultValue->fValue = "0000-00-00 00:00:00";
}
if (isFirstTimestamp)
{
isFirstTimestamp = false;
}
}
}
}
// If no default value exists for TIMESTAMP, we apply
// automatic TIMESTAMP properties.
// TODO: If no default value exists but the constraint is NULL,
// default value should be set to NULL. But this is currently
// not supported since columnstore does not track whether user
// specified a NULL or not
else if (createTable->fTableDef->fColumns[i]->fType->fType == ddlpackage::DDL_TIMESTAMP)
{
if (isFirstTimestamp)
{
isFirstTimestamp = false;
createTable->fTableDef->fColumns[i]->fDefaultValue = new ColumnDefaultValue("current_timestamp() ON UPDATE current_timestamp()");
}
else
{
createTable->fTableDef->fColumns[i]->fDefaultValue = new ColumnDefaultValue("0000-00-00 00:00:00");
}
}
@@ -990,6 +1203,8 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
{
AlterTableStatement* alterTable = dynamic_cast <AlterTableStatement*> ( &stmt );
alterTable->fTimeZone = thd->variables.time_zone->get_name()->ptr();
if ( schema.length() == 0 )
{
schema = alterTable->fTableName->fSchema;
@@ -1065,7 +1280,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
}
//if not null constraint, user has to provide a default value
if ((addColumnPtr->fColumnDef->fConstraints[j]->fConstraintType == DDL_NOT_NULL) && (!addColumnPtr->fColumnDef->fDefaultValue))
if ((addColumnPtr->fColumnDef->fConstraints[j]->fConstraintType == DDL_NOT_NULL) && (!addColumnPtr->fColumnDef->fDefaultValue) && (addColumnPtr->fColumnDef->fType->fType != ddlpackage::DDL_TIMESTAMP))
{
//do select count(*) from the table to check whether there are existing rows. if there is, error out.
@@ -1143,7 +1358,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
try
{
convertedVal = DataConvert::convertColumnData(colType, addColumnPtr->fColumnDef->fDefaultValue->fValue, pushWarning, false, false );
convertedVal = DataConvert::convertColumnData(colType, addColumnPtr->fColumnDef->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false);
}
catch (std::exception&)
{
@@ -1164,6 +1379,39 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
ci->isAlter = false;
return rc;
}
if (addColumnPtr->fColumnDef->fType->fType == ddlpackage::DDL_TIMESTAMP &&
addColumnPtr->fColumnDef->fDefaultValue->fValue == "0")
{
addColumnPtr->fColumnDef->fDefaultValue->fValue = "0000-00-00 00:00:00";
}
}
}
// For TIMESTAMP, if no constraint is given, default to NOT NULL
if (addColumnPtr->fColumnDef->fType->fType == ddlpackage::DDL_TIMESTAMP &&
addColumnPtr->fColumnDef->fConstraints.empty())
{
addColumnPtr->fColumnDef->fConstraints.push_back(new ColumnConstraintDef(DDL_NOT_NULL));
}
// If no default value exists for TIMESTAMP, we apply
// automatic TIMESTAMP properties.
// TODO: If no default value exists but the constraint is NULL,
// default value should be set to NULL. But this is currently
// not supported since columnstore does not track whether user
// specified a NULL or not
if (addColumnPtr->fColumnDef->fType->fType == ddlpackage::DDL_TIMESTAMP &&
!addColumnPtr->fColumnDef->fDefaultValue)
{
// Query calpontsys.syscolumn to see
// if a timestamp column already exists in this table
if (!anyTimestampColumn(alterTable->fTableName->fSchema, alterTable->fTableName->fName, sessionID))
{
addColumnPtr->fColumnDef->fDefaultValue = new ColumnDefaultValue("current_timestamp() ON UPDATE current_timestamp()");
}
else
{
addColumnPtr->fColumnDef->fDefaultValue = new ColumnDefaultValue("0000-00-00 00:00:00");
}
}
@@ -1386,7 +1634,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
}
//if not null constraint, user has to provide a default value
if ((addColumnsPtr->fColumns[0]->fConstraints[j]->fConstraintType == DDL_NOT_NULL) && (!addColumnsPtr->fColumns[0]->fDefaultValue))
if ((addColumnsPtr->fColumns[0]->fConstraints[j]->fConstraintType == DDL_NOT_NULL) && (!addColumnsPtr->fColumns[0]->fDefaultValue) && (addColumnsPtr->fColumns[0]->fType->fType != ddlpackage::DDL_TIMESTAMP))
{
//do select count(*) from the table to check whether there are existing rows. if there is, error out.
@@ -1464,7 +1712,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
try
{
convertedVal = DataConvert::convertColumnData(colType, addColumnsPtr->fColumns[0]->fDefaultValue->fValue, pushWarning, false, false );
convertedVal = DataConvert::convertColumnData(colType, addColumnsPtr->fColumns[0]->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false);
}
catch (std::exception&)
{
@@ -1485,6 +1733,39 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
ci->isAlter = false;
return rc;
}
if (addColumnsPtr->fColumns[0]->fType->fType == ddlpackage::DDL_TIMESTAMP &&
addColumnsPtr->fColumns[0]->fDefaultValue->fValue == "0")
{
addColumnsPtr->fColumns[0]->fDefaultValue->fValue = "0000-00-00 00:00:00";
}
}
}
// For TIMESTAMP, if no constraint is given, default to NOT NULL
if (addColumnsPtr->fColumns[0]->fType->fType == ddlpackage::DDL_TIMESTAMP &&
addColumnsPtr->fColumns[0]->fConstraints.empty())
{
addColumnsPtr->fColumns[0]->fConstraints.push_back(new ColumnConstraintDef(DDL_NOT_NULL));
}
// If no default value exists for TIMESTAMP, we apply
// automatic TIMESTAMP properties.
// TODO: If no default value exists but the constraint is NULL,
// default value should be set to NULL. But this is currently
// not supported since columnstore does not track whether user
// specified a NULL or not
if (addColumnsPtr->fColumns[0]->fType->fType == ddlpackage::DDL_TIMESTAMP &&
!addColumnsPtr->fColumns[0]->fDefaultValue)
{
// Query calpontsys.syscolumn to see
// if a timestamp column already exists in this table
if (!anyTimestampColumn(alterTable->fTableName->fSchema, alterTable->fTableName->fName, sessionID))
{
addColumnsPtr->fColumns[0]->fDefaultValue = new ColumnDefaultValue("current_timestamp() ON UPDATE current_timestamp()");
}
else
{
addColumnsPtr->fColumns[0]->fDefaultValue = new ColumnDefaultValue("0000-00-00 00:00:00");
}
}
@@ -1734,7 +2015,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
try
{
anyNullVal = anyNullInTheColumn (alterTable->fTableName->fSchema, alterTable->fTableName->fName, renameColumnsPtr->fName, sessionID);
anyNullVal = anyNullInTheColumn (thd, alterTable->fTableName->fSchema, alterTable->fTableName->fName, renameColumnsPtr->fName, sessionID);
}
catch (runtime_error& ex)
{

View File

@@ -137,6 +137,8 @@ int buildBuffer(uchar* buf, string& buffer, int& columns, TABLE* table)
(*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("'");
@@ -168,6 +170,8 @@ int buildBuffer(uchar* buf, string& buffer, int& columns, TABLE* table)
(*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("'");
}
@@ -409,6 +413,7 @@ int doProcessInsertValues ( TABLE* table, uint32_t size, cal_connection_info& ci
pDMLPackage->set_TableName(name);
name = table->s->db.str;
pDMLPackage->set_SchemaName(name);
pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr());
if (thd->lex->sql_command == SQLCOM_INSERT_SELECT)
pDMLPackage->set_isInsertSelect(true);
@@ -918,6 +923,41 @@ int ha_calpont_impl_write_batch_row_(uchar* buf, TABLE* table, cal_impl_if::cal_
break;
}
case CalpontSystemCatalog::TIMESTAMP:
{
if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT))
{
fprintf(ci.filePtr, "%c", ci.delimiter);
}
else
{
const uchar* pos = buf;
struct timeval tm;
my_timestamp_from_binary(&tm, pos, table->field[colpos]->decimals());
MySQLTime time;
gmtSecToMySQLTime(tm.tv_sec, time, current_thd->variables.time_zone->get_name()->ptr());
if (!tm.tv_usec)
{
fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d%c",
time.year, time.month, time.day,
time.hour, time.minute, time.second, ci.delimiter);
}
else
{
fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d.%ld%c",
time.year, time.month, time.day,
time.hour, time.minute, time.second,
tm.tv_usec, ci.delimiter);
}
}
buf += table->field[colpos]->pack_length();
break;
}
case CalpontSystemCatalog::CHAR:
{
if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT))

View File

@@ -1236,7 +1236,7 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex)
return 0;
}
ParseTree* buildRowPredicate(RowColumn* lhs, RowColumn* rhs, string predicateOp)
ParseTree* buildRowPredicate(THD* thd, RowColumn* lhs, RowColumn* rhs, string predicateOp)
{
PredicateOperator* po = new PredicateOperator(predicateOp);
boost::shared_ptr<Operator> sop(po);
@@ -1250,6 +1250,7 @@ ParseTree* buildRowPredicate(RowColumn* lhs, RowColumn* rhs, string predicateOp)
ParseTree* pt = new ParseTree(lo);
sop->setOpType(lhs->columnVec()[0]->resultType(), rhs->columnVec()[0]->resultType());
SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[0].get(), rhs->columnVec()[0].get());
sf->timeZone(thd->variables.time_zone->get_name()->ptr());
pt->left(new ParseTree(sf));
for (uint32_t i = 1; i < lhs->columnVec().size(); i++)
@@ -1257,6 +1258,7 @@ ParseTree* buildRowPredicate(RowColumn* lhs, RowColumn* rhs, string predicateOp)
sop.reset(po->clone());
sop->setOpType(lhs->columnVec()[i]->resultType(), rhs->columnVec()[i]->resultType());
SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[i].get(), rhs->columnVec()[i].get());
sf->timeZone(thd->variables.time_zone->get_name()->ptr());
pt->right(new ParseTree(sf));
if (i + 1 < lhs->columnVec().size())
@@ -1276,7 +1278,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
{
// (c1,c2,..) = (v1,v2,...) transform to: c1=v1 and c2=v2 and ...
assert (!lhs->columnVec().empty() && lhs->columnVec().size() == rhs->columnVec().size());
gwip->ptWorkStack.push(buildRowPredicate(rhs, lhs, ifp->func_name()));
gwip->ptWorkStack.push(buildRowPredicate(gwip->thd, rhs, lhs, ifp->func_name()));
}
else if (ifp->functype() == Item_func::IN_FUNC)
{
@@ -1320,7 +1322,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
RowColumn* vals = dynamic_cast<RowColumn*>(tmpStack.top());
valVec.push_back(vals);
tmpStack.pop();
ParseTree* pt = buildRowPredicate(columns, vals, predicateOp);
ParseTree* pt = buildRowPredicate(gwip->thd, columns, vals, predicateOp);
while (!tmpStack.empty())
{
@@ -1329,7 +1331,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
vals = dynamic_cast<RowColumn*>(tmpStack.top());
valVec.push_back(vals);
tmpStack.pop();
pt1->right(buildRowPredicate(columns->clone(), vals, predicateOp));
pt1->right(buildRowPredicate(gwip->thd, columns->clone(), vals, predicateOp));
pt = pt1;
}
@@ -1372,7 +1374,8 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It
sop->setOpType(sc->resultType(), valVec[j]->resultType());
cf->pushFilter(new SimpleFilter(sop, sc->clone(),
valVec[j]->columnVec()[i]->clone()));
valVec[j]->columnVec()[i]->clone(),
gwip->thd->variables.time_zone->get_name()->ptr()));
}
if (j < valVec.size())
@@ -1467,9 +1470,11 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
sop.reset(new PredicateOperator(">"));
sop->setOpType(filterCol->resultType(), rhs->resultType());
sfr = new SimpleFilter(sop, filterCol, rhs);
sfr->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
sop.reset(new PredicateOperator("<"));
sop->setOpType(filterCol->resultType(), lhs->resultType());
sfl = new SimpleFilter(sop, filterCol->clone(), lhs);
sfl->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
ParseTree* ptp = new ParseTree(new LogicOperator("or"));
ptp->left(sfr);
ptp->right(sfl);
@@ -1480,9 +1485,11 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
sop.reset(new PredicateOperator("<="));
sop->setOpType(filterCol->resultType(), rhs->resultType());
sfr = new SimpleFilter(sop, filterCol, rhs);
sfr->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
sop.reset(new PredicateOperator(">="));
sop->setOpType(filterCol->resultType(), lhs->resultType());
sfl = new SimpleFilter(sop, filterCol->clone(), lhs);
sfl->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
ParseTree* ptp = new ParseTree(new LogicOperator("and"));
ptp->left(sfr);
ptp->right(sfl);
@@ -1542,7 +1549,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
cf->op(sop);
sop.reset(new PredicateOperator(eqop));
sop->setOpType(gwip->scsp->resultType(), lhs->resultType());
cf->pushFilter(new SimpleFilter(sop, gwip->scsp->clone(), lhs));
cf->pushFilter(new SimpleFilter(sop, gwip->scsp->clone(), lhs, gwip->thd->variables.time_zone->get_name()->ptr()));
while (!gwip->rcWorkStack.empty())
{
@@ -1553,7 +1560,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
gwip->rcWorkStack.pop();
sop.reset(new PredicateOperator(eqop));
sop->setOpType(gwip->scsp->resultType(), lhs->resultType());
cf->pushFilter(new SimpleFilter(sop, gwip->scsp->clone(), lhs));
cf->pushFilter(new SimpleFilter(sop, gwip->scsp->clone(), lhs, gwip->thd->variables.time_zone->get_name()->ptr()));
}
if (!gwip->rcWorkStack.empty())
@@ -1620,6 +1627,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
{
gwip->rcWorkStack.push(new ConstantColumn((int64_t)udf->val_int()));
}
(dynamic_cast<ConstantColumn*>(gwip->rcWorkStack.top()))->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
}
else
{
@@ -1641,6 +1649,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
{
gwip->rcWorkStack.push(new ConstantColumn(buf.ptr(), ConstantColumn::NUM));
}
(dynamic_cast<ConstantColumn*>(gwip->rcWorkStack.top()))->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
return false;
}
@@ -1813,15 +1822,19 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
SimpleFilter* sfo = 0;
// b IS NULL
ConstantColumn* nlhs1 = new ConstantColumn("", ConstantColumn::NULLDATA);
nlhs1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
sop.reset(new PredicateOperator("isnull"));
sop->setOpType(lhs->resultType(), rhs->resultType());
sfn1 = new SimpleFilter(sop, rhs, nlhs1);
sfn1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
ParseTree* ptpl = new ParseTree(sfn1);
// a IS NULL
ConstantColumn* nlhs2 = new ConstantColumn("", ConstantColumn::NULLDATA);
nlhs2->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
sop.reset(new PredicateOperator("isnull"));
sop->setOpType(lhs->resultType(), rhs->resultType());
sfn2 = new SimpleFilter(sop, lhs, nlhs2);
sfn2->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
ParseTree* ptpr = new ParseTree(sfn2);
// AND them both
ParseTree* ptpn = new ParseTree(new LogicOperator("and"));
@@ -1831,6 +1844,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
sop.reset(new PredicateOperator("="));
sop->setOpType(lhs->resultType(), rhs->resultType());
sfo = new SimpleFilter(sop, lhs->clone(), rhs->clone());
sfo->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
// OR with the NULL comparison tree
ParseTree* ptp = new ParseTree(new LogicOperator("or"));
ptp->left(sfo);
@@ -1929,6 +1943,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
}
SimpleFilter* sf = new SimpleFilter();
sf->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
//@bug 2101 for when there are only constants in a delete or update where clause (eg "where 5 < 6").
//There will be no field column and it will get here only if the comparison is true.
@@ -2036,6 +2051,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
bool buildConstPredicate(Item_func* ifp, ReturnedColumn* rhs, gp_walk_info* gwip)
{
SimpleFilter* sf = new SimpleFilter();
sf->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
boost::shared_ptr<Operator> sop(new PredicateOperator(ifp->func_name()));
ConstantColumn* lhs = 0;
@@ -2054,6 +2070,7 @@ bool buildConstPredicate(Item_func* ifp, ReturnedColumn* rhs, gp_walk_info* gwip
lhs = new ConstantColumn((int64_t)0, ConstantColumn::NUM);
sop.reset(new PredicateOperator("="));
}
lhs->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
CalpontSystemCatalog::ColType opType = rhs->resultType();
@@ -2127,6 +2144,7 @@ SimpleColumn* buildSimpleColFromDerivedTable(gp_walk_info& gwi, Item_field* ifp)
sc->tableAlias(lower(gwi.tbList[i].alias));
sc->viewName(lower(viewName));
sc->resultType(ct);
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
break;
}
}
@@ -2185,6 +2203,7 @@ SimpleColumn* buildSimpleColFromDerivedTable(gp_walk_info& gwi, Item_field* ifp)
string tableAlias(csep->derivedTbAlias());
sc->tableAlias(lower(tableAlias));
sc->viewName(lower(viewName));
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
sc->resultType(cols[j]->resultType());
sc->hasAggregate(cols[j]->hasAggregate());
@@ -2301,6 +2320,7 @@ void collectAllCols(gp_walk_info& gwi, Item_field* ifp)
sc->tableAlias(lower(tableAlias));
sc->viewName(lower(gwi.tbList[i].view));
sc->resultType(cols[j]->resultType());
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
// @bug5634 derived table optimization
cols[j]->incRefCount();
@@ -2335,6 +2355,7 @@ void collectAllCols(gp_walk_info& gwi, Item_field* ifp)
sc->resultType(ct);
sc->tableAlias(lower(gwi.tbList[i].alias));
sc->viewName(lower(viewName));
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
srcp.reset(sc);
gwi.returnedCols.push_back(srcp);
gwi.columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp));
@@ -2629,6 +2650,7 @@ SimpleColumn* getSmallestColumn(boost::shared_ptr<CalpontSystemCatalog> csc,
sc->columnName(rc->alias());
sc->sequence(0);
sc->tableAlias(lower(tan.alias));
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
// @bug5634 derived table optimization.
rc->incRefCount();
sc->derivedTable(csep->derivedTbAlias());
@@ -2649,6 +2671,7 @@ SimpleColumn* getSmallestColumn(boost::shared_ptr<CalpontSystemCatalog> csc,
string alias(table->alias.ptr());
sc->tableAlias(lower(alias));
sc->isInfiniDB(false);
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
sc->resultType(fieldType_MysqlToIDB(field));
sc->oid(field->field_index + 1);
return sc;
@@ -2677,6 +2700,7 @@ SimpleColumn* getSmallestColumn(boost::shared_ptr<CalpontSystemCatalog> csc,
SimpleColumn* sc = new SimpleColumn(tcn.schema, tcn.table, tcn.column, csc->sessionID());
sc->tableAlias(lower(tan.alias));
sc->viewName(lower(tan.view));
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
sc->resultType(csc->colType(oidlist[minWidthColOffset].objnum));
return sc;
}
@@ -2777,14 +2801,19 @@ CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item)
ct.colWidth = 4;
}
else if (item->field_type() == MYSQL_TYPE_DATETIME ||
item->field_type() == MYSQL_TYPE_DATETIME2 ||
item->field_type() == MYSQL_TYPE_TIMESTAMP ||
item->field_type() == MYSQL_TYPE_TIMESTAMP2
item->field_type() == MYSQL_TYPE_DATETIME2
)
{
ct.colDataType = CalpontSystemCatalog::DATETIME;
ct.colWidth = 8;
}
else if (item->field_type() == MYSQL_TYPE_TIMESTAMP ||
item->field_type() == MYSQL_TYPE_TIMESTAMP2
)
{
ct.colDataType = CalpontSystemCatalog::TIMESTAMP;
ct.colWidth = 8;
}
else if (item->field_type() == MYSQL_TYPE_TIME)
{
ct.colDataType = CalpontSystemCatalog::TIME;
@@ -2883,6 +2912,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
{
rc = new ConstantColumn(valStr, (int64_t)item->val_int(), ConstantColumn::NUM);
}
(dynamic_cast<ConstantColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
//return cc;
break;
@@ -2894,6 +2924,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
string valStr;
valStr.assign(str->ptr(), str->length());
rc = new ConstantColumn(valStr);
(dynamic_cast<ConstantColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
break;
}
@@ -2903,6 +2934,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
string valStr;
valStr.assign(str->ptr(), str->length());
rc = new ConstantColumn(valStr, item->val_real());
(dynamic_cast<ConstantColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
break;
}
@@ -2947,10 +2979,12 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
if (!str)
{
rc = new ConstantColumn("", ConstantColumn::NULLDATA);
(dynamic_cast<ConstantColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
}
else if (ifp->result_type() == STRING_RESULT)
{
rc = new ConstantColumn(valStr, ConstantColumn::LITERAL);
(dynamic_cast<ConstantColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
rc->resultType(colType_MysqlToIDB(item));
}
else if (ifp->result_type() == DECIMAL_RESULT)
@@ -2958,6 +2992,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
else
{
rc = new ConstantColumn(valStr, ConstantColumn::NUM);
(dynamic_cast<ConstantColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
rc->resultType(colType_MysqlToIDB(item));
}
@@ -3008,7 +3043,9 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
if (gwi.condPush)
return new SimpleColumn("noop");
return new ConstantColumn("", ConstantColumn::NULLDATA);
ConstantColumn *tmp = new ConstantColumn("", ConstantColumn::NULLDATA);
tmp->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
return tmp;
}
case Item::CACHE_ITEM:
@@ -3046,6 +3083,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
string valStr;
valStr.assign(str->ptr(), str->length());
rc = new ConstantColumn(valStr);
(dynamic_cast<ConstantColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
break;
}
@@ -3113,6 +3151,7 @@ ArithmeticColumn* buildArithmeticColumn(
ArithmeticColumn* ac = new ArithmeticColumn();
Item** sfitempp = item->arguments();
ArithmeticOperator* aop = new ArithmeticOperator(item->func_name());
aop->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
ParseTree* pt = new ParseTree(aop);
//ReturnedColumn *lhs = 0, *rhs = 0;
ParseTree* lhs = 0, *rhs = 0;
@@ -3237,6 +3276,7 @@ ArithmeticColumn* buildArithmeticColumn(
else
{
ConstantColumn* cc = new ConstantColumn(string("0"), (int64_t)0);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
if (gwi.clauseType == SELECT || gwi.clauseType == HAVING || gwi.clauseType == GROUP_BY) // select clause
{
@@ -3552,6 +3592,7 @@ ReturnedColumn* buildFunctionColumn(
{
THD* thd = current_thd;
sptp.reset(new ParseTree(new ConstantColumn(static_cast<uint64_t>(thd->variables.default_week_format))));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(sptp);
}
@@ -3559,7 +3600,7 @@ ReturnedColumn* buildFunctionColumn(
if (funcName == "date_add_interval" || funcName == "extract" || funcName == "timestampdiff")
{
addIntervalArgs(ifp, funcParms);
addIntervalArgs(gwi.thd, ifp, funcParms);
}
// check for unsupported arguments add the keyword unit argument for extract functions
@@ -3610,19 +3651,19 @@ ReturnedColumn* buildFunctionColumn(
// add the keyword unit argument and char length for cast functions
if (funcName == "cast_as_char" )
{
castCharArgs(ifp, funcParms);
castCharArgs(gwi.thd, ifp, funcParms);
}
// add the length and scale arguments
if (funcName == "decimal_typecast" )
{
castDecimalArgs(ifp, funcParms);
castDecimalArgs(gwi.thd, ifp, funcParms);
}
// add the type argument
if (funcName == "get_format")
{
castTypeArgs(ifp, funcParms);
castTypeArgs(gwi.thd, ifp, funcParms);
}
// add my_time_zone
@@ -3637,6 +3678,7 @@ ReturnedColumn* buildFunctionColumn(
//FIXME: Get GMT offset (in seconds east of GMT) in Windows...
sptp.reset(new ParseTree(new ConstantColumn(static_cast<int64_t>(0), ConstantColumn::NUM)));
#endif
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(sptp);
}
@@ -3646,8 +3688,10 @@ ReturnedColumn* buildFunctionColumn(
if (funcParms.size() == 0)
{
sptp.reset(new ParseTree(new ConstantColumn((int64_t)gwi.thd->rand.seed1, ConstantColumn::NUM)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(sptp);
sptp.reset(new ParseTree(new ConstantColumn((int64_t)gwi.thd->rand.seed2, ConstantColumn::NUM)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(sptp);
gwi.no_parm_func_list.push_back(fc);
}
@@ -3675,6 +3719,7 @@ ReturnedColumn* buildFunctionColumn(
sign = -1;
}
sptp.reset(new ParseTree(new ConstantColumn(sign)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(sptp);
}
@@ -3685,15 +3730,21 @@ ReturnedColumn* buildFunctionColumn(
// MySQL give string result type for date function, but has the flag set.
// we should set the result type to be datetime for comparision.
if (ifp->field_type() == MYSQL_TYPE_DATETIME ||
ifp->field_type() == MYSQL_TYPE_DATETIME2 ||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP ||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP2)
ifp->field_type() == MYSQL_TYPE_DATETIME2)
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::DATETIME;
ct.colWidth = 8;
fc->resultType(ct);
}
if (ifp->field_type() == MYSQL_TYPE_TIMESTAMP ||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP2)
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::TIMESTAMP;
ct.colWidth = 8;
fc->resultType(ct);
}
else if (ifp->field_type() == MYSQL_TYPE_DATE)
{
CalpontSystemCatalog::ColType ct;
@@ -3796,6 +3847,8 @@ ReturnedColumn* buildFunctionColumn(
}
}
fc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
return fc;
}
@@ -3941,6 +3994,7 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
fc->functionName(funcName);
fc->functionParms(funcParms);
fc->expressionId(ci->expressionId++);
fc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
// For function join. If any argument has non-zero joininfo, set it to the function.
fc->setSimpleColumnList();
@@ -3994,7 +4048,9 @@ ConstantColumn* buildDecimalColumn(Item* item, gp_walk_info& gwi)
infinidb_decimal.scale = idp->decimals;
infinidb_decimal.precision = idp->max_length - idp->decimals;
return new ConstantColumn(valStr, infinidb_decimal);
ConstantColumn* cc = new ConstantColumn(valStr, infinidb_decimal);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
return cc;
}
SimpleColumn* buildSimpleColumn(Item_field* ifp, gp_walk_info& gwi)
@@ -4130,6 +4186,7 @@ SimpleColumn* buildSimpleColumn(Item_field* ifp, gp_walk_info& gwi)
sc->alias(ifp->name.str);
sc->isInfiniDB(infiniDB);
sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
if (!infiniDB && ifp->field)
sc->oid(ifp->field->field_index + 1); // ExeMgr requires offset started from 1
@@ -4236,6 +4293,8 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
ac = new AggregateColumn(gwi.sessionid);
}
ac->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
if (isp->name.length)
ac->alias(isp->name.str);
@@ -4379,6 +4438,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
case Item::NULL_ITEM:
{
parm.reset(new ConstantColumn("", ConstantColumn::NULLDATA));
(dynamic_cast<ConstantColumn*>(parm.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
ac->constCol(SRCP(buildReturnedColumn(sfitemp, gwi, gwi.fatalParseError)));
break;
}
@@ -4710,7 +4770,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
return ac;
}
void addIntervalArgs(Item_func* ifp, FunctionParm& functionParms)
void addIntervalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms)
{
string funcName = ifp->func_name();
int interval_type = -1;
@@ -4722,7 +4782,7 @@ void addIntervalArgs(Item_func* ifp, FunctionParm& functionParms)
else if (funcName == "extract")
interval_type = ((Item_extract*)ifp)->int_type;
functionParms.push_back(getIntervalType(interval_type));
functionParms.push_back(getIntervalType(thd, interval_type));
SPTP sptp;
if (funcName == "date_add_interval")
@@ -4730,37 +4790,42 @@ void addIntervalArgs(Item_func* ifp, FunctionParm& functionParms)
if (((Item_date_add_interval*)ifp)->date_sub_interval)
{
sptp.reset(new ParseTree(new ConstantColumn((int64_t)OP_SUB)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
functionParms.push_back(sptp);
}
else
{
sptp.reset(new ParseTree(new ConstantColumn((int64_t)OP_ADD)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
functionParms.push_back(sptp);
}
}
}
SPTP getIntervalType(int interval_type)
SPTP getIntervalType(THD* thd, int interval_type)
{
SPTP sptp;
sptp.reset(new ParseTree(new ConstantColumn((int64_t)interval_type)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
return sptp;
}
void castCharArgs(Item_func* ifp, FunctionParm& functionParms)
void castCharArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms)
{
Item_char_typecast* idai = (Item_char_typecast*)ifp;
SPTP sptp;
sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->castLength())));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
functionParms.push_back(sptp);
}
void castDecimalArgs(Item_func* ifp, FunctionParm& functionParms)
void castDecimalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms)
{
Item_decimal_typecast* idai = (Item_decimal_typecast*)ifp;
SPTP sptp;
sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->decimals)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
functionParms.push_back(sptp);
// max length including sign and/or decimal points
@@ -4768,11 +4833,12 @@ void castDecimalArgs(Item_func* ifp, FunctionParm& functionParms)
sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->max_length - 1)));
else
sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->max_length - 2)));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
functionParms.push_back(sptp);
}
void castTypeArgs(Item_func* ifp, FunctionParm& functionParms)
void castTypeArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms)
{
Item_func_get_format* get_format = (Item_func_get_format*)ifp;
SPTP sptp;
@@ -4781,6 +4847,7 @@ void castTypeArgs(Item_func* ifp, FunctionParm& functionParms)
sptp.reset(new ParseTree(new ConstantColumn("DATE")));
else
sptp.reset(new ParseTree(new ConstantColumn("DATETIME")));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
functionParms.push_back(sptp);
}
@@ -4871,6 +4938,7 @@ void gp_walk(const Item* item, void* arg)
}
gwip->rcWorkStack.push(new ConstantColumn(cval));
(dynamic_cast<ConstantColumn*>(gwip->rcWorkStack.top()))->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
break;
}
@@ -4912,6 +4980,7 @@ void gp_walk(const Item* item, void* arg)
}
gwip->rcWorkStack.push(new ConstantColumn("", ConstantColumn::NULLDATA));
(dynamic_cast<ConstantColumn*>(gwip->rcWorkStack.top()))->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
break;
}
@@ -5002,10 +5071,12 @@ void gp_walk(const Item* item, void* arg)
if (!str) //@ bug 2844 check whether parameter is defined
{
cc = new ConstantColumn("", ConstantColumn::NULLDATA);
cc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
}
else if (ifp->result_type() == STRING_RESULT)
{
cc = new ConstantColumn(valStr, ConstantColumn::LITERAL);
cc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
}
else if (ifp->result_type() == DECIMAL_RESULT)
{
@@ -5014,6 +5085,7 @@ void gp_walk(const Item* item, void* arg)
else
{
cc = new ConstantColumn(valStr, ConstantColumn::NUM);
cc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
cc->resultType(colType_MysqlToIDB(item));
}
@@ -5736,6 +5808,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
gwi.sessionid = sessionID;
boost::shared_ptr<CalpontSystemCatalog> csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID);
csc->identity(CalpontSystemCatalog::FE);
csep->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
gwi.csc = csc;
// @bug 2123. Override large table estimate if infinidb_ordered hint was used.
@@ -5997,6 +6070,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
else if (join && join->zero_result_cause)
{
gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM));
(dynamic_cast<ConstantColumn*>(gwi.rcWorkStack.top()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
}
@@ -6384,10 +6458,12 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
if (!str)
{
cc = new ConstantColumn("", ConstantColumn::NULLDATA);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
}
else if (ifp->result_type() == STRING_RESULT)
{
cc = new ConstantColumn(valStr, ConstantColumn::LITERAL);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
}
else if (ifp->result_type() == DECIMAL_RESULT)
{
@@ -6396,6 +6472,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
else
{
cc = new ConstantColumn(valStr, ConstantColumn::NUM);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
cc->resultType(colType_MysqlToIDB(item));
}
@@ -6619,6 +6696,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
selectSubList.push_back(ssub);
SimpleColumn* rc = new SimpleColumn();
rc->colSource(rc->colSource() | SELECT_SUB);
rc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
if (sub->get_select_lex()->get_table_list())
rc->viewName(lower(getViewName(sub->get_select_lex()->get_table_list())));
@@ -7996,6 +8074,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
sc1->tableAlias(sc->tableAlias());
sc1->viewName(lower(sc->viewName()));
sc1->colPosition(0);
sc1->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
minSc.reset(sc1);
}
}
@@ -8077,7 +8156,7 @@ int cp_get_plan(THD* thd, SCSEP& csep)
#endif
// Derived table projection and filter optimization.
derivedTableOptimization(csep);
derivedTableOptimization(thd, csep);
return 0;
}
@@ -8110,6 +8189,7 @@ int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti)
SimpleColumn* sc = new SimpleColumn(table->s->db.str, table->s->table_name.str, field->field_name.str, sessionID);
string alias(table->alias.c_ptr());
sc->tableAlias(lower(alias));
sc->timeZone(gwi->thd->variables.time_zone->get_name()->ptr());
assert (sc);
boost::shared_ptr<SimpleColumn> spsc(sc);
gwi->returnedCols.push_back(spsc);
@@ -8483,6 +8563,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
else if (join && join->zero_result_cause)
{
gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM));
(dynamic_cast<ConstantColumn*>(gwi.rcWorkStack.top()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
}
SELECT_LEX tmp_select_lex;
@@ -8835,10 +8916,12 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
if (!str)
{
cc = new ConstantColumn("", ConstantColumn::NULLDATA);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
}
else if (ifp->result_type() == STRING_RESULT)
{
cc = new ConstantColumn(valStr, ConstantColumn::LITERAL);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
}
else if (ifp->result_type() == DECIMAL_RESULT)
{
@@ -8847,6 +8930,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
else
{
cc = new ConstantColumn(valStr, ConstantColumn::NUM);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
cc->resultType(colType_MysqlToIDB(item));
}
@@ -9068,6 +9152,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
selectSubList.push_back(ssub);
SimpleColumn* rc = new SimpleColumn();
rc->colSource(rc->colSource() | SELECT_SUB);
rc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
if (sub->get_select_lex()->get_table_list())
rc->viewName(lower(getViewName(sub->get_select_lex()->get_table_list())));
@@ -10156,6 +10241,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
sc1->tableName(sc->tableName());
sc1->tableAlias(sc->tableAlias());
sc1->viewName(lower(sc->viewName()));
sc1->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
sc1->colPosition(0);
minSc.reset(sc1);
}

View File

@@ -600,6 +600,19 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h
break;
}
case CalpontSystemCatalog::TIMESTAMP:
{
if ((*f)->null_ptr)
*(*f)->null_ptr &= ~(*f)->null_bit;
intColVal = row.getUintField<8>(s);
DataConvert::timestampToString(intColVal, tmp, 255, current_thd->variables.time_zone->get_name()->ptr(), colType.precision);
Field_varstring* f2 = (Field_varstring*)*f;
f2->store(tmp, strlen(tmp), f2->charset());
break;
}
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
{
@@ -1005,6 +1018,205 @@ void makeUpdateSemiJoin(const ParseTree* n, void* obj)
return;
}
vector<string> getOnUpdateTimestampColumns(string& schema, string& tableName, int sessionID)
{
vector<string> returnVal;
typedef CalpontSelectExecutionPlan::ColumnMap::value_type CMVT_;
boost::shared_ptr<CalpontSystemCatalog> csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID);
csc->identity(execplan::CalpontSystemCatalog::FE);
CalpontSystemCatalog::TableName aTableName;
boost::algorithm::to_lower(schema);
boost::algorithm::to_lower(tableName);
// select columnname from calpontsys.syscolumn
// where schema = schema and tablename = tableName
// and datatype = 'timestamp'
// and defaultvalue = 'current_timestamp() ON UPDATE current_timestamp()'
CalpontSelectExecutionPlan csep;
CalpontSelectExecutionPlan::ReturnedColumnList returnedColumnList;
CalpontSelectExecutionPlan::FilterTokenList filterTokenList;
CalpontSelectExecutionPlan::ColumnMap colMap;
SessionManager sm;
BRM::TxnID txnID;
txnID = sm.getTxnID(sessionID);
if (!txnID.valid)
{
txnID.id = 0;
txnID.valid = true;
}
QueryContext verID;
verID = sm.verID();
csep.txnID(txnID.id);
csep.verID(verID);
csep.sessionID(sessionID);
string sysTable = "calpontsys.syscolumn.";
string firstCol = sysTable + "columnname";
SimpleColumn* c1 = new SimpleColumn(firstCol, sessionID);
string secondCol = sysTable + "schema";
SimpleColumn* c2 = new SimpleColumn(secondCol, sessionID);
string thirdCol = sysTable + "tablename";
SimpleColumn* c3 = new SimpleColumn(thirdCol, sessionID);
string fourthCol = sysTable + "datatype";
SimpleColumn* c4 = new SimpleColumn(fourthCol, sessionID);
string fifthCol = sysTable + "defaultvalue";
SimpleColumn* c5 = new SimpleColumn(fifthCol, sessionID);
SRCP srcp;
srcp.reset(c1);
colMap.insert(CMVT_(firstCol, srcp));
srcp.reset(c2);
colMap.insert(CMVT_(secondCol, srcp));
srcp.reset(c3);
colMap.insert(CMVT_(thirdCol, srcp));
srcp.reset(c4);
colMap.insert(CMVT_(fourthCol, srcp));
srcp.reset(c5);
colMap.insert(CMVT_(fifthCol, srcp));
csep.columnMapNonStatic(colMap);
srcp.reset(c1->clone());
returnedColumnList.push_back(srcp);
csep.returnedCols(returnedColumnList);
// Filters
const SOP opeq(new Operator("="));
SimpleFilter* f1 = new SimpleFilter (opeq,
c2->clone(),
new ConstantColumn(schema, ConstantColumn::LITERAL));
filterTokenList.push_back(f1);
filterTokenList.push_back(new Operator("and"));
SimpleFilter* f2 = new SimpleFilter (opeq,
c3->clone(),
new ConstantColumn(tableName, ConstantColumn::LITERAL));
filterTokenList.push_back(f2);
filterTokenList.push_back(new Operator("and"));
SimpleFilter* f3 = new SimpleFilter (opeq,
c4->clone(),
new ConstantColumn((uint64_t) execplan::CalpontSystemCatalog::TIMESTAMP, ConstantColumn::NUM));
filterTokenList.push_back(f3);
filterTokenList.push_back(new Operator("and"));
string defaultValue = "current_timestamp() ON UPDATE current_timestamp()";
SimpleFilter* f4 = new SimpleFilter (opeq,
c5->clone(),
new ConstantColumn(defaultValue, ConstantColumn::LITERAL));
filterTokenList.push_back(f4);
csep.filterTokenList(filterTokenList);
CalpontSelectExecutionPlan::TableList tablelist;
tablelist.push_back(make_aliastable("calpontsys", "syscolumn", ""));
csep.tableList(tablelist);
boost::shared_ptr<messageqcpp::MessageQueueClient> exemgrClient (new messageqcpp::MessageQueueClient("ExeMgr1"));
ByteStream msg, emsgBs;
rowgroup::RGData rgData;
ByteStream::quadbyte qb = 4;
msg << qb;
rowgroup::RowGroup* rowGroup = 0;
uint32_t rowCount;
exemgrClient->write(msg);
ByteStream msgPlan;
csep.serialize(msgPlan);
exemgrClient->write(msgPlan);
msg.restart();
msg = exemgrClient->read(); //error handling
emsgBs = exemgrClient->read();
ByteStream::quadbyte qb1;
if (emsgBs.length() == 0)
{
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error("Lost conection to ExeMgr.");
}
string emsgStr;
emsgBs >> emsgStr;
if (msg.length() == 4)
{
msg >> qb1;
if (qb1 != 0)
{
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error(emsgStr);
}
}
while (true)
{
msg.restart();
msg = exemgrClient->read();
if ( msg.length() == 0 )
{
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error("Lost conection to ExeMgr.");
}
else
{
if (!rowGroup)
{
//This is mete data
rowGroup = new rowgroup::RowGroup();
rowGroup->deserialize(msg);
qb = 100;
msg.restart();
msg << qb;
exemgrClient->write(msg);
continue;
}
rgData.deserialize(msg);
rowGroup->setData(&rgData);
if (rowGroup->getStatus() != 0)
{
//msg.advance(rowGroup->getDataSize());
msg >> emsgStr;
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
throw runtime_error(emsgStr);
}
rowCount = rowGroup->getRowCount();
if (rowCount > 0)
{
rowgroup::Row row;
rowGroup->initRow(&row);
for (uint32_t i = 0; i < rowCount; i++)
{
rowGroup->getRow(i, &row);
// we are only fetching a single column
returnVal.push_back(row.getStringField(0));
}
}
else
{
break;
}
//exemgrClient->shutdown();
//delete exemgrClient;
//exemgrClient = 0;
}
}
return returnVal;
}
uint32_t doUpdateDelete(THD* thd)
{
if (get_fe_conn_info_ptr() == NULL)
@@ -1123,6 +1335,7 @@ uint32_t doUpdateDelete(THD* thd)
updateCP->queryType(CalpontSelectExecutionPlan::UPDATE);
ci->stats.fQueryType = updateCP->queryType();
uint32_t cnt = 0;
tr1::unordered_set<string> timeStampColumnNames;
// for (; table_ptr; table_ptr= table_ptr->next_local)
// {
@@ -1176,6 +1389,12 @@ uint32_t doUpdateDelete(THD* thd)
else
schemaName = string(item->db_name);
if (item->field_type() == MYSQL_TYPE_TIMESTAMP ||
item->field_type() == MYSQL_TYPE_TIMESTAMP2)
{
timeStampColumnNames.insert(string(item->name.str));
}
columnAssignmentPtr = new ColumnAssignment();
columnAssignmentPtr->fColumn = string(item->name.str);
columnAssignmentPtr->fOperator = "=";
@@ -1364,6 +1583,30 @@ uint32_t doUpdateDelete(THD* thd)
// if (cnt < thd->lex->select_lex.item_list.elements)
// dmlStmt += ", ";
}
// Support for on update current_timestamp() for timestamp fields
// Query calpontsys.syscolumn to get all timestamp columns with
// ON UPDATE current_timestamp() property
vector<string> onUpdateTimeStampColumns = getOnUpdateTimestampColumns(schemaName, tableName, tid2sid(thd->thread_id));
for (size_t i = 0; i < onUpdateTimeStampColumns.size(); i++)
{
if (timeStampColumnNames.find(onUpdateTimeStampColumns[i]) == timeStampColumnNames.end())
{
columnAssignmentPtr = new ColumnAssignment();
columnAssignmentPtr->fColumn = string(onUpdateTimeStampColumns[i]);
columnAssignmentPtr->fOperator = "=";
columnAssignmentPtr->fFuncScale = 0;
columnAssignmentPtr->fFromCol = false;
struct timeval tv;
char buf[64];
gettimeofday(&tv, 0);
MySQLTime time;
gmtSecToMySQLTime(tv.tv_sec, time, thd->variables.time_zone->get_name()->ptr());
sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%06ld", time.year, time.month, time.day, time.hour, time.minute, time.second, tv.tv_usec);
columnAssignmentPtr->fScalarExpression = buf;
colAssignmentListPtr->push_back ( columnAssignmentPtr );
}
}
}
else
{
@@ -1492,6 +1735,7 @@ uint32_t doUpdateDelete(THD* thd)
pDMLPackage->set_TableName(tableName);
pDMLPackage->set_SchemaName(schemaName);
pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr());
pDMLPackage->set_IsFromCol( true );
//cout << " setting isFromCol to " << isFromCol << endl;
@@ -1691,6 +1935,7 @@ uint32_t doUpdateDelete(THD* thd)
CalpontSystemCatalog::TableColName tcn = csc->colName(colrids[minWidthColOffset].objnum);
SimpleColumn* sc = new SimpleColumn(tcn.schema, tcn.table, tcn.column, csc->sessionID());
sc->tableAlias(aliasName);
sc->timeZone(thd->variables.time_zone->get_name()->ptr());
sc->resultType(csc->colType(colrids[minWidthColOffset].objnum));
SRCP srcp;
srcp.reset(sc);
@@ -1820,6 +2065,7 @@ uint32_t doUpdateDelete(THD* thd)
//cout << "doUpdateDelete start new DMLProc client for ctrl-c " << " for session " << sessionID << endl;
VendorDMLStatement cmdStmt( "CTRL+C", DML_COMMAND, sessionID);
CalpontDMLPackage* pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt);
pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr());
ByteStream bytestream;
bytestream << static_cast<uint32_t>(sessionID);
pDMLPackage->write(bytestream);
@@ -1941,6 +2187,7 @@ uint32_t doUpdateDelete(THD* thd)
{
VendorDMLStatement cmdStmt(command, DML_COMMAND, sessionID);
CalpontDMLPackage* pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt);
pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr());
pDMLPackage->setTableOid (ci->tableOid);
ByteStream bytestream;
bytestream << static_cast<uint32_t>(sessionID);
@@ -3293,7 +3540,7 @@ void ha_calpont_impl_start_bulk_insert(ha_rows rows, TABLE* table)
#ifdef _MSC_VER
aCmdLine = aCmdLine + "/bin/cpimport.exe -N -P " + to_string(localModuleId) + " -s " + ci->delimiter + " -e 0" + " -E " + escapechar + ci->enclosed_by + " ";
#else
aCmdLine = aCmdLine + "/bin/cpimport -m 1 -N -P " + boost::to_string(localModuleId) + " -s " + ci->delimiter + " -e 0" + " -E " + escapechar + ci->enclosed_by + " ";
aCmdLine = aCmdLine + "/bin/cpimport -m 1 -N -P " + boost::to_string(localModuleId) + " -s " + ci->delimiter + " -e 0" + " -T " + thd->variables.time_zone->get_name()->ptr() + " -E " + escapechar + ci->enclosed_by + " ";
#endif
}
}
@@ -3302,7 +3549,7 @@ void ha_calpont_impl_start_bulk_insert(ha_rows rows, TABLE* table)
#ifdef _MSC_VER
aCmdLine = aCmdLine + "/bin/cpimport.exe -N -s " + ci->delimiter + " -e 0" + " -E " + escapechar + ci->enclosed_by + " ";
#else
aCmdLine = aCmdLine + "/bin/cpimport -m 1 -N -s " + ci->delimiter + " -e 0" + " -E " + escapechar + ci->enclosed_by + " ";
aCmdLine = aCmdLine + "/bin/cpimport -m 1 -N -s " + ci->delimiter + " -e 0" + " -T " + thd->variables.time_zone->get_name()->ptr() + " -E " + escapechar + ci->enclosed_by + " ";
#endif
}

View File

@@ -348,13 +348,13 @@ execplan::ParseTree* buildParseTree(Item_func* item, gp_walk_info& gwi, bool& no
execplan::ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi);
execplan::ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& nonSupport);
execplan::ReturnedColumn* buildPseudoColumn(Item* item, gp_walk_info& gwi, bool& nonSupport, uint32_t pseudoType);
void addIntervalArgs(Item_func* ifp, funcexp::FunctionParm& functionParms);
void castCharArgs(Item_func* ifp, funcexp::FunctionParm& functionParms);
void castDecimalArgs(Item_func* ifp, funcexp::FunctionParm& functionParms);
void castTypeArgs(Item_func* ifp, funcexp::FunctionParm& functionParms);
void addIntervalArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms);
void castCharArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms);
void castDecimalArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms);
void castTypeArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms);
//void parse_item (Item* item, std::vector<Item_field*>& field_vec, bool& hasNonSupportItem, uint16& parseInfo);
bool isPredicateFunction(Item* item, gp_walk_info* gwip);
execplan::ParseTree* buildRowPredicate(execplan::RowColumn* lhs, execplan::RowColumn* rhs, std::string predicateOp);
execplan::ParseTree* buildRowPredicate(THD* thd, execplan::RowColumn* lhs, execplan::RowColumn* rhs, std::string predicateOp);
bool buildRowColumnFilter(gp_walk_info* gwip, execplan::RowColumn* rhs, execplan::RowColumn* lhs, Item_func* ifp);
bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip);
void collectAllCols(gp_walk_info& gwi, Item_field* ifp);
@@ -364,13 +364,13 @@ std::string getViewName(TABLE_LIST* table_ptr);
bool buildConstPredicate(Item_func* ifp, execplan::ReturnedColumn* rhs, gp_walk_info* gwip);
execplan::CalpontSystemCatalog::ColType fieldType_MysqlToIDB (const Field* field);
execplan::CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item);
execplan::SPTP getIntervalType(int interval_type);
execplan::SPTP getIntervalType(THD* thd, int interval_type);
uint32_t isPseudoColumn(std::string funcName);
void setDerivedTable(execplan::ParseTree* n);
execplan::ParseTree* setDerivedFilter(execplan::ParseTree*& n,
execplan::ParseTree* setDerivedFilter(THD* thd, execplan::ParseTree*& n,
std::map<std::string, execplan::ParseTree*>& obj,
execplan::CalpontSelectExecutionPlan::SelectList& derivedTbList);
void derivedTableOptimization(execplan::SCSEP& csep);
void derivedTableOptimization(THD* thd, execplan::SCSEP& csep);
#ifdef DEBUG_WALK_COND
void debug_walk(const Item* item, void* arg);

View File

@@ -128,6 +128,9 @@ string name(CalpontSystemCatalog::ColType& ct)
case CalpontSystemCatalog::TIME:
return "TIME";
case CalpontSystemCatalog::TIMESTAMP:
return "TIMESTAMP";
case CalpontSystemCatalog::DECIMAL:
return "DECIMAL";
@@ -208,6 +211,7 @@ bool CP_type(CalpontSystemCatalog::ColType& ct)
ct.colDataType == CalpontSystemCatalog::DATE ||
ct.colDataType == CalpontSystemCatalog::DATETIME ||
ct.colDataType == CalpontSystemCatalog::TIME ||
ct.colDataType == CalpontSystemCatalog::TIMESTAMP ||
ct.colDataType == CalpontSystemCatalog::DECIMAL ||
ct.colDataType == CalpontSystemCatalog::UTINYINT ||
ct.colDataType == CalpontSystemCatalog::USMALLINT ||
@@ -268,6 +272,10 @@ const string format(int64_t v, CalpontSystemCatalog::ColType& ct)
oss << DataConvert::datetimeToString(v);
break;
case CalpontSystemCatalog::TIMESTAMP:
oss << DataConvert::timestampToString(v, current_thd->variables.time_zone->get_name()->ptr());
break;
case CalpontSystemCatalog::TIME:
oss << DataConvert::timeToString(v);
@@ -326,7 +334,7 @@ const int64_t IDB_format(char* str, CalpontSystemCatalog::ColType& ct, uint8_t&
int64_t v = 0;
bool pushWarning = false;
rf = 0;
boost::any anyVal = DataConvert::convertColumnData(ct, str, pushWarning, false, true);
boost::any anyVal = DataConvert::convertColumnData(ct, str, pushWarning, current_thd->variables.time_zone->get_name()->ptr(), false, true, false);
switch (ct.colDataType)
{
@@ -393,6 +401,7 @@ const int64_t IDB_format(char* str, CalpontSystemCatalog::ColType& ct, uint8_t&
v = boost::any_cast<uint32_t>(anyVal);
break;
case CalpontSystemCatalog::TIMESTAMP:
case CalpontSystemCatalog::DATETIME:
v = boost::any_cast<uint64_t>(anyVal);
break;

View File

@@ -44,7 +44,7 @@ using namespace execplan;
namespace cal_impl_if
{
void derivedTableOptimization(SCSEP& csep)
void derivedTableOptimization(THD* thd, SCSEP& csep)
{
// @bug5634. replace the unused column with ConstantColumn from derived table column list,
// ExeMgr will not project ConstantColumn. Only count for local derived column.
@@ -102,9 +102,13 @@ void derivedTableOptimization(SCSEP& csep)
cols[i]->derivedRefCol()->decRefCount();
cols[i].reset(new ConstantColumn(val));
(dynamic_cast<ConstantColumn*>(cols[i].get()))->timeZone(thd->variables.time_zone->get_name()->ptr());
for (uint j = 0; j < unionColVec.size(); j++)
{
unionColVec[j][i].reset(new ConstantColumn(val));
(dynamic_cast<ConstantColumn*>(unionColVec[j][i].get()))->timeZone(thd->variables.time_zone->get_name()->ptr());
}
}
}
@@ -136,7 +140,7 @@ void derivedTableOptimization(SCSEP& csep)
if (horizontalOptimization && pt)
{
pt->walk(setDerivedTable);
setDerivedFilter(pt, derivedTbFilterMap, derivedTbList);
setDerivedFilter(thd, pt, derivedTbFilterMap, derivedTbList);
csep->filters(pt);
}
@@ -208,7 +212,7 @@ void derivedTableOptimization(SCSEP& csep)
for (uint i = 0; i < csep->subSelectList().size(); i++)
{
SCSEP subselect(boost::dynamic_pointer_cast<CalpontSelectExecutionPlan>(csep->subSelectList()[i]));
derivedTableOptimization(subselect);
derivedTableOptimization(thd, subselect);
}
}
@@ -246,7 +250,8 @@ void setDerivedTable(execplan::ParseTree* n)
}
}
ParseTree* setDerivedFilter(ParseTree*& n, map<string, ParseTree*>& filterMap,
ParseTree* setDerivedFilter(THD* thd, ParseTree*& n,
map<string, ParseTree*>& filterMap,
CalpontSelectExecutionPlan::SelectList& derivedTbList)
{
if (!(n->derivedTable().empty()))
@@ -288,6 +293,7 @@ ParseTree* setDerivedFilter(ParseTree*& n, map<string, ParseTree*>& filterMap,
int64_t val = 1;
n = new ParseTree(new ConstantColumn(val));
(dynamic_cast<ConstantColumn*>(n->data()))->timeZone(thd->variables.time_zone->get_name()->ptr());
}
else
{
@@ -303,10 +309,10 @@ ParseTree* setDerivedFilter(ParseTree*& n, map<string, ParseTree*>& filterMap,
ParseTree* rhs = n->right();
if (lhs)
n->left(setDerivedFilter(lhs, filterMap, derivedTbList));
n->left(setDerivedFilter(thd, lhs, filterMap, derivedTbList));
if (rhs)
n->right(setDerivedFilter(rhs, filterMap, derivedTbList));
n->right(setDerivedFilter(thd, rhs, filterMap, derivedTbList));
}
}

View File

@@ -503,6 +503,7 @@ execplan::ReturnedColumn* buildPseudoColumn(Item* item,
cc = new ConstantColumn(localPm);
else
cc = new ConstantColumn("", ConstantColumn::NULLDATA);
cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
cc->alias(ifp->full_name() ? ifp->full_name() : "");
return cc;
@@ -566,6 +567,7 @@ execplan::ReturnedColumn* buildPseudoColumn(Item* item,
parms.push_back(sptp);
fc->functionParms(parms);
fc->expressionId(ci->expressionId++);
fc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
// string result type
CalpontSystemCatalog::ColType ct;

View File

@@ -106,6 +106,7 @@ execplan::ParseTree* ScalarSub::transform()
{
fSub = (Item_subselect*)(fFunc->arguments()[0]);
fColumn.reset(new ConstantColumn("", ConstantColumn::NULLDATA));
(dynamic_cast<ConstantColumn*>(fColumn.get()))->timeZone(fGwip.thd->variables.time_zone->get_name()->ptr());
delete rhs;
return buildParseTree(op);
}
@@ -171,6 +172,7 @@ execplan::ParseTree* ScalarSub::transform_between()
SOP sop;
sop.reset(op_LE);
rhs = new ParseTree(new SimpleFilter(sop, fColumn.get(), op3));
(dynamic_cast<SimpleFilter*>(rhs->data()))->timeZone(fGwip.thd->variables.time_zone->get_name()->ptr());
}
SubSelect* sub1 = dynamic_cast<SubSelect*>(op2);
@@ -186,6 +188,7 @@ execplan::ParseTree* ScalarSub::transform_between()
SOP sop;
sop.reset(op_GE);
lhs = new ParseTree(new SimpleFilter(sop, fColumn.get(), op2));
(dynamic_cast<SimpleFilter*>(lhs->data()))->timeZone(fGwip.thd->variables.time_zone->get_name()->ptr());
}
if (!rhs || !lhs)

View File

@@ -144,22 +144,25 @@ ReturnedColumn* buildBoundExp(WF_Boundary& bound, SRCP& order, gp_walk_info& gwi
// put interval val column to bound
(dynamic_cast<FunctionColumn*>(rc))->functionName(funcName);
(dynamic_cast<FunctionColumn*>(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
sptp.reset(new ParseTree(order->clone()));
funcParms.push_back(sptp);
sptp.reset(new ParseTree(intervalCol->val()->clone()));
funcParms.push_back(sptp);
funcParms.push_back(getIntervalType(intervalCol->intervalType()));
funcParms.push_back(getIntervalType(gwi.thd, intervalCol->intervalType()));
SRCP srcp(intervalCol->val());
bound.fVal = srcp;
if (addOp)
{
sptp.reset(new ParseTree(new ConstantColumn("ADD")));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(sptp);
}
else
{
sptp.reset(new ParseTree(new ConstantColumn("SUB")));
(dynamic_cast<ConstantColumn*>(sptp->data()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(sptp);
}
@@ -181,6 +184,7 @@ ReturnedColumn* buildBoundExp(WF_Boundary& bound, SRCP& order, gp_walk_info& gwi
else
aop = new ArithmeticOperator("-");
aop->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
ParseTree* pt = new ParseTree(aop);
ParseTree* lhs = 0, *rhs = 0;
lhs = new ParseTree(order->clone());
@@ -348,6 +352,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n
Item_sum* item_sum = wf->window_func();
string funcName = ConvertFuncName(item_sum);
WindowFunctionColumn* ac = new WindowFunctionColumn(funcName);
ac->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
ac->distinct(item_sum->has_with_distinct());
Window_spec* win_spec = wf->window_spec;
SRCP srcp;
@@ -441,33 +446,42 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n
char sRespectNulls[18];
sprintf(sRespectNulls, "%lu", bRespectNulls);
srcp.reset(new ConstantColumn(sRespectNulls, (uint64_t)bRespectNulls, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
break;
}
case Item_sum::FIRST_VALUE_FUNC:
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // OFFSET (always one)
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // FROM_FIRST
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
break;
case Item_sum::LAST_VALUE_FUNC:
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // OFFSET (always one)
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
srcp.reset(new ConstantColumn("0", (uint64_t)0, ConstantColumn::NUM)); // FROM_LAST
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
break;
case Item_sum::NTH_VALUE_FUNC:
// When the front end supports these paramters, this needs modification
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // FROM FIRST/LAST 1 => FIRST
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
break;
@@ -475,8 +489,10 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n
case Item_sum::LAG_FUNC:
// When the front end supports these paramters, this needs modification
srcp.reset(new ConstantColumn("", ConstantColumn::NULLDATA)); // Default to fill in for NULL values
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
funcParms.push_back(srcp);
break;
@@ -622,6 +638,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::TIME:
case CalpontSystemCatalog::TIMESTAMP:
if (!frm.fIsRange)
boundTypeErr = true;
else if (dynamic_cast<IntervalColumn*>(frm.fStart.fVal.get()) == NULL)
@@ -674,6 +691,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::TIME:
case CalpontSystemCatalog::TIMESTAMP:
if (!frm.fIsRange)
boundTypeErr = true;
else if (dynamic_cast<IntervalColumn*>(frm.fEnd.fVal.get()) == NULL)
@@ -826,6 +844,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n
bound = 1;
srcp.reset(new ConstantColumn((int64_t)bound));
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
frm.fStart.fVal = srcp;
frm.fStart.fBound.reset(buildBoundExp(frm.fStart, srcp, gwi));
@@ -841,6 +860,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n
bound = 1;
srcp.reset(new ConstantColumn((int64_t)bound));
(dynamic_cast<ConstantColumn*>(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
frm.fEnd.fVal = srcp;
frm.fEnd.fBound.reset(buildBoundExp(frm.fEnd, srcp, gwi));

View File

@@ -69,6 +69,7 @@ template <class T> bool isnan(T);
#include "mysqld_error.h"
#include "item_windowfunc.h"
#include "sql_cte.h"
#include "tztime.h"
// Now clean up the pollution as best we can...
#undef min