jdk1.8
mariadb connector 2.4.1
mysql 5.1.71 或者 mariadb 10.3.12
Description
用mysql的connector/j 不会报错
用mariadb的connector/j 会报错 [ERROR] 2019-05-30 09:36:02,452 com.lenovo.leapedge.utils.UpdateDatabasesByScript - sql执行错误
java.sql.SQLException: Parameter metadata not available for these statement Query: /**/ Parameters: []
at org.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:392)
at org.apache.commons.dbutils.QueryRunner.update(QueryRunner.java:491)
at org.apache.commons.dbutils.QueryRunner.update(QueryRunner.java:377)
at com.lenovo.leapedge.utils.UpdateDatabasesByScript.runTableScripts(UpdateDatabasesByScript.java:387)
at com.lenovo.leapedge.utils.UpdateDatabasesByScript.doUpdate(UpdateDatabasesByScript.java:219)
at com.lenovo.leapedge.EdgeMqttRunner.initDatabases(EdgeMqttRunner.java:93)
at com.lenovo.leapedge.EdgeMqttRunner.run(EdgeMqttRunner.java:63)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:797)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:781)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
at com.lenovo.leapedge.Application.main(Application.java:24)
Could you please elaborate on the issue ?
query was "/**/" ? If so error message "Parameter metadata not available for these statement" seems adequate, because server cannot return metadata for this query.
Diego Dupin
added a comment - Could you please elaborate on the issue ?
query was "/**/" ? If so error message "Parameter metadata not available for these statement" seems adequate, because server cannot return metadata for this query.
How the problem manifests itself: Apache Commons DbUtils are crashing when they try to execute a prepared statement with no parameters. For me it was just a "LOAD DATA INFILE '/tmp/data.txt' INTO TABLE mytable";
The problem lies in (I have version 2.6.0 of the mariadb java connector) in org.mariadb.jdbc.MariaDbParameterMetaData around line 77. When the AbstractQueryRunner:334 (of DbUtils) calls fillStatement() it tries to check the numbers of parameters.
DbUtils have some defensive code there. They check if getParameterMetaData() throws SQLFeatureNotSupportedException or returns null. MariaDB does not throw SQLFeatureNotSupportedException and does not return null. The jdbc implementations is considered okish and DbUtils tries to getParameterCount() which calls MariaDbParameterMetaData:77
Now the MariaDB connector calls checkAvailable() if parametersInformation == null then throws
{{ throw new SQLException("Parameter metadata not available for these statement", "S1C00");}}
What it has to be done (according to my opinion)
getParameterCount() should return 0 and do not throw exception.
I can try cook a patch if you agree with this behavior.
I am sure however that there is more to this than my naive approach but MySQL implementation seems to protect it. Not quite sure though about that. Probably the jdbc standard will have an opinion of its own on this.
Please consider altering this behaviour though. It hurts portability from MySQL.
Workaround
Instantiate the QueryRunner with a boolean set to true which sets the internal variable pmdKnownBroken in order to handle substandard jdbc drivers.
Vassilis Virvilis
added a comment - - edited Hi,
I can verify that and answer questions or try builds if required. I can probably try patches also.
The issue is also discussed in https://issues.apache.org/jira/browse/DBUTILS-117
How the problem manifests itself : Apache Commons DbUtils are crashing when they try to execute a prepared statement with no parameters. For me it was just a "LOAD DATA INFILE '/tmp/data.txt' INTO TABLE mytable";
The problem lies in (I have version 2.6.0 of the mariadb java connector) in org.mariadb.jdbc.MariaDbParameterMetaData around line 77. When the AbstractQueryRunner:334 (of DbUtils) calls fillStatement() it tries to check the numbers of parameters.
DbUtils have some defensive code there. They check if getParameterMetaData() throws SQLFeatureNotSupportedException or returns null. MariaDB does not throw SQLFeatureNotSupportedException and does not return null. The jdbc implementations is considered okish and DbUtils tries to getParameterCount() which calls MariaDbParameterMetaData:77
Now the MariaDB connector calls checkAvailable() if parametersInformation == null then throws
{{ throw new SQLException("Parameter metadata not available for these statement", "S1C00");}}
What it has to be done (according to my opinion)
getParameterCount() should return 0 and do not throw exception.
I can try cook a patch if you agree with this behavior.
I am sure however that there is more to this than my naive approach but MySQL implementation seems to protect it. Not quite sure though about that. Probably the jdbc standard will have an opinion of its own on this.
Please consider altering this behaviour though. It hurts portability from MySQL.
Workaround
Instantiate the QueryRunner with a boolean set to true which sets the internal variable pmdKnownBroken in order to handle substandard jdbc drivers.
For client (default) prepare statement, metadata are done by executing a "PREPARE" command and using the resulting metadata.
Problem is that a few commands, like LOAD DATA cmds.
Returns: the description of a ResultSet object's columns or null if the driver cannot return a ResultSetMetaData object
Driver has to return null in this specific case.
Diego Dupin
added a comment - For client (default) prepare statement, metadata are done by executing a "PREPARE" command and using the resulting metadata.
Problem is that a few commands, like LOAD DATA cmds.
Driver return a metadata object without any information, so that will throw an exception for all methods.
Acording to JDBC : https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/PreparedStatement.html#getMetaData( )
Returns: the description of a ResultSet object's columns or null if the driver cannot return a ResultSetMetaData object
Driver has to return null in this specific case.
In the same vain the query of the original reporter '/**/' is a valid SQL query with zero paramters. Why it should throw an exception when we ask the parameter count?
This works in MySQL and apparently in other JDBC drivers so I genuinely believe it is an implementation bug in MariaDB JDBC connector
I am willing to formally submit a patch and create a test case if you agree with it.
Thanks in advance
Vassilis Virvilis
added a comment - Hi thanks for answering and for the link.
I think there is a misunderstanding though.
You are speaking about ResultSetMetaData object while my issue is in the implementation of ParameterMetaData (MariaDbParameterMetaData).
Here is the code from Apache Commons DbUtils AbstractQueryRunner.java It can be found here: https://github.com/apache/commons-dbutils/blob/master/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java#L278
// check the parameter count, if we can
ParameterMetaData pmd = null ;
if (!pmdKnownBroken) {
try {
pmd = stmt.getParameterMetaData();
if (pmd == null ) { // can be returned by implementations that don't support the method
pmdKnownBroken = true ;
} else {
int stmtCount = pmd.getParameterCount(); // <----------------- IT CRASHSES HERE ********
int paramsCount = params == null ? 0 : params.length;
if (stmtCount != paramsCount) {
throw new SQLException( "Wrong number of parameters: expected "
+ stmtCount + ", was given " + paramsCount);
}
}
} catch (SQLFeatureNotSupportedException ex) {
pmdKnownBroken = true ;
}
// TODO see DBUTILS-117: would it make sense to catch any other SQLEx types here?
}
https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/ParameterMetaData.html#getParameterCount( ) does not indicate that it should throw an exception if there are no parameters. If there are no parameters the number of parameters returned should be 0 IMHO (implied not explicitely stated).
In the same vain the query of the original reporter '/**/' is a valid SQL query with zero paramters. Why it should throw an exception when we ask the parameter count?
This works in MySQL and apparently in other JDBC drivers so I genuinely believe it is an implementation bug in MariaDB JDBC connector
Here is the patch I propose:
diff --git a/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java b/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java
index e663eb85..73b53d2b 100644
--- a/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java
+++ b/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java
@@ - 75 , 8 + 75 , 7 @@ public class MariaDbParameterMetaData implements ParameterMetaData {
@Override
public int getParameterCount() throws SQLException {
- checkAvailable();
- return parametersInformation.length;
+ return ( this .parametersInformation != null ) ? parametersInformation.length : 0 ;
}
private ColumnDefinition getParameterInformation( int param) throws SQLException {
I am willing to formally submit a patch and create a test case if you agree with it.
Thanks in advance
Diego Dupin
added a comment - allright, i've added commit https://github.com/mariadb-corporation/mariadb-connector-j/commit/12af84fa31c2fc47280877b18a083ebe1e7be0db that at least permits parameterCount() for parameterMetadata (that's the only known data when query cannot be prepared).
You can test result using snapshot version:
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https: //oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version> 2.6 . 1 -SNAPSHOT</version>
</dependency>
</dependencies>
could you confirm that solve this issue ?
I also saw that you added a test case too. That will prevent it from breaking in the feature. Super cool !!!
Thanks a lot.
I really appreciate it.
Vassilis Virvilis
added a comment - Diego,
I confirm that it works.
I also saw that you added a test case too. That will prevent it from breaking in the feature. Super cool !!!
Thanks a lot.
I really appreciate it.
People
Diego Dupin
Xu Shilin
Votes:
0Vote for this issue
Watchers:
3Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":848.8000001907349,"ttfb":266.2000002861023,"pageVisibility":"visible","entityId":76457,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":1,"journeyId":"5fbfee65-144d-4cf4-91b7-66e751f28563","navigationType":0,"readyForUser":917.3000001907349,"redirectCount":0,"resourceLoadedEnd":579.7000002861023,"resourceLoadedStart":275.30000019073486,"resourceTiming":[{"duration":23.90000009536743,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":275.30000019073486,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":275.30000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":299.2000002861023,"responseStart":0,"secureConnectionStart":0},{"duration":24.399999618530273,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true&whisper-enabled=true","startTime":275.6000003814697,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":275.6000003814697,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":300,"responseStart":0,"secureConnectionStart":0},{"duration":185,"initiatorType":"script","name":"https://jira.mariadb.org/s/0917945aaa57108d00c5076fea35e069-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":275.80000019073486,"connectEnd":275.80000019073486,"connectStart":275.80000019073486,"domainLookupEnd":275.80000019073486,"domainLookupStart":275.80000019073486,"fetchStart":275.80000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":312.30000019073486,"responseEnd":460.80000019073486,"responseStart":337.2000002861023,"secureConnectionStart":275.80000019073486},{"duration":303.80000019073486,"initiatorType":"script","name":"https://jira.mariadb.org/s/2d8175ec2fa4c816e8023260bd8c1786-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true&whisper-enabled=true","startTime":275.90000009536743,"connectEnd":275.90000009536743,"connectStart":275.90000009536743,"domainLookupEnd":275.90000009536743,"domainLookupStart":275.90000009536743,"fetchStart":275.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":307.6000003814697,"responseEnd":579.7000002861023,"responseStart":333.30000019073486,"secureConnectionStart":275.90000009536743},{"duration":65.5,"initiatorType":"script","name":"https://jira.mariadb.org/s/a9324d6758d385eb45c462685ad88f1d-CDN/lu2cib/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":276.1000003814697,"connectEnd":276.1000003814697,"connectStart":276.1000003814697,"domainLookupEnd":276.1000003814697,"domainLookupStart":276.1000003814697,"fetchStart":276.1000003814697,"redirectEnd":0,"redirectStart":0,"requestStart":312.7000002861023,"responseEnd":341.6000003814697,"responseStart":340,"secureConnectionStart":276.1000003814697},{"duration":69.59999990463257,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":276.30000019073486,"connectEnd":276.30000019073486,"connectStart":276.30000019073486,"domainLookupEnd":276.30000019073486,"domainLookupStart":276.30000019073486,"fetchStart":276.30000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":315,"responseEnd":345.90000009536743,"responseStart":342.5,"secureConnectionStart":276.30000019073486},{"duration":69.09999990463257,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":276.6000003814697,"connectEnd":276.6000003814697,"connectStart":276.6000003814697,"domainLookupEnd":276.6000003814697,"domainLookupStart":276.6000003814697,"fetchStart":276.6000003814697,"redirectEnd":0,"redirectStart":0,"requestStart":314.80000019073486,"responseEnd":345.7000002861023,"responseStart":341.80000019073486,"secureConnectionStart":276.6000003814697},{"duration":30.40000009536743,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2cib/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":276.80000019073486,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":276.80000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":307.2000002861023,"responseStart":0,"secureConnectionStart":0},{"duration":69.40000009536743,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":276.90000009536743,"connectEnd":276.90000009536743,"connectStart":276.90000009536743,"domainLookupEnd":276.90000009536743,"domainLookupStart":276.90000009536743,"fetchStart":276.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":316,"responseEnd":346.30000019073486,"responseStart":343.40000009536743,"secureConnectionStart":276.90000009536743},{"duration":33.700000286102295,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":277,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":277,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":310.7000002861023,"responseStart":0,"secureConnectionStart":0},{"duration":70.2999997138977,"initiatorType":"script","name":"https://jira.mariadb.org/s/5d5e8fe91fbc506585e83ea3b62ccc4b-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":277.2000002861023,"connectEnd":277.2000002861023,"connectStart":277.2000002861023,"domainLookupEnd":277.2000002861023,"domainLookupStart":277.2000002861023,"fetchStart":277.2000002861023,"redirectEnd":0,"redirectStart":0,"requestStart":316.30000019073486,"responseEnd":347.5,"responseStart":344.30000019073486,"secureConnectionStart":277.2000002861023},{"duration":247.80000019073486,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":278,"connectEnd":278,"connectStart":278,"domainLookupEnd":278,"domainLookupStart":278,"fetchStart":278,"redirectEnd":0,"redirectStart":0,"requestStart":332.80000019073486,"responseEnd":525.8000001907349,"responseStart":520,"secureConnectionStart":278},{"duration":196,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":331.30000019073486,"connectEnd":331.30000019073486,"connectStart":331.30000019073486,"domainLookupEnd":331.30000019073486,"domainLookupStart":331.30000019073486,"fetchStart":331.30000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":353.30000019073486,"responseEnd":527.3000001907349,"responseStart":523.6000003814697,"secureConnectionStart":331.30000019073486},{"duration":169.2000002861023,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":607,"connectEnd":607,"connectStart":607,"domainLookupEnd":607,"domainLookupStart":607,"fetchStart":607,"redirectEnd":0,"redirectStart":0,"requestStart":741,"responseEnd":776.2000002861023,"responseStart":775.3000001907349,"secureConnectionStart":607},{"duration":141.80000019073486,"initiatorType":"script","name":"https://www.google-analytics.com/analytics.js","startTime":842.4000000953674,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":842.4000000953674,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":984.2000002861023,"responseStart":0,"secureConnectionStart":0},{"duration":125.59999990463257,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":848.8000001907349,"connectEnd":848.8000001907349,"connectStart":848.8000001907349,"domainLookupEnd":848.8000001907349,"domainLookupStart":848.8000001907349,"fetchStart":848.8000001907349,"redirectEnd":0,"redirectStart":0,"requestStart":938.1000003814697,"responseEnd":974.4000000953674,"responseStart":973.4000000953674,"secureConnectionStart":848.8000001907349}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":93,"responseStart":267,"responseEnd":331,"domLoading":270,"domInteractive":1027,"domContentLoadedEventStart":1027,"domContentLoadedEventEnd":1076,"domComplete":1265,"loadEventStart":1265,"loadEventEnd":1266,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":987.1000003814697},{"name":"bigPipe.sidebar-id.end","time":988},{"name":"bigPipe.activity-panel-pipe-id.start","time":988.1000003814697},{"name":"bigPipe.activity-panel-pipe-id.end","time":992.1000003814697},{"name":"activityTabFullyLoaded","time":1096.2000002861023}],"measures":[],"correlationId":"c328953b6b3a16","effectiveType":"4g","downlink":10,"rtt":0,"serverDuration":109,"dbReadsTimeInMs":10,"dbConnsTimeInMs":20,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
Could you please elaborate on the issue ?
query was "/**/" ? If so error message "Parameter metadata not available for these statement" seems adequate, because server cannot return metadata for this query.