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

🐛 Bug Report: SqliteDatabase::prepareSql does not handle CRLF line endings #1300

Closed
KianNH opened this issue Oct 11, 2023 · 2 comments · Fixed by #1322
Closed

🐛 Bug Report: SqliteDatabase::prepareSql does not handle CRLF line endings #1300

KianNH opened this issue Oct 11, 2023 · 2 comments · Fixed by #1322
Labels
D1 D1 Database

Comments

@KianNH
Copy link
Contributor

KianNH commented Oct 11, 2023

workerd will reject prepared statements executed in SINGLE mode appear to have more than one statement.

switch (multi) {
case SINGLE:
SQLITE_REQUIRE(tail == sqlCode.end(),
"A prepared SQL statement must contain only one statement.", tail);
break;

However, the code for incrementing tail seems to only account for \n (LF) whereas users on Windows will have \r\n (CRLF).

while (*tail == ' ' || *tail == '\n') ++tail;

The issue can be seen when using Wrangler and providing a file with a newline, when saved with CRLF line endings:

$ wrangler d1 execute <db> --file ./sql --local
- A prepared SQL statement must contain only one statement.
INSERT INTO foo VALUES ('bar');

It can also be reproduced in a Cloudflare Worker:

// ❌ - A prepared SQL statement must contain only one statement.
await env.DB.prepare("INSERT INTO foo VALUES('bar');\r\n");
// ✅ - runs as expected
await env.DB.prepare("INSERT INTO foo VALUES('bar');\n");
@radix
Copy link

radix commented Nov 4, 2023

So I'm getting this error (only started recently) when running a d1 execute from my Windows machine (only when I run it on prod; local wrangler dev works fine). The file I'm running does not have CRLF line endings -- is this problem only for when the actual file contains CRLF, or is this just a bug with how wrangler is sending the file from Windows?

@radix
Copy link

radix commented Nov 4, 2023

e.g.

PS C:\Users\radix\Projects\arpeggiorpg\worker> bash -c python3
Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> open('schema.sql', 'rb').read()
b'/* remember to include NOT NULL directives when creating new tables! */\n\n/* Also: Don\'t put semicolons in comments! Wrangler has a bug. */\n\nCREATE TABLE IF NOT EXISTS game_metadata (\n    game_id text PRIMARY KEY NOT NULL,\n    name text NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS superusers (\n    user_id text PRIMARY KEY NOT NULL\n);\n\nINSERT OR IGNORE INTO superusers (user_id) VALUES (\'google_105096330625444095578\');\n\n\nCREATE TABLE IF NOT EXISTS user_games (\n    user_id text NOT NULL,\n    game_id text NOT NULL,\n    role text NOT NULL,\n    profile_name text NOT NULL\n);\nCREATE INDEX IF NOT EXISTS user_games_by_user_idx ON user_games (user_id);\n\n\n/* This UNIQUE constraint ensures that each *user* can only be associated to a game once as a GM and\nonce as a player.\n\n(really, the only reason it includes "role" is for testing purposes. I don\'t think there are any\nreal use-cases for a user to be both a GM and a player at the same time)\n*/\nCREATE UNIQUE INDEX IF NOT EXISTS user_game_role_unique ON user_games(user_id, game_id, role);\n'

>>> b'\r' in open('schema.sql', 'rb').read()
False

PS C:\Users\radix\Projects\arpeggiorpg\worker> .\node_modules\.bin\wrangler d1 execute DB --file schema.sql                                                                             
🌀 Mapping SQL input into an array of statements
🌀 Parsing 6 statements
🌀 Executing on remote database DB (9bbbb737-cabc-44cb-bd76-44c3a5625759):
🌀 To execute on your local development database, pass the --local flag to 'wrangler d1 execute'

X [ERROR] A request to the Cloudflare API (/accounts/9da1987464827a8209f127a4e0f02b77/d1/database/9bbbb737-cabc-44cb-bd76-44c3a5625759/query) failed.

  A prepared SQL statement must contain only one statement. [code: 7500]

  If you think this is a bug, please open an issue at:
  https://github.com/cloudflare/workers-sdk/issues/new/choose

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

Successfully merging a pull request may close this issue.

3 participants