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 Optional<ConditionSegment> buildBetweenCondition(final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext predicateNode) { Optional<ColumnSegment> column = buildColumn((ParserRuleContext) predicateNode.getChild(0)); if (!column.isPresent()) { return Optional.absent(); } Optional<? extends ExpressionSegment> beginSQLExpression = expressionExtractor.extract(placeholderIndexes, (ParserRuleContext) predicateNode.getChild(2)); Optional<? extends ExpressionSegment> endSQLExpression = expressionExtractor.extract(placeholderIndexes, (ParserRuleContext) predicateNode.getChild(4)); if (beginSQLExpression.isPresent() && endSQLExpression.isPresent()) { return Optional.of(new ConditionSegment(column.get(), ShardingOperator.BETWEEN, new BetweenValueExpressionSegment(beginSQLExpression.get(), endSQLExpression.get()))); } return Optional.absent(); }
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(); } }
@Override public Optional<ColumnDefinitionSegment> extract(final ParserRuleContext ancestorNode) { Optional<ParserRuleContext> columnNameNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.COLUMN_NAME); if (!columnNameNode.isPresent()) { return Optional.absent(); } Optional<ParserRuleContext> dataTypeNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.DATA_TYPE); Optional<String> dataTypeText = dataTypeNode.isPresent() ? Optional.of(dataTypeNode.get().getChild(0).getText()) : Optional.<String>absent(); boolean isPrimaryKey = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.PRIMARY_KEY).isPresent(); return Optional.of(new ColumnDefinitionSegment(columnNameNode.get().getText(), dataTypeText.orNull(), isPrimaryKey)); } }
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 void extractSetColumns(final ParserRuleContext ancestorNode, final UpdateSetWhereSegment updateSetWhereSegment, final Map<ParserRuleContext, Integer> placeholderIndexes) { Optional<ParserRuleContext> setClauseNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.SET_CLAUSE); if (!setClauseNode.isPresent()) { return; } ColumnSegmentExtractor columnSegmentExtractor = new ColumnSegmentExtractor(); for (ParserRuleContext each : ExtractorUtils.getAllDescendantNodes(setClauseNode.get(), RuleName.ASSIGNMENT)) { Optional<ColumnSegment> columnSegment = columnSegmentExtractor.extract((ParserRuleContext) each.getChild(0)); updateSetWhereSegment.getUpdateColumns().put(columnSegment.get().getName(), expressionExtractor.extract(placeholderIndexes, (ParserRuleContext) each.getChild(2)).get()); } } }
private boolean hasDistinct(final ParserRuleContext selectClauseNode) { return selectClauseNode.getChildCount() > 2 && DefaultKeyword.DISTINCT.name().equalsIgnoreCase(selectClauseNode.getChild(1).getText()); } }
private ExpressionSegment extractExpression(final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext expressionNode) { Optional<ParserRuleContext> functionNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.FUNCTION_CALL); if (functionNode.isPresent()) { return extractFunctionExpressionSegment(functionNode.get()); } if (RuleName.COLUMN_NAME.getName().equals(expressionNode.getChild(0).getClass().getSimpleName())) { return extractPropertyExpressionSegment(expressionNode); } return extractCommonExpressionSegment(placeholderIndexes, expressionNode); }
/** * 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(); }
private void extractAndFillWhere(final FromWhereSegment fromWhereSegment, final Map<ParserRuleContext, Integer> placeholderIndexes, final ParserRuleContext whereNode) { Optional<OrConditionSegment> conditions = buildCondition((ParserRuleContext) whereNode.getChild(1), placeholderIndexes); if (conditions.isPresent()) { fromWhereSegment.getConditions().getAndConditions().addAll(conditions.get().getAndConditions()); } }
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); } } }
@Override public Optional<ColumnSelectItemSegment> extract(final ParserRuleContext expressionNode) { if (!RuleName.COLUMN_NAME.getName().equals(expressionNode.getChild(0).getClass().getSimpleName())) { return Optional.absent(); } ParserRuleContext columnNode = (ParserRuleContext) expressionNode.getChild(0); ColumnSelectItemSegment result = new ColumnSelectItemSegment(columnNode.getText(), columnNode.getStart().getStartIndex()); Optional<ParserRuleContext> aliasNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.ALIAS); if (aliasNode.isPresent()) { result.setAlias(aliasNode.get().getText()); } return Optional.of(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); }
/** * Parse SQL to AST. * * @return Abstract syntax tree of SQL */ public SQLAST parse() { ParseTree parseTree = SQLParserFactory.newInstance(databaseType, sql).execute().getChild(0); if (parseTree instanceof ErrorNode) { throw new SQLParsingUnsupportedException(String.format("Unsupported SQL of `%s`", sql)); } Optional<SQLStatementRule> sqlStatementRule = parsingRuleRegistry.findSQLStatementRule(databaseType, parseTree.getClass().getSimpleName()); if (!sqlStatementRule.isPresent()) { throw new SQLParsingUnsupportedException(String.format("Unsupported SQL of `%s`", sql)); } return new SQLAST((ParserRuleContext) parseTree, sqlStatementRule.get()); } }
@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)); }
private ExpressionSegment extractPropertyExpressionSegment(final ParserRuleContext expressionNode) { ParserRuleContext columnNode = (ParserRuleContext) expressionNode.getChild(0); Optional<ColumnSegment> columnSegment = new ColumnSegmentExtractor().extract(columnNode); Preconditions.checkState(columnSegment.isPresent()); return new PropertyExpressionSegment(columnSegment.get().getName(), columnSegment.get().getOwner().orNull(), columnNode.getStart().getStartIndex(), columnNode.getStop().getStopIndex()); }
@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); }
private LimitValueSegment createLimitValueSegment(final Map<ParserRuleContext, Integer> placeholderAndNodeIndexMap, final ParserRuleContext limitValueNode) { return Symbol.QUESTION.getLiterals().equals(limitValueNode.getText()) ? new PlaceholderLimitValueSegment(placeholderAndNodeIndexMap.get(limitValueNode.getChild(0)), ((ParserRuleContext) limitValueNode.getChild(0)).getStart().getStartIndex()) : new LiteralLimitValueSegment(NumberUtil.getExactlyNumber(limitValueNode.getText(), 10).intValue(), limitValueNode.getStart().getStartIndex()); } }
private ExpressionSegment extractFunctionExpressionSegment(final ParserRuleContext functionNode) { return new FunctionExpressionSegment(functionNode.getChild(0).getText(), functionNode.getStart().getStartIndex(), ((TerminalNode) functionNode.getChild(1)).getSymbol().getStartIndex(), functionNode.getStop().getStopIndex(), -1); }
private SelectItemSegment extractFunctionSelectItemSegment(final ParserRuleContext expressionNode, final ParserRuleContext functionNode) { String functionName = functionNode.getChild(0).getText(); Optional<AggregationType> aggregationType = findAggregationType(functionName); AliasAvailable result = aggregationType.isPresent() ? extractAggregationSelectItemSegment(aggregationType.get(), functionNode) : new ExpressionSelectItemSegment(functionNode.getText(), functionNode.getStart().getStartIndex(), functionNode.getStop().getStopIndex()); Optional<ParserRuleContext> aliasNode = ExtractorUtils.findFirstChildNode(expressionNode, RuleName.ALIAS); if (aliasNode.isPresent()) { result.setAlias(aliasNode.get().getText()); } return (SelectItemSegment) result; }