/* * At any point we should be able to construct an ascii representation of * the type descriptor. Including the variable references. */ str getTypeName(malType tpe) { char buf[PATHLENGTH], *s; size_t l = PATHLENGTH; int k; if (tpe == TYPE_any) return GDKstrdup("any"); if (isaBatType(tpe)) { snprintf(buf, l, "bat["); l -= strlen(buf); s = buf + strlen(buf); k = getColumnIndex(tpe); if (k) snprintf(s, l, ":any%c%d]",TMPMARKER, k); else if (getColumnType(tpe) == TYPE_any) snprintf(s, l, ":any]"); else snprintf(s, l, ":%s]", ATOMname(getColumnType(tpe))); return GDKstrdup(buf); } if (isAnyExpression(tpe)) { strncpy(buf, "any", 4); if (isAnyExpression(tpe)) snprintf(buf + 3, PATHLENGTH - 3, "%c%d", TMPMARKER, getColumnIndex(tpe)); return GDKstrdup(buf); } return GDKstrdup(ATOMname(tpe)); }
bool DBDataTable::putDouble(int row, int column, double value) { // LOGD("DBDataTable::putdouble(row=%u, column=%u, value=%lf)", row, column, value); if (row >= m_rowSpList.size() || column >= m_columnCount) { return false; } if (getColumnType(column) != DBDataType_Null && getColumnType(column) != DBDataType_Float) { return false; } if (NULL == m_rowSpList[row]) { m_rowSpList[row] = new DBDataRow(m_columnCount); if (NULL == m_rowSpList[row]) { return false; } } return m_rowSpList[row]->putDouble(column, value); }
bool DBDataTable::putLong(int row, int column, int value) { // LOGD("DBDataTable::putLong(row=%u, column=%u, value=%lld)", row, column, value); if (row >= m_rowSpList.size() || column >= m_columnCount) { return false; } if (getColumnType(column) != DBDataType_Null && getColumnType(column) != DBDataType_Integer) { return false; } if (NULL == m_rowSpList[row]) { m_rowSpList[row] = new DBDataRow(m_columnCount); if (NULL == m_rowSpList[row]) { return false; } } return m_rowSpList[row]->putLong(column, value); }
bool DBDataTable::putString(int row, int column, const char* value, size_t size) { // LOGD("DBDataTable::putString(row=%u, column=%u, value=[%s], size=%zu)", row, column, value, size); if (row >= m_rowSpList.size() || column >= m_columnCount || NULL == value || 0 == size) { return false; } if (getColumnType(column) != DBDataType_Null && getColumnType(column) != DBDataType_String) { return false; } if (NULL == m_rowSpList[row]) { m_rowSpList[row] = new DBDataRow(m_columnCount); if (NULL == m_rowSpList[row]) { return false; } } return m_rowSpList[row]->putString(column, value, size); }
str CMDbbpbind(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { str name; ValPtr lhs; bat i; int ht,tt; BAT *b; (void) cntxt; (void) mb; /* fool compiler */ lhs = &stk->stk[pci->argv[0]]; name = *getArgReference_str(stk, pci, 1); if (isIdentifier(name) < 0) throw(MAL, "bbp.bind", IDENTIFIER_EXPECTED); i = BBPindex(name); if (i == 0) throw(MAL, "bbp.bind", RUNTIME_OBJECT_MISSING); /* make sure you load the descriptors and heaps */ b = (BAT *) BATdescriptor(i); if (b == 0) /* Simple ignore the binding if you can't find the bat */ throw(MAL, "bbp.bind", RUNTIME_OBJECT_MISSING); /* check conformity of the actual type and the one requested */ ht= getHeadType(getArgType(mb,pci,0)); tt= getColumnType(getArgType(mb,pci,0)); if( b->htype == TYPE_void && ht== TYPE_oid) ht= TYPE_void; if( b->ttype == TYPE_void && tt== TYPE_oid) tt= TYPE_void; if( ht != b->htype || tt != b->ttype){ BBPunfix(i); throw(MAL, "bbp.bind", SEMANTIC_TYPE_MISMATCH ); } /* make sure we are not dealing with an about to be deleted bat */ if( BBP_refs(b->batCacheid) == 1 && BBP_lrefs(b->batCacheid) == 0){ BBPunfix(i); throw(MAL, "bbp.bind", RUNTIME_OBJECT_MISSING); } BBPkeepref(b->batCacheid); lhs->vtype = TYPE_bat; lhs->val.bval = i; return MAL_SUCCEED; }
static str JSONrenderRowObject(BAT **bl, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, BUN idx) { int i, tpe; char *row, *name = 0, *val = 0; size_t len, lim, l; void *p; BATiter bi; row = (char *) GDKmalloc(lim = BUFSIZ); row[0] = '{'; row[1] = 0; len = 1; val = (char *) GDKmalloc(BUFSIZ); for (i = pci->retc; i < pci->argc; i += 2) { name = stk->stk[getArg(pci, i)].val.sval; bi = bat_iterator(bl[i + 1]); p = BUNtail(bi, BUNfirst(bl[i + 1]) + idx); tpe = getColumnType(getArgType(mb, pci, i + 1)); ATOMformat(tpe, p, &val); if (strncmp(val, "nil", 3) == 0) strcpy(val, "null"); l = strlen(name) + strlen(val); while (l > lim - len) row = (char *) GDKrealloc(row, lim += BUFSIZ); snprintf(row + len, lim - len, "\"%s\":%s,", name, val); len += l + 4; } if (row[1]) row[len - 1] = '}'; else { row[1] = '}'; row[2] = 0; } GDKfree(val); return row; }
static str JSONrenderRowArray(BAT **bl, MalBlkPtr mb, InstrPtr pci, BUN idx) { int i, tpe; char *row, *val = 0; size_t len, lim, l; void *p; BATiter bi; row = (char *) GDKmalloc(lim = BUFSIZ); row[0] = '['; row[1] = 0; len = 1; val = (char *) GDKmalloc(BUFSIZ); for (i = pci->retc; i < pci->argc; i++) { bi = bat_iterator(bl[i]); p = BUNtail(bi, BUNfirst(bl[i]) + idx); tpe = getColumnType(getArgType(mb, pci, i)); ATOMformat(tpe, p, &val); if (strncmp(val, "nil", 3) == 0) strcpy(val, "null"); l = strlen(val); while (l > lim - len) row = (char *) GDKrealloc(row, lim += BUFSIZ); snprintf(row + len, lim - len, "%s,", val); len += l + 1; } if (row[1]) row[len - 1] = ']'; else { row[1] = '}'; row[2] = 0; } GDKfree(val); return row; }
void ResultBuilder::build(const bool columnNames) { if (mError==true) return; // Set up the columns try { const int count = getColumnCount(); if (count < 1) { // I think a count of 0 isn't technically an error, because the result set might just be empty. if (count < 0) mError = true; return; } for (int k=0; k<count; ++k) { const int ct = getColumnType(k); if (ct == QUERY_NO_TYPE) mError = true; else mResult.mCol.push_back(ct); if (columnNames) { mResult.mColNames.push_back(getColumnName(k)); } } } catch (std::exception&) { mError = true; return; } // Empty results are considered valid. if (!hasNext()) return; if (mError == true || mResult.mCol.size() < 1) { mError = true; return; } // Read the rows while (hasNext()) { startRow(); for (int k=0; k<mResult.mCol.size(); k++) { const int col = mResult.mCol.data()[k]; if (col == QUERY_NUMERIC) { double v = 0.0f; if (!getDouble(k, v)) mError = true; addNumeric(v); } else if (col == QUERY_STRING) { string v; if (!getString(k, v)) mError = true; addString(v); } else if (col == QUERY_NULL) { // I can't determine at any point the actual type of the column, // because it looks like sqlite always bases that info on the first // row in the result set. So in this case, I've got to just get // every type. double v = 0.0f; if (!getDouble(k, v)) v = 0.0f; addNumeric(v); --mColIdx; string str; getString(k, str); addString(str); } } next(); } }
void IdeTableQuery::onPreRender() { ControlBase::onPreRender(); shared_ptr<XMLDocument> document = getDocument(); shared_ptr<XMLNode> node_root = document->create(_S("table_query")); DataTable result; if(getPage()->getDatabase()->execute(m_sql,result)) { shared_ptr<XMLNode> node_header = node_root->addChild(_S("header")); for(uint32 c = 0; c < result.columns(); c++) { String columnTitle = getColumnTitle(c); if(columnTitle.empty()) columnTitle = result.getColumnName(c); shared_ptr<XMLNode> node_column = node_header->addChild(_S("column")); node_column->setAttributeString(_S("name"), columnTitle); switch(getColumnType(c)) { case IdeTableQuery::ctString: { node_column->setAttributeString(_S("type"), _S("string")); } break; case IdeTableQuery::ctScore: { node_column->setAttributeString(_S("type"), _S("score")); } break; case IdeTableQuery::ctEntityID: { node_column->setAttributeString(_S("type"), _S("entity-id")); } break; case IdeTableQuery::ctObjectID: { node_column->setAttributeString(_S("type"), _S("object-id")); } break; case IdeTableQuery::ctUserID: { node_column->setAttributeString(_S("type"), _S("user-id")); } break; case IdeTableQuery::ctShortDateTime: { node_column->setAttributeString(_S("type"), _S("short-datetime")); } break; case IdeTableQuery::ctLongDateTime: { node_column->setAttributeString(_S("type"), _S("long-datetime")); } break; } } shared_ptr<XMLNode> node_data = node_root->addChild(_S("data")); for(uint32 r=0;r<result.rows();r++) { shared_ptr<XMLNode> node_data_row = node_data->addChild(_S("row")); for(uint32 c=0;c<result.columns();c++) { shared_ptr<XMLNode> node_data_row_item = node_data_row->addChild(_S("item")); String value = result.get(r,c); switch(getColumnType(c)) { case IdeTableQuery::ctScore: { node_data_row_item->setAttributeString(_S("value"), String::format(_S("%1.1f").c_str(), double(result.get(r,c)))); } break; case IdeTableQuery::ctEntityID: { // Sbagliata shared_ptr<XMLPortalExporter> exporter(OS_NEW XMLPortalExporter(node_data_row_item, getPage(), XMLPortalExporter::emLite)); shared_ptr<ObjectsIObject> object = getPage()->getObject(value.to_ascii()); if(object != nullptr) { object->exportXML(exporter); } } break; case IdeTableQuery::ctObjectID: { shared_ptr<XMLPortalExporter> exporter(OS_NEW XMLPortalExporter(node_data_row_item, getPage(), XMLPortalExporter::emLite)); shared_ptr<ObjectsIObject> object = getPage()->getObject(value.to_ascii()); if(object != nullptr) { object->exportXML(exporter); } } break; case IdeTableQuery::ctUserID: { shared_ptr<XMLPortalExporter> exporter(OS_NEW XMLPortalExporter(node_data_row_item, getPage(), XMLPortalExporter::emLite)); shared_ptr<ObjectsIObject> object = getPage()->getObject(value.to_ascii()); if(object != nullptr) { object->exportXML(exporter); } } break; case IdeTableQuery::ctShortDateTime: case IdeTableQuery::ctLongDateTime: { DateTime dt; dt.fromString(value); node_data_row_item->setAttributeDateTime(_S("value"), dt); } break; default: { node_data_row_item->setAttributeString(_S("value"), value); } break; } } } } }
static str renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg) { char *buf =0; char *nme =0; int nameused= 0; size_t len = 0, maxlen = BUFSIZ; ValRecord *val = 0; char *cv =0; str tpe; int showtype = 0, closequote=0; int varid = getArg(p,idx); buf = GDKzalloc(maxlen); // show the name when required or is used if ((flg & LIST_MAL_NAME) && !isVarConstant(mb,varid) && !isVarTypedef(mb,varid)) { nme = getVarName(mb,varid); len +=snprintf(buf, maxlen, "%s", nme); nameused =1; } // show the value when required or being a constant if( ((flg & LIST_MAL_VALUE) && stk != 0) || isVarConstant(mb,varid) ){ if (nameused){ strcat(buf + len,"="); len++; } // locate value record if (isVarConstant(mb,varid)) val = &getVarConstant(mb, varid); else if( stk) val = &stk->stk[varid]; VALformat(&cv, val); if (len + strlen(cv) >= maxlen) buf= GDKrealloc(buf, maxlen =len + strlen(cv) + BUFSIZ); if( buf == 0){ GDKerror("renderTerm:Failed to allocate"); return 0; } if( strcmp(cv,"nil") == 0){ strcat(buf+len,cv); len += strlen(buf+len); if( cv) GDKfree(cv); showtype =getColumnType(getVarType(mb,varid)) > TYPE_str || ((isVarUDFtype(mb,varid) || isVarTypedef(mb,varid)) && isVarConstant(mb,varid)) || isaBatType(getVarType(mb,varid)); } else{ if ( !isaBatType(getVarType(mb,varid)) && getColumnType(getVarType(mb,varid)) > TYPE_str ){ closequote = 1; strcat(buf+len,"\""); len++; } strcat(buf+len,cv); len += strlen(buf+len); if( cv) GDKfree(cv); if( closequote ){ strcat(buf+len,"\""); len++; } showtype =closequote > TYPE_str || ((isVarUDFtype(mb,varid) || isVarTypedef(mb,varid) || (flg & LIST_MAL_REMOTE)) && isVarConstant(mb,varid)) || (isaBatType(getVarType(mb,varid)) && idx < p->retc); if (stk && isaBatType(getVarType(mb,varid)) && abs(stk->stk[varid].val.ival) ){ BAT *d= BBPquickdesc(abs(stk->stk[varid].val.ival),TRUE); if( d) len += snprintf(buf+len,maxlen-len,"[" BUNFMT "]", BATcount(d)); } } } // show the type when required or frozen by the user // special care should be taken with constants, they may have been casted if ((flg & LIST_MAL_TYPE) || (isVarUDFtype(mb, varid) && idx < p->retc) || isVarTypedef(mb,varid) || showtype){ strcat(buf + len,":"); len++; tpe = getTypeName(getVarType(mb, varid)); len += snprintf(buf+len,maxlen-len,"%s",tpe); GDKfree(tpe); } if( len >= maxlen) GDKerror("renderTerm:Value representation too large"); return buf; }
/* * The generic solution to the multiplex operators is to translate * them to a MAL loop. * The call optimizer.multiplex(MOD,FCN,A1,...An) introduces the following code * structure: * * @verbatim * A1rev:=bat.reverse(A1); * resB:= bat.new(A1); * barrier (h,t):= iterator.new(A1); * $1:= algebra.fetch(A1,h); * $2:= A2; # in case of constant? * ... * cr:= MOD.FCN($1,...,$n); * y:=algebra.fetch(A1rev,h); * bat.insert(resB,y,cr); * redo (h,t):= iterator.next(A1); * end h; * @end verbatim * * The algorithm consists of two phases: phase one deals with * collecting the relevant information, phase two is the actual * code construction. */ static str OPTexpandMultiplex(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i = 2, resB, iter = 0, cr; int hvar, tvar; int x, y; str mod, fcn; int *alias; InstrPtr q; int ht, tt; (void) cntxt; (void) stk; ht = getHeadType(getArgType(mb, pci, 0)); if (ht != TYPE_oid) throw(MAL, "optimizer.multiplex", "Target head type is missing"); tt = getColumnType(getArgType(mb, pci, 0)); if (tt== TYPE_any) throw(MAL, "optimizer.multiplex", "Target tail type is missing"); if (isAnyExpression(getArgType(mb, pci, 0))) throw(MAL, "optimizer.multiplex", "Target type is missing"); mod = VALget(&getVar(mb, getArg(pci, pci->retc))->value); mod = putName(mod,strlen(mod)); fcn = VALget(&getVar(mb, getArg(pci, pci->retc+1))->value); fcn = putName(fcn,strlen(fcn)); #ifndef NDEBUG mnstr_printf(GDKstdout,"#WARNING To speedup %s.%s a bulk operator implementation is needed\n", mod,fcn); #endif /* search the iterator bat */ for (i = pci->retc+2; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { iter = getArg(pci, i); if (getHeadType(getVarType(mb,iter)) != TYPE_oid) throw(MAL, "optimizer.multiplex", "Iterator BAT is not OID-headed"); break; } if( i == pci->argc) throw(MAL, "optimizer.multiplex", "Iterator BAT type is missing"); OPTDEBUGmultiplex { char *tpenme; mnstr_printf(cntxt->fdout,"#calling the optimize multiplex script routine\n"); printFunction(cntxt->fdout,mb, 0, LIST_MAL_ALL ); tpenme = getTypeName(getVarType(mb,iter)); mnstr_printf(cntxt->fdout,"#multiplex against operator %d %s\n",iter, tpenme); GDKfree(tpenme); printInstruction(cntxt->fdout,mb, 0, pci,LIST_MAL_ALL); } /* * Beware, the operator constant (arg=1) is passed along as well, * because in the end we issue a recursive function call that should * find the actual arguments at the proper place of the callee. */ alias= (int*) GDKmalloc(sizeof(int) * pci->maxarg); if (alias == NULL) return NULL; /* x := bat.reverse(A1); */ x = newTmpVariable(mb, newBatType(getColumnType(getVarType(mb,iter)), getHeadType(getVarType(mb,iter)))); q = newFcnCall(mb, batRef, reverseRef); getArg(q, 0) = x; (void) pushArgument(mb, q, iter); /* resB := new(refBat) */ q = newFcnCall(mb, batRef, newRef); resB = getArg(q, 0); setVarType(mb, getArg(q, 0), newBatType(ht, tt)); q = pushType(mb, q, ht); q = pushType(mb, q, tt); /* barrier (h,r) := iterator.new(refBat); */ q = newFcnCall(mb, iteratorRef, newRef); q->barrier = BARRIERsymbol; hvar = newTmpVariable(mb, TYPE_any); getArg(q,0) = hvar; tvar = newTmpVariable(mb, TYPE_any); q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); /* $1:= algebra.fetch(Ai,h) or constant */ alias[i] = tvar; for (i++; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { q = newFcnCall(mb, algebraRef, "fetch"); alias[i] = newTmpVariable(mb, getColumnType(getArgType(mb, pci, i))); getArg(q, 0) = alias[i]; q= pushArgument(mb, q, getArg(pci, i)); (void) pushArgument(mb, q, hvar); } /* cr:= mod.CMD($1,...,$n); */ q = newFcnCall(mb, mod, fcn); cr = getArg(q, 0) = newTmpVariable(mb, TYPE_any); for (i = pci->retc+2; i < pci->argc; i++) if (isaBatType(getArgType(mb, pci, i))) { q= pushArgument(mb, q, alias[i]); } else { q = pushArgument(mb, q, getArg(pci, i)); } /* y := algebra.fetch(x,h); */ y = newTmpVariable(mb, getHeadType(getVarType(mb,iter))); q = newFcnCall(mb, algebraRef, "fetch"); getArg(q, 0) = y; q = pushArgument(mb, q, x); q = pushArgument(mb, q, hvar); /* insert(resB,h,cr); not append(resB, cr); the head type (oid) may dynamically change */ q = newFcnCall(mb, batRef, insertRef); q= pushArgument(mb, q, resB); q= pushArgument(mb, q, y); (void) pushArgument(mb, q, cr); /* redo (h,r):= iterator.next(refBat); */ q = newFcnCall(mb, iteratorRef, nextRef); q->barrier = REDOsymbol; getArg(q,0) = hvar; q= pushReturn(mb, q, tvar); (void) pushArgument(mb,q,iter); q = newAssignment(mb); q->barrier = EXITsymbol; getArg(q,0) = hvar; (void) pushReturn(mb, q, tvar); q = newAssignment(mb); getArg(q, 0) = getArg(pci, 0); (void) pushArgument(mb, q, resB); GDKfree(alias); return MAL_SUCCEED; }