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

Syntax error when trying to add enum column with comment that ends with bracket ")". Unterminated quoted string. #17118

Open
1 of 2 tasks
Mauzzz0 opened this issue Feb 20, 2024 · 2 comments

Comments

@Mauzzz0
Copy link

Mauzzz0 commented Feb 20, 2024

Issue

I am not sure is this problem with sequelize-typescript or sequelize, so please correct me.
Syntax error when trying to add enum column with comment that ends with bracket ")".
Other type (tested with DataType.TEXT) works as expected, without problems.

Versions

  • sequelize: 6.37.1
  • sequelize-typescript: 2.1.6
  • typescript: 5.3.3
  • pg: 8.11.3

Issue type

  • bug report
  • feature request

Actual behavior

For example (code in below section) sequelize creates this SQL (prettified):

DO
'BEGIN
CREATE TYPE "public"."enum_Model_status" AS ENUM(''active'', ''pending'', ''available'', ''inactive'', ''suspended'');
EXCEPTION WHEN duplicate_object THEN null;
END';
ALTER TABLE "public"."Model" ADD COLUMN "status" "public"."enum_Model_status"'; <--- Here is unnecessary single quote

And at the end you can see syntax error with unnecessary one single quote, between status" and ;
Error: unterminated quoted string at or near "';"

Expected behavior

  • Successfully creates column with comment with brackets

Steps to reproduce

  • Initialize sequelize, add one model
  • Using queryInterface add enum column with any comment that ends with symbol )
  • You will get syntax error like mentioned above.

Related code

Link to small reproducable repo: https://github.com/Mauzzz0/sequelize-comment-brackets-error
With two files: case_fail.ts, case_success.ts

export enum StatusEnum {
  active = 'active',
  pending = 'pending',
  available = 'available',
  inactive = 'inactive',
  suspended = 'suspended',
}
const qi = sequelize.getQueryInterface();

Failed example:

await qi.addColumn(ModelEntity.tableName, 'status',
  {
    type: DataType.ENUM,
    allowNull: false,
    values: Object.values(StatusEnum),
    defaultValue: StatusEnum.available,
    comment: 'Comment ends with brackets)',
  }, { transaction });

Successfull example:

await qi.addColumn(ModelEntity.tableName, 'status',
  {
    type: DataType.ENUM,
    allowNull: false,
    values: Object.values(StatusEnum),
    defaultValue: StatusEnum.available,
    comment: 'Normal comment',
  }, { transaction });
@WikiRik WikiRik transferred this issue from sequelize/sequelize-typescript Feb 23, 2024
@github-actions github-actions bot added the pending-approval Bug reports that have not been verified yet, or feature requests that have not been accepted yet label Feb 23, 2024
@WikiRik WikiRik added type: bug and removed pending-approval Bug reports that have not been verified yet, or feature requests that have not been accepted yet labels Feb 23, 2024
@WikiRik
Copy link
Member

WikiRik commented Feb 23, 2024

This is an issue with sequelize itself (and not sequelize-typescript where it was first opened). In v6 this is the line that causes the issue;

dataType = dataType.replace(/^ENUM\(.+\)/, this.pgEnumName(tableName, attr));

The issue is that the enum is passed there including the comment. It will now take the last closing bracket and replace the part in between with the enum name. It should stop before it encounters a comment.

It is also present in the v7-alphas, so it would be better to fix it there first and backport it to v6.

@WikiRik
Copy link
Member

WikiRik commented Feb 23, 2024

Looking into it more it seems that createTableQuery has a workaround for this;

for (const attr in attributes) {
const quotedAttr = this.quoteIdentifier(attr);
const i = attributes[attr].indexOf('COMMENT ');
if (i !== -1) {
// Move comment to a separate query
const escapedCommentText = this.escape(attributes[attr].substring(i + 8));
columnComments += `; COMMENT ON COLUMN ${quotedTable}.${quotedAttr} IS ${escapedCommentText}`;
attributes[attr] = attributes[attr].substring(0, i);
}
const dataType = this.dataTypeMapping(tableName, attr, attributes[attr]);
attrStr.push(`${quotedAttr} ${dataType}`);
}

Something similar could be done for addColumnQuery and changeColumnQuery

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants