@Override public int execute(DriverContext driverContext) { PrintStream out = null; try { Path resFile = new Path(work.getResFile()); OutputStream outS = resFile.getFileSystem(conf).create(resFile); out = new PrintStream(outS); QB qb = work.getQb(); TokenRewriteStream stream = work.getCtx().getTokenRewriteStream(); String program = "sq rewrite"; ASTNode ast = work.getAst(); try { addRewrites(stream, qb, program, out); out.println( "\nRewritten Query:\n" + stream.toString(program, ast.getTokenStartIndex(), ast.getTokenStopIndex())); } finally { stream.deleteProgram(program); } out.close(); out = null; return (0); } catch (Exception e) { console.printError( "Failed with exception " + e.getMessage(), "\n" + StringUtils.stringifyException(e)); return (1); } finally { IOUtils.closeStream(out); } }
void addRewrites(TokenRewriteStream stream, QB qb, String program, PrintStream out) { QBSubQuery sqW = qb.getWhereClauseSubQueryPredicate(); QBSubQuery sqH = qb.getHavingClauseSubQueryPredicate(); if (sqW != null || sqH != null) { ASTNode sqNode = sqW != null ? sqW.getOriginalSubQueryASTForRewrite() : sqH.getOriginalSubQueryASTForRewrite(); ASTNode tokQry = getQueryASTNode(sqNode); ASTNode tokFrom = (ASTNode) tokQry.getChild(0); StringBuilder addedJoins = new StringBuilder(); if (sqW != null) { addRewrites(stream, sqW, program, out, qb.getId(), true, addedJoins); } if (sqH != null) { addRewrites(stream, sqH, program, out, qb.getId(), false, addedJoins); } stream.insertAfter(program, tokFrom.getTokenStopIndex(), addedJoins); } Set<String> sqAliases = qb.getSubqAliases(); for (String sqAlias : sqAliases) { addRewrites(stream, qb.getSubqForAlias(sqAlias).getQB(), program, out); } }
void addRewrites( TokenRewriteStream stream, QBSubQuery sq, String program, PrintStream out, String qbAlias, boolean isWhere, StringBuilder addedJoins) { ASTNode sqNode = sq.getOriginalSubQueryASTForRewrite(); ASTNode tokQry = getQueryASTNode(sqNode); ASTNode tokInsert = (ASTNode) tokQry.getChild(1); ASTNode tokWhere = null; for (int i = 0; i < tokInsert.getChildCount(); i++) { if (tokInsert.getChild(i).getType() == HiveParser.TOK_WHERE) { tokWhere = (ASTNode) tokInsert.getChild(i); break; } } SubQueryDiagnostic.QBSubQueryRewrite diag = sq.getDiagnostic(); String sqStr = diag.getRewrittenQuery(); String joinCond = diag.getJoiningCondition(); /* * the SubQuery predicate has been hoisted as a Join. The SubQuery predicate is replaced * by a 'true' predicate in the Outer QB's where/having clause. */ stream.replace(program, sqNode.getTokenStartIndex(), sqNode.getTokenStopIndex(), "1 = 1"); String sqJoin = " " + getJoinKeyWord(sq) + " " + sqStr + " " + joinCond; addedJoins.append(" ").append(sqJoin); String postJoinCond = diag.getOuterQueryPostJoinCond(); if (postJoinCond != null) { stream.insertAfter(program, tokWhere.getTokenStopIndex(), " and " + postJoinCond); } String qualifier = isWhere ? "Where Clause " : "Having Clause "; if (qbAlias != null) { qualifier = qualifier + "for Query Block '" + qbAlias + "' "; } out.println(String.format("\n%s Rewritten SubQuery:\n%s", qualifier, diag.getRewrittenQuery())); out.println( String.format( "\n%s SubQuery Joining Condition:\n%s", qualifier, diag.getJoiningCondition())); }