You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-66 - Make the DDL and DML parsers re-entrant.
Serialize all DDL because the VVS can't handle modifying the same block simultaneously Fix the CTRL+C logic in DML that caused COMMIT issues.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2014 InfiniDB, Inc.
|
||||
Copyright (C) 2016 MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@ -44,25 +45,23 @@ extern "C" int _isatty(int);
|
||||
#define yyerror dml_yyerror*/
|
||||
using namespace dmlpackage;
|
||||
|
||||
void dmlerror(char const *s);
|
||||
void dmlerror(yyscan_t yyscanner, char const *s);
|
||||
|
||||
namespace dmlpackage {
|
||||
int lineno = 1;
|
||||
|
||||
|
||||
/* Handles to the buffer that the lexer uses internally */
|
||||
static YY_BUFFER_STATE scanbufhandle;
|
||||
static char *scanbuf;
|
||||
|
||||
static char* scanner_copy (char *str);
|
||||
static char* scanner_copy (char *str, yyscan_t yyscanner);
|
||||
|
||||
|
||||
/* macro to save the text and return a token */
|
||||
#define TOK(name) { dmllval.strval = scanner_copy(dmltext); return name; }
|
||||
/* macro to save the text and return a token */
|
||||
#define TOK(name) { dmlget_lval(yyscanner)->strval = scanner_copy(dmlget_text(yyscanner), yyscanner); return name; }
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%option reentrant
|
||||
%option bison-bridge
|
||||
%option noyywrap
|
||||
%option nounput
|
||||
%x inquote
|
||||
@ -199,9 +198,9 @@ WORK TOK(WORK)
|
||||
%%
|
||||
using namespace dmlpackage;
|
||||
|
||||
void dmlerror(char const *s)
|
||||
void dmlerror(yyscan_t yyscanner, char const *s)
|
||||
{
|
||||
printf("yyerror: %d: %s at %s\n", lineno, s, yytext);
|
||||
printf("yyerror: %d: %s at %s\n", lineno, s, dmlget_text(yyscanner));
|
||||
}
|
||||
|
||||
namespace dmlpackage {
|
||||
@ -216,28 +215,30 @@ valbuf_t get_valbuffer(void)
|
||||
/*
|
||||
* Called before any actual parsing is done
|
||||
*/
|
||||
void scanner_init(const char *str)
|
||||
void scanner_init(const char *str, yyscan_t yyscanner)
|
||||
{
|
||||
size_t slen = strlen(str);
|
||||
scan_data* pScanData = (scan_data*)dmlget_extra(yyscanner);
|
||||
|
||||
/*
|
||||
* Might be left over after ereport()
|
||||
*/
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; // needed for macro YY_CURRENT_BUFFER
|
||||
if (YY_CURRENT_BUFFER)
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER);
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
|
||||
|
||||
/*
|
||||
* Make a scan buffer with special termination needed by flex.
|
||||
*/
|
||||
scanbuf = (char *)malloc(slen + 2);
|
||||
memcpy(scanbuf, str, slen);
|
||||
scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
|
||||
scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
|
||||
pScanData->scanbuf = (char *)malloc(slen + 2);
|
||||
memcpy(pScanData->scanbuf, str, slen);
|
||||
pScanData->scanbuf[slen] = pScanData->scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
|
||||
pScanData->scanbufhandle = yy_scan_buffer(pScanData->scanbuf, slen + 2, yyscanner);
|
||||
|
||||
BEGIN(INITIAL);
|
||||
|
||||
|
||||
valbuf.clear();
|
||||
pScanData->valbuf.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -246,28 +247,29 @@ void scanner_init(const char *str)
|
||||
*/
|
||||
|
||||
|
||||
void scanner_finish(void)
|
||||
void scanner_finish(yyscan_t yyscanner)
|
||||
{
|
||||
char* str;
|
||||
char* str;
|
||||
scan_data* pScanData = (scan_data*)dmlget_extra(yyscanner);
|
||||
|
||||
yy_delete_buffer(scanbufhandle);
|
||||
free(scanbuf);
|
||||
yy_delete_buffer((YY_BUFFER_STATE)pScanData->scanbufhandle, yyscanner);
|
||||
free(pScanData->scanbuf);
|
||||
unsigned int i;
|
||||
for(i=0; i<valbuf.size(); i++) {
|
||||
str = valbuf[i];
|
||||
for(i=0; i<pScanData->valbuf.size(); i++) {
|
||||
str = pScanData->valbuf[i];
|
||||
if(str) {
|
||||
//std::cout << "valbuf:(" << str << ")" << std::endl;
|
||||
free(valbuf[i]);
|
||||
free(pScanData->valbuf[i]);
|
||||
}
|
||||
}
|
||||
valbuf.clear();
|
||||
pScanData->valbuf.clear();
|
||||
}
|
||||
|
||||
char* scanner_copy (char *str)
|
||||
char* scanner_copy (char *str, yyscan_t yyscanner)
|
||||
{
|
||||
char* nv = strdup(str);
|
||||
if(nv)
|
||||
valbuf.push_back(nv);
|
||||
((scan_data*)dmlget_extra(yyscanner))->valbuf.push_back(nv);
|
||||
return nv;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2014 InfiniDB, Inc.
|
||||
Copyright (C) 2016 MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@ -55,6 +56,7 @@
|
||||
a more recent version of flex. At the time of this writing, our
|
||||
development systems have: flex version 2.5.4
|
||||
|
||||
MCOL-66 Modify to be a reentrant parser
|
||||
*/
|
||||
%{
|
||||
#include <string.h>
|
||||
@ -72,9 +74,9 @@
|
||||
using namespace std;
|
||||
using namespace dmlpackage;
|
||||
|
||||
int dmllex();
|
||||
int dmllex(YYSTYPE* dmllval, void* yyscanner);
|
||||
|
||||
void dmlerror (char const *error);
|
||||
void dmlerror (void* yyscanner, char const *error);
|
||||
|
||||
namespace dmlpackage {
|
||||
|
||||
@ -88,8 +90,12 @@ char* copy_string(const char *str);
|
||||
}
|
||||
|
||||
%}
|
||||
%pure-parser
|
||||
%lex-param {void * scanner}
|
||||
%parse-param {void * scanner}
|
||||
%debug
|
||||
/* symbolic tokens */
|
||||
|
||||
/* symbolic tokens */
|
||||
|
||||
%union {
|
||||
int intval;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2014 InfiniDB, Inc.
|
||||
Copyright (C) 2016 MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@ -37,14 +38,16 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int dmlparse();
|
||||
int dmllex_init_extra(void* user_defined, void** yyscanner);
|
||||
int dmllex_destroy(void* yyscanner);
|
||||
int dmlparse(void* yyscanner);
|
||||
|
||||
namespace dmlpackage
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
void scanner_finish(void);
|
||||
void scanner_init(const char *str);
|
||||
void scanner_finish(void* yyscanner);
|
||||
void scanner_init(const char *str, void* yyscanner);
|
||||
void grammar_init(dmlpackage::ParseTree* _ptree, bool);
|
||||
valbuf_t get_valbuffer(void);
|
||||
|
||||
@ -57,7 +60,8 @@ namespace dmlpackage
|
||||
|
||||
DMLParser::~DMLParser()
|
||||
{
|
||||
scanner_finish();
|
||||
scanner_finish(scanner);
|
||||
dmllex_destroy(scanner);
|
||||
}
|
||||
|
||||
void DMLParser::setDebug(bool debug)
|
||||
@ -67,9 +71,10 @@ namespace dmlpackage
|
||||
|
||||
int DMLParser::parse(const char* dmltext)
|
||||
{
|
||||
scanner_init(dmltext);
|
||||
dmllex_init_extra(&scanData, &scanner);
|
||||
scanner_init(dmltext, scanner);
|
||||
grammar_init(&fParseTree, fDebug);
|
||||
fStatus = dmlparse();
|
||||
fStatus = dmlparse(scanner);
|
||||
if (fStatus == 0)
|
||||
{
|
||||
char* str;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2014 InfiniDB, Inc.
|
||||
Copyright (C) 2016 MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@ -35,9 +36,20 @@ namespace dmlpackage
|
||||
|
||||
typedef SqlStatementList ParseTree;
|
||||
|
||||
/** @brief BISON parser wrapper class
|
||||
*/
|
||||
class DMLParser
|
||||
// instance data for the parser
|
||||
typedef std::vector<char*> valbuf_t;
|
||||
|
||||
struct scan_data
|
||||
{
|
||||
/* Handles to the buffer that the lexer uses internally */
|
||||
char* scanbuf;
|
||||
void* scanbufhandle; // This is a YY_BUFFER_STATE defined in ddl-scan.cpp
|
||||
valbuf_t valbuf;
|
||||
};
|
||||
|
||||
/** @brief BISON parser wrapper class
|
||||
*/
|
||||
class DMLParser
|
||||
{
|
||||
public:
|
||||
/** @brief ctor
|
||||
@ -73,6 +85,8 @@ namespace dmlpackage
|
||||
ParseTree fParseTree;
|
||||
int fStatus;
|
||||
bool fDebug;
|
||||
void* scanner; // yyscan_t * needed for re-entrant flex scanner
|
||||
scan_data scanData;
|
||||
|
||||
private:
|
||||
|
||||
|
Reference in New Issue
Block a user