| 1 | #include "duckdb/parser/parser.hpp" |
|---|---|
| 2 | |
| 3 | #include "duckdb/parser/transformer.hpp" |
| 4 | #include "duckdb/parser/parsed_data/create_table_info.hpp" |
| 5 | #include "duckdb/parser/statement/create_statement.hpp" |
| 6 | #include "duckdb/parser/statement/select_statement.hpp" |
| 7 | #include "duckdb/parser/statement/update_statement.hpp" |
| 8 | #include "duckdb/parser/query_node/select_node.hpp" |
| 9 | #include "duckdb/parser/tableref/expressionlistref.hpp" |
| 10 | #include "postgres_parser.hpp" |
| 11 | |
| 12 | #include "parser/parser.hpp" |
| 13 | |
| 14 | using namespace duckdb; |
| 15 | using namespace std; |
| 16 | |
| 17 | Parser::Parser() { |
| 18 | } |
| 19 | |
| 20 | void Parser::ParseQuery(string query) { |
| 21 | PostgresParser parser; |
| 22 | parser.Parse(query); |
| 23 | |
| 24 | if (!parser.success) { |
| 25 | throw ParserException("%s [%d]", parser.error_message.c_str(), parser.error_location); |
| 26 | } |
| 27 | |
| 28 | if (!parser.parse_tree) { |
| 29 | // empty statement |
| 30 | return; |
| 31 | } |
| 32 | |
| 33 | // if it succeeded, we transform the Postgres parse tree into a list of |
| 34 | // SQLStatements |
| 35 | Transformer transformer; |
| 36 | transformer.TransformParseTree(parser.parse_tree, statements); |
| 37 | n_prepared_parameters = transformer.ParamCount(); |
| 38 | |
| 39 | if (statements.size() > 0) { |
| 40 | auto &last_statement = statements.back(); |
| 41 | last_statement->stmt_length = query.size() - last_statement->stmt_location; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | vector<unique_ptr<ParsedExpression>> Parser::ParseExpressionList(string select_list) { |
| 46 | // construct a mock query prefixed with SELECT |
| 47 | string mock_query = "SELECT "+ select_list; |
| 48 | // parse the query |
| 49 | Parser parser; |
| 50 | parser.ParseQuery(mock_query); |
| 51 | // check the statements |
| 52 | if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) { |
| 53 | throw ParserException("Expected a single SELECT statement"); |
| 54 | } |
| 55 | auto &select = (SelectStatement &)*parser.statements[0]; |
| 56 | if (select.node->type != QueryNodeType::SELECT_NODE) { |
| 57 | throw ParserException("Expected a single SELECT node"); |
| 58 | } |
| 59 | auto &select_node = (SelectNode &)*select.node; |
| 60 | return move(select_node.select_list); |
| 61 | } |
| 62 | |
| 63 | vector<OrderByNode> Parser::ParseOrderList(string select_list) { |
| 64 | // construct a mock query |
| 65 | string mock_query = "SELECT * FROM tbl ORDER BY "+ select_list; |
| 66 | // parse the query |
| 67 | Parser parser; |
| 68 | parser.ParseQuery(mock_query); |
| 69 | // check the statements |
| 70 | if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) { |
| 71 | throw ParserException("Expected a single SELECT statement"); |
| 72 | } |
| 73 | auto &select = (SelectStatement &)*parser.statements[0]; |
| 74 | if (select.node->type != QueryNodeType::SELECT_NODE) { |
| 75 | throw ParserException("Expected a single SELECT node"); |
| 76 | } |
| 77 | auto &select_node = (SelectNode &)*select.node; |
| 78 | if (select_node.modifiers.size() == 0 || select_node.modifiers[0]->type != ResultModifierType::ORDER_MODIFIER) { |
| 79 | throw ParserException("Expected a single ORDER clause"); |
| 80 | } |
| 81 | auto &order = (OrderModifier &)*select_node.modifiers[0]; |
| 82 | return move(order.orders); |
| 83 | } |
| 84 | |
| 85 | void Parser::ParseUpdateList(string update_list, vector<string> &update_columns, |
| 86 | vector<unique_ptr<ParsedExpression>> &expressions) { |
| 87 | // construct a mock query |
| 88 | string mock_query = "UPDATE tbl SET "+ update_list; |
| 89 | // parse the query |
| 90 | Parser parser; |
| 91 | parser.ParseQuery(mock_query); |
| 92 | // check the statements |
| 93 | if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::UPDATE_STATEMENT) { |
| 94 | throw ParserException("Expected a single UPDATE statement"); |
| 95 | } |
| 96 | auto &update = (UpdateStatement &)*parser.statements[0]; |
| 97 | update_columns = move(update.columns); |
| 98 | expressions = move(update.expressions); |
| 99 | } |
| 100 | |
| 101 | vector<vector<unique_ptr<ParsedExpression>>> Parser::ParseValuesList(string value_list) { |
| 102 | // construct a mock query |
| 103 | string mock_query = "VALUES "+ value_list; |
| 104 | // parse the query |
| 105 | Parser parser; |
| 106 | parser.ParseQuery(mock_query); |
| 107 | // check the statements |
| 108 | if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) { |
| 109 | throw ParserException("Expected a single SELECT statement"); |
| 110 | } |
| 111 | auto &select = (SelectStatement &)*parser.statements[0]; |
| 112 | if (select.node->type != QueryNodeType::SELECT_NODE) { |
| 113 | throw ParserException("Expected a single SELECT node"); |
| 114 | } |
| 115 | auto &select_node = (SelectNode &)*select.node; |
| 116 | if (!select_node.from_table || select_node.from_table->type != TableReferenceType::EXPRESSION_LIST) { |
| 117 | throw ParserException("Expected a single VALUES statement"); |
| 118 | } |
| 119 | auto &values_list = (ExpressionListRef &)*select_node.from_table; |
| 120 | return move(values_list.values); |
| 121 | } |
| 122 | |
| 123 | vector<ColumnDefinition> Parser::ParseColumnList(string column_list) { |
| 124 | string mock_query = "CREATE TABLE blabla ("+ column_list + ")"; |
| 125 | Parser parser; |
| 126 | parser.ParseQuery(mock_query); |
| 127 | if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::CREATE_STATEMENT) { |
| 128 | throw ParserException("Expected a single CREATE statement"); |
| 129 | } |
| 130 | auto &create = (CreateStatement &)*parser.statements[0]; |
| 131 | if (create.info->type != CatalogType::TABLE) { |
| 132 | throw ParserException("Expected a single CREATE TABLE statement"); |
| 133 | } |
| 134 | auto &info = ((CreateTableInfo &)*create.info); |
| 135 | return move(info.columns); |
| 136 | } |
| 137 |