diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:00:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:00:34 +0000 |
commit | 3f619478f796eddbba6e39502fe941b285dd97b1 (patch) | |
tree | e2c7b5777f728320e5b5542b6213fd3591ba51e2 /sql/sql_bootstrap.cc | |
parent | Initial commit. (diff) | |
download | mariadb-3f619478f796eddbba6e39502fe941b285dd97b1.tar.xz mariadb-3f619478f796eddbba6e39502fe941b285dd97b1.zip |
Adding upstream version 1:10.11.6.upstream/1%10.11.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sql/sql_bootstrap.cc')
-rw-r--r-- | sql/sql_bootstrap.cc | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/sql/sql_bootstrap.cc b/sql/sql_bootstrap.cc new file mode 100644 index 00000000..b39d7a57 --- /dev/null +++ b/sql/sql_bootstrap.cc @@ -0,0 +1,159 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ + + +#include "mariadb.h" +#include <ctype.h> +#include <string.h> +#include "sql_bootstrap.h" +#include <string> + +static bool is_end_of_query(const char *line, size_t len, + const std::string& delimiter) +{ + if (delimiter.length() > len) + return false; + return !strcmp(line + len-delimiter.length(),delimiter.c_str()); +} + +static std::string delimiter= ";"; +extern "C" int read_bootstrap_query(char *query, int *query_length, + fgets_input_t input, fgets_fn_t fgets_fn, + int preserve_delimiter, int *error) +{ + char line_buffer[MAX_BOOTSTRAP_LINE_SIZE]; + const char *line; + size_t len; + size_t query_len= 0; + int fgets_error= 0; + *error= 0; + + *query_length= 0; + for ( ; ; ) + { + line= (*fgets_fn)(line_buffer, sizeof(line_buffer), input, &fgets_error); + + if (error) + *error= fgets_error; + + if (fgets_error != 0) + return READ_BOOTSTRAP_ERROR; + + if (line == NULL) + return (query_len == 0) ? READ_BOOTSTRAP_EOF : READ_BOOTSTRAP_ERROR; + + len= strlen(line); + + /* + Remove trailing whitespace characters. + This assumes: + - no multibyte encoded character can be found at the very end of a line, + - whitespace characters from the "C" locale only. + which is sufficient for the kind of queries found + in the bootstrap scripts. + */ + while (len && (isspace(line[len - 1]))) + len--; + /* + Cleanly end the string, so we don't have to test len > x + all the time before reading line[x], in the code below. + */ + line_buffer[len]= '\0'; + + /* Skip blank lines */ + if (len == 0) + continue; + + /* Skip # comments */ + if (line[0] == '#') + continue; + + /* Skip -- comments */ + if ((line[0] == '-') && (line[1] == '-')) + continue; + + size_t i=0; + while (line[i] == ' ') + i++; + + /* Skip -- comments */ + if (line[i] == '-' && line[i+1] == '-') + continue; + + if (strncmp(line, "DELIMITER", 9) == 0) + { + const char *p= strrchr(line,' '); + if (!p || !p[1]) + { + /* Invalid DELIMITER specifier */ + return READ_BOOTSTRAP_ERROR; + } + delimiter.assign(p+1); + if (preserve_delimiter) + { + memcpy(query,line,len); + query[len]=0; + *query_length = (int)len; + return READ_BOOTSTRAP_SUCCESS; + } + continue; + } + + /* Append the current line to a multi line query. If the new line will make + the query too long, preserve the partial line to provide context for the + error message. + */ + if (query_len + len + 1 >= MAX_BOOTSTRAP_QUERY_SIZE) + { + size_t new_len= MAX_BOOTSTRAP_QUERY_SIZE - query_len - 1; + if ((new_len > 0) && (query_len < MAX_BOOTSTRAP_QUERY_SIZE)) + { + memcpy(query + query_len, line, new_len); + query_len+= new_len; + } + query[query_len]= '\0'; + *query_length= (int)query_len; + return READ_BOOTSTRAP_QUERY_SIZE; + } + + if (query_len != 0) + { + /* + Append a \n to the current line, if any, + to preserve the intended presentation. + */ + query[query_len++]= '\n'; + } + memcpy(query + query_len, line, len); + query_len+= len; + + if (is_end_of_query(line, len, delimiter)) + { + /* + The last line is terminated by delimiter + Return the query found. + */ + if (!preserve_delimiter) + { + query_len-= delimiter.length(); + query[query_len++]= ';'; + } + query[query_len]= 0; + *query_length= (int)query_len; + return READ_BOOTSTRAP_SUCCESS; + } + } +} + |