Skip to content

Commit

Permalink
parser: Add support for parsing GENERATED ALWAYS AS columns
Browse files Browse the repository at this point in the history
This adds support for parsing, storing, and generating GENERATED ALWAYS
AS columns as added in SQLite 3.31.0.

See issue sqlitebrowser#2107.
  • Loading branch information
MKleusberg committed Feb 9, 2020
1 parent cbced65 commit d522de7
Show file tree
Hide file tree
Showing 10 changed files with 4,492 additions and 3,933 deletions.
6 changes: 3 additions & 3 deletions src/SqlUiLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void SqlUiLexer::setupAutoCompletion()
keywordPatterns
// Keywords
<< "ABORT" << "ACTION" << "ADD" << "AFTER" << "ALL"
<< "ALTER" << "ANALYZE" << "AND" << "AS" << "ASC"
<< "ALTER" << "ALWAYS" << "ANALYZE" << "AND" << "AS" << "ASC"
<< "ATTACH" << "AUTOINCREMENT" << "BEFORE" << "BEGIN" << "BETWEEN"
<< "BY" << "CASCADE" << "CASE" << "CAST" << "CHECK"
<< "COLLATE" << "COLUMN" << "COMMIT" << "CONFLICT" << "CONSTRAINT"
Expand All @@ -33,7 +33,7 @@ void SqlUiLexer::setupAutoCompletion()
<< "DESC" << "DETACH" << "DISTINCT" << "DO" << "DROP" << "EACH"
<< "ELSE" << "END" << "ESCAPE" << "EXCEPT" << "EXCLUSIVE"
<< "EXISTS" << "EXPLAIN" << "FAIL" << "FILTER" << "FOLLOWING" << "FOR" << "FOREIGN"
<< "FROM" << "FULL" << "GLOB" << "GROUP" << "HAVING"
<< "FROM" << "FULL" << "GENERATED" << "GLOB" << "GROUP" << "HAVING"
<< "IF" << "IGNORE" << "IMMEDIATE" << "IN" << "INDEX"
<< "INDEXED" << "INITIALLY" << "INNER" << "INSERT" << "INSTEAD"
<< "INTERSECT" << "INTO" << "IS" << "ISNULL" << "JOIN"
Expand All @@ -43,7 +43,7 @@ void SqlUiLexer::setupAutoCompletion()
<< "OUTER" << "OVER" << "PARTITION" << "PLAN" << "PRAGMA" << "PRECEDING" << "PRIMARY" << "QUERY"
<< "RAISE" << "RANGE" << "RECURSIVE" << "REFERENCES" << "REGEXP" << "REINDEX" << "RELEASE"
<< "RENAME" << "REPLACE" << "RESTRICT" << "RIGHT" << "ROLLBACK"
<< "ROWID" << "ROW" << "ROWS" << "SAVEPOINT" << "SELECT" << "SET" << "TABLE"
<< "ROWID" << "ROW" << "ROWS" << "SAVEPOINT" << "SELECT" << "SET" << "STORED" << "TABLE"
<< "TEMP" << "TEMPORARY" << "THEN" << "TO" << "TRANSACTION"
<< "TRIGGER" << "UNBOUNDED" << "UNION" << "UNIQUE" << "UPDATE" << "USING"
<< "VACUUM" << "VALUES" << "VIEW" << "VIRTUAL" << "WHEN"
Expand Down
1,640 changes: 849 additions & 791 deletions src/sql/parser/sqlite3_lexer.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/sql/parser/sqlite3_lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ extern int yylex (yyscan_t yyscanner);
#undef yyTABLES_NAME
#endif

#line 235 "sqlite3_lexer.ll"
#line 238 "sqlite3_lexer.ll"


#line 609 "sqlite3_lexer.h"
Expand Down
3 changes: 3 additions & 0 deletions src/sql/parser/sqlite3_lexer.ll
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ WS [ \t\f]

"ABORT" return TOKEN(ABORT);
"ACTION" return TOKEN(ACTION);
"ALWAYS" return TOKEN(ALWAYS);
"AS" return TOKEN(AS);
"ASC" return TOKEN(ASC);
"AUTOINCREMENT" return TOKEN(AUTOINCREMENT);
Expand Down Expand Up @@ -144,6 +145,7 @@ WS [ \t\f]
"FILTER" return TOKEN(FILTER);
"FOLLOWING" return TOKEN(FOLLOWING);
"FOREIGN" return TOKEN(FOREIGN);
"GENERATED" return TOKEN(GENERATED);
"GLOB" return TOKEN(GLOB);
"IF" return TOKEN(IF);
"IGNORE" return TOKEN(IGNORE);
Expand Down Expand Up @@ -178,6 +180,7 @@ WS [ \t\f]
"ROWS" return TOKEN(ROWS);
"SELECT" return TOKEN(SELECT);
"SET" return TOKEN(SET);
"STORED" return TOKEN(STORED);
"TABLE" return TOKEN(TABLE);
"TEMP" return TOKEN(TEMP);
"TEMPORARY" return TOKEN(TEMPORARY);
Expand Down
78 changes: 44 additions & 34 deletions src/sql/parser/sqlite3_location.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// A Bison parser, made by GNU Bison 3.4.1.
// A Bison parser, made by GNU Bison 3.5.1.

// Locations for Bison parsers in C++

// Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -38,7 +38,6 @@
#ifndef YY_YY_SQLITE3_LOCATION_H_INCLUDED
# define YY_YY_SQLITE3_LOCATION_H_INCLUDED

# include <algorithm> // std::max
# include <iostream>
# include <string>

Expand All @@ -56,16 +55,19 @@

#line 10 "sqlite3_parser.yy"
namespace sqlb { namespace parser {
#line 60 "sqlite3_location.h"
#line 59 "sqlite3_location.h"

/// A point in a source file.
class position
{
public:
/// Type for line and column numbers.
typedef int counter_type;

/// Construct a position.
explicit position (std::string* f = YY_NULLPTR,
unsigned l = 1u,
unsigned c = 1u)
counter_type l = 1,
counter_type c = 1)
: filename (f)
, line (l)
, column (c)
Expand All @@ -74,8 +76,8 @@ namespace sqlb { namespace parser {

/// Initialization.
void initialize (std::string* fn = YY_NULLPTR,
unsigned l = 1u,
unsigned c = 1u)
counter_type l = 1,
counter_type c = 1)
{
filename = fn;
line = l;
Expand All @@ -85,17 +87,17 @@ namespace sqlb { namespace parser {
/** \name Line and Column related manipulators
** \{ */
/// (line related) Advance to the COUNT next lines.
void lines (int count = 1)
void lines (counter_type count = 1)
{
if (count)
{
column = 1u;
column = 1;
line = add_ (line, count, 1);
}
}

/// (column related) Advance to the COUNT next columns.
void columns (int count = 1)
void columns (counter_type count = 1)
{
column = add_ (column, count, 1);
}
Expand All @@ -104,44 +106,43 @@ namespace sqlb { namespace parser {
/// File name to which this position refers.
std::string* filename;
/// Current line number.
unsigned line;
counter_type line;
/// Current column number.
unsigned column;
counter_type column;

private:
/// Compute max (min, lhs+rhs).
static unsigned add_ (unsigned lhs, int rhs, int min)
static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
{
return static_cast<unsigned> (std::max (min,
static_cast<int> (lhs) + rhs));
return lhs + rhs < min ? min : lhs + rhs;
}
};

/// Add \a width columns, in place.
inline position&
operator+= (position& res, int width)
operator+= (position& res, position::counter_type width)
{
res.columns (width);
return res;
}

/// Add \a width columns.
inline position
operator+ (position res, int width)
operator+ (position res, position::counter_type width)
{
return res += width;
}

/// Subtract \a width columns, in place.
inline position&
operator-= (position& res, int width)
operator-= (position& res, position::counter_type width)
{
return res += -width;
}

/// Subtract \a width columns.
inline position
operator- (position res, int width)
operator- (position res, position::counter_type width)
{
return res -= width;
}
Expand Down Expand Up @@ -181,6 +182,8 @@ namespace sqlb { namespace parser {
class location
{
public:
/// Type for line and column numbers.
typedef position::counter_type counter_type;

/// Construct a location from \a b to \a e.
location (const position& b, const position& e)
Expand All @@ -196,17 +199,17 @@ namespace sqlb { namespace parser {

/// Construct a 0-width location in \a f, \a l, \a c.
explicit location (std::string* f,
unsigned l = 1u,
unsigned c = 1u)
counter_type l = 1,
counter_type c = 1)
: begin (f, l, c)
, end (f, l, c)
{}


/// Initialization.
void initialize (std::string* f = YY_NULLPTR,
unsigned l = 1u,
unsigned c = 1u)
counter_type l = 1,
counter_type c = 1)
{
begin.initialize (f, l, c);
end = begin;
Expand All @@ -222,13 +225,13 @@ namespace sqlb { namespace parser {
}

/// Extend the current location to the COUNT next columns.
void columns (int count = 1)
void columns (counter_type count = 1)
{
end += count;
}

/// Extend the current location to the COUNT next lines.
void lines (int count = 1)
void lines (counter_type count = 1)
{
end.lines (count);
}
Expand All @@ -243,39 +246,45 @@ namespace sqlb { namespace parser {
};

/// Join two locations, in place.
inline location& operator+= (location& res, const location& end)
inline location&
operator+= (location& res, const location& end)
{
res.end = end.end;
return res;
}

/// Join two locations.
inline location operator+ (location res, const location& end)
inline location
operator+ (location res, const location& end)
{
return res += end;
}

/// Add \a width columns to the end position, in place.
inline location& operator+= (location& res, int width)
inline location&
operator+= (location& res, location::counter_type width)
{
res.columns (width);
return res;
}

/// Add \a width columns to the end position.
inline location operator+ (location res, int width)
inline location
operator+ (location res, location::counter_type width)
{
return res += width;
}

/// Subtract \a width columns to the end position, in place.
inline location& operator-= (location& res, int width)
inline location&
operator-= (location& res, location::counter_type width)
{
return res += -width;
}

/// Subtract \a width columns to the end position.
inline location operator- (location res, int width)
inline location
operator- (location res, location::counter_type width)
{
return res -= width;
}
Expand Down Expand Up @@ -304,7 +313,8 @@ namespace sqlb { namespace parser {
std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
{
unsigned end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
location::counter_type end_col
= 0 < loc.end.column ? loc.end.column - 1 : 0;
ostr << loc.begin;
if (loc.end.filename
&& (!loc.begin.filename
Expand All @@ -319,6 +329,6 @@ namespace sqlb { namespace parser {

#line 10 "sqlite3_parser.yy"
} } // sqlb::parser
#line 323 "sqlite3_location.h"
#line 333 "sqlite3_location.h"

#endif // !YY_YY_SQLITE3_LOCATION_H_INCLUDED
Loading

0 comments on commit d522de7

Please sign in to comment.