int main(int argc, char** argv) { vflg = false; uint32_t tlvl = 0; bool dflg = false; int c; int32_t sid = -1; bool Bflg = false; opterr = 0; while ((c = getopt(argc, argv, "vt:ds:Bh")) != EOF) switch (c) { case 't': tlvl = static_cast<uint32_t>(strtoul(optarg, 0, 0)); break; case 'v': vflg = true; break; case 'd': dflg = true; break; case 's': sid = static_cast<int32_t>(strtol(optarg, 0, 0)); break; case 'B': Bflg = true; break; case 'h': case '?': default: usage(); return (c == 'h' ? 0 : 1); break; } if (dflg) vflg = true; if ((argc - optind) < 1) { usage(); return 1; } ifstream inputf; ByteStream bs; ByteStream dbs; ByteStream eoq; ByteStream tbs; ByteStream statsStream; ByteStream::quadbyte q = 0; eoq << q; uint32_t sessionid; time_t t; SJLP jl; DeliveredTableMap tm; DeliveredTableMap::iterator iter; DeliveredTableMap::iterator end; CalpontSelectExecutionPlan csep; struct timeval start_time; struct timeval end_time; MessageQueueClient* mqc = 0; if (!dflg) mqc = new MessageQueueClient("ExeMgr1"); if (sid == -1) { time(&t); sessionid = static_cast<uint32_t>(t); } else { sessionid = static_cast<uint32_t>(sid); } sessionid &= 0x7fffffff; logging::ErrorCodes errorCodes; for ( ; optind < argc; optind++) { inputf.open(argv[optind]); if (!inputf.good()) { cerr << "error opening plan stream " << argv[optind] << endl; return 1; } bs.reset(); inputf >> bs; inputf.close(); csep.unserialize(bs); csep.sessionID(sessionid); SessionManager sm; csep.verID(sm.verID()); csep.traceFlags(0); ResourceManager rm; jl = JobListFactory::makeJobList(&csep, rm); csep.traceFlags(tlvl); if (vflg) { if (dflg) cout << endl << "Query:" << endl; else { cout << endl << "Session: " << sessionid << ", Sending Query"; if (Bflg) cout << " (" << argv[optind] << ')'; cout << ':' << endl; } if (!Bflg) cout << csep.data() << endl << endl; } if (dflg) continue; try { dbs.reset(); csep.serialize(dbs); gettimeofday(&start_time, 0); //try tuples first, but expect the worst... bool expectTuples = false; ByteStream tbs; ByteStream::quadbyte tqb = 4; tbs << tqb; mqc->write(tbs); //send the CSEP mqc->write(dbs); //read the response to the tuple request tbs = mqc->read(); idbassert(tbs.length() == 4); tbs >> tqb; if (tqb == 4) expectTuples = true; if (!expectTuples) cout << "Using TableBand I/F" << endl; else cout << "Using tuple I/F" << endl; tm = jl->deliveredTables(); iter = tm.begin(); end = tm.end(); OID toid; uint64_t rowTot; bool reported = false; bool needRGCtor = true; while (iter != end) { toid = iter->first; q = static_cast<ByteStream::quadbyte>(toid); tbs.reset(); tbs << q; mqc->write(tbs); ByteStream tbbs; TableBand tb; RowGroup rg; rowTot = 0; uint16_t status = 0; TableBand::VBA::size_type rc; ofstream out; for (;;) { tbbs = mqc->read(); #if 0 cout << tbbs.length() << endl; out.open("bs1.dat"); idbassert(out.good()); out << tbbs; out.close(); tbbs = mqc->read(); cout << tbbs.length() << endl; out.open("bs2.dat"); idbassert(out.good()); out << tbbs; out.close(); tbbs = mqc->read(); cout << tbbs.length() << endl; out.open("bs3.dat"); idbassert(out.good()); out << tbbs; out.close(); #endif if(tbbs.length()) { if (!expectTuples) tb.unserialize(tbbs); else { if (needRGCtor) { rg.deserialize(tbbs); needRGCtor = false; tbbs = mqc->read(); } rg.setData((uint8_t*)tbbs.buf()); } } else { //@bug 1346 if (!status) status = logging::makeJobListErr; break; } if (!expectTuples) { rc = tb.getRowCount(); status = tb.getStatus(); } else { rc = rg.getRowCount(); status = rg.getStatus(); if (rc == 0) status = 0; } if (rc == 0) break; rowTot += rc; } BatchPrimitive* step = dynamic_cast<BatchPrimitive*>( iter->second.get() ); if (vflg && step) { cout << "For table " << step->tableName(); if (!Bflg) cout << " " << toid; cout << ": read " << rowTot << " rows" << endl; } if (status && !reported) { cout << "### Query failed: " << errorCodes.errorString(status) << " Check crit.log\n"; reported = true; } if (!step && !reported) { cout << "### Query failed: Did not return project BatchPrimitive. Check crit.log\n"; reported = true; } ++iter; } if (vflg) { gettimeofday(&end_time, 0); cout << "Query time: " << fixed << setprecision(1) << tm_diff(&start_time, &end_time) << " secs" << endl; //...Ask for query stats through special table id of 3 const OID TABLE_ID_TO_GET_QUERY_STATS = 3; if (!Bflg) cout << "Retrieving stats..." << endl; toid = TABLE_ID_TO_GET_QUERY_STATS; q = static_cast<ByteStream::quadbyte>(toid); statsStream.reset(); statsStream << q; mqc->write(statsStream); ByteStream bs_statsString; bs_statsString = mqc->read(); string statsString; bs_statsString >> statsString; string printStatsString; struct timeval startRunTime; parseStatsString (statsString, printStatsString, startRunTime); cout << printStatsString << "; QuerySetupTime-" << tm_diff(&start_time, &startRunTime) << "secs" << endl; } //...Close this query/session mqc->write(eoq); jl.reset(); } catch(const exception& ex) { cout << "### SendPlan caught an exception: " << ex.what() << endl; } } // jl.reset(); CalpontSystemCatalog::removeCalpontSystemCatalog( sessionid ); config::Config::deleteInstanceMap(); delete mqc; return 0; }
/** @brief the wrapper function to Oracle stored function cal_get_explain_plan */ int getPlan( OCIExtProcContext* ctx, int sessionId, const char* curSchemaName, CalpontSelectExecutionPlan &plan, BindValueSet* bindValList) { pu::myCtx = ctx; pu::sessionid = sessionId; strcpy(pu::curschema, curSchemaName); string stmt = get_sql_text(sessionId); plan.data(stmt); // @bug 1331 string sqlCommand = stmt.substr(0, stmt.find_first_of(' ', 0)); if (strcasecmp(sqlCommand.c_str(), "CREATE") == 0) { string tmpsql = stmt; boost::to_upper(tmpsql); string::size_type sPos = tmpsql.find("SELECT"); if (sPos != string::npos) stmt = stmt.substr(sPos); } string newStmt = stmt; #if BIND_VARIABLE_SUPPORT BindValue *elem; BindValue_ind *elem_ind; boolean j; sb4 size; pu::checkerr (pu::errhp, OCICollSize ( envhp, pu::errhp, bindValList, &size )); char sql[SQL_MAX_SIZE]; char bindVar[SQL_MAX_SIZE]; char bindVal[SQL_MAX_SIZE]; for (sb4 i = 0; i < size; i++) { pu::checkerr(pu::errhp, OCICollGetElem ( envhp, pu::errhp, bindValList, i, &j,(void**)&elem, (void**)&elem_ind )); if (!elem->sqltext || !elem->bindVar || !elem->bindValue) continue; strcpy(sql, (char*) OCIStringPtr(envhp, elem->sqltext)); strcpy(bindVar, (char*) OCIStringPtr(envhp, elem->bindVar)); strcpy(bindVal, (char*) OCIStringPtr(envhp, elem->bindValue)); // replace bind variable with bind values if sql stmt matches if (strcmp(sql, stmt.c_str()) == 0) { string bindName = ":"; bindName.append(bindVar); string::size_type pos = newStmt.find(bindName); newStmt.replace(pos, bindName.length(), bindVal); } } #endif strcpy(sqltext, newStmt.c_str()); pu::checkerr(pu::errhp, OCIStmtExecute(svchp, stmthp, pu::errhp, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT)); // fetch result and convert pu::getPlanRecords(stmthp1); pu::doConversion(plan); return 0; }