Double-escaped double-quotes in double-quoted identifiers (yes, really) are parsed and serialized incorrectly
A query like SELECT 5 as "foo ""bar"" baz" works in psql and interprets the inner "" as one double-quote character, escaped:
foo "bar" baz
---------------
5
(1 row)
But pgsql-ast-parser does not account for this escaping. Adding this test to select.spec.ts:
checkSelect(['select 42 as "alias with ""double-quoted"" part"'], aliased('alias with "double-quoted" part'));
fails like this:
1) Select statements
parses select 42 as "alias with ""double-quoted"" part":
Parser has not returned the expected AST
+ expected - actual
{
"columns": [
{
"alias": {
- "name": "alias with \"\"double-quoted\"\" part"
+ "name": "alias with \"double-quoted\" part"
}
"expr": {
"type": "integer"
"value": 42
at Context.<anonymous> (src/syntax/spec-utils.ts:188:26)
at processImmediate (node:internal/timers:466:21)
And adding this test to to-sql.spec.ts (and executing with npx mochapack src/to-sql.spec.ts)
it('quotes quotes in identifiers', () => {
expect(stm(`select "a ""quote"" you say?"`))
.to.equal(`SELECT "a ""quote"" you say?"`);
expect(stm(`select a AS "a ""quote"" you say?"`))
.to.equal(`SELECT a AS "a ""quote"" you say?"`);
expect(toSql.statement({
columns: [
{
expr: { type: 'ref', name: 'a' },
alias: { name: 'a "quote" you say?' }
}
],
type: 'select'
}))
.to.equal(`SELECT a AS "a ""quote"" you say?"`)
})
also fails, like this:
1) SQL builder
quotes quotes in identifiers:
AssertionError: expected 'SELECT a AS "a "quote" you say?"' to equal 'SELECT a AS "a ""quote"" you say?"'
+ expected - actual
-SELECT a AS "a "quote" you say?"
+SELECT a AS "a ""quote"" you say?"
at Context.<anonymous> (src/to-sql.spec.ts:88:17)
at processImmediate (node:internal/timers:466:21)
Note that the first two assertions pass, but that's just because the parse is also wrong :-) — so the third assertion has the explicit AST to reveal the failure.
Sidenote: the tests in to-sql.spec.ts appear not to be executed when I run npm run test 🤔 ... the output for that ends with:
668 passing (2s)
1 failing
1) Select statements
parses select 42 as "alias with ""double-quoted"" part":
Parser has not returned the expected AST
+ expected - actual
{
"columns": [
{
"alias": {
- "name": "alias with \"\"double-quoted\"\" part"
+ "name": "alias with \"double-quoted\" part"
}
"expr": {
"type": "integer"
"value": 42
at Context.<anonymous> (src/syntax/spec-utils.ts:188:26)
at processImmediate (node:internal/timers:466:21)
MOCHA Tests completed with 1 failure(s)
but running directly with npx src/**/*.spec.ts runs them all:
717 passing (2s)
2 failing
1) Select statements
parses select 42 as "alias with ""double-quoted"" part":
Parser has not returned the expected AST
+ expected - actual
{
"columns": [
{
"alias": {
- "name": "alias with \"\"double-quoted\"\" part"
+ "name": "alias with \"double-quoted\" part"
}
"expr": {
"type": "integer"
"value": 42
at Context.<anonymous> (src/syntax/spec-utils.ts:188:26)
at processImmediate (node:internal/timers:466:21)
2) SQL builder
quotes quotes in identifiers:
AssertionError: expected 'SELECT a AS "a "quote" you say?"' to equal 'SELECT a AS "a ""quote"" you say?"'
+ expected - actual
-SELECT a AS "a "quote" you say?"
+SELECT a AS "a ""quote"" you say?"
at Context.<anonymous> (src/to-sql.spec.ts:88:17)
at processImmediate (node:internal/timers:466:21)
MOCHA Tests completed with 2 failure(s)
... is that just something wrong with my environment, or does this happen for someone else?
Sidenote: the tests in to-sql.spec.ts appear not to be executed when I run npm run test 🤔 ... the output for that ends with:
I think this is because the run-scripts run in /bin/sh (i.e. bash) by default, where ** doesn't mean anything different from *:
$ npm run test | grep ' passing '
668 passing (1s)
$ npm_config_script_shell=/bin/sh npm run test | grep ' passing '
668 passing (1s)
$ npm_config_script_shell=/bin/zsh npm run test | grep ' passing '
717 passing (1s)
... @oguimbal do you maybe have npm configured to run scripts in zsh by default? Should there maybe be a .npmrc checked into the repository to enforce that, containing:
script-shell=/bin/zsh
?
Wrote up a separate issue for that run-script problem. https://github.com/oguimbal/pgsql-ast-parser/issues/92