public static SqlParamsFinder newInstance(SqlCall sourceTmpl, final SqlCall sqlCall, boolean isWindowCall) { if (!isWindowCall) { return new SqlParamsFinder(sourceTmpl, sqlCall); } else { return new SqlParamsFinder(sourceTmpl, sqlCall) { @Override public Map<Integer, SqlNode> getParamNodes() { Map<Integer, SqlNode> sqlNodes = new HashMap<>(); List<SqlNode> sqlNodeList = sqlCall.getOperandList(); SqlNode firstParam = ((SqlCall) sqlNodeList.get(0)).getOperandList().get(0); SqlNode secondParam = (SqlCall) sqlNodeList.get(1); sqlNodes.put(0, firstParam); sqlNodes.put(1, secondParam); return sqlNodes; } }; } } }
public Map<Integer, SqlNode> getParamNodes() { paramPath = SqlParamsFinder.PATH_CACHE.getIfPresent(this.sourceTmpl); if (paramPath == null) { this.paramPath = new TreeMap<>(); genParamPath(this.sourceTmpl, new ArrayList<Integer>()); SqlParamsFinder.PATH_CACHE.put(this.sourceTmpl, this.paramPath); } Map<Integer, SqlNode> sqlNodes = new HashMap<>(); for (Map.Entry<Integer, List<Integer>> entry : paramPath.entrySet()) { List<Integer> path = entry.getValue(); sqlNodes.put(entry.getKey(), getParamNode(path, sqlCall, 0)); } return sqlNodes; }
private SqlNode convertSqlCall(SqlCall sqlCall) { SqlOperator operator = sqlCall.getOperator(); if (operator != null) { Pair<SqlNode, SqlNode> matched = convMaster.matchSqlFunc(sqlCall); if (matched != null) { Preconditions.checkState(matched.getFirst() instanceof SqlCall); SqlCall sourceTmpl = (SqlCall) matched.getFirst(); Preconditions.checkState(sourceTmpl.operandCount() == sqlCall.operandCount()); SqlNode targetTmpl = matched.getSecond(); boolean isWindowCall = sourceTmpl.getOperator() instanceof SqlOverOperator; SqlParamsFinder sqlParamsFinder = SqlParamsFinder.newInstance(sourceTmpl, sqlCall, isWindowCall); return targetTmpl.accept(new SqlFuncFiller(sqlParamsFinder.getParamNodes(), isWindowCall)); } } return null; }
@Test public void testParamFinder() throws SqlParseException { SqlParser sqlParser1 = SqlParser.create("POWER($0, $1) + AVG(LN($3)) + EXP($5)"); SqlNode sqlPattern = sqlParser1.parseExpression(); SqlParser sqlParser2 = SqlParser.create("POWER(3, POWER(2, POWER(2, 3))) + AVG(LN(EXP(4))) + EXP(CAST('2018-03-22' AS DATE))"); SqlNode sqlCall = sqlParser2.parseExpression(); SqlParamsFinder sqlParamsFinder = new SqlParamsFinder((SqlCall)sqlPattern, (SqlCall)sqlCall); Map<Integer, SqlNode> paramNodes = sqlParamsFinder.getParamNodes(); Assert.assertEquals("3", paramNodes.get(0).toString()); Assert.assertEquals("POWER(2, POWER(2, 3))", paramNodes.get(1).toString()); Assert.assertEquals("EXP(4)", paramNodes.get(3).toString()); Assert.assertEquals("CAST('2018-03-22' AS DATE)", paramNodes.get(5).toString()); }
private SqlNode getParamNode(List<Integer> path, SqlNode sqlNode, int level) { if (level == path.size() - 1) { return ((SqlCall) sqlNode).getOperandList().get(path.get(level)); } else { return getParamNode(path, ((SqlCall) sqlNode).getOperandList().get(path.get(level)), ++level); } }
private void genParamPath(SqlNode sqlNode, List<Integer> path) { if (sqlNode instanceof SqlIdentifier) { int paramIdx = ParamNodeParser.parseParamIdx(sqlNode.toString()); if (paramIdx >= 0 && path.size() > 0) { paramPath.put(paramIdx, path); } } else if (sqlNode instanceof SqlCall) { List<SqlNode> operands = ((SqlCall) sqlNode).getOperandList(); for (int i = 0; i < operands.size(); i++) { List<Integer> copiedPath = Lists.newArrayList(path); copiedPath.add(i); genParamPath(operands.get(i), copiedPath); } } }
@Test public void testWindowCallParams() throws SqlParseException { SqlParser sqlParser1 = SqlParser.create("STDDEV_POP($0) OVER($1)"); SqlNode sqlPattern = sqlParser1.parseExpression(); SqlParser sqlParser2 = SqlParser.create("STDDEV_POP(C1) OVER (ORDER BY C1)"); SqlNode sqlCall = sqlParser2.parseExpression(); SqlParamsFinder sqlParamsFinder = SqlParamsFinder.newInstance((SqlCall)sqlPattern, (SqlCall)sqlCall, true); Map<Integer, SqlNode> paramNodes = sqlParamsFinder.getParamNodes(); Assert.assertEquals("C1", paramNodes.get(0).toString()); Assert.assertEquals("(ORDER BY `C1`)", paramNodes.get(1).toString()); Assert.assertTrue(paramNodes.get(1) instanceof SqlWindow); } }
private SqlNode getParamNode(List<Integer> path, SqlNode sqlNode, int level) { if (level == path.size() - 1) { return ((SqlCall) sqlNode).getOperandList().get(path.get(level)); } else { return getParamNode(path, ((SqlCall) sqlNode).getOperandList().get(path.get(level)), ++level); } }
private void genParamPath(SqlNode sqlNode, List<Integer> path) { if (sqlNode instanceof SqlIdentifier) { int paramIdx = ParamNodeParser.parseParamIdx(sqlNode.toString()); if (paramIdx >= 0 && path.size() > 0) { paramPath.put(paramIdx, path); } } else if (sqlNode instanceof SqlCall) { List<SqlNode> operands = ((SqlCall) sqlNode).getOperandList(); for (int i = 0; i < operands.size(); i++) { List<Integer> copiedPath = Lists.newArrayList(path); copiedPath.add(i); genParamPath(operands.get(i), copiedPath); } } }
private SqlNode convertSqlCall(SqlCall sqlCall) { SqlOperator operator = sqlCall.getOperator(); if (operator != null) { Pair<SqlNode, SqlNode> matched = convMaster.matchSqlFunc(sqlCall); if (matched != null) { Preconditions.checkState(matched.getFirst() instanceof SqlCall); SqlCall sourceTmpl = (SqlCall) matched.getFirst(); Preconditions.checkState(sourceTmpl.operandCount() == sqlCall.operandCount()); SqlNode targetTmpl = matched.getSecond(); boolean isWindowCall = sourceTmpl.getOperator() instanceof SqlOverOperator; SqlParamsFinder sqlParamsFinder = SqlParamsFinder.newInstance(sourceTmpl, sqlCall, isWindowCall); return targetTmpl.accept(new SqlFuncFiller(sqlParamsFinder.getParamNodes(), isWindowCall)); } } return null; }
public Map<Integer, SqlNode> getParamNodes() { paramPath = SqlParamsFinder.PATH_CACHE.getIfPresent(this.sourceTmpl); if (paramPath == null) { this.paramPath = new TreeMap<>(); genParamPath(this.sourceTmpl, new ArrayList<Integer>()); SqlParamsFinder.PATH_CACHE.put(this.sourceTmpl, this.paramPath); } Map<Integer, SqlNode> sqlNodes = new HashMap<>(); for (Map.Entry<Integer, List<Integer>> entry : paramPath.entrySet()) { List<Integer> path = entry.getValue(); sqlNodes.put(entry.getKey(), getParamNode(path, sqlCall, 0)); } return sqlNodes; }
public static SqlParamsFinder newInstance(SqlCall sourceTmpl, final SqlCall sqlCall, boolean isWindowCall) { if (!isWindowCall) { return new SqlParamsFinder(sourceTmpl, sqlCall); } else { return new SqlParamsFinder(sourceTmpl, sqlCall) { @Override public Map<Integer, SqlNode> getParamNodes() { Map<Integer, SqlNode> sqlNodes = new HashMap<>(); List<SqlNode> sqlNodeList = sqlCall.getOperandList(); SqlNode firstParam = ((SqlCall) sqlNodeList.get(0)).getOperandList().get(0); SqlNode secondParam = (SqlCall) sqlNodeList.get(1); sqlNodes.put(0, firstParam); sqlNodes.put(1, secondParam); return sqlNodes; } }; } } }