mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 11:00:44 -06:00
grammar: Fix parsing of exotic column data types
This fixes two issues with unusual but valid data types for columns: 1) When having a data type that consists of more than one word these wouldn't be separated anymore after parsing. This is fixed now. Example: CREATE TABLE test(a long int); would have become CREATE TABLE test(a longint); 2) Some keywords are allowed to be used as data types. Parsing these tables would have failed entire prior to this. This is fixed, too. Example: CREATE TABLE test(a no); would fail.
This commit is contained in:
@@ -1242,6 +1242,34 @@ void Sqlite3Parser::columndef() {
|
||||
}
|
||||
{
|
||||
switch ( LA(1)) {
|
||||
case ABORT:
|
||||
case ACTION:
|
||||
case ASC:
|
||||
case CASCADE:
|
||||
case CAST:
|
||||
case CONFLICT:
|
||||
case CURRENT_TIME:
|
||||
case CURRENT_DATE:
|
||||
case CURRENT_TIMESTAMP:
|
||||
case DEFERRED:
|
||||
case DESC:
|
||||
case END:
|
||||
case FAIL:
|
||||
case GLOB:
|
||||
case KEY:
|
||||
case LIKE:
|
||||
case IGNORE:
|
||||
case INITIALLY:
|
||||
case IMMEDIATE:
|
||||
case NO:
|
||||
case MATCH:
|
||||
case RAISE:
|
||||
case REGEXP:
|
||||
case REPLACE:
|
||||
case RESTRICT:
|
||||
case ROLLBACK:
|
||||
case TEMPORARY:
|
||||
case TEMP:
|
||||
case ID:
|
||||
case QUOTEDID:
|
||||
case QUOTEDLITERAL:
|
||||
@@ -2495,16 +2523,58 @@ void Sqlite3Parser::type_name() {
|
||||
{ // ( ... )+
|
||||
int _cnt117=0;
|
||||
for (;;) {
|
||||
if ((_tokenSet_1.member(LA(1)))) {
|
||||
switch ( LA(1)) {
|
||||
case ID:
|
||||
case QUOTEDID:
|
||||
case QUOTEDLITERAL:
|
||||
case STRINGLITERAL:
|
||||
{
|
||||
name();
|
||||
if (inputState->guessing==0) {
|
||||
astFactory->addASTChild( currentAST, returnAST );
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
case ABORT:
|
||||
case ACTION:
|
||||
case ASC:
|
||||
case CASCADE:
|
||||
case CAST:
|
||||
case CONFLICT:
|
||||
case CURRENT_TIME:
|
||||
case CURRENT_DATE:
|
||||
case CURRENT_TIMESTAMP:
|
||||
case DEFERRED:
|
||||
case DESC:
|
||||
case END:
|
||||
case FAIL:
|
||||
case GLOB:
|
||||
case KEY:
|
||||
case LIKE:
|
||||
case IGNORE:
|
||||
case INITIALLY:
|
||||
case IMMEDIATE:
|
||||
case NO:
|
||||
case MATCH:
|
||||
case RAISE:
|
||||
case REGEXP:
|
||||
case REPLACE:
|
||||
case RESTRICT:
|
||||
case ROLLBACK:
|
||||
case TEMPORARY:
|
||||
case TEMP:
|
||||
{
|
||||
keywordastablename();
|
||||
if (inputState->guessing==0) {
|
||||
astFactory->addASTChild( currentAST, returnAST );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if ( _cnt117>=1 ) { goto _loop117; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename());}
|
||||
}
|
||||
|
||||
}
|
||||
_cnt117++;
|
||||
}
|
||||
_loop117:;
|
||||
|
||||
@@ -348,7 +348,7 @@ name : ID | QUOTEDID | QUOTEDLITERAL | STRINGLITERAL;
|
||||
|
||||
type_name
|
||||
:
|
||||
(name)+
|
||||
(name | keywordastablename)+
|
||||
(LPAREN signednumber (COMMA signednumber)? RPAREN)?
|
||||
{#type_name = #([TYPE_NAME, "TYPE_NAME"], #type_name);}
|
||||
;
|
||||
|
||||
@@ -429,15 +429,16 @@ QString identifier(antlr::RefAST ident)
|
||||
|
||||
QString concatTextAST(antlr::RefAST t, bool withspace = false)
|
||||
{
|
||||
// When this is called for a KEYWORDASTABLENAME token, we must take the child's content to get the actual value
|
||||
// instead of 'KEYWORDASTABLENAME' as a string. The same applies for KEYWORDASCOLUMNNAME tokens.
|
||||
if(t != antlr::nullAST && (t->getType() == sqlite3TokenTypes::KEYWORDASTABLENAME || t->getType() == sqlite3TokenTypes::KEYWORDASCOLUMNNAME))
|
||||
return concatTextAST(t->getFirstChild());
|
||||
|
||||
QStringList stext;
|
||||
while(t != antlr::nullAST)
|
||||
{
|
||||
stext.append(t->getText().c_str());
|
||||
// When this is called for a KEYWORDASTABLENAME token, we must take the child's content to get the actual value
|
||||
// instead of 'KEYWORDASTABLENAME' as a string. The same applies for KEYWORDASCOLUMNNAME tokens.
|
||||
if(t != antlr::nullAST && (t->getType() == sqlite3TokenTypes::KEYWORDASTABLENAME || t->getType() == sqlite3TokenTypes::KEYWORDASCOLUMNNAME))
|
||||
stext.append(t->getFirstChild()->getText().c_str());
|
||||
else
|
||||
stext.append(t->getText().c_str());
|
||||
|
||||
t = t->getNextSibling();
|
||||
}
|
||||
return stext.join(withspace ? " " : "");
|
||||
@@ -707,7 +708,7 @@ void CreateTableWalker::parsecolumn(Table& table, antlr::RefAST c)
|
||||
c = c->getNextSibling(); //type?
|
||||
if(c != antlr::nullAST && c->getType() == sqlite3TokenTypes::TYPE_NAME)
|
||||
{
|
||||
type = concatTextAST(c->getFirstChild());
|
||||
type = concatTextAST(c->getFirstChild(), true);
|
||||
c = c->getNextSibling();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user