diff --git a/dbcon/execplan/execplan.vpj b/dbcon/execplan/execplan.vpj index 956fe3dac..6f964bc80 100644 --- a/dbcon/execplan/execplan.vpj +++ b/dbcon/execplan/execplan.vpj @@ -1,326 +1,302 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Version="10.0" + VendorName="SlickEdit" + TemplateName="GNU C/C++" + WorkingDir="."> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dbcon/execplan/windowfunctioncolumn.h b/dbcon/execplan/windowfunctioncolumn.h index d8b9fec75..477660b2f 100644 --- a/dbcon/execplan/windowfunctioncolumn.h +++ b/dbcon/execplan/windowfunctioncolumn.h @@ -41,7 +41,7 @@ class ByteStream; */ namespace execplan { -// This enum is made consistant with mysql item_func_window +// This enum is made consistant with mysql Item_window_func enum WF_FRAME { WF_PRECEDING = 0, diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 85fe0b45f..93499aa4d 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -21,7 +21,7 @@ */ /** @file */ -//#define DEBUG_WALK_COND +#define DEBUG_WALK_COND #include #include #include @@ -38,7 +38,6 @@ #include #include #include -//#define NDEBUG #include #include #include @@ -699,13 +698,11 @@ void debug_walk(const Item *item, void *arg) cout << ": " << endl; break; } -#if 0 case Item::WINDOW_FUNC_ITEM: { cout << "Window Function Item" << endl; break; } -#endif default: { cout << "UNKNOWN_ITEM type " << item->type() << endl; @@ -2464,11 +2461,11 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp rc = new ConstantColumn(valStr); break; } -#if 0 case Item::WINDOW_FUNC_ITEM: { return buildWindowFunctionColumn(item, gwi, nonSupport); } +#if INTERVAL_ITEM case Item::INTERVAL_ITEM: { Item_interval* interval = (Item_interval*)item; @@ -2481,7 +2478,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp rc->resultType(srcp->resultType()); break; } -#endif +#endif case Item::SUBSELECT_ITEM: { gwi.hasSubSelect = true; @@ -4437,17 +4434,15 @@ void gp_walk(const Item *item, void *arg) gwip->rcWorkStack.push(buildReturnedColumn(itp, *gwip, gwip->fatalParseError)); break; } -#if 0 case Item::WINDOW_FUNC_ITEM: { gwip->hasWindowFunc = true; - Item_func_window* ifa = (Item_func_window*)item; + Item_window_func* ifa = (Item_window_func*)item; ReturnedColumn* af = buildWindowFunctionColumn(ifa, *gwip, gwip->fatalParseError); if (af) gwip->rcWorkStack.push(af); break; } -#endif case Item::COPY_STR_ITEM: printf("********** received COPY_STR_ITEM *********\n"); break; @@ -4631,11 +4626,9 @@ void parse_item (Item *item, vector& field_vec, bool& hasNonSupport setError(item->thd(), ER_CHECK_NOT_IMPLEMENTED, parseErrorText); break; } -#if 0 case Item::WINDOW_FUNC_ITEM: parseInfo |= AF_BIT; break; -#endif default: break; } @@ -5525,7 +5518,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); return ER_CHECK_NOT_IMPLEMENTED; } -#if 0 case Item::WINDOW_FUNC_ITEM: { SRCP srcp(buildWindowFunctionColumn(item, gwi, gwi.fatalParseError)); @@ -5539,7 +5531,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i gwi.returnedCols.push_back(srcp); break; } -#endif default: { break; @@ -5692,7 +5683,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i // check if window functions are in order by. InfiniDB process order by list if // window functions are involved, either in order by or projection. -#if 0 bool hasWindowFunc = gwi.hasWindowFunc; gwi.hasWindowFunc = false; for (; groupcol; groupcol= groupcol->next) @@ -5708,7 +5698,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i return ER_CHECK_NOT_IMPLEMENTED; } gwi.hasWindowFunc = hasWindowFunc; -#endif groupcol = reinterpret_cast(select_lex.group_list.first); for (; groupcol; groupcol= groupcol->next) @@ -5954,13 +5943,11 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i // check if window functions are in order by. InfiniDB process order by list if // window functions are involved, either in order by or projection. -#if 0 for (; ordercol; ordercol= ordercol->next) { if ((*(ordercol->item))->type() == Item::WINDOW_FUNC_ITEM) gwi.hasWindowFunc = true; } -#endif // re-visit the first of ordercol list ordercol = reinterpret_cast(order_list.first); diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 3d5f1e381..93ce00949 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -3017,7 +3017,7 @@ int ha_calpont_impl_rnd_next(uchar *buf, TABLE* table) rc = fetchNextRow(buf, ti, ci); } catch (std::exception& e) { - string emsg = string("Lost connection to ExeMgr while fetching: ") + e.what(); + string emsg = string("Error while fetching from ExeMgr: ") + e.what(); setError(thd, ER_INTERNAL_ERROR, emsg); CalpontSystemCatalog::removeCalpontSystemCatalog(tid2sid(thd->thread_id)); return ER_INTERNAL_ERROR; diff --git a/dbcon/mysql/ha_window_function.cpp b/dbcon/mysql/ha_window_function.cpp index 4106329da..33e58fff2 100755 --- a/dbcon/mysql/ha_window_function.cpp +++ b/dbcon/mysql/ha_window_function.cpp @@ -63,26 +63,26 @@ ReturnedColumn* nullOnError(gp_walk_info& gwi) return NULL; } -#if 0 -WF_FRAME frame(BOUND& bound) +WF_FRAME frame(Window_frame_bound::Bound_precedence_type bound, Item* offset) { switch (bound) { - case PRECEDING: - return WF_PRECEDING; - case FOLLOWING: - return WF_FOLLOWING; - case UNBOUNDED_PRECEDING: - return WF_UNBOUNDED_PRECEDING; - case UNBOUNDED_FOLLOWING: - return WF_UNBOUNDED_FOLLOWING; - case CURRENT_ROW: + case Window_frame_bound::PRECEDING: + if (offset) + return WF_PRECEDING; + else + return WF_UNBOUNDED_PRECEDING; + case Window_frame_bound::FOLLOWING: + if (offset) + return WF_FOLLOWING; + else + return WF_UNBOUNDED_FOLLOWING; + case Window_frame_bound::CURRENT: // Offset is meaningless return WF_CURRENT_ROW; default: return WF_UNKNOWN; } } -#endif ReturnedColumn* buildBoundExp(WF_Boundary& bound, SRCP& order, gp_walk_info& gwi) { if (!(gwi.thd->infinidb_vtable.cal_conn_info)) @@ -178,6 +178,96 @@ ReturnedColumn* buildBoundExp(WF_Boundary& bound, SRCP& order, gp_walk_info& gwi return rc; } +// Since columnstore implemented Windows Functions before MariaDB, we need +// map from the enum MariaDB uses to the string that columnstore uses to +// identify the function type. +string ConvertFuncName(Item_sum* item) +{ + switch (item->sum_func()) + { + case Item_sum::COUNT_FUNC: + if (!item->arguments()[0]->name) + return "COUNT(*)"; + return "COUNT"; + break; + case Item_sum::COUNT_DISTINCT_FUNC: + return "COUNT_DISTINCT"; + break; + case Item_sum::SUM_FUNC: + return "SUM"; + break; + case Item_sum::SUM_DISTINCT_FUNC: + return "SUM_DISTINCT"; + break; + case Item_sum::AVG_FUNC: + return "AVG"; + break; + case Item_sum::AVG_DISTINCT_FUNC: + return "AVG_DISTINCT"; + break; + case Item_sum::MIN_FUNC: + return "MIN"; + break; + case Item_sum::MAX_FUNC: + return "MAX"; + break; + case Item_sum::STD_FUNC: + return "STDDEV_POP"; + break; + case Item_sum::VARIANCE_FUNC: + return "VAR_POP"; + break; + case Item_sum::SUM_BIT_FUNC: + if (strcmp(item->func_name(), "bit_or(") == 0) + return "BIT_OR"; + if (strcmp(item->func_name(), "bit_and(") == 0) + return "BIT_AND"; + if (strcmp(item->func_name(), "bit_xor(") == 0) + return "BIT_XOR"; + break; + case Item_sum::UDF_SUM_FUNC: + return "UDF_SUM_FUNC"; // Not supported + break; + case Item_sum::GROUP_CONCAT_FUNC: + return "GROUP_CONCAT"; // Not supported + break; + case Item_sum::ROW_NUMBER_FUNC: + return "ROW_NUMBER"; + break; + case Item_sum::RANK_FUNC: + return "RANK"; + break; + case Item_sum::DENSE_RANK_FUNC: + return "DENSE_RANK"; + break; + case Item_sum::PERCENT_RANK_FUNC: + return "PERCENT_RANK"; + break; + case Item_sum::CUME_DIST_FUNC: + return "CUME_DIST"; + break; + case Item_sum::NTILE_FUNC: + return "NTILE"; + break; + case Item_sum::FIRST_VALUE_FUNC: + return "FIRST_VALUE"; + break; + case Item_sum::LAST_VALUE_FUNC: + return "LAST_VALUE"; + break; + case Item_sum::NTH_VALUE_FUNC: + return "NTH_VALUE"; + break; + case Item_sum::LEAD_FUNC: + return "LEAD"; + break; + case Item_sum::LAG_FUNC: + return "LAG"; + break; + }; + return ""; +} + ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& nonSupport) { //@todo fix print for create view @@ -186,37 +276,82 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n //cout << str.c_ptr() << endl; if (!(gwi.thd->infinidb_vtable.cal_conn_info)) gwi.thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info()); -// cal_connection_info* ci = reinterpret_cast(gwi.thd->infinidb_vtable.cal_conn_info); + cal_connection_info* ci = reinterpret_cast(gwi.thd->infinidb_vtable.cal_conn_info); gwi.hasWindowFunc = true; -// Item_func_window* wf = (Item_func_window*)item; - string funcName /*= wf->func_name()*/; + Item_window_func* wf = (Item_window_func*)item; + string funcName = ConvertFuncName(wf->window_func()); WindowFunctionColumn* ac = new WindowFunctionColumn(funcName); -// ac->distinct(wf->isDistinct()); -// Window_context *wf_ctx = wf->window_ctx(); + ac->distinct(wf->window_func()->has_with_distinct()); + Window_spec *win_spec = wf->window_spec; SRCP srcp; -#if 0 + // arguments + vector funcParms; + Item_sum* item_sum = (Item_sum*)wf->arguments()[0]; + for (uint32_t i = 0; i < item_sum->argument_count(); i++) + { + srcp.reset(buildReturnedColumn((item_sum->arguments()[i]), gwi, nonSupport)); + if (!srcp) + return nullOnError(gwi); + funcParms.push_back(srcp); + if (gwi.clauseType == WHERE && !gwi.rcWorkStack.empty()) + gwi.rcWorkStack.pop(); + } + // Some functions, such as LEAD/LAG don't have all parameters implemented in the + // front end. Add dummies here to make the backend use defaults. + // Some of these will be temporary until they are implemented in the front end. + // Others need to stay because the back end expects them, but the front end + // no longer sends them. + // This case is kept in enum order in hopes the compiler can optimize + switch (wf->window_func()->sum_func()) + { + case Item_sum::COUNT_FUNC: + case Item_sum::COUNT_DISTINCT_FUNC: + break; + case Item_sum::FIRST_VALUE_FUNC: + srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // OFFSET (always one) + funcParms.push_back(srcp); + srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // FROM_FIRST + funcParms.push_back(srcp); + srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT + funcParms.push_back(srcp); + break; + case Item_sum::LAST_VALUE_FUNC: + srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // OFFSET (always one) + funcParms.push_back(srcp); + srcp.reset(new ConstantColumn("0", (uint64_t)0, ConstantColumn::NUM)); // FROM_LAST + funcParms.push_back(srcp); + srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT + 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 + funcParms.push_back(srcp); + srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT + funcParms.push_back(srcp); + break; + case Item_sum::LEAD_FUNC: + 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 + funcParms.push_back(srcp); + srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT + funcParms.push_back(srcp); + break; + default: + break; + }; - // arguments - vector funcParms; - for (uint32_t i = 0; i < wf->argument_count(); i++) - { - srcp.reset(buildReturnedColumn(wf->arguments()[i], gwi, nonSupport)); - if (!srcp) - return nullOnError(gwi); - funcParms.push_back(srcp); - if (gwi.clauseType == WHERE && !gwi.rcWorkStack.empty()) - gwi.rcWorkStack.pop(); - } - ac->functionParms(funcParms); + ac->functionParms(funcParms); // Partition by - if (wf_ctx) + if (win_spec) { vector partitions; - for (uint32_t i = 0; i < wf_ctx->partition_count; i++) + for (ORDER *ord= win_spec->partition_list->first; ord; ord=ord->next) { - srcp.reset(buildReturnedColumn(wf_ctx->partitions[i], gwi, nonSupport)); + srcp.reset(buildReturnedColumn(*ord->item, gwi, nonSupport)); if (!srcp) return nullOnError(gwi); partitions.push_back(srcp); @@ -224,40 +359,42 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n ac->partitions(partitions); // Order by - if (wf_ctx->ordering) + if (win_spec->order_list) { WF_OrderBy orderBy; // order columns - if (wf_ctx->ordering->orders) + if (win_spec->order_list) { vector orders; - ORDER* orderCol = reinterpret_cast(wf_ctx->ordering->orders->first); + ORDER* orderCol = reinterpret_cast(win_spec->order_list->first); for (; orderCol; orderCol= orderCol->next) { Item* orderItem = *(orderCol->item); srcp.reset(buildReturnedColumn(orderItem, gwi, nonSupport)); if (!srcp) return nullOnError(gwi); - srcp->asc(orderCol->asc); - srcp->nullsFirst(orderCol->nulls); // nulls 1-nulls first 0-nulls last - orders.push_back(srcp); + srcp->asc(orderCol->direction == ORDER::ORDER_ASC ? true : false); +// srcp->nullsFirst(orderCol->nulls); // nulls 2-default, 1-nulls first, 0-nulls last + srcp->nullsFirst(1); // WINDOWS TODO: implement NULLS FIRST/LAST in 10.2 front end + orders.push_back(srcp); } orderBy.fOrders = orders; } // window frame WF_Frame frm; - if (wf_ctx->ordering->frame) + if (win_spec->window_frame) { - frm.fIsRange = wf_ctx->ordering->frame->isRange; + frm.fIsRange = win_spec->window_frame->units == Window_frame::UNITS_RANGE; // start - if (wf_ctx->ordering->frame->start) + if (win_spec->window_frame->top_bound) { - frm.fStart.fFrame = frame(wf_ctx->ordering->frame->start->bound); + frm.fStart.fFrame = frame(win_spec->window_frame->top_bound->precedence_type, + win_spec->window_frame->top_bound->offset); // offset NULL means UNBOUNDED - if (wf_ctx->ordering->frame->start->item) + if (win_spec->window_frame->top_bound->offset) { - frm.fStart.fVal.reset(buildReturnedColumn(wf_ctx->ordering->frame->start->item, gwi, nonSupport)); + frm.fStart.fVal.reset(buildReturnedColumn(win_spec->window_frame->top_bound->offset, gwi, nonSupport)); if (!frm.fStart.fVal) return nullOnError(gwi); @@ -295,12 +432,13 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n } // end - if (wf_ctx->ordering->frame->end) + if (win_spec->window_frame->bottom_bound) { - frm.fEnd.fFrame = frame(wf_ctx->ordering->frame->end->bound); - if (wf_ctx->ordering->frame->end->item) + frm.fEnd.fFrame = frame(win_spec->window_frame->bottom_bound->precedence_type, + win_spec->window_frame->bottom_bound->offset); + if (win_spec->window_frame->bottom_bound->offset) { - frm.fEnd.fVal.reset(buildReturnedColumn(wf_ctx->ordering->frame->end->item, gwi, nonSupport)); + frm.fEnd.fVal.reset(buildReturnedColumn(win_spec->window_frame->bottom_bound->offset, gwi, nonSupport)); if (!frm.fEnd.fVal) return nullOnError(gwi); @@ -409,8 +547,57 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n } else { - frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; - frm.fEnd.fFrame = WF_CURRENT_ROW; + // Certain function types have different default boundaries + // This case is kept in enum order in hopes the compiler can optimize + switch (wf->window_func()->sum_func()) + { + case Item_sum::COUNT_FUNC: + case Item_sum::COUNT_DISTINCT_FUNC: + case Item_sum::SUM_FUNC: + case Item_sum::SUM_DISTINCT_FUNC: + case Item_sum::AVG_FUNC: + case Item_sum::AVG_DISTINCT_FUNC: + case Item_sum::MIN_FUNC: + case Item_sum::MAX_FUNC: + case Item_sum::STD_FUNC: + case Item_sum::VARIANCE_FUNC: + case Item_sum::SUM_BIT_FUNC: + case Item_sum::UDF_SUM_FUNC: + case Item_sum::GROUP_CONCAT_FUNC: + frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; + frm.fEnd.fFrame = WF_CURRENT_ROW; + break; + case Item_sum::ROW_NUMBER_FUNC: + case Item_sum::RANK_FUNC: + frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; + frm.fEnd.fFrame = WF_UNBOUNDED_FOLLOWING; + break; + case Item_sum::DENSE_RANK_FUNC: + case Item_sum::PERCENT_RANK_FUNC: + case Item_sum::CUME_DIST_FUNC: + frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; + frm.fEnd.fFrame = WF_CURRENT_ROW; + break; + case Item_sum::NTILE_FUNC: + frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; + frm.fEnd.fFrame = WF_UNBOUNDED_FOLLOWING; + break; + case Item_sum::FIRST_VALUE_FUNC: + case Item_sum::LAST_VALUE_FUNC: + case Item_sum::NTH_VALUE_FUNC: + frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; + frm.fEnd.fFrame = WF_CURRENT_ROW; + break; + case Item_sum::LEAD_FUNC: + case Item_sum::LAG_FUNC: + frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; + frm.fEnd.fFrame = WF_UNBOUNDED_FOLLOWING; + break; + default: + frm.fStart.fFrame = WF_UNBOUNDED_PRECEDING; + frm.fEnd.fFrame = WF_CURRENT_ROW; + break; + }; } orderBy.fFrame = frm; @@ -426,8 +613,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n return NULL; } - ac->resultType(colType_MysqlToIDB(wf)); - + ac->resultType(colType_MysqlToIDB(wf->arguments()[0])); // bug5736. Make the result type double for some window functions when // infinidb_double_for_decimal_math is set. ac->adjustResultType(); @@ -438,7 +624,6 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n // put ac on windowFuncList gwi.windowFuncList.push_back(ac); -#endif return ac; } diff --git a/dbcon/mysql/idb_mysql.h b/dbcon/mysql/idb_mysql.h index f8eb5d5c0..670f0e0e0 100644 --- a/dbcon/mysql/idb_mysql.h +++ b/dbcon/mysql/idb_mysql.h @@ -65,6 +65,7 @@ template bool isnan(T); #include "sql_table.h" #include "sql_select.h" +#include "item_windowfunc.h" // Now clean up the pollution as best we can... #undef min diff --git a/utils/windowfunction/wf_lead_lag.cpp b/utils/windowfunction/wf_lead_lag.cpp index 1ab9818f3..8d3b6169b 100644 --- a/utils/windowfunction/wf_lead_lag.cpp +++ b/utils/windowfunction/wf_lead_lag.cpp @@ -121,6 +121,11 @@ void WF_lead_lag::parseParms(const std::vector& parms) { // lead | lag fLead = 1; + fRespectNulls = true; + fDefNull = false; + fDefault = (T)0; + fOffsetNull = false; + fOffset = 0; if (fFunctionId == WF__LAG) fLead = -1; @@ -148,6 +153,32 @@ void WF_lead_lag::parseParms(const std::vector& parms) idbassert(cc != NULL); bool isNull = false; // dummy, harded coded fRespectNulls = (cc->getIntVal(fRow, isNull) > 0); +#if 0 + // parms[1]: offset + for (std::vector::size_type i = 1/*ignore 0th element*/; i < parms.size(); ++i) + { + ConstantColumn* cc = dynamic_cast(parms[i].get()); + if (cc != NULL) + { + fOffset = cc->getIntVal(fRow, fOffsetNull) * fLead; // row not used, no need to setData. + continue; + } + + cc = dynamic_cast(parms[i].get()); + if (cc != NULL) + { + getConstValue(cc, fDefault, fDefNull); + continue; + } + // IGNORE/RESPECT nulls is currently broken in the front end + cc = dynamic_cast(parms[i].get()); + if (cc != NULL) + { + bool isNull = false; // dummy, harded coded + fRespectNulls = (cc->getIntVal(fRow, isNull) > 0); + } + } +#endif }