1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-05-28 13:01:26 +03:00

Fix for date_item and a crash

This commit is contained in:
David Hall 2016-04-26 17:21:35 -05:00
parent 36c09d7c7b
commit a72f053840
4 changed files with 94 additions and 80 deletions

View File

@ -341,8 +341,10 @@ static void calpont_set_error(THD* thd, uint64_t errCode, LEX_STRING* args, uint
return ha_calpont_impl_set_error(thd, errCode, args, argCount); return ha_calpont_impl_set_error(thd, errCode, args, argCount);
} }
ha_calpont::ha_calpont(handlerton *hton, TABLE_SHARE *table_arg) ha_calpont::ha_calpont(handlerton *hton, TABLE_SHARE *table_arg) :
:handler(hton, table_arg) handler(hton, table_arg),
int_table_flags(HA_BINLOG_STMT_CAPABLE | HA_TABLE_SCAN_ON_INDEX | HA_CAN_TABLE_CONDITION_PUSHDOWN)
// int_table_flags(HA_NO_BLOBS | HA_BINLOG_STMT_CAPABLE)
{ {
} }
@ -374,7 +376,6 @@ const char **ha_calpont::bas_ext() const
return ha_calpont_exts; return ha_calpont_exts;
} }
/** /**
@brief @brief
Used for opening tables. The name will be the name of the file. Used for opening tables. The name will be the name of the file.
@ -702,6 +703,12 @@ int ha_calpont::rnd_next(uchar *buf)
@see @see
filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc
*/ */
// @TODO: Implement position() and rnd_pos() and remove HA_NO_BLOBS from table_flags
// This would require us to add a psuedo-column of some sort for a primary index. This
// would only be used in rare cases of ORDER BY, so the slow down would be ok and would
// allow for implementing blobs (is that the same as varbinary?). Perhaps using
// lbid and offset as key would work, or something. We also need to add functionality
// to retrieve records quickly by this "key"
void ha_calpont::position(const uchar *record) void ha_calpont::position(const uchar *record)
{ {
DBUG_ENTER("ha_calpont::position"); DBUG_ENTER("ha_calpont::position");

View File

@ -57,6 +57,7 @@ class ha_calpont: public handler
{ {
THR_LOCK_DATA lock; ///< MySQL lock THR_LOCK_DATA lock; ///< MySQL lock
INFINIDB_SHARE *share; ///< Shared lock info INFINIDB_SHARE *share; ///< Shared lock info
ulonglong int_table_flags;
public: public:
ha_calpont(handlerton *hton, TABLE_SHARE *table_arg); ha_calpont(handlerton *hton, TABLE_SHARE *table_arg);
@ -67,7 +68,7 @@ public:
/** @brief /** @brief
The name that will be used for display purposes. The name that will be used for display purposes.
*/ */
const char *table_type() const { return "InfiniDB"; } const char *table_type() const { return "ColumnStore"; }
/** @brief /** @brief
The name of the index type that will be used for display. The name of the index type that will be used for display.
@ -84,15 +85,7 @@ public:
This is a list of flags that indicate what functionality the storage engine This is a list of flags that indicate what functionality the storage engine
implements. The current table flags are documented in handler.h implements. The current table flags are documented in handler.h
*/ */
ulonglong table_flags() const ulonglong table_flags() const {return int_table_flags;}
{
/*
We are saying that this engine is just row capable to have an
engine that can only handle row-based logging. This is used in
testing.
*/
return HA_BINLOG_STMT_CAPABLE;
}
/** @brief /** @brief
This is a bitmap of flags that indicates how the storage engine This is a bitmap of flags that indicates how the storage engine
@ -104,10 +97,8 @@ public:
If all_parts is set, MySQL wants to know the flags for the combined If all_parts is set, MySQL wants to know the flags for the combined
index, up to and including 'part'. index, up to and including 'part'.
*/ */
ulong index_flags(uint32_t inx, uint32_t part, bool all_parts) const ulong index_flags(uint32_t inx, uint32_t part, bool all_parts) const {return 0;}
{
return 0;
}
/** @brief /** @brief
unireg.cc will call max_supported_record_length(), max_supported_keys(), unireg.cc will call max_supported_record_length(), max_supported_keys(),
@ -118,55 +109,18 @@ public:
*/ */
uint32_t max_supported_record_length() const { return HA_MAX_REC_LENGTH; } uint32_t max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
/** @brief
unireg.cc will call this to make sure that the storage engine can handle
the data it is about to send. Return *real* limits of your storage engine
here; MySQL will do min(your_limits, MySQL_limits) automatically.
@details
There is no need to implement ..._key_... methods if your engine doesn't
support indexes.
*/
uint32_t max_supported_keys() const { return 1; }
/** @brief
unireg.cc will call this to make sure that the storage engine can handle
the data it is about to send. Return *real* limits of your storage engine
here; MySQL will do min(your_limits, MySQL_limits) automatically.
@details
There is no need to implement ..._key_... methods if your engine doesn't
support indexes.
*/
uint32_t max_supported_key_parts() const { return 1; }
/** @brief
unireg.cc will call this to make sure that the storage engine can handle
the data it is about to send. Return *real* limits of your storage engine
here; MySQL will do min(your_limits, MySQL_limits) automatically.
@details
There is no need to implement ..._key_... methods if your engine doesn't
support indexes.
*/
uint32_t max_supported_key_length() const { return 8; }
/** @brief /** @brief
Called in test_quick_select to determine if indexes should be used. Called in test_quick_select to determine if indexes should be used.
*/ */
virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; }
/** @brief
This method will never be called if you do not implement indexes.
*/
virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
/* /*
Everything below are methods that we implement in ha_example.cc. Everything below are methods that we implement in ha_example.cc.
Most of these methods are not obligatory, skip them and Most of these methods are not obligatory, skip them and
MySQL will treat them as not implemented MySQL will treat them as not implemented
*/ */
/** @brief /** @brief
We implement this in ha_example.cc; it's a required method. We implement this in ha_example.cc; it's a required method.
*/ */

View File

@ -540,13 +540,43 @@ void debug_walk(const Item *item, void *arg)
case Item::CACHE_ITEM: case Item::CACHE_ITEM:
{ {
Item_cache* isp = (Item_cache*)item; Item_cache* isp = (Item_cache*)item;
if (item->result_type() == ROW_RESULT) String val, *str = NULL;
switch (item->result_type())
{ {
cout << "CACHE_ROW_ITEM" << endl; case STRING_RESULT:
break; str = isp->val_str(&val);
cout << "CACHE_STRING_ITEM";
break;
case REAL_RESULT:
str = isp->val_str(&val);
cout << "CACHE_REAL_ITEM";
break;
case INT_RESULT:
str = isp->val_str(&val);
cout << "CACHE_INT_ITEM";
break;
case ROW_RESULT:
cout << "CACHE_ROW_ITEM";
break;
case DECIMAL_RESULT:
str = isp->val_str(&val);
cout << "CACHE_DECIMAL_ITEM";
break;
default:
cout << "CACHE_UNKNOWN_ITEM";
break;
} }
String val, *str = isp->val_str(&val); if (str)
cout << "CACHE_ITEM: >" << str->c_ptr() << '<' << endl; cout << ": (" << str->c_ptr() << ')' << endl;
else
cout << ": <NULL>" << endl;
break;
}
case Item::DATE_ITEM:
{
String val;
Item_temporal_literal* itp = (Item_temporal_literal*)item;
cout << "DATE ITEM: " << itp->val_str(&val)->c_ptr() << endl;
break; break;
} }
case Item::WINDOW_FUNC_ITEM: case Item::WINDOW_FUNC_ITEM:
@ -2270,6 +2300,12 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
cout << "EXPR_CACHE_ITEM in buildReturnedColumn" << endl; cout << "EXPR_CACHE_ITEM in buildReturnedColumn" << endl;
break; break;
} }
case Item::DATE_ITEM:
{
String val, *str = item->val_str(&val);
rc = new ConstantColumn(str->c_ptr());
break;
}
case Item::WINDOW_FUNC_ITEM: case Item::WINDOW_FUNC_ITEM:
{ {
return buildWindowFunctionColumn(item, gwi, nonSupport); return buildWindowFunctionColumn(item, gwi, nonSupport);
@ -3905,7 +3941,7 @@ void gp_walk(const Item *item, void *arg)
else else
gwip->rcWorkStack.push(cc); gwip->rcWorkStack.push(cc);
if (str) if (str)
IDEBUG( cout << "Const F&E " << item->name? item->name : "<NULL>" << " evaluate: " << str->ptr() << endl ); IDEBUG( cout << "Const F&E " << item->full_name() << " evaluate: " << str->c_ptr() << endl );
break; break;
} }
@ -4188,6 +4224,12 @@ void gp_walk(const Item *item, void *arg)
((Item_cache_wrapper*)item)->get_orig_item()->traverse_cond(gp_walk, arg, Item::POSTFIX); ((Item_cache_wrapper*)item)->get_orig_item()->traverse_cond(gp_walk, arg, Item::POSTFIX);
break; break;
} }
case Item::DATE_ITEM:
{
Item_temporal_literal* itp = (Item_temporal_literal*)item;
gwip->rcWorkStack.push(buildReturnedColumn(itp, *gwip, gwip->fatalParseError));
break;
}
case Item::WINDOW_FUNC_ITEM: case Item::WINDOW_FUNC_ITEM:
{ {
gwip->hasWindowFunc = true; gwip->hasWindowFunc = true;
@ -4198,46 +4240,43 @@ void gp_walk(const Item *item, void *arg)
break; break;
} }
case Item::COPY_STR_ITEM: case Item::COPY_STR_ITEM:
printf("********** received COPY_STR_ITEM *********"); printf("********** received COPY_STR_ITEM *********\n");
break; break;
case Item::FIELD_AVG_ITEM: case Item::FIELD_AVG_ITEM:
printf("********** received FIELD_AVG_ITEM *********"); printf("********** received FIELD_AVG_ITEM *********\n");
break; break;
case Item::DEFAULT_VALUE_ITEM: case Item::DEFAULT_VALUE_ITEM:
printf("********** received DEFAULT_VALUE_ITEM *********"); printf("********** received DEFAULT_VALUE_ITEM *********\n");
break; break;
case Item::PROC_ITEM: case Item::PROC_ITEM:
printf("********** received PROC_ITEM *********"); printf("********** received PROC_ITEM *********\n");
break; break;
case Item::FIELD_STD_ITEM: case Item::FIELD_STD_ITEM:
printf("********** received FIELD_STD_ITEM *********"); printf("********** received FIELD_STD_ITEM *********\n");
break; break;
case Item::FIELD_VARIANCE_ITEM: case Item::FIELD_VARIANCE_ITEM:
printf("********** received FIELD_VARIANCE_ITEM *********"); printf("********** received FIELD_VARIANCE_ITEM *********\n");
break; break;
case Item::INSERT_VALUE_ITEM: case Item::INSERT_VALUE_ITEM:
printf("********** received INSERT_VALUE_ITEM *********"); printf("********** received INSERT_VALUE_ITEM *********\n");
break; break;
case Item::Item::TYPE_HOLDER: case Item::Item::TYPE_HOLDER:
printf("********** received TYPE_HOLDER *********"); printf("********** received TYPE_HOLDER *********\n");
break; break;
case Item::PARAM_ITEM: case Item::PARAM_ITEM:
printf("********** received PARAM_ITEM *********"); printf("********** received PARAM_ITEM *********\n");
break; break;
case Item::TRIGGER_FIELD_ITEM: case Item::TRIGGER_FIELD_ITEM:
printf("********** received TRIGGER_FIELD_ITEM *********"); printf("********** received TRIGGER_FIELD_ITEM *********\n");
break; break;
case Item::XPATH_NODESET: case Item::XPATH_NODESET:
printf("********** received XPATH_NODESET *********"); printf("********** received XPATH_NODESET *********\n");
break; break;
case Item::XPATH_NODESET_CMP: case Item::XPATH_NODESET_CMP:
printf("********** received XPATH_NODESET_CMP *********"); printf("********** received XPATH_NODESET_CMP *********\n");
break; break;
case Item::VIEW_FIXER_ITEM: case Item::VIEW_FIXER_ITEM:
printf("********** received VIEW_FIXER_ITEM *********"); printf("********** received VIEW_FIXER_ITEM *********\n");
break;
case Item::DATE_ITEM:
printf("********** received DATE_ITEM *********");
break; break;
default: default:
{ {

View File

@ -2435,7 +2435,7 @@ int ha_calpont_impl_rnd_init(TABLE* table)
{ {
if (ci->cal_conn_hndl) if (ci->cal_conn_hndl)
{ {
// send ExeMgr a signal before cloing the connection // send ExeMgr a signal before closing the connection
ByteStream msg; ByteStream msg;
ByteStream::quadbyte qb = 0; ByteStream::quadbyte qb = 0;
msg << qb; msg << qb;
@ -4147,7 +4147,7 @@ COND* ha_calpont_impl_cond_push(COND *cond, TABLE* table)
((thd->lex)->sql_command == SQLCOM_DELETE) || ((thd->lex)->sql_command == SQLCOM_DELETE) ||
((thd->lex)->sql_command == SQLCOM_DELETE_MULTI)) ((thd->lex)->sql_command == SQLCOM_DELETE_MULTI))
return cond; return cond;
IDEBUG( cout << "ha_calpont_impl_cond_push: " << table->alias << endl ); IDEBUG( cout << "ha_calpont_impl_cond_push: " << table->alias.c_ptr() << endl );
if (!thd->infinidb_vtable.cal_conn_info) if (!thd->infinidb_vtable.cal_conn_info)
thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info()); thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info());
@ -4155,6 +4155,16 @@ COND* ha_calpont_impl_cond_push(COND *cond, TABLE* table)
cal_table_info ti = ci->tableMap[table]; cal_table_info ti = ci->tableMap[table];
#ifdef DEBUG_WALK_COND
{
gp_walk_info gwi;
gwi.condPush = true;
gwi.sessionid = tid2sid(thd->thread_id);
cout << "------------------ cond push -----------------------" << endl;
cond->traverse_cond(debug_walk, &gwi, Item::POSTFIX);
cout << "------------------------------------------------\n" << endl;
}
#endif
if (!ti.csep) if (!ti.csep)
{ {
if (!ti.condInfo) if (!ti.condInfo)
@ -4180,9 +4190,13 @@ COND* ha_calpont_impl_cond_push(COND *cond, TABLE* table)
return cond; return cond;
} }
if (gwi->dropCond) if (gwi->dropCond)
{
return cond; return cond;
}
else else
{
return NULL; return NULL;
}
} }
return cond; return cond;
@ -4200,7 +4214,7 @@ int ha_calpont_impl_external_lock(THD *thd, TABLE* table, int lock_type)
// @info called for every table at the beginning and at the end of a query. // @info called for every table at the beginning and at the end of a query.
// used for cleaning up the tableinfo. // used for cleaning up the tableinfo.
IDEBUG( cout << "external_lock for " << table->alias << endl ); IDEBUG( cout << "external_lock for " << table->alias.c_ptr() << endl );
idbassert((thd->infinidb_vtable.vtable_state >= THD::INFINIDB_INIT_CONNECT && idbassert((thd->infinidb_vtable.vtable_state >= THD::INFINIDB_INIT_CONNECT &&
thd->infinidb_vtable.vtable_state <= THD::INFINIDB_REDO_QUERY) || thd->infinidb_vtable.vtable_state <= THD::INFINIDB_REDO_QUERY) ||
thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR); thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR);