I found that my database recently started generating extra backslashes
on round-trips to the database.
The reason seems to be a change to standards_conforming_strings variable in postgresl
Beginning in PostgreSQL 9.1, the default is on (prior releases defaulted to off)
https://stackoverflow.com/a/
3049139
* I created a new protocol function (database-escape-backslashes database)
* I changed the the generic mysql and postgres databases to return T
* I made the postgresql-socket3 backend check for standards_conforming_string
which is exposed in the underlying cl-postgres connection
* It seems likely that postgresql-socket3 could always return NIL, as
cl-postgres would probably handle this escaping anyway
This replaced some special case code in (database-output-sql (string
database))
+2018-04-08 Russ Tyndall <russ@acceleration.net>
+ * sql/db-interface, expressions, fdml, generic-postgres
+ db-mysql/mysql-sql.lisp db-postgresql-socket3/sql.lisp
+
+ - I created a new protocol function (database-escape-backslashes
+ database)
+ - I changed the the generic mysql and postgres databases
+ to return T
+ - I made the postgresql-socket3 backend check for
+ standards_conforming_string which is exposed in the underlying
+ cl-postgres connection
+ - It seems likely that postgresql-socket3 could always return NIL, as
+ cl-postgres would probably handle this escaping anyway
+
+ This replaced some special case code in (database-output-sql (string
+ database))
+
+
2018-02-04 Russ Tyndall <russ@acceleration.net>
* sql/generic-postgres.lisp:
Wall times default to being timestamptz in postgresql now.
(when (clsql-sys:database-type-library-loaded :mysql)
(clsql-sys:initialize-database-type :database-type :mysql))
+
+(defmethod clsql-sys::database-escape-backslashes ((database mysql-database))
+ t)
(clsql-sys:initialize-database-type :database-type :postgresql-socket3))
+
+;; TODO: there is a good chance this could always return nil as cl-postgres probably
+;; handles this nonsense anyway
+(defmethod clsql-sys::database-escape-backslashes ((database postgresql-socket3-database))
+ (let* ((it (gethash "standard_conforming_strings"
+ (cl-postgres:connection-parameters
+ (slot-value database 'connection))))
+ (sit (and it (string it))))
+ (and it (not (string-equal sit "on")))))
--- /dev/null
+I found that my database recently started generating extra backslashes
+on roundtrips to the database.
+
+The reason seems to be a change to standards_conforming_strings variable in postgresl
+Beginning in PostgreSQL 9.1, the default is on (prior releases defaulted to off)
+
+
+https://stackoverflow.com/a/3049139
+
+ * I created a new protocol function (database-escape-backslashes database)
+ * I changed the the generic mysql and postgres databases to return T
+ * I made the postgresql-socket-3 backend check for standards_conforming_string
+ which is exposed in the underlying cl-postgres connection
+ * It seems likely that postgresql-socket-3 could always return NIL, as
+ cl-postgres would probably handle this escaping anyway
"Adds the pathspec PATH \(which should denote a directory) to
the list *FOREIGN-LIBRARY-SEARCH-PATHS*."
(pushnew path *foreign-library-search-paths* :test #'equal))
+
+(defgeneric database-escape-backslashes (database)
+ (:documentation "Should backslases in a string be escaped? ")
+ (:method ( database )
+ nil))
(defmethod output-sql ((expr sql-assignment-exp) database)
(with-slots (operator sub-expressions)
- expr
- (do ((sub sub-expressions (cdr sub)))
- ((null (cdr sub)) (output-sql (car sub) database))
- (output-sql (car sub) database)
+ expr
+ (output-sql (car sub-expressions) database)
+ (dolist (sub (cdr sub-expressions))
(write-char #\Space *sql-stream*)
(%write-operator operator database)
- (write-char #\Space *sql-stream*)))
+ (write-char #\Space *sql-stream*)
+ (output-sql sub database)))
t)
(defclass sql-value-exp (%sql-expression)
(setf (aref buf j) #\'))
((and (char= char #\\)
;; MTP: only escape backslash with pgsql/mysql
- (member (database-underlying-type database)
- '(:postgresql :mysql)
- :test #'eq))
+ (database-escape-backslashes database))
(setf (aref buf j) #\\)
(incf j)
(setf (aref buf j) #\\))
(values))
(defmethod execute-command ((expr %sql-expression)
- &key (database *default-database*))
- (execute-command (sql-output expr database) :database database)
+ &key (database *default-database*)
+ &aux (str-sql (sql-output expr database)))
+ (execute-command str-sql :database database)
(values))
(defmethod query ((query-expression string) &key (database *default-database*)
(defmethod db-type-has-auto-increment? ((db-type (eql :postgresql)))
t)
+
+(defmethod clsql-sys::database-escape-backslashes ((database generic-postgresql-database))
+ t)