diff --git a/dbcon/mysql/ha_calpont.cpp b/dbcon/mysql/ha_calpont.cpp index 55532921a..7db4f0e26 100755 --- a/dbcon/mysql/ha_calpont.cpp +++ b/dbcon/mysql/ha_calpont.cpp @@ -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); } -ha_calpont::ha_calpont(handlerton *hton, TABLE_SHARE *table_arg) - :handler(hton, table_arg) +ha_calpont::ha_calpont(handlerton *hton, TABLE_SHARE *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; } - /** @brief 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 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) { DBUG_ENTER("ha_calpont::position"); diff --git a/dbcon/mysql/ha_calpont.h b/dbcon/mysql/ha_calpont.h index 0b1c9dd8a..5db3e07cb 100755 --- a/dbcon/mysql/ha_calpont.h +++ b/dbcon/mysql/ha_calpont.h @@ -57,6 +57,7 @@ class ha_calpont: public handler { THR_LOCK_DATA lock; ///< MySQL lock INFINIDB_SHARE *share; ///< Shared lock info + ulonglong int_table_flags; public: ha_calpont(handlerton *hton, TABLE_SHARE *table_arg); @@ -67,7 +68,7 @@ public: /** @brief The name that will be used for display purposes. */ - const char *table_type() const { return "InfiniDB"; } + const char *table_type() const { return "ColumnStore"; } /** @brief 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 implements. The current table flags are documented in handler.h */ - ulonglong table_flags() const - { - /* - 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; - } + ulonglong table_flags() const {return int_table_flags;} /** @brief 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 index, up to and including 'part'. */ - ulong index_flags(uint32_t inx, uint32_t part, bool all_parts) const - { - return 0; - } + ulong index_flags(uint32_t inx, uint32_t part, bool all_parts) const {return 0;} + /** @brief 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; } - /** @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 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; } - /** @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. Most of these methods are not obligatory, skip them and MySQL will treat them as not implemented */ + /** @brief We implement this in ha_example.cc; it's a required method. */ diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 4f46399bb..65a3bd949 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -540,13 +540,43 @@ void debug_walk(const Item *item, void *arg) case 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; - break; + case STRING_RESULT: + 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); - cout << "CACHE_ITEM: >" << str->c_ptr() << '<' << endl; + if (str) + cout << ": (" << str->c_ptr() << ')' << endl; + else + cout << ": " << 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; } 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; break; } + case Item::DATE_ITEM: + { + String val, *str = item->val_str(&val); + rc = new ConstantColumn(str->c_ptr()); + break; + } case Item::WINDOW_FUNC_ITEM: { return buildWindowFunctionColumn(item, gwi, nonSupport); @@ -3905,7 +3941,7 @@ void gp_walk(const Item *item, void *arg) else gwip->rcWorkStack.push(cc); if (str) - IDEBUG( cout << "Const F&E " << item->name? item->name : "" << " evaluate: " << str->ptr() << endl ); + IDEBUG( cout << "Const F&E " << item->full_name() << " evaluate: " << str->c_ptr() << endl ); 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); 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: { gwip->hasWindowFunc = true; @@ -4198,46 +4240,43 @@ void gp_walk(const Item *item, void *arg) break; } case Item::COPY_STR_ITEM: - printf("********** received COPY_STR_ITEM *********"); + printf("********** received COPY_STR_ITEM *********\n"); break; case Item::FIELD_AVG_ITEM: - printf("********** received FIELD_AVG_ITEM *********"); + printf("********** received FIELD_AVG_ITEM *********\n"); break; case Item::DEFAULT_VALUE_ITEM: - printf("********** received DEFAULT_VALUE_ITEM *********"); + printf("********** received DEFAULT_VALUE_ITEM *********\n"); break; case Item::PROC_ITEM: - printf("********** received PROC_ITEM *********"); + printf("********** received PROC_ITEM *********\n"); break; case Item::FIELD_STD_ITEM: - printf("********** received FIELD_STD_ITEM *********"); + printf("********** received FIELD_STD_ITEM *********\n"); break; case Item::FIELD_VARIANCE_ITEM: - printf("********** received FIELD_VARIANCE_ITEM *********"); + printf("********** received FIELD_VARIANCE_ITEM *********\n"); break; case Item::INSERT_VALUE_ITEM: - printf("********** received INSERT_VALUE_ITEM *********"); + printf("********** received INSERT_VALUE_ITEM *********\n"); break; case Item::Item::TYPE_HOLDER: - printf("********** received TYPE_HOLDER *********"); + printf("********** received TYPE_HOLDER *********\n"); break; case Item::PARAM_ITEM: - printf("********** received PARAM_ITEM *********"); + printf("********** received PARAM_ITEM *********\n"); break; case Item::TRIGGER_FIELD_ITEM: - printf("********** received TRIGGER_FIELD_ITEM *********"); + printf("********** received TRIGGER_FIELD_ITEM *********\n"); break; case Item::XPATH_NODESET: - printf("********** received XPATH_NODESET *********"); + printf("********** received XPATH_NODESET *********\n"); break; case Item::XPATH_NODESET_CMP: - printf("********** received XPATH_NODESET_CMP *********"); + printf("********** received XPATH_NODESET_CMP *********\n"); break; case Item::VIEW_FIXER_ITEM: - printf("********** received VIEW_FIXER_ITEM *********"); - break; - case Item::DATE_ITEM: - printf("********** received DATE_ITEM *********"); + printf("********** received VIEW_FIXER_ITEM *********\n"); break; default: { diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 9c0cb4f3e..a8e8a97e1 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -2435,7 +2435,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) { if (ci->cal_conn_hndl) { - // send ExeMgr a signal before cloing the connection + // send ExeMgr a signal before closing the connection ByteStream msg; ByteStream::quadbyte qb = 0; 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_MULTI)) 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) 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]; +#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.condInfo) @@ -4180,9 +4190,13 @@ COND* ha_calpont_impl_cond_push(COND *cond, TABLE* table) return cond; } if (gwi->dropCond) + { return cond; + } else + { return NULL; + } } 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. // 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 && thd->infinidb_vtable.vtable_state <= THD::INFINIDB_REDO_QUERY) || thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR);