tursodatabase / libsql

libSQL is a fork of SQLite that is both Open Source, and Open Contributions.
https://turso.tech/libsql
MIT License
11.26k stars 286 forks source link

ALTER COLUMN breaks if it contains a new line at the end #1517

Open brapifra opened 4 months ago

brapifra commented 4 months ago

Steps to reproduce

// Clean, :memory: DB using @libsql/client@^0.6.0

 await client.execute(`
        CREATE TABLE IF NOT EXISTS \`users\` (
            \`id\` text PRIMARY KEY NOT NULL
    );
      `);

  await client.execute(
    `
  CREATE TABLE IF NOT EXISTS \`test\` (
          \`id\` text PRIMARY KEY NOT NULL,
          \`user_id\` text
  );
  `,
  );

  await client.execute(
    `
    ALTER TABLE \`test\` ALTER COLUMN \`user_id\` TO \`user_id\` TEXT NOT NULL REFERENCES users(id);
    `,
  );

The last statement will throw this error:

Serialized Error: { code: 'SQLITE_ERROR', rawCode: 1 }
Caused by: SqliteError: CREATE TABLE `test` (
          `id` text PRIMARY KEY NOT NULL,
          `user_id` TEXT NOT NULL REFERENCES users(id);
    )
 ❯ convertError node_modules/.pnpm/libsql@0.3.18/node_modules/libsql/index.js:48:12
 ❯ Statement.run node_modules/.pnpm/libsql@0.3.18/node_modules/libsql/index.js:295:13
 ❯ executeStmt node_modules/.pnpm/@libsql+client@0.6.0/node_modules/@libsql/client/lib-esm/sqlite3.js:215:34
 ❯ Sqlite3Client.execute node_modules/.pnpm/@libsql+client@0.6.0/node_modules/@libsql/client/lib-esm/sqlite3.js:61:16

But it works if you remove the last newline:

 await client.execute(
    `
    ALTER TABLE \`test\` ALTER COLUMN \`user_id\` TO \`user_id\` TEXT NOT NULL REFERENCES users(id);`,
  );

My guess is that if you add the new line the query gets incorrectly parsed, keeping the semicolon when re-creating the table (as shown in the error)

Took me quite a bit to figure it out! So hopefully it's quick and easy fix 🙏