@Override
            public void replacement(Align align, List<AnnotationBo> annotationBoList) {
                AnnotationBo sqlIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.SQL_ID.getCode());
                if (sqlIdAnnotation == null) {
                    return;
                }
                if (metaDataFilter != null && metaDataFilter.filter(align, MetaData.SQL)) {
                    AnnotationBo annotationBo = metaDataFilter.createAnnotationBo(align, MetaData.SQL);
                    annotationBoList.add(annotationBo);
                    return;
                }

                final IntStringStringValue sqlValue = (IntStringStringValue) sqlIdAnnotation.getValue();

                final int sqlId = sqlValue.getIntValue();
                final String sqlParam = sqlValue.getStringValue1();
                final String bindValue = sqlValue.getStringValue2();

                List<SqlMetaDataBo> sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(align.getAgentId(), align.getAgentStartTime(), sqlId);

                final int size = sqlMetaDataList.size();
                if (size == 0) {
                    String errorMessage = "SQL-ID not found sqlId:" + sqlId;
                    AnnotationBo api = AnnotationBo.of(AnnotationKey.SQL.getCode(), errorMessage);
                    annotationBoList.add(api);
                } else if (size == 1) {
                    final SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(0);
                    if (StringUtils.isEmpty(sqlParam)) {
                        AnnotationBo sqlMeta = AnnotationBo.of(AnnotationKey.SQL_METADATA.getCode(), sqlMetaDataBo.getSql());
                        annotationBoList.add(sqlMeta);
                        AnnotationBo sql = AnnotationBo.of(AnnotationKey.SQL.getCode(), StringUtils.trim(sqlMetaDataBo.getSql()));
                        annotationBoList.add(sql);
                    } else {
                        final String rippedSql = sqlMetaDataBo.getSql();

                        logger.debug("sqlMetaDataBo:{}", sqlMetaDataBo);
                        List<String> parsedOutputParams = outputParameterParser.parseOutputParameter(sqlParam);
                        logger.debug("outputParams:{}, parsedOutputParams:{}", sqlParam, parsedOutputParams);
                        String originalSql = sqlNormalizer.combineOutputParams(rippedSql, parsedOutputParams);
                        logger.debug("outputParams:{}, originalSql:{}", sqlParam, originalSql);

                        AnnotationBo sqlMeta = AnnotationBo.of(AnnotationKey.SQL_METADATA.getCode(), rippedSql);
                        annotationBoList.add(sqlMeta);
                        AnnotationBo sql = AnnotationBo.of(AnnotationKey.SQL.getCode(), StringUtils.trim(originalSql));
                        annotationBoList.add(sql);
                    }
                } else {
                    // TODO need a separate test case to test for hashCode collision (probability way too low for easy replication)
                    String collisionSqlIdCodeMessage = "Collision Sql sqlId:" + sqlId + "\n" +
                            sqlMetaDataList.stream()
                                    .map(SqlMetaDataBo::getSql)
                                    .collect(Collectors.joining("or\n"));
                    AnnotationBo api = AnnotationBo.of(AnnotationKey.SQL.getCode(), collisionSqlIdCodeMessage);
                    annotationBoList.add(api);
                }

                // add if bindValue exists
                if (StringUtils.isNotEmpty(bindValue)) {
                    AnnotationBo bindValueAnnotation = AnnotationBo.of(AnnotationKey.SQL_BINDVALUE.getCode(), bindValue);
                    annotationBoList.add(bindValueAnnotation);
                }
            }
@author emeroad
@author jaehong.kim
@author minwoo.jung
web/src/main/java/com/navercorp/pinpoint/web/service/SpanServiceImpl.java