private static Collection<ParserRuleContext> getChildrenNodes(final ParserRuleContext node) { Collection<ParserRuleContext> result = new LinkedList<>(); for (int i = 0; i < node.getChildCount(); i++) { ParseTree child = node.getChild(i); if (child instanceof ParserRuleContext) { result.add((ParserRuleContext) child); } } return result; } }
private String getInnerExpression(final ParserRuleContext functionNode) { StringBuilder result = new StringBuilder(); for (int i = 1; i < functionNode.getChildCount(); i++) { String text = functionNode.getChild(i).getText(); result.append(text); if ("DISTINCT".equals(text)) { result.append(" "); } } return result.toString(); }
private String getDistinctExpression(final ParserRuleContext functionNode) { StringBuilder result = new StringBuilder(); for (int i = 3; i < functionNode.getChildCount() - 1; i++) { result.append(functionNode.getChild(i).getText()); } return result.toString(); } }
private Optional<ConditionSegment> buildPredicateCondition(final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext exprNode) { Optional<ParserRuleContext> predicateNode = ExtractorUtils.findFirstChildNode(exprNode, RuleName.PREDICATE); if (!predicateNode.isPresent()) { return Optional.absent(); } if (1 != predicateNode.get().getParent().getChildCount()) { return Optional.absent(); } if (5 == predicateNode.get().getChildCount() && DefaultKeyword.BETWEEN.name().equalsIgnoreCase(predicateNode.get().getChild(1).getText())) { Optional<ConditionSegment> result = buildBetweenCondition(placeholderIndexes, predicateNode.get()); if (result.isPresent()) { return result; } } if (5 <= predicateNode.get().getChildCount() && DefaultKeyword.IN.name().equalsIgnoreCase(predicateNode.get().getChild(1).getText())) { Optional<ConditionSegment> result = buildInCondition(placeholderIndexes, predicateNode.get()); if (result.isPresent()) { return result; } } return Optional.absent(); }
private boolean hasDistinct(final ParserRuleContext selectClauseNode) { return selectClauseNode.getChildCount() > 2 && DefaultKeyword.DISTINCT.name().equalsIgnoreCase(selectClauseNode.getChild(1).getText()); } }
private boolean isValidEqualCondition(final ParserRuleContext comparisionNode) { return Symbol.EQ.getLiterals().equalsIgnoreCase(comparisionNode.getText()) && 3 == comparisionNode.getParent().getChildCount(); }
/** * Find first child node. * * @param node start node * @param ruleName rule name * @return matched node */ public static Optional<ParserRuleContext> findFirstChildNode(final ParserRuleContext node, final RuleName ruleName) { if (isMatchedNode(node, ruleName)) { return Optional.of(node); } for (int i = 0; i < node.getChildCount(); i++) { ParseTree child = node.getChild(i); if (child instanceof ParserRuleContext) { Optional<ParserRuleContext> result = findFirstChildNode((ParserRuleContext) child, ruleName); if (result.isPresent()) { return result; } } } return Optional.absent(); }
private Optional<ConditionSegment> buildInCondition(final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext predicateNode) { Optional<ColumnSegment> column = buildColumn((ParserRuleContext) predicateNode.getChild(0)); if (!column.isPresent()) { return Optional.absent(); } List<ExpressionSegment> sqlExpressions = new LinkedList<>(); for (int i = 3; i < predicateNode.getChildCount(); i++) { if (RuleName.SIMPLE_EXPR.getName().equals(predicateNode.getChild(i).getClass().getSimpleName())) { Optional<? extends ExpressionSegment> expression = expressionExtractor.extract(placeholderIndexes, (ParserRuleContext) predicateNode.getChild(i)); if (!expression.isPresent()) { sqlExpressions.clear(); break; } sqlExpressions.add(expression.get()); } } if (!sqlExpressions.isEmpty()) { InValueExpressionSegment inExpressionSegment = new InValueExpressionSegment(); inExpressionSegment.getSqlExpressions().addAll(sqlExpressions); return Optional.of(new ConditionSegment(column.get(), ShardingOperator.IN, inExpressionSegment)); } return Optional.absent(); }
@Override public Optional<LimitSegment> extract(final ParserRuleContext ancestorNode) { Optional<ParserRuleContext> limitNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.LIMIT_CLAUSE); if (!limitNode.isPresent()) { return Optional.absent(); } Optional<ParserRuleContext> rangeNode = ExtractorUtils.findFirstChildNode(limitNode.get(), RuleName.RANGE_CLAUSE); if (!rangeNode.isPresent()) { return Optional.absent(); } Map<ParserRuleContext, Integer> placeholderAndNodeIndexMap = getPlaceholderAndNodeIndexMap(ancestorNode); LimitValueSegment firstLimitValue = createLimitValueSegment(placeholderAndNodeIndexMap, (ParserRuleContext) rangeNode.get().getChild(0)); if (rangeNode.get().getChildCount() >= 3) { LimitValueSegment rowCountLimitValue = createLimitValueSegment(placeholderAndNodeIndexMap, (ParserRuleContext) rangeNode.get().getChild(2)); return Optional.of(new LimitSegment(rowCountLimitValue, firstLimitValue)); } return Optional.of(new LimitSegment(firstLimitValue)); }
/** * Find first child node none recursive. * * @param node start node * @param ruleName rule name * @return matched node */ public static Optional<ParserRuleContext> findFirstChildNodeNoneRecursive(final ParserRuleContext node, final RuleName ruleName) { if (isMatchedNode(node, ruleName)) { return Optional.of(node); } for (int i = 0; i < node.getChildCount(); i++) { if (node.getChild(i) instanceof ParserRuleContext) { ParserRuleContext child = (ParserRuleContext) node.getChild(i); if (isMatchedNode(child, ruleName)) { return Optional.of(child); } } } return Optional.absent(); }
protected void extractTableReference(final FromWhereSegment fromWhereSegment, final ParserRuleContext tableReferenceNode, final Map<ParserRuleContext, Integer> placeholderIndexes) { for (int i = 0; i < tableReferenceNode.getChildCount(); i++) { if (tableReferenceNode.getChild(i) instanceof TerminalNode) { continue; } ParserRuleContext childNode = (ParserRuleContext) tableReferenceNode.getChild(i); if (RuleName.TABLE_REFERENCES.getName().equals(childNode.getClass().getSimpleName())) { Collection<ParserRuleContext> subTableReferenceNodes = ExtractorUtils.getAllDescendantNodes(childNode, RuleName.TABLE_REFERENCE); for (ParserRuleContext each : subTableReferenceNodes) { extractTableReference(fromWhereSegment, each, placeholderIndexes); } } else { fillTable(fromWhereSegment, childNode, placeholderIndexes); } } }
/** * Extract common expression segment. * * @param placeholderIndexes place holder index * @param expressionNode expression node * @return common expression segment */ public CommonExpressionSegment extractCommonExpressionSegment(final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext expressionNode) { CommonExpressionSegment result = new CommonExpressionSegment(expressionNode.getStart().getStartIndex(), expressionNode.getStop().getStopIndex()); Optional<ParserRuleContext> questionNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.QUESTION); if (questionNode.isPresent()) { Integer index = placeholderIndexes.get(questionNode.get()); result.setPlaceholderIndex(index); } else { Optional<ParserRuleContext> bitExprNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.BIT_EXPR); Optional<ParserRuleContext> numberNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.NUMBER); if (numberNode.isPresent() && (!bitExprNode.isPresent() || 1 == bitExprNode.get().getChildCount())) { result.setValue(NumberUtil.getExactlyNumber(numberNode.get().getText(), 10)); } Optional<ParserRuleContext> stringNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.STRING); if (stringNode.isPresent() && (!bitExprNode.isPresent() || 1 == bitExprNode.get().getChildCount())) { result.setText(true); } } return result; } }
private Optional<OrConditionSegment> extractConditionInternal(final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext exprNode) { int index = -1; for (int i = 0; i < exprNode.getChildCount(); i++) { if (LogicalOperator.isLogicalOperator(exprNode.getChild(i).getText())) { index = i; break; } } if (index > 0) { Optional<OrConditionSegment> leftOrCondition = extractConditionInternal(placeholderIndexes, (ParserRuleContext) exprNode.getChild(index - 1)); Optional<OrConditionSegment> rightOrCondition = extractConditionInternal(placeholderIndexes, (ParserRuleContext) exprNode.getChild(index + 1)); if (leftOrCondition.isPresent() && rightOrCondition.isPresent()) { return Optional.of(mergeCondition(placeholderIndexes, leftOrCondition.get(), rightOrCondition.get(), exprNode.getChild(index).getText())); } return leftOrCondition.isPresent() ? leftOrCondition : rightOrCondition; } return extractConditionForParen(placeholderIndexes, exprNode); }
@Override public Collection<OrderByItemSegment> extract(final ParserRuleContext ancestorNode) { Collection<OrderByItemSegment> result = new LinkedList<>(); for (ParserRuleContext each : ExtractorUtils.getAllDescendantNodes(ancestorNode, RuleName.ORDER_BY_ITEM)) { OrderDirection orderDirection = 2 == each.getChildCount() && OrderDirection.DESC.name().equalsIgnoreCase(each.getChild(1).getText()) ? OrderDirection.DESC : OrderDirection.ASC; Optional<ParserRuleContext> indexNode = ExtractorUtils.findFirstChildNode(each, RuleName.NUMBER); if (indexNode.isPresent()) { result.add(new IndexOrderByItemSegment(NumberUtil.getExactlyNumber(indexNode.get().getText(), 10).intValue(), orderDirection, OrderDirection.ASC)); continue; } Optional<ParserRuleContext> expressionNode = ExtractorUtils.findFirstChildNode(each, RuleName.EXPR); if (expressionNode.isPresent()) { result.add(new ExpressionOrderByItemSegment(expressionNode.get().getText(), orderDirection, OrderDirection.ASC)); continue; } Optional<ParserRuleContext> columnNameNode = ExtractorUtils.findFirstChildNode(each, RuleName.COLUMN_NAME); if (columnNameNode.isPresent()) { result.add(new ColumnNameOrderByItemSegment(columnNameNode.get().getText(), ((ParserRuleContext) each.getChild(0)).getStart().getStartIndex(), orderDirection, OrderDirection.ASC)); } } return result; } }
private Optional<OrConditionSegment> extractConditionForParen(final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext exprNode) { int index = -1; for (int i = 0; i < exprNode.getChildCount(); i++) { if (Paren.isLeftParen(exprNode.getChild(i).getText())) { index = i; break; } } if (-1 != index) { Preconditions.checkState(Paren.match(exprNode.getChild(index).getText(), exprNode.getChild(index + 2).getText()), "Missing right paren."); if (RuleName.EXPR.getName().equals(exprNode.getChild(index + 1).getClass().getSimpleName())) { return extractConditionInternal(placeholderIndexes, (ParserRuleContext) exprNode.getChild(index + 1)); } return Optional.absent(); } Optional<ConditionSegment> condition = buildCondition(placeholderIndexes, exprNode); if (!condition.isPresent()) { return Optional.absent(); } OrConditionSegment result = new OrConditionSegment(); AndConditionSegment newAndCondition = new AndConditionSegment(); newAndCondition.getConditions().add(condition.get()); result.getAndConditions().add(newAndCondition); return Optional.of(result); }
@Override public Optional<SelectClauseSegment> extract(final ParserRuleContext ancestorNode) { ParserRuleContext selectClauseNode = ExtractorUtils.getFirstChildNode(ancestorNode, RuleName.SELECT_CLAUSE); ParserRuleContext selectExpressionsNode = ExtractorUtils.getFirstChildNode(selectClauseNode, RuleName.SELECT_EXPRS); SelectClauseSegment result = new SelectClauseSegment(selectExpressionsNode.getStart().getStartIndex(), selectExpressionsNode.getStop().getStopIndex(), hasDistinct(selectClauseNode)); for (int i = 0; i < selectExpressionsNode.getChildCount(); i++) { ParseTree selectExpressionNode = selectExpressionsNode.getChild(i); if (selectExpressionNode instanceof TerminalNodeImpl) { continue; } Optional<? extends SelectItemSegment> selectItemSegment = selectItemExtractor.extract((ParserRuleContext) selectExpressionNode); if (selectItemSegment.isPresent()) { result.getSelectItems().add(selectItemSegment.get()); } } return Optional.of(result); }
Token closingParenthesis = ParseTreeUtil.getStopTokenForNode(ctx.getChild(ctx.getChildCount() - 1)); Location openingParenthesisLoc = ListenerUtil.getTokenLocation(openingParenthesis); if (ctx.getChildCount() == 2) { if (checkLeftSpaces(openingParenthesis, closingParenthesis, 0)) { printer.error(rule, Messages.EMPTY + construct.toLowerCase() + Messages.ILLEGAL_WHITESPACE, Token contentEnd = ParseTreeUtil.getStopTokenForNode(ctx.getChild(ctx.getChildCount() - 2));
/** * Check for the minimum number of children. */ private void checkChildren(ParserRuleContext ctx, int min) { if (ctx.getChildCount() < min) { throw new IllegalStateException("expecting " + min + " children for comparison but got " + ctx.getChildCount()); } }
private void addExpression(ParserRuleContext ctx) { int childCount = ctx.getChildCount(); if (childCount < 3) { throw new IllegalStateException("expecting 3 children for comparison? " + ctx); } String operator = child(ctx, 1); EqlOperator op = operatorMapping.get(operator); if (op == null) { throw new IllegalStateException("No operator found for " + operator); } String path = getLeftHandSidePath(ctx); String rhs = child(ctx, 2); if (path.equals(rhs)) { // the 'value operator path' form // invert the operator and use LHS as RHS op = invert(op); rhs = child(ctx, 0); } // RHS is Path, Literal or Named input parameter helper.addExpression(path, op, rhs); }
/** Replace any subtree siblings of root that are completely to left * or right of lookahead range with a CommonToken(Token.INVALID_TYPE,"...") * node. The source interval for t is not altered to suit smaller range! * * WARNING: destructive to t. * * @since 4.5.1 */ public static void stripChildrenOutOfRange(ParserRuleContext t, ParserRuleContext root, int startIndex, int stopIndex) { if ( t==null ) return; for (int i = 0; i < t.getChildCount(); i++) { ParseTree child = t.getChild(i); Interval range = child.getSourceInterval(); if ( child instanceof ParserRuleContext && (range.b < startIndex || range.a > stopIndex) ) { if ( isAncestorOf(child, root) ) { // replace only if subtree doesn't have displayed root CommonToken abbrev = new CommonToken(Token.INVALID_TYPE, "..."); t.children.set(i, new TerminalNodeImpl(abbrev)); } } } }