yacc_sql.y 11.8 KB
Newer Older
羽飞's avatar
羽飞 已提交
1 2 3 4

%{

#include "sql/parser/parse_defs.h"
羽飞's avatar
羽飞 已提交
5 6 7
#include "sql/parser/yacc_sql.hpp"
#include "sql/parser/lex_sql.h"
#include "common/log/log.h"
羽飞's avatar
羽飞 已提交
8

羽飞's avatar
羽飞 已提交
9 10 11 12
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
羽飞's avatar
羽飞 已提交
13 14 15 16

//获取子串
char *substr(const char *s,int n1,int n2)/*从s中提取下标为n1~n2的字符组成一个新字符串,然后返回这个新串的首地址*/
{
羽飞's avatar
羽飞 已提交
17
  char *sp = (char *)malloc(sizeof(char) * (n2 - n1 + 2));
羽飞's avatar
羽飞 已提交
18 19 20 21 22 23 24 25
  int i, j = 0;
  for (i = n1; i <= n2; i++) {
    sp[j++] = s[i];
  }
  sp[j] = 0;
  return sp;
}

羽飞's avatar
羽飞 已提交
26
int yyerror(YYLTYPE *llocp, ParsedSqlResult *sql_result, yyscan_t scanner, const char *msg)
羽飞's avatar
羽飞 已提交
27
{
羽飞's avatar
羽飞 已提交
28 29 30 31 32 33
  std::unique_ptr<Query> error_query = std::make_unique<Query>(SCF_ERROR);
  error_query->error.error_msg = msg;
  error_query->error.line = llocp->first_line;
  error_query->error.column = llocp->first_column;
  sql_result->add_command(std::move(error_query));
  return 0;
羽飞's avatar
羽飞 已提交
34 35 36 37 38
}

%}

%define api.pure full
羽飞's avatar
羽飞 已提交
39 40
%define parse.error verbose
%locations
羽飞's avatar
羽飞 已提交
41
%lex-param { yyscan_t scanner }
羽飞's avatar
羽飞 已提交
42 43
%parse-param { ParsedSqlResult * sql_result }
%parse-param { void * scanner }
羽飞's avatar
羽飞 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

//标识tokens
%token  SEMICOLON
        CREATE
        DROP
        TABLE
        TABLES
        INDEX
        SELECT
        DESC
        SHOW
        SYNC
        INSERT
        DELETE
        UPDATE
        LBRACE
        RBRACE
        COMMA
        TRX_BEGIN
        TRX_COMMIT
        TRX_ROLLBACK
        INT_T
        STRING_T
        FLOAT_T
        HELP
        EXIT
        DOT //QUOTE
        INTO
        VALUES
        FROM
        WHERE
        AND
        SET
        ON
        LOAD
        DATA
        INFILE
羽飞's avatar
羽飞 已提交
81
        EXPLAIN
羽飞's avatar
羽飞 已提交
82 83 84 85 86 87 88 89
        EQ
        LT
        GT
        LE
        GE
        NE

%union {
羽飞's avatar
羽飞 已提交
90 91 92 93 94 95 96 97 98 99 100
  Query *query;
  Condition *condition;
  Value *value;
  enum CompOp comp;
  RelAttr *rel_attr;
  std::vector<AttrInfo> *attr_infos;
  AttrInfo *attr_info;
  std::vector<Value> *value_list;
  std::vector<Condition> *condition_list;
  std::vector<RelAttr> *rel_attr_list;
  std::vector<std::string> *relation_list;
羽飞's avatar
羽飞 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114
  char *string;
  int number;
  float floats;
}

%token <number> NUMBER
%token <floats> FLOAT 
%token <string> ID
%token <string> PATH
%token <string> SSS
%token <string> STAR
%token <string> STRING_V
//非终结符

羽飞's avatar
羽飞 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
%type <number>              type
%type <condition>           condition
%type <value>               value
%type <number>              number
%type <comp>                comp_op
%type <rel_attr>            rel_attr
%type <attr_infos>          attr_def_list
%type <attr_info>           attr_def
%type <value_list>          value_list
%type <condition_list>      where
%type <condition_list>      condition_list
%type <rel_attr_list>       select_attr
%type <relation_list>       rel_list
%type <rel_attr_list>       attr_list
%type <query> select
%type <query> insert
%type <query> update
%type <query> delete
%type <query> create_table
%type <query> drop_table
%type <query> show_tables
%type <query> desc_table
%type <query> create_index
%type <query> drop_index
%type <query> sync
%type <query> begin
%type <query> commit
%type <query> rollback
%type <query> load_data
%type <query> explain
%type <query> help
%type <query> exit
%type <query> command
// commands should be a list but I use a single command instead
%type <query> commands
羽飞's avatar
羽飞 已提交
150 151
%%

羽飞's avatar
羽飞 已提交
152 153 154 155 156 157
commands: command opt_semicolon  //commands or sqls. parser starts here.
  {
    std::unique_ptr<Query> query_command = std::unique_ptr<Query>($1);
    sql_result->add_command(std::move(query_command));
  }
  ;
羽飞's avatar
羽飞 已提交
158 159

command:
羽飞's avatar
羽飞 已提交
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
    select  
  | insert
  | update
  | delete
  | create_table
  | drop_table
  | show_tables
  | desc_table
  | create_index  
  | drop_index
  | sync
  | begin
  | commit
  | rollback
  | load_data
羽飞's avatar
羽飞 已提交
175
  | explain
羽飞's avatar
羽飞 已提交
176 177
  | help
  | exit
羽飞's avatar
羽飞 已提交
178 179
    ;

羽飞's avatar
羽飞 已提交
180
exit:      
羽飞's avatar
羽飞 已提交
181 182
    EXIT {
      $$ = new Query(SCF_EXIT);
羽飞's avatar
羽飞 已提交
183 184 185
    };

help:
羽飞's avatar
羽飞 已提交
186 187
    HELP {
      $$ = new Query(SCF_HELP);
羽飞's avatar
羽飞 已提交
188 189 190
    };

sync:
羽飞's avatar
羽飞 已提交
191 192
    SYNC {
      $$ = new Query(SCF_SYNC);
羽飞's avatar
羽飞 已提交
193 194 195 196
    }
    ;

begin:
羽飞's avatar
羽飞 已提交
197 198
    TRX_BEGIN  {
      $$ = new Query(SCF_BEGIN);
羽飞's avatar
羽飞 已提交
199 200 201 202
    }
    ;

commit:
羽飞's avatar
羽飞 已提交
203 204
    TRX_COMMIT {
      $$ = new Query(SCF_COMMIT);
羽飞's avatar
羽飞 已提交
205 206 207 208
    }
    ;

rollback:
羽飞's avatar
羽飞 已提交
209 210
    TRX_ROLLBACK  {
      $$ = new Query(SCF_ROLLBACK);
羽飞's avatar
羽飞 已提交
211 212 213
    }
    ;

羽飞's avatar
羽飞 已提交
214
drop_table:    /*drop table 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
215 216 217 218
    DROP TABLE ID {
      $$ = new Query(SCF_DROP_TABLE);
      $$->drop_table.relation_name = $3;
      free($3);
羽飞's avatar
羽飞 已提交
219 220 221
    };

show_tables:
羽飞's avatar
羽飞 已提交
222 223
    SHOW TABLES {
      $$ = new Query(SCF_SHOW_TABLES);
羽飞's avatar
羽飞 已提交
224 225 226 227
    }
    ;

desc_table:
羽飞's avatar
羽飞 已提交
228 229 230 231
    DESC ID  {
      $$ = new Query(SCF_DESC_TABLE);
      $$->desc_table.relation_name = $2;
      free($2);
羽飞's avatar
羽飞 已提交
232 233 234
    }
    ;

羽飞's avatar
羽飞 已提交
235
create_index:    /*create index 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
236
    CREATE INDEX ID ON ID LBRACE ID RBRACE
羽飞's avatar
羽飞 已提交
237
    {
羽飞's avatar
羽飞 已提交
238 239 240 241 242 243 244 245
      $$ = new Query(SCF_CREATE_INDEX);
      CreateIndex &create_index = $$->create_index;
      create_index.index_name = $3;
      create_index.relation_name = $5;
      create_index.attribute_name = $7;
      free($3);
      free($5);
      free($7);
羽飞's avatar
羽飞 已提交
246
    }
羽飞's avatar
羽飞 已提交
247 248
    ;

羽飞's avatar
羽飞 已提交
249
drop_index:      /*drop index 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
250
    DROP INDEX ID 
羽飞's avatar
羽飞 已提交
251
    {
羽飞's avatar
羽飞 已提交
252 253 254
      $$ = new Query(SCF_DROP_INDEX);
      $$->drop_index.index_name = $3;
      free($3);
羽飞's avatar
羽飞 已提交
255
    }
羽飞's avatar
羽飞 已提交
256
    ;
羽飞's avatar
羽飞 已提交
257
create_table:    /*create table 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
258
    CREATE TABLE ID LBRACE attr_def attr_def_list RBRACE
羽飞's avatar
羽飞 已提交
259
    {
羽飞's avatar
羽飞 已提交
260 261 262 263 264 265 266 267 268 269 270 271 272
      $$ = new Query(SCF_CREATE_TABLE);
      CreateTable &create_table = $$->create_table;
      create_table.relation_name = $3;
      free($3);

      std::vector<AttrInfo> *src_attrs = $6;

      if (src_attrs != nullptr) {
        create_table.attr_infos.swap(*src_attrs);
      }
      create_table.attr_infos.emplace_back(*$5);
      std::reverse(create_table.attr_infos.begin(), create_table.attr_infos.end());
      delete $5;
羽飞's avatar
羽飞 已提交
273
    }
羽飞's avatar
羽飞 已提交
274 275 276
    ;
attr_def_list:
    /* empty */
羽飞's avatar
羽飞 已提交
277 278 279 280 281 282 283 284 285 286 287 288 289
    {
      $$ = nullptr;
    }
    | COMMA attr_def attr_def_list
    {
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<AttrInfo>;
      }
      $$->emplace_back(*$2);
      delete $2;
    }
羽飞's avatar
羽飞 已提交
290 291 292
    ;
    
attr_def:
羽飞's avatar
羽飞 已提交
293 294
    ID type LBRACE number RBRACE 
    {
羽飞's avatar
羽飞 已提交
295 296 297 298 299
      $$ = new AttrInfo;
      $$->type = (AttrType)$2;
      $$->name = $1;
      $$->length = $4;
      free($1);
羽飞's avatar
羽飞 已提交
300
    }
羽飞's avatar
羽飞 已提交
301
    | ID type
羽飞's avatar
羽飞 已提交
302
    {
羽飞's avatar
羽飞 已提交
303 304 305 306 307
      $$ = new AttrInfo;
      $$->type = (AttrType)$2;
      $$->name = $1;
      $$->length = 4;
      free($1);
羽飞's avatar
羽飞 已提交
308
    }
羽飞's avatar
羽飞 已提交
309 310
    ;
number:
羽飞's avatar
羽飞 已提交
311 312
    NUMBER {$$ = $1;}
    ;
羽飞's avatar
羽飞 已提交
313
type:
羽飞's avatar
羽飞 已提交
314 315 316 317
    INT_T      { $$=INTS; }
    | STRING_T { $$=CHARS; }
    | FLOAT_T  { $$=FLOATS; }
    ;
羽飞's avatar
羽飞 已提交
318
insert:        /*insert   语句的语法解析树*/
羽飞's avatar
羽飞 已提交
319
    INSERT INTO ID VALUES LBRACE value value_list RBRACE 
羽飞's avatar
羽飞 已提交
320
    {
羽飞's avatar
羽飞 已提交
321 322 323 324 325 326 327 328 329
      $$ = new Query(SCF_INSERT);
      $$->insertion.relation_name = $3;
      if ($7 != nullptr) {
        $$->insertion.values.swap(*$7);
      }
      $$->insertion.values.emplace_back(*$6);
      std::reverse($$->insertion.values.begin(), $$->insertion.values.end());
      delete $6;
      free($3);
羽飞's avatar
羽飞 已提交
330
    }
羽飞's avatar
羽飞 已提交
331
    ;
羽飞's avatar
羽飞 已提交
332 333 334

value_list:
    /* empty */
羽飞's avatar
羽飞 已提交
335 336 337
    {
      $$ = nullptr;
    }
羽飞's avatar
羽飞 已提交
338
    | COMMA value value_list  { 
羽飞's avatar
羽飞 已提交
339 340 341 342 343 344 345
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<Value>;
      }
      $$->emplace_back(*$2);
      delete $2;
羽飞's avatar
羽飞 已提交
346
    }
羽飞's avatar
羽飞 已提交
347 348
    ;
value:
羽飞's avatar
羽飞 已提交
349 350 351 352
    NUMBER {
      $$ = new Value;
      $$->type = INTS;
      $$->int_value = $1;
羽飞's avatar
羽飞 已提交
353
    }
羽飞's avatar
羽飞 已提交
354 355 356 357
    |FLOAT {
      $$ = new Value;
      $$->type = FLOATS;
      $$->float_value = $1;
羽飞's avatar
羽飞 已提交
358
    }
羽飞's avatar
羽飞 已提交
359
    |SSS {
羽飞's avatar
羽飞 已提交
360
      char *tmp = substr($1,1,strlen($1)-2);
羽飞's avatar
羽飞 已提交
361 362 363 364
      $$ = new Value;
      $$->type = CHARS;
      $$->string_value = tmp;
      free(tmp);
羽飞's avatar
羽飞 已提交
365
    }
羽飞's avatar
羽飞 已提交
366 367
    ;
    
羽飞's avatar
羽飞 已提交
368
delete:    /*  delete 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
369
    DELETE FROM ID where 
羽飞's avatar
羽飞 已提交
370
    {
羽飞's avatar
羽飞 已提交
371 372 373 374 375 376 377
      $$ = new Query(SCF_DELETE);
      $$->deletion.relation_name = $3;
      if ($4 != nullptr) {
        $$->deletion.conditions.swap(*$4);
        delete $4;
      }
      free($3);
羽飞's avatar
羽飞 已提交
378 379
    }
    ;
羽飞's avatar
羽飞 已提交
380
update:      /*  update 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
381
    UPDATE ID SET ID EQ value where 
羽飞's avatar
羽飞 已提交
382
    {
羽飞's avatar
羽飞 已提交
383 384 385 386 387 388 389 390 391 392
      $$ = new Query(SCF_UPDATE);
      $$->update.relation_name = $2;
      $$->update.attribute_name = $4;
      $$->update.value = *$6;
      if ($7 != nullptr) {
        $$->update.conditions.swap(*$7);
        delete $7;
      }
      free($2);
      free($4);
羽飞's avatar
羽飞 已提交
393
    }
羽飞's avatar
羽飞 已提交
394
    ;
羽飞's avatar
羽飞 已提交
395
select:        /*  select 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
396
    SELECT select_attr FROM ID rel_list where
羽飞's avatar
羽飞 已提交
397
    {
羽飞's avatar
羽飞 已提交
398 399 400 401 402 403 404 405 406 407 408
      $$ = new Query(SCF_SELECT);
      if ($2 != nullptr) {
        $$->selection.attributes.swap(*$2);
        delete $2;
      }
      if ($5 != nullptr) {
        $$->selection.relations.swap(*$5);
        delete $5;
      }
      $$->selection.relations.push_back($4);
      std::reverse($$->selection.relations.begin(), $$->selection.relations.end());
羽飞's avatar
羽飞 已提交
409

羽飞's avatar
羽飞 已提交
410 411 412 413 414
      if ($6 != nullptr) {
        $$->selection.conditions.swap(*$6);
        delete $6;
      }
      free($4);
羽飞's avatar
羽飞 已提交
415 416
    }
    ;
羽飞's avatar
羽飞 已提交
417 418

select_attr:
羽飞's avatar
羽飞 已提交
419 420
    STAR {
      $$ = new std::vector<RelAttr>;
羽飞's avatar
羽飞 已提交
421
      RelAttr attr;
羽飞's avatar
羽飞 已提交
422 423 424
      attr.relation_name = "";
      attr.attribute_name = "*";
      $$->emplace_back(attr);
羽飞's avatar
羽飞 已提交
425
    }
羽飞's avatar
羽飞 已提交
426 427 428 429 430 431 432 433
    | rel_attr attr_list {
      if ($2 != nullptr) {
        $$ = $2;
      } else {
        $$ = new std::vector<RelAttr>;
      }
      $$->emplace_back(*$1);
      delete $1;
羽飞's avatar
羽飞 已提交
434
    }
羽飞's avatar
羽飞 已提交
435 436 437 438 439 440 441 442 443 444 445 446 447 448
    ;

rel_attr:
    ID {
      $$ = new RelAttr;
      $$->attribute_name = $1;
      free($1);
    }
    | ID DOT ID {
      $$ = new RelAttr;
      $$->relation_name = $1;
      $$->attribute_name = $3;
      free($1);
      free($3);
羽飞's avatar
羽飞 已提交
449
    }
羽飞's avatar
羽飞 已提交
450
    ;
羽飞's avatar
羽飞 已提交
451

羽飞's avatar
羽飞 已提交
452 453
attr_list:
    /* empty */
羽飞's avatar
羽飞 已提交
454 455 456 457 458 459 460 461
    {
      $$ = nullptr;
    }
    | COMMA rel_attr attr_list {
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<RelAttr>;
羽飞's avatar
羽飞 已提交
462
      }
羽飞's avatar
羽飞 已提交
463 464 465 466

      $$->emplace_back(*$2);
      delete $2;
    }
羽飞's avatar
羽飞 已提交
467
    ;
羽飞's avatar
羽飞 已提交
468 469 470

rel_list:
    /* empty */
羽飞's avatar
羽飞 已提交
471 472 473 474 475 476 477 478
    {
      $$ = nullptr;
    }
    | COMMA ID rel_list {
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<std::string>;
羽飞's avatar
羽飞 已提交
479
      }
羽飞's avatar
羽飞 已提交
480 481 482 483

      $$->push_back($2);
      free($2);
    }
羽飞's avatar
羽飞 已提交
484 485
    ;
where:
羽飞's avatar
羽飞 已提交
486 487 488 489 490 491 492
    /* empty */
    {
      $$ = nullptr;
    }
    | WHERE condition_list {
      $$ = $2;  
    }
羽飞's avatar
羽飞 已提交
493 494 495
    ;
condition_list:
    /* empty */
羽飞's avatar
羽飞 已提交
496
    {
羽飞's avatar
羽飞 已提交
497
      $$ = nullptr;
羽飞's avatar
羽飞 已提交
498
    }
羽飞's avatar
羽飞 已提交
499 500 501 502
    | condition {
      $$ = new std::vector<Condition>;
      $$->emplace_back(*$1);
      delete $1;
羽飞's avatar
羽飞 已提交
503
    }
羽飞's avatar
羽飞 已提交
504 505 506 507
    | condition AND condition_list {
      $$ = $3;
      $$->emplace_back(*$1);
      delete $1;
羽飞's avatar
羽飞 已提交
508
    }
羽飞's avatar
羽飞 已提交
509 510 511
    ;
condition:
    rel_attr comp_op value
羽飞's avatar
羽飞 已提交
512
    {
羽飞's avatar
羽飞 已提交
513 514 515 516 517 518 519 520 521
      $$ = new Condition;
      $$->left_is_attr = 1;
      $$->left_attr = *$1;
      $$->right_is_attr = 0;
      $$->right_value = *$3;
      $$->comp = $2;

      delete $1;
      delete $3;
羽飞's avatar
羽飞 已提交
522
    }
羽飞's avatar
羽飞 已提交
523
    | value comp_op value 
羽飞's avatar
羽飞 已提交
524
    {
羽飞's avatar
羽飞 已提交
525 526 527 528 529 530 531 532 533
      $$ = new Condition;
      $$->left_is_attr = 0;
      $$->left_value = *$1;
      $$->right_is_attr = 0;
      $$->right_value = *$3;
      $$->comp = $2;

      delete $1;
      delete $3;
羽飞's avatar
羽飞 已提交
534
    }
羽飞's avatar
羽飞 已提交
535
    | rel_attr comp_op rel_attr
羽飞's avatar
羽飞 已提交
536
    {
羽飞's avatar
羽飞 已提交
537 538 539 540 541 542 543 544 545
      $$ = new Condition;
      $$->left_is_attr = 1;
      $$->left_attr = *$1;
      $$->right_is_attr = 1;
      $$->right_attr = *$3;
      $$->comp = $2;

      delete $1;
      delete $3;
羽飞's avatar
羽飞 已提交
546
    }
羽飞's avatar
羽飞 已提交
547
    | value comp_op rel_attr
羽飞's avatar
羽飞 已提交
548
    {
羽飞's avatar
羽飞 已提交
549 550 551 552 553 554 555 556 557
      $$ = new Condition;
      $$->left_is_attr = 0;
      $$->left_value = *$1;
      $$->right_is_attr = 1;
      $$->right_attr = *$3;
      $$->comp = $2;

      delete $1;
      delete $3;
羽飞's avatar
羽飞 已提交
558 559 560
    }
    ;

羽飞's avatar
羽飞 已提交
561 562 563 564 565 566 567
comp_op:
      EQ { $$ = EQUAL_TO; }
    | LT { $$ = LESS_THAN; }
    | GT { $$ = GREAT_THAN; }
    | LE { $$ = LESS_EQUAL; }
    | GE { $$ = GREAT_EQUAL; }
    | NE { $$ = NOT_EQUAL; }
羽飞's avatar
羽飞 已提交
568 569 570
    ;

load_data:
羽飞's avatar
羽飞 已提交
571 572 573 574 575 576 577 578 579 580 581
    LOAD DATA INFILE SSS INTO TABLE ID 
    {
      $$ = new Query(SCF_LOAD_DATA);
      $$->load_data.relation_name = $7;
      $$->load_data.file_name = $4;
      free($7);
    }
    ;

explain:
    EXPLAIN command
羽飞's avatar
羽飞 已提交
582
    {
羽飞's avatar
羽飞 已提交
583 584
      $$ = new Query(SCF_EXPLAIN);
      $$->explain.query = std::unique_ptr<Query>($2);
羽飞's avatar
羽飞 已提交
585 586
    }
    ;
羽飞's avatar
羽飞 已提交
587 588 589 590

opt_semicolon: /*empty*/
    | SEMICOLON
    ;
羽飞's avatar
羽飞 已提交
591 592 593 594
%%
//_____________________________________________________________________
extern void scan_string(const char *str, yyscan_t scanner);

羽飞's avatar
羽飞 已提交
595
int sql_parse(const char *s, ParsedSqlResult *sql_result){
羽飞's avatar
羽飞 已提交
596
  yyscan_t scanner;
羽飞's avatar
羽飞 已提交
597
  yylex_init(&scanner);
羽飞's avatar
羽飞 已提交
598
  scan_string(s, scanner);
羽飞's avatar
羽飞 已提交
599
  int result = yyparse(sql_result, scanner);
羽飞's avatar
羽飞 已提交
600 601
  yylex_destroy(scanner);
  return result;
羽飞's avatar
羽飞 已提交
602
}