void TableView::parseAttr(std::vector<std::string>* keys, std::vector<std::string>* values) { ScrollView::parseAttr(keys, values); for (auto i = 0; i < keys->size(); ++i) { const auto& _key = keys->at(i); const auto& _value = values->at(i); if (_key == "hspacing") { setHSpacing(ParamUtil::readFloat(_value)); } else if (_key == "vspacing") { setVSpacing(ParamUtil::readFloat(_value)); } else if (_key == "cellsize") { setCellSize(ParamUtil::readSize(_value)); } else if (_key == "columncnt" || _key == "column") { setColumnCnt(ParamUtil::readUInt(_value)); } else if (_key == "rowcnt" || _key == "row") { setRowCnt(ParamUtil::readUInt(_value)); } else if (_key == "padding") { setPadding(ParamUtil::readUInt(_value)); } else if (_key == "paddingtop") { setPaddingTop(ParamUtil::readUInt(_value)); } else if (_key == "paddingright") { setPaddingRight(ParamUtil::readUInt(_value)); } else if (_key == "paddingbottom") { setPaddingBottom(ParamUtil::readUInt(_value)); } else if (_key == "paddingleft") { setPaddingLeft(ParamUtil::readUInt(_value)); } } }
/* * The cost will be used in many places to make decisions. * Access should be fast. * The SQL front-end also makes the BAT index available as the * property bid. This can be used to access the BAT and involve * more properties into the decision procedure. * [to be done] * Also make sure you don't re-use variables, because then the * row count becomes non-deterministic. */ int OPTcostModelImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i; BUN c1, c2; InstrPtr p; (void) cntxt; (void) stk; (void) pci; if ( mb->inlineProp ) return 0; for (i = 0; i < mb->stop; i++) { p = getInstrPtr(mb, i); if (getModuleId(p)==algebraRef) { if (getFunctionId(p) == subselectRef || getFunctionId(p) == thetasubselectRef) { newRows(1,2, (c1 > 2 ? c2 / 2 +1: c1/2+1),0); } else if ( getFunctionId(p) == selectNotNilRef || getFunctionId(p) == sortRef || getFunctionId(p) == subsortRef || getFunctionId(p) == projectRef ){ newRows(1,1,c1,0); } else if (getFunctionId(p) == subjoinRef || getFunctionId(p) == projectionRef || getFunctionId(p) == subbandjoinRef || getFunctionId(p) == projectionpathRef ) { /* assume 1-1 joins */ newRows(1,2,(c1 < c2 ? c1 : c2),0); } else if (getFunctionId(p) == crossRef) { newRows(1,2,((log((double) c1) + log((double) c2) > log(INT_MAX) ? INT_MAX : c1 * c2 +1)),0); /* log sets errno if it cannot compute the log. This will then screw with code that checks errno */ if (errno == ERANGE || errno == EDOM) { errno = 0; } } } else if (getModuleId(p) == batcalcRef) { if( getFunctionId(p) == ifthenelseRef) { if( isaBatType(getArgType(mb,p,2) ) ) { newRows(2,2, c1,0); } else { newRows(3,3, c1,0); } } else if( isaBatType(getArgType(mb,p,1)) ){ newRows(1,1, c1,0); } else { newRows(2, 2, c2,0); } } else if (getModuleId(p) == batstrRef) { newRows(1,1, c1,0); } else if (getModuleId(p) == batRef) { if (getFunctionId(p) == appendRef || getFunctionId(p) == insertRef ){ /* * Updates are a little more complicated, because you have to * propagate changes in the expected size up the expression tree. * For example, the SQL snippet: * _49:bat[:oid,:oid]{rows=0,bid=622} := sql.bind_dbat("sys","example",3); * _54 := bat.setWriteMode(_49); * bat.append(_54,_47,true); * shows what is produced when it encounters a deletion. If a non-empty * append is not properly passed back to _49, the emptySet * optimizer might remove the complete deletion code. * The same holds for replacement operations, which add information to * an initially empty insertion BAT. */ if( isaBatType(getArgType(mb,p,2)) ){ /* insert BAT */ newRows(1,2, (c1 + c2+1),1); } else { /* insert scalars */ newRows(1,1, (c1 +1),1); } } else if (getFunctionId(p) == deleteRef){ if( isaBatType(getArgType(mb,p,2)) ){ /* delete BAT */ newRows(1, 2, (c2 >= c1 ? 1 : c1 - c2), 1); } else { /* insert scalars */ newRows(1, 1, (c1 <= 1 ? 1 : c1 - 1), 1); } } else if (getFunctionId(p) == insertRef){ newRows(1,1,( c1 + 1),0); /* faked */ } } else if (getModuleId(p)==groupRef) { if (getFunctionId(p) ==subgroupRef ) { newRows(1,1,( c1 / 10+1),0); } else { newRows(1,1, c1,0); } } else if (getModuleId(p)== aggrRef) { if (getFunctionId(p) == sumRef || getFunctionId(p) == minRef || getFunctionId(p) == maxRef || getFunctionId(p) == avgRef) { newRows(1, 1, (c1 != 0 ? c1 : 1), 0); } else if (getFunctionId(p) == countRef){ newRows(1,1, 1,0); } } else if( p->token == ASSIGNsymbol && p->argc== 2){ /* copy the rows property */ c1 = getRowCnt(mb, getArg(p,1)); /* just to ensure that rowcnt was/is never set to -1 */ assert(c1 != (BUN) -1); if (c1 != BUN_NONE) setRowCnt(mb, getArg(p,0), c1); } } return 1; }
static void SQLgetStatistics(Client cntxt, mvc *m, MalBlkPtr mb) { InstrPtr *old = NULL; int oldtop, i, actions = 0, size = 0; lng clk = GDKusec(); sql_trans *tr = m->session->tr; str msg; old = mb->stmt; oldtop = mb->stop; size = (mb->stop * 1.2 < mb->ssize) ? mb->ssize : (int) (mb->stop * 1.2); mb->stmt = (InstrPtr *) GDKzalloc(size * sizeof(InstrPtr)); mb->ssize = size; mb->stop = 0; for (i = 0; i < oldtop; i++) { InstrPtr p = old[i]; char *f = getFunctionId(p); if (getModuleId(p) == sqlRef && f == tidRef) { char *sname = getVarConstant(mb, getArg(p, 2)).val.sval; char *tname = getVarConstant(mb, getArg(p, 3)).val.sval; sql_schema *s = mvc_bind_schema(m, sname); sql_table *t; if (!s || strcmp(s->base.name, dt_schema) == 0) { pushInstruction(mb, p); continue; } t = mvc_bind_table(m, s, tname); if (t && (!isRemote(t) && !isMergeTable(t)) && t->p) { int mt_member = t->p->base.id; setMitosisPartition(p,mt_member); } } if (getModuleId(p) == sqlRef && (f == bindRef || f == bindidxRef)) { int upd = (p->argc == 7 || p->argc == 9); char *sname = getVarConstant(mb, getArg(p, 2 + upd)).val.sval; char *tname = getVarConstant(mb, getArg(p, 3 + upd)).val.sval; char *cname = NULL; int mt_member = 0; BUN rows = 1; /* default to cope with delta bats */ int mode = 0; int k = getArg(p, 0); sql_schema *s = mvc_bind_schema(m, sname); BAT *b; if (!s || strcmp(s->base.name, dt_schema) == 0) { pushInstruction(mb, p); continue; } cname = getVarConstant(mb, getArg(p, 4 + upd)).val.sval; mode = getVarConstant(mb, getArg(p, 5 + upd)).val.ival; if (s && f == bindidxRef && cname) { size_t cnt; sql_idx *i = mvc_bind_idx(m, s, cname); if (i && (!isRemote(i->t) && !isMergeTable(i->t))) { cnt = store_funcs.count_idx(tr, i, 1); assert(cnt <= (size_t) GDK_oid_max); b = store_funcs.bind_idx(m->session->tr, i, RDONLY); if (b) { cnt = BATcount(b); BBPunfix(b->batCacheid); } rows = (BUN) cnt; if (i->t->p) mt_member = i->t->p->base.id; } } else if (s && f == bindRef && cname) { size_t cnt; sql_table *t = mvc_bind_table(m, s, tname); sql_column *c = mvc_bind_column(m, t, cname); if (c && (!isRemote(c->t) && !isMergeTable(c->t))) { cnt = store_funcs.count_col(tr, c, 1); assert(cnt <= (size_t) GDK_oid_max); b = store_funcs.bind_col(m->session->tr, c, RDONLY); if (b) { cnt = BATcount(b); BBPunfix(b->batCacheid); } rows = (BUN) cnt; if (c->t->p) mt_member = c->t->p->base.id; } } if (rows > 1 && mode != RD_INS) setRowCnt(mb,k,rows); if (mt_member && mode != RD_INS) setMitosisPartition(p,mt_member); pushInstruction(mb, p); } else { pushInstruction(mb, p); } } GDKfree(old); msg = optimizerCheck(cntxt, mb, "optimizer.SQLgetstatistics", actions, GDKusec() - clk); if (msg) /* what to do with an error? */ GDKfree(msg); }