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

%{

羽飞's avatar
羽飞 已提交
4 5 6 7
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
羽飞's avatar
羽飞 已提交
8

9 10 11 12 13 14
#include "common/log/log.h"
#include "common/lang/string.h"
#include "sql/parser/parse_defs.h"
#include "sql/parser/yacc_sql.hpp"
#include "sql/parser/lex_sql.h"

羽飞's avatar
羽飞 已提交
15

羽飞's avatar
羽飞 已提交
16
int yyerror(YYLTYPE *llocp, ParsedSqlResult *sql_result, yyscan_t scanner, const char *msg)
羽飞's avatar
羽飞 已提交
17
{
18 19 20 21 22
  std::unique_ptr<Command> error_cmd = std::make_unique<Command>(SCF_ERROR);
  error_cmd->error.error_msg = msg;
  error_cmd->error.line = llocp->first_line;
  error_cmd->error.column = llocp->first_column;
  sql_result->add_command(std::move(error_cmd));
羽飞's avatar
羽飞 已提交
23
  return 0;
羽飞's avatar
羽飞 已提交
24 25 26 27 28
}

%}

%define api.pure full
羽飞's avatar
羽飞 已提交
29 30
%define parse.error verbose
%locations
羽飞's avatar
羽飞 已提交
31
%lex-param { yyscan_t scanner }
羽飞's avatar
羽飞 已提交
32 33
%parse-param { ParsedSqlResult * sql_result }
%parse-param { void * scanner }
羽飞's avatar
羽飞 已提交
34 35 36 37 38 39 40 41 42 43 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

//标识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
羽飞 已提交
71
        EXPLAIN
羽飞's avatar
羽飞 已提交
72 73 74 75 76 77 78 79
        EQ
        LT
        GT
        LE
        GE
        NE

%union {
80
  Command *command;
羽飞's avatar
羽飞 已提交
81 82 83 84 85 86 87 88 89 90
  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
羽飞 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104
  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
羽飞 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118
%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
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
%type <command> select
%type <command> insert
%type <command> update
%type <command> delete
%type <command> create_table
%type <command> drop_table
%type <command> show_tables
%type <command> desc_table
%type <command> create_index
%type <command> drop_index
%type <command> sync
%type <command> begin
%type <command> commit
%type <command> rollback
%type <command> load_data
%type <command> explain
羽飞's avatar
羽飞 已提交
135
%type <command> set_variable
136 137 138
%type <command> help
%type <command> exit
%type <command> command_wrapper
羽飞's avatar
羽飞 已提交
139
// commands should be a list but I use a single command instead
140
%type <command> commands
羽飞's avatar
羽飞 已提交
141 142
%%

143
commands: command_wrapper opt_semicolon  //commands or sqls. parser starts here.
羽飞's avatar
羽飞 已提交
144
  {
145 146
    std::unique_ptr<Command> sql_command = std::unique_ptr<Command>($1);
    sql_result->add_command(std::move(sql_command));
羽飞's avatar
羽飞 已提交
147 148
  }
  ;
羽飞's avatar
羽飞 已提交
149

150
command_wrapper:
羽飞's avatar
羽飞 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    select  
  | insert
  | update
  | delete
  | create_table
  | drop_table
  | show_tables
  | desc_table
  | create_index  
  | drop_index
  | sync
  | begin
  | commit
  | rollback
  | load_data
羽飞's avatar
羽飞 已提交
166
  | explain
羽飞's avatar
羽飞 已提交
167
  | set_variable
羽飞's avatar
羽飞 已提交
168 169
  | help
  | exit
羽飞's avatar
羽飞 已提交
170 171
    ;

羽飞's avatar
羽飞 已提交
172
exit:      
羽飞's avatar
羽飞 已提交
173
    EXIT {
羽飞's avatar
羽飞 已提交
174
      (void)yynerrs;  // 这么写为了消除yynerrs未使用的告警。如果你有更好的方法欢迎提PR
175
      $$ = new Command(SCF_EXIT);
羽飞's avatar
羽飞 已提交
176 177 178
    };

help:
羽飞's avatar
羽飞 已提交
179
    HELP {
180
      $$ = new Command(SCF_HELP);
羽飞's avatar
羽飞 已提交
181 182 183
    };

sync:
羽飞's avatar
羽飞 已提交
184
    SYNC {
185
      $$ = new Command(SCF_SYNC);
羽飞's avatar
羽飞 已提交
186 187 188 189
    }
    ;

begin:
羽飞's avatar
羽飞 已提交
190
    TRX_BEGIN  {
191
      $$ = new Command(SCF_BEGIN);
羽飞's avatar
羽飞 已提交
192 193 194 195
    }
    ;

commit:
羽飞's avatar
羽飞 已提交
196
    TRX_COMMIT {
197
      $$ = new Command(SCF_COMMIT);
羽飞's avatar
羽飞 已提交
198 199 200 201
    }
    ;

rollback:
羽飞's avatar
羽飞 已提交
202
    TRX_ROLLBACK  {
203
      $$ = new Command(SCF_ROLLBACK);
羽飞's avatar
羽飞 已提交
204 205 206
    }
    ;

羽飞's avatar
羽飞 已提交
207
drop_table:    /*drop table 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
208
    DROP TABLE ID {
209
      $$ = new Command(SCF_DROP_TABLE);
羽飞's avatar
羽飞 已提交
210 211
      $$->drop_table.relation_name = $3;
      free($3);
羽飞's avatar
羽飞 已提交
212 213 214
    };

show_tables:
羽飞's avatar
羽飞 已提交
215
    SHOW TABLES {
216
      $$ = new Command(SCF_SHOW_TABLES);
羽飞's avatar
羽飞 已提交
217 218 219 220
    }
    ;

desc_table:
羽飞's avatar
羽飞 已提交
221
    DESC ID  {
222
      $$ = new Command(SCF_DESC_TABLE);
羽飞's avatar
羽飞 已提交
223 224
      $$->desc_table.relation_name = $2;
      free($2);
羽飞's avatar
羽飞 已提交
225 226 227
    }
    ;

羽飞's avatar
羽飞 已提交
228
create_index:    /*create index 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
229
    CREATE INDEX ID ON ID LBRACE ID RBRACE
羽飞's avatar
羽飞 已提交
230
    {
231
      $$ = new Command(SCF_CREATE_INDEX);
羽飞's avatar
羽飞 已提交
232 233 234 235 236 237 238
      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
羽飞 已提交
239
    }
羽飞's avatar
羽飞 已提交
240 241
    ;

羽飞's avatar
羽飞 已提交
242
drop_index:      /*drop index 语句的语法解析树*/
243
    DROP INDEX ID ON ID
羽飞's avatar
羽飞 已提交
244
    {
245
      $$ = new Command(SCF_DROP_INDEX);
羽飞's avatar
羽飞 已提交
246
      $$->drop_index.index_name = $3;
247
      $$->drop_index.relation_name = $5;
羽飞's avatar
羽飞 已提交
248
      free($3);
249
      free($5);
羽飞's avatar
羽飞 已提交
250
    }
羽飞's avatar
羽飞 已提交
251
    ;
羽飞's avatar
羽飞 已提交
252
create_table:    /*create table 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
253
    CREATE TABLE ID LBRACE attr_def attr_def_list RBRACE
羽飞's avatar
羽飞 已提交
254
    {
255
      $$ = new Command(SCF_CREATE_TABLE);
羽飞's avatar
羽飞 已提交
256 257 258 259 260 261 262 263 264 265 266 267
      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
羽飞 已提交
268
    }
羽飞's avatar
羽飞 已提交
269 270 271
    ;
attr_def_list:
    /* empty */
羽飞's avatar
羽飞 已提交
272 273 274 275 276 277 278 279 280 281 282 283 284
    {
      $$ = nullptr;
    }
    | COMMA attr_def attr_def_list
    {
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<AttrInfo>;
      }
      $$->emplace_back(*$2);
      delete $2;
    }
羽飞's avatar
羽飞 已提交
285 286 287
    ;
    
attr_def:
羽飞's avatar
羽飞 已提交
288 289
    ID type LBRACE number RBRACE 
    {
羽飞's avatar
羽飞 已提交
290 291 292 293 294
      $$ = new AttrInfo;
      $$->type = (AttrType)$2;
      $$->name = $1;
      $$->length = $4;
      free($1);
羽飞's avatar
羽飞 已提交
295
    }
羽飞's avatar
羽飞 已提交
296
    | ID type
羽飞's avatar
羽飞 已提交
297
    {
羽飞's avatar
羽飞 已提交
298 299 300 301 302
      $$ = new AttrInfo;
      $$->type = (AttrType)$2;
      $$->name = $1;
      $$->length = 4;
      free($1);
羽飞's avatar
羽飞 已提交
303
    }
羽飞's avatar
羽飞 已提交
304 305
    ;
number:
羽飞's avatar
羽飞 已提交
306 307
    NUMBER {$$ = $1;}
    ;
羽飞's avatar
羽飞 已提交
308
type:
羽飞's avatar
羽飞 已提交
309 310 311 312
    INT_T      { $$=INTS; }
    | STRING_T { $$=CHARS; }
    | FLOAT_T  { $$=FLOATS; }
    ;
羽飞's avatar
羽飞 已提交
313
insert:        /*insert   语句的语法解析树*/
羽飞's avatar
羽飞 已提交
314
    INSERT INTO ID VALUES LBRACE value value_list RBRACE 
羽飞's avatar
羽飞 已提交
315
    {
316
      $$ = new Command(SCF_INSERT);
羽飞's avatar
羽飞 已提交
317 318 319 320 321 322 323 324
      $$->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
羽飞 已提交
325
    }
羽飞's avatar
羽飞 已提交
326
    ;
羽飞's avatar
羽飞 已提交
327 328 329

value_list:
    /* empty */
羽飞's avatar
羽飞 已提交
330 331 332
    {
      $$ = nullptr;
    }
羽飞's avatar
羽飞 已提交
333
    | COMMA value value_list  { 
羽飞's avatar
羽飞 已提交
334 335 336 337 338 339 340
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<Value>;
      }
      $$->emplace_back(*$2);
      delete $2;
羽飞's avatar
羽飞 已提交
341
    }
羽飞's avatar
羽飞 已提交
342 343
    ;
value:
羽飞's avatar
羽飞 已提交
344
    NUMBER {
羽飞's avatar
羽飞 已提交
345
      $$ = new Value((int)$1);
羽飞's avatar
羽飞 已提交
346
    }
羽飞's avatar
羽飞 已提交
347
    |FLOAT {
羽飞's avatar
羽飞 已提交
348
      $$ = new Value((float)$1);
羽飞's avatar
羽飞 已提交
349
    }
羽飞's avatar
羽飞 已提交
350
    |SSS {
351
      char *tmp = common::substr($1,1,strlen($1)-2);
羽飞's avatar
羽飞 已提交
352
      $$ = new Value(tmp);
羽飞's avatar
羽飞 已提交
353
      free(tmp);
羽飞's avatar
羽飞 已提交
354
    }
羽飞's avatar
羽飞 已提交
355 356
    ;
    
羽飞's avatar
羽飞 已提交
357
delete:    /*  delete 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
358
    DELETE FROM ID where 
羽飞's avatar
羽飞 已提交
359
    {
360
      $$ = new Command(SCF_DELETE);
羽飞's avatar
羽飞 已提交
361 362 363 364 365 366
      $$->deletion.relation_name = $3;
      if ($4 != nullptr) {
        $$->deletion.conditions.swap(*$4);
        delete $4;
      }
      free($3);
羽飞's avatar
羽飞 已提交
367 368
    }
    ;
羽飞's avatar
羽飞 已提交
369
update:      /*  update 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
370
    UPDATE ID SET ID EQ value where 
羽飞's avatar
羽飞 已提交
371
    {
372
      $$ = new Command(SCF_UPDATE);
羽飞's avatar
羽飞 已提交
373 374 375 376 377 378 379 380 381
      $$->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
羽飞 已提交
382
    }
羽飞's avatar
羽飞 已提交
383
    ;
羽飞's avatar
羽飞 已提交
384
select:        /*  select 语句的语法解析树*/
羽飞's avatar
羽飞 已提交
385
    SELECT select_attr FROM ID rel_list where
羽飞's avatar
羽飞 已提交
386
    {
387
      $$ = new Command(SCF_SELECT);
羽飞's avatar
羽飞 已提交
388 389 390 391 392 393 394 395 396 397
      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
羽飞 已提交
398

羽飞's avatar
羽飞 已提交
399 400 401 402 403
      if ($6 != nullptr) {
        $$->selection.conditions.swap(*$6);
        delete $6;
      }
      free($4);
羽飞's avatar
羽飞 已提交
404 405
    }
    ;
羽飞's avatar
羽飞 已提交
406 407

select_attr:
羽飞's avatar
羽飞 已提交
408 409
    STAR {
      $$ = new std::vector<RelAttr>;
羽飞's avatar
羽飞 已提交
410
      RelAttr attr;
羽飞's avatar
羽飞 已提交
411 412 413
      attr.relation_name = "";
      attr.attribute_name = "*";
      $$->emplace_back(attr);
羽飞's avatar
羽飞 已提交
414
    }
羽飞's avatar
羽飞 已提交
415 416 417 418 419 420 421 422
    | rel_attr attr_list {
      if ($2 != nullptr) {
        $$ = $2;
      } else {
        $$ = new std::vector<RelAttr>;
      }
      $$->emplace_back(*$1);
      delete $1;
羽飞's avatar
羽飞 已提交
423
    }
羽飞's avatar
羽飞 已提交
424 425 426 427 428 429 430 431 432 433 434 435 436 437
    ;

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
羽飞 已提交
438
    }
羽飞's avatar
羽飞 已提交
439
    ;
羽飞's avatar
羽飞 已提交
440

羽飞's avatar
羽飞 已提交
441 442
attr_list:
    /* empty */
羽飞's avatar
羽飞 已提交
443 444 445 446 447 448 449 450
    {
      $$ = nullptr;
    }
    | COMMA rel_attr attr_list {
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<RelAttr>;
羽飞's avatar
羽飞 已提交
451
      }
羽飞's avatar
羽飞 已提交
452 453 454 455

      $$->emplace_back(*$2);
      delete $2;
    }
羽飞's avatar
羽飞 已提交
456
    ;
羽飞's avatar
羽飞 已提交
457 458 459

rel_list:
    /* empty */
羽飞's avatar
羽飞 已提交
460 461 462 463 464 465 466 467
    {
      $$ = nullptr;
    }
    | COMMA ID rel_list {
      if ($3 != nullptr) {
        $$ = $3;
      } else {
        $$ = new std::vector<std::string>;
羽飞's avatar
羽飞 已提交
468
      }
羽飞's avatar
羽飞 已提交
469 470 471 472

      $$->push_back($2);
      free($2);
    }
羽飞's avatar
羽飞 已提交
473 474
    ;
where:
羽飞's avatar
羽飞 已提交
475 476 477 478 479 480 481
    /* empty */
    {
      $$ = nullptr;
    }
    | WHERE condition_list {
      $$ = $2;  
    }
羽飞's avatar
羽飞 已提交
482 483 484
    ;
condition_list:
    /* empty */
羽飞's avatar
羽飞 已提交
485
    {
羽飞's avatar
羽飞 已提交
486
      $$ = nullptr;
羽飞's avatar
羽飞 已提交
487
    }
羽飞's avatar
羽飞 已提交
488 489 490 491
    | condition {
      $$ = new std::vector<Condition>;
      $$->emplace_back(*$1);
      delete $1;
羽飞's avatar
羽飞 已提交
492
    }
羽飞's avatar
羽飞 已提交
493 494 495 496
    | condition AND condition_list {
      $$ = $3;
      $$->emplace_back(*$1);
      delete $1;
羽飞's avatar
羽飞 已提交
497
    }
羽飞's avatar
羽飞 已提交
498 499 500
    ;
condition:
    rel_attr comp_op value
羽飞's avatar
羽飞 已提交
501
    {
羽飞's avatar
羽飞 已提交
502 503 504 505 506 507 508 509 510
      $$ = new Condition;
      $$->left_is_attr = 1;
      $$->left_attr = *$1;
      $$->right_is_attr = 0;
      $$->right_value = *$3;
      $$->comp = $2;

      delete $1;
      delete $3;
羽飞's avatar
羽飞 已提交
511
    }
羽飞's avatar
羽飞 已提交
512
    | value comp_op value 
羽飞's avatar
羽飞 已提交
513
    {
羽飞's avatar
羽飞 已提交
514 515 516 517 518 519 520 521 522
      $$ = new Condition;
      $$->left_is_attr = 0;
      $$->left_value = *$1;
      $$->right_is_attr = 0;
      $$->right_value = *$3;
      $$->comp = $2;

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

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

      delete $1;
      delete $3;
羽飞's avatar
羽飞 已提交
547 548 549
    }
    ;

羽飞's avatar
羽飞 已提交
550 551 552 553 554 555 556
comp_op:
      EQ { $$ = EQUAL_TO; }
    | LT { $$ = LESS_THAN; }
    | GT { $$ = GREAT_THAN; }
    | LE { $$ = LESS_EQUAL; }
    | GE { $$ = GREAT_EQUAL; }
    | NE { $$ = NOT_EQUAL; }
羽飞's avatar
羽飞 已提交
557 558 559
    ;

load_data:
羽飞's avatar
羽飞 已提交
560 561
    LOAD DATA INFILE SSS INTO TABLE ID 
    {
562
      $$ = new Command(SCF_LOAD_DATA);
羽飞's avatar
羽飞 已提交
563 564 565 566 567 568 569
      $$->load_data.relation_name = $7;
      $$->load_data.file_name = $4;
      free($7);
    }
    ;

explain:
570
    EXPLAIN command_wrapper
羽飞's avatar
羽飞 已提交
571
    {
572 573
      $$ = new Command(SCF_EXPLAIN);
      $$->explain.cmd = std::unique_ptr<Command>($2);
羽飞's avatar
羽飞 已提交
574 575
    }
    ;
羽飞's avatar
羽飞 已提交
576

羽飞's avatar
羽飞 已提交
577 578 579 580 581 582 583 584 585 586 587
set_variable:
    SET ID EQ value
    {
      $$ = new Command(SCF_SET_VARIABLE);
      $$->set_variable.name = $2;
      $$->set_variable.value = *$4;
      free($2);
      delete $4;
    }
    ;

羽飞's avatar
羽飞 已提交
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
}