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

Javascript Split function seems not work well #30

Closed
t-sky opened this issue Mar 31, 2023 · 4 comments
Closed

Javascript Split function seems not work well #30

t-sky opened this issue Mar 31, 2023 · 4 comments

Comments

@t-sky
Copy link

t-sky commented Mar 31, 2023

Hi, Mr. Mattila,

Thank you for your module, it's very useful to me.
I found a case that does not match my wants.

This code reproduces the situation.

const named = require('yesql').pg;
const sql = "select 'C:\\work' as path";
console.log(`after=${JSON.stringify((named(sql)({})))}`);

I hoped this should be {"text": "select 'C:\work' as path","values":[]}.
But the result is:

after={"text":"select 'C:\work'\work as path","values":[]}

I guess this "work work" is caused by the spec of Split function of Javascript.

So I added split_reg function to String prototype, and now it works well.

diff --git a/node_modules/yesql/yesql.js b/node_modules/yesql/yesql.js
--- a/node_modules/yesql/yesql.js
+++ b/node_modules/yesql/yesql.js
@@ -41,18 +41,35 @@ const pg = (query, options = {}) => {
     const matchDoubleQuoted = /("[^"\\]*(\\.[^"\\]*)*")/
     const values = []
 
+    String.prototype.split_reg = function (reg) {
+      let ret = [];
+      let start = 0;
+      let str = this;
+      while (true) {
+        str = str.substring(start);
+        let r = reg.exec(str);
+        if (r == null) {
+          ret.push(str);
+          return ret;
+        }
+        ret.push(str.substring(0, r.index));
+        ret.push(str.substring(r.index, r.index + r[0].length));
+        start = r.index + r[0].length;
+      }
+    }
     const text = query
       // remove -- comments
       .replace(/--.*$/gm, '')
       // remove /* */ comments
       .replace(/\/\*(\*(?!\/)|[^*])*\*\//g, '')
-      .split(matchQuoted)
+      //.split(matchQuoted)
+      .split_reg(matchQuoted)
       .map(part => {
         if (!part || matchQuoted.test(part)) {
           return part
         } else {
           return part
-            .split(matchDoubleQuoted)
+            .split_reg(matchDoubleQuoted)
             .map(part => {
                 if (!part || matchDoubleQuoted.test(part)) {
                   return part

How do you think about this workaround? Or is there any better way to go?

Thanks.

@t-sky t-sky changed the title Javascript Split function seems not to work well Javascript Split function seems not work well Mar 31, 2023
@pihvi
Copy link
Owner

pihvi commented Apr 2, 2023

Thanks for the report and use case!

I changed the regexp: 2ca7e32
which seems to make this work. This is now released as version 6.0.0.

Does this work for you? Do you see some other problems happening because of this approach?

@t-sky
Copy link
Author

t-sky commented Apr 3, 2023

Thanks a lot for your quick fix. It works well for my case.
But it seems that \'s in double quotes cause the same problem.
I did not notice that. Can you fix this?

const named = require('yesql').pg;
const sql = "select 'C:\\work' as \"path_with_\\_in_it\"";
const after=named(sql)({})
console.log(`after.text=${after.text}`);

I hope that output should be:
after.text=select 'C:\work' as "path_with_\_in_it"

but:
after.text=select 'C:\work' as "path_with_\_in_it"\_in_it

Thanks.

@pihvi
Copy link
Owner

pihvi commented Apr 3, 2023

Good catch, thank you!

Fixed the same way in release 6.1.0

Does this work for you? Do you see some other problems happening because of this approach?

@t-sky
Copy link
Author

t-sky commented Apr 3, 2023

Now all is Ok! Thank you!

@t-sky t-sky closed this as completed Apr 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants