SQLパラメータの解析

@param sql 解析対象SQL
@return SQLを解析して取得したパラメータキーのセット
5818
public static Set<String> getSqlParams(final String sql) {
		SqlParser parser = new SqlParserImpl(sql);
		ContextTransformer transformer = parser.parse();
		Node rootNode = transformer.getRoot();

		Set<String> params = new LinkedHashSet<>();
		traverseNode(rootNode, params);
		params.removeIf(s -> CONSTANT_PAT.matcher(s).matches());
		return params;
	}
506681
@Override
	public SqlContext createSqlContext() {
		SqlContextImpl sqlContext = new SqlContextImpl();
		Map<String, Parameter> paramMap = new ConcurrentHashMap<>(getConstParameterMap());

		// 自動バインド用パラメータ生成クラスが指定されている場合は、そこで生成されたパラメータをパラメータマップに追加する
		if (autoBindParameterCreators != null && !autoBindParameterCreators.isEmpty()) {
			for (AutoBindParameterCreator creator : getAutoBindParameterCreators()) {
				Map<String, Parameter> bindMap = creator.getBindParameterMap();
				if (bindMap != null && !bindMap.isEmpty()) {
					paramMap.putAll(bindMap);
				}
			}
		}

		sqlContext.setConstParameterMap(paramMap);
		sqlContext.setSqlFilterManager(getSqlFilterManager());
		sqlContext.setParameterMapperManager(new BindParameterMapperManager(parameterMapperManager));
		sqlContext.setQueryAutoParameterBinder(queryAutoParameterBinder);
		sqlContext.setUpdateAutoParameterBinder(updateAutoParameterBinder);

		return sqlContext;
	}
808692
public static Predicate is(final String sql) {
        return new Predicate() {
            public String toSql() {
                return sql;
            }
            public void init(AbstractSqlCreator creator) {
            }
        };
    }
343621
public static function getSqlWithParams(string $sql, array $params = []): string
    {
        if (! empty($params)) {
            $indexed = ($params === array_values($params));
            foreach ($params as $k => $v) {
                if (is_string($v)) {
                    $v = "'${v}'";
                }
                if (is_array($v)) {
                    $v = "'" . implode("','", $v) . "'";
                }
                if ($indexed) {
                    $sql = preg_replace('/\?/', $v, $sql, 1);
                } else {
                    $sql = str_replace(":${k}", $v, $sql);
                }
            }
        }

        return str_replace(PHP_EOL, '', $sql);
    }
1110524
public String[] getColumnsBySql(Sql sql) throws SQLException {
		String columns[] = null;
		
		List<Map<String, String>> table = getMetadataBySql(sql);
		if (table != null) {
			columns = new String[table.size()];
			for (int i = 0 ; i < table.size() ; i++) {
				Map<String, String> row = table.get(i);
				if (row.containsKey("NAME") && row.get("NAME") != null) {
					columns[i] = row.get("NAME");
				}
			}
		}
		
		return columns;
	}
1148107
protected String nullify(String sql) {
        /*
         * Some drivers (Oracle classes12.zip) have difficulty resolving data
         * type if setObject(null). We will modify the query to pass 'null', 'is
         * null', and 'is not null'
         */
        //could be more efficient by compiling expressions in advance.
        int firstWhere = findWhereKeyword(sql);
        if (firstWhere >= 0) {
            Pattern[] patterns = {Pattern.compile("(?is)^(.{" + firstWhere + "}.*?)!=\\s{0,1}(\\s*)\\?'\"\\?(.*)"),
                    Pattern.compile("(?is)^(.{" + firstWhere + "}.*?)<>\\s{0,1}(\\s*)\\?'\"\\?(.*)"),
                    Pattern.compile("(?is)^(.{" + firstWhere + "}.*?[^<>])=\\s{0,1}(\\s*)\\?'\"\\?(.*)"),};
            String[] replacements = {"$1 is not $2null$3", "$1 is not $2null$3", "$1 is $2null$3",};
            for (int i = 0; i < patterns.length; i++) {
                Matcher matcher = patterns[i].matcher(sql);
                while (matcher.matches()) {
                    sql = matcher.replaceAll(replacements[i]);
                    matcher = patterns[i].matcher(sql);
                }
            }
        }
        return sql.replaceAll("\\?'\"\\?", "null");
    }
1094228
private void get(final StringBuilder sql) {
        sql.append("SELECT * FROM ").append(getName()).append(" WHERE ").append(JdbcRepositories.getDefaultKeyName()).append(" = ?");
    }
326157
public String subQuery(String sql) {
    if (options.maxQuerySizeToLog > 0 && sql.length() > options.maxQuerySizeToLog - 3) {
      return sql.substring(0, options.maxQuerySizeToLog - 3) + "...";
    }
    return sql;
  }
791273
public static String converToOrderBySql(String sql, String orderBy) {
        //解析SQL
        Statement stmt = null;
        try {
            stmt = CCJSqlParserUtil.parse(sql);
            Select select = (Select) stmt;
            SelectBody selectBody = select.getSelectBody();
            //处理body-去最外层order by
            List<OrderByElement> orderByElements = extraOrderBy(selectBody);
            String defaultOrderBy = PlainSelect.orderByToString(orderByElements);
            if (defaultOrderBy.indexOf('?') != -1) {
                throw new PageException("原SQL[" + sql + "]中的order by包含参数，因此不能使用OrderBy插件进行修改!");
            }
            //新的sql
            sql = select.toString();
        } catch (Throwable e) {
            throw new PageException("处理排序失败: " + e, e);
        }
        return sql + " order by " + orderBy;
    }
340501
function sqlParams(sql, params)
{
  var args = [];

  var keys = sql.match(/@\w+/g);
  var aKeys = sql.match(/\$\d+/g);

  if (keys && aKeys)
    throw new Error(
      'Cannot use both array-style and object-style parametric values');

  // Array-style (native)
  if (aKeys) {
    return { text: sql, values: params };
  }

  // No params
  if (!keys) {
    return { text: sql, values: [] };
  }

  var n = 1;
  keys.forEach(function(key) {
    key = key.substr(1);
    var val = params[key];
    if (val === undefined)
      throw new Error('No value for @' + key + ' provided');
    args.push(val);
    sql = sql.replace('@' + key, '$' + n++);
  });

  return { text: sql, values: args };
}
968821
public Object querySingleResult(String sql, String[] args, int column) {
		return querySingleResult(sql, args, column, null);
	}
1255888
public static List<Map<String, Object>> getListMap(String sql, Object... arg) {
        Connection connection = JDBCUtils.getConnection();
        PreparedStatement ps = null;
        ResultSet result = null;
        List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
        try {
            ps = connection.prepareStatement(sql);
            for (int i = 0; i < arg.length; i++) {
                ps.setObject(i + 1, arg[i]);
            }

            result = ps.executeQuery();
            listMap = DBUtils.handleResultSetToMapList(result, listMap);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(result, ps, connection);
        }
        return listMap;
    }
1149415
private String createCountSql(String sql) {
        StringBuilder sb = new StringBuilder("select count(0) from ( ");
        sb.append(sql).append(" ) as t");
        return sb.toString();
    }
104823
public static QueryAction create(Client client, String sql) throws SqlParseException, SQLFeatureNotSupportedException {
		sql = sql.replaceAll("\n"," ");
        String firstWord = sql.substring(0, sql.indexOf(' '));
        switch (firstWord.toUpperCase()) {
			case "SELECT":
			    //zhongshu-comment 将sql字符串解析成AST，即SQLQueryExpr sqlExpr就是AST了，下面的代码就开始访问AST、从中获取token
				SQLQueryExpr sqlExpr = (SQLQueryExpr) toSqlExpr(sql);
                if(isMulti(sqlExpr)){//zhongshu-comment 判断是不是union查询，union查询两个select语句，btw：子查询也有多个select语句，至少2个
                    MultiQuerySelect multiSelect = new SqlParser().parseMultiSelect((SQLUnionQuery) sqlExpr.getSubQuery().getQuery());
                    handleSubQueries(client,multiSelect.getFirstSelect());
                    handleSubQueries(client,multiSelect.getSecondSelect());
                    return new MultiQueryAction(client, multiSelect);
                }
                else if(isJoin(sqlExpr,sql)){//zhongshu-comment join连接查询
                    JoinSelect joinSelect = new SqlParser().parseJoinSelect(sqlExpr);
                    handleSubQueries(client, joinSelect.getFirstTable());
                    handleSubQueries(client, joinSelect.getSecondTable());
                    return ESJoinQueryActionFactory.createJoinAction(client, joinSelect);
                }
                else {
                    //zhongshu-comment 大部分查询都是走这个分支，先看懂这个分支
                    Select select = new SqlParser().parseSelect(sqlExpr);
                    //todo 看不懂，测试了好几个常见的sql，都没有进去handleSubQueries该方法，那就先不理了，看别的
                    handleSubQueries(client, select);
                    return handleSelect(client, select);
                }
			case "DELETE":
                SQLStatementParser parser = createSqlStatementParser(sql);
				SQLDeleteStatement deleteStatement = parser.parseDeleteStatement();
				Delete delete = new SqlParser().parseDelete(deleteStatement);
				return new DeleteQueryAction(client, delete);
            case "SHOW":
                return new ShowQueryAction(client,sql);
			default:
				throw new SQLFeatureNotSupportedException(String.format("Unsupported query: %s", sql));
		}
	}
1034611
public ClientSidePreparedStatement clientPrepareStatement(final String sql)
      throws SQLException {
    return new ClientSidePreparedStatement(this,
        sql,
        ResultSet.TYPE_FORWARD_ONLY,
        ResultSet.CONCUR_READ_ONLY,
        Statement.RETURN_GENERATED_KEYS);
  }
1033627
private Parameter getBindParameter(final String paramName) {
		// メソッド呼び出しかどうかで処理を振り分け
		if (paramName.contains(".") && paramName.contains("(") && paramName.contains(")")) {
			// メソッド呼び出しの場合は、SqlParserで値を評価するタイミングでparameterをaddしているので、そのまま返却する
			return parameterMap.get(paramName);
		} else {
			String[] keys = StringUtils.split(paramName, ".");
			String baseName = keys[0];

			Parameter parameter = parameterMap.get(baseName);
			if (parameter == null) {
				return null;
			}

			if (keys.length > 1) {
				String propertyName = keys[1];
				return parameter.createSubParameter(propertyName);
			}

			return parameter;
		}
	}
637537
public Page<T> page(String sql, List<Object> paramValues, PageRow pageRow) {
        return this.page(sql, paramValues.toArray(), pageRow);
    }