CmpStatement::ReturnStatus CmpStatement::process (const CmpMessageDDL& statement) { CmpMain cmpmain; CMPASSERT(statement.getCmpCompileInfo()); char * sqlStr = NULL; Int32 sqlStrLen = 0; Lng32 inputCS = 0; NAString currCatName; NAString currSchName; char * recompControlInfo = NULL; NABoolean isSchNameRecvd; NABoolean nametypeNsk; NABoolean odbcProcess; NABoolean noTextCache; NABoolean aqrPrepare; NABoolean standaloneQuery; isDDL_ = TRUE; if (processRecvdCmpCompileInfo(this, statement, statement.getCmpCompileInfo(), context_, sqlStr, sqlStrLen, // out - long & inputCS, isSchNameRecvd, currCatName, currSchName, recompControlInfo, nametypeNsk, odbcProcess, noTextCache, aqrPrepare, standaloneQuery)) return CmpStatement_ERROR; CmpCommon::context()->sqlSession()->setParentQid( statement.getParentQid()); // process recompControlInfo, if received if (recompControlInfo) setupRecompControlInfo(recompControlInfo, &cmpmain); cmpmain.setSqlParserFlags(statement.getFlags()); // set the current catalog and schema names. InitSchemaDB(); // C control character embedded in sqlStr is not handled. Now replace // control characters tabs, line feeds, spaces with spaces. (no longer // substitute for \n so we can recognized embedded comments) for (Int32 i = 0; sqlStr[i]; i++) if (sqlStr[i] != '\n' && isSpace8859_1((unsigned char)sqlStr[i])) sqlStr[i] = ' '; // skip leading blanks NAString ns(sqlStr); ns = ns.strip(NAString::leading, ' '); // if this is an "update statistics..." request, // then do not send it catalog manager. Int32 foundUpdStat = 0; // check if the first token is UPDATE size_t position = ns.index("UPDATE", 0, NAString::ignoreCase); if (position == 0) { // found UPDATE. See if the next token is STATISTICS. ns = ns(6, ns.length()-6); // skip over UPDATE ns = ns.strip(NAString::leading, ' '); position = ns.index("STATISTICS", 0, NAString::ignoreCase); if (position == 0) foundUpdStat = -1; } if (foundUpdStat) { // TODO, should be removed later // A pointer to user SQL query is stored in CmpStatement; if an exception // is thrown the user query is copied from here. It is reset upon return // from the UpdateStats() method. char *userStr= new (heap()) char[2000]; #pragma nowarn(1506) // warning elimination Int32 len=strlen(sqlStr); #pragma warn(1506) // warning elimination if (len > 1999) len=1999; strncpy(userStr, sqlStr, len); userStr[len]='\0'; sqlTextStr_ = userStr; sqlTextLen_ = len; if (UpdateStats(sqlStr)) { sqlTextStr_ = NULL; sqlTextLen_ = 0; if (recompControlInfo) restoreRecompControlInfo(recompControlInfo); return CmpStatement_ERROR; } sqlTextStr_ = NULL; sqlTextLen_ = 0; if (recompControlInfo) restoreRecompControlInfo(recompControlInfo); return CmpStatement_SUCCESS; } ReturnStatus status = CmpStatement_SUCCESS; if (statement.getCmpCompileInfo()->isHbaseDDL()) { CmpMain::ReturnStatus rs = CmpMain::SUCCESS; QueryText qText(sqlStr, inputCS); CmpMessageReplyCode *bound = new(outHeap_) CmpMessageReplyCode(outHeap_, statement.id(), 0, 0, outHeap_); // CmpMain cmpmain; Set_SqlParser_Flags(DELAYED_RESET); // sqlcompCleanup resets for us Parser parser(CmpCommon::context()); BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), TRUE); // save parser flags Int32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF); ExprNode * exprNode = NULL; if (parser.parseDML(qText, &exprNode, NULL)) { error(arkcmpErrorNoDiags, statement.data()); sqlTextStr_=NULL; return CmpStatement_ERROR; } RelExpr * rRoot = NULL; if (exprNode->getOperatorType() EQU STM_QUERY) { rRoot = (RelRoot*)exprNode->getChild(0); } else if (exprNode->getOperatorType() EQU REL_ROOT) { rRoot = (RelRoot*)exprNode; } CMPASSERT(rRoot); ExprNode *boundDDL = rRoot->bindNode(&bindWA); CMPASSERT(boundDDL); if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_)) { return CmpStatement_ERROR; } ExprNode * ddlNode = NULL; DDLExpr * ddlExpr = NULL; ddlExpr = (DDLExpr*)rRoot->getChild(0); ddlNode = ddlExpr->getDDLNode(); if (ddlNode) { boundDDL = ddlNode->castToStmtDDLNode()->bindNode(&bindWA); CMPASSERT(boundDDL); if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_)) { return CmpStatement_ERROR; } ddlNode = boundDDL; } // reset saved flags Set_SqlParser_Flags (savedParserFlags); CmpSeabaseDDL cmpSBD(heap_); if (cmpSBD.executeSeabaseDDL(ddlExpr, ddlNode, currCatName, currSchName)) { Set_SqlParser_Flags(0); return CmpStatement_ERROR; } Set_SqlParser_Flags (0); // TEMPTEMP. // Until support for metadata invalidation is in, clear up query cache for // this process. That way statements issued later from this session will // not see stale definitions. // This also helps in running tests where tables are modified and accessed from // the same session. // This does not solve the issue of stale definition seen by other processes, // that will be fixed once we have metadata invalidation. CURRENTQCACHE->makeEmpty(); return CmpStatement_SUCCESS; } // hbaseDDL // This is a normal DDL request, call Catalog manager *diags() << DgSqlCode(-4222) << DgString0("SQL Compiler DDL"); return CmpStatement_ERROR; }
/////////////////////////////////////////////////////////////////// // This function takes as input an array of key values, where each // key value is in ASCII string format (the way it is stored in // catalogs). It encodes the key values and returns the encoded // value in the encodedKeyBuffer. // RETURNS: -1, if error. 0, if all Ok. /////////////////////////////////////////////////////////////////// short encodeKeyValues(desc_struct * column_descs, desc_struct * key_descs, NAString * inValuesArray[], // INPUT NABoolean isIndex, char * encodedKeyBuffer, // OUTPUT CollHeap * h, ComDiagsArea * diagsArea) { short error = 0; // assume all will go well NABoolean deleteLater = FALSE; // set up binder/generator stuff so expressions could be generated. InitSchemaDB(); CmpStatement cmpStatement(CmpCommon::context()); ActiveSchemaDB()->createStmtTables(); BindWA bindWA(ActiveSchemaDB(), CmpCommon::context()); Generator generator(CmpCommon::context()); ExpGenerator expGen(&generator); generator.appendAtEnd(); // alloc a new map table generator.setBindWA(&bindWA); generator.setExpGenerator(&expGen); FragmentDir * compFragDir = generator.getFragmentDir(); // create the fragment (independent code space) for this expression CollIndex myFragmentId = compFragDir->pushFragment(FragmentDir::MASTER); // space where RCB will be generated Space * space = generator.getSpace(); // Let's start with a list of size 4 rather than resizing continuously ValueIdList encodedValueIdList(4); desc_struct * column = column_descs; desc_struct * key = key_descs; Int32 i = 0; if (inValuesArray == NULL) deleteLater = TRUE; while (key) { // for an index, keys_desc has columns in the same order as columns_desc, // the following for loop is not needed. if (!isIndex) { column = column_descs; for (Int32 j = 0; j < key->body.keys_desc.tablecolnumber; j++) column = column->header.next; } if (inValuesArray[i] == NULL) inValuesArray[i] = getMinMaxValue(column, key, FALSE, h); ItemExpr * itemExpr = buildEncodeTree(column, key, inValuesArray[i], &generator, diagsArea); if (! itemExpr) return -1; encodedValueIdList.insert(itemExpr->getValueId()); i++; key = key->header.next; if (isIndex) column = column->header.next; } // allocate a work cri desc to encode keys. It has // 3 entries: 0, for consts. 1, for temps. // 2, for the encoded key. ex_cri_desc * workCriDesc = new(space) ex_cri_desc(3, space); short keyAtpIndex = 2; // where the encoded key will be built ULng32 encodedKeyLen; ex_expr * keExpr = 0; expGen.generateContiguousMoveExpr(encodedValueIdList, 0 /*don't add conv nodes*/, 0 /*atp*/, keyAtpIndex, ExpTupleDesc::SQLMX_KEY_FORMAT, encodedKeyLen, &keExpr); // create a DP2 expression and initialize it with the key encode expr. ExpDP2Expr * keyEncodeExpr = new(space) ExpDP2Expr(keExpr, workCriDesc, space); keyEncodeExpr->getExpr()->fixup(0,expGen.getPCodeMode(), (ex_tcb *)space,space, h, FALSE, NULL); atp_struct * workAtp = keyEncodeExpr->getWorkAtp(); workAtp->getTupp(keyAtpIndex).setDataPointer(encodedKeyBuffer); if (keyEncodeExpr->getExpr()->eval(workAtp, 0, space) == ex_expr::EXPR_ERROR) error = -1; if (deleteLater) delete [] inValuesArray; generator.removeAll(NULL); return error; }
CmpStatement::ReturnStatus CmpStatement::process(const CmpMessageDDLwithStatus &statement) { CmpMain cmpmain; CMPASSERT(statement.getCmpCompileInfo()); char * sqlStr = NULL; Int32 sqlStrLen = 0; Lng32 inputCS = 0; NAString currCatName; NAString currSchName; char * recompControlInfo = NULL; NABoolean isSchNameRecvd; NABoolean nametypeNsk; NABoolean odbcProcess; NABoolean noTextCache; NABoolean aqrPrepare; NABoolean standaloneQuery; isDDL_ = TRUE; if (processRecvdCmpCompileInfo(NULL, statement, statement.getCmpCompileInfo(), context_, sqlStr, sqlStrLen, // out - long & inputCS, isSchNameRecvd, currCatName, currSchName, recompControlInfo, nametypeNsk, odbcProcess, noTextCache, aqrPrepare, standaloneQuery)) return CmpStatement_ERROR; CmpCommon::context()->sqlSession()->setParentQid(statement.getParentQid()); // process recompControlInfo, if received if (recompControlInfo) setupRecompControlInfo(recompControlInfo, &cmpmain); cmpmain.setSqlParserFlags(statement.getFlags()); // set the current catalog and schema names. InitSchemaDB(); DDLExpr *ddlExpr = NULL; ExprNode *ddlNode = NULL; if (sqlStr) { if (getDDLExprAndNode(sqlStr, inputCS, ddlExpr, ddlNode)) { return CmpStatement_ERROR; } } CmpDDLwithStatusInfo *dws = statement.getCmpDDLwithStatusInfo(); if ((dws->getMDupgrade()) || (dws->getMDVersion()) || (dws->getSWVersion())) { CmpSeabaseMDupgrade cmpMDU(heap_); NABoolean ddlXns = (CmpCommon::getDefault(DDL_TRANSACTIONS) == DF_ON); if (cmpMDU.executeSeabaseMDupgrade(dws, ddlXns, currCatName, currSchName)) return CmpStatement_ERROR; } else if (dws->getMDcleanup()) { CmpSeabaseDDL cmpSBD(heap_); if (cmpSBD.executeSeabaseDDL(ddlExpr, ddlNode, currCatName, currSchName, dws)) { Set_SqlParser_Flags(0); return CmpStatement_ERROR; } Set_SqlParser_Flags (0); } else { return CmpStatement_ERROR; } /* CmpDDLwithStatusInfo * replyDWS = NULL; replyDWS = new(outHeap_) CmpDDLwithStatusInfo(); replyDWS->copyStatusInfo(dws); */ dws->init(); Lng32 replyDataLen = dws->getLength(); char * replyData = new(outHeap_) char[replyDataLen]; dws->pack(replyData); CmpDDLwithStatusInfo * replyDWS = (CmpDDLwithStatusInfo*)replyData; reply_ = new(outHeap_) CmpMessageReplyCode( outHeap_, statement.id(), 0, 0, outHeap_); reply_->data() = replyData; reply_->size() = replyDataLen; return CmpStatement_SUCCESS; }