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