From 23d8cfb9ce950f12b80314a9840a637177178e29 Mon Sep 17 00:00:00 2001 From: "Michael R. Mauger" Date: Sat, 20 Apr 2019 20:13:56 -0400 Subject: [PATCH] * lisp/progmodes.sql.el (sql-product-alist): Corrected :terminator defns. (sql-debug-send): New variable. (sql-send-string): Use it and correct buffer context. (sql-send-magic-terminator): Use `sql-input-sender'. (sql-placeholders-filter): Bug#11481 Don't recursively replace placeholders * test/lisp/progmodes/sql-tests.el (sql-test-placeholder-filter): Test placeholder functionality. --- lisp/progmodes/sql.el | 42 +++++++++++++++++--------------- test/lisp/progmodes/sql-tests.el | 34 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 4ab174d92b9..fa9354e012e 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@ -223,6 +223,7 @@ ;; Simen Heggestøyl -- Postgres database completion ;; Robert Cochran -- MariaDB support ;; Alex Harsanyi -- sql-indent package and support +;; Roy Mathew -- bug in `sql-send-string' ;; @@ -477,7 +478,7 @@ file. Since that is a plaintext file, this could be dangerous." :prompt-cont-regexp "^\\(?:[ ][ ][1-9]\\|[ ][1-9][0-9]\\|[1-9][0-9]\\{2\\}\\)[ ]\\{2\\}" :statement sql-oracle-statement-starters :syntax-alist ((?$ . "_") (?# . "_")) - :terminator ("\\(^/\\|;\\)$" . "/") + :terminator ("\\(^/\\|;\\)" . "/") :input-filter sql-placeholders-filter) (postgres @@ -495,7 +496,7 @@ file. Since that is a plaintext file, this could be dangerous." :prompt-length 5 :prompt-cont-regexp "^[[:alnum:]_]*[-(][#>] " :input-filter sql-remove-tabs-filter - :terminator ("\\(^\\s-*\\\\g$\\|;\\)" . "\\g")) + :terminator ("\\(^\\s-*\\\\g\\|;\\)" . "\\g")) (solid :name "Solid" @@ -520,8 +521,7 @@ file. Since that is a plaintext file, this could be dangerous." :completion-object sql-sqlite-completion-object :prompt-regexp "^sqlite> " :prompt-length 8 - :prompt-cont-regexp "^ \\.\\.\\.> " - :terminator ";") + :prompt-cont-regexp "^ \\.\\.\\.> ") (sybase :name "Sybase" @@ -3640,12 +3640,16 @@ Inserts SELECT or commas if appropriate." Placeholders are words starting with an ampersand like &this." (when sql-oracle-scan-on - (while (string-match "&?&\\(\\(?:\\sw\\|\\s_\\)+\\)[.]?" string) - (setq string (replace-match - (read-from-minibuffer - (format "Enter value for %s: " (match-string 1 string)) - nil nil nil 'sql-placeholder-history) - t t string)))) + (let ((start 0) + (replacement "")) + (while (string-match "&?&\\(\\(?:\\sw\\|\\s_\\)+\\)[.]?" string start) + (setq replacement (read-from-minibuffer + (format "Enter value for %s: " + (propertize (match-string 1 string) + 'face 'font-lock-variable-name-face)) + nil nil nil 'sql-placeholder-history) + string (replace-match replacement t t string) + start (+ (match-beginning 1) (length replacement)))))) string) ;; Using DB2 interactively, newlines must be escaped with " \". @@ -3794,6 +3798,8 @@ to avoid deleting non-prompt output." oline) ;;; Sending the region to the SQLi buffer. +(defvar sql-debug-send nil + "Display text sent to SQL process pragmatically.") (defun sql-send-string (str) "Send the string STR to the SQL process." @@ -3807,12 +3813,14 @@ to avoid deleting non-prompt output." (save-excursion ;; Set product context (with-current-buffer sql-buffer + (when sql-debug-send + (message ">>SQL> %S" s)) + ;; Send the string (trim the trailing whitespace) - (sql-input-sender (get-buffer-process sql-buffer) s) + (sql-input-sender (get-buffer-process (current-buffer)) s) ;; Send a command terminator if we must - (when sql-send-terminator - (sql-send-magic-terminator sql-buffer s sql-send-terminator)) + (sql-send-magic-terminator sql-buffer s sql-send-terminator) (when sql-pop-to-buffer-after-send-region (message "Sent string to buffer %s" sql-buffer)))) @@ -3874,12 +3882,8 @@ to avoid deleting non-prompt output." ;; Check to see if the pattern is present in the str already sent (unless (and pat term - (string-match (concat pat "\\'") str)) - (comint-simple-send (get-buffer-process buf) term) - (setq sql-output-newline-count - (if sql-output-newline-count - (1+ sql-output-newline-count) - 1))))) + (string-match-p (concat pat "\\'") str)) + (sql-input-sender (get-buffer-process buf) term)))) (defun sql-remove-tabs-filter (str) "Replace tab characters with spaces." diff --git a/test/lisp/progmodes/sql-tests.el b/test/lisp/progmodes/sql-tests.el index 7a11f762eb0..5ac34907c2d 100644 --- a/test/lisp/progmodes/sql-tests.el +++ b/test/lisp/progmodes/sql-tests.el @@ -270,5 +270,39 @@ Perform ACTION and validate results" (sql-test-product-feature-harness (should-not (sql-get-product-feature 'd :Z)))) +;;; SQL Oracle SCAN/DEFINE +(ert-deftest sql-tests-placeholder-filter () + "Test that placeholder relacement is as expected." + (let ((syntab (syntax-table)) + (sql-oracle-scan-on t) + (placeholder-value "")) + (set-syntax-table sql-mode-syntax-table) + + (cl-letf + (((symbol-function 'read-from-minibuffer) + (lambda (&rest _) placeholder-value))) + + (setq placeholder-value "XX") + (should (equal + (sql-placeholders-filter "select '&x' from dual;") + "select 'XX' from dual;")) + + (setq placeholder-value "&Y") + (should (equal + (sql-placeholders-filter "select '&x' from dual;") + "select '&Y' from dual;")) + (should (equal + (sql-placeholders-filter "select '&x' from dual;") + "select '&Y' from dual;")) + (should (equal + (sql-placeholders-filter "select '&x.' from dual;") + "select '&Y' from dual;")) + (should (equal + (sql-placeholders-filter "select '&x.y' from dual;") + "select '&Yy' from dual;"))) + + (set-syntax-table syntab))) + + (provide 'sql-tests) ;;; sql-tests.el ends here -- 2.39.5