seancorfield / next-jdbc

A modern low-level Clojure wrapper for JDBC-based access to databases.
https://cljdoc.org/d/com.github.seancorfield/next.jdbc/
Eclipse Public License 1.0
760 stars 90 forks source link

Illegal reflective access by org.postgresql.jdbc.TimestampUtils #142

Closed curioustolearn closed 3 years ago

curioustolearn commented 3 years ago

Describe the bug

I get the following error/warning when trying to execute the command below using next.jdbc on postgresql.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.postgresql.jdbc.TimestampUtils (file:/Users/myusername/.m2/repository/org/postgresql/postgresql/42.1.4/postgresql-42.1.4.jar) to field java.util.TimeZone.defaultTimeZone
WARNING: Please consider reporting this to the maintainers of org.postgresql.jdbc.TimestampUtils
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

To Reproduce

(def ds-postgres 
  (jdbc/get-datasource {:dbtype "postgres" :dbname "postgres"}))

;; The following command throws the above warnings. It does drop the database. 
(defn clear-db 
  []
  (with-open [con (jdbc/get-connection ds-postgres)]
    (jdbc/execute! con ["DROP DATABASE IF EXISTS mydb"]))
  )

project.clj/deps.edn

{:paths ["src"]
 :deps {org.clojure/clojure {:mvn/version "1.10.1"}
        org.clojure/tools.cli {:mvn/version "1.0.194"}
        commons-io/commons-io {:mvn/version "2.6"}
        seancorfield/next.jdbc {:mvn/version "1.1.588"}
        org.postgresql/postgresql {:mvn/version "42.1.4"}}}

Environment (please complete the following information):

seancorfield commented 3 years ago

As it says in the warning "Please consider reporting this to the maintainers of org.postgresql.jdbc.TimestampUtils" -- that is not next.jdbc, that is the PostgreSQL driver itself, so you're reporting the warning against the wrong library.

The latest version of that library is 42.2.16 (next.jdbc is tested currently against 42.2.10) so if you update to the latest driver version, I suspect that warning will go away.

curioustolearn commented 3 years ago

@seancorfield So sorry for not reading it carefully. You were right. Upgrading fixed that issue. If I run the code as posted above, it runs without any errors.

However, if I try to use ? and pass dbname as a parameter, then I get an error. Please let me know if this needs to be filed as a separate issue.

New function

(def ds-postgres 
  (jdbc/get-datasource {:dbtype "postgres" :dbname "postgres"}))

(defn clear-db 
  [dbname]
  (with-open [con (jdbc/get-connection ds-postgres)]
    (jdbc/execute! con ["DROP DATABASE IF EXISTS ?" dbname]))
  )

Full error

{:clojure.main/message
 "Execution error (PSQLException) at org.postgresql.core.v3.QueryExecutorImpl/receiveErrorResponse (QueryExecutorImpl.java:2510).\nERROR: syntax error at or near \"$1\"\n  Position: 25\n",
 :clojure.main/triage
 {:clojure.error/class org.postgresql.util.PSQLException,
  :clojure.error/line 2510,
  :clojure.error/cause
  "ERROR: syntax error at or near \"$1\"\n  Position: 25",
  :clojure.error/symbol
  org.postgresql.core.v3.QueryExecutorImpl/receiveErrorResponse,
  :clojure.error/source "QueryExecutorImpl.java",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type org.postgresql.util.PSQLException,
    :message "ERROR: syntax error at or near \"$1\"\n  Position: 25",
    :at
    [org.postgresql.core.v3.QueryExecutorImpl
     receiveErrorResponse
     "QueryExecutorImpl.java"
     2510]}],
  :trace
  [[org.postgresql.core.v3.QueryExecutorImpl
    receiveErrorResponse
    "QueryExecutorImpl.java"
    2510]
   [org.postgresql.core.v3.QueryExecutorImpl
    processResults
    "QueryExecutorImpl.java"
    2245]
   [org.postgresql.core.v3.QueryExecutorImpl
    execute
    "QueryExecutorImpl.java"
    311]
   [org.postgresql.jdbc.PgStatement
    executeInternal
    "PgStatement.java"
    447]
   [org.postgresql.jdbc.PgStatement execute "PgStatement.java" 368]
   [org.postgresql.jdbc.PgPreparedStatement
    executeWithFlags
    "PgPreparedStatement.java"
    159]
   [org.postgresql.jdbc.PgPreparedStatement
    execute
    "PgPreparedStatement.java"
    148]
   [next.jdbc.result_set$stmt__GT_result_set
    invokeStatic
    "result_set.clj"
    631]
   [next.jdbc.result_set$stmt__GT_result_set
    invoke
    "result_set.clj"
    626]
   [next.jdbc.result_set$eval2341$fn__2349 invoke "result_set.clj" 837]
   [next.jdbc.protocols$eval1262$fn__1293$G__1253__1302
    invoke
    "protocols.clj"
    33]
   [next.jdbc$execute_BANG_ invokeStatic "jdbc.clj" 237]
   [next.jdbc$execute_BANG_ invoke "jdbc.clj" 224]
   [restoredb$clear_db invokeStatic "restoredb.clj" 38]
   [restoredb$clear_db invoke "restoredb.clj" 35]
   [restoredb$_main invokeStatic "restoredb.clj" 137]
   [restoredb$_main doInvoke "restoredb.clj" 134]
   [clojure.lang.RestFn invoke "RestFn.java" 397]
   [clojure.lang.AFn applyToHelper "AFn.java" 152]
   [clojure.lang.RestFn applyTo "RestFn.java" 132]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.core$apply invokeStatic "core.clj" 665]
   [clojure.main$main_opt invokeStatic "main.clj" 514]
   [clojure.main$main_opt invoke "main.clj" 510]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause "ERROR: syntax error at or near \"$1\"\n  Position: 25"}}
seancorfield commented 3 years ago

Not a bug: that's just not something you cannot do in SQL (JDBC) -- which is why the exception is coming from the PostgreSQL driver and is a syntax error in your SQL.

curioustolearn commented 3 years ago

@seancorfield Thank you. I am sorry to bug you again. But I don't understand what you mean by that you cannot do it in SQL. The command is valid, right? It runs when I don't pass the DBNAME as a parameter, but include it in the String. Are you saying that for that specific command, one cannot use parameters? Because we can use parameters like that for INSERT and SELECT etc. Thanks a million.

seancorfield commented 3 years ago

GitHub issues are not a great place to learn about SQL and DDL and JDBC issues -- you'd do much better to join either the Clojurians Slack or the Clojurians Zulip Chat and ask questions there in real-time. There are #sql channels/streams on both of those services for questions like this.

DDL, in general, cannot be parameterized. SQL can. The error says:

ERROR: syntax error at or near \"$1\"\n  Position: 25

and that is coming from the database itself, via the PostgreSQL driver, and it says you cannot have a parameter in this statement (the DROP statement).

curioustolearn commented 3 years ago

Thank you very much. I appreciate your response. I thought of continuing the conversation there, but was not sure whether that would have made it more inconvenient for you (since the context would be lost). Thanks and I will remember to ask there next time.