yacc_sql.y 11.8 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 135 136 137
%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
%type <command> help
%type <command> exit
%type <command> command_wrapper
羽飞's avatar
羽飞 已提交
138
// commands should be a list but I use a single command instead
139
%type <command> commands
羽飞's avatar
羽飞 已提交
140 141
%%

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      $$->emplace_back(*$2);
      delete $2;
    }
羽飞's avatar
羽飞 已提交
460
    ;
羽飞's avatar
羽飞 已提交
461 462 463

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

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

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

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

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

      delete $1;
      delete $3;
羽飞's avatar
羽飞 已提交
551 552 553
    }
    ;

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

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

explain:
574
    EXPLAIN command_wrapper
羽飞's avatar
羽飞 已提交
575
    {
576 577
      $$ = new Command(SCF_EXPLAIN);
      $$->explain.cmd = std::unique_ptr<Command>($2);
羽飞's avatar
羽飞 已提交
578 579
    }
    ;
羽飞's avatar
羽飞 已提交
580 581 582 583

opt_semicolon: /*empty*/
    | SEMICOLON
    ;
羽飞's avatar
羽飞 已提交
584 585 586 587
%%
//_____________________________________________________________________
extern void scan_string(const char *str, yyscan_t scanner);

羽飞's avatar
羽飞 已提交
588
int sql_parse(const char *s, ParsedSqlResult *sql_result){
羽飞's avatar
羽飞 已提交
589
  yyscan_t scanner;
羽飞's avatar
羽飞 已提交
590
  yylex_init(&scanner);
羽飞's avatar
羽飞 已提交
591
  scan_string(s, scanner);
羽飞's avatar
羽飞 已提交
592
  int result = yyparse(sql_result, scanner);
羽飞's avatar
羽飞 已提交
593 594
  yylex_destroy(scanner);
  return result;
羽飞's avatar
羽飞 已提交
595
}