Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当函数+列名中存在'`'防止关键字时处理出错。 #387

Closed
Anricx opened this issue Sep 24, 2017 · 4 comments
Closed

当函数+列名中存在'`'防止关键字时处理出错。 #387

Anricx opened this issue Sep 24, 2017 · 4 comments

Comments

@Anricx
Copy link

Anricx commented Sep 24, 2017

建议调整下处理结果列名策略,保证兼容性

Which version of Sharding-Jdbc do you using?

1.5.4.1

Expected behavior

NO ERROR!

Actual behavior

Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'COUNT(`status`)' from result set.  Cause: java.lang.NullPointerException
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:68)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createPrimitiveResultObject(DefaultResultSetHandler.java:720)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:607)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:586)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:388)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:347)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:322)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:295)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:192)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
	... 17 more
Caused by: java.lang.NullPointerException
	at com.dangdang.ddframe.rdb.sharding.merger.common.AbstractMemoryResultSetMerger.getValue(AbstractMemoryResultSetMerger.java:64)
	at com.dangdang.ddframe.rdb.sharding.jdbc.core.resultset.ShardingResultSet.getInt(ShardingResultSet.java:100)
	at org.apache.ibatis.type.IntegerTypeHandler.getNullableResult(IntegerTypeHandler.java:37)
	at org.apache.ibatis.type.IntegerTypeHandler.getNullableResult(IntegerTypeHandler.java:26)
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:66)
	... 40 more

Steps to reproduce the behavior

数据库层添加统计方法不为结果添加别名

    <select id="count" resultType="java.lang.Integer">
        SELECT
         COUNT(`status`)
        FROM t_order
    </select>

Please provide the reproduce example codes (such as github link) if possible.

private Map<String, Integer> getColumnLabelIndexMap(ResultSet resultSet) throws SQLException {
        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
        Map<String, Integer> result = new TreeMap(String.CASE_INSENSITIVE_ORDER);

        for(int i = 1; i <= resultSetMetaData.getColumnCount(); ++i) {
            result.put(SQLUtil.getExactlyValue(resultSetMetaData.getColumnLabel(i)), i);
        }

        return result;
    }
@haocao
Copy link
Member

haocao commented Sep 27, 2017

请在github上提供完整重现DEMO,以便跟进调试。

@Anricx
Copy link
Author

Anricx commented Sep 28, 2017

sharding-jdbc-example-mybatis.zip

请参考。

@Anricx
Copy link
Author

Anricx commented Sep 28, 2017

由于底层解析ResultSetMetaData时将查询中的‘’符号去掉了,所以在this.labelAndIndexMap中世纪存储的列名变成了 COUNT(status) , 实际在AbstractMemoryResultSetMerger中getValue方法在从this.labelAndIndexMap取对应列时使用的列名为查询SQL中的 COUNT(status`) 导致未找到列触发了错误。

  1. 当然SQL应该这里加上别名,就不会有这个错误。
  2. 我以为最佳的解决方案或许是在SQLUtil.getExactlyValue中如果是聚合函数中的是否就可以考虑不要移除特殊符号?尽量在最终将结果集返回最终字段才做转换。

@terrymanu terrymanu changed the title 当列名中存在'`'防止关键字时处理出错。 当函数+列名中存在'`'防止关键字时处理出错。 Oct 9, 2017
@terrymanu
Copy link
Member

fixed at 2.0.0.m1

terrymanu added a commit that referenced this issue Oct 10, 2017
@terrymanu terrymanu self-assigned this Aug 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants