Skip to content

Commit 005bc68

Browse files
committed
Fixed CORE-6517 - CREATE DATABASE fails with 'Token unknown' error when DB name
is enclosed in double quotes and 'DEFAULT CHARACTER SET' is specified after DB name.
1 parent 91f7d20 commit 005bc68

3 files changed

Lines changed: 42 additions & 7 deletions

File tree

src/yvalve/prepa_proto.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
#define DSQL_PREPA_PROTO_H
2626

2727
#include "firebird/Interface.h"
28+
#include "../common/classes/fb_string.h"
2829

2930
namespace Why {
3031
class YAttachment;
3132
}
3233

33-
bool PREPARSE_execute(Firebird::CheckStatusWrapper*, Why::YAttachment**,
34-
USHORT, const SCHAR*, bool*, USHORT);
34+
bool PREPARSE_execute(Firebird::CheckStatusWrapper*, Why::YAttachment**, Firebird::string&, bool*, USHORT);
3535

3636
#endif // DSQL_PREPA_PROTO_H

src/yvalve/preparse.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,14 @@ static NoCaseString getToken(unsigned& pos, const Tokens& toks, int symbol = SYM
157157
158158
**/
159159
bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
160-
USHORT stmt_length, const SCHAR* stmt, bool* stmt_eaten, USHORT dialect)
160+
string& stmt, bool* stmt_eaten, USHORT dialect)
161161
{
162162
// no use creating separate pool for a couple of strings
163163
ContextPoolHolder context(getDefaultMemoryPool());
164164

165165
try
166166
{
167-
if (!stmt)
167+
if (stmt.isEmpty())
168168
{
169169
Arg::Gds(isc_command_end_err).raise();
170170
}
@@ -177,7 +177,39 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
177177

178178
Tokens tks;
179179
tks.quotes(quotes);
180-
tks.parse(stmt_length, stmt);
180+
tks.parse(stmt.length(), stmt.c_str());
181+
182+
for (int tokenPos = tks.getCount() - 1; tokenPos >= 0; --tokenPos)
183+
{
184+
const Tokens::Tok& token = tks[tokenPos];
185+
186+
if (token.length > 0 && token.text[0] == '"')
187+
{
188+
string newToken = "'";
189+
190+
for (unsigned i = 1; i < token.length - 1; ++i)
191+
{
192+
switch (token.text[i])
193+
{
194+
case '\'':
195+
newToken += "''";
196+
break;
197+
198+
case '"':
199+
++i;
200+
newToken += '"';
201+
break;
202+
203+
default:
204+
newToken += token.text[i];
205+
}
206+
}
207+
208+
newToken += "'";
209+
stmt.replace(token.origin, token.length, newToken);
210+
}
211+
}
212+
181213
unsigned pos = 0;
182214

183215
if (getToken(pos, tks) != pp_symbols[PP_CREATE].symbol)

src/yvalve/utl.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,10 @@ YAttachment* UtilInterface::executeCreateDatabase(
587587
if (stmtIsCreateDb)
588588
*stmtIsCreateDb = FB_FALSE;
589589

590-
if (!PREPARSE_execute(status, &att, stmtLength, creatDBstatement, &stmtEaten, dialect))
590+
string statement(creatDBstatement,
591+
(stmtLength == 0 && creatDBstatement ? strlen(creatDBstatement) : stmtLength));
592+
593+
if (!PREPARSE_execute(status, &att, statement, &stmtEaten, dialect))
591594
return NULL;
592595

593596
if (stmtIsCreateDb)
@@ -611,7 +614,7 @@ YAttachment* UtilInterface::executeCreateDatabase(
611614

612615
if (!stmtEaten)
613616
{
614-
att->execute(status, crdbTrans, stmtLength, creatDBstatement, dialect, NULL, NULL, NULL, NULL);
617+
att->execute(status, crdbTrans, statement.length(), statement.c_str(), dialect, NULL, NULL, NULL, NULL);
615618
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
616619
{
617620
crdbTrans->rollback(&tempCheckStatusWrapper);

0 commit comments

Comments
 (0)