1 /* Copyright (C) 2014 InfiniDB, Inc.
2 Copyright (C) 2016 MariaDB Corporation
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; version 2 of
7 the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 MA 02110-1301, USA. */
18
19 /***********************************************************************
20 * $Id: sqlparser.cpp 9210 2013-01-21 14:10:42Z rdempsey $
21 *
22 *
23 ***********************************************************************/
24
25 #include <fstream>
26 #include <errno.h>
27
28 #define DDLPKGSQLPARSER_DLLEXPORT
29 #include "sqlparser.h"
30 #undef DDLPKGSQLPARSER_DLLEXPORT
31
32 #ifdef _MSC_VER
33 #include "ddl-gram-win.h"
34 #else
35 #include "ddl-gram.h"
36 #endif
37
38 void scanner_finish(void* yyscanner);
39 void scanner_init(const char* str, void* yyscanner);
40 int ddllex_init_extra(void* user_defined, void** yyscanner);
41 int ddllex_destroy(void* yyscanner);
42 int ddlparse(ddlpackage::pass_to_bison* x);
43 void set_schema(std::string schema);
44 namespace ddlpackage
45 {
46 using namespace std;
47
SqlParser()48 SqlParser::SqlParser() :
49 fStatus(-1),
50 fDebug(false),
51 x(&fParseTree)
52 {
53 }
54
55
SetDebug(bool debug)56 void SqlParser::SetDebug(bool debug)
57 {
58 fDebug = debug;
59 }
60
setDefaultSchema(std::string schema)61 void SqlParser::setDefaultSchema(std::string schema)
62 {
63 x.fDBSchema = schema;
64 }
65
setDefaultCharset(const CHARSET_INFO * default_charset)66 void SqlParser::setDefaultCharset(const CHARSET_INFO* default_charset)
67 {
68 x.default_table_charset = default_charset;
69 }
70
Parse(const char * sqltext)71 int SqlParser::Parse(const char* sqltext)
72 {
73 ddllex_init_extra(&scanData, &x.scanner);
74 scanner_init(sqltext, x.scanner);
75 fStatus = ddlparse(&x);
76 return fStatus;
77 }
78
79
GetParseTree(void)80 const ParseTree& SqlParser::GetParseTree(void)
81 {
82 if (!Good())
83 {
84 throw logic_error("The ParseTree is invalid");
85 }
86
87 return fParseTree;
88 }
89
90
Good()91 bool SqlParser::Good()
92 {
93 return fStatus == 0;
94 }
95
96
~SqlParser()97 SqlParser::~SqlParser()
98 {
99 scanner_finish(x.scanner); // free scanner allocated memory
100 ddllex_destroy(x.scanner);
101 }
102
103
SqlFileParser()104 SqlFileParser::SqlFileParser() :
105 SqlParser()
106 {
107 }
108
109
Parse(const string & sqlfile)110 int SqlFileParser::Parse(const string& sqlfile)
111 {
112 fStatus = -1;
113
114 ifstream ifsql;
115 ifsql.open(sqlfile.c_str());
116
117 if (!ifsql.is_open())
118 {
119 perror(sqlfile.c_str());
120 return fStatus;
121 }
122
123 char sqlbuf[1024 * 1024];
124 unsigned length;
125 ifsql.seekg (0, ios::end);
126 length = ifsql.tellg();
127 ifsql.seekg (0, ios::beg);
128
129 if (length > sizeof(sqlbuf) - 1)
130 {
131 throw length_error("SqlFileParser has file size hard limit of 16K.");
132 }
133
134 std::streamsize rcount;
135 rcount = ifsql.readsome(sqlbuf, sizeof(sqlbuf) - 1);
136
137 if (rcount < 0)
138 return fStatus;
139
140 sqlbuf[rcount] = 0;
141
142 //cout << endl << sqlfile << "(" << rcount << ")" << endl;
143 //cout << "----------------------" << endl;
144 //cout << sqlbuf << endl;
145
146 return SqlParser::Parse(sqlbuf);
147 }
148 }
149